claude-scope 0.5.5 → 0.6.0

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.
Files changed (2) hide show
  1. package/dist/claude-scope.cjs +104 -178
  2. package/package.json +1 -1
@@ -248,14 +248,16 @@ var NativeGit = class {
248
248
  const { stdout } = await execFileAsync("git", args, {
249
249
  cwd: this.cwd
250
250
  });
251
+ const fileMatch = stdout.match(/(\d+)\s+file(s?)\s+changed/);
251
252
  const insertionMatch = stdout.match(/(\d+)\s+insertion/);
252
253
  const deletionMatch = stdout.match(/(\d+)\s+deletion/);
254
+ const fileCount = fileMatch ? parseInt(fileMatch[1], 10) : 0;
253
255
  const insertions = insertionMatch ? parseInt(insertionMatch[1], 10) : 0;
254
256
  const deletions = deletionMatch ? parseInt(deletionMatch[1], 10) : 0;
255
257
  const files = insertions > 0 || deletions > 0 ? [{ file: "(total)", insertions, deletions }] : [];
256
- return { files };
258
+ return { fileCount, files };
257
259
  } catch {
258
- return { files: [] };
260
+ return { fileCount: 0, files: [] };
259
261
  }
260
262
  }
261
263
  async latestTag() {
@@ -281,15 +283,6 @@ function withLabel(prefix, value) {
281
283
  function withIndicator(value) {
282
284
  return `\u25CF ${value}`;
283
285
  }
284
- function withFancy(value) {
285
- return `\xAB${value}\xBB`;
286
- }
287
- function withBrackets(value) {
288
- return `[${value}]`;
289
- }
290
- function withAngleBrackets(value) {
291
- return `\u27E8${value}\u27E9`;
292
- }
293
286
  function progressBar(percent, width = 10) {
294
287
  const clamped = Math.max(0, Math.min(100, percent));
295
288
  const filled = Math.round(clamped / 100 * width);
@@ -299,26 +292,75 @@ function progressBar(percent, width = 10) {
299
292
 
300
293
  // src/widgets/git/styles.ts
301
294
  var gitStyles = {
295
+ minimal: (data) => {
296
+ return data.branch;
297
+ },
302
298
  balanced: (data) => {
299
+ if (data.changes && data.changes.files > 0) {
300
+ const parts = [];
301
+ if (data.changes.insertions > 0) parts.push(`+${data.changes.insertions}`);
302
+ if (data.changes.deletions > 0) parts.push(`-${data.changes.deletions}`);
303
+ if (parts.length > 0) {
304
+ return `${data.branch} [${parts.join(" ")}]`;
305
+ }
306
+ }
303
307
  return data.branch;
304
308
  },
305
309
  compact: (data) => {
310
+ if (data.changes && data.changes.files > 0) {
311
+ const parts = [];
312
+ if (data.changes.insertions > 0) parts.push(`+${data.changes.insertions}`);
313
+ if (data.changes.deletions > 0) parts.push(`-${data.changes.deletions}`);
314
+ if (parts.length > 0) {
315
+ return `${data.branch} ${parts.join("/")}`;
316
+ }
317
+ }
306
318
  return data.branch;
307
319
  },
308
320
  playful: (data) => {
321
+ if (data.changes && data.changes.files > 0) {
322
+ const parts = [];
323
+ if (data.changes.insertions > 0) parts.push(`\u2B06${data.changes.insertions}`);
324
+ if (data.changes.deletions > 0) parts.push(`\u2B07${data.changes.deletions}`);
325
+ if (parts.length > 0) {
326
+ return `\u{1F500} ${data.branch} ${parts.join(" ")}`;
327
+ }
328
+ }
309
329
  return `\u{1F500} ${data.branch}`;
310
330
  },
311
331
  verbose: (data) => {
332
+ if (data.changes && data.changes.files > 0) {
333
+ const parts = [];
334
+ if (data.changes.insertions > 0) parts.push(`+${data.changes.insertions} insertions`);
335
+ if (data.changes.deletions > 0) parts.push(`-${data.changes.deletions} deletions`);
336
+ if (parts.length > 0) {
337
+ return `branch: ${data.branch} [${parts.join(", ")}]`;
338
+ }
339
+ }
312
340
  return `branch: ${data.branch} (HEAD)`;
313
341
  },
314
342
  labeled: (data) => {
315
- return withLabel("Git", data.branch);
343
+ if (data.changes && data.changes.files > 0) {
344
+ const parts = [];
345
+ if (data.changes.insertions > 0) parts.push(`+${data.changes.insertions}`);
346
+ if (data.changes.deletions > 0) parts.push(`-${data.changes.deletions}`);
347
+ if (parts.length > 0) {
348
+ const changes = `${data.changes.files} files: ${parts.join("/")}`;
349
+ return `Git: ${data.branch} [${changes}]`;
350
+ }
351
+ }
352
+ return `Git: ${data.branch}`;
316
353
  },
317
354
  indicator: (data) => {
355
+ if (data.changes && data.changes.files > 0) {
356
+ const parts = [];
357
+ if (data.changes.insertions > 0) parts.push(`+${data.changes.insertions}`);
358
+ if (data.changes.deletions > 0) parts.push(`-${data.changes.deletions}`);
359
+ if (parts.length > 0) {
360
+ return `\u25CF ${data.branch} [${parts.join(" ")}]`;
361
+ }
362
+ }
318
363
  return withIndicator(data.branch);
319
- },
320
- fancy: (data) => {
321
- return withBrackets(data.branch);
322
364
  }
323
365
  };
324
366
 
@@ -365,7 +407,23 @@ var GitWidget = class {
365
407
  if (!branch) {
366
408
  return null;
367
409
  }
368
- const renderData = { branch };
410
+ let changes;
411
+ try {
412
+ const diffSummary = await this.git.diffSummary();
413
+ if (diffSummary.fileCount > 0) {
414
+ let insertions = 0;
415
+ let deletions = 0;
416
+ for (const file of diffSummary.files) {
417
+ insertions += file.insertions || 0;
418
+ deletions += file.deletions || 0;
419
+ }
420
+ if (insertions > 0 || deletions > 0) {
421
+ changes = { files: diffSummary.fileCount, insertions, deletions };
422
+ }
423
+ }
424
+ } catch {
425
+ }
426
+ const renderData = { branch, changes };
369
427
  return this.styleFn(renderData);
370
428
  } catch {
371
429
  return null;
@@ -405,9 +463,6 @@ var gitTagStyles = {
405
463
  },
406
464
  indicator: (data) => {
407
465
  return withIndicator(data.tag || "\u2014");
408
- },
409
- fancy: (data) => {
410
- return withAngleBrackets(data.tag || "\u2014");
411
466
  }
412
467
  };
413
468
 
@@ -494,9 +549,6 @@ var modelStyles = {
494
549
  },
495
550
  indicator: (data) => {
496
551
  return withIndicator(getShortName(data.displayName));
497
- },
498
- fancy: (data) => {
499
- return withBrackets(getShortName(data.displayName));
500
552
  }
501
553
  };
502
554
 
@@ -662,9 +714,6 @@ var contextStyles = {
662
714
  },
663
715
  indicator: (data) => {
664
716
  return `\u25CF ${data.percent}%`;
665
- },
666
- fancy: (data) => {
667
- return `\u27E8${data.percent}%\u27E9`;
668
717
  }
669
718
  };
670
719
 
@@ -733,9 +782,6 @@ var costStyles = {
733
782
  },
734
783
  indicator: (data) => {
735
784
  return withIndicator(formatCostUSD(data.costUsd));
736
- },
737
- fancy: (data) => {
738
- return withFancy(formatCostUSD(data.costUsd));
739
785
  }
740
786
  };
741
787
 
@@ -805,12 +851,6 @@ function createLinesStyles(colors) {
805
851
  const removedStr = colorize(`-${data.removed}`, colors.removed);
806
852
  const lines = `${addedStr}/${removedStr}`;
807
853
  return withIndicator(lines);
808
- },
809
- fancy: (data) => {
810
- const addedStr = colorize(`+${data.added}`, colors.added);
811
- const removedStr = colorize(`-${data.removed}`, colors.removed);
812
- const lines = `${addedStr}|${removedStr}`;
813
- return withAngleBrackets(lines);
814
854
  }
815
855
  };
