@iam-brain/opencode-codex-auth 0.3.1 → 0.3.2

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 (90) hide show
  1. package/dist/index.js +2 -2
  2. package/dist/index.js.map +1 -1
  3. package/dist/lib/codex-native/accounts.d.ts +21 -0
  4. package/dist/lib/codex-native/accounts.d.ts.map +1 -0
  5. package/dist/lib/codex-native/accounts.js +203 -0
  6. package/dist/lib/codex-native/accounts.js.map +1 -0
  7. package/dist/lib/codex-native/acquire-auth.d.ts +22 -0
  8. package/dist/lib/codex-native/acquire-auth.d.ts.map +1 -0
  9. package/dist/lib/codex-native/acquire-auth.js +338 -0
  10. package/dist/lib/codex-native/acquire-auth.js.map +1 -0
  11. package/dist/lib/codex-native/auth-menu-flow.d.ts +9 -0
  12. package/dist/lib/codex-native/auth-menu-flow.d.ts.map +1 -0
  13. package/dist/lib/codex-native/auth-menu-flow.js +192 -0
  14. package/dist/lib/codex-native/auth-menu-flow.js.map +1 -0
  15. package/dist/lib/codex-native/auth-menu-quotas.d.ts +9 -0
  16. package/dist/lib/codex-native/auth-menu-quotas.d.ts.map +1 -0
  17. package/dist/lib/codex-native/auth-menu-quotas.js +111 -0
  18. package/dist/lib/codex-native/auth-menu-quotas.js.map +1 -0
  19. package/dist/lib/codex-native/catalog-sync.d.ts +28 -0
  20. package/dist/lib/codex-native/catalog-sync.d.ts.map +1 -0
  21. package/dist/lib/codex-native/catalog-sync.js +36 -0
  22. package/dist/lib/codex-native/catalog-sync.js.map +1 -0
  23. package/dist/lib/codex-native/chat-hooks.d.ts +76 -0
  24. package/dist/lib/codex-native/chat-hooks.d.ts.map +1 -0
  25. package/dist/lib/codex-native/chat-hooks.js +136 -0
  26. package/dist/lib/codex-native/chat-hooks.js.map +1 -0
  27. package/dist/lib/codex-native/oauth-auth-methods.d.ts +45 -0
  28. package/dist/lib/codex-native/oauth-auth-methods.d.ts.map +1 -0
  29. package/dist/lib/codex-native/oauth-auth-methods.js +171 -0
  30. package/dist/lib/codex-native/oauth-auth-methods.js.map +1 -0
  31. package/dist/lib/codex-native/oauth-persistence.d.ts +4 -0
  32. package/dist/lib/codex-native/oauth-persistence.d.ts.map +1 -0
  33. package/dist/lib/codex-native/oauth-persistence.js +28 -0
  34. package/dist/lib/codex-native/oauth-persistence.js.map +1 -0
  35. package/dist/lib/codex-native/oauth-server.d.ts.map +1 -1
  36. package/dist/lib/codex-native/oauth-server.js +31 -1
  37. package/dist/lib/codex-native/oauth-server.js.map +1 -1
  38. package/dist/lib/codex-native/oauth-utils.d.ts +51 -0
  39. package/dist/lib/codex-native/oauth-utils.d.ts.map +1 -0
  40. package/dist/lib/codex-native/oauth-utils.js +268 -0
  41. package/dist/lib/codex-native/oauth-utils.js.map +1 -0
  42. package/dist/lib/codex-native/openai-loader-fetch.d.ts +36 -0
  43. package/dist/lib/codex-native/openai-loader-fetch.d.ts.map +1 -0
  44. package/dist/lib/codex-native/openai-loader-fetch.js +191 -0
  45. package/dist/lib/codex-native/openai-loader-fetch.js.map +1 -0
  46. package/dist/lib/codex-native/rate-limit-snapshots.d.ts +2 -0
  47. package/dist/lib/codex-native/rate-limit-snapshots.d.ts.map +1 -0
  48. package/dist/lib/codex-native/rate-limit-snapshots.js +24 -0
  49. package/dist/lib/codex-native/rate-limit-snapshots.js.map +1 -0
  50. package/dist/lib/codex-native/request-routing.d.ts +3 -0
  51. package/dist/lib/codex-native/request-routing.d.ts.map +1 -0
  52. package/dist/lib/codex-native/request-routing.js +41 -0
  53. package/dist/lib/codex-native/request-routing.js.map +1 -0
  54. package/dist/lib/codex-native/request-transform-pipeline.d.ts +19 -0
  55. package/dist/lib/codex-native/request-transform-pipeline.d.ts.map +1 -0
  56. package/dist/lib/codex-native/request-transform-pipeline.js +24 -0
  57. package/dist/lib/codex-native/request-transform-pipeline.js.map +1 -0
  58. package/dist/lib/codex-native/request-transform.d.ts +8 -4
  59. package/dist/lib/codex-native/request-transform.d.ts.map +1 -1
  60. package/dist/lib/codex-native/request-transform.js +103 -33
  61. package/dist/lib/codex-native/request-transform.js.map +1 -1
  62. package/dist/lib/codex-native/session-affinity-state.d.ts +15 -0
  63. package/dist/lib/codex-native/session-affinity-state.d.ts.map +1 -0
  64. package/dist/lib/codex-native/session-affinity-state.js +49 -0
  65. package/dist/lib/codex-native/session-affinity-state.js.map +1 -0
  66. package/dist/lib/codex-native/session-messages.d.ts +8 -0
  67. package/dist/lib/codex-native/session-messages.d.ts.map +1 -0
  68. package/dist/lib/codex-native/session-messages.js +55 -0
  69. package/dist/lib/codex-native/session-messages.js.map +1 -0
  70. package/dist/lib/codex-native.d.ts +6 -30
  71. package/dist/lib/codex-native.d.ts.map +1 -1
  72. package/dist/lib/codex-native.js +113 -1641
  73. package/dist/lib/codex-native.js.map +1 -1
  74. package/dist/lib/config.d.ts +11 -11
  75. package/dist/lib/config.d.ts.map +1 -1
  76. package/dist/lib/config.js +109 -152
  77. package/dist/lib/config.js.map +1 -1
  78. package/dist/lib/model-catalog.d.ts +1 -0
  79. package/dist/lib/model-catalog.d.ts.map +1 -1
  80. package/dist/lib/model-catalog.js +166 -8
  81. package/dist/lib/model-catalog.js.map +1 -1
  82. package/dist/lib/request-snapshots.d.ts +2 -0
  83. package/dist/lib/request-snapshots.d.ts.map +1 -1
  84. package/dist/lib/request-snapshots.js +48 -1
  85. package/dist/lib/request-snapshots.js.map +1 -1
  86. package/dist/lib/rotation.d.ts.map +1 -1
  87. package/dist/lib/rotation.js +3 -0
  88. package/dist/lib/rotation.js.map +1 -1
  89. package/package.json +3 -2
  90. package/schemas/codex-config.schema.json +12 -43
