oh-my-claude-sisyphus 3.4.2 → 3.5.0
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/README.md +45 -0
- package/commands/cancel-ultraqa.md +1 -1
- package/dist/__tests__/analytics/analytics-summary.test.d.ts +2 -0
- package/dist/__tests__/analytics/analytics-summary.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/analytics-summary.test.js +267 -0
- package/dist/__tests__/analytics/analytics-summary.test.js.map +1 -0
- package/dist/__tests__/analytics/backfill-dedup.test.d.ts +2 -0
- package/dist/__tests__/analytics/backfill-dedup.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/backfill-dedup.test.js +179 -0
- package/dist/__tests__/analytics/backfill-dedup.test.js.map +1 -0
- package/dist/__tests__/analytics/backfill-engine.test.d.ts +2 -0
- package/dist/__tests__/analytics/backfill-engine.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/backfill-engine.test.js +362 -0
- package/dist/__tests__/analytics/backfill-engine.test.js.map +1 -0
- package/dist/__tests__/analytics/cost-estimator.test.d.ts +2 -0
- package/dist/__tests__/analytics/cost-estimator.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/cost-estimator.test.js +212 -0
- package/dist/__tests__/analytics/cost-estimator.test.js.map +1 -0
- package/dist/__tests__/analytics/output-estimator.test.d.ts +2 -0
- package/dist/__tests__/analytics/output-estimator.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/output-estimator.test.js +106 -0
- package/dist/__tests__/analytics/output-estimator.test.js.map +1 -0
- package/dist/__tests__/analytics/token-extractor.test.d.ts +2 -0
- package/dist/__tests__/analytics/token-extractor.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/token-extractor.test.js +121 -0
- package/dist/__tests__/analytics/token-extractor.test.js.map +1 -0
- package/dist/__tests__/analytics/transcript-parser.test.d.ts +2 -0
- package/dist/__tests__/analytics/transcript-parser.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/transcript-parser.test.js +285 -0
- package/dist/__tests__/analytics/transcript-parser.test.js.map +1 -0
- package/dist/__tests__/analytics/transcript-scanner.test.d.ts +2 -0
- package/dist/__tests__/analytics/transcript-scanner.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/transcript-scanner.test.js +401 -0
- package/dist/__tests__/analytics/transcript-scanner.test.js.map +1 -0
- package/dist/__tests__/analytics/transcript-token-extractor.test.d.ts +2 -0
- package/dist/__tests__/analytics/transcript-token-extractor.test.d.ts.map +1 -0
- package/dist/__tests__/analytics/transcript-token-extractor.test.js +175 -0
- package/dist/__tests__/analytics/transcript-token-extractor.test.js.map +1 -0
- package/dist/__tests__/hud/auto-tracking.integration.test.d.ts +2 -0
- package/dist/__tests__/hud/auto-tracking.integration.test.d.ts.map +1 -0
- package/dist/__tests__/hud/auto-tracking.integration.test.js +12 -0
- package/dist/__tests__/hud/auto-tracking.integration.test.js.map +1 -0
- package/dist/__tests__/learner/auto-learner.test.d.ts +7 -0
- package/dist/__tests__/learner/auto-learner.test.d.ts.map +1 -0
- package/dist/__tests__/learner/auto-learner.test.js +507 -0
- package/dist/__tests__/learner/auto-learner.test.js.map +1 -0
- package/dist/__tests__/learner/matcher.test.d.ts +2 -0
- package/dist/__tests__/learner/matcher.test.d.ts.map +1 -0
- package/dist/__tests__/learner/matcher.test.js +330 -0
- package/dist/__tests__/learner/matcher.test.js.map +1 -0
- package/dist/analytics/analytics-summary.d.ts +47 -0
- package/dist/analytics/analytics-summary.d.ts.map +1 -0
- package/dist/analytics/analytics-summary.js +171 -0
- package/dist/analytics/analytics-summary.js.map +1 -0
- package/dist/analytics/backfill-dedup.d.ts +49 -0
- package/dist/analytics/backfill-dedup.d.ts.map +1 -0
- package/dist/analytics/backfill-dedup.js +115 -0
- package/dist/analytics/backfill-dedup.js.map +1 -0
- package/dist/analytics/backfill-engine.d.ts +59 -0
- package/dist/analytics/backfill-engine.d.ts.map +1 -0
- package/dist/analytics/backfill-engine.js +172 -0
- package/dist/analytics/backfill-engine.js.map +1 -0
- package/dist/analytics/index.d.ts +8 -0
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +10 -0
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/output-estimator.d.ts +26 -0
- package/dist/analytics/output-estimator.d.ts.map +1 -0
- package/dist/analytics/output-estimator.js +61 -0
- package/dist/analytics/output-estimator.js.map +1 -0
- package/dist/analytics/query-engine.d.ts.map +1 -1
- package/dist/analytics/query-engine.js +3 -2
- package/dist/analytics/query-engine.js.map +1 -1
- package/dist/analytics/token-extractor.d.ts +31 -0
- package/dist/analytics/token-extractor.d.ts.map +1 -0
- package/dist/analytics/token-extractor.js +57 -0
- package/dist/analytics/token-extractor.js.map +1 -0
- package/dist/analytics/token-tracker.d.ts +7 -1
- package/dist/analytics/token-tracker.d.ts.map +1 -1
- package/dist/analytics/token-tracker.js +94 -18
- package/dist/analytics/token-tracker.js.map +1 -1
- package/dist/analytics/transcript-parser.d.ts +42 -0
- package/dist/analytics/transcript-parser.d.ts.map +1 -0
- package/dist/analytics/transcript-parser.js +90 -0
- package/dist/analytics/transcript-parser.js.map +1 -0
- package/dist/analytics/transcript-scanner.d.ts +50 -0
- package/dist/analytics/transcript-scanner.d.ts.map +1 -0
- package/dist/analytics/transcript-scanner.js +149 -0
- package/dist/analytics/transcript-scanner.js.map +1 -0
- package/dist/analytics/transcript-token-extractor.d.ts +35 -0
- package/dist/analytics/transcript-token-extractor.d.ts.map +1 -0
- package/dist/analytics/transcript-token-extractor.js +136 -0
- package/dist/analytics/transcript-token-extractor.js.map +1 -0
- package/dist/analytics/types.d.ts +65 -0
- package/dist/analytics/types.d.ts.map +1 -1
- package/dist/analytics/types.js.map +1 -1
- package/dist/cli/analytics.js +26 -1
- package/dist/cli/analytics.js.map +1 -1
- package/dist/cli/commands/backfill.d.ts +15 -0
- package/dist/cli/commands/backfill.d.ts.map +1 -0
- package/dist/cli/commands/backfill.js +146 -0
- package/dist/cli/commands/backfill.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +1 -0
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +67 -31
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/components/CostDashboard.d.ts +15 -0
- package/dist/cli/components/CostDashboard.d.ts.map +1 -0
- package/dist/cli/components/CostDashboard.js +15 -0
- package/dist/cli/components/CostDashboard.js.map +1 -0
- package/dist/cli/components/LiveStats.d.ts +16 -0
- package/dist/cli/components/LiveStats.d.ts.map +1 -0
- package/dist/cli/components/LiveStats.js +16 -0
- package/dist/cli/components/LiveStats.js.map +1 -0
- package/dist/cli/components/SessionBrowser.d.ts +14 -0
- package/dist/cli/components/SessionBrowser.d.ts.map +1 -0
- package/dist/cli/components/SessionBrowser.js +14 -0
- package/dist/cli/components/SessionBrowser.js.map +1 -0
- package/dist/cli/index.js +159 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/tui.d.ts +21 -0
- package/dist/cli/tui.d.ts.map +1 -0
- package/dist/cli/tui.js +21 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/hooks/learner/auto-invoke.d.ts +82 -0
- package/dist/hooks/learner/auto-invoke.d.ts.map +1 -0
- package/dist/hooks/learner/auto-invoke.js +234 -0
- package/dist/hooks/learner/auto-invoke.js.map +1 -0
- package/dist/hooks/learner/auto-learner.d.ts +55 -0
- package/dist/hooks/learner/auto-learner.d.ts.map +1 -0
- package/dist/hooks/learner/auto-learner.js +361 -0
- package/dist/hooks/learner/auto-learner.js.map +1 -0
- package/dist/hooks/learner/index.d.ts +3 -0
- package/dist/hooks/learner/index.d.ts.map +1 -1
- package/dist/hooks/learner/index.js +4 -0
- package/dist/hooks/learner/index.js.map +1 -1
- package/dist/hooks/learner/matcher.d.ts +40 -0
- package/dist/hooks/learner/matcher.d.ts.map +1 -0
- package/dist/hooks/learner/matcher.js +230 -0
- package/dist/hooks/learner/matcher.js.map +1 -0
- package/dist/hud/analytics-display.d.ts +16 -0
- package/dist/hud/analytics-display.d.ts.map +1 -1
- package/dist/hud/analytics-display.js +42 -0
- package/dist/hud/analytics-display.js.map +1 -1
- package/dist/hud/index.js +90 -3
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +27 -1
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/types.d.ts +2 -0
- package/dist/hud/types.d.ts.map +1 -1
- package/dist/hud/types.js.map +1 -1
- package/docs/ANALYTICS-SYSTEM.md +150 -0
- package/hooks/keyword-detector.sh +1 -1
- package/package.json +1 -1
- package/scripts/keyword-detector.mjs +1 -1
- package/scripts/persistent-mode.mjs +1 -1
- package/scripts/test-mutual-exclusion.ts +4 -4
- package/scripts/test-remember-tags.ts +6 -6
- package/scripts/test-session-injection.ts +4 -4
- package/skills/cancel-ultraqa/SKILL.md +1 -1
- package/skills/local-skills-setup/SKILL.md +465 -0
- package/skills/omc-setup/SKILL.md +30 -5
- package/skills/skill/SKILL.md +406 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
const TOKEN_LOG_FILE = path.join(homedir(), '.omc', 'state', 'token-tracking.jsonl');
|
|
6
|
+
const DEDUP_INDEX_FILE = path.join(homedir(), '.omc', 'state', 'backfill-index.json');
|
|
7
|
+
/**
|
|
8
|
+
* BackfillDedup provides fast deduplication for backfill operations.
|
|
9
|
+
*
|
|
10
|
+
* Uses in-memory Set for O(1) lookups and persists state to disk.
|
|
11
|
+
* Loads existing entries from token-tracking.jsonl on initialization.
|
|
12
|
+
*/
|
|
13
|
+
export class BackfillDedup {
|
|
14
|
+
processedSet = new Set();
|
|
15
|
+
totalProcessed = 0;
|
|
16
|
+
lastBackfillTime = new Date().toISOString();
|
|
17
|
+
/**
|
|
18
|
+
* Load existing processed IDs from backfill-index.json and scan token-tracking.jsonl
|
|
19
|
+
*/
|
|
20
|
+
async load() {
|
|
21
|
+
// Load persisted index first
|
|
22
|
+
try {
|
|
23
|
+
const indexContent = await fs.readFile(DEDUP_INDEX_FILE, 'utf-8');
|
|
24
|
+
const index = JSON.parse(indexContent);
|
|
25
|
+
this.processedSet = new Set(index.processedIds);
|
|
26
|
+
this.totalProcessed = index.totalProcessed;
|
|
27
|
+
this.lastBackfillTime = index.lastBackfillTime;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// Index doesn't exist yet, will be created on save
|
|
31
|
+
}
|
|
32
|
+
// Scan token-tracking.jsonl to ensure all existing entries are marked
|
|
33
|
+
try {
|
|
34
|
+
const logContent = await fs.readFile(TOKEN_LOG_FILE, 'utf-8');
|
|
35
|
+
const lines = logContent.trim().split('\n').filter(line => line.length > 0);
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
try {
|
|
38
|
+
const record = JSON.parse(line);
|
|
39
|
+
const entryId = this.generateEntryId(record);
|
|
40
|
+
if (!this.processedSet.has(entryId)) {
|
|
41
|
+
this.processedSet.add(entryId);
|
|
42
|
+
this.totalProcessed++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (parseError) {
|
|
46
|
+
// Skip malformed lines
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// Log file doesn't exist yet, which is fine
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate unique ID for a token usage entry
|
|
56
|
+
* Uses SHA256 hash to match transcript-token-extractor.ts format
|
|
57
|
+
*/
|
|
58
|
+
generateEntryId(record) {
|
|
59
|
+
const hash = createHash('sha256');
|
|
60
|
+
hash.update(`${record.sessionId}:${record.timestamp}:${record.modelName}`);
|
|
61
|
+
return hash.digest('hex');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Check if an entry ID has already been processed
|
|
65
|
+
*/
|
|
66
|
+
isProcessed(entryId) {
|
|
67
|
+
return this.processedSet.has(entryId);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Mark an entry ID as processed
|
|
71
|
+
*/
|
|
72
|
+
markProcessed(entryId) {
|
|
73
|
+
if (!this.processedSet.has(entryId)) {
|
|
74
|
+
this.processedSet.add(entryId);
|
|
75
|
+
this.totalProcessed++;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Persist deduplication state to backfill-index.json
|
|
80
|
+
*/
|
|
81
|
+
async save() {
|
|
82
|
+
const indexDir = path.dirname(DEDUP_INDEX_FILE);
|
|
83
|
+
await fs.mkdir(indexDir, { recursive: true });
|
|
84
|
+
const index = {
|
|
85
|
+
processedIds: Array.from(this.processedSet),
|
|
86
|
+
lastBackfillTime: new Date().toISOString(),
|
|
87
|
+
totalProcessed: this.totalProcessed
|
|
88
|
+
};
|
|
89
|
+
await fs.writeFile(DEDUP_INDEX_FILE, JSON.stringify(index, null, 2), 'utf-8');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Clear all processed entries and delete index file
|
|
93
|
+
*/
|
|
94
|
+
async reset() {
|
|
95
|
+
this.processedSet.clear();
|
|
96
|
+
this.totalProcessed = 0;
|
|
97
|
+
this.lastBackfillTime = new Date().toISOString();
|
|
98
|
+
try {
|
|
99
|
+
await fs.unlink(DEDUP_INDEX_FILE);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// File might not exist, which is fine
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get current statistics
|
|
107
|
+
*/
|
|
108
|
+
getStats() {
|
|
109
|
+
return {
|
|
110
|
+
totalProcessed: this.totalProcessed,
|
|
111
|
+
lastBackfillTime: this.lastBackfillTime
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=backfill-dedup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill-dedup.js","sourceRoot":"","sources":["../../src/analytics/backfill-dedup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface BackfillOptions {
|
|
3
|
+
projectFilter?: string;
|
|
4
|
+
dateFrom?: Date;
|
|
5
|
+
dateTo?: Date;
|
|
6
|
+
dryRun?: boolean;
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface BackfillResult {
|
|
10
|
+
filesProcessed: number;
|
|
11
|
+
entriesAdded: number;
|
|
12
|
+
duplicatesSkipped: number;
|
|
13
|
+
errorsEncountered: number;
|
|
14
|
+
totalCostDiscovered: number;
|
|
15
|
+
timeElapsed: number;
|
|
16
|
+
}
|
|
17
|
+
export interface BackfillProgress {
|
|
18
|
+
currentFile: string;
|
|
19
|
+
filesProcessed: number;
|
|
20
|
+
totalFiles: number;
|
|
21
|
+
entriesAdded: number;
|
|
22
|
+
duplicatesSkipped: number;
|
|
23
|
+
currentCost: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* BackfillEngine orchestrates the offline transcript analysis pipeline.
|
|
27
|
+
*
|
|
28
|
+
* Pipeline:
|
|
29
|
+
* 1. Scan for transcripts
|
|
30
|
+
* 2. Parse each transcript file (streaming)
|
|
31
|
+
* 3. Extract token usage from entries
|
|
32
|
+
* 4. Deduplicate
|
|
33
|
+
* 5. Write to token-tracking.jsonl (batch)
|
|
34
|
+
*
|
|
35
|
+
* Emits 'progress' events during execution.
|
|
36
|
+
*/
|
|
37
|
+
export declare class BackfillEngine extends EventEmitter {
|
|
38
|
+
private aborted;
|
|
39
|
+
private dedup;
|
|
40
|
+
private tracker;
|
|
41
|
+
constructor();
|
|
42
|
+
/**
|
|
43
|
+
* Abort the backfill operation
|
|
44
|
+
*/
|
|
45
|
+
abort(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Run the backfill process
|
|
48
|
+
*/
|
|
49
|
+
run(options?: BackfillOptions): Promise<BackfillResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Process a single transcript file
|
|
52
|
+
*/
|
|
53
|
+
private processTranscript;
|
|
54
|
+
/**
|
|
55
|
+
* Write a batch of token usage entries to the tracker
|
|
56
|
+
*/
|
|
57
|
+
private flushBatch;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=backfill-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill-engine.d.ts","sourceRoot":"","sources":["../../src/analytics/backfill-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAUtC,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAe;;IAQ9B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACG,GAAG,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IAwDjE;;OAEG;YACW,iBAAiB;IAoF/B;;OAEG;YACW,UAAU;CAczB"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { scanTranscripts } from './transcript-scanner.js';
|
|
4
|
+
import { parseTranscript } from './transcript-parser.js';
|
|
5
|
+
import { BackfillDedup } from './backfill-dedup.js';
|
|
6
|
+
import { getTokenTracker } from './token-tracker.js';
|
|
7
|
+
import { calculateCost } from './cost-estimator.js';
|
|
8
|
+
import { extractTokenUsage, extractTaskSpawns } from './transcript-token-extractor.js';
|
|
9
|
+
/**
|
|
10
|
+
* BackfillEngine orchestrates the offline transcript analysis pipeline.
|
|
11
|
+
*
|
|
12
|
+
* Pipeline:
|
|
13
|
+
* 1. Scan for transcripts
|
|
14
|
+
* 2. Parse each transcript file (streaming)
|
|
15
|
+
* 3. Extract token usage from entries
|
|
16
|
+
* 4. Deduplicate
|
|
17
|
+
* 5. Write to token-tracking.jsonl (batch)
|
|
18
|
+
*
|
|
19
|
+
* Emits 'progress' events during execution.
|
|
20
|
+
*/
|
|
21
|
+
export class BackfillEngine extends EventEmitter {
|
|
22
|
+
aborted = false;
|
|
23
|
+
dedup;
|
|
24
|
+
tracker;
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
this.dedup = new BackfillDedup();
|
|
28
|
+
this.tracker = getTokenTracker();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Abort the backfill operation
|
|
32
|
+
*/
|
|
33
|
+
abort() {
|
|
34
|
+
this.aborted = true;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run the backfill process
|
|
38
|
+
*/
|
|
39
|
+
async run(options = {}) {
|
|
40
|
+
const startTime = Date.now();
|
|
41
|
+
this.aborted = false;
|
|
42
|
+
// Load deduplication state
|
|
43
|
+
await this.dedup.load();
|
|
44
|
+
// Scan for transcripts
|
|
45
|
+
const scanResult = await scanTranscripts({
|
|
46
|
+
projectFilter: options.projectFilter,
|
|
47
|
+
minDate: options.dateFrom,
|
|
48
|
+
});
|
|
49
|
+
const result = {
|
|
50
|
+
filesProcessed: 0,
|
|
51
|
+
entriesAdded: 0,
|
|
52
|
+
duplicatesSkipped: 0,
|
|
53
|
+
errorsEncountered: 0,
|
|
54
|
+
totalCostDiscovered: 0,
|
|
55
|
+
timeElapsed: 0,
|
|
56
|
+
};
|
|
57
|
+
const totalFiles = scanResult.transcripts.length;
|
|
58
|
+
// Process each transcript file
|
|
59
|
+
for (const transcript of scanResult.transcripts) {
|
|
60
|
+
if (this.aborted) {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
// Filter by date range if specified
|
|
64
|
+
if (options.dateTo && transcript.modifiedTime > options.dateTo) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
await this.processTranscript(transcript, options, result, totalFiles);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
result.errorsEncountered++;
|
|
72
|
+
if (options.verbose) {
|
|
73
|
+
console.error(`Error processing ${transcript.filePath}:`, error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
result.filesProcessed++;
|
|
77
|
+
}
|
|
78
|
+
// Save deduplication state
|
|
79
|
+
if (!options.dryRun) {
|
|
80
|
+
await this.dedup.save();
|
|
81
|
+
}
|
|
82
|
+
result.timeElapsed = Date.now() - startTime;
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Process a single transcript file
|
|
87
|
+
*/
|
|
88
|
+
async processTranscript(transcript, options, result, totalFiles) {
|
|
89
|
+
const batch = [];
|
|
90
|
+
const BATCH_SIZE = 100;
|
|
91
|
+
// Build a lookup of toolUseId → agentType for attributing progress entries
|
|
92
|
+
// This is populated as we encounter assistant entries with Task tool calls
|
|
93
|
+
const agentLookup = new Map();
|
|
94
|
+
// Emit progress
|
|
95
|
+
this.emit('progress', {
|
|
96
|
+
currentFile: path.basename(transcript.filePath),
|
|
97
|
+
filesProcessed: result.filesProcessed,
|
|
98
|
+
totalFiles,
|
|
99
|
+
entriesAdded: result.entriesAdded,
|
|
100
|
+
duplicatesSkipped: result.duplicatesSkipped,
|
|
101
|
+
currentCost: result.totalCostDiscovered,
|
|
102
|
+
});
|
|
103
|
+
// Parse transcript (streaming)
|
|
104
|
+
for await (const entry of parseTranscript(transcript.filePath, {
|
|
105
|
+
onParseError: (line, error) => {
|
|
106
|
+
result.errorsEncountered++;
|
|
107
|
+
if (options.verbose) {
|
|
108
|
+
console.warn(`Parse error in ${transcript.filePath}: ${error.message}`);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
})) {
|
|
112
|
+
if (this.aborted) {
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
// Extract Task tool spawns from assistant entries to build agent lookup
|
|
116
|
+
// This must happen BEFORE extractTokenUsage so progress entries can look up their parent
|
|
117
|
+
const spawns = extractTaskSpawns(entry);
|
|
118
|
+
for (const spawn of spawns) {
|
|
119
|
+
agentLookup.set(spawn.toolUseId, spawn.agentType);
|
|
120
|
+
}
|
|
121
|
+
// Extract token usage (passing agentLookup for progress entry attribution)
|
|
122
|
+
const extracted = extractTokenUsage(entry, transcript.sessionId, transcript.filePath, agentLookup);
|
|
123
|
+
if (!extracted) {
|
|
124
|
+
continue; // Skip entries without usage data
|
|
125
|
+
}
|
|
126
|
+
// Check deduplication
|
|
127
|
+
if (this.dedup.isProcessed(extracted.entryId)) {
|
|
128
|
+
result.duplicatesSkipped++;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
// Calculate cost
|
|
132
|
+
const cost = calculateCost({
|
|
133
|
+
modelName: extracted.usage.modelName,
|
|
134
|
+
inputTokens: extracted.usage.inputTokens,
|
|
135
|
+
outputTokens: extracted.usage.outputTokens,
|
|
136
|
+
cacheCreationTokens: extracted.usage.cacheCreationTokens,
|
|
137
|
+
cacheReadTokens: extracted.usage.cacheReadTokens,
|
|
138
|
+
});
|
|
139
|
+
result.totalCostDiscovered += cost.totalCost;
|
|
140
|
+
// Add to batch
|
|
141
|
+
batch.push(extracted.usage);
|
|
142
|
+
this.dedup.markProcessed(extracted.entryId);
|
|
143
|
+
result.entriesAdded++;
|
|
144
|
+
// Flush batch if full
|
|
145
|
+
if (batch.length >= BATCH_SIZE && !options.dryRun) {
|
|
146
|
+
await this.flushBatch(batch);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Flush remaining entries
|
|
150
|
+
if (batch.length > 0 && !options.dryRun) {
|
|
151
|
+
await this.flushBatch(batch);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Write a batch of token usage entries to the tracker
|
|
156
|
+
*/
|
|
157
|
+
async flushBatch(batch) {
|
|
158
|
+
for (const usage of batch) {
|
|
159
|
+
await this.tracker.recordTokenUsage({
|
|
160
|
+
modelName: usage.modelName,
|
|
161
|
+
inputTokens: usage.inputTokens,
|
|
162
|
+
outputTokens: usage.outputTokens,
|
|
163
|
+
cacheCreationTokens: usage.cacheCreationTokens,
|
|
164
|
+
cacheReadTokens: usage.cacheReadTokens,
|
|
165
|
+
agentName: usage.agentName,
|
|
166
|
+
isEstimated: usage.isEstimated,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
batch.length = 0; // Clear batch
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=backfill-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill-engine.js","sourceRoot":"","sources":["../../src/analytics/backfill-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,4 +11,12 @@ export * from './session-types.js';
|
|
|
11
11
|
export * from './metrics-collector.js';
|
|
12
12
|
export * from './query-engine.js';
|
|
13
13
|
export * from './export.js';
|
|
14
|
+
export * from './token-extractor.js';
|
|
15
|
+
export * from './output-estimator.js';
|
|
16
|
+
export * from './analytics-summary.js';
|
|
17
|
+
export * from './transcript-scanner.js';
|
|
18
|
+
export * from './transcript-parser.js';
|
|
19
|
+
export * from './transcript-token-extractor.js';
|
|
20
|
+
export * from './backfill-dedup.js';
|
|
21
|
+
export * from './backfill-engine.js';
|
|
14
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAG5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
|
package/dist/analytics/index.js
CHANGED
|
@@ -11,4 +11,14 @@ export * from './session-types.js';
|
|
|
11
11
|
export * from './metrics-collector.js';
|
|
12
12
|
export * from './query-engine.js';
|
|
13
13
|
export * from './export.js';
|
|
14
|
+
// Phase 2 modules (auto-tracking)
|
|
15
|
+
export * from './token-extractor.js';
|
|
16
|
+
export * from './output-estimator.js';
|
|
17
|
+
export * from './analytics-summary.js';
|
|
18
|
+
// Offline transcript analysis modules
|
|
19
|
+
export * from './transcript-scanner.js';
|
|
20
|
+
export * from './transcript-parser.js';
|
|
21
|
+
export * from './transcript-token-extractor.js';
|
|
22
|
+
export * from './backfill-dedup.js';
|
|
23
|
+
export * from './backfill-engine.js';
|
|
14
24
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAE5B,kCAAkC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AAEvC,sCAAsC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-specific output token estimation based on input tokens.
|
|
3
|
+
*
|
|
4
|
+
* Ratios based on empirical observation:
|
|
5
|
+
* - Haiku: 30% (concise responses)
|
|
6
|
+
* - Sonnet: 40% (balanced responses)
|
|
7
|
+
* - Opus: 50% (detailed reasoning)
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Estimate output tokens from input tokens using model-specific ratios.
|
|
11
|
+
*
|
|
12
|
+
* @param inputTokens - Number of input tokens consumed
|
|
13
|
+
* @param modelName - Model name (e.g., "claude-sonnet-4.5")
|
|
14
|
+
* @returns Estimated output tokens (rounded to nearest integer)
|
|
15
|
+
*/
|
|
16
|
+
export declare function estimateOutputTokens(inputTokens: number, modelName: string): number;
|
|
17
|
+
/**
|
|
18
|
+
* Extract session ID from transcript path.
|
|
19
|
+
*
|
|
20
|
+
* Pattern: /path/to/.claude/projects/{sessionId}/transcript.jsonl
|
|
21
|
+
*
|
|
22
|
+
* @param transcriptPath - Full path to transcript file
|
|
23
|
+
* @returns Session ID (extracted or hashed)
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractSessionId(transcriptPath: string): string;
|
|
26
|
+
//# sourceMappingURL=output-estimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-estimator.d.ts","sourceRoot":"","sources":["../../src/analytics/output-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAc/D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-specific output token estimation based on input tokens.
|
|
3
|
+
*
|
|
4
|
+
* Ratios based on empirical observation:
|
|
5
|
+
* - Haiku: 30% (concise responses)
|
|
6
|
+
* - Sonnet: 40% (balanced responses)
|
|
7
|
+
* - Opus: 50% (detailed reasoning)
|
|
8
|
+
*/
|
|
9
|
+
const MODEL_OUTPUT_RATIOS = {
|
|
10
|
+
'haiku': 0.30,
|
|
11
|
+
'sonnet': 0.40,
|
|
12
|
+
'opus': 0.50
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_RATIO = 0.40; // Sonnet baseline
|
|
15
|
+
/**
|
|
16
|
+
* Estimate output tokens from input tokens using model-specific ratios.
|
|
17
|
+
*
|
|
18
|
+
* @param inputTokens - Number of input tokens consumed
|
|
19
|
+
* @param modelName - Model name (e.g., "claude-sonnet-4.5")
|
|
20
|
+
* @returns Estimated output tokens (rounded to nearest integer)
|
|
21
|
+
*/
|
|
22
|
+
export function estimateOutputTokens(inputTokens, modelName) {
|
|
23
|
+
if (inputTokens === 0)
|
|
24
|
+
return 0;
|
|
25
|
+
const ratio = detectModelRatio(modelName);
|
|
26
|
+
return Math.round(inputTokens * ratio);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extract session ID from transcript path.
|
|
30
|
+
*
|
|
31
|
+
* Pattern: /path/to/.claude/projects/{sessionId}/transcript.jsonl
|
|
32
|
+
*
|
|
33
|
+
* @param transcriptPath - Full path to transcript file
|
|
34
|
+
* @returns Session ID (extracted or hashed)
|
|
35
|
+
*/
|
|
36
|
+
export function extractSessionId(transcriptPath) {
|
|
37
|
+
// Try to extract from path pattern
|
|
38
|
+
const match = transcriptPath.match(/projects\/([a-f0-9]{8,})/i);
|
|
39
|
+
if (match) {
|
|
40
|
+
return match[1];
|
|
41
|
+
}
|
|
42
|
+
// Fallback: hash the path
|
|
43
|
+
const crypto = require('crypto');
|
|
44
|
+
return crypto.createHash('md5')
|
|
45
|
+
.update(transcriptPath)
|
|
46
|
+
.digest('hex')
|
|
47
|
+
.slice(0, 16);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Detect model tier and return appropriate output ratio.
|
|
51
|
+
*/
|
|
52
|
+
function detectModelRatio(modelName) {
|
|
53
|
+
const normalized = modelName.toLowerCase();
|
|
54
|
+
for (const [tier, ratio] of Object.entries(MODEL_OUTPUT_RATIOS)) {
|
|
55
|
+
if (normalized.includes(tier)) {
|
|
56
|
+
return ratio;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return DEFAULT_RATIO;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=output-estimator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-estimator.js","sourceRoot":"","sources":["../../src/analytics/output-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,mBAAmB,GAA2B;IAClD,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,IAAI;CACb,CAAC;AAEF,MAAM,aAAa,GAAG,IAAI,CAAC,CAAC,kBAAkB;AAE9C;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB,EAAE,SAAiB;IACzE,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEhC,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,cAAsB;IACrD,mCAAmC;IACnC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAEhE,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,0BAA0B;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;SAC5B,MAAM,CAAC,cAAc,CAAC;SACtB,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,SAAiB;IACzC,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAE3C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAChE,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../src/analytics/query-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../src/analytics/query-engine.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACvC,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,uBAAuB,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,WAAW;IAChB,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAkE1E,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC;IAiEzC,cAAc,CAAC,aAAa,GAAE,MAAW,GAAG,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAU5G,OAAO,CAAC,kBAAkB;CAiB3B;AAKD,wBAAgB,cAAc,IAAI,WAAW,CAK5C"}
|
|
@@ -3,10 +3,11 @@ import { getSessionManager } from './session-manager.js';
|
|
|
3
3
|
import { calculateCost } from './cost-estimator.js';
|
|
4
4
|
import * as fs from 'fs/promises';
|
|
5
5
|
import * as path from 'path';
|
|
6
|
+
import { homedir } from 'os';
|
|
6
7
|
export class QueryEngine {
|
|
7
8
|
async getCostReport(period) {
|
|
8
9
|
const range = this.calculateTimeRange(period);
|
|
9
|
-
const tokenLogPath = path.
|
|
10
|
+
const tokenLogPath = path.join(homedir(), '.omc', 'state', 'token-tracking.jsonl');
|
|
10
11
|
try {
|
|
11
12
|
const content = await fs.readFile(tokenLogPath, 'utf-8');
|
|
12
13
|
const lines = content.trim().split('\n').filter(l => l.length > 0);
|
|
@@ -61,7 +62,7 @@ export class QueryEngine {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
async getUsagePatterns() {
|
|
64
|
-
const tokenLogPath = path.
|
|
65
|
+
const tokenLogPath = path.join(homedir(), '.omc', 'state', 'token-tracking.jsonl');
|
|
65
66
|
const manager = getSessionManager();
|
|
66
67
|
const history = await manager.getHistory();
|
|
67
68
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-engine.js","sourceRoot":"","sources":["../../src/analytics/query-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAuB7B,MAAM,OAAO,WAAW;IACtB,KAAK,CAAC,aAAa,CAAC,MAAsC;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"query-engine.js","sourceRoot":"","sources":["../../src/analytics/query-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StatuslineStdin } from '../hud/types.js';
|
|
2
|
+
export interface ExtractedTokens {
|
|
3
|
+
inputTokens: number;
|
|
4
|
+
outputTokens: number;
|
|
5
|
+
cacheCreationTokens: number;
|
|
6
|
+
cacheReadTokens: number;
|
|
7
|
+
modelName: string;
|
|
8
|
+
agentName?: string;
|
|
9
|
+
isEstimated: boolean;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TokenDelta {
|
|
13
|
+
inputDelta: number;
|
|
14
|
+
cacheDelta: number;
|
|
15
|
+
cacheReadDelta: number;
|
|
16
|
+
}
|
|
17
|
+
export interface TokenSnapshot {
|
|
18
|
+
inputTokens: number;
|
|
19
|
+
cacheCreationTokens: number;
|
|
20
|
+
cacheReadTokens: number;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extract token usage from StatuslineStdin and calculate delta from previous snapshot.
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractTokens(stdin: StatuslineStdin, previousSnapshot: TokenSnapshot | null, modelName: string, agentName?: string): ExtractedTokens;
|
|
27
|
+
/**
|
|
28
|
+
* Create current snapshot for next delta calculation.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createSnapshot(stdin: StatuslineStdin): TokenSnapshot;
|
|
31
|
+
//# sourceMappingURL=token-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-extractor.d.ts","sourceRoot":"","sources":["../../src/analytics/token-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,eAAe,EACtB,gBAAgB,EAAE,aAAa,GAAG,IAAI,EACtC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,CAiCjB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,aAAa,CASpE"}
|