@iam-brain/opencode-codex-auth 1.2.4 → 1.3.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/README.md +42 -83
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -18
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts-tools.d.ts.map +1 -1
- package/dist/lib/accounts-tools.js +112 -29
- package/dist/lib/accounts-tools.js.map +1 -1
- package/dist/lib/cache-io.d.ts.map +1 -1
- package/dist/lib/cache-io.js +6 -1
- package/dist/lib/cache-io.js.map +1 -1
- package/dist/lib/codex-native/accounts.d.ts.map +1 -1
- package/dist/lib/codex-native/accounts.js +18 -12
- package/dist/lib/codex-native/accounts.js.map +1 -1
- package/dist/lib/codex-native/acquire-auth.d.ts +1 -1
- package/dist/lib/codex-native/acquire-auth.d.ts.map +1 -1
- package/dist/lib/codex-native/acquire-auth.js +318 -204
- package/dist/lib/codex-native/acquire-auth.js.map +1 -1
- package/dist/lib/codex-native/auth-menu-flow.d.ts.map +1 -1
- package/dist/lib/codex-native/auth-menu-flow.js +27 -12
- package/dist/lib/codex-native/auth-menu-flow.js.map +1 -1
- package/dist/lib/codex-native/auth-menu-quotas.d.ts.map +1 -1
- package/dist/lib/codex-native/auth-menu-quotas.js +11 -4
- package/dist/lib/codex-native/auth-menu-quotas.js.map +1 -1
- package/dist/lib/codex-native/catalog-auth.d.ts.map +1 -1
- package/dist/lib/codex-native/catalog-auth.js +4 -2
- package/dist/lib/codex-native/catalog-auth.js.map +1 -1
- package/dist/lib/codex-native/chat-hooks.d.ts.map +1 -1
- package/dist/lib/codex-native/chat-hooks.js +0 -8
- package/dist/lib/codex-native/chat-hooks.js.map +1 -1
- package/dist/lib/codex-native/client-identity.d.ts.map +1 -1
- package/dist/lib/codex-native/client-identity.js +11 -4
- package/dist/lib/codex-native/client-identity.js.map +1 -1
- package/dist/lib/codex-native/collaboration.d.ts +1 -1
- package/dist/lib/codex-native/collaboration.d.ts.map +1 -1
- package/dist/lib/codex-native/collaboration.js +9 -116
- package/dist/lib/codex-native/collaboration.js.map +1 -1
- package/dist/lib/codex-native/oauth-auth-methods.d.ts.map +1 -1
- package/dist/lib/codex-native/oauth-auth-methods.js +25 -6
- package/dist/lib/codex-native/oauth-auth-methods.js.map +1 -1
- package/dist/lib/codex-native/oauth-server-debug.d.ts +10 -0
- package/dist/lib/codex-native/oauth-server-debug.d.ts.map +1 -0
- package/dist/lib/codex-native/oauth-server-debug.js +92 -0
- package/dist/lib/codex-native/oauth-server-debug.js.map +1 -0
- package/dist/lib/codex-native/oauth-server-network.d.ts +5 -0
- package/dist/lib/codex-native/oauth-server-network.d.ts.map +1 -0
- package/dist/lib/codex-native/oauth-server-network.js +39 -0
- package/dist/lib/codex-native/oauth-server-network.js.map +1 -0
- package/dist/lib/codex-native/oauth-server-types.d.ts +24 -0
- package/dist/lib/codex-native/oauth-server-types.d.ts.map +1 -0
- package/dist/lib/codex-native/oauth-server-types.js +2 -0
- package/dist/lib/codex-native/oauth-server-types.js.map +1 -0
- package/dist/lib/codex-native/oauth-server.d.ts +2 -16
- package/dist/lib/codex-native/oauth-server.d.ts.map +1 -1
- package/dist/lib/codex-native/oauth-server.js +63 -118
- package/dist/lib/codex-native/oauth-server.js.map +1 -1
- package/dist/lib/codex-native/openai-loader-fetch-quota.d.ts +18 -0
- package/dist/lib/codex-native/openai-loader-fetch-quota.d.ts.map +1 -0
- package/dist/lib/codex-native/openai-loader-fetch-quota.js +71 -0
- package/dist/lib/codex-native/openai-loader-fetch-quota.js.map +1 -0
- package/dist/lib/codex-native/openai-loader-fetch-state.d.ts +27 -0
- package/dist/lib/codex-native/openai-loader-fetch-state.d.ts.map +1 -0
- package/dist/lib/codex-native/openai-loader-fetch-state.js +91 -0
- package/dist/lib/codex-native/openai-loader-fetch-state.js.map +1 -0
- package/dist/lib/codex-native/openai-loader-fetch.d.ts.map +1 -1
- package/dist/lib/codex-native/openai-loader-fetch.js +49 -131
- package/dist/lib/codex-native/openai-loader-fetch.js.map +1 -1
- package/dist/lib/codex-native/originator.d.ts.map +1 -1
- package/dist/lib/codex-native/originator.js +18 -1
- package/dist/lib/codex-native/originator.js.map +1 -1
- package/dist/lib/codex-native/request-transform-instructions.d.ts +16 -0
- package/dist/lib/codex-native/request-transform-instructions.d.ts.map +1 -0
- package/dist/lib/codex-native/request-transform-instructions.js +114 -0
- package/dist/lib/codex-native/request-transform-instructions.js.map +1 -0
- package/dist/lib/codex-native/request-transform-model.d.ts +39 -0
- package/dist/lib/codex-native/request-transform-model.d.ts.map +1 -0
- package/dist/lib/codex-native/request-transform-model.js +270 -0
- package/dist/lib/codex-native/request-transform-model.js.map +1 -0
- package/dist/lib/codex-native/request-transform-payload-helpers.d.ts +26 -0
- package/dist/lib/codex-native/request-transform-payload-helpers.d.ts.map +1 -0
- package/dist/lib/codex-native/request-transform-payload-helpers.js +232 -0
- package/dist/lib/codex-native/request-transform-payload-helpers.js.map +1 -0
- package/dist/lib/codex-native/request-transform-payload.d.ts +53 -0
- package/dist/lib/codex-native/request-transform-payload.d.ts.map +1 -0
- package/dist/lib/codex-native/request-transform-payload.js +214 -0
- package/dist/lib/codex-native/request-transform-payload.js.map +1 -0
- package/dist/lib/codex-native/request-transform-shared.d.ts +8 -0
- package/dist/lib/codex-native/request-transform-shared.d.ts.map +1 -0
- package/dist/lib/codex-native/request-transform-shared.js +49 -0
- package/dist/lib/codex-native/request-transform-shared.js.map +1 -0
- package/dist/lib/codex-native/request-transform.d.ts +3 -122
- package/dist/lib/codex-native/request-transform.d.ts.map +1 -1
- package/dist/lib/codex-native/request-transform.js +3 -831
- package/dist/lib/codex-native/request-transform.js.map +1 -1
- package/dist/lib/codex-native/session-affinity-state.d.ts +14 -1
- package/dist/lib/codex-native/session-affinity-state.d.ts.map +1 -1
- package/dist/lib/codex-native/session-affinity-state.js +21 -8
- package/dist/lib/codex-native/session-affinity-state.js.map +1 -1
- package/dist/lib/codex-native.js.map +1 -1
- package/dist/lib/codex-prompts-cache.d.ts.map +1 -1
- package/dist/lib/codex-prompts-cache.js.map +1 -1
- package/dist/lib/codex-quota-fetch.d.ts.map +1 -1
- package/dist/lib/codex-quota-fetch.js +13 -10
- package/dist/lib/codex-quota-fetch.js.map +1 -1
- package/dist/lib/codex-status-storage.d.ts.map +1 -1
- package/dist/lib/codex-status-storage.js.map +1 -1
- package/dist/lib/codex-status.d.ts.map +1 -1
- package/dist/lib/codex-status.js +28 -3
- package/dist/lib/codex-status.js.map +1 -1
- package/dist/lib/config/io.d.ts +16 -0
- package/dist/lib/config/io.d.ts.map +1 -0
- package/dist/lib/config/io.js +64 -0
- package/dist/lib/config/io.js.map +1 -0
- package/dist/lib/config/parse.d.ts +21 -0
- package/dist/lib/config/parse.d.ts.map +1 -0
- package/dist/lib/config/parse.js +347 -0
- package/dist/lib/config/parse.js.map +1 -0
- package/dist/lib/config/resolve.d.ts +27 -0
- package/dist/lib/config/resolve.d.ts.map +1 -0
- package/dist/lib/config/resolve.js +152 -0
- package/dist/lib/config/resolve.js.map +1 -0
- package/dist/lib/config/types.d.ts +72 -0
- package/dist/lib/config/types.d.ts.map +1 -0
- package/dist/lib/config/types.js +151 -0
- package/dist/lib/config/types.js.map +1 -0
- package/dist/lib/config/validation.d.ts +6 -0
- package/dist/lib/config/validation.d.ts.map +1 -0
- package/dist/lib/config/validation.js +160 -0
- package/dist/lib/config/validation.js.map +1 -0
- package/dist/lib/config.d.ts +5 -111
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +5 -835
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/fetch-orchestrator-helpers.d.ts +13 -0
- package/dist/lib/fetch-orchestrator-helpers.d.ts.map +1 -0
- package/dist/lib/fetch-orchestrator-helpers.js +63 -0
- package/dist/lib/fetch-orchestrator-helpers.js.map +1 -0
- package/dist/lib/fetch-orchestrator-types.d.ts +71 -0
- package/dist/lib/fetch-orchestrator-types.d.ts.map +1 -0
- package/dist/lib/fetch-orchestrator-types.js +11 -0
- package/dist/lib/fetch-orchestrator-types.js.map +1 -0
- package/dist/lib/fetch-orchestrator.d.ts +3 -69
- package/dist/lib/fetch-orchestrator.d.ts.map +1 -1
- package/dist/lib/fetch-orchestrator.js +78 -57
- package/dist/lib/fetch-orchestrator.js.map +1 -1
- package/dist/lib/identity.d.ts +6 -0
- package/dist/lib/identity.d.ts.map +1 -1
- package/dist/lib/identity.js +25 -4
- package/dist/lib/identity.js.map +1 -1
- package/dist/lib/model-catalog/cache-helpers.d.ts +23 -0
- package/dist/lib/model-catalog/cache-helpers.d.ts.map +1 -0
- package/dist/lib/model-catalog/cache-helpers.js +210 -0
- package/dist/lib/model-catalog/cache-helpers.js.map +1 -0
- package/dist/lib/model-catalog/catalog-fetch.d.ts +3 -0
- package/dist/lib/model-catalog/catalog-fetch.d.ts.map +1 -0
- package/dist/lib/model-catalog/catalog-fetch.js +159 -0
- package/dist/lib/model-catalog/catalog-fetch.js.map +1 -0
- package/dist/lib/model-catalog/provider.d.ts +6 -0
- package/dist/lib/model-catalog/provider.d.ts.map +1 -0
- package/dist/lib/model-catalog/provider.js +254 -0
- package/dist/lib/model-catalog/provider.js.map +1 -0
- package/dist/lib/model-catalog/shared.d.ts +95 -0
- package/dist/lib/model-catalog/shared.d.ts.map +1 -0
- package/dist/lib/model-catalog/shared.js +154 -0
- package/dist/lib/model-catalog/shared.js.map +1 -0
- package/dist/lib/model-catalog.d.ts +3 -68
- package/dist/lib/model-catalog.d.ts.map +1 -1
- package/dist/lib/model-catalog.js +3 -767
- package/dist/lib/model-catalog.js.map +1 -1
- package/dist/lib/opencode-install.d.ts.map +1 -1
- package/dist/lib/opencode-install.js +5 -6
- package/dist/lib/opencode-install.js.map +1 -1
- package/dist/lib/orchestrator-agent.d.ts.map +1 -1
- package/dist/lib/orchestrator-agent.js +2 -1
- package/dist/lib/orchestrator-agent.js.map +1 -1
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +8 -2
- package/dist/lib/paths.js.map +1 -1
- package/dist/lib/proactive-refresh.d.ts.map +1 -1
- package/dist/lib/proactive-refresh.js +48 -13
- package/dist/lib/proactive-refresh.js.map +1 -1
- package/dist/lib/quarantine.js.map +1 -1
- package/dist/lib/quota-threshold-alerts.d.ts.map +1 -1
- package/dist/lib/quota-threshold-alerts.js +3 -1
- package/dist/lib/quota-threshold-alerts.js.map +1 -1
- package/dist/lib/refresh-queue.d.ts.map +1 -1
- package/dist/lib/refresh-queue.js +1 -0
- package/dist/lib/refresh-queue.js.map +1 -1
- package/dist/lib/request-snapshots.d.ts.map +1 -1
- package/dist/lib/request-snapshots.js +46 -10
- package/dist/lib/request-snapshots.js.map +1 -1
- package/dist/lib/rotation.d.ts.map +1 -1
- package/dist/lib/rotation.js +3 -2
- package/dist/lib/rotation.js.map +1 -1
- package/dist/lib/session-affinity.d.ts.map +1 -1
- package/dist/lib/session-affinity.js +35 -20
- package/dist/lib/session-affinity.js.map +1 -1
- package/dist/lib/storage/domain-state.d.ts +23 -0
- package/dist/lib/storage/domain-state.d.ts.map +1 -0
- package/dist/lib/storage/domain-state.js +275 -0
- package/dist/lib/storage/domain-state.js.map +1 -0
- package/dist/lib/storage/migration.d.ts +13 -0
- package/dist/lib/storage/migration.d.ts.map +1 -0
- package/dist/lib/storage/migration.js +225 -0
- package/dist/lib/storage/migration.js.map +1 -0
- package/dist/lib/storage.d.ts +2 -9
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +44 -470
- package/dist/lib/storage.js.map +1 -1
- package/dist/lib/ui/auth-menu.d.ts +3 -2
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +1 -1
- package/dist/lib/ui/auth-menu.js.map +1 -1
- package/package.json +28 -15
package/dist/lib/config.js
CHANGED
|
@@ -1,836 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const CONFIG_FILE = "codex-config.json";
|
|
7
|
-
export const DEFAULT_CODEX_CONFIG = {
|
|
8
|
-
$schema: "https://schemas.iam-brain.dev/opencode-codex-auth/codex-config.schema.json",
|
|
9
|
-
debug: false,
|
|
10
|
-
quiet: false,
|
|
11
|
-
refreshAhead: {
|
|
12
|
-
enabled: true,
|
|
13
|
-
bufferMs: 60_000
|
|
14
|
-
},
|
|
15
|
-
runtime: {
|
|
16
|
-
mode: "native",
|
|
17
|
-
rotationStrategy: "sticky",
|
|
18
|
-
sanitizeInputs: false,
|
|
19
|
-
developerMessagesToUser: true,
|
|
20
|
-
promptCacheKeyStrategy: "default",
|
|
21
|
-
headerSnapshots: false,
|
|
22
|
-
headerSnapshotBodies: false,
|
|
23
|
-
headerTransformDebug: false,
|
|
24
|
-
pidOffset: false
|
|
25
|
-
},
|
|
26
|
-
global: {
|
|
27
|
-
personality: "pragmatic",
|
|
28
|
-
verbosityEnabled: true,
|
|
29
|
-
verbosity: "default"
|
|
30
|
-
},
|
|
31
|
-
perModel: {}
|
|
32
|
-
};
|
|
33
|
-
const DEFAULT_CODEX_CONFIG_TEMPLATE = `{
|
|
34
|
-
"$schema": "https://schemas.iam-brain.dev/opencode-codex-auth/codex-config.schema.json",
|
|
35
|
-
|
|
36
|
-
// Enable verbose plugin debug logs.
|
|
37
|
-
// options: true | false
|
|
38
|
-
// default: false
|
|
39
|
-
"debug": false,
|
|
40
|
-
|
|
41
|
-
// Suppress plugin UI toasts/notifications.
|
|
42
|
-
// options: true | false
|
|
43
|
-
// default: false
|
|
44
|
-
"quiet": false,
|
|
45
|
-
|
|
46
|
-
// Proactively refresh access tokens before expiry.
|
|
47
|
-
"refreshAhead": {
|
|
48
|
-
// options: true | false
|
|
49
|
-
// default: true
|
|
50
|
-
"enabled": true,
|
|
51
|
-
|
|
52
|
-
// Milliseconds before expiry to refresh.
|
|
53
|
-
// default: 60000
|
|
54
|
-
"bufferMs": 60000
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
"runtime": {
|
|
58
|
-
// Request identity/profile mode.
|
|
59
|
-
// options: "native" | "codex"
|
|
60
|
-
// default: "native"
|
|
61
|
-
"mode": "native",
|
|
62
|
-
|
|
63
|
-
// Account rotation strategy.
|
|
64
|
-
// options: "sticky" | "hybrid" | "round_robin"
|
|
65
|
-
// default: "sticky"
|
|
66
|
-
"rotationStrategy": "sticky",
|
|
67
|
-
|
|
68
|
-
// Input compatibility sanitizer for edge payloads.
|
|
69
|
-
// options: true | false
|
|
70
|
-
// default: false
|
|
71
|
-
"sanitizeInputs": false,
|
|
72
|
-
|
|
73
|
-
// Experimental: remap non-permissions developer messages to user role.
|
|
74
|
-
// Only applies when runtime.mode is "codex".
|
|
75
|
-
// options: true | false
|
|
76
|
-
// default: true
|
|
77
|
-
"developerMessagesToUser": true,
|
|
78
|
-
|
|
79
|
-
// Prompt cache key policy.
|
|
80
|
-
// "default" keeps upstream session-based keys.
|
|
81
|
-
// "project" overrides with a hashed project path + runtime mode key.
|
|
82
|
-
// options: "default" | "project"
|
|
83
|
-
// default: "default"
|
|
84
|
-
"promptCacheKeyStrategy": "default",
|
|
85
|
-
|
|
86
|
-
// Write request header snapshots to plugin logs.
|
|
87
|
-
// options: true | false
|
|
88
|
-
// default: false
|
|
89
|
-
"headerSnapshots": false,
|
|
90
|
-
|
|
91
|
-
// Capture request bodies in snapshot files.
|
|
92
|
-
// options: true | false
|
|
93
|
-
// default: false
|
|
94
|
-
"headerSnapshotBodies": false,
|
|
95
|
-
|
|
96
|
-
// Capture inbound/outbound header transforms for message requests.
|
|
97
|
-
// options: true | false
|
|
98
|
-
// default: false
|
|
99
|
-
"headerTransformDebug": false,
|
|
100
|
-
|
|
101
|
-
// Session-aware offset for account selection.
|
|
102
|
-
// options: true | false
|
|
103
|
-
// default: false
|
|
104
|
-
"pidOffset": false
|
|
105
|
-
|
|
106
|
-
// Experimental collaboration controls (optional):
|
|
107
|
-
// "collaborationProfile": true,
|
|
108
|
-
// "orchestratorSubagents": true
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
"global": {
|
|
112
|
-
// Global personality key.
|
|
113
|
-
// built-ins: "pragmatic", "friendly"
|
|
114
|
-
// custom: any lowercase key from personalities/<key>.md
|
|
115
|
-
// default: "pragmatic"
|
|
116
|
-
"personality": "pragmatic",
|
|
117
|
-
|
|
118
|
-
// Thinking summaries behavior:
|
|
119
|
-
// true => force on
|
|
120
|
-
// false => force off
|
|
121
|
-
// omit => use model default from catalog cache (recommended)
|
|
122
|
-
// "thinkingSummaries": true
|
|
123
|
-
|
|
124
|
-
// Text verbosity behavior:
|
|
125
|
-
// verbosityEnabled: true => apply verbosity setting/default
|
|
126
|
-
// verbosityEnabled: false => do not send textVerbosity
|
|
127
|
-
// default: true
|
|
128
|
-
"verbosityEnabled": true,
|
|
129
|
-
|
|
130
|
-
// options: "default" | "low" | "medium" | "high"
|
|
131
|
-
// "default" uses each model's catalog default verbosity.
|
|
132
|
-
// default: "default"
|
|
133
|
-
"verbosity": "default"
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
// Optional model-specific overrides.
|
|
137
|
-
// Supports same fields as global plus nested variants.
|
|
138
|
-
"perModel": {
|
|
139
|
-
// "gpt-5.3-codex": {
|
|
140
|
-
// "personality": "friendly",
|
|
141
|
-
// "thinkingSummaries": true,
|
|
142
|
-
// "verbosityEnabled": true,
|
|
143
|
-
// "verbosity": "default",
|
|
144
|
-
// "variants": {
|
|
145
|
-
// "high": {
|
|
146
|
-
// "personality": "pragmatic",
|
|
147
|
-
// "thinkingSummaries": false,
|
|
148
|
-
// "verbosityEnabled": true,
|
|
149
|
-
// "verbosity": "high"
|
|
150
|
-
// }
|
|
151
|
-
// }
|
|
152
|
-
// }
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
`;
|
|
156
|
-
function describeValueType(value) {
|
|
157
|
-
if (Array.isArray(value))
|
|
158
|
-
return "array";
|
|
159
|
-
if (value === null)
|
|
160
|
-
return "null";
|
|
161
|
-
return typeof value;
|
|
162
|
-
}
|
|
163
|
-
function pushValidationIssue(issues, input) {
|
|
164
|
-
issues.push(`${input.path}: expected ${input.expected}, got ${describeValueType(input.actual)}`);
|
|
165
|
-
}
|
|
166
|
-
function validateModelBehaviorShape(value, pathPrefix, issues) {
|
|
167
|
-
if (!isRecord(value)) {
|
|
168
|
-
pushValidationIssue(issues, { path: pathPrefix, expected: "object", actual: value });
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
if ("personality" in value && typeof value.personality !== "string") {
|
|
172
|
-
pushValidationIssue(issues, { path: `${pathPrefix}.personality`, expected: "string", actual: value.personality });
|
|
173
|
-
}
|
|
174
|
-
if ("thinkingSummaries" in value && typeof value.thinkingSummaries !== "boolean") {
|
|
175
|
-
pushValidationIssue(issues, {
|
|
176
|
-
path: `${pathPrefix}.thinkingSummaries`,
|
|
177
|
-
expected: "boolean",
|
|
178
|
-
actual: value.thinkingSummaries
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
if ("verbosityEnabled" in value && typeof value.verbosityEnabled !== "boolean") {
|
|
182
|
-
pushValidationIssue(issues, {
|
|
183
|
-
path: `${pathPrefix}.verbosityEnabled`,
|
|
184
|
-
expected: "boolean",
|
|
185
|
-
actual: value.verbosityEnabled
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
if ("verbosity" in value) {
|
|
189
|
-
const verbosity = value.verbosity;
|
|
190
|
-
const normalized = typeof verbosity === "string" ? verbosity.trim().toLowerCase() : "";
|
|
191
|
-
if (!(normalized === "default" || normalized === "low" || normalized === "medium" || normalized === "high")) {
|
|
192
|
-
pushValidationIssue(issues, {
|
|
193
|
-
path: `${pathPrefix}.verbosity`,
|
|
194
|
-
expected: '"default" | "low" | "medium" | "high"',
|
|
195
|
-
actual: verbosity
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
export function validateConfigFileObject(raw) {
|
|
201
|
-
const issues = [];
|
|
202
|
-
if (!isRecord(raw)) {
|
|
203
|
-
pushValidationIssue(issues, { path: "$", expected: "object", actual: raw });
|
|
204
|
-
return { valid: false, issues };
|
|
205
|
-
}
|
|
206
|
-
if ("$schema" in raw && typeof raw.$schema !== "string") {
|
|
207
|
-
pushValidationIssue(issues, { path: "$schema", expected: "string", actual: raw.$schema });
|
|
208
|
-
}
|
|
209
|
-
if ("debug" in raw && typeof raw.debug !== "boolean") {
|
|
210
|
-
pushValidationIssue(issues, { path: "debug", expected: "boolean", actual: raw.debug });
|
|
211
|
-
}
|
|
212
|
-
if ("quiet" in raw && typeof raw.quiet !== "boolean") {
|
|
213
|
-
pushValidationIssue(issues, { path: "quiet", expected: "boolean", actual: raw.quiet });
|
|
214
|
-
}
|
|
215
|
-
if ("refreshAhead" in raw) {
|
|
216
|
-
if (!isRecord(raw.refreshAhead)) {
|
|
217
|
-
pushValidationIssue(issues, { path: "refreshAhead", expected: "object", actual: raw.refreshAhead });
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
if ("enabled" in raw.refreshAhead && typeof raw.refreshAhead.enabled !== "boolean") {
|
|
221
|
-
pushValidationIssue(issues, {
|
|
222
|
-
path: "refreshAhead.enabled",
|
|
223
|
-
expected: "boolean",
|
|
224
|
-
actual: raw.refreshAhead.enabled
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
if ("bufferMs" in raw.refreshAhead &&
|
|
228
|
-
(typeof raw.refreshAhead.bufferMs !== "number" || !Number.isFinite(raw.refreshAhead.bufferMs))) {
|
|
229
|
-
pushValidationIssue(issues, {
|
|
230
|
-
path: "refreshAhead.bufferMs",
|
|
231
|
-
expected: "number",
|
|
232
|
-
actual: raw.refreshAhead.bufferMs
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if ("runtime" in raw) {
|
|
238
|
-
if (!isRecord(raw.runtime)) {
|
|
239
|
-
pushValidationIssue(issues, { path: "runtime", expected: "object", actual: raw.runtime });
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
const runtime = raw.runtime;
|
|
243
|
-
const enumChecks = [
|
|
244
|
-
{ field: "mode", allowed: ["native", "codex"] },
|
|
245
|
-
{ field: "rotationStrategy", allowed: ["sticky", "hybrid", "round_robin"] },
|
|
246
|
-
{ field: "promptCacheKeyStrategy", allowed: ["default", "project"] }
|
|
247
|
-
];
|
|
248
|
-
for (const check of enumChecks) {
|
|
249
|
-
const value = runtime[check.field];
|
|
250
|
-
if (value === undefined)
|
|
251
|
-
continue;
|
|
252
|
-
const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
253
|
-
if (!check.allowed.includes(normalized)) {
|
|
254
|
-
pushValidationIssue(issues, {
|
|
255
|
-
path: `runtime.${check.field}`,
|
|
256
|
-
expected: check.allowed.map((item) => `"${item}"`).join(" | "),
|
|
257
|
-
actual: value
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
const boolFields = [
|
|
262
|
-
"sanitizeInputs",
|
|
263
|
-
"developerMessagesToUser",
|
|
264
|
-
"codexCompactionOverride",
|
|
265
|
-
"headerSnapshots",
|
|
266
|
-
"headerSnapshotBodies",
|
|
267
|
-
"headerTransformDebug",
|
|
268
|
-
"pidOffset",
|
|
269
|
-
"collaborationProfile",
|
|
270
|
-
"orchestratorSubagents"
|
|
271
|
-
];
|
|
272
|
-
for (const field of boolFields) {
|
|
273
|
-
if (field in runtime && typeof runtime[field] !== "boolean") {
|
|
274
|
-
pushValidationIssue(issues, {
|
|
275
|
-
path: `runtime.${field}`,
|
|
276
|
-
expected: "boolean",
|
|
277
|
-
actual: runtime[field]
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
if ("global" in raw) {
|
|
284
|
-
validateModelBehaviorShape(raw.global, "global", issues);
|
|
285
|
-
}
|
|
286
|
-
if ("perModel" in raw) {
|
|
287
|
-
if (!isRecord(raw.perModel)) {
|
|
288
|
-
pushValidationIssue(issues, { path: "perModel", expected: "object", actual: raw.perModel });
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
for (const [modelName, modelValue] of Object.entries(raw.perModel)) {
|
|
292
|
-
validateModelBehaviorShape(modelValue, `perModel.${modelName}`, issues);
|
|
293
|
-
if (!isRecord(modelValue))
|
|
294
|
-
continue;
|
|
295
|
-
if (!("variants" in modelValue))
|
|
296
|
-
continue;
|
|
297
|
-
const variants = modelValue.variants;
|
|
298
|
-
if (!isRecord(variants)) {
|
|
299
|
-
pushValidationIssue(issues, {
|
|
300
|
-
path: `perModel.${modelName}.variants`,
|
|
301
|
-
expected: "object",
|
|
302
|
-
actual: variants
|
|
303
|
-
});
|
|
304
|
-
continue;
|
|
305
|
-
}
|
|
306
|
-
for (const [variantName, variantValue] of Object.entries(variants)) {
|
|
307
|
-
validateModelBehaviorShape(variantValue, `perModel.${modelName}.variants.${variantName}`, issues);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return { valid: issues.length === 0, issues };
|
|
313
|
-
}
|
|
314
|
-
function parseEnvBoolean(value) {
|
|
315
|
-
if (value === undefined)
|
|
316
|
-
return undefined;
|
|
317
|
-
if (value === "1" || value === "true")
|
|
318
|
-
return true;
|
|
319
|
-
if (value === "0" || value === "false")
|
|
320
|
-
return false;
|
|
321
|
-
return undefined;
|
|
322
|
-
}
|
|
323
|
-
function parseEnvNumber(value) {
|
|
324
|
-
if (value === undefined)
|
|
325
|
-
return undefined;
|
|
326
|
-
const n = Number(value);
|
|
327
|
-
return Number.isFinite(n) ? n : undefined;
|
|
328
|
-
}
|
|
329
|
-
function stripJsonComments(raw) {
|
|
330
|
-
let out = "";
|
|
331
|
-
let inString = false;
|
|
332
|
-
let escaped = false;
|
|
333
|
-
let inLineComment = false;
|
|
334
|
-
let inBlockComment = false;
|
|
335
|
-
for (let index = 0; index < raw.length; index += 1) {
|
|
336
|
-
const ch = raw[index];
|
|
337
|
-
const next = raw[index + 1];
|
|
338
|
-
if (inLineComment) {
|
|
339
|
-
if (ch === "\n" || ch === "\r") {
|
|
340
|
-
inLineComment = false;
|
|
341
|
-
out += ch;
|
|
342
|
-
}
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
if (inBlockComment) {
|
|
346
|
-
if (ch === "*" && next === "/") {
|
|
347
|
-
inBlockComment = false;
|
|
348
|
-
index += 1;
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
if (ch === "\n" || ch === "\r") {
|
|
352
|
-
out += ch;
|
|
353
|
-
}
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
|
-
if (inString) {
|
|
357
|
-
out += ch;
|
|
358
|
-
if (escaped) {
|
|
359
|
-
escaped = false;
|
|
360
|
-
}
|
|
361
|
-
else if (ch === "\\") {
|
|
362
|
-
escaped = true;
|
|
363
|
-
}
|
|
364
|
-
else if (ch === '"') {
|
|
365
|
-
inString = false;
|
|
366
|
-
}
|
|
367
|
-
continue;
|
|
368
|
-
}
|
|
369
|
-
if (ch === '"') {
|
|
370
|
-
inString = true;
|
|
371
|
-
out += ch;
|
|
372
|
-
continue;
|
|
373
|
-
}
|
|
374
|
-
if (ch === "/" && next === "/") {
|
|
375
|
-
inLineComment = true;
|
|
376
|
-
index += 1;
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
if (ch === "/" && next === "*") {
|
|
380
|
-
inBlockComment = true;
|
|
381
|
-
index += 1;
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
out += ch;
|
|
385
|
-
}
|
|
386
|
-
return out;
|
|
387
|
-
}
|
|
388
|
-
export function parseConfigJsonWithComments(raw) {
|
|
389
|
-
return JSON.parse(stripJsonComments(raw));
|
|
390
|
-
}
|
|
391
|
-
export function normalizePersonalityOption(value) {
|
|
392
|
-
if (typeof value !== "string")
|
|
393
|
-
return undefined;
|
|
394
|
-
const normalized = value.trim().toLowerCase();
|
|
395
|
-
if (!normalized)
|
|
396
|
-
return undefined;
|
|
397
|
-
if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("..")) {
|
|
398
|
-
return undefined;
|
|
399
|
-
}
|
|
400
|
-
return normalized;
|
|
401
|
-
}
|
|
402
|
-
function parseSpoofMode(value) {
|
|
403
|
-
if (typeof value !== "string")
|
|
404
|
-
return undefined;
|
|
405
|
-
const normalized = value.trim().toLowerCase();
|
|
406
|
-
if (normalized === "native")
|
|
407
|
-
return "native";
|
|
408
|
-
if (normalized === "codex")
|
|
409
|
-
return "codex";
|
|
410
|
-
return undefined;
|
|
411
|
-
}
|
|
412
|
-
function parseRuntimeMode(value) {
|
|
413
|
-
if (typeof value !== "string")
|
|
414
|
-
return undefined;
|
|
415
|
-
const normalized = value.trim().toLowerCase();
|
|
416
|
-
if (normalized === "native")
|
|
417
|
-
return "native";
|
|
418
|
-
if (normalized === "codex")
|
|
419
|
-
return "codex";
|
|
420
|
-
return undefined;
|
|
421
|
-
}
|
|
422
|
-
function parseRotationStrategy(value) {
|
|
423
|
-
if (typeof value !== "string")
|
|
424
|
-
return undefined;
|
|
425
|
-
const normalized = value.trim().toLowerCase();
|
|
426
|
-
if (normalized === "sticky" || normalized === "hybrid" || normalized === "round_robin") {
|
|
427
|
-
return normalized;
|
|
428
|
-
}
|
|
429
|
-
return undefined;
|
|
430
|
-
}
|
|
431
|
-
function parsePromptCacheKeyStrategy(value) {
|
|
432
|
-
if (typeof value !== "string")
|
|
433
|
-
return undefined;
|
|
434
|
-
const normalized = value.trim().toLowerCase();
|
|
435
|
-
if (normalized === "default" || normalized === "project")
|
|
436
|
-
return normalized;
|
|
437
|
-
return undefined;
|
|
438
|
-
}
|
|
439
|
-
function normalizeVerbosityOption(value) {
|
|
440
|
-
if (typeof value !== "string")
|
|
441
|
-
return undefined;
|
|
442
|
-
const normalized = value.trim().toLowerCase();
|
|
443
|
-
if (normalized === "default" || normalized === "low" || normalized === "medium" || normalized === "high") {
|
|
444
|
-
return normalized;
|
|
445
|
-
}
|
|
446
|
-
return undefined;
|
|
447
|
-
}
|
|
448
|
-
function normalizeModelBehaviorSettings(raw) {
|
|
449
|
-
if (!isRecord(raw))
|
|
450
|
-
return undefined;
|
|
451
|
-
const out = {};
|
|
452
|
-
const personality = normalizePersonalityOption(raw.personality);
|
|
453
|
-
if (personality)
|
|
454
|
-
out.personality = personality;
|
|
455
|
-
if (typeof raw.thinkingSummaries === "boolean") {
|
|
456
|
-
out.thinkingSummaries = raw.thinkingSummaries;
|
|
457
|
-
}
|
|
458
|
-
if (typeof raw.verbosityEnabled === "boolean") {
|
|
459
|
-
out.verbosityEnabled = raw.verbosityEnabled;
|
|
460
|
-
}
|
|
461
|
-
const verbosity = normalizeVerbosityOption(raw.verbosity);
|
|
462
|
-
if (verbosity) {
|
|
463
|
-
out.verbosity = verbosity;
|
|
464
|
-
}
|
|
465
|
-
if (!out.personality &&
|
|
466
|
-
out.thinkingSummaries === undefined &&
|
|
467
|
-
out.verbosityEnabled === undefined &&
|
|
468
|
-
out.verbosity === undefined) {
|
|
469
|
-
return undefined;
|
|
470
|
-
}
|
|
471
|
-
return out;
|
|
472
|
-
}
|
|
473
|
-
function normalizeModelConfigOverride(raw) {
|
|
474
|
-
if (!isRecord(raw))
|
|
475
|
-
return undefined;
|
|
476
|
-
const modelBehavior = normalizeModelBehaviorSettings(raw);
|
|
477
|
-
const rawVariants = isRecord(raw.variants) ? raw.variants : undefined;
|
|
478
|
-
let variants;
|
|
479
|
-
if (rawVariants) {
|
|
480
|
-
const variantMap = {};
|
|
481
|
-
for (const [variantName, value] of Object.entries(rawVariants)) {
|
|
482
|
-
const normalized = normalizeModelBehaviorSettings(value);
|
|
483
|
-
if (!normalized)
|
|
484
|
-
continue;
|
|
485
|
-
variantMap[variantName] = {
|
|
486
|
-
...(normalized.personality ? { personality: normalized.personality } : {}),
|
|
487
|
-
...(normalized.thinkingSummaries !== undefined ? { thinkingSummaries: normalized.thinkingSummaries } : {}),
|
|
488
|
-
...(normalized.verbosityEnabled !== undefined ? { verbosityEnabled: normalized.verbosityEnabled } : {}),
|
|
489
|
-
...(normalized.verbosity ? { verbosity: normalized.verbosity } : {})
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
if (Object.keys(variantMap).length > 0) {
|
|
493
|
-
variants = variantMap;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
if (!modelBehavior && !variants) {
|
|
497
|
-
return undefined;
|
|
498
|
-
}
|
|
499
|
-
return {
|
|
500
|
-
...(modelBehavior?.personality ? { personality: modelBehavior.personality } : {}),
|
|
501
|
-
...(modelBehavior?.thinkingSummaries !== undefined ? { thinkingSummaries: modelBehavior.thinkingSummaries } : {}),
|
|
502
|
-
...(modelBehavior?.verbosityEnabled !== undefined ? { verbosityEnabled: modelBehavior.verbosityEnabled } : {}),
|
|
503
|
-
...(modelBehavior?.verbosity ? { verbosity: modelBehavior.verbosity } : {}),
|
|
504
|
-
...(variants ? { variants } : {})
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
function normalizeNewBehaviorSections(raw) {
|
|
508
|
-
const global = normalizeModelBehaviorSettings(raw.global);
|
|
509
|
-
const perModelRaw = isRecord(raw.perModel) ? raw.perModel : undefined;
|
|
510
|
-
let perModel;
|
|
511
|
-
if (perModelRaw) {
|
|
512
|
-
const modelMap = {};
|
|
513
|
-
for (const [modelName, value] of Object.entries(perModelRaw)) {
|
|
514
|
-
const normalized = normalizeModelConfigOverride(value);
|
|
515
|
-
if (!normalized)
|
|
516
|
-
continue;
|
|
517
|
-
modelMap[modelName] = normalized;
|
|
518
|
-
}
|
|
519
|
-
if (Object.keys(modelMap).length > 0) {
|
|
520
|
-
perModel = modelMap;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
if (!global && !perModel) {
|
|
524
|
-
return undefined;
|
|
525
|
-
}
|
|
526
|
-
return {
|
|
527
|
-
...(global ? { global } : {}),
|
|
528
|
-
...(perModel ? { perModel } : {})
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
function cloneBehaviorSettings(input) {
|
|
532
|
-
if (!input)
|
|
533
|
-
return undefined;
|
|
534
|
-
return {
|
|
535
|
-
...(input.global
|
|
536
|
-
? {
|
|
537
|
-
global: {
|
|
538
|
-
...input.global
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
: {}),
|
|
542
|
-
perModel: input.perModel
|
|
543
|
-
? Object.fromEntries(Object.entries(input.perModel).map(([key, value]) => [
|
|
544
|
-
key,
|
|
545
|
-
{
|
|
546
|
-
...(value.personality !== undefined ? { personality: value.personality } : {}),
|
|
547
|
-
...(value.thinkingSummaries !== undefined ? { thinkingSummaries: value.thinkingSummaries } : {}),
|
|
548
|
-
...(value.verbosityEnabled !== undefined ? { verbosityEnabled: value.verbosityEnabled } : {}),
|
|
549
|
-
...(value.verbosity !== undefined ? { verbosity: value.verbosity } : {}),
|
|
550
|
-
...(value.variants
|
|
551
|
-
? {
|
|
552
|
-
variants: Object.fromEntries(Object.entries(value.variants).map(([variantKey, variantValue]) => [
|
|
553
|
-
variantKey,
|
|
554
|
-
{
|
|
555
|
-
...(variantValue.personality !== undefined ? { personality: variantValue.personality } : {}),
|
|
556
|
-
...(variantValue.thinkingSummaries !== undefined
|
|
557
|
-
? { thinkingSummaries: variantValue.thinkingSummaries }
|
|
558
|
-
: {}),
|
|
559
|
-
...(variantValue.verbosityEnabled !== undefined
|
|
560
|
-
? { verbosityEnabled: variantValue.verbosityEnabled }
|
|
561
|
-
: {}),
|
|
562
|
-
...(variantValue.verbosity !== undefined ? { verbosity: variantValue.verbosity } : {})
|
|
563
|
-
}
|
|
564
|
-
]))
|
|
565
|
-
}
|
|
566
|
-
: {})
|
|
567
|
-
}
|
|
568
|
-
]))
|
|
569
|
-
: undefined
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
function parseConfigFileObject(raw) {
|
|
573
|
-
if (!isRecord(raw))
|
|
574
|
-
return {};
|
|
575
|
-
const behaviorSettings = normalizeNewBehaviorSections(raw);
|
|
576
|
-
const personalityFromBehavior = behaviorSettings?.global?.personality;
|
|
577
|
-
const debug = typeof raw.debug === "boolean" ? raw.debug : undefined;
|
|
578
|
-
const proactiveRefresh = isRecord(raw.refreshAhead) && typeof raw.refreshAhead.enabled === "boolean" ? raw.refreshAhead.enabled : undefined;
|
|
579
|
-
const proactiveRefreshBufferMs = isRecord(raw.refreshAhead) && typeof raw.refreshAhead.bufferMs === "number" ? raw.refreshAhead.bufferMs : undefined;
|
|
580
|
-
const quietMode = typeof raw.quiet === "boolean" ? raw.quiet : undefined;
|
|
581
|
-
const mode = parseRuntimeMode(isRecord(raw.runtime) ? raw.runtime.mode : undefined);
|
|
582
|
-
const rotationStrategy = parseRotationStrategy(isRecord(raw.runtime) ? raw.runtime.rotationStrategy : undefined);
|
|
583
|
-
const promptCacheKeyStrategy = parsePromptCacheKeyStrategy(isRecord(raw.runtime) ? raw.runtime.promptCacheKeyStrategy : undefined);
|
|
584
|
-
const spoofMode = mode === "native" ? "native" : mode === "codex" ? "codex" : undefined;
|
|
585
|
-
const compatInputSanitizer = isRecord(raw.runtime) && typeof raw.runtime.sanitizeInputs === "boolean" ? raw.runtime.sanitizeInputs : undefined;
|
|
586
|
-
const remapDeveloperMessagesToUser = isRecord(raw.runtime) && typeof raw.runtime.developerMessagesToUser === "boolean"
|
|
587
|
-
? raw.runtime.developerMessagesToUser
|
|
588
|
-
: undefined;
|
|
589
|
-
const codexCompactionOverride = isRecord(raw.runtime) && typeof raw.runtime.codexCompactionOverride === "boolean"
|
|
590
|
-
? raw.runtime.codexCompactionOverride
|
|
591
|
-
: undefined;
|
|
592
|
-
const headerSnapshots = isRecord(raw.runtime) && typeof raw.runtime.headerSnapshots === "boolean" ? raw.runtime.headerSnapshots : undefined;
|
|
593
|
-
const headerSnapshotBodies = isRecord(raw.runtime) && typeof raw.runtime.headerSnapshotBodies === "boolean"
|
|
594
|
-
? raw.runtime.headerSnapshotBodies
|
|
595
|
-
: undefined;
|
|
596
|
-
const headerTransformDebug = isRecord(raw.runtime) && typeof raw.runtime.headerTransformDebug === "boolean"
|
|
597
|
-
? raw.runtime.headerTransformDebug
|
|
598
|
-
: undefined;
|
|
599
|
-
const pidOffsetEnabled = isRecord(raw.runtime) && typeof raw.runtime.pidOffset === "boolean" ? raw.runtime.pidOffset : undefined;
|
|
600
|
-
const collaborationProfileEnabled = isRecord(raw.runtime) && typeof raw.runtime.collaborationProfile === "boolean"
|
|
601
|
-
? raw.runtime.collaborationProfile
|
|
602
|
-
: undefined;
|
|
603
|
-
const orchestratorSubagentsEnabled = isRecord(raw.runtime) && typeof raw.runtime.orchestratorSubagents === "boolean"
|
|
604
|
-
? raw.runtime.orchestratorSubagents
|
|
605
|
-
: undefined;
|
|
606
|
-
return {
|
|
607
|
-
debug,
|
|
608
|
-
proactiveRefresh,
|
|
609
|
-
proactiveRefreshBufferMs,
|
|
610
|
-
quietMode,
|
|
611
|
-
pidOffsetEnabled,
|
|
612
|
-
personality: personalityFromBehavior,
|
|
613
|
-
mode,
|
|
614
|
-
rotationStrategy,
|
|
615
|
-
promptCacheKeyStrategy,
|
|
616
|
-
spoofMode,
|
|
617
|
-
compatInputSanitizer,
|
|
618
|
-
remapDeveloperMessagesToUser,
|
|
619
|
-
codexCompactionOverride,
|
|
620
|
-
headerSnapshots,
|
|
621
|
-
headerSnapshotBodies,
|
|
622
|
-
headerTransformDebug,
|
|
623
|
-
collaborationProfileEnabled,
|
|
624
|
-
orchestratorSubagentsEnabled,
|
|
625
|
-
behaviorSettings
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
export function resolveDefaultConfigPath(env) {
|
|
629
|
-
const xdgRoot = env.XDG_CONFIG_HOME?.trim();
|
|
630
|
-
if (xdgRoot) {
|
|
631
|
-
return path.join(xdgRoot, "opencode", CONFIG_FILE);
|
|
632
|
-
}
|
|
633
|
-
return path.join(os.homedir(), ".config", "opencode", CONFIG_FILE);
|
|
634
|
-
}
|
|
635
|
-
export async function ensureDefaultConfigFile(input = {}) {
|
|
636
|
-
const env = input.env ?? process.env;
|
|
637
|
-
const filePath = input.filePath ?? resolveDefaultConfigPath(env);
|
|
638
|
-
const overwrite = input.overwrite === true;
|
|
639
|
-
if (!overwrite && fs.existsSync(filePath)) {
|
|
640
|
-
return { filePath, created: false };
|
|
641
|
-
}
|
|
642
|
-
await fsPromises.mkdir(path.dirname(filePath), { recursive: true });
|
|
643
|
-
const content = DEFAULT_CODEX_CONFIG_TEMPLATE;
|
|
644
|
-
await fsPromises.writeFile(filePath, content, { encoding: "utf8", mode: 0o600 });
|
|
645
|
-
return { filePath, created: true };
|
|
646
|
-
}
|
|
647
|
-
export function loadConfigFile(input = {}) {
|
|
648
|
-
const env = input.env ?? process.env;
|
|
649
|
-
const explicitPath = input.filePath ?? env.OPENCODE_OPENAI_MULTI_CONFIG_PATH?.trim();
|
|
650
|
-
const candidates = explicitPath ? [explicitPath] : [resolveDefaultConfigPath(env)];
|
|
651
|
-
for (const filePath of candidates) {
|
|
652
|
-
if (!filePath)
|
|
653
|
-
continue;
|
|
654
|
-
if (!fs.existsSync(filePath))
|
|
655
|
-
continue;
|
|
656
|
-
try {
|
|
657
|
-
const raw = fs.readFileSync(filePath, "utf8");
|
|
658
|
-
const parsed = parseConfigJsonWithComments(raw);
|
|
659
|
-
const validation = validateConfigFileObject(parsed);
|
|
660
|
-
if (!validation.valid) {
|
|
661
|
-
console.warn(`[opencode-codex-auth] Invalid codex-config at ${filePath}; ignoring file. ${validation.issues.join("; ")}`);
|
|
662
|
-
return {};
|
|
663
|
-
}
|
|
664
|
-
return parseConfigFileObject(parsed);
|
|
665
|
-
}
|
|
666
|
-
catch (error) {
|
|
667
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
668
|
-
console.warn(`[opencode-codex-auth] Failed to read codex-config at ${filePath}; ignoring file. ${detail}`);
|
|
669
|
-
return {};
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
return {};
|
|
673
|
-
}
|
|
674
|
-
export function resolveConfig(input) {
|
|
675
|
-
const env = input.env;
|
|
676
|
-
const file = input.file ?? {};
|
|
677
|
-
const fileBehavior = cloneBehaviorSettings(file.behaviorSettings);
|
|
678
|
-
const envDebug = env.OPENCODE_OPENAI_MULTI_DEBUG === "1" || env.DEBUG_CODEX_PLUGIN === "1";
|
|
679
|
-
const proactiveRefresh = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_PROACTIVE_REFRESH) ?? file.proactiveRefresh;
|
|
680
|
-
const proactiveRefreshBufferMs = parseEnvNumber(env.OPENCODE_OPENAI_MULTI_PROACTIVE_REFRESH_BUFFER_MS) ?? file.proactiveRefreshBufferMs;
|
|
681
|
-
const quietMode = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_QUIET) ?? file.quietMode;
|
|
682
|
-
const pidOffsetEnabled = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_PID_OFFSET) ?? file.pidOffsetEnabled;
|
|
683
|
-
const rotationStrategy = parseRotationStrategy(env.OPENCODE_OPENAI_MULTI_ROTATION_STRATEGY) ?? file.rotationStrategy;
|
|
684
|
-
const promptCacheKeyStrategy = parsePromptCacheKeyStrategy(env.OPENCODE_OPENAI_MULTI_PROMPT_CACHE_KEY_STRATEGY) ?? file.promptCacheKeyStrategy;
|
|
685
|
-
const envPersonality = normalizePersonalityOption(env.OPENCODE_OPENAI_MULTI_PERSONALITY);
|
|
686
|
-
const envThinkingSummaries = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_THINKING_SUMMARIES);
|
|
687
|
-
const envVerbosityEnabled = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_VERBOSITY_ENABLED);
|
|
688
|
-
const envVerbosity = normalizeVerbosityOption(env.OPENCODE_OPENAI_MULTI_VERBOSITY);
|
|
689
|
-
const spoofModeFromEnv = parseSpoofMode(env.OPENCODE_OPENAI_MULTI_SPOOF_MODE);
|
|
690
|
-
const modeFromEnv = parseRuntimeMode(env.OPENCODE_OPENAI_MULTI_MODE);
|
|
691
|
-
const modeFromSpoofEnv = spoofModeFromEnv === "codex" ? "codex" : spoofModeFromEnv === "native" ? "native" : undefined;
|
|
692
|
-
const modeFromFileSpoof = file.spoofMode === "codex" ? "codex" : file.spoofMode === "native" ? "native" : undefined;
|
|
693
|
-
const mode = modeFromEnv ?? file.mode ?? modeFromSpoofEnv ?? modeFromFileSpoof ?? "native";
|
|
694
|
-
const behaviorSettings = cloneBehaviorSettings(fileBehavior) ?? {};
|
|
695
|
-
const globalBehavior = {
|
|
696
|
-
...(behaviorSettings.global ?? {})
|
|
697
|
-
};
|
|
698
|
-
if (envPersonality) {
|
|
699
|
-
globalBehavior.personality = envPersonality;
|
|
700
|
-
}
|
|
701
|
-
if (envThinkingSummaries !== undefined) {
|
|
702
|
-
globalBehavior.thinkingSummaries = envThinkingSummaries;
|
|
703
|
-
}
|
|
704
|
-
if (envVerbosityEnabled !== undefined) {
|
|
705
|
-
globalBehavior.verbosityEnabled = envVerbosityEnabled;
|
|
706
|
-
}
|
|
707
|
-
if (envVerbosity) {
|
|
708
|
-
globalBehavior.verbosity = envVerbosity;
|
|
709
|
-
}
|
|
710
|
-
if (globalBehavior.personality !== undefined ||
|
|
711
|
-
globalBehavior.thinkingSummaries !== undefined ||
|
|
712
|
-
globalBehavior.verbosityEnabled !== undefined ||
|
|
713
|
-
globalBehavior.verbosity !== undefined) {
|
|
714
|
-
behaviorSettings.global = globalBehavior;
|
|
715
|
-
}
|
|
716
|
-
const resolvedBehaviorSettings = behaviorSettings.global !== undefined || behaviorSettings.perModel !== undefined ? behaviorSettings : undefined;
|
|
717
|
-
const personality = envPersonality ?? resolvedBehaviorSettings?.global?.personality;
|
|
718
|
-
// Runtime mode is canonical; spoofMode remains a compatibility input only.
|
|
719
|
-
// Spoof compatibility inputs are only authoritative when runtime mode is otherwise unset.
|
|
720
|
-
// If runtime mode is explicit (env or file), derive spoof mode from runtime mode for consistency.
|
|
721
|
-
const runtimeModeExplicit = modeFromEnv !== undefined || file.mode !== undefined;
|
|
722
|
-
const spoofMode = runtimeModeExplicit
|
|
723
|
-
? mode === "native"
|
|
724
|
-
? "native"
|
|
725
|
-
: "codex"
|
|
726
|
-
: (spoofModeFromEnv ?? (mode === "native" ? "native" : "codex"));
|
|
727
|
-
const compatInputSanitizer = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_COMPAT_INPUT_SANITIZER) ?? file.compatInputSanitizer;
|
|
728
|
-
const remapDeveloperMessagesToUser = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_REMAP_DEVELOPER_MESSAGES_TO_USER) ?? file.remapDeveloperMessagesToUser;
|
|
729
|
-
const codexCompactionOverride = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_CODEX_COMPACTION_OVERRIDE) ?? file.codexCompactionOverride;
|
|
730
|
-
const headerSnapshots = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_HEADER_SNAPSHOTS) ?? file.headerSnapshots;
|
|
731
|
-
const headerSnapshotBodies = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_HEADER_SNAPSHOT_BODIES) ?? file.headerSnapshotBodies;
|
|
732
|
-
const headerTransformDebug = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_HEADER_TRANSFORM_DEBUG) ?? file.headerTransformDebug;
|
|
733
|
-
const collaborationProfileEnabled = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_COLLABORATION_PROFILE) ?? file.collaborationProfileEnabled;
|
|
734
|
-
const orchestratorSubagentsEnabled = parseEnvBoolean(env.OPENCODE_OPENAI_MULTI_ORCHESTRATOR_SUBAGENTS) ?? file.orchestratorSubagentsEnabled;
|
|
735
|
-
return {
|
|
736
|
-
...file,
|
|
737
|
-
debug: envDebug || file.debug === true,
|
|
738
|
-
proactiveRefresh,
|
|
739
|
-
proactiveRefreshBufferMs,
|
|
740
|
-
quietMode,
|
|
741
|
-
pidOffsetEnabled,
|
|
742
|
-
personality,
|
|
743
|
-
mode,
|
|
744
|
-
rotationStrategy,
|
|
745
|
-
promptCacheKeyStrategy,
|
|
746
|
-
spoofMode,
|
|
747
|
-
compatInputSanitizer,
|
|
748
|
-
remapDeveloperMessagesToUser,
|
|
749
|
-
codexCompactionOverride,
|
|
750
|
-
headerSnapshots,
|
|
751
|
-
headerSnapshotBodies,
|
|
752
|
-
headerTransformDebug,
|
|
753
|
-
collaborationProfileEnabled,
|
|
754
|
-
orchestratorSubagentsEnabled,
|
|
755
|
-
behaviorSettings: resolvedBehaviorSettings
|
|
756
|
-
};
|
|
757
|
-
}
|
|
758
|
-
export function getDebugEnabled(cfg) {
|
|
759
|
-
return cfg.debug === true;
|
|
760
|
-
}
|
|
761
|
-
export function getQuietMode(cfg) {
|
|
762
|
-
return cfg.quietMode === true;
|
|
763
|
-
}
|
|
764
|
-
export function getPidOffsetEnabled(cfg) {
|
|
765
|
-
return cfg.pidOffsetEnabled === true;
|
|
766
|
-
}
|
|
767
|
-
export function getProactiveRefreshEnabled(cfg) {
|
|
768
|
-
return cfg.proactiveRefresh === true;
|
|
769
|
-
}
|
|
770
|
-
export function getProactiveRefreshBufferMs(cfg) {
|
|
771
|
-
return typeof cfg.proactiveRefreshBufferMs === "number" && Number.isFinite(cfg.proactiveRefreshBufferMs)
|
|
772
|
-
? Math.max(0, Math.floor(cfg.proactiveRefreshBufferMs))
|
|
773
|
-
: 60_000;
|
|
774
|
-
}
|
|
775
|
-
export function getPersonality(cfg) {
|
|
776
|
-
return cfg.personality;
|
|
777
|
-
}
|
|
778
|
-
export function getSpoofMode(cfg) {
|
|
779
|
-
return cfg.spoofMode === "codex" ? "codex" : "native";
|
|
780
|
-
}
|
|
781
|
-
export function getMode(cfg) {
|
|
782
|
-
if (cfg.mode === "native" || cfg.mode === "codex")
|
|
783
|
-
return cfg.mode;
|
|
784
|
-
return getSpoofMode(cfg) === "codex" ? "codex" : "native";
|
|
785
|
-
}
|
|
786
|
-
export function getRotationStrategy(cfg) {
|
|
787
|
-
return cfg.rotationStrategy === "hybrid" || cfg.rotationStrategy === "round_robin" ? cfg.rotationStrategy : "sticky";
|
|
788
|
-
}
|
|
789
|
-
export function getPromptCacheKeyStrategy(cfg) {
|
|
790
|
-
return cfg.promptCacheKeyStrategy === "project" ? "project" : "default";
|
|
791
|
-
}
|
|
792
|
-
export function getCompatInputSanitizerEnabled(cfg) {
|
|
793
|
-
return cfg.compatInputSanitizer === true;
|
|
794
|
-
}
|
|
795
|
-
export function getRemapDeveloperMessagesToUserEnabled(cfg) {
|
|
796
|
-
if (getMode(cfg) !== "codex")
|
|
797
|
-
return false;
|
|
798
|
-
return cfg.remapDeveloperMessagesToUser !== false;
|
|
799
|
-
}
|
|
800
|
-
export function getCodexCompactionOverrideEnabled(cfg) {
|
|
801
|
-
if (cfg.codexCompactionOverride === true)
|
|
802
|
-
return true;
|
|
803
|
-
if (cfg.codexCompactionOverride === false)
|
|
804
|
-
return false;
|
|
805
|
-
return getMode(cfg) === "codex";
|
|
806
|
-
}
|
|
807
|
-
export function getHeaderSnapshotsEnabled(cfg) {
|
|
808
|
-
return cfg.headerSnapshots === true;
|
|
809
|
-
}
|
|
810
|
-
export function getHeaderTransformDebugEnabled(cfg) {
|
|
811
|
-
return cfg.headerTransformDebug === true;
|
|
812
|
-
}
|
|
813
|
-
export function getHeaderSnapshotBodiesEnabled(cfg) {
|
|
814
|
-
return cfg.headerSnapshotBodies === true;
|
|
815
|
-
}
|
|
816
|
-
export function getCollaborationProfileEnabled(cfg) {
|
|
817
|
-
if (cfg.collaborationProfileEnabled === true)
|
|
818
|
-
return true;
|
|
819
|
-
if (cfg.collaborationProfileEnabled === false)
|
|
820
|
-
return false;
|
|
821
|
-
return getMode(cfg) === "codex";
|
|
822
|
-
}
|
|
823
|
-
export function getOrchestratorSubagentsEnabled(cfg) {
|
|
824
|
-
if (cfg.orchestratorSubagentsEnabled === true)
|
|
825
|
-
return true;
|
|
826
|
-
if (cfg.orchestratorSubagentsEnabled === false)
|
|
827
|
-
return false;
|
|
828
|
-
return getCollaborationProfileEnabled(cfg);
|
|
829
|
-
}
|
|
830
|
-
export function getBehaviorSettings(cfg) {
|
|
831
|
-
return cfg.behaviorSettings;
|
|
832
|
-
}
|
|
833
|
-
export function getThinkingSummariesOverride(cfg) {
|
|
834
|
-
return cfg.behaviorSettings?.global?.thinkingSummaries;
|
|
835
|
-
}
|
|
1
|
+
export { CONFIG_FILE, DEFAULT_CODEX_CONFIG, DEFAULT_CODEX_CONFIG_TEMPLATE } from "./config/types.js";
|
|
2
|
+
export { validateConfigFileObject } from "./config/validation.js";
|
|
3
|
+
export { buildResolvedBehaviorSettings, cloneBehaviorSettings, normalizePersonalityOption, normalizeVerbosityOption, parseConfigFileObject, parseConfigJsonWithComments, parseEnvBoolean, parseEnvNumber, parsePromptCacheKeyStrategy, parseRotationStrategy, parseRuntimeMode, parseSpoofMode } from "./config/parse.js";
|
|
4
|
+
export { ensureDefaultConfigFile, loadConfigFile, resolveDefaultConfigPath } from "./config/io.js";
|
|
5
|
+
export { getBehaviorSettings, getCodexCompactionOverrideEnabled, getCollaborationProfileEnabled, getCompatInputSanitizerEnabled, getDebugEnabled, getHeaderSnapshotBodiesEnabled, getHeaderSnapshotsEnabled, getHeaderTransformDebugEnabled, getMode, getOrchestratorSubagentsEnabled, getPersonality, getPidOffsetEnabled, getProactiveRefreshBufferMs, getProactiveRefreshEnabled, getPromptCacheKeyStrategy, getQuietMode, getRemapDeveloperMessagesToUserEnabled, getRotationStrategy, getSpoofMode, getThinkingSummariesOverride, resolveConfig } from "./config/resolve.js";
|
|
836
6
|
//# sourceMappingURL=config.js.map
|