claude-scope 0.8.32 → 0.8.34
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 +151 -38
- package/package.json +1 -1
package/dist/claude-scope.cjs
CHANGED
|
@@ -2413,12 +2413,96 @@ var init_widget_types = __esm({
|
|
|
2413
2413
|
}
|
|
2414
2414
|
});
|
|
2415
2415
|
|
|
2416
|
+
// src/providers/usage-parser.ts
|
|
2417
|
+
var import_node_fs, import_node_readline, UsageParser;
|
|
2418
|
+
var init_usage_parser = __esm({
|
|
2419
|
+
"src/providers/usage-parser.ts"() {
|
|
2420
|
+
"use strict";
|
|
2421
|
+
import_node_fs = require("node:fs");
|
|
2422
|
+
import_node_readline = require("node:readline");
|
|
2423
|
+
UsageParser = class {
|
|
2424
|
+
/**
|
|
2425
|
+
* Parse the last assistant message with usage data from transcript
|
|
2426
|
+
* Reads file in reverse to find the most recent data quickly
|
|
2427
|
+
*
|
|
2428
|
+
* @param transcriptPath - Path to the JSONL transcript file
|
|
2429
|
+
* @returns ContextUsage or null if not found
|
|
2430
|
+
*/
|
|
2431
|
+
async parseLastUsage(transcriptPath) {
|
|
2432
|
+
if (!(0, import_node_fs.existsSync)(transcriptPath)) {
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
try {
|
|
2436
|
+
const lines = await this.readAllLines(transcriptPath);
|
|
2437
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
2438
|
+
const usage = this.parseLineForUsage(lines[i]);
|
|
2439
|
+
if (usage) {
|
|
2440
|
+
return usage;
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
return null;
|
|
2444
|
+
} catch {
|
|
2445
|
+
return null;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
/**
|
|
2449
|
+
* Read all lines from transcript file
|
|
2450
|
+
*/
|
|
2451
|
+
async readAllLines(transcriptPath) {
|
|
2452
|
+
const lines = [];
|
|
2453
|
+
try {
|
|
2454
|
+
const fileStream = (0, import_node_fs.createReadStream)(transcriptPath, { encoding: "utf-8" });
|
|
2455
|
+
const rl = (0, import_node_readline.createInterface)({
|
|
2456
|
+
input: fileStream,
|
|
2457
|
+
crlfDelay: Infinity
|
|
2458
|
+
});
|
|
2459
|
+
for await (const line of rl) {
|
|
2460
|
+
if (line.trim()) {
|
|
2461
|
+
lines.push(line);
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
} catch {
|
|
2465
|
+
return [];
|
|
2466
|
+
}
|
|
2467
|
+
return lines;
|
|
2468
|
+
}
|
|
2469
|
+
/**
|
|
2470
|
+
* Parse a single transcript line for usage data
|
|
2471
|
+
* Returns null if line is not an assistant message with usage
|
|
2472
|
+
*/
|
|
2473
|
+
parseLineForUsage(line) {
|
|
2474
|
+
try {
|
|
2475
|
+
const entry = JSON.parse(line);
|
|
2476
|
+
if (entry.type !== "assistant") {
|
|
2477
|
+
return null;
|
|
2478
|
+
}
|
|
2479
|
+
const usage = entry.message?.usage;
|
|
2480
|
+
if (!usage) {
|
|
2481
|
+
return null;
|
|
2482
|
+
}
|
|
2483
|
+
if (typeof usage.input_tokens !== "number" || typeof usage.output_tokens !== "number" || typeof usage.cache_read_input_tokens !== "number") {
|
|
2484
|
+
return null;
|
|
2485
|
+
}
|
|
2486
|
+
return {
|
|
2487
|
+
input_tokens: usage.input_tokens,
|
|
2488
|
+
output_tokens: usage.output_tokens,
|
|
2489
|
+
cache_creation_input_tokens: usage.cache_creation_input_tokens ?? 0,
|
|
2490
|
+
cache_read_input_tokens: usage.cache_read_input_tokens
|
|
2491
|
+
};
|
|
2492
|
+
} catch {
|
|
2493
|
+
return null;
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
});
|
|
2499
|
+
|
|
2416
2500
|
// src/storage/cache-manager.ts
|
|
2417
|
-
var
|
|
2501
|
+
var import_node_fs2, import_node_os2, import_node_path2, DEFAULT_CACHE_PATH, DEFAULT_EXPIRY_MS, CacheManager;
|
|
2418
2502
|
var init_cache_manager = __esm({
|
|
2419
2503
|
"src/storage/cache-manager.ts"() {
|
|
2420
2504
|
"use strict";
|
|
2421
|
-
|
|
2505
|
+
import_node_fs2 = require("node:fs");
|
|
2422
2506
|
import_node_os2 = require("node:os");
|
|
2423
2507
|
import_node_path2 = require("node:path");
|
|
2424
2508
|
DEFAULT_CACHE_PATH = `${(0, import_node_os2.homedir)()}/.config/claude-scope/cache.json`;
|
|
@@ -2491,11 +2575,11 @@ var init_cache_manager = __esm({
|
|
|
2491
2575
|
* Load cache from file
|
|
2492
2576
|
*/
|
|
2493
2577
|
loadCache() {
|
|
2494
|
-
if (!(0,
|
|
2578
|
+
if (!(0, import_node_fs2.existsSync)(this.cachePath)) {
|
|
2495
2579
|
return { sessions: {}, version: 1 };
|
|
2496
2580
|
}
|
|
2497
2581
|
try {
|
|
2498
|
-
const content = (0,
|
|
2582
|
+
const content = (0, import_node_fs2.readFileSync)(this.cachePath, "utf-8");
|
|
2499
2583
|
return JSON.parse(content);
|
|
2500
2584
|
} catch {
|
|
2501
2585
|
return { sessions: {}, version: 1 };
|
|
@@ -2506,7 +2590,7 @@ var init_cache_manager = __esm({
|
|
|
2506
2590
|
*/
|
|
2507
2591
|
saveCache(cache) {
|
|
2508
2592
|
try {
|
|
2509
|
-
(0,
|
|
2593
|
+
(0, import_node_fs2.writeFileSync)(this.cachePath, JSON.stringify(cache, null, 2), "utf-8");
|
|
2510
2594
|
} catch {
|
|
2511
2595
|
}
|
|
2512
2596
|
}
|
|
@@ -2516,8 +2600,8 @@ var init_cache_manager = __esm({
|
|
|
2516
2600
|
ensureCacheDir() {
|
|
2517
2601
|
try {
|
|
2518
2602
|
const dir = (0, import_node_path2.dirname)(this.cachePath);
|
|
2519
|
-
if (!(0,
|
|
2520
|
-
(0,
|
|
2603
|
+
if (!(0, import_node_fs2.existsSync)(dir)) {
|
|
2604
|
+
(0, import_node_fs2.mkdirSync)(dir, { recursive: true });
|
|
2521
2605
|
}
|
|
2522
2606
|
} catch {
|
|
2523
2607
|
}
|
|
@@ -2665,6 +2749,7 @@ var init_cache_metrics_widget = __esm({
|
|
|
2665
2749
|
"src/widgets/cache-metrics/cache-metrics-widget.ts"() {
|
|
2666
2750
|
"use strict";
|
|
2667
2751
|
init_widget_types();
|
|
2752
|
+
init_usage_parser();
|
|
2668
2753
|
init_cache_manager();
|
|
2669
2754
|
init_theme();
|
|
2670
2755
|
init_stdin_data_widget();
|
|
@@ -2684,11 +2769,15 @@ var init_cache_metrics_widget = __esm({
|
|
|
2684
2769
|
style = "balanced";
|
|
2685
2770
|
renderData;
|
|
2686
2771
|
cacheManager;
|
|
2772
|
+
usageParser;
|
|
2687
2773
|
lastSessionId;
|
|
2774
|
+
cachedUsage;
|
|
2775
|
+
// Cache parsed usage within render cycle
|
|
2688
2776
|
constructor(theme) {
|
|
2689
2777
|
super();
|
|
2690
2778
|
this.theme = theme ?? DEFAULT_THEME;
|
|
2691
2779
|
this.cacheManager = new CacheManager();
|
|
2780
|
+
this.usageParser = new UsageParser();
|
|
2692
2781
|
}
|
|
2693
2782
|
/**
|
|
2694
2783
|
* Set display style
|
|
@@ -2706,14 +2795,7 @@ var init_cache_metrics_widget = __esm({
|
|
|
2706
2795
|
* Calculate cache metrics from context usage data
|
|
2707
2796
|
* Returns zero metrics if no usage data is available (widget should always be visible)
|
|
2708
2797
|
*/
|
|
2709
|
-
calculateMetrics(
|
|
2710
|
-
let usage = data.context_window?.current_usage;
|
|
2711
|
-
if (!usage) {
|
|
2712
|
-
const cached = this.cacheManager.getCachedUsage(data.session_id);
|
|
2713
|
-
if (cached) {
|
|
2714
|
-
usage = cached.usage;
|
|
2715
|
-
}
|
|
2716
|
-
}
|
|
2798
|
+
calculateMetrics(usage) {
|
|
2717
2799
|
if (!usage) {
|
|
2718
2800
|
return {
|
|
2719
2801
|
cacheRead: 0,
|
|
@@ -2752,24 +2834,42 @@ var init_cache_metrics_widget = __esm({
|
|
|
2752
2834
|
}
|
|
2753
2835
|
this.lastSessionId = data.session_id;
|
|
2754
2836
|
const usage = data.context_window?.current_usage;
|
|
2755
|
-
if (usage &&
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2837
|
+
if (usage && !sessionChanged) {
|
|
2838
|
+
const hasAnyTokens = (usage.input_tokens ?? 0) > 0 || (usage.output_tokens ?? 0) > 0 || (usage.cache_creation_input_tokens ?? 0) > 0 || (usage.cache_read_input_tokens ?? 0) > 0;
|
|
2839
|
+
if (hasAnyTokens) {
|
|
2840
|
+
this.cacheManager.setCachedUsage(data.session_id, {
|
|
2841
|
+
input_tokens: usage.input_tokens,
|
|
2842
|
+
output_tokens: usage.output_tokens,
|
|
2843
|
+
cache_creation_input_tokens: usage.cache_creation_input_tokens,
|
|
2844
|
+
cache_read_input_tokens: usage.cache_read_input_tokens
|
|
2845
|
+
});
|
|
2846
|
+
}
|
|
2847
|
+
}
|
|
2848
|
+
if (!usage) {
|
|
2849
|
+
this.cachedUsage = await this.usageParser.parseLastUsage(data.transcript_path);
|
|
2850
|
+
} else {
|
|
2851
|
+
this.cachedUsage = void 0;
|
|
2762
2852
|
}
|
|
2763
|
-
const metrics = this.calculateMetrics(data);
|
|
2764
|
-
this.renderData = metrics ?? void 0;
|
|
2765
2853
|
}
|
|
2766
2854
|
/**
|
|
2767
2855
|
* Render the cache metrics display
|
|
2768
2856
|
*/
|
|
2769
|
-
renderWithData(
|
|
2770
|
-
|
|
2857
|
+
renderWithData(data, _context) {
|
|
2858
|
+
let usage = data.context_window?.current_usage;
|
|
2859
|
+
if (!usage && this.cachedUsage) {
|
|
2860
|
+
usage = this.cachedUsage;
|
|
2861
|
+
}
|
|
2862
|
+
if (!usage) {
|
|
2863
|
+
const cached = this.cacheManager.getCachedUsage(data.session_id);
|
|
2864
|
+
if (cached) {
|
|
2865
|
+
usage = cached.usage;
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
const metrics = this.calculateMetrics(usage);
|
|
2869
|
+
if (!metrics) {
|
|
2771
2870
|
return null;
|
|
2772
2871
|
}
|
|
2872
|
+
this.renderData = metrics;
|
|
2773
2873
|
const styleFn = cacheMetricsStyles[this.style] ?? cacheMetricsStyles.balanced;
|
|
2774
2874
|
if (!styleFn) {
|
|
2775
2875
|
return null;
|
|
@@ -3256,6 +3356,7 @@ var init_context_widget = __esm({
|
|
|
3256
3356
|
"src/widgets/context-widget.ts"() {
|
|
3257
3357
|
"use strict";
|
|
3258
3358
|
init_widget_types();
|
|
3359
|
+
init_usage_parser();
|
|
3259
3360
|
init_cache_manager();
|
|
3260
3361
|
init_theme();
|
|
3261
3362
|
init_styles4();
|
|
@@ -3274,11 +3375,15 @@ var init_context_widget = __esm({
|
|
|
3274
3375
|
_lineOverride;
|
|
3275
3376
|
styleFn = contextStyles.balanced;
|
|
3276
3377
|
cacheManager;
|
|
3378
|
+
usageParser;
|
|
3277
3379
|
lastSessionId;
|
|
3380
|
+
cachedUsage;
|
|
3381
|
+
// Cache parsed usage within render cycle
|
|
3278
3382
|
constructor(colors2) {
|
|
3279
3383
|
super();
|
|
3280
3384
|
this.colors = colors2 ?? DEFAULT_THEME;
|
|
3281
3385
|
this.cacheManager = new CacheManager();
|
|
3386
|
+
this.usageParser = new UsageParser();
|
|
3282
3387
|
}
|
|
3283
3388
|
setStyle(style = "balanced") {
|
|
3284
3389
|
const fn = contextStyles[style];
|
|
@@ -3311,10 +3416,18 @@ var init_context_widget = __esm({
|
|
|
3311
3416
|
});
|
|
3312
3417
|
}
|
|
3313
3418
|
}
|
|
3419
|
+
if (!current_usage) {
|
|
3420
|
+
this.cachedUsage = await this.usageParser.parseLastUsage(data.transcript_path);
|
|
3421
|
+
} else {
|
|
3422
|
+
this.cachedUsage = void 0;
|
|
3423
|
+
}
|
|
3314
3424
|
}
|
|
3315
3425
|
renderWithData(data, _context) {
|
|
3316
3426
|
const { current_usage, context_window_size } = data.context_window;
|
|
3317
3427
|
let usage = current_usage;
|
|
3428
|
+
if (!usage && this.cachedUsage) {
|
|
3429
|
+
usage = this.cachedUsage;
|
|
3430
|
+
}
|
|
3318
3431
|
if (!usage) {
|
|
3319
3432
|
const cached = this.cacheManager.getCachedUsage(data.session_id);
|
|
3320
3433
|
if (cached) {
|
|
@@ -26146,8 +26259,8 @@ init_renderer();
|
|
|
26146
26259
|
init_widget_registry();
|
|
26147
26260
|
|
|
26148
26261
|
// src/providers/transcript-provider.ts
|
|
26149
|
-
var
|
|
26150
|
-
var
|
|
26262
|
+
var import_node_fs3 = require("node:fs");
|
|
26263
|
+
var import_node_readline2 = require("node:readline");
|
|
26151
26264
|
var TranscriptProvider = class {
|
|
26152
26265
|
MAX_TOOLS = 20;
|
|
26153
26266
|
/**
|
|
@@ -26156,13 +26269,13 @@ var TranscriptProvider = class {
|
|
|
26156
26269
|
* @returns Array of tool entries, limited to last 20
|
|
26157
26270
|
*/
|
|
26158
26271
|
async parseTools(transcriptPath) {
|
|
26159
|
-
if (!(0,
|
|
26272
|
+
if (!(0, import_node_fs3.existsSync)(transcriptPath)) {
|
|
26160
26273
|
return [];
|
|
26161
26274
|
}
|
|
26162
26275
|
const toolMap = /* @__PURE__ */ new Map();
|
|
26163
26276
|
try {
|
|
26164
|
-
const fileStream = (0,
|
|
26165
|
-
const rl = (0,
|
|
26277
|
+
const fileStream = (0, import_node_fs3.createReadStream)(transcriptPath, { encoding: "utf-8" });
|
|
26278
|
+
const rl = (0, import_node_readline2.createInterface)({
|
|
26166
26279
|
input: fileStream,
|
|
26167
26280
|
crlfDelay: Infinity
|
|
26168
26281
|
});
|
|
@@ -26441,13 +26554,13 @@ async function routeCommand(command) {
|
|
|
26441
26554
|
}
|
|
26442
26555
|
|
|
26443
26556
|
// src/config/config-loader.ts
|
|
26444
|
-
var
|
|
26557
|
+
var import_node_fs5 = require("node:fs");
|
|
26445
26558
|
var import_promises2 = require("node:fs/promises");
|
|
26446
26559
|
var import_node_os4 = require("node:os");
|
|
26447
26560
|
var import_node_path4 = require("node:path");
|
|
26448
26561
|
|
|
26449
26562
|
// src/config/default-config-generator.ts
|
|
26450
|
-
var
|
|
26563
|
+
var import_node_fs4 = require("node:fs");
|
|
26451
26564
|
var import_node_os3 = require("node:os");
|
|
26452
26565
|
var import_node_path3 = require("node:path");
|
|
26453
26566
|
function getDefaultConfigPath() {
|
|
@@ -26455,15 +26568,15 @@ function getDefaultConfigPath() {
|
|
|
26455
26568
|
}
|
|
26456
26569
|
async function ensureDefaultConfig() {
|
|
26457
26570
|
const configPath = getDefaultConfigPath();
|
|
26458
|
-
if ((0,
|
|
26571
|
+
if ((0, import_node_fs4.existsSync)(configPath)) {
|
|
26459
26572
|
return;
|
|
26460
26573
|
}
|
|
26461
26574
|
const configDir = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude-scope");
|
|
26462
|
-
if (!(0,
|
|
26463
|
-
(0,
|
|
26575
|
+
if (!(0, import_node_fs4.existsSync)(configDir)) {
|
|
26576
|
+
(0, import_node_fs4.mkdirSync)(configDir, { recursive: true });
|
|
26464
26577
|
}
|
|
26465
26578
|
const defaultConfig = generateRichLayout("balanced", "dracula");
|
|
26466
|
-
(0,
|
|
26579
|
+
(0, import_node_fs4.writeFileSync)(configPath, JSON.stringify(defaultConfig, null, 2), "utf-8");
|
|
26467
26580
|
}
|
|
26468
26581
|
|
|
26469
26582
|
// src/config/config-loader.ts
|
|
@@ -26476,7 +26589,7 @@ function getConfigPath() {
|
|
|
26476
26589
|
async function loadWidgetConfig() {
|
|
26477
26590
|
const configPath = getConfigPath();
|
|
26478
26591
|
await ensureDefaultConfig();
|
|
26479
|
-
if (!(0,
|
|
26592
|
+
if (!(0, import_node_fs5.existsSync)(configPath)) {
|
|
26480
26593
|
return null;
|
|
26481
26594
|
}
|
|
26482
26595
|
try {
|