@victor-software-house/pi-multicodex 2.0.11 → 2.0.13

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.
@@ -52,12 +52,16 @@ export class AccountManager {
52
52
  * (rename, compaction) can resolve a valid API key via AuthStorage.
53
53
  */
54
54
  private syncActiveTokenToAuthJson(account: Account): void {
55
- writeActiveTokenToAuthJson({
56
- access: account.accessToken,
57
- refresh: account.refreshToken,
58
- expires: account.expiresAt,
59
- accountId: account.accountId,
60
- }).catch(() => {});
55
+ try {
56
+ writeActiveTokenToAuthJson({
57
+ access: account.accessToken,
58
+ refresh: account.refreshToken,
59
+ expires: account.expiresAt,
60
+ accountId: account.accountId,
61
+ });
62
+ } catch {
63
+ // Best-effort sync — do not block token resolution.
64
+ }
61
65
  }
62
66
 
63
67
  onStateChange(handler: StateChangeHandler): () => void {
package/auth.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { promises as fs } from "node:fs";
1
+ import {
2
+ existsSync,
3
+ promises as fs,
4
+ readFileSync,
5
+ writeFileSync,
6
+ } from "node:fs";
2
7
  import type { OAuthCredentials } from "@mariozechner/pi-ai/oauth";
3
8
  import { getAgentAuthPath } from "pi-provider-utils/agent-paths";
4
9
 
@@ -90,18 +95,26 @@ export function parseImportedOpenAICodexAuth(
90
95
  * (rename, compaction, inline suggestions) can resolve a valid API key through
91
96
  * the normal AuthStorage path.
92
97
  */
93
- export async function writeActiveTokenToAuthJson(creds: {
98
+ /**
99
+ * Synchronously write the active account's tokens to auth.json so pi's
100
+ * background features (rename, compaction) can resolve a valid API key.
101
+ *
102
+ * Uses synchronous I/O to avoid interleaved writes with pi's own code.
103
+ */
104
+ export function writeActiveTokenToAuthJson(creds: {
94
105
  access: string;
95
106
  refresh: string;
96
107
  expires: number;
97
108
  accountId?: string;
98
- }): Promise<void> {
109
+ }): void {
99
110
  let auth: Record<string, unknown> = {};
100
111
  try {
101
- const raw = await fs.readFile(AUTH_FILE, "utf8");
102
- const parsed = JSON.parse(raw) as unknown;
103
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
104
- auth = parsed as Record<string, unknown>;
112
+ if (existsSync(AUTH_FILE)) {
113
+ const raw = readFileSync(AUTH_FILE, "utf8");
114
+ const parsed = JSON.parse(raw) as unknown;
115
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
116
+ auth = parsed as Record<string, unknown>;
117
+ }
105
118
  }
106
119
  } catch {
107
120
  // File missing or corrupt — start fresh.
@@ -115,7 +128,7 @@ export async function writeActiveTokenToAuthJson(creds: {
115
128
  accountId: creds.accountId,
116
129
  };
117
130
 
118
- await fs.writeFile(AUTH_FILE, JSON.stringify(auth, null, 2));
131
+ writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2));
119
132
  }
120
133
 
121
134
  export async function loadImportedOpenAICodexAuth(): Promise<
@@ -128,11 +141,8 @@ export async function loadImportedOpenAICodexAuth(): Promise<
128
141
  return undefined;
129
142
  }
130
143
  return parseImportedOpenAICodexAuth(parsed as Record<string, unknown>);
131
- } catch (error) {
132
- const withCode = error as Error & { code?: string };
133
- if (withCode.code === "ENOENT") {
134
- return undefined;
135
- }
136
- throw error;
144
+ } catch {
145
+ // File missing, corrupt, or unreadable treat as no imported auth.
146
+ return undefined;
137
147
  }
138
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victor-software-house/pi-multicodex",
3
- "version": "2.0.11",
3
+ "version": "2.0.13",
4
4
  "description": "Codex account rotation extension for pi",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/provider.ts CHANGED
@@ -42,6 +42,22 @@ export function getOpenAICodexMirror(): {
42
42
  };
43
43
  }
44
44
 
45
+ function getActiveApiKey(accountManager: AccountManager): string {
46
+ const active = accountManager.getActiveAccount();
47
+ if (active && !active.needsReauth) {
48
+ return active.accessToken;
49
+ }
50
+ // Fallback: first available account with a valid token.
51
+ for (const account of accountManager.getAccounts()) {
52
+ if (!account.needsReauth && account.accessToken) {
53
+ return account.accessToken;
54
+ }
55
+ }
56
+ // Placeholder — AuthStorage will override on every actual API call
57
+ // as long as auth.json has valid tokens.
58
+ return "pending-login";
59
+ }
60
+
45
61
  export function buildMulticodexProviderConfig(accountManager: AccountManager) {
46
62
  const mirror = getOpenAICodexMirror();
47
63
  const baseProvider = getApiProvider("openai-codex-responses");
@@ -53,7 +69,7 @@ export function buildMulticodexProviderConfig(accountManager: AccountManager) {
53
69
 
54
70
  return {
55
71
  baseUrl: mirror.baseUrl,
56
- apiKey: "managed-by-extension",
72
+ apiKey: getActiveApiKey(accountManager),
57
73
  api: "openai-codex-responses" as const,
58
74
  streamSimple: createStreamWrapper(accountManager, baseProvider),
59
75
  models: mirror.models,