rinco-pi-hud 1.4.0 → 1.5.0

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/README.md CHANGED
@@ -98,6 +98,8 @@ Variables accept `$name` or `${name}`. The [footer reference](docs/footer.md) li
98
98
 
99
99
  `/zentui` writes to `~/.pi/agent/rinco-pi-hud.json` and applies changes immediately. It covers the separator style, icon mode (`nerd`, `ascii`, or `auto`), footer colors (Pi theme tokens or terminal palette styles), context rendering (text, gauge, or both), the project refresh interval, and third-party extension statuses with their own placement and color mode.
100
100
 
101
+ Footer colors follow the active Pi theme by default, including theme switches and automatic light/dark changes. In `/zentui`, **Footer colors → theme** enables this behavior; **terminal** keeps the original Sakura RGB palette. Explicit custom colors (hex, indexed, or `fg:`/`bg:` styles) remain fixed in either mode. Remove those entries from `colors` to restore automatic theme colors.
102
+
101
103
  See [docs/footer.md](docs/footer.md) for the full variable and segment reference.
102
104
 
103
105
  ## Project contents
@@ -156,7 +158,7 @@ The footer measures the terminal and wraps at segment boundaries, so narrow wind
156
158
  <details>
157
159
  <summary>Colors look incorrect</summary>
158
160
 
159
- The default RGB palette follows Pi's detected terminal color mode, with 256-color approximation when needed. Check terminal capability settings and try the theme color source in `/zentui`.
161
+ The default palette follows the active Pi theme. If the footer still uses fixed colors, select **Footer colors → theme** in `/zentui` and remove explicit color overrides from `~/.pi/agent/rinco-pi-hud.json`. Third-party statuses set to `original` retain their own colors. Truecolor and 256-color output follow Pi's detected terminal capabilities.
160
162
  </details>
161
163
 
162
164
  <details>
@@ -98,6 +98,8 @@ Usage 行跟随当前模型的 Provider:
98
98
 
99
99
  `/zentui` 把配置写入 `~/.pi/agent/rinco-pi-hud.json`,改动立即生效。可配置分隔符样式、图标模式(`nerd`、`ascii`、`auto`)、脚注配色(Pi 主题色或终端调色板样式)、Context 渲染方式(文本、进度条或两者)、项目刷新间隔,以及第三方扩展状态的位置与颜色模式。
100
100
 
101
+ 脚注默认自动跟随当前 Pi 主题,包括手动切换主题和自动明暗切换。在 `/zentui` 中选择 **Footer colors → theme** 启用跟随,选择 **terminal** 则保留原有 Sakura RGB 配色。显式自定义颜色(十六进制、索引色或 `fg:`/`bg:` 样式)在两种模式下都会保留;删除 `colors` 中的相应配置即可恢复自动配色。
102
+
101
103
  完整的变量与状态段参考见 [docs/footer.md](footer.md)。
102
104
 
103
105
  ## 仓库结构
@@ -156,7 +158,7 @@ npx tsx assets/readme/source/build-assets.mts /tmp/footer.json
156
158
  <details>
157
159
  <summary>颜色显示异常</summary>
158
160
 
159
- 默认 RGB 配色跟随 Pi 检测到的终端颜色模式,必要时近似为 256 色。请检查终端能力配置,也可以在 `/zentui` 中切换到主题色源。
161
+ 默认配色自动跟随当前 Pi 主题。如果脚注仍使用固定颜色,请在 `/zentui` 中选择 **Footer colors → theme**,并删除 `~/.pi/agent/rinco-pi-hud.json` 中的显式颜色覆盖。设为 `original` 的第三方扩展状态会保留自己的颜色。Truecolor 与 256 色输出仍按 Pi 检测到的终端能力选择。
160
162
  </details>
161
163
 
162
164
  <details>
package/docs/footer.md CHANGED
@@ -26,6 +26,24 @@ Control each default-layout row independently:
26
26
 
27
27
  The command shape is `/zentui row <project|session|activity|usage> <enable|disable|toggle>`. Values persist under `footerRows`; all four default to `true`. Row switches apply only to the default layout and do not alter a custom single-line `footerFormat`.
28
28
 
