Files
2026-07-13 12:52:40 +08:00

48 lines
1.3 KiB
TypeScript

import { getFileIndex } from "@cline/core";
import type { SidecarContext } from "../types";
export function searchWorkspaceFiles(
ctx: Pick<SidecarContext, "workspaceRoot">,
args?: Record<string, unknown>,
): Promise<string[]> {
const root =
typeof args?.workspaceRoot === "string" && args.workspaceRoot.trim()
? args.workspaceRoot.trim()
: ctx.workspaceRoot;
const query =
typeof args?.query === "string" ? args.query.trim().toLowerCase() : "";
const limit =
typeof args?.limit === "number" && Number.isFinite(args.limit)
? Math.max(1, Math.min(50, Math.trunc(args.limit)))
: 10;
const rankPath = (path: string) => {
if (!query) {
return 3;
}
const lower = path.toLowerCase();
if (lower.startsWith(query)) {
return 0;
}
if (lower.includes(`/${query}`)) {
return 1;
}
if (lower.includes(query)) {
return 2;
}
return Number.POSITIVE_INFINITY;
};
return getFileIndex(root).then((index) =>
Array.from(index)
.sort((a, b) => a.localeCompare(b))
.map((path) => ({ path, rank: rankPath(path) }))
.filter((item) => Number.isFinite(item.rank))
.sort((left, right) =>
left.rank !== right.rank
? left.rank - right.rank
: left.path.localeCompare(right.path),
)
.slice(0, limit)
.map((item) => item.path),
);
}