ccstatusline 2.0.10 → 2.0.11

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
@@ -44,6 +44,10 @@
44
44
 
45
45
  ## 🆕 Recent Updates
46
46
 
47
+ ### v2.0.11 - Unlimited Status Lines
48
+
49
+ - **🚀 No Line Limit** - Configure as many status lines as you need - the 3-line limitation has been removed
50
+
47
51
  ### v2.0.10 - Git Updates
48
52
 
49
53
  - **🌳 Git Worktree widget** - Shows the active worktree name when working with git worktrees
@@ -99,7 +103,7 @@
99
103
  - **📊 Real-time Metrics** - Display model name, git branch, token usage, session duration, block timer, and more
100
104
  - **🎨 Fully Customizable** - Choose what to display and customize colors for each element
101
105
  - **⚡ Powerline Support** - Beautiful Powerline-style rendering with arrow separators, caps, and custom fonts
102
- - **📐 Multi-line Support** - Configure up to 3 independent status lines
106
+ - **📐 Multi-line Support** - Configure multiple independent status lines
103
107
  - **🖥️ Interactive TUI** - Built-in configuration interface using React/Ink
104
108
  - **⚙️ Global Options** - Apply consistent formatting across all widgets (padding, separators, bold, background)
105
109
  - **🚀 Cross-platform** - Works seamlessly with both Bun and Node.js
@@ -123,7 +127,7 @@ bunx ccstatusline@latest
123
127
  ### Configure ccstatusline
124
128
 
125
129
  The interactive configuration tool provides a terminal UI where you can:
126
- - Configure up to 3 separate status lines
130
+ - Configure multiple separate status lines
127
131
  - Add/remove/reorder status line widgets
128
132
  - Customize colors for each widget
129
133
  - Configure flex separator behavior
@@ -31861,6 +31861,333 @@ var require_jsx_dev_runtime = __commonJS((exports, module) => {
31861
31861
  }
31862
31862
  });
31863
31863
 
