@cc-x/cc-x 0.4.11 → 0.4.12
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/i18n/messages.js +2 -2
- package/dist/ui/menus.js +33 -30
- package/package.json +1 -1
package/dist/i18n/messages.js
CHANGED
|
@@ -37,8 +37,8 @@ export const messages = {
|
|
|
37
37
|
// —— 菜单通用 ——
|
|
38
38
|
'menu.prompt': { zh: '输入序号 (q 取消): ', en: 'Enter number (q to cancel): ' },
|
|
39
39
|
'menu.mainTitle': {
|
|
40
|
-
zh: 'CC-X v{0}
|
|
41
|
-
en: 'CC-X v{0}
|
|
40
|
+
zh: 'CC-X v{0} 默认:{1}',
|
|
41
|
+
en: 'CC-X v{0} Default: {1}',
|
|
42
42
|
},
|
|
43
43
|
'menu.mainHint': {
|
|
44
44
|
zh: '↑↓ 选择 · Enter 进入 · e 编辑 · s 启动 · d 设默认 · Shift+↑↓ 排序 · q 退出',
|
package/dist/ui/menus.js
CHANGED
|
@@ -7,10 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { launchSession } from '../actions.js';
|
|
9
9
|
import { checkProfile } from '../check.js';
|
|
10
|
-
import {
|
|
10
|
+
import { getProviderState, isOfficial, reconcileCurrent, saveStore } from '../config/store.js';
|
|
11
11
|
import { persistDefaultEnv, setDefault } from '../env/default.js';
|
|
12
12
|
import { getLang, providerDisplayName, setLang, T } from '../i18n/index.js';
|
|
13
|
-
import { currentTerminalLine, hostOf } from '../runtime-info.js';
|
|
14
13
|
import { banner as updateBanner, maybeRefresh, MODE_NOTIFY, upgradeCommand } from '../update/update.js';
|
|
15
14
|
import { paint } from '../utils/ansi.js';
|
|
16
15
|
import { displayWidth, padDisplay } from '../utils/display.js';
|
|
@@ -26,7 +25,7 @@ export async function openMenu(paths, store, scope, version, catalog) {
|
|
|
26
25
|
for (;;) {
|
|
27
26
|
const n = store.providers.length;
|
|
28
27
|
// 更新检查(仅 notify 模式):首轮触发一次后台刷新;横幅永远读缓存(瞬时、不阻塞)。
|
|
29
|
-
const notices = [
|
|
28
|
+
const notices = [];
|
|
30
29
|
if (needsFirstRunHint(store))
|
|
31
30
|
notices.push(T('menu.firstRunHint'));
|
|
32
31
|
if (warnFlash)
|
|
@@ -63,7 +62,7 @@ export async function openMenu(paths, store, scope, version, catalog) {
|
|
|
63
62
|
notice: notices.join('\n'),
|
|
64
63
|
...(flash ? { status: flash } : {}),
|
|
65
64
|
items: buildItems(),
|
|
66
|
-
colors: { [n + 1]: 'yellow' },
|
|
65
|
+
colors: { [n + 1]: 'yellow', [n + 2]: 'dim', [n + 3]: 'dim' },
|
|
67
66
|
start: sel,
|
|
68
67
|
movableCount: n,
|
|
69
68
|
onMove,
|
|
@@ -237,44 +236,48 @@ function applyDefault(paths, store, p, scope) {
|
|
|
237
236
|
return defaultResultMessage(defaultWarning(p), name, setDefault(paths, store, p, scope));
|
|
238
237
|
}
|
|
239
238
|
const ROW_NAME_W = 13; // 名字列宽(显示宽度,CJK 计 2);状态/备注列宽按内容动态算
|
|
240
|
-
// profileRows
|
|
241
|
-
//
|
|
242
|
-
//
|
|
239
|
+
// profileRows 把所有配置格式化成三列菜单行:名字(主信息,默认项加粗、缺密钥变灰)
|
|
240
|
+
// + 备注(紧跟名字、dim,同名配置靠它区分)+ 状态(effort/缺密钥告警,dim,锚成最右一列)。
|
|
241
|
+
// 备注列宽按当前配置实际内容动态取最大值;状态列在最右,无需补宽。
|
|
243
242
|
// TUI 主菜单与 xx --list 共用此函数,保证两处呈现一致。与 Go 版 menu.go ProfileRows 对齐。
|
|
244
243
|
export function profileRows(providers, current) {
|
|
245
|
-
let stateW = 0;
|
|
246
244
|
let noteW = 0;
|
|
247
245
|
for (const p of providers) {
|
|
248
|
-
stateW = Math.max(stateW, displayWidth(stateLabel(p)));
|
|
249
246
|
noteW = Math.max(noteW, displayWidth(p.note ?? ''));
|
|
250
247
|
}
|
|
251
|
-
stateW += 2; // 状态列尾留出与备注列的间距(最宽行否则会与备注贴死)
|
|
252
248
|
if (noteW > 0)
|
|
253
|
-
noteW += 2; //
|
|
254
|
-
return providers.map((p) => profileRow(p, p.name === current,
|
|
249
|
+
noteW += 2; // 备注列尾留出与状态列的间距
|
|
250
|
+
return providers.map((p) => profileRow(p, p.name === current, noteW));
|
|
255
251
|
}
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
function
|
|
252
|
+
// rowStateText 行内状态段:只保留 effort 与「缺密钥」告警。
|
|
253
|
+
// 「登录态/密钥已设/密钥·API_KEY」等可用态不再用文字表达——能不能用由配置名的亮/灰区分。
|
|
254
|
+
function rowStateText(p) {
|
|
255
|
+
const st = getProviderState(p);
|
|
256
|
+
const parts = [];
|
|
257
|
+
if (st.effort)
|
|
258
|
+
parts.push(`effort=${st.effort}`);
|
|
259
|
+
if (st.key === 'noKey')
|
|
260
|
+
parts.push(T('state.noKey'));
|
|
261
|
+
return parts.join(' · ');
|
|
262
|
+
}
|
|
263
|
+
// profileRow 组成一行:名字 + 备注 + 状态三列,次要信息 dim、默认项加粗、缺密钥变灰。
|
|
264
|
+
// 默认项只靠名字加粗标识(不再额外画 ● 符号,与光标 ▶ 重叠冗余);选中行由 selectMenu 整行绿。
|
|
265
|
+
// 亮/灰用加粗(1m)与 dim(2m),reset 都用 22m 不动颜色,不会破坏选中行的外层绿色。
|
|
266
|
+
function profileRow(p, isDefault, noteW) {
|
|
267
|
+
const noKey = getProviderState(p).key === 'noKey';
|
|
259
268
|
let name = padDisplay(providerDisplayName(p), ROW_NAME_W);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
name = paint(name, 'bold');
|
|
264
|
-
|
|
265
|
-
const state = paint(` · ${padDisplay(stateLabel(p), stateW)}`, 'dim');
|
|
266
|
-
// 空备注=定宽空白,撑出 host 前的列间距
|
|
269
|
+
if (noKey)
|
|
270
|
+
name = paint(name, 'dim'); // 灰掉=当前不可用(缺密钥)
|
|
271
|
+
else if (isDefault)
|
|
272
|
+
name = paint(name, 'bold'); // 加粗=默认配置
|
|
273
|
+
// 空备注=定宽空白,撑出状态列前的间距
|
|
267
274
|
const note = (p.note ?? '').trim()
|
|
268
275
|
? paint(padDisplay(p.note ?? '', noteW), 'dim')
|
|
269
276
|
: padDisplay('', noteW);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const base = (getProviderEnvMap(p).ANTHROPIC_BASE_URL ?? '').trim();
|
|
275
|
-
if (!base)
|
|
276
|
-
return '';
|
|
277
|
-
return paint(hostOf(base), 'dim');
|
|
277
|
+
// 状态在最右一列,可用且无 effort 时整列省略
|
|
278
|
+
const seg = rowStateText(p);
|
|
279
|
+
const state = seg ? paint(` · ${seg}`, 'dim') : '';
|
|
280
|
+
return `${name}${note}${state}`;
|
|
278
281
|
}
|
|
279
282
|
function needsFirstRunHint(store) {
|
|
280
283
|
let hasThirdParty = false;
|