claude-scope 0.6.9 → 0.6.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.
@@ -1491,23 +1491,58 @@ function formatTool(name, target, colors) {
1491
1491
  }
1492
1492
  return nameStr;
1493
1493
  }
1494
+ function pluralizeTool(name) {
1495
+ const irregular = {
1496
+ Task: "Tasks",
1497
+ Bash: "Bash",
1498
+ Edit: "Edits",
1499
+ Read: "Reads",
1500
+ Write: "Writes",
1501
+ Grep: "Greps",
1502
+ Glob: "Globs"
1503
+ };
1504
+ return irregular[name] || `${name}s`;
1505
+ }
1494
1506
  var activeToolsStyles = {
1495
1507
  /**
1496
- * balanced: Running tools with ◐ spinner, completed aggregated with ×count
1508
+ * balanced: Group tools by name, showing running and completed counts together
1509
+ * - Running + completed: "ToolName (1 running, 6 done)"
1510
+ * - Only completed: "Tools: 6"
1511
+ * - No symbols, just text format
1497
1512
  */
1498
1513
  balanced: (data, colors) => {
1499
1514
  const parts = [];
1500
- for (const tool of data.running.slice(-2)) {
1501
- const indicator = colors ? colorize("\u25D0", colors.tools.running) : "\u25D0";
1502
- parts.push(
1503
- `${indicator} ${formatTool(tool.name, tool.target, colors ?? getDefaultColors())}`
1504
- );
1515
+ const c = colors ?? getDefaultColors();
1516
+ const allToolNames = /* @__PURE__ */ new Set();
1517
+ for (const tool of data.running) {
1518
+ allToolNames.add(tool.name);
1505
1519
  }
1506
- const sorted = Array.from(data.completed.entries()).sort((a, b) => b[1] - a[1]).slice(0, 4);
1507
- for (const [name, count] of sorted) {
1508
- const check = colors ? colorize("\u2713", colors.tools.completed) : "\u2713";
1509
- const countStr = colors ? colorize(`\xD7${count}`, colors.tools.count) : `\xD7${count}`;
1510
- parts.push(`${check} ${name} ${countStr}`);
1520
+ for (const name of data.completed.keys()) {
1521
+ allToolNames.add(name);
1522
+ }
1523
+ const runningCounts = /* @__PURE__ */ new Map();
1524
+ for (const tool of data.running) {
1525
+ runningCounts.set(tool.name, (runningCounts.get(tool.name) ?? 0) + 1);
1526
+ }
1527
+ for (const name of allToolNames) {
1528
+ const runningCount = runningCounts.get(name) ?? 0;
1529
+ const completedCount = data.completed.get(name) ?? 0;
1530
+ if (runningCount > 0 && completedCount > 0) {
1531
+ const nameStr = colorize(name, c.tools.name);
1532
+ const runningStr = colorize(`${runningCount} running`, c.tools.running);
1533
+ const doneStr = colorize(`${completedCount} done`, c.tools.completed);
1534
+ parts.push(`${nameStr} (${runningStr}, ${doneStr})`);
1535
+ } else if (completedCount > 0) {
1536
+ const pluralName = pluralizeTool(name);
1537
+ const nameStr = colorize(pluralName, c.tools.name);
1538
+ const countStr = colorize(`${completedCount}`, c.tools.count);
1539
+ parts.push(`${nameStr}: ${countStr}`);
1540
+ } else if (runningCount > 0) {
1541
+ const nameStr = colorize(name, c.tools.name);
1542
+ const runningStr = colorize(`${runningCount} running`, c.tools.running);
1543
+ const doneStr = colorize("0 done", c.tools.completed);
1544
+ parts.push(`${nameStr} (${runningStr}, ${doneStr})`);
1545
+ }
1511
1546
  }
1512
1547
  if (parts.length === 0) {
1513
1548
  return "";
@@ -1788,14 +1823,42 @@ function createWidgetMetadata(name, description, version = "1.0.0", author = "cl
1788
1823
  };
1789
1824
  }
1790
1825
 
1791
- // src/widgets/cache-metrics/styles.ts
1826
+ // src/ui/utils/formatters.ts
1827
+ function formatDuration(ms) {
1828
+ if (ms <= 0) return "0s";
1829
+ const seconds = Math.floor(ms / TIME.MS_PER_SECOND);
1830
+ const hours = Math.floor(seconds / TIME.SECONDS_PER_HOUR);
1831
+ const minutes = Math.floor(seconds % TIME.SECONDS_PER_HOUR / TIME.SECONDS_PER_MINUTE);
1832
+ const secs = seconds % TIME.SECONDS_PER_MINUTE;
1833
+ const parts = [];
1834
+ if (hours > 0) {
1835
+ parts.push(`${hours}h`);
1836
+ parts.push(`${minutes}m`);
1837
+ parts.push(`${secs}s`);
1838
+ } else if (minutes > 0) {
1839
+ parts.push(`${minutes}m`);
1840
+ parts.push(`${secs}s`);
1841
+ } else {
1842
+ parts.push(`${secs}s`);
1843
+ }
1844
+ return parts.join(" ");
1845
+ }
1846
+ function formatCostUSD(usd) {
1847
+ return `$${usd.toFixed(2)}`;
1848
+ }
1849
+ function colorize2(text, color) {
1850
+ return `${color}${text}${ANSI_COLORS.RESET}`;
1851
+ }
1792
1852
  function formatK(n) {
1793
- if (n < 1e3) {
1853
+ const absN = Math.abs(n);
1854
+ if (absN < 1e3) {
1794
1855
  return n.toString();
1795
1856
  }
1796
1857
  const k = n / 1e3;
1797
- return k < 10 ? `${k.toFixed(1)}k` : `${Math.round(k)}k`;
1858
+ return Math.abs(k) < 10 ? `${k.toFixed(1)}k` : `${Math.round(k)}k`;
1798
1859
  }
1860
+
1861
+ // src/widgets/cache-metrics/styles.ts
1799
1862
  function formatCurrency(usd) {
1800
1863
  if (usd < 5e-3 && usd > 0) {
1801
1864
  return "<$0.01";
@@ -1926,8 +1989,9 @@ var CacheMetricsWidget = class extends StdinDataWidget {
1926
1989
  const cacheWrite = usage.cache_creation_input_tokens ?? 0;
1927
1990
  const inputTokens = usage.input_tokens ?? 0;
1928
1991
  const outputTokens = usage.output_tokens ?? 0;
1929
- const totalTokens = inputTokens + outputTokens;
1930
- const hitRate = inputTokens > 0 ? Math.round(cacheRead / inputTokens * 100) : 0;
1992
+ const totalInputTokens = cacheRead + cacheWrite + inputTokens;
1993
+ const totalTokens = totalInputTokens + outputTokens;
1994
+ const hitRate = totalInputTokens > 0 ? Math.min(100, Math.round(cacheRead / totalInputTokens * 100)) : 0;
1931
1995
  const costPerToken = 3e-6;
1932
1996
  const savings = cacheRead * 0.9 * costPerToken;
1933
1997
  return {
@@ -2350,33 +2414,6 @@ var ContextWidget = class extends StdinDataWidget {
2350
2414
  }
2351
2415
  };
2352
2416
 
2353
- // src/ui/utils/formatters.ts
2354
- function formatDuration(ms) {
2355
- if (ms <= 0) return "0s";
2356
- const seconds = Math.floor(ms / TIME.MS_PER_SECOND);
2357
- const hours = Math.floor(seconds / TIME.SECONDS_PER_HOUR);
2358
- const minutes = Math.floor(seconds % TIME.SECONDS_PER_HOUR / TIME.SECONDS_PER_MINUTE);
2359
- const secs = seconds % TIME.SECONDS_PER_MINUTE;
2360
- const parts = [];
2361
- if (hours > 0) {
2362
- parts.push(`${hours}h`);
2363
- parts.push(`${minutes}m`);
2364
- parts.push(`${secs}s`);
2365
- } else if (minutes > 0) {
2366
- parts.push(`${minutes}m`);
2367
- parts.push(`${secs}s`);
2368
- } else {
2369
- parts.push(`${secs}s`);
2370
- }
2371
- return parts.join(" ");
2372
- }
2373
- function formatCostUSD(usd) {
2374
- return `$${usd.toFixed(2)}`;
2375
- }
2376
- function colorize2(text, color) {
2377
- return `${color}${text}${ANSI_COLORS.RESET}`;
2378
- }
2379
-
2380
2417
  // src/widgets/cost/styles.ts
2381
2418
  var costStyles = {
2382
2419
  balanced: (data, colors) => {
@@ -3268,7 +3305,8 @@ function getStraightIndices(cards, highCard) {
3268
3305
  indices.push(cardIndicesByRank.get(next1)[0]);
3269
3306
  indices.push(cardIndicesByRank.get(next2)[0]);
3270
3307
  indices.push(cardIndicesByRank.get(next3)[0]);
3271
- indices.push(cardIndicesByRank.get(next4)[0]);
3308
+ const rank4 = next4 === 1 ? 14 : next4;
3309
+ indices.push(cardIndicesByRank.get(rank4)[0]);
3272
3310
  return indices;
3273
3311
  }
3274
3312
  }
@@ -3632,7 +3670,7 @@ var PokerWidget = class extends StdinDataWidget {
3632
3670
  async update(data) {
3633
3671
  await super.update(data);
3634
3672
  const now = Date.now();
3635
- if (now - this.lastUpdateTimestamp < this.THROTTLE_MS) {
3673
+ if (this.lastUpdateTimestamp > 0 && now - this.lastUpdateTimestamp < this.THROTTLE_MS) {
3636
3674
  return;
3637
3675
  }
3638
3676
  const deck = new Deck();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-scope",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
4
4
  "description": "Claude Code plugin for session status and analytics",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,7 +22,7 @@
22
22
  "test": "tsx --test tests/e2e/stdin-flow.test.ts tests/integration/cli-flow.integration.test.ts tests/integration/five-widgets.integration.test.ts tests/unit/cli.test.ts tests/unit/types.test.ts tests/unit/core/*.test.ts tests/unit/data/*.test.ts tests/unit/utils/*.test.ts tests/unit/widgets/*.test.ts tests/unit/ui/theme/*.test.ts",
23
23
  "test:unit": "tsx --test tests/unit/cli.test.ts tests/unit/types.test.ts tests/unit/core/*.test.ts tests/unit/data/*.test.ts tests/unit/utils/*.test.ts tests/unit/widgets/*.test.ts",
24
24
  "test:integration": "tsx --test tests/e2e/stdin-flow.test.ts tests/integration/cli-flow.integration.test.ts tests/integration/five-widgets.integration.test.ts",
25
- "test:coverage": "c8 --reporter=text --reporter=html --exclude='tests/**' --exclude='**/*.test.ts' tsx --test tests/e2e/stdin-flow.test.ts tests/integration/cli-flow.integration.test.ts tests/integration/five-widgets.integration.test.ts tests/unit/cli.test.ts tests/unit/types.test.ts tests/unit/core/*.test.ts tests/unit/data/*.test.ts tests/unit/utils/*.test.ts tests/unit/widgets/*.test.ts tests/unit/ui/theme/*.test.ts",
25
+ "test:coverage": "c8 --check-coverage --lines=80 --functions=75 --statements=80 --branches=65 --reporter=text --reporter=html --exclude='tests/**' --exclude='**/*.test.ts' tsx --test tests/e2e/stdin-flow.test.ts tests/integration/cli-flow.integration.test.ts tests/integration/five-widgets.integration.test.ts tests/unit/cli.test.ts tests/unit/types.test.ts tests/unit/core/*.test.ts tests/unit/data/*.test.ts tests/unit/utils/*.test.ts tests/unit/widgets/*.test.ts tests/unit/ui/theme/*.test.ts",
26
26
  "test:snapshot": "SNAPSHOT_UPDATE=true tsx --test tests/e2e/stdin-flow.test.ts tests/integration/cli-flow.integration.test.ts tests/integration/five-widgets.integration.test.ts tests/unit/cli.test.ts tests/unit/types.test.ts tests/unit/core/*.test.ts tests/unit/data/*.test.ts tests/unit/utils/*.test.ts tests/unit/widgets/*.test.ts",
27
27
  "test:snapshot:verify": "tsx --test tests/e2e/stdin-flow.test.ts tests/integration/cli-flow.integration.test.ts tests/integration/five-widgets.integration.test.ts tests/unit/cli.test.ts tests/unit/types.test.ts tests/unit/core/*.test.ts tests/unit/data/*.test.ts tests/unit/utils/*.test.ts tests/unit/widgets/*.test.ts",
28
28
  "dev": "tsx src/index.ts"