import path from "path" import { Effect } from "effect" import { InstanceState } from "@/effect/instance-state" import type * as Tool from "./tool" import { containsPath } from "../project/instance-context" import { FSUtil } from "@opencode-ai/core/fs-util" type Kind = "file" | "directory" type Options = { bypass?: boolean kind?: Kind } export const assertExternalDirectoryEffect = Effect.fn("Tool.assertExternalDirectory")(function* ( ctx: Tool.Context, target?: string, options?: Options, ) { if (!target) return false if (options?.bypass) return false const ins = yield* InstanceState.context const full = process.platform === "win32" ? FSUtil.normalizePath(target) : target if (containsPath(full, ins)) return false const kind = options?.kind ?? "file" const dir = kind === "directory" ? full : path.dirname(full) const glob = process.platform === "win32" ? FSUtil.normalizePathPattern(path.join(dir, "*")) : path.join(dir, "*").replaceAll("\\", "/") yield* ctx.ask({ permission: "external_directory", patterns: [glob], always: [glob], metadata: { filepath: full, parentDir: dir, }, }) return true }) export async function assertExternalDirectory(ctx: Tool.Context, target?: string, options?: Options) { return Effect.runPromise(assertExternalDirectoryEffect(ctx, target, options)) }