codex-slot 0.1.29 → 0.1.31

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,25 @@ 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. 根 help 的主命令列表保持 Commander 默认风格。
17
+ * 2. relay/use/current 的常见用法只补充到示例区,避免额外文档块打断整体格式。
18
+ *
19
+ * @returns 可追加到根 help 的多行说明。
20
+ * @throws 无显式抛出。
21
+ */
22
+ function renderRelayCommandExamples() {
23
+ return [
24
+ " cslot relay add third --base-url https://relay.example.com/v1 --api-key <key>",
25
+ " cslot relay list",
26
+ " cslot use relay third",
27
+ " cslot use auth",
28
+ " cslot current"
29
+ ];
30
+ }
12
31
  /**
13
32
  * 为 CLI 程序注册根级帮助信息与统一示例。
14
33
  *
@@ -29,6 +48,7 @@ function configureRootProgram(program) {
29
48
  " cslot rename work work-main",
30
49
  " cslot start --port 4399",
31
50
  " cslot status --no-interactive",
51
+ ...renderRelayCommandExamples(),
32
52
  "",
33
53
  `${(0, text_1.bi)("说明", "Notes")}:`,
34
54
  ` ${(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 +102,10 @@ function registerAccountCommands(program) {
82
102
  function registerRelayCommands(program) {
83
103
  const relay = program
84
104
  .command("relay")
85
- .description((0, text_1.bi)("管理 OpenAI-compatible 中转槽位", "Manage OpenAI-compatible relay slots"));
105
+ .description((0, text_1.bi)("管理中转槽位", "Manage relay slots"));
86
106
  relay
87
107
  .command("add")
88
- .description((0, text_1.bi)("新增一个中转槽位", "Add a relay slot"))
108
+ .description((0, text_1.bi)("新增中转槽位", "Add relay slot"))
89
109
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
90
110
  .requiredOption("--base-url <url>", (0, text_1.bi)("OpenAI-compatible base_url,通常以 /v1 结尾", "OpenAI-compatible base_url, usually ending with /v1"))
91
111
  .requiredOption("--api-key <key>", (0, text_1.bi)("中转 API key", "Relay API key"))
@@ -107,29 +127,29 @@ function registerRelayCommands(program) {
107
127
  .action(relay_commands_1.handleRelayRename);
108
128
  relay
109
129
  .command("enable")
110
- .description((0, text_1.bi)("启用一个中转槽位", "Enable a relay slot"))
130
+ .description((0, text_1.bi)("启用中转槽位", "Enable relay slot"))
111
131
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
112
132
  .action(relay_commands_1.handleRelayEnable);
113
133
  relay
114
134
  .command("disable")
115
- .description((0, text_1.bi)("禁用一个中转槽位", "Disable a relay slot"))
135
+ .description((0, text_1.bi)("禁用中转槽位", "Disable relay slot"))
116
136
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
117
137
  .action(relay_commands_1.handleRelayDisable);
118
138
  const use = program
119
139
  .command("use")
120
- .description((0, text_1.bi)("切换模型请求出口", "Switch model route"));
140
+ .description((0, text_1.bi)("切换模型出口", "Switch model route"));
121
141
  use
122
142
  .command("relay")
123
- .description((0, text_1.bi)("固定模型请求到指定中转槽位", "Fix model route to a relay slot"))
143
+ .description((0, text_1.bi)("使用指定中转槽位", "Use relay slot"))
124
144
  .argument("<name>", (0, text_1.bi)("中转槽位名", "Relay slot name"))
125
145
  .action(relay_commands_1.handleUseRelay);
126
146
  use
127
147
  .command("auth")
128
- .description((0, text_1.bi)("恢复模型请求到官方账号池", "Restore model route to the official auth pool"))
148
+ .description((0, text_1.bi)("使用官方账号池", "Use official auth pool"))
129
149
  .action(relay_commands_1.handleUseAuthPool);
130
150
  program
131
151
  .command("current")
132
- .description((0, text_1.bi)("查看当前模型出口与 Codex App 登录态选择", "Show current model route and Codex App auth selection"))
152
+ .description((0, text_1.bi)("查看当前出口", "Show current route"))
133
153
  .action(relay_commands_1.handleCurrent);
134
154
  }
135
155
  /**
@@ -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.31",
4
4
  "description": "本地 Codex 多账号切换与状态管理工具",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cli.js",