rinco-pi-hud 1.0.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/LICENSE +21 -0
- package/NOTICE +18 -0
- package/README.md +204 -0
- package/docs/CONTRIBUTING.md +110 -0
- package/docs/README.zh-CN.md +204 -0
- package/docs/footer.md +139 -0
- package/extensions/hud/commands/settings.ts +765 -0
- package/extensions/hud/config/config-counts.ts +87 -0
- package/extensions/hud/config/config.ts +65 -0
- package/extensions/hud/config/file-io.ts +128 -0
- package/extensions/hud/config/normalize.ts +374 -0
- package/extensions/hud/config/persist.ts +277 -0
- package/extensions/hud/config/schema.ts +303 -0
- package/extensions/hud/footer/format.ts +279 -0
- package/extensions/hud/footer/index.ts +543 -0
- package/extensions/hud/footer/layout.ts +183 -0
- package/extensions/hud/footer/render-labels.ts +305 -0
- package/extensions/hud/index.ts +466 -0
- package/extensions/hud/segments/extension-status.ts +88 -0
- package/extensions/hud/segments/git.ts +384 -0
- package/extensions/hud/segments/mcp-status.ts +25 -0
- package/extensions/hud/segments/package-version.ts +651 -0
- package/extensions/hud/segments/project-state.ts +67 -0
- package/extensions/hud/segments/runtime-definitions.ts +695 -0
- package/extensions/hud/segments/runtime.ts +167 -0
- package/extensions/hud/segments/skill-activity.ts +152 -0
- package/extensions/hud/session/context.ts +19 -0
- package/extensions/hud/session/lifecycle.ts +60 -0
- package/extensions/hud/session/live-context.ts +75 -0
- package/extensions/hud/state/index.ts +67 -0
- package/extensions/hud/state/project-refresh.ts +104 -0
- package/extensions/hud/state/telemetry.ts +261 -0
- package/extensions/hud/telemetry/codex-usage/LICENSE +21 -0
- package/extensions/hud/telemetry/codex-usage/app-server-client.ts +231 -0
- package/extensions/hud/telemetry/codex-usage/format.ts +278 -0
- package/extensions/hud/telemetry/codex-usage/index.ts +462 -0
- package/extensions/hud/telemetry/codex-usage/normalize.ts +264 -0
- package/extensions/hud/telemetry/codex-usage/query.ts +207 -0
- package/extensions/hud/telemetry/codex-usage/safety.ts +27 -0
- package/extensions/hud/telemetry/codex-usage/types.ts +137 -0
- package/extensions/hud/telemetry/format.ts +434 -0
- package/extensions/hud/telemetry/token-switch.ts +114 -0
- package/extensions/hud/ui/icons.ts +239 -0
- package/extensions/hud/ui/style.ts +276 -0
- package/package.json +56 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `save*Patch` functions: validate a partial settings patch, merge it into
|
|
3
|
+
* the on-disk config record via `mutateConfig`, and return the freshly
|
|
4
|
+
* merged `PolishedTuiConfig`. Each function only accepts fields/values that
|
|
5
|
+
* pass the corresponding type guard, so callers (e.g. the `/zentui` settings
|
|
6
|
+
* UI) cannot write malformed values into the config file.
|
|
7
|
+
*/
|
|
8
|
+
import { normalizeIconMode } from "../ui/icons.js";
|
|
9
|
+
import { mutateConfig } from "./file-io.js";
|
|
10
|
+
import {
|
|
11
|
+
isExtensionStatusColorMode,
|
|
12
|
+
isExtensionStatusPlacement,
|
|
13
|
+
isRecord,
|
|
14
|
+
normalizeGitBranchMaxLength,
|
|
15
|
+
parseContextStyle,
|
|
16
|
+
parseSeparatorStyle,
|
|
17
|
+
sanitizeConfigText,
|
|
18
|
+
} from "./normalize.js";
|
|
19
|
+
import {
|
|
20
|
+
configPath,
|
|
21
|
+
type ColorSource,
|
|
22
|
+
type ColorSourcesConfig,
|
|
23
|
+
type ContextStyle,
|
|
24
|
+
type ContextThresholds,
|
|
25
|
+
type ExtensionStatusColorMode,
|
|
26
|
+
type ExtensionStatusPlacement,
|
|
27
|
+
type FooterSegmentsConfig,
|
|
28
|
+
type GitBranchConfig,
|
|
29
|
+
type IconMode,
|
|
30
|
+
type PathDisplayConfig,
|
|
31
|
+
type PolishedTuiConfig,
|
|
32
|
+
type SeparatorStyle,
|
|
33
|
+
type UiFeaturesConfig,
|
|
34
|
+
} from "./schema.js";
|
|
35
|
+
|
|
36
|
+
function isColorSourceKey(value: string): value is keyof ColorSourcesConfig {
|
|
37
|
+
return value === "starship";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isUiFeatureKey(value: string): value is keyof UiFeaturesConfig {
|
|
41
|
+
return value === "statusLine";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isFooterSegmentKey(value: string): value is keyof FooterSegmentsConfig {
|
|
45
|
+
return (
|
|
46
|
+
value === "cwd" ||
|
|
47
|
+
value === "gitBranch" ||
|
|
48
|
+
value === "gitStatus" ||
|
|
49
|
+
value === "gitCounts" ||
|
|
50
|
+
value === "runtime" ||
|
|
51
|
+
value === "context" ||
|
|
52
|
+
value === "tokens" ||
|
|
53
|
+
value === "cost" ||
|
|
54
|
+
value === "sessionDuration" ||
|
|
55
|
+
value === "username" ||
|
|
56
|
+
value === "time" ||
|
|
57
|
+
value === "os" ||
|
|
58
|
+
value === "packageVersion" ||
|
|
59
|
+
value === "gitCommit" ||
|
|
60
|
+
value === "gitMetrics" ||
|
|
61
|
+
value === "sessionName" ||
|
|
62
|
+
value === "model" ||
|
|
63
|
+
value === "thinking" ||
|
|
64
|
+
value === "turnCount" ||
|
|
65
|
+
value === "cacheDetails" ||
|
|
66
|
+
value === "codexUsage" ||
|
|
67
|
+
value === "configCounts" ||
|
|
68
|
+
value === "skills" ||
|
|
69
|
+
value === "mcp" ||
|
|
70
|
+
value === "toolActivity" ||
|
|
71
|
+
value === "agentActivity"
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function validColorSourceEntries(record: Record<string, unknown>): Partial<ColorSourcesConfig> {
|
|
76
|
+
return Object.fromEntries(
|
|
77
|
+
Object.entries(record).filter((entry): entry is [keyof ColorSourcesConfig, ColorSource] => {
|
|
78
|
+
const [key, value] = entry;
|
|
79
|
+
return isColorSourceKey(key) && (value === "theme" || value === "terminal");
|
|
80
|
+
}),
|
|
81
|
+
) as Partial<ColorSourcesConfig>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function validUiFeatureEntries(record: Record<string, unknown>): Partial<UiFeaturesConfig> {
|
|
85
|
+
return Object.fromEntries(
|
|
86
|
+
Object.entries(record).filter((entry): entry is [keyof UiFeaturesConfig, boolean] => {
|
|
87
|
+
const [key, value] = entry;
|
|
88
|
+
return isUiFeatureKey(key) && typeof value === "boolean";
|
|
89
|
+
}),
|
|
90
|
+
) as Partial<UiFeaturesConfig>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function validFooterSegmentEntries(record: Record<string, unknown>): Partial<FooterSegmentsConfig> {
|
|
94
|
+
return Object.fromEntries(
|
|
95
|
+
Object.entries(record).filter((entry): entry is [keyof FooterSegmentsConfig, boolean] => {
|
|
96
|
+
const [key, value] = entry;
|
|
97
|
+
return isFooterSegmentKey(key) && typeof value === "boolean";
|
|
98
|
+
}),
|
|
99
|
+
) as Partial<FooterSegmentsConfig>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function saveColorSourcesPatch(
|
|
103
|
+
patch: Partial<ColorSourcesConfig>,
|
|
104
|
+
path = configPath,
|
|
105
|
+
): PolishedTuiConfig {
|
|
106
|
+
return mutateConfig(path, (record) => {
|
|
107
|
+
const existing = isRecord(record.colorSources)
|
|
108
|
+
? { ...(record.colorSources as Record<string, unknown>) }
|
|
109
|
+
: {};
|
|
110
|
+
record.colorSources = {
|
|
111
|
+
...existing,
|
|
112
|
+
...validColorSourceEntries(patch),
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function saveUiFeaturesPatch(
|
|
118
|
+
patch: Partial<UiFeaturesConfig>,
|
|
119
|
+
path = configPath,
|
|
120
|
+
): PolishedTuiConfig {
|
|
121
|
+
return mutateConfig(path, (record) => {
|
|
122
|
+
const existing = isRecord(record.features)
|
|
123
|
+
? { ...(record.features as Record<string, unknown>) }
|
|
124
|
+
: {};
|
|
125
|
+
record.features = {
|
|
126
|
+
...existing,
|
|
127
|
+
...validUiFeatureEntries(patch),
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function saveFooterSegmentsPatch(
|
|
133
|
+
patch: Partial<FooterSegmentsConfig>,
|
|
134
|
+
path = configPath,
|
|
135
|
+
): PolishedTuiConfig {
|
|
136
|
+
return mutateConfig(path, (record) => {
|
|
137
|
+
const existing = isRecord(record.footerSegments)
|
|
138
|
+
? { ...(record.footerSegments as Record<string, unknown>) }
|
|
139
|
+
: {};
|
|
140
|
+
record.footerSegments = {
|
|
141
|
+
...existing,
|
|
142
|
+
...validFooterSegmentEntries(patch),
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function saveFooterFormatPatch(value: string, path = configPath): PolishedTuiConfig {
|
|
148
|
+
return mutateConfig(path, (record) => {
|
|
149
|
+
record.footerFormat = typeof value === "string" ? sanitizeConfigText(value, 4096) : "";
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function saveIconsModePatch(mode: IconMode, path = configPath): PolishedTuiConfig {
|
|
154
|
+
return mutateConfig(path, (record) => {
|
|
155
|
+
const existing = isRecord(record.icons) ? { ...(record.icons as Record<string, unknown>) } : {};
|
|
156
|
+
record.icons = {
|
|
157
|
+
...existing,
|
|
158
|
+
mode: normalizeIconMode(mode),
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function saveContextStylePatch(style: ContextStyle, path = configPath): PolishedTuiConfig {
|
|
164
|
+
return mutateConfig(path, (record) => {
|
|
165
|
+
record.contextStyle = parseContextStyle(style);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function saveSeparatorPatch(
|
|
170
|
+
separator: SeparatorStyle,
|
|
171
|
+
path = configPath,
|
|
172
|
+
): PolishedTuiConfig {
|
|
173
|
+
return mutateConfig(path, (record) => {
|
|
174
|
+
record.separator = parseSeparatorStyle(separator);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function saveContextThresholdsPatch(
|
|
179
|
+
thresholds: Partial<ContextThresholds>,
|
|
180
|
+
path = configPath,
|
|
181
|
+
): PolishedTuiConfig {
|
|
182
|
+
return mutateConfig(path, (record) => {
|
|
183
|
+
const existing = isRecord(record.contextThresholds)
|
|
184
|
+
? { ...(record.contextThresholds as Record<string, unknown>) }
|
|
185
|
+
: {};
|
|
186
|
+
record.contextThresholds = {
|
|
187
|
+
...existing,
|
|
188
|
+
...thresholds,
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function savePathDisplayPatch(
|
|
194
|
+
patch: Partial<PathDisplayConfig>,
|
|
195
|
+
path = configPath,
|
|
196
|
+
): PolishedTuiConfig {
|
|
197
|
+
return mutateConfig(path, (record) => {
|
|
198
|
+
const existing = isRecord(record.pathDisplay)
|
|
199
|
+
? { ...(record.pathDisplay as Record<string, unknown>) }
|
|
200
|
+
: {};
|
|
201
|
+
if (patch.mode !== undefined) existing.mode = patch.mode;
|
|
202
|
+
if (patch.depth !== undefined) existing.depth = patch.depth;
|
|
203
|
+
record.pathDisplay = existing;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function saveGitBranchPatch(
|
|
208
|
+
patch: Partial<GitBranchConfig>,
|
|
209
|
+
path = configPath,
|
|
210
|
+
): PolishedTuiConfig {
|
|
211
|
+
return mutateConfig(path, (record) => {
|
|
212
|
+
const existing = isRecord(record.gitBranch)
|
|
213
|
+
? { ...(record.gitBranch as Record<string, unknown>) }
|
|
214
|
+
: {};
|
|
215
|
+
if (patch.maxLength !== undefined)
|
|
216
|
+
existing.maxLength = normalizeGitBranchMaxLength(patch.maxLength);
|
|
217
|
+
record.gitBranch = existing;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function saveExtensionStatusPlacement(
|
|
222
|
+
key: string,
|
|
223
|
+
placement: ExtensionStatusPlacement,
|
|
224
|
+
path = configPath,
|
|
225
|
+
): PolishedTuiConfig {
|
|
226
|
+
return mutateConfig(path, (record) => {
|
|
227
|
+
const existingExtensionStatuses = isRecord(record.extensionStatuses)
|
|
228
|
+
? { ...(record.extensionStatuses as Record<string, unknown>) }
|
|
229
|
+
: {};
|
|
230
|
+
const existingPlacements = isRecord(existingExtensionStatuses.placements)
|
|
231
|
+
? { ...(existingExtensionStatuses.placements as Record<string, unknown>) }
|
|
232
|
+
: {};
|
|
233
|
+
|
|
234
|
+
if (!isExtensionStatusPlacement(placement)) return;
|
|
235
|
+
|
|
236
|
+
Object.defineProperty(existingPlacements, key, {
|
|
237
|
+
value: placement,
|
|
238
|
+
enumerable: true,
|
|
239
|
+
configurable: true,
|
|
240
|
+
writable: true,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
record.extensionStatuses = {
|
|
244
|
+
...existingExtensionStatuses,
|
|
245
|
+
placements: existingPlacements,
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export function saveExtensionStatusColorMode(
|
|
251
|
+
key: string,
|
|
252
|
+
colorMode: ExtensionStatusColorMode,
|
|
253
|
+
path = configPath,
|
|
254
|
+
): PolishedTuiConfig {
|
|
255
|
+
return mutateConfig(path, (record) => {
|
|
256
|
+
const existingExtensionStatuses = isRecord(record.extensionStatuses)
|
|
257
|
+
? { ...(record.extensionStatuses as Record<string, unknown>) }
|
|
258
|
+
: {};
|
|
259
|
+
const existingColorModes = isRecord(existingExtensionStatuses.colorModes)
|
|
260
|
+
? { ...(existingExtensionStatuses.colorModes as Record<string, unknown>) }
|
|
261
|
+
: {};
|
|
262
|
+
|
|
263
|
+
if (!isExtensionStatusColorMode(colorMode)) return;
|
|
264
|
+
|
|
265
|
+
Object.defineProperty(existingColorModes, key, {
|
|
266
|
+
value: colorMode,
|
|
267
|
+
enumerable: true,
|
|
268
|
+
configurable: true,
|
|
269
|
+
writable: true,
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
record.extensionStatuses = {
|
|
273
|
+
...existingExtensionStatuses,
|
|
274
|
+
colorModes: existingColorModes,
|
|
275
|
+
};
|
|
276
|
+
});
|
|
277
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zentui config schema: types, format-string vocabulary, and defaults.
|
|
3
|
+
*
|
|
4
|
+
* Pure data/types module — no file I/O, no normalization logic. Parsing
|
|
5
|
+
* untrusted JSON into this shape lives in `normalize.ts`; reading/writing the
|
|
6
|
+
* config file lives in `file-io.ts`.
|
|
7
|
+
*/
|
|
8
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { NERD_DEFAULT_ICONS, type ResolvedIcons } from "../ui/icons.js";
|
|
11
|
+
|
|
12
|
+
export type ColorSpec = string;
|
|
13
|
+
export type ColorSource = "theme" | "terminal";
|
|
14
|
+
export type { IconMode } from "../ui/icons.js";
|
|
15
|
+
|
|
16
|
+
export type ContextStyle = "text" | "gauge" | "text+gauge";
|
|
17
|
+
export type SeparatorStyle = "pipe" | "dot" | "chevron" | "none";
|
|
18
|
+
|
|
19
|
+
export type ContextThresholds = {
|
|
20
|
+
warning: number;
|
|
21
|
+
error: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type PathDisplayMode = "basename" | "full";
|
|
25
|
+
|
|
26
|
+
export type PathDisplayConfig = {
|
|
27
|
+
mode: PathDisplayMode;
|
|
28
|
+
/** Trailing directories to show in full mode. 0 = unlimited; clamped to 0..5. */
|
|
29
|
+
depth: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type GitBranchMaxLength = "full" | number;
|
|
33
|
+
|
|
34
|
+
export type GitBranchConfig = {
|
|
35
|
+
maxLength: GitBranchMaxLength;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ColorSourcesConfig = {
|
|
39
|
+
starship: ColorSource;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type UiFeaturesConfig = {
|
|
43
|
+
statusLine: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type FooterSegmentsConfig = {
|
|
47
|
+
cwd: boolean;
|
|
48
|
+
gitBranch: boolean;
|
|
49
|
+
gitStatus: boolean;
|
|
50
|
+
gitCounts: boolean;
|
|
51
|
+
gitCommit: boolean;
|
|
52
|
+
gitMetrics: boolean;
|
|
53
|
+
runtime: boolean;
|
|
54
|
+
context: boolean;
|
|
55
|
+
tokens: boolean;
|
|
56
|
+
cost: boolean;
|
|
57
|
+
sessionDuration: boolean;
|
|
58
|
+
username: boolean;
|
|
59
|
+
time: boolean;
|
|
60
|
+
os: boolean;
|
|
61
|
+
packageVersion: boolean;
|
|
62
|
+
sessionName: boolean;
|
|
63
|
+
model: boolean;
|
|
64
|
+
thinking: boolean;
|
|
65
|
+
turnCount: boolean;
|
|
66
|
+
cacheDetails: boolean;
|
|
67
|
+
codexUsage: boolean;
|
|
68
|
+
configCounts: boolean;
|
|
69
|
+
skills: boolean;
|
|
70
|
+
mcp: boolean;
|
|
71
|
+
toolActivity: boolean;
|
|
72
|
+
agentActivity: boolean;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type ExtensionStatusPlacement = "off" | "left" | "middle" | "right";
|
|
76
|
+
export type ExtensionStatusColorMode = "zentui" | "original";
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Starship `git_commit`-style options.
|
|
80
|
+
* See https://starship.rs/config/#git-commit
|
|
81
|
+
*/
|
|
82
|
+
export type GitCommitConfig = {
|
|
83
|
+
hashLength: number;
|
|
84
|
+
onlyDetached: boolean;
|
|
85
|
+
showTag: boolean;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Starship `git_metrics`-style options.
|
|
90
|
+
* See https://starship.rs/config/#git-metrics
|
|
91
|
+
*/
|
|
92
|
+
export type GitMetricsConfig = {
|
|
93
|
+
onlyNonzero: boolean;
|
|
94
|
+
ignoreSubmodules: boolean;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const DEFAULT_EXTENSION_STATUS_COLOR_MODE: ExtensionStatusColorMode = "zentui";
|
|
98
|
+
|
|
99
|
+
export type ExtensionStatusesConfig = {
|
|
100
|
+
defaultPlacement: ExtensionStatusPlacement;
|
|
101
|
+
placements: Record<string, ExtensionStatusPlacement>;
|
|
102
|
+
colorModes: Record<string, ExtensionStatusColorMode>;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const DEFAULT_PROJECT_REFRESH_INTERVAL_MS = 30_000;
|
|
106
|
+
export const MIN_PROJECT_REFRESH_INTERVAL_MS = 5_000;
|
|
107
|
+
|
|
108
|
+
export type PolishedTuiConfig = {
|
|
109
|
+
projectRefreshIntervalMs: number;
|
|
110
|
+
footerFormat: string;
|
|
111
|
+
separator: SeparatorStyle;
|
|
112
|
+
contextStyle: ContextStyle;
|
|
113
|
+
contextThresholds: ContextThresholds;
|
|
114
|
+
pathDisplay: PathDisplayConfig;
|
|
115
|
+
gitBranch: GitBranchConfig;
|
|
116
|
+
icons: ResolvedIcons;
|
|
117
|
+
colors: {
|
|
118
|
+
cwd: ColorSpec;
|
|
119
|
+
gitBranch: ColorSpec;
|
|
120
|
+
gitStatus: ColorSpec;
|
|
121
|
+
contextNormal: ColorSpec;
|
|
122
|
+
contextWarning: ColorSpec;
|
|
123
|
+
contextError: ColorSpec;
|
|
124
|
+
tokens: ColorSpec;
|
|
125
|
+
cost: ColorSpec;
|
|
126
|
+
separator: ColorSpec;
|
|
127
|
+
runtimePrefix: ColorSpec;
|
|
128
|
+
extensionStatus: ColorSpec;
|
|
129
|
+
sessionDuration: ColorSpec;
|
|
130
|
+
packageVersion: ColorSpec;
|
|
131
|
+
gitCommit: ColorSpec;
|
|
132
|
+
gitMetricsAdded: ColorSpec;
|
|
133
|
+
gitMetricsDeleted: ColorSpec;
|
|
134
|
+
username: ColorSpec;
|
|
135
|
+
time: ColorSpec;
|
|
136
|
+
os: ColorSpec;
|
|
137
|
+
muted: ColorSpec;
|
|
138
|
+
};
|
|
139
|
+
colorSources: ColorSourcesConfig;
|
|
140
|
+
features: UiFeaturesConfig;
|
|
141
|
+
footerSegments: FooterSegmentsConfig;
|
|
142
|
+
gitCommit: GitCommitConfig;
|
|
143
|
+
gitMetrics: GitMetricsConfig;
|
|
144
|
+
extensionStatuses: ExtensionStatusesConfig;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Canonical footer format variable names. In a `footerFormat` string these
|
|
149
|
+
* are written as `$name` or `${name}`.
|
|
150
|
+
*/
|
|
151
|
+
export const FOOTER_FORMAT_VARIABLES = [
|
|
152
|
+
"cwd",
|
|
153
|
+
"git_branch",
|
|
154
|
+
"git_status",
|
|
155
|
+
"git_state",
|
|
156
|
+
"runtime",
|
|
157
|
+
"session_duration",
|
|
158
|
+
"username",
|
|
159
|
+
"os",
|
|
160
|
+
"time",
|
|
161
|
+
"context",
|
|
162
|
+
"tokens",
|
|
163
|
+
"cost",
|
|
164
|
+
"package",
|
|
165
|
+
"package_version",
|
|
166
|
+
"git_commit",
|
|
167
|
+
"git_tag",
|
|
168
|
+
"git_metrics",
|
|
169
|
+
"git_added",
|
|
170
|
+
"git_deleted",
|
|
171
|
+
"session_name",
|
|
172
|
+
"model",
|
|
173
|
+
"provider",
|
|
174
|
+
"model_id",
|
|
175
|
+
"thinking",
|
|
176
|
+
"turn",
|
|
177
|
+
"cache_read",
|
|
178
|
+
"cache_write",
|
|
179
|
+
"cache_hit",
|
|
180
|
+
"codex_usage",
|
|
181
|
+
"instruction_files",
|
|
182
|
+
"agents_files",
|
|
183
|
+
"claude_files",
|
|
184
|
+
"skills",
|
|
185
|
+
"active_skills",
|
|
186
|
+
"extensions",
|
|
187
|
+
"mcp",
|
|
188
|
+
"tool_counts",
|
|
189
|
+
"running_tools",
|
|
190
|
+
"active_agents",
|
|
191
|
+
"sep",
|
|
192
|
+
] as const;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Alias → canonical variable name mapping for `footerFormat`.
|
|
196
|
+
* `$fill` is special (not a variable) and handled by the parser.
|
|
197
|
+
*/
|
|
198
|
+
export const FOOTER_FORMAT_ALIASES: Record<string, string> = {
|
|
199
|
+
directory: "cwd",
|
|
200
|
+
branch: "git_branch",
|
|
201
|
+
status: "git_status",
|
|
202
|
+
state: "git_state",
|
|
203
|
+
commit: "git_commit",
|
|
204
|
+
tag: "git_tag",
|
|
205
|
+
duration: "session_duration",
|
|
206
|
+
session: "session_name",
|
|
207
|
+
thinking_level: "thinking",
|
|
208
|
+
turn_count: "turn",
|
|
209
|
+
codex: "codex_usage",
|
|
210
|
+
tools: "tool_counts",
|
|
211
|
+
agents: "active_agents",
|
|
212
|
+
separator: "sep",
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export const configPath = join(getAgentDir(), "rinco-pi-hud.json");
|
|
216
|
+
|
|
217
|
+
export const defaultConfig: PolishedTuiConfig = {
|
|
218
|
+
projectRefreshIntervalMs: DEFAULT_PROJECT_REFRESH_INTERVAL_MS,
|
|
219
|
+
footerFormat: "",
|
|
220
|
+
separator: "chevron",
|
|
221
|
+
contextStyle: "text+gauge",
|
|
222
|
+
contextThresholds: { warning: 70, error: 90 },
|
|
223
|
+
pathDisplay: { mode: "basename", depth: 0 },
|
|
224
|
+
gitBranch: { maxLength: 30 },
|
|
225
|
+
icons: {
|
|
226
|
+
mode: "auto",
|
|
227
|
+
...NERD_DEFAULT_ICONS,
|
|
228
|
+
},
|
|
229
|
+
colors: {
|
|
230
|
+
cwd: "bold #F2A7C6",
|
|
231
|
+
gitBranch: "bold #C7B8F5",
|
|
232
|
+
gitStatus: "bold #F6BC9A",
|
|
233
|
+
contextNormal: "#AEE5C5",
|
|
234
|
+
contextWarning: "bold #F3D98B",
|
|
235
|
+
contextError: "bold #FF8FA3",
|
|
236
|
+
tokens: "#A99BAE",
|
|
237
|
+
cost: "bold #AEE5C5",
|
|
238
|
+
separator: "#716879",
|
|
239
|
+
runtimePrefix: "#9FD3F2",
|
|
240
|
+
extensionStatus: "#EFC3E6",
|
|
241
|
+
sessionDuration: "#F3D98B",
|
|
242
|
+
packageVersion: "#F6BC9A",
|
|
243
|
+
gitCommit: "#AEE5C5",
|
|
244
|
+
gitMetricsAdded: "#AEE5C5",
|
|
245
|
+
gitMetricsDeleted: "#FF8FA3",
|
|
246
|
+
username: "#F3D98B",
|
|
247
|
+
time: "#F3D98B",
|
|
248
|
+
os: "#F7EEF8",
|
|
249
|
+
muted: "#A99BAE",
|
|
250
|
+
},
|
|
251
|
+
colorSources: {
|
|
252
|
+
starship: "terminal",
|
|
253
|
+
},
|
|
254
|
+
features: {
|
|
255
|
+
statusLine: true,
|
|
256
|
+
},
|
|
257
|
+
footerSegments: {
|
|
258
|
+
cwd: true,
|
|
259
|
+
gitBranch: true,
|
|
260
|
+
gitStatus: true,
|
|
261
|
+
gitCounts: false,
|
|
262
|
+
runtime: true,
|
|
263
|
+
context: true,
|
|
264
|
+
tokens: true,
|
|
265
|
+
cost: true,
|
|
266
|
+
sessionDuration: false,
|
|
267
|
+
username: false,
|
|
268
|
+
time: false,
|
|
269
|
+
os: true,
|
|
270
|
+
packageVersion: false,
|
|
271
|
+
gitCommit: false,
|
|
272
|
+
gitMetrics: false,
|
|
273
|
+
sessionName: true,
|
|
274
|
+
model: true,
|
|
275
|
+
thinking: true,
|
|
276
|
+
turnCount: true,
|
|
277
|
+
cacheDetails: true,
|
|
278
|
+
codexUsage: true,
|
|
279
|
+
configCounts: false,
|
|
280
|
+
skills: true,
|
|
281
|
+
mcp: true,
|
|
282
|
+
toolActivity: true,
|
|
283
|
+
agentActivity: true,
|
|
284
|
+
},
|
|
285
|
+
gitCommit: {
|
|
286
|
+
hashLength: 7,
|
|
287
|
+
onlyDetached: true,
|
|
288
|
+
showTag: true,
|
|
289
|
+
},
|
|
290
|
+
gitMetrics: {
|
|
291
|
+
onlyNonzero: true,
|
|
292
|
+
ignoreSubmodules: false,
|
|
293
|
+
},
|
|
294
|
+
extensionStatuses: {
|
|
295
|
+
defaultPlacement: "right",
|
|
296
|
+
placements: {
|
|
297
|
+
"dual-subscription-quota": "left",
|
|
298
|
+
"codex-goal": "middle",
|
|
299
|
+
"xai-usage": "right",
|
|
300
|
+
},
|
|
301
|
+
colorModes: {},
|
|
302
|
+
},
|
|
303
|
+
};
|