ccstatusline 2.2.13 → 2.2.14

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.5";
1358
+ exports.version = "19.2.6";
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
  });
@@ -52341,13 +52341,31 @@ var init_Widget = __esm(() => {
52341
52341
  });
52342
52342
 
52343
52343
  // src/types/Settings.ts
52344
- var CURRENT_VERSION = 3, SettingsSchema_v1, SettingsSchema, DEFAULT_SETTINGS;
52344
+ var CURRENT_VERSION = 3, InstallationMetadataSchema, SettingsSchema_v1, SettingsSchema, DEFAULT_SETTINGS;
52345
52345
  var init_Settings = __esm(() => {
52346
52346
  init_zod();
52347
52347
  init_ColorLevel();
52348
52348
  init_FlexMode();
52349
52349
  init_PowerlineConfig();
52350
52350
  init_Widget();
52351
+ InstallationMetadataSchema = exports_external.discriminatedUnion("method", [
52352
+ exports_external.object({
52353
+ method: exports_external.literal("auto-update"),
52354
+ packageManager: exports_external.enum(["npm", "bun"])
52355
+ }),
52356
+ exports_external.object({
52357
+ method: exports_external.literal("pinned"),
52358
+ installedVersion: exports_external.string().optional()
52359
+ }),
52360
+ exports_external.object({
52361
+ method: exports_external.literal("self-managed"),
52362
+ packageManager: exports_external.enum(["npm", "bun", "unknown"]).default("unknown")
52363
+ }),
52364
+ exports_external.object({
52365
+ method: exports_external.literal("unknown"),
52366
+ packageManager: exports_external.enum(["npm", "bun", "unknown"]).default("unknown")
52367
+ })
52368
+ ]);
52351
52369
  SettingsSchema_v1 = exports_external.object({
52352
52370
  lines: exports_external.array(exports_external.array(WidgetItemSchema)).optional(),
52353
52371
  flexMode: FlexModeSchema.optional(),
@@ -52398,7 +52416,8 @@ var init_Settings = __esm(() => {
52398
52416
  updatemessage: exports_external.object({
52399
52417
  message: exports_external.string().nullable().optional(),
52400
52418
  remaining: exports_external.number().nullable().optional()
52401
- }).optional()
52419
+ }).optional(),
52420
+ installation: InstallationMetadataSchema.optional()
52402
52421
  });
52403
52422
  DEFAULT_SETTINGS = SettingsSchema.parse({});
52404
52423
  });