816
856
  }
@@ -880,9 +920,6 @@ var durationStyles = {
880
920
  },
881
921
  indicator: (data) => {
882
922
  return withIndicator(formatDuration(data.durationMs));
883
- },
884
- fancy: (data) => {
885
- return withAngleBrackets(formatDuration(data.durationMs));
886
923
  }
887
924
  };
888
925
 
@@ -913,146 +950,6 @@ var DurationWidget = class extends StdinDataWidget {
913
950
  }
914
951
  };
915
952
 
916
- // src/widgets/git-changes/styles.ts
917
- var gitChangesStyles = {
918
- balanced: (data) => {
919
- const parts = [];
920
- if (data.insertions > 0) parts.push(`+${data.insertions}`);
921
- if (data.deletions > 0) parts.push(`-${data.deletions}`);
922
- return parts.join(" ");
923
- },
924
- compact: (data) => {
925
- const parts = [];
926
- if (data.insertions > 0) parts.push(`+${data.insertions}`);
927
- if (data.deletions > 0) parts.push(`-${data.deletions}`);
928
- return parts.join("/");
929
- },
930
- playful: (data) => {
931
- const parts = [];
932
- if (data.insertions > 0) parts.push(`\u2B06${data.insertions}`);
933
- if (data.deletions > 0) parts.push(`\u2B07${data.deletions}`);
934
- return parts.join(" ");
935
- },
936
- verbose: (data) => {
937
- const parts = [];
938
- if (data.insertions > 0) parts.push(`+${data.insertions} insertions`);
939
- if (data.deletions > 0) parts.push(`-${data.deletions} deletions`);
940
- return parts.join(", ");
941
- },
942
- technical: (data) => {
943
- const parts = [];
944
- if (data.insertions > 0) parts.push(`${data.insertions}`);
945
- if (data.deletions > 0) parts.push(`${data.deletions}`);
946
- return parts.join("/");
947
- },
948
- symbolic: (data) => {
949
- const parts = [];
950
- if (data.insertions > 0) parts.push(`\u25B2${data.insertions}`);
951
- if (data.deletions > 0) parts.push(`\u25BC${data.deletions}`);
952
- return parts.join(" ");
953
- },
954
- labeled: (data) => {
955
- const parts = [];
956
- if (data.insertions > 0) parts.push(`+${data.insertions}`);
957
- if (data.deletions > 0) parts.push(`-${data.deletions}`);
958
- const changes = parts.join(" ");
959
- return withLabel("Diff", changes);
960
- },
961
- indicator: (data) => {
962
- const parts = [];
963
- if (data.insertions > 0) parts.push(`+${data.insertions}`);
964
- if (data.deletions > 0) parts.push(`-${data.deletions}`);
965
- const changes = parts.join(" ");
966
- return withIndicator(changes);
967
- },
968
- fancy: (data) => {
969
- const parts = [];
970
- if (data.insertions > 0) parts.push(`+${data.insertions}`);
971
- if (data.deletions > 0) parts.push(`-${data.deletions}`);
972
- const changes = parts.join("|");
973
- return withAngleBrackets(changes);
974
- }
975
- };
976
-
977
- // src/widgets/git/git-changes-widget.ts
978
- var GitChangesWidget = class {
979
- id = "git-changes";
980
- metadata = createWidgetMetadata(
981
- "Git Changes",
982
- "Displays git diff statistics",
983
- "1.0.0",
984
- "claude-scope",
985
- 0
986
- // First line
987
- );
988
- gitFactory;
989
- git = null;
990
- enabled = true;
991
- cwd = null;
992
- styleFn = gitChangesStyles.balanced;
993
- /**
994
- * @param gitFactory - Optional factory function for creating IGit instances
995
- * If not provided, uses default createGit (production)
996
- * Tests can inject MockGit factory here
997
- */
998
- constructor(gitFactory) {
999
- this.gitFactory = gitFactory || createGit;
1000
- }
1001
- setStyle(style = "balanced") {
1002
- const fn = gitChangesStyles[style];
1003
- if (fn) {
1004
- this.styleFn = fn;
1005
- }
1006
- }
1007
- async initialize(context) {
1008
- this.enabled = context.config?.enabled !== false;
1009
- }
1010
- async update(data) {
1011
- if (data.cwd !== this.cwd) {
1012
- this.cwd = data.cwd;
1013
- this.git = this.gitFactory(data.cwd);
1014
- }
1015
- }
1016
- async render(context) {
1017
- if (!this.enabled || !this.git || !this.cwd) {
1018
- return null;
1019
- }
1020
- let changes;
1021
- try {
1022
- const summary = await this.git.diffSummary(["--shortstat"]);
1023
- let insertions = 0;
1024
- let deletions = 0;
1025
- if (summary.files && summary.files.length > 0) {
1026
- for (const file of summary.files) {
1027
- if (typeof file.insertions === "number") {
1028
- insertions += file.insertions;
1029
- }
1030
- if (typeof file.deletions === "number") {
1031
- deletions += file.deletions;
1032
- }
1033
- }
1034
- }
1035
- if (insertions === 0 && deletions === 0) {
1036
- return null;
1037
- }
1038
- changes = { insertions, deletions };
1039
- } catch {
1040
- return null;
1041
- }
1042
- if (!changes) return null;
1043
- if (changes.insertions === 0 && changes.deletions === 0) {
1044
- return null;
1045
- }
1046
- const renderData = changes;
1047
- return this.styleFn(renderData);
1048
- }
1049
- isEnabled() {
1050
- return this.enabled;
1051
- }
1052
- async cleanup() {
1053
- }
1054
- };
1055
-
1056
953
  // src/providers/config-provider.ts
