opencode-openai-codex-auth-multi 4.3.0-multiaccount.1

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/LICENSE +37 -0
  2. package/README.md +107 -0
  3. package/assets/opencode-logo-ornate-dark.svg +18 -0
  4. package/assets/readme-hero.svg +31 -0
  5. package/config/README.md +110 -0
  6. package/config/minimal-opencode.json +13 -0
  7. package/config/opencode-legacy.json +572 -0
  8. package/config/opencode-modern.json +240 -0
  9. package/dist/index.d.ts +44 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +666 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lib/accounts.d.ts +48 -0
  14. package/dist/lib/accounts.d.ts.map +1 -0
  15. package/dist/lib/accounts.js +282 -0
  16. package/dist/lib/accounts.js.map +1 -0
  17. package/dist/lib/auth/auth.d.ts +43 -0
  18. package/dist/lib/auth/auth.d.ts.map +1 -0
  19. package/dist/lib/auth/auth.js +163 -0
  20. package/dist/lib/auth/auth.js.map +1 -0
  21. package/dist/lib/auth/browser.d.ts +17 -0
  22. package/dist/lib/auth/browser.d.ts.map +1 -0
  23. package/dist/lib/auth/browser.js +76 -0
  24. package/dist/lib/auth/browser.js.map +1 -0
  25. package/dist/lib/auth/server.d.ts +10 -0
  26. package/dist/lib/auth/server.d.ts.map +1 -0
  27. package/dist/lib/auth/server.js +78 -0
  28. package/dist/lib/auth/server.js.map +1 -0
  29. package/dist/lib/cli.d.ts +8 -0
  30. package/dist/lib/cli.d.ts.map +1 -0
  31. package/dist/lib/cli.js +44 -0
  32. package/dist/lib/cli.js.map +1 -0
  33. package/dist/lib/config.d.ts +17 -0
  34. package/dist/lib/config.d.ts.map +1 -0
  35. package/dist/lib/config.js +51 -0
  36. package/dist/lib/config.js.map +1 -0
  37. package/dist/lib/constants.d.ts +67 -0
  38. package/dist/lib/constants.d.ts.map +1 -0
  39. package/dist/lib/constants.js +67 -0
  40. package/dist/lib/constants.js.map +1 -0
  41. package/dist/lib/logger.d.ts +26 -0
  42. package/dist/lib/logger.d.ts.map +1 -0
  43. package/dist/lib/logger.js +110 -0
  44. package/dist/lib/logger.js.map +1 -0
  45. package/dist/lib/oauth-success.html +712 -0
  46. package/dist/lib/prompts/codex-opencode-bridge.d.ts +19 -0
  47. package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +1 -0
  48. package/dist/lib/prompts/codex-opencode-bridge.js +152 -0
  49. package/dist/lib/prompts/codex-opencode-bridge.js.map +1 -0
  50. package/dist/lib/prompts/codex.d.ts +27 -0
  51. package/dist/lib/prompts/codex.d.ts.map +1 -0
  52. package/dist/lib/prompts/codex.js +241 -0
  53. package/dist/lib/prompts/codex.js.map +1 -0
  54. package/dist/lib/prompts/opencode-codex.d.ts +21 -0
  55. package/dist/lib/prompts/opencode-codex.d.ts.map +1 -0
  56. package/dist/lib/prompts/opencode-codex.js +91 -0
  57. package/dist/lib/prompts/opencode-codex.js.map +1 -0
  58. package/dist/lib/request/fetch-helpers.d.ts +81 -0
  59. package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
  60. package/dist/lib/request/fetch-helpers.js +321 -0
  61. package/dist/lib/request/fetch-helpers.js.map +1 -0
  62. package/dist/lib/request/helpers/input-utils.d.ts +6 -0
  63. package/dist/lib/request/helpers/input-utils.d.ts.map +1 -0
  64. package/dist/lib/request/helpers/input-utils.js +174 -0
  65. package/dist/lib/request/helpers/input-utils.js.map +1 -0
  66. package/dist/lib/request/helpers/model-map.d.ts +28 -0
  67. package/dist/lib/request/helpers/model-map.d.ts.map +1 -0
  68. package/dist/lib/request/helpers/model-map.js +109 -0
  69. package/dist/lib/request/helpers/model-map.js.map +1 -0
  70. package/dist/lib/request/request-transformer.d.ts +93 -0
  71. package/dist/lib/request/request-transformer.d.ts.map +1 -0
  72. package/dist/lib/request/request-transformer.js +403 -0
  73. package/dist/lib/request/request-transformer.js.map +1 -0
  74. package/dist/lib/request/response-handler.d.ts +14 -0
  75. package/dist/lib/request/response-handler.d.ts.map +1 -0
  76. package/dist/lib/request/response-handler.js +90 -0
  77. package/dist/lib/request/response-handler.js.map +1 -0
  78. package/dist/lib/storage.d.ts +23 -0
  79. package/dist/lib/storage.d.ts.map +1 -0
  80. package/dist/lib/storage.js +153 -0
  81. package/dist/lib/storage.js.map +1 -0
  82. package/dist/lib/types.d.ts +170 -0
  83. package/dist/lib/types.d.ts.map +1 -0
  84. package/dist/lib/types.js +2 -0
  85. package/dist/lib/types.js.map +1 -0
  86. package/package.json +71 -0
  87. package/scripts/copy-oauth-success.js +37 -0
  88. package/scripts/install-opencode-codex-auth.js +193 -0
  89. package/scripts/test-all-models.sh +260 -0
  90. package/scripts/validate-model-map.sh +97 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Browser utilities for OAuth flow