@@ -56136,7 +56155,7 @@ function getTerminalWidth() {
56136
56155
  function canDetectTerminalWidth() {
56137
56156
  return probeTerminalWidth() !== null;
56138
56157
  }
56139
- var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.13";
56158
+ var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils", PACKAGE_VERSION = "2.2.14";
56140
56159
  var init_terminal = () => {};
56141
56160
 
56142
56161
  // src/utils/renderer.ts
@@ -58896,19 +58915,21 @@ var require_supports_color = __commonJS((exports, module) => {
58896
58915
  var tty2 = __require("tty");
58897
58916
  var hasFlag2 = require_has_flag();
58898
58917
  var { env: env3 } = process;
58899
- var forceColor;
58918
+ var flagForceColor2;
58900
58919
  if (hasFlag2("no-color") || hasFlag2("no-colors") || hasFlag2("color=false") || hasFlag2("color=never")) {
58901
- forceColor = 0;
58920
+ flagForceColor2 = 0;
58902
58921
  } else if (hasFlag2("color") || hasFlag2("colors") || hasFlag2("color=true") || hasFlag2("color=always")) {
58903
- forceColor = 1;
58922
+ flagForceColor2 = 1;
58904
58923
  }
58905
- if ("FORCE_COLOR" in env3) {
58906
- if (env3.FORCE_COLOR === "true") {
58907
- forceColor = 1;
58908
- } else if (env3.FORCE_COLOR === "false") {
58909
- forceColor = 0;
58910
- } else {
58911
- forceColor = env3.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env3.FORCE_COLOR, 10), 3);
58924
+ function envForceColor2() {
58925
+ if ("FORCE_COLOR" in env3) {
58926
+ if (env3.FORCE_COLOR === "true") {
58927
+ return 1;
58928
+ }
58929
+ if (env3.FORCE_COLOR === "false") {
58930
+ return 0;
58931
+ }
58932
+ return env3.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env3.FORCE_COLOR, 10), 3);
58912
58933
  }
58913
58934
  }
58914
58935
  function translateLevel2(level) {
@@ -58922,15 +58943,22 @@ var require_supports_color = __commonJS((exports, module) => {
58922
58943
  has16m: level >= 3
58923
58944
  };
58924
58945
  }
58925
- function supportsColor2(haveStream, streamIsTTY) {
58946
+ function supportsColor2(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
58947
+ const noFlagForceColor = envForceColor2();
58948
+ if (noFlagForceColor !== undefined) {
58949
+ flagForceColor2 = noFlagForceColor;
58950
+ }
58951
+ const forceColor = sniffFlags ? flagForceColor2 : noFlagForceColor;
58926
58952
  if (forceColor === 0) {
58927
58953
  return 0;
58928
58954
  }
58929
- if (hasFlag2("color=16m") || hasFlag2("color=full") || hasFlag2("color=truecolor")) {
58930
- return 3;
58931
- }
58932
- if (hasFlag2("color=256")) {
58933
- return 2;
58955
+ if (sniffFlags) {
58956
+ if (hasFlag2("color=16m") || hasFlag2("color=full") || hasFlag2("color=truecolor")) {
58957
+ return 3;
58958
+ }
58959
+ if (hasFlag2("color=256")) {
58960
+ return 2;
58961
+ }
58934
58962
  }
58935
58963
  if (haveStream && !streamIsTTY && forceColor === undefined) {
58936
58964
  return 0;
@@ -58947,7 +58975,7 @@ var require_supports_color = __commonJS((exports, module) => {
58947
58975
  return 1;
58948
58976
  }
58949
58977
  if ("CI" in env3) {
58950
- if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => (sign in env3)) || env3.CI_NAME === "codeship") {
58978
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE", "DRONE"].some((sign) => (sign in env3)) || env3.CI_NAME === "codeship") {
58951
58979
  return 1;
58952
58980
  }
58953
58981
  return min2;
@@ -58959,7 +58987,7 @@ var require_supports_color = __commonJS((exports, module) => {
58959
58987
  return 3;
58960
58988
  }
58961
58989
  if ("TERM_PROGRAM" in env3) {
58962
- const version2 = parseInt((env3.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
58990
+ const version2 = Number.parseInt((env3.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
58963
58991
  switch (env3.TERM_PROGRAM) {
58964
58992
  case "iTerm.app":
58965
58993
  return version2 >= 3 ? 3 : 2;
@@ -58978,14 +59006,17 @@ var require_supports_color = __commonJS((exports, module) => {
58978
59006
  }
58979
59007
  return min2;
58980
59008
  }
58981
- function getSupportLevel(stream) {
58982
- const level = supportsColor2(stream, stream && stream.isTTY);
59009
+ function getSupportLevel(stream, options = {}) {
59010
+ const level = supportsColor2(stream, {
59011
+ streamIsTTY: stream && stream.isTTY,
59012
+ ...options
59013
+ });
58983
59014
  return translateLevel2(level);
58984
59015
  }
58985
59016
  module.exports = {
58986
59017
  supportsColor: getSupportLevel,
58987
- stdout: translateLevel2(supportsColor2(true, tty2.isatty(1))),
58988
- stderr: translateLevel2(supportsColor2(true, tty2.isatty(2)))
59018
+ stdout: getSupportLevel({ isTTY: tty2.isatty(1) }),
59019
+ stderr: getSupportLevel({ isTTY: tty2.isatty(2) })
58989
59020
  };
58990
59021
  });
58991
59022
 
@@ -67592,6 +67623,23 @@ async function saveSettings(settings) {
67592
67623
  await syncWidgetHooks2(settings);
67593
67624
  } catch {}
67594
67625
  }
67626
+ async function saveInstallationMetadata(metadata) {
67627
+ const paths = getSettingsPaths();
67628
+ if (!metadata && !fs10.existsSync(paths.settingsPath)) {
67629
+ return;
67630
+ }
67631
+ const settings = await loadSettings();
67632
+ const settingsWithVersion = {
67633
+ ...settings,
67634
+ version: CURRENT_VERSION
67635
+ };
67636
+ if (metadata) {
67637
+ settingsWithVersion.installation = metadata;
67638
+ } else {
67639
+ delete settingsWithVersion.installation;
67640
+ }
67641
+ await writeSettingsJson(settingsWithVersion, paths);
67642
+ }
67595
67643
  var readFile3, writeFile, mkdir, DEFAULT_SETTINGS_PATH, settingsPath;
67596
67644
  var init_config = __esm(async () => {
67597
67645
  init_Settings();
@@ -67610,7 +67658,7 @@ import * as fs11 from "fs";
67610
67658
  import * as os9 from "os";
67611
67659
  import * as path8 from "path";
67612
67660
  function isKnownCommand(command) {
67613
- const prefixes = [CCSTATUSLINE_COMMANDS.NPM, CCSTATUSLINE_COMMANDS.BUNX, CCSTATUSLINE_COMMANDS.SELF_MANAGED];
67661
+ const prefixes = [CCSTATUSLINE_COMMANDS.AUTO_NPX, CCSTATUSLINE_COMMANDS.AUTO_BUNX, CCSTATUSLINE_COMMANDS.GLOBAL];
67614
67662
  return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `)) || /(?:^|[\s"'\\/])ccstatusline\.ts(?=$|[\s"'])/.test(command);
67615
67663
  }
67616
67664
  function needsQuoting(filePath) {
@@ -67719,15 +67767,35 @@ async function isInstalled() {
67719
67767
  const command = settings.statusLine?.command ?? "";
67720
67768
  return isKnownCommand(command) && (settings.statusLine?.padding === 0 || settings.statusLine?.padding === undefined);
67721
67769
  }
67722
- function isBunxAvailable() {
67770
+ function isExecutableAvailable(executable) {
67723
67771
  try {
67724
- const command = process.platform === "win32" ? "where bunx" : "which bunx";
67772
+ const command = process.platform === "win32" ? `where ${executable}` : `which ${executable}`;
67725
67773
  execSync4(command, { stdio: "ignore" });
67726
67774
  return true;
67727
67775
  } catch {
67728
67776
  return false;
67729
67777
  }
67730
67778
  }
67779
+ function isNpmAvailable() {
67780
+ return isExecutableAvailable("npm");
67781
+ }
67782
+ function isNpxAvailable() {
67783
+ return isExecutableAvailable("npx");
67784
+ }
67785
+ function isBunAvailable() {
67786
+ return isExecutableAvailable("bun");
67787
+ }
67788
+ function isBunxAvailable() {
67789
+ return isExecutableAvailable("bunx");
67790
+ }
67791
+ function getPackageCommandAvailability() {
67792
+ return {
67793
+ npm: isNpmAvailable(),
67794
+ npx: isNpxAvailable(),
67795
+ bun: isBunAvailable(),
67796
+ bunx: isBunxAvailable()
67797
+ };
67798
+ }
67731
67799
  function getClaudeCodeVersion() {
67732
67800
  try {
67733
67801
  const output = execSync4("claude --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"], timeout: 5000 }).trim();
@@ -67762,6 +67830,59 @@ function buildCommand(baseCommand) {
67762
67830
  }
67763
67831
  return baseCommand;
67764
67832
  }
67833
+ function getBaseCommandForMode(commandMode) {
67834
+ switch (commandMode) {
67835
+ case "auto-npx":
67836
+ return CCSTATUSLINE_COMMANDS.AUTO_NPX;
67837
+ case "auto-bunx":
67838
+ return CCSTATUSLINE_COMMANDS.AUTO_BUNX;
67839
+ case "global":
67840
+ return CCSTATUSLINE_COMMANDS.GLOBAL;
67841
+ }
67842
+ }
67843
+ function buildStatusLineCommand(commandMode) {
67844
+ return buildCommand(getBaseCommandForMode(commandMode));
67845
+ }
67846
+ function matchesCommandBase(command, baseCommand) {
67847
+ return command === baseCommand || command.startsWith(`${baseCommand} --config `);
67848
+ }
67849
+ function isLocalDevelopmentCommand(command) {
67850
+ return /(?:^|[\s"'\\/])ccstatusline\.ts(?=$|[\s"'])/.test(command);
67851
+ }
67852
+ function classifyInstallation(command, metadata) {
67853
+ const statusLineCommand = command ?? "";
67854
+ if (matchesCommandBase(statusLineCommand, CCSTATUSLINE_COMMANDS.AUTO_NPX)) {
67855
+ return {
67856
+ method: "auto-update",
67857
+ packageManager: "npm"
67858
+ };
67859
+ }
67860
+ if (matchesCommandBase(statusLineCommand, CCSTATUSLINE_COMMANDS.AUTO_BUNX)) {
67861
+ return {
67862
+ method: "auto-update",
67863
+ packageManager: "bun"
67864
+ };
67865
+ }
67866
+ if (matchesCommandBase(statusLineCommand, CCSTATUSLINE_COMMANDS.GLOBAL)) {
67867
+ if (metadata?.method === "pinned") {
67868
+ return metadata;
67869
+ }
67870
+ return {
67871
+ method: "self-managed",
67872
+ packageManager: "unknown"
67873
+ };
67874
+ }
67875
+ if (isLocalDevelopmentCommand(statusLineCommand)) {
67876
+ return {
67877
+ method: "self-managed",
67878
+ packageManager: "unknown"
67879
+ };
67880
+ }
67881
+ return {
67882
+ method: "unknown",
67883
+ packageManager: "unknown"
67884
+ };
67885
+ }
67765
67886
  async function loadSavedSettingsForHookSync() {
67766
67887
  const configPath = getConfigPath();
67767
67888
  if (!fs11.existsSync(configPath)) {
@@ -67779,7 +67900,11 @@ async function loadSavedSettingsForHookSync() {
67779
67900
  return null;
67780
67901
  }
67781
67902
  }
67782
- async function installStatusLine(useBunx = false, supportsRefreshInterval = false) {
67903
+ async function installStatusLine({
67904
+ commandMode,
67905
+ supportsRefreshInterval = false,
67906
+ installationMetadata
67907
+ }) {
67783
67908
  let settings;
67784
67909
  const backupPath = await backupClaudeSettings(".orig");
67785
67910
  try {
@@ -67789,17 +67914,19 @@ async function installStatusLine(useBunx = false, supportsRefreshInterval = fals
67789
67914
  console.error(`Warning: Could not read existing Claude settings. A backup exists at ${backupPath ?? fallbackBackupPath}.`);
67790
67915
  settings = {};
67791
67916
  }
67792
- const baseCommand = useBunx ? CCSTATUSLINE_COMMANDS.BUNX : CCSTATUSLINE_COMMANDS.NPM;
67793
67917
  const existingRefreshInterval = settings.statusLine?.refreshInterval;
67794
67918
  settings.statusLine = {
67795
67919
  type: "command",
67796
- command: buildCommand(baseCommand),
67920
+ command: buildStatusLineCommand(commandMode),
67797
67921
  padding: 0
67798
67922
  };
67799
67923
  if (supportsRefreshInterval) {
67800
67924
  settings.statusLine.refreshInterval = existingRefreshInterval ?? 10;
67801
67925
  }
67802
67926
  await saveClaudeSettings(settings);
67927
+ if (installationMetadata !== undefined) {
67928
+ await saveInstallationMetadata(installationMetadata);
67929
+ }
67803
67930
  const savedSettings = await loadSavedSettingsForHookSync();
67804
67931
  if (savedSettings) {
67805
67932
  const { syncWidgetHooks: syncWidgetHooks2 } = await init_hooks().then(() => exports_hooks);
@@ -67818,6 +67945,7 @@ async function uninstallStatusLine() {
67818
67945
  delete settings.statusLine;
67819
67946
  await saveClaudeSettings(settings);
67820
67947
  }
67948
+ await saveInstallationMetadata(undefined);
67821
67949
  try {
67822
67950
  const { removeManagedHooks: removeManagedHooks2 } = await init_hooks().then(() => exports_hooks);
67823
67951
  await removeManagedHooks2();
@@ -67900,7 +68028,7 @@ function getVoiceConfig(cwd2 = process.cwd()) {
67900
68028
  }
67901
68029
  return anyFileExisted ? { enabled: false } : null;
67902
68030
  }
67903
- var readFile4, writeFile2, mkdir2, CCSTATUSLINE_COMMANDS, VoiceConfigSchema;
68031
+ var readFile4, writeFile2, mkdir2, CCSTATUSLINE_COMMANDS, PINNED_INSTALL_COMMANDS, VoiceConfigSchema;
67904
68032
  var init_claude_settings = __esm(async () => {
67905
68033
  init_zod();
67906
68034
  init_Settings();
@@ -67909,10 +68037,17 @@ var init_claude_settings = __esm(async () => {
67909
68037
  writeFile2 = fs11.promises.writeFile;
67910
68038
  mkdir2 = fs11.promises.mkdir;
67911
68039
  CCSTATUSLINE_COMMANDS = {
68040
+ AUTO_NPX: "npx -y ccstatusline@latest",
68041
+ AUTO_BUNX: "bunx -y ccstatusline@latest",
68042
+ GLOBAL: "ccstatusline",
67912
68043
  NPM: "npx -y ccstatusline@latest",
67913
68044
  BUNX: "bunx -y ccstatusline@latest",
67914
68045
  SELF_MANAGED: "ccstatusline"
67915
68046
  };
68047
+ PINNED_INSTALL_COMMANDS = {
68048
+ NPM: (version2) => `npm install -g ccstatusline@${version2}`,
68049
+ BUN: (version2) => `bun add -g ccstatusline@${version2}`
68050
+ };
67916
68051
  VoiceConfigSchema = exports_external.object({ enabled: exports_external.boolean().optional() });
67917
68052
  });
67918
68053
 
@@ -68486,7 +68621,7 @@ var dist_default5 = Gradient;
68486
68621
 
68487
68622
  // src/tui/App.tsx
68488
68623
  await init_claude_settings();
68489
- var import_react50 = __toESM(require_react(), 1);
68624
+ var import_react51 = __toESM(require_react(), 1);
68490
68625
 
68491
68626
  // src/utils/clone-settings.ts
68492
68627
  function cloneSettings(settings) {
@@ -68500,6 +68635,364 @@ function cloneSettings(settings) {
68500
68635
  // src/tui/App.tsx
68501
68636
  await init_config();
68502
68637
 
68638
+ // src/utils/global-command-resolution.ts
68639
+ import { execFileSync as execFileSync5 } from "child_process";
68640
+ import * as path9 from "path";
68641
+
68642
+ // src/utils/package-manager-executable.ts
68643
+ function getPackageManagerExecutable(packageManager, platform2 = process.platform) {
68644
+ return packageManager === "npm" && platform2 === "win32" ? "npm.cmd" : packageManager;
68645
+ }
68646
+
68647
+ // src/utils/global-command-resolution.ts
68648
+ var COMMAND_LOOKUP_TIMEOUT_MS = 5000;
68649
+ function splitCommandOutput(output) {
68650
+ const seen = new Set;
68651
+ const paths = [];
68652
+ for (const line of output.split(/\r?\n/)) {
68653
+ const candidate = line.trim();
68654
+ if (!candidate || seen.has(candidate)) {
68655
+ continue;
68656
+ }
68657
+ seen.add(candidate);
68658
+ paths.push(candidate);
68659
+ }
68660
+ return paths;
68661
+ }
68662
+ function getCommandResolutionPaths(command, { platform: platform2 = process.platform } = {}) {
68663
+ try {
68664
+ const output = platform2 === "win32" ? execFileSync5("where", [command], { encoding: "utf-8", timeout: COMMAND_LOOKUP_TIMEOUT_MS }) : execFileSync5("which", ["-a", command], { encoding: "utf-8", timeout: COMMAND_LOOKUP_TIMEOUT_MS });
68665
+ return splitCommandOutput(output);
68666
+ } catch {
68667
+ return [];
68668
+ }
68669
+ }
68670
+ function getNpmGlobalBinDir(platform2) {
68671
+ try {
68672
+ const prefix = execFileSync5(getPackageManagerExecutable("npm", platform2), ["prefix", "-g"], {
68673
+ encoding: "utf-8",
68674
+ timeout: COMMAND_LOOKUP_TIMEOUT_MS
68675
+ }).trim();
68676
+ if (!prefix) {
68677
+ return null;
68678
+ }
68679
+ return platform2 === "win32" || /^[a-z]:[\\/]/i.test(prefix) ? prefix : path9.join(prefix, "bin");
68680
+ } catch {
68681
+ return null;
68682
+ }
68683
+ }
68684
+ function getBunGlobalBinDir() {
68685
+ try {
68686
+ const binDir = execFileSync5("bun", ["pm", "bin", "-g"], {
68687
+ encoding: "utf-8",
68688
+ timeout: COMMAND_LOOKUP_TIMEOUT_MS
68689
+ }).trim();
68690
+ return binDir || null;
68691
+ } catch {
68692
+ return null;
68693
+ }
68694
+ }
68695
+ function getExpectedGlobalBinDir(packageManager, { platform: platform2 = process.platform } = {}) {
68696
+ return packageManager === "npm" ? getNpmGlobalBinDir(platform2) : getBunGlobalBinDir();
68697
+ }
68698
+ function trimTrailingSlashes(value) {
68699
+ if (/^[a-z]:\/$/i.test(value) || value === "/") {
68700
+ return value;
68701
+ }
68702
+ return value.replace(/\/+$/, "");
68703
+ }
68704
+ function normalizePathForComparison(filePath) {
68705
+ const normalized = trimTrailingSlashes(filePath.trim().replace(/\\/g, "/"));
68706
+ return /^[a-z]:\//i.test(normalized) || normalized.startsWith("/mnt/") ? normalized.toLowerCase() : normalized;
68707
+ }
68708
+ function getPathComparisonVariants(filePath) {
68709
+ const normalized = normalizePathForComparison(filePath);
68710
+ const variants = new Set([normalized]);
68711
+ const driveMatch = /^([a-z]):\/(.*)$/i.exec(normalized);
68712
+ if (driveMatch) {
68713
+ variants.add(`/mnt/${driveMatch[1]?.toLowerCase()}/${driveMatch[2] ?? ""}`);
68714
+ }
68715
+ const wslMountMatch = /^\/mnt\/([a-z])\/(.*)$/i.exec(normalized);
68716
+ if (wslMountMatch) {
68717
+ variants.add(`${wslMountMatch[1]?.toLowerCase()}:/${wslMountMatch[2] ?? ""}`);
68718
+ }
68719
+ return Array.from(variants);
68720
+ }
68721
+ function getDirectoryName(filePath) {
68722
+ const normalized = filePath.replace(/\\/g, "/");
68723
+ const lastSlashIndex = normalized.lastIndexOf("/");
68724
+ return lastSlashIndex === -1 ? "" : normalized.slice(0, lastSlashIndex);
68725
+ }
68726
+ function getUniqueResolvedDirs(resolvedPaths) {
68727
+ const seen = new Set;
68728
+ const dirs = [];
68729
+ for (const resolvedPath of resolvedPaths) {
68730
+ const dir = getDirectoryName(resolvedPath);
68731
+ const comparableDir = normalizePathForComparison(dir);
68732
+ if (seen.has(comparableDir)) {
68733
+ continue;
68734
+ }
68735
+ seen.add(comparableDir);
68736
+ dirs.push(dir);
68737
+ }
68738
+ return dirs;
68739
+ }
68740
+ function isPathInsideDir(filePath, dir) {
68741
+ const pathVariants = getPathComparisonVariants(filePath);
68742
+ const dirVariants = getPathComparisonVariants(dir);
68743
+ return pathVariants.some((pathVariant) => dirVariants.some((dirVariant) => {
68744
+ const withSlash = dirVariant.endsWith("/") ? dirVariant : `${dirVariant}/`;
68745
+ return pathVariant === dirVariant || pathVariant.startsWith(withSlash);
68746
+ }));
68747
+ }
68748
+ function formatPathList(paths) {
68749
+ return paths.join(", ");
68750
+ }
68751
+ function getResolutionWarning(packageManager, resolvedPaths, expectedBinDir) {
68752
+ const firstResolvedPath = resolvedPaths[0] ?? null;
68753
+ if (!firstResolvedPath) {
68754
+ return "⚠ ccstatusline is not currently resolvable on PATH. Claude Code runs ccstatusline, so restart your shell or update PATH if it cannot launch.";
68755
+ }
68756
+ const resolvedDirs = getUniqueResolvedDirs(resolvedPaths);
68757
+ if (resolvedDirs.length > 1) {
68758
+ return `⚠ Multiple ccstatusline binaries are on PATH. Claude Code will run the first match: ${firstResolvedPath}.
68759
+ Other matches: ${formatPathList(resolvedPaths.slice(1))}`;
68760
+ }
68761
+ if (expectedBinDir && !isPathInsideDir(firstResolvedPath, expectedBinDir)) {
68762
+ return `⚠ ccstatusline resolves to ${firstResolvedPath}, which is outside the ${packageManager} global bin directory (${expectedBinDir}). Claude Code will run the first PATH match.`;
68763
+ }
68764
+ return null;
68765
+ }
68766
+ function inspectGlobalCommandResolution(packageManager, options = {}) {
68767
+ const resolvedPaths = getCommandResolutionPaths("ccstatusline", options);
68768
+ const expectedBinDir = getExpectedGlobalBinDir(packageManager, options);
68769
+ return {
68770
+ resolvedPaths,
68771
+ firstResolvedPath: resolvedPaths[0] ?? null,
68772
+ expectedBinDir,
68773
+ warning: getResolutionWarning(packageManager, resolvedPaths, expectedBinDir)
68774
+ };
68775
+ }
68776
+
68777
+ // src/utils/global-package-manager.ts
68778
+ import {
68779
+ execFile,
68780
+ execFileSync as execFileSync6
68781
+ } from "child_process";
68782
+ import * as fs12 from "fs";
68783
+ var GLOBAL_PACKAGE_TIMEOUT_MS = 120000;
68784
+ var VERSION_LOOKUP_TIMEOUT_MS = 5000;
68785
+ var WINDOWS_SHIM_EXTENSIONS = [
68786
+ "",
68787
+ ".cmd",
68788
+ ".ps1"
68789
+ ];
68790
+ function isWindowsStylePath(filePath) {
68791
+ return /^[a-z]:[\\/]/i.test(filePath);
68792
+ }
68793
+ function trimTrailingSeparators(filePath) {
68794
+ return filePath.replace(/[\\/]+$/, "");
68795
+ }
68796
+ function appendPathSegment(dir, segment) {
68797
+ const separator = dir.includes("\\") && !dir.includes("/") ? "\\" : "/";
68798
+ return `${trimTrailingSeparators(dir)}${separator}${segment}`;
68799
+ }
68800
+ function toWindowsPath(filePath) {
68801
+ const match = /^\/mnt\/([a-z])\/(.*)$/i.exec(filePath.replace(/\\/g, "/"));
68802
+ if (!match) {
68803
+ return null;
68804
+ }
68805
+ return `${match[1]?.toUpperCase()}:\\${(match[2] ?? "").replace(/\//g, "\\")}`;
68806
+ }
68807
+ function toWslPath(filePath) {
68808
+ const match = /^([a-z]):[\\/](.*)$/i.exec(filePath);
68809
+ if (!match) {
68810
+ return null;
68811
+ }
68812
+ return `/mnt/${match[1]?.toLowerCase()}/${(match[2] ?? "").replace(/\\/g, "/")}`;
68813
+ }
68814
+ function getFilesystemPathVariants(filePath) {
68815
+ const variants = new Set([filePath]);
68816
+ const windowsPath = toWindowsPath(filePath);
68817
+ const wslPath = toWslPath(filePath);
68818
+ if (windowsPath) {
68819
+ variants.add(windowsPath);
68820
+ }
68821
+ if (wslPath) {
68822
+ variants.add(wslPath);
68823
+ }
68824
+ return Array.from(variants);
68825
+ }
68826
+ function getBinaryPathCandidates(binDir, platform2) {
68827
+ const extensions = platform2 === "win32" || isWindowsStylePath(binDir) ? WINDOWS_SHIM_EXTENSIONS : [""];
68828
+ return extensions.map((extension) => appendPathSegment(binDir, `ccstatusline${extension}`));
68829
+ }
68830
+ function hasBinaryOnDisk(binDir, platform2) {
68831
+ return getBinaryPathCandidates(binDir, platform2).some((candidate) => getFilesystemPathVariants(candidate).some((variant) => fs12.existsSync(variant)));
68832
+ }
68833
+ function hasResolvedBinaryInDir(resolvedPaths, binDir) {
68834
+ return resolvedPaths.some((resolvedPath) => isPathInsideDir(resolvedPath, binDir));
68835
+ }
68836
+ function getDirectoryName2(filePath) {
68837
+ const normalized = filePath.replace(/\\/g, "/");
68838
+ const lastSlashIndex = normalized.lastIndexOf("/");
68839
+ return lastSlashIndex === -1 ? "" : normalized.slice(0, lastSlashIndex);
68840
+ }
68841
+ function getComparablePath(filePath) {
68842
+ return filePath.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
68843
+ }
68844
+ function getUniqueResolvedDirs2(resolvedPaths) {
68845
+ const seen = new Set;
68846
+ const dirs = [];
68847
+ for (const resolvedPath of resolvedPaths) {
68848
+ const dir = getDirectoryName2(resolvedPath);
68849
+ const comparableDir = getComparablePath(dir);
68850
+ if (seen.has(comparableDir)) {
68851
+ continue;
68852
+ }
68853
+ seen.add(comparableDir);
68854
+ dirs.push(dir);
68855
+ }
68856
+ return dirs;
68857
+ }
68858
+ function formatPathList2(paths) {
68859
+ return paths.join(", ");
68860
+ }
68861
+ function readPackageVersion(packageJsonPath) {
68862
+ for (const variant of getFilesystemPathVariants(packageJsonPath)) {
68863
+ try {
68864
+ if (!fs12.existsSync(variant)) {
68865
+ continue;
68866
+ }
68867
+ const packageJson = JSON.parse(fs12.readFileSync(variant, "utf-8"));
68868
+ return typeof packageJson.version === "string" ? packageJson.version : null;
68869
+ } catch {
68870
+ return null;
68871
+ }
68872
+ }
68873
+ return null;
68874
+ }
68875
+ function getNpmGlobalPackageVersion(platform2) {
68876
+ try {
68877
+ const rootDir = execFileSync6(getPackageManagerExecutable("npm", platform2), ["root", "-g"], {
68878
+ encoding: "utf-8",
68879
+ timeout: VERSION_LOOKUP_TIMEOUT_MS
68880
+ }).trim();
68881
+ return rootDir ? readPackageVersion(appendPathSegment(appendPathSegment(rootDir, "ccstatusline"), "package.json")) : null;
68882
+ } catch {
68883
+ return null;
68884
+ }
68885
+ }
68886
+ function getBunInstallRoot(binDir) {
68887
+ const normalized = trimTrailingSeparators(binDir.replace(/\\/g, "/"));
68888
+ const lower = normalized.toLowerCase();
68889
+ return lower.endsWith("/bin") ? normalized.slice(0, -4) : normalized;
68890
+ }
68891
+ function getBunGlobalPackageVersion(binDir) {
68892
+ if (!binDir) {
68893
+ return null;
68894
+ }
68895
+ return readPackageVersion(appendPathSegment(appendPathSegment(appendPathSegment(appendPathSegment(appendPathSegment(getBunInstallRoot(binDir), "install"), "global"), "node_modules"), "ccstatusline"), "package.json"));
68896
+ }
68897
+ function getGlobalPackageVersion(packageManager, binDir, platform2) {
68898
+ if (packageManager === "npm") {
68899
+ return getNpmGlobalPackageVersion(platform2);
68900
+ }
68901
+ if (packageManager === "bun") {
68902
+ return getBunGlobalPackageVersion(binDir);
68903
+ }
68904
+ return null;
68905
+ }
68906
+ function inspectPackageManager(packageManager, available, resolvedPaths, platform2) {
68907
+ const binDir = available ? getExpectedGlobalBinDir(packageManager, { platform: platform2 }) : null;
68908
+ return {
68909
+ packageManager,
68910
+ available,
68911
+ installed: !!binDir && (hasBinaryOnDisk(binDir, platform2) || hasResolvedBinaryInDir(resolvedPaths, binDir)),
68912
+ binDir
68913
+ };
68914
+ }
68915
+ function getManagerBinDir(packageManager, available, platform2) {
68916
+ return available ? getExpectedGlobalBinDir(packageManager, { platform: platform2 }) : null;
68917
+ }
68918
+ function getActivePackageManager(resolvedPath, managerBins) {
68919
+ if (managerBins.bun && isPathInsideDir(resolvedPath, managerBins.bun)) {
68920
+ return {
68921
+ packageManager: "bun",
68922
+ binDir: managerBins.bun
68923
+ };
68924
+ }
68925
+ if (managerBins.npm && isPathInsideDir(resolvedPath, managerBins.npm)) {
68926
+ return {
68927
+ packageManager: "npm",
68928
+ binDir: managerBins.npm
68929
+ };
68930
+ }
68931
+ return {
68932
+ packageManager: "unknown",
68933
+ binDir: null
68934
+ };
68935
+ }
68936
+ function getActiveResolutionWarning(resolvedPaths, active) {
68937
+ if (!active.resolvedPath) {
68938
+ return "⚠ ccstatusline is not currently resolvable on PATH. Claude Code runs ccstatusline, so restart your shell or update PATH if it cannot launch.";
68939
+ }
68940
+ const resolvedDirs = getUniqueResolvedDirs2(resolvedPaths);
68941
+ if (resolvedDirs.length > 1) {
68942
+ return `⚠ Multiple ccstatusline binaries are on PATH. Claude Code will run the first match: ${active.resolvedPath}.
68943
+ Other matches: ${formatPathList2(resolvedPaths.slice(1))}`;
68944
+ }
68945
+ if (active.packageManager === "unknown") {
68946
+ return `⚠ ccstatusline resolves to ${active.resolvedPath}, but it is outside the detected npm and bun global bin directories.`;
68947
+ }
68948
+ return null;
68949
+ }
68950
+ function inspectActiveGlobalCommand({
68951
+ commandAvailability,
68952
+ platform: platform2 = process.platform
68953
+ }) {
68954
+ const resolvedPaths = getCommandResolutionPaths("ccstatusline", { platform: platform2 });
68955
+ const resolvedPath = resolvedPaths[0] ?? null;
68956
+ const managerBins = {
68957
+ npm: getManagerBinDir("npm", commandAvailability.npm, platform2),
68958
+ bun: getManagerBinDir("bun", commandAvailability.bun, platform2)
68959
+ };
68960
+ const active = resolvedPath ? getActivePackageManager(resolvedPath, managerBins) : { packageManager: "unknown", binDir: null };
68961
+ return {
68962
+ ...active,
68963
+ resolvedPath,
68964
+ resolvedPaths,
68965
+ version: resolvedPath ? getGlobalPackageVersion(active.packageManager, active.binDir, platform2) : null,
68966
+ warning: getActiveResolutionWarning(resolvedPaths, {
68967
+ packageManager: active.packageManager,
68968
+ resolvedPath
68969
+ })
68970
+ };
68971
+ }
68972
+ function inspectGlobalPackageInstallations({
68973
+ commandAvailability,
68974
+ platform: platform2 = process.platform
68975
+ }) {
68976
+ const resolvedPaths = getCommandResolutionPaths("ccstatusline", { platform: platform2 });
68977
+ return [
68978
+ inspectPackageManager("npm", commandAvailability.npm, resolvedPaths, platform2),
68979
+ inspectPackageManager("bun", commandAvailability.bun, resolvedPaths, platform2)
68980
+ ];
68981
+ }
68982
+ function runGlobalPackageUninstall(packageManager, { platform: platform2 = process.platform } = {}) {
68983
+ const executable = getPackageManagerExecutable(packageManager, platform2);
68984
+ const args = packageManager === "npm" ? ["uninstall", "-g", "ccstatusline"] : ["remove", "-g", "ccstatusline"];
68985
+ return new Promise((resolve5, reject2) => {
68986
+ execFile(executable, args, { timeout: GLOBAL_PACKAGE_TIMEOUT_MS }, (error48) => {
68987
+ if (error48) {
68988
+ reject2(error48 instanceof Error ? error48 : new Error("Global uninstall command failed"));
68989
+ return;
68990
+ }
68991
+ resolve5();
68992
+ });
68993
+ });
68994
+ }
68995
+
68503
68996
  // src/utils/open-url.ts
68504
68997
  import { spawnSync } from "child_process";
68505
68998
  import * as os10 from "os";
@@ -68589,9 +69082,9 @@ function openExternalUrl(url2) {
68589
69082
 
68590
69083
  // src/utils/powerline.ts
68591
69084
  import { execSync as execSync5 } from "child_process";
68592
- import * as fs12 from "fs";
69085
+ import * as fs13 from "fs";
68593
69086
  import * as os11 from "os";
68594
- import * as path9 from "path";
69087
+ import * as path10 from "path";
68595
69088
  var fontsInstalledThisSession = false;
68596
69089
  function checkPowerlineFonts() {
68597
69090
  if (process.env.DEBUG_FONT_INSTALL === "1" && !fontsInstalledThisSession) {
@@ -68611,20 +69104,20 @@ function checkPowerlineFonts() {
68611
69104
  let fontPaths = [];
68612
69105
  if (platform4 === "darwin") {
68613
69106
  fontPaths = [
68614
- path9.join(os11.homedir(), "Library", "Fonts"),
69107
+ path10.join(os11.homedir(), "Library", "Fonts"),
68615
69108
  "/Library/Fonts",
68616
69109
  "/System/Library/Fonts"
68617
69110
  ];
68618
69111
  } else if (platform4 === "linux") {
68619
69112
  fontPaths = [
68620
- path9.join(os11.homedir(), ".local", "share", "fonts"),
68621
- path9.join(os11.homedir(), ".fonts"),
69113
+ path10.join(os11.homedir(), ".local", "share", "fonts"),
69114
+ path10.join(os11.homedir(), ".fonts"),
68622
69115
  "/usr/share/fonts",
68623
69116
  "/usr/local/share/fonts"
68624
69117
  ];
68625
69118
  } else if (platform4 === "win32") {
68626
69119
  fontPaths = [
68627
- path9.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
69120
+ path10.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts"),
68628
69121
  "C:\\Windows\\Fonts"
68629
69122
  ];
68630
69123
  }
@@ -68640,9 +69133,9 @@ function checkPowerlineFonts() {
68640
69133
  /fira.*code.*nerd/i
68641
69134
  ];
68642
69135
  for (const fontPath of fontPaths) {
68643
- if (fs12.existsSync(fontPath)) {
69136
+ if (fs13.existsSync(fontPath)) {
68644
69137
  try {
68645
- const files = fs12.readdirSync(fontPath);
69138
+ const files = fs13.readdirSync(fontPath);
68646
69139
  for (const file2 of files) {
68647
69140
  for (const pattern of powerlineFontPatterns) {
68648
69141
  if (pattern.test(file2)) {
@@ -68703,33 +69196,33 @@ async function installPowerlineFonts() {
68703
69196
  const platform4 = os11.platform();
68704
69197
  let fontDir;
68705
69198
  if (platform4 === "darwin") {
68706
- fontDir = path9.join(os11.homedir(), "Library", "Fonts");
69199
+ fontDir = path10.join(os11.homedir(), "Library", "Fonts");
68707
69200
  } else if (platform4 === "linux") {
68708
- fontDir = path9.join(os11.homedir(), ".local", "share", "fonts");
69201
+ fontDir = path10.join(os11.homedir(), ".local", "share", "fonts");
68709
69202
  } else if (platform4 === "win32") {
68710
- fontDir = path9.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
69203
+ fontDir = path10.join(os11.homedir(), "AppData", "Local", "Microsoft", "Windows", "Fonts");
68711
69204
  } else {
68712
69205
  return {
68713
69206
  success: false,
68714
69207
  message: "Unsupported platform for font installation"
68715
69208
  };
68716
69209
  }
68717
- if (!fs12.existsSync(fontDir)) {
68718
- fs12.mkdirSync(fontDir, { recursive: true });
69210
+ if (!fs13.existsSync(fontDir)) {
69211
+ fs13.mkdirSync(fontDir, { recursive: true });
68719
69212
  }
68720
- const tempDir = path9.join(os11.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
69213
+ const tempDir = path10.join(os11.tmpdir(), `ccstatusline-powerline-fonts-${Date.now()}`);
68721
69214
  try {
68722
- if (fs12.existsSync(tempDir)) {
68723
- fs12.rmSync(tempDir, { recursive: true, force: true });
69215
+ if (fs13.existsSync(tempDir)) {
69216
+ fs13.rmSync(tempDir, { recursive: true, force: true });
68724
69217
  }
68725
69218
  execSync5(`git clone --depth=1 https://github.com/powerline/fonts.git "${tempDir}"`, {
68726
69219
  stdio: "pipe",
68727
69220
  encoding: "utf8"
68728
69221
  });
68729
69222
  if (platform4 === "darwin" || platform4 === "linux") {
68730
- const installScript = path9.join(tempDir, "install.sh");
68731
- if (fs12.existsSync(installScript)) {
68732
- fs12.chmodSync(installScript, 493);
69223
+ const installScript = path10.join(tempDir, "install.sh");
69224
+ if (fs13.existsSync(installScript)) {
69225
+ fs13.chmodSync(installScript, 493);
68733
69226
  execSync5(`cd "${tempDir}" && ./install.sh`, {
68734
69227
  stdio: "pipe",
68735
69228
  encoding: "utf8",
@@ -68755,10 +69248,10 @@ async function installPowerlineFonts() {
68755
69248
  }
68756
69249
  } else {
68757
69250
  let findFontFiles = function(dir) {
68758
- const files = fs12.readdirSync(dir);
69251
+ const files = fs13.readdirSync(dir);
68759
69252
  for (const file2 of files) {
68760
- const filePath = path9.join(dir, file2);
68761
- const stat2 = fs12.statSync(filePath);
69253
+ const filePath = path10.join(dir, file2);
69254
+ const stat2 = fs13.statSync(filePath);
68762
69255
  if (stat2.isDirectory() && !file2.startsWith(".")) {
68763
69256
  findFontFiles(filePath);
68764
69257
  } else if (file2.endsWith(".ttf") || file2.endsWith(".otf")) {
@@ -68772,10 +69265,10 @@ async function installPowerlineFonts() {
68772
69265
  findFontFiles(tempDir);
68773
69266
  let installedCount = 0;
68774
69267
  for (const fontFile of fontFiles) {
68775
- const fileName = path9.basename(fontFile);
68776
- const destPath = path9.join(fontDir, fileName);
69268
+ const fileName = path10.basename(fontFile);
69269
+ const destPath = path10.join(fontDir, fileName);
68777
69270
  try {
68778
- fs12.copyFileSync(fontFile, destPath);
69271
+ fs13.copyFileSync(fontFile, destPath);
68779
69272
  installedCount++;
68780
69273
  } catch {}
68781
69274
  }
@@ -68793,9 +69286,9 @@ async function installPowerlineFonts() {
68793
69286
  message: "Platform-specific installation not implemented"
68794
69287
  };
68795
69288
  } finally {
68796
- if (fs12.existsSync(tempDir)) {
69289
+ if (fs13.existsSync(tempDir)) {
68797
69290
  try {
68798
- fs12.rmSync(tempDir, { recursive: true, force: true });
69291
+ fs13.rmSync(tempDir, { recursive: true, force: true });
68799
69292
  } catch {}
68800
69293
  }
68801
69294
  }
@@ -68817,6 +69310,204 @@ async function installPowerlineFonts() {
68817
69310
  // src/tui/App.tsx
68818
69311
  init_terminal();
68819
69312
 
69313
+ // src/utils/update-checker.ts
69314
+ await init_claude_settings();
69315
+ import { execFile as execFile2 } from "child_process";
69316
+ import * as https2 from "https";
69317
+ var NPM_REGISTRY_LATEST_URL = "https://registry.npmjs.org/ccstatusline/latest";
69318
+ var DEFAULT_REGISTRY_TIMEOUT_MS = 5000;
69319
+ var GLOBAL_UPDATE_TIMEOUT_MS = 120000;
69320
+ function parseVersion(version2) {
69321
+ return version2.split(/[.-]/).map((part) => {
69322
+ const parsed = parseInt(part, 10);
69323
+ return Number.isFinite(parsed) ? parsed : 0;
69324
+ });
69325
+ }
69326
+ function compareVersions(left, right) {
69327
+ const leftParts = parseVersion(left);
69328
+ const rightParts = parseVersion(right);
69329
+ const length = Math.max(leftParts.length, rightParts.length);
69330
+ for (let i = 0;i < length; i += 1) {
69331
+ const leftPart = leftParts[i] ?? 0;
69332
+ const rightPart = rightParts[i] ?? 0;
69333
+ if (leftPart > rightPart) {
69334
+ return 1;
69335
+ }
69336
+ if (leftPart < rightPart) {
69337
+ return -1;
69338
+ }
69339
+ }
69340
+ return 0;
69341
+ }
69342
+ function getGlobalUpdateAction(packageManager, latestVersion, commandAvailability) {
69343
+ if (packageManager === "npm") {
69344
+ return {
69345
+ id: "npm-global",
69346
+ packageManager,
69347
+ command: PINNED_INSTALL_COMMANDS.NPM(latestVersion),
69348
+ version: latestVersion,
69349
+ available: commandAvailability.npm
69350
+ };
69351
+ }
69352
+ return {
69353
+ id: "bun-global",
69354
+ packageManager,
69355
+ command: PINNED_INSTALL_COMMANDS.BUN(latestVersion),
69356
+ version: latestVersion,
69357
+ available: commandAvailability.bun
69358
+ };
69359
+ }
69360
+ function getAutoUpdateLaunchCommand(installation) {
69361
+ if (installation.method !== "auto-update") {
69362
+ return;
69363
+ }
69364
+ return installation.packageManager === "bun" ? buildStatusLineCommand("auto-bunx") : buildStatusLineCommand("auto-npx");
69365
+ }
69366
+ function getUpdateActions(installation, latestVersion, commandAvailability) {
69367
+ if (installation.method === "auto-update") {
69368
+ return [];
69369
+ }
69370
+ if (installation.method === "pinned" || installation.method === "self-managed") {
69371
+ if (installation.packageManager === "npm") {
69372
+ return [getGlobalUpdateAction("npm", latestVersion, commandAvailability)];
69373
+ }
69374
+ if (installation.packageManager === "bun") {
69375
+ return [getGlobalUpdateAction("bun", latestVersion, commandAvailability)];
69376
+ }
69377
+ }
69378
+ return [
69379
+ getGlobalUpdateAction("npm", latestVersion, commandAvailability),
69380
+ getGlobalUpdateAction("bun", latestVersion, commandAvailability)
69381
+ ];
69382
+ }
69383
+ function getResolvedInstallation(installedCommand, installationMetadata) {
69384
+ const installation = classifyInstallation(installedCommand, installationMetadata);
69385
+ if (installation.method === "self-managed" && installationMetadata?.method === "self-managed") {
69386
+ return {
69387
+ ...installation,
69388
+ packageManager: installationMetadata.packageManager
69389
+ };
69390
+ }
69391
+ if (installation.method !== "pinned") {
69392
+ return installation;
69393
+ }
69394
+ return {
69395
+ ...installation,
69396
+ packageManager: installationMetadata?.method === "pinned" && "packageManager" in installationMetadata ? installationMetadata.packageManager : "unknown"
69397
+ };
69398
+ }
69399
+ function buildUpdateCheckResult({
69400
+ currentVersion,
69401
+ latestVersion,
69402
+ installedCommand,
69403
+ installationMetadata,
69404
+ commandAvailability
69405
+ }) {
69406
+ const installation = getResolvedInstallation(installedCommand, installationMetadata);
69407
+ if (compareVersions(latestVersion, currentVersion) <= 0) {
69408
+ return {
69409
+ status: "up-to-date",
69410
+ currentVersion,
69411
+ latestVersion,
69412
+ installation
69413
+ };
69414
+ }
69415
+ return {
69416
+ status: "update-available",
69417
+ currentVersion,
69418
+ latestVersion,
69419
+ installation,
69420
+ actions: getUpdateActions(installation, latestVersion, commandAvailability),
69421
+ autoUpdateLaunchCommand: getAutoUpdateLaunchCommand(installation)
69422
+ };
69423
+ }
69424
+ function getErrorMessage(error48) {
69425
+ if (error48 instanceof Error && error48.message) {
69426
+ return error48.message;
69427
+ }
69428
+ return "Unable to query npm registry";
69429
+ }
69430
+ async function checkForUpdates({
69431
+ currentVersion,
69432
+ installedCommand,
69433
+ installationMetadata,
69434
+ commandAvailability,
69435
+ timeoutMs = DEFAULT_REGISTRY_TIMEOUT_MS,
69436
+ latestVersionFetcher = fetchLatestNpmVersion
69437
+ }) {
69438
+ try {
69439
+ const latestVersion = await latestVersionFetcher(timeoutMs);
69440
+ return buildUpdateCheckResult({
69441
+ currentVersion,
69442
+ latestVersion,
69443
+ installedCommand,
69444
+ installationMetadata,
69445
+ commandAvailability
69446
+ });
69447
+ } catch (error48) {
69448
+ return {
69449
+ status: "registry-failure",
69450
+ currentVersion,
69451
+ installation: getResolvedInstallation(installedCommand, installationMetadata),
69452
+ errorMessage: getErrorMessage(error48)
69453
+ };
69454
+ }
69455
+ }
69456
+ function fetchLatestNpmVersion(timeoutMs = DEFAULT_REGISTRY_TIMEOUT_MS) {
69457
+ return new Promise((resolve5, reject2) => {
69458
+ const request3 = https2.request(NPM_REGISTRY_LATEST_URL, {
69459
+ headers: {
69460
+ Accept: "application/json",
69461
+ "User-Agent": "ccstatusline"
69462
+ }
69463
+ }, (response) => {
69464
+ if (!response.statusCode || response.statusCode < 200 || response.statusCode >= 300) {
69465
+ response.resume();
69466
+ reject2(new Error(`npm registry returned HTTP ${response.statusCode ?? "unknown"}`));
69467
+ return;
69468
+ }
69469
+ response.setEncoding("utf8");
69470
+ let body = "";
69471
+ response.on("data", (chunk2) => {
69472
+ body += chunk2;
69473
+ });
69474
+ response.on("end", () => {
69475
+ try {
69476
+ const parsed = JSON.parse(body);
69477
+ if (typeof parsed.version !== "string" || parsed.version.trim() === "") {
69478
+ reject2(new Error("npm registry response did not include a version"));
69479
+ return;
69480
+ }
69481
+ resolve5(parsed.version);
69482
+ } catch (error48) {
69483
+ reject2(error48 instanceof Error ? error48 : new Error(String(error48)));
69484
+ }
69485
+ });
69486
+ });
69487
+ request3.setTimeout(timeoutMs, () => {
69488
+ request3.destroy(new Error(`npm registry request timed out after ${timeoutMs}ms`));
69489
+ });
69490
+ request3.on("error", reject2);
69491
+ request3.end();
69492
+ });
69493
+ }
69494
+ function runGlobalPackageInstall(packageManager, version2, { platform: platform4 = process.platform } = {}) {
69495
+ const executable = getPackageManagerExecutable(packageManager, platform4);
69496
+ const args = packageManager === "npm" ? ["install", "-g", `ccstatusline@${version2}`] : ["add", "-g", `ccstatusline@${version2}`];
69497
+ return new Promise((resolve5, reject2) => {
69498
+ execFile2(executable, args, { timeout: GLOBAL_UPDATE_TIMEOUT_MS }, (error48) => {
69499
+ if (error48) {
69500
+ reject2(error48 instanceof Error ? error48 : new Error("Global update command failed"));
69501
+ return;
69502
+ }
69503
+ resolve5();
69504
+ });
69505
+ });
69506
+ }
69507
+ function runGlobalUpdateAction(action) {
69508
+ return runGlobalPackageInstall(action.packageManager, action.version);
69509
+ }
69510
+
68820
69511
  // src/tui/claude-status.ts
68821
69512
  await init_claude_settings();
68822
69513
  async function loadClaudeStatusLineState() {
@@ -70440,47 +71131,102 @@ await __promiseAll([
70440
71131
  init_build2(),
70441
71132
  init_claude_settings()
70442
71133
  ]);
71134
+ var import_react41 = __toESM(require_react(), 1);
70443
71135
  var jsx_dev_runtime14 = __toESM(require_jsx_dev_runtime(), 1);
71136
+ var AUTO_UPDATE_DESCRIPTION = "Runs `@latest` through npx/bunx. Stays current automatically, with a small startup cost when the package runner checks or resolves the package. Because it follows the latest published package, pinned install is available if you prefer explicit updates.";
71137
+ function getPinnedDescription(currentVersion) {
71138
+ return `Installs \`ccstatusline@${currentVersion}\` globally and Claude Code runs \`ccstatusline\`. Fast per-render and only changes when you update.`;
71139
+ }
71140
+ function getStyleItems(currentVersion) {
71141
+ return [
71142
+ {
71143
+ label: "Auto-update",
71144
+ value: "auto-update",
71145
+ description: AUTO_UPDATE_DESCRIPTION
71146
+ },
71147
+ {
71148
+ label: "Pinned global install",
71149
+ value: "pinned",
71150
+ description: getPinnedDescription(currentVersion)
71151
+ }
71152
+ ];
71153
+ }
71154
+ function getManagerItems(updateStyle, commandAvailability, currentVersion) {
71155
+ if (updateStyle === "auto-update") {
71156
+ return [
71157
+ {
71158
+ label: CCSTATUSLINE_COMMANDS.AUTO_NPX,
71159
+ value: "npm",
71160
+ disabled: !commandAvailability.npx,
71161
+ sublabel: commandAvailability.npx ? undefined : "(npx not installed)"
71162
+ },
71163
+ {
71164
+ label: CCSTATUSLINE_COMMANDS.AUTO_BUNX,
71165
+ value: "bun",
71166
+ disabled: !commandAvailability.bunx,
71167
+ sublabel: commandAvailability.bunx ? undefined : "(bunx not installed)"
71168
+ }
71169
+ ];
71170
+ }
71171
+ return [
71172
+ {
71173
+ label: PINNED_INSTALL_COMMANDS.NPM(currentVersion),
71174
+ value: "npm",
71175
+ disabled: !commandAvailability.npm,
71176
+ sublabel: commandAvailability.npm ? undefined : "(npm not installed)"
71177
+ },
71178
+ {
71179
+ label: PINNED_INSTALL_COMMANDS.BUN(currentVersion),
71180
+ value: "bun",
71181
+ disabled: !commandAvailability.bun,
71182
+ sublabel: commandAvailability.bun ? undefined : "(bun not installed)"
71183
+ }
71184
+ ];
71185
+ }
71186
+ function buildSelection(updateStyle, packageManager, currentVersion) {
71187
+ if (updateStyle === "auto-update") {
71188
+ return {
71189
+ updateStyle,
71190
+ packageManager,
71191
+ commandMode: packageManager === "bun" ? "auto-bunx" : "auto-npx",
71192
+ displayedCommand: packageManager === "bun" ? CCSTATUSLINE_COMMANDS.AUTO_BUNX : CCSTATUSLINE_COMMANDS.AUTO_NPX,
71193
+ metadata: {
71194
+ method: "auto-update",
71195
+ packageManager
71196
+ }
71197
+ };
71198
+ }
71199
+ return {
71200
+ updateStyle,
71201
+ packageManager,
71202
+ commandMode: "global",
71203
+ displayedCommand: packageManager === "bun" ? PINNED_INSTALL_COMMANDS.BUN(currentVersion) : PINNED_INSTALL_COMMANDS.NPM(currentVersion),
71204
+ globalInstallCommand: packageManager === "bun" ? PINNED_INSTALL_COMMANDS.BUN(currentVersion) : PINNED_INSTALL_COMMANDS.NPM(currentVersion),
71205
+ metadata: {
71206
+ method: "pinned",
71207
+ installedVersion: currentVersion
71208
+ }
71209
+ };
71210
+ }
70444
71211
  var InstallMenu = ({
70445
- bunxAvailable,
71212
+ commandAvailability,
71213
+ currentVersion,
70446
71214
  existingStatusLine,
70447
- onSelectNpx,
70448
- onSelectBunx,
71215
+ onSelect,
70449
71216
  onCancel,
70450
- initialSelection = 0
71217
+ initialPackageSelection = 0
70451
71218
  }) => {
71219
+ const [step, setStep] = import_react41.useState("style");
71220
+ const [updateStyle, setUpdateStyle] = import_react41.useState("auto-update");
70452
71221
  use_input_default((_, key) => {
70453
71222
  if (key.escape) {
71223
+ if (step === "manager") {
71224
+ setStep("style");
71225
+ return;
71226
+ }
70454
71227
  onCancel();
70455
71228
  }
70456
71229
  });
70457
- function onSelect(value) {
70458
- switch (value) {
70459
- case "npx":
70460
- onSelectNpx();
70461
- break;
70462
- case "bunx":
70463
- if (bunxAvailable) {
70464
- onSelectBunx();
70465
- }
70466
- break;
70467
- case "back":
70468
- onCancel();
70469
- break;
70470
- }
70471
- }
70472
- const listItems = [
70473
- {
70474
- label: "npx - Node Package Execute",
70475
- value: "npx"
70476
- },
70477
- {
70478
- label: "bunx - Bun Package Execute",
70479
- sublabel: bunxAvailable ? undefined : "(not installed)",
70480
- value: "bunx",
70481
- disabled: !bunxAvailable
70482
- }
70483
- ];
70484
71230
  return /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
70485
71231
  flexDirection: "column",
70486
71232
  children: [
@@ -70499,26 +71245,55 @@ var InstallMenu = ({
70499
71245
  ]
70500
71246
  }, undefined, true, undefined, this)
70501
71247
  }, undefined, false, undefined, this),
70502
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
70503
- children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
70504
- dimColor: true,
70505
- children: "Select package manager to use:"
70506
- }, undefined, false, undefined, this)
70507
- }, undefined, false, undefined, this),
70508
- /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(List, {
70509
- color: "blue",
70510
- marginTop: 1,
70511
- items: listItems,
70512
- onSelect: (line) => {
70513
- if (line === "back") {
70514
- onCancel();
70515
- return;
70516
- }
70517
- onSelect(line);
70518
- },
70519
- initialSelection,
70520
- showBackButton: true
70521
- }, undefined, false, undefined, this),
71248
+ step === "style" && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(jsx_dev_runtime14.Fragment, {
71249
+ children: [
71250
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
71251
+ children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
71252
+ dimColor: true,
71253
+ children: "Select update style:"
71254
+ }, undefined, false, undefined, this)
71255
+ }, undefined, false, undefined, this),
71256
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(List, {
71257
+ color: "blue",
71258
+ marginTop: 1,
71259
+ items: getStyleItems(currentVersion),
71260
+ onSelect: (value) => {
71261
+ if (value === "back") {
71262
+ onCancel();
71263
+ return;
71264
+ }
71265
+ setUpdateStyle(value);
71266
+ setStep("manager");
71267
+ },
71268
+ initialSelection: 0,
71269
+ showBackButton: true
71270
+ }, undefined, false, undefined, this)
71271
+ ]
71272
+ }, undefined, true, undefined, this),
71273
+ step === "manager" && /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(jsx_dev_runtime14.Fragment, {
71274
+ children: [
71275
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
71276
+ children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
71277
+ dimColor: true,
71278
+ children: "Select package manager:"
71279
+ }, undefined, false, undefined, this)
71280
+ }, undefined, false, undefined, this),
71281
+ /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(List, {
71282
+ color: "blue",
71283
+ marginTop: 1,
71284
+ items: getManagerItems(updateStyle, commandAvailability, currentVersion),
71285
+ onSelect: (value) => {
71286
+ if (value === "back") {
71287
+ setStep("style");
71288
+ return;
71289
+ }
71290
+ onSelect(buildSelection(updateStyle, value, currentVersion));
71291
+ },
71292
+ initialSelection: initialPackageSelection,
71293
+ showBackButton: true
71294
+ }, undefined, false, undefined, this)
71295
+ ]
71296
+ }, undefined, true, undefined, this),
70522
71297
  /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Box_default, {
70523
71298
  marginTop: 2,
70524
71299
  children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
@@ -70534,7 +71309,7 @@ var InstallMenu = ({
70534
71309
  marginTop: 1,
70535
71310
  children: /* @__PURE__ */ jsx_dev_runtime14.jsxDEV(Text, {
70536
71311
  dimColor: true,
70537
- children: "Press Enter to select, ESC to cancel"
71312
+ children: "Press Enter to select, ESC to go back"
70538
71313
  }, undefined, false, undefined, this)
70539
71314
  }, undefined, false, undefined, this)
70540
71315
  ]
@@ -70547,7 +71322,7 @@ await __promiseAll([
70547
71322
  init_build2(),
70548
71323
  init_widgets2()
70549
71324
  ]);
70550
- var import_react41 = __toESM(require_react(), 1);
71325
+ var import_react42 = __toESM(require_react(), 1);
70551
71326
 
70552
71327
  // src/tui/components/items-editor/input-handlers.ts
70553
71328
  await init_widgets2();
@@ -70889,11 +71664,11 @@ function handleNormalInputMode({
70889
71664
  // src/tui/components/ItemsEditor.tsx
70890
71665
  var jsx_dev_runtime15 = __toESM(require_jsx_dev_runtime(), 1);
70891
71666
  var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
70892
- const [selectedIndex, setSelectedIndex] = import_react41.useState(0);
70893
- const [moveMode, setMoveMode] = import_react41.useState(false);
70894
- const [customEditorWidget, setCustomEditorWidget] = import_react41.useState(null);
70895
- const [widgetPicker, setWidgetPicker] = import_react41.useState(null);
70896
- const [showClearConfirm, setShowClearConfirm] = import_react41.useState(false);
71667
+ const [selectedIndex, setSelectedIndex] = import_react42.useState(0);
71668
+ const [moveMode, setMoveMode] = import_react42.useState(false);
71669
+ const [customEditorWidget, setCustomEditorWidget] = import_react42.useState(null);
71670
+ const [widgetPicker, setWidgetPicker] = import_react42.useState(null);
71671
+ const [showClearConfirm, setShowClearConfirm] = import_react42.useState(false);
70897
71672
  const separatorChars = ["|", "-", ",", " "];
70898
71673
  const widgetCatalog = getWidgetCatalog(settings);
70899
71674
  const widgetCategories = ["All", ...getWidgetCatalogCategories(widgetCatalog)];
@@ -71444,7 +72219,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
71444
72219
  // src/tui/components/LineSelector.tsx
71445
72220
  await init_build2();
71446
72221
  var import_pluralize = __toESM(require_pluralize(), 1);
71447
- var import_react42 = __toESM(require_react(), 1);
72222
+ var import_react43 = __toESM(require_react(), 1);
71448
72223
  var jsx_dev_runtime16 = __toESM(require_jsx_dev_runtime(), 1);
71449
72224
  var LineSelector = ({
71450
72225
  lines,
@@ -71457,17 +72232,17 @@ var LineSelector = ({
71457
72232
  settings,
71458
72233
  allowEditing = false
71459
72234
  }) => {
71460
- const [selectedIndex, setSelectedIndex] = import_react42.useState(initialSelection);
71461
- const [showDeleteDialog, setShowDeleteDialog] = import_react42.useState(false);
71462
- const [moveMode, setMoveMode] = import_react42.useState(false);
71463
- const [localLines, setLocalLines] = import_react42.useState(lines);
71464
- import_react42.useEffect(() => {
72235
+ const [selectedIndex, setSelectedIndex] = import_react43.useState(initialSelection);
72236
+ const [showDeleteDialog, setShowDeleteDialog] = import_react43.useState(false);
72237
+ const [moveMode, setMoveMode] = import_react43.useState(false);
72238
+ const [localLines, setLocalLines] = import_react43.useState(lines);
72239
+ import_react43.useEffect(() => {
71465
72240
  setLocalLines(lines);
71466
72241
  }, [lines]);
71467
- import_react42.useEffect(() => {
72242
+ import_react43.useEffect(() => {
71468
72243
  setSelectedIndex(initialSelection);
71469
72244
  }, [initialSelection]);
71470
- const selectedLine = import_react42.useMemo(() => localLines[selectedIndex], [localLines, selectedIndex]);
72245
+ const selectedLine = import_react43.useMemo(() => localLines[selectedIndex], [localLines, selectedIndex]);
71471
72246
  const appendLine = () => {
71472
72247
  const newLines = [...localLines, []];
71473
72248
  setLocalLines(newLines);
@@ -71740,15 +72515,31 @@ var LineSelector = ({
71740
72515
  // src/tui/components/MainMenu.tsx
71741
72516
  await init_build2();
71742
72517
  var jsx_dev_runtime17 = __toESM(require_jsx_dev_runtime(), 1);
71743
- var MainMenu = ({
71744
- onSelect,
71745
- isClaudeInstalled,
71746
- hasChanges,
71747
- initialSelection = 0,
71748
- powerlineFontStatus,
71749
- settings,
71750
- previewIsTruncated
71751
- }) => {
72518
+ function usesManageInstallation(installation) {
72519
+ return installation?.method === "pinned" || installation?.method === "self-managed";
72520
+ }
72521
+ function getInstallationMenuItem(isClaudeInstalled, installation) {
72522
+ if (!isClaudeInstalled) {
72523
+ return {
72524
+ label: "\uD83D\uDCE6 Install to Claude Code",
72525
+ value: "install",
72526
+ description: "Add ccstatusline to your Claude Code settings for automatic status line rendering"
72527
+ };
72528
+ }
72529
+ if (usesManageInstallation(installation)) {
72530
+ return {
72531
+ label: "\uD83E\uDDF0 Manage Installation",
72532
+ value: "manageInstallation",
72533
+ description: "Check pinned global package updates or uninstall ccstatusline"
72534
+ };
72535
+ }
72536
+ return {
72537
+ label: "\uD83D\uDD0C Uninstall from Claude Code",
72538
+ value: "install",
72539
+ description: "Remove ccstatusline from your Claude Code settings"
72540
+ };
72541
+ }
72542
+ function buildMainMenuItems(isClaudeInstalled, hasChanges, installation) {
71752
72543
  const menuItems = [
71753
72544
  {
71754
72545
  label: "\uD83D\uDCDD Edit Lines",
@@ -71776,28 +72567,18 @@ var MainMenu = ({
71776
72567
  value: "globalOverrides",
71777
72568
  description: "Set global padding, separators, and color overrides that apply to all widgets"
71778
72569
  },
72570
+ {
72571
+ label: "\uD83D\uDD27 Configure Status Line",
72572
+ sublabel: isClaudeInstalled ? undefined : "(install first)",
72573
+ disabled: !isClaudeInstalled,
72574
+ value: "configureStatusLine",
72575
+ description: "Configure Claude Code status line settings like refresh interval"
72576
+ },
71779
72577
  "-",
71780
- ...isClaudeInstalled ? [
71781
- {
71782
- label: "\uD83D\uDD27 Configure Status Line",
71783
- value: "configureStatusLine",
71784
- description: "Configure Claude Code status line settings like refresh interval"
71785
- },
71786
- {
71787
- label: "\uD83D\uDD0C Uninstall from Claude Code",
71788
- value: "install",
71789
- description: "Remove ccstatusline from your Claude Code settings"
71790
- }
71791
- ] : [
71792
- {
71793
- label: "\uD83D\uDCE6 Install to Claude Code",
71794
- value: "install",
71795
- description: "Add ccstatusline to your Claude Code settings for automatic status line rendering"
71796
- }
71797
- ]
72578
+ getInstallationMenuItem(isClaudeInstalled, installation)
71798
72579
  ];
71799
72580
  if (hasChanges) {
71800
- menuItems.push({
72581
+ menuItems.push("-", {
71801
72582
  label: "\uD83D\uDCBE Save & Exit",
71802
72583
  value: "save",
71803
72584
  description: "Save all changes and exit the configuration tool"
@@ -71811,7 +72592,7 @@ var MainMenu = ({
71811
72592
  description: "Open the ccstatusline GitHub repository in your browser so you can star the project"
71812
72593
  });
71813
72594
  } else {
71814
- menuItems.push({
72595
+ menuItems.push("-", {
71815
72596
  label: "\uD83D\uDEAA Exit",
71816
72597
  value: "exit",
71817
72598
  description: "Exit the configuration tool"
@@ -71821,6 +72602,38 @@ var MainMenu = ({
71821
72602
  description: "Open the ccstatusline GitHub repository in your browser so you can star the project"
71822
72603
  });
71823
72604
  }
72605
+ return menuItems;
72606
+ }
72607
+ function getMainMenuSelectionIndex(items, option) {
72608
+ let selectionIndex = 0;
72609
+ for (const item of items) {
72610
+ if (item === "-") {
72611
+ continue;
72612
+ }
72613
+ if (item.value === option) {
72614
+ return selectionIndex;
72615
+ }
72616
+ if (!item.disabled) {
72617
+ selectionIndex += 1;
72618
+ }
72619
+ }
72620
+ return 0;
72621
+ }
72622
+ function getMainMenuInstallSelectionIndex(isClaudeInstalled, installation) {
72623
+ const option = isClaudeInstalled && usesManageInstallation(installation) ? "manageInstallation" : "install";
72624
+ return getMainMenuSelectionIndex(buildMainMenuItems(isClaudeInstalled, false, installation), option);
72625
+ }
72626
+ var MainMenu = ({
72627
+ onSelect,
72628
+ isClaudeInstalled,
72629
+ hasChanges,
72630
+ initialSelection = 0,
72631
+ powerlineFontStatus,
72632
+ settings,
72633
+ installation,
72634
+ previewIsTruncated
72635
+ }) => {
72636
+ const menuItems = buildMainMenuItems(isClaudeInstalled, hasChanges, installation);
71824
72637
  const showTruncationWarning = previewIsTruncated && settings?.flexMode === "full-minus-40";
71825
72638
  return /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(Box_default, {
71826
72639
  flexDirection: "column",
@@ -71850,9 +72663,184 @@ var MainMenu = ({
71850
72663
  ]
71851
72664
  }, undefined, true, undefined, this);
71852
72665
  };
72666
+ // src/tui/components/ManageInstallationMenu.tsx
72667
+ await init_build2();
72668
+ var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
72669
+ function getInstallationLabel(installation) {
72670
+ if (installation.method === "pinned") {
72671
+ const version2 = installation.installedVersion ? ` ${installation.installedVersion}` : "";
72672
+ const manager = installation.packageManager === "unknown" ? "" : ` via ${installation.packageManager}`;
72673
+ return `Pinned global install${manager}${version2}`;
72674
+ }
72675
+ if (installation.method === "self-managed") {
72676
+ return "Self-managed/global install";
72677
+ }
72678
+ if (installation.method === "auto-update") {
72679
+ return `Auto-update via ${installation.packageManager}`;
72680
+ }
72681
+ return "Unknown installation";
72682
+ }
72683
+ function getActiveCommandLabel(activeCommand) {
72684
+ if (!activeCommand?.resolvedPath) {
72685
+ return null;
72686
+ }
72687
+ if (activeCommand.packageManager === "unknown") {
72688
+ return `Active PATH match: ${activeCommand.resolvedPath}`;
72689
+ }
72690
+ const version2 = activeCommand.version ? ` ${activeCommand.version}` : "";
72691
+ return `Active PATH match: ${activeCommand.packageManager} global${version2} (${activeCommand.resolvedPath})`;
72692
+ }
72693
+ function buildManageInstallationItems() {
72694
+ return [
72695
+ {
72696
+ label: "\uD83D\uDD04 Check for Updates",
72697
+ value: "checkUpdates",
72698
+ description: "Check npm for the latest ccstatusline version and update the pinned global package"
72699
+ },
72700
+ {
72701
+ label: "\uD83D\uDD0C Uninstall",
72702
+ value: "uninstall",
72703
+ description: "Remove ccstatusline from Claude Code settings, optionally removing global npm/bun packages"
72704
+ }
72705
+ ];
72706
+ }
72707
+ function formatPackageManagers(packageManagers) {
72708
+ return packageManagers.join(" + ");
72709
+ }
72710
+ function buildUninstallItems(installations) {
72711
+ const removableManagers = installations.filter((installation) => installation.installed && installation.available).map((installation) => installation.packageManager);
72712
+ const items = [
72713
+ {
72714
+ label: "Remove from Claude Code settings only",
72715
+ value: { packageManagers: [] },
72716
+ description: "Leaves any global npm or bun ccstatusline packages installed"
72717
+ }
72718
+ ];
72719
+ for (const packageManager of removableManagers) {
72720
+ items.push({
72721
+ label: `Remove Claude settings and ${packageManager} global package`,
72722
+ value: { packageManagers: [packageManager] },
72723
+ description: `Runs ${packageManager === "npm" ? "npm uninstall -g ccstatusline" : "bun remove -g ccstatusline"} after removing Claude Code settings`
72724
+ });
72725
+ }
72726
+ if (removableManagers.length > 1) {
72727
+ items.push({
72728
+ label: `Remove Claude settings and ${formatPackageManagers(removableManagers)} global packages`,
72729
+ value: { packageManagers: removableManagers },
72730
+ description: "Removes every detected global ccstatusline package after removing Claude Code settings"
72731
+ });
72732
+ }
72733
+ return items;
72734
+ }
72735
+ var ManageInstallationMenu = ({
72736
+ installation,
72737
+ activeCommand,
72738
+ onSelect,
72739
+ onBack
72740
+ }) => {
72741
+ const activeCommandLabel = getActiveCommandLabel(activeCommand);
72742
+ use_input_default((_, key) => {
72743
+ if (key.escape) {
72744
+ onBack();
72745
+ }
72746
+ });
72747
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72748
+ flexDirection: "column",
72749
+ children: [
72750
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72751
+ bold: true,
72752
+ children: "Manage Installation"
72753
+ }, undefined, false, undefined, this),
72754
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72755
+ marginTop: 1,
72756
+ children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72757
+ children: [
72758
+ "Current:",
72759
+ " ",
72760
+ getInstallationLabel(installation)
72761
+ ]
72762
+ }, undefined, true, undefined, this)
72763
+ }, undefined, false, undefined, this),
72764
+ activeCommandLabel && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72765
+ children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72766
+ dimColor: true,
72767
+ children: activeCommandLabel
72768
+ }, undefined, false, undefined, this)
72769
+ }, undefined, false, undefined, this),
72770
+ activeCommand?.warning && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72771
+ marginTop: 1,
72772
+ children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72773
+ color: "yellow",
72774
+ wrap: "wrap",
72775
+ children: activeCommand.warning
72776
+ }, undefined, false, undefined, this)
72777
+ }, undefined, false, undefined, this),
72778
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(List, {
72779
+ marginTop: 1,
72780
+ items: buildManageInstallationItems(),
72781
+ onSelect: (value) => {
72782
+ if (value === "back") {
72783
+ onBack();
72784
+ return;
72785
+ }
72786
+ onSelect(value);
72787
+ },
72788
+ showBackButton: true
72789
+ }, undefined, false, undefined, this)
72790
+ ]
72791
+ }, undefined, true, undefined, this);
72792
+ };
72793
+ var UninstallMenu = ({
72794
+ installations,
72795
+ onSelect,
72796
+ onBack
72797
+ }) => {
72798
+ const items = buildUninstallItems(installations);
72799
+ const detectedManagers = installations.filter((installation) => installation.installed && installation.available).map((installation) => installation.packageManager);
72800
+ use_input_default((_, key) => {
72801
+ if (key.escape) {
72802
+ onBack();
72803
+ }
72804
+ });
72805
+ return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72806
+ flexDirection: "column",
72807
+ children: [
72808
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72809
+ bold: true,
72810
+ children: "Uninstall ccstatusline"
72811
+ }, undefined, false, undefined, this),
72812
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72813
+ marginTop: 1,
72814
+ children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72815
+ dimColor: true,
72816
+ children: "Choose what to remove from this machine."
72817
+ }, undefined, false, undefined, this)
72818
+ }, undefined, false, undefined, this),
72819
+ detectedManagers.length === 0 && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72820
+ marginTop: 1,
72821
+ children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
72822
+ dimColor: true,
72823
+ children: "No global npm or bun ccstatusline package was detected."
72824
+ }, undefined, false, undefined, this)
72825
+ }, undefined, false, undefined, this),
72826
+ /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(List, {
72827
+ marginTop: 1,
72828
+ items,
72829
+ onSelect: (value) => {
72830
+ if (value === "back") {
72831
+ onBack();
72832
+ return;
72833
+ }
72834
+ onSelect(value);
72835
+ },
72836
+ showBackButton: true
72837
+ }, undefined, false, undefined, this)
72838
+ ]
72839
+ }, undefined, true, undefined, this);
72840
+ };
71853
72841
  // src/tui/components/PowerlineSetup.tsx
71854
72842
  await init_build2();
71855
- var import_react45 = __toESM(require_react(), 1);
72843
+ var import_react46 = __toESM(require_react(), 1);
71856
72844
  import * as os12 from "os";
71857
72845
 
71858
72846
  // src/utils/powerline-settings.ts
@@ -71883,8 +72871,8 @@ function buildEnabledPowerlineSettings(settings, removeManualSeparators) {
71883
72871
  // src/tui/components/PowerlineSeparatorEditor.tsx
71884
72872
  init_input_guards();
71885
72873
  await init_build2();
71886
- var import_react43 = __toESM(require_react(), 1);
71887
- var jsx_dev_runtime18 = __toESM(require_jsx_dev_runtime(), 1);
72874
+ var import_react44 = __toESM(require_react(), 1);
72875
+ var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
71888
72876
  var PowerlineSeparatorEditor = ({
71889
72877
  settings,
71890
72878
  mode,
@@ -71904,10 +72892,10 @@ var PowerlineSeparatorEditor = ({
71904
72892
  };
71905
72893
  const separators = getItems();
71906
72894
  const invertBgs = mode === "separator" ? powerlineConfig.separatorInvertBackground : [];
71907
- const [selectedIndex, setSelectedIndex] = import_react43.useState(0);
71908
- const [hexInputMode, setHexInputMode] = import_react43.useState(false);
71909
- const [hexInput, setHexInput] = import_react43.useState("");
71910
- const [cursorPos, setCursorPos] = import_react43.useState(0);
72895
+ const [selectedIndex, setSelectedIndex] = import_react44.useState(0);
72896
+ const [hexInputMode, setHexInputMode] = import_react44.useState(false);
72897
+ const [hexInput, setHexInput] = import_react44.useState("");
72898
+ const [cursorPos, setCursorPos] = import_react44.useState(0);
71911
72899
  const getPresets = () => {
71912
72900
  if (mode === "separator") {
71913
72901
  return [
@@ -72099,18 +73087,18 @@ var PowerlineSeparatorEditor = ({
72099
73087
  }
72100
73088
  };
72101
73089
  const canDelete = mode !== "separator" || separators.length > 1;
72102
- return /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
73090
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
72103
73091
  flexDirection: "column",
72104
73092
  children: [
72105
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73093
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72106
73094
  bold: true,
72107
73095
  children: getTitle()
72108
73096
  }, undefined, false, undefined, this),
72109
- hexInputMode ? /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
73097
+ hexInputMode ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
72110
73098
  marginTop: 2,
72111
73099
  flexDirection: "column",
72112
73100
  children: [
72113
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73101
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72114
73102
  children: [
72115
73103
  "Enter hex code (4-6 digits) for",
72116
73104
  " ",
@@ -72119,51 +73107,51 @@ var PowerlineSeparatorEditor = ({
72119
73107
  ":"
72120
73108
  ]
72121
73109
  }, undefined, true, undefined, this),
72122
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73110
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72123
73111
  children: [
72124
73112
  "U+",
72125
73113
  hexInput.slice(0, cursorPos),
72126
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73114
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72127
73115
  backgroundColor: "gray",
72128
73116
  color: "black",
72129
73117
  children: hexInput[cursorPos] ?? "_"
72130
73118
  }, undefined, false, undefined, this),
72131
73119
  hexInput.slice(cursorPos + 1),
72132
- hexInput.length < 6 && hexInput.length === cursorPos && /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73120
+ hexInput.length < 6 && hexInput.length === cursorPos && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72133
73121
  dimColor: true,
72134
73122
  children: "_".repeat(6 - hexInput.length - 1)
72135
73123
  }, undefined, false, undefined, this)
72136
73124
  ]
72137
73125
  }, undefined, true, undefined, this),
72138
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73126
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72139
73127
  dimColor: true,
72140
73128
  children: "Enter 4-6 hex digits (0-9, A-F) for a Unicode code point, then press Enter. ESC to cancel."
72141
73129
  }, undefined, false, undefined, this),
72142
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73130
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72143
73131
  dimColor: true,
72144
73132
  children: "Examples: E0B0 (powerline), 1F984 (\uD83E\uDD84), 2764 (❤)"
72145
73133
  }, undefined, false, undefined, this)
72146
73134
  ]
72147
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(jsx_dev_runtime18.Fragment, {
73135
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(jsx_dev_runtime19.Fragment, {
72148
73136
  children: [
72149
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72150
- children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73137
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73138
+ children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72151
73139
  dimColor: true,
72152
73140
  children: `↑↓ select, ← → cycle, (a)dd, (i)nsert${canDelete ? ", (d)elete" : ""}, (c)lear, (h)ex${mode === "separator" ? ", (t)oggle invert" : ""}, ESC back`
72153
73141
  }, undefined, false, undefined, this)
72154
73142
  }, undefined, false, undefined, this),
72155
- /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
73143
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
72156
73144
  marginTop: 2,
72157
73145
  flexDirection: "column",
72158
- children: separators.length > 0 ? separators.map((sep2, index) => /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Box_default, {
72159
- children: /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73146
+ children: separators.length > 0 ? separators.map((sep2, index) => /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73147
+ children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72160
73148
  color: index === selectedIndex ? "green" : undefined,
72161
73149
  children: [
72162
73150
  index === selectedIndex ? "▶ " : " ",
72163
73151
  `${index + 1}: ${getSeparatorDisplay(sep2, index)}`
72164
73152
  ]
72165
73153
  }, undefined, true, undefined, this)
72166
- }, index, false, undefined, this)) : /* @__PURE__ */ jsx_dev_runtime18.jsxDEV(Text, {
73154
+ }, index, false, undefined, this)) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
72167
73155
  dimColor: true,
72168
73156
  children: "(none configured - press 'a' to add)"
72169
73157
  }, undefined, false, undefined, this)
@@ -72178,8 +73166,8 @@ var PowerlineSeparatorEditor = ({
72178
73166
  init_ColorLevel();
72179
73167
  init_colors();
72180
73168
  await init_build2();
72181
- var import_react44 = __toESM(require_react(), 1);
72182
- var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
73169
+ var import_react45 = __toESM(require_react(), 1);
73170
+ var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
72183
73171
  function buildPowerlineThemeItems(themes, originalTheme) {
72184
73172
  return themes.map((themeName) => {
72185
73173
  const theme = getPowerlineTheme(themeName);
@@ -72232,20 +73220,20 @@ var PowerlineThemeSelector = ({
72232
73220
  onUpdate,
72233
73221
  onBack
72234
73222
  }) => {
72235
- const themes = import_react44.useMemo(() => getPowerlineThemes(), []);
73223
+ const themes = import_react45.useMemo(() => getPowerlineThemes(), []);
72236
73224
  const currentTheme = settings.powerline.theme ?? "custom";
72237
- const [selectedIndex, setSelectedIndex] = import_react44.useState(Math.max(0, themes.indexOf(currentTheme)));
72238
- const [showCustomizeConfirm, setShowCustomizeConfirm] = import_react44.useState(false);
72239
- const originalThemeRef = import_react44.useRef(currentTheme);
72240
- const originalSettingsRef = import_react44.useRef(settings);
72241
- const latestSettingsRef = import_react44.useRef(settings);
72242
- const latestOnUpdateRef = import_react44.useRef(onUpdate);
72243
- const didHandleInitialSelectionRef = import_react44.useRef(false);
72244
- import_react44.useEffect(() => {
73225
+ const [selectedIndex, setSelectedIndex] = import_react45.useState(Math.max(0, themes.indexOf(currentTheme)));
73226
+ const [showCustomizeConfirm, setShowCustomizeConfirm] = import_react45.useState(false);
73227
+ const originalThemeRef = import_react45.useRef(currentTheme);
73228
+ const originalSettingsRef = import_react45.useRef(settings);
73229
+ const latestSettingsRef = import_react45.useRef(settings);
73230
+ const latestOnUpdateRef = import_react45.useRef(onUpdate);
73231
+ const didHandleInitialSelectionRef = import_react45.useRef(false);
73232
+ import_react45.useEffect(() => {
72245
73233
  latestSettingsRef.current = settings;
72246
73234
  latestOnUpdateRef.current = onUpdate;
72247
73235
  }, [settings, onUpdate]);
72248
- import_react44.useEffect(() => {
73236
+ import_react45.useEffect(() => {
72249
73237
  const themeName = themes[selectedIndex];
72250
73238
  if (!themeName) {
72251
73239
  return;
@@ -72277,41 +73265,41 @@ var PowerlineThemeSelector = ({
72277
73265
  }
72278
73266
  });
72279
73267
  const selectedThemeName = themes[selectedIndex];
72280
- const themeItems = import_react44.useMemo(() => buildPowerlineThemeItems(themes, originalThemeRef.current), [themes]);
73268
+ const themeItems = import_react45.useMemo(() => buildPowerlineThemeItems(themes, originalThemeRef.current), [themes]);
72281
73269
  if (showCustomizeConfirm) {
72282
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73270
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72283
73271
  flexDirection: "column",
72284
73272
  children: [
72285
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73273
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72286
73274
  bold: true,
72287
73275
  color: "yellow",
72288
73276
  children: "⚠ Confirm Customization"
72289
73277
  }, undefined, false, undefined, this),
72290
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73278
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72291
73279
  marginTop: 1,
72292
73280
  flexDirection: "column",
72293
73281
  children: [
72294
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73282
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72295
73283
  children: "This will copy the current theme colors to your widgets"
72296
73284
  }, undefined, false, undefined, this),
72297
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73285
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72298
73286
  children: "and switch to Custom theme mode."
72299
73287
  }, undefined, false, undefined, this),
72300
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73288
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72301
73289
  color: "red",
72302
73290
  children: "This will overwrite any existing custom colors!"
72303
73291
  }, undefined, false, undefined, this)
72304
73292
  ]
72305
73293
  }, undefined, true, undefined, this),
72306
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73294
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72307
73295
  marginTop: 2,
72308
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73296
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72309
73297
  children: "Continue?"
72310
73298
  }, undefined, false, undefined, this)
72311
73299
  }, undefined, false, undefined, this),
72312
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73300
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72313
73301
  marginTop: 1,
72314
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(ConfirmDialog, {
73302
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(ConfirmDialog, {
72315
73303
  inline: true,
72316
73304
  onConfirm: () => {
72317
73305
  if (selectedThemeName) {
@@ -72331,26 +73319,26 @@ var PowerlineThemeSelector = ({
72331
73319
  ]
72332
73320
  }, undefined, true, undefined, this);
72333
73321
  }
72334
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73322
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72335
73323
  flexDirection: "column",
72336
73324
  children: [
72337
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73325
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72338
73326
  bold: true,
72339
73327
  children: [
72340
73328
  `Powerline Theme Selection | `,
72341
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73329
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72342
73330
  dimColor: true,
72343
73331
  children: `Original: ${originalThemeRef.current}`
72344
73332
  }, undefined, false, undefined, this)
72345
73333
  ]
72346
73334
  }, undefined, true, undefined, this),
72347
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
72348
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73335
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73336
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72349
73337
  dimColor: true,
72350
73338
  children: `↑↓ navigate, Enter apply${selectedThemeName && selectedThemeName !== "custom" ? ", (c)ustomize theme" : ""}, ESC cancel`
72351
73339
  }, undefined, false, undefined, this)
72352
73340
  }, undefined, false, undefined, this),
72353
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(List, {
73341
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(List, {
72354
73342
  marginTop: 1,
72355
73343
  items: themeItems,
72356
73344
  onSelect: () => {
@@ -72364,16 +73352,16 @@ var PowerlineThemeSelector = ({
72364
73352
  },
72365
73353
  initialSelection: selectedIndex
72366
73354
  }, undefined, false, undefined, this),
72367
- selectedThemeName && selectedThemeName !== "custom" && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73355
+ selectedThemeName && selectedThemeName !== "custom" && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72368
73356
  marginTop: 1,
72369
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73357
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72370
73358
  dimColor: true,
72371
73359
  children: "Press (c) to customize this theme - copies colors to widgets"
72372
73360
  }, undefined, false, undefined, this)
72373
73361
  }, undefined, false, undefined, this),
72374
- settings.colorLevel === 1 && /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
73362
+ settings.colorLevel === 1 && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72375
73363
  marginTop: 1,
72376
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
73364
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
72377
73365
  color: "yellow",
72378
73366
  children: "⚠ 16 color mode themes have a very limited palette, we recommend switching color level in Terminal Options"
72379
73367
  }, undefined, false, undefined, this)
@@ -72383,7 +73371,7 @@ var PowerlineThemeSelector = ({
72383
73371
  };
72384
73372
 
72385
73373
  // src/tui/components/PowerlineSetup.tsx
72386
- var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
73374
+ var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
72387
73375
  var POWERLINE_MENU_LABEL_WIDTH = 11;
72388
73376
  function formatPowerlineMenuLabel(label) {
72389
73377
  return label.padEnd(POWERLINE_MENU_LABEL_WIDTH, " ");
@@ -72486,10 +73474,10 @@ var PowerlineSetup = ({
72486
73474
  onClearMessage
72487
73475
  }) => {
72488
73476
  const powerlineConfig = settings.powerline;
72489
- const [screen, setScreen] = import_react45.useState("menu");
72490
- const [selectedMenuItem, setSelectedMenuItem] = import_react45.useState(0);
72491
- const [confirmingEnable, setConfirmingEnable] = import_react45.useState(false);
72492
- const [confirmingFontInstall, setConfirmingFontInstall] = import_react45.useState(false);
73477
+ const [screen, setScreen] = import_react46.useState("menu");
73478
+ const [selectedMenuItem, setSelectedMenuItem] = import_react46.useState(0);
73479
+ const [confirmingEnable, setConfirmingEnable] = import_react46.useState(false);
73480
+ const [confirmingFontInstall, setConfirmingFontInstall] = import_react46.useState(false);
72493
73481
  const hasSeparatorItems = settings.lines.some((line) => line.some((item) => item.type === "separator" || item.type === "flex-separator"));
72494
73482
  use_input_default((input, key) => {
72495
73483
  if (fontInstallMessage || installingFonts) {
@@ -72542,7 +73530,7 @@ var PowerlineSetup = ({
72542
73530
  }
72543
73531
  });
72544
73532
  if (screen === "separator") {
72545
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(PowerlineSeparatorEditor, {
73533
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(PowerlineSeparatorEditor, {
72546
73534
  settings,
72547
73535
  mode: "separator",
72548
73536
  onUpdate,
@@ -72552,7 +73540,7 @@ var PowerlineSetup = ({
72552
73540
  }, undefined, false, undefined, this);
72553
73541
  }
72554
73542
  if (screen === "startCap") {
72555
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(PowerlineSeparatorEditor, {
73543
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(PowerlineSeparatorEditor, {
72556
73544
  settings,
72557
73545
  mode: "startCap",
72558
73546
  onUpdate,
@@ -72562,7 +73550,7 @@ var PowerlineSetup = ({
72562
73550
  }, undefined, false, undefined, this);
72563
73551
  }
72564
73552
  if (screen === "endCap") {
72565
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(PowerlineSeparatorEditor, {
73553
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(PowerlineSeparatorEditor, {
72566
73554
  settings,
72567
73555
  mode: "endCap",
72568
73556
  onUpdate,
@@ -72572,7 +73560,7 @@ var PowerlineSetup = ({
72572
73560
  }, undefined, false, undefined, this);
72573
73561
  }
72574
73562
  if (screen === "themes") {
72575
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(PowerlineThemeSelector, {
73563
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(PowerlineThemeSelector, {
72576
73564
  settings,
72577
73565
  onUpdate,
72578
73566
  onBack: () => {
@@ -72580,140 +73568,140 @@ var PowerlineSetup = ({
72580
73568
  }
72581
73569
  }, undefined, false, undefined, this);
72582
73570
  }
72583
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73571
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72584
73572
  flexDirection: "column",
72585
73573
  children: [
72586
- !confirmingFontInstall && !installingFonts && !fontInstallMessage && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73574
+ !confirmingFontInstall && !installingFonts && !fontInstallMessage && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72587
73575
  bold: true,
72588
73576
  children: "Powerline Setup"
72589
73577
  }, undefined, false, undefined, this),
72590
- confirmingFontInstall ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73578
+ confirmingFontInstall ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72591
73579
  flexDirection: "column",
72592
73580
  children: [
72593
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73581
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72594
73582
  marginBottom: 1,
72595
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73583
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72596
73584
  color: "cyan",
72597
73585
  bold: true,
72598
73586
  children: "Font Installation"
72599
73587
  }, undefined, false, undefined, this)
72600
73588
  }, undefined, false, undefined, this),
72601
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73589
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72602
73590
  marginBottom: 1,
72603
73591
  flexDirection: "column",
72604
73592
  children: [
72605
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73593
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72606
73594
  bold: true,
72607
73595
  children: "What will happen:"
72608
73596
  }, undefined, false, undefined, this),
72609
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73597
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72610
73598
  children: [
72611
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73599
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72612
73600
  dimColor: true,
72613
73601
  children: "• Clone fonts from "
72614
73602
  }, undefined, false, undefined, this),
72615
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73603
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72616
73604
  color: "blue",
72617
73605
  children: "https://github.com/powerline/fonts"
72618
73606
  }, undefined, false, undefined, this)
72619
73607
  ]
72620
73608
  }, undefined, true, undefined, this),
72621
- os12.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73609
+ os12.platform() === "darwin" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72622
73610
  children: [
72623
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73611
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72624
73612
  dimColor: true,
72625
73613
  children: "• Run install.sh script which will:"
72626
73614
  }, undefined, false, undefined, this),
72627
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73615
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72628
73616
  dimColor: true,
72629
73617
  children: " - Copy all .ttf/.otf files to ~/Library/Fonts"
72630
73618
  }, undefined, false, undefined, this),
72631
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73619
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72632
73620
  dimColor: true,
72633
73621
  children: " - Register fonts with macOS"
72634
73622
  }, undefined, false, undefined, this)
72635
73623
  ]
72636
73624
  }, undefined, true, undefined, this),
72637
- os12.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73625
+ os12.platform() === "linux" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72638
73626
  children: [
72639
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73627
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72640
73628
  dimColor: true,
72641
73629
  children: "• Run install.sh script which will:"
72642
73630
  }, undefined, false, undefined, this),
72643
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73631
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72644
73632
  dimColor: true,
72645
73633
  children: " - Copy all .ttf/.otf files to ~/.local/share/fonts"
72646
73634
  }, undefined, false, undefined, this),
72647
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73635
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72648
73636
  dimColor: true,
72649
73637
  children: " - Run fc-cache to update font cache"
72650
73638
  }, undefined, false, undefined, this)
72651
73639
  ]
72652
73640
  }, undefined, true, undefined, this),
72653
- os12.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73641
+ os12.platform() === "win32" && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72654
73642
  children: [
72655
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73643
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72656
73644
  dimColor: true,
72657
73645
  children: "• Copy Powerline .ttf/.otf files to:"
72658
73646
  }, undefined, false, undefined, this),
72659
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73647
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72660
73648
  dimColor: true,
72661
73649
  children: " AppData\\Local\\Microsoft\\Windows\\Fonts"
72662
73650
  }, undefined, false, undefined, this)
72663
73651
  ]
72664
73652
  }, undefined, true, undefined, this),
