char-slop/berry

multipurpose self-modifiable agentic harness

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

Charlotte Somadd opt-in conversation moves when removing project workspaces6276dba

main
1.9 KiB57 linesraw
1export type Workspace = { environment: string; cwd: string; platform: string };
2export type Project = { name: string; roots: Workspace[]; defaultRoot: number };
3export type ProjectInput = {
4  name: string;
5  roots: { environment: string; cwd: string }[];
6  defaultRoot: number;
7  moveConversations?: boolean;
8};
9export type ProjectIndex = Record<string, Project>;
10
11export function workspacePath(path: string, platform: string): string {
12  const normalized = platform === "win32" ? path.replaceAll("\\", "/").toLowerCase() : path;
13  return normalized.replace(/\/+$/u, "") || "/";
14}
15
16/** The most specific workspace of this project containing the directory. */
17export function workspaceFor(
18  project: Project,
19  binding: { environment: string; cwd: string } | undefined,
20): Workspace | null {
21  if (!binding) return null;
22  let match: Workspace | null = null;
23  let specificity = -1;
24  for (const root of project.roots) {
25    if (root.environment !== binding.environment) continue;
26    const path = workspacePath(binding.cwd, root.platform);
27    const base = workspacePath(root.cwd, root.platform);
28    if (
29      (path === base || path.startsWith(base === "/" ? "/" : base + "/")) &&
30      base.length > specificity
31    ) {
32      match = root;
33      specificity = base.length;
34    }
35  }
36  return match;
37}
38
39/** The most specific workspace containing this directory, independent of fork ancestry. */
40export function projectFor(
41  projects: ProjectIndex,
42  binding: { environment: string; cwd: string } | undefined,
43): string | null {
44  if (!binding) return null;
45  let match: string | null = null;
46  let specificity = -1;
47  for (const [id, project] of Object.entries(projects)) {
48    const root = workspaceFor(project, binding);
49    if (!root) continue;
50    const length = workspacePath(root.cwd, root.platform).length;
51    if (length > specificity) {
52      match = id;
53      specificity = length;
54    }
55  }
56  return match;
57}