claude-scope 0.8.5 → 0.8.7

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 +141 -780
  2. package/package.json +1 -1
@@ -38,15 +38,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
38
38
  function colorize(text, color) {
39
39
  return `${color}${text}${reset}`;
40
40
  }
41
- var reset, red, gray, lightGray, bold;
41
+ var reset, gray;
42
42
  var init_colors = __esm({
43
43
  "src/ui/utils/colors.ts"() {
44
44
  "use strict";
45
45
  reset = "\x1B[0m";
46
- red = "\x1B[31m";
47
46
  gray = "\x1B[90m";
48
- lightGray = "\x1B[37m";
49
- bold = "\x1B[1m";
50
47
  }
51
48
  });
52
49
 
@@ -1139,7 +1136,7 @@ var init_theme = __esm({
1139
1136
  });
1140
1137
 
1141
1138
  // src/constants.ts
1142
- var TIME, DEFAULTS, ANSI_COLORS, DEMO_DATA, DEFAULT_PROGRESS_BAR_WIDTH;
1139
+ var TIME, DEFAULTS, DEMO_DATA, DEFAULT_PROGRESS_BAR_WIDTH;
1143
1140
  var init_constants = __esm({
1144
1141
  "src/constants.ts"() {
1145
1142
  "use strict";
@@ -1157,16 +1154,6 @@ var init_constants = __esm({
1157
1154
  /** Default width for progress bars in characters */
1158
1155
  PROGRESS_BAR_WIDTH: 20
1159
1156
  };
1160
- ANSI_COLORS = {
1161
- /** Green color */
1162
- GREEN: "\x1B[32m",
1163
- /** Yellow color */
1164
- YELLOW: "\x1B[33m",
1165
- /** Red color */
1166
- RED: "\x1B[31m",
1167
- /** Reset color */
1168
- RESET: "\x1B[0m"
1169
- };
1170
1157
  DEMO_DATA = {
1171
1158
  /** Demo session cost in USD */
1172
1159
  COST_USD: 0.42,
@@ -2078,9 +2065,6 @@ function formatDuration(ms) {
2078
2065
  function formatCostUSD(usd) {
2079
2066
  return `$${usd.toFixed(2)}`;
2080
2067
  }
2081
- function colorize2(text, color) {
2082
- return `${color}${text}${ANSI_COLORS.RESET}`;
2083
- }
2084
2068
  function formatK(n) {
2085
2069
  const absN = Math.abs(n);
2086
2070
  if (absN < 1e3) {
@@ -6624,14 +6608,22 @@ async function generatePreviews(choices, style, themeName) {
6624
6608
  const previews = [];
6625
6609
  const isStyleSelection = choices.length >= 3 && choices.every((c) => isQuickConfigStyle(c.value));
6626
6610
  const availableThemes = [
6627
- "monokai",
6628
- "nord",
6629
- "dracula",
6630
6611
  "catppuccin-mocha",
6631
- "tokyo-night",
6632
- "vscode-dark-plus",
6612
+ // AVAILABLE_THEMES[0]
6613
+ "cyberpunk-neon",
6614
+ // AVAILABLE_THEMES[1]
6615
+ "dracula",
6616
+ // AVAILABLE_THEMES[2]
6617
+ "dusty-sage",
6618
+ // AVAILABLE_THEMES[3]
6633
6619
  "github-dark-dimmed",
6634
- "dusty-sage"
6620
+ // AVAILABLE_THEMES[4]
6621
+ "gray",
6622
+ // AVAILABLE_THEMES[5] - was missing!
6623
+ "monokai",
6624
+ // AVAILABLE_THEMES[6]
6625
+ "muted-gray"
6626
+ // AVAILABLE_THEMES[7] - was missing!
6635
6627
  ];
6636
6628
  const isThemeSelection = choices.some((c) => isThemeName(c.value, availableThemes));
6637
6629
  for (const choice of choices) {
@@ -6701,7 +6693,7 @@ function selectWithPreviewImpl(config, done) {
6701
6693
  if (status === "done") {
6702
6694
  return [`${config.message} ${activeChoice.name}`, ""];
6703
6695
  }
6704
- const line = "\x1B[1;37m" + "\u2500".repeat(60) + "\x1B[0m";
6696
+ const line = `\x1B[1;37m${"\u2500".repeat(60)}\x1B[0m`;
6705
6697
  const previewBox = `${line}
6706
6698
  \x1B[1;37mLive Preview\x1B[0m
6707
6699
 
@@ -6874,6 +6866,11 @@ function generateRichLayout(style, themeName) {
6874
6866
  style,
6875
6867
  colors: { amount: theme.cost.amount, currency: theme.cost.currency }
6876
6868
  },
6869
+ {
6870
+ id: "lines",
6871
+ style,
6872
+ colors: { added: theme.lines.added, removed: theme.lines.removed }
6873
+ },
6877
6874
  {
6878
6875
  id: "duration",
6879
6876
  style,
@@ -6891,11 +6888,6 @@ function generateRichLayout(style, themeName) {
6891
6888
  style,
6892
6889
  colors: { base: theme.base.text }
6893
6890
  },
6894
- {
6895
- id: "lines",
6896
- style,
6897
- colors: { added: theme.lines.added, removed: theme.lines.removed }
6898
- },
6899
6891
  {
6900
6892
  id: "active-tools",
6901
6893
  style,
@@ -7272,16 +7264,39 @@ async function routeCommand(command) {
7272
7264
  }
7273
7265
 
7274
7266
  // src/config/config-loader.ts
7275
- var import_node_fs3 = require("node:fs");
7267
+ var import_node_fs4 = require("node:fs");
7276
7268
  var import_promises2 = require("node:fs/promises");
7269
+ var import_node_os4 = require("node:os");
7270
+ var import_node_path4 = require("node:path");
7271
+
7272
+ // src/config/default-config-generator.ts
7273
+ var import_node_fs3 = require("node:fs");
7277
7274
  var import_node_os3 = require("node:os");
7278
7275
  var import_node_path3 = require("node:path");
7279
- function getConfigPath() {
7276
+ function getDefaultConfigPath() {
7280
7277
  return (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude-scope", "config.json");
7281
7278
  }
7279
+ async function ensureDefaultConfig() {
7280
+ const configPath = getDefaultConfigPath();
7281
+ if ((0, import_node_fs3.existsSync)(configPath)) {
7282
+ return;
7283
+ }
7284
+ const configDir = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude-scope");
7285
+ if (!(0, import_node_fs3.existsSync)(configDir)) {
7286
+ (0, import_node_fs3.mkdirSync)(configDir, { recursive: true });
7287
+ }
7288
+ const defaultConfig = generateBalancedLayout("balanced", "cyberpunk-neon");
7289
+ (0, import_node_fs3.writeFileSync)(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
7290
+ }
7291
+
7292
+ // src/config/config-loader.ts
7293
+ function getConfigPath() {
7294
+ return (0, import_node_path4.join)((0, import_node_os4.homedir)(), ".claude-scope", "config.json");
7295
+ }
7282
7296
  async function loadWidgetConfig() {
7283
7297
  const configPath = getConfigPath();
7284
- if (!(0, import_node_fs3.existsSync)(configPath)) {
7298
+ await ensureDefaultConfig();
7299
+ if (!(0, import_node_fs4.existsSync)(configPath)) {
7285
7300
  return null;
7286
7301
  }
7287
7302
  try {
@@ -7300,18 +7315,78 @@ async function loadWidgetConfig() {
7300
7315
  }
7301
7316
  }
7302
7317
 
7303
- // src/config/widget-flags.ts
7304
- var WIDGET_FLAGS = {
7305
- activeTools: true,
7306
- cacheMetrics: true
7307
- };
7308
- function isWidgetEnabled(name) {
7309
- return WIDGET_FLAGS[name] ?? true;
7310
- }
7311
-
7312
7318
  // src/index.ts
7313
7319
  init_renderer();
7314
7320
  init_style_types();
7321
+
7322
+ // src/core/widget-factory.ts
7323
+ init_theme();
7324
+ init_active_tools();
7325
+ init_cache_metrics();
7326
+ init_config_count_widget();
7327
+ init_context_widget();
7328
+ init_cost_widget();
7329
+ init_duration_widget();
7330
+ init_git_tag_widget();
7331
+ init_git_widget();
7332
+ init_lines_widget();
7333
+ init_model_widget();
7334
+ var WidgetFactory = class {
7335
+ transcriptProvider;
7336
+ constructor() {
7337
+ this.transcriptProvider = new TranscriptProvider();
7338
+ }
7339
+ /**
7340
+ * Create a widget instance by ID
7341
+ * @param widgetId - Widget identifier (e.g., "model", "git", "context")
7342
+ * @returns Widget instance or null if widget ID is unknown
7343
+ */
7344
+ createWidget(widgetId) {
7345
+ switch (widgetId) {
7346
+ case "model":
7347
+ return new ModelWidget();
7348
+ case "context":
7349
+ return new ContextWidget();
7350
+ case "cost":
7351
+ return new CostWidget();
7352
+ case "lines":
7353
+ return new LinesWidget();
7354
+ case "duration":
7355
+ return new DurationWidget();
7356
+ case "git":
7357
+ return new GitWidget();
7358
+ case "git-tag":
7359
+ return new GitTagWidget();
7360
+ case "config-count":
7361
+ return new ConfigCountWidget();
7362
+ case "cache-metrics":
7363
+ return new CacheMetricsWidget(DEFAULT_THEME);
7364
+ case "active-tools":
7365
+ return new ActiveToolsWidget(DEFAULT_THEME, this.transcriptProvider);
7366
+ default:
7367
+ return null;
7368
+ }
7369
+ }
7370
+ /**
7371
+ * Get list of all supported widget IDs
7372
+ */
7373
+ getSupportedWidgetIds() {
7374
+ return [
7375
+ "model",
7376
+ "context",
7377
+ "cost",
7378
+ "lines",
7379
+ "duration",
7380
+ "git",
7381
+ "git-tag",
7382
+ "config-count",
7383
+ "cache-metrics",
7384
+ "active-tools"
7385
+ ];
7386
+ }
7387
+ };
7388
+
7389
+ // src/index.ts
7315
7390
  init_widget_registry();
7316
7391
 
7317
7392
  // src/validation/result.ts
@@ -7489,711 +7564,6 @@ var StdinProvider = class {
7489
7564
  }
7490
7565
  };
7491
7566
 
7492
- // src/index.ts
7493
- init_theme();
7494
- init_active_tools();
7495
- init_cache_metrics();
7496
- init_config_count_widget();
7497
- init_context_widget();
7498
- init_cost_widget();
7499
- init_duration_widget();
7500
-
7501
- // src/widgets/empty-line-widget.ts
7502
- init_widget_types();
7503
- init_stdin_data_widget();
7504
- var EmptyLineWidget = class extends StdinDataWidget {
7505
- id = "empty-line";
7506
- metadata = createWidgetMetadata(
7507
- "Empty Line",
7508
- "Empty line separator",
7509
- "1.0.0",
7510
- "claude-scope",
7511
- 5
7512
- // Sixth line (0-indexed)
7513
- );
7514
- _lineOverride;
7515
- /**
7516
- * All styles return the same value (Braille Pattern Blank).
7517
- * This method exists for API consistency with other widgets.
7518
- */
7519
- setStyle(_style) {
7520
- }
7521
- setLine(line) {
7522
- this._lineOverride = line;
7523
- }
7524
- getLine() {
7525
- return this._lineOverride ?? this.metadata.line ?? 0;
7526
- }
7527
- /**
7528
- * Return Braille Pattern Blank to create a visible empty separator line.
7529
- * U+2800 occupies cell width but appears blank, ensuring the line renders.
7530
- */
7531
- renderWithData(_data, _context) {
7532
- return "\u2800";
7533
- }
7534
- };
7535
-
7536
- // src/index.ts
7537
- init_git_tag_widget();
7538
- init_git_widget();
7539
- init_lines_widget();
7540
- init_model_widget();
7541
-
7542
- // src/widgets/poker-widget.ts
7543
- init_style_types();
7544
- init_widget_types();
7545
- init_theme();
7546
- init_stdin_data_widget();
7547
-
7548
- // src/widgets/poker/deck.ts
7549
- var import_node_crypto = require("node:crypto");
7550
-
7551
- // src/widgets/poker/types.ts
7552
- var Suit = {
7553
- Spades: "spades",
7554
- Hearts: "hearts",
7555
- Diamonds: "diamonds",
7556
- Clubs: "clubs"
7557
- };
7558
- var SUIT_SYMBOLS = {
7559
- spades: "\u2660",
7560
- hearts: "\u2665",
7561
- diamonds: "\u2666",
7562
- clubs: "\u2663"
7563
- };
7564
- var EMOJI_SYMBOLS = {
7565
- spades: "\u2660\uFE0F",
7566
- // ♠️
7567
- hearts: "\u2665\uFE0F",
7568
- // ♥️
7569
- diamonds: "\u2666\uFE0F",
7570
- // ♦️
7571
- clubs: "\u2663\uFE0F"
7572
- // ♣️
7573
- };
7574
- function isRedSuit(suit) {
7575
- return suit === "hearts" || suit === "diamonds";
7576
- }
7577
- var Rank = {
7578
- Two: "2",
7579
- Three: "3",
7580
- Four: "4",
7581
- Five: "5",
7582
- Six: "6",
7583
- Seven: "7",
7584
- Eight: "8",
7585
- Nine: "9",
7586
- Ten: "10",
7587
- Jack: "J",
7588
- Queen: "Q",
7589
- King: "K",
7590
- Ace: "A"
7591
- };
7592
- function getRankValue(rank) {
7593
- const values = {
7594
- "2": 2,
7595
- "3": 3,
7596
- "4": 4,
7597
- "5": 5,
7598
- "6": 6,
7599
- "7": 7,
7600
- "8": 8,
7601
- "9": 9,
7602
- "10": 10,
7603
- J: 11,
7604
- Q: 12,
7605
- K: 13,
7606
- A: 14
7607
- };
7608
- return values[rank];
7609
- }
7610
- function formatCard(card) {
7611
- return `${card.rank}${SUIT_SYMBOLS[card.suit]}`;
7612
- }
7613
- function formatCardEmoji(card) {
7614
- return `${card.rank}${EMOJI_SYMBOLS[card.suit]}`;
7615
- }
7616
-
7617
- // src/widgets/poker/deck.ts
7618
- var ALL_SUITS = [Suit.Spades, Suit.Hearts, Suit.Diamonds, Suit.Clubs];
7619
- var ALL_RANKS = [
7620
- Rank.Two,
7621
- Rank.Three,
7622
- Rank.Four,
7623
- Rank.Five,
7624
- Rank.Six,
7625
- Rank.Seven,
7626
- Rank.Eight,
7627
- Rank.Nine,
7628
- Rank.Ten,
7629
- Rank.Jack,
7630
- Rank.Queen,
7631
- Rank.King,
7632
- Rank.Ace
7633
- ];
7634
- var Deck = class {
7635
- cards = [];
7636
- constructor() {
7637
- this.initialize();
7638
- this.shuffle();
7639
- }
7640
- /**
7641
- * Create a standard 52-card deck
7642
- */
7643
- initialize() {
7644
- this.cards = [];
7645
- for (const suit of ALL_SUITS) {
7646
- for (const rank of ALL_RANKS) {
7647
- this.cards.push({ rank, suit });
7648
- }
7649
- }
7650
- }
7651
- /**
7652
- * Shuffle deck using Fisher-Yates algorithm with crypto.random
7653
- */
7654
- shuffle() {
7655
- for (let i = this.cards.length - 1; i > 0; i--) {
7656
- const j = (0, import_node_crypto.randomInt)(0, i + 1);
7657
- [this.cards[i], this.cards[j]] = [this.cards[j], this.cards[i]];
7658
- }
7659
- }
7660
- /**
7661
- * Deal one card from the top of the deck
7662
- * @throws Error if deck is empty
7663
- */
7664
- deal() {
7665
- if (this.cards.length === 0) {
7666
- throw new Error("Deck is empty");
7667
- }
7668
- return this.cards.pop();
7669
- }
7670
- /**
7671
- * Get number of remaining cards in deck
7672
- */
7673
- remaining() {
7674
- return this.cards.length;
7675
- }
7676
- };
7677
-
7678
- // src/widgets/poker/hand-evaluator.ts
7679
- var HAND_DISPLAY = {
7680
- [10 /* RoyalFlush */]: { name: "Royal Flush", emoji: "\u{1F3C6}" },
7681
- [9 /* StraightFlush */]: { name: "Straight Flush", emoji: "\u{1F525}" },
7682
- [8 /* FourOfAKind */]: { name: "Four of a Kind", emoji: "\u{1F48E}" },
7683
- [7 /* FullHouse */]: { name: "Full House", emoji: "\u{1F3E0}" },
7684
- [6 /* Flush */]: { name: "Flush", emoji: "\u{1F4A7}" },
7685
- [5 /* Straight */]: { name: "Straight", emoji: "\u{1F4C8}" },
7686
- [4 /* ThreeOfAKind */]: { name: "Three of a Kind", emoji: "\u{1F3AF}" },
7687
- [3 /* TwoPair */]: { name: "Two Pair", emoji: "\u270C\uFE0F" },
7688
- [2 /* OnePair */]: { name: "One Pair", emoji: "\u{1F44D}" },
7689
- [1 /* HighCard */]: { name: "High Card", emoji: "\u{1F0CF}" }
7690
- };
7691
- function countRanks(cards) {
7692
- const counts = /* @__PURE__ */ new Map();
7693
- for (const card of cards) {
7694
- const value = getRankValue(card.rank);
7695
- counts.set(value, (counts.get(value) || 0) + 1);
7696
- }
7697
- return counts;
7698
- }
7699
- function countSuits(cards) {
7700
- const counts = /* @__PURE__ */ new Map();
7701
- for (const card of cards) {
7702
- counts.set(card.suit, (counts.get(card.suit) || 0) + 1);
7703
- }
7704
- return counts;
7705
- }
7706
- function findCardsOfRank(cards, targetRank) {
7707
- const indices = [];
7708
- for (let i = 0; i < cards.length; i++) {
7709
- if (getRankValue(cards[i].rank) === targetRank) {
7710
- indices.push(i);
7711
- }
7712
- }
7713
- return indices;
7714
- }
7715
- function findCardsOfSuit(cards, targetSuit) {
7716
- const indices = [];
7717
- for (let i = 0; i < cards.length; i++) {
7718
- if (cards[i].suit === targetSuit) {
7719
- indices.push(i);
7720
- }
7721
- }
7722
- return indices;
7723
- }
7724
- function findFlushSuit(cards) {
7725
- const suitCounts = countSuits(cards);
7726
- for (const [suit, count] of suitCounts.entries()) {
7727
- if (count >= 5) return suit;
7728
- }
7729
- return null;
7730
- }
7731
- function getStraightIndices(cards, highCard) {
7732
- const uniqueValues = /* @__PURE__ */ new Set();
7733
- const cardIndicesByRank = /* @__PURE__ */ new Map();
7734
- for (let i = 0; i < cards.length; i++) {
7735
- const value = getRankValue(cards[i].rank);
7736
- if (!cardIndicesByRank.has(value)) {
7737
- cardIndicesByRank.set(value, []);
7738
- uniqueValues.add(value);
7739
- }
7740
- cardIndicesByRank.get(value)?.push(i);
7741
- }
7742
- const sortedValues = Array.from(uniqueValues).sort((a, b) => b - a);
7743
- if (sortedValues.includes(14)) {
7744
- sortedValues.push(1);
7745
- }
7746
- for (let i = 0; i <= sortedValues.length - 5; i++) {
7747
- const current = sortedValues[i];
7748
- const next1 = sortedValues[i + 1];
7749
- const next2 = sortedValues[i + 2];
7750
- const next3 = sortedValues[i + 3];
7751
- const next4 = sortedValues[i + 4];
7752
- if (current - next1 === 1 && current - next2 === 2 && current - next3 === 3 && current - next4 === 4) {
7753
- if (current === highCard) {
7754
- const indices = [];
7755
- indices.push(cardIndicesByRank.get(current)[0]);
7756
- indices.push(cardIndicesByRank.get(next1)[0]);
7757
- indices.push(cardIndicesByRank.get(next2)[0]);
7758
- indices.push(cardIndicesByRank.get(next3)[0]);
7759
- const rank4 = next4 === 1 ? 14 : next4;
7760
- indices.push(cardIndicesByRank.get(rank4)[0]);
7761
- return indices;
7762
- }
7763
- }
7764
- }
7765
- return [];
7766
- }
7767
- function getStraightFlushHighCard(cards, suit) {
7768
- const suitCards = cards.filter((c) => c.suit === suit);
7769
- return getStraightHighCard(suitCards);
7770
- }
7771
- function getStraightFlushIndices(cards, highCard, suit) {
7772
- const _suitCards = cards.filter((c) => c.suit === suit);
7773
- const suitCardIndices = [];
7774
- const indexMap = /* @__PURE__ */ new Map();
7775
- for (let i = 0; i < cards.length; i++) {
7776
- if (cards[i].suit === suit) {
7777
- indexMap.set(suitCardIndices.length, i);
7778
- suitCardIndices.push(cards[i]);
7779
- }
7780
- }
7781
- const indices = getStraightIndices(suitCardIndices, highCard);
7782
- return indices.map((idx) => indexMap.get(idx));
7783
- }
7784
- function getFullHouseIndices(cards) {
7785
- const rankCounts = countRanks(cards);
7786
- let tripsRank = 0;
7787
- for (const [rank, count] of rankCounts.entries()) {
7788
- if (count === 3) {
7789
- tripsRank = rank;
7790
- break;
7791
- }
7792
- }
7793
- let pairRank = 0;
7794
- for (const [rank, count] of rankCounts.entries()) {
7795
- if (count >= 2 && rank !== tripsRank) {
7796
- pairRank = rank;
7797
- break;
7798
- }
7799
- }
7800
- if (pairRank === 0) {
7801
- const tripsRanks = [];
7802
- for (const [rank, count] of rankCounts.entries()) {
7803
- if (count === 3) {
7804
- tripsRanks.push(rank);
7805
- }
7806
- }
7807
- if (tripsRanks.length >= 2) {
7808
- tripsRanks.sort((a, b) => b - a);
7809
- tripsRank = tripsRanks[0];
7810
- pairRank = tripsRanks[1];
7811
- }
7812
- }
7813
- const tripsIndices = findCardsOfRank(cards, tripsRank);
7814
- const pairIndices = findCardsOfRank(cards, pairRank);
7815
- return [...tripsIndices.slice(0, 3), ...pairIndices.slice(0, 2)];
7816
- }
7817
- function isFlush(cards) {
7818
- const suitCounts = countSuits(cards);
7819
- for (const count of suitCounts.values()) {
7820
- if (count >= 5) return true;
7821
- }
7822
- return false;
7823
- }
7824
- function getStraightHighCard(cards) {
7825
- const uniqueValues = /* @__PURE__ */ new Set();
7826
- for (const card of cards) {
7827
- uniqueValues.add(getRankValue(card.rank));
7828
- }
7829
- const sortedValues = Array.from(uniqueValues).sort((a, b) => b - a);
7830
- if (sortedValues.includes(14)) {
7831
- sortedValues.push(1);
7832
- }
7833
- for (let i = 0; i <= sortedValues.length - 5; i++) {
7834
- const current = sortedValues[i];
7835
- const next1 = sortedValues[i + 1];
7836
- const next2 = sortedValues[i + 2];
7837
- const next3 = sortedValues[i + 3];
7838
- const next4 = sortedValues[i + 4];
7839
- if (current - next1 === 1 && current - next2 === 2 && current - next3 === 3 && current - next4 === 4) {
7840
- return current;
7841
- }
7842
- }
7843
- return null;
7844
- }
7845
- function getMaxCount(cards) {
7846
- const rankCounts = countRanks(cards);
7847
- let maxCount = 0;
7848
- for (const count of rankCounts.values()) {
7849
- if (count > maxCount) {
7850
- maxCount = count;
7851
- }
7852
- }
7853
- return maxCount;
7854
- }
7855
- function getPairCount(cards) {
7856
- const rankCounts = countRanks(cards);
7857
- let pairCount = 0;
7858
- for (const count of rankCounts.values()) {
7859
- if (count === 2) {
7860
- pairCount++;
7861
- }
7862
- }
7863
- return pairCount;
7864
- }
7865
- function getMostCommonRank(cards) {
7866
- const rankCounts = countRanks(cards);
7867
- let bestRank = 0;
7868
- let bestCount = 0;
7869
- for (const [rank, count] of rankCounts.entries()) {
7870
- if (count > bestCount) {
7871
- bestCount = count;
7872
- bestRank = rank;
7873
- }
7874
- }
7875
- return bestRank > 0 ? bestRank : null;
7876
- }
7877
- function getTwoPairRanks(cards) {
7878
- const rankCounts = countRanks(cards);
7879
- const pairRanks = [];
7880
- for (const [rank, count] of rankCounts.entries()) {
7881
- if (count >= 2) {
7882
- pairRanks.push(rank);
7883
- }
7884
- }
7885
- pairRanks.sort((a, b) => b - a);
7886
- return pairRanks.slice(0, 2);
7887
- }
7888
- function getHighestCardIndex(cards) {
7889
- let highestIdx = 0;
7890
- let highestValue = 0;
7891
- for (let i = 0; i < cards.length; i++) {
7892
- const value = getRankValue(cards[i].rank);
7893
- if (value > highestValue) {
7894
- highestValue = value;
7895
- highestIdx = i;
7896
- }
7897
- }
7898
- return highestIdx;
7899
- }
7900
- function evaluateHand(hole, board) {
7901
- const allCards = [...hole, ...board];
7902
- const flush = isFlush(allCards);
7903
- const straightHighCard = getStraightHighCard(allCards);
7904
- const maxCount = getMaxCount(allCards);
7905
- const pairCount = getPairCount(allCards);
7906
- if (flush && straightHighCard === 14) {
7907
- const flushSuit = findFlushSuit(allCards);
7908
- const sfHighCard = getStraightFlushHighCard(allCards, flushSuit);
7909
- if (sfHighCard === 14) {
7910
- const participatingCards = getStraightFlushIndices(allCards, 14, flushSuit);
7911
- return {
7912
- rank: 10 /* RoyalFlush */,
7913
- ...HAND_DISPLAY[10 /* RoyalFlush */],
7914
- participatingCards
7915
- };
7916
- }
7917
- }
7918
- if (flush) {
7919
- const flushSuit = findFlushSuit(allCards);
7920
- const sfHighCard = getStraightFlushHighCard(allCards, flushSuit);
7921
- if (sfHighCard !== null) {
7922
- const participatingCards = getStraightFlushIndices(allCards, sfHighCard, flushSuit);
7923
- return {
7924
- rank: 9 /* StraightFlush */,
7925
- ...HAND_DISPLAY[9 /* StraightFlush */],
7926
- participatingCards
7927
- };
7928
- }
7929
- }
7930
- if (maxCount === 4) {
7931
- const rank = getMostCommonRank(allCards);
7932
- const participatingCards = findCardsOfRank(allCards, rank);
7933
- return {
7934
- rank: 8 /* FourOfAKind */,
7935
- ...HAND_DISPLAY[8 /* FourOfAKind */],
7936
- participatingCards
7937
- };
7938
- }
7939
- if (maxCount === 3 && pairCount >= 1) {
7940
- const participatingCards = getFullHouseIndices(allCards);
7941
- return { rank: 7 /* FullHouse */, ...HAND_DISPLAY[7 /* FullHouse */], participatingCards };
7942
- }
7943
- if (flush) {
7944
- const flushSuit = findFlushSuit(allCards);
7945
- const suitIndices = findCardsOfSuit(allCards, flushSuit);
7946
- const participatingCards = suitIndices.slice(0, 5);
7947
- return { rank: 6 /* Flush */, ...HAND_DISPLAY[6 /* Flush */], participatingCards };
7948
- }
7949
- if (straightHighCard !== null) {
7950
- const participatingCards = getStraightIndices(allCards, straightHighCard);
7951
- return { rank: 5 /* Straight */, ...HAND_DISPLAY[5 /* Straight */], participatingCards };
7952
- }
7953
- if (maxCount === 3) {
7954
- const rank = getMostCommonRank(allCards);
7955
- const participatingCards = findCardsOfRank(allCards, rank);
7956
- return {
7957
- rank: 4 /* ThreeOfAKind */,
7958
- ...HAND_DISPLAY[4 /* ThreeOfAKind */],
7959
- participatingCards
7960
- };
7961
- }
7962
- if (pairCount >= 2) {
7963
- const [rank1, rank2] = getTwoPairRanks(allCards);
7964
- const pair1Indices = findCardsOfRank(allCards, rank1);
7965
- const pair2Indices = findCardsOfRank(allCards, rank2);
7966
- const participatingCards = [...pair1Indices, ...pair2Indices];
7967
- return { rank: 3 /* TwoPair */, ...HAND_DISPLAY[3 /* TwoPair */], participatingCards };
7968
- }
7969
- if (pairCount === 1) {
7970
- const rank = getMostCommonRank(allCards);
7971
- const participatingCards = findCardsOfRank(allCards, rank);
7972
- return { rank: 2 /* OnePair */, ...HAND_DISPLAY[2 /* OnePair */], participatingCards };
7973
- }
7974
- const highestIdx = getHighestCardIndex(allCards);
7975
- return {
7976
- rank: 1 /* HighCard */,
7977
- ...HAND_DISPLAY[1 /* HighCard */],
7978
- participatingCards: [highestIdx]
7979
- };
7980
- }
7981
-
7982
- // src/widgets/poker/styles.ts
7983
- init_colors();
7984
- init_formatters();
7985
- var HAND_ABBREVIATIONS = {
7986
- "Royal Flush": "RF",
7987
- "Straight Flush": "SF",
7988
- "Four of a Kind": "4K",
7989
- "Full House": "FH",
7990
- Flush: "FL",
7991
- Straight: "ST",
7992
- "Three of a Kind": "3K",
7993
- "Two Pair": "2P",
7994
- "One Pair": "1P",
7995
- "High Card": "HC",
7996
- Nothing: "\u2014"
7997
- };
7998
- function formatCardByParticipation(cardData, isParticipating) {
7999
- const color = isRedSuit(cardData.card.suit) ? red : gray;
8000
- const cardText = formatCard(cardData.card);
8001
- if (isParticipating) {
8002
- return `${color}${bold}(${cardText})${reset} `;
8003
- } else {
8004
- return `${color}${cardText}${reset} `;
8005
- }
8006
- }
8007
- function formatCardCompact(cardData, isParticipating) {
8008
- const color = isRedSuit(cardData.card.suit) ? red : gray;
8009
- const cardText = formatCardTextCompact(cardData.card);
8010
- if (isParticipating) {
8011
- return `${color}${bold}(${cardText})${reset}`;
8012
- } else {
8013
- return `${color}${cardText}${reset}`;
8014
- }
8015
- }
8016
- function formatCardTextCompact(card) {
8017
- const rankSymbols = {
8018
- "10": "T",
8019
- "11": "J",
8020
- "12": "Q",
8021
- "13": "K",
8022
- "14": "A"
8023
- };
8024
- const rank = String(card.rank);
8025
- const rankSymbol = rankSymbols[rank] ?? rank;
8026
- return `${rankSymbol}${card.suit}`;
8027
- }
8028
- function formatCardEmojiByParticipation(cardData, isParticipating) {
8029
- const cardText = formatCardEmoji(cardData.card);
8030
- if (isParticipating) {
8031
- return `${bold}(${cardText})${reset} `;
8032
- } else {
8033
- return `${cardText} `;
8034
- }
8035
- }
8036
- function formatHandResult(handResult, colors2) {
8037
- if (!handResult) {
8038
- return "\u2014";
8039
- }
8040
- const playerParticipates = handResult.participatingIndices.some((idx) => idx < 2);
8041
- const resultText = !playerParticipates ? `Nothing \u{1F0CF}` : `${handResult.name}! ${handResult.emoji}`;
8042
- if (!colors2) return resultText;
8043
- return colorize2(resultText, colors2.result);
8044
- }
8045
- function getHandAbbreviation(handResult) {
8046
- if (!handResult) {
8047
- return "\u2014 (\u2014)";
8048
- }
8049
- const abbreviation = HAND_ABBREVIATIONS[handResult.name] ?? "\u2014";
8050
- return `${abbreviation} (${handResult.name})`;
8051
- }
8052
- function balancedStyle2(data, colors2) {
8053
- const { holeCards, boardCards, handResult } = data;
8054
- const participatingSet = new Set(handResult?.participatingIndices || []);
8055
- const handStr = holeCards.map((hc, idx) => formatCardByParticipation(hc, participatingSet.has(idx))).join("");
8056
- const boardStr = boardCards.map((bc, idx) => formatCardByParticipation(bc, participatingSet.has(idx + 2))).join("");
8057
- const labelColor = colors2?.participating ?? lightGray;
8058
- const handLabel = colorize2("Hand:", labelColor);
8059
- const boardLabel = colorize2("Board:", labelColor);
8060
- return `${handLabel} ${handStr}| ${boardLabel} ${boardStr}\u2192 ${formatHandResult(handResult, colors2)}`;
8061
- }
8062
- var pokerStyles = {
8063
- balanced: balancedStyle2,
8064
- compact: balancedStyle2,
8065
- playful: balancedStyle2,
8066
- "compact-verbose": (data, colors2) => {
8067
- const { holeCards, boardCards, handResult } = data;
8068
- const participatingSet = new Set(handResult?.participatingIndices || []);
8069
- const handStr = holeCards.map((hc, idx) => formatCardCompact(hc, participatingSet.has(idx))).join("");
8070
- const boardStr = boardCards.map((bc, idx) => formatCardCompact(bc, participatingSet.has(idx + 2))).join("");
8071
- const abbreviation = getHandAbbreviation(handResult);
8072
- const result = `${handStr}| ${boardStr}\u2192 ${abbreviation}`;
8073
- if (!colors2) return result;
8074
- return colorize2(result, colors2.result);
8075
- },
8076
- emoji: (data, colors2) => {
8077
- const { holeCards, boardCards, handResult } = data;
8078
- const participatingSet = new Set(handResult?.participatingIndices || []);
8079
- const handStr = holeCards.map((hc, idx) => formatCardEmojiByParticipation(hc, participatingSet.has(idx))).join("");
8080
- const boardStr = boardCards.map((bc, idx) => formatCardEmojiByParticipation(bc, participatingSet.has(idx + 2))).join("");
8081
- const labelColor = colors2?.participating ?? lightGray;
8082
- const handLabel = colorize2("Hand:", labelColor);
8083
- const boardLabel = colorize2("Board:", labelColor);
8084
- return `${handLabel} ${handStr}| ${boardLabel} ${boardStr}\u2192 ${formatHandResult(handResult, colors2)}`;
8085
- }
8086
- };
8087
-
8088
- // src/widgets/poker-widget.ts
8089
- var PokerWidget = class extends StdinDataWidget {
8090
- id = "poker";
8091
- metadata = createWidgetMetadata(
8092
- "Poker",
8093
- "Displays random Texas Hold'em hands for entertainment",
8094
- "1.0.0",
8095
- "claude-scope",
8096
- 4
8097
- // Fifth line (0-indexed)
8098
- );
8099
- holeCards = [];
8100
- boardCards = [];
8101
- handResult = null;
8102
- lastUpdateTimestamp = 0;
8103
- THROTTLE_MS = 5e3;
8104
- // 5 seconds
8105
- colors;
8106
- _lineOverride;
8107
- styleFn = pokerStyles.balanced;
8108
- setStyle(style = DEFAULT_WIDGET_STYLE) {
8109
- const fn = pokerStyles[style];
8110
- if (fn) {
8111
- this.styleFn = fn;
8112
- }
8113
- }
8114
- setLine(line) {
8115
- this._lineOverride = line;
8116
- }
8117
- getLine() {
8118
- return this._lineOverride ?? this.metadata.line ?? 0;
8119
- }
8120
- constructor(colors2) {
8121
- super();
8122
- this.colors = colors2 ?? DEFAULT_THEME;
8123
- }
8124
- /**
8125
- * Generate new poker hand on each update
8126
- */
8127
- async update(data) {
8128
- await super.update(data);
8129
- const now = Date.now();
8130
- if (this.lastUpdateTimestamp > 0 && now - this.lastUpdateTimestamp < this.THROTTLE_MS) {
8131
- return;
8132
- }
8133
- const deck = new Deck();
8134
- const hole = [deck.deal(), deck.deal()];
8135
- const board = [deck.deal(), deck.deal(), deck.deal(), deck.deal(), deck.deal()];
8136
- const result = evaluateHand(hole, board);
8137
- this.holeCards = hole.map((card) => ({
8138
- card,
8139
- formatted: this.formatCardColor(card)
8140
- }));
8141
- this.boardCards = board.map((card) => ({
8142
- card,
8143
- formatted: this.formatCardColor(card)
8144
- }));
8145
- const playerParticipates = result.participatingCards.some((idx) => idx < 2);
8146
- if (!playerParticipates) {
8147
- this.handResult = {
8148
- text: `Nothing \u{1F0CF}`,
8149
- participatingIndices: result.participatingCards
8150
- };
8151
- } else {
8152
- this.handResult = {
8153
- text: `${result.name}! ${result.emoji}`,
8154
- participatingIndices: result.participatingCards
8155
- };
8156
- }
8157
- this.lastUpdateTimestamp = now;
8158
- }
8159
- /**
8160
- * Format card with appropriate color (red for ♥♦, gray for ♠♣)
8161
- */
8162
- formatCardColor(card) {
8163
- const _color = isRedSuit(card.suit) ? "red" : "gray";
8164
- return formatCard(card);
8165
- }
8166
- renderWithData(_data, _context) {
8167
- const holeCardsData = this.holeCards.map((hc, idx) => ({
8168
- card: hc.card,
8169
- isParticipating: (this.handResult?.participatingIndices || []).includes(idx)
8170
- }));
8171
- const boardCardsData = this.boardCards.map((bc, idx) => ({
8172
- card: bc.card,
8173
- isParticipating: (this.handResult?.participatingIndices || []).includes(idx + 2)
8174
- }));
8175
- const handResult = this.handResult ? {
8176
- name: this.getHandName(this.handResult.text),
8177
- emoji: this.getHandEmoji(this.handResult.text),
8178
- participatingIndices: this.handResult.participatingIndices
8179
- } : null;
8180
- const renderData = {
8181
- holeCards: holeCardsData,
8182
- boardCards: boardCardsData,
8183
- handResult
8184
- };
8185
- return this.styleFn(renderData, this.colors.poker);
8186
- }
8187
- getHandName(text) {
8188
- const match = text.match(/^([^!]+)/);
8189
- return match ? match[1].trim() : "Nothing";
8190
- }
8191
- getHandEmoji(text) {
8192
- const match = text.match(/([🃏♠️♥️♦️♣️🎉✨🌟])/u);
8193
- return match ? match[1] : "\u{1F0CF}";
8194
- }
8195
- };
8196
-
8197
7567
  // src/index.ts
8198
7568
  async function readStdin() {
8199
7569
  const chunks = [];
@@ -8216,12 +7586,6 @@ function applyWidgetConfig(widget, widgetId, config) {
8216
7586
  }
8217
7587
  }
8218
7588
  }
8219
- async function registerWidgetWithConfig(registry, widget, widgetId, config) {
8220
- if (config) {
8221
- applyWidgetConfig(widget, widgetId, config);
8222
- }
8223
- await registry.register(widget);
8224
- }
8225
7589
  async function main() {
8226
7590
  try {
8227
7591
  const command = parseCommand();
@@ -8237,34 +7601,27 @@ async function main() {
8237
7601
  const provider = new StdinProvider();
8238
7602
  const stdinData = await provider.parse(stdin);
8239
7603
  const registry = new WidgetRegistry();
8240
- const transcriptProvider = new TranscriptProvider();
8241
7604
  const widgetConfig = await loadWidgetConfig();
8242
- await registerWidgetWithConfig(registry, new ModelWidget(), "model", widgetConfig);
8243
- await registerWidgetWithConfig(registry, new ContextWidget(), "context", widgetConfig);
8244
- await registerWidgetWithConfig(registry, new CostWidget(), "cost", widgetConfig);
8245
- await registerWidgetWithConfig(registry, new LinesWidget(), "lines", widgetConfig);
8246
- await registerWidgetWithConfig(registry, new DurationWidget(), "duration", widgetConfig);
8247
- await registerWidgetWithConfig(registry, new GitWidget(), "git", widgetConfig);
8248
- await registerWidgetWithConfig(registry, new GitTagWidget(), "git-tag", widgetConfig);
8249
- await registerWidgetWithConfig(registry, new ConfigCountWidget(), "config-count", widgetConfig);
8250
- if (isWidgetEnabled("cacheMetrics")) {
8251
- await registerWidgetWithConfig(
8252
- registry,
8253
- new CacheMetricsWidget(DEFAULT_THEME),
8254
- "cache-metrics",
8255
- widgetConfig
8256
- );
8257
- }
8258
- if (isWidgetEnabled("activeTools")) {
8259
- await registerWidgetWithConfig(
8260
- registry,
8261
- new ActiveToolsWidget(DEFAULT_THEME, transcriptProvider),
8262
- "active-tools",
8263
- widgetConfig
8264
- );
7605
+ const factory = new WidgetFactory();
7606
+ if (widgetConfig) {
7607
+ for (const [_lineNum, widgets] of Object.entries(widgetConfig.lines)) {
7608
+ for (const widgetConfigItem of widgets) {
7609
+ const widget = factory.createWidget(widgetConfigItem.id);
7610
+ if (widget) {
7611
+ applyWidgetConfig(widget, widgetConfigItem.id, widgetConfig);
7612
+ await registry.register(widget);
7613
+ }
7614
+ }
7615
+ }
7616
+ } else {
7617
+ const defaultWidgets = ["model", "git", "context"];
7618
+ for (const widgetId of defaultWidgets) {
7619
+ const widget = factory.createWidget(widgetId);
7620
+ if (widget) {
7621
+ await registry.register(widget);
7622
+ }
7623
+ }
8265
7624
  }
8266
- await registry.register(new PokerWidget());
8267
- await registry.register(new EmptyLineWidget());
8268
7625
  const renderer = new Renderer({
8269
7626
  separator: " \u2502 ",
8270
7627
  onError: (_error, _widget) => {
@@ -8287,7 +7644,11 @@ async function main() {
8287
7644
  async function tryGitFallback() {
8288
7645
  try {
8289
7646
  const cwd = process.cwd();
8290
- const widget = new GitWidget();
7647
+ const factory = new WidgetFactory();
7648
+ const widget = factory.createWidget("git");
7649
+ if (!widget) {
7650
+ return "";
7651
+ }
8291
7652
  await widget.initialize({ config: {} });
8292
7653
  await widget.update({ cwd, session_id: "fallback" });
8293
7654
  const result = await widget.render({ width: 80, timestamp: Date.now() });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-scope",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "description": "Claude Code plugin for session status and analytics",
5
5
  "license": "MIT",
6
6
  "type": "module",