copilot-statusline 0.1.14 → 0.1.15

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
@@ -265,6 +265,7 @@ Copilot CLI spawns your status line command on every state change, passing sessi
265
265
  | Tokens Input | `tokens-input` | Total input tokens |
266
266
  | Tokens Output | `tokens-output` | Total output tokens |
267
267
  | Tokens Cached | `tokens-cached` | Total cached tokens (read + write) |
268
+ | Tokens Reasoning | `tokens-reasoning` | Total reasoning (thinking) tokens consumed |
268
269
  | Tokens Total | `tokens-total` | Total tokens |
269
270
  | Last Call Input | `last-call-input` | Input tokens from most recent API call |
270
271
  | Last Call Output | `last-call-output` | Output tokens from most recent API call |
@@ -274,11 +275,11 @@ Copilot CLI spawns your status line command on every state change, passing sessi
274
275
  ### Context
275
276
  | Widget | Type | Description |
276
277
  |--------|------|-------------|
277
- | Context Length | `context-length` | Context window size |
278
- | Context % | `context-percentage` | Percentage of context window used or remaining |
278
+ | Context Length | `context-length` | Current context length in tokens (live, from `current_context_tokens`) |
279
+ | Context Window | `context-window` | Model's context window size (max tokens, from `displayed_context_limit ?? context_window_size`) |
279
280
  | Context % | `context-percentage` | Live context % from Copilot (`current_context_used_percentage`) |
280
- | Context Bar | `context-bar` | Visual progress bar for context usage |
281
- | Remaining Tokens | `remaining-tokens` | Absolute remaining context tokens |
281
+ | Context Bar | `context-bar` | Visual progress bar for live context usage |
282
+ | Remaining Tokens | `remaining-tokens` | Live remaining tokens (`displayed_context_limit − current_context_tokens`) |
282
283
 
283
284
  ### Git
284
285
  | Widget | Type | Description |
@@ -289,8 +290,12 @@ Copilot CLI spawns your status line command on every state change, passing sessi
289
290
  | Git Deletions | `git-deletions` | Uncommitted deletions only |
290
291
  | Git Status | `git-status` | Staged/unstaged/untracked/conflicts indicators |
291
292
  | Git Staged | `git-staged` | Staged changes indicator |
293
+ | Git Staged Files | `git-staged-files` | Count of staged files (`S:3`, raw: `3`) |
292
294
  | Git Unstaged | `git-unstaged` | Unstaged changes indicator |
295
+ | Git Unstaged Files | `git-unstaged-files` | Count of unstaged tracked files (`M:2`, raw: `2`) |
293
296
  | Git Untracked | `git-untracked` | Untracked files indicator |
297
+ | Git Untracked Files | `git-untracked-files` | Count of untracked files (`?:1`, raw: `1`) |
298
+ | Git Clean Status | `git-clean-status` | Working tree clean/dirty status (`✓`/`✗`, raw: `clean`/`dirty`) |
294
299
  | Git Conflicts | `git-conflicts` | Merge conflict count |
295
300
  | Git Ahead/Behind | `git-ahead-behind` | Commits ahead/behind upstream |
296
301
  | Git SHA | `git-sha` | Short commit hash |
@@ -303,6 +308,8 @@ Copilot CLI spawns your status line command on every state change, passing sessi
303
308
  | Git Upstream Repo | `git-upstream-repo` | Upstream remote repo name |
304
309
  | Git Upstream Owner/Repo | `git-upstream-owner-repo` | Upstream `owner/repo` |
305
310
  | Git Is Fork | `git-is-fork` | Fork detection indicator |
311
+ | Git Worktree | `git-worktree` | Current git worktree name (probes `git rev-parse --git-dir`) |
312
+ | Git Worktree Mode | `git-worktree-mode` | `⎇` indicator when current dir is a linked worktree |
306
313
 
307
314
  ### System
308
315
  | Widget | Type | Description |
@@ -339,7 +346,8 @@ These widgets are exclusive to copilot-statusline and not available in ccstatusl
339
346
  | Premium Rate | `premium-rate` | Burn rate in requests/minute |
