ccstatusline 2.0.25 → 2.0.26

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
@@ -355,6 +355,7 @@ Once configured, ccstatusline automatically formats your Claude Code status line
355
355
  - **Git Worktree** - Shows the name of the current git worktree
356
356
  - **Session Clock** - Shows elapsed time since session start (e.g., "2hr 15m")
357
357
  - **Session Cost** - Shows total session cost in USD (e.g., "$1.23")
358
+ - **Session Name** - Shows the session name set via `/rename` command in Claude Code
358
359
  - **Block Timer** - Shows time elapsed in current 5-hour block or progress bar
359
360
  - **Current Working Directory** - Shows current working directory with configurable path segments
360
361
  - **Version** - Shows Claude Code version
@@ -51405,7 +51405,7 @@ import { execSync as execSync3 } from "child_process";
51405
51405
  import * as fs5 from "fs";
51406
51406
  import * as path4 from "path";
51407
51407
  var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
51408
- var PACKAGE_VERSION = "2.0.25";
51408
+ var PACKAGE_VERSION = "2.0.26";
51409
51409
  function getPackageVersion() {
51410
51410
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51411
51411
  return PACKAGE_VERSION;
@@ -52234,6 +52234,18 @@ function getDefaultPowerlineTheme() {
52234
52234
  return "nord-aurora";
52235
52235
  }
52236
52236
 
52237
+ // src/utils/input-guards.ts
52238
+ var CONTROL_CHAR_REGEX = /[\u0000-\u001F\u007F]/u;
52239
+ var shouldInsertInput = (input, key) => {
52240
+ if (!input) {
52241
+ return false;
52242
+ }
52243
+ if (key.ctrl || key.meta || key.tab) {
52244
+ return false;
52245
+ }
52246
+ return !CONTROL_CHAR_REGEX.test(input);
52247
+ };
52248
+
52237
52249
  // src/widgets/Model.ts
52238
52250
  class ModelWidget {
52239
52251
  getDefaultColor() {
@@ -52245,6 +52257,9 @@ class ModelWidget {
52245
52257
  getDisplayName() {
52246
52258
  return "Model";
52247
52259
  }
52260
+ getCategory() {
52261
+ return "Core";
52262
+ }
52248
52263
  getEditorDisplay(item) {
52249
52264
  return { displayText: this.getDisplayName() };
52250
52265
  }
@@ -52277,6 +52292,9 @@ class OutputStyleWidget {
52277
52292
  getDisplayName() {
52278
52293
  return "Output Style";
52279
52294
  }
52295
+ getCategory() {
52296
+ return "Core";
52297
+ }
52280
52298
  getEditorDisplay(item) {
52281
52299
  return { displayText: this.getDisplayName() };
52282
52300
  }
@@ -52308,6 +52326,9 @@ class GitBranchWidget {
52308
52326
  getDisplayName() {
52309
52327
  return "Git Branch";
52310
52328
  }
52329
+ getCategory() {
52330
+ return "Git";
52331
+ }
52311
52332
  getEditorDisplay(item) {
52312
52333
  const hideNoGit = item.metadata?.hideNoGit === "true";
52313
52334
  const modifiers = [];
@@ -52378,6 +52399,9 @@ class GitChangesWidget {
52378
52399
  getDisplayName() {
52379
52400
  return "Git Changes";
52380
52401
  }
52402
+ getCategory() {
52403
+ return "Git";
52404
+ }
52381
52405
  getEditorDisplay(item) {
52382
52406
  const hideNoGit = item.metadata?.hideNoGit === "true";
52383
52407
  const modifiers = [];
@@ -52467,6 +52491,9 @@ class GitWorktreeWidget {
52467
52491
  getDisplayName() {
52468
52492
  return "Git Worktree";
52469
52493
  }
52494
+ getCategory() {
52495
+ return "Git";
52496
+ }
52470
52497
  getEditorDisplay(item) {
52471
52498
  const hideNoGit = item.metadata?.hideNoGit === "true";
52472
52499
  const modifiers = [];
@@ -52534,7 +52561,7 @@ function getContextConfig(modelId) {
52534
52561
  };
52535
52562
  if (!modelId)
52536
52563
  return defaultConfig;
52537
- if (modelId.includes("claude-sonnet-4-5") && modelId.toLowerCase().includes("[1m]")) {
52564
+ if (modelId.toLowerCase().includes("[1m]")) {
52538
52565
  return {
52539
52566
  maxTokens: 1e6,
52540
52567
  usableTokens: 800000
@@ -53230,6 +53257,9 @@ class TokensInputWidget {
53230
53257
  getDisplayName() {
53231
53258
  return "Tokens Input";
53232
53259
  }
53260
+ getCategory() {
53261
+ return "Tokens";
53262
+ }
53233
53263
  getEditorDisplay(item) {
53234
53264
  return { displayText: this.getDisplayName() };
53235
53265
  }
@@ -53259,6 +53289,9 @@ class TokensOutputWidget {
53259
53289
  getDisplayName() {
53260
53290
  return "Tokens Output";
53261
53291
  }
53292
+ getCategory() {
53293
+ return "Tokens";
53294
+ }
53262
53295
  getEditorDisplay(item) {
53263
53296
  return { displayText: this.getDisplayName() };
53264
53297
  }
@@ -53288,6 +53321,9 @@ class TokensCachedWidget {
53288
53321
  getDisplayName() {
53289
53322
  return "Tokens Cached";
53290
53323
  }
53324
+ getCategory() {
53325
+ return "Tokens";
53326
+ }
53291
53327
  getEditorDisplay(item) {
53292
53328
  return { displayText: this.getDisplayName() };
53293
53329
  }
@@ -53317,6 +53353,9 @@ class TokensTotalWidget {
53317
53353
  getDisplayName() {
53318
53354
  return "Tokens Total";
53319
53355
  }
53356
+ getCategory() {
53357
+ return "Tokens";
53358
+ }
53320
53359
  getEditorDisplay(item) {
53321
53360
  return { displayText: this.getDisplayName() };
53322
53361
  }
@@ -53346,6 +53385,9 @@ class ContextLengthWidget {
53346
53385
  getDisplayName() {
53347
53386
  return "Context Length";
53348
53387
  }
53388
+ getCategory() {
53389
+ return "Context";
53390
+ }
53349
53391
  getEditorDisplay(item) {
53350
53392
  return { displayText: this.getDisplayName() };
53351
53393
  }
@@ -53375,6 +53417,9 @@ class ContextPercentageWidget {
53375
53417
  getDisplayName() {
53376
53418
  return "Context %";
53377
53419
  }
53420
+ getCategory() {
53421
+ return "Context";
53422
+ }
53378
53423
  getEditorDisplay(item) {
53379
53424
  const isInverse = item.metadata?.inverse === "true";
53380
53425
  const modifiers = [];
@@ -53437,6 +53482,9 @@ class ContextPercentageUsableWidget {
53437
53482
  getDisplayName() {
53438
53483
  return "Context % (usable)";
53439
53484
  }
53485
+ getCategory() {
53486
+ return "Context";
53487
+ }
53440
53488
  getEditorDisplay(item) {
53441
53489
  const isInverse = item.metadata?.inverse === "true";
53442
53490
  const modifiers = [];
@@ -53499,6 +53547,9 @@ class SessionClockWidget {
53499
53547
  getDisplayName() {
53500
53548
  return "Session Clock";
53501
53549
  }
53550
+ getCategory() {
53551
+ return "Session";
53552
+ }
53502
53553
  getEditorDisplay(item) {
53503
53554
  return { displayText: this.getDisplayName() };
53504
53555
  }
@@ -53527,6 +53578,9 @@ class SessionCostWidget {
53527
53578
  getDisplayName() {
53528
53579
  return "Session Cost";
53529
53580
  }
53581
+ getCategory() {
53582
+ return "Session";
53583
+ }
53530
53584
  getEditorDisplay(item) {
53531
53585
  return { displayText: this.getDisplayName() };
53532
53586
  }
@@ -53559,6 +53613,9 @@ class TerminalWidthWidget {
53559
53613
  getDisplayName() {
53560
53614
  return "Terminal Width";
53561
53615
  }
53616
+ getCategory() {
53617
+ return "Environment";
53618
+ }
53562
53619
  getEditorDisplay(item) {
53563
53620
  return { displayText: this.getDisplayName() };
53564
53621
  }
@@ -53590,6 +53647,9 @@ class VersionWidget {
53590
53647
  getDisplayName() {
53591
53648
  return "Version";
53592
53649
  }
53650
+ getCategory() {
53651
+ return "Core";
53652
+ }
53593
53653
  getEditorDisplay(item) {
53594
53654
  return { displayText: this.getDisplayName() };
53595
53655
  }
@@ -53622,6 +53682,9 @@ class CustomTextWidget {
53622
53682
  getDisplayName() {
53623
53683
  return "Custom Text";
53624
53684
  }
53685
+ getCategory() {
53686
+ return "Custom";
53687
+ }
53625
53688
  getEditorDisplay(item) {
53626
53689
  const text = item.customText ?? "Empty";
53627
53690
  return { displayText: `${this.getDisplayName()} (${text})` };
@@ -53724,7 +53787,7 @@ var CustomTextEditor = ({ widget, onComplete, onCancel }) => {
53724
53787
  setText(text.slice(0, deleteFromIndex) + text.slice(deleteToIndex));
53725
53788
  }
53726
53789
  }
53727
- } else if (input && !key.ctrl && !key.meta) {
53790
+ } else if (shouldInsertInput(input, key)) {
53728
53791
  const newText = text.slice(0, cursorPos) + input + text.slice(cursorPos);
53729
53792
  setText(newText);
53730
53793
  setCursorPos(cursorPos + input.length);
@@ -53774,6 +53837,9 @@ class CustomCommandWidget {
53774
53837
  getDisplayName() {
53775
53838
  return "Custom Command";
53776
53839
  }
53840
+ getCategory() {
53841
+ return "Custom";
53842
+ }
53777
53843
  getEditorDisplay(item) {
53778
53844
  const cmd = item.commandPath ?? "No command";
53779
53845
  const truncatedCmd = cmd.length > 20 ? `${cmd.substring(0, 17)}...` : cmd;
@@ -53897,7 +53963,7 @@ var CustomCommandEditor = ({ widget, onComplete, onCancel, action }) => {
53897
53963
  if (commandCursorPos < commandInput.length) {
53898
53964
  setCommandInput(commandInput.slice(0, commandCursorPos) + commandInput.slice(commandCursorPos + 1));
53899
53965
  }
53900
- } else if (input) {
53966
+ } else if (shouldInsertInput(input, key)) {
53901
53967
  setCommandInput(commandInput.slice(0, commandCursorPos) + input + commandInput.slice(commandCursorPos));
53902
53968
  setCommandCursorPos(commandCursorPos + input.length);
53903
53969
  }
@@ -53914,7 +53980,7 @@ var CustomCommandEditor = ({ widget, onComplete, onCancel, action }) => {
53914
53980
  onCancel();
53915
53981
  } else if (key.backspace) {
53916
53982
  setWidthInput(widthInput.slice(0, -1));
53917
- } else if (input && /\d/.test(input)) {
53983
+ } else if (shouldInsertInput(input, key) && /\d/.test(input)) {
53918
53984
  setWidthInput(widthInput + input);
53919
53985
  }
53920
53986
  } else if (mode === "timeout") {
@@ -53930,7 +53996,7 @@ var CustomCommandEditor = ({ widget, onComplete, onCancel, action }) => {
53930
53996
  onCancel();
53931
53997
  } else if (key.backspace) {
53932
53998
  setTimeoutInput(timeoutInput.slice(0, -1));
53933
- } else if (input && /\d/.test(input)) {
53999
+ } else if (shouldInsertInput(input, key) && /\d/.test(input)) {
53934
54000
  setTimeoutInput(timeoutInput + input);
53935
54001
  }
53936
54002
  }
@@ -54024,6 +54090,9 @@ class BlockTimerWidget {
54024
54090
  getDisplayName() {
54025
54091
  return "Block Timer";
54026
54092
  }
54093
+ getCategory() {
54094
+ return "Session";
54095
+ }
54027
54096
  getEditorDisplay(item) {
54028
54097
  const mode = item.metadata?.display ?? "time";
54029
54098
  const modifiers = [];
@@ -54124,8 +54193,8 @@ class BlockTimerWidget {
54124
54193
  }
54125
54194
  // src/widgets/CurrentWorkingDir.tsx
54126
54195
  var import_react31 = __toESM(require_react(), 1);
54127
- var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
54128
54196
  import * as os5 from "node:os";
54197
+ var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
54129
54198
 
54130
54199
  class CurrentWorkingDirWidget {
54131
54200
  getDefaultColor() {
@@ -54137,10 +54206,17 @@ class CurrentWorkingDirWidget {
54137
54206
  getDisplayName() {
54138
54207
  return "Current Working Dir";
54139
54208
  }
54209
+ getCategory() {
54210
+ return "Environment";
54211
+ }
54140
54212
  getEditorDisplay(item) {
54141
54213
  const segments = item.metadata?.segments ? parseInt(item.metadata.segments, 10) : undefined;
54142
54214
  const fishStyle = item.metadata?.fishStyle === "true";
54215
+ const abbreviateHome = item.metadata?.abbreviateHome === "true";
54143
54216
  const modifiers = [];
54217
+ if (abbreviateHome) {
54218
+ modifiers.push("~");
54219
+ }
54144
54220
  if (fishStyle) {
54145
54221
  modifiers.push("fish-style");
54146
54222
  } else if (segments && segments > 0) {
@@ -54152,11 +54228,31 @@ class CurrentWorkingDirWidget {
54152
54228
  };
54153
54229
  }
54154
54230
  handleEditorAction(action, item) {
54231
+ if (action === "toggle-abbreviate-home") {
54232
+ const currentAbbreviateHome = item.metadata?.abbreviateHome === "true";
54233
+ const newAbbreviateHome = !currentAbbreviateHome;
54234
+ if (newAbbreviateHome) {
54235
+ const { fishStyle, ...restMetadata } = item.metadata ?? {};
54236
+ return {
54237
+ ...item,
54238
+ metadata: {
54239
+ ...restMetadata,
54240
+ abbreviateHome: "true"
54241
+ }
54242
+ };
54243
+ } else {
54244
+ const { abbreviateHome, ...restMetadata } = item.metadata ?? {};
54245
+ return {
54246
+ ...item,
54247
+ metadata: Object.keys(restMetadata).length > 0 ? restMetadata : undefined
54248
+ };
54249
+ }
54250
+ }
54155
54251
  if (action === "toggle-fish-style") {
54156
54252
  const currentFishStyle = item.metadata?.fishStyle === "true";
54157
54253
  const newFishStyle = !currentFishStyle;
54158
54254
  if (newFishStyle) {
54159
- const { segments, ...restMetadata } = item.metadata ?? {};
54255
+ const { segments, abbreviateHome, ...restMetadata } = item.metadata ?? {};
54160
54256
  return {
54161
54257
  ...item,
54162
54258
  metadata: {
@@ -54177,10 +54273,19 @@ class CurrentWorkingDirWidget {
54177
54273
  render(item, context, settings) {
54178
54274
  const segments = item.metadata?.segments ? parseInt(item.metadata.segments, 10) : undefined;
54179
54275
  const fishStyle = item.metadata?.fishStyle === "true";
54276
+ const abbreviateHome = item.metadata?.abbreviateHome === "true";
54180
54277
  if (context.isPreview) {
54181
54278
  let previewPath;
54182
54279
  if (fishStyle) {
54183
54280
  previewPath = "~/D/P/my-project";
54281
+ } else if (abbreviateHome && segments && segments > 0) {
54282
+ if (segments === 1) {
54283
+ previewPath = "~/.../my-project";
54284
+ } else {
54285
+ previewPath = "~/.../Projects/my-project";
54286
+ }
54287
+ } else if (abbreviateHome) {
54288
+ previewPath = "~/Documents/Projects/my-project";
54184
54289
  } else if (segments && segments > 0) {
54185
54290
  if (segments === 1) {
54186
54291
  previewPath = ".../project";
@@ -54198,20 +54303,27 @@ class CurrentWorkingDirWidget {
54198
54303
  let displayPath = cwd2;
54199
54304
  if (fishStyle) {
54200
54305
  displayPath = this.abbreviatePath(cwd2);
54201
- } else if (segments && segments > 0) {
54202
- const useBackslash = cwd2.includes("\\") && !cwd2.includes("/");
54203
- const outSep = useBackslash ? "\\" : "/";
54204
- const pathParts = cwd2.split(/[\\/]+/);
54205
- const filteredParts = pathParts.filter((part) => part !== "");
54206
- if (filteredParts.length > segments) {
54207
- const selectedSegments = filteredParts.slice(-segments);
54208
- displayPath = "..." + outSep + selectedSegments.join(outSep);
54306
+ } else {
54307
+ if (abbreviateHome) {
54308
+ displayPath = this.abbreviateHomeDir(displayPath);
54309
+ }
54310
+ if (segments && segments > 0) {
54311
+ const useBackslash = displayPath.includes("\\") && !displayPath.includes("/");
54312
+ const outSep = useBackslash ? "\\" : "/";
54313
+ const pathParts = displayPath.split(/[\\/]+/);
54314
+ const filteredParts = pathParts.filter((part) => part !== "");
54315
+ if (filteredParts.length > segments) {
54316
+ const selectedSegments = filteredParts.slice(-segments);
54317
+ const prefix = displayPath.startsWith("~") ? `~${outSep}` : "";
54318
+ displayPath = prefix + "..." + outSep + selectedSegments.join(outSep);
54319
+ }
54209
54320
  }
54210
54321
  }
54211
54322
  return item.rawValue ? displayPath : `cwd: ${displayPath}`;
54212
54323
  }
54213
54324
  getCustomKeybinds() {
54214
54325
  return [
54326
+ { key: "h", label: "(h)ome ~", action: "toggle-abbreviate-home" },
54215
54327
  { key: "s", label: "(s)egments", action: "edit-segments" },
54216
54328
  { key: "f", label: "(f)ish style", action: "toggle-fish-style" }
54217
54329
  ];
@@ -54227,6 +54339,20 @@ class CurrentWorkingDirWidget {
54227
54339
  supportsColors(item) {
54228
54340
  return true;
54229
54341
  }
54342
+ abbreviateHomeDir(path5) {
54343
+ const homeDir = os5.homedir();
54344
+ if (path5 === homeDir) {
54345
+ return "~";
54346
+ }
54347
+ if (path5.startsWith(homeDir)) {
54348
+ const boundaryChar = path5[homeDir.length];
54349
+ if (boundaryChar !== "/" && boundaryChar !== "\\") {
54350
+ return path5;
54351
+ }
54352
+ return "~" + path5.slice(homeDir.length);
54353
+ }
54354
+ return path5;
54355
+ }
54230
54356
  abbreviatePath(path5) {
54231
54357
  const homeDir = os5.homedir();
54232
54358
  const useBackslash = path5.includes("\\") && !path5.includes("/");
@@ -54279,7 +54405,7 @@ var CurrentWorkingDirEditor = ({ widget, onComplete, onCancel, action }) => {
54279
54405
  onCancel();
54280
54406
  } else if (key.backspace) {
54281
54407
  setSegmentsInput(segmentsInput.slice(0, -1));
54282
- } else if (input && /\d/.test(input) && !key.ctrl) {
54408
+ } else if (shouldInsertInput(input, key) && /\d/.test(input)) {
54283
54409
  setSegmentsInput(segmentsInput + input);
54284
54410
  }
54285
54411
  }
@@ -54325,6 +54451,9 @@ class ClaudeSessionIdWidget {
54325
54451
  getDisplayName() {
54326
54452
  return "Claude Session ID";
54327
54453
  }
54454
+ getCategory() {
54455
+ return "Core";
54456
+ }
54328
54457
  getEditorDisplay(item) {
54329
54458
  return { displayText: this.getDisplayName() };
54330
54459
  }
@@ -54346,6 +54475,58 @@ class ClaudeSessionIdWidget {
54346
54475
  return true;
54347
54476
  }
54348
54477
  }
54478
+ // src/widgets/SessionName.ts
54479
+ import * as fs6 from "fs";
54480
+
54481
+ class SessionNameWidget {
54482
+ getDefaultColor() {
54483
+ return "cyan";
54484
+ }
54485
+ getDescription() {
54486
+ return "Shows the session name set via /rename command in Claude Code";
54487
+ }
54488
+ getDisplayName() {
54489
+ return "Session Name";
54490
+ }
54491
+ getCategory() {
54492
+ return "Session";
54493
+ }
54494
+ getEditorDisplay(item) {
54495
+ return { displayText: this.getDisplayName() };
54496
+ }
54497
+ render(item, context, settings) {
54498
+ if (context.isPreview) {
54499
+ return item.rawValue ? "my-session" : "Session: my-session";
54500
+ }
54501
+ const transcriptPath = context.data?.transcript_path;
54502
+ if (!transcriptPath) {
54503
+ return null;
54504
+ }
54505
+ try {
54506
+ const content = fs6.readFileSync(transcriptPath, "utf-8");
54507
+ const lines = content.split(`
54508
+ `);
54509
+ for (let i = lines.length - 1;i >= 0; i--) {
54510
+ const line = lines[i]?.trim();
54511
+ if (!line)
54512
+ continue;
54513
+ try {
54514
+ const entry = JSON.parse(line);
54515
+ if (entry.type === "custom-title" && entry.customTitle) {
54516
+ return item.rawValue ? entry.customTitle : `Session: ${entry.customTitle}`;
54517
+ }
54518
+ } catch {}
54519
+ }
54520
+ } catch {}
54521
+ return null;
54522
+ }
54523
+ supportsRawValue() {
54524
+ return true;
54525
+ }
54526
+ supportsColors(item) {
54527
+ return true;
54528
+ }
54529
+ }
54349
54530
  // src/utils/widgets.ts
54350
54531
  var widgetRegistry = new Map([
54351
54532
  ["model", new ModelWidget],
@@ -54368,7 +54549,8 @@ var widgetRegistry = new Map([
54368
54549
  ["version", new VersionWidget],
54369
54550
  ["custom-text", new CustomTextWidget],
54370
54551
  ["custom-command", new CustomCommandWidget],
54371
- ["claude-session-id", new ClaudeSessionIdWidget]
54552
+ ["claude-session-id", new ClaudeSessionIdWidget],
54553
+ ["session-name", new SessionNameWidget]
54372
54554
  ]);
54373
54555
  function getWidget(type) {
54374
54556
  return widgetRegistry.get(type) ?? null;
@@ -54383,6 +54565,98 @@ function getAllWidgetTypes(settings) {
54383
54565
  }
54384
54566
  return allTypes;
54385
54567
  }
54568
+ var LAYOUT_WIDGETS = {
54569
+ separator: {
54570
+ displayName: "Separator",
54571
+ description: "A separator character between status line widgets",
54572
+ category: "Layout"
54573
+ },
54574
+ "flex-separator": {
54575
+ displayName: "Flex Separator",
54576
+ description: "Expands to fill available terminal width",
54577
+ category: "Layout"
54578
+ }
54579
+ };
54580
+ function getLayoutCatalogEntry(type) {
54581
+ const layout = LAYOUT_WIDGETS[type];
54582
+ if (!layout) {
54583
+ return null;
54584
+ }
54585
+ return {
54586
+ type,
54587
+ displayName: layout.displayName,
54588
+ description: layout.description,
54589
+ category: layout.category,
54590
+ searchText: `${layout.displayName} ${layout.description} ${type}`.toLowerCase()
54591
+ };
54592
+ }
54593
+ function getWidgetCatalog(settings) {
54594
+ return getAllWidgetTypes(settings).map((type) => {
54595
+ const layoutEntry = getLayoutCatalogEntry(type);
54596
+ if (layoutEntry) {
54597
+ return layoutEntry;
54598
+ }
54599
+ const widget = getWidget(type);
54600
+ const displayName = widget?.getDisplayName() ?? type;
54601
+ const description = widget?.getDescription() ?? `Unknown widget: ${type}`;
54602
+ const category = widget?.getCategory() ?? "Other";
54603
+ return {
54604
+ type,
54605
+ displayName,
54606
+ description,
54607
+ category,
54608
+ searchText: `${displayName} ${description} ${type}`.toLowerCase()
54609
+ };
54610
+ });
54611
+ }
54612
+ function getWidgetCatalogCategories(catalog) {
54613
+ const categories = new Set;
54614
+ for (const entry of catalog) {
54615
+ categories.add(entry.category);
54616
+ }
54617
+ return Array.from(categories);
54618
+ }
54619
+ function filterWidgetCatalog(catalog, category, query) {
54620
+ const normalizedQuery = query.trim().toLowerCase();
54621
+ const categoryFiltered = category === "All" ? [...catalog] : catalog.filter((entry) => entry.category === category);
54622
+ const withScore = categoryFiltered.map((entry) => {
54623
+ if (!normalizedQuery) {
54624
+ return {
54625
+ entry,
54626
+ score: 99
54627
+ };
54628
+ }
54629
+ const name = entry.displayName.toLowerCase();
54630
+ const description = entry.description.toLowerCase();
54631
+ const type = entry.type.toLowerCase();
54632
+ if (name.startsWith(normalizedQuery)) {
54633
+ return { entry, score: 0 };
54634
+ }
54635
+ if (name.includes(normalizedQuery)) {
54636
+ return { entry, score: 1 };
54637
+ }
54638
+ if (type.includes(normalizedQuery)) {
54639
+ return { entry, score: 2 };
54640
+ }
54641
+ if (description.includes(normalizedQuery)) {
54642
+ return { entry, score: 3 };
54643
+ }
54644
+ if (entry.searchText.includes(normalizedQuery)) {
54645
+ return { entry, score: 4 };
54646
+ }
54647
+ return null;
54648
+ }).filter((item) => item !== null);
54649
+ return withScore.sort((a, b) => {
54650
+ if (a.score !== b.score) {
54651
+ return a.score - b.score;
54652
+ }
54653
+ const byDisplayName = a.entry.displayName.localeCompare(b.entry.displayName);
54654
+ if (byDisplayName !== 0) {
54655
+ return byDisplayName;
54656
+ }
54657
+ return a.entry.type.localeCompare(b.entry.type);
54658
+ }).map((item) => item.entry);
54659
+ }
54386
54660
 
54387
54661
  // src/tui/components/ConfirmDialog.tsx
54388
54662
  var import_react32 = __toESM(require_react(), 1);
@@ -54501,7 +54775,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
54501
54775
  }
54502
54776
  } else if (key.backspace || key.delete) {
54503
54777
  setHexInput(hexInput.slice(0, -1));
54504
- } else if (input && hexInput.length < 6) {
54778
+ } else if (shouldInsertInput(input, key) && hexInput.length < 6) {
54505
54779
  const upperInput = input.toUpperCase();
54506
54780
  if (/^[0-9A-F]$/.test(upperInput)) {
54507
54781
  setHexInput(hexInput + upperInput);
@@ -54539,7 +54813,7 @@ var ColorMenu = ({ widgets, lineIndex, settings, onUpdate, onBack }) => {
54539
54813
  }
54540
54814
  } else if (key.backspace || key.delete) {
54541
54815
  setAnsi256Input(ansi256Input.slice(0, -1));
54542
- } else if (input && ansi256Input.length < 3) {
54816
+ } else if (shouldInsertInput(input, key) && ansi256Input.length < 3) {
54543
54817
  if (/^[0-9]$/.test(input)) {
54544
54818
  const newInput = ansi256Input + input;
54545
54819
  const code = parseInt(newInput, 10);
@@ -55013,7 +55287,7 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
55013
55287
  setEditingPadding(false);
55014
55288
  } else if (key.backspace) {
55015
55289
  setPaddingInput(paddingInput.slice(0, -1));
55016
- } else if (key.delete) {} else if (input) {
55290
+ } else if (key.delete) {} else if (shouldInsertInput(input, key)) {
55017
55291
  setPaddingInput(paddingInput + input);
55018
55292
  }
55019
55293
  } else if (editingSeparator) {
@@ -55035,7 +55309,7 @@ var GlobalOverridesMenu = ({ settings, onUpdate, onBack }) => {
55035
55309
  setEditingSeparator(false);
55036
55310
  } else if (key.backspace) {
55037
55311
  setSeparatorInput(separatorInput.slice(0, -1));
55038
- } else if (key.delete) {} else if (input) {
55312
+ } else if (key.delete) {} else if (shouldInsertInput(input, key)) {
55039
55313
  setSeparatorInput(separatorInput + input);
55040
55314
  }
55041
55315
  } else if (confirmingSeparator) {
@@ -55502,21 +55776,11 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55502
55776
  const [selectedIndex, setSelectedIndex] = import_react36.useState(0);
55503
55777
  const [moveMode, setMoveMode] = import_react36.useState(false);
55504
55778
  const [customEditorWidget, setCustomEditorWidget] = import_react36.useState(null);
55779
+ const [widgetPicker, setWidgetPicker] = import_react36.useState(null);
55780
+ const [showClearConfirm, setShowClearConfirm] = import_react36.useState(false);
55505
55781
  const separatorChars = ["|", "-", ",", " "];
55506
- const getAllowedTypes = () => {
55507
- let allowedTypes = getAllWidgetTypes(settings);
55508
- if (settings.defaultSeparator) {
55509
- allowedTypes = allowedTypes.filter((t) => t !== "separator");
55510
- }
55511
- if (settings.powerline.enabled) {
55512
- allowedTypes = allowedTypes.filter((t) => t !== "separator" && t !== "flex-separator");
55513
- }
55514
- return allowedTypes;
55515
- };
55516
- const getDefaultItemType = () => {
55517
- const allowedTypes = getAllowedTypes();
55518
- return allowedTypes.includes("model") ? "model" : allowedTypes[0] ?? "model";
55519
- };
55782
+ const widgetCatalog = getWidgetCatalog(settings);
55783
+ const widgetCategories = ["All", ...getWidgetCatalogCategories(widgetCatalog)];
55520
55784
  const getUniqueBackgroundColor = (insertIndex) => {
55521
55785
  if (!settings.powerline.enabled || settings.powerline.theme === "custom") {
55522
55786
  return;
@@ -55542,10 +55806,187 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55542
55806
  const handleEditorCancel = () => {
55543
55807
  setCustomEditorWidget(null);
55544
55808
  };
55809
+ const getFilteredCategories = (query) => {
55810
+ return [...widgetCategories];
55811
+ };
55812
+ const normalizePickerState = (state) => {
55813
+ const filteredCategories = getFilteredCategories(state.categoryQuery);
55814
+ const selectedCategory = state.selectedCategory && filteredCategories.includes(state.selectedCategory) ? state.selectedCategory : filteredCategories[0] ?? null;
55815
+ const hasTopLevelSearch = state.level === "category" && state.categoryQuery.trim().length > 0;
55816
+ const effectiveCategory = hasTopLevelSearch ? "All" : selectedCategory ?? "All";
55817
+ const effectiveQuery = hasTopLevelSearch ? state.categoryQuery : state.widgetQuery;
55818
+ const filteredWidgets = filterWidgetCatalog(widgetCatalog, effectiveCategory, effectiveQuery);
55819
+ const hasSelectedType = state.selectedType ? filteredWidgets.some((entry) => entry.type === state.selectedType) : false;
55820
+ return {
55821
+ ...state,
55822
+ selectedCategory,
55823
+ selectedType: hasSelectedType ? state.selectedType : filteredWidgets[0]?.type ?? null
55824
+ };
55825
+ };
55826
+ const openWidgetPicker = (action) => {
55827
+ if (widgetCatalog.length === 0) {
55828
+ return;
55829
+ }
55830
+ const currentType = widgets[selectedIndex]?.type;
55831
+ const selectedType = action === "change" ? currentType ?? null : null;
55832
+ setWidgetPicker(normalizePickerState({
55833
+ action,
55834
+ level: "category",
55835
+ selectedCategory: "All",
55836
+ categoryQuery: "",
55837
+ widgetQuery: "",
55838
+ selectedType
55839
+ }));
55840
+ };
55841
+ const applyWidgetPickerSelection = (selectedType) => {
55842
+ if (!widgetPicker) {
55843
+ return;
55844
+ }
55845
+ if (widgetPicker.action === "change") {
55846
+ const currentWidget2 = widgets[selectedIndex];
55847
+ if (currentWidget2) {
55848
+ const newWidgets = [...widgets];
55849
+ newWidgets[selectedIndex] = { ...currentWidget2, type: selectedType };
55850
+ onUpdate(newWidgets);
55851
+ }
55852
+ } else {
55853
+ const insertIndex = widgetPicker.action === "add" ? widgets.length > 0 ? selectedIndex + 1 : 0 : selectedIndex;
55854
+ const backgroundColor = getUniqueBackgroundColor(insertIndex);
55855
+ const newWidget = {
55856
+ id: generateGuid(),
55857
+ type: selectedType,
55858
+ ...backgroundColor && { backgroundColor }
55859
+ };
55860
+ const newWidgets = [...widgets];
55861
+ newWidgets.splice(insertIndex, 0, newWidget);
55862
+ onUpdate(newWidgets);
55863
+ setSelectedIndex(insertIndex);
55864
+ }
55865
+ setWidgetPicker(null);
55866
+ };
55545
55867
  use_input_default((input, key) => {
55546
55868
  if (customEditorWidget) {
55547
55869
  return;
55548
55870
  }
55871
+ if (showClearConfirm) {
55872
+ return;
55873
+ }
55874
+ if (widgetPicker) {
55875
+ const filteredCategories = getFilteredCategories(widgetPicker.categoryQuery);
55876
+ const selectedCategory = widgetPicker.selectedCategory && filteredCategories.includes(widgetPicker.selectedCategory) ? widgetPicker.selectedCategory : filteredCategories[0] ?? null;
55877
+ const hasTopLevelSearch = widgetPicker.level === "category" && widgetPicker.categoryQuery.trim().length > 0;
55878
+ const topLevelSearchEntries2 = hasTopLevelSearch ? filterWidgetCatalog(widgetCatalog, "All", widgetPicker.categoryQuery) : [];
55879
+ const topLevelSelectedEntry = topLevelSearchEntries2.find((entry) => entry.type === widgetPicker.selectedType) ?? topLevelSearchEntries2[0];
55880
+ const filteredWidgets = filterWidgetCatalog(widgetCatalog, selectedCategory ?? "All", widgetPicker.widgetQuery);
55881
+ const selectedEntry = filteredWidgets.find((entry) => entry.type === widgetPicker.selectedType) ?? filteredWidgets[0];
55882
+ if (widgetPicker.level === "category") {
55883
+ if (key.escape) {
55884
+ if (widgetPicker.categoryQuery.length > 0) {
55885
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55886
+ ...prev,
55887
+ categoryQuery: ""
55888
+ }) : prev);
55889
+ } else {
55890
+ setWidgetPicker(null);
55891
+ }
55892
+ } else if (key.return) {
55893
+ if (hasTopLevelSearch) {
55894
+ if (topLevelSelectedEntry) {
55895
+ applyWidgetPickerSelection(topLevelSelectedEntry.type);
55896
+ }
55897
+ } else if (selectedCategory) {
55898
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55899
+ ...prev,
55900
+ level: "widget",
55901
+ selectedCategory
55902
+ }) : prev);
55903
+ }
55904
+ } else if (key.upArrow || key.downArrow) {
55905
+ if (hasTopLevelSearch) {
55906
+ if (topLevelSearchEntries2.length === 0) {
55907
+ return;
55908
+ }
55909
+ let currentIndex = topLevelSearchEntries2.findIndex((entry) => entry.type === widgetPicker.selectedType);
55910
+ if (currentIndex === -1) {
55911
+ currentIndex = 0;
55912
+ }
55913
+ const nextIndex = key.downArrow ? Math.min(topLevelSearchEntries2.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
55914
+ const nextType = topLevelSearchEntries2[nextIndex]?.type ?? null;
55915
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55916
+ ...prev,
55917
+ selectedType: nextType
55918
+ }) : prev);
55919
+ } else {
55920
+ if (filteredCategories.length === 0) {
55921
+ return;
55922
+ }
55923
+ let currentIndex = filteredCategories.findIndex((category) => category === selectedCategory);
55924
+ if (currentIndex === -1) {
55925
+ currentIndex = 0;
55926
+ }
55927
+ const nextIndex = key.downArrow ? Math.min(filteredCategories.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
55928
+ const nextCategory = filteredCategories[nextIndex] ?? null;
55929
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55930
+ ...prev,
55931
+ selectedCategory: nextCategory
55932
+ }) : prev);
55933
+ }
55934
+ } else if (key.backspace || key.delete) {
55935
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55936
+ ...prev,
55937
+ categoryQuery: prev.categoryQuery.slice(0, -1)
55938
+ }) : prev);
55939
+ } else if (input && !key.ctrl && !key.meta && !key.tab) {
55940
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55941
+ ...prev,
55942
+ categoryQuery: prev.categoryQuery + input
55943
+ }) : prev);
55944
+ }
55945
+ } else {
55946
+ if (key.escape) {
55947
+ if (widgetPicker.widgetQuery.length > 0) {
55948
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55949
+ ...prev,
55950
+ widgetQuery: ""
55951
+ }) : prev);
55952
+ } else {
55953
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55954
+ ...prev,
55955
+ level: "category"
55956
+ }) : prev);
55957
+ }
55958
+ } else if (key.return) {
55959
+ if (selectedEntry) {
55960
+ applyWidgetPickerSelection(selectedEntry.type);
55961
+ }
55962
+ } else if (key.upArrow || key.downArrow) {
55963
+ if (filteredWidgets.length === 0) {
55964
+ return;
55965
+ }
55966
+ let currentIndex = filteredWidgets.findIndex((entry) => entry.type === widgetPicker.selectedType);
55967
+ if (currentIndex === -1) {
55968
+ currentIndex = 0;
55969
+ }
55970
+ const nextIndex = key.downArrow ? Math.min(filteredWidgets.length - 1, currentIndex + 1) : Math.max(0, currentIndex - 1);
55971
+ const nextType = filteredWidgets[nextIndex]?.type ?? null;
55972
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55973
+ ...prev,
55974
+ selectedType: nextType
55975
+ }) : prev);
55976
+ } else if (key.backspace || key.delete) {
55977
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55978
+ ...prev,
55979
+ widgetQuery: prev.widgetQuery.slice(0, -1)
55980
+ }) : prev);
55981
+ } else if (input && !key.ctrl && !key.meta && !key.tab) {
55982
+ setWidgetPicker((prev) => prev ? normalizePickerState({
55983
+ ...prev,
55984
+ widgetQuery: prev.widgetQuery + input
55985
+ }) : prev);
55986
+ }
55987
+ }
55988
+ return;
55989
+ }
55549
55990
  if (moveMode) {
55550
55991
  if (key.upArrow && selectedIndex > 0) {
55551
55992
  const newWidgets = [...widgets];
@@ -55569,69 +56010,20 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55569
56010
  setMoveMode(false);
55570
56011
  }
55571
56012
  } else {
55572
- if (key.upArrow) {
56013
+ if (key.upArrow && widgets.length > 0) {
55573
56014
  setSelectedIndex(Math.max(0, selectedIndex - 1));
55574
- } else if (key.downArrow) {
56015
+ } else if (key.downArrow && widgets.length > 0) {
55575
56016
  setSelectedIndex(Math.min(widgets.length - 1, selectedIndex + 1));
55576
56017
  } else if (key.leftArrow && widgets.length > 0) {
55577
- const types = getAllowedTypes();
55578
- const currentWidget2 = widgets[selectedIndex];
55579
- if (currentWidget2) {
55580
- const currentType = currentWidget2.type;
55581
- let currentIndex = types.indexOf(currentType);
55582
- if (currentIndex === -1) {
55583
- currentIndex = 0;
55584
- }
55585
- const prevIndex = currentIndex === 0 ? types.length - 1 : currentIndex - 1;
55586
- const newWidgets = [...widgets];
55587
- const prevType = types[prevIndex];
55588
- if (prevType) {
55589
- newWidgets[selectedIndex] = { ...currentWidget2, type: prevType };
55590
- onUpdate(newWidgets);
55591
- }
55592
- }
56018
+ openWidgetPicker("change");
55593
56019
  } else if (key.rightArrow && widgets.length > 0) {
55594
- const types = getAllowedTypes();
55595
- const currentWidget2 = widgets[selectedIndex];
55596
- if (currentWidget2) {
55597
- const currentType = currentWidget2.type;
55598
- let currentIndex = types.indexOf(currentType);
55599
- if (currentIndex === -1) {
55600
- currentIndex = 0;
55601
- }
55602
- const nextIndex = (currentIndex + 1) % types.length;
55603
- const newWidgets = [...widgets];
55604
- const nextType = types[nextIndex];
55605
- if (nextType) {
55606
- newWidgets[selectedIndex] = { ...currentWidget2, type: nextType };
55607
- onUpdate(newWidgets);
55608
- }
55609
- }
56020
+ openWidgetPicker("change");
55610
56021
  } else if (key.return && widgets.length > 0) {
55611
56022
  setMoveMode(true);
55612
56023
  } else if (input === "a") {
55613
- const insertIndex = widgets.length > 0 ? selectedIndex + 1 : 0;
55614
- const backgroundColor = getUniqueBackgroundColor(insertIndex);
55615
- const newWidget = {
55616
- id: generateGuid(),
55617
- type: getDefaultItemType(),
55618
- ...backgroundColor && { backgroundColor }
55619
- };
55620
- const newWidgets = [...widgets];
55621
- newWidgets.splice(insertIndex, 0, newWidget);
55622
- onUpdate(newWidgets);
55623
- setSelectedIndex(insertIndex);
56024
+ openWidgetPicker("add");
55624
56025
  } else if (input === "i") {
55625
- const insertIndex = selectedIndex;
55626
- const backgroundColor = getUniqueBackgroundColor(insertIndex);
55627
- const newWidget = {
55628
- id: generateGuid(),
55629
- type: getDefaultItemType(),
55630
- ...backgroundColor && { backgroundColor }
55631
- };
55632
- const newWidgets = [...widgets];
55633
- newWidgets.splice(insertIndex, 0, newWidget);
55634
- onUpdate(newWidgets);
56026
+ openWidgetPicker("insert");
55635
56027
  } else if (input === "d" && widgets.length > 0) {
55636
56028
  const newWidgets = widgets.filter((_, i) => i !== selectedIndex);
55637
56029
  onUpdate(newWidgets);
@@ -55639,8 +56031,9 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55639
56031
  setSelectedIndex(selectedIndex - 1);
55640
56032
  }
55641
56033
  } else if (input === "c") {
55642
- onUpdate([]);
55643
- setSelectedIndex(0);
56034
+ if (widgets.length > 0) {
56035
+ setShowClearConfirm(true);
56036
+ }
55644
56037
  } else if (input === " " && widgets.length > 0) {
55645
56038
  const currentWidget2 = widgets[selectedIndex];
55646
56039
  if (currentWidget2 && currentWidget2.type === "separator") {
@@ -55726,6 +56119,12 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55726
56119
  };
55727
56120
  const hasFlexSeparator = widgets.some((widget) => widget.type === "flex-separator");
55728
56121
  const widthDetectionAvailable = canDetectTerminalWidth();
56122
+ const pickerCategories = widgetPicker ? getFilteredCategories(widgetPicker.categoryQuery) : [];
56123
+ const selectedPickerCategory = widgetPicker ? widgetPicker.selectedCategory && pickerCategories.includes(widgetPicker.selectedCategory) ? widgetPicker.selectedCategory : pickerCategories[0] ?? null : null;
56124
+ const topLevelSearchEntries = widgetPicker && widgetPicker.level === "category" && widgetPicker.categoryQuery.trim().length > 0 ? filterWidgetCatalog(widgetCatalog, "All", widgetPicker.categoryQuery) : [];
56125
+ const selectedTopLevelSearchEntry = widgetPicker ? topLevelSearchEntries.find((entry) => entry.type === widgetPicker.selectedType) ?? topLevelSearchEntries[0] : null;
56126
+ const pickerEntries = widgetPicker ? filterWidgetCatalog(widgetCatalog, selectedPickerCategory ?? "All", widgetPicker.widgetQuery) : [];
56127
+ const selectedPickerEntry = widgetPicker ? pickerEntries.find((entry) => entry.type === widgetPicker.selectedType) ?? pickerEntries[0] : null;
55729
56128
  const currentWidget = widgets[selectedIndex];
55730
56129
  const isSeparator = currentWidget?.type === "separator";
55731
56130
  const isFlexSeparator = currentWidget?.type === "flex-separator";
@@ -55743,11 +56142,14 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55743
56142
  }
55744
56143
  }
55745
56144
  const canMerge = currentWidget && selectedIndex < widgets.length - 1 && !isSeparator && !isFlexSeparator;
55746
- let helpText = "↑↓ select, ←→ change type";
56145
+ const hasWidgets = widgets.length > 0;
56146
+ let helpText = hasWidgets ? "↑↓ select, ←→ open type picker" : "(a)dd via picker, (i)nsert via picker";
55747
56147
  if (isSeparator) {
55748
56148
  helpText += ", Space edit separator";
55749
56149
  }
55750
- helpText += ", Enter to move, (a)dd, (i)nsert, (d)elete, (c)lear line";
56150
+ if (hasWidgets) {
56151
+ helpText += ", Enter to move, (a)dd via picker, (i)nsert via picker, (d)elete, (c)lear line";
56152
+ }
55751
56153
  if (canToggleRaw) {
55752
56154
  helpText += ", (r)aw value";
55753
56155
  }
@@ -55756,6 +56158,7 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55756
56158
  }
55757
56159
  helpText += ", ESC back";
55758
56160
  const customKeybindsText = customKeybinds.map((kb) => kb.label).join(", ");
56161
+ const pickerActionLabel = widgetPicker?.action === "add" ? "Add Widget" : widgetPicker?.action === "insert" ? "Insert Widget" : "Change Widget Type";
55759
56162
  if (customEditorWidget?.impl.renderEditor) {
55760
56163
  return customEditorWidget.impl.renderEditor({
55761
56164
  widget: customEditorWidget.widget,
@@ -55764,6 +56167,56 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55764
56167
  action: customEditorWidget.action
55765
56168
  });
55766
56169
  }
56170
+ if (showClearConfirm) {
56171
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56172
+ flexDirection: "column",
56173
+ children: [
56174
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56175
+ bold: true,
56176
+ color: "yellow",
56177
+ children: "⚠ Confirm Clear Line"
56178
+ }, undefined, false, undefined, this),
56179
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56180
+ marginTop: 1,
56181
+ flexDirection: "column",
56182
+ children: [
56183
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56184
+ children: [
56185
+ "This will remove all widgets from Line",
56186
+ " ",
56187
+ lineNumber,
56188
+ "."
56189
+ ]
56190
+ }, undefined, true, undefined, this),
56191
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56192
+ color: "red",
56193
+ children: "This action cannot be undone!"
56194
+ }, undefined, false, undefined, this)
56195
+ ]
56196
+ }, undefined, true, undefined, this),
56197
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56198
+ marginTop: 2,
56199
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56200
+ children: "Continue?"
56201
+ }, undefined, false, undefined, this)
56202
+ }, undefined, false, undefined, this),
56203
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56204
+ marginTop: 1,
56205
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(ConfirmDialog, {
56206
+ inline: true,
56207
+ onConfirm: () => {
56208
+ onUpdate([]);
56209
+ setSelectedIndex(0);
56210
+ setShowClearConfirm(false);
56211
+ },
56212
+ onCancel: () => {
56213
+ setShowClearConfirm(false);
56214
+ }
56215
+ }, undefined, false, undefined, this)
56216
+ }, undefined, false, undefined, this)
56217
+ ]
56218
+ }, undefined, true, undefined, this);
56219
+ }
55767
56220
  return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
55768
56221
  flexDirection: "column",
55769
56222
  children: [
@@ -55782,6 +56235,10 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55782
56235
  color: "blue",
55783
56236
  children: "[MOVE MODE]"
55784
56237
  }, undefined, false, undefined, this),
56238
+ widgetPicker && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56239
+ color: "cyan",
56240
+ children: `[${pickerActionLabel.toUpperCase()}]`
56241
+ }, undefined, false, undefined, this),
55785
56242
  (settings.powerline.enabled || Boolean(settings.defaultSeparator)) && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
55786
56243
  marginLeft: 2,
55787
56244
  children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
@@ -55802,6 +56259,57 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55802
56259
  dimColor: true,
55803
56260
  children: "↑↓ to move widget, ESC or Enter to exit move mode"
55804
56261
  }, undefined, false, undefined, this)
56262
+ }, undefined, false, undefined, this) : widgetPicker ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56263
+ flexDirection: "column",
56264
+ children: widgetPicker.level === "category" ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
56265
+ children: [
56266
+ widgetPicker.categoryQuery.trim().length > 0 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56267
+ dimColor: true,
56268
+ children: "↑↓ select widget match, Enter apply, ESC clear/cancel"
56269
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56270
+ dimColor: true,
56271
+ children: "↑↓ select category, type to search all widgets, Enter continue, ESC cancel"
56272
+ }, undefined, false, undefined, this),
56273
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56274
+ children: [
56275
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56276
+ dimColor: true,
56277
+ children: "Search: "
56278
+ }, undefined, false, undefined, this),
56279
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56280
+ color: "cyan",
56281
+ children: widgetPicker.categoryQuery || "(none)"
56282
+ }, undefined, false, undefined, this)
56283
+ ]
56284
+ }, undefined, true, undefined, this)
56285
+ ]
56286
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
56287
+ children: [
56288
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56289
+ dimColor: true,
56290
+ children: "↑↓ select widget, type to search widgets, Enter apply, ESC back"
56291
+ }, undefined, false, undefined, this),
56292
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56293
+ children: [
56294
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56295
+ dimColor: true,
56296
+ children: [
56297
+ "Category:",
56298
+ " ",
56299
+ selectedPickerCategory ?? "(none)",
56300
+ " ",
56301
+ "| Search:",
56302
+ " "
56303
+ ]
56304
+ }, undefined, true, undefined, this),
56305
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56306
+ color: "cyan",
56307
+ children: widgetPicker.widgetQuery || "(none)"
56308
+ }, undefined, false, undefined, this)
56309
+ ]
56310
+ }, undefined, true, undefined, this)
56311
+ ]
56312
+ }, undefined, true, undefined, this)
55805
56313
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
55806
56314
  flexDirection: "column",
