mastracode 0.18.0-alpha.3 → 0.18.0-alpha.5
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/CHANGELOG.md +20 -0
- package/dist/auth/providers/openai-codex.d.ts +23 -0
- package/dist/auth/providers/openai-codex.d.ts.map +1 -1
- package/dist/{chunk-A3S5I2HC.cjs → chunk-24SDVHO7.cjs} +82 -32
- package/dist/chunk-24SDVHO7.cjs.map +1 -0
- package/dist/{chunk-7D6OWKI5.cjs → chunk-5IY6MTU5.cjs} +46 -46
- package/dist/{chunk-7D6OWKI5.cjs.map → chunk-5IY6MTU5.cjs.map} +1 -1
- package/dist/{chunk-DLPHNLNC.js → chunk-7JEIW7QK.js} +4 -4
- package/dist/{chunk-DLPHNLNC.js.map → chunk-7JEIW7QK.js.map} +1 -1
- package/dist/{chunk-SR76LO2I.js → chunk-GURLKQU4.js} +6 -6
- package/dist/{chunk-SR76LO2I.js.map → chunk-GURLKQU4.js.map} +1 -1
- package/dist/{chunk-RLAPZNQF.cjs → chunk-KNBZLIUE.cjs} +6 -6
- package/dist/{chunk-RLAPZNQF.cjs.map → chunk-KNBZLIUE.cjs.map} +1 -1
- package/dist/{chunk-E56ARDWV.js → chunk-RARRWPIY.js} +3 -3
- package/dist/{chunk-E56ARDWV.js.map → chunk-RARRWPIY.js.map} +1 -1
- package/dist/{chunk-ULADWCHF.cjs → chunk-TWS344XV.cjs} +833 -833
- package/dist/{chunk-ULADWCHF.cjs.map → chunk-TWS344XV.cjs.map} +1 -1
- package/dist/{chunk-BYQZSMN2.js → chunk-VCFYREVH.js} +82 -32
- package/dist/chunk-VCFYREVH.js.map +1 -0
- package/dist/cli.cjs +19 -19
- package/dist/cli.js +4 -4
- package/dist/index.cjs +3 -3
- package/dist/index.js +1 -1
- package/dist/storage-2FGKKCUL.cjs +24 -0
- package/dist/{storage-EKR4Y5CN.cjs.map → storage-2FGKKCUL.cjs.map} +1 -1
- package/dist/storage-DFHKANBS.js +3 -0
- package/dist/{storage-RE6JEE73.js.map → storage-DFHKANBS.js.map} +1 -1
- package/dist/tui.cjs +19 -19
- package/dist/tui.js +2 -2
- package/package.json +11 -11
- package/dist/chunk-A3S5I2HC.cjs.map +0 -1
- package/dist/chunk-BYQZSMN2.js.map +0 -1
- package/dist/storage-EKR4Y5CN.cjs +0 -24
- package/dist/storage-RE6JEE73.js +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# mastracode
|
|
2
2
|
|
|
3
|
+
## 0.18.0-alpha.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- dependencies updates: ([#16126](https://github.com/mastra-ai/mastra/pull/16126))
|
|
8
|
+
- Updated dependency [`@ai-sdk/anthropic@^3.0.74` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/3.0.74) (from `^3.0.71`, in `dependencies`)
|
|
9
|
+
- Updated dependency [`@ai-sdk/openai@^3.0.58` ↗︎](https://www.npmjs.com/package/@ai-sdk/openai/v/3.0.58) (from `^3.0.53`, in `dependencies`)
|
|
10
|
+
- Updated dependency [`ai@^6.0.174` ↗︎](https://www.npmjs.com/package/ai/v/6.0.174) (from `^6.0.168`, in `dependencies`)
|
|
11
|
+
- Updated dependencies [[`9f17410`](https://github.com/mastra-ai/mastra/commit/9f1741080def23d42ee50b39887a385ae316a3c6), [`c6eb39e`](https://github.com/mastra-ai/mastra/commit/c6eb39ea6dca381c6563cb240237fbe608e02f93), [`900d086`](https://github.com/mastra-ai/mastra/commit/900d086bb737b9cf2fcf68f11b0389b801a2738c), [`4c0e286`](https://github.com/mastra-ai/mastra/commit/4c0e28637c9cfb4f416549b55e97ebfa13319dfc), [`25184ff`](https://github.com/mastra-ai/mastra/commit/25184ffaf1293ec95119426eb1a1f8d38831b96c), [`25184ff`](https://github.com/mastra-ai/mastra/commit/25184ffaf1293ec95119426eb1a1f8d38831b96c), [`aebde9c`](https://github.com/mastra-ai/mastra/commit/aebde9cfacf56592c6b6350cae721740fe090b8a)]:
|
|
12
|
+
- @mastra/core@1.33.0-alpha.4
|
|
13
|
+
- @mastra/libsql@1.10.1-alpha.0
|
|
14
|
+
- @mastra/pg@1.10.1-alpha.0
|
|
15
|
+
|
|
16
|
+
## 0.18.0-alpha.4
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [[`087e413`](https://github.com/mastra-ai/mastra/commit/087e4133e5d6efa36619e9556c16750e4179c047), [`087e413`](https://github.com/mastra-ai/mastra/commit/087e4133e5d6efa36619e9556c16750e4179c047), [`087e413`](https://github.com/mastra-ai/mastra/commit/087e4133e5d6efa36619e9556c16750e4179c047)]:
|
|
21
|
+
- @mastra/core@1.33.0-alpha.3
|
|
22
|
+
|
|
3
23
|
## 0.18.0-alpha.3
|
|
4
24
|
|
|
5
25
|
### Minor Changes
|
|
@@ -8,6 +8,24 @@
|
|
|
8
8
|
* It is only intended for CLI use, not browser environments.
|
|
9
9
|
*/
|
|
10
10
|
import type { OAuthCredentials, OAuthPrompt, OAuthProviderInterface } from '../types.js';
|
|
11
|
+
declare function createAuthorizationFlow(redirectUri: string, state: string, originator?: string): Promise<{
|
|
12
|
+
verifier: string;
|
|
13
|
+
url: string;
|
|
14
|
+
}>;
|
|
15
|
+
type OAuthServerInfo = {
|
|
16
|
+
redirectUri: string;
|
|
17
|
+
warning?: string;
|
|
18
|
+
close: () => void;
|
|
19
|
+
cancelWait: () => void;
|
|
20
|
+
waitForCode: () => Promise<{
|
|
21
|
+
code: string;
|
|
22
|
+
} | null>;
|
|
23
|
+
};
|
|
24
|
+
type CallbackPorts = {
|
|
25
|
+
defaultPort: number;
|
|
26
|
+
fallbackPort: number;
|
|
27
|
+
};
|
|
28
|
+
declare function startLocalOAuthServer(state: string, ports?: CallbackPorts): Promise<OAuthServerInfo>;
|
|
11
29
|
/**
|
|
12
30
|
* Login with OpenAI Codex OAuth
|
|
13
31
|
*
|
|
@@ -29,9 +47,14 @@ export declare function loginOpenAICodex(options: {
|
|
|
29
47
|
onManualCodeInput?: () => Promise<string>;
|
|
30
48
|
originator?: string;
|
|
31
49
|
}): Promise<OAuthCredentials>;
|
|
50
|
+
export declare const __testing: {
|
|
51
|
+
createAuthorizationFlow: typeof createAuthorizationFlow;
|
|
52
|
+
startLocalOAuthServer: typeof startLocalOAuthServer;
|
|
53
|
+
};
|
|
32
54
|
/**
|
|
33
55
|
* Refresh OpenAI Codex OAuth token
|
|
34
56
|
*/
|
|
35
57
|
export declare function refreshOpenAICodexToken(refreshToken: string): Promise<OAuthCredentials>;
|
|
36
58
|
export declare const openaiCodexOAuthProvider: OAuthProviderInterface;
|
|
59
|
+
export {};
|
|
37
60
|
//# sourceMappingURL=openai-codex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/openai-codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/openai-codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH,OAAO,KAAK,EAAE,gBAAgB,EAAuB,WAAW,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAyK9G,iBAAe,uBAAuB,CACpC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAa,GACxB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB5C;AAED,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACrD,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAkDF,iBAAe,qBAAqB,CAClC,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,aAAoC,GAC1C,OAAO,CAAC,eAAe,CAAC,CA4E1B;AASD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,MAAM,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/D,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4G5B;AAED,eAAO,MAAM,SAAS;;;CAGrB,CAAC;AAEF;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiB7F;AAED,eAAO,MAAM,wBAAwB,EAAE,sBAqBtC,CAAC"}
|
|
@@ -389,19 +389,22 @@ var anthropicOAuthProvider = {
|
|
|
389
389
|
|
|
390
390
|
// src/auth/providers/openai-codex.ts
|
|
391
391
|
var _randomBytes = null;
|
|
392
|
+
var _httpPromise = null;
|
|
392
393
|
var _http = null;
|
|
393
394
|
if (typeof process !== "undefined" && (process.versions?.node || process.versions?.bun)) {
|
|
394
395
|
import('crypto').then((m) => {
|
|
395
396
|
_randomBytes = m.randomBytes;
|
|
396
397
|
});
|
|
397
|
-
import('http').then((m) => {
|
|
398
|
+
_httpPromise = import('http').then((m) => {
|
|
398
399
|
_http = m;
|
|
400
|
+
return m;
|
|
399
401
|
});
|
|
400
402
|
}
|
|
401
403
|
var CLIENT_ID2 = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
402
404
|
var AUTHORIZE_URL2 = "https://auth.openai.com/oauth/authorize";
|
|
403
405
|
var TOKEN_URL2 = "https://auth.openai.com/oauth/token";
|
|
404
|
-
var
|
|
406
|
+
var DEFAULT_CALLBACK_PORT = 1455;
|
|
407
|
+
var FALLBACK_CALLBACK_PORT = 1457;
|
|
405
408
|
var SCOPE = "openid profile email offline_access";
|
|
406
409
|
var JWT_CLAIM_PATH = "https://api.openai.com/auth";
|
|
407
410
|
var SUCCESS_HTML = `<!doctype html>
|
|
@@ -456,7 +459,7 @@ function decodeJwt(token) {
|
|
|
456
459
|
return null;
|
|
457
460
|
}
|
|
458
461
|
}
|
|
459
|
-
async function exchangeAuthorizationCode(code, verifier, redirectUri
|
|
462
|
+
async function exchangeAuthorizationCode(code, verifier, redirectUri) {
|
|
460
463
|
const response = await fetch(TOKEN_URL2, {
|
|
461
464
|
method: "POST",
|
|
462
465
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
@@ -517,13 +520,12 @@ async function refreshAccessToken(refreshToken) {
|
|
|
517
520
|
return { type: "failed" };
|
|
518
521
|
}
|
|
519
522
|
}
|
|
520
|
-
async function createAuthorizationFlow(originator = "pi") {
|
|
523
|
+
async function createAuthorizationFlow(redirectUri, state, originator = "pi") {
|
|
521
524
|
const { verifier, challenge } = await generatePKCE();
|
|
522
|
-
const state = createState();
|
|
523
525
|
const url = new URL(AUTHORIZE_URL2);
|
|
524
526
|
url.searchParams.set("response_type", "code");
|
|
525
527
|
url.searchParams.set("client_id", CLIENT_ID2);
|
|
526
|
-
url.searchParams.set("redirect_uri",
|
|
528
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
527
529
|
url.searchParams.set("scope", SCOPE);
|
|
528
530
|
url.searchParams.set("code_challenge", challenge);
|
|
529
531
|
url.searchParams.set("code_challenge_method", "S256");
|
|
@@ -531,17 +533,61 @@ async function createAuthorizationFlow(originator = "pi") {
|
|
|
531
533
|
url.searchParams.set("id_token_add_organizations", "true");
|
|
532
534
|
url.searchParams.set("codex_cli_simplified_flow", "true");
|
|
533
535
|
url.searchParams.set("originator", originator);
|
|
534
|
-
return { verifier,
|
|
536
|
+
return { verifier, url: url.toString() };
|
|
537
|
+
}
|
|
538
|
+
var CODEX_CALLBACK_PORTS = {
|
|
539
|
+
defaultPort: DEFAULT_CALLBACK_PORT,
|
|
540
|
+
fallbackPort: FALLBACK_CALLBACK_PORT
|
|
541
|
+
};
|
|
542
|
+
async function requestCancel(port) {
|
|
543
|
+
try {
|
|
544
|
+
await fetch(`http://127.0.0.1:${port}/cancel`, { signal: AbortSignal.timeout(200) });
|
|
545
|
+
} catch {
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
function listen(server, port) {
|
|
549
|
+
return new Promise((resolve) => {
|
|
550
|
+
const onError = () => {
|
|
551
|
+
server.off("listening", onListening);
|
|
552
|
+
resolve(false);
|
|
553
|
+
};
|
|
554
|
+
const onListening = () => {
|
|
555
|
+
server.off("error", onError);
|
|
556
|
+
resolve(true);
|
|
557
|
+
};
|
|
558
|
+
server.once("error", onError);
|
|
559
|
+
server.once("listening", onListening);
|
|
560
|
+
server.listen(port, "127.0.0.1");
|
|
561
|
+
});
|
|
535
562
|
}
|
|
536
|
-
function
|
|
563
|
+
async function bindOAuthServer(server, ports) {
|
|
564
|
+
await requestCancel(ports.defaultPort);
|
|
565
|
+
if (await listen(server, ports.defaultPort)) return ports.defaultPort;
|
|
566
|
+
if (await listen(server, ports.fallbackPort)) return ports.fallbackPort;
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
async function getHttpModule() {
|
|
570
|
+
if (!_http && _httpPromise) {
|
|
571
|
+
_http = await _httpPromise;
|
|
572
|
+
}
|
|
537
573
|
if (!_http) {
|
|
538
574
|
throw new Error("OpenAI Codex OAuth is only available in Node.js environments");
|
|
539
575
|
}
|
|
576
|
+
return _http;
|
|
577
|
+
}
|
|
578
|
+
async function startLocalOAuthServer(state, ports = CODEX_CALLBACK_PORTS) {
|
|
579
|
+
const http = await getHttpModule();
|
|
540
580
|
let lastCode = null;
|
|
541
581
|
let cancelled = false;
|
|
542
|
-
const server =
|
|
582
|
+
const server = http.createServer((req, res) => {
|
|
543
583
|
try {
|
|
544
584
|
const url = new URL(req.url || "", "http://localhost");
|
|
585
|
+
if (url.pathname === "/cancel") {
|
|
586
|
+
cancelled = true;
|
|
587
|
+
res.statusCode = 200;
|
|
588
|
+
res.end("Cancelled");
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
545
591
|
if (url.pathname !== "/auth/callback") {
|
|
546
592
|
res.statusCode = 404;
|
|
547
593
|
res.end("Not found");
|
|
@@ -568,8 +614,25 @@ function startLocalOAuthServer(state) {
|
|
|
568
614
|
}
|
|
569
615
|
});
|
|
570
616
|
return new Promise((resolve) => {
|
|
571
|
-
server
|
|
617
|
+
bindOAuthServer(server, ports).then((port) => {
|
|
618
|
+
if (!port) {
|
|
619
|
+
resolve({
|
|
620
|
+
redirectUri: `http://localhost:${ports.fallbackPort}/auth/callback`,
|
|
621
|
+
warning: `OpenAI Codex OAuth requires localhost port ${ports.defaultPort} or ${ports.fallbackPort}, but both are in use. Automatic browser callback will not work until one is freed.`,
|
|
622
|
+
close: () => {
|
|
623
|
+
try {
|
|
624
|
+
server.close();
|
|
625
|
+
} catch {
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
cancelWait: () => {
|
|
629
|
+
},
|
|
630
|
+
waitForCode: async () => null
|
|
631
|
+
});
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
572
634
|
resolve({
|
|
635
|
+
redirectUri: `http://localhost:${port}/auth/callback`,
|
|
573
636
|
close: () => server.close(),
|
|
574
637
|
cancelWait: () => {
|
|
575
638
|
cancelled = true;
|
|
@@ -584,23 +647,6 @@ function startLocalOAuthServer(state) {
|
|
|
584
647
|
return null;
|
|
585
648
|
}
|
|
586
649
|
});
|
|
587
|
-
}).on("error", (err) => {
|
|
588
|
-
console.error(
|
|
589
|
-
"[openai-codex] Failed to bind http://127.0.0.1:1455 (",
|
|
590
|
-
err.code,
|
|
591
|
-
") Falling back to manual paste."
|
|
592
|
-
);
|
|
593
|
-
resolve({
|
|
594
|
-
close: () => {
|
|
595
|
-
try {
|
|
596
|
-
server.close();
|
|
597
|
-
} catch {
|
|
598
|
-
}
|
|
599
|
-
},
|
|
600
|
-
cancelWait: () => {
|
|
601
|
-
},
|
|
602
|
-
waitForCode: async () => null
|
|
603
|
-
});
|
|
604
650
|
});
|
|
605
651
|
});
|
|
606
652
|
}
|
|
@@ -611,11 +657,15 @@ function getAccountId(accessToken) {
|
|
|
611
657
|
return typeof accountId === "string" && accountId.length > 0 ? accountId : null;
|
|
612
658
|
}
|
|
613
659
|
async function loginOpenAICodex(options) {
|
|
614
|
-
const
|
|
660
|
+
const state = createState();
|
|
615
661
|
const server = await startLocalOAuthServer(state);
|
|
662
|
+
if (server.warning) {
|
|
663
|
+
options.onProgress?.(server.warning);
|
|
664
|
+
}
|
|
665
|
+
const { verifier, url } = await createAuthorizationFlow(server.redirectUri, state, options.originator);
|
|
616
666
|
options.onAuth({
|
|
617
667
|
url,
|
|
618
|
-
instructions: "A browser window should open. Complete login to finish."
|
|
668
|
+
instructions: server.warning ? `${server.warning} You can still paste the authorization code or full redirect URL manually.` : "A browser window should open. Complete login to finish."
|
|
619
669
|
});
|
|
620
670
|
let code;
|
|
621
671
|
try {
|
|
@@ -674,7 +724,7 @@ async function loginOpenAICodex(options) {
|
|
|
674
724
|
if (!code) {
|
|
675
725
|
throw new Error("Missing authorization code");
|
|
676
726
|
}
|
|
677
|
-
const tokenResult = await exchangeAuthorizationCode(code, verifier);
|
|
727
|
+
const tokenResult = await exchangeAuthorizationCode(code, verifier, server.redirectUri);
|
|
678
728
|
if (tokenResult.type !== "success") {
|
|
679
729
|
throw new Error("Token exchange failed");
|
|
680
730
|
}
|
|
@@ -914,5 +964,5 @@ exports.getStorageConfig = getStorageConfig;
|
|
|
914
964
|
exports.getUserId = getUserId;
|
|
915
965
|
exports.getUserName = getUserName;
|
|
916
966
|
exports.getVectorDatabasePath = getVectorDatabasePath;
|
|
917
|
-
//# sourceMappingURL=chunk-
|
|
918
|
-
//# sourceMappingURL=chunk-
|
|
967
|
+
//# sourceMappingURL=chunk-24SDVHO7.cjs.map
|
|
968
|
+
//# sourceMappingURL=chunk-24SDVHO7.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/project.ts","../src/auth/pkce.ts","../src/auth/providers/anthropic.ts","../src/auth/providers/openai-codex.ts","../src/auth/storage.ts"],"names":["execSync","createHash","path","os","fs","scope","rid","CLIENT_ID","AUTHORIZE_URL","TOKEN_URL","join","existsSync","readFileSync","dirname","mkdirSync","writeFileSync","chmodSync"],"mappings":"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","file":"chunk-24SDVHO7.cjs","sourcesContent":["/**\n * Project detection utilities\n *\n * Detects project identity from git repo or filesystem path.\n * Handles git worktrees by finding the main repository.\n */\n\nimport { execSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nexport interface ProjectInfo {\n /** Unique resource ID for this project (used for thread grouping) */\n resourceId: string;\n /** Human-readable project name */\n name: string;\n /** Absolute path to the project root */\n rootPath: string;\n /** Git remote URL if available */\n gitUrl?: string;\n /** Current git branch */\n gitBranch?: string;\n /** Whether this is a git worktree */\n isWorktree: boolean;\n /** Path to main git repo (different from rootPath if worktree) */\n mainRepoPath?: string;\n /** Whether the resourceId was explicitly overridden (env var or config) */\n resourceIdOverride?: boolean;\n}\n\n/**\n * Run a git command and return stdout, or undefined if it fails\n */\nfunction git(args: string, cwd: string): string | undefined {\n try {\n return execSync(`git ${args}`, {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Slugify a string for use in IDs\n */\nfunction slugify(str: string): string {\n return str\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\n/**\n * Create a short hash of a string\n */\nfunction shortHash(str: string): string {\n return createHash('sha256').update(str).digest('hex').slice(0, 12);\n}\n\n/**\n * Normalize a git URL to a canonical form for comparison\n * - Removes .git suffix\n * - Converts SSH to HTTPS format for consistency\n * - Lowercases\n */\nfunction normalizeGitUrl(url: string): string {\n return url\n .replace(/\\.git$/, '')\n .replace(/^git@([^:]+):/, 'https://$1/')\n .replace(/^ssh:\\/\\/git@/, 'https://')\n .toLowerCase();\n}\n\n/**\n * Detect project info from a directory path\n */\nexport function detectProject(projectPath: string): ProjectInfo {\n const absolutePath = path.resolve(projectPath);\n\n // Check if this is a git repo\n const gitDir = git('rev-parse --git-dir', absolutePath);\n const isGitRepo = gitDir !== undefined;\n\n let rootPath = absolutePath;\n let gitUrl: string | undefined;\n let gitBranch: string | undefined;\n let isWorktree = false;\n let mainRepoPath: string | undefined;\n\n if (isGitRepo) {\n // Get the repo root (handles being in a subdirectory)\n rootPath = git('rev-parse --show-toplevel', absolutePath) || absolutePath;\n\n // Check for worktree - git-common-dir differs from git-dir in worktrees\n const commonDir = git('rev-parse --git-common-dir', absolutePath);\n if (commonDir && commonDir !== '.git' && commonDir !== gitDir) {\n isWorktree = true;\n // The common dir is inside the main repo's .git folder\n mainRepoPath = path.dirname(path.resolve(rootPath, commonDir));\n }\n\n // Get remote URL (prefer origin, fall back to first remote)\n gitUrl = git('remote get-url origin', absolutePath);\n if (!gitUrl) {\n const remotes = git('remote', absolutePath);\n if (remotes) {\n const firstRemote = remotes.split('\\n')[0];\n if (firstRemote) {\n gitUrl = git(`remote get-url ${firstRemote}`, absolutePath);\n }\n }\n }\n\n // Get current branch\n gitBranch = git('rev-parse --abbrev-ref HEAD', absolutePath);\n }\n\n // Generate resource ID\n // Priority: normalized git URL > main repo path (for worktrees) > absolute path\n let resourceIdSource: string;\n if (gitUrl) {\n resourceIdSource = normalizeGitUrl(gitUrl);\n } else if (mainRepoPath) {\n resourceIdSource = mainRepoPath;\n } else {\n resourceIdSource = rootPath;\n }\n\n // Create a readable but unique resource ID\n // Format: slugified-name-shorthash\n const baseName = gitUrl\n ? gitUrl\n .split('/')\n .pop()\n ?.replace(/\\.git$/, '') || 'project'\n : path.basename(rootPath);\n\n const resourceId = `${slugify(baseName)}-${shortHash(resourceIdSource)}`;\n\n return {\n resourceId,\n name: baseName,\n rootPath,\n gitUrl,\n gitBranch,\n isWorktree,\n mainRepoPath,\n };\n}\n\n/**\n * Get the current git branch for a given directory.\n * Lightweight alternative to detectProject() for refreshing just the branch.\n */\nexport function getCurrentGitBranch(cwd: string): string | undefined {\n return git('rev-parse --abbrev-ref HEAD', cwd);\n}\n\n/**\n * Get the application data directory for mastracode\n * - macOS: ~/Library/Application Support/mastracode\n * - Linux: ~/.local/share/mastracode\n * - Windows: %APPDATA%/mastracode\n */\nexport function getAppDataDir(): string {\n const platform = os.platform();\n let baseDir: string;\n\n if (platform === 'darwin') {\n baseDir = path.join(os.homedir(), 'Library', 'Application Support');\n } else if (platform === 'win32') {\n baseDir = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');\n } else {\n // Linux and others - follow XDG spec\n baseDir = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n }\n\n const appDir = path.join(baseDir, 'mastracode');\n\n // Ensure directory exists\n if (!fs.existsSync(appDir)) {\n fs.mkdirSync(appDir, { recursive: true });\n }\n\n return appDir;\n}\n/**\n * Get the database path for mastracode\n * Can be overridden with the MASTRA_DB_PATH environment variable for debugging.\n */\nexport function getDatabasePath(): string {\n if (process.env.MASTRA_DB_PATH) {\n return process.env.MASTRA_DB_PATH;\n }\n return path.join(getAppDataDir(), 'mastra.db');\n}\n\n/**\n * Get the vector database path for mastracode.\n * Separate from the main DB to avoid bloating it with embedding data.\n */\nexport function getVectorDatabasePath(): string {\n return path.join(getAppDataDir(), 'mastra-vectors.db');\n}\n\n/**\n * Get the observability DuckDB database path for mastracode.\n * Separate from the main DB — DuckDB is used for OLAP-style trace/score/feedback queries.\n * Can be overridden with the MASTRA_OBSERVABILITY_DB_PATH environment variable.\n */\nexport function getObservabilityDatabasePath(): string {\n if (process.env.MASTRA_OBSERVABILITY_DB_PATH) {\n return process.env.MASTRA_OBSERVABILITY_DB_PATH;\n }\n return path.join(getAppDataDir(), 'observability.duckdb');\n}\n\nimport type { StorageBackend, StorageSettings } from '../onboarding/settings.js';\n\n/**\n * LibSQL storage configuration.\n */\nexport interface LibSQLStorageConfig {\n backend: 'libsql';\n url: string;\n authToken?: string;\n isRemote: boolean;\n}\n\n/**\n * PostgreSQL storage configuration.\n */\nexport interface PgStorageConfig {\n backend: 'pg';\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n schemaName?: string;\n disableInit?: boolean;\n skipDefaultIndexes?: boolean;\n}\n\n/**\n * Resolved storage configuration for either backend.\n */\nexport type StorageConfig = LibSQLStorageConfig | PgStorageConfig;\n\n/**\n * Get the resolved storage configuration.\n *\n * Priority (highest to lowest):\n * 1. Environment variables: MASTRA_STORAGE_BACKEND + backend-specific vars\n * 2. Global settings (from /settings): settings.storage\n * 3. Legacy config files: .mastracode/database.json (LibSQL only)\n * 4. Local file database (LibSQL default)\n *\n * For PG, the env vars are:\n * MASTRA_STORAGE_BACKEND=pg\n * MASTRA_PG_CONNECTION_STRING or MASTRA_PG_HOST/PORT/DATABASE/USER/PASSWORD\n * MASTRA_PG_SCHEMA_NAME (optional)\n *\n * For LibSQL, the legacy env vars still work:\n * MASTRA_DB_URL + MASTRA_DB_AUTH_TOKEN\n */\nexport function getStorageConfig(projectDir?: string, storageSettings?: StorageSettings): StorageConfig {\n // 1. Environment variable — explicit backend selection\n const envBackend = process.env.MASTRA_STORAGE_BACKEND as StorageBackend | undefined;\n\n if (envBackend === 'pg') {\n return resolvePgFromEnv();\n }\n\n // Legacy LibSQL env vars (MASTRA_DB_URL) — treat as explicit libsql\n if (envBackend === 'libsql' || process.env.MASTRA_DB_URL) {\n return resolveLibSQLFromEnv();\n }\n\n // 2. Global settings (from /settings)\n if (storageSettings && storageSettings.backend === 'pg') {\n return resolvePgFromSettings(storageSettings);\n }\n\n if (storageSettings && storageSettings.backend === 'libsql' && storageSettings.libsql.url) {\n return {\n backend: 'libsql',\n url: storageSettings.libsql.url,\n authToken: storageSettings.libsql.authToken,\n isRemote: !storageSettings.libsql.url.startsWith('file:'),\n };\n }\n\n // 3. Legacy project/global config files (.mastracode/database.json)\n if (projectDir) {\n const projectConfig = loadDatabaseConfig(path.join(projectDir, '.mastracode', 'database.json'));\n if (projectConfig) return projectConfig;\n }\n const globalConfig = loadDatabaseConfig(path.join(os.homedir(), '.mastracode', 'database.json'));\n if (globalConfig) return globalConfig;\n\n // 4. Default: local LibSQL file database\n return {\n backend: 'libsql',\n url: `file:${getDatabasePath()}`,\n isRemote: false,\n };\n}\n\nfunction resolveLibSQLFromEnv(): LibSQLStorageConfig {\n const url = process.env.MASTRA_DB_URL!;\n return {\n backend: 'libsql',\n url,\n authToken: process.env.MASTRA_DB_AUTH_TOKEN,\n isRemote: !url.startsWith('file:'),\n };\n}\n\nfunction resolvePgFromEnv(): PgStorageConfig {\n const connectionString = process.env.MASTRA_PG_CONNECTION_STRING;\n if (connectionString) {\n return {\n backend: 'pg',\n connectionString,\n schemaName: process.env.MASTRA_PG_SCHEMA_NAME,\n };\n }\n\n // Host/port style\n return {\n backend: 'pg',\n host: process.env.MASTRA_PG_HOST,\n port: process.env.MASTRA_PG_PORT ? parseInt(process.env.MASTRA_PG_PORT, 10) : undefined,\n database: process.env.MASTRA_PG_DATABASE,\n user: process.env.MASTRA_PG_USER,\n password: process.env.MASTRA_PG_PASSWORD,\n schemaName: process.env.MASTRA_PG_SCHEMA_NAME,\n };\n}\n\nfunction resolvePgFromSettings(settings: StorageSettings): PgStorageConfig {\n const pg = settings.pg;\n return {\n backend: 'pg',\n connectionString: pg.connectionString,\n host: pg.host,\n port: pg.port,\n database: pg.database,\n user: pg.user,\n password: pg.password,\n schemaName: pg.schemaName,\n disableInit: pg.disableInit,\n skipDefaultIndexes: pg.skipDefaultIndexes,\n };\n}\n\n/**\n * Load database config from a legacy JSON file.\n * Expected format: { \"url\": \"libsql://...\", \"authToken\": \"...\" }\n */\nfunction loadDatabaseConfig(filePath: string): LibSQLStorageConfig | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (typeof parsed?.url === 'string' && parsed.url) {\n return {\n backend: 'libsql',\n url: parsed.url,\n authToken: typeof parsed.authToken === 'string' ? parsed.authToken : undefined,\n isRemote: !parsed.url.startsWith('file:'),\n };\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the current user identity.\n *\n * Priority:\n * 1. MASTRA_USER_ID environment variable\n * 2. git config user.email (from project dir or global)\n * 3. OS username as fallback\n */\nexport function getUserId(projectDir?: string): string {\n // 1. Environment variable override\n if (process.env.MASTRA_USER_ID) {\n return process.env.MASTRA_USER_ID;\n }\n\n // 2. git user.email\n const cwd = projectDir || process.cwd();\n const email = git('config user.email', cwd);\n if (email) {\n return email;\n }\n\n // 3. OS username fallback\n return os.userInfo().username || 'unknown';\n}\n\n/**\n * Get the current user's display name.\n *\n * Priority:\n * 1. git config user.name\n * 2. OS username as fallback\n */\nexport function getUserName(projectDir?: string): string {\n const cwd = projectDir || process.cwd();\n const name = git('config user.name', cwd);\n if (name) {\n return name;\n }\n return os.userInfo().username || 'unknown';\n}\n\n/**\n * Observational memory scope: \"thread\" (per-conversation) or \"resource\" (shared across threads).\n */\nexport type OmScope = 'thread' | 'resource';\n\n/**\n * Get the configured observational memory scope.\n *\n * Priority:\n * 1. MASTRA_OM_SCOPE environment variable (\"thread\" or \"resource\")\n * 2. Project config: .mastracode/database.json → omScope\n * 3. Global config: ~/.mastracode/database.json → omScope\n * 4. Default: \"thread\"\n */\nexport function getOmScope(projectDir?: string): OmScope {\n // 1. Environment variable\n const envScope = process.env.MASTRA_OM_SCOPE;\n if (envScope === 'thread' || envScope === 'resource') {\n return envScope;\n }\n\n // 2. Project-level config\n if (projectDir) {\n const scope = loadOmScopeFromConfig(path.join(projectDir, '.mastracode', 'database.json'));\n if (scope) return scope;\n }\n\n // 3. Global config\n const scope = loadOmScopeFromConfig(path.join(os.homedir(), '.mastracode', 'database.json'));\n if (scope) return scope;\n\n // 4. Default\n return 'thread';\n}\n\nfunction loadOmScopeFromConfig(filePath: string): OmScope | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed?.omScope === 'thread' || parsed?.omScope === 'resource') {\n return parsed.omScope;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get an explicit resource ID override, if configured.\n *\n * Resource IDs act as shared tags — two users who set the same resourceId\n * will share threads and observations for that resource.\n *\n * Priority:\n * 1. MASTRA_RESOURCE_ID environment variable\n * 2. Project config: .mastracode/database.json → resourceId\n * 3. Global config: ~/.mastracode/database.json → resourceId\n * 4. null (use auto-detected value)\n */\nexport function getResourceIdOverride(projectDir?: string): string | null {\n // 1. Environment variable\n if (process.env.MASTRA_RESOURCE_ID) {\n return process.env.MASTRA_RESOURCE_ID;\n }\n\n // 2. Project-level config\n if (projectDir) {\n const rid = loadStringField(path.join(projectDir, '.mastracode', 'database.json'), 'resourceId');\n if (rid) return rid;\n }\n\n // 3. Global config\n const rid = loadStringField(path.join(os.homedir(), '.mastracode', 'database.json'), 'resourceId');\n if (rid) return rid;\n\n return null;\n}\n\nfunction loadStringField(filePath: string, field: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n const value = parsed?.[field];\n if (typeof value === 'string' && value) {\n return value;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * PKCE utilities using Web Crypto API.\n * Works in both Node.js 20+ and browsers.\n */\n\n/**\n * Encode bytes as base64url string.\n */\nfunction base64urlEncode(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Generate PKCE code verifier and challenge.\n * Uses Web Crypto API for cross-platform compatibility.\n */\nexport async function generatePKCE(): Promise<{\n verifier: string;\n challenge: string;\n}> {\n // Generate random verifier\n const verifierBytes = new Uint8Array(32);\n crypto.getRandomValues(verifierBytes);\n const verifier = base64urlEncode(verifierBytes);\n\n // Compute SHA-256 challenge\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const challenge = base64urlEncode(new Uint8Array(hashBuffer));\n\n return { verifier, challenge };\n}\n","/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts\n */\n\nimport { generatePKCE } from '../pkce.js';\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from '../types.js';\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode('OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl');\nconst AUTHORIZE_URL = 'https://claude.ai/oauth/authorize';\nconst TOKEN_URL = 'https://console.anthropic.com/v1/oauth/token';\nconst REDIRECT_URI = 'https://console.anthropic.com/oauth/code/callback';\nconst SCOPES = 'org:create_api_key user:profile user:inference';\n\n/**\n * Login with Anthropic OAuth (device code flow)\n */\nexport async function loginAnthropic(\n onAuthUrl: (url: string) => void,\n onPromptCode: () => Promise<string>,\n): Promise<OAuthCredentials> {\n const { verifier, challenge } = await generatePKCE();\n\n // Build authorization URL\n const authParams = new URLSearchParams({\n code: 'true',\n client_id: CLIENT_ID,\n response_type: 'code',\n redirect_uri: REDIRECT_URI,\n scope: SCOPES,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n state: verifier,\n });\n\n const authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`;\n\n // Notify caller with URL to open\n onAuthUrl(authUrl);\n\n // Wait for user to paste authorization code (format: code#state)\n const authCode = await onPromptCode();\n const splits = authCode.split('#');\n const code = splits[0];\n const state = splits[1];\n\n // Exchange code for tokens\n const tokenResponse = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code: code,\n state: state,\n redirect_uri: REDIRECT_URI,\n code_verifier: verifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const error = await tokenResponse.text();\n throw new Error(`Token exchange failed: ${error}`);\n }\n\n const tokenData = (await tokenResponse.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n // Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n const expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n return {\n refresh: tokenData.refresh_token,\n access: tokenData.access_token,\n expires: expiresAt,\n };\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'refresh_token',\n client_id: CLIENT_ID,\n refresh_token: refreshToken,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Anthropic token refresh failed: ${error}`);\n }\n\n const data = (await response.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n return {\n refresh: data.refresh_token,\n access: data.access_token,\n expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n };\n}\n\nexport const anthropicOAuthProvider: OAuthProviderInterface = {\n id: 'anthropic',\n name: 'Anthropic (Claude Pro/Max)',\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginAnthropic(\n url => callbacks.onAuth({ url }),\n () => callbacks.onPrompt({ message: 'Paste the authorization code:' }),\n );\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshAnthropicToken(credentials.refresh);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * OpenAI Codex (ChatGPT OAuth) flow\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/openai-codex.ts\n *\n * NOTE: This module uses Node.js crypto and http for the OAuth callback.\n * It is only intended for CLI use, not browser environments.\n */\n\n// NEVER convert to top-level imports - breaks browser/Vite builds (web-ui)\nlet _randomBytes: ((size: number) => Buffer) | null = null;\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet _httpPromise: Promise<typeof import('node:http')> | null = null;\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet _http: typeof import('node:http') | null = null;\ntype HttpServer = {\n off: (event: 'error' | 'listening', listener: (...args: any[]) => void) => HttpServer;\n once: (event: 'error' | 'listening', listener: (...args: any[]) => void) => HttpServer;\n listen: (port: number, hostname: string) => HttpServer;\n close: () => void;\n};\nif (typeof process !== 'undefined' && (process.versions?.node || process.versions?.bun)) {\n import('node:crypto').then(m => {\n _randomBytes = m.randomBytes;\n });\n _httpPromise = import('node:http').then(m => {\n _http = m;\n return m;\n });\n}\n\nimport { generatePKCE } from '../pkce.js';\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthPrompt, OAuthProviderInterface } from '../types.js';\n\nconst CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';\nconst AUTHORIZE_URL = 'https://auth.openai.com/oauth/authorize';\nconst TOKEN_URL = 'https://auth.openai.com/oauth/token';\nconst DEFAULT_CALLBACK_PORT = 1455;\nconst FALLBACK_CALLBACK_PORT = 1457;\nconst SCOPE = 'openid profile email offline_access';\nconst JWT_CLAIM_PATH = 'https://api.openai.com/auth';\n\nconst SUCCESS_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Authentication successful</title>\n</head>\n<body>\n <p>Authentication successful. Return to your terminal to continue.</p>\n</body>\n</html>`;\n\ntype TokenSuccess = {\n type: 'success';\n access: string;\n refresh: string;\n expires: number;\n};\ntype TokenFailure = { type: 'failed' };\ntype TokenResult = TokenSuccess | TokenFailure;\n\ntype JwtPayload = {\n [JWT_CLAIM_PATH]?: {\n chatgpt_account_id?: string;\n };\n [key: string]: unknown;\n};\n\nfunction createState(): string {\n if (!_randomBytes) {\n throw new Error('OpenAI Codex OAuth is only available in Node.js environments');\n }\n return _randomBytes(16).toString('hex');\n}\n\nfunction parseAuthorizationInput(input: string): {\n code?: string;\n state?: string;\n} {\n const value = input.trim();\n if (!value) return {};\n\n try {\n const url = new URL(value);\n return {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n };\n } catch {\n // not a URL\n }\n\n if (value.includes('#')) {\n const [code, state] = value.split('#', 2);\n return { code, state };\n }\n\n if (value.includes('code=')) {\n const params = new URLSearchParams(value);\n return {\n code: params.get('code') ?? undefined,\n state: params.get('state') ?? undefined,\n };\n }\n\n return { code: value };\n}\n\nfunction decodeJwt(token: string): JwtPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n const payload = parts[1] ?? '';\n const decoded = atob(payload);\n return JSON.parse(decoded) as JwtPayload;\n } catch {\n return null;\n }\n}\n\nasync function exchangeAuthorizationCode(code: string, verifier: string, redirectUri: string): Promise<TokenResult> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code,\n code_verifier: verifier,\n redirect_uri: redirectUri,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error('[openai-codex] code->token failed:', response.status, text);\n return { type: 'failed' };\n }\n\n const json = (await response.json()) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n\n if (!json.access_token || !json.refresh_token || typeof json.expires_in !== 'number') {\n console.error('[openai-codex] token response missing fields:', json);\n return { type: 'failed' };\n }\n\n return {\n type: 'success',\n access: json.access_token,\n refresh: json.refresh_token,\n expires: Date.now() + json.expires_in * 1000,\n };\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<TokenResult> {\n try {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: CLIENT_ID,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error('[openai-codex] Token refresh failed:', response.status, text);\n return { type: 'failed' };\n }\n\n const json = (await response.json()) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n\n if (!json.access_token || !json.refresh_token || typeof json.expires_in !== 'number') {\n console.error('[openai-codex] Token refresh response missing fields:', json);\n return { type: 'failed' };\n }\n\n return {\n type: 'success',\n access: json.access_token,\n refresh: json.refresh_token,\n expires: Date.now() + json.expires_in * 1000,\n };\n } catch (error) {\n console.error('[openai-codex] Token refresh error:', error);\n return { type: 'failed' };\n }\n}\n\nasync function createAuthorizationFlow(\n redirectUri: string,\n state: string,\n originator: string = 'pi',\n): Promise<{ verifier: string; url: string }> {\n const { verifier, challenge } = await generatePKCE();\n\n const url = new URL(AUTHORIZE_URL);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('client_id', CLIENT_ID);\n url.searchParams.set('redirect_uri', redirectUri);\n url.searchParams.set('scope', SCOPE);\n url.searchParams.set('code_challenge', challenge);\n url.searchParams.set('code_challenge_method', 'S256');\n url.searchParams.set('state', state);\n url.searchParams.set('id_token_add_organizations', 'true');\n url.searchParams.set('codex_cli_simplified_flow', 'true');\n url.searchParams.set('originator', originator);\n\n return { verifier, url: url.toString() };\n}\n\ntype OAuthServerInfo = {\n redirectUri: string;\n warning?: string;\n close: () => void;\n cancelWait: () => void;\n waitForCode: () => Promise<{ code: string } | null>;\n};\n\ntype CallbackPorts = {\n defaultPort: number;\n fallbackPort: number;\n};\n\nconst CODEX_CALLBACK_PORTS: CallbackPorts = {\n defaultPort: DEFAULT_CALLBACK_PORT,\n fallbackPort: FALLBACK_CALLBACK_PORT,\n};\n\nasync function requestCancel(port: number): Promise<void> {\n try {\n await fetch(`http://127.0.0.1:${port}/cancel`, { signal: AbortSignal.timeout(200) });\n } catch {\n // The existing listener might not be a Codex auth server.\n }\n}\n\nfunction listen(server: HttpServer, port: number): Promise<boolean> {\n return new Promise(resolve => {\n const onError = () => {\n server.off('listening', onListening);\n resolve(false);\n };\n const onListening = () => {\n server.off('error', onError);\n resolve(true);\n };\n\n server.once('error', onError);\n server.once('listening', onListening);\n server.listen(port, '127.0.0.1');\n });\n}\n\nasync function bindOAuthServer(server: HttpServer, ports: CallbackPorts): Promise<number | null> {\n await requestCancel(ports.defaultPort);\n if (await listen(server, ports.defaultPort)) return ports.defaultPort;\n if (await listen(server, ports.fallbackPort)) return ports.fallbackPort;\n\n return null;\n}\n\nasync function getHttpModule() {\n if (!_http && _httpPromise) {\n _http = await _httpPromise;\n }\n if (!_http) {\n throw new Error('OpenAI Codex OAuth is only available in Node.js environments');\n }\n return _http;\n}\n\nasync function startLocalOAuthServer(\n state: string,\n ports: CallbackPorts = CODEX_CALLBACK_PORTS,\n): Promise<OAuthServerInfo> {\n const http = await getHttpModule();\n let lastCode: string | null = null;\n let cancelled = false;\n const server = http.createServer((req, res) => {\n try {\n const url = new URL(req.url || '', 'http://localhost');\n if (url.pathname === '/cancel') {\n cancelled = true;\n res.statusCode = 200;\n res.end('Cancelled');\n return;\n }\n if (url.pathname !== '/auth/callback') {\n res.statusCode = 404;\n res.end('Not found');\n return;\n }\n if (url.searchParams.get('state') !== state) {\n res.statusCode = 400;\n res.end('State mismatch');\n return;\n }\n const code = url.searchParams.get('code');\n if (!code) {\n res.statusCode = 400;\n res.end('Missing authorization code');\n return;\n }\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(SUCCESS_HTML);\n lastCode = code;\n } catch {\n res.statusCode = 500;\n res.end('Internal error');\n }\n });\n\n return new Promise(resolve => {\n bindOAuthServer(server, ports).then(port => {\n if (!port) {\n resolve({\n redirectUri: `http://localhost:${ports.fallbackPort}/auth/callback`,\n warning: `OpenAI Codex OAuth requires localhost port ${ports.defaultPort} or ${ports.fallbackPort}, but both are in use. Automatic browser callback will not work until one is freed.`,\n close: () => {\n try {\n server.close();\n } catch {\n // ignore\n }\n },\n cancelWait: () => {},\n waitForCode: async () => null,\n });\n return;\n }\n\n resolve({\n redirectUri: `http://localhost:${port}/auth/callback`,\n close: () => server.close(),\n cancelWait: () => {\n cancelled = true;\n },\n waitForCode: async () => {\n const sleep = () => new Promise(r => setTimeout(r, 100));\n for (let i = 0; i < 600; i += 1) {\n if (lastCode) return { code: lastCode };\n if (cancelled) return null;\n await sleep();\n }\n return null;\n },\n });\n });\n });\n}\n\nfunction getAccountId(accessToken: string): string | null {\n const payload = decodeJwt(accessToken);\n const auth = payload?.[JWT_CLAIM_PATH];\n const accountId = auth?.chatgpt_account_id;\n return typeof accountId === 'string' && accountId.length > 0 ? accountId : null;\n}\n\n/**\n * Login with OpenAI Codex OAuth\n *\n * @param options.onAuth - Called with URL and instructions when auth starts\n * @param options.onPrompt - Called to prompt user for manual code paste (fallback if no onManualCodeInput)\n * @param options.onProgress - Optional progress messages\n * @param options.onManualCodeInput - Optional promise that resolves with user-pasted code.\n * Races with browser callback - whichever completes first wins.\n * Useful for showing paste input immediately alongside browser flow.\n * @param options.originator - OAuth originator parameter (defaults to \"pi\")\n */\nexport async function loginOpenAICodex(options: {\n onAuth: (info: { url: string; instructions?: string }) => void;\n onPrompt: (prompt: OAuthPrompt) => Promise<string>;\n onProgress?: (message: string) => void;\n onManualCodeInput?: () => Promise<string>;\n originator?: string;\n}): Promise<OAuthCredentials> {\n const state = createState();\n const server = await startLocalOAuthServer(state);\n if (server.warning) {\n options.onProgress?.(server.warning);\n }\n const { verifier, url } = await createAuthorizationFlow(server.redirectUri, state, options.originator);\n\n options.onAuth({\n url,\n instructions: server.warning\n ? `${server.warning} You can still paste the authorization code or full redirect URL manually.`\n : 'A browser window should open. Complete login to finish.',\n });\n\n let code: string | undefined;\n try {\n if (options.onManualCodeInput) {\n // Race between browser callback and manual input\n let manualCode: string | undefined;\n let manualError: Error | undefined;\n const manualPromise = options\n .onManualCodeInput()\n .then(input => {\n manualCode = input;\n server.cancelWait();\n })\n .catch(err => {\n manualError = err instanceof Error ? err : new Error(String(err));\n server.cancelWait();\n });\n\n const result = await server.waitForCode();\n\n // If manual input was cancelled, throw that error\n if (manualError) {\n throw manualError;\n }\n\n if (result?.code) {\n // Browser callback won\n code = result.code;\n } else if (manualCode) {\n // Manual input won (or callback timed out and user had entered code)\n const parsed = parseAuthorizationInput(manualCode);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n\n // If still no code, wait for manual promise to complete and try that\n if (!code) {\n await manualPromise;\n if (manualError) {\n throw manualError;\n }\n if (manualCode) {\n const parsed = parseAuthorizationInput(manualCode);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n }\n } else {\n // Original flow: wait for callback, then prompt if needed\n const result = await server.waitForCode();\n if (result?.code) {\n code = result.code;\n }\n }\n\n // Fallback to onPrompt if still no code\n if (!code) {\n const input = await options.onPrompt({\n message: 'Paste the authorization code (or full redirect URL):',\n });\n const parsed = parseAuthorizationInput(input);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n\n if (!code) {\n throw new Error('Missing authorization code');\n }\n\n const tokenResult = await exchangeAuthorizationCode(code, verifier, server.redirectUri);\n if (tokenResult.type !== 'success') {\n throw new Error('Token exchange failed');\n }\n\n const accountId = getAccountId(tokenResult.access);\n if (!accountId) {\n throw new Error('Failed to extract accountId from token');\n }\n\n return {\n access: tokenResult.access,\n refresh: tokenResult.refresh,\n expires: tokenResult.expires,\n accountId,\n };\n } finally {\n server.close();\n }\n}\n\nexport const __testing = {\n createAuthorizationFlow,\n startLocalOAuthServer,\n};\n\n/**\n * Refresh OpenAI Codex OAuth token\n */\nexport async function refreshOpenAICodexToken(refreshToken: string): Promise<OAuthCredentials> {\n const result = await refreshAccessToken(refreshToken);\n if (result.type !== 'success') {\n throw new Error('Failed to refresh OpenAI Codex token');\n }\n\n const accountId = getAccountId(result.access);\n if (!accountId) {\n throw new Error('Failed to extract accountId from token');\n }\n\n return {\n access: result.access,\n refresh: result.refresh,\n expires: result.expires,\n accountId,\n };\n}\n\nexport const openaiCodexOAuthProvider: OAuthProviderInterface = {\n id: 'openai-codex',\n name: 'ChatGPT Plus/Pro (Codex Subscription)',\n usesCallbackServer: true,\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginOpenAICodex({\n onAuth: callbacks.onAuth,\n onPrompt: callbacks.onPrompt,\n onProgress: callbacks.onProgress,\n onManualCodeInput: callbacks.onManualCodeInput,\n });\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshOpenAICodexToken(credentials.refresh);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { getAppDataDir } from '../utils/project.js';\nimport { anthropicOAuthProvider } from './providers/anthropic.js';\nimport { openaiCodexOAuthProvider } from './providers/openai-codex.js';\nimport type {\n AuthCredential,\n AuthStorageData,\n OAuthLoginCallbacks,\n OAuthProviderId,\n OAuthProviderInterface,\n} from './types.js';\n\n/**\n * Best/default models for each OAuth provider.\n * Used when auto-selecting a model after login.\n */\nexport const PROVIDER_DEFAULT_MODELS: Record<OAuthProviderId, string> = {\n anthropic: 'anthropic/claude-opus-4-6',\n 'openai-codex': 'openai/gpt-5.5',\n};\n\n// Provider registry\nconst oauthProviderRegistry = new Map<string, OAuthProviderInterface>([\n [anthropicOAuthProvider.id, anthropicOAuthProvider],\n [openaiCodexOAuthProvider.id, openaiCodexOAuthProvider],\n]);\n\n/**\n * Get an OAuth provider by ID\n */\nexport function getOAuthProvider(id: OAuthProviderId): OAuthProviderInterface | undefined {\n return oauthProviderRegistry.get(id);\n}\n\n/**\n * Get all registered OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInterface[] {\n return Array.from(oauthProviderRegistry.values());\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n private data: AuthStorageData = {};\n\n constructor(private authPath: string = join(getAppDataDir(), 'auth.json')) {\n this.reload();\n }\n\n /**\n * Reload credentials from disk.\n */\n reload(): void {\n if (!existsSync(this.authPath)) {\n this.data = {};\n return;\n }\n try {\n this.data = JSON.parse(readFileSync(this.authPath, 'utf-8'));\n } catch {\n this.data = {};\n }\n }\n\n /**\n * Save credentials to disk.\n */\n private save(): void {\n const dir = dirname(this.authPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), 'utf-8');\n chmodSync(this.authPath, 0o600);\n }\n\n /**\n * Get credential for a provider.\n */\n get(provider: string): AuthCredential | undefined {\n return this.data[provider] ?? undefined;\n }\n\n /**\n * Set credential for a provider.\n */\n set(provider: string, credential: AuthCredential): void {\n this.data[provider] = credential;\n this.save();\n }\n\n /**\n * Remove credential for a provider.\n */\n remove(provider: string): void {\n delete this.data[provider];\n this.save();\n }\n\n /**\n * List all providers with credentials.\n */\n list(): string[] {\n return Object.keys(this.data);\n }\n\n /**\n * Check if credentials exist for a provider.\n */\n has(provider: string): boolean {\n return provider in this.data;\n }\n\n /**\n * Check if logged in via OAuth for a provider.\n */\n isLoggedIn(provider: string): boolean {\n const cred = this.data[provider];\n return cred?.type === 'oauth';\n }\n\n /**\n * Check if a stored API key exists for a provider.\n * Keys are stored under `apikey:<provider>` in auth.json.\n */\n hasStoredApiKey(provider: string): boolean {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0;\n }\n\n /**\n * Get a stored API key for a provider, if any.\n */\n getStoredApiKey(provider: string): string | undefined {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0 ? cred.key : undefined;\n }\n\n /**\n * Store an API key for a provider.\n * Also sets the corresponding environment variable so model resolution can find it.\n */\n setStoredApiKey(provider: string, key: string, envVar?: string): void {\n this.set(`apikey:${provider}`, { type: 'api_key', key });\n if (envVar) {\n process.env[envVar] = key;\n }\n }\n\n /**\n * Load all stored API keys into process.env.\n * Called at startup so model resolution can find stored keys.\n * Only sets env vars that aren't already set (env vars take precedence).\n */\n loadStoredApiKeysIntoEnv(providerEnvVars: Record<string, string | undefined>): void {\n for (const [key, cred] of Object.entries(this.data)) {\n if (!key.startsWith('apikey:') || cred.type !== 'api_key' || !cred.key) continue;\n const provider = key.substring('apikey:'.length);\n const envVar = providerEnvVars[provider];\n if (envVar && !process.env[envVar]) {\n process.env[envVar] = cred.key;\n }\n }\n }\n\n /**\n * Login to an OAuth provider.\n */\n async login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n throw new Error(`Unknown OAuth provider: ${providerId}`);\n }\n\n const credentials = await provider.login(callbacks);\n this.set(providerId, { type: 'oauth', ...credentials });\n }\n\n /**\n * Logout from a provider.\n */\n logout(provider: string): void {\n this.remove(provider);\n }\n\n /**\n * Get API key for a provider, auto-refreshing OAuth tokens if needed.\n */\n async getApiKey(providerId: string): Promise<string | undefined> {\n const cred = this.data[providerId];\n\n if (cred?.type === 'api_key') {\n return cred.key;\n }\n\n if (cred?.type === 'oauth') {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n return undefined;\n }\n\n // Check if token needs refresh\n if (Date.now() >= cred.expires) {\n try {\n const newCreds = await provider.refreshToken(cred);\n this.set(providerId, { type: 'oauth', ...newCreds });\n return provider.getApiKey(newCreds);\n } catch {\n // Refresh failed - user needs to re-login\n return undefined;\n }\n }\n\n return provider.getApiKey(cred);\n }\n\n return undefined;\n }\n}\n"]}
|