@vimukthid/ccsl 1.0.0 → 1.0.1

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
@@ -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 | 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` |
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 (!existsSync(settingsPath)) {
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 (!existsSync(settingsPath)) {
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 (!existsSync(dir)) {
810
+ if (!existsSync2(dir)) {
640
811
  mkdirSync(dir, { recursive: true });
641
812
  }
642
813
  let settings = {};
643
- if (existsSync(settingsPath)) {
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 (!existsSync(settingsPath)) {
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 existsSync2 } from "fs";
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 (!existsSync2(dir)) {
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 loadConfig();
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 existsSync3 } from "fs";
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("1.0.0");
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 (!existsSync3(dir)) {
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 (existsSync3(configPath)) {
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 (!existsSync3(dir)) {
1396
+ if (!existsSync4(dir)) {
1211
1397
  mkdirSync3(dir, { recursive: true });
1212
1398
  }
1213
1399
  writeFileSync3(configPath, JSON.stringify(defaultConfig, null, 2));