72665
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73653
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72666
73654
  dimColor: true,
72667
73655
  children: "• Clean up temporary files"
72668
73656
  }, undefined, false, undefined, this)
72669
73657
  ]
72670
73658
  }, undefined, true, undefined, this),
72671
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73659
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72672
73660
  marginBottom: 1,
72673
73661
  children: [
72674
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73662
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72675
73663
  color: "yellow",
72676
73664
  bold: true,
72677
73665
  children: "Requirements: "
72678
73666
  }, undefined, false, undefined, this),
72679
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73667
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72680
73668
  dimColor: true,
72681
73669
  children: "Git installed, Internet connection, Write permissions"
72682
73670
  }, undefined, false, undefined, this)
72683
73671
  ]
72684
73672
  }, undefined, true, undefined, this),
72685
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73673
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72686
73674
  marginBottom: 1,
72687
73675
  flexDirection: "column",
72688
73676
  children: [
72689
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73677
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72690
73678
  color: "green",
72691
73679
  bold: true,
72692
73680
  children: "After install:"
72693
73681
  }, undefined, false, undefined, this),
72694
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73682
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72695
73683
  dimColor: true,
72696
73684
  children: "• Restart terminal"
72697
73685
  }, undefined, false, undefined, this),
72698
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73686
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72699
73687
  dimColor: true,
