@iam-brain/opencode-codex-auth 0.1.3

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 (165) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/bin/opencode-codex-auth.d.ts +3 -0
  4. package/dist/bin/opencode-codex-auth.d.ts.map +1 -0
  5. package/dist/bin/opencode-codex-auth.js +13 -0
  6. package/dist/bin/opencode-codex-auth.js.map +1 -0
  7. package/dist/bin/opencode-openai-multi.d.ts +3 -0
  8. package/dist/bin/opencode-openai-multi.d.ts.map +1 -0
  9. package/dist/bin/opencode-openai-multi.js +13 -0
  10. package/dist/bin/opencode-openai-multi.js.map +1 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +137 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/lib/accounts-tools.d.ts +14 -0
  16. package/dist/lib/accounts-tools.d.ts.map +1 -0
  17. package/dist/lib/accounts-tools.js +100 -0
  18. package/dist/lib/accounts-tools.js.map +1 -0
  19. package/dist/lib/claims.d.ts +20 -0
  20. package/dist/lib/claims.d.ts.map +1 -0
  21. package/dist/lib/claims.js +37 -0
  22. package/dist/lib/claims.js.map +1 -0
  23. package/dist/lib/codex-native.d.ts +74 -0
  24. package/dist/lib/codex-native.d.ts.map +1 -0
  25. package/dist/lib/codex-native.js +2404 -0
  26. package/dist/lib/codex-native.js.map +1 -0
  27. package/dist/lib/codex-quota-fetch.d.ts +11 -0
  28. package/dist/lib/codex-quota-fetch.d.ts.map +1 -0
  29. package/dist/lib/codex-quota-fetch.js +149 -0
  30. package/dist/lib/codex-quota-fetch.js.map +1 -0
  31. package/dist/lib/codex-status-storage.d.ts +5 -0
  32. package/dist/lib/codex-status-storage.d.ts.map +1 -0
  33. package/dist/lib/codex-status-storage.js +58 -0
  34. package/dist/lib/codex-status-storage.js.map +1 -0
  35. package/dist/lib/codex-status-tool.d.ts +6 -0
  36. package/dist/lib/codex-status-tool.d.ts.map +1 -0
  37. package/dist/lib/codex-status-tool.js +37 -0
  38. package/dist/lib/codex-status-tool.js.map +1 -0
  39. package/dist/lib/codex-status-ui.d.ts +7 -0
  40. package/dist/lib/codex-status-ui.d.ts.map +1 -0
  41. package/dist/lib/codex-status-ui.js +109 -0
  42. package/dist/lib/codex-status-ui.js.map +1 -0
  43. package/dist/lib/codex-status.d.ts +14 -0
  44. package/dist/lib/codex-status.d.ts.map +1 -0
  45. package/dist/lib/codex-status.js +31 -0
  46. package/dist/lib/codex-status.js.map +1 -0
  47. package/dist/lib/compat-sanitizer.d.ts +7 -0
  48. package/dist/lib/compat-sanitizer.d.ts.map +1 -0
  49. package/dist/lib/compat-sanitizer.js +101 -0
  50. package/dist/lib/compat-sanitizer.js.map +1 -0
  51. package/dist/lib/config.d.ts +94 -0
  52. package/dist/lib/config.d.ts.map +1 -0
  53. package/dist/lib/config.js +495 -0
  54. package/dist/lib/config.js.map +1 -0
  55. package/dist/lib/constants.d.ts +2 -0
  56. package/dist/lib/constants.d.ts.map +1 -0
  57. package/dist/lib/constants.js +2 -0
  58. package/dist/lib/constants.js.map +1 -0
  59. package/dist/lib/fatal-errors.d.ts +17 -0
  60. package/dist/lib/fatal-errors.d.ts.map +1 -0
  61. package/dist/lib/fatal-errors.js +42 -0
  62. package/dist/lib/fatal-errors.js.map +1 -0
  63. package/dist/lib/fetch-orchestrator.d.ts +56 -0
  64. package/dist/lib/fetch-orchestrator.d.ts.map +1 -0
  65. package/dist/lib/fetch-orchestrator.js +240 -0
  66. package/dist/lib/fetch-orchestrator.js.map +1 -0
  67. package/dist/lib/identity.d.ts +10 -0
  68. package/dist/lib/identity.d.ts.map +1 -0
  69. package/dist/lib/identity.js +31 -0
  70. package/dist/lib/identity.js.map +1 -0
  71. package/dist/lib/installer-cli.d.ts +7 -0
  72. package/dist/lib/installer-cli.d.ts.map +1 -0
  73. package/dist/lib/installer-cli.js +115 -0
  74. package/dist/lib/installer-cli.js.map +1 -0
  75. package/dist/lib/logger.d.ts +11 -0
  76. package/dist/lib/logger.d.ts.map +1 -0
  77. package/dist/lib/logger.js +25 -0
  78. package/dist/lib/logger.js.map +1 -0
  79. package/dist/lib/model-catalog.d.ts +66 -0
  80. package/dist/lib/model-catalog.d.ts.map +1 -0
  81. package/dist/lib/model-catalog.js +532 -0
  82. package/dist/lib/model-catalog.js.map +1 -0
  83. package/dist/lib/oauth-pages.d.ts +2 -0
  84. package/dist/lib/oauth-pages.d.ts.map +1 -0
  85. package/dist/lib/oauth-pages.js +199 -0
  86. package/dist/lib/oauth-pages.js.map +1 -0
  87. package/dist/lib/opencode-install.d.ts +15 -0
  88. package/dist/lib/opencode-install.d.ts.map +1 -0
  89. package/dist/lib/opencode-install.js +53 -0
  90. package/dist/lib/opencode-install.js.map +1 -0
  91. package/dist/lib/orchestrator-agents.d.ts +29 -0
  92. package/dist/lib/orchestrator-agents.d.ts.map +1 -0
  93. package/dist/lib/orchestrator-agents.js +212 -0
  94. package/dist/lib/orchestrator-agents.js.map +1 -0
  95. package/dist/lib/paths.d.ts +7 -0
  96. package/dist/lib/paths.d.ts.map +1 -0
  97. package/dist/lib/paths.js +18 -0
  98. package/dist/lib/paths.js.map +1 -0
  99. package/dist/lib/personalities.d.ts +5 -0
  100. package/dist/lib/personalities.d.ts.map +1 -0
  101. package/dist/lib/personalities.js +69 -0
  102. package/dist/lib/personalities.js.map +1 -0
  103. package/dist/lib/proactive-refresh.d.ts +11 -0
  104. package/dist/lib/proactive-refresh.d.ts.map +1 -0
  105. package/dist/lib/proactive-refresh.js +110 -0
  106. package/dist/lib/proactive-refresh.js.map +1 -0
  107. package/dist/lib/quarantine.d.ts +9 -0
  108. package/dist/lib/quarantine.d.ts.map +1 -0
  109. package/dist/lib/quarantine.js +39 -0
  110. package/dist/lib/quarantine.js.map +1 -0
  111. package/dist/lib/rate-limit.d.ts +9 -0
  112. package/dist/lib/rate-limit.d.ts.map +1 -0
  113. package/dist/lib/rate-limit.js +32 -0
  114. package/dist/lib/rate-limit.js.map +1 -0
  115. package/dist/lib/refresh-queue.d.ts +30 -0
  116. package/dist/lib/refresh-queue.d.ts.map +1 -0
  117. package/dist/lib/refresh-queue.js +67 -0
  118. package/dist/lib/refresh-queue.js.map +1 -0
  119. package/dist/lib/request-snapshots.d.ts +14 -0
  120. package/dist/lib/request-snapshots.d.ts.map +1 -0
  121. package/dist/lib/request-snapshots.js +148 -0
  122. package/dist/lib/request-snapshots.js.map +1 -0
  123. package/dist/lib/rotation.d.ts +29 -0
  124. package/dist/lib/rotation.d.ts.map +1 -0
  125. package/dist/lib/rotation.js +252 -0
  126. package/dist/lib/rotation.js.map +1 -0
  127. package/dist/lib/storage.d.ts +27 -0
  128. package/dist/lib/storage.d.ts.map +1 -0
  129. package/dist/lib/storage.js +610 -0
  130. package/dist/lib/storage.js.map +1 -0
  131. package/dist/lib/toast.d.ts +2 -0
  132. package/dist/lib/toast.d.ts.map +1 -0
  133. package/dist/lib/toast.js +47 -0
  134. package/dist/lib/toast.js.map +1 -0
  135. package/dist/lib/tools-output.d.ts +6 -0
  136. package/dist/lib/tools-output.d.ts.map +1 -0
  137. package/dist/lib/tools-output.js +6 -0
  138. package/dist/lib/tools-output.js.map +1 -0
  139. package/dist/lib/types.d.ts +62 -0
  140. package/dist/lib/types.d.ts.map +1 -0
  141. package/dist/lib/types.js +2 -0
  142. package/dist/lib/types.js.map +1 -0
  143. package/dist/lib/ui/auth-menu-runner.d.ts +19 -0
  144. package/dist/lib/ui/auth-menu-runner.d.ts.map +1 -0
  145. package/dist/lib/ui/auth-menu-runner.js +79 -0
  146. package/dist/lib/ui/auth-menu-runner.js.map +1 -0
  147. package/dist/lib/ui/auth-menu.d.ts +80 -0
  148. package/dist/lib/ui/auth-menu.d.ts.map +1 -0
  149. package/dist/lib/ui/auth-menu.js +321 -0
  150. package/dist/lib/ui/auth-menu.js.map +1 -0
  151. package/dist/lib/ui/tty/ansi.d.ts +18 -0
  152. package/dist/lib/ui/tty/ansi.d.ts.map +1 -0
  153. package/dist/lib/ui/tty/ansi.js +37 -0
  154. package/dist/lib/ui/tty/ansi.js.map +1 -0
  155. package/dist/lib/ui/tty/confirm.d.ts +7 -0
  156. package/dist/lib/ui/tty/confirm.d.ts.map +1 -0
  157. package/dist/lib/ui/tty/confirm.js +20 -0
  158. package/dist/lib/ui/tty/confirm.js.map +1 -0
  159. package/dist/lib/ui/tty/select.d.ts +17 -0
  160. package/dist/lib/ui/tty/select.d.ts.map +1 -0
  161. package/dist/lib/ui/tty/select.js +223 -0
  162. package/dist/lib/ui/tty/select.js.map +1 -0
  163. package/package.json +68 -0
  164. package/schemas/codex-config.schema.json +146 -0
  165. package/schemas/opencode.schema.json +23 -0
