@morphllm/morphsdk 0.2.50 → 0.2.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-4MELBN55.js → chunk-FYQUSDOE.js} +4 -4
- package/dist/{chunk-Z2FBMSNE.js → chunk-HQO45BAJ.js} +5 -1
- package/dist/chunk-HQO45BAJ.js.map +1 -0
- package/dist/{chunk-NRWVMX4O.js → chunk-L5BMGLLQ.js} +29 -22
- package/dist/chunk-L5BMGLLQ.js.map +1 -0
- package/dist/{chunk-SWQPIKPY.js → chunk-LVPVVLTI.js} +70 -49
- package/dist/chunk-LVPVVLTI.js.map +1 -0
- package/dist/{chunk-2TXLSKGU.js → chunk-MZT6HVGD.js} +3 -3
- package/dist/{chunk-DZRBTNQR.js → chunk-PZDR5ZZ2.js} +5 -5
- package/dist/{chunk-KH3RKPPO.js → chunk-UU6XCZG3.js} +4 -4
- package/dist/{chunk-5ASRBH5I.js → chunk-YR53PPVM.js} +4 -4
- package/dist/{chunk-MLDK7SCW.js → chunk-ZJIIICRA.js} +29 -7
- package/dist/chunk-ZJIIICRA.js.map +1 -0
- package/dist/client.cjs +116 -68
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +13 -13
- package/dist/index.cjs +116 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -13
- package/dist/tools/warp_grep/agent/parser.cjs +69 -48
- package/dist/tools/warp_grep/agent/parser.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/parser.d.ts +2 -0
- package/dist/tools/warp_grep/agent/parser.js +1 -1
- package/dist/tools/warp_grep/agent/runner.cjs +88 -62
- package/dist/tools/warp_grep/agent/runner.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/runner.js +7 -7
- package/dist/tools/warp_grep/agent/types.cjs.map +1 -1
- package/dist/tools/warp_grep/agent/types.d.ts +1 -1
- package/dist/tools/warp_grep/anthropic.cjs +116 -68
- package/dist/tools/warp_grep/anthropic.cjs.map +1 -1
- package/dist/tools/warp_grep/anthropic.js +10 -10
- package/dist/tools/warp_grep/index.cjs +116 -68
- package/dist/tools/warp_grep/index.cjs.map +1 -1
- package/dist/tools/warp_grep/index.js +12 -12
- package/dist/tools/warp_grep/openai.cjs +116 -68
- package/dist/tools/warp_grep/openai.cjs.map +1 -1
- package/dist/tools/warp_grep/openai.js +10 -10
- package/dist/tools/warp_grep/providers/local.cjs +28 -6
- package/dist/tools/warp_grep/providers/local.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/local.js +1 -1
- package/dist/tools/warp_grep/providers/types.cjs.map +1 -1
- package/dist/tools/warp_grep/providers/types.d.ts +2 -0
- package/dist/tools/warp_grep/tools/grep.cjs +3 -0
- package/dist/tools/warp_grep/tools/grep.cjs.map +1 -1
- package/dist/tools/warp_grep/tools/grep.js +3 -0
- package/dist/tools/warp_grep/tools/grep.js.map +1 -1
- package/dist/tools/warp_grep/tools/read.cjs +4 -0
- package/dist/tools/warp_grep/tools/read.cjs.map +1 -1
- package/dist/tools/warp_grep/tools/read.js +1 -1
- package/dist/tools/warp_grep/vercel.cjs +116 -68
- package/dist/tools/warp_grep/vercel.cjs.map +1 -1
- package/dist/tools/warp_grep/vercel.js +10 -10
- package/package.json +1 -1
- package/dist/chunk-MLDK7SCW.js.map +0 -1
- package/dist/chunk-NRWVMX4O.js.map +0 -1
- package/dist/chunk-SWQPIKPY.js.map +0 -1
- package/dist/chunk-Z2FBMSNE.js.map +0 -1
- /package/dist/{chunk-4MELBN55.js.map → chunk-FYQUSDOE.js.map} +0 -0
- /package/dist/{chunk-2TXLSKGU.js.map → chunk-MZT6HVGD.js.map} +0 -0
- /package/dist/{chunk-DZRBTNQR.js.map → chunk-PZDR5ZZ2.js.map} +0 -0
- /package/dist/{chunk-KH3RKPPO.js.map → chunk-UU6XCZG3.js.map} +0 -0
- /package/dist/{chunk-5ASRBH5I.js.map → chunk-YR53PPVM.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../tools/warp_grep/providers/local.ts","../../../../tools/warp_grep/utils/ripgrep.ts","../../../../tools/warp_grep/utils/paths.ts","../../../../tools/warp_grep/utils/files.ts","../../../../tools/warp_grep/agent/config.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport fssync from 'fs';\nimport path from 'path';\nimport { runRipgrep } from '../utils/ripgrep.js';\nimport { ensureWithinRepo, resolveUnderRepo, toRepoRelative, isSymlink, isTextualFile } from '../utils/paths.js';\nimport type { WarpGrepProvider, GrepResult, ReadResult, AnalyseEntry } from './types.js';\nimport { readAllLines } from '../utils/files.js';\nimport { DEFAULT_EXCLUDES } from '../agent/config.js';\n\nexport class LocalRipgrepProvider implements WarpGrepProvider {\n constructor(private readonly repoRoot: string, private readonly excludes: string[] = DEFAULT_EXCLUDES) {}\n\n async grep(params: { pattern: string; path: string }): Promise<GrepResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat) return { lines: [] };\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--no-heading',\n '--with-filename',\n '--line-number',\n '--color=never',\n '--trim',\n '--max-columns=400',\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n params.pattern,\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n if (res.exitCode === -1) {\n throw new Error(res.stderr || 'ripgrep (rg) execution failed.');\n }\n if (res.exitCode !== 0 && res.exitCode !== 1) {\n throw new Error(res.stderr || `ripgrep failed with code ${res.exitCode}`);\n }\n const lines = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { lines };\n }\n\n async glob(params: { pattern: string; path: string }): Promise<{ files: string[] }> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--files',\n '-g',\n params.pattern,\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n if (res.exitCode === -1) {\n throw new Error(res.stderr || 'ripgrep (rg) execution failed.');\n }\n const files = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { files };\n }\n\n async read(params: { path: string; start?: number; end?: number }): Promise<ReadResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isFile()) {\n throw new Error(`Path is not a file: ${params.path}`);\n }\n if (isSymlink(abs)) {\n throw new Error(`Refusing to read symlink: ${params.path}`);\n }\n if (!isTextualFile(abs)) {\n throw new Error(`Non-text or too-large file: ${params.path}`);\n }\n const lines = await readAllLines(abs);\n const total = lines.length;\n let s = params.start ?? 1;\n let e = Math.min(params.end ?? total, total);\n if (s > total && total > 0) {\n // Model hallucinated range - fallback to full file\n s = 1;\n e = total;\n }\n const out: string[] = [];\n for (let i = s; i <= e; i += 1) {\n const content = lines[i - 1] ?? '';\n out.push(`${i}|${content}`);\n }\n return { lines: out };\n }\n\n async analyse(params: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }): Promise<AnalyseEntry[]> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isDirectory()) {\n return [];\n }\n const maxResults = params.maxResults ?? 100;\n const maxDepth = params.maxDepth ?? 2;\n const regex = params.pattern ? new RegExp(params.pattern) : null;\n\n const results: AnalyseEntry[] = [];\n async function walk(dir: string, depth: number) {\n if (depth > maxDepth || results.length >= maxResults) return;\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n const rel = toRepoRelative(abs, full).replace(/^[.][/\\\\]?/, '');\n if (DEFAULT_EXCLUDES.some((ex) => rel.split(path.sep).includes(ex))) continue;\n if (regex && !regex.test(entry.name)) continue;\n if (results.length >= maxResults) break;\n results.push({\n name: entry.name,\n path: toRepoRelative(path.resolve(''), full), // relative display\n type: entry.isDirectory() ? 'dir' : 'file',\n depth,\n });\n if (entry.isDirectory()) {\n await walk(full, depth + 1);\n }\n }\n }\n await walk(abs, 0);\n return results;\n }\n}\n\n\n","import { spawn } from 'child_process';\nimport { rgPath } from '@vscode/ripgrep';\n\nexport type ExecResult = { stdout: string; stderr: string; exitCode: number };\n\n// Cache the working ripgrep path to avoid repeated fallback checks\nlet resolvedRgPath: string | null = null;\nlet rgPathChecked = false;\n\nfunction spawnRg(rgBinary: string, args: string[], opts?: { cwd?: string; env?: NodeJS.ProcessEnv }): Promise<ExecResult> {\n return new Promise((resolve) => {\n const child = spawn(rgBinary, args, {\n cwd: opts?.cwd,\n env: { ...process.env, ...(opts?.env || {}) },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (d) => (stdout += d.toString()));\n child.stderr.on('data', (d) => (stderr += d.toString()));\n child.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: typeof code === 'number' ? code : -1 });\n });\n child.on('error', () => {\n resolve({ stdout: '', stderr: 'Failed to spawn ripgrep.', exitCode: -1 });\n });\n });\n}\n\n// Check if a result indicates a binary compatibility failure (not a normal rg error)\nfunction isBinaryFailure(result: ExecResult): boolean {\n // Spawn error\n if (result.exitCode === -1) return true;\n // jemalloc page size issue (common on ARM64 with non-standard page sizes)\n if (result.stderr.includes('jemalloc') || result.stderr.includes('Unsupported system page size')) return true;\n // SIGABRT (134 = 128 + 6)\n if (result.exitCode === 134) return true;\n return false;\n}\n\nexport async function runRipgrep(args: string[], opts?: { cwd?: string; env?: NodeJS.ProcessEnv }): Promise<ExecResult> {\n // If we've already determined the working path, use it\n if (rgPathChecked && resolvedRgPath) {\n return spawnRg(resolvedRgPath, args, opts);\n }\n\n // First attempt: bundled ripgrep\n if (!rgPathChecked) {\n const result = await spawnRg(rgPath, args, opts);\n \n if (!isBinaryFailure(result)) {\n // Bundled binary works, cache it\n resolvedRgPath = rgPath;\n rgPathChecked = true;\n return result;\n }\n\n // Bundled binary failed, try system rg\n const fallbackResult = await spawnRg('rg', args, opts);\n \n if (!isBinaryFailure(fallbackResult)) {\n // System rg works, cache it\n resolvedRgPath = 'rg';\n rgPathChecked = true;\n return fallbackResult;\n }\n\n // Neither works, mark as checked and return the original error\n rgPathChecked = true;\n return { \n stdout: '', \n stderr: 'Failed to spawn ripgrep. Neither bundled nor system rg is available.', \n exitCode: -1 \n };\n }\n\n // rgPathChecked is true but resolvedRgPath is null - no working rg found\n return { \n stdout: '', \n stderr: 'Failed to spawn ripgrep. Neither bundled nor system rg is available.', \n exitCode: -1 \n };\n}\n\n\n","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\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","import fs from 'fs/promises';\n\nexport async function readAllLines(filePath: string): Promise<string[]> {\n const content = await fs.readFile(filePath, 'utf8');\n // Preserve newlines; split keeping consistency\n return content.split(/\\r?\\n/);\n}\n\n\n","// Agent configuration defaults for morph-warp-grep\n// Hard-coded: SDK does not expose control over rounds or timeout.\nexport const AGENT_CONFIG = {\n // Give the model freedom; failsafe cap to prevent infinite loops\n MAX_ROUNDS: 10,\n TIMEOUT_MS: 30000,\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';\n\n\n"],"mappings":"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","names":["import_promises","import_path","path","fs","fs","fs","path"]}
|
|
1
|
+
{"version":3,"sources":["../../../../tools/warp_grep/providers/local.ts","../../../../tools/warp_grep/utils/ripgrep.ts","../../../../tools/warp_grep/utils/paths.ts","../../../../tools/warp_grep/utils/files.ts","../../../../tools/warp_grep/agent/config.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport fssync from 'fs';\nimport path from 'path';\nimport { runRipgrep } from '../utils/ripgrep.js';\nimport { ensureWithinRepo, resolveUnderRepo, toRepoRelative, isSymlink, isTextualFile } from '../utils/paths.js';\nimport type { WarpGrepProvider, GrepResult, ReadResult, AnalyseEntry } from './types.js';\nimport { readAllLines } from '../utils/files.js';\nimport { DEFAULT_EXCLUDES } from '../agent/config.js';\n\nexport class LocalRipgrepProvider implements WarpGrepProvider {\n constructor(private readonly repoRoot: string, private readonly excludes: string[] = DEFAULT_EXCLUDES) {}\n\n async grep(params: { pattern: string; path: string }): Promise<GrepResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat) return { lines: [] };\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--no-heading',\n '--with-filename',\n '--line-number',\n '--color=never',\n '--trim',\n '--max-columns=400',\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n params.pattern,\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n \n // Gracefully handle ripgrep not being available\n if (res.exitCode === -1) {\n return {\n lines: [],\n error: `[RIPGREP NOT AVAILABLE] ripgrep (rg) is required but failed to execute. Please install it:\\n` +\n ` • macOS: brew install ripgrep\\n` +\n ` • Ubuntu/Debian: apt install ripgrep\\n` +\n ` • Windows: choco install ripgrep\\n` +\n ` • Or visit: https://github.com/BurntSushi/ripgrep#installation\\n` +\n `Exit code: ${res.exitCode}${res.stderr ? `\\nDetails: ${res.stderr}` : ''}`,\n };\n }\n \n // Handle other ripgrep errors gracefully\n if (res.exitCode !== 0 && res.exitCode !== 1) {\n return {\n lines: [],\n error: `[RIPGREP ERROR] grep failed with exit code ${res.exitCode}${res.stderr ? `: ${res.stderr}` : ''}`,\n };\n }\n \n const lines = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { lines };\n }\n\n async glob(params: { pattern: string; path: string }): Promise<{ files: string[] }> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const targetArg = abs === path.resolve(this.repoRoot) ? '.' : toRepoRelative(this.repoRoot, abs);\n const args = [\n '--no-config',\n '--files',\n '-g',\n params.pattern,\n ...this.excludes.flatMap((e) => ['-g', `!${e}`]),\n targetArg || '.',\n ];\n const res = await runRipgrep(args, { cwd: this.repoRoot });\n \n // Gracefully handle ripgrep not being available\n if (res.exitCode === -1) {\n // Return empty files with a console warning - glob is less critical than grep\n console.warn(`[warp_grep] ripgrep not available for glob: ${res.stderr || 'execution failed'}`);\n return { files: [] };\n }\n \n const files = (res.stdout || '')\n .trim()\n .split(/\\r?\\n/)\n .filter((l) => l.length > 0);\n return { files };\n }\n\n async read(params: { path: string; start?: number; end?: number }): Promise<ReadResult> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n \n // Gracefully handle file not found / not a file\n if (!stat || !stat.isFile()) {\n return {\n lines: [],\n error: `[FILE NOT FOUND] You tried to read \"${params.path}\" but there is no file at this path. ` +\n `Double-check the path exists and is spelled correctly.`,\n };\n }\n \n // Gracefully handle symlinks\n if (isSymlink(abs)) {\n return {\n lines: [],\n error: `[SYMLINK] You tried to read \"${params.path}\" but this is a symlink. ` +\n `Try reading the actual file it points to instead.`,\n };\n }\n \n // Gracefully handle non-text or too-large files\n if (!isTextualFile(abs)) {\n return {\n lines: [],\n error: `[UNREADABLE FILE] You tried to read \"${params.path}\" but this file is either too large ` +\n `or not a text file, so it cannot be read. Try a different file.`,\n };\n }\n \n const lines = await readAllLines(abs);\n const total = lines.length;\n let s = params.start ?? 1;\n let e = Math.min(params.end ?? total, total);\n if (s > total && total > 0) {\n // Model hallucinated range - fallback to full file\n s = 1;\n e = total;\n }\n const out: string[] = [];\n for (let i = s; i <= e; i += 1) {\n const content = lines[i - 1] ?? '';\n out.push(`${i}|${content}`);\n }\n return { lines: out };\n }\n\n async analyse(params: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }): Promise<AnalyseEntry[]> {\n const abs = resolveUnderRepo(this.repoRoot, params.path);\n const stat = await fs.stat(abs).catch(() => null);\n if (!stat || !stat.isDirectory()) {\n return [];\n }\n const maxResults = params.maxResults ?? 100;\n const maxDepth = params.maxDepth ?? 2;\n const regex = params.pattern ? new RegExp(params.pattern) : null;\n\n const results: AnalyseEntry[] = [];\n async function walk(dir: string, depth: number) {\n if (depth > maxDepth || results.length >= maxResults) return;\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n const rel = toRepoRelative(abs, full).replace(/^[.][/\\\\]?/, '');\n if (DEFAULT_EXCLUDES.some((ex) => rel.split(path.sep).includes(ex))) continue;\n if (regex && !regex.test(entry.name)) continue;\n if (results.length >= maxResults) break;\n results.push({\n name: entry.name,\n path: toRepoRelative(path.resolve(''), full), // relative display\n type: entry.isDirectory() ? 'dir' : 'file',\n depth,\n });\n if (entry.isDirectory()) {\n await walk(full, depth + 1);\n }\n }\n }\n await walk(abs, 0);\n return results;\n }\n}\n\n\n","import { spawn } from 'child_process';\nimport { rgPath } from '@vscode/ripgrep';\n\nexport type ExecResult = { stdout: string; stderr: string; exitCode: number };\n\n// Cache the working ripgrep path to avoid repeated fallback checks\nlet resolvedRgPath: string | null = null;\nlet rgPathChecked = false;\n\nfunction spawnRg(rgBinary: string, args: string[], opts?: { cwd?: string; env?: NodeJS.ProcessEnv }): Promise<ExecResult> {\n return new Promise((resolve) => {\n const child = spawn(rgBinary, args, {\n cwd: opts?.cwd,\n env: { ...process.env, ...(opts?.env || {}) },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (d) => (stdout += d.toString()));\n child.stderr.on('data', (d) => (stderr += d.toString()));\n child.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: typeof code === 'number' ? code : -1 });\n });\n child.on('error', () => {\n resolve({ stdout: '', stderr: 'Failed to spawn ripgrep.', exitCode: -1 });\n });\n });\n}\n\n// Check if a result indicates a binary compatibility failure (not a normal rg error)\nfunction isBinaryFailure(result: ExecResult): boolean {\n // Spawn error\n if (result.exitCode === -1) return true;\n // jemalloc page size issue (common on ARM64 with non-standard page sizes)\n if (result.stderr.includes('jemalloc') || result.stderr.includes('Unsupported system page size')) return true;\n // SIGABRT (134 = 128 + 6)\n if (result.exitCode === 134) return true;\n return false;\n}\n\nexport async function runRipgrep(args: string[], opts?: { cwd?: string; env?: NodeJS.ProcessEnv }): Promise<ExecResult> {\n // If we've already determined the working path, use it\n if (rgPathChecked && resolvedRgPath) {\n return spawnRg(resolvedRgPath, args, opts);\n }\n\n // First attempt: bundled ripgrep\n if (!rgPathChecked) {\n const result = await spawnRg(rgPath, args, opts);\n \n if (!isBinaryFailure(result)) {\n // Bundled binary works, cache it\n resolvedRgPath = rgPath;\n rgPathChecked = true;\n return result;\n }\n\n // Bundled binary failed, try system rg\n const fallbackResult = await spawnRg('rg', args, opts);\n \n if (!isBinaryFailure(fallbackResult)) {\n // System rg works, cache it\n resolvedRgPath = 'rg';\n rgPathChecked = true;\n return fallbackResult;\n }\n\n // Neither works, mark as checked and return the original error\n rgPathChecked = true;\n return { \n stdout: '', \n stderr: 'Failed to spawn ripgrep. Neither bundled nor system rg is available.', \n exitCode: -1 \n };\n }\n\n // rgPathChecked is true but resolvedRgPath is null - no working rg found\n return { \n stdout: '', \n stderr: 'Failed to spawn ripgrep. Neither bundled nor system rg is available.', \n exitCode: -1 \n };\n}\n\n\n","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\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","import fs from 'fs/promises';\n\nexport async function readAllLines(filePath: string): Promise<string[]> {\n const content = await fs.readFile(filePath, 'utf8');\n // Preserve newlines; split keeping consistency\n return content.split(/\\r?\\n/);\n}\n\n\n","// Agent configuration defaults for morph-warp-grep\n// Hard-coded: SDK does not expose control over rounds or timeout.\nexport const AGENT_CONFIG = {\n // Give the model freedom; failsafe cap to prevent infinite loops\n MAX_ROUNDS: 10,\n TIMEOUT_MS: 30000,\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';\n\n\n"],"mappings":"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","names":["import_promises","import_path","path","fs","fs","fs","path"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../tools/warp_grep/providers/types.ts"],"sourcesContent":["export type GrepResult = {\n lines: string[]; // ripgrep style: \"path:line:content\"\n};\n\nexport type ReadResult = {\n lines: string[]; // \"line|content\" format\n};\n\nexport type AnalyseEntry = {\n name: string;\n path: string;\n type: 'file' | 'dir';\n depth: number;\n};\n\nexport interface WarpGrepProvider {\n /**\n * Run regex grep\n */\n grep(params: { pattern: string; path: string }): Promise<GrepResult>;\n\n /**\n * List files by glob pattern (optional; may fallback internally)\n */\n glob?(params: { pattern: string; path: string }): Promise<{ files: string[] }>;\n\n /**\n * Read lines from a file, optionally a range (1-based inclusive)\n */\n read(params: { path: string; start?: number; end?: number }): Promise<ReadResult>;\n\n /**\n * Provide a lightweight directory overview for guidance\n */\n analyse(params: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }): Promise<AnalyseEntry[]>;\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../tools/warp_grep/providers/types.ts"],"sourcesContent":["export type GrepResult = {\n lines: string[]; // ripgrep style: \"path:line:content\"\n error?: string; // Graceful error message (e.g., ripgrep not installed)\n};\n\nexport type ReadResult = {\n lines: string[]; // \"line|content\" format\n error?: string; // Graceful error message (e.g., file not found, not readable)\n};\n\nexport type AnalyseEntry = {\n name: string;\n path: string;\n type: 'file' | 'dir';\n depth: number;\n};\n\nexport interface WarpGrepProvider {\n /**\n * Run regex grep\n */\n grep(params: { pattern: string; path: string }): Promise<GrepResult>;\n\n /**\n * List files by glob pattern (optional; may fallback internally)\n */\n glob?(params: { pattern: string; path: string }): Promise<{ files: string[] }>;\n\n /**\n * Read lines from a file, optionally a range (1-based inclusive)\n */\n read(params: { path: string; start?: number; end?: number }): Promise<ReadResult>;\n\n /**\n * Provide a lightweight directory overview for guidance\n */\n analyse(params: { path: string; pattern?: string | null; maxResults?: number; maxDepth?: number }): Promise<AnalyseEntry[]>;\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -25,6 +25,9 @@ __export(grep_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(grep_exports);
|
|
26
26
|
async function toolGrep(provider, args) {
|
|
27
27
|
const result = await provider.grep({ pattern: args.pattern, path: args.path });
|
|
28
|
+
if (result.error) {
|
|
29
|
+
return `[ERROR] ${result.error}`;
|
|
30
|
+
}
|
|
28
31
|
if (!result.lines.length) return "no new matches";
|
|
29
32
|
return result.lines.join("\n");
|
|
30
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../tools/warp_grep/tools/grep.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolGrep(\n provider: WarpGrepProvider,\n args: { pattern: string; path: string }\n): Promise<string> {\n const result = await provider.grep({ pattern: args.pattern, path: args.path });\n if (!result.lines.length) return 'no new matches';\n return result.lines.join('\\n');\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,eAAsB,SACpB,UACA,MACiB;AACjB,QAAM,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../../../tools/warp_grep/tools/grep.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolGrep(\n provider: WarpGrepProvider,\n args: { pattern: string; path: string }\n): Promise<string> {\n const result = await provider.grep({ pattern: args.pattern, path: args.path });\n // Return error message if present (graceful handling)\n if (result.error) {\n return `[ERROR] ${result.error}`;\n }\n if (!result.lines.length) return 'no new matches';\n return result.lines.join('\\n');\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,eAAsB,SACpB,UACA,MACiB;AACjB,QAAM,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AAE7E,MAAI,OAAO,OAAO;AAChB,WAAO,WAAW,OAAO,KAAK;AAAA,EAChC;AACA,MAAI,CAAC,OAAO,MAAM,OAAQ,QAAO;AACjC,SAAO,OAAO,MAAM,KAAK,IAAI;AAC/B;","names":[]}
|
|
@@ -3,6 +3,9 @@ import "../../../chunk-PZ5AY32C.js";
|
|
|
3
3
|
// tools/warp_grep/tools/grep.ts
|
|
4
4
|
async function toolGrep(provider, args) {
|
|
5
5
|
const result = await provider.grep({ pattern: args.pattern, path: args.path });
|
|
6
|
+
if (result.error) {
|
|
7
|
+
return `[ERROR] ${result.error}`;
|
|
8
|
+
}
|
|
6
9
|
if (!result.lines.length) return "no new matches";
|
|
7
10
|
return result.lines.join("\n");
|
|
8
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../tools/warp_grep/tools/grep.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolGrep(\n provider: WarpGrepProvider,\n args: { pattern: string; path: string }\n): Promise<string> {\n const result = await provider.grep({ pattern: args.pattern, path: args.path });\n if (!result.lines.length) return 'no new matches';\n return result.lines.join('\\n');\n}\n\n\n"],"mappings":";;;AAEA,eAAsB,SACpB,UACA,MACiB;AACjB,QAAM,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../../../tools/warp_grep/tools/grep.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolGrep(\n provider: WarpGrepProvider,\n args: { pattern: string; path: string }\n): Promise<string> {\n const result = await provider.grep({ pattern: args.pattern, path: args.path });\n // Return error message if present (graceful handling)\n if (result.error) {\n return `[ERROR] ${result.error}`;\n }\n if (!result.lines.length) return 'no new matches';\n return result.lines.join('\\n');\n}\n\n\n"],"mappings":";;;AAEA,eAAsB,SACpB,UACA,MACiB;AACjB,QAAM,SAAS,MAAM,SAAS,KAAK,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,CAAC;AAE7E,MAAI,OAAO,OAAO;AAChB,WAAO,WAAW,OAAO,KAAK;AAAA,EAChC;AACA,MAAI,CAAC,OAAO,MAAM,OAAQ,QAAO;AACjC,SAAO,OAAO,MAAM,KAAK,IAAI;AAC/B;","names":[]}
|
|
@@ -25,6 +25,10 @@ __export(read_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(read_exports);
|
|
26
26
|
async function toolRead(provider, args) {
|
|
27
27
|
const res = await provider.read({ path: args.path, start: args.start, end: args.end });
|
|
28
|
+
if (res.error) {
|
|
29
|
+
return res.error;
|
|
30
|
+
}
|
|
31
|
+
if (!res.lines.length) return "(empty file)";
|
|
28
32
|
return res.lines.join("\n");
|
|
29
33
|
}
|
|
30
34
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../tools/warp_grep/tools/read.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number }\n): Promise<string> {\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n return res.lines.join('\\n');\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,eAAsB,SACpB,UACA,MACiB;AACjB,QAAM,MAAM,MAAM,SAAS,KAAK,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,KAAK,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../../../tools/warp_grep/tools/read.ts"],"sourcesContent":["import type { WarpGrepProvider } from '../providers/types.js';\n\nexport async function toolRead(\n provider: WarpGrepProvider,\n args: { path: string; start?: number; end?: number }\n): Promise<string> {\n const res = await provider.read({ path: args.path, start: args.start, end: args.end });\n // Return error message if present (graceful handling)\n if (res.error) {\n return res.error;\n }\n if (!res.lines.length) return '(empty file)';\n return res.lines.join('\\n');\n}\n\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,eAAsB,SACpB,UACA,MACiB;AACjB,QAAM,MAAM,MAAM,SAAS,KAAK,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,KAAK,KAAK,IAAI,CAAC;AAErF,MAAI,IAAI,OAAO;AACb,WAAO,IAAI;AAAA,EACb;AACA,MAAI,CAAC,IAAI,MAAM,OAAQ,QAAO;AAC9B,SAAO,IAAI,MAAM,KAAK,IAAI;AAC5B;","names":[]}
|
|
@@ -252,12 +252,6 @@ function getSystemPrompt() {
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
// tools/warp_grep/agent/parser.ts
|
|
255
|
-
var LLMResponseParseError = class extends Error {
|
|
256
|
-
constructor(message) {
|
|
257
|
-
super(message);
|
|
258
|
-
this.name = "LLMResponseParseError";
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
255
|
var VALID_COMMANDS = ["analyse", "grep", "read", "finish"];
|
|
262
256
|
function preprocessText(text) {
|
|
263
257
|
let processed = text.replace(/<think>[\s\S]*?<\/think>/gi, "");
|
|
@@ -308,24 +302,23 @@ var LLMResponseParser = class {
|
|
|
308
302
|
const lines = preprocessText(text);
|
|
309
303
|
const commands = [];
|
|
310
304
|
let finishAccumulator = null;
|
|
311
|
-
lines.forEach((line
|
|
305
|
+
lines.forEach((line) => {
|
|
312
306
|
if (!line || line.startsWith("#")) return;
|
|
313
|
-
const
|
|
314
|
-
const parts = this.splitLine(line, ctx);
|
|
307
|
+
const parts = this.splitLine(line);
|
|
315
308
|
if (parts.length === 0) return;
|
|
316
309
|
const cmd = parts[0];
|
|
317
310
|
switch (cmd) {
|
|
318
311
|
case "analyse":
|
|
319
|
-
this.handleAnalyse(parts,
|
|
312
|
+
this.handleAnalyse(parts, line, commands);
|
|
320
313
|
break;
|
|
321
314
|
case "grep":
|
|
322
|
-
this.handleGrep(parts,
|
|
315
|
+
this.handleGrep(parts, line, commands);
|
|
323
316
|
break;
|
|
324
317
|
case "read":
|
|
325
|
-
this.handleRead(parts,
|
|
318
|
+
this.handleRead(parts, line, commands);
|
|
326
319
|
break;
|
|
327
320
|
case "finish":
|
|
328
|
-
finishAccumulator = this.handleFinish(parts,
|
|
321
|
+
finishAccumulator = this.handleFinish(parts, line, commands, finishAccumulator);
|
|
329
322
|
break;
|
|
330
323
|
default:
|
|
331
324
|
break;
|
|
@@ -342,53 +335,68 @@ var LLMResponseParser = class {
|
|
|
342
335
|
}
|
|
343
336
|
return commands;
|
|
344
337
|
}
|
|
345
|
-
splitLine(line
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
current = "";
|
|
359
|
-
}
|
|
360
|
-
} else {
|
|
361
|
-
current += ch;
|
|
338
|
+
splitLine(line) {
|
|
339
|
+
const parts = [];
|
|
340
|
+
let current = "";
|
|
341
|
+
let inSingle = false;
|
|
342
|
+
for (let i = 0; i < line.length; i++) {
|
|
343
|
+
const ch = line[i];
|
|
344
|
+
if (ch === "'" && line[i - 1] !== "\\") {
|
|
345
|
+
inSingle = !inSingle;
|
|
346
|
+
current += ch;
|
|
347
|
+
} else if (!inSingle && /\s/.test(ch)) {
|
|
348
|
+
if (current) {
|
|
349
|
+
parts.push(current);
|
|
350
|
+
current = "";
|
|
362
351
|
}
|
|
352
|
+
} else {
|
|
353
|
+
current += ch;
|
|
363
354
|
}
|
|
364
|
-
if (current) parts.push(current);
|
|
365
|
-
return parts;
|
|
366
|
-
} catch {
|
|
367
|
-
throw new LLMResponseParseError(`Line ${ctx.lineNumber}: Unable to parse line.`);
|
|
368
355
|
}
|
|
356
|
+
if (current) parts.push(current);
|
|
357
|
+
return parts;
|
|
358
|
+
}
|
|
359
|
+
/** Helper to create a _skip tool call with an error message */
|
|
360
|
+
skip(message) {
|
|
361
|
+
return { name: "_skip", arguments: { message } };
|
|
369
362
|
}
|
|
370
|
-
handleAnalyse(parts,
|
|
363
|
+
handleAnalyse(parts, rawLine, commands) {
|
|
371
364
|
if (parts.length < 2) {
|
|
372
|
-
|
|
365
|
+
commands.push(this.skip(
|
|
366
|
+
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: analyse <path> [pattern]. Example: analyse src/`
|
|
367
|
+
));
|
|
368
|
+
return;
|
|
373
369
|
}
|
|
374
370
|
const path4 = parts[1];
|
|
375
371
|
const pattern = parts[2]?.replace(/^"|"$/g, "") ?? null;
|
|
376
372
|
commands.push({ name: "analyse", arguments: { path: path4, pattern } });
|
|
377
373
|
}
|
|
378
374
|
// no glob tool in MCP
|
|
379
|
-
handleGrep(parts,
|
|
375
|
+
handleGrep(parts, rawLine, commands) {
|
|
380
376
|
if (parts.length < 3) {
|
|
381
|
-
|
|
377
|
+
commands.push(this.skip(
|
|
378
|
+
`[SKIPPED] Your command "${rawLine}" is missing arguments. Correct format: grep '<pattern>' <path>. Example: grep 'TODO' src/`
|
|
379
|
+
));
|
|
380
|
+
return;
|
|
382
381
|
}
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
|
|
382
|
+
let pat = parts[1];
|
|
383
|
+
if (pat.startsWith("'") && pat.endsWith("'")) {
|
|
384
|
+
pat = pat.slice(1, -1);
|
|
386
385
|
}
|
|
387
|
-
|
|
386
|
+
if (!pat) {
|
|
387
|
+
commands.push(this.skip(
|
|
388
|
+
`[SKIPPED] Your command "${rawLine}" has an empty pattern. Provide a non-empty search pattern. Example: grep 'function' src/`
|
|
389
|
+
));
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
commands.push({ name: "grep", arguments: { pattern: pat, path: parts[2] } });
|
|
388
393
|
}
|
|
389
|
-
handleRead(parts,
|
|
394
|
+
handleRead(parts, rawLine, commands) {
|
|
390
395
|
if (parts.length < 2) {
|
|
391
|
-
|
|
396
|
+
commands.push(this.skip(
|
|
397
|
+
`[SKIPPED] Your command "${rawLine}" is missing a path. Correct format: read <path> or read <path>:<start>-<end>. Example: read src/index.ts:1-50`
|
|
398
|
+
));
|
|
399
|
+
return;
|
|
392
400
|
}
|
|
393
401
|
const spec = parts[1];
|
|
394
402
|
const rangeIdx = spec.indexOf(":");
|
|
@@ -396,31 +404,38 @@ var LLMResponseParser = class {
|
|
|
396
404
|
commands.push({ name: "read", arguments: { path: spec } });
|
|
397
405
|
return;
|
|
398
406
|
}
|
|
399
|
-
const
|
|
407
|
+
const filePath = spec.slice(0, rangeIdx);
|
|
400
408
|
const range = spec.slice(rangeIdx + 1);
|
|
401
409
|
const [s, e] = range.split("-").map((v) => parseInt(v, 10));
|
|
402
410
|
if (!Number.isFinite(s) || !Number.isFinite(e)) {
|
|
403
|
-
|
|
411
|
+
commands.push({ name: "read", arguments: { path: filePath } });
|
|
412
|
+
return;
|
|
404
413
|
}
|
|
405
|
-
commands.push({ name: "read", arguments: { path:
|
|
414
|
+
commands.push({ name: "read", arguments: { path: filePath, start: s, end: e } });
|
|
406
415
|
}
|
|
407
|
-
handleFinish(parts,
|
|
416
|
+
handleFinish(parts, rawLine, commands, acc) {
|
|
408
417
|
const map = acc ?? /* @__PURE__ */ new Map();
|
|
409
418
|
const args = parts.slice(1);
|
|
410
419
|
for (const token of args) {
|
|
411
|
-
const [
|
|
412
|
-
if (!
|
|
413
|
-
|
|
420
|
+
const [filePath, rangesText] = token.split(":", 2);
|
|
421
|
+
if (!filePath || !rangesText) {
|
|
422
|
+
commands.push(this.skip(
|
|
423
|
+
`[SKIPPED] Invalid finish token "${token}". Correct format: finish <path>:<start>-<end>. Example: finish src/index.ts:1-50`
|
|
424
|
+
));
|
|
425
|
+
continue;
|
|
414
426
|
}
|
|
415
427
|
const rangeSpecs = rangesText.split(",").filter(Boolean);
|
|
416
428
|
for (const spec of rangeSpecs) {
|
|
417
429
|
const [s, e] = spec.split("-").map((v) => parseInt(v, 10));
|
|
418
430
|
if (!Number.isFinite(s) || !Number.isFinite(e) || e < s) {
|
|
419
|
-
|
|
431
|
+
commands.push(this.skip(
|
|
432
|
+
`[SKIPPED] Invalid range "${spec}" in "${token}". Ranges must be <start>-<end> where start <= end. Example: 1-50`
|
|
433
|
+
));
|
|
434
|
+
continue;
|
|
420
435
|
}
|
|
421
|
-
const arr = map.get(
|
|
436
|
+
const arr = map.get(filePath) ?? [];
|
|
422
437
|
arr.push([s, e]);
|
|
423
|
-
map.set(
|
|
438
|
+
map.set(filePath, arr);
|
|
424
439
|
}
|
|
425
440
|
}
|
|
426
441
|
return map;
|
|
@@ -430,6 +445,10 @@ var LLMResponseParser = class {
|
|
|
430
445
|
// tools/warp_grep/tools/read.ts
|
|
431
446
|
async function toolRead(provider, args) {
|
|
432
447
|
const res = await provider.read({ path: args.path, start: args.start, end: args.end });
|
|
448
|
+
if (res.error) {
|
|
449
|
+
return res.error;
|
|
450
|
+
}
|
|
451
|
+
if (!res.lines.length) return "(empty file)";
|
|
433
452
|
return res.lines.join("\n");
|
|
434
453
|
}
|
|
435
454
|
|
|
@@ -815,14 +834,7 @@ async function runWarpGrep(config) {
|
|
|
815
834
|
});
|
|
816
835
|
if (!assistantContent) break;
|
|
817
836
|
messages.push({ role: "assistant", content: assistantContent });
|
|
818
|
-
|
|
819
|
-
try {
|
|
820
|
-
toolCalls = parser.parse(assistantContent);
|
|
821
|
-
} catch (e) {
|
|
822
|
-
errors.push({ message: e instanceof Error ? e.message : String(e) });
|
|
823
|
-
terminationReason = "terminated";
|
|
824
|
-
break;
|
|
825
|
-
}
|
|
837
|
+
const toolCalls = parser.parse(assistantContent);
|
|
826
838
|
if (toolCalls.length === 0) {
|
|
827
839
|
errors.push({ message: "No tool calls produced by the model." });
|
|
828
840
|
terminationReason = "terminated";
|
|
@@ -832,7 +844,12 @@ async function runWarpGrep(config) {
|
|
|
832
844
|
const grepCalls = toolCalls.filter((c) => c.name === "grep");
|
|
833
845
|
const analyseCalls = toolCalls.filter((c) => c.name === "analyse");
|
|
834
846
|
const readCalls = toolCalls.filter((c) => c.name === "read");
|
|
847
|
+
const skipCalls = toolCalls.filter((c) => c.name === "_skip");
|
|
835
848
|
const formatted = [];
|
|
849
|
+
for (const c of skipCalls) {
|
|
850
|
+
const msg = c.arguments?.message || "Command skipped due to parsing error";
|
|
851
|
+
formatted.push(msg);
|
|
852
|
+
}
|
|
836
853
|
const otherPromises = [];
|
|
837
854
|
for (const c of analyseCalls) {
|
|
838
855
|
const args = c.arguments ?? {};
|
|
@@ -858,6 +875,15 @@ async function runWarpGrep(config) {
|
|
|
858
875
|
const args = c.arguments ?? {};
|
|
859
876
|
try {
|
|
860
877
|
const grepRes = await provider.grep({ pattern: args.pattern, path: args.path });
|
|
878
|
+
if (grepRes.error) {
|
|
879
|
+
errors.push({ message: grepRes.error });
|
|
880
|
+
terminationReason = "terminated";
|
|
881
|
+
return {
|
|
882
|
+
terminationReason: "terminated",
|
|
883
|
+
messages,
|
|
884
|
+
errors
|
|
885
|
+
};
|
|
886
|
+
}
|
|
861
887
|
const rawOutput = Array.isArray(grepRes.lines) ? grepRes.lines.join("\n") : "";
|
|
862
888
|
const newMatches = parseAndFilterGrepOutput(rawOutput, grepState);
|
|
863
889
|
let formattedPayload = formatTurnGrepOutput(newMatches);
|
|
@@ -1069,10 +1095,22 @@ var LocalRipgrepProvider = class {
|
|
|
1069
1095
|
];
|
|
1070
1096
|
const res = await runRipgrep(args, { cwd: this.repoRoot });
|
|
1071
1097
|
if (res.exitCode === -1) {
|
|
1072
|
-
|
|
1098
|
+
return {
|
|
1099
|
+
lines: [],
|
|
1100
|
+
error: `[RIPGREP NOT AVAILABLE] ripgrep (rg) is required but failed to execute. Please install it:
|
|
1101
|
+
\u2022 macOS: brew install ripgrep
|
|
1102
|
+
\u2022 Ubuntu/Debian: apt install ripgrep
|
|
1103
|
+
\u2022 Windows: choco install ripgrep
|
|
1104
|
+
\u2022 Or visit: https://github.com/BurntSushi/ripgrep#installation
|
|
1105
|
+
Exit code: ${res.exitCode}${res.stderr ? `
|
|
1106
|
+
Details: ${res.stderr}` : ""}`
|
|
1107
|
+
};
|
|
1073
1108
|
}
|
|
1074
1109
|
if (res.exitCode !== 0 && res.exitCode !== 1) {
|
|
1075
|
-
|
|
1110
|
+
return {
|
|
1111
|
+
lines: [],
|
|
1112
|
+
error: `[RIPGREP ERROR] grep failed with exit code ${res.exitCode}${res.stderr ? `: ${res.stderr}` : ""}`
|
|
1113
|
+
};
|
|
1076
1114
|
}
|
|
1077
1115
|
const lines = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
|
|
1078
1116
|
return { lines };
|
|
@@ -1090,7 +1128,8 @@ var LocalRipgrepProvider = class {
|
|
|
1090
1128
|
];
|
|
1091
1129
|
const res = await runRipgrep(args, { cwd: this.repoRoot });
|
|
1092
1130
|
if (res.exitCode === -1) {
|
|
1093
|
-
|
|
1131
|
+
console.warn(`[warp_grep] ripgrep not available for glob: ${res.stderr || "execution failed"}`);
|
|
1132
|
+
return { files: [] };
|
|
1094
1133
|
}
|
|
1095
1134
|
const files = (res.stdout || "").trim().split(/\r?\n/).filter((l) => l.length > 0);
|
|
1096
1135
|
return { files };
|
|
@@ -1099,13 +1138,22 @@ var LocalRipgrepProvider = class {
|
|
|
1099
1138
|
const abs = resolveUnderRepo(this.repoRoot, params.path);
|
|
1100
1139
|
const stat = await import_promises3.default.stat(abs).catch(() => null);
|
|
1101
1140
|
if (!stat || !stat.isFile()) {
|
|
1102
|
-
|
|
1141
|
+
return {
|
|
1142
|
+
lines: [],
|
|
1143
|
+
error: `[FILE NOT FOUND] You tried to read "${params.path}" but there is no file at this path. Double-check the path exists and is spelled correctly.`
|
|
1144
|
+
};
|
|
1103
1145
|
}
|
|
1104
1146
|
if (isSymlink(abs)) {
|
|
1105
|
-
|
|
1147
|
+
return {
|
|
1148
|
+
lines: [],
|
|
1149
|
+
error: `[SYMLINK] You tried to read "${params.path}" but this is a symlink. Try reading the actual file it points to instead.`
|
|
1150
|
+
};
|
|
1106
1151
|
}
|
|
1107
1152
|
if (!isTextualFile(abs)) {
|
|
1108
|
-
|
|
1153
|
+
return {
|
|
1154
|
+
lines: [],
|
|
1155
|
+
error: `[UNREADABLE FILE] You tried to read "${params.path}" but this file is either too large or not a text file, so it cannot be read. Try a different file.`
|
|
1156
|
+
};
|
|
1109
1157
|
}
|
|
1110
1158
|
const lines = await readAllLines(abs);
|
|
1111
1159
|
const total = lines.length;
|