ccstatusline 2.2.18 → 2.2.20

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.
@@ -1355,7 +1355,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
1355
1355
  exports.useTransition = function() {
1356
1356
  return resolveDispatcher().useTransition();
1357
1357
  };
1358
- exports.version = "19.2.6";
1358
+ exports.version = "19.2.7";
1359
1359
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
1360
1360
  })();
1361
1361
  });
@@ -53062,6 +53062,7 @@ var init_Settings = __esm(() => {
53062
53062
  overrideBackgroundColor: exports_external.string().optional(),
53063
53063
  overrideForegroundColor: exports_external.string().optional(),
53064
53064
  globalBold: exports_external.boolean().default(false),
53065
+ gitCacheTtlSeconds: exports_external.number().min(0).max(60).default(5),
53065
53066
  minimalistMode: exports_external.boolean().default(false),
53066
53067
  powerline: PowerlineConfigSchema.default({
53067
53068
  enabled: false,
@@ -53519,6 +53520,175 @@ class OutputStyleWidget {
53519
53520
 
53520
53521
  // src/utils/git.ts
53521
53522
  import { execFileSync } from "child_process";
53523
+ import { createHash } from "node:crypto";
53524
+ import * as fs2 from "node:fs";
53525
+ import * as os3 from "node:os";
53526
+ import * as path from "node:path";
53527
+ function getCacheDir() {
53528
+ return path.join(os3.homedir(), ".cache", "ccstatusline");
53529
+ }
53530
+ function getCachePath(gitDir) {
53531
+ const repoHash = createHash("sha256").update(gitDir).digest("hex").slice(0, 16);
53532
+ return path.join(getCacheDir(), "git-cache", `git-${repoHash}.json`);
53533
+ }
53534
+ function getMtimeMs(filePath) {
53535
+ try {
53536
+ return fs2.statSync(filePath).mtimeMs;
53537
+ } catch {
53538
+ return null;
53539
+ }
53540
+ }
53541
+ function normalizeDirectory(candidate) {
53542
+ try {
53543
+ const resolved = path.resolve(candidate);
53544
+ const stats = fs2.statSync(resolved);
53545
+ return stats.isDirectory() ? resolved : path.dirname(resolved);
53546
+ } catch {
53547
+ return null;
53548
+ }
53549
+ }
53550
+ function readGitDirFile(gitFilePath) {
53551
+ try {
53552
+ const content = fs2.readFileSync(gitFilePath, "utf-8").trim();
53553
+ const match = /^gitdir:\s*(.+)$/i.exec(content);
53554
+ if (!match?.[1]) {
53555
+ return null;
53556
+ }
53557
+ return path.resolve(path.dirname(gitFilePath), match[1]);
53558
+ } catch {
53559
+ return null;
53560
+ }
53561
+ }
53562
+ function discoverGitDir(startDir) {
53563
+ let current = startDir;
53564
+ for (;; ) {
53565
+ const gitPath = path.join(current, ".git");
53566
+ try {
53567
+ const stats = fs2.statSync(gitPath);
53568
+ if (stats.isDirectory()) {
53569
+ return gitPath;
53570
+ }
53571
+ if (stats.isFile()) {
53572
+ return readGitDirFile(gitPath);
53573
+ }
53574
+ } catch {}
53575
+ const parent = path.dirname(current);
53576
+ if (parent === current) {
53577
+ return null;
53578
+ }
53579
+ current = parent;
53580
+ }
53581
+ }
53582
+ function getGitRepoMetadata(cwd2) {
53583
+ if (!cwd2) {
53584
+ return null;
53585
+ }
53586
+ const startDir = normalizeDirectory(cwd2);
53587
+ if (!startDir) {
53588
+ return null;
53589
+ }
53590
+ const gitDir = discoverGitDir(startDir);
53591
+ if (!gitDir) {
53592
+ return null;
53593
+ }
53594
+ return {
53595
+ cachePath: getCachePath(gitDir),
53596
+ headMtimeMs: getMtimeMs(path.join(gitDir, "HEAD")),
53597
+ indexMtimeMs: getMtimeMs(path.join(gitDir, "index"))
53598
+ };
53599
+ }
53600
+ function getGitCacheTtlMs(context) {
53601
+ const ttlSeconds = context.gitCacheTtlSeconds;
53602
+ if (typeof ttlSeconds !== "number" || !Number.isFinite(ttlSeconds)) {
53603
+ return DEFAULT_GIT_CACHE_TTL_SECONDS * 1000;
53604
+ }
53605
+ return Math.min(60, Math.max(0, ttlSeconds)) * 1000;
53606
+ }
53607
+ function isCacheEntry(value) {
53608
+ if (typeof value !== "object" || value === null) {
53609
+ return false;
53610
+ }
53611
+ const entry = value;
53612
+ return (typeof entry.output === "string" || entry.output === null) && typeof entry.createdAt === "number" && (typeof entry.headMtimeMs === "number" || entry.headMtimeMs === null) && (typeof entry.indexMtimeMs === "number" || entry.indexMtimeMs === null);
53613
+ }
53614
+ function isCacheEntryFresh(entry, metadata, ttlMs, now2) {
53615
+ if (metadata) {
53616
+ if (entry.headMtimeMs !== metadata.headMtimeMs || entry.indexMtimeMs !== metadata.indexMtimeMs) {
53617
+ return false;
53618
+ }
53619
+ }
53620
+ return ttlMs === 0 || now2 - entry.createdAt <= ttlMs;
53621
+ }
53622
+ function readPersistentCache(cachePath) {
53623
+ try {
53624
+ const parsed = JSON.parse(fs2.readFileSync(cachePath, "utf-8"));
53625
+ if (typeof parsed !== "object" || parsed === null) {
53626
+ return null;
53627
+ }
53628
+ const data = parsed;
53629
+ if (data.version !== GIT_CACHE_SCHEMA_VERSION || typeof data.cwd !== "string" && data.cwd !== null || typeof data.entries !== "object" || data.entries === null) {
53630
+ return null;
53631
+ }
53632
+ const entries = {};
53633
+ for (const [key, value] of Object.entries(data.entries)) {
53634
+ if (isCacheEntry(value)) {
53635
+ entries[key] = value;
53636
+ }
53637
+ }
53638
+ return {
53639
+ version: GIT_CACHE_SCHEMA_VERSION,
53640
+ cwd: data.cwd,
53641
+ entries
53642
+ };
53643
+ } catch {
53644
+ return null;
53645
+ }
53646
+ }
53647
+ function writePersistentCache(cachePath, cache3) {
53648
+ try {
53649
+ const cacheDir = path.dirname(cachePath);
53650
+ fs2.mkdirSync(cacheDir, { recursive: true });
53651
+ const tempPath = `${cachePath}.${process.pid}.${Date.now()}.tmp`;
53652
+ fs2.writeFileSync(tempPath, JSON.stringify(cache3), "utf-8");
53653
+ fs2.renameSync(tempPath, cachePath);
53654
+ } catch {}
53655
+ }
53656
+ function readPersistentCacheEntry(metadata, cacheKey, cwd2, ttlMs, now2) {
53657
+ if (!metadata) {
53658
+ return null;
53659
+ }
53660
+ const cache3 = readPersistentCache(metadata.cachePath);
53661
+ if (cache3?.cwd !== (cwd2 ?? null)) {
53662
+ return null;
53663
+ }
53664
+ const entry = cache3.entries[cacheKey];
53665
+ if (!entry || !isCacheEntryFresh(entry, metadata, ttlMs, now2)) {
53666
+ return null;
53667
+ }
53668
+ return entry;
53669
+ }
53670
+ function writePersistentCacheEntry(metadata, cacheKey, cwd2, entry) {
53671
+ if (!metadata) {
53672
+ return;
53673
+ }
53674
+ const cacheCwd = cwd2 ?? null;
53675
+ const existingCache = readPersistentCache(metadata.cachePath);
53676
+ const cache3 = existingCache?.cwd === cacheCwd ? existingCache : {
53677
+ version: GIT_CACHE_SCHEMA_VERSION,
53678
+ cwd: cacheCwd,
53679
+ entries: {}
53680
+ };
53681
+ cache3.entries[cacheKey] = entry;
53682
+ writePersistentCache(metadata.cachePath, cache3);
53683
+ }
53684
+ function createCacheEntry(output, metadata, now2) {
53685
+ return {
53686
+ output,
53687
+ createdAt: now2,
53688
+ headMtimeMs: metadata?.headMtimeMs ?? null,
53689
+ indexMtimeMs: metadata?.indexMtimeMs ?? null
53690
+ };
53691
+ }
53522
53692
  function resolveGitCwd(context) {
53523
53693
  const candidates = [
53524
53694
  context.data?.cwd,
@@ -53539,22 +53709,37 @@ function runGit(command, context) {
53539
53709
  function runGitArgs(args, context, cacheCommand) {
53540
53710
  const cwd2 = resolveGitCwd(context);
53541
53711
  const cacheToken = cacheCommand ?? args.join("\x00");
53542
- const cacheKey = `${cacheToken}|${cwd2 ?? ""}`;
53543
- if (gitCommandCache.has(cacheKey)) {
53544
- return gitCommandCache.get(cacheKey) ?? null;
53712
+ const memoryCacheKey = `${cacheToken}|${cwd2 ?? ""}`;
53713
+ const persistentCacheKey = cacheToken;
53714
+ const metadata = getGitRepoMetadata(cwd2);
53715
+ const ttlMs = getGitCacheTtlMs(context);
53716
+ const now2 = Date.now();
53717
+ const memoryEntry = gitCommandCache.get(memoryCacheKey);
53718
+ if (memoryEntry && isCacheEntryFresh(memoryEntry, metadata, ttlMs, now2)) {
53719
+ return memoryEntry.output;
53720
+ }
53721
+ const persistentEntry = readPersistentCacheEntry(metadata, persistentCacheKey, cwd2, ttlMs, now2);
53722
+ if (persistentEntry) {
53723
+ gitCommandCache.set(memoryCacheKey, persistentEntry);
53724
+ return persistentEntry.output;
53545
53725
  }
53546
- const gitArgs = ["--no-optional-locks", ...args];
53547
53726
  try {
53548
- const output = execFileSync("git", gitArgs, {
53727
+ const output = execFileSync("git", args, {
53549
53728
  encoding: "utf8",
53550
53729
  stdio: ["pipe", "pipe", "ignore"],
53730
+ env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" },
53731
+ windowsHide: true,
53551
53732
  ...cwd2 ? { cwd: cwd2 } : {}
53552
53733
  }).trimEnd();
53553
53734
  const result2 = output.length > 0 ? output : null;
53554
- gitCommandCache.set(cacheKey, result2);
53735
+ const entry = createCacheEntry(result2, metadata, now2);
53736
+ gitCommandCache.set(memoryCacheKey, entry);
53737
+ writePersistentCacheEntry(metadata, persistentCacheKey, cwd2, entry);
53555
53738
  return result2;
53556
53739
  } catch {
53557
- gitCommandCache.set(cacheKey, null);
53740
+ const entry = createCacheEntry(null, metadata, now2);
53741
+ gitCommandCache.set(memoryCacheKey, entry);
53742
+ writePersistentCacheEntry(metadata, persistentCacheKey, cwd2, entry);
53558
53743
  return null;
53559
53744
  }
53560
53745
  }
@@ -53660,13 +53845,13 @@ function getGitConflictCount(context) {
53660
53845
  `).map((line) => {
53661
53846
  const parts = line.split(/\s+/).slice(3);
53662
53847
  return parts.join(" ");
53663
- }).filter((path) => path.length > 0));
53848
+ }).filter((path2) => path2.length > 0));
53664
53849
  return files.size;
53665
53850
  }
53666
53851
  function getGitShortSha(context) {
53667
53852
  return runGit("rev-parse --short HEAD", context);
53668
53853
  }
53669
- var gitCommandCache;
53854
+ var DEFAULT_GIT_CACHE_TTL_SECONDS = 5, GIT_CACHE_SCHEMA_VERSION = 1, gitCommandCache;
53670
53855
  var init_git = __esm(() => {
53671
53856
  gitCommandCache = new Map;
53672
53857
  });
@@ -53784,8 +53969,8 @@ function renderOsc8Link(url2, text) {
53784
53969
  function encodeGitRefForUrlPath(ref) {
53785
53970
  return ref.split("/").map((segment) => encodeURIComponent(segment)).join("/");
53786
53971
  }
53787
- function encodeFilePathForUri(path) {
53788
- return path.replace(/\\/g, "/").split("/").map((segment) => encodeURIComponent(segment)).join("/");
53972
+ function encodeFilePathForUri(path2) {
53973
+ return path2.replace(/\\/g, "/").split("/").map((segment) => encodeURIComponent(segment)).join("/");
53789
53974
  }
53790
53975
  function buildIdeFileUrl(filePath, ideLinkMode) {
53791
53976
  const normalizedPath = filePath.replace(/\\/g, "/");
@@ -53934,7 +54119,7 @@ class GitBranchWidget {
53934
54119
  return displayText;
53935
54120
  }
53936
54121
  getGitBranch(context) {
53937
- return runGit("branch --show-current", context);
54122
+ return runGit("symbolic-ref --short HEAD", context);
53938
54123
  }
53939
54124
  getCustomKeybinds() {
53940
54125
  return [
@@ -54440,19 +54625,19 @@ var init_GitRootDir = __esm(() => {
54440
54625
  import { execFileSync as execFileSync2 } from "child_process";
54441
54626
  import {
54442
54627
  existsSync as existsSync2,
54443
- mkdirSync,
54444
- readFileSync as readFileSync2,
54445
- statSync,
54446
- writeFileSync
54628
+ mkdirSync as mkdirSync2,
54629
+ readFileSync as readFileSync3,
54630
+ statSync as statSync2,
54631
+ writeFileSync as writeFileSync2
54447
54632
  } from "fs";
54448
- import { createHash } from "node:crypto";
54449
- import os3 from "node:os";
54450
- import path from "node:path";
54451
- function getCacheDir(deps) {
54452
- return path.join(deps.getHomedir(), ".cache", "ccstatusline");
54633
+ import { createHash as createHash2 } from "node:crypto";
54634
+ import os4 from "node:os";
54635
+ import path2 from "node:path";
54636
+ function getCacheDir2(deps) {
54637
+ return path2.join(deps.getHomedir(), ".cache", "ccstatusline");
54453
54638
  }
54454
54639
  function getGitReviewCacheDir(deps) {
54455
- return path.join(getCacheDir(deps), "git-review");
54640
+ return path2.join(getCacheDir2(deps), "git-review");
54456
54641
  }
54457
54642
  function runGitForCache(args, cwd2, deps) {
54458
54643
  try {
@@ -54460,14 +54645,15 @@ function runGitForCache(args, cwd2, deps) {
54460
54645
  encoding: "utf8",
54461
54646
  stdio: ["pipe", "pipe", "ignore"],
54462
54647
  cwd: cwd2,
54463
- timeout: CLI_TIMEOUT
54648
+ timeout: CLI_TIMEOUT,
54649
+ windowsHide: true
54464
54650
  }).trim();
54465
54651
  } catch {
54466
54652
  return "";
54467
54653
  }
54468
54654
  }
54469
54655
  function getCurrentBranch(cwd2, deps) {
54470
- const branch = runGitForCache(["branch", "--show-current"], cwd2, deps);
54656
+ const branch = runGitForCache(["symbolic-ref", "--short", "HEAD"], cwd2, deps);
54471
54657
  return branch.length > 0 ? branch : null;
54472
54658
  }
54473
54659
  function getCacheRef(cwd2, deps) {
@@ -54481,9 +54667,9 @@ function getCacheRef(cwd2, deps) {
54481
54667
  }
54482
54668
  return "unknown";
54483
54669
  }
54484
- function getCachePath(cwd2, ref, deps) {
54485
- const hash2 = createHash("sha256").update(cwd2).update("\x00").update(ref).digest("hex").slice(0, 16);
54486
- return path.join(getGitReviewCacheDir(deps), `git-review-${hash2}.json`);
54670
+ function getCachePath2(cwd2, ref, deps) {
54671
+ const hash2 = createHash2("sha256").update(cwd2).update("\x00").update(ref).digest("hex").slice(0, 16);
54672
+ return path2.join(getGitReviewCacheDir(deps), `git-review-${hash2}.json`);
54487
54673
  }
54488
54674
  function readCache(cachePath, deps) {
54489
54675
  try {
@@ -54520,35 +54706,70 @@ function getOriginUrl(cwd2, deps) {
54520
54706
  const url2 = runGitForCache(["remote", "get-url", "--", "origin"], cwd2, deps);
54521
54707
  return url2.length > 0 ? url2 : null;
54522
54708
  }
54709
+ function isSshRemoteUrl(url2) {
54710
+ const trimmed = url2.trim().toLowerCase();
54711
+ return trimmed.startsWith("ssh://") || !trimmed.includes("://");
54712
+ }
54713
+ function resolveSshHostAlias(host, deps) {
54714
+ try {
54715
+ const output = deps.execFileSync("ssh", ["-G", host], {
54716
+ encoding: "utf8",
54717
+ stdio: ["pipe", "pipe", "ignore"],
54718
+ timeout: CLI_TIMEOUT,
54719
+ windowsHide: true
54720
+ }).trim();
54721
+ for (const line of output.split(/\r?\n/)) {
54722
+ const match = /^hostname\s+(.+)$/i.exec(line.trim());
54723
+ if (match?.[1]) {
54724
+ return match[1].toLowerCase();
54725
+ }
54726
+ }
54727
+ } catch {}
54728
+ return host.toLowerCase();
54729
+ }
54730
+ function getNamedForgeProvider(host) {
54731
+ if (host.includes("github")) {
54732
+ return "gh";
54733
+ }
54734
+ if (host.includes("gitlab")) {
54735
+ return "glab";
54736
+ }
54737
+ return null;
54738
+ }
54739
+ function getEffectiveRemoteHost(url2, host, deps) {
54740
+ const normalizedHost = host.toLowerCase();
54741
+ if (!isSshRemoteUrl(url2) || getNamedForgeProvider(normalizedHost)) {
54742
+ return normalizedHost;
54743
+ }
54744
+ return resolveSshHostAlias(normalizedHost, deps);
54745
+ }
54523
54746
  function getOriginHost(cwd2, deps) {
54524
54747
  const url2 = getOriginUrl(cwd2, deps);
54525
54748
  if (!url2) {
54526
54749
  return null;
54527
54750
  }
54528
54751
  const parsed = parseRemoteUrl(url2);
54529
- return parsed ? parsed.host.toLowerCase() : null;
54752
+ return parsed ? getEffectiveRemoteHost(url2, parsed.host, deps) : null;
54530
54753
  }
54531
- function toHttpsRepoRef(url2) {
54754
+ function toHttpsRepoRef(url2, deps) {
54532
54755
  const parsed = parseRemoteUrl(url2);
54533
54756
  if (!parsed) {
54534
54757
  return null;
54535
54758
  }
54536
- return `https://${parsed.host}/${parsed.owner}/${parsed.repo}`;
54759
+ return `https://${getEffectiveRemoteHost(url2, parsed.host, deps)}/${parsed.owner}/${parsed.repo}`;
54537
54760
  }
54538
54761
  function getOriginRepoRef(cwd2, deps) {
54539
54762
  const url2 = getOriginUrl(cwd2, deps);
54540
- return url2 ? toHttpsRepoRef(url2) : null;
54763
+ return url2 ? toHttpsRepoRef(url2, deps) : null;
54541
54764
  }
54542
54765
  function getProviderCandidates(cwd2, deps) {
54543
54766
  const host = getOriginHost(cwd2, deps);
54544
54767
  if (!host) {
54545
54768
  return ["gh", "glab"];
54546
54769
  }
54547
- if (host.includes("github")) {
54548
- return ["gh"];
54549
- }
54550
- if (host.includes("gitlab")) {
54551
- return ["glab"];
54770
+ const namedForgeProvider = getNamedForgeProvider(host);
54771
+ if (namedForgeProvider) {
54772
+ return [namedForgeProvider];
54552
54773
  }
54553
54774
  const authed = [];
54554
54775
  if (isCliAuthedForHost("glab", host, deps)) {
@@ -54563,7 +54784,8 @@ function isCliAvailable(cli, deps) {
54563
54784
  try {
54564
54785
  deps.execFileSync(cli, ["--version"], {
54565
54786
  stdio: ["pipe", "pipe", "ignore"],
54566
- timeout: CLI_TIMEOUT
54787
+ timeout: CLI_TIMEOUT,
54788
+ windowsHide: true
54567
54789
  });
54568
54790
  return true;
54569
54791
  } catch {
@@ -54574,7 +54796,8 @@ function isCliAuthedForHost(cli, host, deps) {
54574
54796
  try {
54575
54797
  deps.execFileSync(cli, ["auth", "status", "--hostname", host], {
54576
54798
  stdio: ["pipe", "pipe", "ignore"],
54577
- timeout: CLI_TIMEOUT
54799
+ timeout: CLI_TIMEOUT,
54800
+ windowsHide: true
54578
54801
  });
54579
54802
  return true;
54580
54803
  } catch {
@@ -54606,7 +54829,8 @@ function fetchFromGh(cwd2, repoRef, deps) {
54606
54829
  encoding: "utf8",
54607
54830
  stdio: ["pipe", "pipe", "ignore"],
54608
54831
  cwd: cwd2,
54609
- timeout: CLI_TIMEOUT
54832
+ timeout: CLI_TIMEOUT,
54833
+ windowsHide: true
54610
54834
  }).trim();
54611
54835
  if (output.length === 0) {
54612
54836
  return null;
@@ -54638,7 +54862,8 @@ function fetchFromGlab(cwd2, repoRef, deps) {
54638
54862
  encoding: "utf8",
54639
54863
  stdio: ["pipe", "pipe", "ignore"],
54640
54864
  cwd: cwd2,
54641
- timeout: CLI_TIMEOUT
54865
+ timeout: CLI_TIMEOUT,
54866
+ windowsHide: true
54642
54867
  }).trim();
54643
54868
  if (output.length === 0) {
54644
54869
  return null;
@@ -54670,7 +54895,7 @@ function fetchFromProvider(provider, cwd2, repoRef, deps) {
54670
54895
  return null;
54671
54896
  }
54672
54897
  function fetchGitReviewData(cwd2, deps = DEFAULT_GIT_REVIEW_CACHE_DEPS) {
54673
- const cachePath = getCachePath(cwd2, getCacheRef(cwd2, deps), deps);
54898
+ const cachePath = getCachePath2(cwd2, getCacheRef(cwd2, deps), deps);
54674
54899
  const cached2 = readCache(cachePath, deps);
54675
54900
  if (cached2 !== "miss") {
54676
54901
  return cached2;
@@ -54716,11 +54941,11 @@ var init_git_review_cache = __esm(() => {
54716
54941
  DEFAULT_GIT_REVIEW_CACHE_DEPS = {
54717
54942
  execFileSync: execFileSync2,
54718
54943
  existsSync: existsSync2,
54719
- mkdirSync,
54720
- readFileSync: readFileSync2,
54721
- statSync,
54722
- writeFileSync,
54723
- getHomedir: os3.homedir,
54944
+ mkdirSync: mkdirSync2,
54945
+ readFileSync: readFileSync3,
54946
+ statSync: statSync2,
54947
+ writeFileSync: writeFileSync2,
54948
+ getHomedir: os4.homedir,
54724
54949
  now: Date.now
54725
54950
  };
54726
54951
  });
@@ -55909,6 +56134,278 @@ function getContextWindowSize(data) {
55909
56134
  return getContextWindowMetrics(data).windowSize;
55910
56135
  }
55911
56136
 
56137
+ // src/utils/gradient.ts
56138
+ function isGradientSpec(value) {
56139
+ return value?.startsWith(GRADIENT_PREFIX) ?? false;
56140
+ }
56141
+ function parseGradientSpec(value) {
56142
+ if (!value?.startsWith(GRADIENT_PREFIX)) {
56143
+ return null;
56144
+ }
56145
+ const body = value.slice(GRADIENT_PREFIX.length).trim();
56146
+ if (!body) {
56147
+ return null;
56148
+ }
56149
+ const preset = GRADIENT_PRESETS[body.toLowerCase()];
56150
+ const rawStops = preset ?? body.split(body.includes(",") ? "," : "-");
56151
+ const stops = rawStops.map((stop) => stop.trim()).filter((stop) => stop.length > 0).map(resolveStopToRgb).filter((rgb) => rgb !== null);
56152
+ return stops.length >= 2 ? stops : null;
56153
+ }
56154
+ function hexToRgb(hex3) {
56155
+ if (!HEX_PATTERN.test(hex3)) {
56156
+ return null;
56157
+ }
56158
+ return {
56159
+ r: parseInt(hex3.slice(0, 2), 16),
56160
+ g: parseInt(hex3.slice(2, 4), 16),
56161
+ b: parseInt(hex3.slice(4, 6), 16)
56162
+ };
56163
+ }
56164
+ function resolveStopToRgb(stop) {
56165
+ if (stop.startsWith("hex:")) {
56166
+ return hexToRgb(stop.slice(4));
56167
+ }
56168
+ if (stop.startsWith("#")) {
56169
+ return hexToRgb(stop.slice(1));
56170
+ }
56171
+ return hexToRgb(stop);
56172
+ }
56173
+ function srgbToLinear(channel) {
56174
+ const normalized = channel / 255;
56175
+ return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
56176
+ }
56177
+ function linearToSrgb(channel) {
56178
+ const value = channel <= 0.0031308 ? 12.92 * channel : 1.055 * channel ** (1 / 2.4) - 0.055;
56179
+ return Math.round(Math.min(1, Math.max(0, value)) * 255);
56180
+ }
56181
+ function rgbToOklab(rgb) {
56182
+ const lr = srgbToLinear(rgb.r);
56183
+ const lg = srgbToLinear(rgb.g);
56184
+ const lb = srgbToLinear(rgb.b);
56185
+ const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;
56186
+ const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;
56187
+ const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;
56188
+ const lCbrt = Math.cbrt(l);
56189
+ const mCbrt = Math.cbrt(m);
56190
+ const sCbrt = Math.cbrt(s);
56191
+ return {
56192
+ L: 0.2104542553 * lCbrt + 0.793617785 * mCbrt - 0.0040720468 * sCbrt,
56193
+ a: 1.9779984951 * lCbrt - 2.428592205 * mCbrt + 0.4505937099 * sCbrt,
56194
+ b: 0.0259040371 * lCbrt + 0.7827717662 * mCbrt - 0.808675766 * sCbrt
56195
+ };
56196
+ }
56197
+ function oklabToRgb(lab) {
56198
+ const lCbrt = lab.L + 0.3963377774 * lab.a + 0.2158037573 * lab.b;
56199
+ const mCbrt = lab.L - 0.1055613458 * lab.a - 0.0638541728 * lab.b;
56200
+ const sCbrt = lab.L - 0.0894841775 * lab.a - 1.291485548 * lab.b;
56201
+ const l = lCbrt ** 3;
56202
+ const m = mCbrt ** 3;
56203
+ const s = sCbrt ** 3;
56204
+ return {
56205
+ r: linearToSrgb(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),
56206
+ g: linearToSrgb(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),
56207
+ b: linearToSrgb(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s)
56208
+ };
56209
+ }
56210
+ function sampleGradient(stops, t) {
56211
+ const first = stops[0];
56212
+ if (first === undefined) {
56213
+ return { r: 0, g: 0, b: 0 };
56214
+ }
56215
+ if (stops.length === 1) {
56216
+ return first;
56217
+ }
56218
+ const clamped = Math.min(1, Math.max(0, t));
56219
+ const scaled = clamped * (stops.length - 1);
56220
+ const lowerIndex = Math.min(stops.length - 2, Math.floor(scaled));
56221
+ const lower = stops[lowerIndex];
56222
+ const upper = stops[lowerIndex + 1];
56223
+ if (lower === undefined || upper === undefined) {
56224
+ return first;
56225
+ }
56226
+ const fraction = scaled - lowerIndex;
56227
+ const labLower = rgbToOklab(lower);
56228
+ const labUpper = rgbToOklab(upper);
56229
+ return oklabToRgb({
56230
+ L: labLower.L + (labUpper.L - labLower.L) * fraction,
56231
+ a: labLower.a + (labUpper.a - labLower.a) * fraction,
56232
+ b: labLower.b + (labUpper.b - labLower.b) * fraction
56233
+ });
56234
+ }
56235
+ function rgbToAnsi256(rgb) {
56236
+ if (rgb.r === rgb.g && rgb.g === rgb.b) {
56237
+ if (rgb.r < 8) {
56238
+ return 16;
56239
+ }
56240
+ if (rgb.r > 248) {
56241
+ return 231;
56242
+ }
56243
+ return Math.round((rgb.r - 8) / 247 * 24) + 232;
56244
+ }
56245
+ return 16 + 36 * Math.round(rgb.r / 255 * 5) + 6 * Math.round(rgb.g / 255 * 5) + Math.round(rgb.b / 255 * 5);
56246
+ }
56247
+ function gradientCodeAt(stops, t, colorLevel) {
56248
+ const rgb = sampleGradient(stops, t);
56249
+ if (colorLevel === "truecolor") {
56250
+ return `\x1B[38;2;${rgb.r};${rgb.g};${rgb.b}m`;
56251
+ }
56252
+ return `\x1B[38;5;${rgbToAnsi256(rgb)}m`;
56253
+ }
56254
+ function isCsiFinalByte(codePoint) {
56255
+ return codePoint >= 64 && codePoint <= 126;
56256
+ }
56257
+ function consumeCsi(input, start, bodyStart) {
56258
+ let index = bodyStart;
56259
+ while (index < input.length) {
56260
+ const codePoint = input.charCodeAt(index);
56261
+ if (isCsiFinalByte(codePoint)) {
56262
+ const end = index + 1;
56263
+ return {
56264
+ nextIndex: end,
56265
+ sequence: input.slice(start, end)
56266
+ };
56267
+ }
56268
+ index++;
56269
+ }
56270
+ return {
56271
+ nextIndex: input.length,
56272
+ sequence: input.slice(start)
56273
+ };
56274
+ }
56275
+ function consumeOsc(input, start, bodyStart) {
56276
+ let index = bodyStart;
56277
+ while (index < input.length) {
56278
+ const current = input[index];
56279
+ if (!current) {
56280
+ break;
56281
+ }
56282
+ if (current === BEL2 || current === ST) {
56283
+ const end = index + 1;
56284
+ return {
56285
+ nextIndex: end,
56286
+ sequence: input.slice(start, end)
56287
+ };
56288
+ }
56289
+ if (current === ESC2 && input[index + 1] === "\\") {
56290
+ const end = index + 2;
56291
+ return {
56292
+ nextIndex: end,
56293
+ sequence: input.slice(start, end)
56294
+ };
56295
+ }
56296
+ index++;
56297
+ }
56298
+ return {
56299
+ nextIndex: input.length,
56300
+ sequence: input.slice(start)
56301
+ };
56302
+ }
56303
+ function consumeEscapeSequence(input, index) {
56304
+ const current = input[index];
56305
+ if (!current) {
56306
+ return null;
56307
+ }
56308
+ if (current === ESC2) {
56309
+ const next = input[index + 1];
56310
+ if (next === "[") {
56311
+ return consumeCsi(input, index, index + 2);
56312
+ }
56313
+ if (next === "]") {
56314
+ return consumeOsc(input, index, index + 2);
56315
+ }
56316
+ if (next) {
56317
+ return {
56318
+ nextIndex: index + 2,
56319
+ sequence: input.slice(index, index + 2)
56320
+ };
56321
+ }
56322
+ return {
56323
+ nextIndex: input.length,
56324
+ sequence: current
56325
+ };
56326
+ }
56327
+ if (current === C1_CSI) {
56328
+ return consumeCsi(input, index, index + 1);
56329
+ }
56330
+ if (current === C1_OSC) {
56331
+ return consumeOsc(input, index, index + 1);
56332
+ }
56333
+ return null;
56334
+ }
56335
+ function applyGradientToText(text, stops, colorLevel) {
56336
+ if (colorLevel === "ansi16" || text.length === 0) {
56337
+ return text;
56338
+ }
56339
+ let visibleCount = 0;
56340
+ let scanIndex = 0;
56341
+ while (scanIndex < text.length) {
56342
+ const escape3 = consumeEscapeSequence(text, scanIndex);
56343
+ if (escape3) {
56344
+ scanIndex = escape3.nextIndex;
56345
+ continue;
56346
+ }
56347
+ const codePoint = text.codePointAt(scanIndex);
56348
+ if (codePoint === undefined) {
56349
+ break;
56350
+ }
56351
+ const ch = String.fromCodePoint(codePoint);
56352
+ if (!WHITESPACE.test(ch)) {
56353
+ visibleCount++;
56354
+ }
56355
+ scanIndex += ch.length;
56356
+ }
56357
+ if (visibleCount === 0) {
56358
+ return text;
56359
+ }
56360
+ const denominator = Math.max(1, visibleCount - 1);
56361
+ let result2 = "";
56362
+ let index = 0;
56363
+ let textIndex = 0;
56364
+ while (textIndex < text.length) {
56365
+ const escape3 = consumeEscapeSequence(text, textIndex);
56366
+ if (escape3) {
56367
+ result2 += escape3.sequence;
56368
+ textIndex = escape3.nextIndex;
56369
+ continue;
56370
+ }
56371
+ const codePoint = text.codePointAt(textIndex);
56372
+ if (codePoint === undefined) {
56373
+ break;
56374
+ }
56375
+ const ch = String.fromCodePoint(codePoint);
56376
+ if (WHITESPACE.test(ch)) {
56377
+ result2 += ch;
56378
+ textIndex += ch.length;
56379
+ continue;
56380
+ }
56381
+ result2 += gradientCodeAt(stops, index / denominator, colorLevel) + ch;
56382
+ index++;
56383
+ textIndex += ch.length;
56384
+ }
56385
+ return result2;
56386
+ }
56387
+ var GRADIENT_PREFIX = "gradient:", HEX_PATTERN, ESC2 = "\x1B", BEL2 = "\x07", C1_CSI = "›", C1_OSC = "", ST = "œ", GRADIENT_PRESETS, GRADIENT_PRESET_NAMES, WHITESPACE;
56388
+ var init_gradient = __esm(() => {
56389
+ HEX_PATTERN = /^[0-9A-Fa-f]{6}$/;
56390
+ GRADIENT_PRESETS = {
56391
+ atlas: ["#feac5e", "#c779d0", "#4bc0c8"],
56392
+ cristal: ["#bdfff3", "#4ac29a"],
56393
+ teen: ["#77a1d3", "#79cbca", "#e684ae"],
56394
+ mind: ["#473b7b", "#3584a7", "#30d2be"],
56395
+ morning: ["#ff5f6d", "#ffc371"],
56396
+ vice: ["#5ee7df", "#b490ca"],
56397
+ passion: ["#f43b47", "#453a94"],
56398
+ fruit: ["#ff4e50", "#f9d423"],
56399
+ instagram: ["#833ab4", "#fd1d1d", "#fcb045"],
56400
+ retro: ["#3f51b1", "#5a55ae", "#7b5fac", "#8f6aae", "#a86aa4", "#cc6b8e", "#f18271", "#f3a469", "#f7c978"],
56401
+ summer: ["#fdbb2d", "#22c1c3"],
56402
+ rainbow: ["#ff0000", "#ffff00", "#00ff00", "#00ffff", "#0000ff", "#ff00ff", "#ff0000"],
56403
+ pastel: ["#aee9d8", "#cdeeb0", "#f6f0a8", "#f7c8a8", "#f3aecb", "#c3b6f0", "#aee9d8"]
56404
+ };
56405
+ GRADIENT_PRESET_NAMES = Object.keys(GRADIENT_PRESETS);
56406
+ WHITESPACE = /\s/;
56407
+ });
56408
+
55912
56409
  // src/utils/ansi.ts
55913
56410
  function createUnicodePropertyRegex(pattern) {
55914
56411
  try {
@@ -56027,14 +56524,14 @@ function getTextDisplayWidth(text) {
56027
56524
  }
56028
56525
  return width;
56029
56526
  }
56030
- function isCsiFinalByte(codePoint) {
56527
+ function isCsiFinalByte2(codePoint) {
56031
56528
  return codePoint >= 64 && codePoint <= 126;
56032
56529
  }
56033
56530
  function parseCsi(input, start, bodyStart) {
56034
56531
  let index = bodyStart;
56035
56532
  while (index < input.length) {
56036
56533
  const codePoint = input.charCodeAt(index);
56037
- if (isCsiFinalByte(codePoint)) {
56534
+ if (isCsiFinalByte2(codePoint)) {
56038
56535
  const end = index + 1;
56039
56536
  return {
56040
56537
  nextIndex: end,
@@ -56066,7 +56563,7 @@ function parseOsc(input, start, bodyStart) {
56066
56563
  if (!current) {
56067
56564
  break;
56068
56565
  }
56069
- if (current === BEL2) {
56566
+ if (current === BEL3) {
56070
56567
  const end = index + 1;
56071
56568
  const body = input.slice(bodyStart, index);
56072
56569
  return {
@@ -56076,7 +56573,7 @@ function parseOsc(input, start, bodyStart) {
56076
56573
  osc8Terminator: "bel"
56077
56574
  };
56078
56575
  }
56079
- if (current === ST) {
56576
+ if (current === ST2) {
56080
56577
  const end = index + 1;
56081
56578
  const body = input.slice(bodyStart, index);
56082
56579
  return {
@@ -56086,7 +56583,7 @@ function parseOsc(input, start, bodyStart) {
56086
56583
  osc8Terminator: "st"
56087
56584
  };
56088
56585
  }
56089
- if (current === ESC2 && input[index + 1] === "\\") {
56586
+ if (current === ESC3 && input[index + 1] === "\\") {
56090
56587
  const end = index + 2;
56091
56588
  const body = input.slice(bodyStart, index);
56092
56589
  return {
@@ -56108,7 +56605,7 @@ function parseEscapeSequence(input, index) {
56108
56605
  if (!current) {
56109
56606
  return null;
56110
56607
  }
56111
- if (current === ESC2) {
56608
+ if (current === ESC3) {
56112
56609
  const next = input[index + 1];
56113
56610
  if (next === "[") {
56114
56611
  return parseCsi(input, index, index + 2);
@@ -56127,19 +56624,19 @@ function parseEscapeSequence(input, index) {
56127
56624
  sequence: current
56128
56625
  };
56129
56626
  }
56130
- if (current === C1_CSI) {
56627
+ if (current === C1_CSI2) {
56131
56628
  return parseCsi(input, index, index + 1);
56132
56629
  }
56133
- if (current === C1_OSC) {
56630
+ if (current === C1_OSC2) {
56134
56631
  return parseOsc(input, index, index + 1);
56135
56632
  }
56136
56633
  return null;
56137
56634
  }
56138
56635
  function getOsc8CloseSequence(terminator) {
56139
56636
  if (terminator === "bel") {
56140
- return `${ESC2}]8;;${BEL2}`;
56637
+ return `${ESC3}]8;;${BEL3}`;
56141
56638
  }
56142
- return `${ESC2}]8;;${ESC2}\\`;
56639
+ return `${ESC3}]8;;${ESC3}\\`;
56143
56640
  }
56144
56641
  function stripSgrCodes(text) {
56145
56642
  return text.replace(SGR_REGEX, "");
@@ -56150,7 +56647,7 @@ function stripOscCodes(text) {
56150
56647
  while (index < text.length) {
56151
56648
  const escape3 = parseEscapeSequence(text, index);
56152
56649
  if (escape3) {
56153
- const isOsc = escape3.sequence.startsWith(`${ESC2}]`) || escape3.sequence.startsWith(C1_OSC);
56650
+ const isOsc = escape3.sequence.startsWith(`${ESC3}]`) || escape3.sequence.startsWith(C1_OSC2);
56154
56651
  if (!isOsc) {
56155
56652
  result2 += escape3.sequence;
56156
56653
  }
@@ -56250,9 +56747,56 @@ function truncateStyledText(text, maxWidth, options = {}) {
56250
56747
  }
56251
56748
  return output + ellipsis;
56252
56749
  }
56253
- var ESC2 = "\x1B", BEL2 = "\x07", C1_CSI = "›", C1_OSC = "", ST = "œ", ZERO_WIDTH_JOINER = 8205, COMBINING_ENCLOSING_KEYCAP = 8419, VARIATION_SELECTOR_START = 65024, VARIATION_SELECTOR_END = 65039, VARIATION_SELECTOR_SUPPLEMENT_START = 917760, VARIATION_SELECTOR_SUPPLEMENT_END = 917999, REGIONAL_INDICATOR_START = 127462, REGIONAL_INDICATOR_END = 127487, SGR_REGEX, EXTENDED_PICTOGRAPHIC_REGEX, EMOJI_PRESENTATION_REGEX, EMOJI_MODIFIER_REGEX, COMBINING_MARK_REGEX;
56750
+ function applyLineGradientSegment(text, stops, colorLevel, startColumn, totalWidth) {
56751
+ const visibleWidth = getVisibleWidth(text);
56752
+ if (stops.length === 0 || colorLevel === "ansi16") {
56753
+ return {
56754
+ text,
56755
+ nextColumn: startColumn + visibleWidth
56756
+ };
56757
+ }
56758
+ if (totalWidth <= 1) {
56759
+ return {
56760
+ text,
56761
+ nextColumn: startColumn + visibleWidth
56762
+ };
56763
+ }
56764
+ const denominator = totalWidth - 1;
56765
+ let output = "";
56766
+ let column = startColumn;
56767
+ let index = 0;
56768
+ while (index < text.length) {
56769
+ const escape3 = parseEscapeSequence(text, index);
56770
+ if (escape3) {
56771
+ output += escape3.sequence;
56772
+ index = escape3.nextIndex;
56773
+ continue;
56774
+ }
56775
+ const cluster = consumeDisplayCluster(text, index);
56776
+ if (!cluster) {
56777
+ break;
56778
+ }
56779
+ output += gradientCodeAt(stops, column / denominator, colorLevel) + cluster.text;
56780
+ column += getClusterWidth(cluster.text);
56781
+ index = cluster.nextIndex;
56782
+ }
56783
+ return {
56784
+ text: output,
56785
+ nextColumn: column
56786
+ };
56787
+ }
56788
+ function applyLineGradient(text, stops, colorLevel) {
56789
+ const totalWidth = getVisibleWidth(text);
56790
+ const result2 = applyLineGradientSegment(text, stops, colorLevel, 0, totalWidth);
56791
+ if (result2.text === text) {
56792
+ return text;
56793
+ }
56794
+ return `${result2.text}\x1B[39m`;
56795
+ }
56796
+ var ESC3 = "\x1B", BEL3 = "\x07", C1_CSI2 = "›", C1_OSC2 = "", ST2 = "œ", ZERO_WIDTH_JOINER = 8205, COMBINING_ENCLOSING_KEYCAP = 8419, VARIATION_SELECTOR_START = 65024, VARIATION_SELECTOR_END = 65039, VARIATION_SELECTOR_SUPPLEMENT_START = 917760, VARIATION_SELECTOR_SUPPLEMENT_END = 917999, REGIONAL_INDICATOR_START = 127462, REGIONAL_INDICATOR_END = 127487, SGR_REGEX, EXTENDED_PICTOGRAPHIC_REGEX, EMOJI_PRESENTATION_REGEX, EMOJI_MODIFIER_REGEX, COMBINING_MARK_REGEX;
56254
56797
  var init_ansi = __esm(() => {
56255
56798
  init_string_width();
56799
+ init_gradient();
56256
56800
  SGR_REGEX = /\x1b\[[0-9;]*m/g;
56257
56801
  EXTENDED_PICTOGRAPHIC_REGEX = createUnicodePropertyRegex("\\p{Extended_Pictographic}");
56258
56802
  EMOJI_PRESENTATION_REGEX = createUnicodePropertyRegex("\\p{Emoji_Presentation}");
@@ -56364,6 +56908,10 @@ function applyColors(text, foregroundColor, backgroundColor, bold, colorLevel =
56364
56908
  }
56365
56909
  }
56366
56910
  if (foregroundColor) {
56911
+ const gradientStops = parseGradientSpec(foregroundColor);
56912
+ if (gradientStops && colorLevel !== "ansi16") {
56913
+ return prefix + applyGradientToText(text, gradientStops, colorLevel) + "\x1B[39m" + suffix;
56914
+ }
56367
56915
  const fgCode = getColorAnsiCode(foregroundColor, colorLevel, false);
56368
56916
  if (fgCode) {
56369
56917
  prefix += fgCode;
@@ -56375,6 +56923,20 @@ function applyColors(text, foregroundColor, backgroundColor, bold, colorLevel =
56375
56923
  function getColorAnsiCode(colorName, colorLevel = "ansi16", isBackground = false) {
56376
56924
  if (!colorName)
56377
56925
  return "";
56926
+ if (isGradientSpec(colorName)) {
56927
+ const stops = parseGradientSpec(colorName);
56928
+ const first = stops?.[0];
56929
+ if (!first)
56930
+ return "";
56931
+ if (colorLevel === "ansi16") {
56932
+ return "";
56933
+ }
56934
+ if (colorLevel === "ansi256") {
56935
+ const code = rgbToAnsi256(first);
56936
+ return isBackground ? `\x1B[48;5;${code}m` : `\x1B[38;5;${code}m`;
56937
+ }
56938
+ return isBackground ? `\x1B[48;2;${first.r};${first.g};${first.b}m` : `\x1B[38;2;${first.r};${first.g};${first.b}m`;
56939
+ }
56378
56940
  if (colorName.startsWith("ansi256:")) {
56379
56941
  const code = parseInt(colorName.substring(8), 10);
56380
56942
  if (!isNaN(code) && code >= 0 && code <= 255) {
@@ -56444,6 +57006,7 @@ function getDefaultPowerlineTheme() {
56444
57006
  var COLOR_MAP, POWERLINE_THEMES;
56445
57007
  var init_colors = __esm(() => {
56446
57008
  init_source();
57009
+ init_gradient();
56447
57010
  COLOR_MAP = createColorMap();
56448
57011
  POWERLINE_THEMES = {
56449
57012
  custom: {
@@ -56715,20 +57278,20 @@ var init_context_percentage = () => {};
56715
57278
 
56716
57279
  // src/utils/terminal.ts
56717
57280
  import { execSync } from "child_process";
56718
- import * as fs2 from "fs";
56719
- import * as path2 from "path";
57281
+ import * as fs3 from "fs";
57282
+ import * as path3 from "path";
56720
57283
  function getPackageVersion() {
56721
57284
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
56722
57285
  return PACKAGE_VERSION;
56723
57286
  }
56724
57287
  const possiblePaths = [
56725
- path2.join(__dirname, "..", "..", "package.json"),
56726
- path2.join(__dirname, "..", "package.json")
57288
+ path3.join(__dirname, "..", "..", "package.json"),
57289
+ path3.join(__dirname, "..", "package.json")
56727
57290
  ];
56728
57291
  for (const packageJsonPath of possiblePaths) {
56729
57292
  try {
56730
- if (fs2.existsSync(packageJsonPath)) {
56731
- const packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
57293
+ if (fs3.existsSync(packageJsonPath)) {
57294
+ const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
56732
57295
  return packageJson.version ?? "";
56733
57296
  }
56734
57297
  } catch {}
@@ -56736,6 +57299,13 @@ function getPackageVersion() {
56736
57299
  return "";
56737
57300
  }
56738
57301
  function probeTerminalWidth() {
57302
+ const overrideRaw = process.env.CCSTATUSLINE_WIDTH;
57303
+ if (overrideRaw) {
57304
+ const override = parsePositiveInteger(overrideRaw);
57305
+ if (override !== null) {
57306
+ return override;
57307
+ }
57308
+ }
56739
57309
  if (process.platform === "win32") {
56740
57310
  return null;
56741
57311
  }
@@ -56758,7 +57328,8 @@ function probeTerminalWidth() {
56758
57328
  try {
56759
57329
  const width = execSync("tput cols 2>/dev/null", {
56760
57330
  encoding: "utf8",
56761
- stdio: ["pipe", "pipe", "ignore"]
57331
+ stdio: ["pipe", "pipe", "ignore"],
57332
+ windowsHide: true
56762
57333
  }).trim();
56763
57334
  return parsePositiveInteger(width);
56764
57335
  } catch {}
@@ -56776,7 +57347,8 @@ function getParentProcessId(pid) {
56776
57347
  const parentPidOutput = execSync(`ps -o ppid= -p ${pid}`, {
56777
57348
  encoding: "utf8",
56778
57349
  stdio: ["pipe", "pipe", "ignore"],
56779
- shell: "/bin/sh"
57350
+ shell: "/bin/sh",
57351
+ windowsHide: true
56780
57352
  }).trim();
56781
57353
  return parsePositiveInteger(parentPidOutput);
56782
57354
  } catch {
@@ -56788,7 +57360,8 @@ function getTTYForProcess(pid) {
56788
57360
  const tty2 = execSync(`ps -o tty= -p ${pid}`, {
56789
57361
  encoding: "utf8",
56790
57362
  stdio: ["pipe", "pipe", "ignore"],
56791
- shell: "/bin/sh"
57363
+ shell: "/bin/sh",
57364
+ windowsHide: true
56792
57365
  }).replace(/\s+/g, "");
56793
57366
  if (!tty2 || tty2 === "??" || tty2 === "?") {
56794
57367
  return null;
@@ -56810,7 +57383,8 @@ function getWidthForTTY(tty2) {
56810
57383
  const width = execSync(`${cmd} 2>/dev/null | awk '{print $2}'`, {
56811
57384
  encoding: "utf8",
56812
57385
  stdio: ["pipe", "pipe", "ignore"],
56813
- shell: "/bin/sh"
57386
+ shell: "/bin/sh",
57387
+ windowsHide: true
56814
57388
  }).trim();
56815
57389
  const parsed = parsePositiveInteger(width);
56816
57390
  if (parsed !== null) {
@@ -56826,7 +57400,7 @@ function getTerminalWidth() {
56826
57400
  function canDetectTerminalWidth() {
56827
57401
  return probeTerminalWidth() !== null;
56828
57402
  }
56829
- var __dirname = "/home/runner/work/ccstatusline/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.18";
57403
+ var __dirname = "/home/runner/work/ccstatusline/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.20";
56830
57404
  var init_terminal = () => {};
56831
57405
 
56832
57406
  // src/utils/renderer.ts
@@ -56837,6 +57411,10 @@ function formatTokens(count) {
56837
57411
  return `${(count / 1000).toFixed(1)}k`;
56838
57412
  return count.toString();
56839
57413
  }
57414
+ function maybeApplyForegroundGradient(line, settings, colorLevel) {
57415
+ const stops = parseGradientSpec(settings.overrideForegroundColor);
57416
+ return stops ? applyLineGradient(line, stops, colorLevel) : line;
57417
+ }
56840
57418
  function resolveEffectiveTerminalWidth(detectedWidth, settings, context) {
56841
57419
  if (!detectedWidth) {
56842
57420
  return null;
@@ -56889,6 +57467,7 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
56889
57467
  }
56890
57468
  }
56891
57469
  const colorLevel = getColorLevelString(settings.colorLevel);
57470
+ const overrideForegroundGradientStops = parseGradientSpec(settings.overrideForegroundColor);
56892
57471
  const filteredWidgets = widgets.filter((widget) => widget.type !== "separator" && widget.type !== "flex-separator");
56893
57472
  if (filteredWidgets.length === 0)
56894
57473
  return "";
@@ -56945,7 +57524,7 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
56945
57524
  widgetColorIndex++;
56946
57525
  }
56947
57526
  }
56948
- if (settings.overrideForegroundColor && settings.overrideForegroundColor !== "none") {
57527
+ if (settings.overrideForegroundColor && settings.overrideForegroundColor !== "none" && !isGradientSpec(settings.overrideForegroundColor)) {
56949
57528
  fgColor = settings.overrideForegroundColor;
56950
57529
  }
56951
57530
  widgetElements.push({
@@ -56992,6 +57571,11 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
56992
57571
  }
56993
57572
  }
56994
57573
  }
57574
+ const powerlineGradientWidth = overrideForegroundGradientStops && colorLevel !== "ansi16" ? widgetElements.reduce((sum2, element) => {
57575
+ const isPreserveColors = element.widget.type === "custom-command" && element.widget.preserveColors;
57576
+ return isPreserveColors ? sum2 : sum2 + getVisibleWidth(element.content);
57577
+ }, 0) : 0;
57578
+ let powerlineGradientColumn = 0;
56995
57579
  let result2 = "";
56996
57580
  if (startCap && widgetElements.length > 0) {
56997
57581
  const firstWidget = widgetElements[0];
@@ -57015,13 +57599,20 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
57015
57599
  if (shouldBold && !isPreserveColors) {
57016
57600
  widgetContent += "\x1B[1m";
57017
57601
  }
57018
- if (widget.fgColor && !isPreserveColors) {
57602
+ const textGradientStops = !isPreserveColors && powerlineGradientWidth > 1 ? overrideForegroundGradientStops : null;
57603
+ if (widget.fgColor && !isPreserveColors && !textGradientStops) {
57019
57604
  widgetContent += getColorAnsiCode(widget.fgColor, colorLevel, false);
57020
57605
  }
57021
57606
  if (widget.bgColor) {
57022
57607
  widgetContent += getColorAnsiCode(widget.bgColor, colorLevel, true);
57023
57608
  }
57024
- widgetContent += widget.content;
57609
+ if (textGradientStops) {
57610
+ const gradientResult = applyLineGradientSegment(widget.content, textGradientStops, colorLevel, powerlineGradientColumn, powerlineGradientWidth);
57611
+ widgetContent += gradientResult.text;
57612
+ powerlineGradientColumn = gradientResult.nextColumn;
57613
+ } else {
57614
+ widgetContent += widget.content;
57615
+ }
57025
57616
  if (isPreserveColors) {
57026
57617
  widgetContent += "\x1B[0m";
57027
57618
  } else {
@@ -57198,7 +57789,7 @@ function calculateMaxWidthsFromPreRendered(preRenderedLines, settings) {
57198
57789
  }
57199
57790
  function renderStatusLineWithInfo(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths) {
57200
57791
  const line = renderStatusLine(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths);
57201
- const wasTruncated = line.includes("...");
57792
+ const wasTruncated = getVisibleText(line).includes("...");
57202
57793
  return { line, wasTruncated };
57203
57794
  }
57204
57795
  function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths) {
@@ -57209,8 +57800,13 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
57209
57800
  return renderPowerlineStatusLine(widgets, settings, context, context.lineIndex ?? 0, context.globalSeparatorIndex ?? 0, context.globalPowerlineThemeIndex ?? 0, preRenderedWidgets, preCalculatedMaxWidths);
57210
57801
  const applyColorsWithOverride = (text, foregroundColor, backgroundColor, bold) => {
57211
57802
  let fgColor = foregroundColor;
57212
- if (settings.overrideForegroundColor && settings.overrideForegroundColor !== "none") {
57213
- fgColor = settings.overrideForegroundColor;
57803
+ const fgOverride = settings.overrideForegroundColor;
57804
+ if (fgOverride && fgOverride !== "none") {
57805
+ if (!isGradientSpec(fgOverride)) {
57806
+ fgColor = fgOverride;
57807
+ } else if (colorLevel !== "ansi16") {
57808
+ fgColor = undefined;
57809
+ }
57214
57810
  }
57215
57811
  let bgColor = backgroundColor;
57216
57812
  if (settings.overrideBackgroundColor && settings.overrideBackgroundColor !== "none") {
@@ -57399,6 +57995,7 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
57399
57995
  statusLine = truncateStyledText(statusLine, maxWidth, { ellipsis: true });
57400
57996
  }
57401
57997
  }
57998
+ statusLine = maybeApplyForegroundGradient(statusLine, settings, colorLevel);
57402
57999
  return statusLine;
57403
58000
  }
57404
58001
  var init_renderer2 = __esm(async () => {
@@ -57407,6 +58004,7 @@ var init_renderer2 = __esm(async () => {
57407
58004
  init_ansi();
57408
58005
  init_colors();
57409
58006
  init_context_percentage();
58007
+ init_gradient();
57410
58008
  init_terminal();
57411
58009
  await init_widgets2();
57412
58010
  });
@@ -57437,13 +58035,13 @@ class TokensInputWidget {
57437
58035
  if (context.isPreview) {
57438
58036
  return formatRawOrLabeledValue(item, "In: ", "15.2k");
57439
58037
  }
58038
+ if (context.tokenMetrics) {
58039
+ return formatRawOrLabeledValue(item, "In: ", formatTokens(context.tokenMetrics.inputTokens));
58040
+ }
57440
58041
  const inputTotalTokens = getContextWindowInputTotalTokens(context.data);
57441
58042
  if (inputTotalTokens !== null) {
57442
58043
  return formatRawOrLabeledValue(item, "In: ", formatTokens(inputTotalTokens));
57443
58044
  }
57444
- if (context.tokenMetrics) {
57445
- return formatRawOrLabeledValue(item, "In: ", formatTokens(context.tokenMetrics.inputTokens));
57446
- }
57447
58045
  return null;
57448
58046
  }
57449
58047
  supportsRawValue() {
@@ -57478,13 +58076,13 @@ class TokensOutputWidget {
57478
58076
  if (context.isPreview) {
57479
58077
  return formatRawOrLabeledValue(item, "Out: ", "3.4k");
57480
58078
  }
58079
+ if (context.tokenMetrics) {
58080
+ return formatRawOrLabeledValue(item, "Out: ", formatTokens(context.tokenMetrics.outputTokens));
58081
+ }
57481
58082
  const outputTotalTokens = getContextWindowOutputTotalTokens(context.data);
57482
58083
  if (outputTotalTokens !== null) {
57483
58084
  return formatRawOrLabeledValue(item, "Out: ", formatTokens(outputTotalTokens));
57484
58085
  }
57485
- if (context.tokenMetrics) {
57486
- return formatRawOrLabeledValue(item, "Out: ", formatTokens(context.tokenMetrics.outputTokens));
57487
- }
57488
58086
  return null;
57489
58087
  }
57490
58088
  supportsRawValue() {
@@ -57904,6 +58502,12 @@ function toggleUsageDateMode(item) {
57904
58502
  function toggleUsageHourFormat(item) {
57905
58503
  return toggleMetadataFlag(item, "hour12");
57906
58504
  }
58505
+ function isUsageWeekdayEnabled(item) {
58506
+ return isMetadataFlagEnabled(item, "weekday");
58507
+ }
58508
+ function toggleUsageWeekday(item) {
58509
+ return toggleMetadataFlag(item, "weekday");
58510
+ }
57907
58511
  function getUsageDisplayModifierText(item, options = {}) {
57908
58512
  const mode = getUsageDisplayMode(item);
57909
58513
  const modifiers = [];
@@ -57992,6 +58596,9 @@ function getUsageTimerCustomKeybinds(item, options = {}) {
57992
58596
  if (options.includeHourFormat) {
57993
58597
  keybinds.push(HOUR_FORMAT_TOGGLE_KEYBIND);
57994
58598
  }
58599
+ if (options.includeWeekday) {
58600
+ keybinds.push(WEEKDAY_TOGGLE_KEYBIND);
58601
+ }
57995
58602
  if (options.includeTimezone) {
57996
58603
  keybinds.push(TIMEZONE_KEYBIND);
57997
58604
  }
@@ -58001,7 +58608,7 @@ function getUsageTimerCustomKeybinds(item, options = {}) {
58001
58608
  }
58002
58609
  return keybinds;
58003
58610
  }
58004
- var SLIDER_WIDTH = 10, PROGRESS_TOGGLE_KEYBIND, INVERT_TOGGLE_KEYBIND, COMPACT_TOGGLE_KEYBIND, CURSOR_TOGGLE_KEYBIND, DATE_TOGGLE_KEYBIND, HOUR_FORMAT_TOGGLE_KEYBIND, TIMEZONE_KEYBIND, LOCALE_KEYBIND;
58611
+ var SLIDER_WIDTH = 10, PROGRESS_TOGGLE_KEYBIND, INVERT_TOGGLE_KEYBIND, COMPACT_TOGGLE_KEYBIND, CURSOR_TOGGLE_KEYBIND, DATE_TOGGLE_KEYBIND, HOUR_FORMAT_TOGGLE_KEYBIND, WEEKDAY_TOGGLE_KEYBIND, TIMEZONE_KEYBIND, LOCALE_KEYBIND;
58005
58612
  var init_usage_display = __esm(() => {
58006
58613
  init_locales2();
58007
58614
  PROGRESS_TOGGLE_KEYBIND = { key: "p", label: "(p)rogress toggle", action: "toggle-progress" };
@@ -58010,6 +58617,7 @@ var init_usage_display = __esm(() => {
58010
58617
  CURSOR_TOGGLE_KEYBIND = { key: "t", label: "(t)ime cursor", action: "toggle-cursor" };
58011
58618
  DATE_TOGGLE_KEYBIND = { key: "t", label: "(t)imestamp", action: "toggle-date" };
58012
58619
  HOUR_FORMAT_TOGGLE_KEYBIND = { key: "h", label: "12/24 (h)our", action: "toggle-hour-format" };
58620
+ WEEKDAY_TOGGLE_KEYBIND = { key: "w", label: "(w)eekday", action: "toggle-weekday" };
58013
58621
  TIMEZONE_KEYBIND = { key: "z", label: "time(z)one", action: "edit-timezone" };
58014
58622
  LOCALE_KEYBIND = { key: "l", label: "(l)ocale", action: "edit-locale" };
58015
58623
  });
@@ -58915,7 +59523,8 @@ class CustomCommandWidget {
58915
59523
  input: jsonInput,
58916
59524
  timeout,
58917
59525
  stdio: ["pipe", "pipe", "ignore"],
58918
- env: process.env
59526
+ env: process.env,
59527
+ windowsHide: true
58919
59528
  }).trim();
58920
59529
  if (!item.preserveColors) {
58921
59530
  output = getVisibleText(output);
@@ -59582,7 +60191,7 @@ var require_has_flag = __commonJS((exports, module) => {
59582
60191
 
59583
60192
  // node_modules/supports-color/index.js
59584
60193
  var require_supports_color = __commonJS((exports, module) => {
59585
- var os4 = __require("os");
60194
+ var os5 = __require("os");
59586
60195
  var tty2 = __require("tty");
59587
60196
  var hasFlag2 = require_has_flag();
59588
60197
  var { env: env3 } = process;
@@ -59639,7 +60248,7 @@ var require_supports_color = __commonJS((exports, module) => {
59639
60248
  return min2;
59640
60249
  }
59641
60250
  if (process.platform === "win32") {
59642
- const osRelease = os4.release().split(".");
60251
+ const osRelease = os5.release().split(".");
59643
60252
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
59644
60253
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
59645
60254
  }
@@ -59987,7 +60596,7 @@ var init_dist4 = __esm(() => {
59987
60596
 
59988
60597
  // node_modules/https-proxy-agent/dist/parse-proxy-response.js
59989
60598
  function parseProxyResponse(socket) {
59990
- return new Promise((resolve, reject2) => {
60599
+ return new Promise((resolve2, reject2) => {
59991
60600
  let buffersLength = 0;
59992
60601
  const buffers = [];
59993
60602
  function read() {
@@ -60056,7 +60665,7 @@ function parseProxyResponse(socket) {
60056
60665
  }
60057
60666
  debug("got proxy server response: %o %o", firstLine, headers);
60058
60667
  cleanup();
60059
- resolve({
60668
+ resolve2({
60060
60669
  connect: {
60061
60670
  statusCode,
60062
60671
  statusText,
@@ -60196,10 +60805,10 @@ var init_usage_types = __esm(() => {
60196
60805
 
60197
60806
  // src/utils/usage-fetch.ts
60198
60807
  import { execFileSync as execFileSync3 } from "child_process";
60199
- import * as fs3 from "fs";
60808
+ import * as fs4 from "fs";
60200
60809
  import * as https from "https";
60201
- import * as os4 from "os";
60202
- import * as path3 from "path";
60810
+ import * as os5 from "os";
60811
+ import * as path4 from "path";
60203
60812
  function getUsageApiBucketUtilization(bucket) {
60204
60813
  return bucket === null ? 0 : bucket?.utilization ?? undefined;
60205
60814
  }
@@ -60258,8 +60867,8 @@ function parseUsageApiResponse(rawJson) {
60258
60867
  };
60259
60868
  }
60260
60869
  function ensureCacheDirExists() {
60261
- if (!fs3.existsSync(CACHE_DIR)) {
60262
- fs3.mkdirSync(CACHE_DIR, { recursive: true });
60870
+ if (!fs4.existsSync(CACHE_DIR)) {
60871
+ fs4.mkdirSync(CACHE_DIR, { recursive: true });
60263
60872
  }
60264
60873
  }
60265
60874
  function setCachedUsageError(error51, now2, maxAge = LOCK_MAX_AGE) {
@@ -60279,7 +60888,7 @@ function hasRequiredUsageField(data, field) {
60279
60888
  if (data[field] !== undefined) {
60280
60889
  return true;
60281
60890
  }
60282
- return data.extraUsageEnabled === false && EXTRA_USAGE_DETAIL_FIELDS.has(field);
60891
+ return data.extraUsageEnabled !== undefined && EXTRA_USAGE_DETAIL_FIELDS.has(field);
60283
60892
  }
60284
60893
  function hasRequiredUsageFields(data, requiredFields = []) {
60285
60894
  return requiredFields.every((field) => hasRequiredUsageField(data, field));
@@ -60361,7 +60970,7 @@ function parseMacKeychainCredentialCandidates(rawDump, servicePrefix = MACOS_USA
60361
60970
  }
60362
60971
  function readMacKeychainSecret(service) {
60363
60972
  try {
60364
- return execFileSync3("security", ["find-generic-password", "-s", service, "-w"], { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
60973
+ return execFileSync3("security", ["find-generic-password", "-s", service, "-w"], { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"], windowsHide: true }).trim();
60365
60974
  } catch {
60366
60975
  return null;
60367
60976
  }
@@ -60375,7 +60984,8 @@ function listMacKeychainCredentialCandidates() {
60375
60984
  const rawDump = execFileSync3("security", ["dump-keychain"], {
60376
60985
  encoding: "utf8",
60377
60986
  maxBuffer: MACOS_SECURITY_DUMP_MAX_BUFFER,
60378
- stdio: ["pipe", "pipe", "ignore"]
60987
+ stdio: ["pipe", "pipe", "ignore"],
60988
+ windowsHide: true
60379
60989
  });
60380
60990
  return parseMacKeychainCredentialCandidates(rawDump);
60381
60991
  } catch {
@@ -60394,8 +61004,8 @@ function readUsageTokenFromMacKeychainCandidates() {
60394
61004
  }
60395
61005
  function readUsageTokenFromCredentialsFile() {
60396
61006
  try {
60397
- const credFile = path3.join(getClaudeConfigDir(), ".credentials.json");
60398
- return parseUsageAccessToken(fs3.readFileSync(credFile, "utf8"));
61007
+ const credFile = path4.join(getClaudeConfigDir(), ".credentials.json");
61008
+ return parseUsageAccessToken(fs4.readFileSync(credFile, "utf8"));
60399
61009
  } catch {
60400
61010
  return null;
60401
61011
  }
@@ -60408,7 +61018,7 @@ function getUsageToken() {
60408
61018
  }
60409
61019
  function readStaleUsageCache() {
60410
61020
  try {
60411
- return parseCachedUsageData(fs3.readFileSync(CACHE_FILE, "utf8"));
61021
+ return parseCachedUsageData(fs4.readFileSync(CACHE_FILE, "utf8"));
60412
61022
  } catch {
60413
61023
  return null;
60414
61024
  }
@@ -60416,13 +61026,13 @@ function readStaleUsageCache() {
60416
61026
  function writeUsageLock(blockedUntil, error51) {
60417
61027
  try {
60418
61028
  ensureCacheDirExists();
60419
- fs3.writeFileSync(LOCK_FILE, JSON.stringify({ blockedUntil, error: error51 }));
61029
+ fs4.writeFileSync(LOCK_FILE, JSON.stringify({ blockedUntil, error: error51 }));
60420
61030
  } catch {}
60421
61031
  }
60422
61032
  function readActiveUsageLock(now2) {
60423
61033
  let hasValidJsonLock = false;
60424
61034
  try {
60425
- const parsed = parseJsonWithSchema(fs3.readFileSync(LOCK_FILE, "utf8"), UsageLockSchema);
61035
+ const parsed = parseJsonWithSchema(fs4.readFileSync(LOCK_FILE, "utf8"), UsageLockSchema);
60426
61036
  if (parsed) {
60427
61037
  hasValidJsonLock = true;
60428
61038
  if (parsed.blockedUntil > now2) {
@@ -60438,7 +61048,7 @@ function readActiveUsageLock(now2) {
60438
61048
  return null;
60439
61049
  }
60440
61050
  try {
60441
- const lockStat = fs3.statSync(LOCK_FILE);
61051
+ const lockStat = fs4.statSync(LOCK_FILE);
60442
61052
  const lockMtime = Math.floor(lockStat.mtimeMs / 1000);
60443
61053
  const blockedUntil = lockMtime + LOCK_MAX_AGE;
60444
61054
  if (blockedUntil > now2) {
@@ -60493,14 +61103,14 @@ function getUsageApiRequestOptions(token) {
60493
61103
  }
60494
61104
  }
60495
61105
  async function fetchFromUsageApi(token) {
60496
- return new Promise((resolve) => {
61106
+ return new Promise((resolve2) => {
60497
61107
  let settled = false;
60498
61108
  const finish = (value) => {
60499
61109
  if (settled) {
60500
61110
  return;
60501
61111
  }
60502
61112
  settled = true;
60503
- resolve(value);
61113
+ resolve2(value);
60504
61114
  };
60505
61115
  const requestOptions = getUsageApiRequestOptions(token);
60506
61116
  if (!requestOptions) {
@@ -60551,10 +61161,10 @@ async function fetchUsageData(options = {}) {
60551
61161
  }
60552
61162
  }
60553
61163
  try {
60554
- const stat = fs3.statSync(CACHE_FILE);
61164
+ const stat = fs4.statSync(CACHE_FILE);
60555
61165
  const fileAge = now2 - Math.floor(stat.mtimeMs / 1000);
60556
61166
  if (fileAge < CACHE_MAX_AGE) {
60557
- const fileData = parseCachedUsageData(fs3.readFileSync(CACHE_FILE, "utf8"));
61167
+ const fileData = parseCachedUsageData(fs4.readFileSync(CACHE_FILE, "utf8"));
60558
61168
  if (fileData && !fileData.error && hasRequiredUsageFields(fileData, requiredFields)) {
60559
61169
  return cacheUsageData(fileData, now2);
60560
61170
  }
@@ -60589,7 +61199,7 @@ async function fetchUsageData(options = {}) {
60589
61199
  }
60590
61200
  try {
60591
61201
  ensureCacheDirExists();
60592
- fs3.writeFileSync(CACHE_FILE, JSON.stringify(usageData));
61202
+ fs4.writeFileSync(CACHE_FILE, JSON.stringify(usageData));
60593
61203
  } catch {}
60594
61204
  return cacheUsageData(usageData, now2);
60595
61205
  } catch {
@@ -60603,9 +61213,9 @@ var init_usage_fetch = __esm(async () => {
60603
61213
  init_zod();
60604
61214
  init_usage_types();
60605
61215
  await init_claude_settings();
60606
- CACHE_DIR = path3.join(os4.homedir(), ".cache", "ccstatusline");
60607
- CACHE_FILE = path3.join(CACHE_DIR, "usage.json");
60608
- LOCK_FILE = path3.join(CACHE_DIR, "usage.lock");
61216
+ CACHE_DIR = path4.join(os5.homedir(), ".cache", "ccstatusline");
61217
+ CACHE_FILE = path4.join(CACHE_DIR, "usage.json");
61218
+ LOCK_FILE = path4.join(CACHE_DIR, "usage.lock");
60609
61219
  MACOS_SECURITY_DUMP_MAX_BUFFER = 8 * 1024 * 1024;
60610
61220
  EXTRA_USAGE_DETAIL_FIELDS = new Set([
60611
61221
  "extraUsageLimit",
@@ -60654,31 +61264,31 @@ var init_usage_fetch = __esm(async () => {
60654
61264
 
60655
61265
  // node_modules/fdir/dist/index.mjs
60656
61266
  import { createRequire as createRequire2 } from "module";
60657
- import { basename, dirname, normalize, relative, resolve, sep } from "path";
61267
+ import { basename, dirname as dirname2, normalize, relative, resolve as resolve2, sep } from "path";
60658
61268
  import * as nativeFs from "fs";
60659
- function cleanPath(path4) {
60660
- let normalized = normalize(path4);
61269
+ function cleanPath(path5) {
61270
+ let normalized = normalize(path5);
60661
61271
  if (normalized.length > 1 && normalized[normalized.length - 1] === sep)
60662
61272
  normalized = normalized.substring(0, normalized.length - 1);
60663
61273
  return normalized;
60664
61274
  }
60665
- function convertSlashes(path4, separator) {
60666
- return path4.replace(SLASHES_REGEX, separator);
61275
+ function convertSlashes(path5, separator) {
61276
+ return path5.replace(SLASHES_REGEX, separator);
60667
61277
  }
60668
- function isRootDirectory(path4) {
60669
- return path4 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path4);
61278
+ function isRootDirectory(path5) {
61279
+ return path5 === "/" || WINDOWS_ROOT_DIR_REGEX.test(path5);
60670
61280
  }
60671
- function normalizePath(path4, options) {
61281
+ function normalizePath(path5, options) {
60672
61282
  const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options;
60673
- const pathNeedsCleaning = process.platform === "win32" && path4.includes("/") || path4.startsWith(".");
61283
+ const pathNeedsCleaning = process.platform === "win32" && path5.includes("/") || path5.startsWith(".");
60674
61284
  if (resolvePaths)
60675
- path4 = resolve(path4);
61285
+ path5 = resolve2(path5);
60676
61286
  if (normalizePath$1 || pathNeedsCleaning)
60677
- path4 = cleanPath(path4);
60678
- if (path4 === ".")
61287
+ path5 = cleanPath(path5);
61288
+ if (path5 === ".")
60679
61289
  return "";
60680
- const needsSeperator = path4[path4.length - 1] !== pathSeparator;
60681
- return convertSlashes(needsSeperator ? path4 + pathSeparator : path4, pathSeparator);
61290
+ const needsSeperator = path5[path5.length - 1] !== pathSeparator;
61291
+ return convertSlashes(needsSeperator ? path5 + pathSeparator : path5, pathSeparator);
60682
61292
  }
60683
61293
  function joinPathWithBasePath(filename, directoryPath) {
60684
61294
  return directoryPath + filename;
@@ -60744,10 +61354,10 @@ function build$2(options, isSynchronous) {
60744
61354
  return null;
60745
61355
  return isSynchronous ? resolveSymlinks : resolveSymlinksAsync;
60746
61356
  }
60747
- function isRecursive(path4, resolved, state) {
61357
+ function isRecursive(path5, resolved, state) {
60748
61358
  if (state.options.useRealPaths)
60749
61359
  return isRecursiveUsingRealPaths(resolved, state);
60750
- let parent = dirname(path4);
61360
+ let parent = dirname2(path5);
60751
61361
  let depth = 1;
60752
61362
  while (parent !== state.root && depth < 2) {
60753
61363
  const resolvedPath = state.symlinks.get(parent);
@@ -60755,9 +61365,9 @@ function isRecursive(path4, resolved, state) {
60755
61365
  if (isSameRoot)
60756
61366
  depth++;
60757
61367
  else
60758
- parent = dirname(parent);
61368
+ parent = dirname2(parent);
60759
61369
  }
60760
- state.symlinks.set(path4, resolved);
61370
+ state.symlinks.set(path5, resolved);
60761
61371
  return depth > 1;
60762
61372
  }
60763
61373
  function isRecursiveUsingRealPaths(resolved, state) {
@@ -60803,9 +61413,9 @@ function sync(root, options) {
60803
61413
  var __require2, SLASHES_REGEX, WINDOWS_ROOT_DIR_REGEX, pushDirectory = (directoryPath, paths) => {
60804
61414
  paths.push(directoryPath || ".");
60805
61415
  }, pushDirectoryFilter = (directoryPath, paths, filters) => {
60806
- const path4 = directoryPath || ".";
60807
- if (filters.every((filter2) => filter2(path4, true)))
60808
- paths.push(path4);
61416
+ const path5 = directoryPath || ".";
61417
+ if (filters.every((filter2) => filter2(path5, true)))
61418
+ paths.push(path5);
60809
61419
  }, empty$2 = () => {}, pushFileFilterAndCount = (filename, _paths, counts, filters) => {
60810
61420
  if (filters.every((filter2) => filter2(filename, false)))
60811
61421
  counts.files++;
@@ -60826,28 +61436,28 @@ var __require2, SLASHES_REGEX, WINDOWS_ROOT_DIR_REGEX, pushDirectory = (director
60826
61436
  files,
60827
61437
  dir: directory
60828
61438
  });
60829
- }, empty = () => {}, resolveSymlinksAsync = function(path4, state, callback$1) {
60830
- const { queue, fs: fs4, options: { suppressErrors } } = state;
61439
+ }, empty = () => {}, resolveSymlinksAsync = function(path5, state, callback$1) {
61440
+ const { queue, fs: fs5, options: { suppressErrors } } = state;
60831
61441
  queue.enqueue();
60832
- fs4.realpath(path4, (error51, resolvedPath) => {
61442
+ fs5.realpath(path5, (error51, resolvedPath) => {
60833
61443
  if (error51)
60834
61444
  return queue.dequeue(suppressErrors ? null : error51, state);
60835
- fs4.stat(resolvedPath, (error$1, stat) => {
61445
+ fs5.stat(resolvedPath, (error$1, stat) => {
60836
61446
  if (error$1)
60837
61447
  return queue.dequeue(suppressErrors ? null : error$1, state);
60838
- if (stat.isDirectory() && isRecursive(path4, resolvedPath, state))
61448
+ if (stat.isDirectory() && isRecursive(path5, resolvedPath, state))
60839
61449
  return queue.dequeue(null, state);
60840
61450
  callback$1(stat, resolvedPath);
60841
61451
  queue.dequeue(null, state);
60842
61452
  });
60843
61453
  });
60844
- }, resolveSymlinks = function(path4, state, callback$1) {
60845
- const { queue, fs: fs4, options: { suppressErrors } } = state;
61454
+ }, resolveSymlinks = function(path5, state, callback$1) {
61455
+ const { queue, fs: fs5, options: { suppressErrors } } = state;
60846
61456
  queue.enqueue();
60847
61457
  try {
60848
- const resolvedPath = fs4.realpathSync(path4);
60849
- const stat = fs4.statSync(resolvedPath);
60850
- if (stat.isDirectory() && isRecursive(path4, resolvedPath, state))
61458
+ const resolvedPath = fs5.realpathSync(path5);
61459
+ const stat = fs5.statSync(resolvedPath);
61460
+ if (stat.isDirectory() && isRecursive(path5, resolvedPath, state))
60851
61461
  return;
60852
61462
  callback$1(stat, resolvedPath);
60853
61463
  } catch (e) {
@@ -60878,22 +61488,22 @@ var __require2, SLASHES_REGEX, WINDOWS_ROOT_DIR_REGEX, pushDirectory = (director
60878
61488
  state.queue.enqueue();
60879
61489
  if (currentDepth < 0)
60880
61490
  return state.queue.dequeue(null, state);
60881
- const { fs: fs4 } = state;
61491
+ const { fs: fs5 } = state;
60882
61492
  state.visited.push(crawlPath);
60883
61493
  state.counts.directories++;
60884
- fs4.readdir(crawlPath || ".", readdirOpts, (error51, entries = []) => {
61494
+ fs5.readdir(crawlPath || ".", readdirOpts, (error51, entries = []) => {
60885
61495
  callback$1(entries, directoryPath, currentDepth);
60886
61496
  state.queue.dequeue(state.options.suppressErrors ? null : error51, state);
60887
61497
  });
60888
61498
  }, walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
60889
- const { fs: fs4 } = state;
61499
+ const { fs: fs5 } = state;
60890
61500
  if (currentDepth < 0)
60891
61501
  return;
60892
61502
  state.visited.push(crawlPath);
60893
61503
  state.counts.directories++;
60894
61504
  let entries = [];
60895
61505
  try {
60896
- entries = fs4.readdirSync(crawlPath || ".", readdirOpts);
61506
+ entries = fs5.readdirSync(crawlPath || ".", readdirOpts);
60897
61507
  } catch (e) {
60898
61508
  if (!state.options.suppressErrors)
60899
61509
  throw e;
@@ -60992,23 +61602,23 @@ var __require2, SLASHES_REGEX, WINDOWS_ROOT_DIR_REGEX, pushDirectory = (director
60992
61602
  const filename = this.joinPath(entry.name, directoryPath);
60993
61603
  this.pushFile(filename, files, this.state.counts, filters);
60994
61604
  } else if (entry.isDirectory()) {
60995
- let path4 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
60996
- if (exclude && exclude(entry.name, path4))
61605
+ let path5 = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
61606
+ if (exclude && exclude(entry.name, path5))
60997
61607
  continue;
60998
- this.pushDirectory(path4, paths, filters);
60999
- this.walkDirectory(this.state, path4, path4, depth - 1, this.walk);
61608
+ this.pushDirectory(path5, paths, filters);
61609
+ this.walkDirectory(this.state, path5, path5, depth - 1, this.walk);
61000
61610
  } else if (this.resolveSymlink && entry.isSymbolicLink()) {
61001
- let path4 = joinPathWithBasePath(entry.name, directoryPath);
61002
- this.resolveSymlink(path4, this.state, (stat, resolvedPath) => {
61611
+ let path5 = joinPathWithBasePath(entry.name, directoryPath);
61612
+ this.resolveSymlink(path5, this.state, (stat, resolvedPath) => {
61003
61613
  if (stat.isDirectory()) {
61004
61614
  resolvedPath = normalizePath(resolvedPath, this.state.options);
61005
- if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path4 + pathSeparator))
61615
+ if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path5 + pathSeparator))
61006
61616
  return;
61007
- this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path4 + pathSeparator, depth - 1, this.walk);
61617
+ this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path5 + pathSeparator, depth - 1, this.walk);
61008
61618
  } else {
61009
- resolvedPath = useRealPaths ? resolvedPath : path4;
61619
+ resolvedPath = useRealPaths ? resolvedPath : path5;
61010
61620
  const filename = basename(resolvedPath);
61011
- const directoryPath$1 = normalizePath(dirname(resolvedPath), this.state.options);
61621
+ const directoryPath$1 = normalizePath(dirname2(resolvedPath), this.state.options);
61012
61622
  resolvedPath = this.joinPath(filename, directoryPath$1);
61013
61623
  this.pushFile(resolvedPath, files, this.state.counts, filters);
61014
61624
  }
@@ -61142,7 +61752,7 @@ var __require2, SLASHES_REGEX, WINDOWS_ROOT_DIR_REGEX, pushDirectory = (director
61142
61752
  isMatch2 = globFn(patterns, ...options);
61143
61753
  this.globCache[patterns.join("\x00")] = isMatch2;
61144
61754
  }
61145
- this.options.filters.push((path4) => isMatch2(path4));
61755
+ this.options.filters.push((path5) => isMatch2(path5));
61146
61756
  return this;
61147
61757
  }
61148
61758
  };
@@ -61355,8 +61965,8 @@ var require_utils = __commonJS((exports) => {
61355
61965
  }
61356
61966
  return output;
61357
61967
  };
61358
- exports.basename = (path4, { windows } = {}) => {
61359
- const segs = path4.split(windows ? /[\\/]/ : "/");
61968
+ exports.basename = (path5, { windows } = {}) => {
61969
+ const segs = path5.split(windows ? /[\\/]/ : "/");
61360
61970
  const last2 = segs[segs.length - 1];
61361
61971
  if (last2 === "") {
61362
61972
  return segs[segs.length - 2];
@@ -62837,8 +63447,8 @@ var require_picomatch2 = __commonJS((exports, module) => {
62837
63447
  });
62838
63448
 
62839
63449
  // node_modules/tinyglobby/dist/index.mjs
62840
- import { readdir, readdirSync, realpath, realpathSync, stat, statSync as statSync3 } from "fs";
62841
- import { isAbsolute, posix, resolve as resolve2 } from "path";
63450
+ import { readdir, readdirSync, realpath, realpathSync, stat, statSync as statSync4 } from "fs";
63451
+ import { isAbsolute, posix, resolve as resolve3 } from "path";
62842
63452
  import { fileURLToPath } from "url";
62843
63453
  function getPartialMatcher(patterns, options = {}) {
62844
63454
  const patternsCount = patterns.length;
@@ -62910,10 +63520,13 @@ function buildRelative(cwd2, root) {
62910
63520
  return p[p.length - 1] === "/" && result2 !== "" ? `${result2}/` : result2 || ".";
62911
63521
  };
62912
63522
  }
62913
- function splitPattern(path4) {
63523
+ function ensureNonDriveRelativePath(path5) {
63524
+ return path5.replace(DRIVE_RELATIVE_PATH, (match) => `${match}/`);
63525
+ }
63526
+ function splitPattern(path5) {
62914
63527
  var _result$parts;
62915
- const result2 = import_picomatch.default.scan(path4, splitPatternOptions);
62916
- return ((_result$parts = result2.parts) === null || _result$parts === undefined ? undefined : _result$parts.length) ? result2.parts : [path4];
63528
+ const result2 = import_picomatch.default.scan(path5, splitPatternOptions);
63529
+ return ((_result$parts = result2.parts) === null || _result$parts === undefined ? undefined : _result$parts.length) ? result2.parts : [path5];
62917
63530
  }
62918
63531
  function isDynamicPattern(pattern, options) {
62919
63532
  if ((options === null || options === undefined ? undefined : options.caseSensitiveMatch) === false)
@@ -62949,7 +63562,7 @@ function normalizePattern(pattern, opts, props, isIgnore) {
62949
63562
  }
62950
63563
  const potentialRoot = posix.join(cwd2, parentDir.slice(i * 3));
62951
63564
  if (potentialRoot[0] !== "." && props.root.length > potentialRoot.length) {
62952
- props.root = potentialRoot;
63565
+ props.root = ensureNonDriveRelativePath(potentialRoot);
62953
63566
  props.depthOffset = -n + i;
62954
63567
  }
62955
63568
  }
@@ -62970,7 +63583,7 @@ function normalizePattern(pattern, opts, props, isIgnore) {
62970
63583
  }
62971
63584
  props.depthOffset = newCommonPath.length;
62972
63585
  props.commonPath = newCommonPath;
62973
- props.root = newCommonPath.length > 0 ? posix.join(cwd2, ...newCommonPath) : cwd2;
63586
+ props.root = ensureNonDriveRelativePath(newCommonPath.length > 0 ? posix.join(cwd2, ...newCommonPath) : cwd2);
62974
63587
  }
62975
63588
  return result2;
62976
63589
  }
@@ -63029,14 +63642,14 @@ function buildCrawler(options, patterns) {
63029
63642
  maxDepth = Math.round(options.deep - props.depthOffset);
63030
63643
  const crawler = new Builder({
63031
63644
  filters: [debug3 ? (p, isDirectory) => {
63032
- const path4 = format(p, isDirectory);
63033
- const matches2 = matcher(path4) && !ignore(path4);
63645
+ const path5 = format(p, isDirectory);
63646
+ const matches2 = matcher(path5) && !ignore(path5);
63034
63647
  if (matches2)
63035
- log(`matched ${path4}`);
63648
+ log(`matched ${path5}`);
63036
63649
  return matches2;
63037
63650
  } : (p, isDirectory) => {
63038
- const path4 = format(p, isDirectory);
63039
- return matcher(path4) && !ignore(path4);
63651
+ const path5 = format(p, isDirectory);
63652
+ return matcher(path5) && !ignore(path5);
63040
63653
  }],
63041
63654
  exclude: debug3 ? (_, p) => {
63042
63655
  const skipped = excludePredicate(_, p);
@@ -63069,11 +63682,11 @@ function formatPaths(paths, mapper) {
63069
63682
  return paths;
63070
63683
  }
63071
63684
  function getOptions2(options) {
63072
- const opts = {
63073
- ...defaultOptions,
63074
- ...options
63075
- };
63076
- opts.cwd = (opts.cwd instanceof URL ? fileURLToPath(opts.cwd) : resolve2(opts.cwd)).replace(BACKSLASHES, "/");
63685
+ const opts = Object.assign({}, options);
63686
+ for (const key in defaultOptions)
63687
+ if (opts[key] === undefined)
63688
+ Object.assign(opts, { [key]: defaultOptions[key] });
63689
+ opts.cwd = (opts.cwd instanceof URL ? fileURLToPath(opts.cwd) : resolve3(opts.cwd || process.cwd())).replace(BACKSLASHES, "/");
63077
63690
  opts.ignore = ensureStringArray(opts.ignore);
63078
63691
  opts.fs && (opts.fs = {
63079
63692
  readdir: opts.fs.readdir || readdir,
@@ -63081,7 +63694,7 @@ function getOptions2(options) {
63081
63694
  realpath: opts.fs.realpath || realpath,
63082
63695
  realpathSync: opts.fs.realpathSync || realpathSync,
63083
63696
  stat: opts.fs.stat || stat,
63084
- statSync: opts.fs.statSync || statSync3
63697
+ statSync: opts.fs.statSync || statSync4
63085
63698
  });
63086
63699
  if (opts.debug)
63087
63700
  log("globbing with options:", opts);
@@ -63100,12 +63713,13 @@ function globSync(globInput, options) {
63100
63713
  const [crawler, relative2] = getCrawler(globInput, options);
63101
63714
  return crawler ? formatPaths(crawler.sync(), relative2) : [];
63102
63715
  }
63103
- var import_picomatch, isReadonlyArray, BACKSLASHES, isWin, ONLY_PARENT_DIRECTORIES, WIN32_ROOT_DIR, isRoot, splitPatternOptions, POSIX_UNESCAPED_GLOB_SYMBOLS, WIN32_UNESCAPED_GLOB_SYMBOLS, escapePosixPath = (path4) => path4.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"), escapeWin32Path = (path4) => path4.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"), escapePath, PARENT_DIRECTORY, ESCAPING_BACKSLASHES, defaultOptions;
63716
+ var import_picomatch, isReadonlyArray, BACKSLASHES, DRIVE_RELATIVE_PATH, isWin, ONLY_PARENT_DIRECTORIES, WIN32_ROOT_DIR, isRoot, splitPatternOptions, POSIX_UNESCAPED_GLOB_SYMBOLS, WIN32_UNESCAPED_GLOB_SYMBOLS, escapePosixPath = (path5) => path5.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"), escapeWin32Path = (path5) => path5.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"), escapePath, PARENT_DIRECTORY, ESCAPING_BACKSLASHES, defaultOptions;
63104
63717
  var init_dist7 = __esm(() => {
63105
63718
  init_dist6();
63106
63719
  import_picomatch = __toESM(require_picomatch2(), 1);
63107
63720
  isReadonlyArray = Array.isArray;
63108
63721
  BACKSLASHES = /\\/g;
63722
+ DRIVE_RELATIVE_PATH = /^[A-Za-z]:$/;
63109
63723
  isWin = process.platform === "win32";
63110
63724
  ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/;
63111
63725
  WIN32_ROOT_DIR = /^[A-Z]:\/$/i;
@@ -63118,7 +63732,6 @@ var init_dist7 = __esm(() => {
63118
63732
  ESCAPING_BACKSLASHES = /\\(?=[()[\]{}!*+?@|])/g;
63119
63733
  defaultOptions = {
63120
63734
  caseSensitiveMatch: true,
63121
- cwd: process.cwd(),
63122
63735
  debug: !!process.env.TINYGLOBBY_DEBUG,
63123
63736
  expandDirectories: true,
63124
63737
  followSymbolicLinks: true,
@@ -63127,7 +63740,7 @@ var init_dist7 = __esm(() => {
63127
63740
  });
63128
63741
 
63129
63742
  // src/utils/jsonl-lines.ts
63130
- import * as fs4 from "fs";
63743
+ import * as fs5 from "fs";
63131
63744
  import { promisify } from "util";
63132
63745
  function splitJsonlContent(content) {
63133
63746
  return content.trim().split(`
@@ -63138,7 +63751,7 @@ async function readJsonlLines(filePath) {
63138
63751
  return splitJsonlContent(content);
63139
63752
  }
63140
63753
  function readJsonlLinesSync(filePath) {
63141
- const content = readFileSync6(filePath, "utf-8");
63754
+ const content = readFileSync7(filePath, "utf-8");
63142
63755
  return splitJsonlContent(content);
63143
63756
  }
63144
63757
  function parseJsonlLine(line) {
@@ -63148,15 +63761,15 @@ function parseJsonlLine(line) {
63148
63761
  return null;
63149
63762
  }
63150
63763
  }
63151
- var readFile2, readFileSync6;
63764
+ var readFile2, readFileSync7;
63152
63765
  var init_jsonl_lines = __esm(() => {
63153
- readFile2 = promisify(fs4.readFile);
63154
- readFileSync6 = fs4.readFileSync;
63766
+ readFile2 = promisify(fs5.readFile);
63767
+ readFileSync7 = fs5.readFileSync;
63155
63768
  });
63156
63769
 
63157
63770
  // src/utils/jsonl-blocks.ts
63158
- import * as fs5 from "fs";
63159
- import path4 from "node:path";
63771
+ import * as fs6 from "fs";
63772
+ import path5 from "node:path";
63160
63773
  function getBlockMetrics() {
63161
63774
  const claudeDir = getClaudeConfigDir();
63162
63775
  if (!claudeDir)
@@ -63170,7 +63783,7 @@ function getBlockMetrics() {
63170
63783
  function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
63171
63784
  const sessionDurationMs = sessionDurationHours * 60 * 60 * 1000;
63172
63785
  const now2 = new Date;
63173
- const pattern = path4.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
63786
+ const pattern = path5.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
63174
63787
  const files = globSync([pattern], {
63175
63788
  absolute: true,
63176
63789
  cwd: rootDir
@@ -63178,7 +63791,7 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
63178
63791
  if (files.length === 0)
63179
63792
  return null;
63180
63793
  const filesWithStats = files.map((file2) => {
63181
- const stats = statSync5(file2);
63794
+ const stats = statSync6(file2);
63182
63795
  return { file: file2, mtime: stats.mtime };
63183
63796
  });
63184
63797
  filesWithStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
@@ -63296,26 +63909,26 @@ function floorToHour(timestamp) {
63296
63909
  floored.setUTCMinutes(0, 0, 0);
63297
63910
  return floored;
63298
63911
  }
63299
- var statSync5;
63912
+ var statSync6;
63300
63913
  var init_jsonl_blocks = __esm(async () => {
63301
63914
  init_dist7();
63302
63915
  init_jsonl_lines();
63303
63916
  await init_claude_settings();
63304
- statSync5 = fs5.statSync;
63917
+ statSync6 = fs6.statSync;
63305
63918
  });
63306
63919
 
63307
63920
  // src/utils/jsonl-cache.ts
63308
- import * as fs6 from "fs";
63309
- import { createHash as createHash2 } from "node:crypto";
63310
- import os5 from "node:os";
63311
- import path5 from "node:path";
63921
+ import * as fs7 from "fs";
63922
+ import { createHash as createHash3 } from "node:crypto";
63923
+ import os6 from "node:os";
63924
+ import path6 from "node:path";
63312
63925
  function normalizeConfigDir(configDir) {
63313
- return path5.resolve(configDir);
63926
+ return path6.resolve(configDir);
63314
63927
  }
63315
63928
  function getBlockCachePath(configDir = getClaudeConfigDir()) {
63316
63929
  const normalizedConfigDir = normalizeConfigDir(configDir);
63317
- const configHash = createHash2("sha256").update(normalizedConfigDir).digest("hex").slice(0, 16);
63318
- return path5.join(os5.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
63930
+ const configHash = createHash3("sha256").update(normalizedConfigDir).digest("hex").slice(0, 16);
63931
+ return path6.join(os6.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
63319
63932
  }
63320
63933
  function readBlockCache(expectedConfigDir) {
63321
63934
  try {
@@ -63324,7 +63937,7 @@ function readBlockCache(expectedConfigDir) {
63324
63937
  if (!existsSync6(cachePath)) {
63325
63938
  return null;
63326
63939
  }
63327
- const content = readFileSync8(cachePath, "utf-8");
63940
+ const content = readFileSync9(cachePath, "utf-8");
63328
63941
  const cache3 = JSON.parse(content);
63329
63942
  if (typeof cache3.startTime !== "string") {
63330
63943
  return null;
@@ -63350,15 +63963,15 @@ function writeBlockCache(startTime, configDir = getClaudeConfigDir()) {
63350
63963
  try {
63351
63964
  const normalizedConfigDir = normalizeConfigDir(configDir);
63352
63965
  const cachePath = getBlockCachePath(normalizedConfigDir);
63353
- const cacheDir = path5.dirname(cachePath);
63966
+ const cacheDir = path6.dirname(cachePath);
63354
63967
  if (!existsSync6(cacheDir)) {
63355
- mkdirSync4(cacheDir, { recursive: true });
63968
+ mkdirSync5(cacheDir, { recursive: true });
63356
63969
  }
63357
63970
  const cache3 = {
63358
63971
  startTime: startTime.toISOString(),
63359
63972
  configDir: normalizedConfigDir
63360
63973
  };
63361
- writeFileSync4(cachePath, JSON.stringify(cache3), "utf-8");
63974
+ writeFileSync5(cachePath, JSON.stringify(cache3), "utf-8");
63362
63975
  } catch {}
63363
63976
  }
63364
63977
  function getCachedBlockMetrics(sessionDurationHours = 5) {
@@ -63381,21 +63994,21 @@ function getCachedBlockMetrics(sessionDurationHours = 5) {
63381
63994
  }
63382
63995
  return metrics;
63383
63996
  }
63384
- var readFileSync8, writeFileSync4, mkdirSync4, existsSync6;
63997
+ var readFileSync9, writeFileSync5, mkdirSync5, existsSync6;
63385
63998
  var init_jsonl_cache = __esm(async () => {
63386
63999
  await __promiseAll([
63387
64000
  init_claude_settings(),
63388
64001
  init_jsonl_blocks()
63389
64002
  ]);
63390
- readFileSync8 = fs6.readFileSync;
63391
- writeFileSync4 = fs6.writeFileSync;
63392
- mkdirSync4 = fs6.mkdirSync;
63393
- existsSync6 = fs6.existsSync;
64003
+ readFileSync9 = fs7.readFileSync;
64004
+ writeFileSync5 = fs7.writeFileSync;
64005
+ mkdirSync5 = fs7.mkdirSync;
64006
+ existsSync6 = fs7.existsSync;
63394
64007
  });
63395
64008
 
63396
64009
  // src/utils/jsonl-metrics.ts
63397
- import * as fs7 from "fs";
63398
- import path6 from "node:path";
64010
+ import * as fs8 from "fs";
64011
+ import path7 from "node:path";
63399
64012
  function collectAgentIds(value, agentIds) {
63400
64013
  if (!value || typeof value !== "object") {
63401
64014
  return;
@@ -63427,7 +64040,7 @@ function getReferencedSubagentIds(lines) {
63427
64040
  }
63428
64041
  async function getSessionDuration(transcriptPath) {
63429
64042
  try {
63430
- if (!fs7.existsSync(transcriptPath)) {
64043
+ if (!fs8.existsSync(transcriptPath)) {
63431
64044
  return null;
63432
64045
  }
63433
64046
  const lines = await readJsonlLines(transcriptPath);
@@ -63477,7 +64090,7 @@ async function getSessionDuration(transcriptPath) {
63477
64090
  }
63478
64091
  async function getTokenMetrics(transcriptPath) {
63479
64092
  try {
63480
- if (!fs7.existsSync(transcriptPath)) {
64093
+ if (!fs8.existsSync(transcriptPath)) {
63481
64094
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
63482
64095
  }
63483
64096
  const lines = await readJsonlLines(transcriptPath);
@@ -63691,20 +64304,20 @@ function getSubagentTranscriptPaths(transcriptPath, referencedAgentIds) {
63691
64304
  if (referencedAgentIds.size === 0) {
63692
64305
  return [];
63693
64306
  }
63694
- const transcriptDir = path6.dirname(transcriptPath);
63695
- const transcriptStem = path6.parse(transcriptPath).name;
64307
+ const transcriptDir = path7.dirname(transcriptPath);
64308
+ const transcriptStem = path7.parse(transcriptPath).name;
63696
64309
  const candidateDirs = [
63697
- path6.join(transcriptDir, "subagents"),
63698
- path6.join(transcriptDir, transcriptStem, "subagents")
64310
+ path7.join(transcriptDir, "subagents"),
64311
+ path7.join(transcriptDir, transcriptStem, "subagents")
63699
64312
  ];
63700
64313
  const seenPaths = new Set;
63701
64314
  const matchedPaths = [];
63702
64315
  for (const subagentsDir of candidateDirs) {
63703
- if (!fs7.existsSync(subagentsDir)) {
64316
+ if (!fs8.existsSync(subagentsDir)) {
63704
64317
  continue;
63705
64318
  }
63706
64319
  try {
63707
- const dirEntries = fs7.readdirSync(subagentsDir, { withFileTypes: true });
64320
+ const dirEntries = fs8.readdirSync(subagentsDir, { withFileTypes: true });
63708
64321
  for (const entry of dirEntries) {
63709
64322
  if (!entry.isFile()) {
63710
64323
  continue;
@@ -63716,7 +64329,7 @@ function getSubagentTranscriptPaths(transcriptPath, referencedAgentIds) {
63716
64329
  if (!referencedAgentIds.has(match[1])) {
63717
64330
  continue;
63718
64331
  }
63719
- const fullPath = path6.join(subagentsDir, entry.name);
64332
+ const fullPath = path7.join(subagentsDir, entry.name);
63720
64333
  if (seenPaths.has(fullPath)) {
63721
64334
  continue;
63722
64335
  }
@@ -63733,7 +64346,7 @@ async function getSpeedMetricsCollection(transcriptPath, options = {}) {
63733
64346
  const normalizedWindows = Array.from(new Set((options.windowSeconds ?? []).map((window2) => normalizeWindowSeconds(window2)).filter((window2) => window2 !== null)));
63734
64347
  const emptyWindowedMetrics = buildEmptyWindowedMetrics(normalizedWindows);
63735
64348
  try {
63736
- if (!fs7.existsSync(transcriptPath)) {
64349
+ if (!fs8.existsSync(transcriptPath)) {
63737
64350
  return {
63738
64351
  sessionAverage: createEmptySpeedMetrics(),
63739
64352
  windowed: emptyWindowedMetrics
@@ -63930,44 +64543,69 @@ function formatUsageDuration(durationMs, compact2 = false, useDays = true) {
63930
64543
  function pad2(value) {
63931
64544
  return value.toString().padStart(2, "0");
63932
64545
  }
63933
- function formatResetAtUtc(date5, compact2, hour12) {
64546
+ function formatResetAtUtc(date5, compact2, hour12, weekday = false) {
63934
64547
  const year = date5.getUTCFullYear();
63935
64548
  const month = pad2(date5.getUTCMonth() + 1);
63936
64549
  const day = pad2(date5.getUTCDate());
63937
64550
  const hours = pad2(date5.getUTCHours());
63938
64551
  const minutes = pad2(date5.getUTCMinutes());
64552
+ const weekdayName = weekday ? UTC_WEEKDAY_NAMES[date5.getUTCDay()] : "";
63939
64553
  if (hour12) {
63940
64554
  const hour = date5.getUTCHours();
63941
64555
  const displayHour = hour % 12 || 12;
63942
64556
  const period = hour >= 12 ? "PM" : "AM";
64557
+ if (weekday) {
64558
+ return compact2 ? `${weekdayName} ${displayHour}:${minutes} ${period}Z` : `${weekdayName} ${displayHour}:${minutes} ${period} UTC`;
64559
+ }
63943
64560
  return compact2 ? `${month}-${day} ${displayHour}:${minutes} ${period}Z` : `${year}-${month}-${day} ${displayHour}:${minutes} ${period} UTC`;
63944
64561
  }
64562
+ if (weekday) {
64563
+ return compact2 ? `${weekdayName} ${hours}:${minutes}Z` : `${weekdayName} ${hours}:${minutes} UTC`;
64564
+ }
63945
64565
  return compact2 ? `${month}-${day} ${hours}:${minutes}Z` : `${year}-${month}-${day} ${hours}:${minutes} UTC`;
63946
64566
  }
63947
64567
  function normalizeDayPeriod(dayPeriod) {
63948
64568
  return dayPeriod.replace(/\./g, "").toUpperCase();
63949
64569
  }
63950
- function formatResetAtInTimezone(date5, compact2, timezone, locale, hour12) {
64570
+ function formatResetAtInTimezone(date5, compact2, timezone, locale, hour12, weekday = false) {
63951
64571
  try {
63952
- const formatter = new Intl.DateTimeFormat(locale, {
64572
+ const options = {
63953
64573
  timeZone: timezone,
63954
- year: "numeric",
63955
- month: "2-digit",
63956
- day: "2-digit",
63957
64574
  hour: "2-digit",
63958
64575
  minute: "2-digit",
63959
64576
  hour12,
63960
64577
  timeZoneName: "short"
63961
- });
64578
+ };
64579
+ if (weekday) {
64580
+ options.weekday = "short";
64581
+ } else {
64582
+ options.year = "numeric";
64583
+ options.month = "2-digit";
64584
+ options.day = "2-digit";
64585
+ }
64586
+ const formatter = new Intl.DateTimeFormat(locale, options);
63962
64587
  const parts = formatter.formatToParts(date5);
63963
64588
  const get2 = (type) => parts.find((p) => p.type === type)?.value ?? "";
63964
- const year = get2("year");
63965
- const month = get2("month");
63966
- const day = get2("day");
63967
64589
  const hour = get2("hour");
63968
64590
  const minute = get2("minute");
63969
64591
  const dayPeriod = get2("dayPeriod");
63970
64592
  const tzName = get2("timeZoneName");
64593
+ if (weekday) {
64594
+ const weekdayName = get2("weekday");
64595
+ if (!weekdayName || !hour || !minute) {
64596
+ return null;
64597
+ }
64598
+ if (hour12) {
64599
+ const displayHour = hour.startsWith("0") ? hour.slice(1) : hour;
64600
+ const normalizedDayPeriod = dayPeriod ? normalizeDayPeriod(dayPeriod) : "";
64601
+ const time3 = `${displayHour}:${minute}${normalizedDayPeriod ? ` ${normalizedDayPeriod}` : ""}`;
64602
+ return compact2 ? `${weekdayName} ${time3}` : `${weekdayName} ${time3} ${tzName}`;
64603
+ }
64604
+ return compact2 ? `${weekdayName} ${hour}:${minute}` : `${weekdayName} ${hour}:${minute} ${tzName}`;
64605
+ }
64606
+ const year = get2("year");
64607
+ const month = get2("month");
64608
+ const day = get2("day");
63971
64609
  if (!year || !month || !day || !hour || !minute) {
63972
64610
  return null;
63973
64611
  }
@@ -63982,7 +64620,7 @@ function formatResetAtInTimezone(date5, compact2, timezone, locale, hour12) {
63982
64620
  return null;
63983
64621
  }
63984
64622
  }
63985
- function formatUsageResetAt(resetAt, compact2 = false, timezone, localeOrHour12, hour12Arg = false) {
64623
+ function formatUsageResetAt(resetAt, compact2 = false, timezone, localeOrHour12, hour12Arg = false, weekday = false) {
63986
64624
  if (!resetAt) {
63987
64625
  return null;
63988
64626
  }
@@ -63994,21 +64632,21 @@ function formatUsageResetAt(resetAt, compact2 = false, timezone, localeOrHour12,
63994
64632
  const locale = typeof localeOrHour12 === "string" ? localeOrHour12 : undefined;
63995
64633
  const hour12 = typeof localeOrHour12 === "boolean" ? localeOrHour12 : hour12Arg;
63996
64634
  if (!timezone || timezone === "UTC") {
63997
- return formatResetAtUtc(date5, compact2, hour12);
64635
+ return formatResetAtUtc(date5, compact2, hour12, weekday);
63998
64636
  }
63999
64637
  const resolvedTimezone = timezone === "local" ? undefined : timezone;
64000
64638
  const resolvedLocale = locale && locale.length > 0 ? locale : DEFAULT_TZ_LOCALE;
64001
- const localized = formatResetAtInTimezone(date5, compact2, resolvedTimezone, resolvedLocale, hour12);
64639
+ const localized = formatResetAtInTimezone(date5, compact2, resolvedTimezone, resolvedLocale, hour12, weekday);
64002
64640
  if (localized) {
64003
64641
  return localized;
64004
64642
  }
64005
64643
  if (resolvedLocale !== DEFAULT_TZ_LOCALE) {
64006
- const fallback = formatResetAtInTimezone(date5, compact2, resolvedTimezone, DEFAULT_TZ_LOCALE, hour12);
64644
+ const fallback = formatResetAtInTimezone(date5, compact2, resolvedTimezone, DEFAULT_TZ_LOCALE, hour12, weekday);
64007
64645
  if (fallback) {
64008
64646
  return fallback;
64009
64647
  }
64010
64648
  }
64011
- return formatResetAtUtc(date5, compact2, hour12);
64649
+ return formatResetAtUtc(date5, compact2, hour12, weekday);
64012
64650
  }
64013
64651
  function getUsageErrorMessage(error51) {
64014
64652
  switch (error51) {
@@ -64029,10 +64667,11 @@ function makeUsageProgressBar(percent, width = 15) {
64029
64667
  const empty2 = width - filled;
64030
64668
  return "[" + "█".repeat(filled) + "░".repeat(empty2) + "]";
64031
64669
  }
64032
- var DEFAULT_TZ_LOCALE = "en-US";
64670
+ var UTC_WEEKDAY_NAMES, DEFAULT_TZ_LOCALE = "en-US";
64033
64671
  var init_usage_windows = __esm(async () => {
64034
64672
  init_usage_types();
64035
64673
  await init_jsonl();
64674
+ UTC_WEEKDAY_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
64036
64675
  });
64037
64676
 
64038
64677
  // src/utils/usage.ts
@@ -64148,7 +64787,7 @@ var init_BlockTimer = __esm(async () => {
64148
64787
  });
64149
64788
 
64150
64789
  // src/widgets/CurrentWorkingDir.tsx
64151
- import * as os6 from "node:os";
64790
+ import * as os7 from "node:os";
64152
64791
 
64153
64792
  class CurrentWorkingDirWidget {
64154
64793
  getDefaultColor() {
@@ -64293,27 +64932,27 @@ class CurrentWorkingDirWidget {
64293
64932
  supportsColors(item) {
64294
64933
  return true;
64295
64934
  }
64296
- abbreviateHomeDir(path7) {
64297
- const homeDir = os6.homedir();
64298
- if (path7 === homeDir) {
64935
+ abbreviateHomeDir(path8) {
64936
+ const homeDir = os7.homedir();
64937
+ if (path8 === homeDir) {
64299
64938
  return "~";
64300
64939
  }
64301
- if (path7.startsWith(homeDir)) {
64302
- const boundaryChar = path7[homeDir.length];
64940
+ if (path8.startsWith(homeDir)) {
64941
+ const boundaryChar = path8[homeDir.length];
64303
64942
  if (boundaryChar !== "/" && boundaryChar !== "\\") {
64304
- return path7;
64943
+ return path8;
64305
64944
  }
64306
- return "~" + path7.slice(homeDir.length);
64945
+ return "~" + path8.slice(homeDir.length);
64307
64946
  }
64308
- return path7;
64947
+ return path8;
64309
64948
  }
64310
- abbreviatePath(path7) {
64311
- const homeDir = os6.homedir();
64312
- const useBackslash = path7.includes("\\") && !path7.includes("/");
64949
+ abbreviatePath(path8) {
64950
+ const homeDir = os7.homedir();
64951
+ const useBackslash = path8.includes("\\") && !path8.includes("/");
64313
64952
  const sep2 = useBackslash ? "\\" : "/";
64314
- let normalizedPath = path7;
64315
- if (path7.startsWith(homeDir)) {
64316
- normalizedPath = "~" + path7.slice(homeDir.length);
64953
+ let normalizedPath = path8;
64954
+ if (path8.startsWith(homeDir)) {
64955
+ normalizedPath = "~" + path8.slice(homeDir.length);
64317
64956
  }
64318
64957
  const parts = normalizedPath.split(/[\\/]+/).filter((part) => part !== "");
64319
64958
  const abbreviated = parts.map((part, index) => {
@@ -64445,6 +65084,7 @@ function runJjArgs(args, context, allowEmpty = false) {
64445
65084
  const output = execFileSync4("jj", args, {
64446
65085
  encoding: "utf8",
64447
65086
  stdio: ["pipe", "pipe", "ignore"],
65087
+ windowsHide: true,
64448
65088
  ...cwd2 ? { cwd: cwd2 } : {}
64449
65089
  }).trimEnd();
64450
65090
  return allowEmpty || output.length > 0 ? output : null;
@@ -65082,7 +65722,7 @@ var init_JjRevision = __esm(() => {
65082
65722
  });
65083
65723
 
65084
65724
  // src/widgets/ClaudeAccountEmail.ts
65085
- import * as fs8 from "fs";
65725
+ import * as fs9 from "fs";
65086
65726
 
65087
65727
  class ClaudeAccountEmailWidget {
65088
65728
  getDefaultColor() {
@@ -65105,7 +65745,7 @@ class ClaudeAccountEmailWidget {
65105
65745
  return item.rawValue ? "you@example.com" : "Account: you@example.com";
65106
65746
  }
65107
65747
  try {
65108
- const content = fs8.readFileSync(getClaudeJsonPath(), "utf-8");
65748
+ const content = fs9.readFileSync(getClaudeJsonPath(), "utf-8");
65109
65749
  const data = JSON.parse(content);
65110
65750
  const email3 = data.oauthAccount?.emailAddress;
65111
65751
  if (typeof email3 !== "string" || email3.length === 0) {
@@ -65459,7 +66099,7 @@ var init_TotalSpeed = __esm(async () => {
65459
66099
 
65460
66100
  // src/widgets/FreeMemory.ts
65461
66101
  import { execSync as execSync3 } from "child_process";
65462
- import os7 from "os";
66102
+ import os8 from "os";
65463
66103
  function formatBytes(bytes) {
65464
66104
  const GB = 1024 ** 3;
65465
66105
  const MB = 1024 ** 2;
@@ -65474,7 +66114,7 @@ function formatBytes(bytes) {
65474
66114
  }
65475
66115
  function getUsedMemoryMacOS() {
65476
66116
  try {
65477
- const output = execSync3("vm_stat", { encoding: "utf8" });
66117
+ const output = execSync3("vm_stat", { encoding: "utf8", windowsHide: true });
65478
66118
  const lines = output.split(`
65479
66119
  `);
65480
66120
  const firstLine = lines[0];
@@ -65523,12 +66163,12 @@ class FreeMemoryWidget {
65523
66163
  if (context.isPreview) {
65524
66164
  return item.rawValue ? "12.4G/16.0G" : "Mem: 12.4G/16.0G";
65525
66165
  }
65526
- const total = os7.totalmem();
66166
+ const total = os8.totalmem();
65527
66167
  let used;
65528
- if (os7.platform() === "darwin") {
65529
- used = getUsedMemoryMacOS() ?? total - os7.freemem();
66168
+ if (os8.platform() === "darwin") {
66169
+ used = getUsedMemoryMacOS() ?? total - os8.freemem();
65530
66170
  } else {
65531
- used = total - os7.freemem();
66171
+ used = total - os8.freemem();
65532
66172
  }
65533
66173
  const value = `${formatBytes(used)}/${formatBytes(total)}`;
65534
66174
  return item.rawValue ? value : `Mem: ${value}`;
@@ -65543,7 +66183,7 @@ class FreeMemoryWidget {
65543
66183
  var init_FreeMemory = () => {};
65544
66184
 
65545
66185
  // src/widgets/SessionName.ts
65546
- import * as fs9 from "fs";
66186
+ import * as fs10 from "fs";
65547
66187
 
65548
66188
  class SessionNameWidget {
65549
66189
  getDefaultColor() {
@@ -65570,7 +66210,7 @@ class SessionNameWidget {
65570
66210
  return null;
65571
66211
  }
65572
66212
  try {
65573
- const content = fs9.readFileSync(transcriptPath, "utf-8");
66213
+ const content = fs10.readFileSync(transcriptPath, "utf-8");
65574
66214
  const lines = content.split(`
65575
66215
  `);
65576
66216
  for (let i = lines.length - 1;i >= 0; i--) {
@@ -65895,7 +66535,7 @@ class ExtraUsageUtilizationWidget {
65895
66535
  return getUsageErrorMessage(data.error);
65896
66536
  return null;
65897
66537
  }
65898
- const percent = Math.max(0, Math.min(100, data.extraUsageUtilization * 100));
66538
+ const percent = Math.max(0, Math.min(100, data.extraUsageUtilization));
65899
66539
  const renderedPercent = inverted ? 100 - percent : percent;
65900
66540
  if (isUsageProgressMode(displayMode)) {
65901
66541
  const width = getUsageProgressBarWidth(displayMode);
@@ -65962,7 +66602,8 @@ class ExtraUsageRemainingWidget {
65962
66602
  return null;
65963
66603
  }
65964
66604
  const limitDollars = data.extraUsageLimit / 100;
65965
- const remaining = Math.max(0, limitDollars - data.extraUsageUsed);
66605
+ const usedDollars = data.extraUsageUsed / 100;
66606
+ const remaining = Math.max(0, limitDollars - usedDollars);
65966
66607
  const formatted = `$${remaining.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
65967
66608
  return formatRawOrLabeledValue(item, "Overage Left: ", formatted);
65968
66609
  }
@@ -66797,6 +67438,9 @@ function getWeeklyResetModifierText(item) {
66797
67438
  if (isUsage12HourClock(item)) {
66798
67439
  modifiers.push("12hr");
66799
67440
  }
67441
+ if (isUsageWeekdayEnabled(item)) {
67442
+ modifiers.push("weekday");
67443
+ }
66800
67444
  } else if (isWeeklyResetHoursOnly(item)) {
66801
67445
  modifiers.push("hours only");
66802
67446
  }
@@ -66847,6 +67491,9 @@ class WeeklyResetTimerWidget {
66847
67491
  if (action === "toggle-hour-format") {
66848
67492
  return toggleUsageHourFormat(item);
66849
67493
  }
67494
+ if (action === "toggle-weekday") {
67495
+ return toggleUsageWeekday(item);
67496
+ }
66850
67497
  if (action === "toggle-hours") {
66851
67498
  return toggleWeeklyResetHoursOnly(item);
66852
67499
  }
@@ -66871,8 +67518,10 @@ class WeeklyResetTimerWidget {
66871
67518
  return formatRawOrLabeledValue(item, "Weekly Reset ", sliderDisplay);
66872
67519
  }
66873
67520
  if (dateMode) {
66874
- const resetAt = formatUsageResetAt(WEEKLY_RESET_PREVIEW_AT, compact2, getUsageTimezone(item), getUsageLocale(item), isUsage12HourClock(item));
66875
- return formatRawOrLabeledValue(item, "Weekly Reset: ", resetAt ?? (compact2 ? "03-15 08:30Z" : "2026-03-15 08:30 UTC"));
67521
+ const weekday = isUsageWeekdayEnabled(item);
67522
+ const resetAt = formatUsageResetAt(WEEKLY_RESET_PREVIEW_AT, compact2, getUsageTimezone(item), getUsageLocale(item), isUsage12HourClock(item), weekday);
67523
+ const fallback = weekday ? compact2 ? "Sun 08:30Z" : "Sun 08:30 UTC" : compact2 ? "03-15 08:30Z" : "2026-03-15 08:30 UTC";
67524
+ return formatRawOrLabeledValue(item, "Weekly Reset: ", resetAt ?? fallback);
66876
67525
  }
66877
67526
  return formatRawOrLabeledValue(item, "Weekly Reset: ", formatUsageDuration(WEEKLY_PREVIEW_DURATION_MS, compact2, useDays));
66878
67527
  }
@@ -66900,7 +67549,7 @@ class WeeklyResetTimerWidget {
66900
67549
  if (dateMode) {
66901
67550
  const timezone = getUsageTimezone(item);
66902
67551
  const locale = getUsageLocale(item);
66903
- const resetAt = formatUsageResetAt(usageData.weeklyResetAt, compact2, timezone, locale, isUsage12HourClock(item));
67552
+ const resetAt = formatUsageResetAt(usageData.weeklyResetAt, compact2, timezone, locale, isUsage12HourClock(item), isUsageWeekdayEnabled(item));
66904
67553
  if (resetAt) {
66905
67554
  return formatRawOrLabeledValue(item, "Weekly Reset: ", resetAt);
66906
67555
  }
@@ -66912,6 +67561,7 @@ class WeeklyResetTimerWidget {
66912
67561
  const keybinds = getUsageTimerCustomKeybinds(item, {
66913
67562
  includeDate: true,
66914
67563
  includeHourFormat: true,
67564
+ includeWeekday: true,
66915
67565
  includeLocale: true,
66916
67566
  includeTimezone: true
66917
67567
  });
@@ -68047,6 +68697,137 @@ var init_VoiceStatus = __esm(async () => {
68047
68697
  FORMATS3 = ["icon", "icon-text", "text", "word"];
68048
68698
  });
68049
68699
 
68700
+ // src/widgets/RemoteControlStatus.ts
68701
+ function getFormat4(item) {
68702
+ const f = item.metadata?.format;
68703
+ return FORMATS4.includes(f ?? "") ? f : DEFAULT_FORMAT4;
68704
+ }
68705
+ function setFormat4(item, format) {
68706
+ if (format === DEFAULT_FORMAT4) {
68707
+ const { format: removedFormat, ...restMetadata } = item.metadata ?? {};
68708
+ return {
68709
+ ...item,
68710
+ metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
68711
+ };
68712
+ }
68713
+ return {
68714
+ ...item,
68715
+ metadata: {
68716
+ ...item.metadata ?? {},
68717
+ format
68718
+ }
68719
+ };
68720
+ }
68721
+ function isNerdFontEnabled4(item) {
68722
+ return item.metadata?.[NERD_FONT_METADATA_KEY4] === "true";
68723
+ }
68724
+ function toggleNerdFont4(item) {
68725
+ if (!isNerdFontEnabled4(item)) {
68726
+ return {
68727
+ ...item,
68728
+ metadata: {
68729
+ ...item.metadata ?? {},
68730
+ [NERD_FONT_METADATA_KEY4]: "true"
68731
+ }
68732
+ };
68733
+ }
68734
+ const { [NERD_FONT_METADATA_KEY4]: removedNerdFont, ...restMetadata } = item.metadata ?? {};
68735
+ return {
68736
+ ...item,
68737
+ metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
68738
+ };
68739
+ }
68740
+ function formatStatus2(enabled, format, nerdFont) {
68741
+ const stateText = enabled ? "on" : "off";
68742
+ const stateDot = enabled ? STATE_DOT_ON2 : STATE_DOT_OFF2;
68743
+ const icon = nerdFont ? enabled ? SATELLITE_NERD_FONT : SATELLITE_SLASH_NERD_FONT : SATELLITE_EMOJI;
68744
+ switch (format) {
68745
+ case "icon":
68746
+ return nerdFont ? icon : `${icon} ${stateDot}`;
68747
+ case "icon-text":
68748
+ return `${icon} ${stateText}`;
68749
+ case "text":
68750
+ return stateText;
68751
+ case "word":
68752
+ return `remote ${stateText}`;
68753
+ case "label-check":
68754
+ return `remote ${enabled ? CHECK_EMOJI : CROSS_EMOJI}`;
68755
+ case "label-mark":
68756
+ return `remote ${enabled ? CHECK_MARK : CROSS_MARK}`;
68757
+ }
68758
+ }
68759
+
68760
+ class RemoteControlStatusWidget {
68761
+ getDefaultColor() {
68762
+ return "blue";
68763
+ }
68764
+ getDescription() {
68765
+ return "Shows whether Claude Code remote control is attached to the current session";
68766
+ }
68767
+ getDisplayName() {
68768
+ return "Remote Control Status";
68769
+ }
68770
+ getCategory() {
68771
+ return "Core";
68772
+ }
68773
+ getEditorDisplay(item) {
68774
+ const modifiers = [getFormat4(item)];
68775
+ if (isNerdFontEnabled4(item)) {
68776
+ modifiers.push("nerd font");
68777
+ }
68778
+ return {
68779
+ displayText: this.getDisplayName(),
68780
+ modifierText: `(${modifiers.join(", ")})`
68781
+ };
68782
+ }
68783
+ handleEditorAction(action, item) {
68784
+ if (action === CYCLE_FORMAT_ACTION4) {
68785
+ const currentFormat = getFormat4(item);
68786
+ const nextFormat = FORMATS4[(FORMATS4.indexOf(currentFormat) + 1) % FORMATS4.length] ?? DEFAULT_FORMAT4;
68787
+ return setFormat4(item, nextFormat);
68788
+ }
68789
+ if (action === TOGGLE_NERD_FONT_ACTION4) {
68790
+ return toggleNerdFont4(item);
68791
+ }
68792
+ return null;
68793
+ }
68794
+ render(item, context, _settings) {
68795
+ const format = getFormat4(item);
68796
+ const nerdFont = isNerdFontEnabled4(item);
68797
+ if (context.isPreview) {
68798
+ if (item.rawValue) {
68799
+ return "on";
68800
+ }
68801
+ return formatStatus2(true, format, nerdFont);
68802
+ }
68803
+ const status = getRemoteControlStatus(context.data?.session_id);
68804
+ if (status === null) {
68805
+ return null;
68806
+ }
68807
+ if (item.rawValue) {
68808
+ return status.enabled ? "on" : "off";
68809
+ }
68810
+ return formatStatus2(status.enabled, format, nerdFont);
68811
+ }
68812
+ getCustomKeybinds() {
68813
+ return [
68814
+ { key: "f", label: "(f)ormat", action: CYCLE_FORMAT_ACTION4 },
68815
+ { key: "n", label: "(n)erd font", action: TOGGLE_NERD_FONT_ACTION4 }
68816
+ ];
68817
+ }
68818
+ supportsRawValue() {
68819
+ return true;
68820
+ }
68821
+ supportsColors(_item) {
68822
+ return true;
68823
+ }
68824
+ }
68825
+ var SATELLITE_EMOJI = "\uD83D\uDCE1", SATELLITE_NERD_FONT = "", SATELLITE_SLASH_NERD_FONT = "", STATE_DOT_OFF2 = "○", STATE_DOT_ON2 = "◉", FORMATS4, CHECK_EMOJI = "✅", CROSS_EMOJI = "❌", CHECK_MARK = "✓", CROSS_MARK = "✗", DEFAULT_FORMAT4 = "icon", CYCLE_FORMAT_ACTION4 = "cycle-format", TOGGLE_NERD_FONT_ACTION4 = "toggle-nerd-font", NERD_FONT_METADATA_KEY4 = "nerdFont";
68826
+ var init_RemoteControlStatus = __esm(async () => {
68827
+ await init_claude_settings();
68828
+ FORMATS4 = ["icon", "icon-text", "text", "word", "label-check", "label-mark"];
68829
+ });
68830
+
68050
68831
  // src/widgets/index.ts
68051
68832
  var init_widgets = __esm(async () => {
68052
68833
  init_GitBranch();
@@ -68117,7 +68898,8 @@ var init_widgets = __esm(async () => {
68117
68898
  init_Link(),
68118
68899
  init_Skills(),
68119
68900
  init_ThinkingEffort(),
68120
- init_VoiceStatus()
68901
+ init_VoiceStatus(),
68902
+ init_RemoteControlStatus()
68121
68903
  ]);
68122
68904
  });
68123
68905
 
@@ -68199,6 +68981,7 @@ var init_widget_manifest = __esm(async () => {
68199
68981
  { type: "thinking-effort", create: () => new ThinkingEffortWidget },
68200
68982
  { type: "vim-mode", create: () => new VimModeWidget },
68201
68983
  { type: "voice-status", create: () => new VoiceStatusWidget },
68984
+ { type: "remote-control-status", create: () => new RemoteControlStatusWidget },
68202
68985
  { type: "worktree-mode", create: () => new GitWorktreeModeWidget },
68203
68986
  { type: "worktree-name", create: () => new GitWorktreeNameWidget },
68204
68987
  { type: "worktree-branch", create: () => new GitWorktreeBranchWidget },
@@ -68383,11 +69166,11 @@ var init_hooks = __esm(async () => {
68383
69166
  });
68384
69167
 
68385
69168
  // src/utils/config.ts
68386
- import * as fs10 from "fs";
68387
- import * as os8 from "os";
68388
- import * as path7 from "path";
69169
+ import * as fs11 from "fs";
69170
+ import * as os9 from "os";
69171
+ import * as path8 from "path";
68389
69172
  function initConfigPath(filePath) {
68390
- settingsPath = filePath ? path7.resolve(filePath) : DEFAULT_SETTINGS_PATH;
69173
+ settingsPath = filePath ? path8.resolve(filePath) : DEFAULT_SETTINGS_PATH;
68391
69174
  }
68392
69175
  function getConfigPath() {
68393
69176
  return settingsPath;
@@ -68396,13 +69179,13 @@ function isCustomConfigPath() {
68396
69179
  return settingsPath !== DEFAULT_SETTINGS_PATH;
68397
69180
  }
68398
69181
  function getSettingsPaths() {
68399
- const configDir = path7.dirname(settingsPath);
68400
- const parsedPath = path7.parse(settingsPath);
69182
+ const configDir = path8.dirname(settingsPath);
69183
+ const parsedPath = path8.parse(settingsPath);
68401
69184
  const backupBaseName = parsedPath.ext ? `${parsedPath.name}.bak` : `${parsedPath.base}.bak`;
68402
69185
  return {
68403
69186
  configDir,
68404
69187
  settingsPath,
68405
- settingsBackupPath: path7.join(configDir, backupBaseName)
69188
+ settingsBackupPath: path8.join(configDir, backupBaseName)
68406
69189
  };
68407
69190
  }
68408
69191
  async function writeSettingsJson(settings, paths) {
@@ -68411,7 +69194,7 @@ async function writeSettingsJson(settings, paths) {
68411
69194
  }
68412
69195
  async function backupBadSettings(paths) {
68413
69196
  try {
68414
- if (fs10.existsSync(paths.settingsPath)) {
69197
+ if (fs11.existsSync(paths.settingsPath)) {
68415
69198
  const content = await readFile3(paths.settingsPath, "utf-8");
68416
69199
  await writeFile(paths.settingsBackupPath, content, "utf-8");
68417
69200
  console.error(`Bad settings backed up to ${paths.settingsBackupPath}`);
@@ -68441,7 +69224,7 @@ async function recoverWithDefaults(paths) {
68441
69224
  async function loadSettings() {
68442
69225
  const paths = getSettingsPaths();
68443
69226
  try {
68444
- if (!fs10.existsSync(paths.settingsPath))
69227
+ if (!fs11.existsSync(paths.settingsPath))
68445
69228
  return await writeDefaultSettings(paths);
68446
69229
  const content = await readFile3(paths.settingsPath, "utf-8");
68447
69230
  let rawData;
@@ -68492,7 +69275,7 @@ async function saveSettings(settings) {
68492
69275
  }
68493
69276
  async function saveInstallationMetadata(metadata) {
68494
69277
  const paths = getSettingsPaths();
68495
- if (!metadata && !fs10.existsSync(paths.settingsPath)) {
69278
+ if (!metadata && !fs11.existsSync(paths.settingsPath)) {
68496
69279
  return;
68497
69280
  }
68498
69281
  const settings = await loadSettings();
@@ -68512,18 +69295,18 @@ var init_config = __esm(async () => {
68512
69295
  init_Settings();
68513
69296
  init_migrations();
68514
69297
  await init_widgets2();
68515
- readFile3 = fs10.promises.readFile;
68516
- writeFile = fs10.promises.writeFile;
68517
- mkdir = fs10.promises.mkdir;
68518
- DEFAULT_SETTINGS_PATH = path7.join(os8.homedir(), ".config", "ccstatusline", "settings.json");
69298
+ readFile3 = fs11.promises.readFile;
69299
+ writeFile = fs11.promises.writeFile;
69300
+ mkdir = fs11.promises.mkdir;
69301
+ DEFAULT_SETTINGS_PATH = path8.join(os9.homedir(), ".config", "ccstatusline", "settings.json");
68519
69302
  settingsPath = DEFAULT_SETTINGS_PATH;
68520
69303
  });
68521
69304
 
68522
69305
  // src/utils/claude-settings.ts
68523
69306
  import { execSync as execSync4 } from "child_process";
68524
- import * as fs11 from "fs";
68525
- import * as os9 from "os";
68526
- import * as path8 from "path";
69307
+ import * as fs12 from "fs";
69308
+ import * as os10 from "os";
69309
+ import * as path9 from "path";
68527
69310
  function isKnownCommand(command) {
68528
69311
  const prefixes = [CCSTATUSLINE_COMMANDS.AUTO_NPX, CCSTATUSLINE_COMMANDS.AUTO_BUNX, CCSTATUSLINE_COMMANDS.GLOBAL];
68529
69312
  return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `)) || /(?:^|[\s"'\\/])ccstatusline\.ts(?=$|[\s"'])/.test(command);
@@ -68547,9 +69330,9 @@ function getClaudeConfigDir() {
68547
69330
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
68548
69331
  if (envConfigDir) {
68549
69332
  try {
68550
- const resolvedPath = path8.resolve(envConfigDir);
68551
- if (fs11.existsSync(resolvedPath)) {
68552
- const stats = fs11.statSync(resolvedPath);
69333
+ const resolvedPath = path9.resolve(envConfigDir);
69334
+ if (fs12.existsSync(resolvedPath)) {
69335
+ const stats = fs12.statSync(resolvedPath);
68553
69336
  if (stats.isDirectory()) {
68554
69337
  return resolvedPath;
68555
69338
  }
@@ -68558,24 +69341,24 @@ function getClaudeConfigDir() {
68558
69341
  }
68559
69342
  } catch {}
68560
69343
  }
68561
- return path8.join(os9.homedir(), ".claude");
69344
+ return path9.join(os10.homedir(), ".claude");
68562
69345
  }
68563
69346
  function getClaudeJsonPath() {
68564
69347
  const configDir = getClaudeConfigDir();
68565
69348
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
68566
- if (envConfigDir && configDir === path8.resolve(envConfigDir)) {
68567
- return path8.join(configDir, ".claude.json");
69349
+ if (envConfigDir && configDir === path9.resolve(envConfigDir)) {
69350
+ return path9.join(configDir, ".claude.json");
68568
69351
  }
68569
- return path8.join(path8.dirname(configDir), ".claude.json");
69352
+ return path9.join(path9.dirname(configDir), ".claude.json");
68570
69353
  }
68571
69354
  function getClaudeSettingsPath() {
68572
- return path8.join(getClaudeConfigDir(), "settings.json");
69355
+ return path9.join(getClaudeConfigDir(), "settings.json");
68573
69356
  }
68574
69357
  async function backupClaudeSettings(suffix = ".bak") {
68575
69358
  const settingsPath2 = getClaudeSettingsPath();
68576
69359
  const backupPath = settingsPath2 + suffix;
68577
69360
  try {
68578
- if (fs11.existsSync(settingsPath2)) {
69361
+ if (fs12.existsSync(settingsPath2)) {
68579
69362
  const content = await readFile4(settingsPath2, "utf-8");
68580
69363
  await writeFile2(backupPath, content, "utf-8");
68581
69364
  return backupPath;
@@ -68588,11 +69371,11 @@ async function backupClaudeSettings(suffix = ".bak") {
68588
69371
  function loadClaudeSettingsSync(options = {}) {
68589
69372
  const { logErrors = true } = options;
68590
69373
  const settingsPath2 = getClaudeSettingsPath();
68591
- if (!fs11.existsSync(settingsPath2)) {
69374
+ if (!fs12.existsSync(settingsPath2)) {
68592
69375
  return {};
68593
69376
  }
68594
69377
  try {
68595
- const content = fs11.readFileSync(settingsPath2, "utf-8");
69378
+ const content = fs12.readFileSync(settingsPath2, "utf-8");
68596
69379
  return JSON.parse(content);
68597
69380
  } catch (error51) {
68598
69381
  if (logErrors) {
@@ -68604,7 +69387,7 @@ function loadClaudeSettingsSync(options = {}) {
68604
69387
  async function loadClaudeSettings(options = {}) {
68605
69388
  const { logErrors = true } = options;
68606
69389
  const settingsPath2 = getClaudeSettingsPath();
68607
- if (!fs11.existsSync(settingsPath2)) {
69390
+ if (!fs12.existsSync(settingsPath2)) {
68608
69391
  return {};
68609
69392
  }
68610
69393
  try {
@@ -68619,7 +69402,7 @@ async function loadClaudeSettings(options = {}) {
68619
69402
  }
68620
69403
  async function saveClaudeSettings(settings) {
68621
69404
  const settingsPath2 = getClaudeSettingsPath();
68622
- const dir = path8.dirname(settingsPath2);
69405
+ const dir = path9.dirname(settingsPath2);
68623
69406
  await backupClaudeSettings();
68624
69407
  await mkdir2(dir, { recursive: true });
68625
69408
  await writeFile2(settingsPath2, JSON.stringify(settings, null, 2), "utf-8");
@@ -68637,7 +69420,7 @@ async function isInstalled() {
68637
69420
  function isExecutableAvailable(executable) {
68638
69421
  try {
68639
69422
  const command = process.platform === "win32" ? `where ${executable}` : `which ${executable}`;
68640
- execSync4(command, { stdio: "ignore" });
69423
+ execSync4(command, { stdio: "ignore", windowsHide: true });
68641
69424
  return true;
68642
69425
  } catch {
68643
69426
  return false;
@@ -68665,7 +69448,12 @@ function getPackageCommandAvailability() {
68665
69448
  }
68666
69449
  function getClaudeCodeVersion() {
68667
69450
  try {
68668
- const output = execSync4("claude --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"], timeout: 5000 }).trim();
69451
+ const output = execSync4("claude --version", {
69452
+ encoding: "utf-8",
69453
+ stdio: ["pipe", "pipe", "ignore"],
69454
+ timeout: 5000,
69455
+ windowsHide: true
69456
+ }).trim();
68669
69457
  const match = /^(\d+\.\d+\.\d+)/.exec(output);
68670
69458
  return match?.[1] ?? null;
68671
69459
  } catch {
@@ -68752,7 +69540,7 @@ function classifyInstallation(command, metadata) {
68752
69540
  }
68753
69541
  async function loadSavedSettingsForHookSync() {
68754
69542
  const configPath = getConfigPath();
68755
- if (!fs11.existsSync(configPath)) {
69543
+ if (!fs12.existsSync(configPath)) {
68756
69544
  return null;
68757
69545
  }
68758
69546
  try {
@@ -68853,19 +69641,19 @@ async function setRefreshInterval(interval) {
68853
69641
  }
68854
69642
  function getVoiceConfigCandidatePathsByPriority(cwd2) {
68855
69643
  const userDir = getClaudeConfigDir();
68856
- const projectDir = path8.join(cwd2, ".claude");
69644
+ const projectDir = path9.join(cwd2, ".claude");
68857
69645
  const candidates = [
68858
- path8.join(projectDir, "settings.local.json"),
68859
- path8.join(projectDir, "settings.json"),
68860
- path8.join(userDir, "settings.local.json"),
68861
- path8.join(userDir, "settings.json")
69646
+ path9.join(projectDir, "settings.local.json"),
69647
+ path9.join(projectDir, "settings.json"),
69648
+ path9.join(userDir, "settings.local.json"),
69649
+ path9.join(userDir, "settings.json")
68862
69650
  ];
68863
69651
  return Array.from(new Set(candidates));
68864
69652
  }
68865
69653
  function tryReadVoiceLayer(filePath) {
68866
69654
  let content;
68867
69655
  try {
68868
- content = fs11.readFileSync(filePath, "utf-8");
69656
+ content = fs12.readFileSync(filePath, "utf-8");
68869
69657
  } catch (error51) {
68870
69658
  const isMissing = error51.code === "ENOENT";
68871
69659
  return { fileExisted: !isMissing, enabled: undefined };
@@ -68895,14 +69683,50 @@ function getVoiceConfig(cwd2 = process.cwd()) {
68895
69683
  }
68896
69684
  return anyFileExisted ? { enabled: false } : null;
68897
69685
  }
68898
- var readFile4, writeFile2, mkdir2, CCSTATUSLINE_COMMANDS, PINNED_INSTALL_COMMANDS, VoiceConfigSchema;
69686
+ function getRemoteControlStatus(sessionId) {
69687
+ if (!sessionId) {
69688
+ return null;
69689
+ }
69690
+ const sessionsDir = path9.join(getClaudeConfigDir(), "sessions");
69691
+ let entries;
69692
+ try {
69693
+ entries = fs12.readdirSync(sessionsDir);
69694
+ } catch {
69695
+ return null;
69696
+ }
69697
+ for (const entry of entries) {
69698
+ if (!entry.endsWith(".json")) {
69699
+ continue;
69700
+ }
69701
+ let content;
69702
+ try {
69703
+ content = fs12.readFileSync(path9.join(sessionsDir, entry), "utf-8");
69704
+ } catch {
69705
+ continue;
69706
+ }
69707
+ let parsed;
69708
+ try {
69709
+ parsed = JSON.parse(content);
69710
+ } catch {
69711
+ continue;
69712
+ }
69713
+ const result2 = RemoteSessionFileSchema.safeParse(parsed);
69714
+ if (!result2.success || result2.data.sessionId !== sessionId) {
69715
+ continue;
69716
+ }
69717
+ const bridge = result2.data.bridgeSessionId;
69718
+ return { enabled: typeof bridge === "string" && bridge.length > 0 };
69719
+ }
69720
+ return null;
69721
+ }
69722
+ var readFile4, writeFile2, mkdir2, CCSTATUSLINE_COMMANDS, PINNED_INSTALL_COMMANDS, VoiceConfigSchema, RemoteSessionFileSchema;
68899
69723
  var init_claude_settings = __esm(async () => {
68900
69724
  init_zod();
68901
69725
  init_Settings();
68902
69726
  await init_config();
68903
- readFile4 = fs11.promises.readFile;
68904
- writeFile2 = fs11.promises.writeFile;
68905
- mkdir2 = fs11.promises.mkdir;
69727
+ readFile4 = fs12.promises.readFile;
69728
+ writeFile2 = fs12.promises.writeFile;
69729
+ mkdir2 = fs12.promises.mkdir;
68906
69730
  CCSTATUSLINE_COMMANDS = {
68907
69731
  AUTO_NPX: "npx -y ccstatusline@latest",
68908
69732
  AUTO_BUNX: "bunx -y ccstatusline@latest",
@@ -68916,6 +69740,10 @@ var init_claude_settings = __esm(async () => {
68916
69740
  BUN: (version2) => `bun add -g ccstatusline@${version2}`
68917
69741
  };
68918
69742
  VoiceConfigSchema = exports_external.object({ enabled: exports_external.boolean().optional() });
69743
+ RemoteSessionFileSchema = exports_external.object({
69744
+ sessionId: exports_external.string().optional(),
69745
+ bridgeSessionId: exports_external.string().nullable().optional()
69746
+ });
68919
69747
  });
68920
69748
 
68921
69749
  // node_modules/pluralize/pluralize.js
@@ -69504,9 +70332,12 @@ await init_config();
69504
70332
 
69505
70333
  // src/utils/global-command-resolution.ts
69506
70334
  import { execFileSync as execFileSync5 } from "child_process";
69507
- import * as path9 from "path";
70335
+ import * as path10 from "path";
69508
70336
 
69509
70337
  // src/utils/package-manager-executable.ts
70338
+ function getPackageManagerShellOptions(executable, platform2 = process.platform) {
70339
+ return platform2 === "win32" && /\.(?:cmd|bat)$/i.test(executable) ? { shell: true } : {};
70340
+ }
69510
70341
  function getPackageManagerExecutable(packageManager, platform2 = process.platform) {
69511
70342
  return packageManager === "npm" && platform2 === "win32" ? "npm.cmd" : packageManager;
69512
70343
  }
@@ -69531,11 +70362,19 @@ function isTransientBunxStatusLinePath(filePath) {
69531
70362
  return /(?:^|\/)bunx-[^/]*ccstatusline@[^/]+\/node_modules\/\.bin\/ccstatusline(?:\.(?:cmd|ps1))?$/i.test(normalized);
69532
70363
  }
69533
70364
  function getPersistentCommandResolutionPaths(paths) {
69534
- return paths.filter((path10) => !isTransientBunxStatusLinePath(path10));
70365
+ return paths.filter((path11) => !isTransientBunxStatusLinePath(path11));
69535
70366
  }
69536
70367
  function getCommandResolutionPaths(command, { platform: platform2 = process.platform } = {}) {
69537
70368
  try {
69538
- const output = platform2 === "win32" ? execFileSync5("where", [command], { encoding: "utf-8", timeout: COMMAND_LOOKUP_TIMEOUT_MS }) : execFileSync5("which", ["-a", command], { encoding: "utf-8", timeout: COMMAND_LOOKUP_TIMEOUT_MS });
70369
+ const output = platform2 === "win32" ? execFileSync5("where", [command], {
70370
+ encoding: "utf-8",
70371
+ timeout: COMMAND_LOOKUP_TIMEOUT_MS,
70372
+ windowsHide: true
70373
+ }) : execFileSync5("which", ["-a", command], {
70374
+ encoding: "utf-8",
70375
+ timeout: COMMAND_LOOKUP_TIMEOUT_MS,
70376
+ windowsHide: true
70377
+ });
69539
70378
  return splitCommandOutput(output);
69540
70379
  } catch {
69541
70380
  return [];
@@ -69543,14 +70382,17 @@ function getCommandResolutionPaths(command, { platform: platform2 = process.plat
69543
70382
  }
69544
70383
  function getNpmGlobalBinDir(platform2) {
69545
70384
  try {
69546
- const prefix = execFileSync5(getPackageManagerExecutable("npm", platform2), ["prefix", "-g"], {
70385
+ const executable = getPackageManagerExecutable("npm", platform2);
70386
+ const prefix = execFileSync5(executable, ["prefix", "-g"], {
69547
70387
  encoding: "utf-8",
69548
- timeout: COMMAND_LOOKUP_TIMEOUT_MS
70388
+ timeout: COMMAND_LOOKUP_TIMEOUT_MS,
70389
+ windowsHide: true,
70390
+ ...getPackageManagerShellOptions(executable, platform2)
69549
70391
  }).trim();
69550
70392
  if (!prefix) {
69551
70393
  return null;
69552
70394
  }
69553
- return platform2 === "win32" || /^[a-z]:[\\/]/i.test(prefix) ? prefix : path9.join(prefix, "bin");
70395
+ return platform2 === "win32" || /^[a-z]:[\\/]/i.test(prefix) ? prefix : path10.join(prefix, "bin");
69554
70396
  } catch {
69555
70397
  return null;
69556
70398
  }
@@ -69559,7 +70401,8 @@ function getBunGlobalBinDir() {
69559
70401
  try {
69560
70402
  const binDir = execFileSync5("bun", ["pm", "bin", "-g"], {
69561
70403
  encoding: "utf-8",
69562
- timeout: COMMAND_LOOKUP_TIMEOUT_MS
70404
+ timeout: COMMAND_LOOKUP_TIMEOUT_MS,
70405
+ windowsHide: true
69563
70406
  }).trim();
69564
70407
  return binDir || null;
69565
70408
  } catch {
@@ -69653,7 +70496,7 @@ import {
69653
70496
  execFile,
69654
70497
  execFileSync as execFileSync6
69655
70498
  } from "child_process";
69656
- import * as fs12 from "fs";
70499
+ import * as fs13 from "fs";
69657
70500
  var GLOBAL_PACKAGE_TIMEOUT_MS = 120000;
69658
70501
  var VERSION_LOOKUP_TIMEOUT_MS = 5000;
69659
70502
  var WINDOWS_SHIM_EXTENSIONS = [
@@ -69702,7 +70545,7 @@ function getBinaryPathCandidates(binDir, platform2) {
69702
70545
  return extensions.map((extension) => appendPathSegment(binDir, `ccstatusline${extension}`));
69703
70546
  }
69704
70547
  function hasBinaryOnDisk(binDir, platform2) {
69705
- return getBinaryPathCandidates(binDir, platform2).some((candidate) => getFilesystemPathVariants(candidate).some((variant) => fs12.existsSync(variant)));
70548
+ return getBinaryPathCandidates(binDir, platform2).some((candidate) => getFilesystemPathVariants(candidate).some((variant) => fs13.existsSync(variant)));
69706
70549
  }
69707
70550
  function hasResolvedBinaryInDir(resolvedPaths, binDir) {
69708
70551
  return resolvedPaths.some((resolvedPath) => isPathInsideDir(resolvedPath, binDir));
@@ -69735,10 +70578,10 @@ function formatPathList2(paths) {
69735
70578
  function readPackageVersion(packageJsonPath) {
69736
70579
  for (const variant of getFilesystemPathVariants(packageJsonPath)) {
69737
70580
  try {
69738
- if (!fs12.existsSync(variant)) {
70581
+ if (!fs13.existsSync(variant)) {
69739
70582
  continue;
69740
70583
  }
69741
- const packageJson = JSON.parse(fs12.readFileSync(variant, "utf-8"));
70584
+ const packageJson = JSON.parse(fs13.readFileSync(variant, "utf-8"));
69742
70585
  return typeof packageJson.version === "string" ? packageJson.version : null;
69743
70586
  } catch {
69744
70587
  return null;
@@ -69748,9 +70591,12 @@ function readPackageVersion(packageJsonPath) {
69748
70591
  }
69749
70592
  function getNpmGlobalPackageVersion(platform2) {
69750
70593
  try {
69751
- const rootDir = execFileSync6(getPackageManagerExecutable("npm", platform2), ["root", "-g"], {
70594
+ const executable = getPackageManagerExecutable("npm", platform2);
70595
+ const rootDir = execFileSync6(executable, ["root", "-g"], {
69752
70596
  encoding: "utf-8",
69753
- timeout: VERSION_LOOKUP_TIMEOUT_MS
70597
+ timeout: VERSION_LOOKUP_TIMEOUT_MS,
70598
+ windowsHide: true,
70599
+ ...getPackageManagerShellOptions(executable, platform2)
69754
70600
  }).trim();
69755
70601
  return rootDir ? readPackageVersion(appendPathSegment(appendPathSegment(rootDir, "ccstatusline"), "package.json")) : null;
69756
70602
  } catch {
@@ -69856,20 +70702,24 @@ function inspectGlobalPackageInstallations({
69856
70702
  function runGlobalPackageUninstall(packageManager, { platform: platform2 = process.platform } = {}) {
69857
70703
  const executable = getPackageManagerExecutable(packageManager, platform2);
69858
70704
  const args = packageManager === "npm" ? ["uninstall", "-g", "ccstatusline"] : ["remove", "-g", "ccstatusline"];
69859
- return new Promise((resolve5, reject2) => {
69860
- execFile(executable, args, { timeout: GLOBAL_PACKAGE_TIMEOUT_MS }, (error51) => {
70705
+ return new Promise((resolve6, reject2) => {
70706
+ execFile(executable, args, {
70707
+ timeout: GLOBAL_PACKAGE_TIMEOUT_MS,
70708
+ windowsHide: true,
70709
+ ...getPackageManagerShellOptions(executable, platform2)
70710
+ }, (error51) => {
69861
70711
  if (error51) {
69862
70712
  reject2(error51 instanceof Error ? error51 : new Error("Global uninstall command failed"));
69863
70713
  return;
69864
70714
  }
69865
- resolve5();
70715
+ resolve6();
69866
70716
  });
69867
70717
  });
69868
70718
  }
69869
70719
 
69870
70720
  // src/utils/open-url.ts
69871
70721
  import { spawnSync } from "child_process";
69872
- import * as os10 from "os";
70722
+ import * as os11 from "os";
69873
70723
  function runOpenCommand(command, args) {
69874
70724
  const result2 = spawnSync(command, args, {
69875
70725
  stdio: "ignore",
@@ -69928,7 +70778,7 @@ function openExternalUrl(url2) {
69928
70778
  error: "Only http(s) URLs are supported"
69929
70779
  };
69930
70780
  }
69931
- const platform3 = os10.platform();
70781
+ const platform3 = os11.platform();
69932
70782
  const plans = PLATFORM_OPEN_PLANS[platform3];
69933
70783
  if (!plans) {
69934
70784
  return {
@@ -69956,9 +70806,9 @@ function openExternalUrl(url2) {
69956
70806
 
69957
70807
  // src/utils/powerline.ts
69958
70808
  import { execSync as execSync5 } from "child_process";
69959
- import * as fs13 from "fs";
69960
- import * as os11 from "os";
69961
- import * as path10 from "path";
70809
+ import * as fs14 from "fs";
70810
+ import * as os12 from "os";
70811
+ import * as path11 from "path";
69962
70812
  var fontsInstalledThisSession = false;
69963
70813
  function checkPowerlineFonts() {
69964
70814
  if (process.env.DEBUG_FONT_INSTALL === "1" && !fontsInstalledThisSession) {
@@ -69974,24 +70824,24 @@ function checkPowerlineFonts() {
69974
70824
  leftArrow: "",
69975
70825
  leftThinArrow: ""
69976
70826
  };
69977
- const platform4 = os11.platform();
70827
+ const platform4 = os12.platform();
69978
70828
  let fontPaths = [];
69979
70829
  if (platform4 === "darwin") {
69980
70830
  fontPaths = [
69981
- path10.join(os11.homedir(), "Library", "Fonts"),
70831
+ path11.join(os12.homedir(), "Library", "Fonts"),
69982
70832
  "/Library/Fonts",
69983
70833
  "/System/Library/Fonts"
69984
70834
  ];
69985
70835
  } else if (platform4 === "linux") {
69986
70836
  fontPaths = [
69987
- path10.join(os11.homedir(), ".local", "share", "fonts"),
69988
- path10.join(os11.homedir(), ".fonts"),
70837
+ path11.join(os12.homedir(), ".local", "share", "fonts"),
70838
+ path11.join(os12.homedir(), ".fonts"),
69989
70839
  "/usr/share/fonts",
69990
70840
  "/usr/local/share/fonts"
69991
70841
  ];
69992
70842
  } else if (platform4 === "win32") {
69993
70843
  fontPaths = [
69994
- path10.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
70844
+ path11.join(os12.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
69995
70845
  "C:\\Windows\\Fonts"
69996
70846
  ];
69997
70847
  }
@@ -70007,9 +70857,9 @@ function checkPowerlineFonts() {
70007
70857
  /fira.*code.*nerd/i
70008
70858
  ];
70009
70859
  for (const fontPath of fontPaths) {
70010
- if (fs13.existsSync(fontPath)) {
70860
+ if (fs14.existsSync(fontPath)) {
70011
70861
  try {
70012
- const files = fs13.readdirSync(fontPath);
70862
+ const files = fs14.readdirSync(fontPath);
70013
70863
  for (const file2 of files) {
70014
70864
  for (const pattern of powerlineFontPatterns) {
70015
70865
  if (pattern.test(file2)) {
@@ -70044,13 +70894,16 @@ async function checkPowerlineFontsAsync() {
70044
70894
  if (quickCheck.installed) {
70045
70895
  return quickCheck;
70046
70896
  }
70047
- const platform4 = os11.platform();
70897
+ const platform4 = os12.platform();
70048
70898
  if (platform4 === "linux" || platform4 === "darwin") {
70049
70899
  try {
70050
70900
  const { exec: exec2 } = await import("child_process");
70051
70901
  const { promisify: promisify2 } = await import("util");
70052
70902
  const execAsync = promisify2(exec2);
70053
- const { stdout } = await execAsync("fc-list 2>/dev/null | grep -i powerline", { encoding: "utf8" });
70903
+ const { stdout } = await execAsync("fc-list 2>/dev/null | grep -i powerline", {
70904
+ encoding: "utf8",
70905
+ windowsHide: true
70906
+ });
70054
70907
  if (stdout.trim()) {
70055
70908
  return {
70056
70909
  installed: true,
@@ -70067,46 +70920,49 @@ async function checkPowerlineFontsAsync() {
70067
70920
  async function installPowerlineFonts() {
70068
70921
  await Promise.resolve();
70069
70922
  try {
70070
- const platform4 = os11.platform();
70923
+ const platform4 = os12.platform();
70071
70924
  let fontDir;
70072
70925
  if (platform4 === "darwin") {
70073
- fontDir = path10.join(os11.homedir(), "Library", "Fonts");
70926
+ fontDir = path11.join(os12.homedir(), "Library", "Fonts");
70074
70927
  } else if (platform4 === "linux") {
70075
- fontDir = path10.join(os11.homedir(), ".local", "share", "fonts");
70928
+ fontDir = path11.join(os12.homedir(), ".local", "share", "fonts");
70076
70929
  } else if (platform4 === "win32") {
70077
- fontDir = path10.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
70930
+ fontDir = path11.join(os12.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
70078
70931
  } else {
70079
70932
  return {
70080
70933
  success: false,
70081
70934
  message: "Unsupported platform for font installation"
70082
70935
  };
70083
70936
  }
70084
- if (!fs13.existsSync(fontDir)) {
70085
- fs13.mkdirSync(fontDir, { recursive: true });
70937
+ if (!fs14.existsSync(fontDir)) {
70938
+ fs14.mkdirSync(fontDir, { recursive: true });
70086
70939
  }
70087
- const tempDir = path10.join(os11.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
70940
+ const tempDir = path11.join(os12.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
70088
70941
  try {
70089
- if (fs13.existsSync(tempDir)) {
70090
- fs13.rmSync(tempDir, { recursive: true, force: true });
70942
+ if (fs14.existsSync(tempDir)) {
70943
+ fs14.rmSync(tempDir, { recursive: true, force: true });
70091
70944
  }
70092
70945
  execSync5(`git clone --depth=1 https://github.com/powerline/fonts.git "${tempDir}"`, {
70093
70946
  stdio: "pipe",
70094
- encoding: "utf8"
70947
+ encoding: "utf8",
70948
+ windowsHide: true
70095
70949
  });
70096
70950
  if (platform4 === "darwin" || platform4 === "linux") {
70097
- const installScript = path10.join(tempDir, "install.sh");
70098
- if (fs13.existsSync(installScript)) {
70099
- fs13.chmodSync(installScript, 493);
70951
+ const installScript = path11.join(tempDir, "install.sh");
70952
+ if (fs14.existsSync(installScript)) {
70953
+ fs14.chmodSync(installScript, 493);
70100
70954
  execSync5(`cd "${tempDir}" && ./install.sh`, {
70101
70955
  stdio: "pipe",
70102
70956
  encoding: "utf8",
70103
- shell: "/bin/bash"
70957
+ shell: "/bin/bash",
70958
+ windowsHide: true
70104
70959
  });
70105
70960
  if (platform4 === "linux") {
70106
70961
  try {
70107
70962
  execSync5("fc-cache -f -v", {
70108
70963
  stdio: "pipe",
70109
- encoding: "utf8"
70964
+ encoding: "utf8",
70965
+ windowsHide: true
70110
70966
  });
70111
70967
  } catch {}
70112
70968
  }
@@ -70122,10 +70978,10 @@ async function installPowerlineFonts() {
70122
70978
  }
70123
70979
  } else {
70124
70980
  let findFontFiles = function(dir) {
70125
- const files = fs13.readdirSync(dir);
70981
+ const files = fs14.readdirSync(dir);
70126
70982
  for (const file2 of files) {
70127
- const filePath = path10.join(dir, file2);
70128
- const stat2 = fs13.statSync(filePath);
70983
+ const filePath = path11.join(dir, file2);
70984
+ const stat2 = fs14.statSync(filePath);
70129
70985
  if (stat2.isDirectory() && !file2.startsWith(".")) {
70130
70986
  findFontFiles(filePath);
70131
70987
  } else if (file2.endsWith(".ttf") || file2.endsWith(".otf")) {
@@ -70139,10 +70995,10 @@ async function installPowerlineFonts() {
70139
70995
  findFontFiles(tempDir);
70140
70996
  let installedCount = 0;
70141
70997
  for (const fontFile of fontFiles) {
70142
- const fileName = path10.basename(fontFile);
70143
- const destPath = path10.join(fontDir, fileName);
70998
+ const fileName = path11.basename(fontFile);
70999
+ const destPath = path11.join(fontDir, fileName);
70144
71000
  try {
70145
- fs13.copyFileSync(fontFile, destPath);
71001
+ fs14.copyFileSync(fontFile, destPath);
70146
71002
  installedCount++;
70147
71003
  } catch {}
70148
71004
  }
@@ -70160,9 +71016,9 @@ async function installPowerlineFonts() {
70160
71016
  message: "Platform-specific installation not implemented"
70161
71017
  };
70162
71018
  } finally {
70163
- if (fs13.existsSync(tempDir)) {
71019
+ if (fs14.existsSync(tempDir)) {
70164
71020
  try {
70165
- fs13.rmSync(tempDir, { recursive: true, force: true });
71021
+ fs14.rmSync(tempDir, { recursive: true, force: true });
70166
71022
  } catch {}
70167
71023
  }
70168
71024
  }
@@ -70328,7 +71184,7 @@ async function checkForUpdates({
70328
71184
  }
70329
71185
  }
70330
71186
  function fetchLatestNpmVersion(timeoutMs = DEFAULT_REGISTRY_TIMEOUT_MS) {
70331
- return new Promise((resolve5, reject2) => {
71187
+ return new Promise((resolve6, reject2) => {
70332
71188
  const request3 = https2.request(NPM_REGISTRY_LATEST_URL, {
70333
71189
  headers: {
70334
71190
  Accept: "application/json",
@@ -70352,7 +71208,7 @@ function fetchLatestNpmVersion(timeoutMs = DEFAULT_REGISTRY_TIMEOUT_MS) {
70352
71208
  reject2(new Error("npm registry response did not include a version"));
70353
71209
  return;
70354
71210
  }
70355
- resolve5(parsed.version);
71211
+ resolve6(parsed.version);
70356
71212
  } catch (error51) {
70357
71213
  reject2(error51 instanceof Error ? error51 : new Error(String(error51)));
70358
71214
  }
@@ -70368,13 +71224,17 @@ function fetchLatestNpmVersion(timeoutMs = DEFAULT_REGISTRY_TIMEOUT_MS) {
70368
71224
  function runGlobalPackageInstall(packageManager, version2, { platform: platform4 = process.platform } = {}) {
70369
71225
  const executable = getPackageManagerExecutable(packageManager, platform4);
70370
71226
  const args = packageManager === "npm" ? ["install", "-g", `ccstatusline@${version2}`] : ["add", "-g", `ccstatusline@${version2}`];
70371
- return new Promise((resolve5, reject2) => {
70372
- execFile2(executable, args, { timeout: GLOBAL_UPDATE_TIMEOUT_MS }, (error51) => {
71227
+ return new Promise((resolve6, reject2) => {
71228
+ execFile2(executable, args, {
71229
+ timeout: GLOBAL_UPDATE_TIMEOUT_MS,
71230
+ windowsHide: true,
71231
+ ...getPackageManagerShellOptions(executable, platform4)
71232
+ }, (error51) => {
70373
71233
  if (error51) {
70374
71234
  reject2(error51 instanceof Error ? error51 : new Error("Global update command failed"));
70375
71235
  return;
70376
71236
  }
70377
- resolve5();
71237
+ resolve6();
70378
71238
  });
70379
71239
  });
70380
71240
  }
@@ -70808,6 +71668,7 @@ var SelectInput_default = SelectInput;
70808
71668
  // src/tui/components/ColorMenu.tsx
70809
71669
  init_ColorLevel();
70810
71670
  init_colors();
71671
+ init_gradient();
70811
71672
  init_input_guards();
70812
71673
  await init_widgets2();
70813
71674
  var import_react39 = __toESM(require_react(), 1);
@@ -71112,6 +71973,11 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71112
71973
  const [ansi256InputMode, setAnsi256InputMode] = import_react39.useState(false);
71113
71974
  const [ansi256Input, setAnsi256Input] = import_react39.useState("");
71114
71975
  const [showClearConfirm, setShowClearConfirm] = import_react39.useState(false);
71976
+ const [gradientMode, setGradientMode] = import_react39.useState(false);
71977
+ const [gradientIndex, setGradientIndex] = import_react39.useState(0);
71978
+ const [gradientCustomStep, setGradientCustomStep] = import_react39.useState(null);
71979
+ const [gradientStartHex, setGradientStartHex] = import_react39.useState("");
71980
+ const [gradientHexInput, setGradientHexInput] = import_react39.useState("");
71115
71981
  const powerlineEnabled = settings.powerline.enabled;
71116
71982
  const colorableWidgets = widgets.filter((widget) => {
71117
71983
  if (widget.type === "separator") {
@@ -71191,6 +72057,62 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71191
72057
  }
71192
72058
  return;
71193
72059
  }
72060
+ if (gradientMode) {
72061
+ const exitGradient = () => {
72062
+ setGradientMode(false);
72063
+ setGradientCustomStep(null);
72064
+ setGradientStartHex("");
72065
+ setGradientHexInput("");
72066
+ };
72067
+ const applyGradientValue = (value) => {
72068
+ const selectedWidget2 = colorableWidgets.find((widget) => widget.id === highlightedItemId);
72069
+ if (selectedWidget2) {
72070
+ onUpdate(setWidgetColor(widgets, selectedWidget2.id, value, false));
72071
+ }
72072
+ exitGradient();
72073
+ };
72074
+ if (gradientCustomStep) {
72075
+ if (key.escape) {
72076
+ setGradientCustomStep(null);
72077
+ setGradientHexInput("");
72078
+ } else if (key.return) {
72079
+ if (gradientHexInput.length === 6) {
72080
+ if (gradientCustomStep === "start") {
72081
+ setGradientStartHex(gradientHexInput);
72082
+ setGradientHexInput("");
72083
+ setGradientCustomStep("end");
72084
+ } else {
72085
+ applyGradientValue(`gradient:${gradientStartHex}-${gradientHexInput}`);
72086
+ }
72087
+ }
72088
+ } else if (key.backspace || key.delete) {
72089
+ setGradientHexInput(gradientHexInput.slice(0, -1));
72090
+ } else if (shouldInsertInput(input, key) && gradientHexInput.length < 6) {
72091
+ const upperInput = input.toUpperCase();
72092
+ if (/^[0-9A-F]$/.test(upperInput)) {
72093
+ setGradientHexInput(gradientHexInput + upperInput);
72094
+ }
72095
+ }
72096
+ return;
72097
+ }
72098
+ const total = GRADIENT_PRESET_NAMES.length + 1;
72099
+ if (key.escape) {
72100
+ exitGradient();
72101
+ } else if (key.upArrow) {
72102
+ setGradientIndex((gradientIndex - 1 + total) % total);
72103
+ } else if (key.downArrow) {
72104
+ setGradientIndex((gradientIndex + 1) % total);
72105
+ } else if (key.return) {
72106
+ if (gradientIndex < GRADIENT_PRESET_NAMES.length) {
72107
+ applyGradientValue(`gradient:${GRADIENT_PRESET_NAMES[gradientIndex]}`);
72108
+ } else {
72109
+ setGradientStartHex("");
72110
+ setGradientHexInput("");
72111
+ setGradientCustomStep("start");
72112
+ }
72113
+ }
72114
+ return;
72115
+ }
71194
72116
  if (input && /^[0-9]$/.test(input)) {
71195
72117
  return;
71196
72118
  }
@@ -71210,6 +72132,14 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71210
72132
  setAnsi256InputMode(true);
71211
72133
  setAnsi256Input("");
71212
72134
  }
72135
+ } else if (input === "g" || input === "G") {
72136
+ if (highlightedItemId && highlightedItemId !== "back" && !editingBackground && settings.colorLevel >= 2) {
72137
+ setGradientMode(true);
72138
+ setGradientIndex(0);
72139
+ setGradientCustomStep(null);
72140
+ setGradientStartHex("");
72141
+ setGradientHexInput("");
72142
+ }
71213
72143
  } else if ((input === "s" || input === "S") && !key.ctrl) {
71214
72144
  if (!settings.powerline.enabled && !settings.defaultSeparator) {
71215
72145
  setShowSeparators(!showSeparators);
@@ -71361,6 +72291,13 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71361
72291
  displayName = `ANSI ${currentColor.substring(8)}`;
71362
72292
  } else if (currentColor.startsWith("hex:")) {
71363
72293
  displayName = `#${currentColor.substring(4)}`;
72294
+ } else if (currentColor.startsWith("gradient:")) {
72295
+ const body = currentColor.substring(9);
72296
+ if (GRADIENT_PRESET_NAMES.includes(body.toLowerCase())) {
72297
+ displayName = `Gradient: ${body.toLowerCase()}`;
72298
+ } else {
72299
+ displayName = `Gradient: ${body}`;
72300
+ }
71364
72301
  } else {
71365
72302
  const colorOption = colorOptions.find((c) => c.value === currentColor);
71366
72303
  displayName = colorOption ? colorOption.name : currentColor;
@@ -71369,6 +72306,94 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71369
72306
  colorDisplay = applyColors(displayName, currentColor, undefined, false, level);
71370
72307
  }
71371
72308
  }
72309
+ if (gradientMode) {
72310
+ const level = getColorLevelString(settings.colorLevel);
72311
+ const widgetName = selectedWidget ? getItemLabel(selectedWidget) : "";
72312
+ if (gradientCustomStep) {
72313
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
72314
+ flexDirection: "column",
72315
+ children: [
72316
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72317
+ bold: true,
72318
+ children: [
72319
+ "Custom Gradient",
72320
+ widgetName ? ` - ${widgetName}` : ""
72321
+ ]
72322
+ }, undefined, true, undefined, this),
72323
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
72324
+ marginTop: 1,
72325
+ flexDirection: "column",
72326
+ children: [
72327
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72328
+ children: gradientCustomStep === "start" ? "Enter START hex color (without #):" : "Enter END hex color (without #):"
72329
+ }, undefined, false, undefined, this),
72330
+ gradientCustomStep === "end" && /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72331
+ dimColor: true,
72332
+ children: [
72333
+ "Start: #",
72334
+ gradientStartHex
72335
+ ]
72336
+ }, undefined, true, undefined, this),
72337
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72338
+ children: [
72339
+ "#",
72340
+ gradientHexInput,
72341
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72342
+ dimColor: true,
72343
+ children: gradientHexInput.length < 6 ? "_".repeat(6 - gradientHexInput.length) : ""
72344
+ }, undefined, false, undefined, this)
72345
+ ]
72346
+ }, undefined, true, undefined, this),
72347
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72348
+ children: " "
72349
+ }, undefined, false, undefined, this),
72350
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72351
+ dimColor: true,
72352
+ children: "Press Enter when done, ESC to go back"
72353
+ }, undefined, false, undefined, this)
72354
+ ]
72355
+ }, undefined, true, undefined, this)
72356
+ ]
72357
+ }, undefined, true, undefined, this);
72358
+ }
72359
+ return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
72360
+ flexDirection: "column",
72361
+ children: [
72362
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72363
+ bold: true,
72364
+ children: [
72365
+ "Select Gradient",
72366
+ widgetName ? ` - ${widgetName}` : ""
72367
+ ]
72368
+ }, undefined, true, undefined, this),
72369
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
72370
+ marginTop: 1,
72371
+ children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72372
+ dimColor: true,
72373
+ children: "↑↓ to select, Enter to apply, ESC to cancel"
72374
+ }, undefined, false, undefined, this)
72375
+ }, undefined, false, undefined, this),
72376
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
72377
+ marginTop: 1,
72378
+ flexDirection: "column",
72379
+ children: [
72380
+ GRADIENT_PRESET_NAMES.map((name, idx) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72381
+ children: [
72382
+ idx === gradientIndex ? "▶ " : " ",
72383
+ applyColors(name, `gradient:${name}`, undefined, idx === gradientIndex, level)
72384
+ ]
72385
+ }, name, true, undefined, this)),
72386
+ /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
72387
+ children: [
72388
+ gradientIndex === GRADIENT_PRESET_NAMES.length ? "▶ " : " ",
72389
+ "Custom (enter two hex stops)"
72390
+ ]
72391
+ }, "custom", true, undefined, this)
72392
+ ]
72393
+ }, undefined, true, undefined, this)
72394
+ ]
72395
+ }, undefined, true, undefined, this);
72396
+ }
71372
72397
  if (showClearConfirm) {
71373
72398
  return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
71374
72399
  flexDirection: "column",
@@ -71497,6 +72522,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71497
72522
  editingBackground ? "background" : "foreground",
71498
72523
  ", (f) to toggle bg/fg, (b)old,",
71499
72524
  settings.colorLevel === 3 ? " (h)ex," : settings.colorLevel === 2 ? " (a)nsi256," : "",
72525
+ !editingBackground && settings.colorLevel >= 2 ? " (g)radient," : "",
71500
72526
  " ",
71501
72527
  "(r)eset, (c)lear all, ESC to go back"
71502
72528
  ]
@@ -71576,7 +72602,9 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
71576
72602
  }, undefined, true, undefined, this);
71577
72603
  };
71578
72604
  // src/tui/components/GlobalOverridesMenu.tsx
72605
+ init_ColorLevel();
71579
72606
  init_colors();
72607
+ init_gradient();
71580
72608
  init_input_guards();
71581
72609
  await init_build2();
71582
72610
  var import_react40 = __toESM(require_react(), 1);
@@ -71590,6 +72618,11 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
71590
72618
  const [inheritColors, setInheritColors] = import_react40.useState(settings.inheritSeparatorColors);
71591
72619
  const [globalBold, setGlobalBold] = import_react40.useState(settings.globalBold);
71592
72620
  const [minimalistMode, setMinimalistMode] = import_react40.useState(settings.minimalistMode);
72621
+ const [gradientMode, setGradientMode] = import_react40.useState(false);
72622
+ const [gradientIndex, setGradientIndex] = import_react40.useState(0);
72623
+ const [gradientCustomStep, setGradientCustomStep] = import_react40.useState(null);
72624
+ const [gradientStartHex, setGradientStartHex] = import_react40.useState("");
72625
+ const [gradientHexInput, setGradientHexInput] = import_react40.useState("");
71593
72626
  const isPowerlineEnabled = settings.powerline.enabled;
71594
72627
  const hasManualSeparators = settings.lines.some((line) => line.some((item) => item.type === "separator"));
71595
72628
  const bgColors = ["none", ...COLOR_MAP.filter((c) => c.isBackground).map((c) => c.name)];
@@ -71637,6 +72670,60 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
71637
72670
  }
71638
72671
  } else if (confirmingSeparator) {
71639
72672
  return;
72673
+ } else if (gradientMode) {
72674
+ const exitGradient = () => {
72675
+ setGradientMode(false);
72676
+ setGradientCustomStep(null);
72677
+ setGradientStartHex("");
72678
+ setGradientHexInput("");
72679
+ };
72680
+ const applyGradientValue = (value) => {
72681
+ onUpdate({
72682
+ ...settings,
72683
+ overrideForegroundColor: value
72684
+ });
72685
+ exitGradient();
72686
+ };
72687
+ if (gradientCustomStep) {
72688
+ if (key.escape) {
72689
+ setGradientCustomStep(null);
72690
+ setGradientHexInput("");
72691
+ } else if (key.return) {
72692
+ if (gradientHexInput.length === 6) {
72693
+ if (gradientCustomStep === "start") {
72694
+ setGradientStartHex(gradientHexInput);
72695
+ setGradientHexInput("");
72696
+ setGradientCustomStep("end");
72697
+ } else {
72698
+ applyGradientValue(`gradient:${gradientStartHex}-${gradientHexInput}`);
72699
+ }
72700
+ }
72701
+ } else if (key.backspace || key.delete) {
72702
+ setGradientHexInput(gradientHexInput.slice(0, -1));
72703
+ } else if (shouldInsertInput(input, key) && gradientHexInput.length < 6) {
72704
+ const upperInput = input.toUpperCase();
72705
+ if (/^[0-9A-F]$/.test(upperInput)) {
72706
+ setGradientHexInput(gradientHexInput + upperInput);
72707
+ }
72708
+ }
72709
+ return;
72710
+ }
72711
+ const total = GRADIENT_PRESET_NAMES.length + 1;
72712
+ if (key.escape) {
72713
+ exitGradient();
72714
+ } else if (key.upArrow) {
72715
+ setGradientIndex((gradientIndex - 1 + total) % total);
72716
+ } else if (key.downArrow) {
72717
+ setGradientIndex((gradientIndex + 1) % total);
72718
+ } else if (key.return) {
72719
+ if (gradientIndex < GRADIENT_PRESET_NAMES.length) {
72720
+ applyGradientValue(`gradient:${GRADIENT_PRESET_NAMES[gradientIndex]}`);
72721
+ } else {
72722
+ setGradientStartHex("");
72723
+ setGradientHexInput("");
72724
+ setGradientCustomStep("start");
72725
+ }
72726
+ }
71640
72727
  } else {
71641
72728
  if (key.escape) {
71642
72729
  onBack();
@@ -71691,6 +72778,12 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
71691
72778
  };
71692
72779
  onUpdate(updatedSettings);
71693
72780
  } else if (input === "g" || input === "G") {
72781
+ setGradientMode(true);
72782
+ setGradientIndex(0);
72783
+ setGradientCustomStep(null);
72784
+ setGradientStartHex("");
72785
+ setGradientHexInput("");
72786
+ } else if (input === "x" || input === "X") {
71694
72787
  const updatedSettings = {
71695
72788
  ...settings,
71696
72789
  overrideForegroundColor: undefined
@@ -71699,6 +72792,87 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
71699
72792
  }
71700
72793
  }
71701
72794
  });
72795
+ if (gradientMode) {
72796
+ const level = getColorLevelString(settings.colorLevel);
72797
+ if (gradientCustomStep) {
72798
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
72799
+ flexDirection: "column",
72800
+ children: [
72801
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72802
+ bold: true,
72803
+ children: "Custom Gradient - Override FG Color"
72804
+ }, undefined, false, undefined, this),
72805
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
72806
+ marginTop: 1,
72807
+ flexDirection: "column",
72808
+ children: [
72809
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72810
+ children: gradientCustomStep === "start" ? "Enter START hex color (without #):" : "Enter END hex color (without #):"
72811
+ }, undefined, false, undefined, this),
72812
+ gradientCustomStep === "end" && /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72813
+ dimColor: true,
72814
+ children: [
72815
+ "Start: #",
72816
+ gradientStartHex
72817
+ ]
72818
+ }, undefined, true, undefined, this),
72819
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72820
+ children: [
72821
+ "#",
72822
+ gradientHexInput,
72823
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72824
+ dimColor: true,
72825
+ children: gradientHexInput.length < 6 ? "_".repeat(6 - gradientHexInput.length) : ""
72826
+ }, undefined, false, undefined, this)
72827
+ ]
72828
+ }, undefined, true, undefined, this),
72829
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72830
+ children: " "
72831
+ }, undefined, false, undefined, this),
72832
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72833
+ dimColor: true,
72834
+ children: "Press Enter when done, ESC to go back"
72835
+ }, undefined, false, undefined, this)
72836
+ ]
72837
+ }, undefined, true, undefined, this)
72838
+ ]
72839
+ }, undefined, true, undefined, this);
72840
+ }
72841
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
72842
+ flexDirection: "column",
72843
+ children: [
72844
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72845
+ bold: true,
72846
+ children: "Select Gradient - Override FG Color"
72847
+ }, undefined, false, undefined, this),
72848
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
72849
+ marginTop: 1,
72850
+ children: /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72851
+ dimColor: true,
72852
+ children: "↑↓ to select, Enter to apply, ESC to cancel"
72853
+ }, undefined, false, undefined, this)
72854
+ }, undefined, false, undefined, this),
72855
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
72856
+ marginTop: 1,
72857
+ flexDirection: "column",
72858
+ children: [
72859
+ GRADIENT_PRESET_NAMES.map((name, idx) => /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72860
+ children: [
72861
+ idx === gradientIndex ? "▶ " : " ",
72862
+ applyColors(name, `gradient:${name}`, undefined, idx === gradientIndex, level)
72863
+ ]
72864
+ }, name, true, undefined, this)),
72865
+ /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
72866
+ children: [
72867
+ gradientIndex === GRADIENT_PRESET_NAMES.length ? "▶ " : " ",
72868
+ "Custom (enter two hex stops)"
72869
+ ]
72870
+ }, "custom", true, undefined, this)
72871
+ ]
72872
+ }, undefined, true, undefined, this)
72873
+ ]
72874
+ }, undefined, true, undefined, this);
72875
+ }
71702
72876
  return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Box_default, {
71703
72877
  flexDirection: "column",
71704
72878
  children: [
@@ -71864,6 +73038,13 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
71864
73038
  color: "gray",
71865
73039
  children: "(none)"
71866
73040
  }, undefined, false, undefined, this);
73041
+ } else if (fgColor.startsWith("gradient:")) {
73042
+ const body = fgColor.substring(9);
73043
+ const displayName = GRADIENT_PRESET_NAMES.includes(body.toLowerCase()) ? `Gradient: ${body.toLowerCase()}` : `Gradient: ${body}`;
73044
+ const level = getColorLevelString(settings.colorLevel);
73045
+ return /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
73046
+ children: applyColors(displayName, fgColor, undefined, false, level)
73047
+ }, undefined, false, undefined, this);
71867
73048
  } else {
71868
73049
  const displayName = getColorDisplayName(fgColor);
71869
73050
  const fgChalk = getChalkColor(fgColor, "ansi16", false);
@@ -71875,7 +73056,7 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
71875
73056
  })(),
71876
73057
  /* @__PURE__ */ jsx_dev_runtime13.jsxDEV(Text, {
71877
73058
  dimColor: true,
71878
- children: " - (f) cycle, (g) clear"
73059
+ children: " - (f) cycle, (g) gradient, (x) clear"
71879
73060
  }, undefined, false, undefined, this)
71880
73061
  ]
71881
73062
  }, undefined, true, undefined, this),
@@ -72009,19 +73190,19 @@ var import_react41 = __toESM(require_react(), 1);
72009
73190
  var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
72010
73191
  var AUTO_UPDATE_DESCRIPTION = "Runs `@latest` through npx/bunx. Stays current automatically, with a small startup cost when the package runner checks or resolves the package. Because it follows the latest published package, pinned install is available if you prefer explicit updates.";
72011
73192
  function getPinnedDescription(currentVersion) {
72012
- return `Installs \`ccstatusline@${currentVersion}\` globally and Claude Code runs \`ccstatusline\`. Fast per-render and only changes when you update.`;
73193
+ return `Installs \`ccstatusline@${currentVersion}\` globally and Claude Code runs \`ccstatusline\`. Fast on each render because Claude Code runs the installed ccstatusline binary directly. The version changes only when you update the global install.`;
72013
73194
  }
72014
73195
  function getStyleItems(currentVersion) {
72015
73196
  return [
72016
- {
72017
- label: "Auto-update",
72018
- value: "auto-update",
72019
- description: AUTO_UPDATE_DESCRIPTION
72020
- },
72021
73197
  {
72022
73198
  label: "Pinned global install",
72023
73199
  value: "pinned",
72024
73200
  description: getPinnedDescription(currentVersion)
73201
+ },
73202
+ {
73203
+ label: "Auto-update",
73204
+ value: "auto-update",
73205
+ description: AUTO_UPDATE_DESCRIPTION
72025
73206
  }
72026
73207
  ];
72027
73208
  }
@@ -72091,7 +73272,7 @@ var InstallMenu = ({
72091
73272
  initialPackageSelection = 0
72092
73273
  }) => {
72093
73274
  const [step, setStep] = import_react41.useState("style");
72094
- const [updateStyle, setUpdateStyle] = import_react41.useState("auto-update");
73275
+ const [updateStyle, setUpdateStyle] = import_react41.useState("pinned");
72095
73276
  use_input_default((_, key) => {
72096
73277
  if (key.escape) {
72097
73278
  if (step === "manager") {
@@ -73715,7 +74896,7 @@ var UninstallMenu = ({
73715
74896
  // src/tui/components/PowerlineSetup.tsx
73716
74897
  await init_build2();
73717
74898
  var import_react46 = __toESM(require_react(), 1);
73718
- import * as os12 from "os";
74899
+ import * as os13 from "os";
73719
74900
 
73720
74901
  // src/utils/powerline-settings.ts
73721
74902
  init_colors();
@@ -74353,6 +75534,8 @@ var PowerlineSetup = ({
74353
75534
  const [confirmingEnable, setConfirmingEnable] = import_react46.useState(false);
74354
75535
  const [confirmingFontInstall, setConfirmingFontInstall] = import_react46.useState(false);
74355
75536
  const hasSeparatorItems = settings.lines.some((line) => line.some((item) => item.type === "separator" || item.type === "flex-separator"));
75537
+ const hasGlobalFgOverride = Boolean(settings.overrideForegroundColor && settings.overrideForegroundColor !== "none");
75538
+ const globalOverrideMessage = hasGlobalFgOverride ? "⚠ Global override for FG active" : null;
74356
75539
  use_input_default((input, key) => {
74357
75540
  if (fontInstallMessage || installingFonts) {
74358
75541
  if (fontInstallMessage && !key.escape) {
@@ -74445,10 +75628,22 @@ var PowerlineSetup = ({
74445
75628
  return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
74446
75629
  flexDirection: "column",
74447
75630
  children: [
74448
- !confirmingFontInstall && !installingFonts && !fontInstallMessage && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74449
- bold: true,
74450
- children: "Powerline Setup"
74451
- }, undefined, false, undefined, this),
75631
+ !confirmingFontInstall && !installingFonts && !fontInstallMessage && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
75632
+ children: [
75633
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
75634
+ bold: true,
75635
+ children: "Powerline Setup"
75636
+ }, undefined, false, undefined, this),
75637
+ globalOverrideMessage && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
75638
+ color: "yellow",
75639
+ dimColor: true,
75640
+ children: [
75641
+ ". ",
75642
+ globalOverrideMessage
75643
+ ]
75644
+ }, undefined, true, undefined, this)
75645
+ ]
75646
+ }, undefined, true, undefined, this),
74452
75647
  confirmingFontInstall ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
74453
75648
  flexDirection: "column",
74454
75649
  children: [
@@ -74480,7 +75675,7 @@ var PowerlineSetup = ({
74480
75675
  }, undefined, false, undefined, this)
74481
75676
  ]
74482
75677
  }, undefined, true, undefined, this),
74483
- os12.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
75678
+ os13.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
74484
75679
  children: [
74485
75680
  /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74486
75681
  dimColor: true,
@@ -74496,7 +75691,7 @@ var PowerlineSetup = ({
74496
75691
  }, undefined, false, undefined, this)
74497
75692
  ]
74498
75693
  }, undefined, true, undefined, this),
74499
- os12.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
75694
+ os13.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
74500
75695
  children: [
74501
75696
  /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74502
75697
  dimColor: true,
@@ -74512,7 +75707,7 @@ var PowerlineSetup = ({
74512
75707
  }, undefined, false, undefined, this)
74513
75708
  ]
74514
75709
  }, undefined, true, undefined, this),
74515
- os12.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
75710
+ os13.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
74516
75711
  children: [
74517
75712
  /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74518
75713
  dimColor: true,
@@ -74734,7 +75929,7 @@ var PowerlineSetup = ({
74734
75929
  children: [
74735
75930
  /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74736
75931
  dimColor: true,
74737
- children: "When enabled, global overrides are disabled and powerline separators are used"
75932
+ children: "Powerline mode uses its own separator system"
74738
75933
  }, undefined, false, undefined, this),
74739
75934
  /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74740
75935
  dimColor: true,
@@ -74789,7 +75984,10 @@ function getRefreshIntervalSublabel(interval, supported) {
74789
75984
  }
74790
75985
  return `(${interval}s)`;
74791
75986
  }
74792
- function buildConfigureStatusLineItems(refreshInterval, supportsRefreshInterval) {
75987
+ function getGitCacheTtlSublabel(ttlSeconds) {
75988
+ return ttlSeconds === 0 ? "(mtime only)" : `(${ttlSeconds}s)`;
75989
+ }
75990
+ function buildConfigureStatusLineItems(refreshInterval, supportsRefreshInterval, gitCacheTtlSeconds) {
74793
75991
  return [
74794
75992
  {
74795
75993
  label: "\uD83D\uDD04 Refresh Interval",
@@ -74797,6 +75995,13 @@ function buildConfigureStatusLineItems(refreshInterval, supportsRefreshInterval)
74797
75995
  value: "refreshInterval",
74798
75996
  disabled: !supportsRefreshInterval,
74799
75997
  description: supportsRefreshInterval ? "How often Claude Code refreshes the status line by re-running the command. Enter value in seconds (1-60), or leave empty to remove." : "This setting requires Claude Code version 2.1.97 or later. Please update Claude Code to use this feature."
75998
+ },
75999
+ {
76000
+ label: "\uD83E\uDDEE Git Cache TTL",
76001
+ sublabel: getGitCacheTtlSublabel(gitCacheTtlSeconds),
76002
+ value: "gitCacheTtl",
76003
+ description: `How long git widget subprocess output can be reused while .git/HEAD and .git/index are unchanged. Enter 0-60 seconds;
76004
+ 0 disables age-based expiry, so cached output is reused until those git metadata mtimes change.`
74800
76005
  }
74801
76006
  ];
74802
76007
  }
@@ -74816,14 +76021,31 @@ function validateRefreshIntervalInput(value) {
74816
76021
  }
74817
76022
  return null;
74818
76023
  }
76024
+ function validateGitCacheTtlInput(value) {
76025
+ const parsed = parseInt(value, 10);
76026
+ if (value === "" || isNaN(parsed)) {
76027
+ return "Please enter a valid number";
76028
+ }
76029
+ if (parsed < 0) {
76030
+ return `Minimum Git cache TTL is 0s (you entered ${parsed}s)`;
76031
+ }
76032
+ if (parsed > 60) {
76033
+ return `Maximum Git cache TTL is 60s (you entered ${parsed}s)`;
76034
+ }
76035
+ return null;
76036
+ }
74819
76037
  var RefreshIntervalMenu = ({
74820
76038
  currentInterval,
74821
76039
  supportsRefreshInterval,
76040
+ gitCacheTtlSeconds,
74822
76041
  onUpdate,
76042
+ onGitCacheTtlUpdate,
74823
76043
  onBack
74824
76044
  }) => {
74825
76045
  const [editingRefreshInterval, setEditingRefreshInterval] = import_react47.useState(false);
76046
+ const [editingGitCacheTtl, setEditingGitCacheTtl] = import_react47.useState(false);
74826
76047
  const [refreshInput, setRefreshInput] = import_react47.useState(() => getRefreshInputValue(currentInterval));
76048
+ const [gitCacheTtlInput, setGitCacheTtlInput] = import_react47.useState(() => String(gitCacheTtlSeconds));
74827
76049
  const [validationError, setValidationError] = import_react47.useState(null);
74828
76050
  use_input_default((input, key) => {
74829
76051
  if (editingRefreshInterval) {
@@ -74859,6 +76081,33 @@ var RefreshIntervalMenu = ({
74859
76081
  }
74860
76082
  return;
74861
76083
  }
76084
+ if (editingGitCacheTtl) {
76085
+ if (key.return) {
76086
+ const error51 = validateGitCacheTtlInput(gitCacheTtlInput);
76087
+ if (error51) {
76088
+ setValidationError(error51);
76089
+ } else {
76090
+ const value = parseInt(gitCacheTtlInput, 10);
76091
+ onGitCacheTtlUpdate(value);
76092
+ setEditingGitCacheTtl(false);
76093
+ setValidationError(null);
76094
+ }
76095
+ } else if (key.escape) {
76096
+ setGitCacheTtlInput(String(gitCacheTtlSeconds));
76097
+ setEditingGitCacheTtl(false);
76098
+ setValidationError(null);
76099
+ } else if (key.backspace) {
76100
+ setGitCacheTtlInput(gitCacheTtlInput.slice(0, -1));
76101
+ setValidationError(null);
76102
+ } else if (key.delete) {} else if (shouldInsertInput(input, key) && /\d/.test(input)) {
76103
+ const newValue = gitCacheTtlInput + input;
76104
+ if (newValue.length <= 2) {
76105
+ setGitCacheTtlInput(newValue);
76106
+ setValidationError(null);
76107
+ }
76108
+ }
76109
+ return;
76110
+ }
74862
76111
  if (key.escape) {
74863
76112
  onBack();
74864
76113
  }
@@ -74894,16 +76143,53 @@ var RefreshIntervalMenu = ({
74894
76143
  children: "Press Enter to confirm, ESC to cancel. Leave empty to remove."
74895
76144
  }, undefined, false, undefined, this)
74896
76145
  ]
76146
+ }, undefined, true, undefined, this) : editingGitCacheTtl ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
76147
+ marginTop: 1,
76148
+ flexDirection: "column",
76149
+ children: [
76150
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76151
+ children: [
76152
+ "Enter Git cache TTL in seconds (0-60):",
76153
+ " ",
76154
+ gitCacheTtlInput,
76155
+ gitCacheTtlInput.length > 0 ? "s" : ""
76156
+ ]
76157
+ }, undefined, true, undefined, this),
76158
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76159
+ children: " "
76160
+ }, undefined, false, undefined, this),
76161
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76162
+ dimColor: true,
76163
+ wrap: "wrap",
76164
+ children: "This affects how quickly git widgets notice unstaged and untracked working-tree changes."
76165
+ }, undefined, false, undefined, this),
76166
+ validationError ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76167
+ color: "red",
76168
+ children: validationError
76169
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76170
+ dimColor: true,
76171
+ children: "0 disables age-based expiry; cache validity uses .git/HEAD and .git/index mtimes only."
76172
+ }, undefined, false, undefined, this),
76173
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
76174
+ dimColor: true,
76175
+ children: "Press Enter to confirm, ESC to cancel."
76176
+ }, undefined, false, undefined, this)
76177
+ ]
74897
76178
  }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(List, {
74898
76179
  marginTop: 1,
74899
- items: buildConfigureStatusLineItems(currentInterval, supportsRefreshInterval),
76180
+ items: buildConfigureStatusLineItems(currentInterval, supportsRefreshInterval, gitCacheTtlSeconds),
74900
76181
  onSelect: (value) => {
74901
76182
  if (value === "back") {
74902
76183
  onBack();
74903
76184
  return;
74904
76185
  }
74905
- setRefreshInput(getRefreshInputValue(currentInterval));
74906
- setEditingRefreshInterval(true);
76186
+ if (value === "refreshInterval") {
76187
+ setRefreshInput(getRefreshInputValue(currentInterval));
76188
+ setEditingRefreshInterval(true);
76189
+ return;
76190
+ }
76191
+ setGitCacheTtlInput(String(gitCacheTtlSeconds));
76192
+ setEditingGitCacheTtl(true);
74907
76193
  },
74908
76194
  showBackButton: true
74909
76195
  }, undefined, false, undefined, this)
@@ -74954,6 +76240,7 @@ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSepar
74954
76240
  terminalWidth,
74955
76241
  isPreview: true,
74956
76242
  minimalist: settings.minimalistMode,
76243
+ gitCacheTtlSeconds: settings.gitCacheTtlSeconds,
74957
76244
  lineIndex,
74958
76245
  globalSeparatorIndex,
74959
76246
  globalPowerlineThemeIndex
@@ -74970,7 +76257,12 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
74970
76257
  const { renderedLines, anyTruncated } = import_react48.default.useMemo(() => {
74971
76258
  if (!settings)
74972
76259
  return { renderedLines: [], anyTruncated: false };
74973
- const preRenderedLines = preRenderAllWidgets(lines, settings, { terminalWidth, isPreview: true, minimalist: settings.minimalistMode });
76260
+ const preRenderedLines = preRenderAllWidgets(lines, settings, {
76261
+ terminalWidth,
76262
+ isPreview: true,
76263
+ minimalist: settings.minimalistMode,
76264
+ gitCacheTtlSeconds: settings.gitCacheTtlSeconds
76265
+ });
74974
76266
  const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);
74975
76267
  let globalSeparatorIndex = 0;
74976
76268
  let globalPowerlineThemeIndex = 0;
@@ -76504,6 +77796,7 @@ ${GITHUB_REPO_URL}`,
76504
77796
  screen === "refreshInterval" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(RefreshIntervalMenu, {
76505
77797
  currentInterval: currentRefreshInterval,
76506
77798
  supportsRefreshInterval,
77799
+ gitCacheTtlSeconds: settings.gitCacheTtlSeconds,
76507
77800
  onUpdate: (interval) => {
76508
77801
  const previous = currentRefreshInterval;
76509
77802
  setCurrentRefreshInterval(interval);
@@ -76521,6 +77814,17 @@ ${GITHUB_REPO_URL}`,
76521
77814
  });
76522
77815
  setScreen("main");
76523
77816
  },
77817
+ onGitCacheTtlUpdate: (ttlSeconds) => {
77818
+ setSettings({
77819
+ ...settings,
77820
+ gitCacheTtlSeconds: ttlSeconds
77821
+ });
77822
+ setFlashMessage({
77823
+ text: "✓ Git cache TTL updated",
77824
+ color: "green"
77825
+ });
77826
+ setScreen("main");
77827
+ },
76524
77828
  onBack: () => {
76525
77829
  setScreen("main");
76526
77830
  }
@@ -76643,10 +77947,11 @@ init_colors();
76643
77947
  // src/utils/compaction.ts
76644
77948
  init_zod();
76645
77949
  import * as crypto from "crypto";
76646
- import * as fs14 from "fs";
76647
- import * as os13 from "os";
76648
- import * as path11 from "path";
77950
+ import * as fs15 from "fs";
77951
+ import * as os14 from "os";
77952
+ import * as path12 from "path";
76649
77953
  var DEFAULT_DROP_THRESHOLD = 2;
77954
+ var MIN_CTX_PCT = 1;
76650
77955
  var FRESH_PREV_CTX_PCT = -1;
76651
77956
  var MAX_CACHE_FILE_BYTES = 4096;
76652
77957
  var SESSION_ID_HASH_HEX_LEN = 32;
@@ -76670,7 +77975,7 @@ function normalizeOptions(options) {
76670
77975
  return { dropThreshold, windowSize: options.windowSize ?? null };
76671
77976
  }
76672
77977
  function detectCompaction(currentCtxPct, state, options = DEFAULT_DROP_THRESHOLD) {
76673
- if (!Number.isFinite(currentCtxPct) || currentCtxPct < 0) {
77978
+ if (!Number.isFinite(currentCtxPct) || currentCtxPct < MIN_CTX_PCT) {
76674
77979
  return state;
76675
77980
  }
76676
77981
  const { dropThreshold, windowSize } = normalizeOptions(options);
@@ -76689,8 +77994,8 @@ function detectCompaction(currentCtxPct, state, options = DEFAULT_DROP_THRESHOLD
76689
77994
  ...currentWindowSize !== null ? { prevWindowSize: currentWindowSize } : {}
76690
77995
  };
76691
77996
  }
76692
- function getCacheDir2() {
76693
- return path11.join(os13.homedir(), ".cache", "ccstatusline", "compaction");
77997
+ function getCacheDir3() {
77998
+ return path12.join(os14.homedir(), ".cache", "ccstatusline", "compaction");
76694
77999
  }
76695
78000
  function sanitizeSessionId(sessionId) {
76696
78001
  const sanitized = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -76700,18 +78005,18 @@ function sanitizeSessionId(sessionId) {
76700
78005
  return sanitized;
76701
78006
  }
76702
78007
  function getStatePath(sessionId) {
76703
- return path11.join(getCacheDir2(), `compaction-${sanitizeSessionId(sessionId)}.json`);
78008
+ return path12.join(getCacheDir3(), `compaction-${sanitizeSessionId(sessionId)}.json`);
76704
78009
  }
76705
78010
  function loadCompactionState(sessionId) {
76706
78011
  const statePath = getStatePath(sessionId);
76707
78012
  let fd = null;
76708
78013
  try {
76709
- fd = fs14.openSync(statePath, fs14.constants.O_RDONLY | fs14.constants.O_NOFOLLOW);
76710
- const stats = fs14.fstatSync(fd);
78014
+ fd = fs15.openSync(statePath, fs15.constants.O_RDONLY | fs15.constants.O_NOFOLLOW);
78015
+ const stats = fs15.fstatSync(fd);
76711
78016
  if (!stats.isFile() || stats.size > MAX_CACHE_FILE_BYTES) {
76712
78017
  return FRESH;
76713
78018
  }
76714
- const raw = JSON.parse(fs14.readFileSync(fd, "utf-8"));
78019
+ const raw = JSON.parse(fs15.readFileSync(fd, "utf-8"));
76715
78020
  const result2 = CompactionStateSchema.safeParse(raw);
76716
78021
  return result2.success ? result2.data : FRESH;
76717
78022
  } catch {
@@ -76719,7 +78024,7 @@ function loadCompactionState(sessionId) {
76719
78024
  } finally {
76720
78025
  if (fd !== null) {
76721
78026
  try {
76722
- fs14.closeSync(fd);
78027
+ fs15.closeSync(fd);
76723
78028
  } catch {}
76724
78029
  }
76725
78030
  }
@@ -76727,20 +78032,20 @@ function loadCompactionState(sessionId) {
76727
78032
  function saveCompactionState(sessionId, state) {
76728
78033
  let tmpPath = null;
76729
78034
  try {
76730
- const dir = getCacheDir2();
76731
- if (!fs14.existsSync(dir)) {
76732
- fs14.mkdirSync(dir, { recursive: true });
78035
+ const dir = getCacheDir3();
78036
+ if (!fs15.existsSync(dir)) {
78037
+ fs15.mkdirSync(dir, { recursive: true });
76733
78038
  }
76734
78039
  const targetPath = getStatePath(sessionId);
76735
78040
  tmpPath = `${targetPath}.tmp.${process.pid}.${crypto.randomBytes(4).toString("hex")}`;
76736
- fs14.writeFileSync(tmpPath, JSON.stringify(state) + `
78041
+ fs15.writeFileSync(tmpPath, JSON.stringify(state) + `
76737
78042
  `);
76738
- fs14.renameSync(tmpPath, targetPath);
78043
+ fs15.renameSync(tmpPath, targetPath);
76739
78044
  tmpPath = null;
76740
78045
  } catch {
76741
78046
  if (tmpPath !== null) {
76742
78047
  try {
76743
- fs14.unlinkSync(tmpPath);
78048
+ fs15.unlinkSync(tmpPath);
76744
78049
  } catch {}
76745
78050
  }
76746
78051
  }
@@ -76751,27 +78056,27 @@ init_context_percentage();
76751
78056
  await init_config();
76752
78057
 
76753
78058
  // src/utils/hook-handler.ts
76754
- import * as fs16 from "fs";
76755
- import * as path13 from "path";
78059
+ import * as fs17 from "fs";
78060
+ import * as path14 from "path";
76756
78061
 
76757
78062
  // src/utils/skills.ts
76758
- import * as fs15 from "fs";
76759
- import * as os14 from "os";
76760
- import * as path12 from "path";
78063
+ import * as fs16 from "fs";
78064
+ import * as os15 from "os";
78065
+ import * as path13 from "path";
76761
78066
  var EMPTY = { totalInvocations: 0, uniqueSkills: [], lastSkill: null };
76762
78067
  function getSkillsDir() {
76763
- return path12.join(os14.homedir(), ".cache", "ccstatusline", "skills");
78068
+ return path13.join(os15.homedir(), ".cache", "ccstatusline", "skills");
76764
78069
  }
76765
78070
  function getSkillsFilePath(sessionId) {
76766
- return path12.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
78071
+ return path13.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
76767
78072
  }
76768
78073
  function getSkillsMetrics(sessionId) {
76769
78074
  const filePath = getSkillsFilePath(sessionId);
76770
- if (!fs15.existsSync(filePath)) {
78075
+ if (!fs16.existsSync(filePath)) {
76771
78076
  return EMPTY;
76772
78077
  }
76773
78078
  try {
76774
- const invocations = fs15.readFileSync(filePath, "utf-8").trim().split(`
78079
+ const invocations = fs16.readFileSync(filePath, "utf-8").trim().split(`
76775
78080
  `).filter((line) => line.trim()).map((line) => {
76776
78081
  try {
76777
78082
  return JSON.parse(line);
@@ -76825,14 +78130,14 @@ function handleHookInput(input) {
76825
78130
  return;
76826
78131
  }
76827
78132
  const filePath = getSkillsFilePath(sessionId);
76828
- fs16.mkdirSync(path13.dirname(filePath), { recursive: true });
78133
+ fs17.mkdirSync(path14.dirname(filePath), { recursive: true });
76829
78134
  const entry = JSON.stringify({
76830
78135
  timestamp: new Date().toISOString(),
76831
78136
  session_id: sessionId,
76832
78137
  skill: skillName,
76833
78138
  source: data.hook_event_name
76834
78139
  });
76835
- fs16.appendFileSync(filePath, entry + `
78140
+ fs17.appendFileSync(filePath, entry + `
76836
78141
  `);
76837
78142
  } catch {}
76838
78143
  }
@@ -77032,7 +78337,7 @@ async function ensureWindowsUtf8CodePage() {
77032
78337
  }
77033
78338
  try {
77034
78339
  const { execFileSync: execFileSync7 } = await import("child_process");
77035
- execFileSync7("chcp.com", ["65001"], { stdio: "ignore" });
78340
+ execFileSync7("chcp.com", ["65001"], { stdio: "ignore", windowsHide: true });
77036
78341
  } catch {}
77037
78342
  }
77038
78343
  async function renderMultipleLines(data) {
@@ -77098,7 +78403,8 @@ async function renderMultipleLines(data) {
77098
78403
  skillsMetrics,
77099
78404
  compactionData: hasCompactionWidget ? { count: compactionCount } : null,
77100
78405
  isPreview: false,
77101
- minimalist: settings.minimalistMode
78406
+ minimalist: settings.minimalistMode,
78407
+ gitCacheTtlSeconds: settings.gitCacheTtlSeconds
77102
78408
  };
77103
78409
  const preRenderedLines = preRenderAllWidgets(lines, settings, context);
77104
78410
  const preCalculatedMaxWidths = calculateMaxWidthsFromPreRendered(preRenderedLines, settings);