72700
73688
  children: "• Select a Powerline font"
72701
73689
  }, undefined, false, undefined, this),
72702
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73690
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72703
73691
  dimColor: true,
72704
73692
  children: ' (e.g. "Meslo LG S for Powerline")'
72705
73693
  }, undefined, false, undefined, this)
72706
73694
  ]
72707
73695
  }, undefined, true, undefined, this),
72708
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73696
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72709
73697
  marginTop: 1,
72710
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73698
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72711
73699
  children: "Proceed? "
72712
73700
  }, undefined, false, undefined, this)
72713
73701
  }, undefined, false, undefined, this),
72714
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73702
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72715
73703
  marginTop: 1,
72716
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(ConfirmDialog, {
73704
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ConfirmDialog, {
72717
73705
  inline: true,
72718
73706
  onConfirm: () => {
72719
73707
  setConfirmingFontInstall(false);
@@ -72725,36 +73713,36 @@ var PowerlineSetup = ({
72725
73713
  }, undefined, false, undefined, this)
72726
73714
  }, undefined, false, undefined, this)
72727
73715
  ]
72728
- }, undefined, true, undefined, this) : confirmingEnable ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73716
+ }, undefined, true, undefined, this) : confirmingEnable ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72729
73717
  flexDirection: "column",
72730
73718
  marginTop: 1,