31864
+ // node_modules/pluralize/pluralize.js
31865
+ var require_pluralize = __commonJS((exports, module) => {
31866
+ (function(root, pluralize) {
31867
+ if (typeof exports === "object" && typeof module === "object") {
31868
+ module.exports = pluralize();
31869
+ } else if (typeof define === "function" && define.amd) {
31870
+ define(function() {
31871
+ return pluralize();
31872
+ });
31873
+ } else {
31874
+ root.pluralize = pluralize();
31875
+ }
31876
+ })(exports, function() {
31877
+ var pluralRules = [];
31878
+ var singularRules = [];
31879
+ var uncountables = {};
31880
+ var irregularPlurals = {};
31881
+ var irregularSingles = {};
31882
+ function sanitizeRule(rule) {
31883
+ if (typeof rule === "string") {
31884
+ return new RegExp("^" + rule + "$", "i");
31885
+ }
31886
+ return rule;
31887
+ }
31888
+ function restoreCase(word, token) {
31889
+ if (word === token)
31890
+ return token;
31891
+ if (word === word.toLowerCase())
31892
+ return token.toLowerCase();
31893
+ if (word === word.toUpperCase())
31894
+ return token.toUpperCase();
31895
+ if (word[0] === word[0].toUpperCase()) {
31896
+ return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
31897
+ }
31898
+ return token.toLowerCase();
31899
+ }
31900
+ function interpolate(str, args) {
31901
+ return str.replace(/\$(\d{1,2})/g, function(match, index) {
31902
+ return args[index] || "";
31903
+ });
31904
+ }
31905
+ function replace(word, rule) {
31906
+ return word.replace(rule[0], function(match, index) {
31907
+ var result = interpolate(rule[1], arguments);
31908
+ if (match === "") {
31909
+ return restoreCase(word[index - 1], result);
31910
+ }
31911
+ return restoreCase(match, result);
31912
+ });
31913
+ }
31914
+ function sanitizeWord(token, word, rules) {
31915
+ if (!token.length || uncountables.hasOwnProperty(token)) {
31916
+ return word;
31917
+ }
31918
+ var len = rules.length;
31919
+ while (len--) {
31920
+ var rule = rules[len];
31921
+ if (rule[0].test(word))
31922
+ return replace(word, rule);
31923
+ }
31924
+ return word;
31925
+ }
31926
+ function replaceWord(replaceMap, keepMap, rules) {
31927
+ return function(word) {
31928
+ var token = word.toLowerCase();
31929
+ if (keepMap.hasOwnProperty(token)) {
31930
+ return restoreCase(word, token);
31931
+ }
31932
+ if (replaceMap.hasOwnProperty(token)) {
31933
+ return restoreCase(word, replaceMap[token]);
31934
+ }
31935
+ return sanitizeWord(token, word, rules);
31936
+ };
31937
+ }
31938
+ function checkWord(replaceMap, keepMap, rules, bool) {
31939
+ return function(word) {
31940
+ var token = word.toLowerCase();
31941
+ if (keepMap.hasOwnProperty(token))
31942
+ return true;
31943
+ if (replaceMap.hasOwnProperty(token))
31944
+ return false;
31945
+ return sanitizeWord(token, token, rules) === token;
31946
+ };
31947
+ }
31948
+ function pluralize(word, count, inclusive) {
31949
+ var pluralized = count === 1 ? pluralize.singular(word) : pluralize.plural(word);
31950
+ return (inclusive ? count + " " : "") + pluralized;
31951
+ }
31952
+ pluralize.plural = replaceWord(irregularSingles, irregularPlurals, pluralRules);
31953
+ pluralize.isPlural = checkWord(irregularSingles, irregularPlurals, pluralRules);
31954
+ pluralize.singular = replaceWord(irregularPlurals, irregularSingles, singularRules);
31955
+ pluralize.isSingular = checkWord(irregularPlurals, irregularSingles, singularRules);
31956
+ pluralize.addPluralRule = function(rule, replacement) {
31957
+ pluralRules.push([sanitizeRule(rule), replacement]);
31958
+ };
31959
+ pluralize.addSingularRule = function(rule, replacement) {
31960
+ singularRules.push([sanitizeRule(rule), replacement]);
31961
+ };
31962
+ pluralize.addUncountableRule = function(word) {
31963
+ if (typeof word === "string") {
31964
+ uncountables[word.toLowerCase()] = true;
31965
+ return;
31966
+ }
31967
+ pluralize.addPluralRule(word, "$0");
31968
+ pluralize.addSingularRule(word, "$0");
31969
+ };
31970
+ pluralize.addIrregularRule = function(single, plural) {
31971
+ plural = plural.toLowerCase();
31972
+ single = single.toLowerCase();
31973
+ irregularSingles[single] = plural;
31974
+ irregularPlurals[plural] = single;
31975
+ };
31976
+ [
31977
+ ["I", "we"],
31978
+ ["me", "us"],
31979
+ ["he", "they"],
31980
+ ["she", "they"],
31981
+ ["them", "them"],
31982
+ ["myself", "ourselves"],
31983
+ ["yourself", "yourselves"],
31984
+ ["itself", "themselves"],
31985
+ ["herself", "themselves"],
31986
+ ["himself", "themselves"],
31987
+ ["themself", "themselves"],
31988
+ ["is", "are"],
31989
+ ["was", "were"],
31990
+ ["has", "have"],
31991
+ ["this", "these"],
31992
+ ["that", "those"],
31993
+ ["echo", "echoes"],
31994
+ ["dingo", "dingoes"],
31995
+ ["volcano", "volcanoes"],
31996
+ ["tornado", "tornadoes"],
31997
+ ["torpedo", "torpedoes"],
31998
+ ["genus", "genera"],
31999
+ ["viscus", "viscera"],
32000
+ ["stigma", "stigmata"],
32001
+ ["stoma", "stomata"],
32002
+ ["dogma", "dogmata"],
32003
+ ["lemma", "lemmata"],
32004
+ ["schema", "schemata"],
32005
+ ["anathema", "anathemata"],
32006
+ ["ox", "oxen"],
32007
+ ["axe", "axes"],
32008
+ ["die", "dice"],
32009
+ ["yes", "yeses"],
32010
+ ["foot", "feet"],
32011
+ ["eave", "eaves"],
32012
+ ["goose", "geese"],
32013
+ ["tooth", "teeth"],
32014
+ ["quiz", "quizzes"],
32015
+ ["human", "humans"],
32016
+ ["proof", "proofs"],
32017
+ ["carve", "carves"],
32018
+ ["valve", "valves"],
32019
+ ["looey", "looies"],
32020
+ ["thief", "thieves"],
32021
+ ["groove", "grooves"],
32022
+ ["pickaxe", "pickaxes"],
32023
+ ["passerby", "passersby"]
32024
+ ].forEach(function(rule) {
32025
+ return pluralize.addIrregularRule(rule[0], rule[1]);
32026
+ });
32027
+ [
32028
+ [/s?$/i, "s"],
32029
+ [/[^\u0000-\u007F]$/i, "$0"],
32030
+ [/([^aeiou]ese)$/i, "$1"],
32031
+ [/(ax|test)is$/i, "$1es"],
32032
+ [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, "$1es"],
32033
+ [/(e[mn]u)s?$/i, "$1s"],
32034
+ [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, "$1"],
32035
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1i"],
32036
+ [/(alumn|alg|vertebr)(?:a|ae)$/i, "$1ae"],
32037
+ [/(seraph|cherub)(?:im)?$/i, "$1im"],
32038
+ [/(her|at|gr)o$/i, "$1oes"],
32039
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, "$1a"],
32040
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, "$1a"],
32041
+ [/sis$/i, "ses"],
32042
+ [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, "$1$2ves"],
32043
+ [/([^aeiouy]|qu)y$/i, "$1ies"],
32044
+ [/([^ch][ieo][ln])ey$/i, "$1ies"],
32045
+ [/(x|ch|ss|sh|zz)$/i, "$1es"],
32046
+ [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, "$1ices"],
32047
+ [/\b((?:tit)?m|l)(?:ice|ouse)$/i, "$1ice"],
32048
+ [/(pe)(?:rson|ople)$/i, "$1ople"],
32049
+ [/(child)(?:ren)?$/i, "$1ren"],
32050
+ [/eaux$/i, "$0"],
32051
+ [/m[ae]n$/i, "men"],
32052
+ ["thou", "you"]
32053
+ ].forEach(function(rule) {
32054
+ return pluralize.addPluralRule(rule[0], rule[1]);
32055
+ });
32056
+ [
32057
+ [/s$/i, ""],
32058
+ [/(ss)$/i, "$1"],
32059
+ [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, "$1fe"],
32060
+ [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, "$1f"],
32061
+ [/ies$/i, "y"],
32062
+ [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, "$1ie"],
32063
+ [/\b(mon|smil)ies$/i, "$1ey"],
32064
+ [/\b((?:tit)?m|l)ice$/i, "$1ouse"],
32065
+ [/(seraph|cherub)im$/i, "$1"],
32066
+ [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, "$1"],
32067
+ [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, "$1sis"],
32068
+ [/(movie|twelve|abuse|e[mn]u)s$/i, "$1"],
32069
+ [/(test)(?:is|es)$/i, "$1is"],
32070
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1us"],
32071
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, "$1um"],
32072
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, "$1on"],
32073
+ [/(alumn|alg|vertebr)ae$/i, "$1a"],
32074
+ [/(cod|mur|sil|vert|ind)ices$/i, "$1ex"],
32075
+ [/(matr|append)ices$/i, "$1ix"],
32076
+ [/(pe)(rson|ople)$/i, "$1rson"],
32077
+ [/(child)ren$/i, "$1"],
32078
+ [/(eau)x?$/i, "$1"],
32079
+ [/men$/i, "man"]
32080
+ ].forEach(function(rule) {
32081
+ return pluralize.addSingularRule(rule[0], rule[1]);
32082
+ });
32083
+ [
32084
+ "adulthood",
32085
+ "advice",
32086
+ "agenda",
32087
+ "aid",
32088
+ "aircraft",
32089
+ "alcohol",
32090
+ "ammo",
32091
+ "analytics",
32092
+ "anime",
32093
+ "athletics",
32094
+ "audio",
32095
+ "bison",
32096
+ "blood",
32097
+ "bream",
32098
+ "buffalo",
32099
+ "butter",
32100
+ "carp",
32101
+ "cash",
32102
+ "chassis",
32103
+ "chess",
32104
+ "clothing",
32105
+ "cod",
32106
+ "commerce",
32107
+ "cooperation",
32108
+ "corps",
32109
+ "debris",
32110
+ "diabetes",
32111
+ "digestion",
32112
+ "elk",
32113
+ "energy",
32114
+ "equipment",
32115
+ "excretion",
32116
+ "expertise",
32117
+ "firmware",
32118
+ "flounder",
32119
+ "fun",
32120
+ "gallows",
32121
+ "garbage",
32122
+ "graffiti",
32123
+ "hardware",
32124
+ "headquarters",
32125
+ "health",
32126
+ "herpes",
32127
+ "highjinks",
32128
+ "homework",
32129
+ "housework",
32130
+ "information",
32131
+ "jeans",
32132
+ "justice",
32133
+ "kudos",
32134
+ "labour",
32135
+ "literature",
32136
+ "machinery",
32137
+ "mackerel",
32138
+ "mail",
32139
+ "media",
32140
+ "mews",
32141
+ "moose",
32142
+ "music",
32143
+ "mud",
32144
+ "manga",
32145
+ "news",
32146
+ "only",
32147
+ "personnel",
32148
+ "pike",
32149
+ "plankton",
32150
+ "pliers",
32151
+ "police",
32152
+ "pollution",
32153
+ "premises",
32154
+ "rain",
32155
+ "research",
32156
+ "rice",
32157
+ "salmon",
32158
+ "scissors",
32159
+ "series",
32160
+ "sewage",
32161
+ "shambles",
32162
+ "shrimp",
32163
+ "software",
32164
+ "species",
32165
+ "staff",
32166
+ "swine",
32167
+ "tennis",
32168
+ "traffic",
32169
+ "transportation",
32170
+ "trout",
32171
+ "tuna",
32172
+ "wealth",
32173
+ "welfare",
32174
+ "whiting",
32175
+ "wildebeest",
32176
+ "wildlife",
32177
+ "you",
32178
+ /pok[eé]mon$/i,
32179
+ /[^aeiou]ese$/i,
32180
+ /deer$/i,
32181
+ /fish$/i,
32182
+ /measles$/i,
32183
+ /o[iu]s$/i,
32184
+ /pox$/i,
32185
+ /sheep$/i
32186
+ ].forEach(pluralize.addUncountableRule);
32187
+ return pluralize;
32188
+ });
32189
+ });
32190
+
31864
32191
  // node_modules/picomatch/lib/constants.js
