📦 Release qwen-code CLI as a Standalone Bundled Package (#866)

This commit is contained in:
tanzhenxin
2025-10-24 17:08:59 +08:00
committed by GitHub
parent 5cf609c367
commit be633a80cc
36 changed files with 802 additions and 1077 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@qwen-code/qwen-code-core",
"version": "0.0.14",
"version": "0.1.0",
"description": "Qwen Code Core",
"repository": {
"type": "git",
@@ -14,14 +14,16 @@
"format": "prettier --write .",
"test": "vitest run",
"test:ci": "vitest run",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"postinstall": "node scripts/postinstall.js"
},
"files": [
"dist"
"dist",
"vendor",
"scripts/postinstall.js"
],
"dependencies": {
"@google/genai": "1.16.0",
"@joshua.litt/get-ripgrep": "^0.0.2",
"@modelcontextprotocol/sdk": "^1.11.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/exporter-logs-otlp-grpc": "^0.203.0",

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env node
/**
* @license
* Copyright 2025 Qwen
* SPDX-License-Identifier: Apache-2.0
*/
import { execSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
import fs from 'node:fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Get the package root directory
const packageRoot = path.join(__dirname, '..');
const vendorDir = path.join(packageRoot, 'vendor', 'ripgrep');
/**
* Remove quarantine attribute and set executable permissions on macOS/Linux
*/
function setupRipgrepBinaries() {
if (!fs.existsSync(vendorDir)) {
console.log('Vendor directory not found, skipping ripgrep setup');
return;
}
const platform = process.platform;
const arch = process.arch;
// Determine the binary directory based on platform and architecture
let binaryDir;
if (platform === 'darwin' || platform === 'linux') {
const archStr = arch === 'x64' || arch === 'arm64' ? arch : null;
if (archStr) {
binaryDir = path.join(vendorDir, `${archStr}-${platform}`);
}
} else if (platform === 'win32') {
// Windows doesn't need these fixes
return;
}
if (!binaryDir || !fs.existsSync(binaryDir)) {
console.log(
`Binary directory not found for ${platform}-${arch}, skipping ripgrep setup`,
);
return;
}
const rgBinary = path.join(binaryDir, 'rg');
if (!fs.existsSync(rgBinary)) {
console.log(`Ripgrep binary not found at ${rgBinary}`);
return;
}
try {
// Set executable permissions
fs.chmodSync(rgBinary, 0o755);
console.log(`✓ Set executable permissions on ${rgBinary}`);
// On macOS, remove quarantine attribute
if (platform === 'darwin') {
try {
execSync(`xattr -d com.apple.quarantine "${rgBinary}"`, {
stdio: 'pipe',
});
console.log(`✓ Removed quarantine attribute from ${rgBinary}`);
} catch (error) {
// Quarantine attribute might not exist, which is fine
if (error.message && !error.message.includes('No such xattr')) {
console.warn(
`Warning: Could not remove quarantine attribute: ${error.message}`,
);
}
}
}
} catch (error) {
console.error(`Error setting up ripgrep binary: ${error.message}`);
}
}
setupRipgrepBinaries();

View File

@@ -38,7 +38,8 @@ vi.mock('fs', async (importOriginal) => {
import { ShellTool } from '../tools/shell.js';
import { ReadFileTool } from '../tools/read-file.js';
import { GrepTool } from '../tools/grep.js';
import { RipGrepTool, canUseRipgrep } from '../tools/ripGrep.js';
import { canUseRipgrep } from '../utils/ripgrepUtils.js';
import { RipGrepTool } from '../tools/ripGrep.js';
import { logRipgrepFallback } from '../telemetry/loggers.js';
import { RipgrepFallbackEvent } from '../telemetry/types.js';
import { ToolRegistry } from '../tools/tool-registry.js';
@@ -75,9 +76,11 @@ vi.mock('../tools/ls');
vi.mock('../tools/read-file');
vi.mock('../tools/grep.js');
vi.mock('../tools/ripGrep.js', () => ({
canUseRipgrep: vi.fn(),
RipGrepTool: class MockRipGrepTool {},
}));
vi.mock('../utils/ripgrepUtils.js', () => ({
canUseRipgrep: vi.fn(),
}));
vi.mock('../tools/glob');
vi.mock('../tools/edit');
vi.mock('../tools/shell');

View File

@@ -49,7 +49,8 @@ import { LSTool } from '../tools/ls.js';
import { MemoryTool, setGeminiMdFilename } from '../tools/memoryTool.js';
import { ReadFileTool } from '../tools/read-file.js';
import { ReadManyFilesTool } from '../tools/read-many-files.js';
import { canUseRipgrep, RipGrepTool } from '../tools/ripGrep.js';
import { canUseRipgrep } from '../utils/ripgrepUtils.js';
import { RipGrepTool } from '../tools/ripGrep.js';
import { ShellTool } from '../tools/shell.js';
import { SmartEditTool } from '../tools/smart-edit.js';
import { TaskTool } from '../tools/task.js';

View File

@@ -14,7 +14,7 @@ import {
type Mock,
} from 'vitest';
import type { RipGrepToolParams } from './ripGrep.js';
import { canUseRipgrep, RipGrepTool, ensureRgPath } from './ripGrep.js';
import { RipGrepTool } from './ripGrep.js';
import path from 'node:path';
import fs from 'node:fs/promises';
import os, { EOL } from 'node:os';
@@ -22,24 +22,11 @@ import type { Config } from '../config/config.js';
import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.js';
import type { ChildProcess } from 'node:child_process';
import { spawn } from 'node:child_process';
import { downloadRipGrep } from '@joshua.litt/get-ripgrep';
import { fileExists } from '../utils/fileUtils.js';
import { ensureRipgrepPath } from '../utils/ripgrepUtils.js';
// Mock dependencies for canUseRipgrep
vi.mock('@joshua.litt/get-ripgrep', () => ({
downloadRipGrep: vi.fn(),
}));
vi.mock('../utils/fileUtils.js', async (importOriginal) => {
const actual = await importOriginal<typeof import('../utils/fileUtils.js')>();
return {
...actual,
fileExists: vi.fn(),
};
});
vi.mock('../config/storage.js', () => ({
Storage: {
getGlobalBinDir: vi.fn().mockReturnValue('/mock/bin/dir'),
},
// Mock ripgrepUtils
vi.mock('../utils/ripgrepUtils.js', () => ({
ensureRipgrepPath: vi.fn(),
}));
// Mock child_process for ripgrep calls
@@ -49,97 +36,6 @@ vi.mock('child_process', () => ({
const mockSpawn = vi.mocked(spawn);
describe('canUseRipgrep', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should return true if ripgrep already exists', async () => {
(fileExists as Mock).mockResolvedValue(true);
const result = await canUseRipgrep();
expect(result).toBe(true);
expect(fileExists).toHaveBeenCalledWith(path.join('/mock/bin/dir', 'rg'));
expect(downloadRipGrep).not.toHaveBeenCalled();
});
it('should download ripgrep and return true if it does not exist initially', async () => {
(fileExists as Mock)
.mockResolvedValueOnce(false)
.mockResolvedValueOnce(true);
(downloadRipGrep as Mock).mockResolvedValue(undefined);
const result = await canUseRipgrep();
expect(result).toBe(true);
expect(fileExists).toHaveBeenCalledTimes(2);
expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
});
it('should return false if download fails and file does not exist', async () => {
(fileExists as Mock).mockResolvedValue(false);
(downloadRipGrep as Mock).mockResolvedValue(undefined);
const result = await canUseRipgrep();
expect(result).toBe(false);
expect(fileExists).toHaveBeenCalledTimes(2);
expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
});
it('should propagate errors from downloadRipGrep', async () => {
const error = new Error('Download failed');
(fileExists as Mock).mockResolvedValue(false);
(downloadRipGrep as Mock).mockRejectedValue(error);
await expect(canUseRipgrep()).rejects.toThrow(error);
expect(fileExists).toHaveBeenCalledTimes(1);
expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
});
});
describe('ensureRgPath', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should return rg path if ripgrep already exists', async () => {
(fileExists as Mock).mockResolvedValue(true);
const rgPath = await ensureRgPath();
expect(rgPath).toBe(path.join('/mock/bin/dir', 'rg'));
expect(fileExists).toHaveBeenCalledOnce();
expect(downloadRipGrep).not.toHaveBeenCalled();
});
it('should return rg path if ripgrep is downloaded successfully', async () => {
(fileExists as Mock)
.mockResolvedValueOnce(false)
.mockResolvedValueOnce(true);
(downloadRipGrep as Mock).mockResolvedValue(undefined);
const rgPath = await ensureRgPath();
expect(rgPath).toBe(path.join('/mock/bin/dir', 'rg'));
expect(downloadRipGrep).toHaveBeenCalledOnce();
expect(fileExists).toHaveBeenCalledTimes(2);
});
it('should throw an error if ripgrep cannot be used after download attempt', async () => {
(fileExists as Mock).mockResolvedValue(false);
(downloadRipGrep as Mock).mockResolvedValue(undefined);
await expect(ensureRgPath()).rejects.toThrow('Cannot use ripgrep.');
expect(downloadRipGrep).toHaveBeenCalledOnce();
expect(fileExists).toHaveBeenCalledTimes(2);
});
it('should propagate errors from downloadRipGrep', async () => {
const error = new Error('Download failed');
(fileExists as Mock).mockResolvedValue(false);
(downloadRipGrep as Mock).mockRejectedValue(error);
await expect(ensureRgPath()).rejects.toThrow(error);
expect(fileExists).toHaveBeenCalledTimes(1);
expect(downloadRipGrep).toHaveBeenCalledWith('/mock/bin/dir');
});
});
// Helper function to create mock spawn implementations
function createMockSpawn(
options: {
@@ -201,8 +97,7 @@ describe('RipGrepTool', () => {
beforeEach(async () => {
vi.clearAllMocks();
(downloadRipGrep as Mock).mockResolvedValue(undefined);
(fileExists as Mock).mockResolvedValue(true);
(ensureRipgrepPath as Mock).mockResolvedValue('/mock/path/to/rg');
mockSpawn.mockClear();
tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), 'grep-tool-root-'));
grepTool = new RipGrepTool(mockConfig);
@@ -551,16 +446,18 @@ describe('RipGrepTool', () => {
});
it('should throw an error if ripgrep is not available', async () => {
// Make ensureRgPath throw
(fileExists as Mock).mockResolvedValue(false);
(downloadRipGrep as Mock).mockResolvedValue(undefined);
// Make ensureRipgrepBinary throw
(ensureRipgrepPath as Mock).mockRejectedValue(
new Error('Ripgrep binary not found'),
);
const params: RipGrepToolParams = { pattern: 'world' };
const invocation = grepTool.build(params);
expect(await invocation.execute(abortSignal)).toStrictEqual({
llmContent: 'Error during grep search operation: Cannot use ripgrep.',
returnDisplay: 'Error: Cannot use ripgrep.',
llmContent:
'Error during grep search operation: Ripgrep binary not found',
returnDisplay: 'Error: Ripgrep binary not found',
});
});
});

View File

@@ -8,44 +8,16 @@ import fs from 'node:fs';
import path from 'node:path';
import { EOL } from 'node:os';
import { spawn } from 'node:child_process';
import { downloadRipGrep } from '@joshua.litt/get-ripgrep';
import type { ToolInvocation, ToolResult } from './tools.js';
import { BaseDeclarativeTool, BaseToolInvocation, Kind } from './tools.js';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { makeRelative, shortenPath } from '../utils/paths.js';
import { getErrorMessage, isNodeError } from '../utils/errors.js';
import type { Config } from '../config/config.js';
import { fileExists } from '../utils/fileUtils.js';
import { Storage } from '../config/storage.js';
import { ensureRipgrepPath } from '../utils/ripgrepUtils.js';
const DEFAULT_TOTAL_MAX_MATCHES = 20000;
function getRgPath(): string {
return path.join(Storage.getGlobalBinDir(), 'rg');
}
/**
* Checks if `rg` exists, if not then attempt to download it.
*/
export async function canUseRipgrep(): Promise<boolean> {
if (await fileExists(getRgPath())) {
return true;
}
await downloadRipGrep(Storage.getGlobalBinDir());
return await fileExists(getRgPath());
}
/**
* Ensures `rg` is downloaded, or throws.
*/
export async function ensureRgPath(): Promise<string> {
if (await canUseRipgrep()) {
return getRgPath();
}
throw new Error('Cannot use ripgrep.');
}
/**
* Parameters for the GrepTool
*/
@@ -320,7 +292,7 @@ class GrepToolInvocation extends BaseToolInvocation<
rgArgs.push(absolutePath);
try {
const rgPath = await ensureRgPath();
const rgPath = await ensureRipgrepPath();
const output = await new Promise<string>((resolve, reject) => {
const child = spawn(rgPath, rgArgs, {
windowsHide: true,
@@ -342,11 +314,7 @@ class GrepToolInvocation extends BaseToolInvocation<
child.on('error', (err) => {
options.signal.removeEventListener('abort', cleanup);
reject(
new Error(
`Failed to start ripgrep: ${err.message}. Please ensure @lvce-editor/ripgrep is properly installed.`,
),
);
reject(new Error(`Failed to start ripgrep: ${err.message}.`));
});
child.on('close', (code) => {

View File

@@ -0,0 +1,258 @@
/**
* @license
* Copyright 2025 Qwen
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest';
import {
canUseRipgrep,
ensureRipgrepPath,
getRipgrepPath,
} from './ripgrepUtils.js';
import { fileExists } from './fileUtils.js';
import path from 'node:path';
// Mock fileUtils
vi.mock('./fileUtils.js', async (importOriginal) => {
const actual = await importOriginal<typeof import('./fileUtils.js')>();
return {
...actual,
fileExists: vi.fn(),
};
});
describe('ripgrepUtils', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('getRipgrepPath', () => {
it('should return path with .exe extension on Windows', () => {
const originalPlatform = process.platform;
const originalArch = process.arch;
// Mock Windows x64
Object.defineProperty(process, 'platform', { value: 'win32' });
Object.defineProperty(process, 'arch', { value: 'x64' });
const rgPath = getRipgrepPath();
expect(rgPath).toContain('x64-win32');
expect(rgPath).toContain('rg.exe');
expect(rgPath).toContain(path.join('vendor', 'ripgrep'));
// Restore original values
Object.defineProperty(process, 'platform', { value: originalPlatform });
Object.defineProperty(process, 'arch', { value: originalArch });
});
it('should return path without .exe extension on macOS', () => {
const originalPlatform = process.platform;
const originalArch = process.arch;
// Mock macOS arm64
Object.defineProperty(process, 'platform', { value: 'darwin' });
Object.defineProperty(process, 'arch', { value: 'arm64' });
const rgPath = getRipgrepPath();
expect(rgPath).toContain('arm64-darwin');
expect(rgPath).toContain('rg');
expect(rgPath).not.toContain('.exe');
expect(rgPath).toContain(path.join('vendor', 'ripgrep'));
// Restore original values
Object.defineProperty(process, 'platform', { value: originalPlatform });
Object.defineProperty(process, 'arch', { value: originalArch });
});
it('should return path without .exe extension on Linux', () => {
const originalPlatform = process.platform;
const originalArch = process.arch;
// Mock Linux x64
Object.defineProperty(process, 'platform', { value: 'linux' });
Object.defineProperty(process, 'arch', { value: 'x64' });
const rgPath = getRipgrepPath();
expect(rgPath).toContain('x64-linux');
expect(rgPath).toContain('rg');
expect(rgPath).not.toContain('.exe');
expect(rgPath).toContain(path.join('vendor', 'ripgrep'));
// Restore original values
Object.defineProperty(process, 'platform', { value: originalPlatform });
Object.defineProperty(process, 'arch', { value: originalArch });
});
it('should throw error for unsupported platform', () => {
const originalPlatform = process.platform;
const originalArch = process.arch;
// Mock unsupported platform
Object.defineProperty(process, 'platform', { value: 'freebsd' });
Object.defineProperty(process, 'arch', { value: 'x64' });
expect(() => getRipgrepPath()).toThrow('Unsupported platform: freebsd');
// Restore original values
Object.defineProperty(process, 'platform', { value: originalPlatform });
Object.defineProperty(process, 'arch', { value: originalArch });
});
it('should throw error for unsupported architecture', () => {
const originalPlatform = process.platform;
const originalArch = process.arch;
// Mock unsupported architecture
Object.defineProperty(process, 'platform', { value: 'darwin' });
Object.defineProperty(process, 'arch', { value: 'ia32' });
expect(() => getRipgrepPath()).toThrow('Unsupported architecture: ia32');
// Restore original values
Object.defineProperty(process, 'platform', { value: originalPlatform });
Object.defineProperty(process, 'arch', { value: originalArch });
});
it('should handle all supported platform/arch combinations', () => {
const originalPlatform = process.platform;
const originalArch = process.arch;
const combinations: Array<{
platform: string;
arch: string;
}> = [
{ platform: 'darwin', arch: 'x64' },
{ platform: 'darwin', arch: 'arm64' },
{ platform: 'linux', arch: 'x64' },
{ platform: 'linux', arch: 'arm64' },
{ platform: 'win32', arch: 'x64' },
];
combinations.forEach(({ platform, arch }) => {
Object.defineProperty(process, 'platform', { value: platform });
Object.defineProperty(process, 'arch', { value: arch });
const rgPath = getRipgrepPath();
const binaryName = platform === 'win32' ? 'rg.exe' : 'rg';
const expectedPathSegment = path.join(
`${arch}-${platform}`,
binaryName,
);
expect(rgPath).toContain(expectedPathSegment);
});
// Restore original values
Object.defineProperty(process, 'platform', { value: originalPlatform });
Object.defineProperty(process, 'arch', { value: originalArch });
});
});
describe('canUseRipgrep', () => {
it('should return true if ripgrep binary exists', async () => {
(fileExists as Mock).mockResolvedValue(true);
const result = await canUseRipgrep();
expect(result).toBe(true);
expect(fileExists).toHaveBeenCalledOnce();
});
it('should return false if ripgrep binary does not exist', async () => {
(fileExists as Mock).mockResolvedValue(false);
const result = await canUseRipgrep();
expect(result).toBe(false);
expect(fileExists).toHaveBeenCalledOnce();
});
it('should return false if platform is unsupported', async () => {
const originalPlatform = process.platform;
// Mock unsupported platform
Object.defineProperty(process, 'platform', { value: 'aix' });
const result = await canUseRipgrep();
expect(result).toBe(false);
expect(fileExists).not.toHaveBeenCalled();
// Restore original value
Object.defineProperty(process, 'platform', { value: originalPlatform });
});
it('should return false if architecture is unsupported', async () => {
const originalArch = process.arch;
// Mock unsupported architecture
Object.defineProperty(process, 'arch', { value: 's390x' });
const result = await canUseRipgrep();
expect(result).toBe(false);
expect(fileExists).not.toHaveBeenCalled();
// Restore original value
Object.defineProperty(process, 'arch', { value: originalArch });
});
});
describe('ensureRipgrepBinary', () => {
it('should return ripgrep path if binary exists', async () => {
(fileExists as Mock).mockResolvedValue(true);
const rgPath = await ensureRipgrepPath();
expect(rgPath).toBeDefined();
expect(rgPath).toContain('rg');
expect(fileExists).toHaveBeenCalledOnce();
expect(fileExists).toHaveBeenCalledWith(rgPath);
});
it('should throw error if binary does not exist', async () => {
(fileExists as Mock).mockResolvedValue(false);
await expect(ensureRipgrepPath()).rejects.toThrow(
/Ripgrep binary not found/,
);
await expect(ensureRipgrepPath()).rejects.toThrow(/Platform:/);
await expect(ensureRipgrepPath()).rejects.toThrow(/Architecture:/);
expect(fileExists).toHaveBeenCalled();
});
it('should throw error with correct path information', async () => {
(fileExists as Mock).mockResolvedValue(false);
try {
await ensureRipgrepPath();
// Should not reach here
expect(true).toBe(false);
} catch (error) {
expect(error).toBeInstanceOf(Error);
const errorMessage = (error as Error).message;
expect(errorMessage).toContain('Ripgrep binary not found at');
expect(errorMessage).toContain(process.platform);
expect(errorMessage).toContain(process.arch);
}
});
it('should throw error if platform is unsupported', async () => {
const originalPlatform = process.platform;
// Mock unsupported platform
Object.defineProperty(process, 'platform', { value: 'openbsd' });
await expect(ensureRipgrepPath()).rejects.toThrow(
'Unsupported platform: openbsd',
);
// Restore original value
Object.defineProperty(process, 'platform', { value: originalPlatform });
});
});
});

View File

@@ -0,0 +1,114 @@
/**
* @license
* Copyright 2025 Qwen
* SPDX-License-Identifier: Apache-2.0
*/
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { fileExists } from './fileUtils.js';
// Get the directory of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
type Platform = 'darwin' | 'linux' | 'win32';
type Architecture = 'x64' | 'arm64';
/**
* Maps process.platform values to vendor directory names
*/
function getPlatformString(platform: string): Platform {
switch (platform) {
case 'darwin':
case 'linux':
case 'win32':
return platform;
default:
throw new Error(`Unsupported platform: ${platform}`);
}
}
/**
* Maps process.arch values to vendor directory names
*/
function getArchitectureString(arch: string): Architecture {
switch (arch) {
case 'x64':
case 'arm64':
return arch;
default:
throw new Error(`Unsupported architecture: ${arch}`);
}
}
/**
* Returns the path to the bundled ripgrep binary for the current platform
*/
export function getRipgrepPath(): string {
const platform = getPlatformString(process.platform);
const arch = getArchitectureString(process.arch);
// Binary name includes .exe on Windows
const binaryName = platform === 'win32' ? 'rg.exe' : 'rg';
// Path resolution:
// When running from transpiled code: dist/src/utils/ripgrepUtils.js -> ../../../vendor/ripgrep/
// When running from bundle: dist/index.js -> vendor/ripgrep/
// Detect if we're running from a bundle (single file)
// In bundle, __filename will be something like /path/to/dist/index.js
// In transpiled code, __filename will be /path/to/dist/src/utils/ripgrepUtils.js
const isBundled = !__filename.includes(path.join('src', 'utils'));
const vendorPath = isBundled
? path.join(
__dirname,
'vendor',
'ripgrep',
`${arch}-${platform}`,
binaryName,
)
: path.join(
__dirname,
'..',
'..',
'..',
'vendor',
'ripgrep',
`${arch}-${platform}`,
binaryName,
);
return vendorPath;
}
/**
* Checks if ripgrep binary is available
*/
export async function canUseRipgrep(): Promise<boolean> {
try {
const rgPath = getRipgrepPath();
return await fileExists(rgPath);
} catch (_error) {
// Unsupported platform/arch
return false;
}
}
/**
* Ensures ripgrep binary exists and returns its path
* @throws Error if ripgrep binary is not available
*/
export async function ensureRipgrepPath(): Promise<string> {
const rgPath = getRipgrepPath();
if (!(await fileExists(rgPath))) {
throw new Error(
`Ripgrep binary not found at ${rgPath}. ` +
`Platform: ${process.platform}, Architecture: ${process.arch}`,
);
}
return rgPath;
}

3
packages/core/vendor/ripgrep/COPYING vendored Normal file
View File

@@ -0,0 +1,3 @@
This project is dual-licensed under the Unlicense and MIT licenses.
You may use this code under the terms of either license.

BIN
packages/core/vendor/ripgrep/arm64-darwin/rg vendored Executable file

Binary file not shown.

BIN
packages/core/vendor/ripgrep/arm64-linux/rg vendored Executable file

Binary file not shown.

BIN
packages/core/vendor/ripgrep/x64-darwin/rg vendored Executable file

Binary file not shown.

BIN
packages/core/vendor/ripgrep/x64-linux/rg vendored Executable file

Binary file not shown.

Binary file not shown.