55807
56315
  children: [
@@ -55828,7 +56336,114 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55828
56336
  }, undefined, false, undefined, this)
55829
56337
  ]
55830
56338
  }, undefined, true, undefined, this),
55831
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56339
+ widgetPicker && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56340
+ marginTop: 1,
56341
+ flexDirection: "column",
56342
+ children: widgetPicker.level === "category" ? widgetPicker.categoryQuery.trim().length > 0 ? topLevelSearchEntries.length === 0 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56343
+ dimColor: true,
56344
+ children: "No widgets match the search."
56345
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
56346
+ children: [
56347
+ topLevelSearchEntries.map((entry, index) => {
56348
+ const isSelected = entry.type === selectedTopLevelSearchEntry?.type;
56349
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56350
+ flexDirection: "row",
56351
+ flexWrap: "nowrap",
56352
+ children: [
56353
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56354
+ width: 3,
56355
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56356
+ color: isSelected ? "green" : undefined,
56357
+ children: isSelected ? "▶ " : " "
56358
+ }, undefined, false, undefined, this)
56359
+ }, undefined, false, undefined, this),
56360
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56361
+ color: isSelected ? "green" : undefined,
56362
+ children: `${index + 1}. ${entry.displayName}`
56363
+ }, undefined, false, undefined, this)
56364
+ ]
56365
+ }, entry.type, true, undefined, this);
56366
+ }),
56367
+ selectedTopLevelSearchEntry && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56368
+ marginTop: 1,
56369
+ paddingLeft: 2,
56370
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56371
+ dimColor: true,
56372
+ children: selectedTopLevelSearchEntry.description
56373
+ }, undefined, false, undefined, this)
56374
+ }, undefined, false, undefined, this)
56375
+ ]
56376
+ }, undefined, true, undefined, this) : pickerCategories.length === 0 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56377
+ dimColor: true,
56378
+ children: "No categories available."
56379
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
56380
+ children: [
56381
+ pickerCategories.map((category, index) => {
56382
+ const isSelected = category === selectedPickerCategory;
56383
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56384
+ flexDirection: "row",
56385
+ flexWrap: "nowrap",
56386
+ children: [
56387
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56388
+ width: 3,
56389
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56390
+ color: isSelected ? "green" : undefined,
56391
+ children: isSelected ? "▶ " : " "
56392
+ }, undefined, false, undefined, this)
56393
+ }, undefined, false, undefined, this),
56394
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56395
+ color: isSelected ? "green" : undefined,
56396
+ children: `${index + 1}. ${category}`
56397
+ }, undefined, false, undefined, this)
56398
+ ]
56399
+ }, category, true, undefined, this);
56400
+ }),
56401
+ selectedPickerCategory === "All" && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56402
+ marginTop: 1,
56403
+ paddingLeft: 2,
56404
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56405
+ dimColor: true,
56406
+ children: "Search across all widget categories."
56407
+ }, undefined, false, undefined, this)
56408
+ }, undefined, false, undefined, this)
56409
+ ]
56410
+ }, undefined, true, undefined, this) : pickerEntries.length === 0 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56411
+ dimColor: true,
56412
+ children: "No widgets match the current category/search."
56413
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
56414
+ children: [
56415
+ pickerEntries.map((entry, index) => {
56416
+ const isSelected = entry.type === selectedPickerEntry?.type;
56417
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56418
+ flexDirection: "row",
56419
+ flexWrap: "nowrap",
56420
+ children: [
56421
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56422
+ width: 3,
56423
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56424
+ color: isSelected ? "green" : undefined,
56425
+ children: isSelected ? "▶ " : " "
56426
+ }, undefined, false, undefined, this)
56427
+ }, undefined, false, undefined, this),
56428
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56429
+ color: isSelected ? "green" : undefined,
56430
+ children: `${index + 1}. ${entry.displayName}`
56431
+ }, undefined, false, undefined, this)
56432
+ ]
56433
+ }, entry.type, true, undefined, this);
56434
+ }),
56435
+ selectedPickerEntry && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
56436
+ marginTop: 1,
56437
+ paddingLeft: 2,
56438
+ children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
56439
+ dimColor: true,
56440
+ children: selectedPickerEntry.description
56441
+ }, undefined, false, undefined, this)
56442
+ }, undefined, false, undefined, this)
56443
+ ]
56444
+ }, undefined, true, undefined, this)
56445
+ }, undefined, false, undefined, this),
56446
+ !widgetPicker && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
55832
56447
  marginTop: 1,
