{"version":3,"sources":["../../../../tools/warp_grep/providers/remote.ts","../../../../tools/warp_grep/agent/config.ts"],"sourcesContent":["/**\n * RemoteCommandsProvider - wraps simple RemoteCommands into WarpGrepProvider\n * \n * Handles parsing of raw stdout from grep/read/listDir commands.\n * Users just return stdout, SDK handles all format conversion.\n */\n\nimport type { WarpGrepProvider, GrepResult, ReadResult, GlobResult, ListDirectoryEntry } from './types.js';\nimport type { RemoteCommands } from '../types.js';\nimport { AGENT_CONFIG } from '../agent/config.js';\n\n/**\n * Directories/files to always skip (exact name match)\n */\nconst SKIP_NAMES = new Set([\n  // Version control\n  '.git', '.svn', '.hg', '.bzr',\n  // Dependencies\n  'node_modules', 'bower_components', '.pnpm', '.yarn',\n  'vendor', 'Pods', '.bundle',\n  // Python\n  '__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache',\n  '.venv', 'venv', '.tox', '.nox', '.eggs',\n  // Build outputs\n  'dist', 'build', 'out', 'output', 'target', '_build',\n  '.next', '.nuxt', '.output', '.vercel', '.netlify',\n  // Cache\n  '.cache', '.parcel-cache', '.turbo', '.nx', '.gradle',\n  // IDE\n  '.idea', '.vscode', '.vs',\n  // Coverage\n  'coverage', '.coverage', 'htmlcov', '.nyc_output',\n  // Temp\n  'tmp', 'temp', '.tmp', '.temp',\n  // Lock files\n  'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb',\n  'Cargo.lock', 'Gemfile.lock', 'poetry.lock',\n]);\n\n/**\n * File extensions to skip\n */\nconst SKIP_EXTENSIONS = new Set([\n  '.min.js', '.min.css', '.bundle.js',\n  '.wasm', '.so', '.dll', '.pyc',\n  '.map', '.js.map',\n]);\n\n/**\n * Check if a filename should be skipped\n */\nfunction shouldSkip(name: string): boolean {\n  // Skip exact name matches\n  if (SKIP_NAMES.has(name)) return true;\n  \n  // Skip hidden files/directories (start with .)\n  if (name.startsWith('.')) return true;\n  \n  // Skip files with certain extensions\n  for (const ext of SKIP_EXTENSIONS) {\n    if (name.endsWith(ext)) return true;\n  }\n  \n  return false;\n}\n\n/**\n * Wraps simple RemoteCommands functions into a full WarpGrepProvider.\n * \n * This allows users to provide three simple functions that return raw stdout,\n * and the SDK handles all parsing internally.\n * \n * @example\n * ```typescript\n * const provider = new RemoteCommandsProvider('/home/repo', {\n *   grep: async (pattern, path) => {\n *     const r = await sandbox.run(`rg '${pattern}' '${path}'`);\n *     return r.stdout;\n *   },\n *   read: async (path, start, end) => {\n *     const r = await sandbox.run(`sed -n '${start},${end}p' '${path}'`);\n *     return r.stdout;\n *   },\n *   listDir: async (path, maxDepth) => {\n *     const r = await sandbox.run(`find '${path}' -maxdepth ${maxDepth}`);\n *     return r.stdout;\n *   },\n * });\n * ```\n */\nexport class RemoteCommandsProvider implements WarpGrepProvider {\n  constructor(\n    private readonly repoRoot: string,\n    private readonly commands: RemoteCommands\n  ) {}\n\n  /**\n   * Run grep command and parse ripgrep output\n   */\n  async grep(params: { pattern: string; path: string; glob?: string }): Promise<GrepResult> {\n    try {\n      const stdout = await this.commands.grep(params.pattern, params.path, params.glob);\n      \n      // Parse ripgrep output: each line is \"path:line:content\" or \"path-line-content\" for context\n      const lines = (stdout || '')\n        .trim()\n        .split(/\\r?\\n/)\n        .filter((l) => l.length > 0);\n      \n      // Truncate if too many lines (return partial results like training harness)\n      if (lines.length > AGENT_CONFIG.MAX_OUTPUT_LINES) {\n        const truncated = lines.slice(0, AGENT_CONFIG.MAX_OUTPUT_LINES);\n        truncated.push(`... (output truncated at ${AGENT_CONFIG.MAX_OUTPUT_LINES} of ${lines.length} lines)`);\n        return { lines: truncated };\n      }\n      \n      return { lines };\n    } catch (error) {\n      return {\n        lines: [],\n        error: `[GREP ERROR] ${error instanceof Error ? error.message : String(error)}`,\n      };\n    }\n  }\n\n  /**\n   * Read file and add line numbers\n   */\n  async read(params: { path: string; start?: number; end?: number }): Promise<ReadResult> {\n    const rawStart = params.start;\n    const rawEnd = params.end;\n    \n    const startValid = rawStart === undefined || (Number.isFinite(rawStart) && rawStart > 0);\n    const endValid = rawEnd === undefined || (Number.isFinite(rawEnd) && rawEnd > 0);\n    const rangeValid = startValid && endValid && \n      (rawStart === undefined || rawEnd === undefined || rawStart <= rawEnd);\n    \n    const start = rangeValid && rawStart !== undefined ? rawStart : 1;\n    const end = rangeValid && rawEnd !== undefined ? rawEnd : 1_000_000;\n    \n    try {\n      const stdout = await this.commands.read(params.path, start, end);\n      \n      // Split content into lines and add line numbers\n      const contentLines = (stdout || '').split('\\n');\n      \n      // Remove trailing empty line if present (common with sed output)\n      if (contentLines.length > 0 && contentLines[contentLines.length - 1] === '') {\n        contentLines.pop();\n      }\n      \n      // Format as \"lineNumber|content\"\n      const lines = contentLines.map((content, idx) => `${start + idx}|${content}`);\n      \n      // Check if output is too large\n      if (lines.length > AGENT_CONFIG.MAX_READ_LINES) {\n        const truncated = lines.slice(0, AGENT_CONFIG.MAX_READ_LINES);\n        truncated.push(`... (output truncated at ${AGENT_CONFIG.MAX_READ_LINES} of ${lines.length} lines)`);\n        return { lines: truncated };\n      }\n      \n      return { lines };\n    } catch (error) {\n      return {\n        lines: [],\n        error: `[READ ERROR] ${error instanceof Error ? error.message : String(error)}`,\n      };\n    }\n  }\n\n  /**\n   * List directory and parse find output\n   */\n  async listDirectory(params: { \n    path: string; \n    pattern?: string | null; \n    maxResults?: number; \n    maxDepth?: number;\n  }): Promise<ListDirectoryEntry[]> {\n    const maxDepth = params.maxDepth ?? AGENT_CONFIG.MAX_LIST_DEPTH;\n    const maxResults = params.maxResults ?? AGENT_CONFIG.MAX_OUTPUT_LINES;\n    \n    try {\n      const stdout = await this.commands.listDir(params.path, maxDepth);\n      \n      // Parse find output: one path per line\n      const paths = (stdout || '')\n        .trim()\n        .split(/\\r?\\n/)\n        .filter((p) => p.length > 0);\n      \n      const regex = params.pattern ? new RegExp(params.pattern) : null;\n      const entries: ListDirectoryEntry[] = [];\n      \n      for (const fullPath of paths) {\n        // Skip the root path itself\n        if (fullPath === params.path || fullPath === this.repoRoot) continue;\n        \n        const name = fullPath.split('/').pop() || '';\n        \n        // Simple name-based filtering - skip junk dirs/files\n        if (shouldSkip(name)) continue;\n        \n        // Apply pattern filter if provided\n        if (regex && !regex.test(name)) continue;\n        \n        // Determine relative path\n        let relativePath = fullPath;\n        if (fullPath.startsWith(this.repoRoot)) {\n          relativePath = fullPath.slice(this.repoRoot.length).replace(/^\\//, '');\n        }\n        \n        // Calculate depth based on path separators\n        const depth = relativePath.split('/').filter(Boolean).length - 1;\n        \n        // Determine if it's a directory (ends with / or infer from path structure)\n        // Note: Most sandbox find commands don't indicate type, so we guess based on extension\n        const hasExtension = name.includes('.') && !name.startsWith('.');\n        const type: 'file' | 'dir' = hasExtension ? 'file' : 'dir';\n        \n        entries.push({\n          name,\n          path: relativePath,\n          type,\n          depth: Math.max(0, depth),\n        });\n        \n        if (entries.length >= maxResults) break;\n      }\n      \n      return entries;\n    } catch (error) {\n      // Return empty array on error (consistent with LocalRipgrepProvider)\n      return [];\n    }\n  }\n\n  /**\n   * Glob search - finds files matching a pattern.\n   * Falls back to a grep --files approach via the listDir command.\n   */\n  async glob(params: { pattern: string; path?: string }): Promise<GlobResult> {\n    const searchPath = params.path || this.repoRoot;\n    try {\n      // Use find with -name to simulate glob\n      const stdout = await this.commands.listDir(searchPath, 10);\n      const allPaths = (stdout || '')\n        .trim()\n        .split(/\\r?\\n/)\n        .filter((p) => p.length > 0);\n\n      // Simple glob matching: convert glob pattern to regex\n      const globToRegex = (glob: string) => {\n        const escaped = glob\n          .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n          .replace(/\\*/g, '.*')\n          .replace(/\\?/g, '.');\n        return new RegExp(escaped);\n      };\n      const regex = globToRegex(params.pattern);\n\n      const matched = allPaths\n        .filter(p => {\n          const name = p.split('/').pop() || '';\n          return regex.test(name) && !shouldSkip(name);\n        });\n\n      const totalFound = matched.length;\n      return { files: matched.slice(0, 100), searchDir: searchPath, totalFound };\n    } catch (error) {\n      return {\n        files: [],\n        searchDir: searchPath,\n        totalFound: 0,\n        error: `[GLOB ERROR] ${error instanceof Error ? error.message : String(error)}`,\n      };\n    }\n  }\n}\n","// Parse timeout from env, defaulting to 30 seconds\nconst parseEnvTimeout = (envValue: string | undefined, defaultMs: number): number => {\n  if (!envValue) return defaultMs;\n  const parsed = parseInt(envValue, 10);\n  return isNaN(parsed) || parsed <= 0 ? defaultMs : parsed;\n};\n\nexport const AGENT_CONFIG = {\n  MAX_TURNS: 6,\n  /** Default timeout for model calls. Can be overridden via MORPH_WARP_GREP_TIMEOUT env var (in ms) */\n  TIMEOUT_MS: parseEnvTimeout(process.env.MORPH_WARP_GREP_TIMEOUT, 60_000),\n  MAX_CONTEXT_CHARS: 321_600,\n  MAX_OUTPUT_LINES: 200,\n  MAX_LIST_RESULTS: 500,\n  MAX_READ_LINES: 800,\n  MAX_LIST_DEPTH: 3,\n  LIST_TIMEOUT_MS: 2_000,\n};\n\n/**\n * Comprehensive exclusion list for directories and files\n * These patterns are used with ripgrep's -g flag\n */\nconst BUILTIN_EXCLUDES = [\n  // Version control\n  '.git', '.svn', '.hg', '.bzr',\n  \n  // Dependencies\n  'node_modules', 'bower_components', '.pnpm', '.yarn',\n  'vendor', 'packages', 'Pods', '.bundle',\n  \n  // Python\n  '__pycache__', '.pytest_cache', '.mypy_cache', '.ruff_cache',\n  '.venv', 'venv', '.tox', '.nox', '.eggs', '*.egg-info',\n  \n  // Build outputs\n  'dist', 'build', 'out', 'output', 'target', '_build',\n  '.next', '.nuxt', '.output', '.vercel', '.netlify',\n  \n  // Cache directories\n  '.cache', '.parcel-cache', '.turbo', '.nx', '.gradle',\n  \n  // IDE/Editor\n  '.idea', '.vscode', '.vs',\n  \n  // Coverage\n  'coverage', '.coverage', 'htmlcov', '.nyc_output',\n  \n  // Temporary\n  'tmp', 'temp', '.tmp', '.temp',\n  \n  // Lock files\n  'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb',\n  'Cargo.lock', 'Gemfile.lock', 'poetry.lock',\n  \n  // Binary/minified\n  '*.min.js', '*.min.css', '*.bundle.js',\n  '*.wasm', '*.so', '*.dll', '*.pyc',\n  '*.map', '*.js.map',\n  \n  // Hidden directories catch-all\n  '.*',\n];\n\nexport const DEFAULT_EXCLUDES = (process.env.MORPH_WARP_GREP_EXCLUDE || '')\n  .split(',')\n  .map(s => s.trim())\n  .filter(Boolean)\n  .concat(BUILTIN_EXCLUDES);\n\nexport const DEFAULT_MODEL = 'morph-warp-grep-v2.1';\n"],"mappings":"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","names":[]}