fix(cliproxy): mark Kiro as device_code flow for dashboard auth

CLIProxyAPIPlus uses device code flow for Kiro authentication, returning
{method: "device_code", state, status} without an immediate URL. The URL
is provided via polling the /get-auth-status endpoint.

Previously, Kiro was configured as authorization_code flow, causing
dashboard auth to fail with "No authorization URL received from CLIProxyAPI"
because the web-server routes expected synchronous URL response.

Changes:
- provider-capabilities.ts: kiro.oauthFlow = 'device_code', callbackPort = null
- provider-config.ts: Add 'kiro' to DEVICE_CODE_PROVIDERS array
- provider-capabilities.test.ts: Update test expectations

This routes Kiro through /start endpoint which properly handles device code
flow via WebSocket events (deviceCodeReceived, deviceCodeCompleted, etc).

Closes #552
This commit is contained in:
Tam Nhu Tran committed 2026-02-13 19:33:33 +07:00
1 parent 33a48f2c76
commit 6c2083949f
3 files changed
+5 -5

No files matched your search

+2 -2
View File
@@ -46,8 +46,8 @@ export const PROVIDER_CAPABILITIES: Record<CLIProxyProvider, ProviderCapabilitie
}, },
kiro: { kiro: {
displayName: 'Kiro (AWS)', displayName: 'Kiro (AWS)',
oauthFlow: 'authorization_code', oauthFlow: 'device_code',
callbackPort: 9876, callbackPort: null,
aliases: ['codewhisperer'], aliases: ['codewhisperer'],
}, },
ghcp: { ghcp: {
@@ -30,13 +30,12 @@ describe('provider-capabilities', () => {
}); });
it('returns providers by OAuth flow capability', () => { it('returns providers by OAuth flow capability', () => {
expect(getProvidersByOAuthFlow('device_code')).toEqual(['qwen', 'ghcp']); expect(getProvidersByOAuthFlow('device_code')).toEqual(['qwen', 'kiro', 'ghcp']);
expect(getProvidersByOAuthFlow('authorization_code')).toEqual([ expect(getProvidersByOAuthFlow('authorization_code')).toEqual([
'gemini', 'gemini',
'codex', 'codex',
'agy', 'agy',
'iflow', 'iflow',
'kiro',
'claude', 'claude',
]); ]);
}); });
@@ -53,6 +52,7 @@ describe('provider-capabilities', () => {
it('exposes callback port and display name capabilities', () => { it('exposes callback port and display name capabilities', () => {
expect(getOAuthCallbackPort('qwen')).toBeNull(); expect(getOAuthCallbackPort('qwen')).toBeNull();
expect(getOAuthCallbackPort('kiro')).toBeNull();
expect(getOAuthCallbackPort('gemini')).toBe(8085); expect(getOAuthCallbackPort('gemini')).toBe(8085);
expect(getProviderDisplayName('agy')).toBe('AntiGravity'); expect(getProviderDisplayName('agy')).toBe('AntiGravity');
}); });
+1 -1
View File
@@ -76,7 +76,7 @@ export function getProviderDisplayName(provider: string): string {
* Providers that use Device Code OAuth flow instead of Authorization Code flow. * Providers that use Device Code OAuth flow instead of Authorization Code flow.
* Device Code flow requires displaying a user code for manual entry at provider's website. * Device Code flow requires displaying a user code for manual entry at provider's website.
*/ */
export const DEVICE_CODE_PROVIDERS: CLIProxyProvider[] = ['ghcp', 'qwen']; export const DEVICE_CODE_PROVIDERS: CLIProxyProvider[] = ['ghcp', 'kiro', 'qwen'];
/** Check if provider uses Device Code flow */ /** Check if provider uses Device Code flow */
export function isDeviceCodeProvider(provider: string): boolean { export function isDeviceCodeProvider(provider: string): boolean {