55833
56448
  flexDirection: "column",
55834
56449
  children: widgets.length === 0 ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
@@ -56395,7 +57010,7 @@ var PowerlineSeparatorEditor = ({
56395
57010
  } else if (key.backspace && cursorPos > 0) {
56396
57011
  setHexInput(hexInput.slice(0, cursorPos - 1) + hexInput.slice(cursorPos));
56397
57012
  setCursorPos(cursorPos - 1);
56398
- } else if (input && /[0-9a-fA-F]/.test(input) && hexInput.length < 4) {
57013
+ } else if (shouldInsertInput(input, key) && /[0-9a-fA-F]/.test(input) && hexInput.length < 4) {
56399
57014
  setHexInput(hexInput.slice(0, cursorPos) + input.toUpperCase() + hexInput.slice(cursorPos));
56400
57015
  setCursorPos(cursorPos + 1);
56401
57016
  }
@@ -57671,7 +58286,7 @@ var TerminalWidthMenu = ({ settings, onUpdate, onBack }) => {
57671
58286
  } else if (key.backspace) {
57672
58287
  setThresholdInput(thresholdInput.slice(0, -1));
57673
58288
  setValidationError(null);
57674
- } else if (key.delete) {} else if (input && /\d/.test(input)) {
58289
+ } else if (key.delete) {} else if (shouldInsertInput(input, key) && /\d/.test(input)) {
57675
58290
  const newValue = thresholdInput + input;
57676
58291
  if (newValue.length <= 2) {
57677
58292
  setThresholdInput(newValue);
@@ -58220,7 +58835,7 @@ var StatusJSONSchema = exports_external.looseObject({
58220
58835
  });
58221
58836
 
58222
58837
  // src/utils/jsonl.ts
58223
- import * as fs6 from "fs";
58838
+ import * as fs7 from "fs";
58224
58839
  import path6 from "node:path";
58225
58840
 
58226
58841
  // node_modules/tinyglobby/dist/index.mjs
@@ -58355,12 +58970,12 @@ function build$3(options) {
58355
58970
  return options.group ? groupFiles : empty;
58356
58971
  }
58357
58972
  var resolveSymlinksAsync = function(path5, state, callback$1) {
58358
- const { queue, fs: fs6, options: { suppressErrors } } = state;
58973
+ const { queue, fs: fs7, options: { suppressErrors } } = state;
58359
58974
  queue.enqueue();
58360
- fs6.realpath(path5, (error43, resolvedPath) => {
58975
+ fs7.realpath(path5, (error43, resolvedPath) => {
58361
58976
  if (error43)
58362
58977
  return queue.dequeue(suppressErrors ? null : error43, state);
58363
- fs6.stat(resolvedPath, (error$1, stat) => {
58978
+ fs7.stat(resolvedPath, (error$1, stat) => {
58364
58979
  if (error$1)
58365
58980
  return queue.dequeue(suppressErrors ? null : error$1, state);
58366
58981
  if (stat.isDirectory() && isRecursive(path5, resolvedPath, state))
@@ -58371,11 +58986,11 @@ var resolveSymlinksAsync = function(path5, state, callback$1) {
58371
58986
  });
58372
58987
  };
58373
58988
  var resolveSymlinks = function(path5, state, callback$1) {
58374
- const { queue, fs: fs6, options: { suppressErrors } } = state;
58989
+ const { queue, fs: fs7, options: { suppressErrors } } = state;
58375
58990
  queue.enqueue();
58376
58991
  try {
58377
- const resolvedPath = fs6.realpathSync(path5);
58378
- const stat = fs6.statSync(resolvedPath);
58992
+ const resolvedPath = fs7.realpathSync(path5);
58993
+ const stat = fs7.statSync(resolvedPath);
58379
58994
  if (stat.isDirectory() && isRecursive(path5, resolvedPath, state))
58380
58995
  return;
58381
58996
  callback$1(stat, resolvedPath);
@@ -58458,23 +59073,23 @@ var walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
58458
59073
  state.queue.enqueue();
58459
59074
  if (currentDepth < 0)
58460
59075
  return state.queue.dequeue(null, state);
58461
- const { fs: fs6 } = state;
59076
+ const { fs: fs7 } = state;
58462
59077
  state.visited.push(crawlPath);
58463
59078
  state.counts.directories++;
58464
- fs6.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
59079
+ fs7.readdir(crawlPath || ".", readdirOpts, (error43, entries = []) => {
58465
59080
  callback$1(entries, directoryPath, currentDepth);
58466
59081
  state.queue.dequeue(state.options.suppressErrors ? null : error43, state);
58467
59082
  });
58468
59083
  };
58469
59084
  var walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
58470
- const { fs: fs6 } = state;
59085
+ const { fs: fs7 } = state;
58471
59086
  if (currentDepth < 0)
58472
59087
  return;
58473
59088
  state.visited.push(crawlPath);
58474
59089
  state.counts.directories++;
58475
59090
  let entries = [];
58476
59091
  try {
58477
- entries = fs6.readdirSync(crawlPath || ".", readdirOpts);
59092
+ entries = fs7.readdirSync(crawlPath || ".", readdirOpts);
58478
59093
  } catch (e) {
58479
59094
  if (!state.options.suppressErrors)
58480
59095
  throw e;
@@ -59009,12 +59624,12 @@ function globSync(patternsOrOptions, options) {
59009
59624
 
59010
59625
  // src/utils/jsonl.ts
59011
59626
  import { promisify } from "util";
59012
- var readFile4 = promisify(fs6.readFile);
59013
- var readFileSync4 = fs6.readFileSync;
59014
- var statSync4 = fs6.statSync;
59627
+ var readFile4 = promisify(fs7.readFile);
59628
+ var readFileSync5 = fs7.readFileSync;
59629
+ var statSync4 = fs7.statSync;
59015
59630
  async function getSessionDuration(transcriptPath) {
59016
59631
  try {
59017
- if (!fs6.existsSync(transcriptPath)) {
59632
+ if (!fs7.existsSync(transcriptPath)) {
59018
59633
  return null;
59019
59634
  }
59020
59635
  const content = await readFile4(transcriptPath, "utf-8");
@@ -59066,7 +59681,7 @@ async function getSessionDuration(transcriptPath) {
59066
59681
  }
59067
59682
  async function getTokenMetrics(transcriptPath) {
59068
59683
  try {
59069
- if (!fs6.existsSync(transcriptPath)) {
59684
+ if (!fs7.existsSync(transcriptPath)) {
59070
59685
  return { inputTokens: 0, outputTokens: 0, cachedTokens: 0, totalTokens: 0, contextLength: 0 };
59071
59686
  }
59072
59687
  const content = await readFile4(transcriptPath, "utf-8");
@@ -59213,7 +59828,7 @@ function findMostRecentBlockStartTime(rootDir, sessionDurationHours = 5) {
59213
59828
  function getAllTimestampsFromFile(filePath) {
59214
59829
  const timestamps = [];
59215
59830
  try {
59216
- const content = readFileSync4(filePath, "utf-8");
59831
+ const content = readFileSync5(filePath, "utf-8");
59217
59832
  const lines = content.trim().split(`
59218
59833
  `).filter((line) => line.length > 0);
59219
59834
  for (const line of lines) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "2.0.25",
3
+ "version": "2.0.26",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",