3
+ * Handles platform-specific browser opening
4
+ */
5
+ import { spawn } from "node:child_process";
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { PLATFORM_OPENERS } from "../constants.js";
9
+ /**
10
+ * Gets the platform-specific command to open a URL in the default browser
11
+ * @returns Browser opener command for the current platform
12
+ */
13
+ export function getBrowserOpener() {
14
+ const platform = process.platform;
15
+ if (platform === "darwin")
16
+ return PLATFORM_OPENERS.darwin;
17
+ if (platform === "win32")
18
+ return PLATFORM_OPENERS.win32;
19
+ return PLATFORM_OPENERS.linux;
20
+ }
21
+ function commandExists(command) {
22
+ if (!command)
23
+ return false;
24
+ // "start" is a shell builtin on Windows; rely on shell execution
25
+ if (process.platform === "win32" && command.toLowerCase() === "start") {
26
+ return true;
27
+ }
28
+ const pathValue = process.env.PATH || "";
29
+ const entries = pathValue.split(path.delimiter).filter(Boolean);
30
+ if (entries.length === 0)
31
+ return false;
32
+ if (process.platform === "win32") {
33
+ const pathext = (process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM")
34
+ .split(";")
35
+ .filter(Boolean);
36
+ for (const entry of entries) {
37
+ for (const ext of pathext) {
38
+ const candidate = path.join(entry, `${command}${ext}`);
39
+ if (fs.existsSync(candidate))
40
+ return true;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ for (const entry of entries) {
46
+ const candidate = path.join(entry, command);
47
+ if (fs.existsSync(candidate))
48
+ return true;
49
+ }
50
+ return false;
51
+ }
52
+ /**
53
+ * Opens a URL in the default browser
54
+ * Silently fails if browser cannot be opened (user can copy URL manually)
55
+ * @param url - URL to open
56
+ * @returns True if a browser launch was attempted
57
+ */
58
+ export function openBrowserUrl(url) {
59
+ try {
60
+ const opener = getBrowserOpener();
61
+ if (!commandExists(opener)) {
62
+ return false;
63
+ }
64
+ const child = spawn(opener, [url], {
65
+ stdio: "ignore",
66
+ shell: process.platform === "win32",
67
+ });
68
+ child.on("error", () => { });
69
+ return true;
70
+ }
71
+ catch (error) {
72
+ // Silently fail - user can manually open the URL from instructions
73
+ return false;
74
+ }
75
+ }
76
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../lib/auth/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,gBAAgB,CAAC,MAAM,CAAC;IAC1D,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC;IACxD,OAAO,gBAAgB,CAAC,KAAK,CAAC;AAC/B,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,iEAAiE;IACjE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,qBAAqB,CAAC;aAC5D,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,OAAO,CAAC,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC7B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,OAAO,GAAG,GAAG,EAAE,CAAC,CAAC;gBACvD,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;oBAAE,OAAO,IAAI,CAAC;YAC3C,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE;YAClC,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACnC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,mEAAmE;QACnE,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { OAuthServerInfo } from "../types.js";
2
+ /**
3
+ * Start a small local HTTP server that waits for /auth/callback and returns the code
4
+ * @param options - OAuth state for validation
5
+ * @returns Promise that resolves to server info
6
+ */
7
+ export declare function startLocalOAuthServer({ state }: {
8
+ state: string;
9
+ }): Promise<OAuthServerInfo>;
10
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../lib/auth/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAkE5F"}
@@ -0,0 +1,78 @@
1
+ import http from "node:http";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ // Resolve path to oauth-success.html (one level up from auth/ subfolder)
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const successHtml = fs.readFileSync(path.join(__dirname, "..", "oauth-success.html"), "utf-8");
8
+ /**
9
+ * Start a small local HTTP server that waits for /auth/callback and returns the code
10
+ * @param options - OAuth state for validation
11
+ * @returns Promise that resolves to server info
12
+ */
13
+ export function startLocalOAuthServer({ state }) {
14
+ const server = http.createServer((req, res) => {
15
+ try {
16
+ const url = new URL(req.url || "", "http://localhost");
17
+ if (url.pathname !== "/auth/callback") {
18
+ res.statusCode = 404;
19
+ res.end("Not found");
20
+ return;
21
+ }
22
+ if (url.searchParams.get("state") !== state) {
23
+ res.statusCode = 400;
24
+ res.end("State mismatch");
25
+ return;
26
+ }
27
+ const code = url.searchParams.get("code");
28
+ if (!code) {
29
+ res.statusCode = 400;
30
+ res.end("Missing authorization code");
31
+ return;
32
+ }
33
+ res.statusCode = 200;
34
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
35
+ res.end(successHtml);
36
+ server._lastCode = code;
37
+ }
38
+ catch {
39
+ res.statusCode = 500;
40
+ res.end("Internal error");
41
+ }
42
+ });
43
+ return new Promise((resolve) => {
44
+ server
45
+ .listen(1455, "127.0.0.1", () => {
46
+ resolve({
47
+ port: 1455,
48
+ ready: true,
49
+ close: () => server.close(),
50
+ waitForCode: async () => {
51
+ const poll = () => new Promise((r) => setTimeout(r, 100));
52
+ for (let i = 0; i < 600; i++) {
53
+ const lastCode = server._lastCode;
54
+ if (lastCode)
55
+ return { code: lastCode };
56
+ await poll();
57
+ }
58
+ return null;
59
+ },
60
+ });
61
+ })
62
+ .on("error", (err) => {
63
+ console.error("[openai-codex-plugin] Failed to bind http://127.0.0.1:1455 (", err?.code, ") Falling back to manual paste.");
64
+ resolve({
65
+ port: 1455,
66
+ ready: false,
67
+ close: () => {
68
+ try {
69
+ server.close();
70
+ }
71
+ catch { }
72
+ },
73
+ waitForCode: async () => null,
74
+ });
75
+ });
76
+ });
77
+ }
78
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../lib/auth/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function promptAddAnotherAccount(currentCount: number): Promise<boolean>;
2
+ export type LoginMode = "add" | "fresh";
3
+ export interface ExistingAccountInfo {
4
+ accountId?: string;
5
+ index: number;
6
+ }
7
+ export declare function promptLoginMode(existingAccounts: ExistingAccountInfo[]): Promise<LoginMode>;
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../lib/cli.ts"],"names":[],"mappings":"AAGA,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAQD,wBAAsB,eAAe,CACnC,gBAAgB,EAAE,mBAAmB,EAAE,GACtC,OAAO,CAAC,SAAS,CAAC,CAyBpB"}
@@ -0,0 +1,44 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { stdin as input, stdout as output } from "node:process";
3
+ export async function promptAddAnotherAccount(currentCount) {
4
+ const rl = createInterface({ input, output });
5
+ try {
6
+ const answer = await rl.question(`Add another account? (${currentCount} added) (y/n): `);
7
+ const normalized = answer.trim().toLowerCase();
8
+ return normalized === "y" || normalized === "yes";
9
+ }
10
+ finally {
11
+ rl.close();
12
+ }
13
+ }
14
+ function formatAccountLabel(accountId, index) {
15
+ if (!accountId)
16
+ return `Account ${index + 1}`;
17
+ const suffix = accountId.length > 6 ? accountId.slice(-6) : accountId;
18
+ return `Account ${index + 1} (${suffix})`;
19
+ }
20
+ export async function promptLoginMode(existingAccounts) {
21
+ const rl = createInterface({ input, output });
22
+ try {
23
+ console.log(`\n${existingAccounts.length} account(s) saved:`);
24
+ for (const account of existingAccounts) {
25
+ console.log(` ${formatAccountLabel(account.accountId, account.index)}`);
26
+ }
27
+ console.log("");
28
+ while (true) {
29
+ const answer = await rl.question("(a)dd new account(s) or (f)resh start? [a/f]: ");
30
+ const normalized = answer.trim().toLowerCase();
31
+ if (normalized === "a" || normalized === "add") {
32
+ return "add";
33
+ }
34
+ if (normalized === "f" || normalized === "fresh") {
35
+ return "fresh";
36
+ }
37
+ console.log("Please enter 'a' to add accounts or 'f' to start fresh.");
38
+ }
39
+ }
40
+ finally {
41
+ rl.close();
42
+ }
43
+ }
44
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../lib/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAAoB;IAEpB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,yBAAyB,YAAY,iBAAiB,CACvD,CAAC;QACF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,CAAC;IACpD,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AASD,SAAS,kBAAkB,CAAC,SAA6B,EAAE,KAAa;IACtE,IAAI,CAAC,SAAS;QAAE,OAAO,WAAW,KAAK,GAAG,CAAC,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,OAAO,WAAW,KAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,gBAAuC;IAEvC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,gBAAgB,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAC9D,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,KAAK,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,gDAAgD,CACjD,CAAC;YACF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;gBAC/C,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;gBACjD,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { PluginConfig } from "./types.js";
2
+ /**
3
+ * Load plugin configuration from ~/.opencode/openai-codex-auth-config.json
4
+ * Falls back to defaults if file doesn't exist or is invalid
5
+ *
6
+ * @returns Plugin configuration
7
+ */
8
+ export declare function loadPluginConfig(): PluginConfig;
9
+ /**
10
+ * Get the effective CODEX_MODE setting
11
+ * Priority: environment variable > config file > default (true)
12
+ *
13
+ * @param pluginConfig - Plugin configuration from file
14
+ * @returns True if CODEX_MODE should be enabled
15
+ */
16
+ export declare function getCodexMode(pluginConfig: PluginConfig): boolean;
17
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAY/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAqB/C;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAQhE"}
@@ -0,0 +1,51 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ const CONFIG_PATH = join(homedir(), ".opencode", "openai-codex-auth-config.json");
5
+ /**
6
+ * Default plugin configuration
7
+ * CODEX_MODE is enabled by default for better Codex CLI parity
8
+ */
9
+ const DEFAULT_CONFIG = {
10
+ codexMode: true,
11
+ };
12
+ /**
13
+ * Load plugin configuration from ~/.opencode/openai-codex-auth-config.json
14
+ * Falls back to defaults if file doesn't exist or is invalid
15
+ *
16
+ * @returns Plugin configuration
17
+ */
18
+ export function loadPluginConfig() {
19
+ try {
20
+ if (!existsSync(CONFIG_PATH)) {
21
+ return DEFAULT_CONFIG;
22
+ }
23
+ const fileContent = readFileSync(CONFIG_PATH, "utf-8");
24
+ const userConfig = JSON.parse(fileContent);
25
+ // Merge with defaults
26
+ return {
27
+ ...DEFAULT_CONFIG,
28
+ ...userConfig,
29
+ };
30
+ }
31
+ catch (error) {
32
+ console.warn(`[openai-codex-plugin] Failed to load config from ${CONFIG_PATH}:`, error.message);
33
+ return DEFAULT_CONFIG;
34
+ }
35
+ }
36
+ /**
37
+ * Get the effective CODEX_MODE setting
38
+ * Priority: environment variable > config file > default (true)
39
+ *
40
+ * @param pluginConfig - Plugin configuration from file
41
+ * @returns True if CODEX_MODE should be enabled
42
+ */
43
+ export function getCodexMode(pluginConfig) {
44
+ // Environment variable takes precedence
45
+ if (process.env.CODEX_MODE !== undefined) {
46
+ return process.env.CODEX_MODE === "1";
47
+ }
48
+ // Use config setting (defaults to true)
49
+ return pluginConfig.codexMode ?? true;
50
+ }
51
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,+BAA+B,CAAC,CAAC;AAElF;;;GAGG;AACH,MAAM,cAAc,GAAiB;IACpC,SAAS,EAAE,IAAI;CACf,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB;IAC/B,IAAI,CAAC;QACJ,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9B,OAAO,cAAc,CAAC;QACvB,CAAC;QAED,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAA0B,CAAC;QAEpE,sBAAsB;QACtB,OAAO;YACN,GAAG,cAAc;YACjB,GAAG,UAAU;SACb,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CACX,oDAAoD,WAAW,GAAG,EACjE,KAAe,CAAC,OAAO,CACxB,CAAC;QACF,OAAO,cAAc,CAAC;IACvB,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,YAA0B;IACtD,wCAAwC;IACxC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC;IACvC,CAAC;IAED,wCAAwC;IACxC,OAAO,YAAY,CAAC,SAAS,IAAI,IAAI,CAAC;AACvC,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Constants used throughout the plugin
3
+ * Centralized for easy maintenance and configuration
4
+ */
5
+ /** Plugin identifier for logging and error messages */
6
+ export declare const PLUGIN_NAME = "openai-codex-plugin";
7
+ /** Base URL for ChatGPT backend API */
8
+ export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
9
+ /** Dummy API key used for OpenAI SDK (actual auth via OAuth) */
10
+ export declare const DUMMY_API_KEY = "chatgpt-oauth";
11
+ /** Provider ID for opencode configuration */
12
+ export declare const PROVIDER_ID = "openai";
13
+ /** HTTP Status Codes */
14
+ export declare const HTTP_STATUS: {
15
+ readonly OK: 200;
16
+ readonly UNAUTHORIZED: 401;
17
+ readonly NOT_FOUND: 404;
18
+ readonly TOO_MANY_REQUESTS: 429;
19
+ };
20
+ /** OpenAI-specific headers */
21
+ export declare const OPENAI_HEADERS: {
22
+ readonly BETA: "OpenAI-Beta";
23
+ readonly ACCOUNT_ID: "chatgpt-account-id";
24
+ readonly ORIGINATOR: "originator";
25
+ readonly SESSION_ID: "session_id";
26
+ readonly CONVERSATION_ID: "conversation_id";
27
+ };
28
+ /** OpenAI-specific header values */
29
+ export declare const OPENAI_HEADER_VALUES: {
30
+ readonly BETA_RESPONSES: "responses=experimental";
31
+ readonly ORIGINATOR_CODEX: "codex_cli_rs";
32
+ };
33
+ /** URL path segments */
34
+ export declare const URL_PATHS: {
35
+ readonly RESPONSES: "/responses";
36
+ readonly CODEX_RESPONSES: "/codex/responses";
37
+ };
38
+ /** JWT claim path for ChatGPT account ID */
39
+ export declare const JWT_CLAIM_PATH: "https://api.openai.com/auth";
40
+ /** Error messages */
41
+ export declare const ERROR_MESSAGES: {
42
+ readonly NO_ACCOUNT_ID: "Failed to extract accountId from token";
43
+ readonly TOKEN_REFRESH_FAILED: "Failed to refresh token, authentication required";
44
+ readonly REQUEST_PARSE_ERROR: "Error parsing request";
45
+ };
46
+ /** Log stages for request logging */
47
+ export declare const LOG_STAGES: {
48
+ readonly BEFORE_TRANSFORM: "before-transform";
49
+ readonly AFTER_TRANSFORM: "after-transform";
50
+ readonly RESPONSE: "response";
51
+ readonly ERROR_RESPONSE: "error-response";
52
+ };
53
+ /** Platform-specific browser opener commands */
54
+ export declare const PLATFORM_OPENERS: {
55
+ readonly darwin: "open";
56
+ readonly win32: "start";
57
+ readonly linux: "xdg-open";
58
+ };
59
+ /** OAuth authorization labels */
60
+ export declare const AUTH_LABELS: {
61
+ readonly OAUTH: "ChatGPT Plus/Pro (Codex Subscription)";
62
+ readonly OAUTH_MANUAL: "ChatGPT Plus/Pro (Manual URL Paste)";
63
+ readonly API_KEY: "Manually enter API Key";
64
+ readonly INSTRUCTIONS: "A browser window should open. If it doesn't, copy the URL and open it manually.";
65
+ readonly INSTRUCTIONS_MANUAL: "After logging in, copy the full redirect URL and paste it here.";
66
+ };
67
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,eAAO,MAAM,WAAW,wBAAwB,CAAC;AAEjD,uCAAuC;AACvC,eAAO,MAAM,cAAc,oCAAoC,CAAC;AAEhE,gEAAgE;AAChE,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,6CAA6C;AAC7C,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,wBAAwB;AACxB,eAAO,MAAM,WAAW;;;;;CAKd,CAAC;AAEX,8BAA8B;AAC9B,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AAEX,oCAAoC;AACpC,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX,wBAAwB;AACxB,eAAO,MAAM,SAAS;;;CAGZ,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,cAAc,EAAG,6BAAsC,CAAC;AAErE,qBAAqB;AACrB,eAAO,MAAM,cAAc;;;;CAIjB,CAAC;AAEX,qCAAqC;AACrC,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,iCAAiC;AACjC,eAAO,MAAM,WAAW;;;;;;CAQd,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Constants used throughout the plugin
3
+ * Centralized for easy maintenance and configuration
4
+ */
5
+ /** Plugin identifier for logging and error messages */
6
+ export const PLUGIN_NAME = "openai-codex-plugin";
7
+ /** Base URL for ChatGPT backend API */
8
+ export const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
9
+ /** Dummy API key used for OpenAI SDK (actual auth via OAuth) */
10
+ export const DUMMY_API_KEY = "chatgpt-oauth";
11
+ /** Provider ID for opencode configuration */
12
+ export const PROVIDER_ID = "openai";
13
+ /** HTTP Status Codes */
14
+ export const HTTP_STATUS = {
15
+ OK: 200,
16
+ UNAUTHORIZED: 401,
17
+ NOT_FOUND: 404,
18
+ TOO_MANY_REQUESTS: 429,
19
+ };
20
+ /** OpenAI-specific headers */
21
+ export const OPENAI_HEADERS = {
22
+ BETA: "OpenAI-Beta",
23
+ ACCOUNT_ID: "chatgpt-account-id",
24
+ ORIGINATOR: "originator",
25
+ SESSION_ID: "session_id",
26
+ CONVERSATION_ID: "conversation_id",
27
+ };
28
+ /** OpenAI-specific header values */
29
+ export const OPENAI_HEADER_VALUES = {
30
+ BETA_RESPONSES: "responses=experimental",
31
+ ORIGINATOR_CODEX: "codex_cli_rs",
32
+ };
33
+ /** URL path segments */
34
+ export const URL_PATHS = {
35
+ RESPONSES: "/responses",
36
+ CODEX_RESPONSES: "/codex/responses",
37
+ };
38
+ /** JWT claim path for ChatGPT account ID */
39
+ export const JWT_CLAIM_PATH = "https://api.openai.com/auth";
40
+ /** Error messages */
41
+ export const ERROR_MESSAGES = {
42
+ NO_ACCOUNT_ID: "Failed to extract accountId from token",
43
+ TOKEN_REFRESH_FAILED: "Failed to refresh token, authentication required",
44
+ REQUEST_PARSE_ERROR: "Error parsing request",
45
+ };
46
+ /** Log stages for request logging */
47
+ export const LOG_STAGES = {
48
+ BEFORE_TRANSFORM: "before-transform",
49
+ AFTER_TRANSFORM: "after-transform",
50
+ RESPONSE: "response",
51
+ ERROR_RESPONSE: "error-response",
52
+ };
53
+ /** Platform-specific browser opener commands */
54
+ export const PLATFORM_OPENERS = {
55
+ darwin: "open",
56
+ win32: "start",
57
+ linux: "xdg-open",
58
+ };
59
+ /** OAuth authorization labels */
60
+ export const AUTH_LABELS = {
61
+ OAUTH: "ChatGPT Plus/Pro (Codex Subscription)",
62
+ OAUTH_MANUAL: "ChatGPT Plus/Pro (Manual URL Paste)",
63
+ API_KEY: "Manually enter API Key",
64
+ INSTRUCTIONS: "A browser window should open. If it doesn't, copy the URL and open it manually.",
65
+ INSTRUCTIONS_MANUAL: "After logging in, copy the full redirect URL and paste it here.",
66
+ };
67
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAEjD,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,iCAAiC,CAAC;AAEhE,gEAAgE;AAChE,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C,6CAA6C;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEpC,wBAAwB;AACxB,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,EAAE,EAAE,GAAG;IACP,YAAY,EAAE,GAAG;IACjB,SAAS,EAAE,GAAG;IACd,iBAAiB,EAAE,GAAG;CACb,CAAC;AAEX,8BAA8B;AAC9B,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,IAAI,EAAE,aAAa;IACnB,UAAU,EAAE,oBAAoB;IAChC,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,YAAY;IACxB,eAAe,EAAE,iBAAiB;CACzB,CAAC;AAEX,oCAAoC;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG;IACnC,cAAc,EAAE,wBAAwB;IACxC,gBAAgB,EAAE,cAAc;CACvB,CAAC;AAEX,wBAAwB;AACxB,MAAM,CAAC,MAAM,SAAS,GAAG;IACxB,SAAS,EAAE,YAAY;IACvB,eAAe,EAAE,kBAAkB;CAC1B,CAAC;AAEX,4CAA4C;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAG,6BAAsC,CAAC;AAErE,qBAAqB;AACrB,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,aAAa,EAAE,wCAAwC;IACvD,oBAAoB,EAAE,kDAAkD;IACxE,mBAAmB,EAAE,uBAAuB;CACnC,CAAC;AAEX,qCAAqC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG;IACzB,gBAAgB,EAAE,kBAAkB;IACpC,eAAe,EAAE,iBAAiB;IAClC,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;CACvB,CAAC;AAEX,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC/B,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,UAAU;CACR,CAAC;AAEX,iCAAiC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG;IAC1B,KAAK,EAAE,uCAAuC;IAC9C,YAAY,EAAE,qCAAqC;IACnD,OAAO,EAAE,wBAAwB;IACjC,YAAY,EACX,iFAAiF;IAClF,mBAAmB,EAClB,iEAAiE;CACzD,CAAC"}
@@ -0,0 +1,26 @@
1
+ export declare const LOGGING_ENABLED: boolean;
2
+ export declare const DEBUG_ENABLED: boolean;
3
+ /**
4
+ * Log request data to file (only when LOGGING_ENABLED is true)
5
+ * @param stage - The stage of the request (e.g., "before-transform", "after-transform")
6
+ * @param data - The data to log
7
+ */
8
+ export declare function logRequest(stage: string, data: Record<string, unknown>): void;
9
+ /**
10
+ * Log debug information (only when DEBUG_ENABLED is true)
11
+ * @param message - Debug message
12
+ * @param data - Optional data to log
13
+ */
14
+ export declare function logDebug(message: string, data?: unknown): void;
15
+ /**
16
+ * Log warning (always enabled for important issues)
17
+ * @param message - Warning message
18
+ * @param data - Optional data to log
19
+ */
20
+ export declare function logWarn(message: string, data?: unknown): void;
21
+ export declare function createLogger(scope: string): {
22
+ info(message: string, data?: unknown): void;
23
+ warn(message: string, data?: unknown): void;
24
+ error(message: string, data?: unknown): void;
25
+ };
26
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,eAAe,SAAoD,CAAC;AACjF,eAAO,MAAM,aAAa,SAA4D,CAAC;AAavF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiC7E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAQ9D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAO7D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM;kBAGZ,MAAM,SAAS,OAAO;kBAQtB,MAAM,SAAS,OAAO;mBAQrB,MAAM,SAAS,OAAO;EAQpD"}
@@ -0,0 +1,110 @@
1
+ import { writeFileSync, mkdirSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { PLUGIN_NAME } from "./constants.js";
5
+ // Logging configuration
6
+ export const LOGGING_ENABLED = process.env.ENABLE_PLUGIN_REQUEST_LOGGING === "1";
7
+ export const DEBUG_ENABLED = process.env.DEBUG_CODEX_PLUGIN === "1" || LOGGING_ENABLED;
8
+ const LOG_DIR = join(homedir(), ".opencode", "logs", "codex-plugin");
9
+ // Log startup message about logging state
10
+ if (LOGGING_ENABLED) {
11
+ console.log(`[${PLUGIN_NAME}] Request logging ENABLED - logs will be saved to:`, LOG_DIR);
12
+ }
13
+ if (DEBUG_ENABLED && !LOGGING_ENABLED) {
14
+ console.log(`[${PLUGIN_NAME}] Debug logging ENABLED`);
15
+ }
16
+ let requestCounter = 0;
17
+ /**
18
+ * Log request data to file (only when LOGGING_ENABLED is true)
19
+ * @param stage - The stage of the request (e.g., "before-transform", "after-transform")
20
+ * @param data - The data to log
21
+ */
22
+ export function logRequest(stage, data) {
23
+ // Only log if explicitly enabled via environment variable
24
+ if (!LOGGING_ENABLED)
25
+ return;
26
+ // Ensure log directory exists on first log
27
+ if (!existsSync(LOG_DIR)) {
28
+ mkdirSync(LOG_DIR, { recursive: true });
29
+ }
30
+ const timestamp = new Date().toISOString();
31
+ const requestId = ++requestCounter;
32
+ const filename = join(LOG_DIR, `request-${requestId}-${stage}.json`);
33
+ try {
34
+ writeFileSync(filename, JSON.stringify({
35
+ timestamp,
36
+ requestId,
37
+ stage,
38
+ ...data,
39
+ }, null, 2), "utf8");
40
+ console.log(`[${PLUGIN_NAME}] Logged ${stage} to ${filename}`);
41
+ }
42
+ catch (e) {
43
+ const error = e;
44
+ console.error(`[${PLUGIN_NAME}] Failed to write log:`, error.message);
45
+ }
46
+ }
47
+ /**
48
+ * Log debug information (only when DEBUG_ENABLED is true)
49
+ * @param message - Debug message
50
+ * @param data - Optional data to log
51
+ */
52
+ export function logDebug(message, data) {
53
+ if (!DEBUG_ENABLED)
54
+ return;
55
+ if (data !== undefined) {
56
+ console.log(`[${PLUGIN_NAME}] ${message}`, data);
57
+ }
58
+ else {
59
+ console.log(`[${PLUGIN_NAME}] ${message}`);
60
+ }
61
+ }
62
+ /**
63
+ * Log warning (always enabled for important issues)
64
+ * @param message - Warning message
65
+ * @param data - Optional data to log
66
+ */
67
+ export function logWarn(message, data) {
68
+ if (!DEBUG_ENABLED && !LOGGING_ENABLED)
69
+ return;
70
+ if (data !== undefined) {
71
+ console.warn(`[${PLUGIN_NAME}] ${message}`, data);
72
+ }
73
+ else {
74
+ console.warn(`[${PLUGIN_NAME}] ${message}`);
75
+ }
76
+ }
77
+ export function createLogger(scope) {
78
+ const prefix = `[${PLUGIN_NAME}:${scope}]`;
79
+ return {
80
+ info(message, data) {
81
+ if (!DEBUG_ENABLED && !LOGGING_ENABLED)
82
+ return;
83
+ if (data !== undefined) {
84
+ console.log(`${prefix} ${message}`, data);
85
+ }
86
+ else {
87
+ console.log(`${prefix} ${message}`);
88
+ }
89
+ },
90
+ warn(message, data) {
91
+ if (!DEBUG_ENABLED && !LOGGING_ENABLED)
92
+ return;
93
+ if (data !== undefined) {
94
+ console.warn(`${prefix} ${message}`, data);
95
+ }
96
+ else {
97
+ console.warn(`${prefix} ${message}`);
98
+ }
99
+ },
100
+ error(message, data) {
101
+ if (data !== undefined) {
102
+ console.error(`${prefix} ${message}`, data);
103
+ }
104
+ else {
105
+ console.error(`${prefix} ${message}`);
106
+ }
107
+ },
108
+ };
109
+ }
110
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"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"}