Files
toolLooper/tools/ripgrep.js

66 lines
2.3 KiB
JavaScript

import { spawnSync } from "node:child_process";
const virtual_chroot = '/workspaces/aiTools/root';
export default {
type: "function", name: "ripgrep", strict: true,
description: "ripgrep (rg) search ( rg pattern -g filePattern | head -200) , always limited to 200 lines",
parameters: {
type: "object", required: ["pattern","filePattern","n_flag","i_flag"], additionalProperties: false, properties: {
pattern: {type: "string", description: 'The pattern to search for.'},
filePattern: { type: "string", description: "'*.js' for only js files, '!*.log' for all files except log files , '' for all files"},
n_flag: { type: "boolean",description: "show line numbers."},
i_flag: { type: "boolean",description: "case insensitive search."}
}
}
};
export async function run(args) {
const { pattern, filePattern, n_flag, i_flag } = args;
// Build the args array
let rgArgs = [];
if (n_flag) rgArgs.push('-n');
if (i_flag) rgArgs.push('-i');
if (filePattern) {
rgArgs.push('-g', filePattern);
}
// Add separator, pattern, and explicit search path '.' so rg scans the chroot cwd
rgArgs.push('--', pattern, '.');
try {
const proc = spawnSync('rg', rgArgs, {
cwd: virtual_chroot,
encoding: 'utf8',
maxBuffer: 1024 * 1024 * 10 // 10MB buffer
});
if (proc.error) {
return `ripgrep error: ${proc.error.message}`;
}
let output = proc.stdout;
if (proc.status !== 0) {
if (proc.status === 1) {
// No matches found
return output || '';
}
return `ripgrep error: exit ${proc.status}, ${proc.stderr}`;
}
// Normalize paths (strip leading './') and limit to 200 lines
const lines = output.split('\n').map((l) => l.replace(/^\.\//, ''));
let limitedOutput = lines.slice(0, 200).join('\n');
// Remove a single trailing newline if present to align with tests
if (limitedOutput.endsWith('\n')) {
limitedOutput = limitedOutput.replace(/\n$/, '');
}
return limitedOutput;
} catch (error) {
return `ripgrep error: ${error.message}`;
}
}