@modelprofile.com/authswitch 2.2.0 → 3.0.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.
Files changed (43) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/accounts.d.ts +18 -1
  3. package/dist_ts/accounts.js +55 -1
  4. package/dist_ts/classes.accountlist.d.ts +4 -0
  5. package/dist_ts/classes.accountlist.js +20 -13
  6. package/dist_ts/classes.claudecodeharness.d.ts +4 -4
  7. package/dist_ts/classes.claudecodeharness.js +5 -5
  8. package/dist_ts/classes.cli.d.ts +17 -0
  9. package/dist_ts/classes.cli.js +128 -16
  10. package/dist_ts/classes.credentialstore.d.ts +20 -7
  11. package/dist_ts/classes.credentialstore.js +36 -23
  12. package/dist_ts/classes.fileharness.d.ts +23 -3
  13. package/dist_ts/classes.fileharness.js +102 -16
  14. package/dist_ts/classes.harnessprocesses.d.ts +62 -0
  15. package/dist_ts/classes.harnessprocesses.js +198 -0
  16. package/dist_ts/classes.limits.d.ts +24 -0
  17. package/dist_ts/classes.limits.js +200 -0
  18. package/dist_ts/classes.opencodeharness.d.ts +4 -5
  19. package/dist_ts/classes.opencodeharness.js +5 -5
  20. package/dist_ts/classes.operations.d.ts +9 -1
  21. package/dist_ts/classes.operations.js +4 -2
  22. package/dist_ts/classes.tui.js +48 -3
  23. package/dist_ts/index.d.ts +1 -0
  24. package/dist_ts/index.js +2 -1
  25. package/dist_ts/interfaces.harness.d.ts +61 -0
  26. package/dist_ts/interfaces.list.d.ts +67 -1
  27. package/package.json +2 -2
  28. package/readme.md +155 -19
  29. package/ts/00_commitinfo_data.ts +1 -1
  30. package/ts/accounts.ts +50 -1
  31. package/ts/classes.accountlist.ts +24 -11
  32. package/ts/classes.claudecodeharness.ts +7 -6
  33. package/ts/classes.cli.ts +105 -16
  34. package/ts/classes.credentialstore.ts +41 -18
  35. package/ts/classes.fileharness.ts +80 -16
  36. package/ts/classes.harnessprocesses.ts +225 -0
  37. package/ts/classes.limits.ts +209 -0
  38. package/ts/classes.opencodeharness.ts +7 -7
  39. package/ts/classes.operations.ts +10 -1
  40. package/ts/classes.tui.ts +34 -3
  41. package/ts/index.ts +1 -0
  42. package/ts/interfaces.harness.ts +62 -0
  43. package/ts/interfaces.list.ts +72 -1
@@ -12,6 +12,64 @@ export interface IHarnessLoginHandle {
12
12
  close(): Promise<void>;
13
13
  }
14
14
 
15
+ /** One running instance of a harness binary, owned by the current user. */
16
+ export interface IHarnessProcess {
17
+ pid: number;
18
+ /** Executable name as the platform reports it, without a path. */
19
+ command: string;
20
+ /** Bounded command line, for identifying which instance this is. Never parsed for identity. */
21
+ commandLine: string;
22
+ /** Start time, which distinguishes a reused pid from the process we enumerated. */
23
+ startedAt: string | null;
24
+ /** An ancestor of the running authswitch command: stopping it would kill this command. */
25
+ isAncestor: boolean;
26
+ }
27
+
28
+ export interface IHarnessStopOutcome {
29
+ /** Instances that exited within the bounded wait. */
30
+ stopped: IHarnessProcess[];
31
+ /** Instances that were still running when the wait elapsed. */
32
+ survivors: IHarnessProcess[];
33
+ /** Instances that were re-verified and then killed, only ever with an explicit force request. */
34
+ forced: IHarnessProcess[];
35
+ }
36
+
37
+ /**
38
+ * Enumerating and stopping a harness's own running instances.
39
+ *
40
+ * Only pids this control enumerated for the current user are ever signalled, and a stop is graceful
41
+ * unless the caller explicitly forces it. Adapters whose process lifecycle belongs to another
42
+ * manager (Codex' app-server daemon) expose no control at all.
43
+ */
44
+ export interface IHarnessProcessControl {
45
+ readonly binary: string;
46
+ /** Why enumerated instances cannot be signalled on this platform; null when they can. */
47
+ readonly stopUnavailableReason: string | null;
48
+ list(): IHarnessProcess[];
49
+ stop(processesArg: readonly IHarnessProcess[], optionsArg?: { force?: boolean; timeoutMs?: number }): Promise<IHarnessStopOutcome>;
50
+ }
51
+
52
+ /**
53
+ * A live credential that no longer holds the account the last switch activated.
54
+ *
55
+ * Authswitch records the hash of what it wrote, in its own store. A different hash with the same
56
+ * account is that account's own token refresh; a different account is what a running instance
57
+ * writing its in-memory login back looks like.
58
+ */
59
+ export interface IHarnessCredentialDrift {
60
+ slotId?: string;
61
+ /** The account the recorded switch activated. */
62
+ expectedAccountId: string;
63
+ /** Its saved label, or null when that account is no longer saved. */
64
+ expectedLabel: string | null;
65
+ /** The account the credential file holds now, or null when the slot has no active login. */
66
+ currentAccountId: string | null;
67
+ currentLabel: string | null;
68
+ /** Whether the current account has a saved copy of its own. */
69
+ currentIsSaved: boolean;
70
+ switchedAt: string;
71
+ }
72
+
15
73
  /** Account IDs are opaque and scoped to one harness. Credentials never cross this interface. */
