ccstatusline-usage 2.3.10 → 2.3.11

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
@@ -47,6 +47,7 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
47
47
  ![Demo](https://raw.githubusercontent.com/sirmalloc/ccstatusline/main/screenshots/demo.gif)
48
48
 
49
49
  </div>
50
+ <br />
50
51
 
51
52
  ## 📚 Table of Contents
52
53
 
@@ -54,19 +55,22 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
54
55
  - [Features](#-features)
55
56
  - [Localizations](#-localizations)
56
57
  - [Quick Start](#-quick-start)
57
- - [Windows Support](#-windows-support)
58
- - [Usage](#-usage)
59
- - [API Documentation](#-api-documentation)
60
- - [Development](#️-development)
58
+ - [Windows Support](docs/WINDOWS.md)
59
+ - [Usage](docs/USAGE.md)
60
+ - [Development](docs/DEVELOPMENT.md)
61
61
  - [Contributing](#-contributing)
62
62
  - [Uninstall](#️-uninstall)
63
63
  - [License](#-license)
64
64
  - [Related Projects](#-related-projects)
65
65
 
66
- ---
66
+ <br />
67
67
 
68
68
  ## 🆕 Recent Updates
69
69
 
70
+ ### [v2.3.11](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.11) - Fix dual-cache drift between Weekly Usage and Weekly Pace
71
+
72
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Unified usage data source** — Session Usage, Weekly Usage, and Reset Timer widgets now read from the shared `context.usageData` pipeline instead of maintaining a separate API cache. Previously, around the weekly reset boundary the two caches could drift and show contradictory data (e.g. `Weekly: 99%` alongside `Pace: D1/7 +2%`). Deleted ~330 lines of duplicate fetching/caching infrastructure from `ApiUsage.tsx` (556 → 227 lines). Upstream merge: #278 (JSONL token overcounting fix), #283 (model display name parenthetical strip — integrated into fork's existing `[1m]`-aware display logic).
73
+
70
74
  ### [v2.3.10](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.10) - Extra usage on session limit, fix empty separator for null widgets
71
75
 
72
76
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Extra usage on session limit** — Reset Timer now shows extra usage spending when session limit reaches 100% (not just weekly limit or charged 1M model).
@@ -182,6 +186,10 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
182
186
  - **🔗 Git widget link modes (v2.2.6)** - `Git Branch` can render clickable GitHub branch links, and `Git Root Dir` can render clickable IDE links for VS Code and Cursor.
183
187
  - **🤝 Better subagent-aware speed reporting** - Token speed calculations continue to include referenced subagent activity so displayed speeds better reflect actual concurrent work.
184
188
 
189
+ <br />
190
+ <details>
191
+ <summary><b>Older updates (v2.1.10 and earlier)</b></summary>
192
+
185
193
  ### v2.1.0 - v2.1.10 - Usage widgets, links, new git insertions / deletions widgets, and reliability fixes
186
194
 
187
195
  - **🧩 New Usage widgets (v2.1.0)** - Added **Session Usage**, **Weekly Usage**, **Block Reset Timer**, and **Context Bar** widgets.
@@ -278,7 +286,9 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
278
286
  - **🔤 Custom Separators** - Add multiple Powerline separators with custom hex codes for font support
279
287
  - **🚀 Auto Font Install** - Automatic Powerline font installation with user consent
280
288
 
281
- ---
289
+ </details>
290
+
291
+ <br />
282
292
 
283
293
  ## ✨ Features
284
294
 
@@ -290,13 +300,13 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
290
300
  - **📐 Multi-line Support** - Configure multiple independent status lines
291
301
  - **🖥️ Interactive TUI** - Built-in configuration interface using React/Ink
292
302
  - **🔎 Fast Widget Picker** - Add/change widgets by category with search and ranked matching
293
- - **⚙️ Global Options** - Apply consistent formatting across all widgets (padding, separators, bold, background)
303
+ - **⚙️ Global Options** - Apply consistent formatting across all widgets (padding, separators, bold, minimalist mode, and color overrides)
294
304
  - **🚀 Cross-platform** - Works seamlessly with both Bun and Node.js
295
305
  - **🔧 Flexible Configuration** - Supports custom Claude Code config directory via `CLAUDE_CONFIG_DIR` environment variable
296
306
  - **📏 Smart Width Detection** - Automatically adapts to terminal width with flex separators
297
307
  - **⚡ Zero Config** - Sensible defaults that work out of the box
298
308
 
299
- ---
309
+ <br />
300
310
 
301
311
  ## 🌐 Localizations
302
312
 
@@ -304,7 +314,7 @@ The localizations in this section are third-party forks maintained outside this
304
314
 
305
315
  - 🌏 **中文版 (Chinese):** [ccstatusline-zh](https://github.com/huangguang1999/ccstatusline-zh)
306
316
 
307
- ---
317
+ <br />
308
318
 
309
319
  ## 🚀 Quick Start
310
320
 
@@ -318,7 +328,9 @@ npx -y ccstatusline-usage@latest
318
328
  bunx -y ccstatusline-usage@latest
319
329
  ```
320
330
 
321
- ### Configure ccstatusline
331
+ <br />
332
+ <details>
333
+ <summary><b>Configure ccstatusline</b></summary>
322
334
 
323
335
  The interactive configuration tool provides a terminal UI where you can:
324
336
  - Configure multiple separate status lines
@@ -335,14 +347,16 @@ The interactive configuration tool provides a terminal UI where you can:
335
347
  > ```bash
336
348
  > # Linux/macOS
337
349
  > export CLAUDE_CONFIG_DIR=/custom/path/to/.claude
338
- >
339
- > # Windows PowerShell
340
- > $env:CLAUDE_CONFIG_DIR="C:\custom\path\.claude"
341
350
  > ```
342
351
 
343
352
  > 🌐 **Usage API proxy:** Usage widgets honor the uppercase `HTTPS_PROXY` environment variable for their direct API call to Anthropic.
344
353
 
345
- ### Claude Code settings.json format
354
+ > 🪟 **Windows Support:** PowerShell examples, installation notes, fonts, troubleshooting, WSL, and Windows Terminal configuration are in [docs/WINDOWS.md](docs/WINDOWS.md).
355
+
356
+ </details>
357
+
358
+ <details>
359
+ <summary><b>Claude Code settings.json format</b></summary>
346
360
 
347
361
  When you install from the TUI, ccstatusline writes a `statusLine` command object to your Claude Code settings:
348
362
 
@@ -894,7 +908,6 @@ Contributions are welcome! Please feel free to submit a Pull Request.
894
908
  4. Push to the branch (`git push origin feature/amazing-feature`)
895
909
  5. Open a Pull Request
896
910
 
897
- ---
898
911
 
899
912
  ## 🗑️ Uninstall
900
913
 
@@ -904,13 +917,11 @@ rm -rf ~/.npm/_npx ~/.config/ccstatusline ~/.cache/ccstatusline*
904
917
  jq 'del(.statusLine)' ~/.claude/settings.json > /tmp/cs.json && cat /tmp/cs.json > ~/.claude/settings.json
905
918
  ```
906
919
 
907
- ---
908
920
 
909
921
  ## 📄 License
910
922
 
911
923
  [MIT](LICENSE) © Matthew Breedlove
912
924
 
913
- ---
914
925
 
915
926
  ## 👤 Author
916
927
 
@@ -930,7 +941,6 @@ jq 'del(.statusLine)' ~/.claude/settings.json > /tmp/cs.json && cat /tmp/cs.json
930
941
  - [ccusage](https://github.com/ryoppippi/ccusage) - Track and display Claude Code usage metrics.
931
942
  - [codachi](https://github.com/vincent-k2026/codachi) - A tamagotchi-style statusline pet that grows with your context window.
932
943
 
933
- ---
934
944
 
935
945
  ## 🙏 Acknowledgments
936
946
 
@@ -938,7 +948,7 @@ jq 'del(.statusLine)' ~/.claude/settings.json > /tmp/cs.json && cat /tmp/cs.json
938
948
  - Powered by [Ink](https://github.com/vadimdemedes/ink) for the terminal UI
939
949
  - Made with ❤️ for the Claude Code community
940
950
 
941
- ---
951
+ <br />
942
952
 
943
953
  ## Star History
944
954
 
@@ -52660,7 +52660,7 @@ class ModelWidget {
52660
52660
  return null;
52661
52661
  const is1m = modelId?.includes("[1m]") ?? false;
52662
52662
  const suffix = is1m ? "[1m]" : "";
52663
- const cleanDisplayName = modelDisplayName.replace(/\[1m\]/gi, "").replace(/\(1M context\)/gi, "").trim();
52663
+ const cleanDisplayName = modelDisplayName.replace(/\[1m\]/gi, "").replace(/\s*\(.*\)$/, "").trim();
52664
52664
  const mobile = (context.terminalWidth ?? 0) > 0 && (context.terminalWidth ?? 0) < MEDIUM_THRESHOLD;
52665
52665
  if (mobile && modelId) {
52666
52666
  return `M: ${compactModelName(modelId)}${suffix}`;
@@ -55593,7 +55593,7 @@ function getTerminalWidth() {
55593
55593
  function canDetectTerminalWidth() {
55594
55594
  return probeTerminalWidth() !== null;
55595
55595
  }
55596
- var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.10";
55596
+ var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.11";
55597
55597
  var init_terminal = () => {};
55598
55598
 
55599
55599
  // src/utils/renderer.ts
@@ -61697,19 +61697,35 @@ async function getTokenMetrics(transcriptPath) {
61697
61697
  let contextLength = 0;
61698
61698
  let mostRecentMainChainEntry = null;
61699
61699
  let mostRecentTimestamp = null;
61700
+ const parsedEntries = [];
61701
+ let hasStopReasonField = false;
61700
61702
  for (const line of lines) {
61701
61703
  const data = parseJsonlLine(line);
61702
61704
  if (data?.message?.usage) {
61703
- inputTokens += data.message.usage.input_tokens || 0;
61704
- outputTokens += data.message.usage.output_tokens || 0;
61705
- cachedTokens += data.message.usage.cache_read_input_tokens ?? 0;
61706
- cachedTokens += data.message.usage.cache_creation_input_tokens ?? 0;
61707
- if (data.isSidechain !== true && data.timestamp && !data.isApiErrorMessage) {
61708
- const entryTime = new Date(data.timestamp);
61709
- if (!mostRecentTimestamp || entryTime > mostRecentTimestamp) {
61710
- mostRecentTimestamp = entryTime;
61711
- mostRecentMainChainEntry = data;
61712
- }
61705
+ parsedEntries.push(data);
61706
+ if (Object.hasOwn(data.message, "stop_reason")) {
61707
+ hasStopReasonField = true;
61708
+ }
61709
+ }
61710
+ }
61711
+ const entriesToCount = hasStopReasonField ? parsedEntries.filter((data, index) => {
61712
+ const stopReason = data.message?.stop_reason;
61713
+ return Boolean(stopReason) || stopReason === null && index === parsedEntries.length - 1;
61714
+ }) : parsedEntries;
61715
+ for (const data of entriesToCount) {
61716
+ const usage = data.message?.usage;
61717
+ if (!usage) {
61718
+ continue;
61719
+ }
61720
+ inputTokens += usage.input_tokens || 0;
61721
+ outputTokens += usage.output_tokens || 0;
61722
+ cachedTokens += usage.cache_read_input_tokens ?? 0;
61723
+ cachedTokens += usage.cache_creation_input_tokens ?? 0;
61724
+ if (data.isSidechain !== true && data.timestamp && !data.isApiErrorMessage) {
61725
+ const entryTime = new Date(data.timestamp);
61726
+ if (!mostRecentTimestamp || entryTime > mostRecentTimestamp) {
61727
+ mostRecentTimestamp = entryTime;
61728
+ mostRecentMainChainEntry = data;
61713
61729
  }
61714
61730
  }
61715
61731
  }
@@ -63108,226 +63124,6 @@ class SessionNameWidget {
63108
63124
  var init_SessionName = () => {};
63109
63125
 
63110
63126
  // src/widgets/ApiUsage.tsx
63111
- import {
63112
- execSync as execSync5,
63113
- spawnSync
63114
- } from "child_process";
63115
- import * as fs10 from "fs";
63116
- import * as os8 from "os";
63117
- import * as path9 from "path";
63118
- function readTokenFromFile() {
63119
- try {
63120
- const creds = JSON.parse(fs10.readFileSync(CRED_FILE, "utf8"));
63121
- return creds.claudeAiOauth?.accessToken ?? null;
63122
- } catch {
63123
- return null;
63124
- }
63125
- }
63126
- function readTokenFromKeychain() {
63127
- try {
63128
- const result2 = execSync5('security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null', { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
63129
- const parsed = JSON.parse(result2);
63130
- return parsed.claudeAiOauth?.accessToken ?? null;
63131
- } catch {
63132
- return null;
63133
- }
63134
- }
63135
- function invalidateTokenCache() {
63136
- cachedToken = null;
63137
- tokenCacheTime = 0;
63138
- }
63139
- function getToken() {
63140
- const now2 = Math.floor(Date.now() / 1000);
63141
- if (cachedToken && now2 - tokenCacheTime < TOKEN_CACHE_MAX_AGE) {
63142
- return cachedToken;
63143
- }
63144
- let token = null;
63145
- if (process.platform === "darwin")
63146
- token = readTokenFromKeychain();
63147
- token ??= readTokenFromFile();
63148
- if (token) {
63149
- cachedToken = token;
63150
- tokenCacheTime = now2;
63151
- }
63152
- return token;
63153
- }
63154
- function readStaleCache() {
63155
- try {
63156
- return JSON.parse(fs10.readFileSync(CACHE_FILE2, "utf8"));
63157
- } catch {
63158
- return null;
63159
- }
63160
- }
63161
- function fetchFromApi(token) {
63162
- const script = `
63163
- const https = require('https');
63164
- const options = {
63165
- hostname: 'api.anthropic.com',
63166
- path: '/api/oauth/usage',
63167
- method: 'GET',
63168
- headers: {
63169
- 'Authorization': 'Bearer ' + process.env.TOKEN,
63170
- 'anthropic-beta': 'oauth-2025-04-20'
63171
- },
63172
- timeout: 5000
63173
- };
63174
- const req = https.request(options, (res) => {
63175
- let data = '';
63176
- res.on('data', chunk => data += chunk);
63177
- res.on('end', () => {
63178
- if (res.statusCode === 200) {
63179
- process.stdout.write(data);
63180
- } else if (res.statusCode === 401) {
63181
- process.exit(2);
63182
- } else if (res.statusCode === 429) {
63183
- process.exit(3);
63184
- } else {
63185
- process.exit(1);
63186
- }
63187
- });
63188
- });
63189
- req.on('error', () => process.exit(1));
63190
- req.on('timeout', () => { req.destroy(); process.exit(1); });
63191
- req.end();
63192
- `;
63193
- const result2 = spawnSync("node", ["-e", script], {
63194
- encoding: "utf8",
63195
- timeout: 6000,
63196
- env: { ...process.env, TOKEN: token }
63197
- });
63198
- if (result2.error || !result2.stdout) {
63199
- if (result2.status === 2)
63200
- return "auth-error";
63201
- if (result2.status === 3)
63202
- return "rate-limited";
63203
- return null;
63204
- }
63205
- if (result2.status !== 0) {
63206
- if (result2.status === 2)
63207
- return "auth-error";
63208
- if (result2.status === 3)
63209
- return "rate-limited";
63210
- return null;
63211
- }
63212
- return result2.stdout;
63213
- }
63214
- function fetchApiData() {
63215
- const now2 = Math.floor(Date.now() / 1000);
63216
- if (cachedData && !cachedData.error && now2 - cacheTime < CACHE_MAX_AGE2) {
63217
- return cachedData;
63218
- }
63219
- try {
63220
- const stat = fs10.statSync(CACHE_FILE2);
63221
- const fileAge = now2 - Math.floor(stat.mtimeMs / 1000);
63222
- if (fileAge < CACHE_MAX_AGE2) {
63223
- const fileData = JSON.parse(fs10.readFileSync(CACHE_FILE2, "utf8"));
63224
- if (!fileData.error) {
63225
- cachedData = fileData;
63226
- cacheTime = now2;
63227
- return fileData;
63228
- }
63229
- }
63230
- } catch {}
63231
- try {
63232
- const lockStat = fs10.statSync(LOCK_FILE2);
63233
- const lockAge = now2 - Math.floor(lockStat.mtimeMs / 1000);
63234
- if (lockAge < LOCK_MAX_AGE2) {
63235
- const stale = readStaleCache();
63236
- if (stale && !stale.error)
63237
- return stale;
63238
- return { error: "timeout" };
63239
- }
63240
- } catch {}
63241
- try {
63242
- const lockDir = path9.dirname(LOCK_FILE2);
63243
- if (!fs10.existsSync(lockDir)) {
63244
- fs10.mkdirSync(lockDir, { recursive: true });
63245
- }
63246
- fs10.writeFileSync(LOCK_FILE2, "");
63247
- } catch {}
63248
- const token = getToken();
63249
- if (!token) {
63250
- const stale = readStaleCache();
63251
- if (stale && !stale.error)
63252
- return stale;
63253
- return { error: "no-credentials" };
63254
- }
63255
- try {
63256
- const response = fetchFromApi(token);
63257
- if (response === "auth-error") {
63258
- invalidateTokenCache();
63259
- const stale = readStaleCache();
63260
- if (stale && !stale.error)
63261
- return stale;
63262
- return { error: "api-error" };
63263
- }
63264
- if (response === "rate-limited") {
63265
- try {
63266
- const futureTime = new Date(Date.now() + 90000);
63267
- fs10.utimesSync(LOCK_FILE2, futureTime, futureTime);
63268
- } catch {}
63269
- const stale = readStaleCache();
63270
- if (stale && !stale.error)
63271
- return stale;
63272
- return { error: "timeout" };
63273
- }
63274
- if (!response) {
63275
- const stale = readStaleCache();
63276
- if (stale && !stale.error)
63277
- return stale;
63278
- return { error: "api-error" };
63279
- }
63280
- const data = JSON.parse(response);
63281
- const apiData = {};
63282
- if (data.five_hour) {
63283
- apiData.sessionUsage = data.five_hour.utilization;
63284
- apiData.sessionResetAt = data.five_hour.resets_at;
63285
- }
63286
- if (data.seven_day) {
63287
- apiData.weeklyUsage = data.seven_day.utilization;
63288
- }
63289
- if (data.extra_usage) {
63290
- apiData.extraUsageEnabled = data.extra_usage.is_enabled === true;
63291
- apiData.extraUsageLimit = data.extra_usage.monthly_limit;
63292
- apiData.extraUsageUsed = data.extra_usage.used_credits;
63293
- apiData.extraUsageUtilization = data.extra_usage.utilization;
63294
- }
63295
- if (apiData.sessionUsage === undefined && apiData.weeklyUsage === undefined) {
63296
- const stale = readStaleCache();
63297
- if (stale && !stale.error)
63298
- return stale;
63299
- return { error: "parse-error" };
63300
- }
63301
- apiData.fetchedAt = now2;
63302
- try {
63303
- const cacheDir = path9.dirname(CACHE_FILE2);
63304
- if (!fs10.existsSync(cacheDir)) {
63305
- fs10.mkdirSync(cacheDir, { recursive: true });
63306
- }
63307
- fs10.writeFileSync(CACHE_FILE2, JSON.stringify(apiData));
63308
- } catch {}
63309
- cachedData = apiData;
63310
- cacheTime = now2;
63311
- return apiData;
63312
- } catch {
63313
- const stale = readStaleCache();
63314
- if (stale && !stale.error)
63315
- return stale;
63316
- return { error: "parse-error" };
63317
- }
63318
- }
63319
- function getErrorMessage(error48) {
63320
- switch (error48) {
63321
- case "no-credentials":
63322
- return "[No credentials]";
63323
- case "timeout":
63324
- return "[Timeout]";
63325
- case "api-error":
63326
- return "[API Error]";
63327
- case "parse-error":
63328
- return "[Parse Error]";
63329
- }
63330
- }
63331
63127
  function getDisplaySize(context) {
63332
63128
  const w = context.terminalWidth ?? 0;
63333
63129
  if (w > 0 && w < MOBILE_THRESHOLD)
@@ -63352,6 +63148,18 @@ function formatUsageBar(label, shortLabel, percent, size2) {
63352
63148
  const bar = makeProgressBar(percent, getBarWidth(size2));
63353
63149
  return `${size2 === "mobile" ? shortLabel : label}: ${bar} ${percent.toFixed(1)}%`;
63354
63150
  }
63151
+ function getCurrencySymbol() {
63152
+ try {
63153
+ const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
63154
+ if (tz.startsWith("Europe/"))
63155
+ return "€";
63156
+ } catch {}
63157
+ return "$";
63158
+ }
63159
+ function formatCents(cents) {
63160
+ const symbol2 = getCurrencySymbol();
63161
+ return `${symbol2}${(cents / 100).toFixed(2)}`;
63162
+ }
63355
63163
 
63356
63164
  class SessionUsageWidget {
63357
63165
  getDefaultColor() {
@@ -63366,15 +63174,15 @@ class SessionUsageWidget {
63366
63174
  getCategory() {
63367
63175
  return "API Usage";
63368
63176
  }
63369
- getEditorDisplay(item) {
63177
+ getEditorDisplay(_item) {
63370
63178
  return { displayText: this.getDisplayName() };
63371
63179
  }
63372
- render(item, context, settings) {
63180
+ render(_item, context, _settings) {
63373
63181
  if (context.isPreview)
63374
63182
  return "Session: [███░░░░░░░░░░░░] 20%";
63375
- const data = fetchApiData();
63183
+ const data = context.usageData ?? {};
63376
63184
  if (data.error)
63377
- return getErrorMessage(data.error);
63185
+ return getUsageErrorMessage(data.error);
63378
63186
  if (data.sessionUsage === undefined)
63379
63187
  return null;
63380
63188
  return formatUsageBar("Session", "S", data.sessionUsage, getDisplaySize(context));
@@ -63382,7 +63190,7 @@ class SessionUsageWidget {
63382
63190
  supportsRawValue() {
63383
63191
  return false;
63384
63192
  }
63385
- supportsColors(item) {
63193
+ supportsColors(_item) {
63386
63194
  return true;
63387
63195
  }
63388
63196
  }
@@ -63400,15 +63208,15 @@ class WeeklyUsageWidget {
63400
63208
  getCategory() {
63401
63209
  return "API Usage";
63402
63210
  }
63403
- getEditorDisplay(item) {
63211
+ getEditorDisplay(_item) {
63404
63212
  return { displayText: this.getDisplayName() };
63405
63213
  }
63406
- render(item, context, settings) {
63214
+ render(_item, context, _settings) {
63407
63215
  if (context.isPreview)
63408
63216
  return "Weekly: [██░░░░░░░░░░░░░] 12%";
63409
- const data = fetchApiData();
63217
+ const data = context.usageData ?? {};
63410
63218
  if (data.error)
63411
- return getErrorMessage(data.error);
63219
+ return getUsageErrorMessage(data.error);
63412
63220
  if (data.weeklyUsage === undefined)
63413
63221
  return null;
63414
63222
  return formatUsageBar("Weekly", "W", data.weeklyUsage, getDisplaySize(context));
@@ -63416,7 +63224,7 @@ class WeeklyUsageWidget {
63416
63224
  supportsRawValue() {
63417
63225
  return false;
63418
63226
  }
63419
- supportsColors(item) {
63227
+ supportsColors(_item) {
63420
63228
  return true;
63421
63229
  }
63422
63230
  }
@@ -63434,15 +63242,15 @@ class ResetTimerWidget {
63434
63242
  getCategory() {
63435
63243
  return "API Usage";
63436
63244
  }
63437
- getEditorDisplay(item) {
63245
+ getEditorDisplay(_item) {
63438
63246
  return { displayText: this.getDisplayName() };
63439
63247
  }
63440
- render(item, context, settings) {
63248
+ render(_item, context, settings) {
63441
63249
  if (context.isPreview)
63442
63250
  return "4:30 hr";
63443
- const data = fetchApiData();
63251
+ const data = context.usageData ?? {};
63444
63252
  if (data.error)
63445
- return getErrorMessage(data.error);
63253
+ return getUsageErrorMessage(data.error);
63446
63254
  const model = context.data?.model;
63447
63255
  const modelId = (typeof model === "string" ? model : model?.id) ?? "";
63448
63256
  const is1mModel = modelId.includes("[1m]");
@@ -63472,22 +63280,10 @@ class ResetTimerWidget {
63472
63280
  supportsRawValue() {
63473
63281
  return false;
63474
63282
  }
63475
- supportsColors(item) {
63283
+ supportsColors(_item) {
63476
63284
  return true;
63477
63285
  }
63478
63286
  }
63479
- function getCurrencySymbol() {
63480
- try {
63481
- const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
63482
- if (tz.startsWith("Europe/"))
63483
- return "€";
63484
- } catch {}
63485
- return "$";
63486
- }
63487
- function formatCents(cents) {
63488
- const symbol2 = getCurrencySymbol();
63489
- return `${symbol2}${(cents / 100).toFixed(2)}`;
63490
- }
63491
63287
 
63492
63288
  class ContextBarWidget {
63493
63289
  getDefaultColor() {
@@ -63502,10 +63298,10 @@ class ContextBarWidget {
63502
63298
  getCategory() {
63503
63299
  return "API Usage";
63504
63300
  }
63505
- getEditorDisplay(item) {
63301
+ getEditorDisplay(_item) {
63506
63302
  return { displayText: this.getDisplayName() };
63507
63303
  }
63508
- render(item, context, settings) {
63304
+ render(_item, context, _settings) {
63509
63305
  if (context.isPreview)
63510
63306
  return "Context: [████░░░░░░░░░░░] 50k/200k (25%)";
63511
63307
  const cw = context.data?.context_window;
@@ -63533,15 +63329,13 @@ class ContextBarWidget {
63533
63329
  supportsRawValue() {
63534
63330
  return false;
63535
63331
  }
63536
- supportsColors(item) {
63332
+ supportsColors(_item) {
63537
63333
  return true;
63538
63334
  }
63539
63335
  }
63540
- var CACHE_FILE2, LOCK_FILE2, CACHE_MAX_AGE2 = 600, LOCK_MAX_AGE2 = 60, TOKEN_CACHE_MAX_AGE = 3600, cachedData = null, cacheTime = 0, cachedToken = null, tokenCacheTime = 0, CRED_FILE, MOBILE_THRESHOLD = 134, MEDIUM_THRESHOLD2 = 178, MOBILE_BAR_WIDTH = 4, MEDIUM_BAR_WIDTH = 8, DEFAULT_BAR_WIDTH = 15;
63336
+ var MOBILE_THRESHOLD = 134, MEDIUM_THRESHOLD2 = 178, MOBILE_BAR_WIDTH = 4, MEDIUM_BAR_WIDTH = 8, DEFAULT_BAR_WIDTH = 15;
63541
63337
  var init_ApiUsage = __esm(() => {
63542
- CACHE_FILE2 = path9.join(os8.homedir(), ".cache", "ccstatusline-api.json");
63543
- LOCK_FILE2 = path9.join(os8.homedir(), ".cache", "ccstatusline-api.lock");
63544
- CRED_FILE = path9.join(os8.homedir(), ".claude", ".credentials.json");
63338
+ init_usage();
63545
63339
  });
63546
63340
 
63547
63341
  // src/widgets/WeeklyResetTimer.ts
@@ -64118,11 +63912,11 @@ var init_ThinkingEffort = __esm(() => {
64118
63912
  });
64119
63913
 
64120
63914
  // src/widgets/Battery.ts
64121
- import { execSync as execSync6 } from "child_process";
64122
- import { readFileSync as readFileSync12 } from "fs";
63915
+ import { execSync as execSync5 } from "child_process";
63916
+ import { readFileSync as readFileSync11 } from "fs";
64123
63917
  function getMacBatteryInfo() {
64124
63918
  try {
64125
- const output = execSync6("pmset -g batt", { encoding: "utf-8", timeout: 2000 });
63919
+ const output = execSync5("pmset -g batt", { encoding: "utf-8", timeout: 2000 });
64126
63920
  const match = /(\d+)%;\s*(charging|discharging|charged|finishing charge|AC attached)/i.exec(output);
64127
63921
  const percentStr = match?.[1];
64128
63922
  const stateStr = match?.[2];
@@ -64139,8 +63933,8 @@ function getMacBatteryInfo() {
64139
63933
  }
64140
63934
  function getLinuxBatteryInfo() {
64141
63935
  try {
64142
- const capacity = readFileSync12("/sys/class/power_supply/BAT0/capacity", "utf-8").trim();
64143
- const status = readFileSync12("/sys/class/power_supply/BAT0/status", "utf-8").trim().toLowerCase();
63936
+ const capacity = readFileSync11("/sys/class/power_supply/BAT0/capacity", "utf-8").trim();
63937
+ const status = readFileSync11("/sys/class/power_supply/BAT0/status", "utf-8").trim().toLowerCase();
64144
63938
  const percent = parseInt(capacity, 10);
64145
63939
  if (isNaN(percent)) {
64146
63940
  return null;
@@ -65123,11 +64917,11 @@ var init_hooks = __esm(async () => {
65123
64917
  });
65124
64918
 
65125
64919
  // src/utils/config.ts
65126
- import * as fs11 from "fs";
65127
- import * as os9 from "os";
65128
- import * as path10 from "path";
64920
+ import * as fs10 from "fs";
64921
+ import * as os8 from "os";
64922
+ import * as path9 from "path";
65129
64923
  function initConfigPath(filePath) {
65130
- settingsPath = filePath ? path10.resolve(filePath) : DEFAULT_SETTINGS_PATH;
64924
+ settingsPath = filePath ? path9.resolve(filePath) : DEFAULT_SETTINGS_PATH;
65131
64925
  }
65132
64926
  function getConfigPath() {
65133
64927
  return settingsPath;
@@ -65136,13 +64930,13 @@ function isCustomConfigPath() {
65136
64930
  return settingsPath !== DEFAULT_SETTINGS_PATH;
65137
64931
  }
65138
64932
  function getSettingsPaths() {
65139
- const configDir = path10.dirname(settingsPath);
65140
- const parsedPath = path10.parse(settingsPath);
64933
+ const configDir = path9.dirname(settingsPath);
64934
+ const parsedPath = path9.parse(settingsPath);
65141
64935
  const backupBaseName = parsedPath.ext ? `${parsedPath.name}.bak` : `${parsedPath.base}.bak`;
65142
64936
  return {
65143
64937
  configDir,
65144
64938
  settingsPath,
65145
- settingsBackupPath: path10.join(configDir, backupBaseName)
64939
+ settingsBackupPath: path9.join(configDir, backupBaseName)
65146
64940
  };
65147
64941
  }
65148
64942
  async function ensureDir(dir) {
@@ -65159,7 +64953,7 @@ async function writeSettingsJson(settings, paths) {
65159
64953
  }
65160
64954
  async function backupBadSettings(paths) {
65161
64955
  try {
65162
- if (fs11.existsSync(paths.settingsPath)) {
64956
+ if (fs10.existsSync(paths.settingsPath)) {
65163
64957
  const content = await readFile3(paths.settingsPath, "utf-8");
65164
64958
  await writeFile(paths.settingsBackupPath, content, "utf-8");
65165
64959
  console.error(`Bad settings backed up to ${paths.settingsBackupPath}`);
@@ -65189,7 +64983,7 @@ async function recoverWithDefaults(paths) {
65189
64983
  async function loadSettings() {
65190
64984
  const paths = getSettingsPaths();
65191
64985
  try {
65192
- if (!fs11.existsSync(paths.settingsPath))
64986
+ if (!fs10.existsSync(paths.settingsPath))
65193
64987
  return await writeDefaultSettings(paths);
65194
64988
  const content = await readFile3(paths.settingsPath, "utf-8");
65195
64989
  let rawData;
@@ -65239,18 +65033,18 @@ var readFile3, writeFile, mkdir, DEFAULT_SETTINGS_PATH, settingsPath;
65239
65033
  var init_config = __esm(() => {
65240
65034
  init_Settings();
65241
65035
  init_migrations();
65242
- readFile3 = fs11.promises.readFile;
65243
- writeFile = fs11.promises.writeFile;
65244
- mkdir = fs11.promises.mkdir;
65245
- DEFAULT_SETTINGS_PATH = path10.join(os9.homedir(), ".config", "ccstatusline", "settings.json");
65036
+ readFile3 = fs10.promises.readFile;
65037
+ writeFile = fs10.promises.writeFile;
65038
+ mkdir = fs10.promises.mkdir;
65039
+ DEFAULT_SETTINGS_PATH = path9.join(os8.homedir(), ".config", "ccstatusline", "settings.json");
65246
65040
  settingsPath = DEFAULT_SETTINGS_PATH;
65247
65041
  });
65248
65042
 
65249
65043
  // src/utils/claude-settings.ts
65250
- import { execSync as execSync7 } from "child_process";
65251
- import * as fs12 from "fs";
65252
- import * as os10 from "os";
65253
- import * as path11 from "path";
65044
+ import { execSync as execSync6 } from "child_process";
65045
+ import * as fs11 from "fs";
65046
+ import * as os9 from "os";
65047
+ import * as path10 from "path";
65254
65048
  function isKnownCommand(command) {
65255
65049
  const prefixes = [CCSTATUSLINE_COMMANDS.NPM, CCSTATUSLINE_COMMANDS.BUNX, CCSTATUSLINE_COMMANDS.SELF_MANAGED];
65256
65050
  return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `));
@@ -65274,9 +65068,9 @@ function getClaudeConfigDir() {
65274
65068
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
65275
65069
  if (envConfigDir) {
65276
65070
  try {
65277
- const resolvedPath = path11.resolve(envConfigDir);
65278
- if (fs12.existsSync(resolvedPath)) {
65279
- const stats = fs12.statSync(resolvedPath);
65071
+ const resolvedPath = path10.resolve(envConfigDir);
65072
+ if (fs11.existsSync(resolvedPath)) {
65073
+ const stats = fs11.statSync(resolvedPath);
65280
65074
  if (stats.isDirectory()) {
65281
65075
  return resolvedPath;
65282
65076
  }
@@ -65285,16 +65079,16 @@ function getClaudeConfigDir() {
65285
65079
  }
65286
65080
  } catch {}
65287
65081
  }
65288
- return path11.join(os10.homedir(), ".claude");
65082
+ return path10.join(os9.homedir(), ".claude");
65289
65083
  }
65290
65084
  function getClaudeSettingsPath() {
65291
- return path11.join(getClaudeConfigDir(), "settings.json");
65085
+ return path10.join(getClaudeConfigDir(), "settings.json");
65292
65086
  }
65293
65087
  async function backupClaudeSettings(suffix = ".bak") {
65294
65088
  const settingsPath2 = getClaudeSettingsPath();
65295
65089
  const backupPath = settingsPath2 + suffix;
65296
65090
  try {
65297
- if (fs12.existsSync(settingsPath2)) {
65091
+ if (fs11.existsSync(settingsPath2)) {
65298
65092
  const content = await readFile4(settingsPath2, "utf-8");
65299
65093
  await writeFile2(backupPath, content, "utf-8");
65300
65094
  return backupPath;
@@ -65307,11 +65101,11 @@ async function backupClaudeSettings(suffix = ".bak") {
65307
65101
  function loadClaudeSettingsSync(options = {}) {
65308
65102
  const { logErrors = true } = options;
65309
65103
  const settingsPath2 = getClaudeSettingsPath();
65310
- if (!fs12.existsSync(settingsPath2)) {
65104
+ if (!fs11.existsSync(settingsPath2)) {
65311
65105
  return {};
65312
65106
  }
65313
65107
  try {
65314
- const content = fs12.readFileSync(settingsPath2, "utf-8");
65108
+ const content = fs11.readFileSync(settingsPath2, "utf-8");
65315
65109
  return JSON.parse(content);
65316
65110
  } catch (error48) {
65317
65111
  if (logErrors) {
@@ -65323,7 +65117,7 @@ function loadClaudeSettingsSync(options = {}) {
65323
65117
  async function loadClaudeSettings(options = {}) {
65324
65118
  const { logErrors = true } = options;
65325
65119
  const settingsPath2 = getClaudeSettingsPath();
65326
- if (!fs12.existsSync(settingsPath2)) {
65120
+ if (!fs11.existsSync(settingsPath2)) {
65327
65121
  return {};
65328
65122
  }
65329
65123
  try {
@@ -65338,7 +65132,7 @@ async function loadClaudeSettings(options = {}) {
65338
65132
  }
65339
65133
  async function saveClaudeSettings(settings) {
65340
65134
  const settingsPath2 = getClaudeSettingsPath();
65341
- const dir = path11.dirname(settingsPath2);
65135
+ const dir = path10.dirname(settingsPath2);
65342
65136
  await backupClaudeSettings();
65343
65137
  await ensureDir(dir);
65344
65138
  await writeFile2(settingsPath2, JSON.stringify(settings, null, 2), "utf-8");
@@ -65356,7 +65150,7 @@ async function isInstalled() {
65356
65150
  function isBunxAvailable() {
65357
65151
  try {
65358
65152
  const command = process.platform === "win32" ? "where bunx" : "which bunx";
65359
- execSync7(command, { stdio: "ignore" });
65153
+ execSync6(command, { stdio: "ignore" });
65360
65154
  return true;
65361
65155
  } catch {
65362
65156
  return false;
@@ -65370,7 +65164,7 @@ function buildCommand(baseCommand) {
65370
65164
  }
65371
65165
  async function loadSavedSettingsForHookSync() {
65372
65166
  const configPath = getConfigPath();
65373
- if (!fs12.existsSync(configPath)) {
65167
+ if (!fs11.existsSync(configPath)) {
65374
65168
  return null;
65375
65169
  }
65376
65170
  try {
@@ -65437,8 +65231,8 @@ var readFile4, writeFile2, CCSTATUSLINE_COMMANDS;
65437
65231
  var init_claude_settings = __esm(() => {
65438
65232
  init_Settings();
65439
65233
  init_config();
65440
- readFile4 = fs12.promises.readFile;
65441
- writeFile2 = fs12.promises.writeFile;
65234
+ readFile4 = fs11.promises.readFile;
65235
+ writeFile2 = fs11.promises.writeFile;
65442
65236
  CCSTATUSLINE_COMMANDS = {
65443
65237
  NPM: "npx -y ccstatusline-usage@latest",
65444
65238
  BUNX: "bunx -y ccstatusline-usage@latest",
@@ -66031,10 +65825,10 @@ function cloneSettings(settings) {
66031
65825
  init_config();
66032
65826
 
66033
65827
  // src/utils/open-url.ts
66034
- import { spawnSync as spawnSync2 } from "child_process";
66035
- import * as os11 from "os";
65828
+ import { spawnSync } from "child_process";
65829
+ import * as os10 from "os";
66036
65830
  function runOpenCommand(command, args) {
66037
- const result2 = spawnSync2(command, args, {
65831
+ const result2 = spawnSync(command, args, {
66038
65832
  stdio: "ignore",
66039
65833
  windowsHide: true
66040
65834
  });
@@ -66091,7 +65885,7 @@ function openExternalUrl(url2) {
66091
65885
  error: "Only http(s) URLs are supported"
66092
65886
  };
66093
65887
  }
66094
- const platform3 = os11.platform();
65888
+ const platform3 = os10.platform();
66095
65889
  const plans = PLATFORM_OPEN_PLANS[platform3];
66096
65890
  if (!plans) {
66097
65891
  return {
@@ -66118,10 +65912,10 @@ function openExternalUrl(url2) {
66118
65912
  }
66119
65913
 
66120
65914
  // src/utils/powerline.ts
66121
- import { execSync as execSync8 } from "child_process";
66122
- import * as fs13 from "fs";
66123
- import * as os12 from "os";
66124
- import * as path12 from "path";
65915
+ import { execSync as execSync7 } from "child_process";
65916
+ import * as fs12 from "fs";
65917
+ import * as os11 from "os";
65918
+ import * as path11 from "path";
66125
65919
  var fontsInstalledThisSession = false;
66126
65920
  function checkPowerlineFonts() {
66127
65921
  if (process.env.DEBUG_FONT_INSTALL === "1" && !fontsInstalledThisSession) {
@@ -66137,24 +65931,24 @@ function checkPowerlineFonts() {
66137
65931
  leftArrow: "",
66138
65932
  leftThinArrow: ""
66139
65933
  };
66140
- const platform4 = os12.platform();
65934
+ const platform4 = os11.platform();
66141
65935
  let fontPaths = [];
66142
65936
  if (platform4 === "darwin") {
66143
65937
  fontPaths = [
66144
- path12.join(os12.homedir(), "Library", "Fonts"),
65938
+ path11.join(os11.homedir(), "Library", "Fonts"),
66145
65939
  "/Library/Fonts",
66146
65940
  "/System/Library/Fonts"
66147
65941
  ];
66148
65942
  } else if (platform4 === "linux") {
66149
65943
  fontPaths = [
66150
- path12.join(os12.homedir(), ".local", "share", "fonts"),
66151
- path12.join(os12.homedir(), ".fonts"),
65944
+ path11.join(os11.homedir(), ".local", "share", "fonts"),
65945
+ path11.join(os11.homedir(), ".fonts"),
66152
65946
  "/usr/share/fonts",
66153
65947
  "/usr/local/share/fonts"
66154
65948
  ];
66155
65949
  } else if (platform4 === "win32") {
66156
65950
  fontPaths = [
66157
- path12.join(os12.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
65951
+ path11.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
66158
65952
  "C:\\Windows\\Fonts"
66159
65953
  ];
66160
65954
  }
@@ -66170,9 +65964,9 @@ function checkPowerlineFonts() {
66170
65964
  /fira.*code.*nerd/i
66171
65965
  ];
66172
65966
  for (const fontPath of fontPaths) {
66173
- if (fs13.existsSync(fontPath)) {
65967
+ if (fs12.existsSync(fontPath)) {
66174
65968
  try {
66175
- const files = fs13.readdirSync(fontPath);
65969
+ const files = fs12.readdirSync(fontPath);
66176
65970
  for (const file2 of files) {
66177
65971
  for (const pattern of powerlineFontPatterns) {
66178
65972
  if (pattern.test(file2)) {
@@ -66207,7 +66001,7 @@ async function checkPowerlineFontsAsync() {
66207
66001
  if (quickCheck.installed) {
66208
66002
  return quickCheck;
66209
66003
  }
66210
- const platform4 = os12.platform();
66004
+ const platform4 = os11.platform();
66211
66005
  if (platform4 === "linux" || platform4 === "darwin") {
66212
66006
  try {
66213
66007
  const { exec: exec2 } = await import("child_process");
@@ -66230,44 +66024,44 @@ async function checkPowerlineFontsAsync() {
66230
66024
  async function installPowerlineFonts() {
66231
66025
  await Promise.resolve();
66232
66026
  try {
66233
- const platform4 = os12.platform();
66027
+ const platform4 = os11.platform();
66234
66028
  let fontDir;
66235
66029
  if (platform4 === "darwin") {
66236
- fontDir = path12.join(os12.homedir(), "Library", "Fonts");
66030
+ fontDir = path11.join(os11.homedir(), "Library", "Fonts");
66237
66031
  } else if (platform4 === "linux") {
66238
- fontDir = path12.join(os12.homedir(), ".local", "share", "fonts");
66032
+ fontDir = path11.join(os11.homedir(), ".local", "share", "fonts");
66239
66033
  } else if (platform4 === "win32") {
66240
- fontDir = path12.join(os12.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
66034
+ fontDir = path11.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
66241
66035
  } else {
66242
66036
  return {
66243
66037
  success: false,
66244
66038
  message: "Unsupported platform for font installation"
66245
66039
  };
66246
66040
  }
66247
- if (!fs13.existsSync(fontDir)) {
66248
- fs13.mkdirSync(fontDir, { recursive: true });
66041
+ if (!fs12.existsSync(fontDir)) {
66042
+ fs12.mkdirSync(fontDir, { recursive: true });
66249
66043
  }
66250
- const tempDir = path12.join(os12.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
66044
+ const tempDir = path11.join(os11.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
66251
66045
  try {
66252
- if (fs13.existsSync(tempDir)) {
66253
- fs13.rmSync(tempDir, { recursive: true, force: true });
66046
+ if (fs12.existsSync(tempDir)) {
66047
+ fs12.rmSync(tempDir, { recursive: true, force: true });
66254
66048
  }
66255
- execSync8(`git clone --depth=1 https://github.com/powerline/fonts.git "${tempDir}"`, {
66049
+ execSync7(`git clone --depth=1 https://github.com/powerline/fonts.git "${tempDir}"`, {
66256
66050
  stdio: "pipe",
66257
66051
  encoding: "utf8"
66258
66052
  });
66259
66053
  if (platform4 === "darwin" || platform4 === "linux") {
66260
- const installScript = path12.join(tempDir, "install.sh");
66261
- if (fs13.existsSync(installScript)) {
66262
- fs13.chmodSync(installScript, 493);
66263
- execSync8(`cd "${tempDir}" && ./install.sh`, {
66054
+ const installScript = path11.join(tempDir, "install.sh");
66055
+ if (fs12.existsSync(installScript)) {
66056
+ fs12.chmodSync(installScript, 493);
66057
+ execSync7(`cd "${tempDir}" && ./install.sh`, {
66264
66058
  stdio: "pipe",
66265
66059
  encoding: "utf8",
66266
66060
  shell: "/bin/bash"
66267
66061
  });
66268
66062
  if (platform4 === "linux") {
66269
66063
  try {
66270
- execSync8("fc-cache -f -v", {
66064
+ execSync7("fc-cache -f -v", {
66271
66065
  stdio: "pipe",
66272
66066
  encoding: "utf8"
66273
66067
  });
@@ -66285,10 +66079,10 @@ async function installPowerlineFonts() {
66285
66079
  }
66286
66080
  } else {
66287
66081
  let findFontFiles = function(dir) {
66288
- const files = fs13.readdirSync(dir);
66082
+ const files = fs12.readdirSync(dir);
66289
66083
  for (const file2 of files) {
66290
- const filePath = path12.join(dir, file2);
66291
- const stat = fs13.statSync(filePath);
66084
+ const filePath = path11.join(dir, file2);
66085
+ const stat = fs12.statSync(filePath);
66292
66086
  if (stat.isDirectory() && !file2.startsWith(".")) {
66293
66087
  findFontFiles(filePath);
66294
66088
  } else if (file2.endsWith(".ttf") || file2.endsWith(".otf")) {
@@ -66302,10 +66096,10 @@ async function installPowerlineFonts() {
66302
66096
  findFontFiles(tempDir);
66303
66097
  let installedCount = 0;
66304
66098
  for (const fontFile of fontFiles) {
66305
- const fileName = path12.basename(fontFile);
66306
- const destPath = path12.join(fontDir, fileName);
66099
+ const fileName = path11.basename(fontFile);
66100
+ const destPath = path11.join(fontDir, fileName);
66307
66101
  try {
66308
- fs13.copyFileSync(fontFile, destPath);
66102
+ fs12.copyFileSync(fontFile, destPath);
66309
66103
  installedCount++;
66310
66104
  } catch {}
66311
66105
  }
@@ -66323,9 +66117,9 @@ async function installPowerlineFonts() {
66323
66117
  message: "Platform-specific installation not implemented"
66324
66118
  };
66325
66119
  } finally {
66326
- if (fs13.existsSync(tempDir)) {
66120
+ if (fs12.existsSync(tempDir)) {
66327
66121
  try {
66328
- fs13.rmSync(tempDir, { recursive: true, force: true });
66122
+ fs12.rmSync(tempDir, { recursive: true, force: true });
66329
66123
  } catch {}
66330
66124
  }
66331
66125
  }
@@ -69326,7 +69120,7 @@ var MainMenu = ({
69326
69120
  // src/tui/components/PowerlineSetup.tsx
69327
69121
  await init_build2();
69328
69122
  var import_react43 = __toESM(require_react(), 1);
69329
- import * as os13 from "os";
69123
+ import * as os12 from "os";
69330
69124
 
69331
69125
  // src/utils/powerline-settings.ts
69332
69126
  init_colors();
@@ -70092,7 +69886,7 @@ var PowerlineSetup = ({
70092
69886
  }, undefined, false, undefined, this)
70093
69887
  ]
70094
69888
  }, undefined, true, undefined, this),
70095
- os13.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
69889
+ os12.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
70096
69890
  children: [
70097
69891
  /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
70098
69892
  dimColor: true,
@@ -70108,7 +69902,7 @@ var PowerlineSetup = ({
70108
69902
  }, undefined, false, undefined, this)
70109
69903
  ]
70110
69904
  }, undefined, true, undefined, this),
70111
- os13.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
69905
+ os12.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
70112
69906
  children: [
70113
69907
  /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
70114
69908
  dimColor: true,
@@ -70124,7 +69918,7 @@ var PowerlineSetup = ({
70124
69918
  }, undefined, false, undefined, this)
70125
69919
  ]
70126
69920
  }, undefined, true, undefined, this),
70127
- os13.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
69921
+ os12.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
70128
69922
  children: [
70129
69923
  /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
70130
69924
  dimColor: true,
@@ -71339,23 +71133,23 @@ init_jsonl();
71339
71133
  await init_renderer2();
71340
71134
 
71341
71135
  // src/utils/skills.ts
71342
- import * as fs14 from "fs";
71343
- import * as os14 from "os";
71344
- import * as path13 from "path";
71136
+ import * as fs13 from "fs";
71137
+ import * as os13 from "os";
71138
+ import * as path12 from "path";
71345
71139
  var EMPTY = { totalInvocations: 0, uniqueSkills: [], lastSkill: null };
71346
71140
  function getSkillsDir() {
71347
- return path13.join(os14.homedir(), ".cache", "ccstatusline", "skills");
71141
+ return path12.join(os13.homedir(), ".cache", "ccstatusline", "skills");
71348
71142
  }
71349
71143
  function getSkillsFilePath(sessionId) {
71350
- return path13.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
71144
+ return path12.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
71351
71145
  }
71352
71146
  function getSkillsMetrics(sessionId) {
71353
71147
  const filePath = getSkillsFilePath(sessionId);
71354
- if (!fs14.existsSync(filePath)) {
71148
+ if (!fs13.existsSync(filePath)) {
71355
71149
  return EMPTY;
71356
71150
  }
71357
71151
  try {
71358
- const invocations = fs14.readFileSync(filePath, "utf-8").trim().split(`
71152
+ const invocations = fs13.readFileSync(filePath, "utf-8").trim().split(`
71359
71153
  `).filter((line) => line.trim()).map((line) => {
71360
71154
  try {
71361
71155
  return JSON.parse(line);
@@ -71690,16 +71484,16 @@ async function handleHook() {
71690
71484
  return;
71691
71485
  }
71692
71486
  const filePath = getSkillsFilePath(sessionId);
71693
- const fs15 = await import("fs");
71694
- const path14 = await import("path");
71695
- fs15.mkdirSync(path14.dirname(filePath), { recursive: true });
71487
+ const fs14 = await import("fs");
71488
+ const path13 = await import("path");
71489
+ fs14.mkdirSync(path13.dirname(filePath), { recursive: true });
71696
71490
  const entry = JSON.stringify({
71697
71491
  timestamp: new Date().toISOString(),
71698
71492
  session_id: sessionId,
71699
71493
  skill: skillName,
71700
71494
  source: data.hook_event_name
71701
71495
  });
71702
- fs15.appendFileSync(filePath, entry + `
71496
+ fs14.appendFileSync(filePath, entry + `
71703
71497
  `);
71704
71498
  } catch {}
71705
71499
  console.log("{}");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.3.10",
3
+ "version": "2.3.11",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",
@@ -19,7 +19,7 @@
19
19
  "lint": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0",
20
20
  "lint:fix": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0 --fix",
21
21
  "docs": "typedoc",
22
- "docs:clean": "rm -rf docs"
22
+ "docs:clean": "rm -rf typedoc"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@eslint/js": "^10.0.1",