maxpool 1.5.24 → 1.5.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/tui.js +40 -13
package/package.json
CHANGED
package/src/tui.js
CHANGED
|
@@ -402,8 +402,8 @@ export class TUI {
|
|
|
402
402
|
};
|
|
403
403
|
} else if (k === 'l') {
|
|
404
404
|
this._confirm(
|
|
405
|
-
'Log in via browser?',
|
|
406
|
-
'Opens a browser
|
|
405
|
+
'Log in / re-authenticate via browser?',
|
|
406
|
+
'Opens a browser. Logging into an account that\'s already added RE-AUTHENTICATES it in place (revives a reauth/error account) — no duplicate. Otherwise a new account is added.',
|
|
407
407
|
() => this._doLogin(),
|
|
408
408
|
);
|
|
409
409
|
} else if (k === 'n' && this.am.accounts.length > 0) {
|
|
@@ -577,8 +577,10 @@ export class TUI {
|
|
|
577
577
|
}
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
-
// Browser OAuth login
|
|
581
|
-
//
|
|
580
|
+
// Browser OAuth login — the SAME flow re-authenticates an existing account (matched
|
|
581
|
+
// by accountUuid) or adds a new one. When the login is for an account already added,
|
|
582
|
+
// we say so, keep its name, and skip the "name this account" prompt — so it's clear
|
|
583
|
+
// it's a RE-AUTH in place (revives a dead-refresh/reauth account), not a duplicate.
|
|
582
584
|
async _doLogin() {
|
|
583
585
|
const wasRunning = this.running;
|
|
584
586
|
if (wasRunning) this.stop();
|
|
@@ -586,14 +588,26 @@ export class TUI {
|
|
|
586
588
|
process.stdout.write('\nOpening browser to log into Claude…\n');
|
|
587
589
|
const creds = await loginOAuth();
|
|
588
590
|
const profile = await fetchProfile(creds.accessToken);
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
591
|
+
const existing = this._findExistingOAuthAccount(profile);
|
|
592
|
+
let name;
|
|
593
|
+
if (existing) {
|
|
594
|
+
process.stdout.write(`\nThis Claude account is already added as "${existing.name}" — re-authenticating it in place (no duplicate).\n`);
|
|
595
|
+
name = existing.name;
|
|
596
|
+
} else {
|
|
597
|
+
const suggested = profile?.email
|
|
598
|
+
|| `account-${this.config.accounts.filter(a => a.name.startsWith('account-')).length + 1}`;
|
|
599
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
600
|
+
const answer = await new Promise(resolve => rl.question(`Name this NEW account [${suggested}]: `, resolve));
|
|
601
|
+
rl.close();
|
|
602
|
+
name = String(answer || '').trim() || suggested;
|
|
603
|
+
}
|
|
604
|
+
// Message honors the ACTUAL result: if a manually-typed name collided with a
|
|
605
|
+
// different existing account, upsert updates in place → "Re-authenticated", never
|
|
606
|
+
// a false "Added new account".
|
|
607
|
+
const { updated } = await this._upsertOAuthAccount({ creds, profile, name, source: 'login' });
|
|
608
|
+
process.stdout.write(updated
|
|
609
|
+
? `\nRe-authenticated "${name}". Returning to maxpool…\n`
|
|
610
|
+
: `\nAdded new account "${name}". Returning to maxpool…\n`);
|
|
597
611
|
} catch (e) {
|
|
598
612
|
process.stdout.write(`\nLogin failed: ${e.message}\n`);
|
|
599
613
|
} finally {
|
|
@@ -671,6 +685,7 @@ export class TUI {
|
|
|
671
685
|
if (amAcct.status === 'error') amAcct.status = 'active';
|
|
672
686
|
}
|
|
673
687
|
this._addLog(`Updated account "${name}"`);
|
|
688
|
+
return { updated: true, name };
|
|
674
689
|
} else {
|
|
675
690
|
this.config.accounts.push(entry);
|
|
676
691
|
try {
|
|
@@ -681,9 +696,21 @@ export class TUI {
|
|
|
681
696
|
}
|
|
682
697
|
this.am.addAccount(entry);
|
|
683
698
|
this._addLog(`${verb} account "${name}"`);
|
|
699
|
+
return { updated: false, name };
|
|
684
700
|
}
|
|
685
701
|
}
|
|
686
702
|
|
|
703
|
+
// Find an already-configured OAuth account matching a fresh browser-login profile —
|
|
704
|
+
// by accountUuid (primary), then name===email — the SAME precedence _upsertOAuthAccount
|
|
705
|
+
// dedupes on, so the login flow can honestly say "re-authenticating" vs "adding new".
|
|
706
|
+
_findExistingOAuthAccount(profile) {
|
|
707
|
+
const uuid = profile?.accountUuid || null;
|
|
708
|
+
const email = profile?.email || null;
|
|
709
|
+
let acct = uuid ? this.config.accounts.find(a => a.type === 'oauth' && a.accountUuid === uuid) : null;
|
|
710
|
+
if (!acct && email) acct = this.config.accounts.find(a => a.type === 'oauth' && a.name === email);
|
|
711
|
+
return acct || null;
|
|
712
|
+
}
|
|
713
|
+
|
|
687
714
|
async _doAddKey(apiKey) {
|
|
688
715
|
const key = String(apiKey || '').trim();
|
|
689
716
|
if (!key) { this._addLog('No API key entered'); return; }
|
|
@@ -1120,7 +1147,7 @@ export class TUI {
|
|
|
1120
1147
|
case 'normal':
|
|
1121
1148
|
return ` ${bold('a')} Accounts ${bold('m')} Routing ${bold('s')} Sync ${bold('r')} Restart ${bold('q')} Stop`;
|
|
1122
1149
|
case 'accounts':
|
|
1123
|
-
return ` ${bold('l')} Login (browser) ${bold('k')} API key ${bold('n')} Rename ${bold('t')} Enable/disable ${bold('d')} Delete ${bold('Esc')} Back`;
|
|
1150
|
+
return ` ${bold('l')} Login/re-auth (browser) ${bold('k')} API key ${bold('n')} Rename ${bold('t')} Enable/disable ${bold('d')} Delete ${bold('Esc')} Back`;
|
|
1124
1151
|
case 'routing':
|
|
1125
1152
|
return ` ${bold('a')} Automatic ${bold('p')} Manual preference ${bold('f')} Cross-provider fallback ${bold('Esc')} Back`;
|
|
1126
1153
|
case 'select': {
|