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
3 changes: 3 additions & 0 deletions packages/happy-cli/scripts/claude_local_launcher.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ global.fetch = function(...args) {
Object.defineProperty(global.fetch, 'name', { value: 'fetch' });
Object.defineProperty(global.fetch, 'length', { value: originalFetch.length });

// Remove CLAUDECODE to prevent nested session detection when spawning Claude CLI
delete process.env.CLAUDECODE;

// Import global Claude Code CLI
const { getClaudeCliPath, runClaudeCli } = require('./claude_version_utils.cjs');

Expand Down
3 changes: 3 additions & 0 deletions packages/happy-cli/scripts/claude_remote_launcher.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ global.setTimeout = function(callback, delay, ...args) {
Object.defineProperty(global.setTimeout, 'name', { value: 'setTimeout' });
Object.defineProperty(global.setTimeout, 'length', { value: originalSetTimeout.length });

// Remove CLAUDECODE to prevent nested session detection when spawning Claude CLI
delete process.env.CLAUDECODE;

// Import global Claude Code CLI
const { getClaudeCliPath, runClaudeCli } = require('./claude_version_utils.cjs');

Expand Down
2 changes: 2 additions & 0 deletions packages/happy-cli/src/claude/claudeLocal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ export async function claudeLocal(opts: {
...process.env,
...opts.claudeEnvVars
}
// Remove CLAUDECODE to prevent nested session detection when spawning Claude CLI
delete env.CLAUDECODE

logger.debug(`[ClaudeLocal] Spawning launcher: ${claudeCliPath}`);
logger.debug(`[ClaudeLocal] Args: ${JSON.stringify(args)}`);
Expand Down
3 changes: 2 additions & 1 deletion packages/happy-cli/src/claude/claudeRemoteLauncher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,8 @@ export async function claudeRemoteLauncher(session: Session): Promise<'switch' |
session.client.sendSessionEvent({ type: 'message', message: 'Aborted by user' });
}
} catch (e) {
logger.debug('[remote]: launch error', e);
const errorDetail = e instanceof Error ? `${e.message}\n${e.stack}` : String(e);
logger.debug(`[remote]: launch error: ${errorDetail}`);
if (!exitReason) {
session.client.closeClaudeSessionTurn('failed');
session.client.sendSessionEvent({ type: 'message', message: 'Process exited unexpectedly' });
Expand Down
2 changes: 1 addition & 1 deletion packages/happy-cli/src/claude/sdk/metadataExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function extractSDKMetadata(): Promise<SDKMetadata> {
logger.debug('[metadataExtractor] SDK query aborted after capturing metadata')
return {}
}
logger.debug('[metadataExtractor] Error extracting SDK metadata:', error)
logger.debug(`[metadataExtractor] Error extracting SDK metadata: ${error instanceof Error ? error.message : String(error)}`)
return {}
}
}
Expand Down
5 changes: 4 additions & 1 deletion packages/happy-cli/src/claude/sdk/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,10 @@ export function query(config: {

// Spawn Claude Code process
// Use clean env for global claude to avoid local node_modules/.bin taking precedence
const spawnEnv = isCommandOnly ? getCleanEnv() : process.env
const baseEnv = isCommandOnly ? getCleanEnv() : { ...process.env }
// Remove CLAUDECODE to prevent nested session detection when spawning Claude CLI
delete baseEnv.CLAUDECODE
const spawnEnv = baseEnv
logDebug(`Spawning Claude Code process: ${spawnCommand} ${spawnArgs.join(' ')} (using ${isCommandOnly ? 'clean' : 'normal'} env)`)

const child = spawn(spawnCommand, spawnArgs, {
Expand Down
13 changes: 9 additions & 4 deletions packages/happy-cli/src/daemon/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,14 +497,19 @@ export async function startDaemon(): Promise<void> {

// TODO: In future, sessionId could be used with --resume to continue existing sessions
// For now, we ignore it - each spawn creates a new session
// Build clean environment for child process
const childEnv = {
...process.env,
...extraEnv
};
// Remove CLAUDECODE to prevent nested session detection when spawning Claude CLI
delete childEnv.CLAUDECODE;

const happyProcess = spawnHappyCLI(args, {
cwd: directory,
detached: true, // Sessions stay alive when daemon stops
stdio: ['ignore', 'pipe', 'pipe'], // Capture stdout/stderr for debugging
env: {
...process.env,
...extraEnv
}
env: childEnv
});

// Log output for debugging
Expand Down