{"version":3,"sources":["../../../../tools/warp_grep/utils/paths.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nexport function resolveUnderRepo(repoRoot: string, targetPath: string): string {\n  const absRoot = path.resolve(repoRoot);\n  const resolved = path.resolve(absRoot, targetPath);\n  ensureWithinRepo(absRoot, resolved);\n  return resolved;\n}\n\nexport function ensureWithinRepo(repoRoot: string, absTarget: string): void {\n  const rel = path.relative(path.resolve(repoRoot), path.resolve(absTarget));\n  if (rel.startsWith('..') || path.isAbsolute(rel)) {\n    throw new Error(`Path outside repository root: ${absTarget}`);\n  }\n}\n\nexport function toRepoRelative(repoRoot: string, absPath: string): string {\n  return path.relative(path.resolve(repoRoot), path.resolve(absPath));\n}\n\nexport function isSymlink(p: string): boolean {\n  try {\n    const st = fs.lstatSync(p);\n    return st.isSymbolicLink();\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Detects and removes consecutive duplicate path segments.\n *\n * When the model predicts a path that includes the repo directory name,\n * joining with repoRoot creates duplication:\n *   repoRoot=\"/Users/dhruv/repo\" + predicted=\"repo/src/file.ts\"\n *   → \"/Users/dhruv/repo/repo/src/file.ts\"\n *\n * This function detects such patterns and returns the corrected path,\n * or null if no duplication is found.\n */\nexport function fixPathRepetition(fullPath: string): string | null {\n  const segments = fullPath.split(path.sep).filter(Boolean);\n  if (segments.length < 2) return null;\n\n  for (let len = Math.floor(segments.length / 2); len >= 1; len--) {\n    for (let i = 0; i <= segments.length - 2 * len; i++) {\n      const first = segments.slice(i, i + len);\n      const second = segments.slice(i + len, i + 2 * len);\n\n      if (first.every((seg, idx) => seg === second[idx])) {\n        const fixed = [...segments.slice(0, i), ...segments.slice(i + len)];\n        return path.sep + fixed.join(path.sep);\n      }\n    }\n  }\n\n  return null;\n}\n\nexport function isTextualFile(filePath: string, maxBytes = 2_000_000): boolean {\n  try {\n    const st = fs.statSync(filePath);\n    if (!st.isFile()) return false;\n    if (st.size > maxBytes) return false;\n    const fd = fs.openSync(filePath, 'r');\n    const buf = Buffer.alloc(512);\n    const read = fs.readSync(fd, buf, 0, buf.length, 0);\n    fs.closeSync(fd);\n    for (let i = 0; i < read; i++) {\n      const c = buf[i];\n      if (c === 0) return false; // binary heuristic\n    }\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAiB;AAEV,SAAS,iBAAiB,UAAkB,YAA4B;AAC7E,QAAM,UAAU,YAAAA,QAAK,QAAQ,QAAQ;AACrC,QAAM,WAAW,YAAAA,QAAK,QAAQ,SAAS,UAAU;AACjD,mBAAiB,SAAS,QAAQ;AAClC,SAAO;AACT;AAEO,SAAS,iBAAiB,UAAkB,WAAyB;AAC1E,QAAM,MAAM,YAAAA,QAAK,SAAS,YAAAA,QAAK,QAAQ,QAAQ,GAAG,YAAAA,QAAK,QAAQ,SAAS,CAAC;AACzE,MAAI,IAAI,WAAW,IAAI,KAAK,YAAAA,QAAK,WAAW,GAAG,GAAG;AAChD,UAAM,IAAI,MAAM,iCAAiC,SAAS,EAAE;AAAA,EAC9D;AACF;AAEO,SAAS,eAAe,UAAkB,SAAyB;AACxE,SAAO,YAAAA,QAAK,SAAS,YAAAA,QAAK,QAAQ,QAAQ,GAAG,YAAAA,QAAK,QAAQ,OAAO,CAAC;AACpE;AAEO,SAAS,UAAU,GAAoB;AAC5C,MAAI;AACF,UAAM,KAAK,UAAAC,QAAG,UAAU,CAAC;AACzB,WAAO,GAAG,eAAe;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAaO,SAAS,kBAAkB,UAAiC;AACjE,QAAM,WAAW,SAAS,MAAM,YAAAD,QAAK,GAAG,EAAE,OAAO,OAAO;AACxD,MAAI,SAAS,SAAS,EAAG,QAAO;AAEhC,WAAS,MAAM,KAAK,MAAM,SAAS,SAAS,CAAC,GAAG,OAAO,GAAG,OAAO;AAC/D,aAAS,IAAI,GAAG,KAAK,SAAS,SAAS,IAAI,KAAK,KAAK;AACnD,YAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,GAAG;AACvC,YAAM,SAAS,SAAS,MAAM,IAAI,KAAK,IAAI,IAAI,GAAG;AAElD,UAAI,MAAM,MAAM,CAAC,KAAK,QAAQ,QAAQ,OAAO,GAAG,CAAC,GAAG;AAClD,cAAM,QAAQ,CAAC,GAAG,SAAS,MAAM,GAAG,CAAC,GAAG,GAAG,SAAS,MAAM,IAAI,GAAG,CAAC;AAClE,eAAO,YAAAA,QAAK,MAAM,MAAM,KAAK,YAAAA,QAAK,GAAG;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,UAAkB,WAAW,KAAoB;AAC7E,MAAI;AACF,UAAM,KAAK,UAAAC,QAAG,SAAS,QAAQ;AAC/B,QAAI,CAAC,GAAG,OAAO,EAAG,QAAO;AACzB,QAAI,GAAG,OAAO,SAAU,QAAO;AAC/B,UAAM,KAAK,UAAAA,QAAG,SAAS,UAAU,GAAG;AACpC,UAAM,MAAM,OAAO,MAAM,GAAG;AAC5B,UAAM,OAAO,UAAAA,QAAG,SAAS,IAAI,KAAK,GAAG,IAAI,QAAQ,CAAC;AAClD,cAAAA,QAAG,UAAU,EAAE;AACf,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,IAAI,IAAI,CAAC;AACf,UAAI,MAAM,EAAG,QAAO;AAAA,IACtB;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":["path","fs"]}