diff --git a/src/core/request/request-handler.ts b/src/core/request/request-handler.ts index 9f8b8e3..b534ae5 100644 --- a/src/core/request/request-handler.ts +++ b/src/core/request/request-handler.ts @@ -28,7 +28,8 @@ export class RequestHandler { constructor( private accountManager: AccountManager, private config: KiroConfig, - private repository: AccountRepository + private repository: AccountRepository, + private client?: any ) { this.accountSelector = new AccountSelector(accountManager, config, syncFromKiroCli, repository) this.tokenRefresher = new TokenRefresher(config, accountManager, syncFromKiroCli, repository) @@ -70,7 +71,11 @@ export class RequestHandler { } if (this.allAccountsPermanentlyUnhealthy()) { - throw new Error('All accounts are permanently unhealthy (quota exceeded or suspended)') + const reauthed = await this.triggerReauth(showToast) + if (!reauthed) { + throw new Error('All accounts are permanently unhealthy. Please re-authenticate.') + } + continue } let acc = await this.accountSelector.selectHealthyAccount(showToast) @@ -259,6 +264,29 @@ export class RequestHandler { } } + private async triggerReauth(showToast: ToastFunction): Promise { + if (!this.client) return false + try { + showToast('Session expired. Re-authenticating...', 'warning') + await this.client.provider.oauth.authorize({ + path: { id: 'kiro' }, + body: { method: 0 } + }) + // Sync fresh tokens from CLI after re-auth + await syncFromKiroCli() + this.repository.invalidateCache() + const accounts = await this.repository.findAll() + for (const acc of accounts) { + this.accountManager.addAccount(acc) + } + showToast('Re-authentication successful.', 'success') + return true + } catch (e) { + logger.error('Re-auth failed', e instanceof Error ? e : new Error(String(e))) + return false + } + } + private allAccountsPermanentlyUnhealthy(): boolean { const accounts = this.accountManager.getAccounts() if (accounts.length === 0) { diff --git a/src/plugin.ts b/src/plugin.ts index aa987e2..87da6d7 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -26,14 +26,14 @@ export const createKiroPlugin = const accountManager = await AccountManager.loadFromDisk(config.account_selection_strategy) authHandler.setAccountManager(accountManager) - const requestHandler = new RequestHandler(accountManager, config, repository) + const requestHandler = new RequestHandler(accountManager, config, repository, client) return { auth: { provider: id, loader: async (getAuth: any) => { await getAuth() - await authHandler.initialize() + await authHandler.initialize(showToast as any) return { apiKey: '',