@minniexcode/codex-switch 0.0.5 → 0.0.7
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.AI.md +5 -2
- package/README.md +44 -100
- package/dist/app/add-provider.js +28 -4
- package/dist/app/edit-provider.js +47 -19
- package/dist/app/export-providers.js +2 -2
- package/dist/app/get-current-profile.js +1 -1
- package/dist/app/get-status.js +10 -3
- package/dist/app/import-providers.js +15 -7
- package/dist/app/init-codex.js +68 -0
- package/dist/app/list-backups.js +1 -1
- package/dist/app/list-config-profiles.js +3 -2
- package/dist/app/list-providers.js +2 -1
- package/dist/app/remove-provider.js +2 -2
- package/dist/app/rollback-backup.js +1 -1
- package/dist/app/rollback-latest.js +1 -1
- package/dist/app/run-doctor.js +83 -6
- package/dist/app/run-mutation.js +2 -2
- package/dist/app/setup-codex.js +21 -12
- package/dist/app/show-config.js +11 -3
- package/dist/app/show-provider.js +1 -1
- package/dist/app/switch-provider.js +16 -9
- package/dist/cli/add-interactive.js +7 -104
- package/dist/cli/args.js +6 -135
- package/dist/cli/help.js +8 -313
- package/dist/cli/interactive.js +17 -225
- package/dist/cli/output.js +21 -6
- package/dist/cli/prompt.js +4 -106
- package/dist/cli.js +10 -404
- package/dist/commands/args.js +132 -0
- package/dist/commands/dispatch.js +16 -0
- package/dist/commands/handlers.js +460 -0
- package/dist/commands/help.js +120 -0
- package/dist/commands/registry.js +351 -0
- package/dist/commands/types.js +2 -0
- package/dist/domain/config.js +235 -21
- package/dist/domain/providers.js +16 -2
- package/dist/domain/setup.js +1 -0
- package/dist/infra/backup-repo.js +9 -206
- package/dist/infra/codex-cli.js +9 -126
- package/dist/infra/codex-paths.js +6 -67
- package/dist/infra/config-repo.js +59 -0
- package/dist/infra/fs-utils.js +8 -93
- package/dist/infra/lock-repo.js +4 -95
- package/dist/infra/providers-repo.js +8 -94
- package/dist/interaction/add-interactive.js +99 -0
- package/dist/interaction/interactive.js +289 -0
- package/dist/interaction/prompt.js +110 -0
- package/dist/runtime/codex-cli.js +130 -0
- package/dist/runtime/codex-probe.js +57 -0
- package/dist/runtime/types.js +2 -0
- package/dist/storage/auth-repo.js +160 -0
- package/dist/storage/backup-repo.js +210 -0
- package/dist/storage/codex-paths.js +71 -0
- package/dist/storage/config-repo.js +266 -0
- package/dist/storage/fs-utils.js +97 -0
- package/dist/storage/lock-repo.js +99 -0
- package/dist/storage/providers-repo.js +98 -0
- package/docs/Design/codex-switch-v0.0.5-design.md +32 -22
- package/docs/Design/codex-switch-v0.0.6-design.md +708 -0
- package/docs/Design/codex-switch-v0.0.7-design.md +862 -0
- package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +227 -89
- package/docs/PRD/codex-switch-prd-v0.1.0.md +200 -226
- package/docs/PRD/codex-switch-prd.md +1 -1
- package/docs/Reference/codex-config-reference.md +604 -0
- package/docs/Reference/codex-config-reference.zh-CN.md +633 -0
- package/docs/cli-usage.md +78 -29
- package/docs/codex-switch-technical-architecture.md +73 -4
- package/docs/test-report-0.0.5.md +163 -0
- package/docs/test-report-0.0.7.md +118 -0
- package/docs/testing.md +151 -0
- package/package.json +1 -1
|
@@ -1,210 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.createBackup =
|
|
37
|
-
exports.restoreManifest = restoreManifest;
|
|
38
|
-
exports.saveLatestManifest = saveLatestManifest;
|
|
39
|
-
exports.loadLatestManifest = loadLatestManifest;
|
|
40
|
-
exports.loadManifestById = loadManifestById;
|
|
41
|
-
exports.listBackups = listBackups;
|
|
42
|
-
const fs = __importStar(require("node:fs"));
|
|
43
|
-
const path = __importStar(require("node:path"));
|
|
44
|
-
const backups_1 = require("../domain/backups");
|
|
45
|
-
const errors_1 = require("../domain/errors");
|
|
46
|
-
const fs_utils_1 = require("./fs-utils");
|
|
3
|
+
exports.saveLatestManifest = exports.restoreManifest = exports.loadManifestById = exports.loadLatestManifest = exports.listBackups = exports.createBackup = void 0;
|
|
47
4
|
/**
|
|
48
|
-
*
|
|
5
|
+
* Compatibility facade that re-exports backup repository helpers from storage.
|
|
49
6
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const exists = fs.existsSync(file.absolutePath);
|
|
58
|
-
const backupFileName = exists ? file.relativePath.replace(/[\\/]/g, "__") : null;
|
|
59
|
-
if (exists && backupFileName) {
|
|
60
|
-
// Flatten relative paths into a single filename inside the backup directory.
|
|
61
|
-
fs.copyFileSync(file.absolutePath, path.join(backupDir, backupFileName));
|
|
62
|
-
}
|
|
63
|
-
entries.push({
|
|
64
|
-
relativePath: file.relativePath,
|
|
65
|
-
existed: exists,
|
|
66
|
-
backupFileName,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
const manifest = {
|
|
70
|
-
version: 1,
|
|
71
|
-
createdAt: new Date().toISOString(),
|
|
72
|
-
reason,
|
|
73
|
-
rootDir: codexDir,
|
|
74
|
-
backupDir,
|
|
75
|
-
files: entries,
|
|
76
|
-
};
|
|
77
|
-
(0, fs_utils_1.writeTextFileAtomic)(path.join(backupDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
78
|
-
return manifest;
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
throw (0, errors_1.cliError)("BACKUP_FAILED", "Failed to create backup.", {
|
|
82
|
-
cause: (0, errors_1.normalizeError)(error).message,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Restores all files described by a backup manifest back into the Codex directory.
|
|
88
|
-
*/
|
|
89
|
-
function restoreManifest(manifest) {
|
|
90
|
-
for (const entry of manifest.files) {
|
|
91
|
-
const targetPath = path.join(manifest.rootDir, entry.relativePath);
|
|
92
|
-
if (!entry.existed) {
|
|
93
|
-
if (fs.existsSync(targetPath)) {
|
|
94
|
-
// Remove files that were created by the failed mutation but were absent before it.
|
|
95
|
-
fs.rmSync(targetPath, { force: true });
|
|
96
|
-
}
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
if (!entry.backupFileName) {
|
|
100
|
-
throw new Error(`Backup file for ${entry.relativePath} is missing from manifest.`);
|
|
101
|
-
}
|
|
102
|
-
const sourcePath = path.join(manifest.backupDir, entry.backupFileName);
|
|
103
|
-
if (!fs.existsSync(sourcePath)) {
|
|
104
|
-
throw new Error(`Backup file not found: ${sourcePath}`);
|
|
105
|
-
}
|
|
106
|
-
(0, fs_utils_1.ensureDir)(path.dirname(targetPath));
|
|
107
|
-
fs.copyFileSync(sourcePath, targetPath);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Persists the latest successful backup manifest for manual rollback.
|
|
112
|
-
*/
|
|
113
|
-
function saveLatestManifest(latestBackupPath, manifest) {
|
|
114
|
-
(0, fs_utils_1.writeTextFileAtomic)(latestBackupPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Loads and validates the latest rollback manifest file.
|
|
118
|
-
*/
|
|
119
|
-
function loadLatestManifest(latestBackupPath) {
|
|
120
|
-
if (!fs.existsSync(latestBackupPath)) {
|
|
121
|
-
throw (0, errors_1.cliError)("BACKUP_NOT_FOUND", "No rollback backup is available.", {
|
|
122
|
-
file: latestBackupPath,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
try {
|
|
126
|
-
return (0, backups_1.validateBackupManifest)(JSON.parse(fs.readFileSync(latestBackupPath, "utf8")));
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
throw (0, errors_1.cliError)("ROLLBACK_FAILED", "Failed to read latest backup manifest.", {
|
|
130
|
-
file: latestBackupPath,
|
|
131
|
-
cause: (0, errors_1.normalizeError)(error).message,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Loads a backup manifest by its explicit backup id.
|
|
137
|
-
*/
|
|
138
|
-
function loadManifestById(backupsDir, backupId) {
|
|
139
|
-
const manifestPath = path.join(backupsDir, backupId, "manifest.json");
|
|
140
|
-
if (!fs.existsSync(manifestPath)) {
|
|
141
|
-
throw (0, errors_1.cliError)("BACKUP_NOT_FOUND", `Backup "${backupId}" was not found.`, {
|
|
142
|
-
backupId,
|
|
143
|
-
file: manifestPath,
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
try {
|
|
147
|
-
return (0, backups_1.validateBackupManifest)(JSON.parse(fs.readFileSync(manifestPath, "utf8")));
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
throw (0, errors_1.cliError)("ROLLBACK_FAILED", `Failed to read backup manifest "${backupId}".`, {
|
|
151
|
-
backupId,
|
|
152
|
-
file: manifestPath,
|
|
153
|
-
cause: (0, errors_1.normalizeError)(error).message,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Lists valid backup manifests under backups/, newest first, while skipping corrupt entries with warnings.
|
|
159
|
-
*/
|
|
160
|
-
function listBackups(backupsDir) {
|
|
161
|
-
if (!fs.existsSync(backupsDir)) {
|
|
162
|
-
throw (0, errors_1.cliError)("BACKUP_NOT_FOUND", "No backups directory exists.", {
|
|
163
|
-
directory: backupsDir,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
const entries = fs.readdirSync(backupsDir, { withFileTypes: true });
|
|
167
|
-
const backups = [];
|
|
168
|
-
const warnings = [];
|
|
169
|
-
for (const entry of entries) {
|
|
170
|
-
if (!entry.isDirectory() || entry.name === "latest.json") {
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
const manifestPath = path.join(backupsDir, entry.name, "manifest.json");
|
|
174
|
-
if (!fs.existsSync(manifestPath)) {
|
|
175
|
-
warnings.push(`Skipped backup "${entry.name}" because manifest.json is missing.`);
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
try {
|
|
179
|
-
backups.push((0, backups_1.toBackupListItem)((0, backups_1.validateBackupManifest)(JSON.parse(fs.readFileSync(manifestPath, "utf8")))));
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
warnings.push(`Skipped backup "${entry.name}" because manifest.json is invalid: ${(0, errors_1.normalizeError)(error).message}`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (backups.length === 0) {
|
|
186
|
-
throw (0, errors_1.cliError)("BACKUP_NOT_FOUND", "No valid backups were found.", {
|
|
187
|
-
directory: backupsDir,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
backups: (0, backups_1.sortBackupList)(backups),
|
|
192
|
-
warnings,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Formats a filesystem-safe timestamp for backup directory names.
|
|
197
|
-
*/
|
|
198
|
-
function createTimestamp() {
|
|
199
|
-
const now = new Date();
|
|
200
|
-
const pad = (value) => value.toString().padStart(2, "0");
|
|
201
|
-
return [
|
|
202
|
-
now.getFullYear().toString(),
|
|
203
|
-
pad(now.getMonth() + 1),
|
|
204
|
-
pad(now.getDate()),
|
|
205
|
-
"-",
|
|
206
|
-
pad(now.getHours()),
|
|
207
|
-
pad(now.getMinutes()),
|
|
208
|
-
pad(now.getSeconds()),
|
|
209
|
-
].join("");
|
|
210
|
-
}
|
|
7
|
+
var backup_repo_1 = require("../storage/backup-repo");
|
|
8
|
+
Object.defineProperty(exports, "createBackup", { enumerable: true, get: function () { return backup_repo_1.createBackup; } });
|
|
9
|
+
Object.defineProperty(exports, "listBackups", { enumerable: true, get: function () { return backup_repo_1.listBackups; } });
|
|
10
|
+
Object.defineProperty(exports, "loadLatestManifest", { enumerable: true, get: function () { return backup_repo_1.loadLatestManifest; } });
|
|
11
|
+
Object.defineProperty(exports, "loadManifestById", { enumerable: true, get: function () { return backup_repo_1.loadManifestById; } });
|
|
12
|
+
Object.defineProperty(exports, "restoreManifest", { enumerable: true, get: function () { return backup_repo_1.restoreManifest; } });
|
|
13
|
+
Object.defineProperty(exports, "saveLatestManifest", { enumerable: true, get: function () { return backup_repo_1.saveLatestManifest; } });
|
package/dist/infra/codex-cli.js
CHANGED
|
@@ -1,130 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.setCodexSpawnImplementation =
|
|
4
|
-
exports.resetCodexSpawnImplementation = resetCodexSpawnImplementation;
|
|
5
|
-
exports.runCodexLogin = runCodexLogin;
|
|
6
|
-
exports.checkCodexAvailable = checkCodexAvailable;
|
|
7
|
-
exports.readCodexVersion = readCodexVersion;
|
|
8
|
-
exports.checkCodexVersion = checkCodexVersion;
|
|
9
|
-
const node_child_process_1 = require("node:child_process");
|
|
10
|
-
const errors_1 = require("../domain/errors");
|
|
11
|
-
let spawnImplementation = node_child_process_1.spawnSync;
|
|
12
|
-
function getCodexInvocation(args) {
|
|
13
|
-
if (process.platform === "win32") {
|
|
14
|
-
return {
|
|
15
|
-
command: process.env.ComSpec || "cmd.exe",
|
|
16
|
-
args: ["/d", "/s", "/c", ["codex", ...args].join(" ")],
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
return {
|
|
20
|
-
command: "codex",
|
|
21
|
-
args,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
3
|
+
exports.setCodexSpawnImplementation = exports.runCodexLogin = exports.resetCodexSpawnImplementation = exports.readCodexVersion = exports.checkCodexVersion = exports.checkCodexAvailable = void 0;
|
|
24
4
|
/**
|
|
25
|
-
*
|
|
5
|
+
* Compatibility facade that re-exports codex CLI runtime helpers.
|
|
26
6
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
function
|
|
34
|
-
spawnImplementation = node_child_process_1.spawnSync;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Runs `codex login --with-api-key` in the target Codex directory.
|
|
38
|
-
*/
|
|
39
|
-
function runCodexLogin(apiKey, workingDir) {
|
|
40
|
-
const invocation = getCodexInvocation(["login", "--with-api-key"]);
|
|
41
|
-
const result = spawnImplementation(invocation.command, invocation.args, {
|
|
42
|
-
cwd: workingDir,
|
|
43
|
-
input: `${apiKey}\n`,
|
|
44
|
-
stdio: "pipe",
|
|
45
|
-
encoding: "utf8",
|
|
46
|
-
});
|
|
47
|
-
if (result.error || result.status !== 0) {
|
|
48
|
-
throw (0, errors_1.cliError)("CODEX_LOGIN_FAILED", "codex login --with-api-key failed.", {
|
|
49
|
-
cause: result.error?.message ?? (result.stderr.trim() || "Unknown codex login failure"),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Checks whether the Codex CLI is available on PATH.
|
|
55
|
-
*/
|
|
56
|
-
function checkCodexAvailable() {
|
|
57
|
-
const invocation = getCodexInvocation(["--version"]);
|
|
58
|
-
const result = spawnImplementation(invocation.command, invocation.args, {
|
|
59
|
-
stdio: "pipe",
|
|
60
|
-
encoding: "utf8",
|
|
61
|
-
});
|
|
62
|
-
if (result.error || result.status !== 0) {
|
|
63
|
-
return {
|
|
64
|
-
ok: false,
|
|
65
|
-
cause: result.error?.message ?? (result.stderr.trim() || "Unknown failure"),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
return { ok: true };
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Reads the installed codex CLI version string.
|
|
72
|
-
*/
|
|
73
|
-
function readCodexVersion() {
|
|
74
|
-
const invocation = getCodexInvocation(["--version"]);
|
|
75
|
-
const result = spawnImplementation(invocation.command, invocation.args, {
|
|
76
|
-
stdio: "pipe",
|
|
77
|
-
encoding: "utf8",
|
|
78
|
-
});
|
|
79
|
-
if (result.error || result.status !== 0) {
|
|
80
|
-
return {
|
|
81
|
-
ok: false,
|
|
82
|
-
cause: result.error?.message ?? (result.stderr.trim() || "Unknown failure"),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
const raw = `${result.stdout ?? ""} ${result.stderr ?? ""}`.trim();
|
|
86
|
-
const match = raw.match(/(\d+\.\d+\.\d+)/);
|
|
87
|
-
if (!match) {
|
|
88
|
-
return {
|
|
89
|
-
ok: false,
|
|
90
|
-
cause: `Unable to parse codex version from output: ${raw || "(empty output)"}`,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
return { ok: true, version: match[1] };
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Compares the installed codex version against a minimum required version.
|
|
97
|
-
*/
|
|
98
|
-
function checkCodexVersion(minVersion) {
|
|
99
|
-
const current = readCodexVersion();
|
|
100
|
-
if (!current.ok) {
|
|
101
|
-
return {
|
|
102
|
-
ok: false,
|
|
103
|
-
cause: current.cause,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
if (compareVersions(current.version, minVersion) < 0) {
|
|
107
|
-
return {
|
|
108
|
-
ok: false,
|
|
109
|
-
currentVersion: current.version,
|
|
110
|
-
cause: `codex ${current.version} is below required ${minVersion}`,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
ok: true,
|
|
115
|
-
currentVersion: current.version,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function compareVersions(left, right) {
|
|
119
|
-
const leftParts = left.split(".").map((value) => Number.parseInt(value, 10));
|
|
120
|
-
const rightParts = right.split(".").map((value) => Number.parseInt(value, 10));
|
|
121
|
-
const length = Math.max(leftParts.length, rightParts.length);
|
|
122
|
-
for (let index = 0; index < length; index += 1) {
|
|
123
|
-
const leftValue = leftParts[index] ?? 0;
|
|
124
|
-
const rightValue = rightParts[index] ?? 0;
|
|
125
|
-
if (leftValue !== rightValue) {
|
|
126
|
-
return leftValue - rightValue;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return 0;
|
|
130
|
-
}
|
|
7
|
+
var codex_cli_1 = require("../runtime/codex-cli");
|
|
8
|
+
Object.defineProperty(exports, "checkCodexAvailable", { enumerable: true, get: function () { return codex_cli_1.checkCodexAvailable; } });
|
|
9
|
+
Object.defineProperty(exports, "checkCodexVersion", { enumerable: true, get: function () { return codex_cli_1.checkCodexVersion; } });
|
|
10
|
+
Object.defineProperty(exports, "readCodexVersion", { enumerable: true, get: function () { return codex_cli_1.readCodexVersion; } });
|
|
11
|
+
Object.defineProperty(exports, "resetCodexSpawnImplementation", { enumerable: true, get: function () { return codex_cli_1.resetCodexSpawnImplementation; } });
|
|
12
|
+
Object.defineProperty(exports, "runCodexLogin", { enumerable: true, get: function () { return codex_cli_1.runCodexLogin; } });
|
|
13
|
+
Object.defineProperty(exports, "setCodexSpawnImplementation", { enumerable: true, get: function () { return codex_cli_1.setCodexSpawnImplementation; } });
|
|
@@ -1,71 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CODEX_DIR_ENV_NAME = void 0;
|
|
37
|
-
exports.resolveCodexDir = resolveCodexDir;
|
|
38
|
-
exports.createCodexPaths = createCodexPaths;
|
|
39
|
-
const os = __importStar(require("node:os"));
|
|
40
|
-
const path = __importStar(require("node:path"));
|
|
41
|
-
exports.CODEX_DIR_ENV_NAME = "CODEXS_CODEX_DIR";
|
|
42
|
-
const DEVELOPMENT_DEFAULT_CODEX_DIR = path.resolve(process.cwd(), "dev-codex", "local-sandbox");
|
|
3
|
+
exports.resolveCodexDir = exports.createCodexPaths = exports.CODEX_DIR_ENV_NAME = void 0;
|
|
43
4
|
/**
|
|
44
|
-
*
|
|
5
|
+
* Compatibility facade that re-exports Codex path utilities from storage.
|
|
45
6
|
*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const envCodexDir = process.env[exports.CODEX_DIR_ENV_NAME];
|
|
51
|
-
if (envCodexDir) {
|
|
52
|
-
return path.resolve(envCodexDir);
|
|
53
|
-
}
|
|
54
|
-
if (process.env.NODE_ENV === "development") {
|
|
55
|
-
return DEVELOPMENT_DEFAULT_CODEX_DIR;
|
|
56
|
-
}
|
|
57
|
-
return path.join(os.homedir(), ".codex");
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Expands a Codex home directory into the file paths used by the CLI.
|
|
61
|
-
*/
|
|
62
|
-
function createCodexPaths(codexDir) {
|
|
63
|
-
return {
|
|
64
|
-
codexDir,
|
|
65
|
-
configPath: path.join(codexDir, "config.toml"),
|
|
66
|
-
providersPath: path.join(codexDir, "providers.json"),
|
|
67
|
-
authPath: path.join(codexDir, "auth.json"),
|
|
68
|
-
backupsDir: path.join(codexDir, "backups"),
|
|
69
|
-
latestBackupPath: path.join(codexDir, "backups", "latest.json"),
|
|
70
|
-
};
|
|
71
|
-
}
|
|
7
|
+
var codex_paths_1 = require("../storage/codex-paths");
|
|
8
|
+
Object.defineProperty(exports, "CODEX_DIR_ENV_NAME", { enumerable: true, get: function () { return codex_paths_1.CODEX_DIR_ENV_NAME; } });
|
|
9
|
+
Object.defineProperty(exports, "createCodexPaths", { enumerable: true, get: function () { return codex_paths_1.createCodexPaths; } });
|
|
10
|
+
Object.defineProperty(exports, "resolveCodexDir", { enumerable: true, get: function () { return codex_paths_1.resolveCodexDir; } });
|
|
@@ -38,6 +38,8 @@ exports.readStructuredConfig = readStructuredConfig;
|
|
|
38
38
|
exports.readCurrentProfile = readCurrentProfile;
|
|
39
39
|
exports.listConfigProfiles = listConfigProfiles;
|
|
40
40
|
exports.ensureProfileExists = ensureProfileExists;
|
|
41
|
+
exports.requireManagedProfileRuntime = requireManagedProfileRuntime;
|
|
42
|
+
exports.requireModelProviderRuntimeSection = requireModelProviderRuntimeSection;
|
|
41
43
|
exports.updateTopLevelProfile = updateTopLevelProfile;
|
|
42
44
|
exports.createConfigMutationPlan = createConfigMutationPlan;
|
|
43
45
|
exports.applyConfigMutation = applyConfigMutation;
|
|
@@ -102,6 +104,63 @@ function ensureProfileExists(configPath, profile, provider) {
|
|
|
102
104
|
}
|
|
103
105
|
return document;
|
|
104
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Resolves one profile view and enforces the managed model_provider contract.
|
|
109
|
+
*/
|
|
110
|
+
function requireManagedProfileRuntime(document, providers, profile) {
|
|
111
|
+
const view = (0, config_1.buildManagedProfileViews)(document, providers).find((entry) => entry.name === profile);
|
|
112
|
+
if (!view) {
|
|
113
|
+
throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Profile "${profile}" does not exist in config.toml.`, {
|
|
114
|
+
profile,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (!view.modelProvider) {
|
|
118
|
+
throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Managed profile "${profile}" requires model_provider.`, {
|
|
119
|
+
profile,
|
|
120
|
+
missingFields: ["model_provider"],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (view.modelProvider !== profile) {
|
|
124
|
+
throw (0, errors_1.cliError)("INVALID_ARGUMENT", `Managed profile "${profile}" must use the same model_provider name.`, {
|
|
125
|
+
profile,
|
|
126
|
+
modelProvider: view.modelProvider,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
const modelProviderSection = document.modelProviders.find((entry) => entry.name === view.modelProvider);
|
|
130
|
+
if (!modelProviderSection) {
|
|
131
|
+
throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Model provider "${view.modelProvider}" does not exist in config.toml.`, {
|
|
132
|
+
profile,
|
|
133
|
+
modelProvider: view.modelProvider,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
if (!modelProviderSection.baseUrl) {
|
|
137
|
+
throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Model provider "${view.modelProvider}" requires base_url.`, {
|
|
138
|
+
profile,
|
|
139
|
+
modelProvider: view.modelProvider,
|
|
140
|
+
missingFields: ["base_url"],
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return view;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Verifies that a same-named model_provider runtime section exists and has base_url.
|
|
147
|
+
*/
|
|
148
|
+
function requireModelProviderRuntimeSection(document, profile) {
|
|
149
|
+
const modelProviderSection = document.modelProviders.find((entry) => entry.name === profile);
|
|
150
|
+
if (!modelProviderSection) {
|
|
151
|
+
throw (0, errors_1.cliError)("PROFILE_NOT_FOUND", `Model provider "${profile}" does not exist in config.toml.`, {
|
|
152
|
+
profile,
|
|
153
|
+
modelProvider: profile,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (!modelProviderSection.baseUrl) {
|
|
157
|
+
throw (0, errors_1.cliError)("MANAGED_PROFILE_FIELDS_MISSING", `Model provider "${profile}" requires base_url.`, {
|
|
158
|
+
profile,
|
|
159
|
+
modelProvider: profile,
|
|
160
|
+
missingFields: ["base_url"],
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
105
164
|
/**
|
|
106
165
|
* Rewrites config.toml so the requested profile becomes the active top-level profile.
|
|
107
166
|
*/
|
package/dist/infra/fs-utils.js
CHANGED
|
@@ -1,97 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.ensureDir =
|
|
37
|
-
exports.writeTextFileAtomic = writeTextFileAtomic;
|
|
38
|
-
exports.readRequiredFile = readRequiredFile;
|
|
39
|
-
exports.formatDetail = formatDetail;
|
|
40
|
-
exports.printErrorDetails = printErrorDetails;
|
|
41
|
-
const fs = __importStar(require("node:fs"));
|
|
42
|
-
const path = __importStar(require("node:path"));
|
|
43
|
-
const errors_1 = require("../domain/errors");
|
|
3
|
+
exports.writeTextFileAtomic = exports.readRequiredFile = exports.printErrorDetails = exports.formatDetail = exports.ensureDir = void 0;
|
|
44
4
|
/**
|
|
45
|
-
*
|
|
5
|
+
* Compatibility facade that re-exports shared filesystem helpers from storage.
|
|
46
6
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
function writeTextFileAtomic(filePath, contents) {
|
|
54
|
-
ensureDir(path.dirname(filePath));
|
|
55
|
-
// Use the current process id in the temp name to reduce collision risk.
|
|
56
|
-
const tempPath = `${filePath}.tmp-${process.pid}`;
|
|
57
|
-
fs.writeFileSync(tempPath, contents, "utf8");
|
|
58
|
-
fs.renameSync(tempPath, filePath);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Reads a required text file and throws a typed error when it is missing.
|
|
62
|
-
*/
|
|
63
|
-
function readRequiredFile(filePath, code, label) {
|
|
64
|
-
if (!fs.existsSync(filePath)) {
|
|
65
|
-
throw (0, errors_1.cliError)(code, `${label} does not exist.`, { file: filePath });
|
|
66
|
-
}
|
|
67
|
-
return fs.readFileSync(filePath, "utf8");
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Formats arbitrary error detail values for human-readable output.
|
|
71
|
-
*/
|
|
72
|
-
function formatDetail(value) {
|
|
73
|
-
if (Array.isArray(value)) {
|
|
74
|
-
return value.join(", ");
|
|
75
|
-
}
|
|
76
|
-
if (value && typeof value === "object") {
|
|
77
|
-
return JSON.stringify(value);
|
|
78
|
-
}
|
|
79
|
-
return String(value);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Renders structured error details while suppressing secret-looking API key fields.
|
|
83
|
-
*/
|
|
84
|
-
function printErrorDetails(error) {
|
|
85
|
-
if (!error.details) {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
const lines = [];
|
|
89
|
-
for (const [key, value] of Object.entries(error.details)) {
|
|
90
|
-
if (typeof value === "string" && key.toLowerCase().includes("apikey")) {
|
|
91
|
-
// Do not leak API keys back into the terminal if one appears in error details.
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
lines.push(` ${key}: ${formatDetail(value)}`);
|
|
95
|
-
}
|
|
96
|
-
return lines;
|
|
97
|
-
}
|
|
7
|
+
var fs_utils_1 = require("../storage/fs-utils");
|
|
8
|
+
Object.defineProperty(exports, "ensureDir", { enumerable: true, get: function () { return fs_utils_1.ensureDir; } });
|
|
9
|
+
Object.defineProperty(exports, "formatDetail", { enumerable: true, get: function () { return fs_utils_1.formatDetail; } });
|
|
10
|
+
Object.defineProperty(exports, "printErrorDetails", { enumerable: true, get: function () { return fs_utils_1.printErrorDetails; } });
|
|
11
|
+
Object.defineProperty(exports, "readRequiredFile", { enumerable: true, get: function () { return fs_utils_1.readRequiredFile; } });
|
|
12
|
+
Object.defineProperty(exports, "writeTextFileAtomic", { enumerable: true, get: function () { return fs_utils_1.writeTextFileAtomic; } });
|