@modelprofile.com/authswitch 4.0.0 → 5.1.0

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.
@@ -53,7 +53,7 @@ export class OpenCodeHarness extends FileHarness {
53
53
  public beginLogin(options: IHarnessLoginOptions = { providerId: 'openai', flow: 'device' }) {
54
54
  return beginSavedOpenAiLogin(async result => {
55
55
  const saved = await this.importCredential('openai', openCodeCredentialFromLogin(result.credential));
56
- const account = this.readState().accounts.find(account => account.id === saved.accountId)!;
56
+ const account = (await this.readState()).accounts.find(account => account.id === saved.accountId)!;
57
57
  return { outcome: { lines: [`Saved OpenAI login for ${plainText(account.label)}. Select it to switch OpenCode.`], problems: [] }, account: { id: account.id, label: account.label, slotId: account.slotId } };
58
58
  }, options, this.fetcher);
59
59
  }
@@ -52,6 +52,10 @@ export const assertAuthSwitchMutation: (value: unknown) => asserts value is TAut
52
52
  }
53
53
  };
54
54
 
55
+ /** Whether a mutation replaces the harness's active login, and therefore concerns running instances. */
56
+ export const authSwitchMutationReplacesLogin = (mutationArg: TAuthSwitchMutation): boolean =>
57
+ mutationArg.action === 'switch' || (mutationArg.action === 'save' && !mutationArg.keepActive);
58
+
55
59
  export const runAuthSwitchMutation = async (harness: IAuthHarness, mutation: TAuthSwitchMutation): Promise<IHarnessOutcome> => {
56
60
  assertAuthSwitchMutation(mutation);
57
61
  if (harness.id !== mutation.harnessId) throw new Error('Account operation targets a different harness.');
package/ts/classes.tui.ts CHANGED
@@ -2,7 +2,7 @@ import * as plugins from './plugins.js';
2
2
  import type { IAuthHarness, IHarnessOutcome, IHarnessProcess, IHarnessState, IHarnessStopOutcome } from './interfaces.harness.js';
3
3
  import { accountBadge, accountDetails, accountPlan, accountQuotaSummary, accountResets, accountState, accountUsageWindows, usageWindowName, until, readAccountRows, type IAccountRow } from './accounts.js';
4
4
  import { plainText } from './formatting.js';
5
- import { AuthSwitchOperations } from './classes.operations.js';
5
+ import { AuthSwitchOperations, authSwitchMutationReplacesLogin, type TAuthSwitchMutation } from './classes.operations.js';
6
6
  import { describeHarnessProcesses, describeStopOutcome } from './classes.harnessprocesses.js';
7
7
 
8
8
  /** Owns account-management actions; terminal rendering and interaction belong to smartconsole. */
@@ -89,6 +89,9 @@ export class AuthSwitchTui {
89
89
  }
90
90
  for (const line of describeStopOutcome(harness.label, outcome)) ui.logs.append(line);
91
91
  };
92
+ const mutate = (screen: plugins.smartconsole.ITuiContext, mutation: TAuthSwitchMutation): Promise<IHarnessOutcome> =>
93
+ this.operations.run(harness, mutation, message => screen.confirm(message),
94
+ authSwitchMutationReplacesLogin(mutation) ? settleInstances(screen) : undefined);
92
95
  const save = async (screen: plugins.smartconsole.ITuiContext, keepActiveArg: boolean): Promise<void> => {
93
96
  const latest = await harness.readState();
94
97
  const activeAccounts = latest.accounts.filter(account => account.isActive);
@@ -97,8 +100,7 @@ export class AuthSwitchTui {
97
100
  if (!active || latest.saveUnavailableReason) { footer.setText(latest.saveUnavailableReason ?? 'No active login to save.'); return; }
98
101
  if (!await screen.confirm(`Save ${plainText(active.label)}${keepActiveArg ? ' and keep it active' : ' and clear the active login'}?`)) return;
99
102
  if (screen.signal.aborted) return;
100
- const outcome = await this.operations.run(harness, { harnessId: harness.id, action: 'save', keepActive: keepActiveArg, accountId: active.id },
101
- message => screen.confirm(message), keepActiveArg ? undefined : settleInstances(screen));
103
+ const outcome = await mutate(screen, { harnessId: harness.id, action: 'save', keepActive: keepActiveArg, accountId: active.id });
102
104
  await refresh(screen); showOutcome(outcome);
103
105
  };
104
106
  const switchSelected = async (screen: plugins.smartconsole.ITuiContext): Promise<void> => {
@@ -112,7 +114,7 @@ export class AuthSwitchTui {
112
114
  if (latest.saveUnavailableReason) { footer.setText(latest.saveUnavailableReason); return; }
113
115
  if (!await screen.confirm(`${plainText(active.label)} is not saved. Save this login before switching?`, { confirmLabel: 'Save first' })) return;
114
116
  if (screen.signal.aborted) return;
115
- if (!showOutcome(await this.operations.run(harness, { harnessId: harness.id, action: 'save', keepActive: true, accountId: active.id }, message => screen.confirm(message)))) return;
117
+ if (!showOutcome(await mutate(screen, { harnessId: harness.id, action: 'save', keepActive: true, accountId: active.id }))) return;
116
118
  const verified = await harness.readState();
117
119
  if (!verified.accounts.some(account => account.isActive && account.isStashed && account.id === active.id)) { footer.setText('The current login could not be verified as saved. Switching was cancelled.'); return; }
118
120
  }
@@ -120,8 +122,7 @@ export class AuthSwitchTui {
120
122
  const badge = accountBadge(rows.find(row => row.account.id === target.id)?.status);
121
123
  if (!await screen.confirm(`Switch ${plainText(harness.label)} to ${plainText(target.label)}${badge}?`, { confirmLabel: 'Switch' })) return;
122
124
  if (screen.signal.aborted) return;
123
- const outcome = await this.operations.run(harness, { harnessId: harness.id, action: 'switch', accountId: target.id },
124
- message => screen.confirm(message), settleInstances(screen));
125
+ const outcome = await mutate(screen, { harnessId: harness.id, action: 'switch', accountId: target.id });
125
126
  await refresh(screen);
126
127
  if (showOutcome(outcome)) ui.logs.append(`Now active: ${plainText(target.label)}${badge}`);
127
128
  };