claude-scope 0.8.34 → 0.8.35
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 +137 -43
- package/package.json +1 -1
package/dist/claude-scope.cjs
CHANGED
|
@@ -2414,12 +2414,12 @@ var init_widget_types = __esm({
|
|
|
2414
2414
|
});
|
|
2415
2415
|
|
|
2416
2416
|
// src/providers/usage-parser.ts
|
|
2417
|
-
var
|
|
2417
|
+
var import_fs, import_readline, UsageParser;
|
|
2418
2418
|
var init_usage_parser = __esm({
|
|
2419
2419
|
"src/providers/usage-parser.ts"() {
|
|
2420
2420
|
"use strict";
|
|
2421
|
-
|
|
2422
|
-
|
|
2421
|
+
import_fs = require("fs");
|
|
2422
|
+
import_readline = require("readline");
|
|
2423
2423
|
UsageParser = class {
|
|
2424
2424
|
/**
|
|
2425
2425
|
* Parse the last assistant message with usage data from transcript
|
|
@@ -2429,30 +2429,55 @@ var init_usage_parser = __esm({
|
|
|
2429
2429
|
* @returns ContextUsage or null if not found
|
|
2430
2430
|
*/
|
|
2431
2431
|
async parseLastUsage(transcriptPath) {
|
|
2432
|
-
if (!(0,
|
|
2432
|
+
if (!(0, import_fs.existsSync)(transcriptPath)) {
|
|
2433
2433
|
return null;
|
|
2434
2434
|
}
|
|
2435
2435
|
try {
|
|
2436
2436
|
const lines = await this.readAllLines(transcriptPath);
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2437
|
+
let mostRecentUsage = null;
|
|
2438
|
+
let mostRecentTimestamp = null;
|
|
2439
|
+
let hasAnyTimestamp = false;
|
|
2440
|
+
for (const line of lines) {
|
|
2441
|
+
const entry = this.parseLineForUsage(line);
|
|
2442
|
+
if (entry) {
|
|
2443
|
+
const entryTime = this.parseTimestamp(line);
|
|
2444
|
+
if (entryTime) {
|
|
2445
|
+
hasAnyTimestamp = true;
|
|
2446
|
+
if (!mostRecentTimestamp || entryTime > mostRecentTimestamp) {
|
|
2447
|
+
mostRecentUsage = entry;
|
|
2448
|
+
mostRecentTimestamp = entryTime;
|
|
2449
|
+
}
|
|
2450
|
+
} else if (!hasAnyTimestamp) {
|
|
2451
|
+
mostRecentUsage = entry;
|
|
2452
|
+
}
|
|
2441
2453
|
}
|
|
2442
2454
|
}
|
|
2443
|
-
return
|
|
2455
|
+
return mostRecentUsage;
|
|
2444
2456
|
} catch {
|
|
2445
2457
|
return null;
|
|
2446
2458
|
}
|
|
2447
2459
|
}
|
|
2460
|
+
/**
|
|
2461
|
+
* Parse timestamp from a transcript line
|
|
2462
|
+
*/
|
|
2463
|
+
parseTimestamp(line) {
|
|
2464
|
+
try {
|
|
2465
|
+
const entry = JSON.parse(line);
|
|
2466
|
+
if (entry.timestamp) {
|
|
2467
|
+
return new Date(entry.timestamp);
|
|
2468
|
+
}
|
|
2469
|
+
} catch {
|
|
2470
|
+
}
|
|
2471
|
+
return null;
|
|
2472
|
+
}
|
|
2448
2473
|
/**
|
|
2449
2474
|
* Read all lines from transcript file
|
|
2450
2475
|
*/
|
|
2451
2476
|
async readAllLines(transcriptPath) {
|
|
2452
2477
|
const lines = [];
|
|
2453
2478
|
try {
|
|
2454
|
-
const fileStream = (0,
|
|
2455
|
-
const rl = (0,
|
|
2479
|
+
const fileStream = (0, import_fs.createReadStream)(transcriptPath, { encoding: "utf-8" });
|
|
2480
|
+
const rl = (0, import_readline.createInterface)({
|
|
2456
2481
|
input: fileStream,
|
|
2457
2482
|
crlfDelay: Infinity
|
|
2458
2483
|
});
|
|
@@ -2466,6 +2491,63 @@ var init_usage_parser = __esm({
|
|
|
2466
2491
|
}
|
|
2467
2492
|
return lines;
|
|
2468
2493
|
}
|
|
2494
|
+
/**
|
|
2495
|
+
* Parse cumulative cache tokens from all assistant messages in transcript
|
|
2496
|
+
* Sums ALL cache_read and cache_creation tokens across the entire session
|
|
2497
|
+
*
|
|
2498
|
+
* @param transcriptPath - Path to the JSONL transcript file
|
|
2499
|
+
* @returns Object with cumulative cacheRead and cacheCreation, or null if not found
|
|
2500
|
+
*/
|
|
2501
|
+
async parseCumulativeCache(transcriptPath) {
|
|
2502
|
+
if (!(0, import_fs.existsSync)(transcriptPath)) {
|
|
2503
|
+
return null;
|
|
2504
|
+
}
|
|
2505
|
+
try {
|
|
2506
|
+
const lines = await this.readAllLines(transcriptPath);
|
|
2507
|
+
let cumulativeCacheRead = 0;
|
|
2508
|
+
let cumulativeCacheCreation = 0;
|
|
2509
|
+
for (const line of lines) {
|
|
2510
|
+
const entry = this.parseLineForCache(line);
|
|
2511
|
+
if (entry) {
|
|
2512
|
+
cumulativeCacheRead += entry.cacheRead;
|
|
2513
|
+
cumulativeCacheCreation += entry.cacheCreation;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
if (cumulativeCacheRead === 0 && cumulativeCacheCreation === 0) {
|
|
2517
|
+
return null;
|
|
2518
|
+
}
|
|
2519
|
+
return {
|
|
2520
|
+
cacheRead: cumulativeCacheRead,
|
|
2521
|
+
cacheCreation: cumulativeCacheCreation
|
|
2522
|
+
};
|
|
2523
|
+
} catch {
|
|
2524
|
+
return null;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
/**
|
|
2528
|
+
* Parse a single transcript line for cache data
|
|
2529
|
+
* Returns null if line is not an assistant message with usage
|
|
2530
|
+
*/
|
|
2531
|
+
parseLineForCache(line) {
|
|
2532
|
+
try {
|
|
2533
|
+
const entry = JSON.parse(line);
|
|
2534
|
+
if (entry.type !== "assistant") {
|
|
2535
|
+
return null;
|
|
2536
|
+
}
|
|
2537
|
+
const usage = entry.message?.usage;
|
|
2538
|
+
if (!usage) {
|
|
2539
|
+
return null;
|
|
2540
|
+
}
|
|
2541
|
+
const cacheRead = usage.cache_read_input_tokens ?? 0;
|
|
2542
|
+
const cacheCreation = usage.cache_creation_input_tokens ?? 0;
|
|
2543
|
+
if (cacheRead === 0 && cacheCreation === 0) {
|
|
2544
|
+
return null;
|
|
2545
|
+
}
|
|
2546
|
+
return { cacheRead, cacheCreation };
|
|
2547
|
+
} catch {
|
|
2548
|
+
return null;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2469
2551
|
/**
|
|
2470
2552
|
* Parse a single transcript line for usage data
|
|
2471
2553
|
* Returns null if line is not an assistant message with usage
|
|
@@ -2480,14 +2562,15 @@ var init_usage_parser = __esm({
|
|
|
2480
2562
|
if (!usage) {
|
|
2481
2563
|
return null;
|
|
2482
2564
|
}
|
|
2483
|
-
if (typeof usage.input_tokens !== "number" || typeof usage.output_tokens !== "number"
|
|
2565
|
+
if (typeof usage.input_tokens !== "number" || typeof usage.output_tokens !== "number") {
|
|
2484
2566
|
return null;
|
|
2485
2567
|
}
|
|
2486
2568
|
return {
|
|
2487
2569
|
input_tokens: usage.input_tokens,
|
|
2488
2570
|
output_tokens: usage.output_tokens,
|
|
2489
2571
|
cache_creation_input_tokens: usage.cache_creation_input_tokens ?? 0,
|
|
2490
|
-
cache_read_input_tokens: usage.cache_read_input_tokens
|
|
2572
|
+
cache_read_input_tokens: usage.cache_read_input_tokens ?? 0
|
|
2573
|
+
// Default to 0 if missing
|
|
2491
2574
|
};
|
|
2492
2575
|
} catch {
|
|
2493
2576
|
return null;
|
|
@@ -2498,11 +2581,11 @@ var init_usage_parser = __esm({
|
|
|
2498
2581
|
});
|
|
2499
2582
|
|
|
2500
2583
|
// src/storage/cache-manager.ts
|
|
2501
|
-
var
|
|
2584
|
+
var import_node_fs, import_node_os2, import_node_path2, DEFAULT_CACHE_PATH, DEFAULT_EXPIRY_MS, CacheManager;
|
|
2502
2585
|
var init_cache_manager = __esm({
|
|
2503
2586
|
"src/storage/cache-manager.ts"() {
|
|
2504
2587
|
"use strict";
|
|
2505
|
-
|
|
2588
|
+
import_node_fs = require("node:fs");
|
|
2506
2589
|
import_node_os2 = require("node:os");
|
|
2507
2590
|
import_node_path2 = require("node:path");
|
|
2508
2591
|
DEFAULT_CACHE_PATH = `${(0, import_node_os2.homedir)()}/.config/claude-scope/cache.json`;
|
|
@@ -2575,11 +2658,11 @@ var init_cache_manager = __esm({
|
|
|
2575
2658
|
* Load cache from file
|
|
2576
2659
|
*/
|
|
2577
2660
|
loadCache() {
|
|
2578
|
-
if (!(0,
|
|
2661
|
+
if (!(0, import_node_fs.existsSync)(this.cachePath)) {
|
|
2579
2662
|
return { sessions: {}, version: 1 };
|
|
2580
2663
|
}
|
|
2581
2664
|
try {
|
|
2582
|
-
const content = (0,
|
|
2665
|
+
const content = (0, import_node_fs.readFileSync)(this.cachePath, "utf-8");
|
|
2583
2666
|
return JSON.parse(content);
|
|
2584
2667
|
} catch {
|
|
2585
2668
|
return { sessions: {}, version: 1 };
|
|
@@ -2590,7 +2673,7 @@ var init_cache_manager = __esm({
|
|
|
2590
2673
|
*/
|
|
2591
2674
|
saveCache(cache) {
|
|
2592
2675
|
try {
|
|
2593
|
-
(0,
|
|
2676
|
+
(0, import_node_fs.writeFileSync)(this.cachePath, JSON.stringify(cache, null, 2), "utf-8");
|
|
2594
2677
|
} catch {
|
|
2595
2678
|
}
|
|
2596
2679
|
}
|
|
@@ -2600,8 +2683,8 @@ var init_cache_manager = __esm({
|
|
|
2600
2683
|
ensureCacheDir() {
|
|
2601
2684
|
try {
|
|
2602
2685
|
const dir = (0, import_node_path2.dirname)(this.cachePath);
|
|
2603
|
-
if (!(0,
|
|
2604
|
-
(0,
|
|
2686
|
+
if (!(0, import_node_fs.existsSync)(dir)) {
|
|
2687
|
+
(0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
2605
2688
|
}
|
|
2606
2689
|
} catch {
|
|
2607
2690
|
}
|
|
@@ -2773,6 +2856,8 @@ var init_cache_metrics_widget = __esm({
|
|
|
2773
2856
|
lastSessionId;
|
|
2774
2857
|
cachedUsage;
|
|
2775
2858
|
// Cache parsed usage within render cycle
|
|
2859
|
+
cachedCumulativeCache;
|
|
2860
|
+
// Cumulative cache for session
|
|
2776
2861
|
constructor(theme) {
|
|
2777
2862
|
super();
|
|
2778
2863
|
this.theme = theme ?? DEFAULT_THEME;
|
|
@@ -2794,9 +2879,14 @@ var init_cache_metrics_widget = __esm({
|
|
|
2794
2879
|
/**
|
|
2795
2880
|
* Calculate cache metrics from context usage data
|
|
2796
2881
|
* Returns zero metrics if no usage data is available (widget should always be visible)
|
|
2882
|
+
*
|
|
2883
|
+
* @param usage - Current usage data (for total tokens calculation)
|
|
2884
|
+
* @param cumulativeCache - Cumulative cache data for the session (optional)
|
|
2797
2885
|
*/
|
|
2798
|
-
calculateMetrics(usage) {
|
|
2799
|
-
|
|
2886
|
+
calculateMetrics(usage, cumulativeCache) {
|
|
2887
|
+
const cacheRead = cumulativeCache?.cacheRead ?? usage?.cache_read_input_tokens ?? 0;
|
|
2888
|
+
const cacheWrite = cumulativeCache?.cacheCreation ?? usage?.cache_creation_input_tokens ?? 0;
|
|
2889
|
+
if (!usage && !cumulativeCache) {
|
|
2800
2890
|
return {
|
|
2801
2891
|
cacheRead: 0,
|
|
2802
2892
|
cacheWrite: 0,
|
|
@@ -2805,10 +2895,8 @@ var init_cache_metrics_widget = __esm({
|
|
|
2805
2895
|
savings: 0
|
|
2806
2896
|
};
|
|
2807
2897
|
}
|
|
2808
|
-
const
|
|
2809
|
-
const
|
|
2810
|
-
const inputTokens = usage.input_tokens ?? 0;
|
|
2811
|
-
const outputTokens = usage.output_tokens ?? 0;
|
|
2898
|
+
const inputTokens = usage?.input_tokens ?? 0;
|
|
2899
|
+
const outputTokens = usage?.output_tokens ?? 0;
|
|
2812
2900
|
const totalInputTokens = cacheRead + cacheWrite + inputTokens;
|
|
2813
2901
|
const totalTokens = totalInputTokens + outputTokens;
|
|
2814
2902
|
const hitRate = totalInputTokens > 0 ? Math.min(100, Math.round(cacheRead / totalInputTokens * 100)) : 0;
|
|
@@ -2845,18 +2933,21 @@ var init_cache_metrics_widget = __esm({
|
|
|
2845
2933
|
});
|
|
2846
2934
|
}
|
|
2847
2935
|
}
|
|
2848
|
-
|
|
2936
|
+
const hasRealUsage = usage && ((usage.input_tokens ?? 0) > 0 || (usage.output_tokens ?? 0) > 0 || (usage.cache_read_input_tokens ?? 0) > 0 || (usage.cache_creation_input_tokens ?? 0) > 0);
|
|
2937
|
+
if (!usage || !hasRealUsage) {
|
|
2849
2938
|
this.cachedUsage = await this.usageParser.parseLastUsage(data.transcript_path);
|
|
2850
2939
|
} else {
|
|
2851
2940
|
this.cachedUsage = void 0;
|
|
2852
2941
|
}
|
|
2942
|
+
this.cachedCumulativeCache = await this.usageParser.parseCumulativeCache(data.transcript_path);
|
|
2853
2943
|
}
|
|
2854
2944
|
/**
|
|
2855
2945
|
* Render the cache metrics display
|
|
2856
2946
|
*/
|
|
2857
2947
|
renderWithData(data, _context) {
|
|
2858
2948
|
let usage = data.context_window?.current_usage;
|
|
2859
|
-
|
|
2949
|
+
const hasRealUsage = usage && ((usage.input_tokens ?? 0) > 0 || (usage.output_tokens ?? 0) > 0 || (usage.cache_read_input_tokens ?? 0) > 0 || (usage.cache_creation_input_tokens ?? 0) > 0);
|
|
2950
|
+
if ((!usage || !hasRealUsage) && this.cachedUsage) {
|
|
2860
2951
|
usage = this.cachedUsage;
|
|
2861
2952
|
}
|
|
2862
2953
|
if (!usage) {
|
|
@@ -2865,7 +2956,8 @@ var init_cache_metrics_widget = __esm({
|
|
|
2865
2956
|
usage = cached.usage;
|
|
2866
2957
|
}
|
|
2867
2958
|
}
|
|
2868
|
-
const
|
|
2959
|
+
const cumulativeCacheToUse = this.cachedCumulativeCache;
|
|
2960
|
+
const metrics = this.calculateMetrics(usage, cumulativeCacheToUse);
|
|
2869
2961
|
if (!metrics) {
|
|
2870
2962
|
return null;
|
|
2871
2963
|
}
|
|
@@ -3416,7 +3508,8 @@ var init_context_widget = __esm({
|
|
|
3416
3508
|
});
|
|
3417
3509
|
}
|
|
3418
3510
|
}
|
|
3419
|
-
|
|
3511
|
+
const hasRealUsage = current_usage && ((current_usage.input_tokens ?? 0) > 0 || (current_usage.output_tokens ?? 0) > 0 || (current_usage.cache_read_input_tokens ?? 0) > 0 || (current_usage.cache_creation_input_tokens ?? 0) > 0);
|
|
3512
|
+
if (!current_usage || !hasRealUsage) {
|
|
3420
3513
|
this.cachedUsage = await this.usageParser.parseLastUsage(data.transcript_path);
|
|
3421
3514
|
} else {
|
|
3422
3515
|
this.cachedUsage = void 0;
|
|
@@ -3425,7 +3518,8 @@ var init_context_widget = __esm({
|
|
|
3425
3518
|
renderWithData(data, _context) {
|
|
3426
3519
|
const { current_usage, context_window_size } = data.context_window;
|
|
3427
3520
|
let usage = current_usage;
|
|
3428
|
-
|
|
3521
|
+
const hasRealUsage = usage && ((usage.input_tokens ?? 0) > 0 || (usage.output_tokens ?? 0) > 0 || (usage.cache_read_input_tokens ?? 0) > 0 || (usage.cache_creation_input_tokens ?? 0) > 0);
|
|
3522
|
+
if ((!usage || !hasRealUsage) && this.cachedUsage) {
|
|
3429
3523
|
usage = this.cachedUsage;
|
|
3430
3524
|
}
|
|
3431
3525
|
if (!usage) {
|
|
@@ -26259,8 +26353,8 @@ init_renderer();
|
|
|
26259
26353
|
init_widget_registry();
|
|
26260
26354
|
|
|
26261
26355
|
// src/providers/transcript-provider.ts
|
|
26262
|
-
var
|
|
26263
|
-
var
|
|
26356
|
+
var import_node_fs2 = require("node:fs");
|
|
26357
|
+
var import_node_readline = require("node:readline");
|
|
26264
26358
|
var TranscriptProvider = class {
|
|
26265
26359
|
MAX_TOOLS = 20;
|
|
26266
26360
|
/**
|
|
@@ -26269,13 +26363,13 @@ var TranscriptProvider = class {
|
|
|
26269
26363
|
* @returns Array of tool entries, limited to last 20
|
|
26270
26364
|
*/
|
|
26271
26365
|
async parseTools(transcriptPath) {
|
|
26272
|
-
if (!(0,
|
|
26366
|
+
if (!(0, import_node_fs2.existsSync)(transcriptPath)) {
|
|
26273
26367
|
return [];
|
|
26274
26368
|
}
|
|
26275
26369
|
const toolMap = /* @__PURE__ */ new Map();
|
|
26276
26370
|
try {
|
|
26277
|
-
const fileStream = (0,
|
|
26278
|
-
const rl = (0,
|
|
26371
|
+
const fileStream = (0, import_node_fs2.createReadStream)(transcriptPath, { encoding: "utf-8" });
|
|
26372
|
+
const rl = (0, import_node_readline.createInterface)({
|
|
26279
26373
|
input: fileStream,
|
|
26280
26374
|
crlfDelay: Infinity
|
|
26281
26375
|
});
|
|
@@ -26554,13 +26648,13 @@ async function routeCommand(command) {
|
|
|
26554
26648
|
}
|
|
26555
26649
|
|
|
26556
26650
|
// src/config/config-loader.ts
|
|
26557
|
-
var
|
|
26651
|
+
var import_node_fs4 = require("node:fs");
|
|
26558
26652
|
var import_promises2 = require("node:fs/promises");
|
|
26559
26653
|
var import_node_os4 = require("node:os");
|
|
26560
26654
|
var import_node_path4 = require("node:path");
|
|
26561
26655
|
|
|
26562
26656
|
// src/config/default-config-generator.ts
|
|
26563
|
-
var
|
|
26657
|
+
var import_node_fs3 = require("node:fs");
|
|
26564
26658
|
var import_node_os3 = require("node:os");
|
|
26565
26659
|
var import_node_path3 = require("node:path");
|
|
26566
26660
|
function getDefaultConfigPath() {
|
|
@@ -26568,15 +26662,15 @@ function getDefaultConfigPath() {
|
|
|
26568
26662
|
}
|
|
26569
26663
|
async function ensureDefaultConfig() {
|
|
26570
26664
|
const configPath = getDefaultConfigPath();
|
|
26571
|
-
if ((0,
|
|
26665
|
+
if ((0, import_node_fs3.existsSync)(configPath)) {
|
|
26572
26666
|
return;
|
|
26573
26667
|
}
|
|
26574
26668
|
const configDir = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude-scope");
|
|
26575
|
-
if (!(0,
|
|
26576
|
-
(0,
|
|
26669
|
+
if (!(0, import_node_fs3.existsSync)(configDir)) {
|
|
26670
|
+
(0, import_node_fs3.mkdirSync)(configDir, { recursive: true });
|
|
26577
26671
|
}
|
|
26578
26672
|
const defaultConfig = generateRichLayout("balanced", "dracula");
|
|
26579
|
-
(0,
|
|
26673
|
+
(0, import_node_fs3.writeFileSync)(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
|
|
26580
26674
|
}
|
|
26581
26675
|
|
|
26582
26676
|
// src/config/config-loader.ts
|
|
@@ -26589,7 +26683,7 @@ function getConfigPath() {
|
|
|
26589
26683
|
async function loadWidgetConfig() {
|
|
26590
26684
|
const configPath = getConfigPath();
|
|
26591
26685
|
await ensureDefaultConfig();
|
|
26592
|
-
if (!(0,
|
|
26686
|
+
if (!(0, import_node_fs4.existsSync)(configPath)) {
|
|
26593
26687
|
return null;
|
|
26594
26688
|
}
|
|
26595
26689
|
try {
|