72731
73719
  children: [
72732
- hasSeparatorItems && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73720
+ hasSeparatorItems && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72733
73721
  children: [
72734
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72735
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73722
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
73723
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72736
73724
  color: "yellow",
72737
73725
  children: "⚠ Warning: Enabling Powerline mode will remove all existing separators and flex-separators from your status lines."
72738
73726
  }, undefined, false, undefined, this)
72739
73727
  }, undefined, false, undefined, this),
72740
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73728
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72741
73729
  marginBottom: 1,
72742
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73730
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72743
73731
  dimColor: true,
72744
73732
  children: "Powerline mode uses its own separator system and is incompatible with manual separators."
72745
73733
  }, undefined, false, undefined, this)
72746
73734
  }, undefined, false, undefined, this)
72747
73735
  ]
72748
73736
  }, undefined, true, undefined, this),
72749
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73737
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72750
73738
  marginTop: hasSeparatorItems ? 1 : 0,
72751
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73739
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72752
73740
  children: "Do you want to continue? "
72753
73741
  }, undefined, false, undefined, this)
72754
73742
  }, undefined, false, undefined, this),
72755
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73743
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72756
73744
  marginTop: 1,
72757
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(ConfirmDialog, {
73745
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ConfirmDialog, {
72758
73746
  inline: true,
72759
73747
  onConfirm: () => {
72760
73748
  onUpdate(buildEnabledPowerlineSettings(settings, true));
@@ -72766,51 +73754,51 @@ var PowerlineSetup = ({
72766
73754
  }, undefined, false, undefined, this)
72767
73755
  }, undefined, false, undefined, this)
72768
73756
  ]
72769
- }, undefined, true, undefined, this) : installingFonts ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
72770
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73757
+ }, undefined, true, undefined, this) : installingFonts ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
73758
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72771
73759
  color: "yellow",
72772
73760
  children: "Installing Powerline fonts... This may take a moment."
72773
73761
  }, undefined, false, undefined, this)
72774
- }, undefined, false, undefined, this) : fontInstallMessage ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73762
+ }, undefined, false, undefined, this) : fontInstallMessage ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72775
73763
  flexDirection: "column",
72776
73764
  children: [
72777
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73765
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72778
73766
  color: fontInstallMessage.includes("success") ? "green" : "red",
72779
73767
  children: fontInstallMessage
72780
73768
  }, undefined, false, undefined, this),
72781
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73769
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72782
73770
  marginTop: 1,
72783
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73771
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72784
73772
  dimColor: true,
72785
73773
  children: "Press any key to continue..."
72786
73774
  }, undefined, false, undefined, this)
72787
73775
  }, undefined, false, undefined, this)
72788
73776
  ]
72789
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73777
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72790
73778
  children: [
72791
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73779
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72792
73780
  flexDirection: "column",
72793
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73781
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72794
73782
  children: [
72795
73783
  " Font Status: ",
72796
- powerlineFontStatus.installed ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73784
+ powerlineFontStatus.installed ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72797
73785
  children: [
72798
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73786
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72799
73787
  color: "green",
72800
73788
  children: "✓ Installed"
72801
73789
  }, undefined, false, undefined, this),
72802
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73790
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72803
73791
  dimColor: true,
72804
73792
  children: " - Ensure fonts are active in your terminal"
72805
73793
  }, undefined, false, undefined, this)
72806
73794
  ]
72807
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73795
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72808
73796
  children: [
72809
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73797
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72810
73798
  color: "yellow",
72811
73799
  children: "✗ Not Installed"
72812
73800
  }, undefined, false, undefined, this),
72813
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73801
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72814
73802
  dimColor: true,
72815
73803
  children: " - Press (i) to install Powerline fonts"
72816
73804
  }, undefined, false, undefined, this)
@@ -72819,62 +73807,62 @@ var PowerlineSetup = ({
72819
73807
  ]
72820
73808
  }, undefined, true, undefined, this)
72821
73809
  }, undefined, false, undefined, this),
72822
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73810
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72823
73811
  children: [
72824
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73812
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72825
73813
  children: " Powerline Mode: "
72826
73814
  }, undefined, false, undefined, this),
72827
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73815
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72828
73816
  color: powerlineConfig.enabled ? "green" : "red",
72829
73817
  children: powerlineConfig.enabled ? "✓ Enabled " : "✗ Disabled "
72830
73818
  }, undefined, false, undefined, this),
72831
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73819
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72832
73820
  dimColor: true,
72833
73821
  children: " - Press (t) to toggle"
72834
73822
  }, undefined, false, undefined, this)
72835
73823
  ]
72836
73824
  }, undefined, true, undefined, this),
72837
- powerlineConfig.enabled && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
73825
+ powerlineConfig.enabled && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
72838
73826
  children: [
72839
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73827
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72840
73828
  children: [
72841
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73829
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72842
73830
  children: " Align Widgets: "
72843
73831
  }, undefined, false, undefined, this),
72844
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73832
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72845
73833
  color: powerlineConfig.autoAlign ? "green" : "red",
72846
73834
  children: powerlineConfig.autoAlign ? "✓ Enabled " : "✗ Disabled "
72847
73835
  }, undefined, false, undefined, this),
72848
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73836
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72849
73837
  dimColor: true,
72850
73838
  children: " - Press (a) to toggle"
72851
73839
  }, undefined, false, undefined, this)
72852
73840
  ]
72853
73841
  }, undefined, true, undefined, this),
72854
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73842
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72855
73843
  children: [
72856
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73844
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72857
73845
  children: " Continue Theme: "
72858
73846
  }, undefined, false, undefined, this),
72859
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73847
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72860
73848
  color: powerlineConfig.continueThemeAcrossLines ? "green" : "red",
72861
73849
  children: powerlineConfig.continueThemeAcrossLines ? "✓ Enabled " : "✗ Disabled "
72862
73850
  }, undefined, false, undefined, this),
72863
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73851
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72864
73852
  dimColor: true,
72865
73853
  children: " - Press (c) to toggle"
72866
73854
  }, undefined, false, undefined, this)
72867
73855
  ]
72868
73856
  }, undefined, true, undefined, this),
72869
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73857
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72870
73858
  flexDirection: "column",
72871
73859
  marginTop: 1,
72872
73860
  children: [
72873
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73861
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72874
73862
  dimColor: true,
72875
73863
  children: "When enabled, global overrides are disabled and powerline separators are used"
72876
73864
  }, undefined, false, undefined, this),
72877
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73865
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72878
73866
  dimColor: true,
72879
73867
  children: "Continue Theme keeps the Powerline color sequence running across lines"
72880
73868
  }, undefined, false, undefined, this)
@@ -72882,14 +73870,14 @@ var PowerlineSetup = ({
72882
73870
  }, undefined, true, undefined, this)
72883
73871
  ]
72884
73872
  }, undefined, true, undefined, this),
72885
- !powerlineConfig.enabled && /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
73873
+ !powerlineConfig.enabled && /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
72886
73874
  marginTop: 1,
72887
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
73875
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
72888
73876
  dimColor: true,
72889
73877
  children: "Enable Powerline mode to configure separators, caps, and themes."
72890
73878
  }, undefined, false, undefined, this)
72891
73879
  }, undefined, false, undefined, this),