16
74
  export interface IHarnessAccount {
17
75
  id: string;
@@ -28,6 +86,8 @@ export interface IHarnessState {
28
86
  accounts: IHarnessAccount[];
29
87
  /** Explains why an active login cannot be saved, when applicable. */
30
88
  saveUnavailableReason: string | null;
89
+ /** Slots whose credential file no longer holds the account the last switch wrote. */
90
+ credentialDrift?: IHarnessCredentialDrift[];
31
91
  }
32
92
 
33
93
  export interface IHarnessAccountStatus {
@@ -97,6 +157,8 @@ export interface IAuthHarness {
97
157
  readonly loginHint: string;
98
158
  readonly diagnosticsLabel: string;
99
159
  readState(): THarnessResult<IHarnessState>;
160
+ /** Running instances of this harness, when the adapter owns their lifecycle. */
161
+ readonly processes?: IHarnessProcessControl;
100
162
  readAccountStatus(accountIdArg: string): Promise<IHarnessAccountStatus>;
101
163
  readonly loginProviders?: IHarnessLoginProvider[];
102
164
  beginLogin?(options: IHarnessLoginOptions): Promise<IHarnessLoginHandle>;
@@ -1,4 +1,4 @@
1
- import type { IHarnessAccount, IHarnessAccountStatus } from './interfaces.harness.js';
1
+ import type { IHarnessAccount, IHarnessAccountStatus, IHarnessCredentialDrift } from './interfaces.harness.js';
2
2
 
3
3
  /** Credential-free, versioned output of list --json. Missing status fields stay omitted. */
4
4
  export interface IAccountList {
@@ -14,6 +14,77 @@ export interface IHarnessAccountList {
14
14
  loginHint: string;
15
15
  saveUnavailableReason: string | null;
16
16
  accounts: (IHarnessAccount & { status: IHarnessAccountStatus })[];
17
+ /** Slots whose credential file no longer holds the account the last switch wrote. */
18
+ credentialDrift: IHarnessCredentialDrift[];
17
19
  /** A state lookup failure is distinct from an empty account list. */
18
20
  problems: string[];
19
21
  }
22
+
23
+ /** Credential-free, versioned output of limits --json. One entry per account and limit type. */
24
+ export interface IAccountLimits {
25
+ schemaVersion: 1;
26
+ generatedAt: string;
27
+ complete: boolean;
28
+ limits: IAccountLimitRow[];
29
+ /** Why a row has no numbers. Never a substitute for a value. */
30
+ notes: string[];
31
+ }
32
+
33
+ export interface IAccountLimitRow {
34
+ harnessId: string;
35
+ /** Harness label, qualified by the credential slot when the harness owns several. */
36
+ provider: string;
37
+ /** The account's public label, which is its email wherever the provider reports one. */
38
+ account: string | null;
39
+ accountId: string | null;
40
+ slotId?: string;
41
+ isActive: boolean;
42
+ /** The provider's own window name, or null when no limit data is available. */
43
+ limitType: string | null;
44
+ scope: 'account' | 'feature' | null;
45
+ windowSeconds: number | null;
46
+ /** Never inferred: null means the provider reported no percentage, not zero usage. */
47
+ usedPercent: number | null;
48
+ resetAt: string | null;
49
+ /** Human countdown for the same `resetAt`, relative to `generatedAt`. */
50
+ resetsIn: string;
51
+ unavailableReason: string | null;
52
+ }
53
+
54
+ /** Credential-free, versioned output of active --json. One entry per active credential slot. */
55
+ export interface IActiveAccounts {
56
+ schemaVersion: 1;
57
+ generatedAt: string;
58
+ complete: boolean;
59
+ active: IActiveAccountRow[];
60
+ notes: string[];
61
+ }
62
+
63
+ export interface IActiveAccountRow {
64
+ harnessId: string;
65
+ provider: string;
66
+ account: string | null;
67
+ accountId: string | null;
68
+ slotId?: string;
69
+ /** When authswitch last saved this login; null when it was never stashed. */
70
+ savedAt: string | null;
71
+ /** Human elapsed time for the same `savedAt`, relative to `generatedAt`. */
72
+ savedAgo: string;
73
+ /** Where the shown account comes from. Whether it is also saved is the `savedAt` field's answer. */
74
+ source: 'credential file' | 'stash only' | 'none';
75
+ unavailableReason: string | null;
76
+ /** Set when the credential file no longer holds the account the last switch wrote. */
77
+ drift: IActiveAccountDrift | null;
78
+ }
79
+
80
+ /** A credential file that changed underneath a switch, with both accounts named where known. */
81
+ export interface IActiveAccountDrift {
82
+ expectedAccountId: string;
83
+ expectedAccount: string | null;
84
+ currentAccountId: string | null;
85
+ currentAccount: string | null;
86
+ currentIsSaved: boolean;
87
+ switchedAt: string;
88
+ /** The sentence the table footnotes, for consumers that display one string. */
89
+ reason: string;
90
+ }