ccstatusline-usage 2.3.15 → 2.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,7 @@ This fork adds API-based usage widgets beyond the upstream:
40
40
  ### Enhanced Status Line Preview
41
41
 
42
42
  ```
43
- Session: [████░░░░░░░░░░░] 27.0% | Weekly: [████░░░░░░░░░░░] 34.0% | 2:03 hr | Model: Opus 4.6 | Session ID: 0109b99d...
43
+ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [████░░░░░░░░░░░] 34.0% | 2:03 hr | Model: Opus 4.7 | Session ID: 0109b99d...
44
44
  Context: [██████░░░░░░░░░] 389k/1M (39%) | Pace: [░░░░░░█|░░░░░░░] D4/7 -8% | Off-peak (4:03 hr)
45
45
  ```
46
46
 
@@ -67,6 +67,12 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
67
67
 
68
68
  ## 🆕 Recent Updates
69
69
 
70
+ ### [v2.3.16](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.16) - Reset Timer fix + model ref updates + upstream sync
71
+
72
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Reset Timer fix** — When session hits 100% but weekly is still below 100%, the Reset Timer now correctly shows the session reset countdown (5-hour window) instead of the weekly reset time. Previously it jumped to the weekly timer as soon as session filled up.
73
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): Updated all Opus 4.6 references to Opus 4.7 throughout docs, examples, and test data.
74
+ - Upstream sync (5 commits): refreshInterval configuration for Claude Code status line (#297), xhigh thinking effort level (#314), dev-dependency bumps.
75
+
70
76
  ### [v2.3.15](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.3.15) - Move extra amounts into Weekly bar, Reset Timer shows weekly reset time
71
77
 
72
78
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Extra amounts in Weekly bar** — When at 100% / on a charged model, the split bar now shows `€spent/€limit` after the bar instead of `100.0%`. Mobile shows the spent amount only.
@@ -155,7 +161,7 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
155
161
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **1M context indicator** — Model widget now appends `[1m]` when a 1M context model is active, both in full (`Model: claude-sonnet-4-6 [1m]`) and compact (`M: s4.6[1m]`) display modes
156
162
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Revert extra usage on 1M** — Removed the v2.1.15 trigger that showed extra usage spending on 1M models. 1M context is not included in Max without extra usage — the `[1m]` suffix on the Model widget now makes this visible, so the Reset Timer no longer needs to duplicate that awareness
157
163
 
158
- ### [v2.1.15](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.15) - Show extra usage balance on 1M context models
164
+ ### [v2.1.15](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.15) - Show extra usage Kelp on 1M context models
159
165
 
160
166
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Extra usage on 1M models** — Reset Timer widget now shows extra usage spending (`Extra: €X.XX/€Y.YY`) whenever a 1M context model is active (Opus/Sonnet with 1M context window), in addition to the existing trigger when weekly limit reaches 100%. *Reverted in v2.1.16.*
161
167
 
@@ -174,9 +180,9 @@ Session: [████░░░░░░░░░░░] 27.0% | Weekly: [██
174
180
 
175
181
  - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Remove thinking effort bars** — Claude Code now shows thinking intensity natively in its own UI, so the `▌▌▌` bars after the model name have been removed from the Model widget
176
182
 
177
- ### [v2.1.11](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.11) - Configurable extra usage balance
183
+ ### [v2.1.11](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.11) - Configurable extra usage Kelp
178
184
 
179
- - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Configurable extra usage balance** — Add `extraUsageBalance` setting (in cents) to `~/.config/ccstatusline/settings.json` to override the API's monthly limit with your actual prepaid balance (e.g., `"extraUsageBalance": 5000` shows `Extra: €0.00/€50.00`)
185
+ - [pcvelz/ccstatusline-usage](https://github.com/pcvelz/ccstatusline-usage): **Configurable extra usage Kelp** — Add `extraUsageBalance` setting (in cents) to `~/.config/ccstatusline/settings.json` to override the API's monthly limit with your actual prepaid Kelp (e.g., `"extraUsageBalance": 5000` shows `Extra: €0.00/€50.00`)
180
186
 
181
187
  ### [v2.1.8](https://github.com/pcvelz/ccstatusline-usage/releases/tag/v2.1.8) - Windows support for API usage widgets
182
188
 
@@ -55592,7 +55592,7 @@ function getTerminalWidth() {
55592
55592
  function canDetectTerminalWidth() {
55593
55593
  return probeTerminalWidth() !== null;
55594
55594
  }
55595
- var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.15";
55595
+ var __dirname = "/Users/peter/Documents/Code/ccstatusline-usage/src/utils", PACKAGE_VERSION = "2.3.16";
55596
55596
  var init_terminal = () => {};
55597
55597
 
55598
55598
  // src/utils/renderer.ts
@@ -61996,8 +61996,11 @@ function normalizeThinkingEffort(value) {
61996
61996
  return;
61997
61997
  }
61998
61998
  const normalized = value.toLowerCase();
61999
- if (normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "max") {
62000
- return normalized;
61999
+ if (KNOWN_THINKING_EFFORTS_SET.has(normalized)) {
62000
+ return { value: normalized, known: true };
62001
+ }
62002
+ if (UNKNOWN_EFFORT_PATTERN.test(normalized)) {
62003
+ return { value: normalized, known: false };
62001
62004
  }
62002
62005
  return;
62003
62006
  }
@@ -62028,11 +62031,14 @@ function getTranscriptThinkingEffort(transcriptPath) {
62028
62031
  }
62029
62032
  return;
62030
62033
  }
62031
- var MODEL_STDOUT_PREFIX = "<local-command-stdout>Set model to ", MODEL_STDOUT_EFFORT_REGEX;
62034
+ var KNOWN_THINKING_EFFORTS, KNOWN_THINKING_EFFORTS_SET, MODEL_STDOUT_PREFIX = "<local-command-stdout>Set model to ", MODEL_STDOUT_EFFORT_REGEX, UNKNOWN_EFFORT_PATTERN;
62032
62035
  var init_jsonl_metadata = __esm(() => {
62033
62036
  init_ansi();
62034
62037
  init_jsonl_lines();
62035
- MODEL_STDOUT_EFFORT_REGEX = /^<local-command-stdout>Set model to[\s\S]*? with (low|medium|high|max) effort<\/local-command-stdout>$/i;
62038
+ KNOWN_THINKING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
62039
+ KNOWN_THINKING_EFFORTS_SET = new Set(KNOWN_THINKING_EFFORTS);
62040
+ MODEL_STDOUT_EFFORT_REGEX = /^<local-command-stdout>Set model to[\s\S]*? with ([a-zA-Z0-9-]+) effort<\/local-command-stdout>$/i;
62041
+ UNKNOWN_EFFORT_PATTERN = /^(?=.*[a-z0-9])[a-z0-9-]{2,20}$/;
62036
62042
  });
62037
62043
 
62038
62044
  // src/utils/jsonl.ts
@@ -63293,7 +63299,7 @@ class ResetTimerWidget {
63293
63299
  const is1mModel = modelId.includes("[1m]");
63294
63300
  const isOpus = modelId.includes("opus");
63295
63301
  const isChargedModel = is1mModel && !isOpus;
63296
- const extraActive = data.extraUsageEnabled && data.extraUsageUsed !== undefined && data.extraUsageLimit !== undefined && (data.weeklyUsage !== undefined && data.weeklyUsage >= 100 || data.sessionUsage !== undefined && data.sessionUsage >= 100 || isChargedModel);
63302
+ const extraActive = data.extraUsageEnabled && data.extraUsageUsed !== undefined && data.extraUsageLimit !== undefined && (data.weeklyUsage !== undefined && data.weeklyUsage >= 100 || isChargedModel);
63297
63303
  if (extraActive) {
63298
63304
  const weeklyWindow = resolveWeeklyUsageWindow(data);
63299
63305
  if (weeklyWindow) {
@@ -63894,25 +63900,21 @@ var init_Skills = __esm(async () => {
63894
63900
  });
63895
63901
 
63896
63902
  // src/widgets/ThinkingEffort.ts
63897
- function normalizeThinkingEffort2(value) {
63898
- if (!value) {
63899
- return;
63900
- }
63901
- const normalized = value.toLowerCase();
63902
- if (normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "max") {
63903
- return normalized;
63904
- }
63905
- return;
63906
- }
63907
63903
  function resolveThinkingEffortFromSettings() {
63908
63904
  try {
63909
63905
  const settings = loadClaudeSettingsSync({ logErrors: false });
63910
- return normalizeThinkingEffort2(settings.effortLevel);
63906
+ return normalizeThinkingEffort(settings.effortLevel);
63911
63907
  } catch {}
63912
63908
  return;
63913
63909
  }
63914
63910
  function resolveThinkingEffort(context) {
63915
- return getTranscriptThinkingEffort(context.data?.transcript_path) ?? resolveThinkingEffortFromSettings() ?? "medium";
63911
+ return getTranscriptThinkingEffort(context.data?.transcript_path) ?? resolveThinkingEffortFromSettings() ?? null;
63912
+ }
63913
+ function formatEffort(resolved) {
63914
+ if (!resolved) {
63915
+ return "default";
63916
+ }
63917
+ return resolved.known ? resolved.value : `${resolved.value}?`;
63916
63918
  }
63917
63919
 
63918
63920
  class ThinkingEffortWidget {
@@ -63920,7 +63922,8 @@ class ThinkingEffortWidget {
63920
63922
  return "magenta";
63921
63923
  }
63922
63924
  getDescription() {
63923
- return `Displays the current thinking effort level (low, medium, high, max).
63925
+ return `Displays the current thinking effort level (low, medium, high, xhigh, max).
63926
+ Unknown levels are shown with a trailing "?" (e.g. "super-max?").
63924
63927
  May be incorrect when multiple Claude Code sessions are running due to current Claude Code limitations.`;
63925
63928
  }
63926
63929
  getDisplayName() {
@@ -63936,7 +63939,7 @@ May be incorrect when multiple Claude Code sessions are running due to current C
63936
63939
  if (context.isPreview) {
63937
63940
  return item.rawValue ? "high" : "Thinking: high";
63938
63941
  }
63939
- const effort = resolveThinkingEffort(context);
63942
+ const effort = formatEffort(resolveThinkingEffort(context));
63940
63943
  return item.rawValue ? effort : `Thinking: ${effort}`;
63941
63944
  }
63942
63945
  supportsRawValue() {
@@ -65087,7 +65090,7 @@ import * as os9 from "os";
65087
65090
  import * as path10 from "path";
65088
65091
  function isKnownCommand(command) {
65089
65092
  const prefixes = [CCSTATUSLINE_COMMANDS.NPM, CCSTATUSLINE_COMMANDS.BUNX, CCSTATUSLINE_COMMANDS.SELF_MANAGED];
65090
- return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `));
65093
+ return prefixes.some((prefix) => command === prefix || command.startsWith(`${prefix} --config `)) || /(?:^|[\s"'\\/])ccstatusline\.ts(?=$|[\s"'])/.test(command);
65091
65094
  }
65092
65095
  function needsQuoting(filePath) {
65093
65096
  if (process.platform === "win32") {
@@ -65196,6 +65199,34 @@ function isBunxAvailable() {
65196
65199
  return false;
65197
65200
  }
65198
65201
  }
65202
+ function getClaudeCodeVersion() {
65203
+ try {
65204
+ const output = execSync6("claude --version", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"], timeout: 5000 }).trim();
65205
+ const match = /^(\d+\.\d+\.\d+)/.exec(output);
65206
+ return match?.[1] ?? null;
65207
+ } catch {
65208
+ return null;
65209
+ }
65210
+ }
65211
+ function isClaudeCodeVersionAtLeast(minVersion) {
65212
+ const version2 = getClaudeCodeVersion();
65213
+ if (!version2) {
65214
+ return false;
65215
+ }
65216
+ const current = version2.split(".").map(Number);
65217
+ const minimum = minVersion.split(".").map(Number);
65218
+ for (let i = 0;i < 3; i++) {
65219
+ const c = current[i] ?? 0;
65220
+ const m = minimum[i] ?? 0;
65221
+ if (c > m) {
65222
+ return true;
65223
+ }
65224
+ if (c < m) {
65225
+ return false;
65226
+ }
65227
+ }
65228
+ return true;
65229
+ }
65199
65230
  function buildCommand(baseCommand) {
65200
65231
  if (isCustomConfigPath()) {
65201
65232
  return `${baseCommand} --config ${quotePathIfNeeded(getConfigPath())}`;
@@ -65219,7 +65250,7 @@ async function loadSavedSettingsForHookSync() {
65219
65250
  return null;
65220
65251
  }
65221
65252
  }
65222
- async function installStatusLine(useBunx = false) {
65253
+ async function installStatusLine(useBunx = false, supportsRefreshInterval = false) {
65223
65254
  let settings;
65224
65255
  const backupPath = await backupClaudeSettings(".orig");
65225
65256
  try {
@@ -65230,11 +65261,15 @@ async function installStatusLine(useBunx = false) {
65230
65261
  settings = {};
65231
65262
  }
65232
65263
  const baseCommand = useBunx ? CCSTATUSLINE_COMMANDS.BUNX : CCSTATUSLINE_COMMANDS.NPM;
65264
+ const existingRefreshInterval = settings.statusLine?.refreshInterval;
65233
65265
  settings.statusLine = {
65234
65266
  type: "command",
65235
65267
  command: buildCommand(baseCommand),
65236
65268
  padding: 0
65237
65269
  };
65270
+ if (supportsRefreshInterval) {
65271
+ settings.statusLine.refreshInterval = existingRefreshInterval ?? 10;
65272
+ }
65238
65273
  await saveClaudeSettings(settings);
65239
65274
  const savedSettings = await loadSavedSettingsForHookSync();
65240
65275
  if (savedSettings) {
@@ -65267,6 +65302,31 @@ async function getExistingStatusLine() {
65267
65302
  return null;
65268
65303
  }
65269
65304
  }
65305
+ async function getRefreshInterval() {
65306
+ try {
65307
+ const settings = await loadClaudeSettings({ logErrors: false });
65308
+ return settings.statusLine?.refreshInterval ?? null;
65309
+ } catch {
65310
+ return null;
65311
+ }
65312
+ }
65313
+ async function setRefreshInterval(interval) {
65314
+ let settings;
65315
+ try {
65316
+ settings = await loadClaudeSettings({ logErrors: false });
65317
+ } catch {
65318
+ return;
65319
+ }
65320
+ if (!settings.statusLine) {
65321
+ return;
65322
+ }
65323
+ if (interval === null) {
65324
+ delete settings.statusLine.refreshInterval;
65325
+ } else {
65326
+ settings.statusLine.refreshInterval = interval;
65327
+ }
65328
+ await saveClaudeSettings(settings);
65329
+ }
65270
65330
  var readFile4, writeFile2, CCSTATUSLINE_COMMANDS;
65271
65331
  var init_claude_settings = __esm(() => {
65272
65332
  init_Settings();
@@ -65850,7 +65910,7 @@ var dist_default5 = Gradient;
65850
65910
 
65851
65911
  // src/tui/App.tsx
65852
65912
  init_claude_settings();
65853
- var import_react47 = __toESM(require_react(), 1);
65913
+ var import_react48 = __toESM(require_react(), 1);
65854
65914
 
65855
65915
  // src/utils/clone-settings.ts
65856
65916
  function cloneSettings(settings) {
@@ -66181,6 +66241,22 @@ async function installPowerlineFonts() {
66181
66241
  // src/tui/App.tsx
66182
66242
  init_terminal();
66183
66243
 
66244
+ // src/tui/claude-status.ts
66245
+ init_claude_settings();
66246
+ async function loadClaudeStatusLineState() {
66247
+ const [
66248
+ existingStatusLine,
66249
+ refreshInterval
66250
+ ] = await Promise.all([
66251
+ getExistingStatusLine(),
66252
+ getRefreshInterval()
66253
+ ]);
66254
+ return {
66255
+ existingStatusLine,
66256
+ refreshInterval
66257
+ };
66258
+ }
66259
+
66184
66260
  // src/tui/components/ColorMenu.tsx
66185
66261
  init_source();
66186
66262
  await init_build2();
@@ -69097,11 +69173,24 @@ var MainMenu = ({
69097
69173
  description: "Set global padding, separators, and color overrides that apply to all widgets"
69098
69174
  },
69099
69175
  "-",
69100
- {
69101
- label: isClaudeInstalled ? "\uD83D\uDD0C Uninstall from Claude Code" : "\uD83D\uDCE6 Install to Claude Code",
69102
- value: "install",
69103
- description: isClaudeInstalled ? "Remove ccstatusline from your Claude Code settings" : "Add ccstatusline to your Claude Code settings for automatic status line rendering"
69104
- }
69176
+ ...isClaudeInstalled ? [
69177
+ {
69178
+ label: "\uD83D\uDD27 Configure Status Line",
69179
+ value: "configureStatusLine",
69180
+ description: "Configure Claude Code status line settings like refresh interval"
69181
+ },
69182
+ {
69183
+ label: "\uD83D\uDD0C Uninstall from Claude Code",
69184
+ value: "install",
69185
+ description: "Remove ccstatusline from your Claude Code settings"
69186
+ }
69187
+ ] : [
69188
+ {
69189
+ label: "\uD83D\uDCE6 Install to Claude Code",
69190
+ value: "install",
69191
+ description: "Add ccstatusline to your Claude Code settings for automatic status line rendering"
69192
+ }
69193
+ ]
69105
69194
  ];
69106
69195
  if (hasChanges) {
69107
69196
  menuItems.push({
@@ -70218,10 +70307,148 @@ var PowerlineSetup = ({
70218
70307
  ]
70219
70308
  }, undefined, true, undefined, this);
70220
70309
  };
70310
+ // src/tui/components/RefreshIntervalMenu.tsx
70311
+ init_input_guards();
70312
+ await init_build2();
70313
+ var import_react44 = __toESM(require_react(), 1);
70314
+ var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
70315
+ function getRefreshInputValue(interval) {
70316
+ return interval === null ? "" : String(interval);
70317
+ }
70318
+ function getRefreshIntervalSublabel(interval, supported) {
70319
+ if (!supported) {
70320
+ return "(requires Claude Code >=2.1.97)";
70321
+ }
70322
+ if (interval === null) {
70323
+ return "(not set)";
70324
+ }
70325
+ return `(${interval}s)`;
70326
+ }
70327
+ function buildConfigureStatusLineItems(refreshInterval, supportsRefreshInterval) {
70328
+ return [
70329
+ {
70330
+ label: "\uD83D\uDD04 Refresh Interval",
70331
+ sublabel: getRefreshIntervalSublabel(refreshInterval, supportsRefreshInterval),
70332
+ value: "refreshInterval",
70333
+ disabled: !supportsRefreshInterval,
70334
+ description: supportsRefreshInterval ? "How often Claude Code refreshes the status line by re-running the command. Enter value in seconds (1-60), or leave empty to remove." : "This setting requires Claude Code version 2.1.97 or later. Please update Claude Code to use this feature."
70335
+ }
70336
+ ];
70337
+ }
70338
+ function validateRefreshIntervalInput(value) {
70339
+ if (value === "") {
70340
+ return null;
70341
+ }
70342
+ const parsed = parseInt(value, 10);
70343
+ if (isNaN(parsed)) {
70344
+ return "Please enter a valid number";
70345
+ }
70346
+ if (parsed < 1) {
70347
+ return `Minimum interval is 1s (you entered ${parsed}s)`;
70348
+ }
70349
+ if (parsed > 60) {
70350
+ return `Maximum interval is 60s (you entered ${parsed}s)`;
70351
+ }
70352
+ return null;
70353
+ }
70354
+ var RefreshIntervalMenu = ({
70355
+ currentInterval,
70356
+ supportsRefreshInterval,
70357
+ onUpdate,
70358
+ onBack
70359
+ }) => {
70360
+ const [editingRefreshInterval, setEditingRefreshInterval] = import_react44.useState(false);
70361
+ const [refreshInput, setRefreshInput] = import_react44.useState(() => getRefreshInputValue(currentInterval));
70362
+ const [validationError, setValidationError] = import_react44.useState(null);
70363
+ use_input_default((input, key) => {
70364
+ if (editingRefreshInterval) {
70365
+ if (key.return) {
70366
+ if (refreshInput === "") {
70367
+ onUpdate(null);
70368
+ setEditingRefreshInterval(false);
70369
+ setValidationError(null);
70370
+ return;
70371
+ }
70372
+ const error48 = validateRefreshIntervalInput(refreshInput);
70373
+ if (error48) {
70374
+ setValidationError(error48);
70375
+ } else {
70376
+ const value = parseInt(refreshInput, 10);
70377
+ onUpdate(value);
70378
+ setEditingRefreshInterval(false);
70379
+ setValidationError(null);
70380
+ }
70381
+ } else if (key.escape) {
70382
+ setRefreshInput(getRefreshInputValue(currentInterval));
70383
+ setEditingRefreshInterval(false);
70384
+ setValidationError(null);
70385
+ } else if (key.backspace) {
70386
+ setRefreshInput(refreshInput.slice(0, -1));
70387
+ setValidationError(null);
70388
+ } else if (key.delete) {} else if (shouldInsertInput(input, key) && /\d/.test(input)) {
70389
+ const newValue = refreshInput + input;
70390
+ if (newValue.length <= 2) {
70391
+ setRefreshInput(newValue);
70392
+ setValidationError(null);
70393
+ }
70394
+ }
70395
+ return;
70396
+ }
70397
+ if (key.escape) {
70398
+ onBack();
70399
+ }
70400
+ });
70401
+ return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70402
+ flexDirection: "column",
70403
+ children: [
70404
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70405
+ bold: true,
70406
+ children: "Configure Status Line"
70407
+ }, undefined, false, undefined, this),
70408
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70409
+ color: "white",
70410
+ children: "Configure Claude Code status line settings"
70411
+ }, undefined, false, undefined, this),
70412
+ editingRefreshInterval ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70413
+ marginTop: 1,
70414
+ flexDirection: "column",
70415
+ children: [
70416
+ /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70417
+ children: [
70418
+ "Enter refresh interval in seconds (1-60):",
70419
+ " ",
70420
+ refreshInput,
70421
+ refreshInput.length > 0 ? "s" : ""
70422
+ ]
70423
+ }, undefined, true, undefined, this),
70424
+ validationError ? /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70425
+ color: "red",
70426
+ children: validationError
70427
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70428
+ dimColor: true,
70429
+ children: "Press Enter to confirm, ESC to cancel. Leave empty to remove."
70430
+ }, undefined, false, undefined, this)
70431
+ ]
70432
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(List, {
70433
+ marginTop: 1,
70434
+ items: buildConfigureStatusLineItems(currentInterval, supportsRefreshInterval),
70435
+ onSelect: (value) => {
70436
+ if (value === "back") {
70437
+ onBack();
70438
+ return;
70439
+ }
70440
+ setRefreshInput(getRefreshInputValue(currentInterval));
70441
+ setEditingRefreshInterval(true);
70442
+ },
70443
+ showBackButton: true
70444
+ }, undefined, false, undefined, this)
70445
+ ]
70446
+ }, undefined, true, undefined, this);
70447
+ };
70221
70448
  // src/tui/components/StatusLinePreview.tsx
70222
70449
  init_source();
70223
70450
  await init_build2();
70224
- var import_react44 = __toESM(require_react(), 1);
70451
+ var import_react45 = __toESM(require_react(), 1);
70225
70452
 
70226
70453
  // src/utils/powerline-theme-index.ts
70227
70454
  function countPowerlineThemeSlots(entries) {
@@ -70255,7 +70482,7 @@ function advanceGlobalSeparatorIndex(currentIndex, widgets) {
70255
70482
  }
70256
70483
 
70257
70484
  // src/tui/components/StatusLinePreview.tsx
70258
- var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
70485
+ var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
70259
70486
  var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSeparatorIndex, globalPowerlineThemeIndex, preRenderedWidgets, preCalculatedMaxWidths) => {
70260
70487
  const context = {
70261
70488
  terminalWidth,
@@ -70268,7 +70495,7 @@ var renderSingleLine = (widgets, terminalWidth, settings, lineIndex, globalSepar
70268
70495
  return renderStatusLineWithInfo(widgets, settings, context, preRenderedWidgets, preCalculatedMaxWidths);
70269
70496
  };
70270
70497
  var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange }) => {
70271
- const { renderedLines, anyTruncated } = import_react44.default.useMemo(() => {
70498
+ const { renderedLines, anyTruncated } = import_react45.default.useMemo(() => {
70272
70499
  if (!settings)
70273
70500
  return { renderedLines: [], anyTruncated: false };
70274
70501
  const preRenderedLines = preRenderAllWidgets(lines, settings, { terminalWidth, isPreview: true, minimalist: settings.minimalistMode });
@@ -70294,29 +70521,29 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
70294
70521
  }
70295
70522
  return { renderedLines: result2, anyTruncated: truncated };
70296
70523
  }, [lines, terminalWidth, settings]);
70297
- import_react44.default.useEffect(() => {
70524
+ import_react45.default.useEffect(() => {
70298
70525
  onTruncationChange?.(anyTruncated);
70299
70526
  }, [anyTruncated, onTruncationChange]);
70300
- return /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70527
+ return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70301
70528
  flexDirection: "column",
70302
70529
  children: [
70303
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Box_default, {
70530
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70304
70531
  borderStyle: "round",
70305
70532
  borderColor: "gray",
70306
70533
  borderDimColor: true,
70307
70534
  width: "100%",
70308
70535
  paddingLeft: 1,
70309
- children: /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70536
+ children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70310
70537
  children: [
70311
70538
  ">",
70312
- /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70539
+ /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70313
70540
  dimColor: true,
70314
70541
  children: " Preview (ctrl+s to save configuration at any time)"
70315
70542
  }, undefined, false, undefined, this)
70316
70543
  ]
70317
70544
  }, undefined, true, undefined, this)
70318
70545
  }, undefined, false, undefined, this),
70319
- renderedLines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime19.jsxDEV(Text, {
70546
+ renderedLines.map((line, index) => /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70320
70547
  children: [
70321
70548
  " ",
70322
70549
  line,
@@ -70329,7 +70556,7 @@ var StatusLinePreview = ({ lines, terminalWidth, settings, onTruncationChange })
70329
70556
  // src/tui/components/TerminalOptionsMenu.tsx
70330
70557
  init_source();
70331
70558
  await init_build2();
70332
- var import_react45 = __toESM(require_react(), 1);
70559
+ var import_react46 = __toESM(require_react(), 1);
70333
70560
 
70334
70561
  // src/utils/color-sanitize.ts
70335
70562
  await init_widgets2();
@@ -70384,7 +70611,7 @@ function sanitizeLinesForColorLevel(lines, nextLevel) {
70384
70611
  }
70385
70612
 
70386
70613
  // src/tui/components/TerminalOptionsMenu.tsx
70387
- var jsx_dev_runtime20 = __toESM(require_jsx_dev_runtime(), 1);
70614
+ var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
70388
70615
  function getNextColorLevel(level) {
70389
70616
  return (level + 1) % 4;
70390
70617
  }
@@ -70418,8 +70645,8 @@ var TerminalOptionsMenu = ({
70418
70645
  onUpdate,
70419
70646
  onBack
70420
70647
  }) => {
70421
- const [showColorWarning, setShowColorWarning] = import_react45.useState(false);
70422
- const [pendingColorLevel, setPendingColorLevel] = import_react45.useState(null);
70648
+ const [showColorWarning, setShowColorWarning] = import_react46.useState(false);
70649
+ const [pendingColorLevel, setPendingColorLevel] = import_react46.useState(null);
70423
70650
  const handleSelect = (value) => {
70424
70651
  if (value === "back") {
70425
70652
  onBack();
@@ -70467,27 +70694,27 @@ var TerminalOptionsMenu = ({
70467
70694
  onBack();
70468
70695
  }
70469
70696
  });
70470
- return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70697
+ return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70471
70698
  flexDirection: "column",
70472
70699
  children: [
70473
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70700
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70474
70701
  bold: true,
70475
70702
  children: "Terminal Options"
70476
70703
  }, undefined, false, undefined, this),
70477
- showColorWarning ? /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70704
+ showColorWarning ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70478
70705
  flexDirection: "column",
70479
70706
  marginTop: 1,
70480
70707
  children: [
70481
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70708
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70482
70709
  color: "yellow",
70483
70710
  children: "⚠ Warning: Custom colors detected!"
70484
70711
  }, undefined, false, undefined, this),
70485
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70712
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70486
70713
  children: "Switching color modes will reset custom ansi256 or hex colors to defaults."
70487
70714
  }, undefined, false, undefined, this),
70488
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
70715
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70489
70716
  marginTop: 1,
70490
- children: /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(ConfirmDialog, {
70717
+ children: /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(ConfirmDialog, {
70491
70718
  message: "Continue?",
70492
70719
  onConfirm: handleColorConfirm,
70493
70720
  onCancel: handleColorCancel,
@@ -70495,13 +70722,13 @@ var TerminalOptionsMenu = ({
70495
70722
  }, undefined, false, undefined, this)
70496
70723
  }, undefined, false, undefined, this)
70497
70724
  ]
70498
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(jsx_dev_runtime20.Fragment, {
70725
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(jsx_dev_runtime21.Fragment, {
70499
70726
  children: [
70500
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
70727
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70501
70728
  color: "white",
70502
70729
  children: "Configure terminal-specific settings for optimal display"
70503
70730
  }, undefined, false, undefined, this),
70504
- /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(List, {
70731
+ /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(List, {
70505
70732
  marginTop: 1,
70506
70733
  items: buildTerminalOptionsItems(settings.colorLevel),
70507
70734
  onSelect: handleSelect,
@@ -70530,8 +70757,8 @@ var getColorLevelLabel = (level) => {
70530
70757
  // src/tui/components/TerminalWidthMenu.tsx
70531
70758
  init_input_guards();
70532
70759
  await init_build2();
70533
- var import_react46 = __toESM(require_react(), 1);
70534
- var jsx_dev_runtime21 = __toESM(require_jsx_dev_runtime(), 1);
70760
+ var import_react47 = __toESM(require_react(), 1);
70761
+ var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
70535
70762
  var TERMINAL_WIDTH_OPTIONS = ["full", "full-minus-40", "full-until-compact"];
70536
70763
  function getTerminalWidthSelectionIndex(selectedOption) {
70537
70764
  const selectedIndex = TERMINAL_WIDTH_OPTIONS.indexOf(selectedOption);
@@ -70578,11 +70805,11 @@ var TerminalWidthMenu = ({
70578
70805
  onUpdate,
70579
70806
  onBack
70580
70807
  }) => {
70581
- const [selectedOption, setSelectedOption] = import_react46.useState(settings.flexMode);
70582
- const [compactThreshold, setCompactThreshold] = import_react46.useState(settings.compactThreshold);
70583
- const [editingThreshold, setEditingThreshold] = import_react46.useState(false);
70584
- const [thresholdInput, setThresholdInput] = import_react46.useState(String(settings.compactThreshold));
70585
- const [validationError, setValidationError] = import_react46.useState(null);
70808
+ const [selectedOption, setSelectedOption] = import_react47.useState(settings.flexMode);
70809
+ const [compactThreshold, setCompactThreshold] = import_react47.useState(settings.compactThreshold);
70810
+ const [editingThreshold, setEditingThreshold] = import_react47.useState(false);
70811
+ const [thresholdInput, setThresholdInput] = import_react47.useState(String(settings.compactThreshold));
70812
+ const [validationError, setValidationError] = import_react47.useState(null);
70586
70813
  use_input_default((input, key) => {
70587
70814
  if (editingThreshold) {
70588
70815
  if (key.return) {
@@ -70621,27 +70848,27 @@ var TerminalWidthMenu = ({
70621
70848
  onBack();
70622
70849
  }
70623
70850
  });
70624
- return /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70851
+ return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
70625
70852
  flexDirection: "column",
70626
70853
  children: [
70627
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70854
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70628
70855
  bold: true,
70629
70856
  children: "Terminal Width"
70630
70857
  }, undefined, false, undefined, this),
70631
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70858
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70632
70859
  color: "white",
70633
70860
  children: "These settings affect where long lines are truncated, and where right-alignment occurs when using flex separators"
70634
70861
  }, undefined, false, undefined, this),
70635
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70862
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70636
70863
  dimColor: true,
70637
70864
  wrap: "wrap",
70638
70865
  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"
70639
70866
  }, undefined, false, undefined, this),
70640
- editingThreshold ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Box_default, {
70867
+ editingThreshold ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
70641
70868
  marginTop: 1,
70642
70869
  flexDirection: "column",
70643
70870
  children: [
70644
- /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70871
+ /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70645
70872
  children: [
70646
70873
  "Enter compact threshold (1-99):",
70647
70874
  " ",
@@ -70649,15 +70876,15 @@ var TerminalWidthMenu = ({
70649
70876
  "%"
70650
70877
  ]
70651
70878
  }, undefined, true, undefined, this),
70652
- validationError ? /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70879
+ validationError ? /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70653
70880
  color: "red",
70654
70881
  children: validationError
70655
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(Text, {
70882
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
70656
70883
  dimColor: true,
70657
70884
  children: "Press Enter to confirm, ESC to cancel"
70658
70885
  }, undefined, false, undefined, this)
70659
70886
  ]
70660
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime21.jsxDEV(List, {
70887
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(List, {
70661
70888
  marginTop: 1,
70662
70889
  items: buildTerminalWidthItems(selectedOption, compactThreshold),
70663
70890
  initialSelection: getTerminalWidthSelectionIndex(selectedOption),
@@ -70683,7 +70910,7 @@ var TerminalWidthMenu = ({
70683
70910
  }, undefined, true, undefined, this);
70684
70911
  };
70685
70912
  // src/tui/App.tsx
70686
- var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
70913
+ var jsx_dev_runtime23 = __toESM(require_jsx_dev_runtime(), 1);
70687
70914
  var GITHUB_REPO_URL = "https://github.com/sirmalloc/ccstatusline";
70688
70915
  function getConfirmCancelScreen(confirmDialog) {
70689
70916
  return confirmDialog?.cancelScreen ?? "main";
@@ -70698,23 +70925,28 @@ function clearInstallMenuSelection(menuSelections) {
70698
70925
  }
70699
70926
  var App2 = () => {
70700
70927
  const { exit } = use_app_default();
70701
- const [settings, setSettings] = import_react47.useState(null);
70702
- const [originalSettings, setOriginalSettings] = import_react47.useState(null);
70703
- const [hasChanges, setHasChanges] = import_react47.useState(false);
70704
- const [screen, setScreen] = import_react47.useState("main");
70705
- const [selectedLine, setSelectedLine] = import_react47.useState(0);
70706
- const [menuSelections, setMenuSelections] = import_react47.useState({});
70707
- const [confirmDialog, setConfirmDialog] = import_react47.useState(null);
70708
- const [isClaudeInstalled, setIsClaudeInstalled] = import_react47.useState(false);
70709
- const [terminalWidth, setTerminalWidth] = import_react47.useState(process.stdout.columns || 80);
70710
- const [powerlineFontStatus, setPowerlineFontStatus] = import_react47.useState({ installed: false });
70711
- const [installingFonts, setInstallingFonts] = import_react47.useState(false);
70712
- const [fontInstallMessage, setFontInstallMessage] = import_react47.useState(null);
70713
- const [existingStatusLine, setExistingStatusLine] = import_react47.useState(null);
70714
- const [flashMessage, setFlashMessage] = import_react47.useState(null);
70715
- const [previewIsTruncated, setPreviewIsTruncated] = import_react47.useState(false);
70716
- import_react47.useEffect(() => {
70717
- getExistingStatusLine().then(setExistingStatusLine);
70928
+ const [settings, setSettings] = import_react48.useState(null);
70929
+ const [originalSettings, setOriginalSettings] = import_react48.useState(null);
70930
+ const [hasChanges, setHasChanges] = import_react48.useState(false);
70931
+ const [screen, setScreen] = import_react48.useState("main");
70932
+ const [selectedLine, setSelectedLine] = import_react48.useState(0);
70933
+ const [menuSelections, setMenuSelections] = import_react48.useState({});
70934
+ const [confirmDialog, setConfirmDialog] = import_react48.useState(null);
70935
+ const [isClaudeInstalled, setIsClaudeInstalled] = import_react48.useState(false);
70936
+ const [terminalWidth, setTerminalWidth] = import_react48.useState(process.stdout.columns || 80);
70937
+ const [powerlineFontStatus, setPowerlineFontStatus] = import_react48.useState({ installed: false });
70938
+ const [installingFonts, setInstallingFonts] = import_react48.useState(false);
70939
+ const [fontInstallMessage, setFontInstallMessage] = import_react48.useState(null);
70940
+ const [existingStatusLine, setExistingStatusLine] = import_react48.useState(null);
70941
+ const [flashMessage, setFlashMessage] = import_react48.useState(null);
70942
+ const [previewIsTruncated, setPreviewIsTruncated] = import_react48.useState(false);
70943
+ const [currentRefreshInterval, setCurrentRefreshInterval] = import_react48.useState(null);
70944
+ const [supportsRefreshInterval] = import_react48.useState(() => isClaudeCodeVersionAtLeast("2.1.97"));
70945
+ import_react48.useEffect(() => {
70946
+ loadClaudeStatusLineState().then((statusLineState) => {
70947
+ setExistingStatusLine(statusLineState.existingStatusLine);
70948
+ setCurrentRefreshInterval(statusLineState.refreshInterval);
70949
+ });
70718
70950
  loadSettings().then((loadedSettings) => {
70719
70951
  source_default.level = loadedSettings.colorLevel;
70720
70952
  setSettings(loadedSettings);
@@ -70734,13 +70966,13 @@ var App2 = () => {
70734
70966
  process.stdout.off("resize", handleResize);
70735
70967
  };
70736
70968
  }, []);
70737
- import_react47.useEffect(() => {
70969
+ import_react48.useEffect(() => {
70738
70970
  if (originalSettings) {
70739
70971
  const hasAnyChanges = JSON.stringify(settings) !== JSON.stringify(originalSettings);
70740
70972
  setHasChanges(hasAnyChanges);
70741
70973
  }
70742
70974
  }, [settings, originalSettings]);
70743
- import_react47.useEffect(() => {
70975
+ import_react48.useEffect(() => {
70744
70976
  if (flashMessage) {
70745
70977
  const timer = setTimeout(() => {
70746
70978
  setFlashMessage(null);
@@ -70766,7 +70998,7 @@ var App2 = () => {
70766
70998
  })();
70767
70999
  }
70768
71000
  });
70769
- const handleInstallSelection = import_react47.useCallback((command, displayName, useBunx) => {
71001
+ const handleInstallSelection = import_react48.useCallback((command, displayName, useBunx) => {
70770
71002
  getExistingStatusLine().then((existing) => {
70771
71003
  const isAlreadyInstalled = isKnownCommand(existing ?? "");
70772
71004
  let message;
@@ -70786,30 +71018,32 @@ Continue?`;
70786
71018
  message,
70787
71019
  cancelScreen: "install",
70788
71020
  action: async () => {
70789
- await installStatusLine(useBunx);
71021
+ await installStatusLine(useBunx, supportsRefreshInterval);
71022
+ const installedStatusLineState = await loadClaudeStatusLineState();
70790
71023
  setIsClaudeInstalled(true);
70791
- setExistingStatusLine(command);
71024
+ setExistingStatusLine(installedStatusLineState.existingStatusLine ?? command);
71025
+ setCurrentRefreshInterval(installedStatusLineState.refreshInterval);
70792
71026
  setScreen("main");
70793
71027
  setConfirmDialog(null);
70794
71028
  }
70795
71029
  });
70796
71030
  setScreen("confirm");
70797
71031
  });
70798
- }, []);
70799
- const handleNpxInstall = import_react47.useCallback(() => {
71032
+ }, [supportsRefreshInterval]);
71033
+ const handleNpxInstall = import_react48.useCallback(() => {
70800
71034
  setMenuSelections((prev) => ({ ...prev, install: 0 }));
70801
71035
  handleInstallSelection(CCSTATUSLINE_COMMANDS.NPM, "npx", false);
70802
71036
  }, [handleInstallSelection]);
70803
- const handleBunxInstall = import_react47.useCallback(() => {
71037
+ const handleBunxInstall = import_react48.useCallback(() => {
70804
71038
  setMenuSelections((prev) => ({ ...prev, install: 1 }));
70805
71039
  handleInstallSelection(CCSTATUSLINE_COMMANDS.BUNX, "bunx", true);
70806
71040
  }, [handleInstallSelection]);
70807
- const handleInstallMenuCancel = import_react47.useCallback(() => {
71041
+ const handleInstallMenuCancel = import_react48.useCallback(() => {
70808
71042
  setMenuSelections(clearInstallMenuSelection);
70809
71043
  setScreen("main");
70810
71044
  }, []);
70811
71045
  if (!settings) {
70812
- return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71046
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70813
71047
  children: "Loading settings..."
70814
71048
  }, undefined, false, undefined, this);
70815
71049
  }
@@ -70821,6 +71055,7 @@ Continue?`;
70821
71055
  await uninstallStatusLine();
70822
71056
  setIsClaudeInstalled(false);
70823
71057
  setExistingStatusLine(null);
71058
+ setCurrentRefreshInterval(null);
70824
71059
  setScreen("main");
70825
71060
  setConfirmDialog(null);
70826
71061
  }
@@ -70850,6 +71085,9 @@ Continue?`;
70850
71085
  case "install":
70851
71086
  handleInstallUninstall();
70852
71087
  break;
71088
+ case "configureStatusLine":
71089
+ setScreen("refreshInterval");
71090
+ break;
70853
71091
  case "starGithub":
70854
71092
  setConfirmDialog({
70855
71093
  message: `Open the ccstatusline GitHub repository in your browser?
@@ -70898,44 +71136,44 @@ ${GITHUB_REPO_URL}`,
70898
71136
  setSelectedLine(lineIndex);
70899
71137
  setScreen("items");
70900
71138
  };
70901
- return /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
71139
+ return /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70902
71140
  flexDirection: "column",
70903
71141
  children: [
70904
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
71142
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70905
71143
  marginBottom: 1,
70906
71144
  children: [
70907
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71145
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70908
71146
  bold: true,
70909
- children: /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(dist_default5, {
71147
+ children: /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(dist_default5, {
70910
71148
  name: "retro",
70911
71149
  children: "CCStatusline Configuration"
70912
71150
  }, undefined, false, undefined, this)
70913
71151
  }, undefined, false, undefined, this),
70914
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71152
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70915
71153
  bold: true,
70916
71154
  children: ` | ${getPackageVersion() && `v${getPackageVersion()}`}`
70917
71155
  }, undefined, false, undefined, this),
70918
- flashMessage && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71156
+ flashMessage && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70919
71157
  color: flashMessage.color,
70920
71158
  bold: true,
70921
71159
  children: ` ${flashMessage.text}`
70922
71160
  }, undefined, false, undefined, this)
70923
71161
  ]
70924
71162
  }, undefined, true, undefined, this),
70925
- isCustomConfigPath() && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Text, {
71163
+ isCustomConfigPath() && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Text, {
70926
71164
  dimColor: true,
70927
71165
  children: `Config: ${getConfigPath()}`
70928
71166
  }, undefined, false, undefined, this),
70929
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(StatusLinePreview, {
71167
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(StatusLinePreview, {
70930
71168
  lines: settings.lines,
70931
71169
  terminalWidth,
70932
71170
  settings,
70933
71171
  onTruncationChange: setPreviewIsTruncated
70934
71172
  }, undefined, false, undefined, this),
70935
- /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(Box_default, {
71173
+ /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(Box_default, {
70936
71174
  marginTop: 1,
70937
71175
  children: [
70938
- screen === "main" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(MainMenu, {
71176
+ screen === "main" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(MainMenu, {
70939
71177
  onSelect: (value, index) => {
70940
71178
  if (value !== "save" && value !== "exit") {
70941
71179
  setMenuSelections((prev) => ({ ...prev, main: index }));
@@ -70949,7 +71187,7 @@ ${GITHUB_REPO_URL}`,
70949
71187
  settings,
70950
71188
  previewIsTruncated
70951
71189
  }, undefined, false, undefined, this),
70952
- screen === "lines" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(LineSelector, {
71190
+ screen === "lines" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(LineSelector, {
70953
71191
  lines: settings.lines,
70954
71192
  onSelect: (line) => {
70955
71193
  setMenuSelections((prev) => ({ ...prev, lines: line }));
@@ -70964,7 +71202,7 @@ ${GITHUB_REPO_URL}`,
70964
71202
  title: "Select Line to Edit Items",
70965
71203
  allowEditing: true
70966
71204
  }, undefined, false, undefined, this),
70967
- screen === "items" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ItemsEditor, {
71205
+ screen === "items" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ItemsEditor, {
70968
71206
  widgets: settings.lines[selectedLine] ?? [],
70969
71207
  onUpdate: (widgets) => {
70970
71208
  updateLine(selectedLine, widgets);
@@ -70976,7 +71214,7 @@ ${GITHUB_REPO_URL}`,
70976
71214
  lineNumber: selectedLine + 1,
70977
71215
  settings
70978
71216
  }, undefined, false, undefined, this),
70979
- screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(LineSelector, {
71217
+ screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(LineSelector, {
70980
71218
  lines: settings.lines,
70981
71219
  onLinesUpdate: updateLines,
70982
71220
  onSelect: (line) => {
@@ -70994,7 +71232,7 @@ ${GITHUB_REPO_URL}`,
70994
71232
  settings,
70995
71233
  allowEditing: false
70996
71234
  }, undefined, false, undefined, this),
70997
- screen === "colors" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ColorMenu, {
71235
+ screen === "colors" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ColorMenu, {
70998
71236
  widgets: settings.lines[selectedLine] ?? [],
70999
71237
  lineIndex: selectedLine,
71000
71238
  settings,
@@ -71007,7 +71245,7 @@ ${GITHUB_REPO_URL}`,
71007
71245
  setScreen("colorLines");
71008
71246
  }
71009
71247
  }, undefined, false, undefined, this),
71010
- screen === "terminalConfig" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(TerminalOptionsMenu, {
71248
+ screen === "terminalConfig" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TerminalOptionsMenu, {
71011
71249
  settings,
71012
71250
  onUpdate: (updatedSettings) => {
71013
71251
  setSettings(updatedSettings);
@@ -71021,7 +71259,7 @@ ${GITHUB_REPO_URL}`,
71021
71259
  }
71022
71260
  }
71023
71261
  }, undefined, false, undefined, this),
71024
- screen === "terminalWidth" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(TerminalWidthMenu, {
71262
+ screen === "terminalWidth" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(TerminalWidthMenu, {
71025
71263
  settings,
71026
71264
  onUpdate: (updatedSettings) => {
71027
71265
  setSettings(updatedSettings);
@@ -71030,7 +71268,7 @@ ${GITHUB_REPO_URL}`,
71030
71268
  setScreen("terminalConfig");
71031
71269
  }
71032
71270
  }, undefined, false, undefined, this),
71033
- screen === "globalOverrides" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(GlobalOverridesMenu, {
71271
+ screen === "globalOverrides" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(GlobalOverridesMenu, {
71034
71272
  settings,
71035
71273
  onUpdate: (updatedSettings) => {
71036
71274
  setSettings(updatedSettings);
@@ -71040,7 +71278,7 @@ ${GITHUB_REPO_URL}`,
71040
71278
  setScreen("main");
71041
71279
  }
71042
71280
  }, undefined, false, undefined, this),
71043
- screen === "confirm" && confirmDialog && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ConfirmDialog, {
71281
+ screen === "confirm" && confirmDialog && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(ConfirmDialog, {
71044
71282
  message: confirmDialog.message,
71045
71283
  onConfirm: () => void confirmDialog.action(),
71046
71284
  onCancel: () => {
@@ -71048,7 +71286,7 @@ ${GITHUB_REPO_URL}`,
71048
71286
  setConfirmDialog(null);
71049
71287
  }
71050
71288
  }, undefined, false, undefined, this),
71051
- screen === "install" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(InstallMenu, {
71289
+ screen === "install" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(InstallMenu, {
71052
71290
  bunxAvailable: isBunxAvailable(),
71053
71291
  existingStatusLine,
71054
71292
  onSelectNpx: handleNpxInstall,
@@ -71056,7 +71294,31 @@ ${GITHUB_REPO_URL}`,
71056
71294
  onCancel: handleInstallMenuCancel,
71057
71295
  initialSelection: menuSelections.install
71058
71296
  }, undefined, false, undefined, this),
71059
- screen === "powerline" && /* @__PURE__ */ jsx_dev_runtime22.jsxDEV(PowerlineSetup, {
71297
+ screen === "refreshInterval" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(RefreshIntervalMenu, {
71298
+ currentInterval: currentRefreshInterval,
71299
+ supportsRefreshInterval,
71300
+ onUpdate: (interval) => {
71301
+ const previous = currentRefreshInterval;
71302
+ setCurrentRefreshInterval(interval);
71303
+ setRefreshInterval(interval).then(() => {
71304
+ setFlashMessage({
71305
+ text: "✓ Refresh interval updated",
71306
+ color: "green"
71307
+ });
71308
+ }).catch(() => {
71309
+ setCurrentRefreshInterval(previous);
71310
+ setFlashMessage({
71311
+ text: "✗ Failed to save refresh interval",
71312
+ color: "red"
71313
+ });
71314
+ });
71315
+ setScreen("main");
71316
+ },
71317
+ onBack: () => {
71318
+ setScreen("main");
71319
+ }
71320
+ }, undefined, false, undefined, this),
71321
+ screen === "powerline" && /* @__PURE__ */ jsx_dev_runtime23.jsxDEV(PowerlineSetup, {
71060
71322
  settings,
71061
71323
  powerlineFontStatus,
71062
71324
  onUpdate: (updatedSettings) => {
@@ -71090,7 +71352,7 @@ ${GITHUB_REPO_URL}`,
71090
71352
  };
71091
71353
  function runTUI() {
71092
71354
  process.stdout.write("\x1B[2J\x1B[H");
71093
- render_default(/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(App2, {}, undefined, false, undefined, this));
71355
+ render_default(/* @__PURE__ */ jsx_dev_runtime23.jsxDEV(App2, {}, undefined, false, undefined, this));
71094
71356
  }
71095
71357
  // src/types/StatusJSON.ts
71096
71358
  init_zod();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline-usage",
3
- "version": "2.3.15",
3
+ "version": "2.3.16",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",
@@ -35,7 +35,7 @@
35
35
  "eslint-plugin-react": "^7.37.5",
36
36
  "eslint-plugin-react-hooks": "^7.0.1",
37
37
  "globals": "^17.3.0",
38
- "https-proxy-agent": "^7.0.0",
38
+ "https-proxy-agent": "^8.0.0",
39
39
  "ink": "6.2.0",
40
40
  "ink-gradient": "^4.0.0",
41
41
  "ink-select-input": "^6.2.0",