1057
954
  var fs = __toESM(require("fs/promises"), 1);
1058
955
  var path = __toESM(require("path"), 1);
@@ -1343,6 +1240,16 @@ var SUIT_SYMBOLS = {
1343
1240
  diamonds: "\u2666",
1344
1241
  clubs: "\u2663"
1345
1242
  };
1243
+ var EMOJI_SYMBOLS = {
1244
+ spades: "\u2660\uFE0F",
1245
+ // ♠️
1246
+ hearts: "\u2665\uFE0F",
1247
+ // ♥️
1248
+ diamonds: "\u2666\uFE0F",
1249
+ // ♦️
1250
+ clubs: "\u2663\uFE0F"
1251
+ // ♣️
1252
+ };
1346
1253
  function isRedSuit(suit) {
1347
1254
  return suit === "hearts" || suit === "diamonds";
1348
1255
  }
@@ -1382,6 +1289,9 @@ function getRankValue(rank) {
1382
1289
  function formatCard(card) {
1383
1290
  return `${card.rank}${SUIT_SYMBOLS[card.suit]}`;
1384
1291
  }
1292
+ function formatCardEmoji(card) {
1293
+ return `${card.rank}${EMOJI_SYMBOLS[card.suit]}`;
1294
+ }
1385
1295
 
1386
1296
  // src/widgets/poker/deck.ts
1387
1297
  var ALL_SUITS = [Suit.Spades, Suit.Hearts, Suit.Diamonds, Suit.Clubs];
@@ -1791,6 +1701,14 @@ function formatCardTextCompact(card) {
1791
1701
  const rankSymbol = rankSymbols[rank] ?? rank;
1792
1702
  return `${rankSymbol}${card.suit}`;
1793
1703
  }
1704
+ function formatCardEmojiByParticipation(cardData, isParticipating) {
1705
+ const cardText = formatCardEmoji(cardData.card);
1706
+ if (isParticipating) {
1707
+ return `${bold}(${cardText})${reset} `;
1708
+ } else {
1709
+ return `${cardText} `;
1710
+ }
1711
+ }
1794
1712
  function formatHandResult(handResult) {
1795
1713
  if (!handResult) {
1796
1714
  return "\u2014";
@@ -1832,6 +1750,15 @@ var pokerStyles = {
1832
1750
  const boardStr = boardCards.map((bc, idx) => formatCardCompact(bc, participatingSet.has(idx + 2))).join("");
1833
1751
  const abbreviation = getHandAbbreviation(handResult);
1834
1752
  return `${handStr}| ${boardStr}\u2192 ${abbreviation}`;
1753
+ },
1754
+ emoji: (data) => {
1755
+ const { holeCards, boardCards, handResult } = data;
1756
+ const participatingSet = new Set(handResult?.participatingIndices || []);
1757
+ const handStr = holeCards.map((hc, idx) => formatCardEmojiByParticipation(hc, participatingSet.has(idx))).join("");
1758
+ const boardStr = boardCards.map((bc, idx) => formatCardEmojiByParticipation(bc, participatingSet.has(idx + 2))).join("");
1759
+ const handLabel = colorize("Hand:", lightGray);
1760
+ const boardLabel = colorize("Board:", lightGray);
1761
+ return `${handLabel} ${handStr}| ${boardLabel} ${boardStr}\u2192 ${formatHandResult(handResult)}`;
1835
1762
  }
1836
1763
  };
1837
1764
 
@@ -2158,7 +2085,6 @@ async function main() {
2158
2085
  await registry.register(new DurationWidget());
2159
2086
  await registry.register(new GitWidget());
2160
2087
  await registry.register(new GitTagWidget());
2161
- await registry.register(new GitChangesWidget());
2162
2088
  await registry.register(new ConfigCountWidget());
2163
2089
  await registry.register(new PokerWidget());
2164
2090
  await registry.register(new EmptyLineWidget());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-scope",
3
- "version": "0.5.5",
3
+ "version": "0.6.0",
4
4
  "description": "Claude Code plugin for session status and analytics",
5
5
  "license": "MIT",
6
6
  "type": "module",