fix(core): prevent hangs in non-interactive mode and improve agent guidance

- Injects headless-safe environment variables into non-interactive subprocesses to prevent credential prompt deadlocks (fixes #16567).
- Updates system instructions for non-interactive mode to discourage impossible user questions (addresses #5724).
- Adds unit tests to verify environment injection.
This commit is contained in:
cocosheng-g
2026-03-02 17:14:33 -05:00
committed by Coco Sheng
parent 1b69637032
commit 050fefe0c7
4 changed files with 50 additions and 3 deletions

View File

@@ -1703,4 +1703,39 @@ describe('ShellExecutionService environment variables', () => {
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);
});
it('should include headless git and gh environment variables in non-interactive mode', async () => {
vi.resetModules();
const { ShellExecutionService } = await import(
'./shellExecutionService.js'
);
mockGetPty.mockResolvedValue(null); // Force child_process fallback
await ShellExecutionService.execute(
'test-cp-headless-git',
'/',
vi.fn(),
new AbortController().signal,
false, // non-interactive
shellExecutionConfig,
);
expect(mockCpSpawn).toHaveBeenCalled();
const cpEnv = mockCpSpawn.mock.calls[0][2].env;
expect(cpEnv).toHaveProperty('GIT_TERMINAL_PROMPT', '0');
expect(cpEnv).toHaveProperty('GIT_ASKPASS', '');
expect(cpEnv).toHaveProperty('SSH_ASKPASS', '');
expect(cpEnv).toHaveProperty('GH_PROMPT_DISABLED', '1');
expect(cpEnv).toHaveProperty('GCM_INTERACTIVE', 'never');
expect(cpEnv).toHaveProperty('DISPLAY', '');
expect(cpEnv).toHaveProperty('DBUS_SESSION_BUS_ADDRESS', '');
expect(cpEnv).toHaveProperty('GIT_CONFIG_COUNT', '1');
expect(cpEnv).toHaveProperty('GIT_CONFIG_KEY_0', 'credential.helper');
expect(cpEnv).toHaveProperty('GIT_CONFIG_VALUE_0', '');
// Ensure child_process exits
mockChildProcess.emit('exit', 0, null);
mockChildProcess.emit('close', 0, null);
await new Promise(process.nextTick);
});
});