29
+ ## Colors and theme switching
30
+
31
+ By default, `colorSources.starship` is `"theme"`. Built-in footer colors use semantic Pi theme tokens such as `accent`, `muted`, `success`, `warning`, and `error`; runtime labels also use the active theme. Switching themes, including automatic light/dark switching, recolors the footer without reloading the extension. This applies to both the default rows and custom templates.
32
+
33
+ To enable theme colors in an existing configuration, use **Footer colors → theme** in `/zentui`, or set:
34
+
35
+ ```json
36
+ {
37
+ "colorSources": {
38
+ "starship": "theme"
39
+ }
40
+ }
41
+ ```
42
+
43
+ Select `"terminal"` to retain the original Sakura RGB defaults and Starship runtime colors. Changing the source does not write a palette into your configuration.
44
+
45
+ Entries you explicitly set under `colors` override the selected defaults. Semantic tokens (for example, `"cwd": "bold accent"`) follow the theme; hex colors, indexed colors, and explicit `fg:`/`bg:` styles remain fixed. Remove an override to restore the default for that segment. Third-party extension statuses in `original` color mode retain their own ANSI colors; use `zentui` color mode to recolor them with the HUD.
46
+
29
47
  ## Built-in status segments
30
48
 
31
49
  | Key | Default | Group | Description |