@@ -0,0 +1,47 @@
1
+ const MAX_TOAST_MESSAGE_LENGTH = 160;
2
+ const MAX_TOKEN_LENGTH = 48;
3
+ const MAX_PATH_LENGTH = 48;
4
+ function truncateMiddle(value, maxLength) {
5
+ if (maxLength <= 0)
6
+ return "";
7
+ if (value.length <= maxLength)
8
+ return value;
9
+ if (maxLength === 1)
10
+ return "…";
11
+ const head = Math.max(1, Math.floor(maxLength * 0.4));
12
+ const tail = Math.max(0, maxLength - head - 1);
13
+ if (tail === 0)
14
+ return `${value.slice(0, head)}…`;
15
+ return `${value.slice(0, head)}…${value.slice(-tail)}`;
16
+ }
17
+ function truncatePath(input, maxLength) {
18
+ if (input.length <= maxLength)
19
+ return input;
20
+ const parts = input.split(/[\\/]/);
21
+ const last = parts[parts.length - 1] ?? input;
22
+ if (last.length + 2 >= maxLength) {
23
+ return truncateMiddle(last, maxLength);
24
+ }
25
+ const headLen = Math.max(1, maxLength - last.length - 1);
26
+ return `${input.slice(0, headLen)}…${last}`;
27
+ }
28
+ function normalizeWhitespace(message) {
29
+ return message.replace(/\s+/g, " ").trim();
30
+ }
31
+ function truncateToken(token) {
32
+ if (token.length <= MAX_TOKEN_LENGTH)
33
+ return token;
34
+ if (token.includes("/") || token.includes("\\")) {
35
+ return truncatePath(token, MAX_PATH_LENGTH);
36
+ }
37
+ return truncateMiddle(token, MAX_TOKEN_LENGTH);
38
+ }
39
+ export function formatToastMessage(message) {
40
+ const normalized = normalizeWhitespace(message);
41
+ const tokens = normalized.split(" ");
42
+ const formatted = tokens.map((token) => truncateToken(token)).join(" ");
43
+ if (formatted.length <= MAX_TOAST_MESSAGE_LENGTH)
44
+ return formatted;
45
+ return truncateMiddle(formatted, MAX_TOAST_MESSAGE_LENGTH);
46
+ }
47
+ //# sourceMappingURL=toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../lib/toast.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,GAAG,CAAA;AACpC,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAC3B,MAAM,eAAe,GAAG,EAAE,CAAA;AAE1B,SAAS,cAAc,CAAC,KAAa,EAAE,SAAiB;IACtD,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IAC7B,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,GAAG,CAAA;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAA;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,CAAA;IAC9C,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAA;IACjD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAA;AACxD,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,SAAiB;IACpD,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,KAAK,CAAA;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAA;IAC7C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACxC,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACxD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,CAAA;AAC7C,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,KAAK,CAAC,MAAM,IAAI,gBAAgB;QAAE,OAAO,KAAK,CAAA;IAClD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,OAAO,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,cAAc,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACvE,IAAI,SAAS,CAAC,MAAM,IAAI,wBAAwB;QAAE,OAAO,SAAS,CAAA;IAClE,OAAO,cAAc,CAAC,SAAS,EAAE,wBAAwB,CAAC,CAAA;AAC5D,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function switchToolMessage(input: {
2
+ email?: string;
3
+ plan?: string;
4
+ index1: number;
5
+ }): string;
6
+ //# sourceMappingURL=tools-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools-output.d.ts","sourceRoot":"","sources":["../../lib/tools-output.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,UAIzF"}
@@ -0,0 +1,6 @@
1
+ export function switchToolMessage(input) {
2
+ const label = input.email ?? "account";
3
+ const plan = input.plan ? ` (${input.plan})` : "";
4
+ return `Switched to #${input.index1}: ${label}${plan}`;
5
+ }
6
+ //# sourceMappingURL=tools-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools-output.js","sourceRoot":"","sources":["../../lib/tools-output.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,KAAwD;IACxF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,SAAS,CAAA;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACjD,OAAO,gBAAgB,KAAK,CAAC,MAAM,KAAK,KAAK,GAAG,IAAI,EAAE,CAAA;AACxD,CAAC"}
@@ -0,0 +1,62 @@
1
+ export type RotationStrategy = "round_robin" | "sticky" | "hybrid";
2
+ export type AccountAuthType = "native" | "codex";
3
+ export type OpenAIAuthMode = "native" | "codex";
4
+ export type AccountRecord = {
5
+ identityKey?: string;
6
+ accountId?: string;
7
+ email?: string;
8
+ plan?: string;
9
+ authTypes?: AccountAuthType[];
10
+ enabled?: boolean;
11
+ access?: string;
12
+ refresh?: string;
13
+ expires?: number;
14
+ refreshLeaseUntil?: number;
15
+ cooldownUntil?: number;
16
+ lastUsed?: number;
17
+ };
18
+ export type OpenAIOAuthDomain = {
19
+ strategy?: RotationStrategy;
20
+ accounts: AccountRecord[];
21
+ activeIdentityKey?: string;
22
+ };
23
+ export type OpenAIMultiOauthAuth = {
24
+ type: "oauth";
25
+ /**
26
+ * Compatibility aggregate view across auth domains.
27
+ * Canonical storage lives in `native`/`codex`.
28
+ */
29
+ strategy?: RotationStrategy;
30
+ accounts: AccountRecord[];
31
+ activeIdentityKey?: string;
32
+ native?: OpenAIOAuthDomain;
33
+ codex?: OpenAIOAuthDomain;
34
+ };
35
+ export type AuthFile = {
36
+ openai?: OpenAIMultiOauthAuth | {
37
+ type: "oauth";
38
+ refresh: string;
39
+ access: string;
40
+ expires: number;
41
+ accountId?: string;
42
+ email?: string;
43
+ plan?: string;
44
+ };
45
+ };
46
+ export type CodexLimit = {
47
+ name: string;
48
+ leftPct: number;
49
+ resetsAt?: number;
50
+ extra?: string;
51
+ };
52
+ export type CodexRateLimitSnapshot = {
53
+ updatedAt: number;
54
+ modelFamily: string;
55
+ limits: CodexLimit[];
56
+ credits?: {
57
+ hasCredits?: boolean;
58
+ unlimited?: boolean;
59
+ balance?: string;
60
+ };
61
+ };
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAClE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAA;AAChD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE/C,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,eAAe,EAAE,CAAA;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,OAAO,CAAA;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,CAAC,EACH,oBAAoB,GACpB;QACE,IAAI,EAAE,OAAO,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAA;CACN,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,OAAO,CAAA;QACpB,SAAS,CAAC,EAAE,OAAO,CAAA;QACnB,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;CACF,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { AccountInfo, DeleteScope } from "./auth-menu";
2
+ export type AuthMenuHandlers = {
3
+ onCheckQuotas: () => Promise<void>;
4
+ onConfigureModels: () => Promise<void>;
5
+ onDeleteAll: (scope: DeleteScope) => Promise<void>;
6
+ onTransfer: () => Promise<void>;
7
+ onToggleAccount: (account: AccountInfo) => Promise<void>;
8
+ onRefreshAccount: (account: AccountInfo) => Promise<void>;
9
+ onDeleteAccount: (account: AccountInfo, scope: DeleteScope) => Promise<void>;
10
+ };
11
+ export type AuthMenuResult = "add" | "continue" | "exit";
12
+ export declare function runAuthMenuOnce(args: {
13
+ accounts: AccountInfo[];
14
+ handlers: AuthMenuHandlers;
15
+ allowTransfer?: boolean;
16
+ input?: NodeJS.ReadStream;
17
+ output?: NodeJS.WriteStream;
18
+ }): Promise<AuthMenuResult>;
19
+ //# sourceMappingURL=auth-menu-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-menu-runner.d.ts","sourceRoot":"","sources":["../../../lib/ui/auth-menu-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAG5E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,gBAAgB,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7E,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAA;AAoBxD,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAA;CAC5B,GAAG,OAAO,CAAC,cAAc,CAAC,CA6D1B"}
@@ -0,0 +1,79 @@
1
+ import { showAccountDetails, showAuthMenu, selectAccount } from "./auth-menu";
2
+ function collectAuthTypes(accounts) {
3
+ const out = [];
4
+ const seen = new Set();
5
+ for (const account of accounts) {
6
+ const authTypes = account.authTypes && account.authTypes.length > 0 ? account.authTypes : ["native"];
7
+ for (const authType of authTypes) {
8
+ if (authType !== "native" && authType !== "codex")
9
+ continue;
10
+ if (seen.has(authType))
11
+ continue;
12
+ seen.add(authType);
13
+ out.push(authType);
14
+ }
15
+ }
16
+ if (out.length === 0)
17
+ out.push("native");
18
+ return out;
19
+ }
20
+ export async function runAuthMenuOnce(args) {
21
+ const action = await showAuthMenu(args.accounts, {
22
+ input: args.input,
23
+ output: args.output,
24
+ allowTransfer: args.allowTransfer
25
+ });
26
+ if (action.type === "cancel")
27
+ return "exit";
28
+ if (action.type === "add")
29
+ return "add";
30
+ if (action.type === "check") {
31
+ await args.handlers.onCheckQuotas();
32
+ return "continue";
33
+ }
34
+ if (action.type === "configure-models") {
35
+ await args.handlers.onConfigureModels();
36
+ return "continue";
37
+ }
38
+ if (action.type === "transfer") {
39
+ await args.handlers.onTransfer();
40
+ return "continue";
41
+ }
42
+ if (action.type === "delete-all") {
43
+ await args.handlers.onDeleteAll(action.scope);
44
+ return "continue";
45
+ }
46
+ const account = action.type === "select-account"
47
+ ? action.account
48
+ : await selectAccount(args.accounts, {
49
+ input: args.input,
50
+ output: args.output
51
+ });
52
+ if (!account)
53
+ return "continue";
54
+ const accountAction = await showAccountDetails(account, {
55
+ input: args.input,
56
+ output: args.output,
57
+ availableAuthTypes: collectAuthTypes(args.accounts)
58
+ });
59
+ if (accountAction.type === "toggle") {
60
+ await args.handlers.onToggleAccount(account);
61
+ return "continue";
62
+ }
63
+ if (accountAction.type === "refresh") {
64
+ if (account.enabled !== false) {
65
+ await args.handlers.onRefreshAccount(account);
66
+ }
67
+ return "continue";
68
+ }
69
+ if (accountAction.type === "delete") {
70
+ await args.handlers.onDeleteAccount(account, accountAction.scope);
71
+ return "continue";
72
+ }
73
+ if (accountAction.type === "delete-all") {
74
+ await args.handlers.onDeleteAll(accountAction.scope);
75
+ return "continue";
76
+ }
77
+ return "continue";
78
+ }
79
+ //# sourceMappingURL=auth-menu-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-menu-runner.js","sourceRoot":"","sources":["../../../lib/ui/auth-menu-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { type MenuItem } from "./tty/select";
2
+ export type AccountStatus = "active" | "rate-limited" | "expired" | "unknown";
3
+ export type AccountAuthType = "native" | "codex";
4
+ export type DeleteScope = AccountAuthType | "both";
5
+ export interface AccountInfo {
6
+ identityKey?: string;
7
+ email?: string;
8
+ plan?: string;
9
+ accountId?: string;
10
+ authTypes?: AccountAuthType[];
11
+ index: number;
12
+ addedAt?: number;
13
+ lastUsed?: number;
14
+ status?: AccountStatus;
15
+ isCurrentAccount?: boolean;
16
+ enabled?: boolean;
17
+ }
18
+ export type AuthMenuAction = {
19
+ type: "add";
20
+ } | {
21
+ type: "select-account";
22
+ account: AccountInfo;
23
+ } | {
24
+ type: "delete-all";
25
+ scope: DeleteScope;
26
+ } | {
27
+ type: "check";
28
+ } | {
29
+ type: "manage";
30
+ } | {
31
+ type: "configure-models";
32
+ } | {
33
+ type: "transfer";
34
+ } | {
35
+ type: "cancel";
36
+ };
37
+ export type AccountAction = {
38
+ type: "back";
39
+ } | {
40
+ type: "delete";
41
+ scope: DeleteScope;
42
+ } | {
43
+ type: "delete-all";
44
+ scope: DeleteScope;
45
+ } | {
46
+ type: "refresh";
47
+ } | {
48
+ type: "toggle";
49
+ } | {
50
+ type: "cancel";
51
+ };
52
+ export declare function formatAccountAuthTypes(input: readonly AccountAuthType[] | undefined): string;
53
+ export declare function formatRelativeTime(timestamp: number | undefined, now?: number): string;
54
+ export declare function formatStatusBadges(account: Pick<AccountInfo, "enabled" | "status" | "isCurrentAccount">, useColor?: boolean): string;
55
+ export declare function buildAuthMenuItems(accounts: AccountInfo[], options?: {
56
+ useColor?: boolean;
57
+ allowTransfer?: boolean;
58
+ }): MenuItem<AuthMenuAction>[];
59
+ export declare function buildAccountActionItems(account: AccountInfo, options?: {
60
+ availableAuthTypes?: AccountAuthType[];
61
+ }): MenuItem<AccountAction>[];
62
+ export declare function buildAccountSelectItems(accounts: AccountInfo[], useColor?: boolean): MenuItem<AccountInfo>[];
63
+ export declare function selectAccount(accounts: AccountInfo[], options?: {
64
+ input?: NodeJS.ReadStream;
65
+ output?: NodeJS.WriteStream;
66
+ useColor?: boolean;
67
+ }): Promise<AccountInfo | null>;
68
+ export declare function showAuthMenu(accounts: AccountInfo[], options?: {
69
+ input?: NodeJS.ReadStream;
70
+ output?: NodeJS.WriteStream;
71
+ useColor?: boolean;
72
+ allowTransfer?: boolean;
73
+ }): Promise<AuthMenuAction>;
74
+ export declare function showAccountDetails(account: AccountInfo, options?: {
75
+ input?: NodeJS.ReadStream;
76
+ output?: NodeJS.WriteStream;
77
+ useColor?: boolean;
78
+ availableAuthTypes?: AccountAuthType[];
79
+ }): Promise<AccountAction>;
80
+ //# sourceMappingURL=auth-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-menu.d.ts","sourceRoot":"","sources":["../../../lib/ui/auth-menu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,321 @@
1
+ import { ANSI, shouldUseColor } from "./tty/ansi";
2
+ import { confirm } from "./tty/confirm";
3
+ import { select } from "./tty/select";
4
+ const AUTH_TYPE_ORDER = ["native", "codex"];
5
+ function normalizeAccountAuthTypes(input) {
6
+ const seen = new Set();
7
+ const out = [];
8
+ for (const type of input ?? ["native"]) {
9
+ if (type !== "native" && type !== "codex")
10
+ continue;
11
+ if (seen.has(type))
12
+ continue;
13
+ seen.add(type);
14
+ out.push(type);
15
+ }
16
+ if (out.length === 0)
17
+ return ["native"];
18
+ out.sort((a, b) => AUTH_TYPE_ORDER.indexOf(a) - AUTH_TYPE_ORDER.indexOf(b));
19
+ return out;
20
+ }
21
+ function displayAuthType(type) {
22
+ return type === "codex" ? "Codex" : "Native";
23
+ }
24
+ export function formatAccountAuthTypes(input) {
25
+ return normalizeAccountAuthTypes(input).map(displayAuthType).join("+");
26
+ }
27
+ function getDeleteScopes(input) {
28
+ const authTypes = normalizeAccountAuthTypes(input);
29
+ if (authTypes.length === 1)
30
+ return [authTypes[0]];
31
+ return ["native", "codex", "both"];
32
+ }
33
+ function scopeLabel(scope) {
34
+ if (scope === "native")
35
+ return "Native";
36
+ if (scope === "codex")
37
+ return "Codex";
38
+ return "all auth types";
39
+ }
40
+ function authTypesFromAccounts(accounts) {
41
+ const seen = new Set();
42
+ for (const account of accounts) {
43
+ for (const type of normalizeAccountAuthTypes(account.authTypes)) {
44
+ seen.add(type);
45
+ }
46
+ }
47
+ const out = Array.from(seen);
48
+ out.sort((a, b) => AUTH_TYPE_ORDER.indexOf(a) - AUTH_TYPE_ORDER.indexOf(b));
49
+ return out.length > 0 ? out : ["native"];
50
+ }
51
+ export function formatRelativeTime(timestamp, now = Date.now()) {
52
+ if (!timestamp)
53
+ return "never";
54
+ const days = Math.floor((now - timestamp) / 86_400_000);
55
+ if (days <= 0)
56
+ return "today";
57
+ if (days === 1)
58
+ return "yesterday";
59
+ if (days < 7)
60
+ return `${days}d ago`;
61
+ if (days < 30)
62
+ return `${Math.floor(days / 7)}w ago`;
63
+ return new Date(timestamp).toLocaleDateString();
64
+ }
65
+ function formatDate(timestamp) {
66
+ if (!timestamp)
67
+ return "unknown";
68
+ return new Date(timestamp).toLocaleDateString();
69
+ }
70
+ function colorize(text, color, useColor) {
71
+ return useColor ? `${color}${text}${ANSI.reset}` : text;
72
+ }
73
+ function formatAccountDisplayName(account) {
74
+ const base = account.email || `Account ${account.index + 1}`;
75
+ const plan = typeof account.plan === "string" ? account.plan.trim() : "";
76
+ return plan ? `${base} (${plan})` : base;
77
+ }
78
+ function getStatusBadge(status, useColor) {
79
+ switch (status) {
80
+ case "rate-limited":
81
+ return colorize("[rate-limited]", ANSI.yellow, useColor);
82
+ case "expired":
83
+ return colorize("[expired]", ANSI.red, useColor);
84
+ default:
85
+ return "";
86
+ }
87
+ }
88
+ export function formatStatusBadges(account, useColor = shouldUseColor()) {
89
+ const badges = [];
90
+ if (account.enabled === false) {
91
+ badges.push(colorize("[disabled]", ANSI.red, useColor));
92
+ }
93
+ else {
94
+ badges.push(colorize("[enabled]", ANSI.green, useColor));
95
+ }
96
+ const statusBadge = getStatusBadge(account.status, useColor);
97
+ if (statusBadge)
98
+ badges.push(statusBadge);
99
+ if (account.isCurrentAccount) {
100
+ badges.push(colorize("[last active]", ANSI.cyan, useColor));
101
+ }
102
+ return badges.join(" ");
103
+ }
104
+ function buildAccountLabel(account, useColor) {
105
+ const baseLabel = formatAccountDisplayName(account);
106
+ const accountAuthTypes = colorize(`[${formatAccountAuthTypes(account.authTypes)}]`, ANSI.cyan, useColor);
107
+ const badges = formatStatusBadges(account, useColor);
108
+ return badges ? `${baseLabel} ${accountAuthTypes} ${badges}` : `${baseLabel} ${accountAuthTypes}`;
109
+ }
110
+ export function buildAuthMenuItems(accounts, options = {}) {
111
+ const useColor = options.useColor ?? shouldUseColor();
112
+ const items = [
113
+ { label: "Add new account", value: { type: "add" } },
114
+ { label: "Check quotas", value: { type: "check" } },
115
+ { label: "Manage accounts (enable/disable)", value: { type: "manage" } },
116
+ { label: "Configure models in codex-config.json", value: { type: "configure-models" } },
117
+ ...(options.allowTransfer
118
+ ? [
119
+ {
120
+ label: "Transfer OpenAI accounts from native & old plugins?",
121
+ value: { type: "transfer" }
122
+ }
123
+ ]
124
+ : []),
125
+ ...accounts.map((account) => {
126
+ const label = buildAccountLabel(account, useColor);
127
+ return {
128
+ label,
129
+ hint: account.lastUsed ? `used ${formatRelativeTime(account.lastUsed)}` : "",
130
+ value: { type: "select-account", account }
131
+ };
132
+ })
133
+ ];
134
+ if (accounts.length > 0) {
135
+ items.push({
136
+ label: "Delete all accounts",
137
+ value: { type: "delete-all", scope: "both" },
138
+ color: "red"
139
+ });
140
+ }
141
+ return items;
142
+ }
143
+ export function buildAccountActionItems(account, options = {}) {
144
+ const accountScopes = getDeleteScopes(account.authTypes);
145
+ const globalScopes = getDeleteScopes(options.availableAuthTypes ?? account.authTypes);
146
+ const accountDeleteItems = [];
147
+ if (accountScopes.length === 1) {
148
+ accountDeleteItems.push({
149
+ label: `Delete this account (${scopeLabel(accountScopes[0])})`,
150
+ value: { type: "delete", scope: accountScopes[0] },
151
+ color: "red"
152
+ });
153
+ }
154
+ else {
155
+ accountDeleteItems.push({
156
+ label: "Delete Native auth from this account",
157
+ value: { type: "delete", scope: "native" },
158
+ color: "red"
159
+ }, {
160
+ label: "Delete Codex auth from this account",
161
+ value: { type: "delete", scope: "codex" },
162
+ color: "red"
163
+ }, {
164
+ label: "Delete this account (all auth types)",
165
+ value: { type: "delete", scope: "both" },
166
+ color: "red"
167
+ });
168
+ }
169
+ const globalDeleteItems = [];
170
+ if (globalScopes.length === 1) {
171
+ globalDeleteItems.push({
172
+ label: `Delete all accounts (${scopeLabel(globalScopes[0])})`,
173
+ value: { type: "delete-all", scope: globalScopes[0] },
174
+ color: "red"
175
+ });
176
+ }
177
+ else {
178
+ globalDeleteItems.push({
179
+ label: "Delete all Native accounts",
180
+ value: { type: "delete-all", scope: "native" },
181
+ color: "red"
182
+ }, {
183
+ label: "Delete all Codex accounts",
184
+ value: { type: "delete-all", scope: "codex" },
185
+ color: "red"
186
+ }, {
187
+ label: "Delete all accounts (all auth types)",
188
+ value: { type: "delete-all", scope: "both" },
189
+ color: "red"
190
+ });
191
+ }
192
+ return [
193
+ { label: "Back", value: { type: "back" } },
194
+ {
195
+ label: account.enabled === false ? "Enable account" : "Disable account",
196
+ value: { type: "toggle" },
197
+ color: account.enabled === false ? "green" : "yellow"
198
+ },
199
+ {
200
+ label: "Refresh token",
201
+ value: { type: "refresh" },
202
+ color: "cyan",
203
+ disabled: account.enabled === false
204
+ },
205
+ ...accountDeleteItems,
206
+ ...globalDeleteItems
207
+ ];
208
+ }
209
+ export function buildAccountSelectItems(accounts, useColor = shouldUseColor()) {
210
+ return accounts.map((account) => ({
211
+ label: buildAccountLabel(account, useColor),
212
+ hint: account.lastUsed ? `used ${formatRelativeTime(account.lastUsed)}` : "",
213
+ value: account
214
+ }));
215
+ }
216
+ export async function selectAccount(accounts, options = {}) {
217
+ const useColor = options.useColor ?? shouldUseColor();
218
+ const items = buildAccountSelectItems(accounts, useColor);
219
+ const result = await select(items, {
220
+ message: "Manage accounts",
221
+ subtitle: "Select account",
222
+ input: options.input,
223
+ output: options.output,
224
+ useColor
225
+ });
226
+ return result ?? null;
227
+ }
228
+ export async function showAuthMenu(accounts, options = {}) {
229
+ const useColor = options.useColor ?? shouldUseColor();
230
+ const items = buildAuthMenuItems(accounts, {
231
+ useColor,
232
+ allowTransfer: options.allowTransfer === true
233
+ });
234
+ while (true) {
235
+ const result = await select(items, {
236
+ message: "Manage accounts",
237
+ subtitle: "Select account",
238
+ input: options.input,
239
+ output: options.output,
240
+ useColor
241
+ });
242
+ if (!result)
243
+ return { type: "cancel" };
244
+ if (result.type === "delete-all") {
245
+ const menuAuthTypes = authTypesFromAccounts(accounts);
246
+ let scope;
247
+ const scopes = getDeleteScopes(menuAuthTypes);
248
+ if (scopes.length === 1) {
249
+ scope = scopes[0];
250
+ }
251
+ else {
252
+ const scopeSelection = await select([
253
+ { label: "Delete all Native accounts", value: "native", color: "red" },
254
+ { label: "Delete all Codex accounts", value: "codex", color: "red" },
255
+ { label: "Delete all accounts (all auth types)", value: "both", color: "red" }
256
+ ], {
257
+ message: "Delete accounts",
258
+ subtitle: "Choose scope",
259
+ input: options.input,
260
+ output: options.output,
261
+ useColor
262
+ });
263
+ if (!scopeSelection)
264
+ continue;
265
+ scope = scopeSelection;
266
+ }
267
+ const confirmed = await confirm(`Delete ALL ${scopeLabel(scope)} accounts? This cannot be undone.`, false, options);
268
+ if (!confirmed)
269
+ continue;
270
+ return { type: "delete-all", scope };
271
+ }
272
+ return result;
273
+ }
274
+ }
275
+ export async function showAccountDetails(account, options = {}) {
276
+ const useColor = options.useColor ?? shouldUseColor();
277
+ const output = options.output ?? process.stdout;
278
+ const label = formatAccountDisplayName(account);
279
+ const badges = formatStatusBadges(account, useColor);
280
+ const bold = useColor ? ANSI.bold : "";
281
+ const dim = useColor ? ANSI.dim : "";
282
+ const reset = useColor ? ANSI.reset : "";
283
+ output.write("\n");
284
+ output.write(`${bold}Account: ${label}${badges ? ` ${badges}` : ""}${reset}\n`);
285
+ output.write(`${dim}Added: ${formatDate(account.addedAt)}${reset}\n`);
286
+ output.write(`${dim}Last used: ${formatRelativeTime(account.lastUsed)}${reset}\n`);
287
+ output.write("\n");
288
+ while (true) {
289
+ const actionItems = buildAccountActionItems(account, {
290
+ availableAuthTypes: options.availableAuthTypes
291
+ });
292
+ const selected = await select(actionItems, {
293
+ message: "Account options",
294
+ subtitle: "Select action",
295
+ input: options.input,
296
+ output: options.output,
297
+ useColor
298
+ });
299
+ if (!selected)
300
+ return { type: "cancel" };
301
+ if (selected.type === "delete") {
302
+ const confirmed = await confirm(selected.scope === "both"
303
+ ? `Delete ${label}?`
304
+ : `Delete ${scopeLabel(selected.scope)} auth from ${label}?`, false, options);
305
+ if (!confirmed)
306
+ continue;
307
+ }
308
+ if (selected.type === "delete-all") {
309
+ const confirmed = await confirm(`Delete ALL ${scopeLabel(selected.scope)} accounts? This cannot be undone.`, false, options);
310
+ if (!confirmed)
311
+ continue;
312
+ }
313
+ if (selected.type === "refresh") {
314
+ const confirmed = await confirm(`Re-authenticate ${label}?`, false, options);
315
+ if (!confirmed)
316
+ continue;
317
+ }
318
+ return selected;
319
+ }
320
+ }
321
+ //# sourceMappingURL=auth-menu.js.map