claude-contextline 2.1.0 → 2.3.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 +6 -9
- package/dist/index.js +47 -156
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,15 +23,12 @@ Add to your Claude Code settings (`~/.claude/settings.json`):
|
|
|
23
23
|
(main) myproject
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Colors
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- **Line 1**: Context window battery bar (blue) with usage percentage, model name (red)
|
|
34
|
-
- **Line 2**: Git branch (mauve), working directory (blue) aligned below the model
|
|
26
|
+
Colors reflect [lasso](https://github.com/)'s Onyx design system — lasso's
|
|
27
|
+
single, fixed (dark) palette — so the statusline stays in step with lasso's
|
|
28
|
+
indigo-forward look. The tokens mirror lasso's canonical Onyx colors.
|
|
29
|
+
|
|
30
|
+
- **Line 1**: Context window battery bar (Onyx accent) with usage percentage, model name (Onyx danger)
|
|
31
|
+
- **Line 2**: Git branch (Onyx secondary indigo), working directory (Onyx accent) aligned below the model
|
|
35
32
|
|
|
36
33
|
## Requirements
|
|
37
34
|
|
package/dist/index.js
CHANGED
|
@@ -89,162 +89,52 @@ function getUsedPercentage(hookData) {
|
|
|
89
89
|
import { readFileSync } from "fs";
|
|
90
90
|
import { homedir } from "os";
|
|
91
91
|
import { join } from "path";
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
}
|
|
92
|
+
function fg(hex) {
|
|
93
|
+
const r = parseInt(hex.slice(1, 3), 16);
|
|
94
|
+
const g = parseInt(hex.slice(3, 5), 16);
|
|
95
|
+
const b = parseInt(hex.slice(5, 7), 16);
|
|
96
|
+
return `\x1B[38;2;${r};${g};${b}m`;
|
|
162
97
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
98
|
+
var NOTHING = {
|
|
99
|
+
dark: {
|
|
100
|
+
bar: fg("#ededed"),
|
|
101
|
+
// --h-fg (filled bar + percentage)
|
|
102
|
+
barFull: fg("#d71921"),
|
|
103
|
+
// --h-bad (context ≥90% — interrupt)
|
|
104
|
+
text: fg("#ededed"),
|
|
105
|
+
// --h-fg (model + directory)
|
|
106
|
+
branch: fg("#8a8a8a"),
|
|
107
|
+
// --h-muted (git branch)
|
|
108
|
+
empty: fg("#3a3a3a")
|
|
109
|
+
// --h-border+ (empty bar cells)
|
|
110
|
+
},
|
|
111
|
+
light: {
|
|
112
|
+
bar: fg("#1a1a1a"),
|
|
113
|
+
// --h-fg (light)
|
|
114
|
+
barFull: fg("#c0141b"),
|
|
115
|
+
// --h-bad (light, darkened)
|
|
116
|
+
text: fg("#1a1a1a"),
|
|
117
|
+
// --h-fg (light)
|
|
118
|
+
branch: fg("#666666"),
|
|
119
|
+
// --h-muted (light)
|
|
120
|
+
empty: fg("#cccccc")
|
|
121
|
+
// light seam
|
|
167
122
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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")];
|
|
123
|
+
};
|
|
124
|
+
function settingsPath() {
|
|
125
|
+
const dir = process.env.LASSO_DIR || join(homedir(), ".lasso");
|
|
126
|
+
return join(dir, "settings.json");
|
|
191
127
|
}
|
|
192
|
-
function
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
}
|
|
128
|
+
function resolvedAppearance() {
|
|
129
|
+
try {
|
|
130
|
+
const parsed = JSON.parse(readFileSync(settingsPath(), "utf8"));
|
|
131
|
+
return parsed?.theme?.resolved === "light" ? "light" : "dark";
|
|
132
|
+
} catch {
|
|
133
|
+
return "dark";
|
|
220
134
|
}
|
|
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
135
|
}
|
|
228
|
-
function
|
|
229
|
-
|
|
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
|
-
};
|
|
136
|
+
function loadLassoTheme() {
|
|
137
|
+
return NOTHING[resolvedAppearance()];
|
|
248
138
|
}
|
|
249
139
|
|
|
250
140
|
// src/renderer.ts
|
|
@@ -253,7 +143,7 @@ var BAR_WIDTH = 10;
|
|
|
253
143
|
var FILLED_CHAR = "\u2588";
|
|
254
144
|
var EMPTY_CHAR = "\u2591";
|
|
255
145
|
function render(envInfo) {
|
|
256
|
-
const {
|
|
146
|
+
const { bar: BAR, barFull: BAR_FULL, text: TEXT, branch: BRANCH, empty: EMPTY } = loadLassoTheme();
|
|
257
147
|
let out = "";
|
|
258
148
|
let modelCol = 0;
|
|
259
149
|
if (envInfo.usedPercentage != null) {
|
|
@@ -266,23 +156,24 @@ function render(envInfo) {
|
|
|
266
156
|
const nEmpty = BAR_WIDTH - nFilled;
|
|
267
157
|
const filled = FILLED_CHAR.repeat(nFilled);
|
|
268
158
|
const empty = EMPTY_CHAR.repeat(nEmpty);
|
|
269
|
-
|
|
159
|
+
const fill = pct >= 90 ? BAR_FULL : BAR;
|
|
160
|
+
out += `${fill}[${filled}${EMPTY}${empty}${fill}] ${pctStr}%`;
|
|
270
161
|
modelCol = 16 + pctStr.length;
|
|
271
162
|
}
|
|
272
163
|
if (out.length > 0) {
|
|
273
164
|
out += " ";
|
|
274
165
|
}
|
|
275
|
-
out += `${
|
|
166
|
+
out += `${TEXT}${envInfo.model}`;
|
|
276
167
|
out += "\n";
|
|
277
168
|
if (envInfo.gitBranch) {
|
|
278
169
|
const branchText = `(${envInfo.gitBranch})`;
|
|
279
|
-
out += `${
|
|
170
|
+
out += `${BRANCH}${branchText}`;
|
|
280
171
|
const gap = Math.max(2, modelCol - branchText.length);
|
|
281
172
|
out += " ".repeat(gap);
|
|
282
173
|
} else {
|
|
283
174
|
out += " ".repeat(modelCol);
|
|
284
175
|
}
|
|
285
|
-
out += `${
|
|
176
|
+
out += `${TEXT}${envInfo.directory}`;
|
|
286
177
|
out += RESET;
|
|
287
178
|
return out;
|
|
288
179
|
}
|