mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
fix: Preserve direct TUI input in native terminals
Direct native CLI launches already inherit their user's shell environment, so recapturing a login interactive shell from the same TTY is unnecessary and can interfere with prompt input on macOS terminals. The desktop and non-interactive subprocess paths still keep the shell-env bridge because they do not own the user's interactive terminal. Constraint: Windows was already excluded from terminal shell env capture, which explains why v0.2.8 remained healthy there. Rejected: Disable terminal shell env capture globally | desktop subprocesses still need the captured login-shell environment. Confidence: high Scope-risk: narrow Directive: Do not re-enable interactive shell env capture for direct TTY launches without a native PTY input regression test. Tested: bun test src/utils/terminalShellEnvironment.test.ts src/utils/mcpStdioEnvironment.test.ts Tested: Native PTY smoke confirmed typed characters appear in claude-haha prompt Tested: SKIP_INSTALL=1 ./desktop/scripts/build-macos-arm64.sh Not-tested: Full bun run verify was intentionally not completed after user requested only a local macOS build
This commit is contained in:
parent
dffe83b83a
commit
10d75852bb
@ -101,4 +101,42 @@ describe('terminal shell environment', () => {
|
||||
|
||||
expect(env).toBeNull()
|
||||
})
|
||||
|
||||
it('does not capture shell env when the current process owns an interactive TTY', async () => {
|
||||
const stdinDescriptor = Object.getOwnPropertyDescriptor(process.stdin, 'isTTY')
|
||||
const stdoutDescriptor = Object.getOwnPropertyDescriptor(process.stdout, 'isTTY')
|
||||
|
||||
Object.defineProperty(process.stdin, 'isTTY', {
|
||||
configurable: true,
|
||||
value: true,
|
||||
})
|
||||
Object.defineProperty(process.stdout, 'isTTY', {
|
||||
configurable: true,
|
||||
value: true,
|
||||
})
|
||||
|
||||
try {
|
||||
const shellPath = path.join(tmpDir, 'zsh')
|
||||
await writeFakeZsh(shellPath)
|
||||
|
||||
const env = await getTerminalShellEnvironment({
|
||||
HOME: tmpDir,
|
||||
SHELL: shellPath,
|
||||
PATH: '/usr/bin:/bin',
|
||||
})
|
||||
|
||||
expect(env).toBeNull()
|
||||
} finally {
|
||||
if (stdinDescriptor) {
|
||||
Object.defineProperty(process.stdin, 'isTTY', stdinDescriptor)
|
||||
} else {
|
||||
delete (process.stdin as { isTTY?: boolean }).isTTY
|
||||
}
|
||||
if (stdoutDescriptor) {
|
||||
Object.defineProperty(process.stdout, 'isTTY', stdoutDescriptor)
|
||||
} else {
|
||||
delete (process.stdout as { isTTY?: boolean }).isTTY
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@ -104,7 +104,10 @@ async function captureTerminalShellEnvironment(
|
||||
): Promise<Record<string, string> | null> {
|
||||
if (
|
||||
process.platform === 'win32' ||
|
||||
isEnvTruthy(baseEnv.CC_HAHA_DISABLE_TERMINAL_SHELL_ENV)
|
||||
isEnvTruthy(baseEnv.CC_HAHA_DISABLE_TERMINAL_SHELL_ENV) ||
|
||||
// Direct terminal launches already inherit shell env; spawning an
|
||||
// interactive login shell here can interfere with the active TTY.
|
||||
(process.stdin.isTTY && process.stdout.isTTY)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user