ccstatusline 2.2.8 → 2.2.9

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.4";
1358
+ exports.version = "19.2.5";
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
  });
@@ -52581,7 +52581,8 @@ class ModelWidget {
52581
52581
  const model = context.data?.model;
52582
52582
  const modelDisplayName = typeof model === "string" ? model : model?.display_name ?? model?.id;
52583
52583
  if (modelDisplayName) {
52584
- return item.rawValue ? modelDisplayName : `Model: ${modelDisplayName}`;
52584
+ const shortName = modelDisplayName.replace(/\s*\(.*\)$/, "");
52585
+ return item.rawValue ? shortName : `Model: ${shortName}`;
52585
52586
  }
52586
52587
  return null;
52587
52588
  }
@@ -52627,7 +52628,7 @@ class OutputStyleWidget {
52627
52628
  }
52628
52629
 
52629
52630
  // src/utils/git.ts
52630
- import { execSync } from "child_process";
52631
+ import { execFileSync } from "child_process";
52631
52632
  function resolveGitCwd(context) {
52632
52633
  const candidates = [
52633
52634
  context.data?.cwd,
@@ -52642,13 +52643,18 @@ function resolveGitCwd(context) {
52642
52643
  return;
52643
52644
  }
52644
52645
  function runGit(command, context) {
52646
+ const args = command.trim().split(/\s+/).filter(Boolean);
52647
+ return runGitArgs(args, context, command);
52648
+ }
52649
+ function runGitArgs(args, context, cacheCommand) {
52645
52650
  const cwd2 = resolveGitCwd(context);
52646
- const cacheKey = `${command}|${cwd2 ?? ""}`;
52651
+ const cacheToken = cacheCommand ?? args.join("\x00");
52652
+ const cacheKey = `${cacheToken}|${cwd2 ?? ""}`;
52647
52653
  if (gitCommandCache.has(cacheKey)) {
52648
52654
  return gitCommandCache.get(cacheKey) ?? null;
52649
52655
  }
52650
52656
  try {
52651
- const output = execSync(`git ${command}`, {
52657
+ const output = execFileSync("git", args, {
52652
52658
  encoding: "utf8",
52653
52659
  stdio: ["pipe", "pipe", "ignore"],
52654
52660
  ...cwd2 ? { cwd: cwd2 } : {}
@@ -52745,47 +52751,116 @@ var init_git = __esm(() => {
52745
52751
  gitCommandCache = new Map;
52746
52752
  });
52747
52753
 
52748
- // src/utils/hyperlink.ts
52749
- function renderOsc8Link(url2, text) {
52750
- return `\x1B]8;;${url2}\x1B\\${text}\x1B]8;;\x1B\\`;
52751
- }
52752
- function parseGitHubRepositoryPath(pathname) {
52753
- const trimmedPath = pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
52754
- const segments = trimmedPath.split("/").filter(Boolean);
52755
- if (segments.length !== 2) {
52756
- return null;
52757
- }
52758
- return `${segments[0]}/${segments[1]}`;
52759
- }
52760
- function parseGitHubBaseUrl(remoteUrl) {
52761
- const trimmed = remoteUrl.trim();
52754
+ // src/utils/git-remote.ts
52755
+ function parseRemoteUrl(url2) {
52756
+ const trimmed = url2.trim();
52762
52757
  if (trimmed.length === 0) {
52763
52758
  return null;
52764
52759
  }
52765
- const sshMatch = /^(?:[^@]+@)?github\.com:([^/]+\/[^/]+?)(?:\.git)?\/?$/.exec(trimmed);
52766
- if (sshMatch?.[1]) {
52767
- return `https://github.com/${sshMatch[1]}`;
52760
+ const sshMatch = !trimmed.includes("://") ? /^(?:[^@]+@)?([^:]+):(.+?)(?:\.git)?\/?$/.exec(trimmed) : null;
52761
+ if (sshMatch?.[1] && sshMatch[2]) {
52762
+ const pathSegments = sshMatch[2].split("/").filter(Boolean);
52763
+ const repo = pathSegments.at(-1);
52764
+ const owner = pathSegments.slice(0, -1).join("/");
52765
+ if (!owner || !repo) {
52766
+ return null;
52767
+ }
52768
+ return {
52769
+ host: sshMatch[1],
52770
+ owner,
52771
+ repo
52772
+ };
52768
52773
  }
52769
52774
  try {
52770
52775
  const parsedUrl = new URL(trimmed);
52771
- const supportedProtocols = new Set([
52772
- "http:",
52773
- "https:",
52774
- "ssh:",
52775
- "git:"
52776
- ]);
52777
- if (parsedUrl.hostname.toLowerCase() !== "github.com" || !supportedProtocols.has(parsedUrl.protocol)) {
52776
+ const supportedProtocols = new Set(["http:", "https:", "ssh:", "git:"]);
52777
+ if (!supportedProtocols.has(parsedUrl.protocol)) {
52778
52778
  return null;
52779
52779
  }
52780
- const repoPath = parseGitHubRepositoryPath(parsedUrl.pathname);
52781
- if (!repoPath) {
52780
+ const pathname = parsedUrl.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
52781
+ const segments = pathname.split("/").filter(Boolean);
52782
+ const repo = segments.at(-1);
52783
+ const owner = segments.slice(0, -1).join("/");
52784
+ if (!owner || !repo) {
52782
52785
  return null;
52783
52786
  }
52784
- return `https://github.com/${repoPath}`;
52787
+ return {
52788
+ host: parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:" ? parsedUrl.host : parsedUrl.hostname,
52789
+ owner,
52790
+ repo
52791
+ };
52785
52792
  } catch {
52786
52793
  return null;
52787
52794
  }
52788
52795
  }
52796
+ function getRemoteInfo(remoteName, context) {
52797
+ const url2 = runGitArgs(["remote", "get-url", "--", remoteName], context, `remote get-url -- ${remoteName}`);
52798
+ if (!url2) {
52799
+ return null;
52800
+ }
52801
+ const parsed = parseRemoteUrl(url2);
52802
+ if (!parsed) {
52803
+ return null;
52804
+ }
52805
+ return {
52806
+ name: remoteName,
52807
+ url: url2,
52808
+ host: parsed.host,
52809
+ owner: parsed.owner,
52810
+ repo: parsed.repo
52811
+ };
52812
+ }
52813
+ function getTrackingRemoteName(context) {
52814
+ const upstreamRef = runGit("rev-parse --abbrev-ref --symbolic-full-name @{upstream}", context);
52815
+ if (!upstreamRef) {
52816
+ return null;
52817
+ }
52818
+ const remotes = listRemotes(context).slice().sort((left, right) => right.length - left.length);
52819
+ return remotes.find((remote) => upstreamRef === remote || upstreamRef.startsWith(`${remote}/`)) ?? null;
52820
+ }
52821
+ function getUpstreamRemoteInfo(context) {
52822
+ const namedUpstream = getRemoteInfo("upstream", context);
52823
+ if (namedUpstream) {
52824
+ return namedUpstream;
52825
+ }
52826
+ const trackingRemoteName = getTrackingRemoteName(context);
52827
+ if (!trackingRemoteName) {
52828
+ return null;
52829
+ }
52830
+ return getRemoteInfo(trackingRemoteName, context);
52831
+ }
52832
+ function getForkStatus(context) {
52833
+ const origin = getRemoteInfo("origin", context);
52834
+ const upstream = getRemoteInfo("upstream", context);
52835
+ const isFork = Boolean(origin && upstream && (origin.owner !== upstream.owner || origin.repo !== upstream.repo));
52836
+ return {
52837
+ isFork,
52838
+ origin,
52839
+ upstream
52840
+ };
52841
+ }
52842
+ function listRemotes(context) {
52843
+ const output = runGit("remote", context);
52844
+ if (!output) {
52845
+ return [];
52846
+ }
52847
+ return output.split(`
52848
+ `).filter(Boolean);
52849
+ }
52850
+ function buildRepoWebUrl(remote) {
52851
+ return `https://${remote.host}/${remote.owner}/${remote.repo}`;
52852
+ }
52853
+ function buildBranchWebUrl(remote, encodedBranch) {
52854
+ return `${buildRepoWebUrl(remote)}/tree/${encodedBranch}`;
52855
+ }
52856
+ var init_git_remote = __esm(() => {
52857
+ init_git();
52858
+ });
52859
+
52860
+ // src/utils/hyperlink.ts
52861
+ function renderOsc8Link(url2, text) {
52862
+ return `\x1B]8;;${url2}\x1B\\${text}\x1B]8;;\x1B\\`;
52863
+ }
52789
52864
  function encodeGitRefForUrlPath(ref) {
52790
52865
  return ref.split("/").map((segment) => encodeURIComponent(segment)).join("/");
52791
52866
  }
@@ -52866,6 +52941,23 @@ var init_git_no_git = __esm(() => {
52866
52941
  });
52867
52942
 
52868
52943
  // src/widgets/GitBranch.ts
52944
+ function isLinkEnabled(item) {
52945
+ return isMetadataFlagEnabled(item, LINK_KEY) || item.metadata?.[LINK_KEY] === undefined && isMetadataFlagEnabled(item, LEGACY_LINK_KEY);
52946
+ }
52947
+ function toggleLink(item) {
52948
+ const nextEnabled = !isLinkEnabled(item);
52949
+ const {
52950
+ [LINK_KEY]: removedLink,
52951
+ [LEGACY_LINK_KEY]: removedLegacyLink,
52952
+ ...restMetadata
52953
+ } = item.metadata ?? {};
52954
+ const nextMetadata = nextEnabled ? { ...restMetadata, [LINK_KEY]: "true" } : restMetadata;
52955
+ return {
52956
+ ...item,
52957
+ metadata: Object.keys(nextMetadata).length > 0 ? nextMetadata : undefined
52958
+ };
52959
+ }
52960
+
52869
52961
  class GitBranchWidget {
52870
52962
  getDefaultColor() {
52871
52963
  return "magenta";
@@ -52880,13 +52972,13 @@ class GitBranchWidget {
52880
52972
  return "Git";
52881
52973
  }
52882
52974
  getEditorDisplay(item) {
52883
- const isLink = isMetadataFlagEnabled(item, LINK_KEY);
52975
+ const isLink = isLinkEnabled(item);
52884
52976
  const modifiers = [];
52885
52977
  const noGitText = getHideNoGitModifierText(item);
52886
52978
  if (noGitText)
52887
52979
  modifiers.push("hide 'no git'");
52888
52980
  if (isLink)
52889
- modifiers.push("GitHub link");
52981
+ modifiers.push("repo link");
52890
52982
  return {
52891
52983
  displayText: this.getDisplayName(),
52892
52984
  modifierText: makeModifierText(modifiers)
@@ -52894,13 +52986,13 @@ class GitBranchWidget {
52894
52986
  }
52895
52987
  handleEditorAction(action, item) {
52896
52988
  if (action === TOGGLE_LINK_ACTION) {
52897
- return toggleMetadataFlag(item, LINK_KEY);
52989
+ return toggleLink(item);
52898
52990
  }
52899
52991
  return handleToggleNoGitAction(action, item);
52900
52992
  }
52901
52993
  render(item, context, settings) {
52902
52994
  const hideNoGit = isHideNoGitEnabled(item);
52903
- const isLink = isMetadataFlagEnabled(item, LINK_KEY);
52995
+ const isLink = isLinkEnabled(item);
52904
52996
  if (context.isPreview) {
52905
52997
  const text = item.rawValue ? "main" : "⎇ main";
52906
52998
  return isLink ? renderOsc8Link("https://github.com/owner/repo/tree/main", text) : text;
@@ -52914,10 +53006,9 @@ class GitBranchWidget {
52914
53006
  }
52915
53007
  const displayText = item.rawValue ? branch : `⎇ ${branch}`;
52916
53008
  if (isLink) {
52917
- const remoteUrl = runGit("remote get-url origin", context);
52918
- const baseUrl = remoteUrl ? parseGitHubBaseUrl(remoteUrl) : null;
52919
- if (baseUrl) {
52920
- return renderOsc8Link(`${baseUrl}/tree/${encodeGitRefForUrlPath(branch)}`, displayText);
53009
+ const origin = getRemoteInfo("origin", context);
53010
+ if (origin) {
53011
+ return renderOsc8Link(buildBranchWebUrl(origin, encodeGitRefForUrlPath(branch)), displayText);
52921
53012
  }
52922
53013
  }
52923
53014
  return displayText;
@@ -52928,7 +53019,7 @@ class GitBranchWidget {
52928
53019
  getCustomKeybinds() {
52929
53020
  return [
52930
53021
  ...getHideNoGitKeybinds(),
52931
- { key: "l", label: "(l)ink to GitHub", action: TOGGLE_LINK_ACTION }
53022
+ { key: "l", label: "(l)ink to repo", action: TOGGLE_LINK_ACTION }
52932
53023
  ];
52933
53024
  }
52934
53025
  supportsRawValue() {
@@ -52938,9 +53029,10 @@ class GitBranchWidget {
52938
53029
  return true;
52939
53030
  }
52940
53031
  }
52941
- var LINK_KEY = "linkToGitHub", TOGGLE_LINK_ACTION = "toggle-link";
53032
+ var LINK_KEY = "linkToRepo", LEGACY_LINK_KEY = "linkToGitHub", TOGGLE_LINK_ACTION = "toggle-link";
52942
53033
  var init_GitBranch = __esm(() => {
52943
53034
  init_git();
53035
+ init_git_remote();
52944
53036
  init_hyperlink();
52945
53037
  init_git_no_git();
52946
53038
  });
@@ -53206,8 +53298,8 @@ var init_GitRootDir = __esm(() => {
53206
53298
  };
53207
53299
  });
53208
53300
 
53209
- // src/utils/gh-pr-cache.ts
53210
- import { execFileSync } from "child_process";
53301
+ // src/utils/git-review-cache.ts
53302
+ import { execFileSync as execFileSync2 } from "child_process";
53211
53303
  import {
53212
53304
  existsSync as existsSync2,
53213
53305
  mkdirSync,
@@ -53221,8 +53313,8 @@ import path from "node:path";
53221
53313
  function getCacheDir(deps) {
53222
53314
  return path.join(deps.getHomedir(), ".cache", "ccstatusline");
53223
53315
  }
53224
- function getPrCacheDir(deps) {
53225
- return path.join(getCacheDir(deps), "pr");
53316
+ function getGitReviewCacheDir(deps) {
53317
+ return path.join(getCacheDir(deps), "git-review");
53226
53318
  }
53227
53319
  function runGitForCache(args, cwd2, deps) {
53228
53320
  try {
@@ -53230,15 +53322,19 @@ function runGitForCache(args, cwd2, deps) {
53230
53322
  encoding: "utf8",
53231
53323
  stdio: ["pipe", "pipe", "ignore"],
53232
53324
  cwd: cwd2,
53233
- timeout: GH_TIMEOUT
53325
+ timeout: CLI_TIMEOUT
53234
53326
  }).trim();
53235
53327
  } catch {
53236
53328
  return "";
53237
53329
  }
53238
53330
  }
53239
- function getCacheRef(cwd2, deps) {
53331
+ function getCurrentBranch(cwd2, deps) {
53240
53332
  const branch = runGitForCache(["branch", "--show-current"], cwd2, deps);
53241
- if (branch.length > 0) {
53333
+ return branch.length > 0 ? branch : null;
53334
+ }
53335
+ function getCacheRef(cwd2, deps) {
53336
+ const branch = getCurrentBranch(cwd2, deps);
53337
+ if (branch) {
53242
53338
  return `branch:${branch}`;
53243
53339
  }
53244
53340
  const head3 = runGitForCache(["rev-parse", "--short", "HEAD"], cwd2, deps);
@@ -53249,7 +53345,7 @@ function getCacheRef(cwd2, deps) {
53249
53345
  }
53250
53346
  function getCachePath(cwd2, ref, deps) {
53251
53347
  const hash2 = createHash("sha256").update(cwd2).update("\x00").update(ref).digest("hex").slice(0, 16);
53252
- return path.join(getPrCacheDir(deps), `pr-${hash2}.json`);
53348
+ return path.join(getGitReviewCacheDir(deps), `git-review-${hash2}.json`);
53253
53349
  }
53254
53350
  function readCache(cachePath, deps) {
53255
53351
  try {
@@ -53257,7 +53353,7 @@ function readCache(cachePath, deps) {
53257
53353
  return "miss";
53258
53354
  }
53259
53355
  const age = deps.now() - deps.statSync(cachePath).mtimeMs;
53260
- if (age > PR_CACHE_TTL) {
53356
+ if (age > GIT_REVIEW_CACHE_TTL) {
53261
53357
  return "miss";
53262
53358
  }
53263
53359
  const content = deps.readFileSync(cachePath, "utf-8").trim();
@@ -53275,59 +53371,189 @@ function readCache(cachePath, deps) {
53275
53371
  }
53276
53372
  function writeCache(cachePath, data, deps) {
53277
53373
  try {
53278
- const cacheDir = getPrCacheDir(deps);
53374
+ const cacheDir = getGitReviewCacheDir(deps);
53279
53375
  if (!deps.existsSync(cacheDir)) {
53280
53376
  deps.mkdirSync(cacheDir, { recursive: true });
53281
53377
  }
53282
53378
  deps.writeFileSync(cachePath, data ? JSON.stringify(data) : "", "utf-8");
53283
53379
  } catch {}
53284
53380
  }
53285
- function fetchPrData(cwd2, deps = DEFAULT_PR_CACHE_DEPS) {
53286
- const cachePath = getCachePath(cwd2, getCacheRef(cwd2, deps), deps);
53287
- const cached2 = readCache(cachePath, deps);
53288
- if (cached2 !== "miss") {
53289
- return cached2;
53381
+ function getOriginUrl(cwd2, deps) {
53382
+ const url2 = runGitForCache(["remote", "get-url", "--", "origin"], cwd2, deps);
53383
+ return url2.length > 0 ? url2 : null;
53384
+ }
53385
+ function getOriginHost(cwd2, deps) {
53386
+ const url2 = getOriginUrl(cwd2, deps);
53387
+ if (!url2) {
53388
+ return null;
53389
+ }
53390
+ const parsed = parseRemoteUrl(url2);
53391
+ return parsed ? parsed.host.toLowerCase() : null;
53392
+ }
53393
+ function toHttpsRepoRef(url2) {
53394
+ const parsed = parseRemoteUrl(url2);
53395
+ if (!parsed) {
53396
+ return null;
53397
+ }
53398
+ return `https://${parsed.host}/${parsed.owner}/${parsed.repo}`;
53399
+ }
53400
+ function getOriginRepoRef(cwd2, deps) {
53401
+ const url2 = getOriginUrl(cwd2, deps);
53402
+ return url2 ? toHttpsRepoRef(url2) : null;
53403
+ }
53404
+ function getProviderCandidates(cwd2, deps) {
53405
+ const host = getOriginHost(cwd2, deps);
53406
+ if (!host) {
53407
+ return ["gh", "glab"];
53408
+ }
53409
+ if (host.includes("github")) {
53410
+ return ["gh"];
53411
+ }
53412
+ if (host.includes("gitlab")) {
53413
+ return ["glab"];
53290
53414
  }
53415
+ const authed = [];
53416
+ if (isCliAuthedForHost("glab", host, deps)) {
53417
+ authed.push("glab");
53418
+ }
53419
+ if (isCliAuthedForHost("gh", host, deps)) {
53420
+ authed.push("gh");
53421
+ }
53422
+ return authed;
53423
+ }
53424
+ function isCliAvailable(cli, deps) {
53291
53425
  try {
53292
- deps.execFileSync("gh", ["--version"], {
53426
+ deps.execFileSync(cli, ["--version"], {
53293
53427
  stdio: ["pipe", "pipe", "ignore"],
53294
- timeout: GH_TIMEOUT
53428
+ timeout: CLI_TIMEOUT
53295
53429
  });
53430
+ return true;
53296
53431
  } catch {
53297
- writeCache(cachePath, null, deps);
53298
- return null;
53432
+ return false;
53299
53433
  }
53434
+ }
53435
+ function isCliAuthedForHost(cli, host, deps) {
53300
53436
  try {
53301
- const output = deps.execFileSync("gh", ["pr", "view", "--json", "url,number,title,state,reviewDecision"], {
53302
- encoding: "utf8",
53437
+ deps.execFileSync(cli, ["auth", "status", "--hostname", host], {
53303
53438
  stdio: ["pipe", "pipe", "ignore"],
53304
- cwd: cwd2,
53305
- timeout: GH_TIMEOUT
53306
- }).trim();
53307
- if (output.length === 0) {
53308
- writeCache(cachePath, null, deps);
53439
+ timeout: CLI_TIMEOUT
53440
+ });
53441
+ return true;
53442
+ } catch {
53443
+ return false;
53444
+ }
53445
+ }
53446
+ function mapGlabState(state) {
53447
+ if (state === "opened")
53448
+ return "OPEN";
53449
+ if (state === "closed")
53450
+ return "CLOSED";
53451
+ if (state === "merged")
53452
+ return "MERGED";
53453
+ if (state === "locked")
53454
+ return "LOCKED";
53455
+ return state.toUpperCase();
53456
+ }
53457
+ function fetchFromGh(cwd2, repoRef, deps) {
53458
+ const args = ["pr", "view"];
53459
+ if (repoRef) {
53460
+ const branch = getCurrentBranch(cwd2, deps);
53461
+ if (!branch) {
53309
53462
  return null;
53310
53463
  }
53311
- const parsed = JSON.parse(output);
53312
- if (typeof parsed.number !== "number" || typeof parsed.url !== "string") {
53313
- writeCache(cachePath, null, deps);
53464
+ args.push(branch, "--repo", repoRef);
53465
+ }
53466
+ args.push("--json", "url,number,title,state,reviewDecision");
53467
+ const output = deps.execFileSync("gh", args, {
53468
+ encoding: "utf8",
53469
+ stdio: ["pipe", "pipe", "ignore"],
53470
+ cwd: cwd2,
53471
+ timeout: CLI_TIMEOUT
53472
+ }).trim();
53473
+ if (output.length === 0) {
53474
+ return null;
53475
+ }
53476
+ const parsed = JSON.parse(output);
53477
+ if (typeof parsed.number !== "number" || typeof parsed.url !== "string") {
53478
+ return null;
53479
+ }
53480
+ return {
53481
+ number: parsed.number,
53482
+ url: parsed.url,
53483
+ title: typeof parsed.title === "string" ? parsed.title : "",
53484
+ state: typeof parsed.state === "string" ? parsed.state : "",
53485
+ reviewDecision: typeof parsed.reviewDecision === "string" ? parsed.reviewDecision : "",
53486
+ provider: "gh"
53487
+ };
53488
+ }
53489
+ function fetchFromGlab(cwd2, repoRef, deps) {
53490
+ const args = ["mr", "view"];
53491
+ if (repoRef) {
53492
+ const branch = getCurrentBranch(cwd2, deps);
53493
+ if (!branch) {
53314
53494
  return null;
53315
53495
  }
53316
- const data = {
53317
- number: parsed.number,
53318
- url: parsed.url,
53319
- title: typeof parsed.title === "string" ? parsed.title : "",
53320
- state: typeof parsed.state === "string" ? parsed.state : "",
53321
- reviewDecision: typeof parsed.reviewDecision === "string" ? parsed.reviewDecision : ""
53322
- };
53323
- writeCache(cachePath, data, deps);
53324
- return data;
53325
- } catch {
53326
- writeCache(cachePath, null, deps);
53496
+ args.push(branch, "--repo", repoRef);
53497
+ }
53498
+ args.push("--output", "json");
53499
+ const output = deps.execFileSync("glab", args, {
53500
+ encoding: "utf8",
53501
+ stdio: ["pipe", "pipe", "ignore"],
53502
+ cwd: cwd2,
53503
+ timeout: CLI_TIMEOUT
53504
+ }).trim();
53505
+ if (output.length === 0) {
53506
+ return null;
53507
+ }
53508
+ const parsed = JSON.parse(output);
53509
+ if (typeof parsed.iid !== "number" || typeof parsed.web_url !== "string") {
53327
53510
  return null;
53328
53511
  }
53512
+ return {
53513
+ number: parsed.iid,
53514
+ url: parsed.web_url,
53515
+ title: typeof parsed.title === "string" ? parsed.title : "",
53516
+ state: typeof parsed.state === "string" ? mapGlabState(parsed.state) : "",
53517
+ reviewDecision: "",
53518
+ provider: "glab"
53519
+ };
53329
53520
  }
53330
- function getPrStatusLabel(state, reviewDecision) {
53521
+ function fetchFromProvider(provider, cwd2, repoRef, deps) {
53522
+ const fetchFn = provider === "gh" ? fetchFromGh : fetchFromGlab;
53523
+ try {
53524
+ const unpinned = fetchFn(cwd2, null, deps);
53525
+ if (unpinned) {
53526
+ return unpinned;
53527
+ }
53528
+ } catch {}
53529
+ if (repoRef) {
53530
+ return fetchFn(cwd2, repoRef, deps);
53531
+ }
53532
+ return null;
53533
+ }
53534
+ function fetchGitReviewData(cwd2, deps = DEFAULT_GIT_REVIEW_CACHE_DEPS) {
53535
+ const cachePath = getCachePath(cwd2, getCacheRef(cwd2, deps), deps);
53536
+ const cached2 = readCache(cachePath, deps);
53537
+ if (cached2 !== "miss") {
53538
+ return cached2;
53539
+ }
53540
+ const repoRef = getOriginRepoRef(cwd2, deps);
53541
+ for (const provider of getProviderCandidates(cwd2, deps)) {
53542
+ if (!isCliAvailable(provider, deps)) {
53543
+ continue;
53544
+ }
53545
+ try {
53546
+ const data = fetchFromProvider(provider, cwd2, repoRef, deps);
53547
+ if (data) {
53548
+ writeCache(cachePath, data, deps);
53549
+ return data;
53550
+ }
53551
+ } catch {}
53552
+ }
53553
+ writeCache(cachePath, null, deps);
53554
+ return null;
53555
+ }
53556
+ function getGitReviewStatusLabel(state, reviewDecision) {
53331
53557
  if (state === "MERGED")
53332
53558
  return "MERGED";
53333
53559
  if (state === "CLOSED")
@@ -53346,10 +53572,11 @@ function truncateTitle(title, maxWidth) {
53346
53572
  return title;
53347
53573
  return `${title.slice(0, limit - 1)}…`;
53348
53574
  }
53349
- var PR_CACHE_TTL = 30000, GH_TIMEOUT = 5000, DEFAULT_TITLE_MAX_WIDTH = 30, DEFAULT_PR_CACHE_DEPS;
53350
- var init_gh_pr_cache = __esm(() => {
53351
- DEFAULT_PR_CACHE_DEPS = {
53352
- execFileSync,
53575
+ var GIT_REVIEW_CACHE_TTL = 30000, CLI_TIMEOUT = 5000, DEFAULT_TITLE_MAX_WIDTH = 30, DEFAULT_GIT_REVIEW_CACHE_DEPS;
53576
+ var init_git_review_cache = __esm(() => {
53577
+ init_git_remote();
53578
+ DEFAULT_GIT_REVIEW_CACHE_DEPS = {
53579
+ execFileSync: execFileSync2,
53353
53580
  existsSync: existsSync2,
53354
53581
  mkdirSync,
53355
53582
  readFileSync: readFileSync2,
@@ -53361,11 +53588,27 @@ var init_gh_pr_cache = __esm(() => {
53361
53588
  });
53362
53589
 
53363
53590
  // src/widgets/GitPr.ts
53364
- function buildDisplay(item, pr, showStatus, showTitle) {
53365
- const linkText = item.rawValue ? `#${pr.number}` : `PR #${pr.number}`;
53591
+ function resolvePrNoun(pr, context, deps) {
53592
+ if (pr?.provider === "glab")
53593
+ return "MR";
53594
+ if (pr?.provider === "gh")
53595
+ return "PR";
53596
+ if (pr) {
53597
+ const url2 = pr.url.toLowerCase();
53598
+ if (url2.includes("/-/merge_requests/") || url2.includes("gitlab"))
53599
+ return "MR";
53600
+ } else {
53601
+ const origin = deps.getRemoteInfo("origin", context);
53602
+ if (origin?.host.toLowerCase().includes("gitlab"))
53603
+ return "MR";
53604
+ }
53605
+ return "PR";
53606
+ }
53607
+ function buildDisplay(item, pr, showStatus, showTitle, noun) {
53608
+ const linkText = item.rawValue ? `#${pr.number}` : `${noun} #${pr.number}`;
53366
53609
  const parts = [renderOsc8Link(pr.url, linkText)];
53367
53610
  if (showStatus) {
53368
- const status = getPrStatusLabel(pr.state, pr.reviewDecision);
53611
+ const status = getGitReviewStatusLabel(pr.state, pr.reviewDecision);
53369
53612
  if (status.length > 0) {
53370
53613
  parts.push(status);
53371
53614
  }
@@ -53385,10 +53628,10 @@ class GitPrWidget {
53385
53628
  return "cyan";
53386
53629
  }
53387
53630
  getDescription() {
53388
- return "Shows PR info for the current branch (clickable link, status, title)";
53631
+ return "Shows PR/MR info for the current branch (clickable link, status, title)";
53389
53632
  }
53390
53633
  getDisplayName() {
53391
- return "Git PR";
53634
+ return "Git PR/MR";
53392
53635
  }
53393
53636
  getCategory() {
53394
53637
  return "Git";
@@ -53421,17 +53664,17 @@ class GitPrWidget {
53421
53664
  const showStatus = !isMetadataFlagEnabled(item, HIDE_STATUS_KEY);
53422
53665
  const showTitle = !isMetadataFlagEnabled(item, HIDE_TITLE_KEY);
53423
53666
  if (context.isPreview) {
53424
- return buildDisplay(item, PREVIEW_PR, showStatus, showTitle);
53667
+ return buildDisplay(item, PREVIEW_PR, showStatus, showTitle, resolvePrNoun(PREVIEW_PR, context, this.deps));
53425
53668
  }
53426
53669
  if (!this.deps.isInsideGitWorkTree(context)) {
53427
- return hideNoGit ? null : "(no PR)";
53670
+ return hideNoGit ? null : `(no ${resolvePrNoun(null, context, this.deps)})`;
53428
53671
  }
53429
53672
  const cwd2 = this.deps.resolveGitCwd(context) ?? this.deps.getProcessCwd();
53430
- const prData = this.deps.fetchPrData(cwd2);
53673
+ const prData = this.deps.fetchGitReviewData(cwd2);
53431
53674
  if (!prData) {
53432
- return hideNoGit ? null : "(no PR)";
53675
+ return hideNoGit ? null : `(no ${resolvePrNoun(null, context, this.deps)})`;
53433
53676
  }
53434
- return buildDisplay(item, prData, showStatus, showTitle);
53677
+ return buildDisplay(item, prData, showStatus, showTitle, resolvePrNoun(prData, context, this.deps));
53435
53678
  }
53436
53679
  getCustomKeybinds() {
53437
53680
  return [
@@ -53449,13 +53692,15 @@ class GitPrWidget {
53449
53692
  }
53450
53693
  var HIDE_STATUS_KEY = "hideStatus", HIDE_TITLE_KEY = "hideTitle", TOGGLE_STATUS_ACTION = "toggle-status", TOGGLE_TITLE_ACTION = "toggle-title", DEFAULT_GIT_PR_WIDGET_DEPS, PREVIEW_PR;
53451
53694
  var init_GitPr = __esm(() => {
53452
- init_gh_pr_cache();
53453
53695
  init_git();
53696
+ init_git_remote();
53697
+ init_git_review_cache();
53454
53698
  init_hyperlink();
53455
53699
  init_git_no_git();
53456
53700
  DEFAULT_GIT_PR_WIDGET_DEPS = {
53457
- fetchPrData,
53701
+ fetchGitReviewData,
53458
53702
  getProcessCwd: () => process.cwd(),
53703
+ getRemoteInfo,
53459
53704
  isInsideGitWorkTree,
53460
53705
  resolveGitCwd
53461
53706
  };
@@ -53984,109 +54229,6 @@ var init_GitSha = __esm(() => {
53984
54229
  init_git_no_git();
53985
54230
  });
53986
54231
 
53987
- // src/utils/git-remote.ts
53988
- function parseRemoteUrl(url2) {
53989
- const trimmed = url2.trim();
53990
- if (trimmed.length === 0) {
53991
- return null;
53992
- }
53993
- const sshMatch = !trimmed.includes("://") ? /^(?:[^@]+@)?([^:]+):(.+?)(?:\.git)?\/?$/.exec(trimmed) : null;
53994
- if (sshMatch?.[1] && sshMatch[2]) {
53995
- const pathSegments = sshMatch[2].split("/").filter(Boolean);
53996
- const repo = pathSegments.at(-1);
53997
- const owner = pathSegments.slice(0, -1).join("/");
53998
- if (!owner || !repo) {
53999
- return null;
54000
- }
54001
- return {
54002
- host: sshMatch[1],
54003
- owner,
54004
- repo
54005
- };
54006
- }
54007
- try {
54008
- const parsedUrl = new URL(trimmed);
54009
- const supportedProtocols = new Set(["http:", "https:", "ssh:", "git:"]);
54010
- if (!supportedProtocols.has(parsedUrl.protocol)) {
54011
- return null;
54012
- }
54013
- const pathname = parsedUrl.pathname.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
54014
- const segments = pathname.split("/").filter(Boolean);
54015
- const repo = segments.at(-1);
54016
- const owner = segments.slice(0, -1).join("/");
54017
- if (!owner || !repo) {
54018
- return null;
54019
- }
54020
- return {
54021
- host: parsedUrl.hostname,
54022
- owner,
54023
- repo
54024
- };
54025
- } catch {
54026
- return null;
54027
- }
54028
- }
54029
- function getRemoteInfo(remoteName, context) {
54030
- const url2 = runGit(`remote get-url ${remoteName}`, context);
54031
- if (!url2) {
54032
- return null;
54033
- }
54034
- const parsed = parseRemoteUrl(url2);
54035
- if (!parsed) {
54036
- return null;
54037
- }
54038
- return {
54039
- name: remoteName,
54040
- url: url2,
54041
- host: parsed.host,
54042
- owner: parsed.owner,
54043
- repo: parsed.repo
54044
- };
54045
- }
54046
- function getTrackingRemoteName(context) {
54047
- const upstreamRef = runGit("rev-parse --abbrev-ref --symbolic-full-name @{upstream}", context);
54048
- if (!upstreamRef) {
54049
- return null;
54050
- }
54051
- const remotes = listRemotes(context).slice().sort((left, right) => right.length - left.length);
54052
- return remotes.find((remote) => upstreamRef === remote || upstreamRef.startsWith(`${remote}/`)) ?? null;
54053
- }
54054
- function getUpstreamRemoteInfo(context) {
54055
- const namedUpstream = getRemoteInfo("upstream", context);
54056
- if (namedUpstream) {
54057
- return namedUpstream;
54058
- }
54059
- const trackingRemoteName = getTrackingRemoteName(context);
54060
- if (!trackingRemoteName) {
54061
- return null;
54062
- }
54063
- return getRemoteInfo(trackingRemoteName, context);
54064
- }
54065
- function getForkStatus(context) {
54066
- const origin = getRemoteInfo("origin", context);
54067
- const upstream = getRemoteInfo("upstream", context);
54068
- const isFork = Boolean(origin && upstream && (origin.owner !== upstream.owner || origin.repo !== upstream.repo));
54069
- return {
54070
- isFork,
54071
- origin,
54072
- upstream
54073
- };
54074
- }
54075
- function listRemotes(context) {
54076
- const output = runGit("remote", context);
54077
- if (!output) {
54078
- return [];
54079
- }
54080
- return output.split(`
54081
- `).filter(Boolean);
54082
- }
54083
- function buildRepoWebUrl(remote) {
54084
- return `https://${remote.host}/${remote.owner}/${remote.repo}`;
54085
- }
54086
- var init_git_remote = __esm(() => {
54087
- init_git();
54088
- });
54089
-
54090
54232
  // src/widgets/shared/git-remote.ts
54091
54233
  function isHideNoRemoteEnabled(item) {
54092
54234
  return isMetadataFlagEnabled(item, HIDE_NO_REMOTE_KEY);
@@ -54861,6 +55003,29 @@ function getOsc8CloseSequence(terminator) {
54861
55003
  function stripSgrCodes(text) {
54862
55004
  return text.replace(SGR_REGEX, "");
54863
55005
  }
55006
+ function stripOscCodes(text) {
55007
+ let result2 = "";
55008
+ let index = 0;
55009
+ while (index < text.length) {
55010
+ const escape3 = parseEscapeSequence(text, index);
55011
+ if (escape3) {
55012
+ const isOsc = escape3.sequence.startsWith(`${ESC2}]`) || escape3.sequence.startsWith(C1_OSC);
55013
+ if (!isOsc) {
55014
+ result2 += escape3.sequence;
55015
+ }
55016
+ index = escape3.nextIndex;
55017
+ continue;
55018
+ }
55019
+ const codePoint = text.codePointAt(index);
55020
+ if (codePoint === undefined) {
55021
+ break;
55022
+ }
55023
+ const character = String.fromCodePoint(codePoint);
55024
+ result2 += character;
55025
+ index += character.length;
55026
+ }
55027
+ return result2;
55028
+ }
54864
55029
  function getVisibleText(text) {
54865
55030
  let result2 = "";
54866
55031
  let index = 0;
@@ -55399,7 +55564,7 @@ function calculateContextPercentage(context) {
55399
55564
  var init_context_percentage = () => {};
55400
55565
 
55401
55566
  // src/utils/terminal.ts
55402
- import { execSync as execSync2 } from "child_process";
55567
+ import { execSync } from "child_process";
55403
55568
  import * as fs2 from "fs";
55404
55569
  import * as path2 from "path";
55405
55570
  function getPackageVersion() {
@@ -55441,7 +55606,7 @@ function probeTerminalWidth() {
55441
55606
  }
55442
55607
  }
55443
55608
  try {
55444
- const width = execSync2("tput cols 2>/dev/null", {
55609
+ const width = execSync("tput cols 2>/dev/null", {
55445
55610
  encoding: "utf8",
55446
55611
  stdio: ["pipe", "pipe", "ignore"]
55447
55612
  }).trim();
@@ -55458,7 +55623,7 @@ function parsePositiveInteger(value) {
55458
55623
  }
55459
55624
  function getParentProcessId(pid) {
55460
55625
  try {
55461
- const parentPidOutput = execSync2(`ps -o ppid= -p ${pid}`, {
55626
+ const parentPidOutput = execSync(`ps -o ppid= -p ${pid}`, {
55462
55627
  encoding: "utf8",
55463
55628
  stdio: ["pipe", "pipe", "ignore"],
55464
55629
  shell: "/bin/sh"
@@ -55470,7 +55635,7 @@ function getParentProcessId(pid) {
55470
55635
  }
55471
55636
  function getTTYForProcess(pid) {
55472
55637
  try {
55473
- const tty2 = execSync2(`ps -o tty= -p ${pid}`, {
55638
+ const tty2 = execSync(`ps -o tty= -p ${pid}`, {
55474
55639
  encoding: "utf8",
55475
55640
  stdio: ["pipe", "pipe", "ignore"],
55476
55641
  shell: "/bin/sh"
@@ -55485,7 +55650,7 @@ function getTTYForProcess(pid) {
55485
55650
  }
55486
55651
  function getWidthForTTY(tty2) {
55487
55652
  try {
55488
- const width = execSync2(`stty size < /dev/${tty2} | awk '{print $2}'`, {
55653
+ const width = execSync(`stty size < /dev/${tty2} | awk '{print $2}'`, {
55489
55654
  encoding: "utf8",
55490
55655
  stdio: ["pipe", "pipe", "ignore"],
55491
55656
  shell: "/bin/sh"
@@ -55501,7 +55666,7 @@ function getTerminalWidth() {
55501
55666
  function canDetectTerminalWidth() {
55502
55667
  return probeTerminalWidth() !== null;
55503
55668
  }
55504
- var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.8";
55669
+ var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.9";
55505
55670
  var init_terminal = () => {};
55506
55671
 
55507
55672
  // src/utils/renderer.ts
@@ -57075,7 +57240,7 @@ var init_CustomSymbol = __esm(async () => {
57075
57240
  });
57076
57241
 
57077
57242
  // src/widgets/CustomCommand.tsx
57078
- import { execSync as execSync3 } from "child_process";
57243
+ import { execSync as execSync2 } from "child_process";
57079
57244
 
57080
57245
  class CustomCommandWidget {
57081
57246
  getDefaultColor() {
@@ -57122,7 +57287,7 @@ class CustomCommandWidget {
57122
57287
  try {
57123
57288
  const timeout = item.timeout ?? 1000;
57124
57289
  const jsonInput = JSON.stringify(context.data);
57125
- let output = execSync3(item.commandPath, {
57290
+ let output = execSync2(item.commandPath, {
57126
57291
  encoding: "utf8",
57127
57292
  input: jsonInput,
57128
57293
  timeout,
@@ -57447,7 +57612,7 @@ var require_ms = __commonJS((exports, module) => {
57447
57612
  }
57448
57613
  });
57449
57614
 
57450
- // node_modules/https-proxy-agent/node_modules/debug/src/common.js
57615
+ // node_modules/debug/src/common.js
57451
57616
  var require_common = __commonJS((exports, module) => {
57452
57617
  function setup(env3) {
57453
57618
  createDebug.debug = createDebug;
@@ -57622,7 +57787,7 @@ var require_common = __commonJS((exports, module) => {
57622
57787
  module.exports = setup;
57623
57788
  });
57624
57789
 
57625
- // node_modules/https-proxy-agent/node_modules/debug/src/browser.js
57790
+ // node_modules/debug/src/browser.js
57626
57791
  var require_browser = __commonJS((exports, module) => {
57627
57792
  exports.formatArgs = formatArgs;
57628
57793
  exports.save = save;
@@ -57891,7 +58056,7 @@ var require_supports_color = __commonJS((exports, module) => {
57891
58056
  };
57892
58057
  });
57893
58058
 
57894
- // node_modules/https-proxy-agent/node_modules/debug/src/node.js
58059
+ // node_modules/debug/src/node.js
57895
58060
  var require_node = __commonJS((exports, module) => {
57896
58061
  var tty2 = __require("tty");
57897
58062
  var util = __require("util");
@@ -58062,7 +58227,7 @@ var require_node = __commonJS((exports, module) => {
58062
58227
  };
58063
58228
  });
58064
58229
 
58065
- // node_modules/https-proxy-agent/node_modules/debug/src/index.js
58230
+ // node_modules/debug/src/index.js
58066
58231
  var require_src = __commonJS((exports, module) => {
58067
58232
  if (typeof process === "undefined" || process.type === "renderer" || false || process.__nwjs) {
58068
58233
  module.exports = require_browser();
@@ -58072,125 +58237,17 @@ var require_src = __commonJS((exports, module) => {
58072
58237
  });
58073
58238
 
58074
58239
  // node_modules/agent-base/dist/helpers.js
58075
- var require_helpers = __commonJS((exports) => {
58076
- var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
58077
- if (k2 === undefined)
58078
- k2 = k;
58079
- var desc = Object.getOwnPropertyDescriptor(m, k);
58080
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
58081
- desc = { enumerable: true, get: function() {
58082
- return m[k];
58083
- } };
58084
- }
58085
- Object.defineProperty(o, k2, desc);
58086
- } : function(o, m, k, k2) {
58087
- if (k2 === undefined)
58088
- k2 = k;
58089
- o[k2] = m[k];
58090
- });
58091
- var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
58092
- Object.defineProperty(o, "default", { enumerable: true, value: v });
58093
- } : function(o, v) {
58094
- o["default"] = v;
58095
- });
58096
- var __importStar = exports && exports.__importStar || function(mod) {
58097
- if (mod && mod.__esModule)
58098
- return mod;
58099
- var result2 = {};
58100
- if (mod != null) {
58101
- for (var k in mod)
58102
- if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
58103
- __createBinding(result2, mod, k);
58104
- }
58105
- __setModuleDefault(result2, mod);
58106
- return result2;
58107
- };
58108
- Object.defineProperty(exports, "__esModule", { value: true });
58109
- exports.req = exports.json = exports.toBuffer = undefined;
58110
- var http = __importStar(__require("http"));
58111
- var https = __importStar(__require("https"));
58112
- async function toBuffer(stream) {
58113
- let length = 0;
58114
- const chunks = [];
58115
- for await (const chunk2 of stream) {
58116
- length += chunk2.length;
58117
- chunks.push(chunk2);
58118
- }
58119
- return Buffer.concat(chunks, length);
58120
- }
58121
- exports.toBuffer = toBuffer;
58122
- async function json2(stream) {
58123
- const buf = await toBuffer(stream);
58124
- const str = buf.toString("utf8");
58125
- try {
58126
- return JSON.parse(str);
58127
- } catch (_err) {
58128
- const err = _err;
58129
- err.message += ` (input: ${str})`;
58130
- throw err;
58131
- }
58132
- }
58133
- exports.json = json2;
58134
- function req(url2, opts = {}) {
58135
- const href = typeof url2 === "string" ? url2 : url2.href;
58136
- const req2 = (href.startsWith("https:") ? https : http).request(url2, opts);
58137
- const promise2 = new Promise((resolve, reject2) => {
58138
- req2.once("response", resolve).once("error", reject2).end();
58139
- });
58140
- req2.then = promise2.then.bind(promise2);
58141
- return req2;
58142
- }
58143
- exports.req = req;
58144
- });
58240
+ var init_helpers = () => {};
58145
58241
 
58146
58242
  // node_modules/agent-base/dist/index.js
58147
- var require_dist = __commonJS((exports) => {
58148
- var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
58149
- if (k2 === undefined)
58150
- k2 = k;
58151
- var desc = Object.getOwnPropertyDescriptor(m, k);
58152
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
58153
- desc = { enumerable: true, get: function() {
58154
- return m[k];
58155
- } };
58156
- }
58157
- Object.defineProperty(o, k2, desc);
58158
- } : function(o, m, k, k2) {
58159
- if (k2 === undefined)
58160
- k2 = k;
58161
- o[k2] = m[k];
58162
- });
58163
- var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
58164
- Object.defineProperty(o, "default", { enumerable: true, value: v });
58165
- } : function(o, v) {
58166
- o["default"] = v;
58167
- });
58168
- var __importStar = exports && exports.__importStar || function(mod) {
58169
- if (mod && mod.__esModule)
58170
- return mod;
58171
- var result2 = {};
58172
- if (mod != null) {
58173
- for (var k in mod)
58174
- if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
58175
- __createBinding(result2, mod, k);
58176
- }
58177
- __setModuleDefault(result2, mod);
58178
- return result2;
58179
- };
58180
- var __exportStar = exports && exports.__exportStar || function(m, exports2) {
58181
- for (var p in m)
58182
- if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
58183
- __createBinding(exports2, m, p);
58184
- };
58185
- Object.defineProperty(exports, "__esModule", { value: true });
58186
- exports.Agent = undefined;
58187
- var net = __importStar(__require("net"));
58188
- var http = __importStar(__require("http"));
58189
- var https_1 = __require("https");
58190
- __exportStar(require_helpers(), exports);
58191
- var INTERNAL = Symbol("AgentBaseInternalState");
58192
-
58193
- class Agent extends http.Agent {
58243
+ import * as net from "net";
58244
+ import * as http from "http";
58245
+ import { Agent as HttpsAgent } from "https";
58246
+ var INTERNAL, Agent2;
58247
+ var init_dist4 = __esm(() => {
58248
+ init_helpers();
58249
+ INTERNAL = Symbol("AgentBaseInternalState");
58250
+ Agent2 = class Agent2 extends http.Agent {
58194
58251
  constructor(opts) {
58195
58252
  super(opts);
58196
58253
  this[INTERNAL] = {};
@@ -58239,7 +58296,7 @@ var require_dist = __commonJS((exports) => {
58239
58296
  getName(options) {
58240
58297
  const secureEndpoint = this.isSecureEndpoint(options);
58241
58298
  if (secureEndpoint) {
58242
- return https_1.Agent.prototype.getName.call(this, options);
58299
+ return HttpsAgent.prototype.getName.call(this, options);
58243
58300
  }
58244
58301
  return super.getName(options);
58245
58302
  }
@@ -58290,170 +58347,139 @@ var require_dist = __commonJS((exports) => {
58290
58347
  this[INTERNAL].protocol = v;
58291
58348
  }
58292
58349
  }
58293
- }
58294
- exports.Agent = Agent;
58350
+ };
58295
58351
  });
58296
58352
 
58297
58353
  // node_modules/https-proxy-agent/dist/parse-proxy-response.js
58298
- var require_parse_proxy_response = __commonJS((exports) => {
58299
- var __importDefault = exports && exports.__importDefault || function(mod) {
58300
- return mod && mod.__esModule ? mod : { default: mod };
58301
- };
58302
- Object.defineProperty(exports, "__esModule", { value: true });
58303
- exports.parseProxyResponse = undefined;
58304
- var debug_1 = __importDefault(require_src());
58305
- var debug = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
58306
- function parseProxyResponse(socket) {
58307
- return new Promise((resolve, reject2) => {
58308
- let buffersLength = 0;
58309
- const buffers = [];
58310
- function read() {
58311
- const b = socket.read();
58312
- if (b)
58313
- ondata(b);
58314
- else
58315
- socket.once("readable", read);
58316
- }
58317
- function cleanup() {
58318
- socket.removeListener("end", onend);
58319
- socket.removeListener("error", onerror);
58320
- socket.removeListener("readable", read);
58321
- }
58322
- function onend() {
58323
- cleanup();
58324
- debug("onend");
58325
- reject2(new Error("Proxy connection ended before receiving CONNECT response"));
58326
- }
58327
- function onerror(err) {
58328
- cleanup();
58329
- debug("onerror %o", err);
58330
- reject2(err);
58331
- }
58332
- function ondata(b) {
58333
- buffers.push(b);
58334
- buffersLength += b.length;
58335
- const buffered = Buffer.concat(buffers, buffersLength);
58336
- const endOfHeaders = buffered.indexOf(`\r
58354
+ function parseProxyResponse(socket) {
58355
+ return new Promise((resolve, reject2) => {
58356
+ let buffersLength = 0;
58357
+ const buffers = [];
58358
+ function read() {
58359
+ const b = socket.read();
58360
+ if (b)
58361
+ ondata(b);
58362
+ else
58363
+ socket.once("readable", read);
58364
+ }
58365
+ function cleanup() {
58366
+ socket.removeListener("end", onend);
58367
+ socket.removeListener("error", onerror);
58368
+ socket.removeListener("readable", read);
58369
+ }
58370
+ function onend() {
58371
+ cleanup();
58372
+ debug("onend");
58373
+ reject2(new Error("Proxy connection ended before receiving CONNECT response"));
58374
+ }
58375
+ function onerror(err) {
58376
+ cleanup();
58377
+ debug("onerror %o", err);
58378
+ reject2(err);
58379
+ }
58380
+ function ondata(b) {
58381
+ buffers.push(b);
58382
+ buffersLength += b.length;
58383
+ const buffered = Buffer.concat(buffers, buffersLength);
58384
+ const endOfHeaders = buffered.indexOf(`\r
58337
58385
  \r
58338
58386
  `);
58339
- if (endOfHeaders === -1) {
58340
- debug("have not received end of HTTP headers yet...");
58341
- read();
58342
- return;
58343
- }
58344
- const headerParts = buffered.slice(0, endOfHeaders).toString("ascii").split(`\r
58387
+ if (endOfHeaders === -1) {
58388
+ debug("have not received end of HTTP headers yet...");
58389
+ read();
58390
+ return;
58391
+ }
58392
+ const headerParts = buffered.slice(0, endOfHeaders).toString("ascii").split(`\r
58345
58393
  `);
58346
- const firstLine = headerParts.shift();
58347
- if (!firstLine) {
58394
+ const firstLine = headerParts.shift();
58395
+ if (!firstLine) {
58396
+ socket.destroy();
58397
+ return reject2(new Error("No header received from proxy CONNECT response"));
58398
+ }
58399
+ const firstLineParts = firstLine.split(" ");
58400
+ const statusCode = +firstLineParts[1];
58401
+ const statusText = firstLineParts.slice(2).join(" ");
58402
+ const headers = {};
58403
+ for (const header of headerParts) {
58404
+ if (!header)
58405
+ continue;
58406
+ const firstColon = header.indexOf(":");
58407
+ if (firstColon === -1) {
58348
58408
  socket.destroy();
58349
- return reject2(new Error("No header received from proxy CONNECT response"));
58350
- }
58351
- const firstLineParts = firstLine.split(" ");
58352
- const statusCode = +firstLineParts[1];
58353
- const statusText = firstLineParts.slice(2).join(" ");
58354
- const headers = {};
58355
- for (const header of headerParts) {
58356
- if (!header)
58357
- continue;
58358
- const firstColon = header.indexOf(":");
58359
- if (firstColon === -1) {
58360
- socket.destroy();
58361
- return reject2(new Error(`Invalid header from proxy CONNECT response: "${header}"`));
58362
- }
58363
- const key = header.slice(0, firstColon).toLowerCase();
58364
- const value = header.slice(firstColon + 1).trimStart();
58365
- const current = headers[key];
58366
- if (typeof current === "string") {
58367
- headers[key] = [current, value];
58368
- } else if (Array.isArray(current)) {
58369
- current.push(value);
58370
- } else {
58371
- headers[key] = value;
58372
- }
58409
+ return reject2(new Error(`Invalid header from proxy CONNECT response: "${header}"`));
58410
+ }
58411
+ const key = header.slice(0, firstColon).toLowerCase();
58412
+ const value = header.slice(firstColon + 1).trimStart();
58413
+ const current = headers[key];
58414
+ if (typeof current === "string") {
58415
+ headers[key] = [current, value];
58416
+ } else if (Array.isArray(current)) {
58417
+ current.push(value);
58418
+ } else {
58419
+ headers[key] = value;
58373
58420
  }
58374
- debug("got proxy server response: %o %o", firstLine, headers);
58375
- cleanup();
58376
- resolve({
58377
- connect: {
58378
- statusCode,
58379
- statusText,
58380
- headers
58381
- },
58382
- buffered
58383
- });
58384
58421
  }
58385
- socket.on("error", onerror);
58386
- socket.on("end", onend);
58387
- read();
58388
- });
58389
- }
58390
- exports.parseProxyResponse = parseProxyResponse;
58422
+ debug("got proxy server response: %o %o", firstLine, headers);
58423
+ cleanup();
58424
+ resolve({
58425
+ connect: {
58426
+ statusCode,
58427
+ statusText,
58428
+ headers
58429
+ },
58430
+ buffered
58431
+ });
58432
+ }
58433
+ socket.on("error", onerror);
58434
+ socket.on("end", onend);
58435
+ read();
58436
+ });
58437
+ }
58438
+ var import_debug, debug;
58439
+ var init_parse_proxy_response = __esm(() => {
58440
+ import_debug = __toESM(require_src(), 1);
58441
+ debug = import_debug.default("https-proxy-agent:parse-proxy-response");
58391
58442
  });
58392
58443
 
58393
58444
  // node_modules/https-proxy-agent/dist/index.js
58394
- var require_dist2 = __commonJS((exports) => {
58395
- var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
58396
- if (k2 === undefined)
58397
- k2 = k;
58398
- var desc = Object.getOwnPropertyDescriptor(m, k);
58399
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
58400
- desc = { enumerable: true, get: function() {
58401
- return m[k];
58402
- } };
58403
- }
58404
- Object.defineProperty(o, k2, desc);
58405
- } : function(o, m, k, k2) {
58406
- if (k2 === undefined)
58407
- k2 = k;
58408
- o[k2] = m[k];
58409
- });
58410
- var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
58411
- Object.defineProperty(o, "default", { enumerable: true, value: v });
58412
- } : function(o, v) {
58413
- o["default"] = v;
58414
- });
58415
- var __importStar = exports && exports.__importStar || function(mod) {
58416
- if (mod && mod.__esModule)
58417
- return mod;
58418
- var result2 = {};
58419
- if (mod != null) {
58420
- for (var k in mod)
58421
- if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
58422
- __createBinding(result2, mod, k);
58423
- }
58424
- __setModuleDefault(result2, mod);
58425
- return result2;
58426
- };
58427
- var __importDefault = exports && exports.__importDefault || function(mod) {
58428
- return mod && mod.__esModule ? mod : { default: mod };
58429
- };
58430
- Object.defineProperty(exports, "__esModule", { value: true });
58431
- exports.HttpsProxyAgent = undefined;
58432
- var net = __importStar(__require("net"));
58433
- var tls = __importStar(__require("tls"));
58434
- var assert_1 = __importDefault(__require("assert"));
58435
- var debug_1 = __importDefault(require_src());
58436
- var agent_base_1 = require_dist();
58437
- var url_1 = __require("url");
58438
- var parse_proxy_response_1 = require_parse_proxy_response();
58439
- var debug = (0, debug_1.default)("https-proxy-agent");
58440
- var setServernameFromNonIpHost = (options) => {
58441
- if (options.servername === undefined && options.host && !net.isIP(options.host)) {
58442
- return {
58443
- ...options,
58444
- servername: options.host
58445
- };
58445
+ import * as net2 from "net";
58446
+ import * as tls from "tls";
58447
+ import assert2 from "assert";
58448
+ import { URL as URL2 } from "url";
58449
+ function resume(socket) {
58450
+ socket.resume();
58451
+ }
58452
+ function omit3(obj, ...keys2) {
58453
+ const ret = {};
58454
+ let key;
58455
+ for (key in obj) {
58456
+ if (!keys2.includes(key)) {
58457
+ ret[key] = obj[key];
58446
58458
  }
58447
- return options;
58448
- };
58449
-
58450
- class HttpsProxyAgent extends agent_base_1.Agent {
58459
+ }
58460
+ return ret;
58461
+ }
58462
+ var import_debug2, debug2, setServernameFromNonIpHost = (options) => {
58463
+ if (options.servername === undefined && options.host && !net2.isIP(options.host)) {
58464
+ return {
58465
+ ...options,
58466
+ servername: options.host
58467
+ };
58468
+ }
58469
+ return options;
58470
+ }, HttpsProxyAgent;
58471
+ var init_dist5 = __esm(() => {
58472
+ init_dist4();
58473
+ init_parse_proxy_response();
58474
+ import_debug2 = __toESM(require_src(), 1);
58475
+ debug2 = import_debug2.default("https-proxy-agent");
58476
+ HttpsProxyAgent = class HttpsProxyAgent extends Agent2 {
58451
58477
  constructor(proxy, opts) {
58452
58478
  super(opts);
58453
58479
  this.options = { path: undefined };
58454
- this.proxy = typeof proxy === "string" ? new url_1.URL(proxy) : proxy;
58480
+ this.proxy = typeof proxy === "string" ? new URL2(proxy) : proxy;
58455
58481
  this.proxyHeaders = opts?.headers ?? {};
58456
- debug("Creating new HttpsProxyAgent instance: %o", this.proxy.href);
58482
+ debug2("Creating new HttpsProxyAgent instance: %o", this.proxy.href);
58457
58483
  const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, "");
58458
58484
  const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.proxy.protocol === "https:" ? 443 : 80;
58459
58485
  this.connectOpts = {
@@ -58470,14 +58496,14 @@ var require_dist2 = __commonJS((exports) => {
58470
58496
  }
58471
58497
  let socket;
58472
58498
  if (proxy.protocol === "https:") {
58473
- debug("Creating `tls.Socket`: %o", this.connectOpts);
58499
+ debug2("Creating `tls.Socket`: %o", this.connectOpts);
58474
58500
  socket = tls.connect(setServernameFromNonIpHost(this.connectOpts));
58475
58501
  } else {
58476
- debug("Creating `net.Socket`: %o", this.connectOpts);
58477
- socket = net.connect(this.connectOpts);
58502
+ debug2("Creating `net.Socket`: %o", this.connectOpts);
58503
+ socket = net2.connect(this.connectOpts);
58478
58504
  }
58479
58505
  const headers = typeof this.proxyHeaders === "function" ? this.proxyHeaders() : { ...this.proxyHeaders };
58480
- const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
58506
+ const host = net2.isIPv6(opts.host) ? `[${opts.host}]` : opts.host;
58481
58507
  let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r
58482
58508
  `;
58483
58509
  if (proxy.username || proxy.password) {
@@ -58492,16 +58518,16 @@ var require_dist2 = __commonJS((exports) => {
58492
58518
  payload += `${name}: ${headers[name]}\r
58493
58519
  `;
58494
58520
  }
58495
- const proxyResponsePromise = (0, parse_proxy_response_1.parseProxyResponse)(socket);
58521
+ const proxyResponsePromise = parseProxyResponse(socket);
58496
58522
  socket.write(`${payload}\r
58497
58523
  `);
58498
- const { connect, buffered } = await proxyResponsePromise;
58499
- req.emit("proxyConnect", connect);
58500
- this.emit("proxyConnect", connect, req);
58501
- if (connect.statusCode === 200) {
58524
+ const { connect: connect3, buffered } = await proxyResponsePromise;
58525
+ req.emit("proxyConnect", connect3);
58526
+ this.emit("proxyConnect", connect3, req);
58527
+ if (connect3.statusCode === 200) {
58502
58528
  req.once("socket", resume);
58503
58529
  if (opts.secureEndpoint) {
58504
- debug("Upgrading socket connection to TLS");
58530
+ debug2("Upgrading socket connection to TLS");
58505
58531
  return tls.connect({
58506
58532
  ...omit3(setServernameFromNonIpHost(opts), "host", "path", "port"),
58507
58533
  socket
@@ -58510,32 +58536,18 @@ var require_dist2 = __commonJS((exports) => {
58510
58536
  return socket;
58511
58537
  }
58512
58538
  socket.destroy();
58513
- const fakeSocket = new net.Socket({ writable: false });
58539
+ const fakeSocket = new net2.Socket({ writable: false });
58514
58540
  fakeSocket.readable = true;
58515
58541
  req.once("socket", (s) => {
58516
- debug("Replaying proxy buffer for failed request");
58517
- (0, assert_1.default)(s.listenerCount("data") > 0);
58542
+ debug2("Replaying proxy buffer for failed request");
58543
+ assert2(s.listenerCount("data") > 0);
58518
58544
  s.push(buffered);
58519
58545
  s.push(null);
58520
58546
  });
58521
58547
  return fakeSocket;
58522
58548
  }
58523
- }
58549
+ };
58524
58550
  HttpsProxyAgent.protocols = ["http", "https"];
58525
- exports.HttpsProxyAgent = HttpsProxyAgent;
58526
- function resume(socket) {
58527
- socket.resume();
58528
- }
58529
- function omit3(obj, ...keys2) {
58530
- const ret = {};
58531
- let key;
58532
- for (key in obj) {
58533
- if (!keys2.includes(key)) {
58534
- ret[key] = obj[key];
58535
- }
58536
- }
58537
- return ret;
58538
- }
58539
58551
  });
58540
58552
 
58541
58553
  // src/utils/usage-types.ts
@@ -58548,7 +58560,7 @@ var init_usage_types = __esm(() => {
58548
58560
  });
58549
58561
 
58550
58562
  // src/utils/usage-fetch.ts
58551
- import { execFileSync as execFileSync2 } from "child_process";
58563
+ import { execFileSync as execFileSync3 } from "child_process";
58552
58564
  import * as fs3 from "fs";
58553
58565
  import * as https from "https";
58554
58566
  import * as os4 from "os";
@@ -58694,7 +58706,7 @@ function parseMacKeychainCredentialCandidates(rawDump, servicePrefix = MACOS_USA
58694
58706
  }
58695
58707
  function readMacKeychainSecret(service) {
58696
58708
  try {
58697
- return execFileSync2("security", ["find-generic-password", "-s", service, "-w"], { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
58709
+ return execFileSync3("security", ["find-generic-password", "-s", service, "-w"], { encoding: "utf8", stdio: ["pipe", "pipe", "ignore"] }).trim();
58698
58710
  } catch {
58699
58711
  return null;
58700
58712
  }
@@ -58705,7 +58717,7 @@ function readUsageTokenFromMacKeychainService(service) {
58705
58717
  }
58706
58718
  function listMacKeychainCredentialCandidates() {
58707
58719
  try {
58708
- const rawDump = execFileSync2("security", ["dump-keychain"], {
58720
+ const rawDump = execFileSync3("security", ["dump-keychain"], {
58709
58721
  encoding: "utf8",
58710
58722
  maxBuffer: MACOS_SECURITY_DUMP_MAX_BUFFER,
58711
58723
  stdio: ["pipe", "pipe", "ignore"]
@@ -58819,7 +58831,7 @@ function getUsageApiRequestOptions(token) {
58819
58831
  "anthropic-beta": "oauth-2025-04-20"
58820
58832
  },
58821
58833
  timeout: USAGE_API_TIMEOUT_MS,
58822
- ...proxyUrl ? { agent: new import_https_proxy_agent.HttpsProxyAgent(proxyUrl) } : {}
58834
+ ...proxyUrl ? { agent: new HttpsProxyAgent(proxyUrl) } : {}
58823
58835
  };
58824
58836
  } catch {
58825
58837
  return null;
@@ -58926,12 +58938,12 @@ async function fetchUsageData() {
58926
58938
  return getStaleUsageOrError("parse-error", now2);
58927
58939
  }
58928
58940
  }
58929
- var import_https_proxy_agent, CACHE_DIR, CACHE_FILE, LOCK_FILE, CACHE_MAX_AGE = 180, LOCK_MAX_AGE = 30, DEFAULT_RATE_LIMIT_BACKOFF = 300, MACOS_USAGE_CREDENTIALS_SERVICE = "Claude Code-credentials", MACOS_SECURITY_DUMP_MAX_BUFFER, UsageCredentialsSchema, UsageLockErrorSchema, UsageLockSchema, CachedUsageDataSchema, UsageApiResponseSchema, cachedUsageData = null, usageCacheTime = 0, usageErrorCacheMaxAge, USAGE_API_HOST = "api.anthropic.com", USAGE_API_PATH = "/api/oauth/usage", USAGE_API_TIMEOUT_MS = 5000;
58930
- var init_usage_fetch = __esm(() => {
58941
+ var CACHE_DIR, CACHE_FILE, LOCK_FILE, CACHE_MAX_AGE = 180, LOCK_MAX_AGE = 30, DEFAULT_RATE_LIMIT_BACKOFF = 300, MACOS_USAGE_CREDENTIALS_SERVICE = "Claude Code-credentials", MACOS_SECURITY_DUMP_MAX_BUFFER, UsageCredentialsSchema, UsageLockErrorSchema, UsageLockSchema, CachedUsageDataSchema, UsageApiResponseSchema, cachedUsageData = null, usageCacheTime = 0, usageErrorCacheMaxAge, USAGE_API_HOST = "api.anthropic.com", USAGE_API_PATH = "/api/oauth/usage", USAGE_API_TIMEOUT_MS = 5000;
58942
+ var init_usage_fetch = __esm(async () => {
58943
+ init_dist5();
58931
58944
  init_zod();
58932
- init_claude_settings();
58933
58945
  init_usage_types();
58934
- import_https_proxy_agent = __toESM(require_dist2(), 1);
58946
+ await init_claude_settings();
58935
58947
  CACHE_DIR = path3.join(os4.homedir(), ".cache", "ccstatusline");
58936
58948
  CACHE_FILE = path3.join(CACHE_DIR, "usage.json");
58937
58949
  LOCK_FILE = path3.join(CACHE_DIR, "usage.lock");
@@ -59466,7 +59478,7 @@ var __require2, SLASHES_REGEX, WINDOWS_ROOT_DIR_REGEX, pushDirectory = (director
59466
59478
  return this;
59467
59479
  }
59468
59480
  };
59469
- var init_dist4 = __esm(() => {
59481
+ var init_dist6 = __esm(() => {
59470
59482
  __require2 = /* @__PURE__ */ createRequire2(import.meta.url);
59471
59483
  SLASHES_REGEX = /[\\/]/g;
59472
59484
  WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i;
@@ -59477,10 +59489,11 @@ var init_dist4 = __esm(() => {
59477
59489
  } catch {}
59478
59490
  });
59479
59491
 
59480
- // node_modules/picomatch/lib/constants.js
59492
+ // node_modules/tinyglobby/node_modules/picomatch/lib/constants.js
59481
59493
  var require_constants3 = __commonJS((exports, module) => {
59482
59494
  var WIN_SLASH = "\\\\/";
59483
59495
  var WIN_NO_SLASH = `[^${WIN_SLASH}]`;
59496
+ var DEFAULT_MAX_EXTGLOB_RECURSION = 0;
59484
59497
  var DOT_LITERAL = "\\.";
59485
59498
  var PLUS_LITERAL = "\\+";
59486
59499
  var QMARK_LITERAL = "\\?";
@@ -59531,6 +59544,7 @@ var require_constants3 = __commonJS((exports, module) => {
59531
59544
  SEP: "\\"
59532
59545
  };
59533
59546
  var POSIX_REGEX_SOURCE = {
59547
+ __proto__: null,
59534
59548
  alnum: "a-zA-Z0-9",
59535
59549
  alpha: "a-zA-Z",
59536
59550
  ascii: "\\x00-\\x7F",
@@ -59547,6 +59561,7 @@ var require_constants3 = __commonJS((exports, module) => {
59547
59561
  xdigit: "A-Fa-f0-9"
59548
59562
  };
59549
59563
  module.exports = {
59564
+ DEFAULT_MAX_EXTGLOB_RECURSION,
59550
59565
  MAX_LENGTH: 1024 * 64,
59551
59566
  POSIX_REGEX_SOURCE,
59552
59567
  REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
@@ -59619,7 +59634,7 @@ var require_constants3 = __commonJS((exports, module) => {
59619
59634
  };
59620
59635
  });
59621
59636
 
59622
- // node_modules/picomatch/lib/utils.js
59637
+ // node_modules/tinyglobby/node_modules/picomatch/lib/utils.js
59623
59638
  var require_utils = __commonJS((exports) => {
59624
59639
  var {
59625
59640
  REGEX_BACKSLASH,
@@ -59682,7 +59697,7 @@ var require_utils = __commonJS((exports) => {
59682
59697
  };
59683
59698
  });
59684
59699
 
59685
- // node_modules/picomatch/lib/scan.js
59700
+ // node_modules/tinyglobby/node_modules/picomatch/lib/scan.js
59686
59701
  var require_scan = __commonJS((exports, module) => {
59687
59702
  var utils = require_utils();
59688
59703
  var {
@@ -59997,7 +60012,7 @@ var require_scan = __commonJS((exports, module) => {
59997
60012
  module.exports = scan;
59998
60013
  });
59999
60014
 
60000
- // node_modules/picomatch/lib/parse.js
60015
+ // node_modules/tinyglobby/node_modules/picomatch/lib/parse.js
60001
60016
  var require_parse = __commonJS((exports, module) => {
60002
60017
  var constants2 = require_constants3();
60003
60018
  var utils = require_utils();
@@ -60024,6 +60039,213 @@ var require_parse = __commonJS((exports, module) => {
60024
60039
  var syntaxError = (type, char) => {
60025
60040
  return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
60026
60041
  };
60042
+ var splitTopLevel = (input) => {
60043
+ const parts = [];
60044
+ let bracket = 0;
60045
+ let paren = 0;
60046
+ let quote = 0;
60047
+ let value = "";
60048
+ let escaped = false;
60049
+ for (const ch of input) {
60050
+ if (escaped === true) {
60051
+ value += ch;
60052
+ escaped = false;
60053
+ continue;
60054
+ }
60055
+ if (ch === "\\") {
60056
+ value += ch;
60057
+ escaped = true;
60058
+ continue;
60059
+ }
60060
+ if (ch === '"') {
60061
+ quote = quote === 1 ? 0 : 1;
60062
+ value += ch;
60063
+ continue;
60064
+ }
60065
+ if (quote === 0) {
60066
+ if (ch === "[") {
60067
+ bracket++;
60068
+ } else if (ch === "]" && bracket > 0) {
60069
+ bracket--;
60070
+ } else if (bracket === 0) {
60071
+ if (ch === "(") {
60072
+ paren++;
60073
+ } else if (ch === ")" && paren > 0) {
60074
+ paren--;
60075
+ } else if (ch === "|" && paren === 0) {
60076
+ parts.push(value);
60077
+ value = "";
60078
+ continue;
60079
+ }
60080
+ }
60081
+ }
60082
+ value += ch;
60083
+ }
60084
+ parts.push(value);
60085
+ return parts;
60086
+ };
60087
+ var isPlainBranch = (branch) => {
60088
+ let escaped = false;
60089
+ for (const ch of branch) {
60090
+ if (escaped === true) {
60091
+ escaped = false;
60092
+ continue;
60093
+ }
60094
+ if (ch === "\\") {
60095
+ escaped = true;
60096
+ continue;
60097
+ }
60098
+ if (/[?*+@!()[\]{}]/.test(ch)) {
60099
+ return false;
60100
+ }
60101
+ }
60102
+ return true;
60103
+ };
60104
+ var normalizeSimpleBranch = (branch) => {
60105
+ let value = branch.trim();
60106
+ let changed = true;
60107
+ while (changed === true) {
60108
+ changed = false;
60109
+ if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
60110
+ value = value.slice(2, -1);
60111
+ changed = true;
60112
+ }
60113
+ }
60114
+ if (!isPlainBranch(value)) {
60115
+ return;
60116
+ }
60117
+ return value.replace(/\\(.)/g, "$1");
60118
+ };
60119
+ var hasRepeatedCharPrefixOverlap = (branches) => {
60120
+ const values2 = branches.map(normalizeSimpleBranch).filter(Boolean);
60121
+ for (let i = 0;i < values2.length; i++) {
60122
+ for (let j = i + 1;j < values2.length; j++) {
60123
+ const a = values2[i];
60124
+ const b = values2[j];
60125
+ const char = a[0];
60126
+ if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) {
60127
+ continue;
60128
+ }
60129
+ if (a === b || a.startsWith(b) || b.startsWith(a)) {
60130
+ return true;
60131
+ }
60132
+ }
60133
+ }
60134
+ return false;
60135
+ };
60136
+ var parseRepeatedExtglob = (pattern, requireEnd = true) => {
60137
+ if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") {
60138
+ return;
60139
+ }
60140
+ let bracket = 0;
60141
+ let paren = 0;
60142
+ let quote = 0;
60143
+ let escaped = false;
60144
+ for (let i = 1;i < pattern.length; i++) {
60145
+ const ch = pattern[i];
60146
+ if (escaped === true) {
60147
+ escaped = false;
60148
+ continue;
60149
+ }
60150
+ if (ch === "\\") {
60151
+ escaped = true;
60152
+ continue;
60153
+ }
60154
+ if (ch === '"') {
60155
+ quote = quote === 1 ? 0 : 1;
60156
+ continue;
60157
+ }
60158
+ if (quote === 1) {
60159
+ continue;
60160
+ }
60161
+ if (ch === "[") {
60162
+ bracket++;
60163
+ continue;
60164
+ }
60165
+ if (ch === "]" && bracket > 0) {
60166
+ bracket--;
60167
+ continue;
60168
+ }
60169
+ if (bracket > 0) {
60170
+ continue;
60171
+ }
60172
+ if (ch === "(") {
60173
+ paren++;
60174
+ continue;
60175
+ }
60176
+ if (ch === ")") {
60177
+ paren--;
60178
+ if (paren === 0) {
60179
+ if (requireEnd === true && i !== pattern.length - 1) {
60180
+ return;
60181
+ }
60182
+ return {
60183
+ type: pattern[0],
60184
+ body: pattern.slice(2, i),
60185
+ end: i
60186
+ };
60187
+ }
60188
+ }
60189
+ }
60190
+ };
60191
+ var getStarExtglobSequenceOutput = (pattern) => {
60192
+ let index = 0;
60193
+ const chars = [];
60194
+ while (index < pattern.length) {
60195
+ const match = parseRepeatedExtglob(pattern.slice(index), false);
60196
+ if (!match || match.type !== "*") {
60197
+ return;
60198
+ }
60199
+ const branches = splitTopLevel(match.body).map((branch2) => branch2.trim());
60200
+ if (branches.length !== 1) {
60201
+ return;
60202
+ }
60203
+ const branch = normalizeSimpleBranch(branches[0]);
60204
+ if (!branch || branch.length !== 1) {
60205
+ return;
60206
+ }
60207
+ chars.push(branch);
60208
+ index += match.end + 1;
60209
+ }
60210
+ if (chars.length < 1) {
60211
+ return;
60212
+ }
60213
+ const source = chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`;
60214
+ return `${source}*`;
60215
+ };
60216
+ var repeatedExtglobRecursion = (pattern) => {
60217
+ let depth = 0;
60218
+ let value = pattern.trim();
60219
+ let match = parseRepeatedExtglob(value);
60220
+ while (match) {
60221
+ depth++;
60222
+ value = match.body.trim();
60223
+ match = parseRepeatedExtglob(value);
60224
+ }
60225
+ return depth;
60226
+ };
60227
+ var analyzeRepeatedExtglob = (body, options) => {
60228
+ if (options.maxExtglobRecursion === false) {
60229
+ return { risky: false };
60230
+ }
60231
+ const max2 = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants2.DEFAULT_MAX_EXTGLOB_RECURSION;
60232
+ const branches = splitTopLevel(body).map((branch) => branch.trim());
60233
+ if (branches.length > 1) {
60234
+ if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) {
60235
+ return { risky: true };
60236
+ }
60237
+ }
60238
+ for (const branch of branches) {
60239
+ const safeOutput = getStarExtglobSequenceOutput(branch);
60240
+ if (safeOutput) {
60241
+ return { risky: true, safeOutput };
60242
+ }
60243
+ if (repeatedExtglobRecursion(branch) > max2) {
60244
+ return { risky: true };
60245
+ }
60246
+ }
60247
+ return { risky: false };
60248
+ };
60027
60249
  var parse5 = (input, options) => {
60028
60250
  if (typeof input !== "string") {
60029
60251
  throw new TypeError("Expected a string");
@@ -60155,6 +60377,8 @@ var require_parse = __commonJS((exports, module) => {
60155
60377
  token.prev = prev;
60156
60378
  token.parens = state.parens;
60157
60379
  token.output = state.output;
60380
+ token.startIndex = state.index;
60381
+ token.tokensIndex = tokens.length;
60158
60382
  const output = (opts.capture ? "(" : "") + token.open;
60159
60383
  increment("parens");
60160
60384
  push({ type, value: value2, output: state.output ? "" : ONE_CHAR });
@@ -60162,6 +60386,26 @@ var require_parse = __commonJS((exports, module) => {
60162
60386
  extglobs.push(token);
60163
60387
  };
60164
60388
  const extglobClose = (token) => {
60389
+ const literal2 = input.slice(token.startIndex, state.index + 1);
60390
+ const body = input.slice(token.startIndex + 2, state.index);
60391
+ const analysis = analyzeRepeatedExtglob(body, opts);
60392
+ if ((token.type === "plus" || token.type === "star") && analysis.risky) {
60393
+ const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : undefined;
60394
+ const open = tokens[token.tokensIndex];
60395
+ open.type = "text";
60396
+ open.value = literal2;
60397
+ open.output = safeOutput || utils.escapeRegex(literal2);
60398
+ for (let i = token.tokensIndex + 1;i < tokens.length; i++) {
60399
+ tokens[i].value = "";
60400
+ tokens[i].output = "";
60401
+ delete tokens[i].suffix;
60402
+ }
60403
+ state.output = token.output + open.output;
60404
+ state.backtrack = true;
60405
+ push({ type: "paren", extglob: true, value, output: "" });
60406
+ decrement("parens");
60407
+ return;
60408
+ }
60165
60409
  let output = token.close + (opts.capture ? ")" : "");
60166
60410
  let rest2;
60167
60411
  if (token.type === "negate") {
@@ -60770,7 +61014,7 @@ var require_parse = __commonJS((exports, module) => {
60770
61014
  module.exports = parse5;
60771
61015
  });
60772
61016
 
60773
- // node_modules/picomatch/lib/picomatch.js
61017
+ // node_modules/tinyglobby/node_modules/picomatch/lib/picomatch.js
60774
61018
  var require_picomatch = __commonJS((exports, module) => {
60775
61019
  var scan = require_scan();
60776
61020
  var parse5 = require_parse();
@@ -60910,7 +61154,7 @@ var require_picomatch = __commonJS((exports, module) => {
60910
61154
  module.exports = picomatch;
60911
61155
  });
60912
61156
 
60913
- // node_modules/picomatch/index.js
61157
+ // node_modules/tinyglobby/node_modules/picomatch/index.js
60914
61158
  var require_picomatch2 = __commonJS((exports, module) => {
60915
61159
  var pico = require_picomatch();
60916
61160
  var utils = require_utils();
@@ -60925,20 +61169,20 @@ var require_picomatch2 = __commonJS((exports, module) => {
60925
61169
  });
60926
61170
 
60927
61171
  // node_modules/tinyglobby/dist/index.mjs
60928
- import nativeFs2 from "fs";
60929
- import path4, { posix } from "path";
61172
+ import { readdir, readdirSync, realpath, realpathSync, stat, statSync as statSync3 } from "fs";
61173
+ import { isAbsolute, posix, resolve as resolve2 } from "path";
60930
61174
  import { fileURLToPath } from "url";
60931
61175
  function getPartialMatcher(patterns, options = {}) {
60932
61176
  const patternsCount = patterns.length;
60933
61177
  const patternsParts = Array(patternsCount);
60934
61178
  const matchers = Array(patternsCount);
60935
- const globstarEnabled = !options.noglobstar;
60936
- for (let i = 0;i < patternsCount; i++) {
61179
+ let i, j;
61180
+ for (i = 0;i < patternsCount; i++) {
60937
61181
  const parts = splitPattern(patterns[i]);
60938
61182
  patternsParts[i] = parts;
60939
61183
  const partsCount = parts.length;
60940
61184
  const partMatchers = Array(partsCount);
60941
- for (let j = 0;j < partsCount; j++)
61185
+ for (j = 0;j < partsCount; j++)
60942
61186
  partMatchers[j] = import_picomatch.default(parts[j], options);
60943
61187
  matchers[i] = partMatchers;
60944
61188
  }
@@ -60946,20 +61190,19 @@ function getPartialMatcher(patterns, options = {}) {
60946
61190
  const inputParts = input.split("/");
60947
61191
  if (inputParts[0] === ".." && ONLY_PARENT_DIRECTORIES.test(input))
60948
61192
  return true;
60949
- for (let i = 0;i < patterns.length; i++) {
61193
+ for (i = 0;i < patternsCount; i++) {
60950
61194
  const patternParts = patternsParts[i];
60951
61195
  const matcher = matchers[i];
60952
61196
  const inputPatternCount = inputParts.length;
60953
61197
  const minParts = Math.min(inputPatternCount, patternParts.length);
60954
- let j = 0;
61198
+ j = 0;
60955
61199
  while (j < minParts) {
60956
61200
  const part = patternParts[j];
60957
61201
  if (part.includes("/"))
60958
61202
  return true;
60959
- const match = matcher[j](inputParts[j]);
60960
- if (!match)
61203
+ if (!matcher[j](inputParts[j]))
60961
61204
  break;
60962
- if (globstarEnabled && part === "**")
61205
+ if (!options.noglobstar && part === "**")
60963
61206
  return true;
60964
61207
  j++;
60965
61208
  }
@@ -60972,7 +61215,7 @@ function getPartialMatcher(patterns, options = {}) {
60972
61215
  function buildFormat(cwd2, root, absolute) {
60973
61216
  if (cwd2 === root || root.startsWith(`${cwd2}/`)) {
60974
61217
  if (absolute) {
60975
- const start = isRoot(cwd2) ? cwd2.length : cwd2.length + 1;
61218
+ const start = cwd2.length + +!isRoot(cwd2);
60976
61219
  return (p, isDir) => p.slice(start, isDir ? -1 : undefined) || ".";
60977
61220
  }
60978
61221
  const prefix = root.slice(cwd2.length + 1);
@@ -60996,15 +61239,13 @@ function buildRelative(cwd2, root) {
60996
61239
  }
60997
61240
  return (p) => {
60998
61241
  const result2 = posix.relative(cwd2, `${root}/${p}`);
60999
- if (p.endsWith("/") && result2 !== "")
61000
- return `${result2}/`;
61001
- return result2 || ".";
61242
+ return p[p.length - 1] === "/" && result2 !== "" ? `${result2}/` : result2 || ".";
61002
61243
  };
61003
61244
  }
61004
- function splitPattern(path$1) {
61245
+ function splitPattern(path4) {
61005
61246
  var _result$parts;
61006
- const result2 = import_picomatch.default.scan(path$1, splitPatternOptions);
61007
- return ((_result$parts = result2.parts) === null || _result$parts === undefined ? undefined : _result$parts.length) ? result2.parts : [path$1];
61247
+ const result2 = import_picomatch.default.scan(path4, splitPatternOptions);
61248
+ return ((_result$parts = result2.parts) === null || _result$parts === undefined ? undefined : _result$parts.length) ? result2.parts : [path4];
61008
61249
  }
61009
61250
  function isDynamicPattern(pattern, options) {
61010
61251
  if ((options === null || options === undefined ? undefined : options.caseSensitiveMatch) === false)
@@ -61015,29 +61256,31 @@ function isDynamicPattern(pattern, options) {
61015
61256
  function log(...tasks) {
61016
61257
  console.log(`[tinyglobby ${(/* @__PURE__ */ new Date()).toLocaleTimeString("es")}]`, ...tasks);
61017
61258
  }
61018
- function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
61259
+ function ensureStringArray(value) {
61260
+ return typeof value === "string" ? [value] : value !== null && value !== undefined ? value : [];
61261
+ }
61262
+ function normalizePattern(pattern, opts, props, isIgnore) {
61263
+ var _PARENT_DIRECTORY$exe;
61264
+ const cwd2 = opts.cwd;
61019
61265
  let result2 = pattern;
61020
- if (pattern.endsWith("/"))
61266
+ if (pattern[pattern.length - 1] === "/")
61021
61267
  result2 = pattern.slice(0, -1);
61022
- if (!result2.endsWith("*") && expandDirectories)
61268
+ if (result2[result2.length - 1] !== "*" && opts.expandDirectories)
61023
61269
  result2 += "/**";
61024
61270
  const escapedCwd = escapePath(cwd2);
61025
- if (path4.isAbsolute(result2.replace(ESCAPING_BACKSLASHES, "")))
61026
- result2 = posix.relative(escapedCwd, result2);
61027
- else
61028
- result2 = posix.normalize(result2);
61029
- const parentDirectoryMatch = PARENT_DIRECTORY.exec(result2);
61271
+ result2 = isAbsolute(result2.replace(ESCAPING_BACKSLASHES, "")) ? posix.relative(escapedCwd, result2) : posix.normalize(result2);
61272
+ const parentDir = (_PARENT_DIRECTORY$exe = PARENT_DIRECTORY.exec(result2)) === null || _PARENT_DIRECTORY$exe === undefined ? undefined : _PARENT_DIRECTORY$exe[0];
61030
61273
  const parts = splitPattern(result2);
61031
- if (parentDirectoryMatch === null || parentDirectoryMatch === undefined ? undefined : parentDirectoryMatch[0]) {
61032
- const n = (parentDirectoryMatch[0].length + 1) / 3;
61274
+ if (parentDir) {
61275
+ const n = (parentDir.length + 1) / 3;
61033
61276
  let i = 0;
61034
61277
  const cwdParts = escapedCwd.split("/");
61035
61278
  while (i < n && parts[i + n] === cwdParts[cwdParts.length + i - n]) {
61036
61279
  result2 = result2.slice(0, (n - i - 1) * 3) + result2.slice((n - i) * 3 + parts[i + n].length + 1) || ".";
61037
61280
  i++;
61038
61281
  }
61039
- const potentialRoot = posix.join(cwd2, parentDirectoryMatch[0].slice(i * 3));
61040
- if (!potentialRoot.startsWith(".") && props.root.length > potentialRoot.length) {
61282
+ const potentialRoot = posix.join(cwd2, parentDir.slice(i * 3));
61283
+ if (potentialRoot[0] !== "." && props.root.length > potentialRoot.length) {
61041
61284
  props.root = potentialRoot;
61042
61285
  props.depthOffset = -n + i;
61043
61286
  }
@@ -61053,7 +61296,7 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
61053
61296
  newCommonPath.pop();
61054
61297
  break;
61055
61298
  }
61056
- if (part !== props.commonPath[i] || isDynamicPattern(part) || i === parts.length - 1)
61299
+ if (i === parts.length - 1 || part !== props.commonPath[i] || isDynamicPattern(part))
61057
61300
  break;
61058
61301
  newCommonPath.push(part);
61059
61302
  }
@@ -61063,162 +61306,138 @@ function normalizePattern(pattern, expandDirectories, cwd2, props, isIgnore) {
61063
61306
  }
61064
61307
  return result2;
61065
61308
  }
61066
- function processPatterns({ patterns = ["**/*"], ignore = [], expandDirectories = true }, cwd2, props) {
61067
- if (typeof patterns === "string")
61068
- patterns = [patterns];
61069
- if (typeof ignore === "string")
61070
- ignore = [ignore];
61309
+ function processPatterns(options, patterns, props) {
61071
61310
  const matchPatterns = [];
61072
61311
  const ignorePatterns = [];
61073
- for (const pattern of ignore) {
61312
+ for (const pattern of options.ignore) {
61074
61313
  if (!pattern)
61075
61314
  continue;
61076
61315
  if (pattern[0] !== "!" || pattern[1] === "(")
61077
- ignorePatterns.push(normalizePattern(pattern, expandDirectories, cwd2, props, true));
61316
+ ignorePatterns.push(normalizePattern(pattern, options, props, true));
61078
61317
  }
61079
61318
  for (const pattern of patterns) {
61080
61319
  if (!pattern)
61081
61320
  continue;
61082
61321
  if (pattern[0] !== "!" || pattern[1] === "(")
61083
- matchPatterns.push(normalizePattern(pattern, expandDirectories, cwd2, props, false));
61322
+ matchPatterns.push(normalizePattern(pattern, options, props, false));
61084
61323
  else if (pattern[1] !== "!" || pattern[2] === "(")
61085
- ignorePatterns.push(normalizePattern(pattern.slice(1), expandDirectories, cwd2, props, true));
61324
+ ignorePatterns.push(normalizePattern(pattern.slice(1), options, props, true));
61086
61325
  }
61087
61326
  return {
61088
61327
  match: matchPatterns,
61089
61328
  ignore: ignorePatterns
61090
61329
  };
61091
61330
  }
61092
- function formatPaths(paths, relative2) {
61093
- for (let i = paths.length - 1;i >= 0; i--) {
61094
- const path$1 = paths[i];
61095
- paths[i] = relative2(path$1);
61096
- }
61097
- return paths;
61098
- }
61099
- function normalizeCwd(cwd2) {
61100
- if (!cwd2)
61101
- return process.cwd().replace(BACKSLASHES, "/");
61102
- if (cwd2 instanceof URL)
61103
- return fileURLToPath(cwd2).replace(BACKSLASHES, "/");
61104
- return path4.resolve(cwd2).replace(BACKSLASHES, "/");
61105
- }
61106
- function getCrawler(patterns, inputOptions = {}) {
61107
- const options = process.env.TINYGLOBBY_DEBUG ? {
61108
- ...inputOptions,
61109
- debug: true
61110
- } : inputOptions;
61111
- const cwd2 = normalizeCwd(options.cwd);
61112
- if (options.debug)
61113
- log("globbing with:", {
61114
- patterns,
61115
- options,
61116
- cwd: cwd2
61117
- });
61118
- if (Array.isArray(patterns) && patterns.length === 0)
61119
- return [{
61120
- sync: () => [],
61121
- withPromise: async () => []
61122
- }, false];
61331
+ function buildCrawler(options, patterns) {
61332
+ const cwd2 = options.cwd;
61123
61333
  const props = {
61124
61334
  root: cwd2,
61125
- commonPath: null,
61126
61335
  depthOffset: 0
61127
61336
  };
61128
- const processed = processPatterns({
61129
- ...options,
61130
- patterns
61131
- }, cwd2, props);
61337
+ const processed = processPatterns(options, patterns, props);
61132
61338
  if (options.debug)
61133
61339
  log("internal processing patterns:", processed);
61340
+ const { absolute, caseSensitiveMatch, debug: debug3, dot, followSymbolicLinks, onlyDirectories } = options;
61341
+ const root = props.root.replace(BACKSLASHES, "");
61134
61342
  const matchOptions = {
61135
- dot: options.dot,
61343
+ dot,
61136
61344
  nobrace: options.braceExpansion === false,
61137
- nocase: options.caseSensitiveMatch === false,
61345
+ nocase: !caseSensitiveMatch,
61138
61346
  noextglob: options.extglob === false,
61139
61347
  noglobstar: options.globstar === false,
61140
61348
  posix: true
61141
61349
  };
61142
- const matcher = import_picomatch.default(processed.match, {
61143
- ...matchOptions,
61144
- ignore: processed.ignore
61145
- });
61350
+ const matcher = import_picomatch.default(processed.match, matchOptions);
61146
61351
  const ignore = import_picomatch.default(processed.ignore, matchOptions);
61147
61352
  const partialMatcher = getPartialMatcher(processed.match, matchOptions);
61148
- const format = buildFormat(cwd2, props.root, options.absolute);
61149
- const formatExclude = options.absolute ? format : buildFormat(cwd2, props.root, true);
61150
- const fdirOptions = {
61151
- filters: [options.debug ? (p, isDirectory) => {
61152
- const path$1 = format(p, isDirectory);
61153
- const matches2 = matcher(path$1);
61353
+ const format = buildFormat(cwd2, root, absolute);
61354
+ const excludeFormatter = absolute ? format : buildFormat(cwd2, root, true);
61355
+ const excludePredicate = (_, p) => {
61356
+ const relativePath = excludeFormatter(p, true);
61357
+ return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
61358
+ };
61359
+ let maxDepth;
61360
+ if (options.deep !== undefined)
61361
+ maxDepth = Math.round(options.deep - props.depthOffset);
61362
+ const crawler = new Builder({
61363
+ filters: [debug3 ? (p, isDirectory) => {
61364
+ const path4 = format(p, isDirectory);
61365
+ const matches2 = matcher(path4) && !ignore(path4);
61154
61366
  if (matches2)
61155
- log(`matched ${path$1}`);
61367
+ log(`matched ${path4}`);
61156
61368
  return matches2;
61157
- } : (p, isDirectory) => matcher(format(p, isDirectory))],
61158
- exclude: options.debug ? (_, p) => {
61159
- const relativePath = formatExclude(p, true);
61160
- const skipped = relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
61161
- if (skipped)
61162
- log(`skipped ${p}`);
61163
- else
61164
- log(`crawling ${p}`);
61369
+ } : (p, isDirectory) => {
61370
+ const path4 = format(p, isDirectory);
61371
+ return matcher(path4) && !ignore(path4);
61372
+ }],
61373
+ exclude: debug3 ? (_, p) => {
61374
+ const skipped = excludePredicate(_, p);
61375
+ log(`${skipped ? "skipped" : "crawling"} ${p}`);
61165
61376
  return skipped;
61166
- } : (_, p) => {
61167
- const relativePath = formatExclude(p, true);
61168
- return relativePath !== "." && !partialMatcher(relativePath) || ignore(relativePath);
61169
- },
61170
- fs: options.fs ? {
61171
- readdir: options.fs.readdir || nativeFs2.readdir,
61172
- readdirSync: options.fs.readdirSync || nativeFs2.readdirSync,
61173
- realpath: options.fs.realpath || nativeFs2.realpath,
61174
- realpathSync: options.fs.realpathSync || nativeFs2.realpathSync,
61175
- stat: options.fs.stat || nativeFs2.stat,
61176
- statSync: options.fs.statSync || nativeFs2.statSync
61177
- } : undefined,
61377
+ } : excludePredicate,
61378
+ fs: options.fs,
61178
61379
  pathSeparator: "/",
61179
- relativePaths: true,
61180
- resolveSymlinks: true,
61380
+ relativePaths: !absolute,
61381
+ resolvePaths: absolute,
61382
+ includeBasePath: absolute,
61383
+ resolveSymlinks: followSymbolicLinks,
61384
+ excludeSymlinks: !followSymbolicLinks,
61385
+ excludeFiles: onlyDirectories,
61386
+ includeDirs: onlyDirectories || !options.onlyFiles,
61387
+ maxDepth,
61181
61388
  signal: options.signal
61182
- };
61183
- if (options.deep !== undefined)
61184
- fdirOptions.maxDepth = Math.round(options.deep - props.depthOffset);
61185
- if (options.absolute) {
61186
- fdirOptions.relativePaths = false;
61187
- fdirOptions.resolvePaths = true;
61188
- fdirOptions.includeBasePath = true;
61189
- }
61190
- if (options.followSymbolicLinks === false) {
61191
- fdirOptions.resolveSymlinks = false;
61192
- fdirOptions.excludeSymlinks = true;
61193
- }
61194
- if (options.onlyDirectories) {
61195
- fdirOptions.excludeFiles = true;
61196
- fdirOptions.includeDirs = true;
61197
- } else if (options.onlyFiles === false)
61198
- fdirOptions.includeDirs = true;
61199
- props.root = props.root.replace(BACKSLASHES, "");
61200
- const root = props.root;
61389
+ }).crawl(root);
61201
61390
  if (options.debug)
61202
- log("internal properties:", props);
61203
- const relative2 = cwd2 !== root && !options.absolute && buildRelative(cwd2, props.root);
61204
- return [new Builder(fdirOptions).crawl(root), relative2];
61391
+ log("internal properties:", {
61392
+ ...props,
61393
+ root
61394
+ });
61395
+ return [crawler, cwd2 !== root && !absolute && buildRelative(cwd2, root)];
61396
+ }
61397
+ function formatPaths(paths, mapper) {
61398
+ if (mapper)
61399
+ for (let i = paths.length - 1;i >= 0; i--)
61400
+ paths[i] = mapper(paths[i]);
61401
+ return paths;
61205
61402
  }
61206
- function globSync(patternsOrOptions, options) {
61207
- if (patternsOrOptions && (options === null || options === undefined ? undefined : options.patterns))
61403
+ function getOptions2(options) {
61404
+ const opts = {
61405
+ ...defaultOptions,
61406
+ ...options
61407
+ };
61408
+ opts.cwd = (opts.cwd instanceof URL ? fileURLToPath(opts.cwd) : resolve2(opts.cwd)).replace(BACKSLASHES, "/");
61409
+ opts.ignore = ensureStringArray(opts.ignore);
61410
+ opts.fs && (opts.fs = {
61411
+ readdir: opts.fs.readdir || readdir,
61412
+ readdirSync: opts.fs.readdirSync || readdirSync,
61413
+ realpath: opts.fs.realpath || realpath,
61414
+ realpathSync: opts.fs.realpathSync || realpathSync,
61415
+ stat: opts.fs.stat || stat,
61416
+ statSync: opts.fs.statSync || statSync3
61417
+ });
61418
+ if (opts.debug)
61419
+ log("globbing with options:", opts);
61420
+ return opts;
61421
+ }
61422
+ function getCrawler(globInput, inputOptions = {}) {
61423
+ var _ref;
61424
+ if (globInput && (inputOptions === null || inputOptions === undefined ? undefined : inputOptions.patterns))
61208
61425
  throw new Error("Cannot pass patterns as both an argument and an option");
61209
- const isModern = isReadonlyArray(patternsOrOptions) || typeof patternsOrOptions === "string";
61210
- const opts = isModern ? options : patternsOrOptions;
61211
- const patterns = isModern ? patternsOrOptions : patternsOrOptions.patterns;
61212
- const [crawler, relative2] = getCrawler(patterns, opts);
61213
- if (!relative2)
61214
- return crawler.sync();
61215
- return formatPaths(crawler.sync(), relative2);
61216
- }
61217
- var import_picomatch, isReadonlyArray, isWin, ONLY_PARENT_DIRECTORIES, WIN32_ROOT_DIR, isRoot, splitPatternOptions, POSIX_UNESCAPED_GLOB_SYMBOLS, WIN32_UNESCAPED_GLOB_SYMBOLS, escapePosixPath = (path$1) => path$1.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, "\\$&"), escapeWin32Path = (path$1) => path$1.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, "\\$&"), escapePath, PARENT_DIRECTORY, ESCAPING_BACKSLASHES, BACKSLASHES;
61218
- var init_dist5 = __esm(() => {
61219
- init_dist4();
61426
+ const isModern = isReadonlyArray(globInput) || typeof globInput === "string";
61427
+ const patterns = ensureStringArray((_ref = isModern ? globInput : globInput.patterns) !== null && _ref !== undefined ? _ref : "**/*");
61428
+ const options = getOptions2(isModern ? inputOptions : globInput);
61429
+ return patterns.length > 0 ? buildCrawler(options, patterns) : [];
61430
+ }
61431
+ function globSync(globInput, options) {
61432
+ const [crawler, relative2] = getCrawler(globInput, options);
61433
+ return crawler ? formatPaths(crawler.sync(), relative2) : [];
61434
+ }
61435
+ 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;
61436
+ var init_dist7 = __esm(() => {
61437
+ init_dist6();
61220
61438
  import_picomatch = __toESM(require_picomatch2(), 1);
61221
61439
  isReadonlyArray = Array.isArray;
61440
+ BACKSLASHES = /\\/g;
61222
61441
  isWin = process.platform === "win32";
61223
61442
  ONLY_PARENT_DIRECTORIES = /^(\/?\.\.)+$/;
61224
61443
  WIN32_ROOT_DIR = /^[A-Z]:\/$/i;
@@ -61229,7 +61448,14 @@ var init_dist5 = __esm(() => {
61229
61448
  escapePath = isWin ? escapeWin32Path : escapePosixPath;
61230
61449
  PARENT_DIRECTORY = /^(\/?\.\.)+/;
61231
61450
  ESCAPING_BACKSLASHES = /\\(?=[()[\]{}!*+?@|])/g;
61232
- BACKSLASHES = /\\/g;
61451
+ defaultOptions = {
61452
+ caseSensitiveMatch: true,
61453
+ cwd: process.cwd(),
61454
+ debug: !!process.env.TINYGLOBBY_DEBUG,
61455
+ expandDirectories: true,
61456
+ followSymbolicLinks: true,
61457
+ onlyFiles: true
61458
+ };
61233
61459
  });
61234
61460
 
61235
61461
  // src/utils/jsonl-lines.ts
@@ -61262,7 +61488,7 @@ var init_jsonl_lines = __esm(() => {
61262
61488
 
61263
61489
  // src/utils/jsonl-blocks.ts
61264
61490
  import * as fs5 from "fs";
61265
- import path5 from "node:path";
61491
+ import path4 from "node:path";
61266
61492
  function getBlockMetrics() {
61267
61493
  const claudeDir = getClaudeConfigDir();
61268
61494
  if (!claudeDir)
@@ -61276,7 +61502,7 @@ function getBlockMetrics() {
61276
61502
  function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
61277
61503
  const sessionDurationMs = sessionDurationHours * 60 * 60 * 1000;
61278
61504
  const now2 = new Date;
61279
- const pattern = path5.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
61505
+ const pattern = path4.posix.join(rootDir.replace(/\\/g, "/"), "projects", "**", "*.jsonl");
61280
61506
  const files = globSync([pattern], {
61281
61507
  absolute: true,
61282
61508
  cwd: rootDir
@@ -61284,7 +61510,7 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
61284
61510
  if (files.length === 0)
61285
61511
  return null;
61286
61512
  const filesWithStats = files.map((file2) => {
61287
- const stats = statSync4(file2);
61513
+ const stats = statSync5(file2);
61288
61514
  return { file: file2, mtime: stats.mtime };
61289
61515
  });
61290
61516
  filesWithStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
@@ -61402,26 +61628,26 @@ function floorToHour(timestamp) {
61402
61628
  floored.setUTCMinutes(0, 0, 0);
61403
61629
  return floored;
61404
61630
  }
61405
- var statSync4;
61406
- var init_jsonl_blocks = __esm(() => {
61407
- init_dist5();
61408
- init_claude_settings();
61631
+ var statSync5;
61632
+ var init_jsonl_blocks = __esm(async () => {
61633
+ init_dist7();
61409
61634
  init_jsonl_lines();
61410
- statSync4 = fs5.statSync;
61635
+ await init_claude_settings();
61636
+ statSync5 = fs5.statSync;
61411
61637
  });
61412
61638
 
61413
61639
  // src/utils/jsonl-cache.ts
61414
61640
  import * as fs6 from "fs";
61415
61641
  import { createHash as createHash2 } from "node:crypto";
61416
61642
  import os5 from "node:os";
61417
- import path6 from "node:path";
61643
+ import path5 from "node:path";
61418
61644
  function normalizeConfigDir(configDir) {
61419
- return path6.resolve(configDir);
61645
+ return path5.resolve(configDir);
61420
61646
  }
61421
61647
  function getBlockCachePath(configDir = getClaudeConfigDir()) {
61422
61648
  const normalizedConfigDir = normalizeConfigDir(configDir);
61423
61649
  const configHash = createHash2("sha256").update(normalizedConfigDir).digest("hex").slice(0, 16);
61424
- return path6.join(os5.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
61650
+ return path5.join(os5.homedir(), ".cache", "ccstatusline", `block-cache-${configHash}.json`);
61425
61651
  }
61426
61652
  function readBlockCache(expectedConfigDir) {
61427
61653
  try {
@@ -61456,7 +61682,7 @@ function writeBlockCache(startTime, configDir = getClaudeConfigDir()) {
61456
61682
  try {
61457
61683
  const normalizedConfigDir = normalizeConfigDir(configDir);
61458
61684
  const cachePath = getBlockCachePath(normalizedConfigDir);
61459
- const cacheDir = path6.dirname(cachePath);
61685
+ const cacheDir = path5.dirname(cachePath);
61460
61686
  if (!existsSync6(cacheDir)) {
61461
61687
  mkdirSync4(cacheDir, { recursive: true });
61462
61688
  }
@@ -61488,9 +61714,11 @@ function getCachedBlockMetrics(sessionDurationHours = 5) {
61488
61714
  return metrics;
61489
61715
  }
61490
61716
  var readFileSync8, writeFileSync4, mkdirSync4, existsSync6;
61491
- var init_jsonl_cache = __esm(() => {
61492
- init_claude_settings();
61493
- init_jsonl_blocks();
61717
+ var init_jsonl_cache = __esm(async () => {
61718
+ await __promiseAll([
61719
+ init_claude_settings(),
61720
+ init_jsonl_blocks()
61721
+ ]);
61494
61722
  readFileSync8 = fs6.readFileSync;
61495
61723
  writeFileSync4 = fs6.writeFileSync;
61496
61724
  mkdirSync4 = fs6.mkdirSync;
@@ -61499,7 +61727,7 @@ var init_jsonl_cache = __esm(() => {
61499
61727
 
61500
61728
  // src/utils/jsonl-metrics.ts
61501
61729
  import * as fs7 from "fs";
61502
- import path7 from "node:path";
61730
+ import path6 from "node:path";
61503
61731
  function collectAgentIds(value, agentIds) {
61504
61732
  if (!value || typeof value !== "object") {
61505
61733
  return;
@@ -61591,19 +61819,35 @@ async function getTokenMetrics(transcriptPath) {
61591
61819
  let contextLength = 0;
61592
61820
  let mostRecentMainChainEntry = null;
61593
61821
  let mostRecentTimestamp = null;
61822
+ const parsedEntries = [];
61823
+ let hasStopReasonField = false;
61594
61824
  for (const line of lines) {
61595
61825
  const data = parseJsonlLine(line);
61596
61826
  if (data?.message?.usage) {
61597
- inputTokens += data.message.usage.input_tokens || 0;
61598
- outputTokens += data.message.usage.output_tokens || 0;
61599
- cachedTokens += data.message.usage.cache_read_input_tokens ?? 0;
61600
- cachedTokens += data.message.usage.cache_creation_input_tokens ?? 0;
61601
- if (data.isSidechain !== true && data.timestamp && !data.isApiErrorMessage) {
61602
- const entryTime = new Date(data.timestamp);
61603
- if (!mostRecentTimestamp || entryTime > mostRecentTimestamp) {
61604
- mostRecentTimestamp = entryTime;
61605
- mostRecentMainChainEntry = data;
61606
- }
61827
+ parsedEntries.push(data);
61828
+ if (Object.hasOwn(data.message, "stop_reason")) {
61829
+ hasStopReasonField = true;
61830
+ }
61831
+ }
61832
+ }
61833
+ const entriesToCount = hasStopReasonField ? parsedEntries.filter((data, index) => {
61834
+ const stopReason = data.message?.stop_reason;
61835
+ return Boolean(stopReason) || stopReason === null && index === parsedEntries.length - 1;
61836
+ }) : parsedEntries;
61837
+ for (const data of entriesToCount) {
61838
+ const usage = data.message?.usage;
61839
+ if (!usage) {
61840
+ continue;
61841
+ }
61842
+ inputTokens += usage.input_tokens || 0;
61843
+ outputTokens += usage.output_tokens || 0;
61844
+ cachedTokens += usage.cache_read_input_tokens ?? 0;
61845
+ cachedTokens += usage.cache_creation_input_tokens ?? 0;
61846
+ if (data.isSidechain !== true && data.timestamp && !data.isApiErrorMessage) {
61847
+ const entryTime = new Date(data.timestamp);
61848
+ if (!mostRecentTimestamp || entryTime > mostRecentTimestamp) {
61849
+ mostRecentTimestamp = entryTime;
61850
+ mostRecentMainChainEntry = data;
61607
61851
  }
61608
61852
  }
61609
61853
  }
@@ -61779,11 +62023,11 @@ function getSubagentTranscriptPaths(transcriptPath, referencedAgentIds) {
61779
62023
  if (referencedAgentIds.size === 0) {
61780
62024
  return [];
61781
62025
  }
61782
- const transcriptDir = path7.dirname(transcriptPath);
61783
- const transcriptStem = path7.parse(transcriptPath).name;
62026
+ const transcriptDir = path6.dirname(transcriptPath);
62027
+ const transcriptStem = path6.parse(transcriptPath).name;
61784
62028
  const candidateDirs = [
61785
- path7.join(transcriptDir, "subagents"),
61786
- path7.join(transcriptDir, transcriptStem, "subagents")
62029
+ path6.join(transcriptDir, "subagents"),
62030
+ path6.join(transcriptDir, transcriptStem, "subagents")
61787
62031
  ];
61788
62032
  const seenPaths = new Set;
61789
62033
  const matchedPaths = [];
@@ -61804,7 +62048,7 @@ function getSubagentTranscriptPaths(transcriptPath, referencedAgentIds) {
61804
62048
  if (!referencedAgentIds.has(match[1])) {
61805
62049
  continue;
61806
62050
  }
61807
- const fullPath = path7.join(subagentsDir, entry.name);
62051
+ const fullPath = path6.join(subagentsDir, entry.name);
61808
62052
  if (seenPaths.has(fullPath)) {
61809
62053
  continue;
61810
62054
  }
@@ -61875,8 +62119,11 @@ function normalizeThinkingEffort(value) {
61875
62119
  return;
61876
62120
  }
61877
62121
  const normalized = value.toLowerCase();
61878
- if (normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "max") {
61879
- return normalized;
62122
+ if (KNOWN_THINKING_EFFORTS_SET.has(normalized)) {
62123
+ return { value: normalized, known: true };
62124
+ }
62125
+ if (UNKNOWN_EFFORT_PATTERN.test(normalized)) {
62126
+ return { value: normalized, known: false };
61880
62127
  }
61881
62128
  return;
61882
62129
  }
@@ -61907,19 +62154,24 @@ function getTranscriptThinkingEffort(transcriptPath) {
61907
62154
  }
61908
62155
  return;
61909
62156
  }
61910
- var MODEL_STDOUT_PREFIX = "<local-command-stdout>Set model to ", MODEL_STDOUT_EFFORT_REGEX;
62157
+ var KNOWN_THINKING_EFFORTS, KNOWN_THINKING_EFFORTS_SET, MODEL_STDOUT_PREFIX = "<local-command-stdout>Set model to ", MODEL_STDOUT_EFFORT_REGEX, UNKNOWN_EFFORT_PATTERN;
61911
62158
  var init_jsonl_metadata = __esm(() => {
61912
62159
  init_ansi();
61913
62160
  init_jsonl_lines();
61914
- MODEL_STDOUT_EFFORT_REGEX = /^<local-command-stdout>Set model to[\s\S]*? with (low|medium|high|max) effort<\/local-command-stdout>$/i;
62161
+ KNOWN_THINKING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
62162
+ KNOWN_THINKING_EFFORTS_SET = new Set(KNOWN_THINKING_EFFORTS);
62163
+ MODEL_STDOUT_EFFORT_REGEX = /^<local-command-stdout>Set model to[\s\S]*? with ([a-zA-Z0-9-]+) effort<\/local-command-stdout>$/i;
62164
+ UNKNOWN_EFFORT_PATTERN = /^(?=.*[a-z0-9])[a-z0-9-]{2,20}$/;
61915
62165
  });
61916
62166
 
61917
62167
  // src/utils/jsonl.ts
61918
- var init_jsonl = __esm(() => {
61919
- init_jsonl_cache();
61920
- init_jsonl_blocks();
62168
+ var init_jsonl = __esm(async () => {
61921
62169
  init_jsonl_metrics();
61922
62170
  init_jsonl_metadata();
62171
+ await __promiseAll([
62172
+ init_jsonl_cache(),
62173
+ init_jsonl_blocks()
62174
+ ]);
61923
62175
  });
61924
62176
 
61925
62177
  // src/utils/usage-windows.ts
@@ -62013,16 +62265,18 @@ function makeUsageProgressBar(percent, width = 15) {
62013
62265
  const empty2 = width - filled;
62014
62266
  return "[" + "█".repeat(filled) + "░".repeat(empty2) + "]";
62015
62267
  }
62016
- var init_usage_windows = __esm(() => {
62017
- init_jsonl();
62268
+ var init_usage_windows = __esm(async () => {
62018
62269
  init_usage_types();
62270
+ await init_jsonl();
62019
62271
  });
62020
62272
 
62021
62273
  // src/utils/usage.ts
62022
- var init_usage = __esm(() => {
62023
- init_usage_fetch();
62024
- init_usage_windows();
62274
+ var init_usage = __esm(async () => {
62025
62275
  init_usage_types();
62276
+ await __promiseAll([
62277
+ init_usage_fetch(),
62278
+ init_usage_windows()
62279
+ ]);
62026
62280
  });
62027
62281
 
62028
62282
  // src/widgets/shared/usage-display.ts
@@ -62185,9 +62439,9 @@ class BlockTimerWidget {
62185
62439
  return true;
62186
62440
  }
62187
62441
  }
62188
- var init_BlockTimer = __esm(() => {
62189
- init_usage();
62442
+ var init_BlockTimer = __esm(async () => {
62190
62443
  init_usage_display();
62444
+ await init_usage();
62191
62445
  });
62192
62446
 
62193
62447
  // src/widgets/CurrentWorkingDir.tsx
@@ -62336,27 +62590,27 @@ class CurrentWorkingDirWidget {
62336
62590
  supportsColors(item) {
62337
62591
  return true;
62338
62592
  }
62339
- abbreviateHomeDir(path8) {
62593
+ abbreviateHomeDir(path7) {
62340
62594
  const homeDir = os6.homedir();
62341
- if (path8 === homeDir) {
62595
+ if (path7 === homeDir) {
62342
62596
  return "~";
62343
62597
  }
62344
- if (path8.startsWith(homeDir)) {
62345
- const boundaryChar = path8[homeDir.length];
62598
+ if (path7.startsWith(homeDir)) {
62599
+ const boundaryChar = path7[homeDir.length];
62346
62600
  if (boundaryChar !== "/" && boundaryChar !== "\\") {
62347
- return path8;
62601
+ return path7;
62348
62602
  }
62349
- return "~" + path8.slice(homeDir.length);
62603
+ return "~" + path7.slice(homeDir.length);
62350
62604
  }
62351
- return path8;
62605
+ return path7;
62352
62606
  }
62353
- abbreviatePath(path8) {
62607
+ abbreviatePath(path7) {
62354
62608
  const homeDir = os6.homedir();
62355
- const useBackslash = path8.includes("\\") && !path8.includes("/");
62609
+ const useBackslash = path7.includes("\\") && !path7.includes("/");
62356
62610
  const sep2 = useBackslash ? "\\" : "/";
62357
- let normalizedPath = path8;
62358
- if (path8.startsWith(homeDir)) {
62359
- normalizedPath = "~" + path8.slice(homeDir.length);
62611
+ let normalizedPath = path7;
62612
+ if (path7.startsWith(homeDir)) {
62613
+ normalizedPath = "~" + path7.slice(homeDir.length);
62360
62614
  }
62361
62615
  const parts = normalizedPath.split(/[\\/]+/).filter((part) => part !== "");
62362
62616
  const abbreviated = parts.map((part, index) => {
@@ -62482,7 +62736,6 @@ class ClaudeSessionIdWidget {
62482
62736
 
62483
62737
  // src/widgets/ClaudeAccountEmail.ts
62484
62738
  import * as fs8 from "fs";
62485
- import * as path8 from "path";
62486
62739
 
62487
62740
  class ClaudeAccountEmailWidget {
62488
62741
  getDefaultColor() {
@@ -62505,16 +62758,10 @@ class ClaudeAccountEmailWidget {
62505
62758
  return item.rawValue ? "you@example.com" : "Account: you@example.com";
62506
62759
  }
62507
62760
  try {
62508
- const configDir = getClaudeConfigDir();
62509
- const claudeJsonPath = path8.join(configDir, "..", ".claude.json");
62510
- const resolved = path8.resolve(claudeJsonPath);
62511
- if (!fs8.existsSync(resolved)) {
62512
- return null;
62513
- }
62514
- const content = fs8.readFileSync(resolved, "utf-8");
62761
+ const content = fs8.readFileSync(getClaudeJsonPath(), "utf-8");
62515
62762
  const data = JSON.parse(content);
62516
62763
  const email3 = data.oauthAccount?.emailAddress;
62517
- if (!email3) {
62764
+ if (typeof email3 !== "string" || email3.length === 0) {
62518
62765
  return null;
62519
62766
  }
62520
62767
  return item.rawValue ? email3 : `Account: ${email3}`;
@@ -62529,8 +62776,8 @@ class ClaudeAccountEmailWidget {
62529
62776
  return true;
62530
62777
  }
62531
62778
  }
62532
- var init_ClaudeAccountEmail = __esm(() => {
62533
- init_claude_settings();
62779
+ var init_ClaudeAccountEmail = __esm(async () => {
62780
+ await init_claude_settings();
62534
62781
  });
62535
62782
 
62536
62783
  // src/utils/speed-metrics.ts
@@ -62864,7 +63111,7 @@ var init_TotalSpeed = __esm(async () => {
62864
63111
  });
62865
63112
 
62866
63113
  // src/widgets/FreeMemory.ts
62867
- import { execSync as execSync4 } from "child_process";
63114
+ import { execSync as execSync3 } from "child_process";
62868
63115
  import os7 from "os";
62869
63116
  function formatBytes(bytes) {
62870
63117
  const GB = 1024 ** 3;
@@ -62880,7 +63127,7 @@ function formatBytes(bytes) {
62880
63127
  }
62881
63128
  function getUsedMemoryMacOS() {
62882
63129
  try {
62883
- const output = execSync4("vm_stat", { encoding: "utf8" });
63130
+ const output = execSync3("vm_stat", { encoding: "utf8" });
62884
63131
  const lines = output.split(`
62885
63132
  `);
62886
63133
  const firstLine = lines[0];
@@ -63068,9 +63315,9 @@ class SessionUsageWidget {
63068
63315
  return true;
63069
63316
  }
63070
63317
  }
63071
- var init_SessionUsage = __esm(() => {
63072
- init_usage();
63318
+ var init_SessionUsage = __esm(async () => {
63073
63319
  init_usage_display();
63320
+ await init_usage();
63074
63321
  });
63075
63322
 
63076
63323
  // src/widgets/WeeklyUsage.ts
@@ -63139,9 +63386,9 @@ class WeeklyUsageWidget {
63139
63386
  return true;
63140
63387
  }
63141
63388
  }
63142
- var init_WeeklyUsage = __esm(() => {
63143
- init_usage();
63389
+ var init_WeeklyUsage = __esm(async () => {
63144
63390
  init_usage_display();
63391
+ await init_usage();
63145
63392
  });
63146
63393
 
63147
63394
  // src/widgets/BlockResetTimer.ts
@@ -63224,9 +63471,9 @@ class BlockResetTimerWidget {
63224
63471
  return true;
63225
63472
  }
63226
63473
  }
63227
- var init_BlockResetTimer = __esm(() => {
63228
- init_usage();
63474
+ var init_BlockResetTimer = __esm(async () => {
63229
63475
  init_usage_display();
63476
+ await init_usage();
63230
63477
  });
63231
63478
 
63232
63479
  // src/widgets/WeeklyResetTimer.ts
@@ -63345,9 +63592,9 @@ class WeeklyResetTimerWidget {
63345
63592
  }
63346
63593
  }
63347
63594
  var WEEKLY_PREVIEW_DURATION_MS;
63348
- var init_WeeklyResetTimer = __esm(() => {
63349
- init_usage();
63595
+ var init_WeeklyResetTimer = __esm(async () => {
63350
63596
  init_usage_display();
63597
+ await init_usage();
63351
63598
  WEEKLY_PREVIEW_DURATION_MS = 36.5 * 60 * 60 * 1000;
63352
63599
  });
63353
63600
 
@@ -63433,8 +63680,8 @@ class ContextBarWidget {
63433
63680
  return true;
63434
63681
  }
63435
63682
  }
63436
- var init_ContextBar = __esm(() => {
63437
- init_usage();
63683
+ var init_ContextBar = __esm(async () => {
63684
+ await init_usage();
63438
63685
  });
63439
63686
 
63440
63687
  // src/widgets/Link.tsx
@@ -63831,25 +64078,21 @@ var init_Skills = __esm(async () => {
63831
64078
  });
63832
64079
 
63833
64080
  // src/widgets/ThinkingEffort.ts
63834
- function normalizeThinkingEffort2(value) {
63835
- if (!value) {
63836
- return;
63837
- }
63838
- const normalized = value.toLowerCase();
63839
- if (normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "max") {
63840
- return normalized;
63841
- }
63842
- return;
63843
- }
63844
64081
  function resolveThinkingEffortFromSettings() {
63845
64082
  try {
63846
64083
  const settings = loadClaudeSettingsSync({ logErrors: false });
63847
- return normalizeThinkingEffort2(settings.effortLevel);
64084
+ return normalizeThinkingEffort(settings.effortLevel);
63848
64085
  } catch {}
63849
64086
  return;
63850
64087
  }
63851
64088
  function resolveThinkingEffort(context) {
63852
- return getTranscriptThinkingEffort(context.data?.transcript_path) ?? resolveThinkingEffortFromSettings() ?? "medium";
64089
+ return getTranscriptThinkingEffort(context.data?.transcript_path) ?? resolveThinkingEffortFromSettings() ?? null;
64090
+ }
64091
+ function formatEffort(resolved) {
64092
+ if (!resolved) {
64093
+ return "default";
64094
+ }
64095
+ return resolved.known ? resolved.value : `${resolved.value}?`;
63853
64096
  }
63854
64097
 
63855
64098
  class ThinkingEffortWidget {
@@ -63857,7 +64100,8 @@ class ThinkingEffortWidget {
63857
64100
  return "magenta";
63858
64101
  }
63859
64102
  getDescription() {
63860
- return `Displays the current thinking effort level (low, medium, high, max).
64103
+ return `Displays the current thinking effort level (low, medium, high, xhigh, max).
64104
+ Unknown levels are shown with a trailing "?" (e.g. "super-max?").
63861
64105
  May be incorrect when multiple Claude Code sessions are running due to current Claude Code limitations.`;
63862
64106
  }
63863
64107
  getDisplayName() {
@@ -63873,7 +64117,7 @@ May be incorrect when multiple Claude Code sessions are running due to current C
63873
64117
  if (context.isPreview) {
63874
64118
  return item.rawValue ? "high" : "Thinking: high";
63875
64119
  }
63876
- const effort = resolveThinkingEffort(context);
64120
+ const effort = formatEffort(resolveThinkingEffort(context));
63877
64121
  return item.rawValue ? effort : `Thinking: ${effort}`;
63878
64122
  }
63879
64123
  supportsRawValue() {
@@ -63883,9 +64127,11 @@ May be incorrect when multiple Claude Code sessions are running due to current C
63883
64127
  return true;
63884
64128
  }
63885
64129
  }
63886
- var init_ThinkingEffort = __esm(() => {
63887
- init_claude_settings();
63888
- init_jsonl();
64130
+ var init_ThinkingEffort = __esm(async () => {
64131
+ await __promiseAll([
64132
+ init_claude_settings(),
64133
+ init_jsonl()
64134
+ ]);
63889
64135
  });
63890
64136
 
63891
64137
  // src/widgets/VimMode.ts
@@ -64164,16 +64410,8 @@ var init_widgets = __esm(async () => {
64164
64410
  init_ContextPercentage();
64165
64411
  init_ContextPercentageUsable();
64166
64412
  init_TerminalWidth();
64167
- init_BlockTimer();
64168
- init_ClaudeAccountEmail();
64169
64413
  init_FreeMemory();
64170
64414
  init_SessionName();
64171
- init_SessionUsage();
64172
- init_WeeklyUsage();
64173
- init_BlockResetTimer();
64174
- init_WeeklyResetTimer();
64175
- init_ContextBar();
64176
- init_ThinkingEffort();
64177
64415
  init_VimMode();
64178
64416
  await __promiseAll([
64179
64417
  init_TokensInput(),
@@ -64184,12 +64422,20 @@ var init_widgets = __esm(async () => {
64184
64422
  init_CustomText(),
64185
64423
  init_CustomSymbol(),
64186
64424
  init_CustomCommand(),
64425
+ init_BlockTimer(),
64187
64426
  init_CurrentWorkingDir(),
64427
+ init_ClaudeAccountEmail(),
64188
64428
  init_InputSpeed(),
64189
64429
  init_OutputSpeed(),
64190
64430
  init_TotalSpeed(),
64431
+ init_SessionUsage(),
64432
+ init_WeeklyUsage(),
64433
+ init_BlockResetTimer(),
64434
+ init_WeeklyResetTimer(),
64435
+ init_ContextBar(),
64191
64436
  init_Link(),
64192
- init_Skills()
64437
+ init_Skills(),
64438
+ init_ThinkingEffort()
64193
64439
  ]);
64194
64440
  });
64195
64441
 
@@ -64205,7 +64451,7 @@ var init_widget_manifest = __esm(async () => {
64205
64451
  { type: "git-insertions", create: () => new GitInsertionsWidget },
64206
64452
  { type: "git-deletions", create: () => new GitDeletionsWidget },
64207
64453
  { type: "git-root-dir", create: () => new GitRootDirWidget },
64208
- { type: "git-pr", create: () => new GitPrWidget },
64454
+ { type: "git-review", create: () => new GitPrWidget },
64209
64455
  { type: "git-worktree", create: () => new GitWorktreeWidget },
64210
64456
  { type: "git-status", create: () => new GitStatusWidget },
64211
64457
  { type: "git-staged", create: () => new GitStagedWidget },
@@ -64275,8 +64521,17 @@ var init_widget_manifest = __esm(async () => {
64275
64521
  });
64276
64522
 
64277
64523
  // src/utils/widgets.ts
64524
+ function resolveLegacyWidgetType(type) {
64525
+ return LEGACY_WIDGET_TYPE_ALIASES[type] ?? type;
64526
+ }
64527
+ function upgradeLegacyWidgetTypes(lines) {
64528
+ return lines.map((line) => line.map((item) => {
64529
+ const resolved = resolveLegacyWidgetType(item.type);
64530
+ return resolved === item.type ? item : { ...item, type: resolved };
64531
+ }));
64532
+ }
64278
64533
  function getWidget(type) {
64279
- return widgetRegistry.get(type) ?? null;
64534
+ return widgetRegistry.get(resolveLegacyWidgetType(type)) ?? null;
64280
64535
  }
64281
64536
  function getAllWidgetTypes(settings) {
64282
64537
  const allTypes = WIDGET_MANIFEST.map((entry) => entry.type);
@@ -64526,11 +64781,12 @@ function getMatchSegments(text, query) {
64526
64781
  }
64527
64782
  return segments;
64528
64783
  }
64529
- var widgetRegistry, layoutWidgetTypes, layoutCatalogEntries;
64784
+ var widgetRegistry, layoutWidgetTypes, LEGACY_WIDGET_TYPE_ALIASES, layoutCatalogEntries;
64530
64785
  var init_widgets2 = __esm(async () => {
64531
64786
  await init_widget_manifest();
64532
64787
  widgetRegistry = new Map(WIDGET_MANIFEST.map((entry) => [entry.type, entry.create()]));
64533
64788
  layoutWidgetTypes = new Set(LAYOUT_WIDGET_MANIFEST.map((entry) => entry.type));
64789
+ LEGACY_WIDGET_TYPE_ALIASES = { "git-pr": "git-review" };
64534
64790
  layoutCatalogEntries = new Map(LAYOUT_WIDGET_MANIFEST.map((entry) => [
64535
64791
  entry.type,
64536
64792
  {
@@ -64612,16 +64868,18 @@ async function removeManagedHooks() {
64612
64868
  }
64613
64869
  var HOOK_TAG = "ccstatusline-managed";
64614
64870
  var init_hooks = __esm(async () => {
64615
- init_claude_settings();
64616
- await init_widgets2();
64871
+ await __promiseAll([
64872
+ init_claude_settings(),
64873
+ init_widgets2()
64874
+ ]);
64617
64875
  });
64618
64876
 
64619
64877
  // src/utils/config.ts
64620
64878
  import * as fs10 from "fs";
64621
64879
  import * as os8 from "os";
64622
- import * as path9 from "path";
64880
+ import * as path7 from "path";
64623
64881
  function initConfigPath(filePath) {
64624
- settingsPath = filePath ? path9.resolve(filePath) : DEFAULT_SETTINGS_PATH;
64882
+ settingsPath = filePath ? path7.resolve(filePath) : DEFAULT_SETTINGS_PATH;
64625
64883
  }
64626
64884
  function getConfigPath() {
64627
64885
  return settingsPath;
@@ -64630,13 +64888,13 @@ function isCustomConfigPath() {
64630
64888
  return settingsPath !== DEFAULT_SETTINGS_PATH;
64631
64889
  }
64632
64890
  function getSettingsPaths() {
64633
- const configDir = path9.dirname(settingsPath);
64634
- const parsedPath = path9.parse(settingsPath);
64891
+ const configDir = path7.dirname(settingsPath);
64892
+ const parsedPath = path7.parse(settingsPath);
64635
64893
  const backupBaseName = parsedPath.ext ? `${parsedPath.name}.bak` : `${parsedPath.base}.bak`;
64636
64894
  return {
64637
64895
  configDir,
64638
64896
  settingsPath,
64639
- settingsBackupPath: path9.join(configDir, backupBaseName)
64897
+ settingsBackupPath: path7.join(configDir, backupBaseName)
64640
64898
  };
64641
64899
  }
64642
64900
  async function writeSettingsJson(settings, paths) {
@@ -64703,7 +64961,10 @@ async function loadSettings() {
64703
64961
  console.error("Failed to parse settings:", result2.error);
64704
64962
  return await recoverWithDefaults(paths);
64705
64963
  }
64706
- return result2.data;
64964
+ return {
64965
+ ...result2.data,
64966
+ lines: upgradeLegacyWidgetTypes(result2.data.lines)
64967
+ };
64707
64968
  } catch (error48) {
64708
64969
  console.error("Error loading settings:", error48);
64709
64970
  return await recoverWithDefaults(paths);
@@ -64722,24 +64983,25 @@ async function saveSettings(settings) {
64722
64983
  } catch {}
64723
64984
  }
64724
64985
  var readFile3, writeFile, mkdir, DEFAULT_SETTINGS_PATH, settingsPath;
64725
- var init_config = __esm(() => {
64986
+ var init_config = __esm(async () => {
64726
64987
  init_Settings();
64727
64988
  init_migrations();
64989
+ await init_widgets2();
64728
64990
  readFile3 = fs10.promises.readFile;
64729
64991
  writeFile = fs10.promises.writeFile;
64730
64992
  mkdir = fs10.promises.mkdir;
64731
- DEFAULT_SETTINGS_PATH = path9.join(os8.homedir(), ".config", "ccstatusline", "settings.json");
64993
+ DEFAULT_SETTINGS_PATH = path7.join(os8.homedir(), ".config", "ccstatusline", "settings.json");
64732
64994
  settingsPath = DEFAULT_SETTINGS_PATH;
64733
64995
  });
64734
64996
 
64735
64997
  // src/utils/claude-settings.ts
64736
- import { execSync as execSync5 } from "child_process";
64998
+ import { execSync as execSync4 } from "child_process";
64737
64999
  import * as fs11 from "fs";
64738
65000
  import * as os9 from "os";
64739
- import * as path10 from "path";
65001
+ import * as path8 from "path";
64740
65002
  function isKnownCommand(command) {
64741
65003
  const prefixes = [CCSTATUSLINE_COMMANDS.NPM, CCSTATUSLINE_COMMANDS.BUNX, CCSTATUSLINE_COMMANDS.SELF_MANAGED];
64742
- return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `));
65004
+ return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `)) || /(?:^|[\s"'\\/])ccstatusline\.ts(?=$|[\s"'])/.test(command);
64743
65005
  }
64744
65006
  function needsQuoting(filePath) {
64745
65007
  if (process.platform === "win32") {
@@ -64760,7 +65022,7 @@ function getClaudeConfigDir() {
64760
65022
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
64761
65023
  if (envConfigDir) {
64762
65024
  try {
64763
- const resolvedPath = path10.resolve(envConfigDir);
65025
+ const resolvedPath = path8.resolve(envConfigDir);
64764
65026
  if (fs11.existsSync(resolvedPath)) {
64765
65027
  const stats = fs11.statSync(resolvedPath);
64766
65028
  if (stats.isDirectory()) {
@@ -64771,10 +65033,18 @@ function getClaudeConfigDir() {
64771
65033
  }
64772
65034
  } catch {}
64773
65035
  }
64774
- return path10.join(os9.homedir(), ".claude");
65036
+ return path8.join(os9.homedir(), ".claude");
65037
+ }
65038
+ function getClaudeJsonPath() {
65039
+ const configDir = getClaudeConfigDir();
65040
+ const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
65041
+ if (envConfigDir && configDir === path8.resolve(envConfigDir)) {
65042
+ return path8.join(configDir, ".claude.json");
65043
+ }
65044
+ return path8.join(path8.dirname(configDir), ".claude.json");
64775
65045
  }
64776
65046
  function getClaudeSettingsPath() {
64777
- return path10.join(getClaudeConfigDir(), "settings.json");
65047
+ return path8.join(getClaudeConfigDir(), "settings.json");
64778
65048
  }
64779
65049
  async function backupClaudeSettings(suffix = ".bak") {
64780
65050
  const settingsPath2 = getClaudeSettingsPath();
@@ -64824,7 +65094,7 @@ async function loadClaudeSettings(options = {}) {
64824
65094
  }
64825
65095
  async function saveClaudeSettings(settings) {
64826
65096
  const settingsPath2 = getClaudeSettingsPath();
64827
- const dir = path10.dirname(settingsPath2);
65097
+ const dir = path8.dirname(settingsPath2);
64828
65098
  await backupClaudeSettings();
64829
65099
  await mkdir2(dir, { recursive: true });
64830
65100
  await writeFile2(settingsPath2, JSON.stringify(settings, null, 2), "utf-8");
@@ -64842,12 +65112,40 @@ async function isInstalled() {
64842
65112
  function isBunxAvailable() {
64843
65113
  try {
64844
65114
  const command = process.platform === "win32" ? "where bunx" : "which bunx";
64845
- execSync5(command, { stdio: "ignore" });
65115
+ execSync4(command, { stdio: "ignore" });
64846
65116
  return true;
64847
65117
  } catch {
64848
65118
  return false;
64849
65119
  }
64850
65120
  }
65121
+ function getClaudeCodeVersion() {
65122
+ try {
65123
+ const output = execSync4("claude --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"], timeout: 5000 }).trim();
65124
+ const match = /^(\d+\.\d+\.\d+)/.exec(output);
65125
+ return match?.[1] ?? null;
65126
+ } catch {
65127
+ return null;
65128
+ }
65129
+ }
65130
+ function isClaudeCodeVersionAtLeast(minVersion) {
65131
+ const version2 = getClaudeCodeVersion();
65132
+ if (!version2) {
65133
+ return false;
65134
+ }
65135
+ const current = version2.split(".").map(Number);
65136
+ const minimum = minVersion.split(".").map(Number);
65137
+ for (let i = 0;i < 3; i++) {
65138
+ const c = current[i] ?? 0;
65139
+ const m = minimum[i] ?? 0;
65140
+ if (c > m) {
65141
+ return true;
65142
+ }
65143
+ if (c < m) {
65144
+ return false;
65145
+ }
65146
+ }
65147
+ return true;
65148
+ }
64851
65149
  function buildCommand(baseCommand) {
64852
65150
  if (isCustomConfigPath()) {
64853
65151
  return `${baseCommand} --config ${quotePathIfNeeded(getConfigPath())}`;
@@ -64871,7 +65169,7 @@ async function loadSavedSettingsForHookSync() {
64871
65169
  return null;
64872
65170
  }
64873
65171
  }
64874
- async function installStatusLine(useBunx = false) {
65172
+ async function installStatusLine(useBunx = false, supportsRefreshInterval = false) {
64875
65173
  let settings;
64876
65174
  const backupPath = await backupClaudeSettings(".orig");
64877
65175
  try {
@@ -64882,11 +65180,15 @@ async function installStatusLine(useBunx = false) {
64882
65180
  settings = {};
64883
65181
  }
64884
65182
  const baseCommand = useBunx ? CCSTATUSLINE_COMMANDS.BUNX : CCSTATUSLINE_COMMANDS.NPM;
65183
+ const existingRefreshInterval = settings.statusLine?.refreshInterval;
64885
65184
  settings.statusLine = {
64886
65185
  type: "command",
64887
65186
  command: buildCommand(baseCommand),
64888
65187
  padding: 0
64889
65188
  };
65189
+ if (supportsRefreshInterval) {
65190
+ settings.statusLine.refreshInterval = existingRefreshInterval ?? 10;
65191
+ }
64890
65192
  await saveClaudeSettings(settings);
64891
65193
  const savedSettings = await loadSavedSettingsForHookSync();
64892
65194
  if (savedSettings) {
@@ -64919,10 +65221,35 @@ async function getExistingStatusLine() {
64919
65221
  return null;
64920
65222
  }
64921
65223
  }
65224
+ async function getRefreshInterval() {
65225
+ try {
65226
+ const settings = await loadClaudeSettings({ logErrors: false });
65227
+ return settings.statusLine?.refreshInterval ?? null;
65228
+ } catch {
65229
+ return null;
65230
+ }
65231
+ }
65232
+ async function setRefreshInterval(interval) {
65233
+ let settings;
65234
+ try {
65235
+ settings = await loadClaudeSettings({ logErrors: false });
65236
+ } catch {
65237
+ return;
65238
+ }
65239
+ if (!settings.statusLine) {
65240
+ return;
65241
+ }
65242
+ if (interval === null) {
65243
+ delete settings.statusLine.refreshInterval;
65244
+ } else {
65245
+ settings.statusLine.refreshInterval = interval;
65246
+ }
65247
+ await saveClaudeSettings(settings);
65248
+ }
64922
65249
  var readFile4, writeFile2, mkdir2, CCSTATUSLINE_COMMANDS;
64923
- var init_claude_settings = __esm(() => {
65250
+ var init_claude_settings = __esm(async () => {
64924
65251
  init_Settings();
64925
- init_config();
65252
+ await init_config();
64926
65253
  readFile4 = fs11.promises.readFile;
64927
65254
  writeFile2 = fs11.promises.writeFile;
64928
65255
  mkdir2 = fs11.promises.mkdir;
@@ -65502,8 +65829,8 @@ var Gradient = (props) => {
65502
65829
  var dist_default5 = Gradient;
65503
65830
 
65504
65831
  // src/tui/App.tsx
65505
- init_claude_settings();
65506
- var import_react47 = __toESM(require_react(), 1);
65832
+ await init_claude_settings();
65833
+ var import_react48 = __toESM(require_react(), 1);
65507
65834
 
65508
65835
  // src/utils/clone-settings.ts
65509
65836
  function cloneSettings(settings) {
@@ -65515,7 +65842,7 @@ function cloneSettings(settings) {
65515
65842
  }
65516
65843
 
65517
65844
  // src/tui/App.tsx
65518
- init_config();
65845
+ await init_config();
65519
65846
 
65520
65847
  // src/utils/open-url.ts
65521
65848
  import { spawnSync } from "child_process";
@@ -65605,10 +65932,10 @@ function openExternalUrl(url2) {
65605
65932
  }
65606
65933
 
65607
65934
  // src/utils/powerline.ts
65608
- import { execSync as execSync6 } from "child_process";
65935
+ import { execSync as execSync5 } from "child_process";
65609
65936
  import * as fs12 from "fs";
65610
65937
  import * as os11 from "os";
65611
- import * as path11 from "path";
65938
+ import * as path9 from "path";
65612
65939
  var fontsInstalledThisSession = false;
65613
65940
  function checkPowerlineFonts() {
65614
65941
  if (process.env.DEBUG_FONT_INSTALL === "1" && !fontsInstalledThisSession) {
@@ -65628,20 +65955,20 @@ function checkPowerlineFonts() {
65628
65955
  let fontPaths = [];
65629
65956
  if (platform4 === "darwin") {
65630
65957
  fontPaths = [
65631
- path11.join(os11.homedir(), "Library", "Fonts"),
65958
+ path9.join(os11.homedir(), "Library", "Fonts"),
65632
65959
  "/Library/Fonts",
65633
65960
  "/System/Library/Fonts"
65634
65961
  ];
65635
65962
  } else if (platform4 === "linux") {
65636
65963
  fontPaths = [
65637
- path11.join(os11.homedir(), ".local", "share", "fonts"),
65638
- path11.join(os11.homedir(), ".fonts"),
65964
+ path9.join(os11.homedir(), ".local", "share", "fonts"),
65965
+ path9.join(os11.homedir(), ".fonts"),
65639
65966
  "/usr/share/fonts",
65640
65967
  "/usr/local/share/fonts"
65641
65968
  ];
65642
65969
  } else if (platform4 === "win32") {
65643
65970
  fontPaths = [
65644
- path11.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
65971
+ path9.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
65645
65972
  "C:\\Windows\\Fonts"
65646
65973
  ];
65647
65974
  }
@@ -65720,11 +66047,11 @@ async function installPowerlineFonts() {
65720
66047
  const platform4 = os11.platform();
65721
66048
  let fontDir;
65722
66049
  if (platform4 === "darwin") {
65723
- fontDir = path11.join(os11.homedir(), "Library", "Fonts");
66050
+ fontDir = path9.join(os11.homedir(), "Library", "Fonts");
65724
66051
  } else if (platform4 === "linux") {
65725
- fontDir = path11.join(os11.homedir(), ".local", "share", "fonts");
66052
+ fontDir = path9.join(os11.homedir(), ".local", "share", "fonts");
65726
66053
  } else if (platform4 === "win32") {
65727
- fontDir = path11.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
66054
+ fontDir = path9.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
65728
66055
  } else {
65729
66056
  return {
65730
66057
  success: false,
@@ -65734,27 +66061,27 @@ async function installPowerlineFonts() {
65734
66061
  if (!fs12.existsSync(fontDir)) {
65735
66062
  fs12.mkdirSync(fontDir, { recursive: true });
65736
66063
  }
65737
- const tempDir = path11.join(os11.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
66064
+ const tempDir = path9.join(os11.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
65738
66065
  try {
65739
66066
  if (fs12.existsSync(tempDir)) {
65740
66067
  fs12.rmSync(tempDir, { recursive: true, force: true });
65741
66068
  }
65742
- execSync6(`git clone --depth=1 https://github.com/powerline/fonts.git "${tempDir}"`, {
66069
+ execSync5(`git clone --depth=1 https://github.com/powerline/fonts.git "${tempDir}"`, {
65743
66070
  stdio: "pipe",
65744
66071
  encoding: "utf8"
65745
66072
  });
65746
66073
  if (platform4 === "darwin" || platform4 === "linux") {
65747
- const installScript = path11.join(tempDir, "install.sh");
66074
+ const installScript = path9.join(tempDir, "install.sh");
65748
66075
  if (fs12.existsSync(installScript)) {
65749
66076
  fs12.chmodSync(installScript, 493);
65750
- execSync6(`cd "${tempDir}" && ./install.sh`, {
66077
+ execSync5(`cd "${tempDir}" && ./install.sh`, {
65751
66078
  stdio: "pipe",
65752
66079
  encoding: "utf8",
65753
66080
  shell: "/bin/bash"
65754
66081
  });
65755
66082
  if (platform4 === "linux") {
65756
66083
  try {
65757
- execSync6("fc-cache -f -v", {
66084
+ execSync5("fc-cache -f -v", {
65758
66085
  stdio: "pipe",
65759
66086
  encoding: "utf8"
65760
66087
  });
@@ -65774,9 +66101,9 @@ async function installPowerlineFonts() {
65774
66101
  let findFontFiles = function(dir) {
65775
66102
  const files = fs12.readdirSync(dir);
65776
66103
  for (const file2 of files) {
65777
- const filePath = path11.join(dir, file2);
65778
- const stat = fs12.statSync(filePath);
65779
- if (stat.isDirectory() && !file2.startsWith(".")) {
66104
+ const filePath = path9.join(dir, file2);
66105
+ const stat2 = fs12.statSync(filePath);
66106
+ if (stat2.isDirectory() && !file2.startsWith(".")) {
65780
66107
  findFontFiles(filePath);
65781
66108
  } else if (file2.endsWith(".ttf") || file2.endsWith(".otf")) {
65782
66109
  if (filePath.toLowerCase().includes("powerline")) {
@@ -65789,8 +66116,8 @@ async function installPowerlineFonts() {
65789
66116
  findFontFiles(tempDir);
65790
66117
  let installedCount = 0;
65791
66118
  for (const fontFile of fontFiles) {
65792
- const fileName = path11.basename(fontFile);
65793
- const destPath = path11.join(fontDir, fileName);
66119
+ const fileName = path9.basename(fontFile);
66120
+ const destPath = path9.join(fontDir, fileName);
65794
66121
  try {
65795
66122
  fs12.copyFileSync(fontFile, destPath);
65796
66123
  installedCount++;
@@ -65834,6 +66161,22 @@ async function installPowerlineFonts() {
65834
66161
  // src/tui/App.tsx
65835
66162
  init_terminal();
65836
66163
 
66164
+ // src/tui/claude-status.ts
66165
+ await init_claude_settings();
66166
+ async function loadClaudeStatusLineState() {
66167
+ const [
66168
+ existingStatusLine,
66169
+ refreshInterval
66170
+ ] = await Promise.all([
66171
+ getExistingStatusLine(),
66172
+ getRefreshInterval()
66173
+ ]);
66174
+ return {
66175
+ existingStatusLine,
66176
+ refreshInterval
66177
+ };
66178
+ }
66179
+
65837
66180
  // src/tui/components/ColorMenu.tsx
65838
66181
  init_source();
65839
66182
  await init_build2();
@@ -66262,7 +66605,7 @@ function List({
66262
66605
  initialSelection = 0,
66263
66606
  showBackButton,
66264
66607
  color,
66265
- wrapNavigation = false,
66608
+ wrapNavigation = true,
66266
66609
  ...boxProps
66267
66610
  }) {
66268
66611
  const [selectedIndex, setSelectedIndex] = import_react36.useState(initialSelection);
@@ -67437,8 +67780,10 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
67437
67780
  }, undefined, true, undefined, this);
67438
67781
  };
67439
67782
  // src/tui/components/InstallMenu.tsx
67440
- init_claude_settings();
67441
- await init_build2();
67783
+ await __promiseAll([
67784
+ init_build2(),
67785
+ init_claude_settings()
67786
+ ]);
67442
67787
  var jsx_dev_runtime12 = __toESM(require_jsx_dev_runtime(), 1);
67443
67788
  var InstallMenu = ({
67444
67789
  bunxAvailable,
@@ -67643,7 +67988,7 @@ function handlePickerInputMode({
67643
67988
  if (currentIndex === -1) {
67644
67989
  currentIndex = 0;
67645
67990
  }
67646
- const nextIndex = key.downArrow ? Math.min(topLevelSearchEntries.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
67991
+ const nextIndex = key.downArrow ? currentIndex + 1 > topLevelSearchEntries.length - 1 ? 0 : currentIndex + 1 : currentIndex - 1 < 0 ? topLevelSearchEntries.length - 1 : currentIndex - 1;
67647
67992
  const nextType = topLevelSearchEntries[nextIndex]?.type ?? null;
67648
67993
  setPickerState(setWidgetPicker, normalizeState, (prev) => ({
67649
67994
  ...prev,
@@ -67657,7 +68002,7 @@ function handlePickerInputMode({
67657
68002
  if (currentIndex === -1) {
67658
68003
  currentIndex = 0;
67659
68004
  }
67660
- const nextIndex = key.downArrow ? Math.min(filteredCategories.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
68005
+ const nextIndex = key.downArrow ? currentIndex + 1 > filteredCategories.length - 1 ? 0 : currentIndex + 1 : currentIndex - 1 < 0 ? filteredCategories.length - 1 : currentIndex - 1;
67661
68006
  const nextCategory = filteredCategories[nextIndex] ?? null;
67662
68007
  setPickerState(setWidgetPicker, normalizeState, (prev) => ({
67663
68008
  ...prev,
@@ -67702,7 +68047,7 @@ function handlePickerInputMode({
67702
68047
  if (currentIndex === -1) {
67703
68048
  currentIndex = 0;
67704
68049
  }
67705
- const nextIndex = key.downArrow ? Math.min(filteredWidgets.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
68050
+ const nextIndex = key.downArrow ? currentIndex + 1 > filteredWidgets.length - 1 ? 0 : currentIndex + 1 : currentIndex - 1 < 0 ? filteredWidgets.length - 1 : currentIndex - 1;
67706
68051
  const nextType = filteredWidgets[nextIndex]?.type ?? null;
67707
68052
  setPickerState(setWidgetPicker, normalizeState, (prev) => ({
67708
68053
  ...prev,
@@ -67731,24 +68076,26 @@ function handleMoveInputMode({
67731
68076
  setSelectedIndex,
67732
68077
  setMoveMode
67733
68078
  }) {
67734
- if (key.upArrow && selectedIndex > 0) {
68079
+ if (key.upArrow && widgets.length > 1) {
67735
68080
  const newWidgets = [...widgets];
68081
+ const targetIndex = selectedIndex - 1 < 0 ? widgets.length - 1 : selectedIndex - 1;
67736
68082
  const temp = newWidgets[selectedIndex];
67737
- const prev = newWidgets[selectedIndex - 1];
68083
+ const prev = newWidgets[targetIndex];
67738
68084
  if (temp && prev) {
67739
- [newWidgets[selectedIndex], newWidgets[selectedIndex - 1]] = [prev, temp];
68085
+ [newWidgets[selectedIndex], newWidgets[targetIndex]] = [prev, temp];
67740
68086
  }
67741
68087
  onUpdate(newWidgets);
67742
- setSelectedIndex(selectedIndex - 1);
67743
- } else if (key.downArrow && selectedIndex < widgets.length - 1) {
68088
+ setSelectedIndex(targetIndex);
68089
+ } else if (key.downArrow && widgets.length > 1) {
67744
68090
  const newWidgets = [...widgets];
68091
+ const targetIndex = selectedIndex + 1 > widgets.length - 1 ? 0 : selectedIndex + 1;
67745
68092
  const temp = newWidgets[selectedIndex];
67746
- const next = newWidgets[selectedIndex + 1];
68093
+ const next = newWidgets[targetIndex];
67747
68094
  if (temp && next) {
67748
- [newWidgets[selectedIndex], newWidgets[selectedIndex + 1]] = [next, temp];
68095
+ [newWidgets[selectedIndex], newWidgets[targetIndex]] = [next, temp];
67749
68096
  }
67750
68097
  onUpdate(newWidgets);
67751
- setSelectedIndex(selectedIndex + 1);
68098
+ setSelectedIndex(targetIndex);
67752
68099
  } else if (key.escape || key.return) {
67753
68100
  setMoveMode(false);
67754
68101
  }
@@ -67766,12 +68113,13 @@ function handleNormalInputMode({
67766
68113
  setShowClearConfirm,
67767
68114
  openWidgetPicker,
67768
68115
  getCustomKeybindsForWidget,
67769
- setCustomEditorWidget
68116
+ setCustomEditorWidget,
68117
+ getUniqueBackgroundColor
67770
68118
  }) {
67771
68119
  if (key.upArrow && widgets.length > 0) {
67772
- setSelectedIndex(Math.max(0, selectedIndex - 1));
68120
+ setSelectedIndex(selectedIndex - 1 < 0 ? widgets.length - 1 : selectedIndex - 1);
67773
68121
  } else if (key.downArrow && widgets.length > 0) {
67774
- setSelectedIndex(Math.min(widgets.length - 1, selectedIndex + 1));
68122
+ setSelectedIndex(selectedIndex + 1 > widgets.length - 1 ? 0 : selectedIndex + 1);
67775
68123
  } else if (key.leftArrow && widgets.length > 0) {
67776
68124
  openWidgetPicker("change");
67777
68125
  } else if (key.rightArrow && widgets.length > 0) {
@@ -67788,6 +68136,26 @@ function handleNormalInputMode({
67788
68136
  if (selectedIndex >= newWidgets.length && selectedIndex > 0) {
67789
68137
  setSelectedIndex(selectedIndex - 1);
67790
68138
  }
68139
+ } else if (input === "k" && widgets.length > 0) {
68140
+ const source = widgets[selectedIndex];
68141
+ if (!source) {
68142
+ return;
68143
+ }
68144
+ const insertIndex = selectedIndex + 1;
68145
+ const newBg = getUniqueBackgroundColor?.(insertIndex);
68146
+ const clone3 = {
68147
+ ...source,
68148
+ id: generateGuid(),
68149
+ ...source.metadata && { metadata: { ...source.metadata } },
68150
+ ...newBg && { backgroundColor: newBg }
68151
+ };
68152
+ const newWidgets = [
68153
+ ...widgets.slice(0, insertIndex),
68154
+ clone3,
68155
+ ...widgets.slice(insertIndex)
68156
+ ];
68157
+ onUpdate(newWidgets);
68158
+ setSelectedIndex(insertIndex);
67791
68159
  } else if (input === "c") {
67792
68160
  if (widgets.length > 0) {
67793
68161
  setShowClearConfirm(true);
@@ -67988,7 +68356,8 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
67988
68356
  setShowClearConfirm,
67989
68357
  openWidgetPicker,
67990
68358
  getCustomKeybindsForWidget,
67991
- setCustomEditorWidget
68359
+ setCustomEditorWidget,
68360
+ getUniqueBackgroundColor
67992
68361
  });
67993
68362
  });
67994
68363
  const getWidgetDisplay = (widget) => {
@@ -68036,7 +68405,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
68036
68405
  helpText += ", Space edit separator";
68037
68406
  }
68038
68407
  if (hasWidgets) {
68039
- helpText += ", Enter to move, (a)dd via picker, (i)nsert via picker, (d)elete, (c)lear line";
68408
+ helpText += ", Enter to move, (a)dd via picker, (i)nsert via picker, (k) clone, (d)elete, (c)lear line";
68040
68409
  }
68041
68410
  if (canToggleRaw) {
68042
68411
  helpText += ", (r)aw value";
@@ -68470,26 +68839,28 @@ var LineSelector = ({
68470
68839
  return;
68471
68840
  }
68472
68841
  if (moveMode) {
68473
- if (key.upArrow && selectedIndex > 0) {
68842
+ if (key.upArrow && localLines.length > 1) {
68474
68843
  const newLines = [...localLines];
68844
+ const targetIndex = selectedIndex - 1 < 0 ? localLines.length - 1 : selectedIndex - 1;
68475
68845
  const temp = newLines[selectedIndex];
68476
- const prev = newLines[selectedIndex - 1];
68846
+ const prev = newLines[targetIndex];
68477
68847
  if (temp && prev) {
68478
- [newLines[selectedIndex], newLines[selectedIndex - 1]] = [prev, temp];
68848
+ [newLines[selectedIndex], newLines[targetIndex]] = [prev, temp];
68479
68849
  }
68480
68850
  setLocalLines(newLines);
68481
68851
  onLinesUpdate(newLines);
68482
- setSelectedIndex(selectedIndex - 1);
68483
- } else if (key.downArrow && selectedIndex < localLines.length - 1) {
68852
+ setSelectedIndex(targetIndex);
68853
+ } else if (key.downArrow && localLines.length > 1) {
68484
68854
  const newLines = [...localLines];
68855
+ const targetIndex = selectedIndex + 1 > localLines.length - 1 ? 0 : selectedIndex + 1;
68485
68856
  const temp = newLines[selectedIndex];
68486
- const next = newLines[selectedIndex + 1];
68857
+ const next = newLines[targetIndex];
68487
68858
  if (temp && next) {
68488
- [newLines[selectedIndex], newLines[selectedIndex + 1]] = [next, temp];
68859
+ [newLines[selectedIndex], newLines[targetIndex]] = [next, temp];
68489
68860
  }
68490
68861
  setLocalLines(newLines);
68491
68862
  onLinesUpdate(newLines);
68492
- setSelectedIndex(selectedIndex + 1);
68863
+ setSelectedIndex(targetIndex);
68493
68864
  } else if (key.escape || key.return) {
68494
68865
  setMoveMode(false);
68495
68866
  }
@@ -68750,11 +69121,24 @@ var MainMenu = ({
68750
69121
  description: "Set global padding, separators, and color overrides that apply to all widgets"
68751
69122
  },
68752
69123
  "-",
68753
- {
68754
- label: isClaudeInstalled ? "\uD83D\uDD0C Uninstall from Claude Code" : "\uD83D\uDCE6 Install to Claude Code",
68755
- value: "install",
68756
- description: isClaudeInstalled ? "Remove ccstatusline from your Claude Code settings" : "Add ccstatusline to your Claude Code settings for automatic status line rendering"
68757
- }
69124
+ ...isClaudeInstalled ? [
69125
+ {
69126
+ label: "\uD83D\uDD27 Configure Status Line",
69127
+ value: "configureStatusLine",
69128
+ description: "Configure Claude Code status line settings like refresh interval"
69129
+ },
69130
+ {
69131
+ label: "\uD83D\uDD0C Uninstall from Claude Code",
69132
+ value: "install",
69133
+ description: "Remove ccstatusline from your Claude Code settings"
69134
+ }
69135
+ ] : [
69136
+ {
69137
+ label: "\uD83D\uDCE6 Install to Claude Code",
69138
+ value: "install",
69139
+ description: "Add ccstatusline to your Claude Code settings for automatic status line rendering"
69140
+ }
69141
+ ]
68758
69142
  ];
68759
69143
  if (hasChanges) {
68760
69144
  menuItems.push({
@@ -68956,10 +69340,10 @@ var PowerlineSeparatorEditor = ({
68956
69340
  } else {
68957
69341
  if (key.escape) {
68958
69342
  onBack();
68959
- } else if (key.upArrow) {
68960
- setSelectedIndex(Math.max(0, selectedIndex - 1));
69343
+ } else if (key.upArrow && separators.length > 0) {
69344
+ setSelectedIndex(selectedIndex - 1 < 0 ? separators.length - 1 : selectedIndex - 1);
68961
69345
  } else if (key.downArrow && separators.length > 0) {
68962
- setSelectedIndex(Math.min(separators.length - 1, selectedIndex + 1));
69346
+ setSelectedIndex(selectedIndex + 1 > separators.length - 1 ? 0 : selectedIndex + 1);
68963
69347
  } else if ((key.leftArrow || key.rightArrow) && separators.length > 0) {
68964
69348
  const currentChar = separators[selectedIndex] ?? "";
68965
69349
  const currentPresetIndex = presetSeparators.findIndex((p) => p.char === currentChar);
@@ -69871,10 +70255,149 @@ var PowerlineSetup = ({
69871
70255
  ]
69872
70256
  }, undefined, true, undefined, this);
69873
70257
  };
70258
+ // src/tui/components/RefreshIntervalMenu.tsx
70259
+ init_input_guards();
70260
+ await init_build2();
70261
+ var import_react44 = __toESM(require_react(), 1);
70262
+ var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
70263
+ function getRefreshInputValue(interval) {
70264
+ return interval === null ? "" : String(interval);
70265
+ }
70266
+ function getRefreshIntervalSublabel(interval, supported) {
70267
+ if (!supported) {
70268
+ return "(requires Claude Code >=2.1.97)";
70269
+ }
70270
+ if (interval === null) {
70271
+ return "(not set)";
70272
+ }
70273
+ return `(${interval}s)`;
70274
+ }
70275
+ function buildConfigureStatusLineItems(refreshInterval, supportsRefreshInterval) {
70276
+ return [
70277
+ {
70278
+ label: "\uD83D\uDD04 Refresh Interval",
70279
+ sublabel: getRefreshIntervalSublabel(refreshInterval, supportsRefreshInterval),
70280
+ value: "refreshInterval",
70281
+ disabled: !supportsRefreshInterval,
70282
+ 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."
70283
+ }
70284
+ ];
70285
+ }
70286
+ function validateRefreshIntervalInput(value) {
70287
+ if (value === "") {
70288
+ return null;
70289
+ }
70290
+ const parsed = parseInt(value, 10);
70291
+ if (isNaN(parsed)) {
70292
+ return "Please enter a valid number";
70293
+ }
70294
+ if (parsed < 1) {
70295
+ return `Minimum interval is 1s (you entered ${parsed}s)`;
70296
+ }
70297
+ if (parsed > 60) {
70298
+ return `Maximum interval is 60s (you entered ${parsed}s)`;
70299
+ }
70300
+ return null;
70301
+ }
70302
+ var RefreshIntervalMenu = ({
70303
+ currentInterval,
70304
+ supportsRefreshInterval,
70305
+ onUpdate,
70306
+ onBack
70307
+ }) => {
70308
+ const [editingRefreshInterval, setEditingRefreshInterval] = import_react44.useState(false);
70309
+ const [refreshInput, setRefreshInput] = import_react44.useState(() => getRefreshInputValue(currentInterval));
70310
+ const [validationError, setValidationError] = import_react44.useState(null);
70311
+ use_input_default((input, key) => {
70312
+ if (editingRefreshInterval) {
70313
+ if (key.return) {
70314
+ if (refreshInput === "") {
70315
+ onUpdate(null);
70316
+ setEditingRefreshInterval(false);
70317
+ setValidationError(null);
70318
+ return;
70319
+ }
70320
+ const error48 = validateRefreshIntervalInput(refreshInput);
70321
+ if (error48) {
70322
+ setValidationError(error48);
70323
+ } else {
70324
+ const value = parseInt(refreshInput, 10);
70325
+ onUpdate(value);
70326
+ setEditingRefreshInterval(false);
70327
+ setValidationError(null);
70328
+ }
70329
+ } else if (key.escape) {
70330
+ setRefreshInput(getRefreshInputValue(currentInterval));
70331
+ setEditingRefreshInterval(false);
70332
+ setValidationError(null);
70333
+ } else if (key.backspace) {
70334
+ setRefreshInput(refreshInput.slice(0, -1));
70335
+ setValidationError(null);
70336
+ } else if (key.delete) {} else if (shouldInsertInput(input, key) && /\d/.test(input)) {
70337
+ const newValue = refreshInput + input;
70338
+ if (newValue.length <= 2) {
70339
+ setRefreshInput(newValue);
70340
+ setValidationError(null);
70341
+ }
70342
+ }
70343
+ return;
70344
+ }
70345
+ if (key.escape) {
70346
+ onBack();
70347
+ }
70348
+ });
70349
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70350
+ flexDirection: "column",
70351
+ children: [
70352
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70353
+ bold: true,
70354
+ children: "Configure Status Line"
70355
+ }, undefined, false, undefined, this),
70356
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70357
+ color: "white",
70358
+ children: "Configure Claude Code status line settings"
70359
+ }, undefined, false, undefined, this),
70360
+ editingRefreshInterval ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70361
+ marginTop: 1,
70362
+ flexDirection: "column",
70363
+ children: [
70364
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70365
+ children: [
70366
+ "Enter refresh interval in seconds (1-60):",
70367
+ " ",
70368
+ refreshInput,
70369
+ refreshInput.length > 0 ? "s" : ""
70370
+ ]
70371
+ }, undefined, true, undefined, this),
70372
+ validationError ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70373
+ color: "red",
70374
+ children: validationError
70375
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70376
+ dimColor: true,
70377
+ children: "Press Enter to confirm, ESC to cancel. Leave empty to remove."
70378
+ }, undefined, false, undefined, this)
70379
+ ]
70380
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(List, {
70381
+ marginTop: 1,
70382
+ items: buildConfigureStatusLineItems(currentInterval, supportsRefreshInterval),
70383
+ onSelect: (value) => {
70384
+ if (value === "back") {
70385
+ onBack();
70386
+ return;
70387
+ }
70388
+ setRefreshInput(getRefreshInputValue(currentInterval));
70389
+ setEditingRefreshInterval(true);
70390
+ },
70391
+ showBackButton: true
70392
+ }, undefined, false, undefined, this)
70393
+ ]
70394
+ }, undefined, true, undefined, this);
70395
+ };
69874
70396
  // src/tui/components/StatusLinePreview.tsx
69875
70397
  init_source();
70398
+ init_ansi();
69876
70399
  await init_build2();
69877
- var import_react44 = __toESM(require_react(), 1);
70400
+ var import_react45 = __toESM(require_react(), 1);
69878
70401
 
69879
70402
  // src/utils/powerline-theme-index.ts
69880
70403
  function countPowerlineThemeSlots(entries) {
@@ -69908,7 +70431,7 @@ function advanceGlobalSeparatorIndex(currentIndex, widgets) {
69908
70431
  }
69909
70432
 
69910
70433
  // src/tui/components/StatusLinePreview.tsx
69911
- var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
70434
+ var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
69912
70435
  var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, globalPowerlineThemeIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
69913
70436
  const context = {
69914
70437
  terminalWidth,
@@ -69920,8 +70443,14 @@ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSepar
69920
70443
  };
69921
70444
  return renderStatusLineWithInfo(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths);
69922
70445
  };
70446
+ var PREVIEW_LINE_INDENT = " ";
70447
+ function preparePreviewLineForTerminal(line, terminalWidth) {
70448
+ const printableLine = stripOscCodes(line);
70449
+ const availableWidth = Math.max(0, terminalWidth - getVisibleWidth(PREVIEW_LINE_INDENT));
70450
+ return truncateStyledText(printableLine, availableWidth, { ellipsis: true });
70451
+ }
69923
70452
  var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange }) => {
69924
- const { renderedLines, anyTruncated } = import_react44.default.useMemo(() => {
70453
+ const { renderedLines, anyTruncated } = import_react45.default.useMemo(() => {
69925
70454
  if (!settings)
69926
70455
  return { renderedLines: [], anyTruncated: false };
69927
70456
  const preRenderedLines = preRenderAllWidgets(lines, settings, { terminalWidth, isPreview: true, minimalist: settings.minimalistMode });
@@ -69947,32 +70476,33 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
69947
70476
  }
69948
70477
  return { renderedLines: result2, anyTruncated: truncated };
69949
70478
  }, [lines, terminalWidth, settings]);
69950
- import_react44.default.useEffect(() => {
70479
+ import_react45.default.useEffect(() => {
69951
70480
  onTruncationChange?.(anyTruncated);
69952
70481
  }, [anyTruncated, onTruncationChange]);
69953
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70482
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
69954
70483
  flexDirection: "column",
69955
70484
  children: [
69956
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70485
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
69957
70486
  borderStyle: "round",
69958
70487
  borderColor: "gray",
69959
70488
  borderDimColor: true,
69960
70489
  width: "100%",
69961
70490
  paddingLeft: 1,
69962
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70491
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
69963
70492
  children: [
69964
70493
  ">",
69965
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70494
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
69966
70495
  dimColor: true,
69967
70496
  children: " Preview (ctrl+s to save configuration at any time)"
69968
70497
  }, undefined, false, undefined, this)
69969
70498
  ]
69970
70499
  }, undefined, true, undefined, this)
69971
70500
  }, undefined, false, undefined, this),
69972
- renderedLines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70501
+ renderedLines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70502
+ wrap: "truncate",
69973
70503
  children: [
69974
- " ",
69975
- line,
70504
+ PREVIEW_LINE_INDENT,
70505
+ preparePreviewLineForTerminal(line, terminalWidth),
69976
70506
  source_default.reset("")
69977
70507
  ]
69978
70508
  }, index, true, undefined, this))
@@ -69982,7 +70512,7 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
69982
70512
  // src/tui/components/TerminalOptionsMenu.tsx
69983
70513
  init_source();
69984
70514
  await init_build2();
69985
- var import_react45 = __toESM(require_react(), 1);
70515
+ var import_react46 = __toESM(require_react(), 1);
69986
70516
 
69987
70517
  // src/utils/color-sanitize.ts
69988
70518
  await init_widgets2();
@@ -70037,7 +70567,7 @@ function sanitizeLinesForColorLevel(lines, nextLevel) {
70037
70567
  }
70038
70568
 
70039
70569
  // src/tui/components/TerminalOptionsMenu.tsx
70040
- var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
70570
+ var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
70041
70571
  function getNextColorLevel(level) {
70042
70572
  return (level + 1) % 4;
70043
70573
  }
@@ -70071,8 +70601,8 @@ var TerminalOptionsMenu = ({
70071
70601
  onUpdate,
70072
70602
  onBack
70073
70603
  }) => {
70074
- const [showColorWarning, setShowColorWarning] = import_react45.useState(false);
70075
- const [pendingColorLevel, setPendingColorLevel] = import_react45.useState(null);
70604
+ const [showColorWarning, setShowColorWarning] = import_react46.useState(false);
70605
+ const [pendingColorLevel, setPendingColorLevel] = import_react46.useState(null);
70076
70606
  const handleSelect = (value) => {
70077
70607
  if (value === "back") {
70078
70608
  onBack();
@@ -70120,27 +70650,27 @@ var TerminalOptionsMenu = ({
70120
70650
  onBack();
70121
70651
  }
70122
70652
  });
70123
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70653
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70124
70654
  flexDirection: "column",
70125
70655
  children: [
70126
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70656
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70127
70657
  bold: true,
70128
70658
  children: "Terminal Options"
70129
70659
  }, undefined, false, undefined, this),
70130
- showColorWarning ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70660
+ showColorWarning ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70131
70661
  flexDirection: "column",
70132
70662
  marginTop: 1,
70133
70663
  children: [
70134
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70664
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70135
70665
  color: "yellow",
70136
70666
  children: "⚠ Warning: Custom colors detected!"
70137
70667
  }, undefined, false, undefined, this),
70138
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70668
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70139
70669
  children: "Switching color modes will reset custom ansi256 or hex colors to defaults."
70140
70670
  }, undefined, false, undefined, this),
70141
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70671
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70142
70672
  marginTop: 1,
70143
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(ConfirmDialog, {
70673
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ConfirmDialog, {
70144
70674
  message: "Continue?",
70145
70675
  onConfirm: handleColorConfirm,
70146
70676
  onCancel: handleColorCancel,
@@ -70148,13 +70678,13 @@ var TerminalOptionsMenu = ({
70148
70678
  }, undefined, false, undefined, this)
70149
70679
  }, undefined, false, undefined, this)
70150
70680
  ]
70151
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
70681
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
70152
70682
  children: [
70153
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70683
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70154
70684
  color: "white",
70155
70685
  children: "Configure terminal-specific settings for optimal display"
70156
70686
  }, undefined, false, undefined, this),
70157
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(List, {
70687
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(List, {
70158
70688
  marginTop: 1,
70159
70689
  items: buildTerminalOptionsItems(settings.colorLevel),
70160
70690
  onSelect: handleSelect,
@@ -70183,8 +70713,8 @@ var getColorLevelLabel = (level) => {
70183
70713
  // src/tui/components/TerminalWidthMenu.tsx
70184
70714
  init_input_guards();
70185
70715
  await init_build2();
70186
- var import_react46 = __toESM(require_react(), 1);
70187
- var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
70716
+ var import_react47 = __toESM(require_react(), 1);
70717
+ var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
70188
70718
  var TERMINAL_WIDTH_OPTIONS = ["full", "full-minus-40", "full-until-compact"];
70189
70719
  function getTerminalWidthSelectionIndex(selectedOption) {
70190
70720
  const selectedIndex = TERMINAL_WIDTH_OPTIONS.indexOf(selectedOption);
@@ -70231,11 +70761,11 @@ var TerminalWidthMenu = ({
70231
70761
  onUpdate,
70232
70762
  onBack
70233
70763
  }) => {
70234
- const [selectedOption, setSelectedOption] = import_react46.useState(settings.flexMode);
70235
- const [compactThreshold, setCompactThreshold] = import_react46.useState(settings.compactThreshold);
70236
- const [editingThreshold, setEditingThreshold] = import_react46.useState(false);
70237
- const [thresholdInput, setThresholdInput] = import_react46.useState(String(settings.compactThreshold));
70238
- const [validationError, setValidationError] = import_react46.useState(null);
70764
+ const [selectedOption, setSelectedOption] = import_react47.useState(settings.flexMode);
70765
+ const [compactThreshold, setCompactThreshold] = import_react47.useState(settings.compactThreshold);
70766
+ const [editingThreshold, setEditingThreshold] = import_react47.useState(false);
70767
+ const [thresholdInput, setThresholdInput] = import_react47.useState(String(settings.compactThreshold));
70768
+ const [validationError, setValidationError] = import_react47.useState(null);
70239
70769
  use_input_default((input, key) => {
70240
70770
  if (editingThreshold) {
70241
70771
  if (key.return) {
@@ -70274,27 +70804,27 @@ var TerminalWidthMenu = ({
70274
70804
  onBack();
70275
70805
  }
70276
70806
  });
70277
- return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70807
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
70278
70808
  flexDirection: "column",
70279
70809
  children: [
70280
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70810
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70281
70811
  bold: true,
70282
70812
  children: "Terminal Width"
70283
70813
  }, undefined, false, undefined, this),
70284
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70814
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70285
70815
  color: "white",
70286
70816
  children: "These settings affect where long lines are truncated, and where right-alignment occurs when using flex separators"
70287
70817
  }, undefined, false, undefined, this),
70288
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70818
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70289
70819
  dimColor: true,
70290
70820
  wrap: "wrap",
70291
70821
  children: "Claude code does not currently provide an available width variable for the statusline and features like IDE integration, auto-compaction notices, etc all cause the statusline to wrap if we do not truncate it"
70292
70822
  }, undefined, false, undefined, this),
70293
- editingThreshold ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70823
+ editingThreshold ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
70294
70824
  marginTop: 1,
70295
70825
  flexDirection: "column",
70296
70826
  children: [
70297
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70827
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70298
70828
  children: [
70299
70829
  "Enter compact threshold (1-99):",
70300
70830
  " ",
@@ -70302,15 +70832,15 @@ var TerminalWidthMenu = ({
70302
70832
  "%"
70303
70833
  ]
70304
70834
  }, undefined, true, undefined, this),
70305
- validationError ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70835
+ validationError ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70306
70836
  color: "red",
70307
70837
  children: validationError
70308
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70838
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70309
70839
  dimColor: true,
70310
70840
  children: "Press Enter to confirm, ESC to cancel"
70311
70841
  }, undefined, false, undefined, this)
70312
70842
  ]
70313
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(List, {
70843
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(List, {
70314
70844
  marginTop: 1,
70315
70845
  items: buildTerminalWidthItems(selectedOption, compactThreshold),
70316
70846
  initialSelection: getTerminalWidthSelectionIndex(selectedOption),
@@ -70336,7 +70866,7 @@ var TerminalWidthMenu = ({
70336
70866
  }, undefined, true, undefined, this);
70337
70867
  };
70338
70868
  // src/tui/App.tsx
70339
- var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
70869
+ var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
70340
70870
  var GITHUB_REPO_URL = "https://github.com/sirmalloc/ccstatusline";
70341
70871
  function getConfirmCancelScreen(confirmDialog) {
70342
70872
  return confirmDialog?.cancelScreen ?? "main";
@@ -70351,23 +70881,28 @@ function clearInstallMenuSelection(menuSelections) {
70351
70881
  }
70352
70882
  var App2 = () => {
70353
70883
  const { exit } = use_app_default();
70354
- const [settings, setSettings] = import_react47.useState(null);
70355
- const [originalSettings, setOriginalSettings] = import_react47.useState(null);
70356
- const [hasChanges, setHasChanges] = import_react47.useState(false);
70357
- const [screen, setScreen] = import_react47.useState("main");
70358
- const [selectedLine, setSelectedLine] = import_react47.useState(0);
70359
- const [menuSelections, setMenuSelections] = import_react47.useState({});
70360
- const [confirmDialog, setConfirmDialog] = import_react47.useState(null);
70361
- const [isClaudeInstalled, setIsClaudeInstalled] = import_react47.useState(false);
70362
- const [terminalWidth, setTerminalWidth] = import_react47.useState(process.stdout.columns || 80);
70363
- const [powerlineFontStatus, setPowerlineFontStatus] = import_react47.useState({ installed: false });
70364
- const [installingFonts, setInstallingFonts] = import_react47.useState(false);
70365
- const [fontInstallMessage, setFontInstallMessage] = import_react47.useState(null);
70366
- const [existingStatusLine, setExistingStatusLine] = import_react47.useState(null);
70367
- const [flashMessage, setFlashMessage] = import_react47.useState(null);
70368
- const [previewIsTruncated, setPreviewIsTruncated] = import_react47.useState(false);
70369
- import_react47.useEffect(() => {
70370
- getExistingStatusLine().then(setExistingStatusLine);
70884
+ const [settings, setSettings] = import_react48.useState(null);
70885
+ const [originalSettings, setOriginalSettings] = import_react48.useState(null);
70886
+ const [hasChanges, setHasChanges] = import_react48.useState(false);
70887
+ const [screen, setScreen] = import_react48.useState("main");
70888
+ const [selectedLine, setSelectedLine] = import_react48.useState(0);
70889
+ const [menuSelections, setMenuSelections] = import_react48.useState({});
70890
+ const [confirmDialog, setConfirmDialog] = import_react48.useState(null);
70891
+ const [isClaudeInstalled, setIsClaudeInstalled] = import_react48.useState(false);
70892
+ const [terminalWidth, setTerminalWidth] = import_react48.useState(process.stdout.columns || 80);
70893
+ const [powerlineFontStatus, setPowerlineFontStatus] = import_react48.useState({ installed: false });
70894
+ const [installingFonts, setInstallingFonts] = import_react48.useState(false);
70895
+ const [fontInstallMessage, setFontInstallMessage] = import_react48.useState(null);
70896
+ const [existingStatusLine, setExistingStatusLine] = import_react48.useState(null);
70897
+ const [flashMessage, setFlashMessage] = import_react48.useState(null);
70898
+ const [previewIsTruncated, setPreviewIsTruncated] = import_react48.useState(false);
70899
+ const [currentRefreshInterval, setCurrentRefreshInterval] = import_react48.useState(null);
70900
+ const [supportsRefreshInterval] = import_react48.useState(() => isClaudeCodeVersionAtLeast("2.1.97"));
70901
+ import_react48.useEffect(() => {
70902
+ loadClaudeStatusLineState().then((statusLineState) => {
70903
+ setExistingStatusLine(statusLineState.existingStatusLine);
70904
+ setCurrentRefreshInterval(statusLineState.refreshInterval);
70905
+ });
70371
70906
  loadSettings().then((loadedSettings) => {
70372
70907
  source_default.level = loadedSettings.colorLevel;
70373
70908
  setSettings(loadedSettings);
@@ -70387,13 +70922,13 @@ var App2 = () => {
70387
70922
  process.stdout.off("resize", handleResize);
70388
70923
  };
70389
70924
  }, []);
70390
- import_react47.useEffect(() => {
70925
+ import_react48.useEffect(() => {
70391
70926
  if (originalSettings) {
70392
70927
  const hasAnyChanges = JSON.stringify(settings) !== JSON.stringify(originalSettings);
70393
70928
  setHasChanges(hasAnyChanges);
70394
70929
  }
70395
70930
  }, [settings, originalSettings]);
70396
- import_react47.useEffect(() => {
70931
+ import_react48.useEffect(() => {
70397
70932
  if (flashMessage) {
70398
70933
  const timer = setTimeout(() => {
70399
70934
  setFlashMessage(null);
@@ -70419,7 +70954,7 @@ var App2 = () => {
70419
70954
  })();
70420
70955
  }
70421
70956
  });
70422
- const handleInstallSelection = import_react47.useCallback((command, displayName, useBunx) => {
70957
+ const handleInstallSelection = import_react48.useCallback((command, displayName, useBunx) => {
70423
70958
  getExistingStatusLine().then((existing) => {
70424
70959
  const isAlreadyInstalled = isKnownCommand(existing ?? "");
70425
70960
  let message;
@@ -70439,30 +70974,32 @@ Continue?`;
70439
70974
  message,
70440
70975
  cancelScreen: "install",
70441
70976
  action: async () => {
70442
- await installStatusLine(useBunx);
70977
+ await installStatusLine(useBunx, supportsRefreshInterval);
70978
+ const installedStatusLineState = await loadClaudeStatusLineState();
70443
70979
  setIsClaudeInstalled(true);
70444
- setExistingStatusLine(command);
70980
+ setExistingStatusLine(installedStatusLineState.existingStatusLine ?? command);
70981
+ setCurrentRefreshInterval(installedStatusLineState.refreshInterval);
70445
70982
  setScreen("main");
70446
70983
  setConfirmDialog(null);
70447
70984
  }
70448
70985
  });
70449
70986
  setScreen("confirm");
70450
70987
  });
70451
- }, []);
70452
- const handleNpxInstall = import_react47.useCallback(() => {
70988
+ }, [supportsRefreshInterval]);
70989
+ const handleNpxInstall = import_react48.useCallback(() => {
70453
70990
  setMenuSelections((prev) => ({ ...prev, install: 0 }));
70454
70991
  handleInstallSelection(CCSTATUSLINE_COMMANDS.NPM, "npx", false);
70455
70992
  }, [handleInstallSelection]);
70456
- const handleBunxInstall = import_react47.useCallback(() => {
70993
+ const handleBunxInstall = import_react48.useCallback(() => {
70457
70994
  setMenuSelections((prev) => ({ ...prev, install: 1 }));
70458
70995
  handleInstallSelection(CCSTATUSLINE_COMMANDS.BUNX, "bunx", true);
70459
70996
  }, [handleInstallSelection]);
70460
- const handleInstallMenuCancel = import_react47.useCallback(() => {
70997
+ const handleInstallMenuCancel = import_react48.useCallback(() => {
70461
70998
  setMenuSelections(clearInstallMenuSelection);
70462
70999
  setScreen("main");
70463
71000
  }, []);
70464
71001
  if (!settings) {
70465
- return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71002
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70466
71003
  children: "Loading settings..."
70467
71004
  }, undefined, false, undefined, this);
70468
71005
  }
@@ -70474,6 +71011,7 @@ Continue?`;
70474
71011
  await uninstallStatusLine();
70475
71012
  setIsClaudeInstalled(false);
70476
71013
  setExistingStatusLine(null);
71014
+ setCurrentRefreshInterval(null);
70477
71015
  setScreen("main");
70478
71016
  setConfirmDialog(null);
70479
71017
  }
@@ -70503,6 +71041,9 @@ Continue?`;
70503
71041
  case "install":
70504
71042
  handleInstallUninstall();
70505
71043
  break;
71044
+ case "configureStatusLine":
71045
+ setScreen("refreshInterval");
71046
+ break;
70506
71047
  case "starGithub":
70507
71048
  setConfirmDialog({
70508
71049
  message: `Open the ccstatusline GitHub repository in your browser?
@@ -70551,44 +71092,44 @@ ${GITHUB_REPO_URL}`,
70551
71092
  setSelectedLine(lineIndex);
70552
71093
  setScreen("items");
70553
71094
  };
70554
- return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
71095
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70555
71096
  flexDirection: "column",
70556
71097
  children: [
70557
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
71098
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70558
71099
  marginBottom: 1,
70559
71100
  children: [
70560
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71101
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70561
71102
  bold: true,
70562
- children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(dist_default5, {
71103
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(dist_default5, {
70563
71104
  name: "retro",
70564
71105
  children: "CCStatusline Configuration"
70565
71106
  }, undefined, false, undefined, this)
70566
71107
  }, undefined, false, undefined, this),
70567
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71108
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70568
71109
  bold: true,
70569
71110
  children: ` | ${getPackageVersion() && `v${getPackageVersion()}`}`
70570
71111
  }, undefined, false, undefined, this),
70571
- flashMessage && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71112
+ flashMessage && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70572
71113
  color: flashMessage.color,
70573
71114
  bold: true,
70574
71115
  children: ` ${flashMessage.text}`
70575
71116
  }, undefined, false, undefined, this)
70576
71117
  ]
70577
71118
  }, undefined, true, undefined, this),
70578
- isCustomConfigPath() && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71119
+ isCustomConfigPath() && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70579
71120
  dimColor: true,
70580
71121
  children: `Config: ${getConfigPath()}`
70581
71122
  }, undefined, false, undefined, this),
70582
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(StatusLinePreview, {
71123
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(StatusLinePreview, {
70583
71124
  lines: settings.lines,
70584
71125
  terminalWidth,
70585
71126
  settings,
70586
71127
  onTruncationChange: setPreviewIsTruncated
70587
71128
  }, undefined, false, undefined, this),
70588
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
71129
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70589
71130
  marginTop: 1,
70590
71131
  children: [
70591
- screen === "main" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(MainMenu, {
71132
+ screen === "main" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(MainMenu, {
70592
71133
  onSelect: (value, index) => {
70593
71134
  if (value !== "save" && value !== "exit") {
70594
71135
  setMenuSelections((prev) => ({ ...prev, main: index }));
@@ -70602,7 +71143,7 @@ ${GITHUB_REPO_URL}`,
70602
71143
  settings,
70603
71144
  previewIsTruncated
70604
71145
  }, undefined, false, undefined, this),
70605
- screen === "lines" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(LineSelector, {
71146
+ screen === "lines" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(LineSelector, {
70606
71147
  lines: settings.lines,
70607
71148
  onSelect: (line) => {
70608
71149
  setMenuSelections((prev) => ({ ...prev, lines: line }));
@@ -70617,7 +71158,7 @@ ${GITHUB_REPO_URL}`,
70617
71158
  title: "Select Line to Edit Items",
70618
71159
  allowEditing: true
70619
71160
  }, undefined, false, undefined, this),
70620
- screen === "items" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ItemsEditor, {
71161
+ screen === "items" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ItemsEditor, {
70621
71162
  widgets: settings.lines[selectedLine] ?? [],
70622
71163
  onUpdate: (widgets) => {
70623
71164
  updateLine(selectedLine, widgets);
@@ -70629,7 +71170,7 @@ ${GITHUB_REPO_URL}`,
70629
71170
  lineNumber: selectedLine + 1,
70630
71171
  settings
70631
71172
  }, undefined, false, undefined, this),
70632
- screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(LineSelector, {
71173
+ screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(LineSelector, {
70633
71174
  lines: settings.lines,
70634
71175
  onLinesUpdate: updateLines,
70635
71176
  onSelect: (line) => {
@@ -70647,7 +71188,7 @@ ${GITHUB_REPO_URL}`,
70647
71188
  settings,
70648
71189
  allowEditing: false
70649
71190
  }, undefined, false, undefined, this),
70650
- screen === "colors" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ColorMenu, {
71191
+ screen === "colors" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ColorMenu, {
70651
71192
  widgets: settings.lines[selectedLine] ?? [],
70652
71193
  lineIndex: selectedLine,
70653
71194
  settings,
@@ -70660,7 +71201,7 @@ ${GITHUB_REPO_URL}`,
70660
71201
  setScreen("colorLines");
70661
71202
  }
70662
71203
  }, undefined, false, undefined, this),
70663
- screen === "terminalConfig" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(TerminalOptionsMenu, {
71204
+ screen === "terminalConfig" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TerminalOptionsMenu, {
70664
71205
  settings,
70665
71206
  onUpdate: (updatedSettings) => {
70666
71207
  setSettings(updatedSettings);
@@ -70674,7 +71215,7 @@ ${GITHUB_REPO_URL}`,
70674
71215
  }
70675
71216
  }
70676
71217
  }, undefined, false, undefined, this),
70677
- screen === "terminalWidth" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(TerminalWidthMenu, {
71218
+ screen === "terminalWidth" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TerminalWidthMenu, {
70678
71219
  settings,
70679
71220
  onUpdate: (updatedSettings) => {
70680
71221
  setSettings(updatedSettings);
@@ -70683,7 +71224,7 @@ ${GITHUB_REPO_URL}`,
70683
71224
  setScreen("terminalConfig");
70684
71225
  }
70685
71226
  }, undefined, false, undefined, this),
70686
- screen === "globalOverrides" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(GlobalOverridesMenu, {
71227
+ screen === "globalOverrides" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(GlobalOverridesMenu, {
70687
71228
  settings,
70688
71229
  onUpdate: (updatedSettings) => {
70689
71230
  setSettings(updatedSettings);
@@ -70693,7 +71234,7 @@ ${GITHUB_REPO_URL}`,
70693
71234
  setScreen("main");
70694
71235
  }
70695
71236
  }, undefined, false, undefined, this),
70696
- screen === "confirm" && confirmDialog && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ConfirmDialog, {
71237
+ screen === "confirm" && confirmDialog && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ConfirmDialog, {
70697
71238
  message: confirmDialog.message,
70698
71239
  onConfirm: () => void confirmDialog.action(),
70699
71240
  onCancel: () => {
@@ -70701,7 +71242,7 @@ ${GITHUB_REPO_URL}`,
70701
71242
  setConfirmDialog(null);
70702
71243
  }
70703
71244
  }, undefined, false, undefined, this),
70704
- screen === "install" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(InstallMenu, {
71245
+ screen === "install" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(InstallMenu, {
70705
71246
  bunxAvailable: isBunxAvailable(),
70706
71247
  existingStatusLine,
70707
71248
  onSelectNpx: handleNpxInstall,
@@ -70709,7 +71250,31 @@ ${GITHUB_REPO_URL}`,
70709
71250
  onCancel: handleInstallMenuCancel,
70710
71251
  initialSelection: menuSelections.install
70711
71252
  }, undefined, false, undefined, this),
70712
- screen === "powerline" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(PowerlineSetup, {
71253
+ screen === "refreshInterval" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(RefreshIntervalMenu, {
71254
+ currentInterval: currentRefreshInterval,
71255
+ supportsRefreshInterval,
71256
+ onUpdate: (interval) => {
71257
+ const previous = currentRefreshInterval;
71258
+ setCurrentRefreshInterval(interval);
71259
+ setRefreshInterval(interval).then(() => {
71260
+ setFlashMessage({
71261
+ text: "✓ Refresh interval updated",
71262
+ color: "green"
71263
+ });
71264
+ }).catch(() => {
71265
+ setCurrentRefreshInterval(previous);
71266
+ setFlashMessage({
71267
+ text: "✗ Failed to save refresh interval",
71268
+ color: "red"
71269
+ });
71270
+ });
71271
+ setScreen("main");
71272
+ },
71273
+ onBack: () => {
71274
+ setScreen("main");
71275
+ }
71276
+ }, undefined, false, undefined, this),
71277
+ screen === "powerline" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(PowerlineSetup, {
70713
71278
  settings,
70714
71279
  powerlineFontStatus,
70715
71280
  onUpdate: (updatedSettings) => {
@@ -70743,7 +71308,7 @@ ${GITHUB_REPO_URL}`,
70743
71308
  };
70744
71309
  function runTUI() {
70745
71310
  process.stdout.write("\x1B[2J\x1B[H");
70746
- render_default(/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(App2, {}, undefined, false, undefined, this));
71311
+ render_default(/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(App2, {}, undefined, false, undefined, this));
70747
71312
  }
70748
71313
  // src/types/StatusJSON.ts
70749
71314
  init_zod();
@@ -70820,20 +71385,22 @@ var StatusJSONSchema = exports_external.looseObject({
70820
71385
  // src/ccstatusline.ts
70821
71386
  init_ansi();
70822
71387
  init_colors();
70823
- init_config();
70824
- init_jsonl();
71388
+ await __promiseAll([
71389
+ init_config(),
71390
+ init_jsonl()
71391
+ ]);
70825
71392
  await init_renderer2();
70826
71393
 
70827
71394
  // src/utils/skills.ts
70828
71395
  import * as fs13 from "fs";
70829
71396
  import * as os13 from "os";
70830
- import * as path12 from "path";
71397
+ import * as path10 from "path";
70831
71398
  var EMPTY = { totalInvocations: 0, uniqueSkills: [], lastSkill: null };
70832
71399
  function getSkillsDir() {
70833
- return path12.join(os13.homedir(), ".cache", "ccstatusline", "skills");
71400
+ return path10.join(os13.homedir(), ".cache", "ccstatusline", "skills");
70834
71401
  }
70835
71402
  function getSkillsFilePath(sessionId) {
70836
- return path12.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
71403
+ return path10.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
70837
71404
  }
70838
71405
  function getSkillsMetrics(sessionId) {
70839
71406
  const filePath = getSkillsFilePath(sessionId);
@@ -70871,7 +71438,7 @@ function getSkillsMetrics(sessionId) {
70871
71438
  }
70872
71439
  }
70873
71440
  // src/utils/usage-prefetch.ts
70874
- init_usage();
71441
+ await init_usage();
70875
71442
  var USAGE_WIDGET_TYPES = new Set([
70876
71443
  "session-usage",
70877
71444
  "weekly-usage",
@@ -70947,8 +71514,8 @@ async function ensureWindowsUtf8CodePage() {
70947
71514
  return;
70948
71515
  }
70949
71516
  try {
70950
- const { execFileSync: execFileSync3 } = await import("child_process");
70951
- execFileSync3("chcp.com", ["65001"], { stdio: "ignore" });
71517
+ const { execFileSync: execFileSync4 } = await import("child_process");
71518
+ execFileSync4("chcp.com", ["65001"], { stdio: "ignore" });
70952
71519
  } catch {}
70953
71520
  }
70954
71521
  async function renderMultipleLines(data) {
@@ -71085,8 +71652,8 @@ async function handleHook() {
71085
71652
  }
71086
71653
  const filePath = getSkillsFilePath(sessionId);
71087
71654
  const fs14 = await import("fs");
71088
- const path13 = await import("path");
71089
- fs14.mkdirSync(path13.dirname(filePath), { recursive: true });
71655
+ const path11 = await import("path");
71656
+ fs14.mkdirSync(path11.dirname(filePath), { recursive: true });
71090
71657
  const entry = JSON.stringify({
71091
71658
  timestamp: new Date().toISOString(),
71092
71659
  session_id: sessionId,