72892
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(List, {
73880
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(List, {
72893
73881
  marginTop: 1,
72894
73882
  items: buildPowerlineSetupMenuItems(powerlineConfig),
72895
73883
  onSelect: (value) => {
@@ -72913,8 +73901,8 @@ var PowerlineSetup = ({
72913
73901
  // src/tui/components/RefreshIntervalMenu.tsx
72914
73902
  init_input_guards();
72915
73903
  await init_build2();
72916
- var import_react46 = __toESM(require_react(), 1);
72917
- var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
73904
+ var import_react47 = __toESM(require_react(), 1);
73905
+ var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
72918
73906
  function getRefreshInputValue(interval) {
72919
73907
  return interval === null ? "" : String(interval);
72920
73908
  }
@@ -72960,9 +73948,9 @@ var RefreshIntervalMenu = ({
72960
73948
  onUpdate,
72961
73949
  onBack
72962
73950
  }) => {
72963
- const [editingRefreshInterval, setEditingRefreshInterval] = import_react46.useState(false);
72964
- const [refreshInput, setRefreshInput] = import_react46.useState(() => getRefreshInputValue(currentInterval));
72965
- const [validationError, setValidationError] = import_react46.useState(null);
73951
+ const [editingRefreshInterval, setEditingRefreshInterval] = import_react47.useState(false);
73952
+ const [refreshInput, setRefreshInput] = import_react47.useState(() => getRefreshInputValue(currentInterval));
73953
+ const [validationError, setValidationError] = import_react47.useState(null);
72966
73954
  use_input_default((input, key) => {
72967
73955
  if (editingRefreshInterval) {
72968
73956
  if (key.return) {
@@ -73001,22 +73989,22 @@ var RefreshIntervalMenu = ({
73001
73989
  onBack();
73002
73990
  }
73003
73991
  });
73004
- return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
73992
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
73005
73993
  flexDirection: "column",
73006
73994
  children: [
73007
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
73995
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
73008
73996
  bold: true,
73009
73997
  children: "Configure Status Line"
73010
73998
  }, undefined, false, undefined, this),
73011
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
73999
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
73012
74000
  color: "white",
73013
74001
  children: "Configure Claude Code status line settings"
73014
74002
  }, undefined, false, undefined, this),
73015
- editingRefreshInterval ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
74003
+ editingRefreshInterval ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
73016
74004
  marginTop: 1,
73017
74005
  flexDirection: "column",
73018
74006
  children: [
73019
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74007
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
73020
74008
  children: [
73021
74009
  "Enter refresh interval in seconds (1-60):",
73022
74010
  " ",
@@ -73024,15 +74012,15 @@ var RefreshIntervalMenu = ({
73024
74012
  refreshInput.length > 0 ? "s" : ""
73025
74013
  ]
73026
74014
  }, undefined, true, undefined, this),
73027
- validationError ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74015
+ validationError ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
73028
74016
  color: "red",
73029
74017
  children: validationError
73030
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
74018
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
73031
74019
  dimColor: true,
73032
74020
  children: "Press Enter to confirm, ESC to cancel. Leave empty to remove."
73033
74021
  }, undefined, false, undefined, this)
73034
74022
  ]
73035
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(List, {
74023
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(List, {
73036
74024
  marginTop: 1,
73037
74025
  items: buildConfigureStatusLineItems(currentInterval, supportsRefreshInterval),
73038
74026
  onSelect: (value) => {
@@ -73052,7 +74040,7 @@ var RefreshIntervalMenu = ({
73052
74040
  init_source();
73053
74041
  init_ansi();
73054
74042
  await init_build2();
73055
- var import_react47 = __toESM(require_react(), 1);
74043
+ var import_react48 = __toESM(require_react(), 1);
73056
74044
 
73057
74045
  // src/utils/powerline-theme-index.ts
73058
74046
  function countPowerlineThemeSlots(entries) {
@@ -73086,7 +74074,7 @@ function advanceGlobalSeparatorIndex(currentIndex, widgets) {
73086
74074
  }
73087
74075
 
73088
74076
  // src/tui/components/StatusLinePreview.tsx
73089
- var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
74077
+ var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
73090
74078
  var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, globalPowerlineThemeIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
73091
74079
  const context = {
73092
74080
  terminalWidth,
@@ -73105,7 +74093,7 @@ function preparePreviewLineForTerminal(line, terminalWidth) {
73105
74093
  return truncateStyledText(printableLine, availableWidth, { ellipsis: true });
73106
74094
  }
73107
74095
  var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange }) => {
73108
- const { renderedLines, anyTruncated } = import_react47.default.useMemo(() => {
74096
+ const { renderedLines, anyTruncated } = import_react48.default.useMemo(() => {
73109
74097
  if (!settings)
73110
74098
  return { renderedLines: [], anyTruncated: false };
73111
74099
  const preRenderedLines = preRenderAllWidgets(lines, settings, { terminalWidth, isPreview: true, minimalist: settings.minimalistMode });
@@ -73131,29 +74119,29 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
73131
74119
  }
73132
74120
  return { renderedLines: result2, anyTruncated: truncated };
73133
74121
  }, [lines, terminalWidth, settings]);
73134
- import_react47.default.useEffect(() => {
74122
+ import_react48.default.useEffect(() => {
73135
74123
  onTruncationChange?.(anyTruncated);
73136
74124
  }, [anyTruncated, onTruncationChange]);
73137
- return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
74125
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
73138
74126
  flexDirection: "column",
73139
74127
  children: [
73140
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
74128
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
73141
74129
  borderStyle: "round",
73142
74130
  borderColor: "gray",
73143
74131
  borderDimColor: true,
73144
74132
  width: "100%",
73145
74133
  paddingLeft: 1,
73146
- children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
74134
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
73147
74135
  children: [
73148
74136
  ">",
73149
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
74137
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
73150
74138
  dimColor: true,
73151
74139
  children: " Preview (ctrl+s to save configuration at any time)"
73152
74140
  }, undefined, false, undefined, this)
73153
74141
  ]
73154
74142
  }, undefined, true, undefined, this)
73155
74143
  }, undefined, false, undefined, this),
73156
- renderedLines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
74144
+ renderedLines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
73157
74145
  wrap: "truncate",
73158
74146
  children: [
73159
74147
  PREVIEW_LINE_INDENT,
@@ -73167,7 +74155,7 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
73167
74155
  // src/tui/components/TerminalOptionsMenu.tsx
73168
74156
  init_source();
73169
74157
  await init_build2();
73170
- var import_react48 = __toESM(require_react(), 1);
74158
+ var import_react49 = __toESM(require_react(), 1);
73171
74159
 
73172
74160
  // src/utils/color-sanitize.ts
73173
74161
  await init_widgets2();
@@ -73222,7 +74210,7 @@ function sanitizeLinesForColorLevel(lines, nextLevel) {
73222
74210
  }
73223
74211
 
73224
74212
  // src/tui/components/TerminalOptionsMenu.tsx
73225
- var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
74213
+ var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
73226
74214
  function getNextColorLevel(level) {
73227
74215
  return (level + 1) % 4;
73228
74216
  }
@@ -73256,8 +74244,8 @@ var TerminalOptionsMenu = ({
73256
74244
  onUpdate,
73257
74245
  onBack
73258
74246
  }) => {
73259
- const [showColorWarning, setShowColorWarning] = import_react48.useState(false);
73260
- const [pendingColorLevel, setPendingColorLevel] = import_react48.useState(null);
74247
+ const [showColorWarning, setShowColorWarning] = import_react49.useState(false);
74248
+ const [pendingColorLevel, setPendingColorLevel] = import_react49.useState(null);
73261
74249
  const handleSelect = (value) => {
73262
74250
  if (value === "back") {
73263
74251
  onBack();
@@ -73305,27 +74293,27 @@ var TerminalOptionsMenu = ({
73305
74293
  onBack();
73306
74294
  }
73307
74295
  });
73308
- return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
74296
+ return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
73309
74297
  flexDirection: "column",
73310
74298
  children: [
73311
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
74299
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
73312
74300
  bold: true,
73313
74301
  children: "Terminal Options"
73314
74302
  }, undefined, false, undefined, this),
73315
- showColorWarning ? /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
74303
+ showColorWarning ? /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
73316
74304
  flexDirection: "column",
73317
74305
  marginTop: 1,
73318
74306
  children: [
73319
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
74307
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
73320
74308
  color: "yellow",
73321
74309
  children: "⚠ Warning: Custom colors detected!"
73322
74310
  }, undefined, false, undefined, this),
73323
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
74311
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
73324
74312
  children: "Switching color modes will reset custom ansi256 or hex colors to defaults."
73325
74313
  }, undefined, false, undefined, this),
73326
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
74314
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
73327
74315
  marginTop: 1,
73328
- children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ConfirmDialog, {
74316
+ children: /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(ConfirmDialog, {
73329
74317
  message: "Continue?",
73330
74318
  onConfirm: handleColorConfirm,
73331
74319
  onCancel: handleColorCancel,
@@ -73333,13 +74321,13 @@ var TerminalOptionsMenu = ({
73333
74321
  }, undefined, false, undefined, this)
73334
74322
  }, undefined, false, undefined, this)
73335
74323
  ]
73336
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(jsx_dev_runtime23.Fragment, {
74324
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(jsx_dev_runtime24.Fragment, {
73337
74325
  children: [
73338
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
74326
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
73339
74327
  color: "white",
73340
74328
  children: "Configure terminal-specific settings for optimal display"
73341
74329
  }, undefined, false, undefined, this),
73342
- /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(List, {
74330
+ /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(List, {
73343
74331
  marginTop: 1,
73344
74332
  items: buildTerminalOptionsItems(settings.colorLevel),
73345
74333
  onSelect: handleSelect,
@@ -73368,8 +74356,8 @@ var getColorLevelLabel = (level) => {
73368
74356
  // src/tui/components/TerminalWidthMenu.tsx
73369
74357
  init_input_guards();
73370
74358
  await init_build2();
73371
- var import_react49 = __toESM(require_react(), 1);
73372
- var jsx_dev_runtime24 = __toESM(require_jsx_dev_runtime(), 1);
74359
+ var import_react50 = __toESM(require_react(), 1);
74360
+ var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
73373
74361
  var TERMINAL_WIDTH_OPTIONS = ["full", "full-minus-40", "full-until-compact"];
73374
74362
  function getTerminalWidthSelectionIndex(selectedOption) {
73375
74363
  const selectedIndex = TERMINAL_WIDTH_OPTIONS.indexOf(selectedOption);
@@ -73416,11 +74404,11 @@ var TerminalWidthMenu = ({
73416
74404
  onUpdate,
73417
74405
  onBack
73418
74406
  }) => {
73419
- const [selectedOption, setSelectedOption] = import_react49.useState(settings.flexMode);
73420
- const [compactThreshold, setCompactThreshold] = import_react49.useState(settings.compactThreshold);
73421
- const [editingThreshold, setEditingThreshold] = import_react49.useState(false);
73422
- const [thresholdInput, setThresholdInput] = import_react49.useState(String(settings.compactThreshold));
73423
- const [validationError, setValidationError] = import_react49.useState(null);
74407
+ const [selectedOption, setSelectedOption] = import_react50.useState(settings.flexMode);
74408
+ const [compactThreshold, setCompactThreshold] = import_react50.useState(settings.compactThreshold);
74409
+ const [editingThreshold, setEditingThreshold] = import_react50.useState(false);
74410
+ const [thresholdInput, setThresholdInput] = import_react50.useState(String(settings.compactThreshold));
74411
+ const [validationError, setValidationError] = import_react50.useState(null);
73424
74412
  use_input_default((input, key) => {
73425
74413
  if (editingThreshold) {
73426
74414
  if (key.return) {
@@ -73459,27 +74447,27 @@ var TerminalWidthMenu = ({
73459
74447
  onBack();
73460
74448
  }
73461
74449
  });
73462
- return /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
74450
+ return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
73463
74451
  flexDirection: "column",
73464
74452
  children: [
73465
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
74453
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
73466
74454
  bold: true,
73467
74455
  children: "Terminal Width"
73468
74456
  }, undefined, false, undefined, this),
73469
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
74457
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
73470
74458
  color: "white",
73471
74459
  children: "These settings affect where long lines are truncated, and where right-alignment occurs when using flex separators"
73472
74460
  }, undefined, false, undefined, this),
73473
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
74461
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
73474
74462
  dimColor: true,
73475
74463
  wrap: "wrap",
73476
74464
  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"
73477
74465
  }, undefined, false, undefined, this),
73478
- editingThreshold ? /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Box_default, {
74466
+ editingThreshold ? /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
73479
74467
  marginTop: 1,
73480
74468
  flexDirection: "column",
73481
74469
  children: [
73482
- /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
74470
+ /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
73483
74471
  children: [
73484
74472
  "Enter compact threshold (1-99):",
73485
74473
  " ",
@@ -73487,15 +74475,15 @@ var TerminalWidthMenu = ({
73487
74475
  "%"
73488
74476
  ]
73489
74477
  }, undefined, true, undefined, this),
73490
- validationError ? /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
74478
+ validationError ? /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
73491
74479
  color: "red",
73492
74480
  children: validationError
73493
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(Text, {
74481
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
73494
74482
  dimColor: true,
73495
74483
  children: "Press Enter to confirm, ESC to cancel"
73496
74484
  }, undefined, false, undefined, this)
73497
74485
  ]
73498
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime24.jsxDEV(List, {
74486
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(List, {
73499
74487
  marginTop: 1,
73500
74488
  items: buildTerminalWidthItems(selectedOption, compactThreshold),
73501
74489
  initialSelection: getTerminalWidthSelectionIndex(selectedOption),
@@ -73520,50 +74508,487 @@ var TerminalWidthMenu = ({
73520
74508
  ]
73521
74509
  }, undefined, true, undefined, this);
73522
74510
  };
74511
+ // src/tui/components/UpdateCheckerMenu.tsx
74512
+ await init_build2();
74513
+ var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
74514
+ function getInstallationLabel2(result2) {
74515
+ const { installation } = result2;
74516
+ if (installation.method === "auto-update") {
74517
+ return `Auto-update via ${installation.packageManager}`;
74518
+ }
74519
+ if (installation.method === "pinned") {
74520
+ const version2 = installation.installedVersion ? ` ${installation.installedVersion}` : "";
74521
+ const manager = installation.packageManager === "unknown" ? "" : ` via ${installation.packageManager}`;
74522
+ return `Pinned global install${manager}${version2}`;
74523
+ }
74524
+ if (installation.method === "self-managed") {
74525
+ return "Self-managed/global install";
74526
+ }
74527
+ return "Unknown or not installed";
74528
+ }
74529
+ function getActionLabel(action) {
74530
+ return `Run ${action.command}`;
74531
+ }
74532
+ function getActionSublabel(action) {
74533
+ if (action.available) {
74534
+ return;
74535
+ }
74536
+ return action.packageManager === "npm" ? "(npm not installed)" : "(bun not installed)";
74537
+ }
74538
+ function getActionItems(actions) {
74539
+ return [
74540
+ ...actions.map((action) => ({
74541
+ label: getActionLabel(action),
74542
+ value: action,
74543
+ disabled: !action.available,
74544
+ sublabel: getActionSublabel(action)
74545
+ })),
74546
+ {
74547
+ label: "Check again",
74548
+ value: "refresh"
74549
+ }
74550
+ ];
74551
+ }
74552
+ var UpdateCheckerMenu = ({
74553
+ state,
74554
+ onBack,
74555
+ onRefresh,
74556
+ onRunAction
74557
+ }) => {
74558
+ use_input_default((_, key) => {
74559
+ if (key.escape) {
74560
+ onBack();
74561
+ }
74562
+ });
74563
+ if (state.status === "checking") {
74564
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74565
+ flexDirection: "column",
74566
+ children: [
74567
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74568
+ bold: true,
74569
+ children: "Check for Updates"
74570
+ }, undefined, false, undefined, this),
74571
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74572
+ marginTop: 1,
74573
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74574
+ dimColor: true,
74575
+ children: "Checking npm registry..."
74576
+ }, undefined, false, undefined, this)
74577
+ }, undefined, false, undefined, this)
74578
+ ]
74579
+ }, undefined, true, undefined, this);
74580
+ }
74581
+ return /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74582
+ flexDirection: "column",
74583
+ children: [
74584
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74585
+ bold: true,
74586
+ children: "Check for Updates"
74587
+ }, undefined, false, undefined, this),
74588
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74589
+ marginTop: 1,
74590
+ flexDirection: "column",
74591
+ children: [
74592
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74593
+ children: [
74594
+ "Current:",
74595
+ " ",
74596
+ state.currentVersion
74597
+ ]
74598
+ }, undefined, true, undefined, this),
74599
+ state.status !== "registry-failure" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74600
+ children: [
74601
+ "Latest:",
74602
+ " ",
74603
+ state.latestVersion
74604
+ ]
74605
+ }, undefined, true, undefined, this),
74606
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74607
+ children: [
74608
+ "Install:",
74609
+ " ",
74610
+ getInstallationLabel2(state)
74611
+ ]
74612
+ }, undefined, true, undefined, this)
74613
+ ]
74614
+ }, undefined, true, undefined, this),
74615
+ state.status === "registry-failure" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(jsx_dev_runtime26.Fragment, {
74616
+ children: [
74617
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74618
+ marginTop: 1,
74619
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74620
+ color: "red",
74621
+ children: [
74622
+ "Registry check failed:",
74623
+ " ",
74624
+ state.errorMessage
74625
+ ]
74626
+ }, undefined, true, undefined, this)
74627
+ }, undefined, false, undefined, this),
74628
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(List, {
74629
+ marginTop: 1,
74630
+ items: [{ label: "Check again", value: "refresh" }],
74631
+ onSelect: (value) => {
74632
+ if (value === "back") {
74633
+ onBack();
74634
+ return;
74635
+ }
74636
+ onRefresh();
74637
+ },
74638
+ showBackButton: true
74639
+ }, undefined, false, undefined, this)
74640
+ ]
74641
+ }, undefined, true, undefined, this),
74642
+ state.status === "up-to-date" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(jsx_dev_runtime26.Fragment, {
74643
+ children: [
74644
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74645
+ marginTop: 1,
74646
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74647
+ color: "green",
74648
+ children: "ccstatusline is up to date."
74649
+ }, undefined, false, undefined, this)
74650
+ }, undefined, false, undefined, this),
74651
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(List, {
74652
+ marginTop: 1,
74653
+ items: [{ label: "Check again", value: "refresh" }],
74654
+ onSelect: (value) => {
74655
+ if (value === "back") {
74656
+ onBack();
74657
+ return;
74658
+ }
74659
+ onRefresh();
74660
+ },
74661
+ showBackButton: true
74662
+ }, undefined, false, undefined, this)
74663
+ ]
74664
+ }, undefined, true, undefined, this),
74665
+ state.status === "update-available" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(jsx_dev_runtime26.Fragment, {
74666
+ children: [
74667
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74668
+ marginTop: 1,
74669
+ children: /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74670
+ color: "yellow",
74671
+ children: "An update is available."
74672
+ }, undefined, false, undefined, this)
74673
+ }, undefined, false, undefined, this),
74674
+ state.installation.method === "auto-update" && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Box_default, {
74675
+ marginTop: 1,
74676
+ flexDirection: "column",
74677
+ children: [
74678
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74679
+ children: "No manual hook change is needed. Claude Code already runs @latest."
74680
+ }, undefined, false, undefined, this),
74681
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74682
+ children: "The next @latest invocation will resolve the latest package."
74683
+ }, undefined, false, undefined, this),
74684
+ /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(Text, {
74685
+ children: [
74686
+ "Launch command for a fresh TUI:",
74687
+ " ",
74688
+ state.autoUpdateLaunchCommand
74689
+ ]
74690
+ }, undefined, true, undefined, this)
74691
+ ]
74692
+ }, undefined, true, undefined, this),
74693
+ state.actions.length > 0 && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(List, {
74694
+ marginTop: 1,
74695
+ items: getActionItems(state.actions),
74696
+ onSelect: (value) => {
74697
+ if (value === "back") {
74698
+ onBack();
74699
+ return;
74700
+ }
74701
+ if (value === "refresh") {
74702
+ onRefresh();
74703
+ return;
74704
+ }
74705
+ onRunAction(value);
74706
+ },
74707
+ showBackButton: true
74708
+ }, undefined, false, undefined, this),
74709
+ state.actions.length === 0 && /* @__PURE__ */ jsx_dev_runtime26.jsxDEV(List, {
74710
+ marginTop: 1,
74711
+ items: [{ label: "Check again", value: "refresh" }],
74712
+ onSelect: (value) => {
74713
+ if (value === "back") {
74714
+ onBack();
74715
+ return;
74716
+ }
74717
+ onRefresh();
74718
+ },
74719
+ showBackButton: true
74720
+ }, undefined, false, undefined, this)
74721
+ ]
74722
+ }, undefined, true, undefined, this)
74723
+ ]
74724
+ }, undefined, true, undefined, this);
74725
+ };
73523
74726
  // src/tui/App.tsx
73524
- var jsx_dev_runtime25 = __toESM(require_jsx_dev_runtime(), 1);
74727
+ var jsx_dev_runtime27 = __toESM(require_jsx_dev_runtime(), 1);
73525
74728
  var GITHUB_REPO_URL = "https://github.com/sirmalloc/ccstatusline";
74729
+ var NOTICE_ITEMS = [
74730
+ {
74731
+ label: "Continue",
74732
+ value: "continue"
74733
+ }
74734
+ ];
74735
+ var FlowNotice = ({
74736
+ title,
74737
+ message,
74738
+ color,
74739
+ onContinue
74740
+ }) => {
74741
+ use_input_default((_, key) => {
74742
+ if (key.escape) {
74743
+ onContinue();
74744
+ }
74745
+ });
74746
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
74747
+ flexDirection: "column",
74748
+ children: [
74749
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
74750
+ bold: true,
74751
+ children: title
74752
+ }, undefined, false, undefined, this),
74753
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
74754
+ marginTop: 1,
74755
+ children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
74756
+ color,
74757
+ wrap: "wrap",
74758
+ children: message
74759
+ }, undefined, false, undefined, this)
74760
+ }, undefined, false, undefined, this),
74761
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(List, {
74762
+ marginTop: 1,
74763
+ items: NOTICE_ITEMS,
74764
+ onSelect: () => {
74765
+ onContinue();
74766
+ },
74767
+ color: "cyan"
74768
+ }, undefined, false, undefined, this)
74769
+ ]
74770
+ }, undefined, true, undefined, this);
74771
+ };
74772
+ function getPinnedMismatchItems(mismatch, canRunPackageManager) {
74773
+ const items = [];
74774
+ if (mismatch.canUpdateToRunningVersion) {
74775
+ items.push({
74776
+ label: `Update ${mismatch.packageManager} global install to v${mismatch.runningVersion}`,
74777
+ value: "update",
74778
+ disabled: !canRunPackageManager,
74779
+ sublabel: canRunPackageManager ? undefined : `(${mismatch.packageManager} not installed)`,
74780
+ description: `Runs ${mismatch.packageManager === "npm" ? `npm install -g ccstatusline@${mismatch.runningVersion}` : `bun add -g ccstatusline@${mismatch.runningVersion}`}`
74781
+ });
74782
+ }
74783
+ items.push({
74784
+ label: "Exit",
74785
+ value: "exit",
74786
+ description: `Relaunch manually with ${mismatch.relaunchCommand}`
74787
+ });
74788
+ return items;
74789
+ }
74790
+ var PinnedVersionMismatchScreen = ({
74791
+ mismatch,
74792
+ canRunPackageManager,
74793
+ onUpdate,
74794
+ onExit
74795
+ }) => {
74796
+ use_input_default((_, key) => {
74797
+ if (key.escape) {
74798
+ onExit();
74799
+ }
74800
+ });
74801
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
74802
+ flexDirection: "column",
74803
+ children: [
74804
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
74805
+ bold: true,
74806
+ children: "Pinned Install Version Mismatch"
74807
+ }, undefined, false, undefined, this),
74808
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
74809
+ marginTop: 1,
74810
+ flexDirection: "column",
74811
+ children: [
74812
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
74813
+ color: "yellow",
74814
+ children: [
74815
+ "Claude Code is pinned to ccstatusline v",
74816
+ mismatch.installedVersion,
74817
+ ", but this TUI is v",
74818
+ mismatch.runningVersion,
74819
+ "."
74820
+ ]
74821
+ }, undefined, true, undefined, this),
74822
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
74823
+ dimColor: true,
74824
+ wrap: "wrap",
74825
+ children: "To avoid writing config that the pinned runtime may not support, update the pinned global install or exit and relaunch the pinned version."
74826
+ }, undefined, false, undefined, this)
74827
+ ]
74828
+ }, undefined, true, undefined, this),
74829
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
74830
+ marginTop: 1,
74831
+ flexDirection: "column",
74832
+ children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
74833
+ children: [
74834
+ "Current pinned version:",
74835
+ " ",
74836
+ mismatch.relaunchCommand
74837
+ ]
74838
+ }, undefined, true, undefined, this)
74839
+ }, undefined, false, undefined, this),
74840
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(List, {
74841
+ marginTop: 1,
74842
+ items: getPinnedMismatchItems(mismatch, canRunPackageManager),
74843
+ onSelect: (value) => {
74844
+ if (value === "back") {
74845
+ return;
74846
+ }
74847
+ if (value === "update") {
74848
+ onUpdate();
74849
+ return;
74850
+ }
74851
+ onExit();
74852
+ },
74853
+ color: "cyan"
74854
+ }, undefined, false, undefined, this)
74855
+ ]
74856
+ }, undefined, true, undefined, this);
74857
+ };
74858
+ function getGlobalUninstallCommand(packageManager) {
74859
+ return packageManager === "npm" ? "npm uninstall -g ccstatusline" : "bun remove -g ccstatusline";
74860
+ }
74861
+ function buildUninstallConfirmMessage(selection) {
74862
+ if (selection.packageManagers.length === 0) {
74863
+ return `This will remove ccstatusline from ${getClaudeSettingsPath()}. Continue?`;
74864
+ }
74865
+ const commands = selection.packageManagers.map((packageManager) => getGlobalUninstallCommand(packageManager)).join(`
74866
+ `);
74867
+ return `This will remove ccstatusline from ${getClaudeSettingsPath()} and run:
74868
+
74869
+ ${commands}
74870
+
74871
+ Continue?`;
74872
+ }
74873
+ function clearInstallationMetadata(settings) {
74874
+ if (!settings) {
74875
+ return settings;
74876
+ }
74877
+ const { installation, ...next } = settings;
74878
+ return next;
74879
+ }
74880
+ function getCurrentInstallation(isClaudeInstalled, existingStatusLine, settings) {
74881
+ return isClaudeInstalled && !existingStatusLine && settings.installation ? settings.installation : classifyInstallation(existingStatusLine, settings.installation);
74882
+ }
74883
+ function trimTrailingSeparators2(filePath) {
74884
+ return filePath.replace(/[\\/]+$/, "");
74885
+ }
74886
+ function joinCommandPath(dir, command) {
74887
+ const separator = dir.includes("\\") && !dir.includes("/") ? "\\" : "/";
74888
+ return `${trimTrailingSeparators2(dir)}${separator}${command}`;
74889
+ }
74890
+ function getCommandFileName(globalBinDir, platform5) {
74891
+ if (platform5 === "win32" || /^[a-z]:[\\/]/i.test(globalBinDir)) {
74892
+ return "ccstatusline.cmd";
74893
+ }
74894
+ return "ccstatusline";
74895
+ }
74896
+ function getPinnedGlobalRelaunchCommand(packageManager) {
74897
+ const resolution = inspectGlobalCommandResolution(packageManager);
74898
+ if (resolution.firstResolvedPath && (!resolution.expectedBinDir || isPathInsideDir(resolution.firstResolvedPath, resolution.expectedBinDir))) {
74899
+ return resolution.firstResolvedPath;
74900
+ }
74901
+ if (resolution.expectedBinDir) {
74902
+ return joinCommandPath(resolution.expectedBinDir, getCommandFileName(resolution.expectedBinDir, process.platform));
74903
+ }
74904
+ return "ccstatusline";
74905
+ }
74906
+ function getPinnedVersionMismatch(installation, runningVersion, relaunchCommand) {
74907
+ if (installation.method !== "pinned" || !installation.installedVersion || installation.packageManager === "unknown" || !runningVersion || installation.installedVersion === runningVersion) {
74908
+ return null;
74909
+ }
74910
+ return {
74911
+ packageManager: installation.packageManager,
74912
+ installedVersion: installation.installedVersion,
74913
+ runningVersion,
74914
+ relaunchCommand,
74915
+ canUpdateToRunningVersion: compareVersions(runningVersion, installation.installedVersion) > 0
74916
+ };
74917
+ }
74918
+ function getPathInferredInstallation(installation, activeCommand) {
74919
+ if (installation.method === "pinned") {
74920
+ return {
74921
+ ...installation,
74922
+ packageManager: activeCommand?.packageManager ?? "unknown",
74923
+ installedVersion: activeCommand?.version ?? installation.installedVersion
74924
+ };
74925
+ }
74926
+ if (activeCommand && activeCommand.packageManager !== "unknown" && installation.method === "self-managed") {
74927
+ return {
74928
+ ...installation,
74929
+ packageManager: activeCommand.packageManager
74930
+ };
74931
+ }
74932
+ return installation;
74933
+ }
73526
74934
  function getConfirmCancelScreen(confirmDialog) {
73527
74935
  return confirmDialog?.cancelScreen ?? "main";
73528
74936
  }
