|
|
@@ -1,10 +1,9 @@
|
|
|
import path from "path"
|
|
|
import z from "zod"
|
|
|
-import { Effect, Option } from "effect"
|
|
|
-import * as Stream from "effect/Stream"
|
|
|
+import { Effect } from "effect"
|
|
|
import { InstanceState } from "@/effect/instance-state"
|
|
|
import { AppFileSystem } from "../filesystem"
|
|
|
-import { Ripgrep } from "../file/ripgrep"
|
|
|
+import { Search } from "../file/search"
|
|
|
import { assertExternalDirectoryEffect } from "./external-directory"
|
|
|
import DESCRIPTION from "./glob.txt"
|
|
|
import { Tool } from "./tool"
|
|
|
@@ -12,8 +11,8 @@ import { Tool } from "./tool"
|
|
|
export const GlobTool = Tool.define(
|
|
|
"glob",
|
|
|
Effect.gen(function* () {
|
|
|
- const rg = yield* Ripgrep.Service
|
|
|
const fs = yield* AppFileSystem.Service
|
|
|
+ const searchSvc = yield* Search.Service
|
|
|
|
|
|
return {
|
|
|
description: DESCRIPTION,
|
|
|
@@ -48,36 +47,18 @@ export const GlobTool = Tool.define(
|
|
|
yield* assertExternalDirectoryEffect(ctx, search, { kind: "directory" })
|
|
|
|
|
|
const limit = 100
|
|
|
- let truncated = false
|
|
|
- const files = yield* rg.files({ cwd: search, glob: [params.pattern], signal: ctx.abort }).pipe(
|
|
|
- Stream.mapEffect((file) =>
|
|
|
- Effect.gen(function* () {
|
|
|
- const full = path.resolve(search, file)
|
|
|
- const info = yield* fs.stat(full).pipe(Effect.catch(() => Effect.succeed(undefined)))
|
|
|
- const mtime =
|
|
|
- info?.mtime.pipe(
|
|
|
- Option.map((date) => date.getTime()),
|
|
|
- Option.getOrElse(() => 0),
|
|
|
- ) ?? 0
|
|
|
- return { path: full, mtime }
|
|
|
- }),
|
|
|
- ),
|
|
|
- Stream.take(limit + 1),
|
|
|
- Stream.runCollect,
|
|
|
- Effect.map((chunk) => [...chunk]),
|
|
|
- )
|
|
|
-
|
|
|
- if (files.length > limit) {
|
|
|
- truncated = true
|
|
|
- files.length = limit
|
|
|
- }
|
|
|
- files.sort((a, b) => b.mtime - a.mtime)
|
|
|
+ const files = yield* searchSvc.glob({
|
|
|
+ cwd: search,
|
|
|
+ pattern: params.pattern,
|
|
|
+ limit,
|
|
|
+ signal: ctx.abort,
|
|
|
+ })
|
|
|
|
|
|
const output = []
|
|
|
- if (files.length === 0) output.push("No files found")
|
|
|
- if (files.length > 0) {
|
|
|
- output.push(...files.map((file) => file.path))
|
|
|
- if (truncated) {
|
|
|
+ if (files.files.length === 0) output.push("No files found")
|
|
|
+ if (files.files.length > 0) {
|
|
|
+ output.push(...files.files)
|
|
|
+ if (files.truncated) {
|
|
|
output.push("")
|
|
|
output.push(
|
|
|
`(Results are truncated: showing first ${limit} results. Consider using a more specific path or pattern.)`,
|
|
|
@@ -88,8 +69,8 @@ export const GlobTool = Tool.define(
|
|
|
return {
|
|
|
title: path.relative(ins.worktree, search),
|
|
|
metadata: {
|
|
|
- count: files.length,
|
|
|
- truncated,
|
|
|
+ count: files.files.length,
|
|
|
+ truncated: files.truncated,
|
|
|
},
|
|
|
output: output.join("\n"),
|
|
|
}
|