oh-my-claude-sisyphus 3.4.1 ā 3.4.3
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/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/analytics/analytics-summary.d.ts +47 -0
- package/dist/analytics/analytics-summary.d.ts.map +1 -0
- package/dist/analytics/analytics-summary.js +170 -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 +118 -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 +163 -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/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 +81 -0
- 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 +19 -0
- package/dist/analytics/transcript-token-extractor.d.ts.map +1 -0
- package/dist/analytics/transcript-token-extractor.js +89 -0
- package/dist/analytics/transcript-token-extractor.js.map +1 -0
- package/dist/analytics/types.d.ts +52 -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/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/docs/FULL-README.md +2 -2
- 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/omc-setup/SKILL.md +30 -5
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { readdir, stat } from 'fs/promises';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
/**
|
|
6
|
+
* UUID regex pattern for session IDs
|
|
7
|
+
*/
|
|
8
|
+
const UUID_REGEX = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
|
|
9
|
+
/**
|
|
10
|
+
* Decode project directory name back to original path.
|
|
11
|
+
*
|
|
12
|
+
* The encoding scheme used by Claude Code is lossy - it converts all path
|
|
13
|
+
* separators (/) to dashes (-), but legitimate dashes in directory names
|
|
14
|
+
* also become dashes, making them indistinguishable.
|
|
15
|
+
*
|
|
16
|
+
* Strategy:
|
|
17
|
+
* 1. Try simple decode (all dashes -> slashes) and check if path exists
|
|
18
|
+
* 2. If not, try to reconstruct by checking filesystem for partial matches
|
|
19
|
+
* 3. Fall back to simple decode if nothing else works
|
|
20
|
+
*
|
|
21
|
+
* Example: "-home-bellman-my-project"
|
|
22
|
+
* - Simple decode: "/home/bellman/my/project" (WRONG if "my-project" is one dir)
|
|
23
|
+
* - Smart decode: "/home/bellman/my-project" (checks filesystem)
|
|
24
|
+
*
|
|
25
|
+
* @internal Exported for testing
|
|
26
|
+
*/
|
|
27
|
+
export function decodeProjectPath(dirName) {
|
|
28
|
+
if (!dirName.startsWith('-')) {
|
|
29
|
+
return dirName;
|
|
30
|
+
}
|
|
31
|
+
// Simple decode: replace all dashes with slashes
|
|
32
|
+
const simplePath = '/' + dirName.slice(1).replace(/-/g, '/');
|
|
33
|
+
// If simple decode exists, we're done
|
|
34
|
+
if (existsSync(simplePath)) {
|
|
35
|
+
return simplePath;
|
|
36
|
+
}
|
|
37
|
+
// Try to reconstruct by checking filesystem for partial matches
|
|
38
|
+
const segments = dirName.slice(1).split('-');
|
|
39
|
+
const possiblePaths = [];
|
|
40
|
+
// Generate all possible interpretations by trying different hyphen positions
|
|
41
|
+
function generatePaths(parts, index, currentPath) {
|
|
42
|
+
if (index >= parts.length) {
|
|
43
|
+
possiblePaths.push(currentPath);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Try adding next segment as a new directory
|
|
47
|
+
generatePaths(parts, index + 1, currentPath + '/' + parts[index]);
|
|
48
|
+
// Try combining with previous segment using hyphen (if not first segment)
|
|
49
|
+
if (index > 0 && currentPath) {
|
|
50
|
+
const pathParts = currentPath.split('/');
|
|
51
|
+
const lastPart = pathParts.pop() || '';
|
|
52
|
+
const newPath = pathParts.join('/') + '/' + lastPart + '-' + parts[index];
|
|
53
|
+
generatePaths(parts, index + 1, newPath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
generatePaths(segments, 0, '');
|
|
57
|
+
// Find the first path that exists on filesystem
|
|
58
|
+
for (const path of possiblePaths) {
|
|
59
|
+
if (existsSync(path)) {
|
|
60
|
+
return path;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Fall back to simple decode
|
|
64
|
+
return simplePath;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if a path matches a glob pattern (simple implementation)
|
|
68
|
+
*/
|
|
69
|
+
function matchesPattern(path, pattern) {
|
|
70
|
+
if (!pattern)
|
|
71
|
+
return true;
|
|
72
|
+
// Convert glob pattern to regex
|
|
73
|
+
const regexPattern = pattern
|
|
74
|
+
.replace(/\./g, '\\.')
|
|
75
|
+
.replace(/\*/g, '.*')
|
|
76
|
+
.replace(/\?/g, '.');
|
|
77
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
78
|
+
return regex.test(path);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Scan for all transcript files in ~/.claude/projects/
|
|
82
|
+
*/
|
|
83
|
+
export async function scanTranscripts(options = {}) {
|
|
84
|
+
const projectsDir = join(homedir(), '.claude', 'projects');
|
|
85
|
+
const transcripts = [];
|
|
86
|
+
const projectDirs = new Set();
|
|
87
|
+
try {
|
|
88
|
+
// Read all project directories
|
|
89
|
+
const entries = await readdir(projectsDir, { withFileTypes: true });
|
|
90
|
+
for (const entry of entries) {
|
|
91
|
+
if (!entry.isDirectory())
|
|
92
|
+
continue;
|
|
93
|
+
const projectDir = entry.name;
|
|
94
|
+
const projectPath = decodeProjectPath(projectDir);
|
|
95
|
+
// Apply project filter if specified
|
|
96
|
+
if (!matchesPattern(projectPath, options.projectFilter)) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const fullProjectPath = join(projectsDir, projectDir);
|
|
100
|
+
// Read all files in this project directory
|
|
101
|
+
const projectFiles = await readdir(fullProjectPath);
|
|
102
|
+
for (const fileName of projectFiles) {
|
|
103
|
+
// Skip sessions-index.json and any non-.jsonl files
|
|
104
|
+
if (fileName === 'sessions-index.json' || !fileName.endsWith('.jsonl')) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
// Extract session ID from filename
|
|
108
|
+
const sessionId = fileName.replace('.jsonl', '');
|
|
109
|
+
// Validate session ID format (must be UUID)
|
|
110
|
+
if (!UUID_REGEX.test(sessionId)) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const filePath = join(fullProjectPath, fileName);
|
|
114
|
+
const fileStats = await stat(filePath);
|
|
115
|
+
// Apply date filter if specified
|
|
116
|
+
if (options.minDate && fileStats.mtime < options.minDate) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
transcripts.push({
|
|
120
|
+
projectPath,
|
|
121
|
+
projectDir,
|
|
122
|
+
sessionId,
|
|
123
|
+
filePath,
|
|
124
|
+
fileSize: fileStats.size,
|
|
125
|
+
modifiedTime: fileStats.mtime
|
|
126
|
+
});
|
|
127
|
+
projectDirs.add(projectDir);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// If projects directory doesn't exist, return empty result
|
|
133
|
+
if (error.code === 'ENOENT') {
|
|
134
|
+
return {
|
|
135
|
+
transcripts: [],
|
|
136
|
+
totalSize: 0,
|
|
137
|
+
projectCount: 0
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
const totalSize = transcripts.reduce((sum, t) => sum + t.fileSize, 0);
|
|
143
|
+
return {
|
|
144
|
+
transcripts,
|
|
145
|
+
totalSize,
|
|
146
|
+
projectCount: projectDirs.size
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=transcript-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-scanner.js","sourceRoot":"","sources":["../../src/analytics/transcript-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TokenUsage, TranscriptEntry } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extracted usage with metadata
|
|
4
|
+
*/
|
|
5
|
+
export interface ExtractedUsage {
|
|
6
|
+
usage: TokenUsage;
|
|
7
|
+
entryId: string;
|
|
8
|
+
sourceFile: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Extract token usage from transcript entry
|
|
12
|
+
*
|
|
13
|
+
* @param entry - Transcript entry from JSONL file
|
|
14
|
+
* @param sessionId - Session ID (override if not in entry)
|
|
15
|
+
* @param sourceFile - Source file path for tracking
|
|
16
|
+
* @returns ExtractedUsage or null if entry has no usage data
|
|
17
|
+
*/
|
|
18
|
+
export declare function extractTokenUsage(entry: TranscriptEntry, sessionId: string, sourceFile: string): ExtractedUsage | null;
|
|
19
|
+
//# sourceMappingURL=transcript-token-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-token-extractor.d.ts","sourceRoot":"","sources":["../../src/analytics/transcript-token-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAqDD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,GAAG,IAAI,CA2CvB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize model name to pricing tier
|
|
4
|
+
*/
|
|
5
|
+
function normalizeModelName(model) {
|
|
6
|
+
const lower = model.toLowerCase();
|
|
7
|
+
if (lower.includes('opus')) {
|
|
8
|
+
return 'claude-opus-4.5';
|
|
9
|
+
}
|
|
10
|
+
else if (lower.includes('sonnet')) {
|
|
11
|
+
return 'claude-sonnet-4.5';
|
|
12
|
+
}
|
|
13
|
+
else if (lower.includes('haiku')) {
|
|
14
|
+
return 'claude-haiku-4';
|
|
15
|
+
}
|
|
16
|
+
// Fallback to original if no match
|
|
17
|
+
return model;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Detect agent name from transcript entry context
|
|
21
|
+
*/
|
|
22
|
+
function detectAgentName(entry) {
|
|
23
|
+
// Check for agent context in entry
|
|
24
|
+
if (entry.agentId || entry.slug) {
|
|
25
|
+
return entry.slug || entry.agentId;
|
|
26
|
+
}
|
|
27
|
+
// Check for Task tool usage in content
|
|
28
|
+
if (entry.message?.content) {
|
|
29
|
+
for (const block of entry.message.content) {
|
|
30
|
+
if (block.type === 'tool_use' && block.name === 'Task') {
|
|
31
|
+
const input = block.input;
|
|
32
|
+
if (input?.subagent_type) {
|
|
33
|
+
return input.subagent_type;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generate unique entry ID for deduplication
|
|
42
|
+
*/
|
|
43
|
+
function generateEntryId(sessionId, timestamp, model) {
|
|
44
|
+
const hash = createHash('sha256');
|
|
45
|
+
hash.update(`${sessionId}:${timestamp}:${model}`);
|
|
46
|
+
return hash.digest('hex');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Extract token usage from transcript entry
|
|
50
|
+
*
|
|
51
|
+
* @param entry - Transcript entry from JSONL file
|
|
52
|
+
* @param sessionId - Session ID (override if not in entry)
|
|
53
|
+
* @param sourceFile - Source file path for tracking
|
|
54
|
+
* @returns ExtractedUsage or null if entry has no usage data
|
|
55
|
+
*/
|
|
56
|
+
export function extractTokenUsage(entry, sessionId, sourceFile) {
|
|
57
|
+
// Only process assistant entries with usage data
|
|
58
|
+
if (entry.type !== 'assistant' || !entry.message?.usage) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const usage = entry.message.usage;
|
|
62
|
+
const model = entry.message.model;
|
|
63
|
+
if (!model) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
// Use ACTUAL output_tokens from transcript (not estimates!)
|
|
67
|
+
const outputTokens = usage.output_tokens;
|
|
68
|
+
const inputTokens = usage.input_tokens || 0;
|
|
69
|
+
// Handle cache tokens
|
|
70
|
+
const cacheCreationTokens = usage.cache_creation_input_tokens || 0;
|
|
71
|
+
const cacheReadTokens = usage.cache_read_input_tokens || 0;
|
|
72
|
+
const tokenUsage = {
|
|
73
|
+
timestamp: entry.timestamp,
|
|
74
|
+
sessionId: sessionId || entry.sessionId,
|
|
75
|
+
agentName: detectAgentName(entry),
|
|
76
|
+
modelName: normalizeModelName(model),
|
|
77
|
+
inputTokens,
|
|
78
|
+
outputTokens,
|
|
79
|
+
cacheCreationTokens,
|
|
80
|
+
cacheReadTokens
|
|
81
|
+
};
|
|
82
|
+
const entryId = generateEntryId(tokenUsage.sessionId, tokenUsage.timestamp, tokenUsage.modelName);
|
|
83
|
+
return {
|
|
84
|
+
usage: tokenUsage,
|
|
85
|
+
entryId,
|
|
86
|
+
sourceFile
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=transcript-token-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-token-extractor.js","sourceRoot":"","sources":["../../src/analytics/transcript-token-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcript entry from .claude session logs
|
|
3
|
+
*/
|
|
4
|
+
export interface TranscriptEntry {
|
|
5
|
+
type: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
agentId?: string;
|
|
9
|
+
slug?: string;
|
|
10
|
+
message?: {
|
|
11
|
+
model?: string;
|
|
12
|
+
role?: string;
|
|
13
|
+
usage?: {
|
|
14
|
+
input_tokens: number;
|
|
15
|
+
output_tokens: number;
|
|
16
|
+
cache_creation_input_tokens?: number;
|
|
17
|
+
cache_read_input_tokens?: number;
|
|
18
|
+
cache_creation?: {
|
|
19
|
+
ephemeral_5m_input_tokens?: number;
|
|
20
|
+
ephemeral_1h_input_tokens?: number;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
content?: Array<{
|
|
24
|
+
type: string;
|
|
25
|
+
name?: string;
|
|
26
|
+
input?: {
|
|
27
|
+
subagent_type?: string;
|
|
28
|
+
model?: string;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
1
33
|
export interface TokenUsage {
|
|
2
34
|
timestamp: string;
|
|
3
35
|
sessionId: string;
|
|
@@ -7,6 +39,7 @@ export interface TokenUsage {
|
|
|
7
39
|
outputTokens: number;
|
|
8
40
|
cacheCreationTokens: number;
|
|
9
41
|
cacheReadTokens: number;
|
|
42
|
+
isEstimated?: boolean;
|
|
10
43
|
}
|
|
11
44
|
export interface CostBreakdown {
|
|
12
45
|
inputCost: number;
|
|
@@ -33,5 +66,24 @@ export interface ModelPricing {
|
|
|
33
66
|
cacheWriteMarkup: number;
|
|
34
67
|
cacheReadDiscount: number;
|
|
35
68
|
}
|
|
69
|
+
export interface AggregateTokenStats {
|
|
70
|
+
totalInputTokens: number;
|
|
71
|
+
totalOutputTokens: number;
|
|
72
|
+
totalCacheCreation: number;
|
|
73
|
+
totalCacheRead: number;
|
|
74
|
+
totalCost: number;
|
|
75
|
+
byAgent: Record<string, {
|
|
76
|
+
tokens: number;
|
|
77
|
+
cost: number;
|
|
78
|
+
}>;
|
|
79
|
+
byModel: Record<string, {
|
|
80
|
+
tokens: number;
|
|
81
|
+
cost: number;
|
|
82
|
+
}>;
|
|
83
|
+
sessionCount: number;
|
|
84
|
+
entryCount: number;
|
|
85
|
+
firstEntry: string | null;
|
|
86
|
+
lastEntry: string | null;
|
|
87
|
+
}
|
|
36
88
|
export declare const PRICING: Record<string, ModelPricing>;
|
|
37
89
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analytics/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analytics/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analytics/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analytics/types.ts"],"names":[],"mappings":"AAuFA,MAAM,CAAC,MAAM,OAAO,GAAiC;IACnD,gBAAgB,EAAE;QAChB,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,IAAI;QACtB,gBAAgB,EAAE,IAAI;QACtB,iBAAiB,EAAE,IAAI;KACxB;IACD,mBAAmB,EAAE;QACnB,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,KAAK;QACvB,gBAAgB,EAAE,IAAI;QACtB,iBAAiB,EAAE,IAAI;KACxB;IACD,iBAAiB,EAAE;QACjB,eAAe,EAAE,KAAK;QACtB,gBAAgB,EAAE,KAAK;QACvB,gBAAgB,EAAE,IAAI;QACtB,iBAAiB,EAAE,IAAI;KACxB;CACF,CAAC"}
|
package/dist/cli/analytics.js
CHANGED
|
@@ -6,10 +6,35 @@ import { sessionsCommand } from './commands/sessions.js';
|
|
|
6
6
|
import { agentsCommand } from './commands/agents.js';
|
|
7
7
|
import { exportCommand } from './commands/export.js';
|
|
8
8
|
import { cleanupCommand } from './commands/cleanup.js';
|
|
9
|
+
// Display enhanced banner using gradient-string (loaded dynamically)
|
|
10
|
+
async function displayBanner() {
|
|
11
|
+
try {
|
|
12
|
+
// @ts-ignore - gradient-string will be installed during setup
|
|
13
|
+
const gradient = await import('gradient-string');
|
|
14
|
+
const banner = gradient.default.pastel.multiline([
|
|
15
|
+
'āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā',
|
|
16
|
+
'ā OMC Analytics - Token Tracking CLI ā',
|
|
17
|
+
'āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'
|
|
18
|
+
].join('\n'));
|
|
19
|
+
console.log(banner);
|
|
20
|
+
console.log('');
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
// Fallback if gradient-string not installed
|
|
24
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
25
|
+
console.log('ā OMC Analytics - Token Tracking CLI ā');
|
|
26
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
27
|
+
console.log('');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
9
30
|
program
|
|
10
31
|
.name('omc-analytics')
|
|
11
32
|
.description('OMC Analytics CLI - Token tracking, cost reports, and session management')
|
|
12
|
-
.version('1.0.0')
|
|
33
|
+
.version('1.0.0')
|
|
34
|
+
.hook('preAction', async () => {
|
|
35
|
+
// Show banner before each command
|
|
36
|
+
await displayBanner();
|
|
37
|
+
});
|
|
13
38
|
// Stats command
|
|
14
39
|
program
|
|
15
40
|
.command('stats')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/cli/analytics.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,0EAA0E,CAAC;KACvF,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/cli/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface BackfillCommandOptions {
|
|
2
|
+
project?: string;
|
|
3
|
+
from?: string;
|
|
4
|
+
to?: string;
|
|
5
|
+
dryRun?: boolean;
|
|
6
|
+
reset?: boolean;
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* omc backfill command handler
|
|
12
|
+
*/
|
|
13
|
+
export declare function backfillCommand(options: BackfillCommandOptions): Promise<void>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=backfill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/backfill.ts"],"names":[],"mappings":"AAIA,UAAU,sBAAsB;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAgCD;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwIpF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { BackfillEngine } from '../../analytics/backfill-engine.js';
|
|
2
|
+
import { BackfillDedup } from '../../analytics/backfill-dedup.js';
|
|
3
|
+
import { colors, formatCostWithColor, formatDuration } from '../utils/formatting.js';
|
|
4
|
+
/**
|
|
5
|
+
* Simple ASCII progress bar
|
|
6
|
+
*/
|
|
7
|
+
function renderProgressBar(current, total, width = 40) {
|
|
8
|
+
const percentage = total > 0 ? current / total : 0;
|
|
9
|
+
const filled = Math.round(width * percentage);
|
|
10
|
+
const empty = width - filled;
|
|
11
|
+
const bar = 'ā'.repeat(filled) + 'ā'.repeat(empty);
|
|
12
|
+
const percent = (percentage * 100).toFixed(1);
|
|
13
|
+
return `[${bar}] ${percent}%`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Format file size in human-readable format
|
|
17
|
+
*/
|
|
18
|
+
function formatFileSize(bytes) {
|
|
19
|
+
if (bytes < 1024)
|
|
20
|
+
return `${bytes} B`;
|
|
21
|
+
if (bytes < 1024 * 1024)
|
|
22
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
23
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Clear current line in terminal
|
|
27
|
+
*/
|
|
28
|
+
function clearLine() {
|
|
29
|
+
process.stdout.write('\r\x1b[K');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* omc backfill command handler
|
|
33
|
+
*/
|
|
34
|
+
export async function backfillCommand(options) {
|
|
35
|
+
// Handle --reset flag
|
|
36
|
+
if (options.reset) {
|
|
37
|
+
const dedup = new BackfillDedup();
|
|
38
|
+
await dedup.reset();
|
|
39
|
+
if (!options.json) {
|
|
40
|
+
console.log(colors.green('ā Deduplication index reset successfully'));
|
|
41
|
+
console.log(colors.gray(' All transcripts will be re-processed on next backfill'));
|
|
42
|
+
}
|
|
43
|
+
// Exit if only resetting
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Parse date options
|
|
47
|
+
const backfillOptions = {
|
|
48
|
+
projectFilter: options.project,
|
|
49
|
+
dateFrom: options.from ? new Date(options.from) : undefined,
|
|
50
|
+
dateTo: options.to ? new Date(options.to) : undefined,
|
|
51
|
+
dryRun: options.dryRun,
|
|
52
|
+
verbose: options.verbose,
|
|
53
|
+
};
|
|
54
|
+
// Validate dates
|
|
55
|
+
if (backfillOptions.dateFrom && isNaN(backfillOptions.dateFrom.getTime())) {
|
|
56
|
+
console.error(colors.red('Error: Invalid --from date. Use ISO format (YYYY-MM-DD)'));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (backfillOptions.dateTo && isNaN(backfillOptions.dateTo.getTime())) {
|
|
60
|
+
console.error(colors.red('Error: Invalid --to date. Use ISO format (YYYY-MM-DD)'));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
// Initialize engine
|
|
64
|
+
const engine = new BackfillEngine();
|
|
65
|
+
// Setup progress handler
|
|
66
|
+
let lastProgress = null;
|
|
67
|
+
engine.on('progress', (progress) => {
|
|
68
|
+
lastProgress = progress;
|
|
69
|
+
if (!options.json && !options.verbose) {
|
|
70
|
+
// Show progress bar
|
|
71
|
+
clearLine();
|
|
72
|
+
const progressBar = renderProgressBar(progress.filesProcessed, progress.totalFiles);
|
|
73
|
+
const currentFile = progress.currentFile.length > 30
|
|
74
|
+
? '...' + progress.currentFile.slice(-27)
|
|
75
|
+
: progress.currentFile;
|
|
76
|
+
process.stdout.write(`${progressBar} ${colors.cyan(currentFile)} | ` +
|
|
77
|
+
`${colors.green('+' + progress.entriesAdded)} | ` +
|
|
78
|
+
`${colors.yellow('~' + progress.duplicatesSkipped)} | ` +
|
|
79
|
+
formatCostWithColor(progress.currentCost));
|
|
80
|
+
}
|
|
81
|
+
else if (options.verbose && !options.json) {
|
|
82
|
+
console.log(`[${progress.filesProcessed}/${progress.totalFiles}] ${progress.currentFile} ` +
|
|
83
|
+
`(+${progress.entriesAdded}, ~${progress.duplicatesSkipped})`);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// Show header
|
|
87
|
+
if (!options.json) {
|
|
88
|
+
console.log(colors.bold('\nš Backfill Analytics from Transcripts\n'));
|
|
89
|
+
if (options.dryRun) {
|
|
90
|
+
console.log(colors.yellow('ā ļø DRY RUN MODE - No data will be written\n'));
|
|
91
|
+
}
|
|
92
|
+
if (backfillOptions.projectFilter) {
|
|
93
|
+
console.log(colors.gray(` Project filter: ${backfillOptions.projectFilter}`));
|
|
94
|
+
}
|
|
95
|
+
if (backfillOptions.dateFrom) {
|
|
96
|
+
console.log(colors.gray(` From: ${backfillOptions.dateFrom.toISOString().split('T')[0]}`));
|
|
97
|
+
}
|
|
98
|
+
if (backfillOptions.dateTo) {
|
|
99
|
+
console.log(colors.gray(` To: ${backfillOptions.dateTo.toISOString().split('T')[0]}`));
|
|
100
|
+
}
|
|
101
|
+
console.log('');
|
|
102
|
+
}
|
|
103
|
+
// Run backfill
|
|
104
|
+
const startTime = Date.now();
|
|
105
|
+
const result = await engine.run(backfillOptions);
|
|
106
|
+
// Clear progress line
|
|
107
|
+
if (!options.json && !options.verbose) {
|
|
108
|
+
clearLine();
|
|
109
|
+
}
|
|
110
|
+
// Output results
|
|
111
|
+
if (options.json) {
|
|
112
|
+
console.log(JSON.stringify(result, null, 2));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.log(colors.bold('\nā Backfill Complete\n'));
|
|
116
|
+
// Summary table
|
|
117
|
+
const summaryTable = [
|
|
118
|
+
['Files Processed', colors.cyan(result.filesProcessed.toString())],
|
|
119
|
+
['Entries Added', colors.green(result.entriesAdded.toString())],
|
|
120
|
+
['Duplicates Skipped', colors.yellow(result.duplicatesSkipped.toString())],
|
|
121
|
+
['Errors Encountered', result.errorsEncountered > 0
|
|
122
|
+
? colors.red(result.errorsEncountered.toString())
|
|
123
|
+
: colors.gray(result.errorsEncountered.toString())
|
|
124
|
+
],
|
|
125
|
+
['Total Cost Discovered', formatCostWithColor(result.totalCostDiscovered)],
|
|
126
|
+
['Time Elapsed', colors.gray(formatDuration(result.timeElapsed))],
|
|
127
|
+
];
|
|
128
|
+
// Find max label length for alignment
|
|
129
|
+
const maxLabelLength = Math.max(...summaryTable.map(row => row[0].length));
|
|
130
|
+
for (const [label, value] of summaryTable) {
|
|
131
|
+
const padding = ' '.repeat(maxLabelLength - label.length);
|
|
132
|
+
console.log(` ${label}${padding} ${value}`);
|
|
133
|
+
}
|
|
134
|
+
console.log('');
|
|
135
|
+
if (options.dryRun) {
|
|
136
|
+
console.log(colors.yellow(' This was a dry run. Run without --dry-run to write data.'));
|
|
137
|
+
console.log('');
|
|
138
|
+
}
|
|
139
|
+
if (result.errorsEncountered > 0) {
|
|
140
|
+
console.log(colors.yellow(` ā ļø ${result.errorsEncountered} errors encountered during processing`));
|
|
141
|
+
console.log(colors.gray(' Run with --verbose to see error details'));
|
|
142
|
+
console.log('');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=backfill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../../src/cli/commands/backfill.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/stats.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/stats.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyF/F"}
|