diff --git a/src/provider/accounts.ts b/src/provider/accounts.ts index 52533d4..fedbfb8 100644 --- a/src/provider/accounts.ts +++ b/src/provider/accounts.ts @@ -118,7 +118,7 @@ function callbacks(interaction: AuthInteraction): OAuthLoginCallbacks { }; } -function openAuthorizationUrl(url: string, onError: () => void) { +function openAuthorizationUrl(url: string) { const command: [string, string[]] = process.platform === 'darwin' ? ['open', [url]] @@ -126,7 +126,7 @@ function openAuthorizationUrl(url: string, onError: () => void) { ? ['rundll32', ['url.dll,FileProtocolHandler', url]] : ['xdg-open', [url]]; const child = spawn(command[0], command[1], { detached: true, stdio: 'ignore' }); - child.once('error', onError); + child.once('error', () => {}); child.unref(); } @@ -134,9 +134,8 @@ function terminalInteraction(ctx: ExtensionCommandContext): AuthInteraction { return { notify(event) { if (event.type === 'auth_url') { - openAuthorizationUrl(event.url, () => { - ctx.ui.notify(`Open this URL to continue login: ${event.url}`, 'warning'); - }); + openAuthorizationUrl(event.url); + ctx.ui.notify(`Open this URL to continue login: ${event.url}`, 'warning'); ctx.ui.notify(event.instructions ?? 'Complete the Grok CLI login in your browser.', 'info'); return; } diff --git a/tests/provider/accounts.test.ts b/tests/provider/accounts.test.ts index 917d894..655edfe 100644 --- a/tests/provider/accounts.test.ts +++ b/tests/provider/accounts.test.ts @@ -379,12 +379,11 @@ describe('vault account management', () => { await expect(accounts.activate(ctx, account.id)).rejects.toThrow('environment token'); }); - it('reports the authorization URL when the browser opener fails', async () => { + it('reports the authorization URL as a warning in terminal and launches browser opener', async () => { const child = Object.assign(new EventEmitter(), { unref: vi.fn() }); spawnProcess.mockReturnValue(child); login.mockImplementationOnce(async (callbacks) => { callbacks.onAuth({ url: 'https://accounts.x.ai/authorize?state=test' }); - child.emit('error', new Error('xdg-open missing')); throw new Error('stop test login'); }); const commands = new Map< @@ -413,10 +412,17 @@ describe('vault account management', () => { await commands.get('grok-cli-accounts')?.handler('', commandContext); + expect(spawnProcess).toHaveBeenCalled(); + expect(child.unref).toHaveBeenCalled(); + expect(() => child.emit('error', new Error('spawn failed'))).not.toThrow(); expect(commandContext.ui.notify).toHaveBeenCalledWith( expect.stringContaining('https://accounts.x.ai/authorize?state=test'), 'warning', ); + expect(commandContext.ui.notify).toHaveBeenCalledWith( + 'Complete the Grok CLI login in your browser.', + 'info', + ); }); it('does not save quota after the captured account logs out', async () => {