31865
32192
  var require_constants3 = __commonJS((exports, module) => {
31866
32193
  var WIN_SLASH = "\\\\/";
@@ -50581,7 +50908,7 @@ var SettingsSchema_v1 = exports_external.object({
50581
50908
  });
50582
50909
  var SettingsSchema = exports_external.object({
50583
50910
  version: exports_external.number().default(CURRENT_VERSION),
50584
- lines: exports_external.array(exports_external.array(WidgetItemSchema)).min(1).max(3).default([
50911
+ lines: exports_external.array(exports_external.array(WidgetItemSchema)).min(1).default([
50585
50912
  [
50586
50913
  { id: "1", type: "model", color: "cyan" },
50587
50914
  { id: "2", type: "separator" },
@@ -50590,8 +50917,10 @@ var SettingsSchema = exports_external.object({
50590
50917
  { id: "5", type: "git-branch", color: "magenta" },
50591
50918
  { id: "6", type: "separator" },
50592
50919
  { id: "7", type: "git-changes", color: "yellow" }
50593
- ]
50594
- ]).transform((lines) => lines.slice(0, 3)),
50920
+ ],
50921
+ [],
50922
+ []
50923
+ ]),
50595
50924
  flexMode: FlexModeSchema.default("full-minus-40"),
50596
50925
  compactThreshold: exports_external.number().min(1).max(99).default(60),
50597
50926
  colorLevel: ColorLevelSchema.default(2),
@@ -51045,7 +51374,7 @@ import { execSync as execSync3 } from "child_process";
51045
51374
  import * as fs5 from "fs";
51046
51375
  import * as path4 from "path";
51047
51376
  var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
51048
- var PACKAGE_VERSION = "2.0.10";
51377
+ var PACKAGE_VERSION = "2.0.11";
51049
51378
  function getPackageVersion() {
51050
51379
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51051
51380
  return PACKAGE_VERSION;
@@ -52570,6 +52899,8 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
52570
52899
  if (!widget)
52571
52900
  continue;
52572
52901
  if (widget.type === "separator") {
52902
+ if (i > 0 && !preRenderedWidgets[i - 1]?.content)
52903
+ continue;
52573
52904
  const sepChar = widget.character ?? (settings.defaultSeparator ?? "|");
52574
52905
  const formattedSep = formatSeparator(sepChar);
52575
52906
  let separatorColor = widget.color ?? "gray";
@@ -55246,26 +55577,73 @@ var ItemsEditor = ({ widgets, onUpdate, onBack, lineNumber, settings }) => {
55246
55577
  }, undefined, true, undefined, this);
55247
55578
  };
55248
55579
  // src/tui/components/LineSelector.tsx
55580
+ var import_pluralize = __toESM(require_pluralize(), 1);
55249
55581
  var import_react37 = __toESM(require_react(), 1);
55250
55582
  var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
55251
- var LineSelector = ({ lines, onSelect, onBack, initialSelection = 0, title, blockIfPowerlineActive = false, settings }) => {
55583
+ var LineSelector = ({
55584
+ lines,
55585
+ onSelect,
55586
+ onBack,
55587
+ onLinesUpdate,
55588
+ initialSelection = 0,
55589
+ title,
55590
+ blockIfPowerlineActive = false,
55591
+ settings,
55592
+ allowEditing = false
55593
+ }) => {
55252
55594
  const [selectedIndex, setSelectedIndex] = import_react37.useState(initialSelection);
55595
+ const [showDeleteDialog, setShowDeleteDialog] = import_react37.useState(false);
55596
+ const [localLines, setLocalLines] = import_react37.useState(lines);
55597
+ import_react37.useEffect(() => {
55598
+ setLocalLines(lines);
55599
+ }, [lines]);
55600
+ const selectedLine = import_react37.useMemo(() => localLines[selectedIndex], [localLines, selectedIndex]);
55601
+ const appendLine = () => {
55602
+ const newLines = [...localLines, []];
55603
+ setLocalLines(newLines);
55604
+ onLinesUpdate(newLines);
55605
+ setSelectedIndex(newLines.length - 1);
55606
+ };
55607
+ const deleteLine = (lineIndex) => {
55608
+ if (localLines.length <= 1) {
55609
+ return;
55610
+ }
55611
+ const newLines = [...localLines];
55612
+ newLines.splice(lineIndex, 1);
55613
+ setLocalLines(newLines);
55614
+ onLinesUpdate(newLines);
55615
+ };
55253
55616
  const powerlineEnabled = settings ? settings.powerline.enabled : false;
55254
55617
  const powerlineTheme = settings ? settings.powerline.theme : undefined;
55255
55618
  const isThemeManaged = blockIfPowerlineActive && powerlineEnabled && powerlineTheme && powerlineTheme !== "custom";
55256
55619
  use_input_default((input, key) => {
55620
+ if (showDeleteDialog) {
55621
+ return;
55622
+ }
55257
55623
  if (isThemeManaged) {
55258
55624
  onBack();
55259
55625
  return;
55260
55626
  }
55627
+ switch (input) {
55628
+ case "a":
55629
+ if (allowEditing) {
55630
+ appendLine();
55631
+ }
55632
+ return;
55633
+ case "d":
55634
+ if (allowEditing && localLines.length > 1) {
55635
+ setShowDeleteDialog(true);
55636
+ }
55637
+ return;
55638
+ }
55261
55639
  if (key.escape) {
55262
55640
  onBack();
55263
55641
  } else if (key.upArrow) {
55264
55642
  setSelectedIndex(Math.max(0, selectedIndex - 1));
55265
55643
  } else if (key.downArrow) {
55266
- setSelectedIndex(Math.min(3, selectedIndex + 1));
55644
+ setSelectedIndex(Math.min(localLines.length, selectedIndex + 1));
55267
55645
  } else if (key.return) {
55268
- if (selectedIndex === 3) {
55646
+ if (selectedIndex === localLines.length) {
55269
55647
  onBack();
55270
55648
  } else {
55271
55649
  onSelect(selectedIndex);
@@ -55320,69 +55698,130 @@ var LineSelector = ({ lines, onSelect, onBack, initialSelection = 0, title, bloc
55320
55698
  ]
55321
55699
  }, undefined, true, undefined, this);
55322
55700
  }
55323
- return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55324
- flexDirection: "column",
55325
- children: [
55326
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55327
- bold: true,
55328
- children: title ?? "Select Line to Edit"
55329
- }, undefined, false, undefined, this),
55330
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55331
- dimColor: true,
55332
- children: "Choose which status line to configure (up to 3 lines supported)"
55333
- }, undefined, false, undefined, this),
55334
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55335
- dimColor: true,
55336
- children: "Press ESC to go back"
55337
- }, undefined, false, undefined, this),
55338
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55339
- marginTop: 1,
55340
- flexDirection: "column",
55341
- children: [
55342
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55343
- children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55344
- color: selectedIndex === 0 ? "green" : undefined,
55345
- children: [
55346
- selectedIndex === 0 ? "▶ " : " ",
55347
- "☰ Line 1",
55348
- lines[0] && lines[0].length > 0 ? ` (${lines[0].length} widgets)` : " (empty)"
55349
- ]
55350
- }, undefined, true, undefined, this)
55351
- }, undefined, false, undefined, this),
55352
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55353
- children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55354
- color: selectedIndex === 1 ? "green" : undefined,
55355
- children: [
55356
- selectedIndex === 1 ? "▶ " : " ",
55357
- " Line 2",
55358
- lines[1] && lines[1].length > 0 ? ` (${lines[1].length} widgets)` : " (empty)"
55359
- ]
55360
- }, undefined, true, undefined, this)
55361
- }, undefined, false, undefined, this),
55362
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55363
- children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55364
- color: selectedIndex === 2 ? "green" : undefined,
55365
- children: [
55366
- selectedIndex === 2 ? "▶ " : " ",
55367
- "☰ Line 3",
55368
- lines[2] && lines[2].length > 0 ? ` (${lines[2].length} widgets)` : " (empty)"
55369
- ]
55370
- }, undefined, true, undefined, this)
55371
- }, undefined, false, undefined, this),
55372
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55373
- marginTop: 1,
55374
- children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55375
- color: selectedIndex === 3 ? "green" : undefined,
55376
- children: [
55377
- selectedIndex === 3 ? "▶ " : " ",
55378
- "← Back"
55379
- ]
55380
- }, undefined, true, undefined, this)
55701
+ if (showDeleteDialog && selectedLine) {
55702
+ const suffix = selectedLine.length > 0 ? import_pluralize.default("widget", selectedLine.length, true) : "empty";
55703
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55704
+ flexDirection: "column",
55705
+ children: [
55706
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55707
+ flexDirection: "column",
55708
+ gap: 1,
55709
+ children: [
55710
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55711
+ bold: true,
55712
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55713
+ children: [
55714
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55715
+ children: [
55716
+ "☰ Line",
55717
+ " ",
55718
+ selectedIndex + 1
55719
+ ]
55720
+ }, undefined, true, undefined, this),
55721
+ " ",
55722
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55723
+ dimColor: true,
55724
+ children: [
55725
+ "(",
55726
+ suffix,
55727
+ ")"
55728
+ ]
55729
+ }, undefined, true, undefined, this)
55730
+ ]
55731
+ }, undefined, true, undefined, this)
55732
+ }, undefined, false, undefined, this),
55733
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55734
+ bold: true,
55735
+ children: "Are you sure you want to delete line?"
55736
+ }, undefined, false, undefined, this)
55737
+ ]
55738
+ }, undefined, true, undefined, this),
55739
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55740
+ marginTop: 1,
55741
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(ConfirmDialog, {
55742
+ inline: true,
55743
+ onConfirm: () => {
55744
+ deleteLine(selectedIndex);
55745
+ setSelectedIndex(Math.max(0, selectedIndex - 1));
55746
+ setShowDeleteDialog(false);
55747
+ },
55748
+ onCancel: () => {
55749
+ setShowDeleteDialog(false);
55750
+ }
55381
55751
  }, undefined, false, undefined, this)
