// tools/warp_grep/utils/paths.ts
import fs from "fs";
import path from "path";
function resolveUnderRepo(repoRoot, targetPath) {
  const absRoot = path.resolve(repoRoot);
  const resolved = path.resolve(absRoot, targetPath);
  ensureWithinRepo(absRoot, resolved);
  return resolved;
}
function ensureWithinRepo(repoRoot, absTarget) {
  const rel = path.relative(path.resolve(repoRoot), path.resolve(absTarget));
  if (rel.startsWith("..") || path.isAbsolute(rel)) {
    throw new Error(`Path outside repository root: ${absTarget}`);
  }
}
function toRepoRelative(repoRoot, absPath) {
  return path.relative(path.resolve(repoRoot), path.resolve(absPath));
}
function isSymlink(p) {
  try {
    const st = fs.lstatSync(p);
    return st.isSymbolicLink();
  } catch {
    return false;
  }
}
function fixPathRepetition(fullPath) {
  const segments = fullPath.split(path.sep).filter(Boolean);
  if (segments.length < 2) return null;
  for (let len = Math.floor(segments.length / 2); len >= 1; len--) {
    for (let i = 0; i <= segments.length - 2 * len; i++) {
      const first = segments.slice(i, i + len);
      const second = segments.slice(i + len, i + 2 * len);
      if (first.every((seg, idx) => seg === second[idx])) {
        const fixed = [...segments.slice(0, i), ...segments.slice(i + len)];
        return path.sep + fixed.join(path.sep);
      }
    }
  }
  return null;
}
function isTextualFile(filePath, maxBytes = 2e6) {
  try {
    const st = fs.statSync(filePath);
    if (!st.isFile()) return false;
    if (st.size > maxBytes) return false;
    const fd = fs.openSync(filePath, "r");
    const buf = Buffer.alloc(512);
    const read = fs.readSync(fd, buf, 0, buf.length, 0);
    fs.closeSync(fd);
    for (let i = 0; i < read; i++) {
      const c = buf[i];
      if (c === 0) return false;
    }
    return true;
  } catch {
    return false;
  }
}

export {
  resolveUnderRepo,
  ensureWithinRepo,
  toRepoRelative,
  isSymlink,
  fixPathRepetition,
  isTextualFile
};
//# sourceMappingURL=chunk-YPKNMYD4.js.map