codex-slot 0.1.29 → 0.1.30

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/dist/cli.js CHANGED
@@ -9,6 +9,40 @@ const relay_commands_1 = require("./relay-commands");
9
9
  const service_control_1 = require("./service-control");
10
10
  const status_command_1 = require("./status-command");
11
11
  const text_1 = require("./text");
12
+ /**
13
+ * 生成根 help 中的 relay 与模型出口命令说明。
14
+ *
15
+ * 业务含义:
16
+ * 1. Commander 默认命令列表会按终端宽度折行,中英混排时可读性较差。
17
+ * 2. 最近新增的 relay/use/current 命令需要用固定双语格式补充业务含义和使用方式。
18
+ *
19
+ * @returns 可追加到根 help 的多行说明。
20
+ * @throws 无显式抛出。
21
+ */
22
+ function renderRelayCommandHelp() {
23
+ return [
24
+ "",
25
+ "中转命令 / Relay commands:",
26
+ " cslot relay add <name> --base-url <url> --api-key <key>",
27
+ " 中文: 新增 OpenAI-compatible 中转槽位。",
28
+ " English: Add an OpenAI-compatible relay slot.",
29
+ " cslot relay list",
30
+ " 中文: 查看全部中转槽位,API key 会脱敏。",
31
+ " English: List relay slots with API keys masked.",
32
+ " cslot relay enable <name> / cslot relay disable <name>",
33
+ " 中文: 控制某个中转槽位是否参与模型出口选择。",
34
+ " English: Enable or disable a relay slot for model routing.",
35
+ " cslot use relay <name>",
36
+ " 中文: 固定模型请求走指定中转槽位。",
37
+ " English: Route model requests through the selected relay slot.",
38
+ " cslot use auth",
39
+ " 中文: 恢复使用官方 Codex 账号池。",
40
+ " English: Restore routing through the official Codex auth pool.",
41
+ " cslot current",
42
+ " 中文: 查看当前模型出口和 Codex App 登录态选择。",
43
+ " English: Show the active model route and Codex App auth selection."
44
+ ];
45
+ }
12
46
  /**
13
47
  * 为 CLI 程序注册根级帮助信息与统一示例。
14
48
  *
@@ -29,6 +63,7 @@ function configureRootProgram(program) {
29
63
  " cslot rename work work-main",
30
64
  " cslot start --port 4399",
31
65
  " cslot status --no-interactive",
66
+ ...renderRelayCommandHelp(),
32
67
  "",
33
68
  `${(0, text_1.bi)("说明", "Notes")}:`,
34
69
  ` ${(0, text_1.bi)("`import current ~` 里的 current 只是示例槽位名,不是内置账号或工作空间。", "`current` in `import current ~` is only an example slot name, not a built-in account or workspace.")}`
@@ -82,10 +117,10 @@ function registerAccountCommands(program) {
82
117
  function registerRelayCommands(program) {
83
118
  const relay = program
84
119
  .command("relay")
85
- .description((0, text_1.bi)("管理 OpenAI-compatible 中转槽位", "Manage OpenAI-compatible relay slots"));
120
+ .description((0, text_1.bi)("管理中转槽位", "Manage relay slots"));
86
121
  relay
87
122
  .command("add")
88
- .description((0, text_1.bi)("新增一个中转槽位", "Add a relay slot"))
123
+ .description((0, text_1.bi)("新增中转槽位", "Add relay slot"))
89
124
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
90
125
  .requiredOption("--base-url <url>", (0, text_1.bi)("OpenAI-compatible base_url,通常以 /v1 结尾", "OpenAI-compatible base_url, usually ending with /v1"))
91
126
  .requiredOption("--api-key <key>", (0, text_1.bi)("中转 API key", "Relay API key"))
@@ -107,29 +142,29 @@ function registerRelayCommands(program) {
107
142
  .action(relay_commands_1.handleRelayRename);
108
143
  relay
109
144
  .command("enable")
110
- .description((0, text_1.bi)("启用一个中转槽位", "Enable a relay slot"))
145
+ .description((0, text_1.bi)("启用中转槽位", "Enable relay slot"))
111
146
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
112
147
  .action(relay_commands_1.handleRelayEnable);
113
148
  relay
114
149
  .command("disable")
115
- .description((0, text_1.bi)("禁用一个中转槽位", "Disable a relay slot"))
150
+ .description((0, text_1.bi)("禁用中转槽位", "Disable relay slot"))
116
151
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
117
152
  .action(relay_commands_1.handleRelayDisable);
118
153
  const use = program
119
154
  .command("use")
120
- .description((0, text_1.bi)("切换模型请求出口", "Switch model route"));
155
+ .description((0, text_1.bi)("切换模型出口", "Switch model route"));
121
156
  use
122
157
  .command("relay")
123
- .description((0, text_1.bi)("固定模型请求到指定中转槽位", "Fix model route to a relay slot"))
158
+ .description((0, text_1.bi)("使用指定中转槽位", "Use relay slot"))
124
159
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
125
160
  .action(relay_commands_1.handleUseRelay);
126
161
  use
127
162
  .command("auth")
128
- .description((0, text_1.bi)("恢复模型请求到官方账号池", "Restore model route to the official auth pool"))
163
+ .description((0, text_1.bi)("使用官方账号池", "Use official auth pool"))
129
164
  .action(relay_commands_1.handleUseAuthPool);
130
165
  program
131
166
  .command("current")
132
- .description((0, text_1.bi)("查看当前模型出口与 Codex App 登录态选择", "Show current model route and Codex App auth selection"))
167
+ .description((0, text_1.bi)("查看当前出口", "Show current route"))
133
168
  .action(relay_commands_1.handleCurrent);
134
169
  }
135
170
  /**
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.renderInteractiveHelpLines = renderInteractiveHelpLines;
6
7
  exports.handleStatus = handleStatus;
7
8
  const node_readline_1 = __importDefault(require("node:readline"));
8
9
  const account_store_1 = require("./account-store");
@@ -94,6 +95,32 @@ function renderSummaryLine(summary, narrowScreen, styled) {
94
95
  }
95
96
  return `available=${available} 5h_limited=${fiveHourLimited} weekly_limited=${weeklyLimited}`;
96
97
  }
98
+ /**
99
+ * 渲染交互状态面板的快捷键说明,并确保每一行都能放进右侧详情栏。
100
+ *
101
+ * 业务含义:
102
+ * 1. 状态页在宽终端使用双栏布局,右栏宽度可能仍然较窄。
103
+ * 2. 快捷键说明必须逐行展示,避免单条长 help 在终端自动换行后打乱面板。
104
+ *
105
+ * @param maxWidth 右侧详情栏可用显示宽度;小于等于 0 时返回空列表。
106
+ * @returns 逐行渲染后的快捷键说明。
107
+ * @throws 无显式抛出。
108
+ */
109
+ function renderInteractiveHelpLines(maxWidth) {
110
+ if (maxWidth <= 0) {
111
+ return [];
112
+ }
113
+ const lines = [
114
+ "↑/↓ move/select",
115
+ "Space toggle enabled",
116
+ "a app auth",
117
+ "m model route",
118
+ "c clear app auth",
119
+ "r refresh usage",
120
+ "Enter/q exit"
121
+ ];
122
+ return lines.map((line) => truncateVisible(line, maxWidth));
123
+ }
97
124
  /**
98
125
  * 移除 ANSI 控制序列,避免布局计算把颜色码当成可见字符。
99
126
  *
@@ -150,6 +177,37 @@ function getDisplayWidth(value) {
150
177
  function padVisible(value, width) {
151
178
  return `${value}${" ".repeat(Math.max(0, width - getDisplayWidth(value)))}`;
152
179
  }
180
+ /**
181
+ * 按显示宽度截断文本,保留省略号提示内容被压缩。
182
+ *
183
+ * @param value 原始文本。
184
+ * @param maxWidth 最大显示列宽。
185
+ * @returns 截断后的文本。
186
+ * @throws 无显式抛出。
187
+ */
188
+ function truncateVisible(value, maxWidth) {
189
+ if (maxWidth <= 0) {
190
+ return "";
191
+ }
192
+ if (getDisplayWidth(value) <= maxWidth) {
193
+ return value;
194
+ }
195
+ if (maxWidth <= 2) {
196
+ return value.slice(0, maxWidth);
197
+ }
198
+ let output = "";
199
+ let width = 0;
200
+ const ellipsisWidth = getDisplayWidth("…");
201
+ for (const char of value) {
202
+ const charWidth = getDisplayWidth(char);
203
+ if (width + charWidth + ellipsisWidth > maxWidth) {
204
+ break;
205
+ }
206
+ output += char;
207
+ width += charWidth;
208
+ }
209
+ return `${output}…`;
210
+ }
153
211
  /**
154
212
  * 将左右两组文本行渲染为双栏布局。
155
213
  *
@@ -400,7 +458,7 @@ async function handleInteractiveToggle(initialStatuses) {
400
458
  ...(refreshStatusText ? [`refresh=${refreshStatusText}`] : []),
401
459
  "",
402
460
  renderSectionHeader("help", rightWidth, styled),
403
- "↑/↓ move Space toggle a app-auth m model-route c clear r refresh Enter/q exit"
461
+ ...renderInteractiveHelpLines(rightWidth)
404
462
  ];
405
463
  const leftLines = [
406
464
  ...accountLines,
package/dist/status.js CHANGED
@@ -575,7 +575,7 @@ function renderRelayStatusTable(slots, options) {
575
575
  const statusWidth = compactHeader ? 8 : 10;
576
576
  const fixedWidth = (selectorColumn ? 4 + 2 : 0) + relayWidth + 2 + statusWidth + 2;
577
577
  const baseUrlWidth = Number.isFinite(maxWidth)
578
- ? Math.max(12, Math.floor(maxWidth) - fixedWidth)
578
+ ? Math.max(12, Math.min(72, Math.floor(maxWidth) - fixedWidth))
579
579
  : Math.max(getDisplayWidth("BASE_URL"), ...slots.map((item) => getDisplayWidth(item.base_url)));
580
580
  const rows = [
581
581
  [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-slot",
3
- "version": "0.1.29",
3
+ "version": "0.1.30",
4
4
  "description": "本地 Codex 多账号切换与状态管理工具",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cli.js",