@mars-sea/dsh-commandcode-provider 0.8.3 → 0.9.1
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/CHANGELOG.md +38 -0
- package/README.md +3 -0
- package/README.zh-CN.md +3 -0
- package/lib/client.js +563 -91
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +44 -4
- package/lib/index.js +146 -42
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ declare const KNOWN_EFFORTS: Readonly<Record<string, readonly string[]>>;
|
|
|
24
24
|
*/
|
|
25
25
|
declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
|
|
26
26
|
/**
|
|
27
|
-
* Models the official CLI's model table (command-code@1.
|
|
27
|
+
* Models the official CLI's model table (command-code@1.37.0) marks
|
|
28
28
|
* `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
|
|
29
29
|
* think automatically, with Command Code driving the depth. This is the
|
|
30
30
|
* authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
|
|
@@ -32,10 +32,13 @@ declare const KNOWN_IMAGE_MODELS: ReadonlySet<string>;
|
|
|
32
32
|
* effort levels, and this snapshot is not surfaced in the picker's compact
|
|
33
33
|
* description — it exists for programmatic consumers.
|
|
34
34
|
*
|
|
35
|
-
* Source: the command-code@1.
|
|
35
|
+
* Source: the command-code@1.37.0 bundled model table (dist/cli.mjs),
|
|
36
36
|
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
37
37
|
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
38
|
-
* selectable `['low', 'high', 'max']` efforts
|
|
38
|
+
* selectable `['low', 'high', 'max']` efforts; the preview then ended in
|
|
39
|
+
* 1.34.0, removing the model from the catalog entirely. `tencent/hy4-preview`
|
|
40
|
+
* joined this set in command-code@1.37.0 — reasoning:!0, no efforts, 1M
|
|
41
|
+
* context, routed through OpenRouter.)
|
|
39
42
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
40
43
|
*/
|
|
41
44
|
declare const KNOWN_THINKING_MODELS: ReadonlySet<string>;
|
|
@@ -186,7 +189,7 @@ declare function peakPricingState(modelId: string, now?: number): 'peak' | 'off-
|
|
|
186
189
|
* for models without time-of-day pricing.
|
|
187
190
|
*/
|
|
188
191
|
declare function peakPricingLabel(modelId: string, now?: number): string | undefined;
|
|
189
|
-
declare const COMMAND_CODE_CLI_VERSION = "1.
|
|
192
|
+
declare const COMMAND_CODE_CLI_VERSION = "1.37.0";
|
|
190
193
|
declare const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
191
194
|
declare const DEFAULT_GENERATE_MAX_TOKENS = 64000;
|
|
192
195
|
declare const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -599,6 +602,23 @@ declare const USAGE_REPORT_ENDPOINT = "commandcode/report";
|
|
|
599
602
|
*/
|
|
600
603
|
declare const usageReportSchema: TypertSchema<CommandCodeAccountsReport>;
|
|
601
604
|
//#endregion
|
|
605
|
+
//#region src/command-locales.d.ts
|
|
606
|
+
/**
|
|
607
|
+
* Locale copy for the `/commandcode` usage command and the friendly
|
|
608
|
+
* image-gate error rewrite. Distinct from `./client/locales.ts` (the
|
|
609
|
+
* settings-page namespace `settings.commandcode`): the command runs on the
|
|
610
|
+
* Host and has no access to the client's `ctx.locale`, so the dictionaries
|
|
611
|
+
* are exposed as plain constants for direct lookup; the resolver lives in
|
|
612
|
+
* `pickCommandLocale()`. The image-gate wrapper also lives on the client
|
|
613
|
+
* but is reached from a non-React path that has no `t` in scope, so the
|
|
614
|
+
* same dictionaries serve both surfaces.
|
|
615
|
+
*
|
|
616
|
+
* zh is the source of truth for the key set; en must carry the exact same
|
|
617
|
+
* keys — a mismatch is a compile error at the lookup site.
|
|
618
|
+
*/
|
|
619
|
+
/** Active locale id recognized by the command and the image-gate wrapper. */
|
|
620
|
+
type LocaleId = 'zh' | 'en';
|
|
621
|
+
//#endregion
|
|
602
622
|
//#region src/commands.d.ts
|
|
603
623
|
/** Everything the command needs beyond the adapter itself. */
|
|
604
624
|
interface CommandCodeCommandDeps<C extends CommandCodeConnectionOptions = CommandCodeConnectionOptions> {
|
|
@@ -610,6 +630,14 @@ interface CommandCodeCommandDeps<C extends CommandCodeConnectionOptions = Comman
|
|
|
610
630
|
* `adapter.getUsage()` report.
|
|
611
631
|
*/
|
|
612
632
|
reports?: () => Promise<CommandCodeAccountsReport>;
|
|
633
|
+
/**
|
|
634
|
+
* Resolve the active locale for one command run. The plugin entry wires
|
|
635
|
+
* this from `Config.lang` and the shell's `LC_ALL`/`LANG`. Absent in
|
|
636
|
+
* programmatic setups (notably the existing test), the command renders
|
|
637
|
+
* with the default locale (`'zh'`) — historically the only language the
|
|
638
|
+
* command ever shipped in.
|
|
639
|
+
*/
|
|
640
|
+
getLocale?: () => LocaleId;
|
|
613
641
|
}
|
|
614
642
|
/** The one registered `/commandcode` command. */
|
|
615
643
|
declare function commandDefinition<C extends CommandCodeConnectionOptions>(deps: CommandCodeCommandDeps<C>): CommandDefinition;
|
|
@@ -905,6 +933,18 @@ interface Config {
|
|
|
905
933
|
* rotation still applies). Unset means "first usable account".
|
|
906
934
|
*/
|
|
907
935
|
activeAccount?: string;
|
|
936
|
+
/**
|
|
937
|
+
* Language override for the `/commandcode` Host-side command's user-facing
|
|
938
|
+
* copy. Host commands cannot read the client's `ctx.locale`, so this is
|
|
939
|
+
* the explicit knob: `'zh'` or `'en'`. Unset means the command reads
|
|
940
|
+
* `LC_ALL`/`LANG` from the launching shell, falling back to `'zh'`. The
|
|
941
|
+
* web settings page is unaffected — it follows the browser's language
|
|
942
|
+
* preference on its own. Two surfaces, two independent locales. The
|
|
943
|
+
* declared type is `string` (the schemastery `pattern` cannot narrow
|
|
944
|
+
* literal types); an unknown value is treated as "unset" by
|
|
945
|
+
* `pickCommandLocale`.
|
|
946
|
+
*/
|
|
947
|
+
lang?: string;
|
|
908
948
|
}
|
|
909
949
|
declare const Config: z<Config>;
|
|
910
950
|
/** One resolution's complete request facts: connection plus credential reference. */
|
package/lib/index.js
CHANGED
|
@@ -216,7 +216,7 @@ var CommandCodeAccountPool = class {
|
|
|
216
216
|
* and API key or subscription, and Command Code's terms apply.
|
|
217
217
|
*
|
|
218
218
|
* Wire protocol (reverse-engineered by the pi plugin, command-code@1.28.4;
|
|
219
|
-
* re-verified against command-code@1.
|
|
219
|
+
* re-verified against command-code@1.37.0 — endpoints, request shape, and
|
|
220
220
|
* stream events unchanged):
|
|
221
221
|
* POST {apiBase}/alpha/generate
|
|
222
222
|
* body: { config, memory, taste, skills, params: { model, messages, tools,
|
|
@@ -240,6 +240,11 @@ const KNOWN_EFFORTS = {
|
|
|
240
240
|
"medium",
|
|
241
241
|
"xhigh"
|
|
242
242
|
],
|
|
243
|
+
"Qwen/Qwen3.8-Flash": [
|
|
244
|
+
"low",
|
|
245
|
+
"medium",
|
|
246
|
+
"xhigh"
|
|
247
|
+
],
|
|
243
248
|
"claude-fable-5": [
|
|
244
249
|
"low",
|
|
245
250
|
"medium",
|
|
@@ -355,11 +360,6 @@ const KNOWN_EFFORTS = {
|
|
|
355
360
|
"max"
|
|
356
361
|
],
|
|
357
362
|
"sakana/fugu-ultra": ["high", "xhigh"],
|
|
358
|
-
"stealth/ox-alpha": [
|
|
359
|
-
"low",
|
|
360
|
-
"high",
|
|
361
|
-
"max"
|
|
362
|
-
],
|
|
363
363
|
"xai/grok-4.5": [
|
|
364
364
|
"low",
|
|
365
365
|
"medium",
|
|
@@ -371,6 +371,11 @@ const KNOWN_EFFORTS = {
|
|
|
371
371
|
"high",
|
|
372
372
|
"xhigh"
|
|
373
373
|
],
|
|
374
|
+
"z-ai/glm-5.3-flash": [
|
|
375
|
+
"low",
|
|
376
|
+
"high",
|
|
377
|
+
"max"
|
|
378
|
+
],
|
|
374
379
|
"zai-org/GLM-5.2": ["high", "max"],
|
|
375
380
|
"zai-org/GLM-5.3": [
|
|
376
381
|
"low",
|
|
@@ -399,6 +404,7 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
399
404
|
"Qwen/Qwen3.7-Flash",
|
|
400
405
|
"Qwen/Qwen3.7-Plus",
|
|
401
406
|
"Qwen/Qwen3.8-27B",
|
|
407
|
+
"Qwen/Qwen3.8-Flash",
|
|
402
408
|
"Qwen/Qwen3.8-Max",
|
|
403
409
|
"claude-fable-5",
|
|
404
410
|
"claude-haiku-4-5-20251001",
|
|
@@ -430,15 +436,15 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
430
436
|
"moonshotai/Kimi-K2.7-Code-Highspeed",
|
|
431
437
|
"moonshotai/Kimi-K3",
|
|
432
438
|
"sakana/fugu-ultra",
|
|
433
|
-
"stealth/ox-alpha",
|
|
434
439
|
"stepfun/Step-3.7-Flash",
|
|
435
440
|
"thinkingmachines/inkling",
|
|
436
441
|
"thinkingmachines/inkling-small",
|
|
437
442
|
"xai/grok-4.5",
|
|
438
|
-
"xiaomi/mimo-v2.5"
|
|
443
|
+
"xiaomi/mimo-v2.5",
|
|
444
|
+
"z-ai/glm-5.3-flash"
|
|
439
445
|
]);
|
|
440
446
|
/**
|
|
441
|
-
* Models the official CLI's model table (command-code@1.
|
|
447
|
+
* Models the official CLI's model table (command-code@1.37.0) marks
|
|
442
448
|
* `reasoning:!0` but defines no selectable `reasoning_effort` levels — they
|
|
443
449
|
* think automatically, with Command Code driving the depth. This is the
|
|
444
450
|
* authoritative "thinks, effort not adjustable" set: `KNOWN_EFFORTS` (which
|
|
@@ -446,10 +452,13 @@ const KNOWN_IMAGE_MODELS = /* @__PURE__ */ new Set([
|
|
|
446
452
|
* effort levels, and this snapshot is not surfaced in the picker's compact
|
|
447
453
|
* description — it exists for programmatic consumers.
|
|
448
454
|
*
|
|
449
|
-
* Source: the command-code@1.
|
|
455
|
+
* Source: the command-code@1.37.0 bundled model table (dist/cli.mjs),
|
|
450
456
|
* cross-checked with https://commandcode.ai/docs/reference/cli/models.
|
|
451
457
|
* (`stealth/ox-alpha` left this set in command-code@1.32.1, which gave it
|
|
452
|
-
* selectable `['low', 'high', 'max']` efforts
|
|
458
|
+
* selectable `['low', 'high', 'max']` efforts; the preview then ended in
|
|
459
|
+
* 1.34.0, removing the model from the catalog entirely. `tencent/hy4-preview`
|
|
460
|
+
* joined this set in command-code@1.37.0 — reasoning:!0, no efforts, 1M
|
|
461
|
+
* context, routed through OpenRouter.)
|
|
453
462
|
* Keep in sync via the dsh-commandcode-upstream skill.
|
|
454
463
|
*/
|
|
455
464
|
const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
@@ -466,6 +475,7 @@ const KNOWN_THINKING_MODELS = /* @__PURE__ */ new Set([
|
|
|
466
475
|
"stepfun/Step-3.5-Flash",
|
|
467
476
|
"stepfun/Step-3.7-Flash",
|
|
468
477
|
"tencent/hy3-paid",
|
|
478
|
+
"tencent/hy4-preview",
|
|
469
479
|
"nvidia/nemotron-3-ultra-550b-a55b",
|
|
470
480
|
"thinkingmachines/inkling",
|
|
471
481
|
"thinkingmachines/inkling-small",
|
|
@@ -499,6 +509,7 @@ const KNOWN_PLANS = {
|
|
|
499
509
|
"Qwen/Qwen3.7-Max": "go",
|
|
500
510
|
"Qwen/Qwen3.7-Plus": "go",
|
|
501
511
|
"Qwen/Qwen3.8-27B": "go",
|
|
512
|
+
"Qwen/Qwen3.8-Flash": "go",
|
|
502
513
|
"Qwen/Qwen3.8-Max": "go",
|
|
503
514
|
"deepseek/deepseek-v4-flash": "go",
|
|
504
515
|
"deepseek/deepseek-v4-flash-vision-exp": "go",
|
|
@@ -514,15 +525,16 @@ const KNOWN_PLANS = {
|
|
|
514
525
|
"moonshotai/Kimi-K3": "go",
|
|
515
526
|
"nvidia/nemotron-3-ultra-550b-a55b": "go",
|
|
516
527
|
"poolside/laguna-s-2.1-free": "go",
|
|
517
|
-
"stealth/ox-alpha": "go",
|
|
518
528
|
"stepfun/Step-3.5-Flash": "go",
|
|
519
529
|
"stepfun/Step-3.7-Flash": "go",
|
|
520
530
|
"tencent/hy3-paid": "go",
|
|
531
|
+
"tencent/hy4-preview": "go",
|
|
521
532
|
"thinkingmachines/inkling": "go",
|
|
522
533
|
"thinkingmachines/inkling-small": "go",
|
|
523
534
|
"xai/grok-4.5": "go",
|
|
524
535
|
"xiaomi/mimo-v2.5": "go",
|
|
525
536
|
"xiaomi/mimo-v2.5-pro": "go",
|
|
537
|
+
"z-ai/glm-5.3-flash": "go",
|
|
526
538
|
"zai-org/GLM-5": "go",
|
|
527
539
|
"zai-org/GLM-5.1": "go",
|
|
528
540
|
"zai-org/GLM-5.2": "go",
|
|
@@ -699,10 +711,6 @@ const KNOWN_DEALS = {
|
|
|
699
711
|
"poolside/laguna-s-2.1-free": {
|
|
700
712
|
label: "FREE",
|
|
701
713
|
free: true
|
|
702
|
-
},
|
|
703
|
-
"stealth/ox-alpha": {
|
|
704
|
-
label: "FREE",
|
|
705
|
-
free: true
|
|
706
714
|
}
|
|
707
715
|
};
|
|
708
716
|
/**
|
|
@@ -755,7 +763,7 @@ function peakPricingLabel(modelId, now = Date.now()) {
|
|
|
755
763
|
if (state === void 0) return void 0;
|
|
756
764
|
return state === "peak" ? "Peak" : "Half";
|
|
757
765
|
}
|
|
758
|
-
const COMMAND_CODE_CLI_VERSION = "1.
|
|
766
|
+
const COMMAND_CODE_CLI_VERSION = "1.37.0";
|
|
759
767
|
const DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
760
768
|
const DEFAULT_GENERATE_MAX_TOKENS = 64e3;
|
|
761
769
|
const DEFAULT_MAX_OUTPUT_TOKENS = 65536;
|
|
@@ -1786,6 +1794,97 @@ function mapFinishReason(reason) {
|
|
|
1786
1794
|
return { kind: "stop" };
|
|
1787
1795
|
}
|
|
1788
1796
|
//#endregion
|
|
1797
|
+
//#region src/command-locales.ts
|
|
1798
|
+
const commandcodeCommand = {
|
|
1799
|
+
zh: {
|
|
1800
|
+
title: "📊 Command Code 用量{account}",
|
|
1801
|
+
accountTitle: "📊 {label}{badges}",
|
|
1802
|
+
accountSeparator: "────────────────────",
|
|
1803
|
+
activeBadge: " ✅ 当前使用",
|
|
1804
|
+
invalidCredentialBadge: " ⛔ 密钥无效",
|
|
1805
|
+
cooldownBadge: " ⏳ 限额冷却中,重置 {when}",
|
|
1806
|
+
rateLimitBadge: " ⏳ 已达限额(等待窗口探测)",
|
|
1807
|
+
unconfigured: " (未配置 API 密钥)",
|
|
1808
|
+
blockedInvalidKey: "⛔ API 密钥无效或已过期 — 服务端拒绝了全部请求(401),请检查该账户的密钥配置",
|
|
1809
|
+
blockedServiceUnavailable: "⚠️ Command Code 服务暂时不可用(5xx),稍后重试",
|
|
1810
|
+
blockedNetwork: "⚠️ 无法连接 Command Code 服务 — 请检查网络或 API 地址",
|
|
1811
|
+
planLine: " 📦 套餐 {name}{status}{period}",
|
|
1812
|
+
planPeriodSuffix: " · 账期截止 {date}",
|
|
1813
|
+
usageHeader: "── 请求 ──────────────────────────────",
|
|
1814
|
+
requestsLine: " 💬 请求 {n} 次 / 失败 {f} 成功率 {r}%",
|
|
1815
|
+
costLine: " 💰 花费 {money} ({credits} credits)",
|
|
1816
|
+
tokensLine: " 🔤 Token {in} 入 / {out} 出",
|
|
1817
|
+
creditsHeader: "── 信用 ──────────────────────────────",
|
|
1818
|
+
monthlyLine: " 💳 月额度 {monthly} (已购 {purchased} / 赠送 {free})",
|
|
1819
|
+
barLine: " └ {bar} {pct}%",
|
|
1820
|
+
windowsHeader: "── 窗口用量 ──────────────────────────",
|
|
1821
|
+
fiveHourLine: " ⏱ 5 小时 {used} / {cap}{warn}",
|
|
1822
|
+
weeklyLine: " 📅 每周 {used} / {cap}{warn}",
|
|
1823
|
+
windowBarLine: " └ {bar} 重置 {when}",
|
|
1824
|
+
exceededWarning: " ⚠️ 超限!",
|
|
1825
|
+
resetSuffix: "重置 {when}",
|
|
1826
|
+
partialFailures: "⚠️ 部分端点失败: {list}",
|
|
1827
|
+
noData: "(no data — check your API key)",
|
|
1828
|
+
errorText: "Could not fetch Command Code usage: {message}",
|
|
1829
|
+
imageGate: "当前会话已包含图片,而模型 {model} 不支持图片输入;请选择支持图片的模型,或先移除会话中的图片。"
|
|
1830
|
+
},
|
|
1831
|
+
en: {
|
|
1832
|
+
title: "📊 Command Code usage{account}",
|
|
1833
|
+
accountTitle: "📊 {label}{badges}",
|
|
1834
|
+
accountSeparator: "────────────────────",
|
|
1835
|
+
activeBadge: " ✅ active",
|
|
1836
|
+
invalidCredentialBadge: " ⛔ invalid key",
|
|
1837
|
+
cooldownBadge: " ⏳ cooling down, resets {when}",
|
|
1838
|
+
rateLimitBadge: " ⏳ rate-limited (waiting for window probe)",
|
|
1839
|
+
unconfigured: " (no API key configured)",
|
|
1840
|
+
blockedInvalidKey: "⛔ API key invalid or expired — the server rejected every request (401); check the key configured for this account",
|
|
1841
|
+
blockedServiceUnavailable: "⚠️ Command Code service temporarily unavailable (5xx); try again later",
|
|
1842
|
+
blockedNetwork: "⚠️ could not reach the Command Code service — check your network or the API base setting",
|
|
1843
|
+
planLine: " 📦 Plan {name}{status}{period}",
|
|
1844
|
+
planPeriodSuffix: " · period ends {date}",
|
|
1845
|
+
usageHeader: "── Requests ──────────────────────────",
|
|
1846
|
+
requestsLine: " 💬 Requests {n} / failed {f} success rate {r}%",
|
|
1847
|
+
costLine: " 💰 Spend {money} ({credits} credits)",
|
|
1848
|
+
tokensLine: " 🔤 Tokens {in} in / {out} out",
|
|
1849
|
+
creditsHeader: "── Credits ───────────────────────────",
|
|
1850
|
+
monthlyLine: " 💳 Monthly {monthly} (purchased {purchased} / free {free})",
|
|
1851
|
+
barLine: " └ {bar} {pct}%",
|
|
1852
|
+
windowsHeader: "── Window usage ──────────────────────",
|
|
1853
|
+
fiveHourLine: " ⏱ 5-hour {used} / {cap}{warn}",
|
|
1854
|
+
weeklyLine: " 📅 Weekly {used} / {cap}{warn}",
|
|
1855
|
+
windowBarLine: " └ {bar} resets {when}",
|
|
1856
|
+
exceededWarning: " ⚠️ exceeded!",
|
|
1857
|
+
resetSuffix: "resets {when}",
|
|
1858
|
+
partialFailures: "⚠️ some endpoints failed: {list}",
|
|
1859
|
+
noData: "(no data — check your API key)",
|
|
1860
|
+
errorText: "Could not fetch Command Code usage: {message}",
|
|
1861
|
+
imageGate: "This session already contains images, and model {model} does not accept image input; please select an image-capable model, or remove the images from the session first."
|
|
1862
|
+
}
|
|
1863
|
+
};
|
|
1864
|
+
/**
|
|
1865
|
+
* Resolve the active locale for a Host-side command run.
|
|
1866
|
+
*
|
|
1867
|
+
* Priority: explicit `override` (from `Config.lang`) → `LC_ALL` → `LANG` →
|
|
1868
|
+
* the conventional fallback (`'zh'`, matching the existing single-language
|
|
1869
|
+
* behavior so unconfigured deployments keep their current output).
|
|
1870
|
+
*
|
|
1871
|
+
* The values are matched on the leading tag only — `zh_CN.UTF-8`,
|
|
1872
|
+
* `zh-Hans`, `zh` all map to `'zh'`; everything starting with `en` maps to
|
|
1873
|
+
* `'en'`; anything else falls back to `'zh'` (a non-`en` shell that
|
|
1874
|
+
* already has Chinese in the terminal is the closest sensible default;
|
|
1875
|
+
* a Western shell that happens to be neither keeps the existing Chinese
|
|
1876
|
+
* output rather than swapping to half-translated English).
|
|
1877
|
+
*/
|
|
1878
|
+
function pickCommandLocale(override, env = process.env) {
|
|
1879
|
+
if (override === "zh" || override === "en") return override;
|
|
1880
|
+
if (((env.LC_ALL ?? env.LANG ?? "").toLowerCase().split(/[._-]/)[0] ?? "") === "en") return "en";
|
|
1881
|
+
return "zh";
|
|
1882
|
+
}
|
|
1883
|
+
/** Look up a key in the active locale, with an internal en fallback. */
|
|
1884
|
+
function commandCopy(locale, key) {
|
|
1885
|
+
return commandcodeCommand[locale][key] ?? commandcodeCommand.en[key] ?? key;
|
|
1886
|
+
}
|
|
1887
|
+
//#endregion
|
|
1789
1888
|
//#region src/commands.ts
|
|
1790
1889
|
/** Format a dollar amount. */
|
|
1791
1890
|
function money(value) {
|
|
@@ -1802,7 +1901,7 @@ function tokensCompact(value) {
|
|
|
1802
1901
|
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
|
|
1803
1902
|
return String(value);
|
|
1804
1903
|
}
|
|
1805
|
-
/** Format a millis timestamp as a local date. */
|
|
1904
|
+
/** Format a millis timestamp as a local date; `n/a` when unset. */
|
|
1806
1905
|
function resetLabel(ms) {
|
|
1807
1906
|
if (ms <= 0) return "n/a";
|
|
1808
1907
|
return new Date(ms).toLocaleString();
|
|
@@ -1818,37 +1917,37 @@ function bar(used, cap) {
|
|
|
1818
1917
|
return "█".repeat(filled) + "░".repeat(10 - filled);
|
|
1819
1918
|
}
|
|
1820
1919
|
/** Render one account's rotation mark / cooldown as a short badge. */
|
|
1821
|
-
function markLabel(entry) {
|
|
1822
|
-
if (entry.mark === "invalid-credential") return
|
|
1823
|
-
if (entry.cooldownUntil > 0) return
|
|
1824
|
-
if (entry.mark === "rate-limit") return
|
|
1920
|
+
function markLabel(entry, locale) {
|
|
1921
|
+
if (entry.mark === "invalid-credential") return commandCopy(locale, "invalidCredentialBadge");
|
|
1922
|
+
if (entry.cooldownUntil > 0) return commandCopy(locale, "cooldownBadge").replace("{when}", resetLabel(entry.cooldownUntil));
|
|
1923
|
+
if (entry.mark === "rate-limit") return commandCopy(locale, "rateLimitBadge");
|
|
1825
1924
|
return "";
|
|
1826
1925
|
}
|
|
1827
1926
|
/** Render the usage report as a structured, aligned, bar-chart text view. */
|
|
1828
|
-
function renderReport(report, title) {
|
|
1927
|
+
function renderReport(report, locale, title) {
|
|
1829
1928
|
const lines = [];
|
|
1830
1929
|
const account = report.account ? ` (${report.account.userName || report.account.name})` : "";
|
|
1831
|
-
lines.push(title ??
|
|
1832
|
-
if (report.blocked === "invalid-key") lines.push(
|
|
1833
|
-
else if (report.blocked === "service-unavailable") lines.push(
|
|
1834
|
-
else if (report.blocked === "network") lines.push(
|
|
1930
|
+
lines.push(title ?? commandCopy(locale, "title").replace("{account}", account), "");
|
|
1931
|
+
if (report.blocked === "invalid-key") lines.push(commandCopy(locale, "blockedInvalidKey"), "");
|
|
1932
|
+
else if (report.blocked === "service-unavailable") lines.push(commandCopy(locale, "blockedServiceUnavailable"), "");
|
|
1933
|
+
else if (report.blocked === "network") lines.push(commandCopy(locale, "blockedNetwork"), "");
|
|
1835
1934
|
if (report.plan && report.plan.name !== "") {
|
|
1836
1935
|
const p = report.plan;
|
|
1837
1936
|
const status = p.status !== "" && p.status !== "active" ? ` (${p.status})` : "";
|
|
1838
|
-
const period = p.currentPeriodEnd > 0 ?
|
|
1839
|
-
lines.push(
|
|
1937
|
+
const period = p.currentPeriodEnd > 0 ? commandCopy(locale, "planPeriodSuffix").replace("{date}", new Date(p.currentPeriodEnd).toLocaleDateString()) : "";
|
|
1938
|
+
lines.push(commandCopy(locale, "planLine").replace("{name}", p.name).replace("{status}", status).replace("{period}", period), "");
|
|
1840
1939
|
}
|
|
1841
1940
|
if (report.usage) {
|
|
1842
1941
|
const u = report.usage;
|
|
1843
|
-
lines.push("
|
|
1942
|
+
lines.push(commandCopy(locale, "usageHeader"), commandCopy(locale, "requestsLine").replace("{n}", String(u.completedCount)).replace("{f}", String(u.failedCount)).replace("{r}", String(u.successRate)), commandCopy(locale, "costLine").replace("{money}", money(u.totalCost)).replace("{credits}", moneyShort(u.totalCredits)), commandCopy(locale, "tokensLine").replace("{in}", tokensCompact(u.totalTokensIn)).replace("{out}", tokensCompact(u.totalTokensOut)), "");
|
|
1844
1943
|
}
|
|
1845
1944
|
if (report.credits) {
|
|
1846
1945
|
const c = report.credits;
|
|
1847
1946
|
const monthlyPct = c.monthlyCredits > 0 ? `${(c.monthlyCredits / (c.monthlyCredits + c.purchasedCredits) * 100).toFixed(0)}%` : "—";
|
|
1848
|
-
lines.push("
|
|
1947
|
+
lines.push(commandCopy(locale, "creditsHeader"), commandCopy(locale, "monthlyLine").replace("{monthly}", moneyShort(c.monthlyCredits)).replace("{purchased}", moneyShort(c.purchasedCredits)).replace("{free}", moneyShort(c.freeCredits)), commandCopy(locale, "barLine").replace("{bar}", bar(c.monthlyCredits, c.monthlyCredits + c.purchasedCredits)).replace("{pct}", monthlyPct), "", commandCopy(locale, "windowsHeader"), commandCopy(locale, "fiveHourLine").replace("{used}", moneyShort(c.fiveHour.used)).replace("{cap}", moneyShort(c.fiveHour.cap)).replace("{warn}", c.fiveHour.exceeded ? commandCopy(locale, "exceededWarning") : ""), commandCopy(locale, "windowBarLine").replace("{bar}", bar(c.fiveHour.used, c.fiveHour.cap)).replace("{when}", resetLabel(c.fiveHour.resetAt)), commandCopy(locale, "weeklyLine").replace("{used}", moneyShort(c.weekly.used)).replace("{cap}", moneyShort(c.weekly.cap)).replace("{warn}", c.weekly.exceeded ? commandCopy(locale, "exceededWarning") : ""), commandCopy(locale, "windowBarLine").replace("{bar}", bar(c.weekly.used, c.weekly.cap)).replace("{when}", resetLabel(c.weekly.resetAt)), "");
|
|
1849
1948
|
}
|
|
1850
|
-
if (report.failures.length > 0) lines.push(
|
|
1851
|
-
if (!report.account && !report.usage && !report.credits) lines.push(
|
|
1949
|
+
if (report.failures.length > 0) lines.push(commandCopy(locale, "partialFailures").replace("{list}", report.failures.join("; ")), "");
|
|
1950
|
+
if (!report.account && !report.usage && !report.credits) lines.push(commandCopy(locale, "noData"), "");
|
|
1852
1951
|
return lines.join("\n").trimEnd();
|
|
1853
1952
|
}
|
|
1854
1953
|
/** The one registered `/commandcode` command. */
|
|
@@ -1859,27 +1958,29 @@ function commandDefinition(deps) {
|
|
|
1859
1958
|
description: "Command Code account usage dashboard",
|
|
1860
1959
|
input: { hint: "[status]" },
|
|
1861
1960
|
handler: async () => {
|
|
1961
|
+
const locale = deps.getLocale?.() ?? "zh";
|
|
1862
1962
|
try {
|
|
1863
1963
|
if (deps.reports !== void 0) {
|
|
1864
1964
|
const { accounts } = await deps.reports();
|
|
1865
1965
|
return {
|
|
1866
1966
|
kind: "success",
|
|
1867
1967
|
text: accounts.map((entry) => {
|
|
1868
|
-
const badges = `${entry.active ?
|
|
1869
|
-
const title =
|
|
1870
|
-
if (!entry.configured) return `${title}\n\n
|
|
1871
|
-
return renderReport(entry.report, title);
|
|
1872
|
-
}).join(
|
|
1968
|
+
const badges = `${entry.active ? commandCopy(locale, "activeBadge") : ""}${markLabel(entry, locale)}`;
|
|
1969
|
+
const title = commandCopy(locale, "accountTitle").replace("{label}", entry.label).replace("{badges}", badges);
|
|
1970
|
+
if (!entry.configured) return `${title}\n\n${commandCopy(locale, "unconfigured")}`;
|
|
1971
|
+
return renderReport(entry.report, locale, title);
|
|
1972
|
+
}).join(`\n\n${commandCopy(locale, "accountSeparator")}\n\n`)
|
|
1873
1973
|
};
|
|
1874
1974
|
}
|
|
1875
1975
|
return {
|
|
1876
1976
|
kind: "success",
|
|
1877
|
-
text: renderReport(await adapter.getUsage())
|
|
1977
|
+
text: renderReport(await adapter.getUsage(), locale)
|
|
1878
1978
|
};
|
|
1879
1979
|
} catch (error) {
|
|
1980
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1880
1981
|
return {
|
|
1881
1982
|
kind: "error",
|
|
1882
|
-
text:
|
|
1983
|
+
text: commandCopy(locale, "errorText").replace("{message}", message)
|
|
1883
1984
|
};
|
|
1884
1985
|
}
|
|
1885
1986
|
}
|
|
@@ -2619,7 +2720,8 @@ const Config = z.object({
|
|
|
2619
2720
|
apiKeyEnv: z.string().role("credential-ref"),
|
|
2620
2721
|
apiKey: z.string()
|
|
2621
2722
|
})),
|
|
2622
|
-
activeAccount: z.string()
|
|
2723
|
+
activeAccount: z.string(),
|
|
2724
|
+
lang: z.string().pattern(/^(zh|en)$/).default("zh")
|
|
2623
2725
|
});
|
|
2624
2726
|
/**
|
|
2625
2727
|
* The one explicit resolve step from raw config to validated connection
|
|
@@ -2743,10 +2845,12 @@ function apply(ctx, config) {
|
|
|
2743
2845
|
};
|
|
2744
2846
|
})) };
|
|
2745
2847
|
};
|
|
2848
|
+
const commandLocale = () => pickCommandLocale(current().lang);
|
|
2746
2849
|
ctx.inject(["commands"], (commandCtx) => {
|
|
2747
2850
|
applyCommands(commandCtx, {
|
|
2748
2851
|
adapter,
|
|
2749
|
-
reports: usageReports
|
|
2852
|
+
reports: usageReports,
|
|
2853
|
+
getLocale: commandLocale
|
|
2750
2854
|
});
|
|
2751
2855
|
});
|
|
2752
2856
|
const loginFlow = new CommandCodeLoginFlow({
|