@@ -0,0 +1,111 @@
1
+ import { extractEmailFromClaims, extractPlanFromClaims, parseJwtClaims } from "../claims";
2
+ import { loadSnapshots, saveSnapshots } from "../codex-status-storage";
3
+ import { fetchQuotaSnapshotFromBackend } from "../codex-quota-fetch";
4
+ import { defaultSnapshotsPath } from "../paths";
5
+ import { resolveRequestUserAgent } from "./client-identity";
6
+ import { resolveCodexOriginator } from "./originator";
7
+ import { hydrateAccountIdentityFromAccessClaims } from "./accounts";
8
+ import { extractAccountId, refreshAccessToken } from "./oauth-utils";
9
+ import { ensureOpenAIOAuthDomain, listOpenAIOAuthDomains, loadAuthStorage, saveAuthStorage } from "../storage";
10
+ const AUTH_MENU_QUOTA_SNAPSHOT_TTL_MS = 60_000;
11
+ const AUTH_MENU_QUOTA_FAILURE_COOLDOWN_MS = 30_000;
12
+ const AUTH_MENU_QUOTA_FETCH_TIMEOUT_MS = 5000;
13
+ export async function refreshQuotaSnapshotsForAuthMenu(input) {
14
+ const auth = await loadAuthStorage();
15
+ const snapshotPath = defaultSnapshotsPath();
16
+ const existingSnapshots = await loadSnapshots(snapshotPath).catch(() => ({}));
17
+ const snapshotUpdates = {};
18
+ for (const { mode, domain } of listOpenAIOAuthDomains(auth)) {
19
+ for (let index = 0; index < domain.accounts.length; index += 1) {
20
+ const account = domain.accounts[index];
21
+ if (!account || account.enabled === false)
22
+ continue;
23
+ hydrateAccountIdentityFromAccessClaims(account);
24
+ const identityKey = account.identityKey;
25
+ const now = Date.now();
26
+ if (identityKey) {
27
+ const cooldownUntil = input.cooldownByIdentity.get(identityKey);
28
+ if (typeof cooldownUntil === "number" && cooldownUntil > now)
29
+ continue;
30
+ const existing = existingSnapshots[identityKey];
31
+ if (existing &&
32
+ typeof existing.updatedAt === "number" &&
33
+ Number.isFinite(existing.updatedAt) &&
34
+ now - existing.updatedAt < AUTH_MENU_QUOTA_SNAPSHOT_TTL_MS) {
35
+ continue;
36
+ }
37
+ }
38
+ let accessToken = typeof account.access === "string" && account.access.length > 0 ? account.access : undefined;
39
+ const expired = typeof account.expires === "number" && Number.isFinite(account.expires) && account.expires <= now;
40
+ if ((!accessToken || expired) && account.refresh) {
41
+ try {
42
+ await saveAuthStorage(undefined, async (authFile) => {
43
+ const current = ensureOpenAIOAuthDomain(authFile, mode);
44
+ const target = current.accounts[index];
45
+ if (!target || target.enabled === false || !target.refresh)
46
+ return authFile;
47
+ const tokens = await refreshAccessToken(target.refresh);
48
+ const refreshedAt = Date.now();
49
+ const claims = parseJwtClaims(tokens.id_token ?? tokens.access_token);
50
+ target.refresh = tokens.refresh_token;
51
+ target.access = tokens.access_token;
52
+ target.expires = refreshedAt + (tokens.expires_in ?? 3600) * 1000;
53
+ target.accountId = extractAccountId(tokens) || target.accountId;
54
+ target.email = extractEmailFromClaims(claims) || target.email;
55
+ target.plan = extractPlanFromClaims(claims) || target.plan;
56
+ target.lastUsed = refreshedAt;
57
+ hydrateAccountIdentityFromAccessClaims(target);
58
+ account.refresh = target.refresh;
59
+ account.access = target.access;
60
+ account.expires = target.expires;
61
+ account.accountId = target.accountId;
62
+ account.email = target.email;
63
+ account.plan = target.plan;
64
+ account.identityKey = target.identityKey;
65
+ accessToken = target.access;
66
+ return authFile;
67
+ });
68
+ }
69
+ catch (error) {
70
+ if (identityKey) {
71
+ input.cooldownByIdentity.set(identityKey, Date.now() + AUTH_MENU_QUOTA_FAILURE_COOLDOWN_MS);
72
+ }
73
+ input.log?.debug("quota check refresh failed", {
74
+ index,
75
+ mode,
76
+ error: error instanceof Error ? error.message : String(error)
77
+ });
78
+ }
79
+ }
80
+ if (!accessToken)
81
+ continue;
82
+ if (!account.identityKey) {
83
+ hydrateAccountIdentityFromAccessClaims(account);
84
+ }
85
+ if (!account.identityKey)
86
+ continue;
87
+ const snapshot = await fetchQuotaSnapshotFromBackend({
88
+ accessToken,
89
+ accountId: account.accountId,
90
+ now: Date.now(),
91
+ modelFamily: "gpt-5.3-codex",
92
+ userAgent: resolveRequestUserAgent(input.spoofMode, resolveCodexOriginator(input.spoofMode)),
93
+ log: input.log,
94
+ timeoutMs: AUTH_MENU_QUOTA_FETCH_TIMEOUT_MS
95
+ });
96
+ if (!snapshot) {
97
+ input.cooldownByIdentity.set(account.identityKey, Date.now() + AUTH_MENU_QUOTA_FAILURE_COOLDOWN_MS);
98
+ continue;
99
+ }
100
+ input.cooldownByIdentity.delete(account.identityKey);
101
+ snapshotUpdates[account.identityKey] = snapshot;
102
+ }
103
+ }
104
+ if (Object.keys(snapshotUpdates).length === 0)
105
+ return;
106
+ await saveSnapshots(snapshotPath, (current) => ({
107
+ ...current,
108
+ ...snapshotUpdates
109
+ }));
110
+ }
111
+ //# sourceMappingURL=auth-menu-quotas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-menu-quotas.js","sourceRoot":"","sources":["../../../lib/codex-native/auth-menu-quotas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { PersonalityOption } from "../config";
2
+ import type { Logger } from "../logger";
3
+ import { type CodexModelInfo } from "../model-catalog";
4
+ import type { OpenAIAuthMode, RotationStrategy } from "../types";
5
+ type CatalogHeaders = {
6
+ originator: string;
7
+ userAgent: string;
8
+ clientVersion: string;
9
+ versionHeader: string;
10
+ openaiBeta?: string;
11
+ };
12
+ export declare function initializeCatalogSync(input: {
13
+ authMode: OpenAIAuthMode;
14
+ pidOffsetEnabled: boolean;
15
+ rotationStrategy?: RotationStrategy;
16
+ resolveCatalogHeaders: () => CatalogHeaders;
17
+ providerModels: Record<string, Record<string, unknown>>;
18
+ fallbackModels: string[];
19
+ personality?: PersonalityOption;
20
+ log?: Logger;
21
+ getLastCatalogModels: () => CodexModelInfo[] | undefined;
22
+ setLastCatalogModels: (models: CodexModelInfo[] | undefined) => void;
23
+ }): Promise<(auth: {
24
+ accessToken?: string;
25
+ accountId?: string;
26
+ }) => Promise<CodexModelInfo[] | undefined>>;
27
+ export {};
28
+ //# sourceMappingURL=catalog-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-sync.d.ts","sourceRoot":"","sources":["../../../lib/codex-native/catalog-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAA2D,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC/G,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAGhE,KAAK,cAAc,GAAG;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE;IACjD,QAAQ,EAAE,cAAc,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,qBAAqB,EAAE,MAAM,cAAc,CAAA;IAC3C,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACvD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,oBAAoB,EAAE,MAAM,cAAc,EAAE,GAAG,SAAS,CAAA;IACxD,oBAAoB,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,SAAS,KAAK,IAAI,CAAA;CACrE,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,cAAc,EAAE,GAAG,SAAS,CAAC,CAAC,CAmCzG"}
@@ -0,0 +1,36 @@
1
+ import { applyCodexCatalogToProviderModels, getCodexModelCatalog } from "../model-catalog";
2
+ import { selectCatalogAuthCandidate } from "./catalog-auth";
3
+ export async function initializeCatalogSync(input) {
4
+ const catalogAuth = await selectCatalogAuthCandidate(input.authMode, input.pidOffsetEnabled, input.rotationStrategy);
5
+ const applyCatalogModels = (models) => {
6
+ if (models) {
7
+ input.setLastCatalogModels(models);
8
+ }
9
+ applyCodexCatalogToProviderModels({
10
+ providerModels: input.providerModels,
11
+ catalogModels: models ?? input.getLastCatalogModels(),
12
+ fallbackModels: input.fallbackModels,
13
+ personality: input.personality
14
+ });
15
+ };
16
+ const initialCatalog = await getCodexModelCatalog({
17
+ accessToken: catalogAuth.accessToken,
18
+ accountId: catalogAuth.accountId,
19
+ ...input.resolveCatalogHeaders(),
20
+ onEvent: (event) => input.log?.debug("codex model catalog", event)
21
+ });
22
+ applyCatalogModels(initialCatalog);
23
+ return async (auth) => {
24
+ if (!auth.accessToken)
25
+ return undefined;
26
+ const refreshedCatalog = await getCodexModelCatalog({
27
+ accessToken: auth.accessToken,
28
+ accountId: auth.accountId,
29
+ ...input.resolveCatalogHeaders(),
30
+ onEvent: (event) => input.log?.debug("codex model catalog", event)
31
+ });
32
+ applyCatalogModels(refreshedCatalog);
33
+ return refreshedCatalog;
34
+ };
35
+ }
36
+ //# sourceMappingURL=catalog-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-sync.js","sourceRoot":"","sources":["../../../lib/codex-native/catalog-sync.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iCAAiC,EAAE,oBAAoB,EAAuB,MAAM,kBAAkB,CAAA;AAE/G,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAU3D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAW3C;IACC,MAAM,WAAW,GAAG,MAAM,0BAA0B,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;IAEpH,MAAM,kBAAkB,GAAG,CAAC,MAAoC,EAAQ,EAAE;QACxE,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;QACpC,CAAC;QACD,iCAAiC,CAAC;YAChC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,aAAa,EAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE;YACrD,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC;QAChD,WAAW,EAAE,WAAW,CAAC,WAAW;QACpC,SAAS,EAAE,WAAW,CAAC,SAAS;QAChC,GAAG,KAAK,CAAC,qBAAqB,EAAE;QAChC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC;KACnE,CAAC,CAAA;IAEF,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAElC,OAAO,KAAK,EAAE,IAAkD,EAAyC,EAAE;QACzG,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAA;QACvC,MAAM,gBAAgB,GAAG,MAAM,oBAAoB,CAAC;YAClD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,GAAG,KAAK,CAAC,qBAAqB,EAAE;YAChC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC;SACnE,CAAC,CAAA;QACF,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;QACpC,OAAO,gBAAgB,CAAA;IACzB,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1,76 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ import type { BehaviorSettings, CodexSpoofMode, PersonalityOption } from "../config";
3
+ import type { CodexModelInfo } from "../model-catalog";
4
+ import { applyCodexRuntimeDefaultsToParams } from "./request-transform";
5
+ export declare function handleChatMessageHook(input: {
6
+ hookInput: {
7
+ model?: {
8
+ providerID?: string;
9
+ };
10
+ sessionID: string;
11
+ };
12
+ output: {
13
+ parts: unknown[];
14
+ };
15
+ client: PluginInput["client"] | undefined;
16
+ }): Promise<void>;
17
+ export declare function handleChatParamsHook(input: {
18
+ hookInput: {
19
+ model: {
20
+ providerID?: string;
21
+ options?: unknown;
22
+ id: string;
23
+ api?: {
24
+ id?: string;
25
+ };
26
+ capabilities?: {
27
+ toolcall?: boolean;
28
+ };
29
+ };
30
+ message: unknown;
31
+ };
32
+ output: Parameters<typeof applyCodexRuntimeDefaultsToParams>[0]["output"];
33
+ lastCatalogModels: CodexModelInfo[] | undefined;
34
+ behaviorSettings?: BehaviorSettings;
35
+ fallbackPersonality?: PersonalityOption;
36
+ spoofMode: CodexSpoofMode;
37
+ }): Promise<void>;
38
+ export declare function handleChatHeadersHook(input: {
39
+ hookInput: {
40
+ model: {
41
+ providerID?: string;
42
+ };
43
+ sessionID: string;
44
+ };
45
+ output: {
46
+ headers: Record<string, unknown>;
47
+ };
48
+ spoofMode: CodexSpoofMode;
49
+ internalCollaborationModeHeader: string;
50
+ }): Promise<void>;
51
+ export declare function handleSessionCompactingHook(input: {
52
+ enabled: boolean;
53
+ hookInput: {
54
+ sessionID: string;
55
+ };
56
+ output: {
57
+ prompt?: string;
58
+ };
59
+ client: PluginInput["client"] | undefined;
60
+ summaryPrefixSessions: Set<string>;
61
+ compactPrompt: string;
62
+ }): Promise<void>;
63
+ export declare function handleTextCompleteHook(input: {
64
+ enabled: boolean;
65
+ hookInput: {
66
+ sessionID: string;
67
+ messageID: string;
68
+ };
69
+ output: {
70
+ text: string;
71
+ };
72
+ client: PluginInput["client"] | undefined;
73
+ summaryPrefixSessions: Set<string>;
74
+ compactSummaryPrefix: string;
75
+ }): Promise<void>;
76
+ //# sourceMappingURL=chat-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-hooks.d.ts","sourceRoot":"","sources":["../../../lib/codex-native/chat-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import { getRuntimeDefaultsForModel, resolveInstructionsForModel } from "../model-catalog";
2
+ import { applyCodexRuntimeDefaultsToParams, findCatalogModelForCandidates, getModelLookupCandidates, getModelThinkingSummariesOverride, getModelVerbosityEnabledOverride, getModelVerbosityOverride, getVariantLookupCandidates, resolvePersonalityForModel } from "./request-transform";
3
+ import { resolveRequestUserAgent } from "./client-identity";
4
+ import { resolveCodexOriginator } from "./originator";
5
+ import { asString, getMessageProviderID, isRecord, readSessionMessageInfo, sessionUsesOpenAIProvider } from "./session-messages";
6
+ function normalizeVerbositySetting(value) {
7
+ if (typeof value !== "string")
8
+ return undefined;
9
+ const normalized = value.trim().toLowerCase();
10
+ if (normalized === "default" || normalized === "low" || normalized === "medium" || normalized === "high") {
11
+ return normalized;
12
+ }
13
+ return undefined;
14
+ }
15
+ export async function handleChatMessageHook(input) {
16
+ const directProviderID = input.hookInput.model?.providerID;
17
+ const isOpenAI = directProviderID === "openai" ||
18
+ (directProviderID === undefined && (await sessionUsesOpenAIProvider(input.client, input.hookInput.sessionID)));
19
+ if (!isOpenAI)
20
+ return;
21
+ for (const part of input.output.parts) {
22
+ const partRecord = part;
23
+ if (asString(partRecord.type) !== "subtask")
24
+ continue;
25
+ if ((asString(partRecord.command) ?? "").trim().toLowerCase() !== "review")
26
+ continue;
27
+ partRecord.agent = "Codex Review";
28
+ }
29
+ }
30
+ export async function handleChatParamsHook(input) {
31
+ if (input.hookInput.model.providerID !== "openai")
32
+ return;
33
+ const modelOptions = isRecord(input.hookInput.model.options) ? input.hookInput.model.options : {};
34
+ const modelCandidates = getModelLookupCandidates({
35
+ id: input.hookInput.model.id,
36
+ api: { id: input.hookInput.model.api?.id }
37
+ });
38
+ const variantCandidates = getVariantLookupCandidates({
39
+ message: input.hookInput.message,
40
+ modelCandidates
41
+ });
42
+ const catalogModelFallback = findCatalogModelForCandidates(input.lastCatalogModels, modelCandidates);
43
+ const effectivePersonality = resolvePersonalityForModel({
44
+ behaviorSettings: input.behaviorSettings,
45
+ modelCandidates,
46
+ variantCandidates,
47
+ fallback: input.fallbackPersonality
48
+ });
49
+ const modelThinkingSummariesOverride = getModelThinkingSummariesOverride(input.behaviorSettings, modelCandidates, variantCandidates);
50
+ const modelVerbosityEnabledOverride = getModelVerbosityEnabledOverride(input.behaviorSettings, modelCandidates, variantCandidates);
51
+ const modelVerbosityOverride = getModelVerbosityOverride(input.behaviorSettings, modelCandidates, variantCandidates);
52
+ const globalBehavior = input.behaviorSettings?.global;
53
+ const globalVerbosityEnabled = typeof globalBehavior?.verbosityEnabled === "boolean" ? globalBehavior.verbosityEnabled : undefined;
54
+ const globalVerbosity = normalizeVerbositySetting(globalBehavior?.verbosity);
55
+ const catalogModelFromOptions = isRecord(modelOptions.codexCatalogModel)
56
+ ? modelOptions.codexCatalogModel
57
+ : undefined;
58
+ let renderedCatalogInstructions = catalogModelFromOptions
59
+ ? resolveInstructionsForModel(catalogModelFromOptions, effectivePersonality)
60
+ : undefined;
61
+ if (!renderedCatalogInstructions && catalogModelFallback) {
62
+ if (!catalogModelFromOptions) {
63
+ modelOptions.codexCatalogModel = catalogModelFallback;
64
+ }
65
+ renderedCatalogInstructions = resolveInstructionsForModel(catalogModelFallback, effectivePersonality);
66
+ const defaults = getRuntimeDefaultsForModel(catalogModelFallback);
67
+ if (defaults) {
68
+ modelOptions.codexRuntimeDefaults = defaults;
69
+ }
70
+ }
71
+ if (renderedCatalogInstructions) {
72
+ modelOptions.codexInstructions = renderedCatalogInstructions;
73
+ }
74
+ else {
75
+ const directModelInstructions = asString(input.hookInput.model.instructions);
76
+ if (directModelInstructions) {
77
+ modelOptions.codexInstructions = directModelInstructions;
78
+ }
79
+ else if (asString(modelOptions.codexInstructions) === undefined) {
80
+ delete modelOptions.codexInstructions;
81
+ }
82
+ }
83
+ applyCodexRuntimeDefaultsToParams({
84
+ modelOptions,
85
+ modelToolCallCapable: input.hookInput.model.capabilities?.toolcall,
86
+ thinkingSummariesOverride: modelThinkingSummariesOverride ?? globalBehavior?.thinkingSummaries,
87
+ verbosityEnabledOverride: modelVerbosityEnabledOverride ?? globalVerbosityEnabled,
88
+ verbosityOverride: modelVerbosityOverride ?? globalVerbosity,
89
+ preferCodexInstructions: input.spoofMode === "codex",
90
+ output: input.output
91
+ });
92
+ }
93
+ export async function handleChatHeadersHook(input) {
94
+ if (input.hookInput.model.providerID !== "openai")
95
+ return;
96
+ const originator = resolveCodexOriginator(input.spoofMode);
97
+ input.output.headers.originator = originator;
98
+ input.output.headers["User-Agent"] = resolveRequestUserAgent(input.spoofMode, originator);
99
+ input.output.headers.session_id = input.hookInput.sessionID;
100
+ delete input.output.headers["OpenAI-Beta"];
101
+ delete input.output.headers.conversation_id;
102
+ if (input.spoofMode !== "native") {
103
+ delete input.output.headers["x-openai-subagent"];
104
+ delete input.output.headers[input.internalCollaborationModeHeader];
105
+ }
106
+ }
107
+ export async function handleSessionCompactingHook(input) {
108
+ if (!input.enabled)
109
+ return;
110
+ if (await sessionUsesOpenAIProvider(input.client, input.hookInput.sessionID)) {
111
+ input.output.prompt = input.compactPrompt;
112
+ input.summaryPrefixSessions.add(input.hookInput.sessionID);
113
+ }
114
+ }
115
+ export async function handleTextCompleteHook(input) {
116
+ if (!input.enabled)
117
+ return;
118
+ if (!input.summaryPrefixSessions.has(input.hookInput.sessionID))
119
+ return;
120
+ const info = await readSessionMessageInfo(input.client, input.hookInput.sessionID, input.hookInput.messageID);
121
+ input.summaryPrefixSessions.delete(input.hookInput.sessionID);
122
+ if (!info)
123
+ return;
124
+ if (asString(info.role) !== "assistant")
125
+ return;
126
+ if (asString(info.agent) !== "compaction")
127
+ return;
128
+ if (info.summary !== true)
129
+ return;
130
+ if (getMessageProviderID(info) !== "openai")
131
+ return;
132
+ if (input.output.text.startsWith(input.compactSummaryPrefix))
133
+ return;
134
+ input.output.text = `${input.compactSummaryPrefix}\n${input.output.text.trimStart()}`;
135
+ }
136
+ //# sourceMappingURL=chat-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-hooks.js","sourceRoot":"","sources":["../../../lib/codex-native/chat-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { CodexSpoofMode } from "../config";
2
+ import type { OpenAIAuthMode } from "../types";
3
+ import { type PkceCodes, type TokenResponse } from "./oauth-utils";
4
+ type OAuthSuccess = {
5
+ type: "success";
6
+ refresh: string;
7
+ access: string;
8
+ expires: number;
9
+ accountId?: string;
10
+ };
11
+ type OAuthFailure = {
12
+ type: "failed";
13
+ };
14
+ type OAuthCallbackResult = OAuthSuccess | OAuthFailure;
15
+ type OAuthAuthorizePayload = {
16
+ url: string;
17
+ instructions: string;
18
+ method: "auto";
19
+ callback: () => Promise<OAuthCallbackResult>;
20
+ };
21
+ type AuthMenuResult = "add" | "exit";
22
+ type BrowserAuthorizeDeps = {
23
+ authMode: OpenAIAuthMode;
24
+ spoofMode: CodexSpoofMode;
25
+ runInteractiveAuthMenu: (options: {
26
+ allowExit: boolean;
27
+ }) => Promise<AuthMenuResult>;
28
+ startOAuthServer: () => Promise<{
29
+ redirectUri: string;
30
+ }>;
31
+ waitForOAuthCallback: (pkce: PkceCodes, state: string, authMode: OpenAIAuthMode) => Promise<TokenResponse>;
32
+ scheduleOAuthServerStop: (delayMs: number, reason: "success" | "error" | "other") => void;
33
+ persistOAuthTokens: (tokens: TokenResponse) => Promise<void>;
34
+ openAuthUrl: (url: string) => void;
35
+ shutdownGraceMs: number;
36
+ shutdownErrorGraceMs: number;
37
+ };
38
+ type HeadlessAuthorizeDeps = {
39
+ spoofMode: CodexSpoofMode;
40
+ persistOAuthTokens: (tokens: TokenResponse) => Promise<void>;
41
+ };
42
+ export declare function createBrowserOAuthAuthorize(deps: BrowserAuthorizeDeps): (inputs?: Record<string, string>) => Promise<OAuthAuthorizePayload>;
43
+ export declare function createHeadlessOAuthAuthorize(deps: HeadlessAuthorizeDeps): () => Promise<OAuthAuthorizePayload>;
44
+ export {};
45
+ //# sourceMappingURL=oauth-auth-methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-auth-methods.d.ts","sourceRoot":"","sources":["../../../lib/codex-native/oauth-auth-methods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAG9C,OAAO,EAYL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,eAAe,CAAA;AAEtB,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,KAAK,mBAAmB,GAAG,YAAY,GAAG,YAAY,CAAA;AAEtD,KAAK,qBAAqB,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAA;CAC7C,CAAA;AAED,KAAK,cAAc,GAAG,KAAK,GAAG,MAAM,CAAA;AAEpC,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,EAAE,cAAc,CAAA;IACxB,SAAS,EAAE,cAAc,CAAA;IACzB,sBAAsB,EAAE,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAA;IACpF,gBAAgB,EAAE,MAAM,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxD,oBAAoB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1G,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,KAAK,IAAI,CAAA;IACzF,kBAAkB,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;CAC7B,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAA;IACzB,kBAAkB,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7D,CAAA;AAYD,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,oBAAoB,IACtD,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,OAAO,CAAC,qBAAqB,CAAC,CA+G/E;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,qBAAqB,SACrD,OAAO,CAAC,qBAAqB,CAAC,CA6FhD"}
@@ -0,0 +1,171 @@
1
+ import { resolveRequestUserAgent } from "./client-identity";
2
+ import { resolveCodexOriginator } from "./originator";
3
+ import { buildAuthorizeUrl, CLIENT_ID, extractAccountId, fetchWithTimeout, generatePKCE, generateState, ISSUER, OAUTH_DEVICE_AUTH_TIMEOUT_MS, OAUTH_HTTP_TIMEOUT_MS, OAUTH_POLLING_SAFETY_MARGIN_MS, sleep } from "./oauth-utils";
4
+ function toOAuthSuccess(tokens) {
5
+ return {
6
+ type: "success",
7
+ refresh: tokens.refresh_token,
8
+ access: tokens.access_token,
9
+ expires: Date.now() + (tokens.expires_in ?? 3600) * 1000,
10
+ accountId: extractAccountId(tokens)
11
+ };
12
+ }
13
+ export function createBrowserOAuthAuthorize(deps) {
14
+ return async (inputs) => {
15
+ const runSingleBrowserOAuthInline = async () => {
16
+ const { redirectUri } = await deps.startOAuthServer();
17
+ const pkce = await generatePKCE();
18
+ const state = generateState();
19
+ const authUrl = buildAuthorizeUrl(redirectUri, pkce, state, deps.spoofMode === "codex" ? "codex_cli_rs" : "opencode");
20
+ const callbackPromise = deps.waitForOAuthCallback(pkce, state, deps.authMode);
21
+ deps.openAuthUrl(authUrl);
22
+ process.stdout.write(`\nGo to: ${authUrl}\n`);
23
+ process.stdout.write("Complete authorization in your browser. This window will close automatically.\n");
24
+ let authFailed = false;
25
+ try {
26
+ const tokens = await callbackPromise;
27
+ await deps.persistOAuthTokens(tokens);
28
+ process.stdout.write("\nAccount added.\n\n");
29
+ return tokens;
30
+ }
31
+ catch (error) {
32
+ authFailed = true;
33
+ const reason = error instanceof Error ? error.message : "Authorization failed";
34
+ process.stdout.write(`\nAuthorization failed: ${reason}\n\n`);
35
+ return null;
36
+ }
37
+ finally {
38
+ deps.scheduleOAuthServerStop(authFailed ? deps.shutdownErrorGraceMs : deps.shutdownGraceMs, authFailed ? "error" : "success");
39
+ }
40
+ };
41
+ const runInteractiveBrowserAuthLoop = async () => {
42
+ let lastAddedTokens;
43
+ while (true) {
44
+ const menuResult = await deps.runInteractiveAuthMenu({ allowExit: true });
45
+ if (menuResult === "exit") {
46
+ if (!lastAddedTokens) {
47
+ return {
48
+ url: "",
49
+ method: "auto",
50
+ instructions: "Login cancelled.",
51
+ callback: async () => ({ type: "failed" })
52
+ };
53
+ }
54
+ const latest = lastAddedTokens;
55
+ return {
56
+ url: "",
57
+ method: "auto",
58
+ instructions: "",
59
+ callback: async () => toOAuthSuccess(latest)
60
+ };
61
+ }
62
+ const tokens = await runSingleBrowserOAuthInline();
63
+ if (tokens) {
64
+ lastAddedTokens = tokens;
65
+ continue;
66
+ }
67
+ return {
68
+ url: "",
69
+ method: "auto",
70
+ instructions: "Authorization failed.",
71
+ callback: async () => ({ type: "failed" })
72
+ };
73
+ }
74
+ };
75
+ if (inputs && process.env.OPENCODE_NO_BROWSER !== "1" && process.stdin.isTTY && process.stdout.isTTY) {
76
+ return runInteractiveBrowserAuthLoop();
77
+ }
78
+ const { redirectUri } = await deps.startOAuthServer();
79
+ const pkce = await generatePKCE();
80
+ const state = generateState();
81
+ const authUrl = buildAuthorizeUrl(redirectUri, pkce, state, deps.spoofMode === "codex" ? "codex_cli_rs" : "opencode");
82
+ const callbackPromise = deps.waitForOAuthCallback(pkce, state, deps.authMode);
83
+ deps.openAuthUrl(authUrl);
84
+ return {
85
+ url: authUrl,
86
+ instructions: "Complete authorization in your browser. If you close the tab early, cancel (Ctrl+C) and retry.",
87
+ method: "auto",
88
+ callback: async () => {
89
+ let authFailed = false;
90
+ try {
91
+ const tokens = await callbackPromise;
92
+ await deps.persistOAuthTokens(tokens);
93
+ return toOAuthSuccess(tokens);
94
+ }
95
+ catch {
96
+ authFailed = true;
97
+ return { type: "failed" };
98
+ }
99
+ finally {
100
+ deps.scheduleOAuthServerStop(authFailed ? deps.shutdownErrorGraceMs : deps.shutdownGraceMs, authFailed ? "error" : "success");
101
+ }
102
+ }
103
+ };
104
+ };
105
+ }
106
+ export function createHeadlessOAuthAuthorize(deps) {
107
+ return async () => {
108
+ const deviceResponse = await fetchWithTimeout(`${ISSUER}/api/accounts/deviceauth/usercode`, {
109
+ method: "POST",
110
+ headers: {
111
+ "Content-Type": "application/json",
112
+ "User-Agent": resolveRequestUserAgent(deps.spoofMode, resolveCodexOriginator(deps.spoofMode))
113
+ },
114
+ body: JSON.stringify({ client_id: CLIENT_ID })
115
+ }, OAUTH_HTTP_TIMEOUT_MS);
116
+ if (!deviceResponse.ok) {
117
+ throw new Error("Failed to initiate device authorization");
118
+ }
119
+ const deviceData = (await deviceResponse.json());
120
+ const interval = Math.max(parseInt(deviceData.interval) || 5, 1) * 1000;
121
+ return {
122
+ url: `${ISSUER}/codex/device`,
123
+ instructions: `Enter code: ${deviceData.user_code}`,
124
+ method: "auto",
125
+ async callback() {
126
+ const startedAt = Date.now();
127
+ while (true) {
128
+ if (Date.now() - startedAt > OAUTH_DEVICE_AUTH_TIMEOUT_MS) {
129
+ return { type: "failed" };
130
+ }
131
+ const response = await fetchWithTimeout(`${ISSUER}/api/accounts/deviceauth/token`, {
132
+ method: "POST",
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ "User-Agent": resolveRequestUserAgent(deps.spoofMode, resolveCodexOriginator(deps.spoofMode))
136
+ },
137
+ body: JSON.stringify({
138
+ device_auth_id: deviceData.device_auth_id,
139
+ user_code: deviceData.user_code
140
+ })
141
+ }, OAUTH_HTTP_TIMEOUT_MS);
142
+ if (response.ok) {
143
+ const data = (await response.json());
144
+ const tokenResponse = await fetchWithTimeout(`${ISSUER}/oauth/token`, {
145
+ method: "POST",
146
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
147
+ body: new URLSearchParams({
148
+ grant_type: "authorization_code",
149
+ code: data.authorization_code,
150
+ redirect_uri: `${ISSUER}/deviceauth/callback`,
151
+ client_id: CLIENT_ID,
152
+ code_verifier: data.code_verifier
153
+ }).toString()
154
+ }, OAUTH_HTTP_TIMEOUT_MS);
155
+ if (!tokenResponse.ok) {
156
+ throw new Error(`Token exchange failed: ${tokenResponse.status}`);
157
+ }
158
+ const tokens = (await tokenResponse.json());
159
+ await deps.persistOAuthTokens(tokens);
160
+ return toOAuthSuccess(tokens);
161
+ }
162
+ if (response.status !== 403 && response.status !== 404) {
163
+ return { type: "failed" };
164
+ }
165
+ await sleep(interval + OAUTH_POLLING_SAFETY_MARGIN_MS);
166
+ }
167
+ }
168
+ };
169
+ };
170
+ }
171
+ //# sourceMappingURL=oauth-auth-methods.js.map