55382
- ]
55383
- }, undefined, true, undefined, this)
55384
- ]
55385
- }, undefined, true, undefined, this);
55752
+ }, undefined, false, undefined, this)
55753
+ ]
55754
+ }, undefined, true, undefined, this);
55755
+ }
55756
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(jsx_dev_runtime9.Fragment, {
55757
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55758
+ flexDirection: "column",
55759
+ children: [
55760
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55761
+ bold: true,
55762
+ children: title ?? "Select Line to Edit"
55763
+ }, undefined, false, undefined, this),
55764
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55765
+ dimColor: true,
55766
+ children: "Choose which status line to configure"
55767
+ }, undefined, false, undefined, this),
55768
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55769
+ dimColor: true,
55770
+ children: allowEditing ? localLines.length > 1 ? "(a) to append new line, (d) to delete line, ESC to go back" : "(a) to append new line, ESC to go back" : "ESC to go back"
55771
+ }, undefined, false, undefined, this),
55772
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55773
+ marginTop: 1,
55774
+ flexDirection: "column",
55775
+ children: [
55776
+ localLines.map((line, index) => {
55777
+ const isSelected = selectedIndex === index;
55778
+ const suffix = line.length ? import_pluralize.default("widget", line.length, true) : "empty";
55779
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55780
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55781
+ color: isSelected ? "green" : undefined,
55782
+ children: [
55783
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55784
+ children: isSelected ? "▶ " : " "
55785
+ }, undefined, false, undefined, this),
55786
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55787
+ children: [
55788
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55789
+ children: [
55790
+ "☰ Line",
55791
+ " ",
55792
+ index + 1
55793
+ ]
55794
+ }, undefined, true, undefined, this),
55795
+ " ",
55796
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55797
+ dimColor: !isSelected,
55798
+ children: [
55799
+ "(",
55800
+ suffix,
55801
+ ")"
55802
+ ]
55803
+ }, undefined, true, undefined, this)
55804
+ ]
55805
+ }, undefined, true, undefined, this)
55806
+ ]
55807
+ }, undefined, true, undefined, this)
55808
+ }, index, false, undefined, this);
55809
+ }),
55810
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
55811
+ marginTop: 1,
55812
+ children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
55813
+ color: selectedIndex === localLines.length ? "green" : undefined,
55814
+ children: [
55815
+ selectedIndex === localLines.length ? "▶ " : " ",
55816
+ "← Back"
55817
+ ]
55818
+ }, undefined, true, undefined, this)
55819
+ }, undefined, false, undefined, this)
55820
+ ]
55821
+ }, undefined, true, undefined, this)
55822
+ ]
55823
+ }, undefined, true, undefined, this)
55824
+ }, undefined, false, undefined, this);
55386
55825
  };