73529
74937
  function clearInstallMenuSelection(menuSelections) {
73530
- if (menuSelections.install === undefined) {
74938
+ if (menuSelections.install === undefined && menuSelections.installPackage === undefined) {
73531
74939
  return menuSelections;
73532
74940
  }
73533
74941
  const next = { ...menuSelections };
73534
74942
  delete next.install;
74943
+ delete next.installPackage;
73535
74944
  return next;
73536
74945
  }
73537
74946
  var App2 = () => {
73538
74947
  const { exit } = use_app_default();
73539
- const [settings, setSettings] = import_react50.useState(null);
73540
- const [originalSettings, setOriginalSettings] = import_react50.useState(null);
73541
- const [hasChanges, setHasChanges] = import_react50.useState(false);
73542
- const [screen, setScreen] = import_react50.useState("main");
73543
- const [selectedLine, setSelectedLine] = import_react50.useState(0);
73544
- const [menuSelections, setMenuSelections] = import_react50.useState({});
73545
- const [confirmDialog, setConfirmDialog] = import_react50.useState(null);
73546
- const [isClaudeInstalled, setIsClaudeInstalled] = import_react50.useState(false);
73547
- const [terminalWidth, setTerminalWidth] = import_react50.useState(process.stdout.columns || 80);
73548
- const [powerlineFontStatus, setPowerlineFontStatus] = import_react50.useState({ installed: false });
73549
- const [installingFonts, setInstallingFonts] = import_react50.useState(false);
73550
- const [fontInstallMessage, setFontInstallMessage] = import_react50.useState(null);
73551
- const [existingStatusLine, setExistingStatusLine] = import_react50.useState(null);
73552
- const [flashMessage, setFlashMessage] = import_react50.useState(null);
73553
- const [previewIsTruncated, setPreviewIsTruncated] = import_react50.useState(false);
73554
- const [currentRefreshInterval, setCurrentRefreshInterval] = import_react50.useState(null);
73555
- const [supportsRefreshInterval] = import_react50.useState(() => isClaudeCodeVersionAtLeast("2.1.97"));
73556
- import_react50.useEffect(() => {
74948
+ const [settings, setSettings] = import_react51.useState(null);
74949
+ const [originalSettings, setOriginalSettings] = import_react51.useState(null);
74950
+ const [hasChanges, setHasChanges] = import_react51.useState(false);
74951
+ const [screen, setScreen] = import_react51.useState("main");
74952
+ const [selectedLine, setSelectedLine] = import_react51.useState(0);
74953
+ const [menuSelections, setMenuSelections] = import_react51.useState({});
74954
+ const [confirmDialog, setConfirmDialog] = import_react51.useState(null);
74955
+ const [isClaudeInstalled, setIsClaudeInstalled] = import_react51.useState(false);
74956
+ const [terminalWidth, setTerminalWidth] = import_react51.useState(process.stdout.columns || 80);
74957
+ const [powerlineFontStatus, setPowerlineFontStatus] = import_react51.useState({ installed: false });
74958
+ const [installingFonts, setInstallingFonts] = import_react51.useState(false);
74959
+ const [fontInstallMessage, setFontInstallMessage] = import_react51.useState(null);
74960
+ const [existingStatusLine, setExistingStatusLine] = import_react51.useState(null);
74961
+ const [flashMessage, setFlashMessage] = import_react51.useState(null);
74962
+ const [previewIsTruncated, setPreviewIsTruncated] = import_react51.useState(false);
74963
+ const [currentRefreshInterval, setCurrentRefreshInterval] = import_react51.useState(null);
74964
+ const [supportsRefreshInterval] = import_react51.useState(() => isClaudeCodeVersionAtLeast("2.1.97"));
74965
+ const [commandAvailability] = import_react51.useState(() => getPackageCommandAvailability());
74966
+ const [updateCheckerState, setUpdateCheckerState] = import_react51.useState({ status: "checking" });
74967
+ const [flowNotice, setFlowNotice] = import_react51.useState(null);
74968
+ const [globalPackageInstallations, setGlobalPackageInstallations] = import_react51.useState([]);
74969
+ const [updatesReturnScreen, setUpdatesReturnScreen] = import_react51.useState("main");
74970
+ const [hasLoadedClaudeStatus, setHasLoadedClaudeStatus] = import_react51.useState(false);
74971
+ const [hasLoadedInstalledState, setHasLoadedInstalledState] = import_react51.useState(false);
74972
+ import_react51.useEffect(() => {
73557
74973
  loadClaudeStatusLineState().then((statusLineState) => {
73558
74974
  setExistingStatusLine(statusLineState.existingStatusLine);
73559
74975
  setCurrentRefreshInterval(statusLineState.refreshInterval);
74976
+ }).catch(() => {
74977
+ setExistingStatusLine(null);
74978
+ setCurrentRefreshInterval(null);
74979
+ }).finally(() => {
74980
+ setHasLoadedClaudeStatus(true);
73560
74981
  });
73561
74982
  loadSettings().then((loadedSettings) => {
73562
74983
  source_default.level = loadedSettings.colorLevel;
73563
74984
  setSettings(loadedSettings);
73564
74985
  setOriginalSettings(cloneSettings(loadedSettings));
73565
74986
  });
73566
- isInstalled().then(setIsClaudeInstalled);
74987
+ isInstalled().then(setIsClaudeInstalled).catch(() => {
74988
+ setIsClaudeInstalled(false);
74989
+ }).finally(() => {
74990
+ setHasLoadedInstalledState(true);
74991
+ });
73567
74992
  const fontStatus = checkPowerlineFonts();
73568
74993
  setPowerlineFontStatus(fontStatus);
73569
74994
  checkPowerlineFontsAsync().then((asyncStatus) => {
@@ -73577,13 +75002,13 @@ var App2 = () => {
73577
75002
  process.stdout.off("resize", handleResize);
73578
75003
  };
73579
75004
  }, []);
73580
- import_react50.useEffect(() => {
75005
+ import_react51.useEffect(() => {
73581
75006
  if (originalSettings) {
73582
75007
  const hasAnyChanges = JSON.stringify(settings) !== JSON.stringify(originalSettings);
73583
75008
  setHasChanges(hasAnyChanges);
73584
75009
  }
73585
75010
  }, [settings, originalSettings]);
73586
- import_react50.useEffect(() => {
75011
+ import_react51.useEffect(() => {
73587
75012
  if (flashMessage) {
73588
75013
  const timer = setTimeout(() => {
73589
75014
  setFlashMessage(null);
@@ -73598,6 +75023,13 @@ var App2 = () => {
73598
75023
  exit();
73599
75024
  }
73600
75025
  if (key.ctrl && input === "s" && settings) {
75026
+ const installation = getCurrentInstallation(isClaudeInstalled, existingStatusLine, settings);
75027
+ const activeCommand = installation.method === "pinned" || installation.method === "self-managed" ? inspectActiveGlobalCommand({ commandAvailability }) : null;
75028
+ const effectiveInstallation2 = getPathInferredInstallation(installation, activeCommand);
75029
+ const mismatch = getPinnedVersionMismatch(effectiveInstallation2, getPackageVersion(), "ccstatusline");
75030
+ if (mismatch) {
75031
+ return;
75032
+ }
73601
75033
  (async () => {
73602
75034
  await saveSettings(settings);
73603
75035
  setOriginalSettings(cloneSettings(settings));
@@ -73609,73 +75041,276 @@ var App2 = () => {
73609
75041
  })();
73610
75042
  }
73611
75043
  });
73612
- const handleInstallSelection = import_react50.useCallback((command, displayName, useBunx) => {
75044
+ const getGlobalResolutionWarning = import_react51.useCallback((packageManager) => inspectGlobalCommandResolution(packageManager).warning, []);
75045
+ const handleInstallSelection = import_react51.useCallback((selection) => {
73613
75046
  getExistingStatusLine().then((existing) => {
73614
75047
  const isAlreadyInstalled = isKnownCommand(existing ?? "");
73615
- let message;
75048
+ const finalCommand = buildStatusLineCommand(selection.commandMode);
75049
+ const hookCommand = `${finalCommand} --hook`;
75050
+ const sideEffects = [
75051
+ `Claude settings path: ${getClaudeSettingsPath()}`,
75052
+ ...selection.globalInstallCommand ? [`Global install command before settings write: ${selection.globalInstallCommand}`] : [],
75053
+ `Final statusLine.command: ${finalCommand}`,
75054
+ `Hook command behavior: hook-enabled widgets run ${hookCommand}`
75055
+ ];
75056
+ let message = sideEffects.join(`
75057
+ `);
73616
75058
  if (existing && !isAlreadyInstalled) {
73617
- message = `This will modify ${getClaudeSettingsPath()}
75059
+ message = `A status line is already configured: "${existing}"
73618
75060
 
73619
- A status line is already configured: "${existing}"
73620
- Replace it with ${command}?`;
75061
+ ${message}
75062
+
75063
+ Replace it?`;
73621
75064
  } else if (isAlreadyInstalled) {
73622
- message = `ccstatusline is already installed in ${getClaudeSettingsPath()}
73623
- Update it with ${command}?`;
75065
+ message = `ccstatusline is already installed.
75066
+
75067
+ ${message}
75068
+
75069
+ Update it?`;
73624
75070
  } else {
73625
- message = `This will modify ${getClaudeSettingsPath()} to add ccstatusline with ${displayName}.
75071
+ message = `${message}
75072
+
73626
75073
  Continue?`;
73627
75074
  }
73628
75075
  setConfirmDialog({
73629
75076
  message,
73630
75077
  cancelScreen: "install",
73631
75078
  action: async () => {
73632
- await installStatusLine(useBunx, supportsRefreshInterval);
73633
- const installedStatusLineState = await loadClaudeStatusLineState();
73634
- setIsClaudeInstalled(true);
73635
- setExistingStatusLine(installedStatusLineState.existingStatusLine ?? command);
73636
- setCurrentRefreshInterval(installedStatusLineState.refreshInterval);
73637
- setScreen("main");
75079
+ try {
75080
+ if (selection.globalInstallCommand) {
75081
+ await runGlobalPackageInstall(selection.packageManager, getPackageVersion());
75082
+ }
75083
+ await installStatusLine({
75084
+ commandMode: selection.commandMode,
75085
+ supportsRefreshInterval,
75086
+ installationMetadata: selection.metadata
75087
+ });
75088
+ const installedStatusLineState = await loadClaudeStatusLineState();
75089
+ setIsClaudeInstalled(true);
75090
+ setExistingStatusLine(installedStatusLineState.existingStatusLine ?? finalCommand);
75091
+ setCurrentRefreshInterval(installedStatusLineState.refreshInterval);
75092
+ setSettings((prev) => prev ? { ...prev, installation: selection.metadata } : prev);
75093
+ setOriginalSettings((prev) => prev ? { ...prev, installation: selection.metadata } : prev);
75094
+ setMenuSelections((prev) => ({
75095
+ ...prev,
75096
+ main: getMainMenuInstallSelectionIndex(true, selection.metadata)
75097
+ }));
75098
+ const resolutionWarning = selection.globalInstallCommand ? getGlobalResolutionWarning(selection.packageManager) : null;
75099
+ if (resolutionWarning) {
75100
+ setFlashMessage(null);
75101
+ setFlowNotice({
75102
+ title: "Install Complete",
75103
+ message: `Installed to Claude Code.
75104
+
75105
+ ${resolutionWarning}`,
75106
+ color: "yellow",
75107
+ continueScreen: "main"
75108
+ });
75109
+ setScreen("flowNotice");
75110
+ } else {
75111
+ setScreen("main");
75112
+ setFlashMessage({
75113
+ text: "✓ Installed to Claude Code",
75114
+ color: "green"
75115
+ });
75116
+ }
75117
+ } catch {
75118
+ setFlashMessage({
75119
+ text: "✗ Install failed",
75120
+ color: "red"
75121
+ });
75122
+ setScreen("install");
75123
+ }
73638
75124
  setConfirmDialog(null);
73639
75125
  }
73640
75126
  });
73641
75127
  setScreen("confirm");
73642
75128
  });
73643
- }, [supportsRefreshInterval]);
73644
- const handleNpxInstall = import_react50.useCallback(() => {
73645
- setMenuSelections((prev) => ({ ...prev, install: 0 }));
73646
- handleInstallSelection(CCSTATUSLINE_COMMANDS.NPM, "npx", false);
73647
- }, [handleInstallSelection]);
73648
- const handleBunxInstall = import_react50.useCallback(() => {
73649
- setMenuSelections((prev) => ({ ...prev, install: 1 }));
73650
- handleInstallSelection(CCSTATUSLINE_COMMANDS.BUNX, "bunx", true);
73651
- }, [handleInstallSelection]);
73652
- const handleInstallMenuCancel = import_react50.useCallback(() => {
75129
+ }, [getGlobalResolutionWarning, supportsRefreshInterval]);
75130
+ const handleInstallMenuCancel = import_react51.useCallback(() => {
73653
75131
  setMenuSelections(clearInstallMenuSelection);
73654
75132
  setScreen("main");
73655
75133
  }, []);
73656
- if (!settings) {
73657
- return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
75134
+ const handleUpdateCheck = import_react51.useCallback(() => {
75135
+ setUpdateCheckerState({ status: "checking" });
75136
+ const installation = settings ? getCurrentInstallation(isClaudeInstalled, existingStatusLine, settings) : classifyInstallation(existingStatusLine, undefined);
75137
+ const activeCommand = installation.method === "pinned" || installation.method === "self-managed" ? inspectActiveGlobalCommand({ commandAvailability }) : null;
75138
+ const effectiveUpdateInstallation = getPathInferredInstallation(installation, activeCommand);
75139
+ const currentUpdateVersion = effectiveUpdateInstallation.method === "pinned" && effectiveUpdateInstallation.installedVersion ? effectiveUpdateInstallation.installedVersion : getPackageVersion();
75140
+ checkForUpdates({
75141
+ currentVersion: currentUpdateVersion,
75142
+ installedCommand: existingStatusLine,
75143
+ installationMetadata: effectiveUpdateInstallation,
75144
+ commandAvailability
75145
+ }).then(setUpdateCheckerState);
75146
+ }, [commandAvailability, existingStatusLine, isClaudeInstalled, settings]);
75147
+ const handleRunUpdateAction = import_react51.useCallback((action) => {
75148
+ setConfirmDialog({
75149
+ message: `Run global update command?
75150
+
75151
+ ${action.command}
75152
+
75153
+ Claude settings will not be changed.`,
75154
+ cancelScreen: "updates",
75155
+ action: async () => {
75156
+ try {
75157
+ await runGlobalUpdateAction(action);
75158
+ const installation = {
75159
+ method: "pinned",
75160
+ installedVersion: action.version
75161
+ };
75162
+ await saveInstallationMetadata(installation);
75163
+ setSettings((prev) => prev ? { ...prev, installation } : prev);
75164
+ setOriginalSettings((prev) => prev ? { ...prev, installation } : prev);
75165
+ const resolutionWarning = getGlobalResolutionWarning(action.packageManager);
75166
+ if (resolutionWarning) {
75167
+ setFlashMessage(null);
75168
+ setFlowNotice({
75169
+ title: "Update Complete",
75170
+ message: `Global package updated.
75171
+
75172
+ ${resolutionWarning}`,
75173
+ color: "yellow",
75174
+ continueScreen: "updates"
75175
+ });
75176
+ setScreen("flowNotice");
75177
+ } else {
75178
+ setFlashMessage({
75179
+ text: "✓ Global package updated",
75180
+ color: "green"
75181
+ });
75182
+ setScreen("updates");
75183
+ }
75184
+ } catch {
75185
+ setFlashMessage({
75186
+ text: "✗ Global update failed",
75187
+ color: "red"
75188
+ });
75189
+ setScreen("updates");
75190
+ }
75191
+ setConfirmDialog(null);
75192
+ }
75193
+ });
75194
+ setScreen("confirm");
75195
+ }, [getGlobalResolutionWarning]);
75196
+ if (!settings || !hasLoadedClaudeStatus || !hasLoadedInstalledState) {
75197
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
73658
75198
  children: "Loading settings..."
73659
75199
  }, undefined, false, undefined, this);
73660
75200
  }
73661
- const handleInstallUninstall = () => {
73662
- if (isClaudeInstalled) {
73663
- setConfirmDialog({
73664
- message: `This will remove ccstatusline from ${getClaudeSettingsPath()}. Continue?`,
73665
- action: async () => {
75201
+ const runningVersion = getPackageVersion();
75202
+ const currentInstallation = getCurrentInstallation(isClaudeInstalled, existingStatusLine, settings);
75203
+ const activeGlobalCommand = currentInstallation.method === "pinned" || currentInstallation.method === "self-managed" ? inspectActiveGlobalCommand({ commandAvailability }) : null;
75204
+ const effectiveInstallation = getPathInferredInstallation(currentInstallation, activeGlobalCommand);
75205
+ const pinnedVersionMismatch = effectiveInstallation.method === "pinned" && effectiveInstallation.packageManager !== "unknown" ? getPinnedVersionMismatch(effectiveInstallation, runningVersion, getPinnedGlobalRelaunchCommand(effectiveInstallation.packageManager)) : null;
75206
+ const handlePinnedVersionMismatchUpdate = async (mismatch) => {
75207
+ try {
75208
+ await runGlobalPackageInstall(mismatch.packageManager, mismatch.runningVersion);
75209
+ const installation = {
75210
+ method: "pinned",
75211
+ installedVersion: mismatch.runningVersion
75212
+ };
75213
+ await saveInstallationMetadata(installation);
75214
+ setSettings((prev) => prev ? { ...prev, installation } : prev);
75215
+ setOriginalSettings((prev) => prev ? { ...prev, installation } : prev);
75216
+ const resolutionWarning = getGlobalResolutionWarning(mismatch.packageManager);
75217
+ if (resolutionWarning) {
75218
+ setFlashMessage(null);
75219
+ setFlowNotice({
75220
+ title: "Update Complete",
75221
+ message: `Global package updated.
75222
+
75223
+ ${resolutionWarning}`,
75224
+ color: "yellow",
75225
+ continueScreen: "main"
75226
+ });
75227
+ setScreen("flowNotice");
75228
+ } else {
75229
+ setFlashMessage({
75230
+ text: "✓ Global package updated",
75231
+ color: "green"
75232
+ });
75233
+ setScreen("main");
75234
+ }
75235
+ } catch {
75236
+ setFlashMessage({
75237
+ text: "✗ Global update failed",
75238
+ color: "red"
75239
+ });
75240
+ }
75241
+ };
75242
+ const handleUninstallSelection = (selection, cancelScreen) => {
75243
+ setConfirmDialog({
75244
+ message: buildUninstallConfirmMessage(selection),
75245
+ cancelScreen,
75246
+ action: async () => {
75247
+ let removedClaudeSettings = false;
75248
+ try {
73666
75249
  await uninstallStatusLine();
75250
+ removedClaudeSettings = true;
75251
+ for (const packageManager of selection.packageManagers) {
75252
+ await runGlobalPackageUninstall(packageManager);
75253
+ }
73667
75254
  setIsClaudeInstalled(false);
73668
75255
  setExistingStatusLine(null);
73669
75256
  setCurrentRefreshInterval(null);
75257
+ setSettings(clearInstallationMetadata);
75258
+ setOriginalSettings(clearInstallationMetadata);
75259
+ setMenuSelections((prev) => ({
75260
+ ...prev,
75261
+ main: getMainMenuInstallSelectionIndex(false)
75262
+ }));
75263
+ setFlashMessage({
75264
+ text: selection.packageManagers.length > 0 ? "✓ Uninstalled from Claude Code and removed global package" : "✓ Uninstalled from Claude Code",
75265
+ color: "green"
75266
+ });
73670
75267
  setScreen("main");
73671
- setConfirmDialog(null);
75268
+ } catch {
75269
+ if (removedClaudeSettings) {
75270
+ setIsClaudeInstalled(false);
75271
+ setExistingStatusLine(null);
75272
+ setCurrentRefreshInterval(null);
75273
+ setSettings(clearInstallationMetadata);
75274
+ setOriginalSettings(clearInstallationMetadata);
75275
+ setMenuSelections((prev) => ({
75276
+ ...prev,
75277
+ main: getMainMenuInstallSelectionIndex(false)
75278
+ }));
75279
+ setFlashMessage({
75280
+ text: "✗ Removed Claude settings, but global package removal failed",
75281
+ color: "red"
75282
+ });
75283
+ setScreen("main");
75284
+ } else {
75285
+ setFlashMessage({
75286
+ text: "✗ Uninstall failed",
75287
+ color: "red"
75288
+ });
75289
+ setScreen(cancelScreen);
75290
+ }
73672
75291
  }
73673
- });
73674
- setScreen("confirm");
75292
+ setConfirmDialog(null);
75293
+ }
75294
+ });
75295
+ setScreen("confirm");
75296
+ };
75297
+ const handleInstallUninstall = () => {
75298
+ if (isClaudeInstalled) {
75299
+ handleUninstallSelection({ packageManagers: [] }, "main");
73675
75300
  } else {
73676
75301
  setScreen("install");
73677
75302
  }
73678
75303
  };
75304
+ const handleManageInstallationSelect = (action) => {
75305
+ if (action === "checkUpdates") {
75306
+ setUpdatesReturnScreen("manageInstallation");
75307
+ setScreen("updates");
75308
+ handleUpdateCheck();
75309
+ return;
75310
+ }
75311
+ setGlobalPackageInstallations(inspectGlobalPackageInstallations({ commandAvailability }));
75312
+ setScreen("uninstallOptions");
75313
+ };
73679
75314
  const handleMainMenuSelect = async (value) => {
73680
75315
  switch (value) {
73681
75316
  case "lines":
@@ -73696,6 +75331,14 @@ Continue?`;
73696
75331
  case "install":
73697
75332
  handleInstallUninstall();
73698
75333
  break;
75334
+ case "manageInstallation":
75335
+ setScreen("manageInstallation");
75336
+ break;
75337
+ case "checkUpdates":
75338
+ setUpdatesReturnScreen("main");
75339
+ setScreen("updates");
75340
+ handleUpdateCheck();
75341
+ break;
73699
75342
  case "configureStatusLine":
73700
75343
  setScreen("refreshInterval");
73701
75344
  break;
@@ -73735,6 +75378,42 @@ ${GITHUB_REPO_URL}`,
73735
75378
  break;
73736
75379
  }
73737
75380
  };
75381
+ if (pinnedVersionMismatch) {
75382
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
75383
+ flexDirection: "column",
75384
+ children: [
75385
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
75386
+ marginBottom: 1,
75387
+ children: [
75388
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
75389
+ bold: true,
75390
+ children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(dist_default5, {
75391
+ name: "retro",
75392
+ children: "CCStatusline Configuration"
75393
+ }, undefined, false, undefined, this)
75394
+ }, undefined, false, undefined, this),
75395
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
75396
+ bold: true,
75397
+ children: ` | ${runningVersion && `v${runningVersion}`}`
75398
+ }, undefined, false, undefined, this),
75399
+ flashMessage && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
75400
+ color: flashMessage.color,
75401
+ bold: true,
75402
+ children: ` ${flashMessage.text}`
75403
+ }, undefined, false, undefined, this)
75404
+ ]
75405
+ }, undefined, true, undefined, this),
75406
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(PinnedVersionMismatchScreen, {
75407
+ mismatch: pinnedVersionMismatch,
75408
+ canRunPackageManager: commandAvailability[pinnedVersionMismatch.packageManager],
75409
+ onUpdate: () => {
75410
+ handlePinnedVersionMismatchUpdate(pinnedVersionMismatch);
75411
+ },
75412
+ onExit: exit
75413
+ }, undefined, false, undefined, this)
75414
+ ]
75415
+ }, undefined, true, undefined, this);
75416
+ }
73738
75417
  const updateLine = (lineIndex, widgets) => {
73739
75418
  const newLines = [...settings.lines];
73740
75419
  newLines[lineIndex] = widgets;
@@ -73747,44 +75426,44 @@ ${GITHUB_REPO_URL}`,
73747
75426
  setSelectedLine(lineIndex);
73748
75427
  setScreen("items");
73749
75428
  };
73750
- return /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
75429
+ return /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
73751
75430
  flexDirection: "column",
73752
75431
  children: [
73753
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
75432
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
73754
75433
  marginBottom: 1,
73755
75434
  children: [
73756
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
75435
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
73757
75436
  bold: true,
73758
- children: /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(dist_default5, {
75437
+ children: /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(dist_default5, {
73759
75438
  name: "retro",
73760
75439
  children: "CCStatusline Configuration"
73761
75440
  }, undefined, false, undefined, this)
73762
75441
  }, undefined, false, undefined, this),
73763
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
75442
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
73764
75443
  bold: true,
73765
- children: ` | ${getPackageVersion() && `v${getPackageVersion()}`}`
75444
+ children: ` | ${runningVersion && `v${runningVersion}`}`
73766
75445
  }, undefined, false, undefined, this),
73767
- flashMessage && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
75446
+ flashMessage && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
73768
75447
  color: flashMessage.color,
73769
75448
  bold: true,
73770
75449
  children: ` ${flashMessage.text}`
73771
75450
  }, undefined, false, undefined, this)
73772
75451
  ]
73773
75452
  }, undefined, true, undefined, this),
73774
- isCustomConfigPath() && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Text, {
75453
+ isCustomConfigPath() && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Text, {
73775
75454
  dimColor: true,
73776
75455
  children: `Config: ${getConfigPath()}`
73777
75456
  }, undefined, false, undefined, this),
73778
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(StatusLinePreview, {
75457
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(StatusLinePreview, {
73779
75458
  lines: settings.lines,
73780
75459
  terminalWidth,
73781
75460
  settings,
73782
75461
  onTruncationChange: setPreviewIsTruncated
73783
75462
  }, undefined, false, undefined, this),
73784
- /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(Box_default, {
75463
+ /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(Box_default, {
73785
75464
  marginTop: 1,
73786
75465
  children: [
73787
- screen === "main" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(MainMenu, {
75466
+ screen === "main" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(MainMenu, {
73788
75467
  onSelect: (value, index) => {
73789
75468
  if (value !== "save" && value !== "exit") {
73790
75469
  setMenuSelections((prev) => ({ ...prev, main: index }));
@@ -73796,9 +75475,10 @@ ${GITHUB_REPO_URL}`,
73796
75475
  initialSelection: menuSelections.main,
73797
75476
  powerlineFontStatus,
73798
75477
  settings,
75478
+ installation: effectiveInstallation,
73799
75479
  previewIsTruncated
73800
75480
  }, undefined, false, undefined, this),
73801
- screen === "lines" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(LineSelector, {
75481
+ screen === "lines" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(LineSelector, {
73802
75482
  lines: settings.lines,
73803
75483
  onSelect: (line) => {
73804
75484
  setMenuSelections((prev) => ({ ...prev, lines: line }));
@@ -73813,7 +75493,7 @@ ${GITHUB_REPO_URL}`,
73813
75493
  title: "Select Line to Edit Items",
73814
75494
  allowEditing: true
73815
75495
  }, undefined, false, undefined, this),
73816
- screen === "items" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(ItemsEditor, {
75496
+ screen === "items" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(ItemsEditor, {
73817
75497
  widgets: settings.lines[selectedLine] ?? [],
73818
75498
  onUpdate: (widgets) => {
73819
75499
  updateLine(selectedLine, widgets);
@@ -73825,7 +75505,7 @@ ${GITHUB_REPO_URL}`,
73825
75505
  lineNumber: selectedLine + 1,
73826
75506
  settings
73827
75507
  }, undefined, false, undefined, this),
73828
- screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(LineSelector, {
75508
+ screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(LineSelector, {
73829
75509
  lines: settings.lines,
73830
75510
  onLinesUpdate: updateLines,
73831
75511
  onSelect: (line) => {
@@ -73843,7 +75523,7 @@ ${GITHUB_REPO_URL}`,
73843
75523
  settings,
73844
75524
  allowEditing: false
73845
75525
  }, undefined, false, undefined, this),
73846
- screen === "colors" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(ColorMenu, {
75526
+ screen === "colors" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(ColorMenu, {
73847
75527
  widgets: settings.lines[selectedLine] ?? [],
73848
75528
  lineIndex: selectedLine,
73849
75529
  settings,
@@ -73856,7 +75536,7 @@ ${GITHUB_REPO_URL}`,
73856
75536
  setScreen("colorLines");
73857
75537
  }
73858
75538
  }, undefined, false, undefined, this),
73859
- screen === "terminalConfig" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(TerminalOptionsMenu, {
75539
+ screen === "terminalConfig" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(TerminalOptionsMenu, {
73860
75540
  settings,
73861
75541
  onUpdate: (updatedSettings) => {
73862
75542
  setSettings(updatedSettings);
@@ -73870,7 +75550,7 @@ ${GITHUB_REPO_URL}`,
73870
75550
  }
73871
75551
  }
73872
75552
  }, undefined, false, undefined, this),
73873
- screen === "terminalWidth" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(TerminalWidthMenu, {
75553
+ screen === "terminalWidth" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(TerminalWidthMenu, {
73874
75554
  settings,
73875
75555
  onUpdate: (updatedSettings) => {
73876
75556
  setSettings(updatedSettings);
@@ -73879,7 +75559,7 @@ ${GITHUB_REPO_URL}`,
73879
75559
  setScreen("terminalConfig");
73880
75560
  }
73881
75561
  }, undefined, false, undefined, this),
73882
- screen === "globalOverrides" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(GlobalOverridesMenu, {
75562
+ screen === "globalOverrides" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(GlobalOverridesMenu, {
73883
75563
  settings,
73884
75564
  onUpdate: (updatedSettings) => {
73885
75565
  setSettings(updatedSettings);
@@ -73889,7 +75569,7 @@ ${GITHUB_REPO_URL}`,
73889
75569
  setScreen("main");
73890
75570
  }
73891
75571
  }, undefined, false, undefined, this),
73892
- screen === "confirm" && confirmDialog && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(ConfirmDialog, {
75572
+ screen === "confirm" && confirmDialog && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(ConfirmDialog, {
73893
75573
  message: confirmDialog.message,
73894
75574
  onConfirm: () => void confirmDialog.action(),
73895
75575
  onCancel: () => {
@@ -73897,15 +75577,57 @@ ${GITHUB_REPO_URL}`,
73897
75577
  setConfirmDialog(null);
73898
75578
  }
73899
75579
  }, undefined, false, undefined, this),
73900
- screen === "install" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(InstallMenu, {
73901
- bunxAvailable: isBunxAvailable(),
75580
+ screen === "flowNotice" && flowNotice && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(FlowNotice, {
75581
+ ...flowNotice,
75582
+ onContinue: () => {
75583
+ setScreen(flowNotice.continueScreen);
75584
+ setFlowNotice(null);
75585
+ }
75586
+ }, undefined, false, undefined, this),
75587
+ screen === "install" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(InstallMenu, {
75588
+ commandAvailability,
75589
+ currentVersion: getPackageVersion(),
73902
75590
  existingStatusLine,
73903
- onSelectNpx: handleNpxInstall,
73904
- onSelectBunx: handleBunxInstall,
75591
+ onSelect: (selection) => {
75592
+ setMenuSelections((prev) => ({
75593
+ ...prev,
75594
+ installPackage: selection.packageManager === "bun" ? 1 : 0
75595
+ }));
75596
+ handleInstallSelection(selection);
75597
+ },
73905
75598
  onCancel: handleInstallMenuCancel,
73906
- initialSelection: menuSelections.install
75599
+ initialPackageSelection: menuSelections.installPackage
73907
75600
  }, undefined, false, undefined, this),
73908
- screen === "refreshInterval" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(RefreshIntervalMenu, {
75601
+ screen === "manageInstallation" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(ManageInstallationMenu, {
75602
+ installation: effectiveInstallation,
75603
+ activeCommand: activeGlobalCommand,
75604
+ onSelect: handleManageInstallationSelect,
75605
+ onBack: () => {
75606
+ setMenuSelections((prev) => ({
75607
+ ...prev,
75608
+ main: getMainMenuInstallSelectionIndex(true, effectiveInstallation)
75609
+ }));
75610
+ setScreen("main");
75611
+ }
75612
+ }, undefined, false, undefined, this),
75613
+ screen === "uninstallOptions" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(UninstallMenu, {
75614
+ installations: globalPackageInstallations,
75615
+ onSelect: (selection) => {
75616
+ handleUninstallSelection(selection, "uninstallOptions");
75617
+ },
75618
+ onBack: () => {
75619
+ setScreen("manageInstallation");
75620
+ }
75621
+ }, undefined, false, undefined, this),
75622
+ screen === "updates" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(UpdateCheckerMenu, {
75623
+ state: updateCheckerState,
75624
+ onBack: () => {
75625
+ setScreen(updatesReturnScreen);
75626
+ },
75627
+ onRefresh: handleUpdateCheck,
75628
+ onRunAction: handleRunUpdateAction
75629
+ }, undefined, false, undefined, this),
75630
+ screen === "refreshInterval" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(RefreshIntervalMenu, {
73909
75631
  currentInterval: currentRefreshInterval,
73910
75632
  supportsRefreshInterval,
73911
75633
  onUpdate: (interval) => {
@@ -73929,7 +75651,7 @@ ${GITHUB_REPO_URL}`,
73929
75651
  setScreen("main");
73930
75652
  }
73931
75653
  }, undefined, false, undefined, this),
73932
- screen === "powerline" && /* @__PURE__ */ jsx_dev_runtime25.jsxDEV(PowerlineSetup, {
75654
+ screen === "powerline" && /* @__PURE__ */ jsx_dev_runtime27.jsxDEV(PowerlineSetup, {
73933
75655
  settings,
73934
75656
  powerlineFontStatus,
73935
75657
  onUpdate: (updatedSettings) => {
@@ -73963,7 +75685,7 @@ ${GITHUB_REPO_URL}`,
73963
75685
  };
73964
75686
  function runTUI() {
73965
75687
  process.stdout.write("\x1B[2J\x1B[H");
73966
- render_default(/* @__PURE__ */ jsx_dev_runtime25.jsxDEV(App2, {}, undefined, false, undefined, this));
75688
+ render_default(/* @__PURE__ */ jsx_dev_runtime27.jsxDEV(App2, {}, undefined, false, undefined, this));
73967
75689
  }
73968
75690
  // src/types/StatusJSON.ts
73969
75691
  init_zod();
@@ -74047,9 +75769,9 @@ init_colors();
74047
75769
  // src/utils/compaction.ts
74048
75770
  init_zod();
74049
75771
  import * as crypto from "crypto";
74050
- import * as fs13 from "fs";
75772
+ import * as fs14 from "fs";
74051
75773
  import * as os13 from "os";
74052
- import * as path10 from "path";
75774
+ import * as path11 from "path";
74053
75775
  var DEFAULT_DROP_THRESHOLD = 2;
74054
75776
  var FRESH_PREV_CTX_PCT = -1;
74055
75777
  var MAX_CACHE_FILE_BYTES = 4096;
@@ -74094,7 +75816,7 @@ function detectCompaction(currentCtxPct, state, options = DEFAULT_DROP_THRESHOLD
74094
75816
  };
74095
75817
  }
74096
75818
  function getCacheDir2() {
74097
- return path10.join(os13.homedir(), ".cache", "ccstatusline", "compaction");
75819
+ return path11.join(os13.homedir(), ".cache", "ccstatusline", "compaction");
74098
75820
  }
74099
75821
  function sanitizeSessionId(sessionId) {
74100
75822
  const sanitized = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -74104,18 +75826,18 @@ function sanitizeSessionId(sessionId) {
74104
75826
  return sanitized;
74105
75827
  }
74106
75828
  function getStatePath(sessionId) {
74107
- return path10.join(getCacheDir2(), `compaction-${sanitizeSessionId(sessionId)}.json`);
75829
+ return path11.join(getCacheDir2(), `compaction-${sanitizeSessionId(sessionId)}.json`);
74108
75830
  }
74109
75831
  function loadCompactionState(sessionId) {
74110
75832
  const statePath = getStatePath(sessionId);
74111
75833
  let fd = null;
74112
75834
  try {
74113
- fd = fs13.openSync(statePath, fs13.constants.O_RDONLY | fs13.constants.O_NOFOLLOW);
74114
- const stats = fs13.fstatSync(fd);
75835
+ fd = fs14.openSync(statePath, fs14.constants.O_RDONLY | fs14.constants.O_NOFOLLOW);
75836
+ const stats = fs14.fstatSync(fd);
74115
75837
  if (!stats.isFile() || stats.size > MAX_CACHE_FILE_BYTES) {
74116
75838
  return FRESH;
74117
75839
  }
74118
- const raw = JSON.parse(fs13.readFileSync(fd, "utf-8"));
75840
+ const raw = JSON.parse(fs14.readFileSync(fd, "utf-8"));
74119
75841
  const result2 = CompactionStateSchema.safeParse(raw);
74120
75842
  return result2.success ? result2.data : FRESH;
74121
75843
  } catch {
@@ -74123,7 +75845,7 @@ function loadCompactionState(sessionId) {
74123
75845
  } finally {
74124
75846
  if (fd !== null) {
74125
75847
  try {
74126
- fs13.closeSync(fd);
75848
+ fs14.closeSync(fd);
74127
75849
  } catch {}
74128
75850
  }
74129
75851
  }
@@ -74132,19 +75854,19 @@ function saveCompactionState(sessionId, state) {
74132
75854
  let tmpPath = null;
74133
75855
  try {
74134
75856
  const dir = getCacheDir2();
74135
- if (!fs13.existsSync(dir)) {
74136
- fs13.mkdirSync(dir, { recursive: true });
75857
+ if (!fs14.existsSync(dir)) {
75858
+ fs14.mkdirSync(dir, { recursive: true });
74137
75859
  }
74138
75860
  const targetPath = getStatePath(sessionId);
74139
75861
  tmpPath = `${targetPath}.tmp.${process.pid}.${crypto.randomBytes(4).toString("hex")}`;
74140
- fs13.writeFileSync(tmpPath, JSON.stringify(state) + `
75862
+ fs14.writeFileSync(tmpPath, JSON.stringify(state) + `
74141
75863
  `);
74142
- fs13.renameSync(tmpPath, targetPath);
75864
+ fs14.renameSync(tmpPath, targetPath);
74143
75865
  tmpPath = null;
74144
75866
  } catch {
74145
75867
  if (tmpPath !== null) {
74146
75868
  try {
74147
- fs13.unlinkSync(tmpPath);
75869
+ fs14.unlinkSync(tmpPath);
74148
75870
  } catch {}
74149
75871
  }
74150
75872
  }
@@ -74155,27 +75877,27 @@ init_context_percentage();
74155
75877
  await init_config();
74156
75878
 
74157
75879
  // src/utils/hook-handler.ts
74158
- import * as fs15 from "fs";
74159
- import * as path12 from "path";
75880
+ import * as fs16 from "fs";
75881
+ import * as path13 from "path";
74160
75882
 
74161
75883
  // src/utils/skills.ts
74162
- import * as fs14 from "fs";
75884
+ import * as fs15 from "fs";
74163
75885
  import * as os14 from "os";
74164
- import * as path11 from "path";
75886
+ import * as path12 from "path";
74165
75887
  var EMPTY = { totalInvocations: 0, uniqueSkills: [], lastSkill: null };
74166
75888
  function getSkillsDir() {
74167
- return path11.join(os14.homedir(), ".cache", "ccstatusline", "skills");
75889
+ return path12.join(os14.homedir(), ".cache", "ccstatusline", "skills");
74168
75890
  }
74169
75891
  function getSkillsFilePath(sessionId) {
74170
- return path11.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
75892
+ return path12.join(getSkillsDir(), `skills-${sessionId}.jsonl`);
74171
75893
  }
74172
75894
  function getSkillsMetrics(sessionId) {
74173
75895
  const filePath = getSkillsFilePath(sessionId);
74174
- if (!fs14.existsSync(filePath)) {
75896
+ if (!fs15.existsSync(filePath)) {
74175
75897
  return EMPTY;
74176
75898
  }
74177
75899
  try {
74178
- const invocations = fs14.readFileSync(filePath, "utf-8").trim().split(`
75900
+ const invocations = fs15.readFileSync(filePath, "utf-8").trim().split(`
74179
75901
  `).filter((line) => line.trim()).map((line) => {
74180
75902
  try {
74181
75903
  return JSON.parse(line);
@@ -74229,14 +75951,14 @@ function handleHookInput(input) {
74229
75951
  return;
74230
75952
  }
74231
75953
  const filePath = getSkillsFilePath(sessionId);
74232
- fs15.mkdirSync(path12.dirname(filePath), { recursive: true });
75954
+ fs16.mkdirSync(path13.dirname(filePath), { recursive: true });
74233
75955
  const entry = JSON.stringify({
74234
75956
  timestamp: new Date().toISOString(),
74235
75957
  session_id: sessionId,
74236
75958
  skill: skillName,
74237
75959
  source: data.hook_event_name
74238
75960
  });
74239
- fs15.appendFileSync(filePath, entry + `
75961
+ fs16.appendFileSync(filePath, entry + `
74240
75962
  `);
74241
75963
  } catch {}
74242
75964
  }
@@ -74379,8 +76101,8 @@ async function ensureWindowsUtf8CodePage() {
74379
76101
  return;
74380
76102
  }
74381
76103
  try {
74382
- const { execFileSync: execFileSync5 } = await import("child_process");
74383
- execFileSync5("chcp.com", ["65001"], { stdio: "ignore" });
76104
+ const { execFileSync: execFileSync7 } = await import("child_process");
76105
+ execFileSync7("chcp.com", ["65001"], { stdio: "ignore" });
74384
76106
  } catch {}
74385
76107
  }
74386
76108
  async function renderMultipleLines(data) {