Default HUD language to English; Chinese remains switchable
New installs and missing language fall back to en. Settings menu lists English first; grok-hud lang zh|tw still switches to Chinese variants.
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.3.14
|
||||||
|
|
||||||
|
### Config
|
||||||
|
- **Default language is English** (`en`). Switch to 简体中文 / 繁體 via
|
||||||
|
`grok-hud settings` or `grok-hud lang zh` / `lang tw`.
|
||||||
|
|
||||||
## 0.3.13
|
## 0.3.13
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ ctx ██████░░░░ 50% (252k/500k) · i … o … c 99% · use 2
|
|||||||
| Activity | Tools, agents, todos |
|
| Activity | Tools, agents, todos |
|
||||||
| Theme | Follows Grok `[ui].theme` (not locked) |
|
| Theme | Follows Grok `[ui].theme` (not locked) |
|
||||||
| Multi-terminal | Independent session per tab |
|
| Multi-terminal | Independent session per tab |
|
||||||
| Language | Default **简体中文**; English / 繁體 available |
|
| Language | Default **English**; 简体中文 / 繁體 available |
|
||||||
|
|
||||||
Repo: http://172.238.15.154:3000/Redredchen01/grok-build-hud
|
Repo: http://172.238.15.154:3000/Redredchen01/grok-build-hud
|
||||||
Plugin id: `grok-build-hud` · version in [`plugin.json`](./plugin.json)
|
Plugin id: `grok-build-hud` · version in [`plugin.json`](./plugin.json)
|
||||||
@@ -154,7 +154,7 @@ scripts/install.sh # one-shot installer
|
|||||||
| **essential** | 2 | Model/git + context/usage + activity |
|
| **essential** | 2 | Model/git + context/usage + activity |
|
||||||
| **minimal** | 1 | Dense single row |
|
| **minimal** | 1 | Dense single row |
|
||||||
|
|
||||||
`language`: `zh-Hans` (default) / `en` / `zh-Hant`
|
`language`: `en` (default) / `zh-Hans` / `zh-Hant`
|
||||||
|
|
||||||
Theme always tracks Grok `/theme` unless `GROK_HUD_LOCK=1`.
|
Theme always tracks Grok `/theme` unless `GROK_HUD_LOCK=1`.
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Grok 4.5 · AI FILM SPACE/0717 · ●
|
|||||||
| 活动 | 工具、agent、todos |
|
| 活动 | 工具、agent、todos |
|
||||||
| 主题 | 跟随 Grok `[ui].theme`,不锁死 |
|
| 主题 | 跟随 Grok `[ui].theme`,不锁死 |
|
||||||
| 多终端 | 每个标签页**独立** session,互不串线 |
|
| 多终端 | 每个标签页**独立** session,互不串线 |
|
||||||
| 语言 | 默认**简体中文**,可切英文 / 繁體 |
|
| 语言 | 默认 **English**,可切简体中文 / 繁體 |
|
||||||
|
|
||||||
仓库:http://172.238.15.154:3000/Redredchen01/grok-build-hud
|
仓库:http://172.238.15.154:3000/Redredchen01/grok-build-hud
|
||||||
插件名:`grok-build-hud` · 版本见 [`plugin.json`](./plugin.json)
|
插件名:`grok-build-hud` · 版本见 [`plugin.json`](./plugin.json)
|
||||||
@@ -216,8 +216,8 @@ grok-hud stop
|
|||||||
grok-hud settings
|
grok-hud settings
|
||||||
|
|
||||||
# 快捷切语言
|
# 快捷切语言
|
||||||
grok-hud lang zh # 简体中文(默认)
|
grok-hud lang en # English(默认)
|
||||||
grok-hud lang en # English
|
grok-hud lang zh # 简体中文
|
||||||
grok-hud lang tw # 繁體中文
|
grok-hud lang tw # 繁體中文
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ tmux source-file ~/.grok/hud/tmux.conf && tmux refresh-client -S
|
|||||||
|
|
||||||
常用字段:
|
常用字段:
|
||||||
|
|
||||||
- `language`:`zh-Hans`(默认)/ `en` / `zh-Hant`
|
- `language`:`en`(默认)/ `zh-Hans` / `zh-Hant`
|
||||||
- `bold: true` — 粗体数值
|
- `bold: true` — 粗体数值
|
||||||
- `barWidth: 14` — 进度条宽度
|
- `barWidth: 14` — 进度条宽度
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ grok-build-hud --settings
|
|||||||
## Language shortcuts
|
## Language shortcuts
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
grok-hud lang zh # 简体中文 (default)
|
grok-hud lang en # English (default)
|
||||||
grok-hud lang en # English
|
grok-hud lang zh # 简体中文
|
||||||
grok-hud lang tw # 繁體中文
|
grok-hud lang tw # 繁體中文
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "grok-build-hud",
|
"name": "grok-build-hud",
|
||||||
"version": "0.3.13",
|
"version": "0.3.14",
|
||||||
"description": "第三方 Grok Build 状态条(非 xAI 官方):同窗口上下文/配额/token/工具;plugin + CLI + tmux HUD",
|
"description": "第三方 Grok Build 状态条(非 xAI 官方):同窗口上下文/配额/token/工具;plugin + CLI + tmux HUD",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/src/index.js",
|
"main": "dist/src/index.js",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "grok-build-hud",
|
"name": "grok-build-hud",
|
||||||
"version": "0.3.13",
|
"version": "0.3.14",
|
||||||
"description": "第三方 Grok Build 状态条(非官方):同窗口上下文/配额/token/工具/待办;tmux HUD + 会话斜杠命令",
|
"description": "第三方 Grok Build 状态条(非官方):同窗口上下文/配额/token/工具/待办;tmux HUD + 会话斜杠命令",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Redredchen01"
|
"name": "Redredchen01"
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ One-shot: build CLI → install tmux dashboard → `grok plugin install . --trus
|
|||||||
```bash
|
```bash
|
||||||
grok # wrapped: Grok + bottom HUD (same tab)
|
grok # wrapped: Grok + bottom HUD (same tab)
|
||||||
grok-hud status # one-shot print
|
grok-hud status # one-shot print
|
||||||
grok-hud settings # language (中/英), preset, rows
|
grok-hud settings # language (default en; 中文可选), preset, rows
|
||||||
grok-hud lang zh|en|tw
|
grok-hud lang en|zh|tw # en default
|
||||||
grok-build-hud --preset full|essential|minimal
|
grok-build-hud --preset full|essential|minimal
|
||||||
grok-build-hud --theme auto # follow Grok [ui].theme
|
grok-build-hud --theme auto # follow Grok [ui].theme
|
||||||
grok-hud stop # stop dashboard daemon
|
grok-hud stop # stop dashboard daemon
|
||||||
|
|||||||
+8
-8
@@ -58,8 +58,8 @@ export const PRESET_FULL: HudDisplayConfig = {
|
|||||||
preset: "full",
|
preset: "full",
|
||||||
lineLayout: "expanded",
|
lineLayout: "expanded",
|
||||||
pathLevels: 2,
|
pathLevels: 2,
|
||||||
/** Default UI language: 简体中文 (switch to en in settings) */
|
/** Default UI language: English (switch to 中文 in settings) */
|
||||||
language: "zh-Hans",
|
language: "en",
|
||||||
statusLines: 3,
|
statusLines: 3,
|
||||||
bold: true,
|
bold: true,
|
||||||
barWidth: 14,
|
barWidth: 14,
|
||||||
@@ -150,7 +150,7 @@ export function loadHudConfig(
|
|||||||
if (!fs.existsSync(p)) {
|
if (!fs.existsSync(p)) {
|
||||||
return {
|
return {
|
||||||
...PRESET_FULL,
|
...PRESET_FULL,
|
||||||
language: "zh-Hans",
|
language: "en",
|
||||||
display: { ...PRESET_FULL.display },
|
display: { ...PRESET_FULL.display },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -164,8 +164,8 @@ export function loadHudConfig(
|
|||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
...raw,
|
...raw,
|
||||||
// Prefer saved language; default 中文 when missing
|
// Prefer saved language; default English when missing
|
||||||
language: raw.language ?? base.language ?? "zh-Hans",
|
language: raw.language ?? base.language ?? "en",
|
||||||
bold: raw.bold ?? base.bold ?? true,
|
bold: raw.bold ?? base.bold ?? true,
|
||||||
barWidth: raw.barWidth ?? base.barWidth ?? 14,
|
barWidth: raw.barWidth ?? base.barWidth ?? 14,
|
||||||
statusLines: raw.statusLines ?? base.statusLines ?? 3,
|
statusLines: raw.statusLines ?? base.statusLines ?? 3,
|
||||||
@@ -174,13 +174,13 @@ export function loadHudConfig(
|
|||||||
} catch {
|
} catch {
|
||||||
return {
|
return {
|
||||||
...PRESET_FULL,
|
...PRESET_FULL,
|
||||||
language: "zh-Hans",
|
language: "en",
|
||||||
display: { ...PRESET_FULL.display },
|
display: { ...PRESET_FULL.display },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Ensure config exists with Chinese default (idempotent). */
|
/** Ensure config exists with English default (idempotent). */
|
||||||
export function ensureDefaultConfig(
|
export function ensureDefaultConfig(
|
||||||
grokHome = path.join(os.homedir(), ".grok"),
|
grokHome = path.join(os.homedir(), ".grok"),
|
||||||
): HudDisplayConfig {
|
): HudDisplayConfig {
|
||||||
@@ -188,7 +188,7 @@ export function ensureDefaultConfig(
|
|||||||
if (!fs.existsSync(p)) {
|
if (!fs.existsSync(p)) {
|
||||||
const cfg = {
|
const cfg = {
|
||||||
...PRESET_FULL,
|
...PRESET_FULL,
|
||||||
language: "zh-Hans" as const,
|
language: "en" as const,
|
||||||
display: { ...PRESET_FULL.display },
|
display: { ...PRESET_FULL.display },
|
||||||
};
|
};
|
||||||
saveHudConfig(cfg, grokHome);
|
saveHudConfig(cfg, grokHome);
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* HUD + settings UI strings.
|
* HUD + settings UI strings.
|
||||||
* Default language: zh-Hans (简体中文). Switch via settings → English.
|
* Default language: en (English). Switch via settings → 中文 / 繁體.
|
||||||
*/
|
*/
|
||||||
import type { HudDisplayConfig } from "./hud-config.js";
|
import type { HudDisplayConfig } from "./hud-config.js";
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ const EN: HudStrings = {
|
|||||||
|
|
||||||
export function normalizeLang(raw?: string | null): HudLang {
|
export function normalizeLang(raw?: string | null): HudLang {
|
||||||
const s = (raw || "").trim().toLowerCase();
|
const s = (raw || "").trim().toLowerCase();
|
||||||
if (!s) return "zh-Hans";
|
if (!s) return "en";
|
||||||
if (s === "en" || s === "english" || s === "eng") return "en";
|
if (s === "en" || s === "english" || s === "eng") return "en";
|
||||||
if (
|
if (
|
||||||
s === "zh-hant" ||
|
s === "zh-hant" ||
|
||||||
@@ -216,7 +216,7 @@ export function normalizeLang(raw?: string | null): HudLang {
|
|||||||
) {
|
) {
|
||||||
return "zh-Hans";
|
return "zh-Hans";
|
||||||
}
|
}
|
||||||
return "zh-Hans";
|
return "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function t(lang?: string | null): HudStrings {
|
export function t(lang?: string | null): HudStrings {
|
||||||
|
|||||||
+6
-5
@@ -269,13 +269,14 @@ Also:
|
|||||||
grok-build-hud --theme auto # follow Grok /theme (default, not locked)
|
grok-build-hud --theme auto # follow Grok /theme (default, not locked)
|
||||||
grok-build-hud --preset full|essential|minimal
|
grok-build-hud --preset full|essential|minimal
|
||||||
grok-hud settings # 设定界面(语言 中/英、预设、行数)
|
grok-hud settings # 设定界面(语言 中/英、预设、行数)
|
||||||
grok-hud lang zh # 快捷:简体中文
|
grok-hud lang en # English (default)
|
||||||
grok-hud lang en # 快捷:English
|
grok-hud lang zh # 简体中文
|
||||||
|
grok-hud lang tw # 繁體中文
|
||||||
|
|
||||||
Theme: always tracks Grok [ui].theme (auto → OS light/dark maps).
|
Theme: always tracks Grok [ui].theme (auto → OS light/dark maps).
|
||||||
Change inside Grok with /theme — HUD re-paints in ~1s.
|
Change inside Grok with /theme — HUD re-paints in ~1s.
|
||||||
|
|
||||||
Language: default 简体中文; switch in settings or: grok-hud lang en
|
Language: default English; switch in settings or: grok-hud lang zh
|
||||||
|
|
||||||
Lifecycle: Terminal open → ready (not machine boot).
|
Lifecycle: Terminal open → ready (not machine boot).
|
||||||
文档: README.md(中文)· README.en.md(English)
|
文档: README.md(中文)· README.en.md(English)
|
||||||
@@ -391,7 +392,7 @@ export async function runCli(
|
|||||||
// keep readability defaults + user language
|
// keep readability defaults + user language
|
||||||
cfg.bold = true;
|
cfg.bold = true;
|
||||||
cfg.barWidth = Math.max(cfg.barWidth ?? 12, 12);
|
cfg.barWidth = Math.max(cfg.barWidth ?? 12, 12);
|
||||||
cfg.language = prev.language ?? "zh-Hans";
|
cfg.language = prev.language ?? "en";
|
||||||
const saved = saveHudConfig(cfg, grokHome);
|
const saved = saveHudConfig(cfg, grokHome);
|
||||||
writeTmuxConfFile(opts.grokHome);
|
writeTmuxConfFile(opts.grokHome);
|
||||||
applyTmuxStatusBar({ grokHome: opts.grokHome });
|
applyTmuxStatusBar({ grokHome: opts.grokHome });
|
||||||
@@ -485,7 +486,7 @@ export async function runCli(
|
|||||||
out(` (plain command — auto HUD; no extra flags)`);
|
out(` (plain command — auto HUD; no extra flags)`);
|
||||||
out(` theme: follows Grok /theme (not locked)`);
|
out(` theme: follows Grok /theme (not locked)`);
|
||||||
out(
|
out(
|
||||||
` language: ${hudCfg.language} (设定: grok-hud settings · 切英文: grok-hud lang en)`,
|
` language: ${hudCfg.language} (settings: grok-hud settings · 中文: grok-hud lang zh)`,
|
||||||
);
|
);
|
||||||
if (r.grokWrap) {
|
if (r.grokWrap) {
|
||||||
out(` wrap: ${r.grokWrap.wrapperPath}`);
|
out(` wrap: ${r.grokWrap.wrapperPath}`);
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ if-shell '[ -f "$HOME/.grok/hud/tmux.conf" ]' 'source-file ~/.grok/hud/tmux.conf
|
|||||||
|
|
||||||
// Theme: always follow Grok [ui].theme (clear legacy locks)
|
// Theme: always follow Grok [ui].theme (clear legacy locks)
|
||||||
ensureFollowMode(grokHome);
|
ensureFollowMode(grokHome);
|
||||||
// Default language 简体中文 (user can switch in settings)
|
// Default language English (user can switch to 中文 in settings)
|
||||||
ensureDefaultConfig(grokHome);
|
ensureDefaultConfig(grokHome);
|
||||||
|
|
||||||
// Terminal-open hook (primary lifecycle): interactive zsh → ensure daemon
|
// Terminal-open hook (primary lifecycle): interactive zsh → ensure daemon
|
||||||
|
|||||||
+8
-8
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Interactive settings UI for language / preset / rows.
|
* Interactive settings UI for language / preset / rows.
|
||||||
* Default language: 简体中文; switchable to English / 繁體.
|
* Default language: English; switchable to 简体中文 / 繁體.
|
||||||
*/
|
*/
|
||||||
import * as readline from "node:readline";
|
import * as readline from "node:readline";
|
||||||
import {
|
import {
|
||||||
@@ -77,14 +77,14 @@ async function pickLanguage(
|
|||||||
out: (s: string) => void,
|
out: (s: string) => void,
|
||||||
): Promise<HudLang> {
|
): Promise<HudLang> {
|
||||||
const s = t(cfg.language);
|
const s = t(cfg.language);
|
||||||
out(` 1) ${s.langZh}`);
|
out(` 1) ${s.langEn} (default)`);
|
||||||
out(` 2) ${s.langZhHant}`);
|
out(` 2) ${s.langZh}`);
|
||||||
out(` 3) ${s.langEn}`);
|
out(` 3) ${s.langZhHant}`);
|
||||||
out(` b) ${s.back}`);
|
out(` b) ${s.back}`);
|
||||||
const ans = await ask(rl, ` ${s.choose}: `);
|
const ans = await ask(rl, ` ${s.choose}: `);
|
||||||
if (ans === "1" || ans === "zh" || ans === "cn") return "zh-Hans";
|
if (ans === "1" || ans === "en") return "en";
|
||||||
if (ans === "2" || ans === "tw" || ans === "hant") return "zh-Hant";
|
if (ans === "2" || ans === "zh" || ans === "cn") return "zh-Hans";
|
||||||
if (ans === "3" || ans === "en") return "en";
|
if (ans === "3" || ans === "tw" || ans === "hant") return "zh-Hant";
|
||||||
return normalizeLang(cfg.language);
|
return normalizeLang(cfg.language);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ export async function runSettingsUi(
|
|||||||
|
|
||||||
// Default to Chinese if somehow empty
|
// Default to Chinese if somehow empty
|
||||||
if (!cfg.language) {
|
if (!cfg.language) {
|
||||||
cfg = { ...cfg, language: "zh-Hans" };
|
cfg = { ...cfg, language: "en" };
|
||||||
}
|
}
|
||||||
|
|
||||||
const rl = readline.createInterface({
|
const rl = readline.createInterface({
|
||||||
|
|||||||
+4
-7
@@ -22,12 +22,9 @@ import {
|
|||||||
/** Brand-new Terminal status: ctx 0%, no leakage from previous windows. */
|
/** Brand-new Terminal status: ctx 0%, no leakage from previous windows. */
|
||||||
export function seedIdleTmuxStatus(instDir: string): void {
|
export function seedIdleTmuxStatus(instDir: string): void {
|
||||||
fs.mkdirSync(instDir, { recursive: true });
|
fs.mkdirSync(instDir, { recursive: true });
|
||||||
const idleSingle = "窗 ░░░░░░░░░░ 0% · —\n";
|
// English labels (default UI language); live dashboard rewrites with user lang
|
||||||
const idleLines = [
|
const idleSingle = "ctx ░░░░░░░░░░ 0% · —\n";
|
||||||
"— · —",
|
const idleLines = ["— · —", "ctx ░░░░░░░░░░ 0% · —", ""].join("\n") + "\n";
|
||||||
"窗 ░░░░░░░░░░ 0% · —",
|
|
||||||
"",
|
|
||||||
].join("\n") + "\n";
|
|
||||||
fs.writeFileSync(path.join(instDir, "tmux-status.txt"), idleSingle, "utf8");
|
fs.writeFileSync(path.join(instDir, "tmux-status.txt"), idleSingle, "utf8");
|
||||||
fs.writeFileSync(path.join(instDir, "tmux-lines.txt"), idleLines, "utf8");
|
fs.writeFileSync(path.join(instDir, "tmux-lines.txt"), idleLines, "utf8");
|
||||||
fs.writeFileSync(path.join(instDir, "status-line.txt"), "[hud] ctx 0%\n", "utf8");
|
fs.writeFileSync(path.join(instDir, "status-line.txt"), "[hud] ctx 0%\n", "utf8");
|
||||||
@@ -83,7 +80,7 @@ export function tmuxStatusCommands(grokHome = defaultGrokHome()): string[][] {
|
|||||||
const scopedSingle = `${instRoot}/#{session_name}/tmux-status.txt`;
|
const scopedSingle = `${instRoot}/#{session_name}/tmux-status.txt`;
|
||||||
// NEVER fall back to global ~/.grok/hud/tmux-*.txt — that leaked the previous
|
// NEVER fall back to global ~/.grok/hud/tmux-*.txt — that leaked the previous
|
||||||
// Terminal's high ctx% into brand-new windows (should show 0% / idle).
|
// Terminal's high ctx% into brand-new windows (should show 0% / idle).
|
||||||
const idleSingle = "窗 ░░░░░░░░░░ 0% · —";
|
const idleSingle = "ctx ░░░░░░░░░░ 0% · —";
|
||||||
// Up to 3 status rows in the SAME terminal window
|
// Up to 3 status rows in the SAME terminal window
|
||||||
const statusLines = Math.max(
|
const statusLines = Math.max(
|
||||||
1,
|
1,
|
||||||
|
|||||||
+2
-1
@@ -13,7 +13,8 @@ import type { SessionSnapshot } from "../src/types.js";
|
|||||||
|
|
||||||
describe("i18n + settings language", () => {
|
describe("i18n + settings language", () => {
|
||||||
it("defaults and normalizes languages", () => {
|
it("defaults and normalizes languages", () => {
|
||||||
assert.equal(normalizeLang(undefined), "zh-Hans");
|
assert.equal(normalizeLang(undefined), "en");
|
||||||
|
assert.equal(normalizeLang(""), "en");
|
||||||
assert.equal(normalizeLang("zh"), "zh-Hans");
|
assert.equal(normalizeLang("zh"), "zh-Hans");
|
||||||
assert.equal(normalizeLang("en"), "en");
|
assert.equal(normalizeLang("en"), "en");
|
||||||
assert.equal(normalizeLang("tw"), "zh-Hant");
|
assert.equal(normalizeLang("tw"), "zh-Hant");
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ describe("layout", () => {
|
|||||||
for (const ln of narrow) {
|
for (const ln of narrow) {
|
||||||
assert.ok(visibleLen(ln) <= 50, `line too long: ${visibleLen(ln)} ${stripTmuxStyles(ln)}`);
|
assert.ok(visibleLen(ln) <= 50, `line too long: ${visibleLen(ln)} ${stripTmuxStyles(ln)}`);
|
||||||
}
|
}
|
||||||
// hierarchy styles present on wide (default language 中文 labels)
|
// hierarchy styles present on wide (default language English labels)
|
||||||
const joined = wide.join("\n");
|
const joined = wide.join("\n");
|
||||||
assert.match(joined, /italics|dim|bold/);
|
assert.match(joined, /italics|dim|bold/);
|
||||||
assert.match(joined, /入 |出 |缓 |窗 /);
|
assert.match(joined, /\bi |\bo |\bc |ctx /);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user