340
347
  | Last Call Input | `last-call-input` | Input tokens from the most recent API call |
341
348
  | Last Call Output | `last-call-output` | Output tokens from the most recent API call |
342
- | Remaining Tokens | `remaining-tokens` | Absolute remaining context window tokens |
349
+ | Remaining Tokens | `remaining-tokens` | Live remaining tokens (`displayed_context_limit current_context_tokens`) |
350
+ | Tokens Reasoning | `tokens-reasoning` | Total reasoning (thinking) tokens consumed |
343
351
  | Cache Read Tokens | `cache-read-tokens` | Total cache read tokens |
344
352
  | Cache Write Tokens | `cache-write-tokens` | Total cache write tokens |
345
353
 
@@ -368,7 +376,8 @@ Widget-specific shortcuts:
368
376
  | Git widgets | `h` | Toggle hide `no git` output |
369
377
  | Git Branch | `l` | Toggle GitHub link |
370
378
  | Context % widgets | `u` | Toggle used/remaining display |
371
- | Context Bar | `p` | Cycle bar style (short/full) |
379
+ | Context % widgets | `p` | Cycle numeric/short bar display |
380
+ | Context Bar | `p` | Cycle bar style (medium/full/short/short-only) |
372
381
  | Current Working Dir | `h` | Toggle `~` home abbreviation |
373
382
  | Current Working Dir | `s` | Edit segment limit |
374
383
  | Current Working Dir | `f` | Toggle fish-style path |
