claude-contextline 2.0.1 → 2.1.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 +8 -1
- package/dist/index.js +165 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,8 +23,15 @@ Add to your Claude Code settings (`~/.claude/settings.json`):
|
|
|
23
23
|
(main) myproject
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
Colors track your active [herdr](https://github.com/) theme, read from
|
|
27
|
+
`~/.config/herdr/config.toml` (respects `$XDG_CONFIG_HOME` and
|
|
28
|
+
`$HERDR_CONFIG_PATH`) on every render — including `[theme.custom]` overrides.
|
|
29
|
+
All of herdr's built-in themes are supported (catppuccin, tokyo-night, dracula,
|
|
30
|
+
nord, gruvbox, solarized, kanagawa, rosé-pine, vesper, …); if no config is found
|
|
31
|
+
it falls back to Catppuccin Mocha.
|
|
32
|
+
|
|
26
33
|
- **Line 1**: Context window battery bar (blue) with usage percentage, model name (red)
|
|
27
|
-
- **Line 2**: Git branch (
|
|
34
|
+
- **Line 2**: Git branch (mauve), working directory (blue) aligned below the model
|
|
28
35
|
|
|
29
36
|
## Requirements
|
|
30
37
|
|
package/dist/index.js
CHANGED
|
@@ -85,16 +85,175 @@ function getUsedPercentage(hookData) {
|
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// src/theme.ts
|
|
89
|
+
import { readFileSync } from "fs";
|
|
90
|
+
import { homedir } from "os";
|
|
91
|
+
import { join } from "path";
|
|
92
|
+
var rgb = (r, g, b) => ({ kind: "rgb", r, g, b });
|
|
93
|
+
var ansi = (code) => ({ kind: "ansi", code });
|
|
94
|
+
var RESET_COLOR = { kind: "reset" };
|
|
95
|
+
var PALETTES = {
|
|
96
|
+
catppuccin: { blue: rgb(137, 180, 250), red: rgb(243, 139, 168), mauve: rgb(203, 166, 247), overlay0: rgb(108, 112, 134) },
|
|
97
|
+
"catppuccin-latte": { blue: rgb(30, 102, 245), red: rgb(210, 15, 57), mauve: rgb(136, 57, 239), overlay0: rgb(156, 160, 176) },
|
|
98
|
+
terminal: { blue: ansi(34), red: ansi(91), mauve: ansi(37), overlay0: ansi(37) },
|
|
99
|
+
"tokyo-night": { blue: rgb(122, 162, 247), red: rgb(247, 118, 142), mauve: rgb(187, 154, 247), overlay0: rgb(86, 95, 137) },
|
|
100
|
+
"tokyo-night-day": { blue: rgb(46, 125, 233), red: rgb(245, 42, 101), mauve: rgb(120, 71, 189), overlay0: rgb(137, 144, 179) },
|
|
101
|
+
dracula: { blue: rgb(139, 233, 253), red: rgb(255, 85, 85), mauve: rgb(255, 121, 198), overlay0: rgb(98, 114, 164) },
|
|
102
|
+
nord: { blue: rgb(129, 161, 193), red: rgb(191, 97, 106), mauve: rgb(180, 142, 173), overlay0: rgb(76, 86, 106) },
|
|
103
|
+
gruvbox: { blue: rgb(131, 165, 152), red: rgb(251, 73, 52), mauve: rgb(211, 134, 155), overlay0: rgb(146, 131, 116) },
|
|
104
|
+
"gruvbox-light": { blue: rgb(7, 102, 120), red: rgb(157, 0, 6), mauve: rgb(143, 63, 113), overlay0: rgb(146, 131, 116) },
|
|
105
|
+
"one-dark": { blue: rgb(97, 175, 239), red: rgb(224, 108, 117), mauve: rgb(198, 120, 221), overlay0: rgb(92, 99, 112) },
|
|
106
|
+
"one-light": { blue: rgb(64, 120, 242), red: rgb(228, 86, 73), mauve: rgb(166, 38, 164), overlay0: rgb(160, 161, 167) },
|
|
107
|
+
solarized: { blue: rgb(38, 139, 210), red: rgb(220, 50, 47), mauve: rgb(211, 54, 130), overlay0: rgb(88, 110, 117) },
|
|
108
|
+
"solarized-light": { blue: rgb(38, 139, 210), red: rgb(220, 50, 47), mauve: rgb(211, 54, 130), overlay0: rgb(147, 161, 161) },
|
|
109
|
+
kanagawa: { blue: rgb(126, 156, 216), red: rgb(195, 64, 67), mauve: rgb(149, 127, 184), overlay0: rgb(114, 113, 105) },
|
|
110
|
+
"kanagawa-lotus": { blue: rgb(77, 105, 155), red: rgb(200, 64, 83), mauve: rgb(98, 76, 131), overlay0: rgb(160, 156, 172) },
|
|
111
|
+
"rose-pine": { blue: rgb(49, 116, 143), red: rgb(235, 111, 146), mauve: rgb(196, 167, 231), overlay0: rgb(110, 106, 134) },
|
|
112
|
+
"rose-pine-dawn": { blue: rgb(40, 105, 131), red: rgb(180, 99, 122), mauve: rgb(144, 122, 169), overlay0: rgb(152, 147, 165) },
|
|
113
|
+
vesper: { blue: rgb(176, 176, 176), red: rgb(255, 128, 128), mauve: rgb(255, 209, 168), overlay0: rgb(92, 92, 92) }
|
|
114
|
+
};
|
|
115
|
+
var ALIASES = {
|
|
116
|
+
"catppuccin-mocha": "catppuccin",
|
|
117
|
+
latte: "catppuccin-latte",
|
|
118
|
+
light: "catppuccin-latte",
|
|
119
|
+
tokyonight: "tokyo-night",
|
|
120
|
+
"tokyo-day": "tokyo-night-day",
|
|
121
|
+
"tokyonight-day": "tokyo-night-day",
|
|
122
|
+
"gruvbox-dark": "gruvbox",
|
|
123
|
+
onedark: "one-dark",
|
|
124
|
+
onelight: "one-light",
|
|
125
|
+
"solarized-dark": "solarized",
|
|
126
|
+
lotus: "kanagawa-lotus",
|
|
127
|
+
rosepine: "rose-pine",
|
|
128
|
+
"rosepine-dawn": "rose-pine-dawn",
|
|
129
|
+
dawn: "rose-pine-dawn"
|
|
130
|
+
};
|
|
131
|
+
var DEFAULT_THEME = "catppuccin";
|
|
132
|
+
var NAMED_ANSI = {
|
|
133
|
+
black: 30,
|
|
134
|
+
red: 31,
|
|
135
|
+
green: 32,
|
|
136
|
+
yellow: 33,
|
|
137
|
+
blue: 34,
|
|
138
|
+
magenta: 35,
|
|
139
|
+
purple: 35,
|
|
140
|
+
cyan: 36,
|
|
141
|
+
gray: 37,
|
|
142
|
+
grey: 37,
|
|
143
|
+
white: 97,
|
|
144
|
+
darkgray: 90,
|
|
145
|
+
darkgrey: 90,
|
|
146
|
+
lightred: 91,
|
|
147
|
+
lightgreen: 92,
|
|
148
|
+
lightyellow: 93,
|
|
149
|
+
lightblue: 94,
|
|
150
|
+
lightmagenta: 95,
|
|
151
|
+
lightcyan: 96
|
|
152
|
+
};
|
|
153
|
+
function fg(color) {
|
|
154
|
+
switch (color.kind) {
|
|
155
|
+
case "rgb":
|
|
156
|
+
return `\x1B[38;2;${color.r};${color.g};${color.b}m`;
|
|
157
|
+
case "ansi":
|
|
158
|
+
return `\x1B[${color.code}m`;
|
|
159
|
+
case "reset":
|
|
160
|
+
return `\x1B[39m`;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function parseColor(input) {
|
|
164
|
+
const s = input.trim().toLowerCase();
|
|
165
|
+
if (s === "reset" || s === "default" || s === "none" || s === "transparent") {
|
|
166
|
+
return RESET_COLOR;
|
|
167
|
+
}
|
|
168
|
+
if (s.startsWith("#")) {
|
|
169
|
+
const hex = s.slice(1);
|
|
170
|
+
if (/^[0-9a-f]{6}$/.test(hex)) {
|
|
171
|
+
return rgb(parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16));
|
|
172
|
+
}
|
|
173
|
+
if (/^[0-9a-f]{3}$/.test(hex)) {
|
|
174
|
+
return rgb(parseInt(hex[0], 16) * 17, parseInt(hex[1], 16) * 17, parseInt(hex[2], 16) * 17);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const rgbMatch = s.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);
|
|
178
|
+
if (rgbMatch) {
|
|
179
|
+
return rgb(Number(rgbMatch[1]), Number(rgbMatch[2]), Number(rgbMatch[3]));
|
|
180
|
+
}
|
|
181
|
+
if (s in NAMED_ANSI) {
|
|
182
|
+
return ansi(NAMED_ANSI[s]);
|
|
183
|
+
}
|
|
184
|
+
return ansi(36);
|
|
185
|
+
}
|
|
186
|
+
function configPaths() {
|
|
187
|
+
const override = process.env.HERDR_CONFIG_PATH;
|
|
188
|
+
if (override) return [override];
|
|
189
|
+
const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
|
|
190
|
+
return [join(base, "herdr", "config.toml"), join(base, "herdr-dev", "config.toml")];
|
|
191
|
+
}
|
|
192
|
+
function parseThemeSection(toml) {
|
|
193
|
+
const result = { custom: {} };
|
|
194
|
+
let section = "";
|
|
195
|
+
for (const rawLine of toml.split(/\r?\n/)) {
|
|
196
|
+
const line = rawLine.trim();
|
|
197
|
+
if (!line || line.startsWith("#")) continue;
|
|
198
|
+
const sectionMatch = line.match(/^\[([^\]]+)\]$/);
|
|
199
|
+
if (sectionMatch) {
|
|
200
|
+
section = sectionMatch[1].trim();
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const eq = line.indexOf("=");
|
|
204
|
+
if (eq === -1) continue;
|
|
205
|
+
const key = line.slice(0, eq).trim();
|
|
206
|
+
let value = line.slice(eq + 1).trim();
|
|
207
|
+
if (value.startsWith('"') || value.startsWith("'")) {
|
|
208
|
+
const quote = value[0];
|
|
209
|
+
const end = value.indexOf(quote, 1);
|
|
210
|
+
if (end !== -1) value = value.slice(1, end);
|
|
211
|
+
} else {
|
|
212
|
+
const hash = value.indexOf("#");
|
|
213
|
+
if (hash !== -1) value = value.slice(0, hash).trim();
|
|
214
|
+
}
|
|
215
|
+
if (section === "theme" && key === "name") {
|
|
216
|
+
result.name = value;
|
|
217
|
+
} else if (section === "theme.custom") {
|
|
218
|
+
result.custom[key] = value;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
function resolvePalette(name) {
|
|
224
|
+
const normalized = (name ?? DEFAULT_THEME).toLowerCase().replace(/[ _]/g, "-");
|
|
225
|
+
const canonical = ALIASES[normalized] ?? normalized;
|
|
226
|
+
return PALETTES[canonical] ?? PALETTES[DEFAULT_THEME];
|
|
227
|
+
}
|
|
228
|
+
function loadHerdrTheme() {
|
|
229
|
+
let parsed = { custom: {} };
|
|
230
|
+
for (const path of configPaths()) {
|
|
231
|
+
try {
|
|
232
|
+
parsed = parseThemeSection(readFileSync(path, "utf8"));
|
|
233
|
+
break;
|
|
234
|
+
} catch {
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const palette = { ...resolvePalette(parsed.name) };
|
|
238
|
+
for (const token of ["blue", "red", "mauve", "overlay0"]) {
|
|
239
|
+
const override = parsed.custom[token];
|
|
240
|
+
if (override) palette[token] = parseColor(override);
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
blue: fg(palette.blue),
|
|
244
|
+
red: fg(palette.red),
|
|
245
|
+
mauve: fg(palette.mauve),
|
|
246
|
+
overlay0: fg(palette.overlay0)
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
88
250
|
// src/renderer.ts
|
|
89
|
-
var
|
|
90
|
-
var RESET = `${ESC}[0m`;
|
|
91
|
-
var BLUE = `${ESC}[38;5;69m`;
|
|
92
|
-
var RED = `${ESC}[38;5;196m`;
|
|
93
|
-
var GRAY = `${ESC}[38;5;243m`;
|
|
251
|
+
var RESET = "\x1B[0m";
|
|
94
252
|
var BAR_WIDTH = 10;
|
|
95
253
|
var FILLED_CHAR = "\u2588";
|
|
96
254
|
var EMPTY_CHAR = "\u2591";
|
|
97
255
|
function render(envInfo) {
|
|
256
|
+
const { blue: BLUE, red: RED, mauve: MAUVE, overlay0: GRAY } = loadHerdrTheme();
|
|
98
257
|
let out = "";
|
|
99
258
|
let modelCol = 0;
|
|
100
259
|
if (envInfo.usedPercentage != null) {
|
|
@@ -117,7 +276,7 @@ function render(envInfo) {
|
|
|
117
276
|
out += "\n";
|
|
118
277
|
if (envInfo.gitBranch) {
|
|
119
278
|
const branchText = `(${envInfo.gitBranch})`;
|
|
120
|
-
out += `${
|
|
279
|
+
out += `${MAUVE}${branchText}`;
|
|
121
280
|
const gap = Math.max(2, modelCol - branchText.length);
|
|
122
281
|
out += " ".repeat(gap);
|
|
123
282
|
} else {
|