@vimukthid/ccsl 1.0.0 → 1.0.3
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 +54 -17
- package/dist/cli.js +226 -40
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +220 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -3
- package/dist/index.d.ts +75 -3
- package/dist/index.js +212 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,16 +51,18 @@ Claude Code passes JSON data via stdin to ccsl, which formats it into a beautifu
|
|
|
51
51
|
|
|
52
52
|
### Available Widgets
|
|
53
53
|
|
|
54
|
-
| Widget | Description
|
|
55
|
-
|
|
56
|
-
| `model` | Claude model name
|
|
57
|
-
| `context` | Context window usage %
|
|
58
|
-
| `tokens` | Input/Output tokens
|
|
59
|
-
| `cost` | Session cost USD
|
|
60
|
-
| `duration` | Session duration
|
|
61
|
-
| `lines` | Lines added/removed
|
|
62
|
-
| `directory` | Current directory
|
|
63
|
-
| `version` | Claude Code version
|
|
54
|
+
| Widget | Description | Example |
|
|
55
|
+
|-------------|----------------------------|----------------------|
|
|
56
|
+
| `model` | Claude model name | `Opus` |
|
|
57
|
+
| `context` | Context window usage % | `42%` |
|
|
58
|
+
| `tokens` | Input/Output tokens | `↑15.2k ↓4.5k` |
|
|
59
|
+
| `cost` | Session cost USD | `$0.02` |
|
|
60
|
+
| `duration` | Session duration | `45s` |
|
|
61
|
+
| `lines` | Lines added/removed | `+156 -23` |
|
|
62
|
+
| `directory` | Current directory | `my-project` |
|
|
63
|
+
| `version` | Claude Code version | `v1.0.80` |
|
|
64
|
+
| `usage` | Session usage with limit | `▰▰▰▱▱ 75/100 (Pro)` |
|
|
65
|
+
| `resetTime` | Time until usage resets | `1h30m` |
|
|
64
66
|
|
|
65
67
|
### Built-in Themes
|
|
66
68
|
|
|
@@ -99,7 +101,8 @@ ccsl theme --list # List available themes
|
|
|
99
101
|
ccsl preview # Preview with sample data
|
|
100
102
|
ccsl init # Create local config file
|
|
101
103
|
ccsl init --global # Create global config file
|
|
102
|
-
ccsl config # Open TUI configuration
|
|
104
|
+
ccsl config # Open TUI configuration (local)
|
|
105
|
+
ccsl config --global # Open TUI configuration (global)
|
|
103
106
|
ccsl --version # Show version
|
|
104
107
|
ccsl --help # Show help
|
|
105
108
|
```
|
|
@@ -108,10 +111,20 @@ ccsl --help # Show help
|
|
|
108
111
|
|
|
109
112
|
### Config File Locations
|
|
110
113
|
|
|
111
|
-
| Scope | Location | Priority |
|
|
112
|
-
|
|
113
|
-
| Local | `.ccslrc.json` | Highest |
|
|
114
|
-
| Global | `~/.config/ccsl/config.json` | Default |
|
|
114
|
+
| Scope | Location | Priority | Use Case |
|
|
115
|
+
|--------|------------------------------|----------|-----------------------------|
|
|
116
|
+
| Local | `.ccslrc.json` | Highest | Project-specific settings |
|
|
117
|
+
| Global | `~/.config/ccsl/config.json` | Default | User-wide default settings |
|
|
118
|
+
|
|
119
|
+
**Configuration Priority:** Local config takes precedence over global config. If no local config exists, the global config is used.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Configure global settings (applies to all projects)
|
|
123
|
+
ccsl config --global
|
|
124
|
+
|
|
125
|
+
# Configure local settings (project-specific)
|
|
126
|
+
ccsl config --local # or just: ccsl config
|
|
127
|
+
```
|
|
115
128
|
|
|
116
129
|
### Config Schema
|
|
117
130
|
|
|
@@ -145,7 +158,11 @@ ccsl --help # Show help
|
|
|
145
158
|
"linesRemoved": { "fg": "#e06c75" },
|
|
146
159
|
"directory": { "fg": "#61afef" },
|
|
147
160
|
"version": { "fg": "#abb2bf" },
|
|
148
|
-
"separator": { "fg": "#5c6370" }
|
|
161
|
+
"separator": { "fg": "#5c6370" },
|
|
162
|
+
"usage": { "fg": "#98c379" },
|
|
163
|
+
"usageHigh": { "fg": "#e5c07b" },
|
|
164
|
+
"usageCritical": { "fg": "#e06c75" },
|
|
165
|
+
"resetTime": { "fg": "#61afef" }
|
|
149
166
|
}
|
|
150
167
|
}
|
|
151
168
|
}
|
|
@@ -170,10 +187,30 @@ ccsl receives JSON from Claude Code via stdin:
|
|
|
170
187
|
"total_lines_removed": 23
|
|
171
188
|
},
|
|
172
189
|
"workspace": { "current_dir": "/path/to/project" },
|
|
173
|
-
"version": "1.0.80"
|
|
190
|
+
"version": "1.0.80",
|
|
191
|
+
"session_usage": {
|
|
192
|
+
"requests_used": 45,
|
|
193
|
+
"requests_limit": 100,
|
|
194
|
+
"usage_percentage": 45,
|
|
195
|
+
"reset_in_seconds": 7200,
|
|
196
|
+
"plan": "Pro"
|
|
197
|
+
}
|
|
174
198
|
}
|
|
175
199
|
```
|
|
176
200
|
|
|
201
|
+
### Session Usage Fields
|
|
202
|
+
|
|
203
|
+
The `session_usage` object supports the following fields for the `usage` and `resetTime` widgets:
|
|
204
|
+
|
|
205
|
+
| Field | Type | Description |
|
|
206
|
+
|--------------------|--------|-------------------------------------------|
|
|
207
|
+
| `requests_used` | number | Number of requests used in current period |
|
|
208
|
+
| `requests_limit` | number | Maximum requests allowed |
|
|
209
|
+
| `usage_percentage` | number | Usage percentage (0-100) |
|
|
210
|
+
| `reset_at` | string | ISO timestamp when usage resets |
|
|
211
|
+
| `reset_in_seconds` | number | Seconds until usage resets |
|
|
212
|
+
| `plan` | string | Plan/tier name (e.g., "Pro", "Max") |
|
|
213
|
+
|
|
177
214
|
## Development
|
|
178
215
|
|
|
179
216
|
### Build from Source
|
package/dist/cli.js
CHANGED
|
@@ -37,16 +37,40 @@ var init_defaults = __esm({
|
|
|
37
37
|
|
|
38
38
|
// src/config/loader.ts
|
|
39
39
|
import { cosmiconfig } from "cosmiconfig";
|
|
40
|
+
import { existsSync } from "fs";
|
|
40
41
|
async function loadConfig(searchFrom) {
|
|
41
42
|
try {
|
|
42
43
|
const result = await explorer.search(searchFrom);
|
|
43
44
|
if (result && result.config) {
|
|
44
45
|
return mergeConfig(defaultConfig, result.config);
|
|
45
46
|
}
|
|
47
|
+
const globalPath = getConfigPath("global");
|
|
48
|
+
if (existsSync(globalPath)) {
|
|
49
|
+
const globalResult = await explorer.load(globalPath);
|
|
50
|
+
if (globalResult && globalResult.config) {
|
|
51
|
+
return mergeConfig(defaultConfig, globalResult.config);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
46
54
|
} catch {
|
|
47
55
|
}
|
|
48
56
|
return { ...defaultConfig };
|
|
49
57
|
}
|
|
58
|
+
async function loadConfigForScope(scope) {
|
|
59
|
+
const configPath = getConfigPath(scope);
|
|
60
|
+
if (scope === "global") {
|
|
61
|
+
if (existsSync(configPath)) {
|
|
62
|
+
try {
|
|
63
|
+
const result = await explorer.load(configPath);
|
|
64
|
+
if (result && result.config) {
|
|
65
|
+
return mergeConfig(defaultConfig, result.config);
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { ...defaultConfig };
|
|
71
|
+
}
|
|
72
|
+
return loadConfig();
|
|
73
|
+
}
|
|
50
74
|
function mergeConfig(defaults, userConfig) {
|
|
51
75
|
return {
|
|
52
76
|
theme: userConfig.theme ?? defaults.theme,
|
|
@@ -107,7 +131,11 @@ var init_themes = __esm({
|
|
|
107
131
|
linesRemoved: { fg: "#ff0066" },
|
|
108
132
|
directory: { fg: "#00ffff" },
|
|
109
133
|
version: { fg: "#aaaaff" },
|
|
110
|
-
separator: { fg: "#666666" }
|
|
134
|
+
separator: { fg: "#666666" },
|
|
135
|
+
usage: { fg: "#00ffaa" },
|
|
136
|
+
usageHigh: { fg: "#ffff00" },
|
|
137
|
+
usageCritical: { fg: "#ff0000", bold: true },
|
|
138
|
+
resetTime: { fg: "#ff00ff" }
|
|
111
139
|
}
|
|
112
140
|
};
|
|
113
141
|
rainbowTheme = {
|
|
@@ -125,7 +153,11 @@ var init_themes = __esm({
|
|
|
125
153
|
linesRemoved: { fg: "#ff0000" },
|
|
126
154
|
directory: { fg: "#ff7f00" },
|
|
127
155
|
version: { fg: "#9400d3" },
|
|
128
|
-
separator: { fg: "#888888" }
|
|
156
|
+
separator: { fg: "#888888" },
|
|
157
|
+
usage: { fg: "#00ffff" },
|
|
158
|
+
usageHigh: { fg: "#ffff00" },
|
|
159
|
+
usageCritical: { fg: "#ff0000", bold: true },
|
|
160
|
+
resetTime: { fg: "#ff7f00" }
|
|
129
161
|
}
|
|
130
162
|
};
|
|
131
163
|
oceanTheme = {
|
|
@@ -143,7 +175,11 @@ var init_themes = __esm({
|
|
|
143
175
|
linesRemoved: { fg: "#ff5252" },
|
|
144
176
|
directory: { fg: "#00bcd4" },
|
|
145
177
|
version: { fg: "#80deea" },
|
|
146
|
-
separator: { fg: "#37474f" }
|
|
178
|
+
separator: { fg: "#37474f" },
|
|
179
|
+
usage: { fg: "#26c6da" },
|
|
180
|
+
usageHigh: { fg: "#4dd0e1" },
|
|
181
|
+
usageCritical: { fg: "#ff5252", bold: true },
|
|
182
|
+
resetTime: { fg: "#0288d1" }
|
|
147
183
|
}
|
|
148
184
|
};
|
|
149
185
|
minimalTheme = {
|
|
@@ -161,7 +197,11 @@ var init_themes = __esm({
|
|
|
161
197
|
linesRemoved: { fg: "#e06c75" },
|
|
162
198
|
directory: { fg: "#888888" },
|
|
163
199
|
version: { fg: "#5c6370" },
|
|
164
|
-
separator: { fg: "#444444" }
|
|
200
|
+
separator: { fg: "#444444" },
|
|
201
|
+
usage: { fg: "#98c379" },
|
|
202
|
+
usageHigh: { fg: "#e5c07b" },
|
|
203
|
+
usageCritical: { fg: "#e06c75", bold: true },
|
|
204
|
+
resetTime: { fg: "#61afef" }
|
|
165
205
|
},
|
|
166
206
|
icons: {
|
|
167
207
|
model: "",
|
|
@@ -169,7 +209,9 @@ var init_themes = __esm({
|
|
|
169
209
|
tokens: "",
|
|
170
210
|
duration: "",
|
|
171
211
|
lines: "",
|
|
172
|
-
directory: ""
|
|
212
|
+
directory: "",
|
|
213
|
+
usage: "",
|
|
214
|
+
resetTime: ""
|
|
173
215
|
}
|
|
174
216
|
};
|
|
175
217
|
monochromeTheme = {
|
|
@@ -187,7 +229,11 @@ var init_themes = __esm({
|
|
|
187
229
|
linesRemoved: { fg: "#888888" },
|
|
188
230
|
directory: { fg: "#aaaaaa" },
|
|
189
231
|
version: { fg: "#666666" },
|
|
190
|
-
separator: { fg: "#444444" }
|
|
232
|
+
separator: { fg: "#444444" },
|
|
233
|
+
usage: { fg: "#bbbbbb" },
|
|
234
|
+
usageHigh: { fg: "#ffffff", bold: true },
|
|
235
|
+
usageCritical: { fg: "#ffffff", bold: true, underline: true },
|
|
236
|
+
resetTime: { fg: "#999999" }
|
|
191
237
|
},
|
|
192
238
|
icons: {
|
|
193
239
|
model: "",
|
|
@@ -195,7 +241,9 @@ var init_themes = __esm({
|
|
|
195
241
|
tokens: "",
|
|
196
242
|
duration: "",
|
|
197
243
|
lines: "",
|
|
198
|
-
directory: ""
|
|
244
|
+
directory: "",
|
|
245
|
+
usage: "",
|
|
246
|
+
resetTime: ""
|
|
199
247
|
}
|
|
200
248
|
};
|
|
201
249
|
corporateTheme = {
|
|
@@ -213,7 +261,11 @@ var init_themes = __esm({
|
|
|
213
261
|
linesRemoved: { fg: "#ef4444" },
|
|
214
262
|
directory: { fg: "#3b82f6" },
|
|
215
263
|
version: { fg: "#94a3b8" },
|
|
216
|
-
separator: { fg: "#334155" }
|
|
264
|
+
separator: { fg: "#334155" },
|
|
265
|
+
usage: { fg: "#22c55e" },
|
|
266
|
+
usageHigh: { fg: "#f59e0b" },
|
|
267
|
+
usageCritical: { fg: "#ef4444", bold: true },
|
|
268
|
+
resetTime: { fg: "#3b82f6" }
|
|
217
269
|
}
|
|
218
270
|
};
|
|
219
271
|
themes = {
|
|
@@ -281,7 +333,9 @@ var init_icons = __esm({
|
|
|
281
333
|
duration: "\u23F1",
|
|
282
334
|
lines: "\xB1",
|
|
283
335
|
directory: "",
|
|
284
|
-
version: ""
|
|
336
|
+
version: "",
|
|
337
|
+
usage: "\u{F04C5}",
|
|
338
|
+
resetTime: "\u{F051F}"
|
|
285
339
|
};
|
|
286
340
|
unicodeIcons = {
|
|
287
341
|
model: "\u25C8",
|
|
@@ -291,7 +345,9 @@ var init_icons = __esm({
|
|
|
291
345
|
duration: "\u23F1",
|
|
292
346
|
lines: "\xB1",
|
|
293
347
|
directory: "\u{1F4C1}",
|
|
294
|
-
version: "v"
|
|
348
|
+
version: "v",
|
|
349
|
+
usage: "\u25B0",
|
|
350
|
+
resetTime: "\u27F3"
|
|
295
351
|
};
|
|
296
352
|
asciiIcons = {
|
|
297
353
|
model: "*",
|
|
@@ -301,7 +357,9 @@ var init_icons = __esm({
|
|
|
301
357
|
duration: "",
|
|
302
358
|
lines: "",
|
|
303
359
|
directory: "",
|
|
304
|
-
version: "v"
|
|
360
|
+
version: "v",
|
|
361
|
+
usage: "#",
|
|
362
|
+
resetTime: "~"
|
|
305
363
|
};
|
|
306
364
|
detectedIconMode = null;
|
|
307
365
|
}
|
|
@@ -399,6 +457,10 @@ function renderWidget(widget, input, theme, config) {
|
|
|
399
457
|
return renderDirectory(input, theme, config);
|
|
400
458
|
case "version":
|
|
401
459
|
return renderVersion(input, theme, config);
|
|
460
|
+
case "usage":
|
|
461
|
+
return renderUsage(input, theme, config);
|
|
462
|
+
case "resetTime":
|
|
463
|
+
return renderResetTime(input, theme, config);
|
|
402
464
|
default:
|
|
403
465
|
return { content: "", visible: false };
|
|
404
466
|
}
|
|
@@ -517,6 +579,106 @@ function renderVersion(input, theme, config) {
|
|
|
517
579
|
const content = applyStyle(text, theme.colors.version);
|
|
518
580
|
return { content, visible: true };
|
|
519
581
|
}
|
|
582
|
+
function renderUsage(input, theme, config) {
|
|
583
|
+
const sessionUsage = input.session_usage;
|
|
584
|
+
if (!sessionUsage) {
|
|
585
|
+
return { content: "", visible: false };
|
|
586
|
+
}
|
|
587
|
+
const { requests_used, requests_limit, usage_percentage, plan } = sessionUsage;
|
|
588
|
+
if (requests_used === void 0 && usage_percentage === void 0) {
|
|
589
|
+
return { content: "", visible: false };
|
|
590
|
+
}
|
|
591
|
+
const icon = getIcon("usage", theme, config.icons);
|
|
592
|
+
let percent = usage_percentage;
|
|
593
|
+
if (percent === void 0 && requests_used !== void 0 && requests_limit !== void 0 && requests_limit > 0) {
|
|
594
|
+
percent = requests_used / requests_limit * 100;
|
|
595
|
+
}
|
|
596
|
+
let text = "";
|
|
597
|
+
if (icon) {
|
|
598
|
+
text += `${icon} `;
|
|
599
|
+
}
|
|
600
|
+
if (percent !== void 0) {
|
|
601
|
+
const progressBar = renderUsageBar(percent, theme);
|
|
602
|
+
text += progressBar + " ";
|
|
603
|
+
}
|
|
604
|
+
if (requests_used !== void 0 && requests_limit !== void 0) {
|
|
605
|
+
text += `${requests_used}/${requests_limit}`;
|
|
606
|
+
} else if (percent !== void 0) {
|
|
607
|
+
text += `${Math.round(percent)}%`;
|
|
608
|
+
}
|
|
609
|
+
if (plan) {
|
|
610
|
+
text += ` (${plan})`;
|
|
611
|
+
}
|
|
612
|
+
let colorKey = "usage";
|
|
613
|
+
if (percent !== void 0) {
|
|
614
|
+
if (percent >= 90) {
|
|
615
|
+
colorKey = "usageCritical";
|
|
616
|
+
} else if (percent >= 70) {
|
|
617
|
+
colorKey = "usageHigh";
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
const style = theme.colors[colorKey] || theme.colors.usage;
|
|
621
|
+
const content = applyStyle(text.trim(), style);
|
|
622
|
+
return { content, visible: true };
|
|
623
|
+
}
|
|
624
|
+
function renderUsageBar(percentage, theme) {
|
|
625
|
+
const totalBars = 5;
|
|
626
|
+
const filledBars = Math.round(percentage / 100 * totalBars);
|
|
627
|
+
const emptyBars = totalBars - filledBars;
|
|
628
|
+
const filledChar = "\u25B0";
|
|
629
|
+
const emptyChar = "\u25B1";
|
|
630
|
+
let filledStyle = theme.colors.usage;
|
|
631
|
+
if (percentage >= 90) {
|
|
632
|
+
filledStyle = theme.colors.usageCritical || theme.colors.usage;
|
|
633
|
+
} else if (percentage >= 70) {
|
|
634
|
+
filledStyle = theme.colors.usageHigh || theme.colors.usage;
|
|
635
|
+
}
|
|
636
|
+
const filled = applyStyle(filledChar.repeat(filledBars), filledStyle);
|
|
637
|
+
const empty = applyStyle(emptyChar.repeat(emptyBars), { fg: "#444444", dim: true });
|
|
638
|
+
return `${filled}${empty}`;
|
|
639
|
+
}
|
|
640
|
+
function renderResetTime(input, theme, config) {
|
|
641
|
+
const sessionUsage = input.session_usage;
|
|
642
|
+
if (!sessionUsage) {
|
|
643
|
+
return { content: "", visible: false };
|
|
644
|
+
}
|
|
645
|
+
const { reset_at, reset_in_seconds } = sessionUsage;
|
|
646
|
+
if (reset_at === void 0 && reset_in_seconds === void 0) {
|
|
647
|
+
return { content: "", visible: false };
|
|
648
|
+
}
|
|
649
|
+
const icon = getIcon("resetTime", theme, config.icons);
|
|
650
|
+
let timeStr = "";
|
|
651
|
+
if (reset_in_seconds !== void 0) {
|
|
652
|
+
timeStr = formatResetDuration(reset_in_seconds);
|
|
653
|
+
} else if (reset_at) {
|
|
654
|
+
try {
|
|
655
|
+
const resetDate = new Date(reset_at);
|
|
656
|
+
const now = /* @__PURE__ */ new Date();
|
|
657
|
+
const diffSeconds = Math.max(0, Math.floor((resetDate.getTime() - now.getTime()) / 1e3));
|
|
658
|
+
timeStr = formatResetDuration(diffSeconds);
|
|
659
|
+
} catch {
|
|
660
|
+
timeStr = reset_at;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
const text = icon ? `${icon} ${timeStr}` : timeStr;
|
|
664
|
+
const content = applyStyle(text, theme.colors.resetTime);
|
|
665
|
+
return { content, visible: true };
|
|
666
|
+
}
|
|
667
|
+
function formatResetDuration(seconds) {
|
|
668
|
+
if (seconds <= 0) {
|
|
669
|
+
return "now";
|
|
670
|
+
}
|
|
671
|
+
const hours = Math.floor(seconds / 3600);
|
|
672
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
673
|
+
if (hours > 0) {
|
|
674
|
+
return minutes > 0 ? `${hours}h${minutes}m` : `${hours}h`;
|
|
675
|
+
}
|
|
676
|
+
if (minutes > 0) {
|
|
677
|
+
const secs = seconds % 60;
|
|
678
|
+
return secs > 0 ? `${minutes}m${secs}s` : `${minutes}m`;
|
|
679
|
+
}
|
|
680
|
+
return `${seconds}s`;
|
|
681
|
+
}
|
|
520
682
|
var availableWidgets;
|
|
521
683
|
var init_widgets = __esm({
|
|
522
684
|
"src/widgets/index.ts"() {
|
|
@@ -533,7 +695,9 @@ var init_widgets = __esm({
|
|
|
533
695
|
"duration",
|
|
534
696
|
"lines",
|
|
535
697
|
"directory",
|
|
536
|
-
"version"
|
|
698
|
+
"version",
|
|
699
|
+
"usage",
|
|
700
|
+
"resetTime"
|
|
537
701
|
];
|
|
538
702
|
}
|
|
539
703
|
});
|
|
@@ -595,13 +759,20 @@ var init_formatter = __esm({
|
|
|
595
759
|
cache_creation_input_tokens: 5e3,
|
|
596
760
|
cache_read_input_tokens: 2e3
|
|
597
761
|
}
|
|
762
|
+
},
|
|
763
|
+
session_usage: {
|
|
764
|
+
requests_used: 45,
|
|
765
|
+
requests_limit: 100,
|
|
766
|
+
usage_percentage: 45,
|
|
767
|
+
reset_in_seconds: 7200,
|
|
768
|
+
plan: "Pro"
|
|
598
769
|
}
|
|
599
770
|
};
|
|
600
771
|
}
|
|
601
772
|
});
|
|
602
773
|
|
|
603
774
|
// src/config/claude.ts
|
|
604
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync } from "fs";
|
|
775
|
+
import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync, copyFileSync } from "fs";
|
|
605
776
|
import { dirname, join } from "path";
|
|
606
777
|
import { homedir } from "os";
|
|
607
778
|
function getClaudeSettingsPath() {
|
|
@@ -610,7 +781,7 @@ function getClaudeSettingsPath() {
|
|
|
610
781
|
}
|
|
611
782
|
function getClaudeSettings() {
|
|
612
783
|
const settingsPath = getClaudeSettingsPath();
|
|
613
|
-
if (!
|
|
784
|
+
if (!existsSync2(settingsPath)) {
|
|
614
785
|
return null;
|
|
615
786
|
}
|
|
616
787
|
try {
|
|
@@ -622,7 +793,7 @@ function getClaudeSettings() {
|
|
|
622
793
|
}
|
|
623
794
|
function backupClaudeSettings() {
|
|
624
795
|
const settingsPath = getClaudeSettingsPath();
|
|
625
|
-
if (!
|
|
796
|
+
if (!existsSync2(settingsPath)) {
|
|
626
797
|
return null;
|
|
627
798
|
}
|
|
628
799
|
const backupPath = settingsPath + ".backup";
|
|
@@ -636,11 +807,11 @@ function backupClaudeSettings() {
|
|
|
636
807
|
function installToClaudeSettings(command = "npx @vimukthid/ccsl") {
|
|
637
808
|
const settingsPath = getClaudeSettingsPath();
|
|
638
809
|
const dir = dirname(settingsPath);
|
|
639
|
-
if (!
|
|
810
|
+
if (!existsSync2(dir)) {
|
|
640
811
|
mkdirSync(dir, { recursive: true });
|
|
641
812
|
}
|
|
642
813
|
let settings = {};
|
|
643
|
-
if (
|
|
814
|
+
if (existsSync2(settingsPath)) {
|
|
644
815
|
try {
|
|
645
816
|
const content = readFileSync(settingsPath, "utf8");
|
|
646
817
|
settings = JSON.parse(content);
|
|
@@ -661,7 +832,7 @@ function installToClaudeSettings(command = "npx @vimukthid/ccsl") {
|
|
|
661
832
|
}
|
|
662
833
|
function uninstallFromClaudeSettings() {
|
|
663
834
|
const settingsPath = getClaudeSettingsPath();
|
|
664
|
-
if (!
|
|
835
|
+
if (!existsSync2(settingsPath)) {
|
|
665
836
|
return true;
|
|
666
837
|
}
|
|
667
838
|
try {
|
|
@@ -701,7 +872,7 @@ __export(app_exports, {
|
|
|
701
872
|
import { useState } from "react";
|
|
702
873
|
import { render, Box, Text, useApp, useInput } from "ink";
|
|
703
874
|
import SelectInput from "ink-select-input";
|
|
704
|
-
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as
|
|
875
|
+
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
|
|
705
876
|
import { dirname as dirname2 } from "path";
|
|
706
877
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
707
878
|
function App({ initialConfig, scope }) {
|
|
@@ -725,7 +896,7 @@ function App({ initialConfig, scope }) {
|
|
|
725
896
|
const configPath = getConfigPath(scope);
|
|
726
897
|
try {
|
|
727
898
|
const dir = dirname2(configPath);
|
|
728
|
-
if (!
|
|
899
|
+
if (!existsSync3(dir)) {
|
|
729
900
|
mkdirSync2(dir, { recursive: true });
|
|
730
901
|
}
|
|
731
902
|
writeFileSync2(configPath, JSON.stringify(config, null, 2));
|
|
@@ -737,13 +908,13 @@ function App({ initialConfig, scope }) {
|
|
|
737
908
|
};
|
|
738
909
|
const renderMain = () => {
|
|
739
910
|
const items = [
|
|
740
|
-
{ label: "Select Theme", value: "themes" },
|
|
741
|
-
{ label: "Configure Widgets", value: "widgets" },
|
|
742
|
-
{ label: "General Settings", value: "settings" },
|
|
743
|
-
{ label: "Live Preview", value: "preview" },
|
|
744
|
-
{ label: "Install to Claude Code", value: "install" },
|
|
745
|
-
{ label: "Save Configuration", value: "save" },
|
|
746
|
-
{ label: "Exit", value: "exit" }
|
|
911
|
+
{ label: "\u{1F3A8} Select Theme", value: "themes" },
|
|
912
|
+
{ label: "\u{1F4CA} Configure Widgets", value: "widgets" },
|
|
913
|
+
{ label: "\u2699\uFE0F General Settings", value: "settings" },
|
|
914
|
+
{ label: "\u{1F441}\uFE0F Live Preview", value: "preview" },
|
|
915
|
+
{ label: "\u{1F4E6} Install to Claude Code", value: "install" },
|
|
916
|
+
{ label: "\u{1F4BE} Save Configuration", value: "save" },
|
|
917
|
+
{ label: "\u274C Exit", value: "exit" }
|
|
747
918
|
];
|
|
748
919
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
749
920
|
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
@@ -779,7 +950,7 @@ function App({ initialConfig, scope }) {
|
|
|
779
950
|
value: name
|
|
780
951
|
}));
|
|
781
952
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
782
|
-
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Select Theme" }) }),
|
|
953
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F3A8} Select Theme" }) }),
|
|
783
954
|
/* @__PURE__ */ jsx(
|
|
784
955
|
SelectInput,
|
|
785
956
|
{
|
|
@@ -803,7 +974,7 @@ function App({ initialConfig, scope }) {
|
|
|
803
974
|
value: widget
|
|
804
975
|
}));
|
|
805
976
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
806
|
-
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Configure Widgets" }) }),
|
|
977
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F4CA} Configure Widgets" }) }),
|
|
807
978
|
/* @__PURE__ */ jsx(
|
|
808
979
|
SelectInput,
|
|
809
980
|
{
|
|
@@ -855,7 +1026,7 @@ function App({ initialConfig, scope }) {
|
|
|
855
1026
|
];
|
|
856
1027
|
const items = [...iconOptions, ...separatorOptions];
|
|
857
1028
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
858
|
-
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "General Settings" }) }),
|
|
1029
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2699\uFE0F General Settings" }) }),
|
|
859
1030
|
/* @__PURE__ */ jsx(
|
|
860
1031
|
SelectInput,
|
|
861
1032
|
{
|
|
@@ -877,7 +1048,7 @@ function App({ initialConfig, scope }) {
|
|
|
877
1048
|
};
|
|
878
1049
|
const renderPreview = () => {
|
|
879
1050
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
880
|
-
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Live Preview" }) }),
|
|
1051
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F441}\uFE0F Live Preview" }) }),
|
|
881
1052
|
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [
|
|
882
1053
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
883
1054
|
"Theme: ",
|
|
@@ -901,11 +1072,11 @@ function App({ initialConfig, scope }) {
|
|
|
901
1072
|
const installed = isInstalledInClaude();
|
|
902
1073
|
const currentCmd = getCurrentClaudeCommand();
|
|
903
1074
|
const items = [
|
|
904
|
-
{ label: installed ? "Update Installation" : "Install to Claude Code", value: "install" },
|
|
905
|
-
{ label: "Back", value: "back" }
|
|
1075
|
+
{ label: installed ? "\u{1F504} Update Installation" : "\u{1F4E5} Install to Claude Code", value: "install" },
|
|
1076
|
+
{ label: "\u2B05\uFE0F Back", value: "back" }
|
|
906
1077
|
];
|
|
907
1078
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
908
|
-
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Claude Code Integration" }) }),
|
|
1079
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F4E6} Claude Code Integration" }) }),
|
|
909
1080
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, flexDirection: "column", children: installed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
910
1081
|
/* @__PURE__ */ jsx(Text, { color: "green", children: "Status: Installed" }),
|
|
911
1082
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
@@ -946,7 +1117,7 @@ function App({ initialConfig, scope }) {
|
|
|
946
1117
|
] });
|
|
947
1118
|
}
|
|
948
1119
|
async function launchTui(scope) {
|
|
949
|
-
const config = await
|
|
1120
|
+
const config = await loadConfigForScope(scope);
|
|
950
1121
|
const { waitUntilExit } = render(/* @__PURE__ */ jsx(App, { initialConfig: config, scope }));
|
|
951
1122
|
await waitUntilExit();
|
|
952
1123
|
}
|
|
@@ -1006,6 +1177,21 @@ var StatusInputSchema = z.object({
|
|
|
1006
1177
|
cache_creation_input_tokens: z.number().optional(),
|
|
1007
1178
|
cache_read_input_tokens: z.number().optional()
|
|
1008
1179
|
}).nullable().optional()
|
|
1180
|
+
}).optional(),
|
|
1181
|
+
// Session usage and rate limit information
|
|
1182
|
+
session_usage: z.object({
|
|
1183
|
+
// Number of requests/messages used in current session
|
|
1184
|
+
requests_used: z.number().optional(),
|
|
1185
|
+
// Maximum requests allowed in the session period
|
|
1186
|
+
requests_limit: z.number().optional(),
|
|
1187
|
+
// Percentage of session usage (0-100)
|
|
1188
|
+
usage_percentage: z.number().optional(),
|
|
1189
|
+
// ISO timestamp when the usage limit resets
|
|
1190
|
+
reset_at: z.string().optional(),
|
|
1191
|
+
// Seconds until reset
|
|
1192
|
+
reset_in_seconds: z.number().optional(),
|
|
1193
|
+
// Plan/tier name (e.g., "Pro", "Free", "Max")
|
|
1194
|
+
plan: z.string().optional()
|
|
1009
1195
|
}).optional()
|
|
1010
1196
|
}).passthrough();
|
|
1011
1197
|
function parseStatusInput(input) {
|
|
@@ -1051,10 +1237,10 @@ init_formatter();
|
|
|
1051
1237
|
init_themes();
|
|
1052
1238
|
init_claude();
|
|
1053
1239
|
init_defaults();
|
|
1054
|
-
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as
|
|
1240
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync4 } from "fs";
|
|
1055
1241
|
import { dirname as dirname3 } from "path";
|
|
1056
1242
|
var program = new Command();
|
|
1057
|
-
program.name("ccsl").description("Customizable status line formatter for Claude Code CLI").version("
|
|
1243
|
+
program.name("ccsl").description("Customizable status line formatter for Claude Code CLI").version("0.0.1");
|
|
1058
1244
|
program.command("install").description("Install ccsl to Claude Code settings.json").option("-c, --command <cmd>", "Custom command to use", "npx @vimukthid/ccsl").action(async (options) => {
|
|
1059
1245
|
console.log("\nInstalling ccsl to Claude Code...\n");
|
|
1060
1246
|
if (isInstalledInClaude()) {
|
|
@@ -1162,7 +1348,7 @@ Error: Unknown theme '${themeName}'`);
|
|
|
1162
1348
|
config.theme = themeName;
|
|
1163
1349
|
try {
|
|
1164
1350
|
const dir = dirname3(configPath);
|
|
1165
|
-
if (!
|
|
1351
|
+
if (!existsSync4(dir)) {
|
|
1166
1352
|
mkdirSync3(dir, { recursive: true });
|
|
1167
1353
|
}
|
|
1168
1354
|
writeFileSync3(configPath, JSON.stringify(config, null, 2));
|
|
@@ -1199,7 +1385,7 @@ async function previewConfig() {
|
|
|
1199
1385
|
}
|
|
1200
1386
|
async function initConfig(scope) {
|
|
1201
1387
|
const configPath = getConfigPath(scope);
|
|
1202
|
-
if (
|
|
1388
|
+
if (existsSync4(configPath)) {
|
|
1203
1389
|
console.log(`
|
|
1204
1390
|
Config file already exists at ${configPath}
|
|
1205
1391
|
`);
|
|
@@ -1207,7 +1393,7 @@ Config file already exists at ${configPath}
|
|
|
1207
1393
|
}
|
|
1208
1394
|
try {
|
|
1209
1395
|
const dir = dirname3(configPath);
|
|
1210
|
-
if (!
|
|
1396
|
+
if (!existsSync4(dir)) {
|
|
1211
1397
|
mkdirSync3(dir, { recursive: true });
|
|
1212
1398
|
}
|
|
1213
1399
|
writeFileSync3(configPath, JSON.stringify(defaultConfig, null, 2));
|