abelworkflow 1.0.0-rc.1 → 1.1.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 +7 -8
- package/extensions/pi-gpt-responses-compat/index.ts +1 -1
- package/lib/cli/args.mjs +2 -2
- package/lib/cli/main.mjs +39 -41
- package/lib/cli/prompts.mjs +16 -29
- package/lib/installer/assets.mjs +13 -15
- package/lib/installer/install.mjs +18 -32
- package/lib/installer/state.mjs +0 -19
- package/lib/providers/claude.mjs +23 -214
- package/lib/providers/codex.mjs +14 -22
- package/lib/providers/pi.mjs +273 -58
- package/lib/providers/skills.mjs +39 -88
- package/lib/templates/workflow/AGENTS.md +10 -10
- package/lib/templates/workflow/commands/abel-design.md +175 -0
- package/lib/templates/workflow/commands/abel-implement.md +64 -46
- package/lib/templates/workflow/commands/abel-init.md +2 -4
- package/package.json +1 -7
- package/skills/grok-search/.env.example +3 -3
- package/skills/grok-search/SKILL.md +1 -1
- package/skills/grok-search/defaults.json +1 -1
- package/skills/grok-search/scripts/groksearch_cli.py +42 -15
- package/skills/prompt-enhancer/SKILL.md +2 -27
- package/lib/installer/render.mjs +0 -46
- package/lib/templates/workflow/commands/abel-plan.md +0 -82
- package/lib/templates/workflow/commands/abel-research.md +0 -126
- package/skills/prompt-enhancer/.env.example +0 -12
- package/skills/prompt-enhancer/ADVANCED.md +0 -103
- package/skills/prompt-enhancer/requirements.txt +0 -1
- package/skills/prompt-enhancer/scripts/_dotenv.py +0 -32
- package/skills/prompt-enhancer/scripts/enhance.py +0 -144
- package/skills/prompt-enhancer/scripts/prompt_enhancer_entry.py +0 -238
package/lib/providers/claude.mjs
CHANGED
|
@@ -1,30 +1,10 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import {
|
|
3
|
-
pathExists,
|
|
4
3
|
readJsonFileSafe,
|
|
5
4
|
writeJsonFileWithBackup
|
|
6
5
|
} from "../config/store.mjs";
|
|
7
6
|
import { defaultPaths, maskSecret, pathToLabel } from "../paths.mjs";
|
|
8
7
|
|
|
9
|
-
const augmentContextEnginePermission = "mcp__augment-context-engine";
|
|
10
|
-
const claudePermissionProfiles = ["standard", "trusted"];
|
|
11
|
-
const trustedClaudePermissions = [
|
|
12
|
-
"Bash",
|
|
13
|
-
"Skill",
|
|
14
|
-
"LS",
|
|
15
|
-
"Read",
|
|
16
|
-
"Agent",
|
|
17
|
-
"Write",
|
|
18
|
-
"Edit",
|
|
19
|
-
"MultiEdit",
|
|
20
|
-
"Glob",
|
|
21
|
-
"Grep",
|
|
22
|
-
"WebFetch",
|
|
23
|
-
"WebSearch",
|
|
24
|
-
"TodoWrite",
|
|
25
|
-
"NotebookRead",
|
|
26
|
-
"NotebookEdit"
|
|
27
|
-
];
|
|
28
8
|
const claudeModelEnvKeys = [
|
|
29
9
|
"ANTHROPIC_MODEL",
|
|
30
10
|
"ANTHROPIC_DEFAULT_OPUS_MODEL",
|
|
@@ -37,47 +17,32 @@ const defaultClaudeSettings = {
|
|
|
37
17
|
env: {
|
|
38
18
|
DISABLE_TELEMETRY: "1",
|
|
39
19
|
DISABLE_ERROR_REPORTING: "1",
|
|
40
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
|
41
|
-
ANTHROPIC_BASE_URL: "",
|
|
42
|
-
ANTHROPIC_API_KEY: "",
|
|
43
|
-
ANTHROPIC_MODEL: "",
|
|
44
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "",
|
|
45
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "",
|
|
46
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "",
|
|
47
|
-
CLAUDE_CODE_SUBAGENT_MODEL: ""
|
|
20
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
|
48
21
|
},
|
|
49
22
|
includeCoAuthoredBy: false,
|
|
50
23
|
permissions: {
|
|
51
24
|
allow: [],
|
|
52
|
-
deny: []
|
|
25
|
+
deny: [],
|
|
26
|
+
defaultMode: "bypassPermissions"
|
|
53
27
|
},
|
|
54
28
|
hooks: {},
|
|
55
29
|
alwaysThinkingEnabled: true,
|
|
56
30
|
language: "Chinese"
|
|
57
31
|
};
|
|
58
|
-
function buildDefaultClaudeSettings(
|
|
59
|
-
|
|
60
|
-
throw new Error(`Unknown Claude permission profile: ${profile}`);
|
|
61
|
-
}
|
|
62
|
-
const settings = {
|
|
32
|
+
function buildDefaultClaudeSettings() {
|
|
33
|
+
return {
|
|
63
34
|
...defaultClaudeSettings,
|
|
64
35
|
env: { ...defaultClaudeSettings.env },
|
|
65
36
|
permissions: {
|
|
66
37
|
...defaultClaudeSettings.permissions,
|
|
67
|
-
allow:
|
|
38
|
+
allow: [...defaultClaudeSettings.permissions.allow],
|
|
68
39
|
deny: [...defaultClaudeSettings.permissions.deny]
|
|
69
40
|
},
|
|
70
41
|
hooks: { ...defaultClaudeSettings.hooks }
|
|
71
42
|
};
|
|
72
|
-
|
|
73
|
-
if (augmentContextEngine && !settings.permissions.allow.includes(augmentContextEnginePermission)) {
|
|
74
|
-
settings.permissions.allow.push(augmentContextEnginePermission);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return settings;
|
|
78
43
|
}
|
|
79
|
-
function mergeClaudeSettingsWithDefaults(settings
|
|
80
|
-
const defaults = buildDefaultClaudeSettings(
|
|
44
|
+
function mergeClaudeSettingsWithDefaults(settings) {
|
|
45
|
+
const defaults = buildDefaultClaudeSettings();
|
|
81
46
|
const env = settings?.env && typeof settings.env === "object" ? settings.env : {};
|
|
82
47
|
const permissions = settings?.permissions && typeof settings.permissions === "object" ? settings.permissions : {};
|
|
83
48
|
return {
|
|
@@ -107,138 +72,11 @@ function applyClaudeInsecureTlsSetting(env = {}, enabled = false) {
|
|
|
107
72
|
return nextEnv;
|
|
108
73
|
}
|
|
109
74
|
|
|
110
|
-
function getPreviousManagedClaudePermissions(previousMetadata = {}) {
|
|
111
|
-
return Array.isArray(previousMetadata.managedClaudePermissions)
|
|
112
|
-
? previousMetadata.managedClaudePermissions.filter((value) => typeof value === "string")
|
|
113
|
-
: [];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function applyClaudePermissionProfile(settings, {
|
|
117
|
-
profile = "standard",
|
|
118
|
-
previousManagedPermissions = []
|
|
119
|
-
} = {}) {
|
|
120
|
-
if (!claudePermissionProfiles.includes(profile)) {
|
|
121
|
-
throw new Error(`Unknown Claude permission profile: ${profile}`);
|
|
122
|
-
}
|
|
123
|
-
const hasSettings = settings && typeof settings === "object" && !Array.isArray(settings);
|
|
124
|
-
const nextSettings = hasSettings
|
|
125
|
-
? {
|
|
126
|
-
...settings,
|
|
127
|
-
permissions: settings.permissions && typeof settings.permissions === "object"
|
|
128
|
-
? { ...settings.permissions }
|
|
129
|
-
: {}
|
|
130
|
-
}
|
|
131
|
-
: buildDefaultClaudeSettings();
|
|
132
|
-
const allow = Array.isArray(nextSettings.permissions.allow)
|
|
133
|
-
? [...nextSettings.permissions.allow]
|
|
134
|
-
: [];
|
|
135
|
-
const previousManaged = new Set(previousManagedPermissions.filter((value) => typeof value === "string"));
|
|
136
|
-
const retainedManaged = [];
|
|
137
|
-
|
|
138
|
-
for (const permission of previousManaged) {
|
|
139
|
-
if (permission === augmentContextEnginePermission) {
|
|
140
|
-
if (allow.includes(permission)) retainedManaged.push(permission);
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
const index = allow.indexOf(permission);
|
|
144
|
-
if (index !== -1) allow.splice(index, 1);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (profile === "trusted") {
|
|
148
|
-
for (const permission of trustedClaudePermissions) {
|
|
149
|
-
if (allow.includes(permission)) continue;
|
|
150
|
-
allow.push(permission);
|
|
151
|
-
retainedManaged.push(permission);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const previousAllow = Array.isArray(nextSettings.permissions.allow)
|
|
156
|
-
? nextSettings.permissions.allow
|
|
157
|
-
: [];
|
|
158
|
-
nextSettings.permissions.allow = allow;
|
|
159
|
-
return {
|
|
160
|
-
settings: nextSettings,
|
|
161
|
-
changed: !hasSettings || previousAllow.length !== allow.length
|
|
162
|
-
|| previousAllow.some((permission, index) => permission !== allow[index]),
|
|
163
|
-
managedPermissions: [...new Set(retainedManaged)]
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function applyClaudePermissionFeature(settings, {
|
|
168
|
-
augmentContextEngine = false,
|
|
169
|
-
previousManagedPermissions = []
|
|
170
|
-
} = {}) {
|
|
171
|
-
const hasSettings = settings && typeof settings === "object";
|
|
172
|
-
const wasManaged = previousManagedPermissions.includes(augmentContextEnginePermission);
|
|
173
|
-
if (!hasSettings && !augmentContextEngine) {
|
|
174
|
-
return { settings, changed: false, managedPermissions: [] };
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const nextSettings = hasSettings
|
|
178
|
-
? {
|
|
179
|
-
...settings,
|
|
180
|
-
permissions: settings.permissions && typeof settings.permissions === "object"
|
|
181
|
-
? { ...settings.permissions }
|
|
182
|
-
: {}
|
|
183
|
-
}
|
|
184
|
-
: { permissions: {} };
|
|
185
|
-
const permissions = nextSettings.permissions;
|
|
186
|
-
const allow = Array.isArray(permissions.allow)
|
|
187
|
-
? [...permissions.allow]
|
|
188
|
-
: [];
|
|
189
|
-
let changed = !hasSettings;
|
|
190
|
-
let isManaged = wasManaged;
|
|
191
|
-
|
|
192
|
-
if (augmentContextEngine) {
|
|
193
|
-
if (!allow.includes(augmentContextEnginePermission)) {
|
|
194
|
-
allow.push(augmentContextEnginePermission);
|
|
195
|
-
changed = true;
|
|
196
|
-
isManaged = true;
|
|
197
|
-
}
|
|
198
|
-
} else if (wasManaged && allow.includes(augmentContextEnginePermission)) {
|
|
199
|
-
allow.splice(allow.indexOf(augmentContextEnginePermission), 1);
|
|
200
|
-
changed = true;
|
|
201
|
-
isManaged = false;
|
|
202
|
-
} else {
|
|
203
|
-
isManaged = false;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
permissions.allow = allow;
|
|
207
|
-
nextSettings.permissions = permissions;
|
|
208
|
-
|
|
209
|
-
return {
|
|
210
|
-
settings: nextSettings,
|
|
211
|
-
changed,
|
|
212
|
-
managedPermissions: [
|
|
213
|
-
...previousManagedPermissions.filter((permission) => permission !== augmentContextEnginePermission && allow.includes(permission)),
|
|
214
|
-
...(isManaged ? [augmentContextEnginePermission] : [])
|
|
215
|
-
]
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
async function ensureClaudeSettingsForFeature(paths, augmentContextEngine, previousMetadata) {
|
|
220
|
-
const settingsExists = await pathExists(paths.claudeSettingsPath);
|
|
221
|
-
const settings = settingsExists
|
|
222
|
-
? await readJsonFileSafe(paths.claudeSettingsPath, {}, { sensitive: true })
|
|
223
|
-
: undefined;
|
|
224
|
-
const result = applyClaudePermissionFeature(settings, {
|
|
225
|
-
augmentContextEngine,
|
|
226
|
-
previousManagedPermissions: getPreviousManagedClaudePermissions(previousMetadata)
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
if (result.changed && result.settings) {
|
|
230
|
-
await writeJsonFileWithBackup(paths.claudeSettingsPath, result.settings, { sensitive: true });
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
return result.managedPermissions;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
75
|
function getExistingClaudeApiConfig(settings) {
|
|
237
76
|
const env = mergeClaudeSettingsWithDefaults(settings).env;
|
|
238
77
|
return {
|
|
239
78
|
baseUrl: env.ANTHROPIC_BASE_URL || "https://api.anthropic.com",
|
|
240
|
-
|
|
241
|
-
key: env.ANTHROPIC_AUTH_TOKEN || env.ANTHROPIC_API_KEY || "",
|
|
79
|
+
key: env.ANTHROPIC_API_KEY || "",
|
|
242
80
|
model: claudeModelEnvKeys.map((field) => env[field]).find(Boolean) || "",
|
|
243
81
|
insecureTls: env.NODE_TLS_REJECT_UNAUTHORIZED === "0"
|
|
244
82
|
};
|
|
@@ -269,7 +107,6 @@ function ensureApprovedClaudeApiKey(config, apiKey) {
|
|
|
269
107
|
}
|
|
270
108
|
|
|
271
109
|
function buildClaudeApiSettings(settings, {
|
|
272
|
-
authType,
|
|
273
110
|
baseUrl,
|
|
274
111
|
key,
|
|
275
112
|
model,
|
|
@@ -281,13 +118,8 @@ function buildClaudeApiSettings(settings, {
|
|
|
281
118
|
insecureTls
|
|
282
119
|
);
|
|
283
120
|
nextSettings.env.ANTHROPIC_BASE_URL = baseUrl;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
delete nextSettings.env.ANTHROPIC_API_KEY;
|
|
287
|
-
} else {
|
|
288
|
-
nextSettings.env.ANTHROPIC_API_KEY = key;
|
|
289
|
-
delete nextSettings.env.ANTHROPIC_AUTH_TOKEN;
|
|
290
|
-
}
|
|
121
|
+
nextSettings.env.ANTHROPIC_API_KEY = key;
|
|
122
|
+
delete nextSettings.env.ANTHROPIC_AUTH_TOKEN;
|
|
291
123
|
for (const field of claudeModelEnvKeys) {
|
|
292
124
|
nextSettings.env[field] = model;
|
|
293
125
|
}
|
|
@@ -299,39 +131,30 @@ async function persistClaudeConfiguration(paths, { settings, metaConfig }) {
|
|
|
299
131
|
await writeJsonFileWithBackup(paths.claudeMetaConfigPath, metaConfig, { sensitive: true });
|
|
300
132
|
}
|
|
301
133
|
|
|
302
|
-
async function configureClaudeApi(paths = defaultPaths, promptApi
|
|
134
|
+
async function configureClaudeApi(paths = defaultPaths, promptApi) {
|
|
303
135
|
const {
|
|
304
136
|
assertNotCancelled,
|
|
305
137
|
confirmOrCancel,
|
|
138
|
+
passwordPromptOptions,
|
|
306
139
|
required,
|
|
307
140
|
requiredUnlessExisting,
|
|
308
|
-
resolvePasswordValue
|
|
309
|
-
selectOrCancel
|
|
141
|
+
resolvePasswordValue
|
|
310
142
|
} = promptApi;
|
|
311
143
|
const settings = await readJsonFileSafe(paths.claudeSettingsPath, {}, { sensitive: true });
|
|
312
144
|
const existing = getExistingClaudeApiConfig(settings);
|
|
313
|
-
const authType = await selectOrCancel({
|
|
314
|
-
message: "Claude Code 第三方 API 认证方式",
|
|
315
|
-
options: [
|
|
316
|
-
{ value: "api_key", label: "API Key" },
|
|
317
|
-
{ value: "auth_token", label: "Auth Token" }
|
|
318
|
-
],
|
|
319
|
-
initialValue: existing.authType
|
|
320
|
-
});
|
|
321
145
|
|
|
322
146
|
const baseUrl = await p.text({
|
|
323
147
|
message: "Claude Code Base URL",
|
|
324
|
-
|
|
148
|
+
initialValue: existing.baseUrl,
|
|
325
149
|
validate: required()
|
|
326
150
|
});
|
|
327
151
|
assertNotCancelled(baseUrl);
|
|
328
152
|
|
|
329
|
-
const key = await p.password(
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
});
|
|
153
|
+
const key = await p.password(passwordPromptOptions(
|
|
154
|
+
"Claude Code API Key",
|
|
155
|
+
existing.key,
|
|
156
|
+
requiredUnlessExisting(existing.key, "API Key 不能为空")
|
|
157
|
+
));
|
|
335
158
|
assertNotCancelled(key);
|
|
336
159
|
const finalKey = resolvePasswordValue(key, existing.key);
|
|
337
160
|
|
|
@@ -342,47 +165,33 @@ async function configureClaudeApi(paths = defaultPaths, promptApi, options = {})
|
|
|
342
165
|
|
|
343
166
|
const model = await p.text({
|
|
344
167
|
message: "Claude Code 模型",
|
|
345
|
-
|
|
168
|
+
initialValue: existing.model || undefined,
|
|
346
169
|
validate: required()
|
|
347
170
|
});
|
|
348
171
|
assertNotCancelled(model);
|
|
349
172
|
|
|
350
173
|
const apiSettings = buildClaudeApiSettings(settings, {
|
|
351
|
-
authType,
|
|
352
174
|
baseUrl,
|
|
353
175
|
key: finalKey,
|
|
354
176
|
model,
|
|
355
177
|
insecureTls
|
|
356
178
|
});
|
|
357
|
-
const profileResult = applyClaudePermissionProfile(apiSettings, {
|
|
358
|
-
profile: options.permissionProfile ?? "standard",
|
|
359
|
-
previousManagedPermissions: options.previousManagedPermissions ?? []
|
|
360
|
-
});
|
|
361
179
|
const metaConfig = await readJsonFileSafe(paths.claudeMetaConfigPath, {}, { sensitive: true });
|
|
362
180
|
metaConfig.hasCompletedOnboarding = true;
|
|
363
181
|
ensureApprovedClaudeApiKey(metaConfig, finalKey);
|
|
364
182
|
await persistClaudeConfiguration(paths, {
|
|
365
|
-
settings:
|
|
183
|
+
settings: apiSettings,
|
|
366
184
|
metaConfig
|
|
367
185
|
});
|
|
368
186
|
|
|
369
|
-
p.log.step(`已更新 ${pathToLabel(paths.claudeSettingsPath, paths.homeDir)} (${
|
|
370
|
-
return {
|
|
371
|
-
managedPermissions: profileResult.managedPermissions,
|
|
372
|
-
permissionProfile: options.permissionProfile ?? "standard"
|
|
373
|
-
};
|
|
187
|
+
p.log.step(`已更新 ${pathToLabel(paths.claudeSettingsPath, paths.homeDir)} (${baseUrl}, ${maskSecret(finalKey)})`);
|
|
374
188
|
}
|
|
375
189
|
|
|
376
|
-
|
|
377
190
|
export {
|
|
378
191
|
applyClaudeInsecureTlsSetting,
|
|
379
|
-
applyClaudePermissionFeature,
|
|
380
|
-
applyClaudePermissionProfile,
|
|
381
192
|
buildClaudeApiSettings,
|
|
382
193
|
buildDefaultClaudeSettings,
|
|
383
194
|
configureClaudeApi,
|
|
384
|
-
ensureClaudeSettingsForFeature,
|
|
385
|
-
getPreviousManagedClaudePermissions,
|
|
386
195
|
mergeClaudeSettingsWithDefaults,
|
|
387
196
|
persistClaudeConfiguration
|
|
388
197
|
};
|
package/lib/providers/codex.mjs
CHANGED
|
@@ -25,6 +25,8 @@ import {
|
|
|
25
25
|
import { defaultPaths, maskSecret, pathToLabel } from "../paths.mjs";
|
|
26
26
|
import { normalizeOpenAiBaseUrl } from "./pi.mjs";
|
|
27
27
|
|
|
28
|
+
const CODEX_ENV_KEY = "OPENAI_API_KEY";
|
|
29
|
+
|
|
28
30
|
const publishedCodexDeveloperInstructionHashes = new Set([
|
|
29
31
|
"957adb227dd3fc298985acca38db4c22b8e018d387dab91f1ea8287db35385db"
|
|
30
32
|
]);
|
|
@@ -249,13 +251,6 @@ async function deployBundledCodexAgents(paths = defaultPaths, previousManagedFil
|
|
|
249
251
|
return result;
|
|
250
252
|
}
|
|
251
253
|
|
|
252
|
-
function getDefaultCodexEnvKey(providerId) {
|
|
253
|
-
if (providerId === "openai") return "OPENAI_API_KEY";
|
|
254
|
-
if (providerId === "abelworkflow") return "ABELWORKFLOW_API_KEY";
|
|
255
|
-
const digest = createHash("sha256").update(providerId).digest("hex").toUpperCase();
|
|
256
|
-
return `ABELWORKFLOW_PROVIDER_${digest}_API_KEY`;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
254
|
function getCodexProviderSectionName(providerId) {
|
|
260
255
|
return `model_providers.${formatTomlKeySegment(providerId)}`;
|
|
261
256
|
}
|
|
@@ -275,8 +270,7 @@ function assertCodexAuthKeyAvailable(auth, envKey) {
|
|
|
275
270
|
function resolveExistingCodexApiConfig(content, auth = {}) {
|
|
276
271
|
const providerId = readTopLevelTomlString(content, "model_provider") || "abelworkflow";
|
|
277
272
|
const provider = parseTomlSection(content, getCodexProviderSectionName(providerId));
|
|
278
|
-
const
|
|
279
|
-
const envKey = configuredEnvKey || getDefaultCodexEnvKey(providerId);
|
|
273
|
+
const envKey = CODEX_ENV_KEY;
|
|
280
274
|
assertCodexAuthKeyAvailable(auth, envKey);
|
|
281
275
|
const apiKey = typeof auth[envKey] === "string" ? auth[envKey] : "";
|
|
282
276
|
|
|
@@ -304,6 +298,7 @@ async function configureCodexApi(paths = defaultPaths, promptApi, ownership = {}
|
|
|
304
298
|
const {
|
|
305
299
|
assertNotCancelled,
|
|
306
300
|
confirmOrCancel,
|
|
301
|
+
passwordPromptOptions,
|
|
307
302
|
required,
|
|
308
303
|
requiredUnlessExisting,
|
|
309
304
|
resolvePasswordValue
|
|
@@ -313,25 +308,24 @@ async function configureCodexApi(paths = defaultPaths, promptApi, ownership = {}
|
|
|
313
308
|
const providerName = existing.providerName || providerId;
|
|
314
309
|
const baseUrlInput = await p.text({
|
|
315
310
|
message: "Codex Base URL",
|
|
316
|
-
|
|
311
|
+
initialValue: existing.baseUrl,
|
|
317
312
|
validate: required()
|
|
318
313
|
});
|
|
319
314
|
assertNotCancelled(baseUrlInput);
|
|
320
315
|
const baseUrl = normalizeOpenAiBaseUrl(baseUrlInput);
|
|
321
316
|
|
|
322
|
-
const apiKey = await p.password(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
});
|
|
317
|
+
const apiKey = await p.password(passwordPromptOptions(
|
|
318
|
+
"Codex 第三方 API Key",
|
|
319
|
+
existing.apiKey,
|
|
320
|
+
requiredUnlessExisting(existing.apiKey, "API Key 不能为空")
|
|
321
|
+
));
|
|
328
322
|
assertNotCancelled(apiKey);
|
|
329
323
|
const finalApiKey = resolvePasswordValue(apiKey, existing.apiKey);
|
|
330
324
|
|
|
331
325
|
const shouldDeploySubagents = await confirmOrCancel({ message: "是否部署 Codex subagents 配置?", initialValue: true });
|
|
332
326
|
let managedCodexAgentFiles = { ...(ownership.managedCodexAgentFiles ?? {}) };
|
|
333
327
|
|
|
334
|
-
const envKey =
|
|
328
|
+
const envKey = CODEX_ENV_KEY;
|
|
335
329
|
const currentContent = await pathExists(paths.codexConfigPath) ? await readFile(paths.codexConfigPath, "utf8") : "";
|
|
336
330
|
const templateContent = await loadBundledCodexConfigTemplate(paths);
|
|
337
331
|
const content = buildCodexConfigContent(currentContent, {
|
|
@@ -340,8 +334,7 @@ async function configureCodexApi(paths = defaultPaths, promptApi, ownership = {}
|
|
|
340
334
|
includeSubagentDefaults: shouldDeploySubagents,
|
|
341
335
|
providerId,
|
|
342
336
|
providerName,
|
|
343
|
-
baseUrl
|
|
344
|
-
envKey
|
|
337
|
+
baseUrl
|
|
345
338
|
});
|
|
346
339
|
|
|
347
340
|
const auth = mergeCodexAuthData(
|
|
@@ -382,8 +375,7 @@ function buildCodexConfigContent(currentContent, {
|
|
|
382
375
|
includeSubagentDefaults = true,
|
|
383
376
|
providerId,
|
|
384
377
|
providerName,
|
|
385
|
-
baseUrl
|
|
386
|
-
envKey
|
|
378
|
+
baseUrl
|
|
387
379
|
}) {
|
|
388
380
|
const effectiveTemplateContent = includeSubagentDefaults
|
|
389
381
|
? templateContent
|
|
@@ -403,7 +395,7 @@ function buildCodexConfigContent(currentContent, {
|
|
|
403
395
|
name: providerName,
|
|
404
396
|
base_url: baseUrl,
|
|
405
397
|
wire_api: "responses",
|
|
406
|
-
temp_env_key:
|
|
398
|
+
temp_env_key: CODEX_ENV_KEY,
|
|
407
399
|
requires_openai_auth: true,
|
|
408
400
|
supports_websockets: true
|
|
409
401
|
});
|