import { describe, expect, it } from 'vitest'; import { mergeJsonSettingsArgs } from '../../../../src/main/services/runtime/cliSettingsArgs'; function getSettingsValues(args: string[]): string[] { const values: string[] = []; for (let i = 0; i < args.length; i += 1) { if (args[i] === '--settings' && typeof args[i + 1] === 'string') { values.push(args[i + 1]); i += 1; } } return values; } describe('mergeJsonSettingsArgs', () => { it('merges app and provider JSON settings into a single settings argument', () => { const merged = mergeJsonSettingsArgs([ '--settings', '{"fastMode":false}', '--model', 'gpt-5.4', '--settings', '{"codex":{"forced_login_method":"chatgpt"}}', ]); expect(merged).toEqual([ '--settings', '{"fastMode":false,"codex":{"forced_login_method":"chatgpt"}}', '--model', 'gpt-5.4', ]); }); it('deep merges nested JSON settings and lets later values win', () => { const merged = mergeJsonSettingsArgs([ '--settings', '{"codex":{"forced_login_method":"api","existing":true}}', '--settings', '{"codex":{"forced_login_method":"chatgpt"}}', ]); expect(JSON.parse(getSettingsValues(merged)[0] ?? '{}')).toEqual({ codex: { forced_login_method: 'chatgpt', existing: true, }, }); }); it('preserves non-JSON settings values while merging JSON settings', () => { const merged = mergeJsonSettingsArgs([ '--settings', '/tmp/settings.json', '--settings={"fastMode":false}', '--settings', '{"codex":{"forced_login_method":"chatgpt"}}', ]); expect(merged).toEqual([ '--settings', '/tmp/settings.json', '--settings', '{"fastMode":false,"codex":{"forced_login_method":"chatgpt"}}', ]); }); it('preserves multiple hook entries for the same hook event', () => { const merged = mergeJsonSettingsArgs([ '--settings', JSON.stringify({ hooks: { Stop: [ { matcher: '', hooks: [{ type: 'command', command: '/bin/sh user-stop.sh' }], }, ], }, }), '--settings', JSON.stringify({ hooks: { Stop: [ { matcher: '', hooks: [{ type: 'command', command: '/bin/sh app-stop.sh' }], }, ], }, }), ]); expect(JSON.parse(getSettingsValues(merged)[0] ?? '{}')).toEqual({ hooks: { Stop: [ { matcher: '', hooks: [{ type: 'command', command: '/bin/sh user-stop.sh' }], }, { matcher: '', hooks: [{ type: 'command', command: '/bin/sh app-stop.sh' }], }, ], }, }); }); it('dedupes identical hook entries while preserving unrelated array replacement semantics', () => { const appHook = { matcher: '', hooks: [{ type: 'command', command: '/bin/sh app-stop.sh' }], }; const merged = mergeJsonSettingsArgs([ '--settings', JSON.stringify({ permissions: { allow: ['Read'] }, hooks: { Stop: [appHook] }, }), '--settings', JSON.stringify({ permissions: { allow: ['Bash'] }, hooks: { Stop: [appHook] }, }), ]); expect(JSON.parse(getSettingsValues(merged)[0] ?? '{}')).toEqual({ permissions: { allow: ['Bash'] }, hooks: { Stop: [appHook] }, }); }); });