@openxiaobu/codexl 0.1.2 → 0.1.3
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 -14
- package/dist/cli.js +57 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- Fetch the latest usage from the official usage endpoint
|
|
12
12
|
- Expose a local provider endpoint for Codex
|
|
13
13
|
- Apply local cooldown rules for temporary, 5-hour, and weekly limits
|
|
14
|
-
-
|
|
14
|
+
- Automatically switch `~/.codex/config.toml` to the `codexl` provider while the local proxy is running
|
|
15
15
|
|
|
16
16
|
## Installation
|
|
17
17
|
|
|
@@ -51,16 +51,10 @@ codexl start
|
|
|
51
51
|
codexl start --port 4399
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
`start` will automatically write the required provider config into `~/.codex/config.toml`:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
codexl
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Write provider config into `~/.codex/config.toml`:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
codexl config
|
|
57
|
+
codexl start
|
|
64
58
|
```
|
|
65
59
|
|
|
66
60
|
## Commands
|
|
@@ -72,8 +66,6 @@ codexl import <name> [HOME]
|
|
|
72
66
|
codexl status
|
|
73
67
|
codexl start [--port <port>]
|
|
74
68
|
codexl stop
|
|
75
|
-
codexl get
|
|
76
|
-
codexl config [codexPath]
|
|
77
69
|
```
|
|
78
70
|
|
|
79
71
|
## How `status` Works
|
|
@@ -87,9 +79,9 @@ Instead it:
|
|
|
87
79
|
3. Stores the latest result in `~/.codexl/state.json`
|
|
88
80
|
4. Renders the latest local cache
|
|
89
81
|
|
|
90
|
-
##
|
|
82
|
+
## Managed Codex Config
|
|
91
83
|
|
|
92
|
-
`codexl
|
|
84
|
+
`codexl start` writes a managed provider block like this:
|
|
93
85
|
|
|
94
86
|
```toml
|
|
95
87
|
# >>> codexl managed start >>>
|
|
@@ -107,7 +99,8 @@ Behavior:
|
|
|
107
99
|
- If global `model_provider` exists, it is changed to `codexl`
|
|
108
100
|
- If commented `# model_provider = ...` exists, it is reopened as `model_provider = "codexl"`
|
|
109
101
|
- Global `model` is kept unchanged
|
|
110
|
-
- If you start with `--port`, the port is saved to `~/.codexl/config.yaml
|
|
102
|
+
- If you start with `--port`, the port is saved to `~/.codexl/config.yaml`
|
|
103
|
+
- `codexl stop` comments out the active `model_provider = "codexl"` line and keeps the rest of the file unchanged
|
|
111
104
|
|
|
112
105
|
## Data Directory
|
|
113
106
|
|
package/dist/cli.js
CHANGED
|
@@ -115,6 +115,7 @@ async function handleStart(portOverride) {
|
|
|
115
115
|
}
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
|
+
applyManagedCodexConfig();
|
|
118
119
|
const logPath = (0, config_1.getServiceLogPath)();
|
|
119
120
|
const logFd = node_fs_1.default.openSync(logPath, "a");
|
|
120
121
|
const child = (0, node_child_process_1.spawn)(process.execPath, [__filename.replace(/cli\.js$/, "serve.js"), "--port", String(port)], {
|
|
@@ -136,38 +137,41 @@ function handleStop() {
|
|
|
136
137
|
const pid = getRunningPid();
|
|
137
138
|
if (!pid) {
|
|
138
139
|
console.log("服务未运行");
|
|
140
|
+
deactivateManagedCodexConfig();
|
|
139
141
|
return;
|
|
140
142
|
}
|
|
141
143
|
process.kill(pid, "SIGTERM");
|
|
142
144
|
node_fs_1.default.rmSync((0, config_1.getPidPath)(), { force: true });
|
|
145
|
+
deactivateManagedCodexConfig();
|
|
143
146
|
console.log(`服务已停止,PID=${pid}`);
|
|
144
147
|
}
|
|
145
148
|
/**
|
|
146
|
-
*
|
|
149
|
+
* 对正则元字符做转义,供动态构造匹配模式使用。
|
|
147
150
|
*
|
|
148
|
-
* @
|
|
151
|
+
* @param input 原始字符串。
|
|
152
|
+
* @returns 经过转义后的安全正则片段。
|
|
149
153
|
*/
|
|
150
|
-
function handleGetConfig() {
|
|
151
|
-
const config = (0, config_1.loadConfig)();
|
|
152
|
-
console.log(`base_url=${`http://${config.server.host}:${config.server.port}/v1`}`);
|
|
153
|
-
console.log(`api_key=${config.server.api_key}`);
|
|
154
|
-
}
|
|
155
154
|
function escapeRegExp(input) {
|
|
156
155
|
return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
157
156
|
}
|
|
158
157
|
/**
|
|
159
|
-
*
|
|
158
|
+
* 返回默认的 `codex config.toml` 路径。
|
|
160
159
|
*
|
|
161
|
-
* @
|
|
162
|
-
* @returns 无返回值。
|
|
160
|
+
* @returns 默认 `config.toml` 绝对路径。
|
|
163
161
|
*/
|
|
164
|
-
function
|
|
162
|
+
function getDefaultCodexConfigPath() {
|
|
163
|
+
return node_path_1.default.join(process.env.HOME ?? "", ".codex", "config.toml");
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 生成 codexl 托管的 provider 配置块。
|
|
167
|
+
*
|
|
168
|
+
* @returns 可直接写入 `config.toml` 的配置块内容。
|
|
169
|
+
*/
|
|
170
|
+
function buildManagedConfigBlock() {
|
|
165
171
|
const config = (0, config_1.loadConfig)();
|
|
166
|
-
const rawTarget = targetPathOrDir ? (0, config_1.expandHome)(targetPathOrDir) : node_path_1.default.join(process.env.HOME ?? "", ".codex", "config.toml");
|
|
167
|
-
const targetFile = rawTarget.endsWith(".toml") ? rawTarget : node_path_1.default.join(rawTarget, "config.toml");
|
|
168
172
|
const startMarker = "# >>> codexl managed start >>>";
|
|
169
173
|
const endMarker = "# <<< codexl managed end <<<";
|
|
170
|
-
|
|
174
|
+
return [
|
|
171
175
|
startMarker,
|
|
172
176
|
"[model_providers.codexl]",
|
|
173
177
|
'name = "codexl"',
|
|
@@ -176,6 +180,19 @@ function handleConfig(targetPathOrDir) {
|
|
|
176
180
|
'wire_api = "responses"',
|
|
177
181
|
endMarker
|
|
178
182
|
].join("\n");
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 将 codexl provider 配置写入指定的 codex config.toml。
|
|
186
|
+
*
|
|
187
|
+
* @param targetPathOrDir 可选的 codex 配置目录或 config.toml 文件路径。
|
|
188
|
+
* @returns 实际写入的 `config.toml` 文件路径。
|
|
189
|
+
*/
|
|
190
|
+
function applyManagedCodexConfig(targetPathOrDir, options) {
|
|
191
|
+
const rawTarget = targetPathOrDir ? (0, config_1.expandHome)(targetPathOrDir) : getDefaultCodexConfigPath();
|
|
192
|
+
const targetFile = rawTarget.endsWith(".toml") ? rawTarget : node_path_1.default.join(rawTarget, "config.toml");
|
|
193
|
+
const startMarker = "# >>> codexl managed start >>>";
|
|
194
|
+
const endMarker = "# <<< codexl managed end <<<";
|
|
195
|
+
const block = buildManagedConfigBlock();
|
|
179
196
|
let original = "";
|
|
180
197
|
if (node_fs_1.default.existsSync(targetFile)) {
|
|
181
198
|
original = node_fs_1.default.readFileSync(targetFile, "utf8");
|
|
@@ -240,10 +257,31 @@ function handleConfig(targetPathOrDir) {
|
|
|
240
257
|
}
|
|
241
258
|
const nextContent = `${lines.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd()}\n`;
|
|
242
259
|
node_fs_1.default.writeFileSync(targetFile, nextContent, "utf8");
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
260
|
+
if (!options?.silent) {
|
|
261
|
+
const config = (0, config_1.loadConfig)();
|
|
262
|
+
console.log(`已写入: ${targetFile}`);
|
|
263
|
+
console.log(`base_url=http://${config.server.host}:${config.server.port}/v1`);
|
|
264
|
+
console.log(`api_key=${config.server.api_key}`);
|
|
265
|
+
console.log("提示: start 会自动接管 codex provider,stop 会自动恢复。");
|
|
266
|
+
}
|
|
267
|
+
return targetFile;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* 关闭 codexl 作为当前默认 provider 的接管状态。
|
|
271
|
+
*
|
|
272
|
+
* @returns 无返回值。
|
|
273
|
+
*/
|
|
274
|
+
function deactivateManagedCodexConfig() {
|
|
275
|
+
const targetFile = getDefaultCodexConfigPath();
|
|
276
|
+
if (!node_fs_1.default.existsSync(targetFile)) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const original = node_fs_1.default.readFileSync(targetFile, "utf8");
|
|
280
|
+
const nextContent = original.replace(/^(\s*)model_provider\s*=\s*"codexl"\s*$/m, '$1# model_provider = "codexl"');
|
|
281
|
+
if (nextContent !== original) {
|
|
282
|
+
node_fs_1.default.writeFileSync(targetFile, nextContent, "utf8");
|
|
283
|
+
console.log(`已更新: ${targetFile}`);
|
|
284
|
+
}
|
|
247
285
|
}
|
|
248
286
|
/**
|
|
249
287
|
* CLI 主入口,负责命令注册与执行。
|
|
@@ -256,10 +294,9 @@ async function main() {
|
|
|
256
294
|
(0, config_1.getCodexSwHome)();
|
|
257
295
|
(0, config_1.loadConfig)();
|
|
258
296
|
program
|
|
259
|
-
.name("codexsw")
|
|
260
297
|
.name("codexl")
|
|
261
298
|
.description("本地 Codex 多账号切换与状态管理工具")
|
|
262
|
-
.version("0.1.
|
|
299
|
+
.version("0.1.2");
|
|
263
300
|
program
|
|
264
301
|
.command("add")
|
|
265
302
|
.description("登录并新增一个账号或工作空间")
|
|
@@ -292,12 +329,6 @@ async function main() {
|
|
|
292
329
|
await handleStart(options.port);
|
|
293
330
|
});
|
|
294
331
|
program.command("stop").description("停止后台代理服务").action(handleStop);
|
|
295
|
-
program.command("get").description("输出当前 base_url 和 api_key").action(handleGetConfig);
|
|
296
|
-
program
|
|
297
|
-
.command("config")
|
|
298
|
-
.description("自动写入 codex 的 config.toml,默认 ~/.codex/config.toml")
|
|
299
|
-
.argument("[codexPath]", "codex 配置目录或 config.toml 文件路径")
|
|
300
|
-
.action(handleConfig);
|
|
301
332
|
await program.parseAsync(process.argv);
|
|
302
333
|
}
|
|
303
334
|
void main().catch((error) => {
|