55387
55826
  // src/tui/components/MainMenu.tsx
55388
55827
  var import_react38 = __toESM(require_react(), 1);
@@ -57037,9 +57476,6 @@ var App2 = () => {
57037
57476
  getExistingStatusLine().then(setExistingStatusLine);
57038
57477
  loadSettings().then((loadedSettings) => {
57039
57478
  source_default.level = loadedSettings.colorLevel;
57040
- while (loadedSettings.lines.length < 3) {
57041
- loadedSettings.lines.push([]);
57042
- }
57043
57479
  setSettings(loadedSettings);
57044
57480
  setOriginalSettings(JSON.parse(JSON.stringify(loadedSettings)));
57045
57481
  });
@@ -57144,6 +57580,9 @@ var App2 = () => {
57144
57580
  newLines[lineIndex] = widgets;
57145
57581
  setSettings({ ...settings, lines: newLines });
57146
57582
  };
57583
+ const updateLines = (newLines) => {
57584
+ setSettings({ ...settings, lines: newLines });
57585
+ };
57147
57586
  const handleLineSelect = (lineIndex) => {
57148
57587
  setSelectedLine(lineIndex);
57149
57588
  setScreen("items");
@@ -57209,12 +57648,14 @@ var App2 = () => {
57209
57648
  setMenuSelections({ ...menuSelections, lines: line });
57210
57649
  handleLineSelect(line);
57211
57650
  },
57651
+ onLinesUpdate: updateLines,
57212
57652
  onBack: () => {
57213
57653
  setMenuSelections({ ...menuSelections, main: 0 });
57214
57654
  setScreen("main");
57215
57655
  },
57216
57656
  initialSelection: menuSelections.lines,
57217
- title: "Select Line to Edit Items"
57657
+ title: "Select Line to Edit Items",
57658
+ allowEditing: true
57218
57659
  }, undefined, false, undefined, this),
