From bbe8354bfd3c6e82870acee78e67cb439bb25044 Mon Sep 17 00:00:00 2001 From: Eyejoker Date: Tue, 10 Mar 2026 21:46:36 +0900 Subject: [PATCH] fix: add npm-global to PATH for codex CLI, clear typing after response - Enrich spawned process PATH with ~/.npm-global/bin so codex CLI is findable when running under launchd - Clear typing indicator in streaming callback after sending response, instead of waiting for runner process to fully exit --- src/container-runner.ts | 12 ++++++++---- src/index.ts | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/container-runner.ts b/src/container-runner.ts index 1700a69..32b486b 100644 --- a/src/container-runner.ts +++ b/src/container-runner.ts @@ -133,12 +133,16 @@ function prepareGroupEnvironment( delete cleanEnv.CLAUDECODE; delete cleanEnv.CLAUDE_CODE_ENTRYPOINT; - // Ensure node is findable by SDK subprocess (cli.js uses #!/usr/bin/env node) + // Ensure node and npm-global binaries (codex, etc.) are findable const nodeBin = path.dirname(process.execPath); + const npmGlobalBin = path.join(os.homedir(), '.npm-global', 'bin'); const currentPath = cleanEnv.PATH || '/usr/local/bin:/usr/bin:/bin'; - const enrichedPath = currentPath.includes(nodeBin) - ? currentPath - : `${nodeBin}:${currentPath}`; + const extraPaths = [nodeBin, npmGlobalBin].filter( + (p) => !currentPath.includes(p) && fs.existsSync(p), + ); + const enrichedPath = extraPaths.length > 0 + ? `${extraPaths.join(':')}:${currentPath}` + : currentPath; const env: Record = { ...cleanEnv, diff --git a/src/index.ts b/src/index.ts index 7548d53..c0667ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -257,6 +257,9 @@ async function processGroupMessages(chatJid: string): Promise { await channel.sendMessage(chatJid, text); outputSentToUser = true; } + // Clear typing indicator after sending a response — the runner may stay + // alive waiting for IPC messages, but the user shouldn't see "typing..." + await channel.setTyping?.(chatJid, false); // Only reset idle timer on actual results, not session-update markers (result: null) resetIdleTimer(); }