opencode-openai-codex-multi-auth 4.4.0
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/LICENSE +37 -0
- package/README.md +89 -0
- package/assets/openai-codex-auth-config.schema.json +63 -0
- package/assets/opencode-logo-ornate-dark.svg +18 -0
- package/assets/readme-hero.svg +31 -0
- package/config/README.md +103 -0
- package/config/minimal-opencode.json +12 -0
- package/config/opencode-legacy.json +571 -0
- package/config/opencode-modern.json +239 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +564 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/accounts.d.ts +58 -0
- package/dist/lib/accounts.d.ts.map +1 -0
- package/dist/lib/accounts.js +405 -0
- package/dist/lib/accounts.js.map +1 -0
- package/dist/lib/auth/auth.d.ts +43 -0
- package/dist/lib/auth/auth.d.ts.map +1 -0
- package/dist/lib/auth/auth.js +163 -0
- package/dist/lib/auth/auth.js.map +1 -0
- package/dist/lib/auth/browser.d.ts +17 -0
- package/dist/lib/auth/browser.d.ts.map +1 -0
- package/dist/lib/auth/browser.js +76 -0
- package/dist/lib/auth/browser.js.map +1 -0
- package/dist/lib/auth/server.d.ts +10 -0
- package/dist/lib/auth/server.d.ts.map +1 -0
- package/dist/lib/auth/server.js +78 -0
- package/dist/lib/auth/server.js.map +1 -0
- package/dist/lib/cli.d.ts +8 -0
- package/dist/lib/cli.d.ts.map +1 -0
- package/dist/lib/cli.js +36 -0
- package/dist/lib/cli.js.map +1 -0
- package/dist/lib/config.d.ts +25 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +112 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +67 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +67 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/logger.d.ts +21 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +77 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/oauth-success.html +712 -0
- package/dist/lib/prompts/codex-opencode-bridge.d.ts +19 -0
- package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +1 -0
- package/dist/lib/prompts/codex-opencode-bridge.js +152 -0
- package/dist/lib/prompts/codex-opencode-bridge.js.map +1 -0
- package/dist/lib/prompts/codex.d.ts +28 -0
- package/dist/lib/prompts/codex.d.ts.map +1 -0
- package/dist/lib/prompts/codex.js +248 -0
- package/dist/lib/prompts/codex.js.map +1 -0
- package/dist/lib/prompts/opencode-codex.d.ts +21 -0
- package/dist/lib/prompts/opencode-codex.d.ts.map +1 -0
- package/dist/lib/prompts/opencode-codex.js +91 -0
- package/dist/lib/prompts/opencode-codex.js.map +1 -0
- package/dist/lib/request/fetch-helpers.d.ts +73 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
- package/dist/lib/request/fetch-helpers.js +221 -0
- package/dist/lib/request/fetch-helpers.js.map +1 -0
- package/dist/lib/request/helpers/input-utils.d.ts +6 -0
- package/dist/lib/request/helpers/input-utils.d.ts.map +1 -0
- package/dist/lib/request/helpers/input-utils.js +174 -0
- package/dist/lib/request/helpers/input-utils.js.map +1 -0
- package/dist/lib/request/helpers/model-map.d.ts +28 -0
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -0
- package/dist/lib/request/helpers/model-map.js +109 -0
- package/dist/lib/request/helpers/model-map.js.map +1 -0
- package/dist/lib/request/request-transformer.d.ts +93 -0
- package/dist/lib/request/request-transformer.d.ts.map +1 -0
- package/dist/lib/request/request-transformer.js +403 -0
- package/dist/lib/request/request-transformer.js.map +1 -0
- package/dist/lib/request/response-handler.d.ts +14 -0
- package/dist/lib/request/response-handler.d.ts.map +1 -0
- package/dist/lib/request/response-handler.js +88 -0
- package/dist/lib/request/response-handler.js.map +1 -0
- package/dist/lib/storage.d.ts +5 -0
- package/dist/lib/storage.d.ts.map +1 -0
- package/dist/lib/storage.js +46 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/types.d.ts +236 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +77 -0
- package/scripts/install-opencode-codex-auth.js +450 -0
- package/scripts/test-all-models.sh +259 -0
- package/scripts/validate-model-map.sh +97 -0
|
@@ -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,21 @@
|
|
|
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
|
+
//# 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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"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"}
|