57219
57660
  screen === "items" && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(ItemsEditor, {
57220
57661
  widgets: settings.lines[selectedLine] ?? [],
@@ -57230,6 +57671,7 @@ var App2 = () => {
57230
57671
  }, undefined, false, undefined, this),
57231
57672
  screen === "colorLines" && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(LineSelector, {
57232
57673
  lines: settings.lines,
57674
+ onLinesUpdate: updateLines,
57233
57675
  onSelect: (line) => {
57234
57676
  setMenuSelections({ ...menuSelections, lines: line });
57235
57677
  setSelectedLine(line);
@@ -57242,7 +57684,8 @@ var App2 = () => {
57242
57684
  initialSelection: menuSelections.lines,
57243
57685
  title: "Select Line to Edit Colors",
57244
57686
  blockIfPowerlineActive: true,
57245
- settings
57687
+ settings,
57688
+ allowEditing: false
57246
57689
  }, undefined, false, undefined, this),
57247
57690
  screen === "colors" && /* @__PURE__ */ jsx_dev_runtime17.jsxDEV(ColorMenu, {
57248
57691
  widgets: settings.lines[selectedLine] ?? [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "2.0.10",
3
+ "version": "2.0.11",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",
@@ -12,9 +12,9 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "start": "bun run src/ccstatusline.ts",
15
- "statusline": "bun run src/ccstatusline.ts",
16
15
  "build": "rm -rf dist/* && bun build src/ccstatusline.ts --target=node --outfile=dist/ccstatusline.js --target-version=14",
17
16
  "postbuild": "bun run scripts/replace-version.ts",
17
+ "example": "cat scripts/payload.example.json | bun start",
18
18
  "prepublishOnly": "bun run build",
19
19
  "lint": "bun tsc --noEmit; eslint . --config eslint.config.js --max-warnings=999999 --fix",
20
20
  "test": "bun vitest"
@@ -41,7 +41,9 @@
41
41
  "typescript": "^5.9.2",
42
42
  "typescript-eslint": "^8.39.1",
43
43
  "vitest": "^3.2.4",
44
- "zod": "^4.0.17"
44
+ "zod": "^4.0.17",
45
+ "pluralize": "^8.0.0",
46
+ "@types/pluralize": "^0.0.33"
45
47
  },
46
48
  "keywords": [
47
49
  "claude",