@@ -620,4 +629,4 @@ This project includes substantial portions of code from [ccstatusline](https://g
620
629
  [![npm downloads](https://img.shields.io/npm/dm/copilot-statusline.svg)](https://www.npmjs.com/package/copilot-statusline)
621
630
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
622
631
 
623
- </div>
632
+ </div>
@@ -52913,7 +52913,7 @@ import { execSync as execSync3 } from "child_process";
52913
52913
  import * as fs5 from "fs";
52914
52914
  import * as path4 from "path";
52915
52915
  var __dirname = "/Users/ts/workspace/active/statusline/copilot_statusline/src/utils";
52916
- var PACKAGE_VERSION = "0.1.14";
52916
+ var PACKAGE_VERSION = "0.1.15";
52917
52917
  function getPackageVersion() {
52918
52918
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
52919
52919
  return PACKAGE_VERSION;
@@ -54411,6 +54411,64 @@ function handleContextInverseAction(action, item) {
54411
54411
  return toggleMetadataFlag(item, INVERSE_KEY);
54412
54412
  }
54413
54413
 
54414
+ // src/widgets/shared/context-slider.ts
54415
+ var SLIDER_WIDTH = 10;
54416
+ var SLIDER_TOGGLE_KEYBIND = { key: "p", label: "(p)rogress toggle", action: "toggle-slider" };
54417
+ function makeSliderBar(percent, width = SLIDER_WIDTH) {
54418
+ const clamped = Math.max(0, Math.min(100, percent));
54419
+ const filled = Math.round(clamped / 100 * width);
54420
+ return "▓".repeat(filled) + "░".repeat(width - filled);
54421
+ }
54422
+ function getContextSliderMode(item) {
54423
+ const mode = item.metadata?.display;
54424
+ if (mode === "slider" || mode === "slider-only") {
54425
+ return mode;
54426
+ }
54427
+ return "none";
54428
+ }
54429
+ function cycleContextSliderMode(item) {
54430
+ const currentMode = getContextSliderMode(item);
54431
+ const nextMode = currentMode === "none" ? "slider" : currentMode === "slider" ? "slider-only" : "none";
54432
+ if (nextMode === "none") {
54433
+ const nextMetadata = { ...item.metadata ?? {} };
54434
+ delete nextMetadata.display;
54435
+ return {
54436
+ ...item,
54437
+ metadata: Object.keys(nextMetadata).length > 0 ? nextMetadata : undefined
54438
+ };
54439
+ }
54440
+ return {
54441
+ ...item,
54442
+ metadata: {
54443
+ ...item.metadata ?? {},
54444
+ display: nextMode
54445
+ }
54446
+ };
54447
+ }
54448
+ function renderContextSlider(mode, percent) {
54449
+ if (mode === "none") {
54450
+ return null;
54451
+ }
54452
+ const slider = makeSliderBar(percent);
54453
+ if (mode === "slider") {
54454
+ return `${slider} ${percent.toFixed(1)}%`;
54455
+ }
54456
+ return slider;
54457
+ }
54458
+ function getContextSliderModifierText(item) {
54459
+ const mode = getContextSliderMode(item);
54460
+ if (mode === "slider") {
54461
+ return "(short bar)";
54462
+ }
54463
+ if (mode === "slider-only") {
54464
+ return "(short bar only)";
54465
+ }
54466
+ return;
54467
+ }
54468
+ function getContextSliderKeybinds() {
54469
+ return [SLIDER_TOGGLE_KEYBIND];
54470
+ }
54471
+
54414
54472
  // src/widgets/ContextPercentage.ts
54415
54473
  class ContextPercentageWidget {
54416
54474
  getDefaultColor() {
@@ -54426,31 +54484,44 @@ class ContextPercentageWidget {
54426
54484
  return "Context";
54427
54485
  }
54428
54486
  getEditorDisplay(item) {
54487
+ const modifiers = [
54488
+ getContextInverseModifierText(item),
54489
+ getContextSliderModifierText(item)
54490
+ ].filter((modifier) => modifier !== undefined);
54429
54491
  return {
54430
54492
  displayText: this.getDisplayName(),
54431
- modifierText: getContextInverseModifierText(item)
54493
+ modifierText: modifiers.length > 0 ? `(${modifiers.map((modifier) => modifier.replace(/^\(|\)$/g, "")).join(", ")})` : undefined
54432
54494
  };
54433
54495
  }
54434
54496
  handleEditorAction(action, item) {
54497
+ if (action === "toggle-slider") {
54498
+ return cycleContextSliderMode(item);
54499
+ }
54435
54500
  return handleContextInverseAction(action, item);
54436
54501
  }
54437
54502
  render(item, context, settings) {
54438
54503
  const isInverse = isContextInverse(item);
54504
+ const label = isInverse ? "Ctx Left: " : "Ctx Used: ";
54505
+ const sliderMode = getContextSliderMode(item);
54506
+ const formatPercentage = (displayPercentage) => {
54507
+ const sliderDisplay = renderContextSlider(sliderMode, displayPercentage);
54508
+ return formatRawOrLabeledValue(item, label, sliderDisplay ?? `${displayPercentage.toFixed(1)}%`);
54509
+ };
54439
54510
  if (context.isPreview) {
54440
- const previewValue = isInverse ? "90.7%" : "9.3%";
54441
- return formatRawOrLabeledValue(item, "Ctx: ", previewValue);
54511
+ return formatPercentage(isInverse ? 90.7 : 9.3);
54442
54512
  }
54443
54513
  const metrics = getContextWindowMetrics(context.data);
54444
54514
  if (metrics.currentContextUsedPercentage !== null) {
54445
54515
  const pct = metrics.currentContextUsedPercentage;
54446
54516
  const displayPercentage = isInverse ? 100 - pct : pct;
54447
- return formatRawOrLabeledValue(item, "Ctx: ", `${displayPercentage.toFixed(1)}%`);
54517
+ return formatPercentage(displayPercentage);
54448
54518
  }
54449
54519
  return null;
54450
54520
  }
54451
54521
  getCustomKeybinds() {
54452
54522
  return [
54453
- { key: "u", label: "(u)sed/remaining", action: "toggle-inverse" }
54523
+ { key: "u", label: "(u)sed/remaining", action: "toggle-inverse" },
54524
+ ...getContextSliderKeybinds()
54454
54525
  ];
54455
54526
  }
54456
54527
  supportsRawValue() {
@@ -54475,7 +54546,14 @@ function makeUsageProgressBar(percent, width = 15, powerlineMode = false) {
54475
54546
 
54476
54547
  // src/widgets/ContextBar.ts
54477
54548
  function getDisplayMode(item) {
54478
- return item.metadata?.display === "progress" ? "progress" : "progress-short";
54549
+ const mode = item.metadata?.display;
54550
+ if (mode === "progress" || mode === "slider" || mode === "slider-only") {
54551
+ return mode;
54552
+ }
54553
+ return "progress-short";
54554
+ }
54555
+ function isSliderMode(mode) {
54556
+ return mode === "slider" || mode === "slider-only";
54479
54557
  }
54480
54558
 
54481
54559
  class ContextBarWidget {
@@ -54495,7 +54573,11 @@ class ContextBarWidget {
54495
54573
  const mode = getDisplayMode(item);
54496
54574
  const modifiers = [];
54497
54575
  if (mode === "progress-short") {
54576
+ modifiers.push("medium bar");
54577
+ } else if (mode === "slider") {
54498
54578
  modifiers.push("short bar");
54579
+ } else if (mode === "slider-only") {
54580
+ modifiers.push("short bar only");
54499
54581
  }
54500
54582
  return {
54501
54583
  displayText: this.getDisplayName(),
@@ -54507,7 +54589,7 @@ class ContextBarWidget {
54507
54589
  return null;
54508
54590
  }
54509
54591
  const currentMode = getDisplayMode(item);
54510
- const nextMode = currentMode === "progress-short" ? "progress" : "progress-short";
54592
+ const nextMode = currentMode === "progress-short" ? "progress" : currentMode === "progress" ? "slider" : currentMode === "slider" ? "slider-only" : "progress-short";
54511
54593
  return {
54512
54594
  ...item,
54513
54595
  metadata: {
@@ -54521,6 +54603,11 @@ class ContextBarWidget {
54521
54603
  const barWidth = displayMode === "progress" ? 32 : 16;
54522
54604
  const powerlineMode = settings.powerline.enabled;
54523
54605
  if (context.isPreview) {
54606
+ if (isSliderMode(displayMode)) {
54607
+ const slider = renderContextSlider("slider-only", 25);
54608
+ const sliderDisplay = displayMode === "slider" ? `${slider} 50k/200k (25%)` : slider;
54609
+ return item.rawValue ? sliderDisplay : `Context: ${sliderDisplay}`;
54610
+ }
54524
54611
  const previewDisplay = `${makeUsageProgressBar(25, barWidth, powerlineMode)} 50k/200k (25%)`;
54525
54612
  return item.rawValue ? previewDisplay : `Context: ${previewDisplay}`;
54526
54613
  }
@@ -54534,6 +54621,11 @@ class ContextBarWidget {
54534
54621
  const clampedPercent = Math.max(0, Math.min(100, upstreamPct));
54535
54622
  const usedK = Math.round(used / 1000);
54536
54623
  const totalK = Math.round(total / 1000);
54624
+ if (isSliderMode(displayMode)) {
54625
+ const slider = renderContextSlider("slider-only", clampedPercent);
54626
+ const sliderDisplay = displayMode === "slider" ? `${slider} ${usedK}k/${totalK}k (${Math.round(clampedPercent)}%)` : slider;
54627
+ return item.rawValue ? sliderDisplay : `Context: ${sliderDisplay}`;
54628
+ }
54537
54629
  const display = `${makeUsageProgressBar(clampedPercent, barWidth, powerlineMode)} ${usedK}k/${totalK}k (${Math.round(clampedPercent)}%)`;
54538
54630
  return item.rawValue ? display : `Context: ${display}`;
54539
54631
  }
@@ -54945,6 +55037,9 @@ function getGitChangeCounts(context) {
54945
55037
  deletions: unstagedCounts.deletions + stagedCounts.deletions
54946
55038
  };
54947
55039
  }
55040
+ function hasRenameOrCopyStatus(line) {
55041
+ return line.startsWith("R") || line.startsWith("C") || line[1] === "R" || line[1] === "C";
55042
+ }
54948
55043
  function getGitStatus(context) {
54949
55044
  const output = runGit("--no-optional-locks status --porcelain -z", context);
54950
55045
  if (!output) {
@@ -54969,13 +55064,39 @@ function getGitStatus(context) {
54969
55064
  untracked = true;
54970
55065
  if (staged && unstaged && untracked && conflicts)
54971
55066
  break;
54972
- const indexStatus = line[0];
54973
- if (indexStatus === "R" || indexStatus === "C") {
55067
+ if (hasRenameOrCopyStatus(line)) {
54974
55068
  index += 1;
54975
55069
  }
54976
55070
  }
54977
55071
  return { staged, unstaged, untracked, conflicts };
54978
55072
  }
55073
+ function getGitFileStatusCounts(context) {
55074
+ const output = runGit("--no-optional-locks status --porcelain -z", context);
55075
+ if (!output) {
55076
+ return { staged: 0, unstaged: 0, untracked: 0 };
55077
+ }
55078
+ let staged = 0;
55079
+ let unstaged = 0;
55080
+ let untracked = 0;
55081
+ const entries = output.split("\x00");
55082
+ for (let index = 0;index < entries.length; index += 1) {
55083
+ const line = entries[index];
55084
+ if (typeof line !== "string" || line.length < 2)
55085
+ continue;
55086
+ if (line.startsWith("??")) {
55087
+ untracked += 1;
55088
+ } else {
55089
+ if (/^[MADRCTU]/.test(line))
55090
+ staged += 1;
55091
+ if (/^.[MADRCTU]/.test(line))
55092
+ unstaged += 1;
55093
+ }
55094
+ if (hasRenameOrCopyStatus(line)) {
55095
+ index += 1;
55096
+ }
55097
+ }
55098
+ return { staged, unstaged, untracked };
55099
+ }
54979
55100
  function getGitAheadBehind(context) {
54980
55101
  const output = runGit("rev-list --left-right --count HEAD...@{upstream}", context);
54981
55102
  if (!output)
@@ -55894,6 +56015,55 @@ class GitStagedWidget {
55894
56015
  return true;
55895
56016
  }
55896
56017
  }
56018
+ // src/widgets/GitStagedFiles.ts
56019
+ class GitStagedFilesWidget {
56020
+ getDefaultColor() {
56021
+ return "green";
56022
+ }
56023
+ getDescription() {
56024
+ return "Shows count of staged files";
56025
+ }
56026
+ getDisplayName() {
56027
+ return "Git Staged Files";
56028
+ }
56029
+ getCategory() {
56030
+ return "Git";
56031
+ }
56032
+ getEditorDisplay(item) {
56033
+ return {
56034
+ displayText: this.getDisplayName(),
56035
+ modifierText: getHideNoGitModifierText(item)
56036
+ };
56037
+ }
56038
+ handleEditorAction(action, item) {
56039
+ return handleToggleNoGitAction(action, item);
56040
+ }
56041
+ render(item, context, _settings) {
56042
+ const hideNoGit = isHideNoGitEnabled(item);
56043
+ if (context.isPreview) {
56044
+ return item.rawValue ? "3" : "S:3";
56045
+ }
56046
+ if (!isInsideGitWorkTree(context)) {
56047
+ return hideNoGit ? null : "(no git)";
56048
+ }
56049
+ const count = getGitFileStatusCounts(context).staged;
56050
+ return item.rawValue ? count.toString() : `S:${count}`;
56051
+ }
56052
+ getCustomKeybinds() {
56053
+ return getHideNoGitKeybinds();
56054
+ }
56055
+ getNumericValue(context, _item) {
56056
+ if (!isInsideGitWorkTree(context))
56057
+ return null;
56058
+ return getGitFileStatusCounts(context).staged;
56059
+ }
56060
+ supportsRawValue() {
56061
+ return true;
56062
+ }
56063
+ supportsColors(_item) {
56064
+ return true;
56065
+ }
56066
+ }
55897
56067
  // src/widgets/GitUnstaged.ts
55898
56068
  var DEFAULT_SYMBOL2 = "*";
55899
56069
 
@@ -55953,6 +56123,55 @@ class GitUnstagedWidget {
55953
56123
  return true;
55954
56124
  }
55955
56125
  }
56126
+ // src/widgets/GitUnstagedFiles.ts
56127
+ class GitUnstagedFilesWidget {
56128
+ getDefaultColor() {
56129
+ return "yellow";
56130
+ }
56131
+ getDescription() {
56132
+ return "Shows count of unstaged tracked files";
56133
+ }
56134
+ getDisplayName() {
56135
+ return "Git Unstaged Files";
56136
+ }
56137
+ getCategory() {
56138
+ return "Git";
56139
+ }
56140
+ getEditorDisplay(item) {
56141
+ return {
56142
+ displayText: this.getDisplayName(),
56143
+ modifierText: getHideNoGitModifierText(item)
56144
+ };
56145
+ }
56146
+ handleEditorAction(action, item) {
56147
+ return handleToggleNoGitAction(action, item);
56148
+ }
56149
+ render(item, context, _settings) {
56150
+ const hideNoGit = isHideNoGitEnabled(item);
56151
+ if (context.isPreview) {
56152
+ return item.rawValue ? "2" : "M:2";
56153
+ }
56154
+ if (!isInsideGitWorkTree(context)) {
56155
+ return hideNoGit ? null : "(no git)";
56156
+ }
56157
+ const count = getGitFileStatusCounts(context).unstaged;
56158
+ return item.rawValue ? count.toString() : `M:${count}`;
56159
+ }
56160
+ getCustomKeybinds() {
56161
+ return getHideNoGitKeybinds();
56162
+ }
56163
+ getNumericValue(context, _item) {
56164
+ if (!isInsideGitWorkTree(context))
56165
+ return null;
56166
+ return getGitFileStatusCounts(context).unstaged;
56167
+ }
56168
+ supportsRawValue() {
56169
+ return true;
56170
+ }
56171
+ supportsColors(_item) {
56172
+ return true;
56173
+ }
56174
+ }
55956
56175
  // src/widgets/GitUntracked.ts
55957
56176
  var DEFAULT_SYMBOL3 = "?";
55958
56177
 
@@ -56012,6 +56231,103 @@ class GitUntrackedWidget {
56012
56231
  return true;
56013
56232
  }
56014
56233
  }
56234
+ // src/widgets/GitUntrackedFiles.ts
56235
+ class GitUntrackedFilesWidget {
56236
+ getDefaultColor() {
56237
+ return "red";
56238
+ }
56239
+ getDescription() {
56240
+ return "Shows count of untracked files";
56241
+ }
56242
+ getDisplayName() {
56243
+ return "Git Untracked Files";
56244
+ }
56245
+ getCategory() {
56246
+ return "Git";
56247
+ }
56248
+ getEditorDisplay(item) {
56249
+ return {
56250
+ displayText: this.getDisplayName(),
56251
+ modifierText: getHideNoGitModifierText(item)
56252
+ };
56253
+ }
56254
+ handleEditorAction(action, item) {
56255
+ return handleToggleNoGitAction(action, item);
56256
+ }
56257
+ render(item, context, _settings) {
56258
+ const hideNoGit = isHideNoGitEnabled(item);
56259
+ if (context.isPreview) {
56260
+ return item.rawValue ? "1" : "?:1";
56261
+ }
56262
+ if (!isInsideGitWorkTree(context)) {
56263
+ return hideNoGit ? null : "(no git)";
56264
+ }
56265
+ const count = getGitFileStatusCounts(context).untracked;
56266
+ return item.rawValue ? count.toString() : `?:${count}`;
56267
+ }
56268
+ getCustomKeybinds() {
56269
+ return getHideNoGitKeybinds();
56270
+ }
56271
+ getNumericValue(context, _item) {
56272
+ if (!isInsideGitWorkTree(context))
56273
+ return null;
56274
+ return getGitFileStatusCounts(context).untracked;
56275
+ }
56276
+ supportsRawValue() {
56277
+ return true;
56278
+ }
56279
+ supportsColors(_item) {
56280
+ return true;
56281
+ }
56282
+ }
56283
+ // src/widgets/GitCleanStatus.ts
56284
+ class GitCleanStatusWidget {
56285
+ getDefaultColor() {
56286
+ return "green";
56287
+ }
56288
+ getDescription() {
56289
+ return "Shows ✓ when the working tree is clean and ✗ when it is dirty";
56290
+ }
56291
+ getDisplayName() {
56292
+ return "Git Clean Status";
56293
+ }
56294
+ getCategory() {
56295
+ return "Git";
56296
+ }
56297
+ getEditorDisplay(item) {
56298
+ return {
56299
+ displayText: this.getDisplayName(),
56300
+ modifierText: getHideNoGitModifierText(item)
56301
+ };
56302
+ }
56303
+ handleEditorAction(action, item) {
56304
+ return handleToggleNoGitAction(action, item);
56305
+ }
56306
+ render(item, context, _settings) {
56307
+ const hideNoGit = isHideNoGitEnabled(item);
56308
+ if (context.isPreview) {
56309
+ return item.rawValue ? "clean" : "✓";
56310
+ }
56311
+ if (!isInsideGitWorkTree(context)) {
56312
+ return hideNoGit ? null : "(no git)";
56313
+ }
56314
+ const status = getGitStatus(context);
56315
+ const clean = !status.staged && !status.unstaged && !status.untracked && !status.conflicts;
56316
+ if (item.rawValue) {
56317
+ return clean ? "clean" : "dirty";
56318
+ }
56319
+ return clean ? "✓" : "✗";
56320
+ }
56321
+ getCustomKeybinds() {
56322
+ return getHideNoGitKeybinds();
56323
+ }
56324
+ supportsRawValue() {
56325
+ return true;
56326
+ }
56327
+ supportsColors(_item) {
56328
+ return true;
56329
+ }
56330
+ }
56015
56331
  // src/widgets/GitAheadBehind.ts
56016
56332
  class GitAheadBehindWidget {
56017
56333
  getDefaultColor() {
@@ -58157,8 +58473,12 @@ var WIDGET_MANIFEST = [
58157
58473
  { type: "git-pr", create: () => new GitPrWidget },
58158
58474
  { type: "git-status", create: () => new GitStatusWidget },
58159
58475
  { type: "git-staged", create: () => new GitStagedWidget },
58476
+ { type: "git-staged-files", create: () => new GitStagedFilesWidget },
58160
58477
  { type: "git-unstaged", create: () => new GitUnstagedWidget },
58478
+ { type: "git-unstaged-files", create: () => new GitUnstagedFilesWidget },
58161
58479
  { type: "git-untracked", create: () => new GitUntrackedWidget },
58480
+ { type: "git-untracked-files", create: () => new GitUntrackedFilesWidget },
58481
+ { type: "git-clean-status", create: () => new GitCleanStatusWidget },
58162
58482
  { type: "git-ahead-behind", create: () => new GitAheadBehindWidget },
58163
58483
  { type: "git-conflicts", create: () => new GitConflictsWidget },
58164
58484
  { type: "git-sha", create: () => new GitShaWidget },
@@ -62429,17 +62749,18 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
62429
62749
  if (!widget)
62430
62750
  continue;
62431
62751
  if (widget.type === "separator") {
62432
- let hasContentBefore = false;
62752
+ let previousWidgetRenderedContent = false;
62433
62753
  for (let j = i - 1;j >= 0; j--) {
62434
62754
  const prevWidget = widgets[j];
62435
- if (prevWidget && prevWidget.type !== "separator" && prevWidget.type !== "flex-separator") {
62436
- if (preRenderedWidgets[j]?.content) {
62437
- hasContentBefore = true;
62438
- break;
62439
- }
62755
+ if (prevWidget?.type === "separator" || prevWidget?.type === "flex-separator") {
62756
+ continue;
62757
+ }
62758
+ if (prevWidget) {
62759
+ previousWidgetRenderedContent = Boolean(preRenderedWidgets[j]?.content);
62760
+ break;
62440
62761
  }
62441
62762
  }
62442
- if (!hasContentBefore)
62763
+ if (!previousWidgetRenderedContent)
62443
62764
  continue;
62444
62765
  const sepChar = widget.character ?? (settings.defaultSeparator ?? "|");
62445
62766
  const formattedSep = formatSeparator(sepChar);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copilot-statusline",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "A customizable status line formatter for GitHub Copilot CLI — based on ccstatusline",
5
5
  "module": "src/copilot-statusline.ts",
6
6
  "type": "module",