Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/codex/runCodex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,12 @@ export async function runCodex(opts: {

// Start Happy MCP server (HTTP) and prepare STDIO bridge config for Codex
const happyServer = await startHappyServer(session);
const bridgeCommand = join(projectPath(), 'bin', 'happy-mcp.mjs');
const bridgeScript = join(projectPath(), 'bin', 'happy-mcp.mjs');
// Use process.execPath (bun or node) as command to support both runtimes
const mcpServers = {
happy: {
command: bridgeCommand,
args: ['--url', happyServer.url]
command: process.execPath,
args: [bridgeScript, '--url', happyServer.url]
}
} as const;
let first = true;
Expand Down
7 changes: 4 additions & 3 deletions src/gemini/runGemini.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,12 @@ export async function runGemini(opts: {
//

const happyServer = await startHappyServer(session);
const bridgeCommand = join(projectPath(), 'bin', 'happy-mcp.mjs');
const bridgeScript = join(projectPath(), 'bin', 'happy-mcp.mjs');
// Use process.execPath (bun or node) as command to support both runtimes
const mcpServers = {
happy: {
command: bridgeCommand,
args: ['--url', happyServer.url]
command: process.execPath,
args: [bridgeScript, '--url', happyServer.url]
}
};

Expand Down
16 changes: 10 additions & 6 deletions src/utils/spawnHappyCLI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
*/

import { spawn, SpawnOptions, type ChildProcess } from 'child_process';
import { join } from 'node:path';
import { join, basename } from 'node:path';
import { projectPath } from '@/projectPath';
import { logger } from '@/ui/logger';
import { existsSync } from 'node:fs';
Expand All @@ -69,6 +69,10 @@ import { existsSync } from 'node:fs';
export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): ChildProcess {
const projectRoot = projectPath();
const entrypoint = join(projectRoot, 'dist', 'index.mjs');
const overrideRuntime = process.env.HAPPY_NODE_BIN;
const runtimePath = overrideRuntime || process.execPath || 'node';
const isBunRuntime = typeof (process as any).versions?.bun === 'string'
|| basename(runtimePath).toLowerCase().includes('bun');

let directory: string | URL | undefined;
if ('cwd' in options) {
Expand All @@ -84,10 +88,9 @@ export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child
const fullCommand = `happy ${args.join(' ')}`;
logger.debug(`[SPAWN HAPPY CLI] Spawning: ${fullCommand} in ${directory}`);

// Use the same Node.js flags that the wrapper script uses
const nodeArgs = [
'--no-warnings',
'--no-deprecation',
// Use the same Node.js flags that the wrapper script uses (Bun doesn't support these)
const runtimeArgs = [
...(isBunRuntime ? [] : ['--no-warnings', '--no-deprecation']),
entrypoint,
...args
];
Expand All @@ -99,5 +102,6 @@ export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child
throw new Error(errorMessage);
}

return spawn('node', nodeArgs, options);
logger.debug(`[SPAWN HAPPY CLI] Runtime: ${runtimePath} (bun=${isBunRuntime})`);
return spawn(runtimePath, runtimeArgs, options);
}