refactor(core): simplify search root protocol (#31060)

This commit is contained in:
Kit Langton
2026-06-06 03:20:06 +00:00
committed by GitHub
parent 4ac4df448a
commit 09d9cf01f9
8 changed files with 18 additions and 89 deletions
@@ -243,32 +243,6 @@ describe("LocationSearch", () => {
),
)
it.live("rejects an approved root swapped to a symlink before ripgrep traversal", () =>
withTmp((directory) =>
Effect.gen(function* () {
if (process.platform === "win32") return
const source = path.join(directory, "src")
const outside = `${directory}-outside`
yield* Effect.promise(async () => {
await fs.mkdir(source)
await fs.mkdir(outside)
await fs.writeFile(path.join(outside, "secret.txt"), "secret\n")
})
const filesystem = yield* FileSystem.Service
const approved = yield* filesystem.resolveRoot({ path: RelativePath.make("src") })
yield* Effect.promise(async () => {
await fs.rmdir(source)
await fs.symlink(outside, source)
})
expect(
Exit.isFailure(yield* (yield* LocationSearch.Service).files({ pattern: "*" }, approved).pipe(Effect.exit)),
).toBe(true)
yield* Effect.promise(() => fs.rm(outside, { recursive: true, force: true }))
}).pipe(provide(directory)),
),
)
it.live("honors a pre-aborted cancellation signal", () =>
withTmp((directory) =>
Effect.gen(function* () {
+1 -9
View File
@@ -13,7 +13,6 @@ const sessionID = SessionV2.ID.make("ses_glob_tool_test")
const assertions: PermissionV2.AssertInput[] = []
const resolutions: FileSystem.ListInput[] = []
const searches: LocationSearch.FilesInput[] = []
const roots: FileSystem.RootTarget[] = []
let allow = true
let result = new LocationSearch.FilesResult({ items: [], truncated: false, partial: false })
@@ -45,17 +44,13 @@ const filesystem = Layer.succeed(
const relative = input.path ?? RelativePath.make(".")
const resource = input.reference === undefined ? relative : `${input.reference}:${relative}`
return new FileSystem.RootTarget({
absolute: `/project/${relative}`,
real: `/project/${relative}`,
directory: "/project",
root: "/project",
resource,
reference: input.reference,
type: "directory",
dev: 1,
})
}),
revalidateRoot: Effect.succeed,
resolveList: () => Effect.die("unused"),
listResolved: () => Effect.die("unused"),
listPage: () => Effect.die("unused"),
@@ -69,10 +64,9 @@ const filesystem = Layer.succeed(
const search = Layer.succeed(
LocationSearch.Service,
LocationSearch.Service.of({
files: (input, root) =>
files: (input) =>
Effect.sync(() => {
searches.push(input)
if (root) roots.push(root)
return result
}),
grep: () => Effect.die("unused"),
@@ -92,7 +86,6 @@ const reset = () => {
assertions.length = 0
resolutions.length = 0
searches.length = 0
roots.length = 0
allow = true
result = new LocationSearch.FilesResult({ items: [], truncated: false, partial: false })
}
@@ -130,7 +123,6 @@ describe("GlobTool", () => {
])
expect(resolutions).toEqual([{ path: RelativePath.make("src"), reference: undefined }])
expect(searches).toEqual([{ pattern: "**/*.ts", path: RelativePath.make("src"), limit: 12 }])
expect(roots).toMatchObject([{ resource: "src" }])
}),
)
+1 -9
View File
@@ -22,7 +22,6 @@ import { testEffect } from "./lib/effect"
const assertions: PermissionV2.AssertInput[] = []
const searches: LocationSearch.GrepInput[] = []
const roots: FileSystem.RootTarget[] = []
let allow = true
let result = new LocationSearch.GrepResult({ items: [], truncated: false, partial: false })
let searchFailure: Ripgrep.InvalidPatternError | undefined
@@ -37,17 +36,13 @@ const filesystem = Layer.succeed(
resolveRoot: (input = {}) =>
Effect.succeed(
new FileSystem.RootTarget({
absolute: `/project/${input.path ?? "."}`,
real: `/project/${input.path ?? "."}`,
directory: "/project",
root: "/project",
resource: input.reference === undefined ? (input.path ?? ".") : `${input.reference}:${input.path ?? "."}`,
reference: input.reference,
type: "directory",
dev: 1,
}),
),
revalidateRoot: Effect.succeed,
resolveList: () => Effect.die("unused"),
listResolved: () => Effect.die("unused"),
listPage: () => Effect.die("unused"),
@@ -61,10 +56,9 @@ const search = Layer.succeed(
LocationSearch.Service,
LocationSearch.Service.of({
files: () => Effect.die("unused"),
grep: (input, root) =>
grep: (input) =>
Effect.sync(() => {
searches.push(input)
if (root) roots.push(root)
if (searchFailure) throw searchFailure
return result
}),
@@ -107,7 +101,6 @@ const settle = (input: Record<string, unknown>) =>
const reset = () => {
assertions.length = 0
searches.length = 0
roots.length = 0
allow = true
searchFailure = undefined
result = new LocationSearch.GrepResult({ items: [], truncated: false, partial: false })
@@ -172,7 +165,6 @@ describe("GrepTool", () => {
},
])
expect(searches).toEqual([{ pattern: "needle", path: RelativePath.make("src"), include: "*.ts", limit: 2 }])
expect(roots).toMatchObject([{ resource: "src" }])
}),
)
-1
View File
@@ -43,7 +43,6 @@ const filesystem = Layer.succeed(
return Effect.succeed(readResult)
},
resolveRoot: () => Effect.die("unused"),
revalidateRoot: Effect.succeed,
list: () => Effect.die("unused"),
resolveList: () => Effect.die("unused"),
listResolved: () => Effect.die("unused"),