@@ -92,7 +92,7 @@ const colorSettingLabels: Record<ColorSettingId, string> = {
92
92
 
93
93
  const colorSettingDescriptions: Record<ColorSettingId, string> = {
94
94
  starship:
95
- "Choose whether footer runtime/git/context colors use Pi theme tokens or terminal palette styles.",
95
+ "Follow the active Pi theme automatically (theme), or keep the original Sakura/runtime palette (terminal). Explicit color overrides are preserved.",
96
96
  };
97
97
 
98
98
  const featureSettingLabels: Record<FeatureSettingId, string> = {
@@ -34,6 +34,7 @@ import {
34
34
  type PathDisplayConfig,
35
35
  type PolishedTuiConfig,
36
36
  type SeparatorStyle,
37
+ terminalDefaultColors,
37
38
  type UiFeaturesConfig,
38
39
  } from "./schema.js";
39
40
 
@@ -374,7 +375,7 @@ export function mergeConfig(parsed: unknown): PolishedTuiConfig {
374
375
  gitBranch,
375
376
  icons: resolveConfiguredIcons(iconMode, iconOverrides),
376
377
  colors: {
377
- ...defaultConfig.colors,
378
+ ...(colorSources.starship === "terminal" ? terminalDefaultColors : defaultConfig.colors),
378
379
  ...colors,
379
380
  },
380
381
  colorSources: { ...colorSources },
@@ -226,6 +226,30 @@ export const FOOTER_FORMAT_ALIASES: Record<string, string> = {
226
226
 
227
227
  export const configPath = join(getAgentDir(), "rinco-pi-hud.json");
228
228
 
229
+ /** Preserve the original Sakura palette for users who explicitly select terminal colors. */
230
+ export const terminalDefaultColors: PolishedTuiConfig["colors"] = {
231
+ cwd: "bold #F2A7C6",
232
+ gitBranch: "bold #C7B8F5",
233
+ gitStatus: "bold #F6BC9A",
234
+ contextNormal: "#AEE5C5",
235
+ contextWarning: "bold #F3D98B",
236
+ contextError: "bold #FF8FA3",
237
+ tokens: "#A99BAE",
238
+ cost: "bold #AEE5C5",
239
+ separator: "#716879",
240
+ runtimePrefix: "#9FD3F2",
241
+ extensionStatus: "#EFC3E6",
242
+ sessionDuration: "#F3D98B",
243
+ packageVersion: "#F6BC9A",
244
+ gitCommit: "#AEE5C5",
245
+ gitMetricsAdded: "#AEE5C5",
246
+ gitMetricsDeleted: "#FF8FA3",
247
+ username: "#F3D98B",
248
+ time: "#F3D98B",
249
+ os: "#F7EEF8",
250
+ muted: "#A99BAE",
251
+ };
252
+
229
253
  export const defaultConfig: PolishedTuiConfig = {
230
254
  projectRefreshIntervalMs: DEFAULT_PROJECT_REFRESH_INTERVAL_MS,
231
255
  footerFormat: "",
@@ -239,29 +263,29 @@ export const defaultConfig: PolishedTuiConfig = {
239
263
  ...NERD_DEFAULT_ICONS,
240
264
  },
241
265
  colors: {
242
- cwd: "bold #F2A7C6",
243
- gitBranch: "bold #C7B8F5",
244
- gitStatus: "bold #F6BC9A",
245
- contextNormal: "#AEE5C5",
246
- contextWarning: "bold #F3D98B",
247
- contextError: "bold #FF8FA3",
248
- tokens: "#A99BAE",
249
- cost: "bold #AEE5C5",
250
- separator: "#716879",
251
- runtimePrefix: "#9FD3F2",
252
- extensionStatus: "#EFC3E6",
253
- sessionDuration: "#F3D98B",
254
- packageVersion: "#F6BC9A",
255
- gitCommit: "#AEE5C5",
256
- gitMetricsAdded: "#AEE5C5",
257
- gitMetricsDeleted: "#FF8FA3",
258
- username: "#F3D98B",
259
- time: "#F3D98B",
260
- os: "#F7EEF8",
261
- muted: "#A99BAE",
266
+ cwd: "bold accent",
267
+ gitBranch: "bold syntaxVariable",
268
+ gitStatus: "bold warning",
269
+ contextNormal: "success",
270
+ contextWarning: "bold warning",
271
+ contextError: "bold error",
272
+ tokens: "muted",
273
+ cost: "bold success",
274
+ separator: "dim",
275
+ runtimePrefix: "syntaxFunction",
276
+ extensionStatus: "customMessageLabel",
277
+ sessionDuration: "syntaxNumber",
278
+ packageVersion: "syntaxType",
279
+ gitCommit: "success",
280
+ gitMetricsAdded: "toolDiffAdded",
281
+ gitMetricsDeleted: "toolDiffRemoved",
282
+ username: "syntaxNumber",
283
+ time: "syntaxNumber",
284
+ os: "text",
285
+ muted: "muted",
262
286
  },
263
287
  colorSources: {
264
- starship: "terminal",
288
+ starship: "theme",
265
289
  },
266
290
  features: {
267
291
  statusLine: true,
@@ -26,10 +26,10 @@ import {
26
26
  formatOsLabel,
27
27
  formatPackageVersionSegment,
28
28
  formatRuntimeSegment,
29
+ formatRuntimeValue,
29
30
  formatTimeLabel,
30
31
  formatUsernameHostLabel,
31
32
  } from "../telemetry/format.js";
32
- import { resolveRuntimeSymbol } from "../ui/icons.js";
33
33
  import type { LiveContextOverride } from "../session/live-context.js";
34
34
  import type { FooterState } from "../state/index.js";
35
35
  import { renderStyleForSource } from "../ui/style.js";
@@ -180,12 +180,8 @@ export function installFooter(
180
180
  return statusBlock;
181
181
  case "git_state":
182
182
  return gitStateBlock;
183
- case "runtime": {
184
- if (!safeRuntime) return "";
185
- const symbol = resolveRuntimeSymbol(safeRuntime.name, safeRuntime.symbol, iconMode);
186
- const label = safeRuntime.version ? `${symbol} ${safeRuntime.version}` : symbol;
187
- return renderStyleForSource(theme, colorSource, safeRuntime.style, label);
188
- }
183
+ case "runtime":
184
+ return formatRuntimeValue(theme, safeRuntime, colorSource, iconMode);
189
185
  case "session_duration":
190
186
  return state.sessionStartEpoch
191
187
  ? renderStyleForSource(
@@ -13,6 +13,7 @@ import { truncateToWidth } from "@earendil-works/pi-tui";
13
13
  import type { ColorSource, PolishedTuiConfig } from "../config/config.js";
14
14
  import { formatSkillCounts } from "../segments/skill-activity.js";
15
15
  import type { FooterState } from "../state/index.js";
16
+ import type { RuntimeInfo } from "../segments/runtime.js";
16
17
  import { getTelemetryStats } from "../state/telemetry.js";
17
18
  import { buildSessionDurationLabel, formatCount } from "../telemetry/format.js";
18
19
  import { renderStyleForSource, type ThemeLike } from "../ui/style.js";
@@ -25,8 +26,7 @@ export function safeStatusText(value: string | null | undefined, maxLength = 256
25
26
 
26
27
  export type SanitizedFooterInputs = {
27
28
  safeCwd: string;
28
- safeRuntime:
29
- { name: string; symbol: string; style: string; version: string | undefined } | undefined;
29
+ safeRuntime: RuntimeInfo | undefined;
30
30
  safePackageVersion: { ecosystem: string; version: string } | undefined;
31
31
  safeCommit: { oid: string | null; detached: boolean; tag: string | null } | undefined;
32
32
  };
@@ -240,6 +240,7 @@ const runtimes: RuntimeDef[] = [
240
240
  name: "php",
241
241
  symbol: "",
242
242
  style: "147 bold",
243
+ themeStyle: "bold syntaxVariable",
243
244
  priority: PRIORITY_COMMON,
244
245
  detect: { files: ["composer.json"] },
245
246
  version: async () =>
@@ -265,6 +266,7 @@ const runtimes: RuntimeDef[] = [
265
266
  name: "cpp",
266
267
  symbol: "",
267
268
  style: "bold 149",
269
+ themeStyle: "bold success",
268
270
  priority: PRIORITY_DEFAULT,
269
271
  detect: { extensions: ["cpp", "cc", "cxx", "c++", "hpp", "hh", "hxx", "h++", "tcc"] },
270
272
  version: versionFromCommands([
@@ -277,6 +279,7 @@ const runtimes: RuntimeDef[] = [
277
279
  name: "c",
278
280
  symbol: "",
279
281
  style: "bold 149",
282
+ themeStyle: "bold success",
280
283
  priority: PRIORITY_DEFAULT,
281
284
  detect: { extensions: ["c", "h"] },
282
285
  version: versionFromCommands([
@@ -414,6 +417,7 @@ const runtimes: RuntimeDef[] = [
414
417
  name: "gleam",
415
418
  symbol: "",
416
419
  style: "bold #FFAFF3",
420
+ themeStyle: "bold syntaxKeyword",
417
421
  priority: PRIORITY_DEFAULT,
418
422
  detect: { extensions: ["gleam"], files: ["gleam.toml"] },
419
423
  version: versionFromCommands([{ command: "gleam", args: ["--version"] }]),
@@ -438,6 +442,7 @@ const runtimes: RuntimeDef[] = [
438
442
  name: "haxe",
439
443
  symbol: "",
440
444
  style: "bold fg:202",
445
+ themeStyle: "bold syntaxType",
441
446
  priority: PRIORITY_DEFAULT,
442
447
  detect: {
443
448
  extensions: ["hx", "hxml"],
@@ -482,6 +487,7 @@ const runtimes: RuntimeDef[] = [
482
487
  name: "mojo",
483
488
  symbol: "󰈸",
484
489
  style: "bold 208",
490
+ themeStyle: "bold syntaxType",
485
491
  priority: PRIORITY_DEFAULT,
486
492
  detect: { extensions: ["mojo", "🔥"] },
487
493
  version: versionFromCommands([{ command: "mojo", args: ["--version"] }]),
@@ -534,6 +540,7 @@ const runtimes: RuntimeDef[] = [
534
540
  name: "perl",
535
541
  symbol: "",
536
542
  style: "bold 149",
543
+ themeStyle: "bold success",
537
544
  priority: PRIORITY_DEFAULT,
538
545
  detect: {
539
546
  extensions: ["pl", "pm", "pod"],
@@ -564,6 +571,7 @@ const runtimes: RuntimeDef[] = [
564
571
  name: "pulumi",
565
572
  symbol: "",
566
573
  style: "bold 5",
574
+ themeStyle: "bold syntaxKeyword",
567
575
  priority: PRIORITY_DEFAULT,
568
576
  detect: { files: ["Pulumi.yaml", "Pulumi.yml"] },
569
577
  version: versionFromCommands([{ command: "pulumi", args: ["version"] }]),
@@ -580,6 +588,7 @@ const runtimes: RuntimeDef[] = [
580
588
  name: "raku",
581
589
  symbol: "󱖊",
582
590
  style: "bold 149",
591
+ themeStyle: "bold success",
583
592
  priority: PRIORITY_DEFAULT,
584
593
  detect: { extensions: ["p6", "pm6", "pod6", "raku", "rakumod"], files: ["META6.json"] },
585
594
  version: versionFromCommands([{ command: "raku", args: ["--version"] }]),
@@ -636,6 +645,7 @@ const runtimes: RuntimeDef[] = [
636
645
  name: "swift",
637
646
  symbol: "",
638
647
  style: "bold 202",
648
+ themeStyle: "bold syntaxType",
639
649
  priority: PRIORITY_DEFAULT,
640
650
  detect: { extensions: ["swift"], files: ["Package.swift"] },
641
651
  version: versionFromCommands([
@@ -646,6 +656,7 @@ const runtimes: RuntimeDef[] = [
646
656
  name: "terraform",
647
657
  symbol: "",
648
658
  style: "bold 105",
659
+ themeStyle: "bold syntaxVariable",
649
660
  priority: PRIORITY_DEFAULT,
650
661
  detect: { extensions: ["tf", "tfplan", "tfstate"], folders: [".terraform"] },
651
662
  version: versionFromCommands([
@@ -657,6 +668,7 @@ const runtimes: RuntimeDef[] = [
657
668
  name: "typst",
658
669
  symbol: "",
659
670
  style: "bold #0093A7",
671
+ themeStyle: "bold syntaxFunction",
660
672
  priority: PRIORITY_DEFAULT,
661
673
  detect: { extensions: ["typ"], files: ["template.typ"] },
662
674
  version: versionFromCommands([{ command: "typst", args: ["--version"] }]),
@@ -7,9 +7,11 @@ export type RuntimeMetadata = {
7
7
  name: string;
8
8
  symbol: string;
9
9
  style: string;
10
+ /** Semantic alternative for built-in RGB/indexed terminal styles. */
11
+ themeStyle?: string;
10
12
  };
11
13
 
12
- export type RuntimeInfo = Pick<RuntimeMetadata, "name" | "symbol" | "style"> & {
14
+ export type RuntimeInfo = RuntimeMetadata & {
13
15
  version?: string;
14
16
  };
15
17
 
@@ -114,10 +116,11 @@ function matchesDetection(
114
116
  const sortedRuntimes = runtimeDefinitions;
115
117
 
116
118
  export const runtimeMetadata: RuntimeMetadata[] = runtimeDefinitions.map(
117
- ({ name, symbol, style }) => ({
119
+ ({ name, symbol, style, themeStyle }) => ({
118
120
  name,
119
121
  symbol,
120
122
  style,
123
+ themeStyle,
121
124
  }),
122
125
  );
123
126
 
@@ -170,6 +173,7 @@ export async function readRuntimeInfo(cwd: string): Promise<RuntimeReadResult> {
170
173
  name: runtime.name,
171
174
  symbol: runtime.symbol,
172
175
  style: runtime.style,
176
+ themeStyle: runtime.themeStyle,
173
177
  version: await runtime.version(cwd),
174
178
  },
175
179
  };
@@ -304,17 +304,29 @@ export function buildContextLabel(ctx: ExtensionContext): string {
304
304
  return formatContextPercentLabel(usage?.percent, contextWindow);
305
305
  }
306
306
 
307
- export function formatRuntimeSegment(
307
+ /** Render just the runtime value for both default rows and custom templates. */
308
+ export function formatRuntimeValue(
308
309
  theme: Pick<Theme, "fg">,
309
310
  runtime: RuntimeInfo | undefined,
310
- prefixStyle: ColorSpec,
311
311
  colorSource: ColorSource,
312
312
  mode: IconMode = "auto",
313
313
  ): string {
314
314
  if (!runtime) return "";
315
315
  const symbol = resolveRuntimeSymbol(runtime.name, runtime.symbol, mode);
316
316
  const label = runtime.version ? `${symbol} ${runtime.version}` : symbol;
317
- return `${renderStyleForSource(theme, colorSource, prefixStyle, "via")} ${renderStyleForSource(theme, colorSource, runtime.style, label)}`;
317
+ const style = colorSource === "theme" ? (runtime.themeStyle ?? runtime.style) : runtime.style;
318
+ return renderStyleForSource(theme, colorSource, style, label);
319
+ }
320
+
321
+ export function formatRuntimeSegment(
322
+ theme: Pick<Theme, "fg">,
323
+ runtime: RuntimeInfo | undefined,
324
+ prefixStyle: ColorSpec,
325
+ colorSource: ColorSource,
326
+ mode: IconMode = "auto",
327
+ ): string {
328
+ if (!runtime) return "";
329
+ return `${renderStyleForSource(theme, colorSource, prefixStyle, "via")} ${formatRuntimeValue(theme, runtime, colorSource, mode)}`;
318
330
  }
319
331
 
320
332
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rinco-pi-hud",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "A dynamic HUD footer for Pi, ported from Sakura Zentui Footer.",
5
5
  "type": "module",
6
6
  "license": "MIT",