From 80725a2d34c4d5d65e2d60bae274dd0fa1762837 Mon Sep 17 00:00:00 2001 From: weishu Date: Sat, 20 Dec 2025 16:03:51 +0800 Subject: [PATCH] feat(cli): add Bun runtime support for ripgrep and CLI spawning Replace hardcoded 'node' commands with process.execPath to support Bun runtime alongside Node.js. Add runtime detection and entrypoint resolution for Bun. Update documentation to reflect multi-runtime support. --- cli/scripts/ripgrep_launcher.cjs | 2 +- cli/src/modules/ripgrep/index.ts | 14 +++------- cli/src/utils/spawnHappyCLI.ts | 44 +++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/cli/scripts/ripgrep_launcher.cjs b/cli/scripts/ripgrep_launcher.cjs index 648277ab..96b6abe7 100644 --- a/cli/scripts/ripgrep_launcher.cjs +++ b/cli/scripts/ripgrep_launcher.cjs @@ -30,4 +30,4 @@ try { } catch (error) { console.error('Ripgrep error:', error.message); process.exit(1); -} \ No newline at end of file +} diff --git a/cli/src/modules/ripgrep/index.ts b/cli/src/modules/ripgrep/index.ts index 41b5be7c..b4cbe5f3 100644 --- a/cli/src/modules/ripgrep/index.ts +++ b/cli/src/modules/ripgrep/index.ts @@ -3,8 +3,8 @@ */ import { spawn } from 'child_process'; -import { projectPath } from '@/projectPath'; import { join, resolve } from 'path'; +import { projectPath } from '@/projectPath'; export interface RipgrepResult { exitCode: number @@ -16,16 +16,10 @@ export interface RipgrepOptions { cwd?: string } -/** - * Run ripgrep with the given arguments - * @param args - Array of command line arguments to pass to ripgrep - * @param options - Options for ripgrep execution - * @returns Promise with exit code, stdout and stderr - */ export function run(args: string[], options?: RipgrepOptions): Promise { - const RUNNER_PATH = resolve(join(projectPath(), 'scripts', 'ripgrep_launcher.cjs')); + const runnerPath = resolve(join(projectPath(), 'scripts', 'ripgrep_launcher.cjs')); return new Promise((resolve, reject) => { - const child = spawn('node', [RUNNER_PATH, JSON.stringify(args)], { + const child = spawn(process.execPath, [runnerPath, JSON.stringify(args)], { stdio: ['pipe', 'pipe', 'pipe'], cwd: options?.cwd }); @@ -53,4 +47,4 @@ export function run(args: string[], options?: RipgrepOptions): Promise).bun); + const entrypoint = isBunRuntime ? resolveEntrypointForBun(projectRoot) : distEntrypoint; let directory: string | URL | undefined; if ('cwd' in options) { @@ -76,7 +96,7 @@ export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child } else { directory = process.cwd() } - // Note: We're actually executing 'node' with the calculated entrypoint path below, + // Note: We're executing the current runtime with the calculated entrypoint path below, // bypassing the 'happy' wrapper that would normally be found in the shell's PATH. // However, we log it as 'happy' here because other engineers are typically looking // for when "happy" was started and don't care about the underlying node process @@ -84,8 +104,8 @@ export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child const fullCommand = `hapi ${args.join(' ')}`; logger.debug(`[SPAWN HAPI CLI] Spawning: ${fullCommand} in ${directory}`); - // Use the same Node.js flags that the wrapper script uses - const nodeArgs = [ + const spawnCommand = process.execPath; + const spawnArgs = isBunRuntime ? [entrypoint, ...args] : [ '--no-warnings', '--no-deprecation', entrypoint, @@ -99,5 +119,5 @@ export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child throw new Error(errorMessage); } - return spawn('node', nodeArgs, options); + return spawn(spawnCommand, spawnArgs, options); }