claude-scope 0.6.10 → 0.6.14
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/dist/claude-scope.cjs +244 -61
- package/package.json +12 -2
package/dist/claude-scope.cjs
CHANGED
|
@@ -102,7 +102,7 @@ var Renderer = class {
|
|
|
102
102
|
if (!lineMap.has(line)) {
|
|
103
103
|
lineMap.set(line, []);
|
|
104
104
|
}
|
|
105
|
-
lineMap.get(line)
|
|
105
|
+
lineMap.get(line)?.push(widget);
|
|
106
106
|
}
|
|
107
107
|
const lines = [];
|
|
108
108
|
const sortedLines = Array.from(lineMap.entries()).sort((a, b) => a[0] - b[0]);
|
|
@@ -392,8 +392,8 @@ var StdinProvider = class {
|
|
|
392
392
|
};
|
|
393
393
|
|
|
394
394
|
// src/providers/transcript-provider.ts
|
|
395
|
-
var
|
|
396
|
-
var
|
|
395
|
+
var import_node_fs = require("node:fs");
|
|
396
|
+
var import_node_readline = require("node:readline");
|
|
397
397
|
var TranscriptProvider = class {
|
|
398
398
|
MAX_TOOLS = 20;
|
|
399
399
|
/**
|
|
@@ -402,13 +402,13 @@ var TranscriptProvider = class {
|
|
|
402
402
|
* @returns Array of tool entries, limited to last 20
|
|
403
403
|
*/
|
|
404
404
|
async parseTools(transcriptPath) {
|
|
405
|
-
if (!(0,
|
|
405
|
+
if (!(0, import_node_fs.existsSync)(transcriptPath)) {
|
|
406
406
|
return [];
|
|
407
407
|
}
|
|
408
408
|
const toolMap = /* @__PURE__ */ new Map();
|
|
409
409
|
try {
|
|
410
|
-
const fileStream = (0,
|
|
411
|
-
const rl = (0,
|
|
410
|
+
const fileStream = (0, import_node_fs.createReadStream)(transcriptPath, { encoding: "utf-8" });
|
|
411
|
+
const rl = (0, import_node_readline.createInterface)({
|
|
412
412
|
input: fileStream,
|
|
413
413
|
crlfDelay: Infinity
|
|
414
414
|
});
|
|
@@ -487,7 +487,7 @@ var TranscriptProvider = class {
|
|
|
487
487
|
*/
|
|
488
488
|
truncateCommand(cmd) {
|
|
489
489
|
if (cmd.length <= 30) return cmd;
|
|
490
|
-
return cmd.slice(0, 30)
|
|
490
|
+
return `${cmd.slice(0, 30)}...`;
|
|
491
491
|
}
|
|
492
492
|
};
|
|
493
493
|
|
|
@@ -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:
|
|
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
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
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
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
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 "";
|
|
@@ -1758,7 +1793,7 @@ var ActiveToolsWidget = class extends StdinDataWidget {
|
|
|
1758
1793
|
* @param context - Render context
|
|
1759
1794
|
* @returns Rendered string or null if no tools
|
|
1760
1795
|
*/
|
|
1761
|
-
renderWithData(
|
|
1796
|
+
renderWithData(_data, _context) {
|
|
1762
1797
|
if (!this.renderData || this.tools.length === 0) {
|
|
1763
1798
|
return null;
|
|
1764
1799
|
}
|
|
@@ -1788,6 +1823,113 @@ function createWidgetMetadata(name, description, version = "1.0.0", author = "cl
|
|
|
1788
1823
|
};
|
|
1789
1824
|
}
|
|
1790
1825
|
|
|
1826
|
+
// src/storage/cache-manager.ts
|
|
1827
|
+
var import_node_fs2 = require("node:fs");
|
|
1828
|
+
var import_node_os = require("node:os");
|
|
1829
|
+
var import_node_path = require("node:path");
|
|
1830
|
+
var DEFAULT_CACHE_PATH = `${(0, import_node_os.homedir)()}/.config/claude-scope/cache.json`;
|
|
1831
|
+
var DEFAULT_EXPIRY_MS = 5 * 60 * 1e3;
|
|
1832
|
+
var CacheManager = class {
|
|
1833
|
+
cachePath;
|
|
1834
|
+
expiryMs;
|
|
1835
|
+
constructor(options) {
|
|
1836
|
+
this.cachePath = options?.cachePath ?? DEFAULT_CACHE_PATH;
|
|
1837
|
+
this.expiryMs = options?.expiryMs ?? DEFAULT_EXPIRY_MS;
|
|
1838
|
+
this.ensureCacheDir();
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Get cached usage data for a session
|
|
1842
|
+
* @param sessionId - Session identifier
|
|
1843
|
+
* @returns Cached usage if valid and not expired, null otherwise
|
|
1844
|
+
*/
|
|
1845
|
+
getCachedUsage(sessionId) {
|
|
1846
|
+
const cache = this.loadCache();
|
|
1847
|
+
const cached = cache.sessions[sessionId];
|
|
1848
|
+
if (!cached) {
|
|
1849
|
+
return null;
|
|
1850
|
+
}
|
|
1851
|
+
const age = Date.now() - cached.timestamp;
|
|
1852
|
+
if (age > this.expiryMs) {
|
|
1853
|
+
delete cache.sessions[sessionId];
|
|
1854
|
+
this.saveCache(cache);
|
|
1855
|
+
return null;
|
|
1856
|
+
}
|
|
1857
|
+
return cached;
|
|
1858
|
+
}
|
|
1859
|
+
/**
|
|
1860
|
+
* Store usage data for a session
|
|
1861
|
+
* @param sessionId - Session identifier
|
|
1862
|
+
* @param usage - Context usage data to cache
|
|
1863
|
+
*/
|
|
1864
|
+
setCachedUsage(sessionId, usage) {
|
|
1865
|
+
const cache = this.loadCache();
|
|
1866
|
+
cache.sessions[sessionId] = {
|
|
1867
|
+
timestamp: Date.now(),
|
|
1868
|
+
usage
|
|
1869
|
+
};
|
|
1870
|
+
this.saveCache(cache);
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Clear all cached data (useful for testing)
|
|
1874
|
+
*/
|
|
1875
|
+
clearCache() {
|
|
1876
|
+
const emptyCache = {
|
|
1877
|
+
sessions: {},
|
|
1878
|
+
version: 1
|
|
1879
|
+
};
|
|
1880
|
+
this.saveCache(emptyCache);
|
|
1881
|
+
}
|
|
1882
|
+
/**
|
|
1883
|
+
* Clean up expired sessions
|
|
1884
|
+
*/
|
|
1885
|
+
cleanupExpired() {
|
|
1886
|
+
const cache = this.loadCache();
|
|
1887
|
+
const now = Date.now();
|
|
1888
|
+
for (const [sessionId, cached] of Object.entries(cache.sessions)) {
|
|
1889
|
+
const age = now - cached.timestamp;
|
|
1890
|
+
if (age > this.expiryMs) {
|
|
1891
|
+
delete cache.sessions[sessionId];
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
this.saveCache(cache);
|
|
1895
|
+
}
|
|
1896
|
+
/**
|
|
1897
|
+
* Load cache from file
|
|
1898
|
+
*/
|
|
1899
|
+
loadCache() {
|
|
1900
|
+
if (!(0, import_node_fs2.existsSync)(this.cachePath)) {
|
|
1901
|
+
return { sessions: {}, version: 1 };
|
|
1902
|
+
}
|
|
1903
|
+
try {
|
|
1904
|
+
const content = (0, import_node_fs2.readFileSync)(this.cachePath, "utf-8");
|
|
1905
|
+
return JSON.parse(content);
|
|
1906
|
+
} catch {
|
|
1907
|
+
return { sessions: {}, version: 1 };
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
/**
|
|
1911
|
+
* Save cache to file
|
|
1912
|
+
*/
|
|
1913
|
+
saveCache(cache) {
|
|
1914
|
+
try {
|
|
1915
|
+
(0, import_node_fs2.writeFileSync)(this.cachePath, JSON.stringify(cache, null, 2), "utf-8");
|
|
1916
|
+
} catch {
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* Ensure cache directory exists
|
|
1921
|
+
*/
|
|
1922
|
+
ensureCacheDir() {
|
|
1923
|
+
try {
|
|
1924
|
+
const dir = (0, import_node_path.dirname)(this.cachePath);
|
|
1925
|
+
if (!(0, import_node_fs2.existsSync)(dir)) {
|
|
1926
|
+
(0, import_node_fs2.mkdirSync)(dir, { recursive: true });
|
|
1927
|
+
}
|
|
1928
|
+
} catch {
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1791
1933
|
// src/ui/utils/formatters.ts
|
|
1792
1934
|
function formatDuration(ms) {
|
|
1793
1935
|
if (ms <= 0) return "0s";
|
|
@@ -1931,9 +2073,11 @@ var CacheMetricsWidget = class extends StdinDataWidget {
|
|
|
1931
2073
|
theme;
|
|
1932
2074
|
style = "balanced";
|
|
1933
2075
|
renderData;
|
|
2076
|
+
cacheManager;
|
|
1934
2077
|
constructor(theme) {
|
|
1935
2078
|
super();
|
|
1936
2079
|
this.theme = theme ?? DEFAULT_THEME;
|
|
2080
|
+
this.cacheManager = new CacheManager();
|
|
1937
2081
|
}
|
|
1938
2082
|
/**
|
|
1939
2083
|
* Set display style
|
|
@@ -1943,10 +2087,16 @@ var CacheMetricsWidget = class extends StdinDataWidget {
|
|
|
1943
2087
|
}
|
|
1944
2088
|
/**
|
|
1945
2089
|
* Calculate cache metrics from context usage data
|
|
1946
|
-
* Returns null if no usage data is available
|
|
2090
|
+
* Returns null if no usage data is available (current or cached)
|
|
1947
2091
|
*/
|
|
1948
2092
|
calculateMetrics(data) {
|
|
1949
|
-
|
|
2093
|
+
let usage = data.context_window?.current_usage;
|
|
2094
|
+
if (!usage) {
|
|
2095
|
+
const cached = this.cacheManager.getCachedUsage(data.session_id);
|
|
2096
|
+
if (cached) {
|
|
2097
|
+
usage = cached.usage;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
1950
2100
|
if (!usage) {
|
|
1951
2101
|
return null;
|
|
1952
2102
|
}
|
|
@@ -1969,9 +2119,19 @@ var CacheMetricsWidget = class extends StdinDataWidget {
|
|
|
1969
2119
|
}
|
|
1970
2120
|
/**
|
|
1971
2121
|
* Update widget with new data and calculate metrics
|
|
2122
|
+
* Stores valid usage data in cache for future use
|
|
1972
2123
|
*/
|
|
1973
2124
|
async update(data) {
|
|
1974
2125
|
await super.update(data);
|
|
2126
|
+
const usage = data.context_window?.current_usage;
|
|
2127
|
+
if (usage) {
|
|
2128
|
+
this.cacheManager.setCachedUsage(data.session_id, {
|
|
2129
|
+
input_tokens: usage.input_tokens,
|
|
2130
|
+
output_tokens: usage.output_tokens,
|
|
2131
|
+
cache_creation_input_tokens: usage.cache_creation_input_tokens,
|
|
2132
|
+
cache_read_input_tokens: usage.cache_read_input_tokens
|
|
2133
|
+
});
|
|
2134
|
+
}
|
|
1975
2135
|
const metrics = this.calculateMetrics(data);
|
|
1976
2136
|
this.renderData = metrics ?? void 0;
|
|
1977
2137
|
}
|
|
@@ -2000,9 +2160,9 @@ var CacheMetricsWidget = class extends StdinDataWidget {
|
|
|
2000
2160
|
var DEFAULT_WIDGET_STYLE = "balanced";
|
|
2001
2161
|
|
|
2002
2162
|
// src/providers/config-provider.ts
|
|
2003
|
-
var fs = __toESM(require("fs/promises"), 1);
|
|
2004
|
-
var os = __toESM(require("os"), 1);
|
|
2005
|
-
var path = __toESM(require("path"), 1);
|
|
2163
|
+
var fs = __toESM(require("node:fs/promises"), 1);
|
|
2164
|
+
var os = __toESM(require("node:os"), 1);
|
|
2165
|
+
var path = __toESM(require("node:path"), 1);
|
|
2006
2166
|
var ConfigProvider = class {
|
|
2007
2167
|
cachedCounts;
|
|
2008
2168
|
lastScan = 0;
|
|
@@ -2253,7 +2413,7 @@ var ConfigCountWidget = class {
|
|
|
2253
2413
|
const { claudeMdCount, rulesCount, mcpCount, hooksCount } = this.configs;
|
|
2254
2414
|
return claudeMdCount > 0 || rulesCount > 0 || mcpCount > 0 || hooksCount > 0;
|
|
2255
2415
|
}
|
|
2256
|
-
async render(
|
|
2416
|
+
async render(_context) {
|
|
2257
2417
|
if (!this.configs) {
|
|
2258
2418
|
return null;
|
|
2259
2419
|
}
|
|
@@ -2312,7 +2472,7 @@ var contextStyles = {
|
|
|
2312
2472
|
const bar = progressBar(data.percent, 10);
|
|
2313
2473
|
const output = `\u{1F9E0} [${bar}] ${data.percent}%`;
|
|
2314
2474
|
if (!colors) return output;
|
|
2315
|
-
return `\u{1F9E0}
|
|
2475
|
+
return `\u{1F9E0} ${colorize(`[${bar}] ${data.percent}%`, getContextColor(data.percent, colors))}`;
|
|
2316
2476
|
},
|
|
2317
2477
|
verbose: (data, colors) => {
|
|
2318
2478
|
const usedFormatted = data.used.toLocaleString();
|
|
@@ -2355,9 +2515,11 @@ var ContextWidget = class extends StdinDataWidget {
|
|
|
2355
2515
|
);
|
|
2356
2516
|
colors;
|
|
2357
2517
|
styleFn = contextStyles.balanced;
|
|
2518
|
+
cacheManager;
|
|
2358
2519
|
constructor(colors) {
|
|
2359
2520
|
super();
|
|
2360
2521
|
this.colors = colors ?? DEFAULT_THEME;
|
|
2522
|
+
this.cacheManager = new CacheManager();
|
|
2361
2523
|
}
|
|
2362
2524
|
setStyle(style = "balanced") {
|
|
2363
2525
|
const fn = contextStyles[style];
|
|
@@ -2365,10 +2527,32 @@ var ContextWidget = class extends StdinDataWidget {
|
|
|
2365
2527
|
this.styleFn = fn;
|
|
2366
2528
|
}
|
|
2367
2529
|
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Update widget with new data, storing valid values in cache
|
|
2532
|
+
*/
|
|
2533
|
+
async update(data) {
|
|
2534
|
+
await super.update(data);
|
|
2535
|
+
const { current_usage } = data.context_window;
|
|
2536
|
+
if (current_usage) {
|
|
2537
|
+
this.cacheManager.setCachedUsage(data.session_id, {
|
|
2538
|
+
input_tokens: current_usage.input_tokens,
|
|
2539
|
+
output_tokens: current_usage.output_tokens,
|
|
2540
|
+
cache_creation_input_tokens: current_usage.cache_creation_input_tokens,
|
|
2541
|
+
cache_read_input_tokens: current_usage.cache_read_input_tokens
|
|
2542
|
+
});
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2368
2545
|
renderWithData(data, _context) {
|
|
2369
2546
|
const { current_usage, context_window_size } = data.context_window;
|
|
2370
|
-
|
|
2371
|
-
|
|
2547
|
+
let usage = current_usage;
|
|
2548
|
+
if (!usage) {
|
|
2549
|
+
const cached = this.cacheManager.getCachedUsage(data.session_id);
|
|
2550
|
+
if (cached) {
|
|
2551
|
+
usage = cached.usage;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
if (!usage) return null;
|
|
2555
|
+
const used = usage.input_tokens + usage.cache_creation_input_tokens + usage.cache_read_input_tokens + usage.output_tokens;
|
|
2372
2556
|
const percent = Math.round(used / context_window_size * 100);
|
|
2373
2557
|
const renderData = {
|
|
2374
2558
|
used,
|
|
@@ -2377,19 +2561,21 @@ var ContextWidget = class extends StdinDataWidget {
|
|
|
2377
2561
|
};
|
|
2378
2562
|
return this.styleFn(renderData, this.colors.context);
|
|
2379
2563
|
}
|
|
2564
|
+
isEnabled() {
|
|
2565
|
+
return true;
|
|
2566
|
+
}
|
|
2380
2567
|
};
|
|
2381
2568
|
|
|
2382
2569
|
// src/widgets/cost/styles.ts
|
|
2570
|
+
function balancedStyle(data, colors) {
|
|
2571
|
+
const formatted = formatCostUSD(data.costUsd);
|
|
2572
|
+
if (!colors) return formatted;
|
|
2573
|
+
const amountStr = data.costUsd.toFixed(2);
|
|
2574
|
+
return colorize("$", colors.currency) + colorize(amountStr, colors.amount);
|
|
2575
|
+
}
|
|
2383
2576
|
var costStyles = {
|
|
2384
|
-
balanced:
|
|
2385
|
-
|
|
2386
|
-
if (!colors) return formatted;
|
|
2387
|
-
const amountStr = data.costUsd.toFixed(2);
|
|
2388
|
-
return colorize("$", colors.currency) + colorize(amountStr, colors.amount);
|
|
2389
|
-
},
|
|
2390
|
-
compact: (data, colors) => {
|
|
2391
|
-
return costStyles.balanced(data, colors);
|
|
2392
|
-
},
|
|
2577
|
+
balanced: balancedStyle,
|
|
2578
|
+
compact: balancedStyle,
|
|
2393
2579
|
playful: (data, colors) => {
|
|
2394
2580
|
const formatted = formatCostUSD(data.costUsd);
|
|
2395
2581
|
if (!colors) return `\u{1F4B0} ${formatted}`;
|
|
@@ -2481,7 +2667,7 @@ var durationStyles = {
|
|
|
2481
2667
|
const colored = colorize(`${hours}`, colors.value) + colorize("h", colors.unit) + colorize(` ${minutes}`, colors.value) + colorize("m", colors.unit);
|
|
2482
2668
|
return `\u231B ${colored}`;
|
|
2483
2669
|
}
|
|
2484
|
-
return `\u231B
|
|
2670
|
+
return `\u231B ${colorize(`${minutes}`, colors.value)}${colorize("m", colors.unit)}`;
|
|
2485
2671
|
},
|
|
2486
2672
|
technical: (data, colors) => {
|
|
2487
2673
|
const value = `${Math.floor(data.durationMs)}ms`;
|
|
@@ -2712,7 +2898,7 @@ var GitTagWidget = class {
|
|
|
2712
2898
|
async initialize(context) {
|
|
2713
2899
|
this.enabled = context.config?.enabled !== false;
|
|
2714
2900
|
}
|
|
2715
|
-
async render(
|
|
2901
|
+
async render(_context) {
|
|
2716
2902
|
if (!this.enabled || !this.git || !this.cwd) {
|
|
2717
2903
|
return null;
|
|
2718
2904
|
}
|
|
@@ -2861,7 +3047,7 @@ var GitWidget = class {
|
|
|
2861
3047
|
async initialize(context) {
|
|
2862
3048
|
this.enabled = context.config?.enabled !== false;
|
|
2863
3049
|
}
|
|
2864
|
-
async render(
|
|
3050
|
+
async render(_context) {
|
|
2865
3051
|
if (!this.enabled || !this.git || !this.cwd) {
|
|
2866
3052
|
return null;
|
|
2867
3053
|
}
|
|
@@ -3251,7 +3437,7 @@ function getStraightIndices(cards, highCard) {
|
|
|
3251
3437
|
cardIndicesByRank.set(value, []);
|
|
3252
3438
|
uniqueValues.add(value);
|
|
3253
3439
|
}
|
|
3254
|
-
cardIndicesByRank.get(value)
|
|
3440
|
+
cardIndicesByRank.get(value)?.push(i);
|
|
3255
3441
|
}
|
|
3256
3442
|
const sortedValues = Array.from(uniqueValues).sort((a, b) => b - a);
|
|
3257
3443
|
if (sortedValues.includes(14)) {
|
|
@@ -3283,7 +3469,7 @@ function getStraightFlushHighCard(cards, suit) {
|
|
|
3283
3469
|
return getStraightHighCard(suitCards);
|
|
3284
3470
|
}
|
|
3285
3471
|
function getStraightFlushIndices(cards, highCard, suit) {
|
|
3286
|
-
const
|
|
3472
|
+
const _suitCards = cards.filter((c) => c.suit === suit);
|
|
3287
3473
|
const suitCardIndices = [];
|
|
3288
3474
|
const indexMap = /* @__PURE__ */ new Map();
|
|
3289
3475
|
for (let i = 0; i < cards.length; i++) {
|
|
@@ -3561,23 +3747,20 @@ function getHandAbbreviation(handResult) {
|
|
|
3561
3747
|
const abbreviation = HAND_ABBREVIATIONS[handResult.name] ?? "\u2014";
|
|
3562
3748
|
return `${abbreviation} (${handResult.name})`;
|
|
3563
3749
|
}
|
|
3750
|
+
function balancedStyle2(data, colors) {
|
|
3751
|
+
const { holeCards, boardCards, handResult } = data;
|
|
3752
|
+
const participatingSet = new Set(handResult?.participatingIndices || []);
|
|
3753
|
+
const handStr = holeCards.map((hc, idx) => formatCardByParticipation(hc, participatingSet.has(idx))).join("");
|
|
3754
|
+
const boardStr = boardCards.map((bc, idx) => formatCardByParticipation(bc, participatingSet.has(idx + 2))).join("");
|
|
3755
|
+
const labelColor = colors?.participating ?? lightGray;
|
|
3756
|
+
const handLabel = colorize2("Hand:", labelColor);
|
|
3757
|
+
const boardLabel = colorize2("Board:", labelColor);
|
|
3758
|
+
return `${handLabel} ${handStr}| ${boardLabel} ${boardStr}\u2192 ${formatHandResult(handResult, colors)}`;
|
|
3759
|
+
}
|
|
3564
3760
|
var pokerStyles = {
|
|
3565
|
-
balanced:
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
const handStr = holeCards.map((hc, idx) => formatCardByParticipation(hc, participatingSet.has(idx))).join("");
|
|
3569
|
-
const boardStr = boardCards.map((bc, idx) => formatCardByParticipation(bc, participatingSet.has(idx + 2))).join("");
|
|
3570
|
-
const labelColor = colors?.participating ?? lightGray;
|
|
3571
|
-
const handLabel = colorize2("Hand:", labelColor);
|
|
3572
|
-
const boardLabel = colorize2("Board:", labelColor);
|
|
3573
|
-
return `${handLabel} ${handStr}| ${boardLabel} ${boardStr}\u2192 ${formatHandResult(handResult, colors)}`;
|
|
3574
|
-
},
|
|
3575
|
-
compact: (data, colors) => {
|
|
3576
|
-
return pokerStyles.balanced(data, colors);
|
|
3577
|
-
},
|
|
3578
|
-
playful: (data, colors) => {
|
|
3579
|
-
return pokerStyles.balanced(data, colors);
|
|
3580
|
-
},
|
|
3761
|
+
balanced: balancedStyle2,
|
|
3762
|
+
compact: balancedStyle2,
|
|
3763
|
+
playful: balancedStyle2,
|
|
3581
3764
|
"compact-verbose": (data, colors) => {
|
|
3582
3765
|
const { holeCards, boardCards, handResult } = data;
|
|
3583
3766
|
const participatingSet = new Set(handResult?.participatingIndices || []);
|
|
@@ -3668,7 +3851,7 @@ var PokerWidget = class extends StdinDataWidget {
|
|
|
3668
3851
|
* Format card with appropriate color (red for ♥♦, gray for ♠♣)
|
|
3669
3852
|
*/
|
|
3670
3853
|
formatCardColor(card) {
|
|
3671
|
-
const
|
|
3854
|
+
const _color = isRedSuit(card.suit) ? "red" : "gray";
|
|
3672
3855
|
return formatCard(card);
|
|
3673
3856
|
}
|
|
3674
3857
|
renderWithData(_data, _context) {
|
|
@@ -3739,7 +3922,7 @@ async function main() {
|
|
|
3739
3922
|
await registry.register(new EmptyLineWidget());
|
|
3740
3923
|
const renderer = new Renderer({
|
|
3741
3924
|
separator: " \u2502 ",
|
|
3742
|
-
onError: (
|
|
3925
|
+
onError: (_error, _widget) => {
|
|
3743
3926
|
},
|
|
3744
3927
|
showErrors: false
|
|
3745
3928
|
});
|
|
@@ -3751,7 +3934,7 @@ async function main() {
|
|
|
3751
3934
|
timestamp: Date.now()
|
|
3752
3935
|
});
|
|
3753
3936
|
return lines.join("\n");
|
|
3754
|
-
} catch (
|
|
3937
|
+
} catch (_error) {
|
|
3755
3938
|
const fallback = await tryGitFallback();
|
|
3756
3939
|
return fallback;
|
|
3757
3940
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-scope",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14",
|
|
4
4
|
"description": "Claude Code plugin for session status and analytics",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -25,7 +25,10 @@
|
|
|
25
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
|
-
"dev": "tsx src/index.ts"
|
|
28
|
+
"dev": "tsx src/index.ts",
|
|
29
|
+
"prepare": "husky",
|
|
30
|
+
"lint": "biome check .",
|
|
31
|
+
"lint:fix": "biome check --write ."
|
|
29
32
|
},
|
|
30
33
|
"devDependencies": {
|
|
31
34
|
"@biomejs/biome": "^2.3.11",
|
|
@@ -33,11 +36,18 @@
|
|
|
33
36
|
"c8": "^10.1.3",
|
|
34
37
|
"chai": "^6.2.2",
|
|
35
38
|
"esbuild": "^0.24.2",
|
|
39
|
+
"husky": "^9.1.7",
|
|
40
|
+
"lint-staged": "^16.2.7",
|
|
36
41
|
"rimraf": "^6.1.2",
|
|
37
42
|
"tsx": "^4.19.2",
|
|
38
43
|
"typescript": "^5.7.2"
|
|
39
44
|
},
|
|
40
45
|
"engines": {
|
|
41
46
|
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"lint-staged": {
|
|
49
|
+
"*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [
|
|
50
|
+
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
|
|
51
|
+
]
|
|
42
52
|
}
|
|
43
53
|
}
|