@rdmind/rdmind 0.0.21-alpha.0 → 0.0.21-alpha.1

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.
Files changed (2) hide show
  1. package/cli.js +161 -163
  2. package/package.json +2 -2
package/cli.js CHANGED
@@ -183747,7 +183747,7 @@ function createContentGeneratorConfig(config, authType, generationConfig) {
183747
183747
  };
183748
183748
  }
183749
183749
  async function createContentGenerator(config, gcConfig, sessionId2) {
183750
- const version2 = "0.0.21-alpha.0";
183750
+ const version2 = "0.0.21-alpha.1";
183751
183751
  const userAgent2 = `QwenCode/${version2} (${process.platform}; ${process.arch})`;
183752
183752
  const baseHeaders = {
183753
183753
  "User-Agent": userAgent2
@@ -185643,7 +185643,7 @@ var init_tool_names = __esm({
185643
185643
  WRITE_FILE: "write_file",
185644
185644
  READ_FILE: "read_file",
185645
185645
  READ_MANY_FILES: "read_many_files",
185646
- GREP: "search_file_content",
185646
+ GREP: "grep_search",
185647
185647
  GLOB: "glob",
185648
185648
  SHELL: "run_shell_command",
185649
185649
  TODO_WRITE: "todo_write",
@@ -233968,10 +233968,20 @@ function getRipgrepPath() {
233968
233968
  );
233969
233969
  return vendorPath;
233970
233970
  }
233971
- async function canUseRipgrep() {
233971
+ async function canUseRipgrep(useBuiltin = true) {
233972
233972
  try {
233973
- const rgPath = getRipgrepPath();
233974
- return await fileExists(rgPath);
233973
+ if (useBuiltin) {
233974
+ const rgPath = getRipgrepPath();
233975
+ if (await fileExists(rgPath)) {
233976
+ return true;
233977
+ }
233978
+ }
233979
+ const { spawn: spawn13 } = await import("node:child_process");
233980
+ return await new Promise((resolve25) => {
233981
+ const proc2 = spawn13("rg", ["--version"]);
233982
+ proc2.on("error", () => resolve25(false));
233983
+ proc2.on("exit", (code2) => resolve25(code2 === 0));
233984
+ });
233975
233985
  } catch (_error) {
233976
233986
  return false;
233977
233987
  }
@@ -234006,17 +234016,19 @@ import fs36 from "node:fs";
234006
234016
  import path40 from "node:path";
234007
234017
  import { EOL as EOL3 } from "node:os";
234008
234018
  import { spawn as spawn6 } from "node:child_process";
234009
- var DEFAULT_TOTAL_MAX_MATCHES, GrepToolInvocation2, RipGrepTool;
234019
+ var MAX_LLM_CONTENT_LENGTH, GrepToolInvocation2, RipGrepTool;
234010
234020
  var init_ripGrep = __esm({
234011
234021
  "packages/core/src/tools/ripGrep.ts"() {
234012
234022
  "use strict";
234013
234023
  init_esbuild_shims();
234014
234024
  init_tools();
234015
- init_schemaValidator();
234025
+ init_tool_names();
234016
234026
  init_paths();
234017
234027
  init_errors();
234018
234028
  init_ripgrepUtils();
234019
- DEFAULT_TOTAL_MAX_MATCHES = 2e4;
234029
+ init_schemaValidator();
234030
+ init_constants3();
234031
+ MAX_LLM_CONTENT_LENGTH = 2e4;
234020
234032
  GrepToolInvocation2 = class extends BaseToolInvocation {
234021
234033
  constructor(config, params) {
234022
234034
  super(params);
@@ -234028,14 +234040,12 @@ var init_ripGrep = __esm({
234028
234040
  /**
234029
234041
  * Checks if a path is within the root directory and resolves it.
234030
234042
  * @param relativePath Path relative to the root directory (or undefined for root).
234031
- * @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
234043
+ * @returns The absolute path to search within.
234032
234044
  * @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
234033
234045
  */
234034
234046
  resolveAndValidatePath(relativePath) {
234035
- if (!relativePath) {
234036
- return null;
234037
- }
234038
- const targetPath = path40.resolve(this.config.getTargetDir(), relativePath);
234047
+ const targetDir = this.config.getTargetDir();
234048
+ const targetPath = relativePath ? path40.resolve(targetDir, relativePath) : targetDir;
234039
234049
  const workspaceContext = this.config.getWorkspaceContext();
234040
234050
  if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
234041
234051
  const directories = workspaceContext.getDirectories();
@@ -234043,6 +234053,9 @@ var init_ripGrep = __esm({
234043
234053
  `Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`
234044
234054
  );
234045
234055
  }
234056
+ return this.ensureDirectory(targetPath);
234057
+ }
234058
+ ensureDirectory(targetPath) {
234046
234059
  try {
234047
234060
  const stats = fs36.statSync(targetPath);
234048
234061
  if (!stats.isDirectory()) {
@@ -234060,85 +234073,50 @@ var init_ripGrep = __esm({
234060
234073
  }
234061
234074
  async execute(signal) {
234062
234075
  try {
234063
- const workspaceContext = this.config.getWorkspaceContext();
234064
234076
  const searchDirAbs = this.resolveAndValidatePath(this.params.path);
234065
234077
  const searchDirDisplay = this.params.path || ".";
234066
- let searchDirectories;
234067
- if (searchDirAbs === null) {
234068
- searchDirectories = workspaceContext.getDirectories();
234069
- } else {
234070
- searchDirectories = [searchDirAbs];
234071
- }
234072
- let allMatches = [];
234073
- const totalMaxMatches = DEFAULT_TOTAL_MAX_MATCHES;
234074
- if (this.config.getDebugMode()) {
234075
- console.log(`[GrepTool] Total result limit: ${totalMaxMatches}`);
234076
- }
234077
- for (const searchDir of searchDirectories) {
234078
- const searchResult = await this.performRipgrepSearch({
234079
- pattern: this.params.pattern,
234080
- path: searchDir,
234081
- include: this.params.include,
234082
- signal
234083
- });
234084
- if (searchDirectories.length > 1) {
234085
- const dirName = path40.basename(searchDir);
234086
- searchResult.forEach((match2) => {
234087
- match2.filePath = path40.join(dirName, match2.filePath);
234088
- });
234089
- }
234090
- allMatches = allMatches.concat(searchResult);
234091
- if (allMatches.length >= totalMaxMatches) {
234092
- allMatches = allMatches.slice(0, totalMaxMatches);
234093
- break;
234094
- }
234095
- }
234096
- let searchLocationDescription;
234097
- if (searchDirAbs === null) {
234098
- const numDirs = workspaceContext.getDirectories().length;
234099
- searchLocationDescription = numDirs > 1 ? `across ${numDirs} workspace directories` : `in the workspace directory`;
234100
- } else {
234101
- searchLocationDescription = `in path "${searchDirDisplay}"`;
234102
- }
234103
- if (allMatches.length === 0) {
234104
- const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}.`;
234078
+ const rawOutput = await this.performRipgrepSearch({
234079
+ pattern: this.params.pattern,
234080
+ path: searchDirAbs,
234081
+ glob: this.params.glob,
234082
+ signal
234083
+ });
234084
+ const searchLocationDescription = this.params.path ? `in path "${searchDirDisplay}"` : `in the workspace directory`;
234085
+ const filterDescription = this.params.glob ? ` (filter: "${this.params.glob}")` : "";
234086
+ if (!rawOutput.trim()) {
234087
+ const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}.`;
234105
234088
  return { llmContent: noMatchMsg, returnDisplay: `No matches found` };
234106
234089
  }
234107
- const wasTruncated = allMatches.length >= totalMaxMatches;
234108
- const matchesByFile = allMatches.reduce(
234109
- (acc, match2) => {
234110
- const fileKey = match2.filePath;
234111
- if (!acc[fileKey]) {
234112
- acc[fileKey] = [];
234113
- }
234114
- acc[fileKey].push(match2);
234115
- acc[fileKey].sort((a, b) => a.lineNumber - b.lineNumber);
234116
- return acc;
234117
- },
234118
- {}
234119
- );
234120
- const matchCount = allMatches.length;
234121
- const matchTerm = matchCount === 1 ? "match" : "matches";
234122
- let llmContent = `Found ${matchCount} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}`;
234123
- if (wasTruncated) {
234124
- llmContent += ` (results limited to ${totalMaxMatches} matches for performance)`;
234125
- }
234126
- llmContent += `:
234090
+ const allLines = rawOutput.split(EOL3).filter((line) => line.trim());
234091
+ const totalMatches = allLines.length;
234092
+ const matchTerm = totalMatches === 1 ? "match" : "matches";
234093
+ const header = `Found ${totalMatches} ${matchTerm} for pattern "${this.params.pattern}" ${searchLocationDescription}${filterDescription}:
234127
234094
  ---
234128
234095
  `;
234129
- for (const filePath in matchesByFile) {
234130
- llmContent += `File: ${filePath}
234131
- `;
234132
- matchesByFile[filePath].forEach((match2) => {
234133
- const trimmedLine = match2.line.trim();
234134
- llmContent += `L${match2.lineNumber}: ${trimmedLine}
234135
- `;
234136
- });
234137
- llmContent += "---\n";
234138
- }
234139
- let displayMessage = `Found ${matchCount} ${matchTerm}`;
234140
- if (wasTruncated) {
234141
- displayMessage += ` (limited)`;
234096
+ const maxTruncationNoticeLength = 100;
234097
+ const maxGrepOutputLength = MAX_LLM_CONTENT_LENGTH - header.length - maxTruncationNoticeLength;
234098
+ let truncatedByLineLimit = false;
234099
+ let linesToInclude = allLines;
234100
+ if (this.params.limit !== void 0 && allLines.length > this.params.limit) {
234101
+ linesToInclude = allLines.slice(0, this.params.limit);
234102
+ truncatedByLineLimit = true;
234103
+ }
234104
+ let grepOutput = linesToInclude.join(EOL3);
234105
+ let truncatedByCharLimit = false;
234106
+ if (grepOutput.length > maxGrepOutputLength) {
234107
+ grepOutput = grepOutput.slice(0, maxGrepOutputLength) + "...";
234108
+ truncatedByCharLimit = true;
234109
+ }
234110
+ const finalLines = grepOutput.split(EOL3).filter((line) => line.trim());
234111
+ const includedLines = finalLines.length;
234112
+ let llmContent = header + grepOutput;
234113
+ if (truncatedByLineLimit || truncatedByCharLimit) {
234114
+ const omittedMatches = totalMatches - includedLines;
234115
+ llmContent += ` [${omittedMatches} ${omittedMatches === 1 ? "line" : "lines"} truncated] ...`;
234116
+ }
234117
+ let displayMessage = `Found ${totalMatches} ${matchTerm}`;
234118
+ if (truncatedByLineLimit || truncatedByCharLimit) {
234119
+ displayMessage += ` (truncated)`;
234142
234120
  }
234143
234121
  return {
234144
234122
  llmContent: llmContent.trim(),
@@ -234153,37 +234131,8 @@ var init_ripGrep = __esm({
234153
234131
  };
234154
234132
  }
234155
234133
  }
234156
- parseRipgrepOutput(output, basePath) {
234157
- const results = [];
234158
- if (!output) return results;
234159
- const lines = output.split(EOL3);
234160
- for (const line of lines) {
234161
- if (!line.trim()) continue;
234162
- const firstColonIndex = line.indexOf(":");
234163
- if (firstColonIndex === -1) continue;
234164
- const secondColonIndex = line.indexOf(":", firstColonIndex + 1);
234165
- if (secondColonIndex === -1) continue;
234166
- const filePathRaw = line.substring(0, firstColonIndex);
234167
- const lineNumberStr = line.substring(
234168
- firstColonIndex + 1,
234169
- secondColonIndex
234170
- );
234171
- const lineContent = line.substring(secondColonIndex + 1);
234172
- const lineNumber = parseInt(lineNumberStr, 10);
234173
- if (!isNaN(lineNumber)) {
234174
- const absoluteFilePath = path40.resolve(basePath, filePathRaw);
234175
- const relativeFilePath = path40.relative(basePath, absoluteFilePath);
234176
- results.push({
234177
- filePath: relativeFilePath || path40.basename(absoluteFilePath),
234178
- lineNumber,
234179
- line: lineContent
234180
- });
234181
- }
234182
- }
234183
- return results;
234184
- }
234185
234134
  async performRipgrepSearch(options2) {
234186
- const { pattern, path: absolutePath, include } = options2;
234135
+ const { pattern, path: absolutePath, glob: glob2 } = options2;
234187
234136
  const rgArgs = [
234188
234137
  "--line-number",
234189
234138
  "--no-heading",
@@ -234192,26 +234141,26 @@ var init_ripGrep = __esm({
234192
234141
  "--regexp",
234193
234142
  pattern
234194
234143
  ];
234195
- if (include) {
234196
- rgArgs.push("--glob", include);
234197
- }
234198
- const excludes = [
234199
- ".git",
234200
- "node_modules",
234201
- "bower_components",
234202
- "*.log",
234203
- "*.tmp",
234204
- "build",
234205
- "dist",
234206
- "coverage"
234207
- ];
234208
- excludes.forEach((exclude) => {
234209
- rgArgs.push("--glob", `!${exclude}`);
234210
- });
234144
+ const filteringOptions = this.getFileFilteringOptions();
234145
+ if (!filteringOptions.respectGitIgnore) {
234146
+ rgArgs.push("--no-ignore-vcs");
234147
+ }
234148
+ if (filteringOptions.respectQwenIgnore) {
234149
+ const qwenIgnorePath = path40.join(
234150
+ this.config.getTargetDir(),
234151
+ ".qwenignore"
234152
+ );
234153
+ if (fs36.existsSync(qwenIgnorePath)) {
234154
+ rgArgs.push("--ignore-file", qwenIgnorePath);
234155
+ }
234156
+ }
234157
+ if (glob2) {
234158
+ rgArgs.push("--glob", glob2);
234159
+ }
234211
234160
  rgArgs.push("--threads", "4");
234212
234161
  rgArgs.push(absolutePath);
234213
234162
  try {
234214
- const rgPath = await ensureRipgrepPath();
234163
+ const rgPath = this.config.getUseBuiltinRipgrep() ? await ensureRipgrepPath() : "rg";
234215
234164
  const output = await new Promise((resolve25, reject) => {
234216
234165
  const child = spawn6(rgPath, rgArgs, {
234217
234166
  windowsHide: true
@@ -234245,21 +234194,27 @@ var init_ripGrep = __esm({
234245
234194
  }
234246
234195
  });
234247
234196
  });
234248
- return this.parseRipgrepOutput(output, absolutePath);
234197
+ return output;
234249
234198
  } catch (error) {
234250
234199
  console.error(`GrepLogic: ripgrep failed: ${getErrorMessage(error)}`);
234251
234200
  throw error;
234252
234201
  }
234253
234202
  }
234203
+ getFileFilteringOptions() {
234204
+ const options2 = this.config.getFileFilteringOptions?.();
234205
+ return {
234206
+ respectGitIgnore: options2?.respectGitIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectGitIgnore,
234207
+ respectQwenIgnore: options2?.respectQwenIgnore ?? DEFAULT_FILE_FILTERING_OPTIONS.respectQwenIgnore
234208
+ };
234209
+ }
234254
234210
  /**
234255
234211
  * Gets a description of the grep operation
234256
- * @param params Parameters for the grep operation
234257
234212
  * @returns A string describing the grep
234258
234213
  */
234259
234214
  getDescription() {
234260
234215
  let description = `'${this.params.pattern}'`;
234261
- if (this.params.include) {
234262
- description += ` in ${this.params.include}`;
234216
+ if (this.params.glob) {
234217
+ description += ` in ${this.params.glob}`;
234263
234218
  }
234264
234219
  if (this.params.path) {
234265
234220
  const resolvedPath = path40.resolve(
@@ -234289,22 +234244,26 @@ var init_ripGrep = __esm({
234289
234244
  constructor(config) {
234290
234245
  super(
234291
234246
  _RipGrepTool.Name,
234292
- "SearchText",
234293
- "Searches for a regular expression pattern within the content of files in a specified directory (or current working directory). Can filter files by a glob pattern. Returns the lines containing matches, along with their file paths and line numbers. Total results limited to 20,000 matches like VSCode.",
234247
+ "Grep",
234248
+ 'A powerful search tool built on ripgrep\n\n Usage:\n - ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access.\n - Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")\n - Filter files with glob parameter (e.g., "*.js", "**/*.tsx")\n - Use Task tool for open-ended searches requiring multiple rounds\n - Pattern syntax: Uses ripgrep (not grep) - special regex characters need escaping (use `interface\\{\\}` to find `interface{}` in Go code)\n',
234294
234249
  "search" /* Search */,
234295
234250
  {
234296
234251
  properties: {
234297
234252
  pattern: {
234298
- description: "The regular expression (regex) pattern to search for within file contents (e.g., 'function\\s+myFunction', 'import\\s+\\{.*\\}\\s+from\\s+.*').",
234299
- type: "string"
234253
+ type: "string",
234254
+ description: "The regular expression pattern to search for in file contents"
234255
+ },
234256
+ glob: {
234257
+ type: "string",
234258
+ description: 'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'
234300
234259
  },
234301
234260
  path: {
234302
- description: "Optional: The absolute path to the directory to search within. If omitted, searches the current working directory.",
234303
- type: "string"
234261
+ type: "string",
234262
+ description: "File or directory to search in (rg PATH). Defaults to current working directory."
234304
234263
  },
234305
- include: {
234306
- description: "Optional: A glob pattern to filter which files are searched (e.g., '*.js', '*.{ts,tsx}', 'src/**'). If omitted, searches all files (respecting potential global ignores).",
234307
- type: "string"
234264
+ limit: {
234265
+ type: "number",
234266
+ description: "Limit output to first N lines/entries. Optional - shows all matches if not specified."
234308
234267
  }
234309
234268
  },
234310
234269
  required: ["pattern"],
@@ -234316,16 +234275,16 @@ var init_ripGrep = __esm({
234316
234275
  static {
234317
234276
  __name(this, "RipGrepTool");
234318
234277
  }
234319
- static Name = "search_file_content";
234278
+ static Name = ToolNames.GREP;
234320
234279
  /**
234321
234280
  * Checks if a path is within the root directory and resolves it.
234322
234281
  * @param relativePath Path relative to the root directory (or undefined for root).
234323
- * @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
234282
+ * @returns The absolute path to search within.
234324
234283
  * @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
234325
234284
  */
234326
234285
  resolveAndValidatePath(relativePath) {
234327
234286
  if (!relativePath) {
234328
- return null;
234287
+ return this.config.getTargetDir();
234329
234288
  }
234330
234289
  const targetPath = path40.resolve(this.config.getTargetDir(), relativePath);
234331
234290
  const workspaceContext = this.config.getWorkspaceContext();
@@ -234355,7 +234314,7 @@ var init_ripGrep = __esm({
234355
234314
  * @param params Parameters to validate
234356
234315
  * @returns An error message string if invalid, null otherwise
234357
234316
  */
234358
- validateToolParams(params) {
234317
+ validateToolParamValues(params) {
234359
234318
  const errors = SchemaValidator.validate(
234360
234319
  this.schema.parametersJsonSchema,
234361
234320
  params
@@ -234363,6 +234322,11 @@ var init_ripGrep = __esm({
234363
234322
  if (errors) {
234364
234323
  return errors;
234365
234324
  }
234325
+ try {
234326
+ new RegExp(params.pattern);
234327
+ } catch (error) {
234328
+ return `Invalid regular expression pattern: ${params.pattern}. Error: ${getErrorMessage(error)}`;
234329
+ }
234366
234330
  if (params.path) {
234367
234331
  try {
234368
234332
  this.resolveAndValidatePath(params.path);
@@ -247285,6 +247249,7 @@ var init_config3 = __esm({
247285
247249
  interactive;
247286
247250
  trustedFolder;
247287
247251
  useRipgrep;
247252
+ useBuiltinRipgrep;
247288
247253
  shouldUseNodePtyShell;
247289
247254
  skipNextSpeakerCheck;
247290
247255
  shellExecutionConfig;
@@ -247375,11 +247340,10 @@ var init_config3 = __esm({
247375
247340
  this.chatCompression = params.chatCompression;
247376
247341
  this.interactive = params.interactive ?? false;
247377
247342
  this.trustedFolder = params.trustedFolder;
247378
- this.shouldUseNodePtyShell = params.shouldUseNodePtyShell ?? false;
247379
- this.skipNextSpeakerCheck = params.skipNextSpeakerCheck ?? false;
247380
247343
  this.skipLoopDetection = params.skipLoopDetection ?? false;
247381
247344
  this.tavilyApiKey = params.tavilyApiKey;
247382
247345
  this.useRipgrep = params.useRipgrep ?? true;
247346
+ this.useBuiltinRipgrep = params.useBuiltinRipgrep ?? true;
247383
247347
  this.shouldUseNodePtyShell = params.shouldUseNodePtyShell ?? false;
247384
247348
  this.skipNextSpeakerCheck = params.skipNextSpeakerCheck ?? true;
247385
247349
  this.shellExecutionConfig = {
@@ -247762,6 +247726,9 @@ var init_config3 = __esm({
247762
247726
  getUseRipgrep() {
247763
247727
  return this.useRipgrep;
247764
247728
  }
247729
+ getUseBuiltinRipgrep() {
247730
+ return this.useBuiltinRipgrep;
247731
+ }
247765
247732
  getShouldUseNodePtyShell() {
247766
247733
  return this.shouldUseNodePtyShell;
247767
247734
  }
@@ -247854,13 +247821,14 @@ var init_config3 = __esm({
247854
247821
  let useRipgrep = false;
247855
247822
  let errorString = void 0;
247856
247823
  try {
247857
- useRipgrep = await canUseRipgrep();
247824
+ useRipgrep = await canUseRipgrep(this.getUseBuiltinRipgrep());
247858
247825
  } catch (error) {
247859
247826
  errorString = String(error);
247860
247827
  }
247861
247828
  if (useRipgrep) {
247862
247829
  registerCoreTool(RipGrepTool, this);
247863
247830
  } else {
247831
+ errorString = errorString || "Ripgrep is not available. Please install ripgrep globally.";
247864
247832
  logRipgrepFallback(this, new RipgrepFallbackEvent(errorString));
247865
247833
  registerCoreTool(GrepTool, this);
247866
247834
  }
@@ -255591,6 +255559,7 @@ var init_src = __esm({
255591
255559
  init_textUtils();
255592
255560
  init_formatters();
255593
255561
  init_generateContentResponseUtilities();
255562
+ init_ripgrepUtils();
255594
255563
  init_fileSearch();
255595
255564
  init_errorParsing();
255596
255565
  init_workspaceContext();
@@ -319943,7 +319912,7 @@ init_esbuild_shims();
319943
319912
 
319944
319913
  // packages/cli/src/generated/git-commit.ts
319945
319914
  init_esbuild_shims();
319946
- var GIT_COMMIT_INFO2 = "28a6f7e6";
319915
+ var GIT_COMMIT_INFO2 = "34a4d574";
319947
319916
 
319948
319917
  // packages/cli/src/ui/components/AboutBox.tsx
319949
319918
  var import_jsx_runtime43 = __toESM(require_jsx_runtime(), 1);
@@ -322790,6 +322759,15 @@ var SETTINGS_SCHEMA = {
322790
322759
  description: "Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance.",
322791
322760
  showInDialog: true
322792
322761
  },
322762
+ useBuiltinRipgrep: {
322763
+ type: "boolean",
322764
+ label: "Use Builtin Ripgrep",
322765
+ category: "Tools",
322766
+ requiresRestart: false,
322767
+ default: true,
322768
+ description: 'Use the bundled ripgrep binary. When set to false, the system-level "rg" command will be used instead. This setting is only effective when useRipgrep is true.',
322769
+ showInDialog: true
322770
+ },
322793
322771
  enableToolOutputTruncation: {
322794
322772
  type: "boolean",
322795
322773
  label: "Enable Tool Output Truncation",
@@ -342045,7 +342023,7 @@ __name(getPackageJson, "getPackageJson");
342045
342023
  // packages/cli/src/utils/version.ts
342046
342024
  async function getCliVersion() {
342047
342025
  const pkgJson = await getPackageJson();
342048
- return "0.0.21-alpha.0";
342026
+ return "0.0.21-alpha.1";
342049
342027
  }
342050
342028
  __name(getCliVersion, "getCliVersion");
342051
342029
 
@@ -342930,6 +342908,7 @@ async function loadCliConfig(settings, extensions, extensionEnablementManager, s
342930
342908
  interactive,
342931
342909
  trustedFolder,
342932
342910
  useRipgrep: settings.tools?.useRipgrep,
342911
+ useBuiltinRipgrep: settings.tools?.useBuiltinRipgrep,
342933
342912
  shouldUseNodePtyShell: settings.tools?.shell?.enableInteractiveShell,
342934
342913
  skipNextSpeakerCheck: settings.model?.skipNextSpeakerCheck,
342935
342914
  enablePromptCompletion: settings.general?.enablePromptCompletion ?? false,
@@ -359032,15 +359011,16 @@ __name(getStartupWarnings, "getStartupWarnings");
359032
359011
 
359033
359012
  // packages/cli/src/utils/userStartupWarnings.ts
359034
359013
  init_esbuild_shims();
359014
+ init_core2();
359035
359015
  import fs95 from "node:fs/promises";
359036
359016
  import * as os38 from "node:os";
359037
359017
  import path107 from "node:path";
359038
359018
  var homeDirectoryCheck = {
359039
359019
  id: "home-directory",
359040
- check: /* @__PURE__ */ __name(async (workspaceRoot) => {
359020
+ check: /* @__PURE__ */ __name(async (options2) => {
359041
359021
  try {
359042
359022
  const [workspaceRealPath, homeRealPath] = await Promise.all([
359043
- fs95.realpath(workspaceRoot),
359023
+ fs95.realpath(options2.workspaceRoot),
359044
359024
  fs95.realpath(os38.homedir())
359045
359025
  ]);
359046
359026
  if (workspaceRealPath === homeRealPath) {
@@ -359054,9 +359034,9 @@ var homeDirectoryCheck = {
359054
359034
  };
359055
359035
  var rootDirectoryCheck = {
359056
359036
  id: "root-directory",
359057
- check: /* @__PURE__ */ __name(async (workspaceRoot) => {
359037
+ check: /* @__PURE__ */ __name(async (options2) => {
359058
359038
  try {
359059
- const workspaceRealPath = await fs95.realpath(workspaceRoot);
359039
+ const workspaceRealPath = await fs95.realpath(options2.workspaceRoot);
359060
359040
  const errorMessage = "Warning: You are running RDMind in the root directory. Your entire folder structure will be used for context. It is strongly recommended to run in a project-specific directory.";
359061
359041
  if (path107.dirname(workspaceRealPath) === workspaceRealPath) {
359062
359042
  return errorMessage;
@@ -359067,13 +359047,27 @@ var rootDirectoryCheck = {
359067
359047
  }
359068
359048
  }, "check")
359069
359049
  };
359050
+ var ripgrepAvailabilityCheck = {
359051
+ id: "ripgrep-availability",
359052
+ check: /* @__PURE__ */ __name(async (options2) => {
359053
+ if (!options2.useRipgrep) {
359054
+ return null;
359055
+ }
359056
+ const isAvailable = await canUseRipgrep(options2.useBuiltinRipgrep);
359057
+ if (!isAvailable) {
359058
+ return "Ripgrep not available: Please install ripgrep globally to enable faster file content search. Falling back to built-in grep.";
359059
+ }
359060
+ return null;
359061
+ }, "check")
359062
+ };
359070
359063
  var WARNING_CHECKS = [
359071
359064
  homeDirectoryCheck,
359072
- rootDirectoryCheck
359065
+ rootDirectoryCheck,
359066
+ ripgrepAvailabilityCheck
359073
359067
  ];
359074
- async function getUserStartupWarnings(workspaceRoot = process.cwd()) {
359068
+ async function getUserStartupWarnings(options2) {
359075
359069
  const results = await Promise.all(
359076
- WARNING_CHECKS.map((check) => check.check(workspaceRoot))
359070
+ WARNING_CHECKS.map((check) => check.check(options2))
359077
359071
  );
359078
359072
  return results.filter((msg) => msg !== null);
359079
359073
  }
@@ -361007,7 +361001,11 @@ ${finalArgs[promptIndex + 1]}`;
361007
361001
  let input = config.getQuestion();
361008
361002
  const startupWarnings = [
361009
361003
  ...await getStartupWarnings(),
361010
- ...await getUserStartupWarnings()
361004
+ ...await getUserStartupWarnings({
361005
+ workspaceRoot: process.cwd(),
361006
+ useRipgrep: settings.merged.tools?.useRipgrep ?? true,
361007
+ useBuiltinRipgrep: settings.merged.tools?.useBuiltinRipgrep ?? true
361008
+ })
361011
361009
  ];
361012
361010
  if (config.isInteractive()) {
361013
361011
  await kittyProtocolDetectionComplete;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdmind/rdmind",
3
- "version": "0.0.21-alpha.0",
3
+ "version": "0.0.21-alpha.1",
4
4
  "description": "RDMind - AI-powered coding assistant",
5
5
  "type": "module",
6
6
  "main": "cli.js",
@@ -19,7 +19,7 @@
19
19
  "LICENSE"
20
20
  ],
21
21
  "config": {
22
- "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.0.21-alpha.0"
22
+ "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.0.21-alpha.1"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"