char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somadd workspace projects and folder autocompleteeda338f

main
1.7 KiB36 linesraw
1import type { Context } from "@earendil-works/chord";
2import { getOrThrow } from "@earendil-works/pi-durable/env";
3import { posix, win32 } from "node:path";
4import type { Environment } from "@berry/api/environment.ts";
5
6export async function folders(
7  env: Environment,
8  prefix: string,
9  context: Context,
10): Promise<string[]> {
11  if (prefix.includes("\0")) throw new Error("Invalid directory prefix");
12  const paths = env.platform === "win32" ? win32 : posix;
13  const expanded = prefix === "~" || /^~[/\\]/u.test(prefix) ? env.home + prefix.slice(1) : prefix;
14  const trailing = expanded === "" ||
15    (env.platform === "win32" ? /[/\\]$/u : /\/$/u).test(expanded);
16  const parent = trailing ? expanded || "." : paths.dirname(expanded);
17  const query = trailing ? "" : paths.basename(expanded);
18  const absolute = getOrThrow(await env.absolutePath(parent, context));
19  const entries = getOrThrow(await env.listDir(absolute, context));
20  const matches = [];
21  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
22    const matchesPrefix = env.platform === "win32"
23      ? entry.name.toLowerCase().startsWith(query.toLowerCase())
24      : entry.name.startsWith(query);
25    if (!matchesPrefix || (entry.kind !== "directory" && entry.kind !== "symlink")) continue;
26    if (entry.kind === "symlink") {
27      const canonical = await env.canonicalPath(entry.path, context);
28      if (!canonical.ok) continue;
29      const info = await env.fileInfo(canonical.value, context);
30      if (!info.ok || info.value.kind !== "directory") continue;
31    }
32    matches.push(paths.join(parent === "." ? "" : parent, entry.name) + paths.sep);
33    if (matches.length === 50) break;
34  }
35  return matches;
36}