zozul-cli 0.3.8 → 0.4.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/.claude/settings.local.json +4 -1
- package/DEVELOPMENT.md +16 -9
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +4 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/dashboard/index.html +133 -35
- package/dist/storage/db.d.ts.map +1 -1
- package/dist/storage/db.js +12 -0
- package/dist/storage/db.js.map +1 -1
- package/dist/storage/repo.d.ts +7 -2
- package/dist/storage/repo.d.ts.map +1 -1
- package/dist/storage/repo.js +37 -26
- package/dist/storage/repo.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands.ts +5 -0
- package/src/dashboard/index.html +133 -35
- package/src/storage/db.ts +12 -0
- package/src/storage/repo.ts +44 -32
package/dist/storage/repo.js
CHANGED
|
@@ -34,14 +34,14 @@ export class SessionRepo {
|
|
|
34
34
|
ended_at = COALESCE(@ended_at, ended_at),
|
|
35
35
|
total_turns = @total_turns,
|
|
36
36
|
model = COALESCE(@model, model),
|
|
37
|
-
--
|
|
38
|
-
--
|
|
39
|
-
total_input_tokens =
|
|
40
|
-
total_output_tokens =
|
|
41
|
-
total_cache_read_tokens =
|
|
42
|
-
total_cache_creation_tokens =
|
|
43
|
-
total_cost_usd =
|
|
44
|
-
total_duration_ms =
|
|
37
|
+
-- JSONL values act as initial estimates; recomputeSessionCostsFromOtel
|
|
38
|
+
-- overwrites with authoritative OTEL data when available.
|
|
39
|
+
total_input_tokens = @total_input_tokens,
|
|
40
|
+
total_output_tokens = @total_output_tokens,
|
|
41
|
+
total_cache_read_tokens = @total_cache_read_tokens,
|
|
42
|
+
total_cache_creation_tokens = @total_cache_creation_tokens,
|
|
43
|
+
total_cost_usd = @total_cost_usd,
|
|
44
|
+
total_duration_ms = @total_duration_ms
|
|
45
45
|
`).run({
|
|
46
46
|
...session,
|
|
47
47
|
ended_at: session.ended_at ?? null,
|
|
@@ -143,11 +143,13 @@ export class SessionRepo {
|
|
|
143
143
|
listSessions(limit = 50, offset = 0, from, to) {
|
|
144
144
|
if (from && to) {
|
|
145
145
|
return this.db.prepare(`
|
|
146
|
-
SELECT * FROM
|
|
146
|
+
SELECT s.*, (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id AND t.is_real_user = 1) as user_turns
|
|
147
|
+
FROM sessions s WHERE s.parent_session_id IS NULL AND s.started_at >= ? AND s.started_at <= ? ORDER BY s.started_at DESC LIMIT ? OFFSET ?
|
|
147
148
|
`).all(from, to, limit, offset);
|
|
148
149
|
}
|
|
149
150
|
return this.db.prepare(`
|
|
150
|
-
SELECT * FROM
|
|
151
|
+
SELECT s.*, (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id AND t.is_real_user = 1) as user_turns
|
|
152
|
+
FROM sessions s WHERE s.parent_session_id IS NULL ORDER BY s.started_at DESC LIMIT ? OFFSET ?
|
|
151
153
|
`).all(limit, offset);
|
|
152
154
|
}
|
|
153
155
|
countSessions(from, to) {
|
|
@@ -159,7 +161,10 @@ export class SessionRepo {
|
|
|
159
161
|
return row.n;
|
|
160
162
|
}
|
|
161
163
|
getSession(id) {
|
|
162
|
-
return this.db.prepare(`
|
|
164
|
+
return this.db.prepare(`
|
|
165
|
+
SELECT s.*, (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id AND t.is_real_user = 1) as user_turns
|
|
166
|
+
FROM sessions s WHERE s.id = ?
|
|
167
|
+
`).get(id);
|
|
163
168
|
}
|
|
164
169
|
getSubSessions(parentSessionId) {
|
|
165
170
|
return this.db.prepare(`
|
|
@@ -214,13 +219,13 @@ export class SessionRepo {
|
|
|
214
219
|
// ── OTEL data ──
|
|
215
220
|
insertOtelMetric(metric) {
|
|
216
221
|
this.db.prepare(`
|
|
217
|
-
INSERT INTO otel_metrics (name, value, attributes, session_id, model, timestamp)
|
|
222
|
+
INSERT OR IGNORE INTO otel_metrics (name, value, attributes, session_id, model, timestamp)
|
|
218
223
|
VALUES (@name, @value, @attributes, @session_id, @model, @timestamp)
|
|
219
224
|
`).run(metric);
|
|
220
225
|
}
|
|
221
226
|
insertOtelMetricBatch(metrics) {
|
|
222
227
|
const stmt = this.db.prepare(`
|
|
223
|
-
INSERT INTO otel_metrics (name, value, attributes, session_id, model, timestamp)
|
|
228
|
+
INSERT OR IGNORE INTO otel_metrics (name, value, attributes, session_id, model, timestamp)
|
|
224
229
|
VALUES (@name, @value, @attributes, @session_id, @model, @timestamp)
|
|
225
230
|
`);
|
|
226
231
|
const tx = this.db.transaction((rows) => {
|
|
@@ -523,6 +528,7 @@ export class SessionRepo {
|
|
|
523
528
|
SUM(CASE WHEN t.is_real_user = 1 THEN 1 ELSE 0 END) as human_interventions,
|
|
524
529
|
COALESCE(SUM(t.duration_ms), 0) as total_duration_ms,
|
|
525
530
|
COALESCE(SUM(${PROPORTIONAL_COST_SQL}), 0) as total_cost_usd,
|
|
531
|
+
COALESCE(SUM(t.input_tokens), 0) + COALESCE(SUM(t.output_tokens), 0) + COALESCE(SUM(t.cache_read_tokens), 0) as total_tokens,
|
|
526
532
|
MAX(t.timestamp) as last_seen
|
|
527
533
|
FROM turns t
|
|
528
534
|
LEFT JOIN turn_tag_sets tts ON tts.turn_id = t.id
|
|
@@ -533,7 +539,7 @@ export class SessionRepo {
|
|
|
533
539
|
`).all(...params);
|
|
534
540
|
}
|
|
535
541
|
recomputeSessionCostsFromOtel() {
|
|
536
|
-
// Recompute from raw OTEL for sessions that have metrics
|
|
542
|
+
// Step 1: Recompute from raw OTEL for sessions that have metrics (authoritative)
|
|
537
543
|
const updated = this.db.prepare(`
|
|
538
544
|
UPDATE sessions SET
|
|
539
545
|
total_cost_usd = COALESCE((
|
|
@@ -543,30 +549,35 @@ export class SessionRepo {
|
|
|
543
549
|
total_input_tokens = COALESCE((
|
|
544
550
|
SELECT SUM(value) FROM otel_metrics
|
|
545
551
|
WHERE name = 'claude_code.token.usage' AND json_extract(attributes, '$.type') = 'input' AND session_id = sessions.id
|
|
546
|
-
),
|
|
552
|
+
), 0),
|
|
547
553
|
total_output_tokens = COALESCE((
|
|
548
554
|
SELECT SUM(value) FROM otel_metrics
|
|
549
555
|
WHERE name = 'claude_code.token.usage' AND json_extract(attributes, '$.type') = 'output' AND session_id = sessions.id
|
|
550
|
-
),
|
|
556
|
+
), 0),
|
|
551
557
|
total_cache_read_tokens = COALESCE((
|
|
552
558
|
SELECT SUM(value) FROM otel_metrics
|
|
553
559
|
WHERE name = 'claude_code.token.usage' AND json_extract(attributes, '$.type') = 'cacheRead' AND session_id = sessions.id
|
|
554
|
-
),
|
|
560
|
+
), 0),
|
|
555
561
|
total_cache_creation_tokens = COALESCE((
|
|
556
562
|
SELECT SUM(value) FROM otel_metrics
|
|
557
563
|
WHERE name = 'claude_code.token.usage' AND json_extract(attributes, '$.type') = 'cacheCreation' AND session_id = sessions.id
|
|
558
|
-
),
|
|
559
|
-
total_duration_ms = COALESCE((
|
|
560
|
-
SELECT SUM(value) * 1000 FROM otel_metrics
|
|
561
|
-
WHERE name = 'claude_code.active_time.total' AND session_id = sessions.id
|
|
562
|
-
), total_duration_ms)
|
|
564
|
+
), 0)
|
|
563
565
|
WHERE id IN (SELECT DISTINCT session_id FROM otel_metrics WHERE session_id IS NOT NULL)
|
|
564
566
|
`).run();
|
|
565
|
-
//
|
|
567
|
+
// Step 2: Recompute duration from turns for all sessions
|
|
568
|
+
this.db.prepare(`
|
|
569
|
+
UPDATE sessions SET
|
|
570
|
+
total_duration_ms = COALESCE((
|
|
571
|
+
SELECT SUM(duration_ms) FROM turns WHERE session_id = sessions.id
|
|
572
|
+
), 0)
|
|
573
|
+
`).run();
|
|
574
|
+
// Step 3: Fallback for sessions without OTEL — use SUM(turns.cost_usd)
|
|
566
575
|
this.db.prepare(`
|
|
567
|
-
UPDATE sessions SET
|
|
568
|
-
|
|
569
|
-
|
|
576
|
+
UPDATE sessions SET
|
|
577
|
+
total_cost_usd = COALESCE((
|
|
578
|
+
SELECT SUM(cost_usd) FROM turns WHERE session_id = sessions.id
|
|
579
|
+
), 0)
|
|
580
|
+
WHERE id NOT IN (SELECT DISTINCT session_id FROM otel_metrics WHERE session_id IS NOT NULL)
|
|
570
581
|
`).run();
|
|
571
582
|
return updated.changes;
|
|
572
583
|
}
|
package/dist/storage/repo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/storage/repo.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/storage/repo.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/commands.ts
CHANGED
|
@@ -350,6 +350,11 @@ export function buildCli(): Command {
|
|
|
350
350
|
console.log("Scanning for Claude Code session files...");
|
|
351
351
|
const result = await ingestAllSessions(repo, { force: opts.force, noTag: opts.tag === false });
|
|
352
352
|
console.log(`Ingested: ${result.ingested} Skipped: ${result.skipped}`);
|
|
353
|
+
|
|
354
|
+
// Recompute costs from OTEL to overwrite JSONL estimates with authoritative data
|
|
355
|
+
const fixed = repo.recomputeSessionCostsFromOtel();
|
|
356
|
+
if (fixed > 0) console.log(`Recomputed costs for ${fixed} sessions from OTEL data`);
|
|
357
|
+
|
|
353
358
|
db.close();
|
|
354
359
|
});
|
|
355
360
|
|
package/src/dashboard/index.html
CHANGED
|
@@ -58,6 +58,21 @@
|
|
|
58
58
|
.source-badge.local { border-color: var(--blue); color: var(--blue); }
|
|
59
59
|
.source-badge.clickable { cursor: pointer; }
|
|
60
60
|
.source-badge.clickable:hover { opacity: 0.7; }
|
|
61
|
+
.view-toggle {
|
|
62
|
+
background: none;
|
|
63
|
+
border: 1px solid var(--border);
|
|
64
|
+
color: var(--text-dim);
|
|
65
|
+
padding: 4px 10px;
|
|
66
|
+
border-radius: 6px;
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
font-family: var(--mono);
|
|
69
|
+
font-size: 13px;
|
|
70
|
+
font-weight: 600;
|
|
71
|
+
min-width: 32px;
|
|
72
|
+
transition: border-color 0.15s, color 0.15s;
|
|
73
|
+
}
|
|
74
|
+
.view-toggle:hover { border-color: var(--accent); color: var(--text); }
|
|
75
|
+
.view-toggle.tokens { color: var(--blue, #64b5f6); border-color: var(--blue, #64b5f6); }
|
|
61
76
|
.auto-btn {
|
|
62
77
|
background: none;
|
|
63
78
|
border: 1px solid var(--border);
|
|
@@ -437,6 +452,7 @@
|
|
|
437
452
|
<span class="subtitle">Agent Observability</span>
|
|
438
453
|
<div class="header-right">
|
|
439
454
|
<span class="source-badge" id="source-badge" style="display:none" onclick="toggleDataSource()">Local</span>
|
|
455
|
+
<button class="view-toggle" id="view-mode-toggle" onclick="toggleViewMode()" title="Switch between cost and token view">$</button>
|
|
440
456
|
<button class="auto-btn" onclick="manualRefresh()" title="Auto-refresh every 10s">
|
|
441
457
|
<span class="live-dot"></span>
|
|
442
458
|
Auto
|
|
@@ -458,9 +474,9 @@
|
|
|
458
474
|
<div id="view-summary" class="view active">
|
|
459
475
|
<div class="time-selector"></div>
|
|
460
476
|
<div class="stats-grid" id="summary-stats"></div>
|
|
461
|
-
<div class="chart-card"><h3>Daily Cost (30d)</h3><canvas id="chart-daily-cost"></canvas></div>
|
|
477
|
+
<div class="chart-card"><h3 id="chart-title">Daily Cost (30d)</h3><canvas id="chart-daily-cost"></canvas></div>
|
|
462
478
|
<div class="panel">
|
|
463
|
-
<div class="panel-header"><span>Cost by Project</span></div>
|
|
479
|
+
<div class="panel-header"><span id="project-panel-title">Cost by Project</span></div>
|
|
464
480
|
<ul class="project-list" id="project-breakdown"></ul>
|
|
465
481
|
</div>
|
|
466
482
|
</div>
|
|
@@ -512,7 +528,7 @@
|
|
|
512
528
|
<th class="sortable" data-sort="sessions:project_path">Project</th>
|
|
513
529
|
<th class="sortable" data-sort="sessions:started_at">Started</th>
|
|
514
530
|
<th class="sortable" data-sort="sessions:total_duration_ms">Duration</th>
|
|
515
|
-
<th class="sortable" data-sort="sessions:
|
|
531
|
+
<th class="sortable" data-sort="sessions:user_turns">Prompts</th>
|
|
516
532
|
<th class="sortable desc" data-sort="sessions:total_cost_usd">Cost</th>
|
|
517
533
|
<th class="sortable" data-sort="sessions:model">Model</th>
|
|
518
534
|
</tr></thead>
|
|
@@ -640,6 +656,7 @@ let remoteAvailable = false;
|
|
|
640
656
|
let autoRefreshTimer = null;
|
|
641
657
|
let currentView = 'summary';
|
|
642
658
|
let currentTimeWindow = '7d';
|
|
659
|
+
let viewMode = 'cost'; // 'cost' or 'tokens'
|
|
643
660
|
let previousView = 'tasks';
|
|
644
661
|
let allTaskGroups = [];
|
|
645
662
|
let allTagStats = [];
|
|
@@ -712,7 +729,16 @@ function toggleDataSource() {
|
|
|
712
729
|
async function fetchJson(path) {
|
|
713
730
|
if (dataSource === 'remote' && typeof ZOZUL_CONFIG !== 'undefined') {
|
|
714
731
|
try {
|
|
715
|
-
|
|
732
|
+
let remotePath = path.replace('/api/', '/');
|
|
733
|
+
// Ensure trailing slash before query params to avoid 307 redirects (which drop headers)
|
|
734
|
+
const qIdx = remotePath.indexOf('?');
|
|
735
|
+
if (qIdx === -1) {
|
|
736
|
+
if (!remotePath.endsWith('/')) remotePath += '/';
|
|
737
|
+
} else {
|
|
738
|
+
const base = remotePath.slice(0, qIdx);
|
|
739
|
+
if (!base.endsWith('/')) remotePath = base + '/' + remotePath.slice(qIdx);
|
|
740
|
+
}
|
|
741
|
+
const url = ZOZUL_CONFIG.remote.baseUrl + remotePath;
|
|
716
742
|
const res = await fetch(url, { headers: { 'X-API-Key': ZOZUL_CONFIG.remote.apiKey } });
|
|
717
743
|
if (res.ok) return res.json();
|
|
718
744
|
} catch {}
|
|
@@ -771,6 +797,24 @@ function fmtCost(n) {
|
|
|
771
797
|
const v = n ?? 0;
|
|
772
798
|
return v >= 1 ? '$' + v.toFixed(2) : '$' + v.toFixed(4);
|
|
773
799
|
}
|
|
800
|
+
function fmtTokens(n) {
|
|
801
|
+
const v = n ?? 0;
|
|
802
|
+
if (v >= 1_000_000) return (v / 1_000_000).toFixed(1) + 'M';
|
|
803
|
+
if (v >= 1_000) return (v / 1_000).toFixed(1) + 'K';
|
|
804
|
+
return v.toLocaleString();
|
|
805
|
+
}
|
|
806
|
+
function fmtMetric(cost, tokens) {
|
|
807
|
+
if (viewMode === 'tokens') return tokens != null ? fmtTokens(tokens) : '\u2014';
|
|
808
|
+
return fmtCost(cost);
|
|
809
|
+
}
|
|
810
|
+
function toggleViewMode() {
|
|
811
|
+
viewMode = viewMode === 'cost' ? 'tokens' : 'cost';
|
|
812
|
+
const btn = document.getElementById('view-mode-toggle');
|
|
813
|
+
btn.textContent = viewMode === 'cost' ? '$' : 'T';
|
|
814
|
+
btn.classList.toggle('tokens', viewMode === 'tokens');
|
|
815
|
+
btn.title = viewMode === 'cost' ? 'Switch to token view' : 'Switch to cost view';
|
|
816
|
+
loadViewData(currentView);
|
|
817
|
+
}
|
|
774
818
|
function fmtDuration(ms) {
|
|
775
819
|
if (!ms || ms <= 0) return '\u2014';
|
|
776
820
|
const s = Math.floor(ms / 1000);
|
|
@@ -836,9 +880,13 @@ function timeQueryString() {
|
|
|
836
880
|
return 'from=' + encodeURIComponent(from) + '&to=' + encodeURIComponent(now.toISOString());
|
|
837
881
|
}
|
|
838
882
|
|
|
883
|
+
function chartStepForWindow() {
|
|
884
|
+
return currentTimeWindow === '24h' ? '1h' : '1d';
|
|
885
|
+
}
|
|
886
|
+
|
|
839
887
|
function renderTimeSelectors() {
|
|
840
888
|
document.querySelectorAll('.time-selector').forEach(el => {
|
|
841
|
-
el.innerHTML = ['7d', '30d', 'all'].map(w =>
|
|
889
|
+
el.innerHTML = ['24h', '7d', '30d', 'all'].map(w =>
|
|
842
890
|
'<button class="time-btn' + (w === currentTimeWindow ? ' active' : '') + '" data-window="' + w + '">' +
|
|
843
891
|
(w === 'all' ? 'All' : w) + '</button>'
|
|
844
892
|
).join('');
|
|
@@ -934,18 +982,23 @@ async function loadSummary() {
|
|
|
934
982
|
const timeQs = timeQueryString();
|
|
935
983
|
const timeParam = timeQs ? '?' + timeQs : '';
|
|
936
984
|
const timeSep = timeQs ? '&' + timeQs : '';
|
|
937
|
-
const
|
|
985
|
+
const chartRange = currentTimeWindow === 'all' ? '90d' : currentTimeWindow;
|
|
986
|
+
const chartStep = currentTimeWindow === '24h' ? '1h' : '1d';
|
|
987
|
+
const [stats, tasks, costSeries, tokenSeries, sessionsResp] = await Promise.all([
|
|
938
988
|
fetchJson('/api/stats' + timeParam),
|
|
939
989
|
fetchJson('/api/tasks'),
|
|
940
|
-
fetchJson('/api/metrics/cost?range=' +
|
|
990
|
+
fetchJson('/api/metrics/cost?range=' + chartRange + '&step=' + chartStep),
|
|
991
|
+
fetchJson('/api/metrics/tokens?range=' + chartRange + '&step=' + chartStep),
|
|
941
992
|
fetchJson('/api/sessions?limit=500&offset=0' + timeSep),
|
|
942
993
|
]);
|
|
994
|
+
const totalTokens = (stats.total_input_tokens ?? 0) + (stats.total_output_tokens ?? 0) + (stats.total_cache_read_tokens ?? 0);
|
|
943
995
|
renderSummaryStats({
|
|
944
996
|
totalCost: stats.total_cost_usd ?? 0,
|
|
997
|
+
totalTokens,
|
|
945
998
|
totalSessions: stats.total_sessions ?? 0,
|
|
946
999
|
totalTasks: tasks.length ?? 0,
|
|
947
1000
|
});
|
|
948
|
-
|
|
1001
|
+
renderUsageChart(costSeries, tokenSeries);
|
|
949
1002
|
const sessions = Array.isArray(sessionsResp) ? sessionsResp : sessionsResp.sessions;
|
|
950
1003
|
renderProjectBreakdown(sessions);
|
|
951
1004
|
} catch (e) {
|
|
@@ -953,18 +1006,52 @@ async function loadSummary() {
|
|
|
953
1006
|
}
|
|
954
1007
|
}
|
|
955
1008
|
|
|
956
|
-
function
|
|
957
|
-
|
|
958
|
-
const
|
|
1009
|
+
function renderUsageChart(costData, tokenData) {
|
|
1010
|
+
const isTokens = viewMode === 'tokens';
|
|
1011
|
+
const isHourly = currentTimeWindow === '24h';
|
|
1012
|
+
const sourceData = isTokens ? tokenData : costData;
|
|
1013
|
+
|
|
1014
|
+
const titleEl = document.getElementById('chart-title');
|
|
1015
|
+
if (titleEl) {
|
|
1016
|
+
const period = isHourly ? 'Hourly' : 'Daily';
|
|
1017
|
+
titleEl.textContent = isTokens ? period + ' Tokens' : period + ' Cost';
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
if (!sourceData || !sourceData.length) return;
|
|
1021
|
+
|
|
1022
|
+
const labels = sourceData.map(d => {
|
|
959
1023
|
const dt = new Date(d.timestamp);
|
|
960
|
-
return
|
|
1024
|
+
return isHourly
|
|
1025
|
+
? dt.toLocaleTimeString(undefined, { hour: 'numeric', hour12: true })
|
|
1026
|
+
: dt.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
|
|
961
1027
|
});
|
|
962
|
-
|
|
1028
|
+
|
|
1029
|
+
let data, label, bgColor, borderColor, tooltipFmt, yFmt;
|
|
1030
|
+
if (isTokens) {
|
|
1031
|
+
data = sourceData.map(d => (d.input ?? 0) + (d.output ?? 0) + (d.cache_read ?? 0));
|
|
1032
|
+
label = 'Tokens';
|
|
1033
|
+
bgColor = 'rgba(100,181,246,0.3)';
|
|
1034
|
+
borderColor = '#64b5f6';
|
|
1035
|
+
tooltipFmt = ctx => fmtTokens(ctx.parsed.y);
|
|
1036
|
+
yFmt = v => fmtTokens(v);
|
|
1037
|
+
} else {
|
|
1038
|
+
data = sourceData.map(d => d.cost);
|
|
1039
|
+
label = 'Cost (USD)';
|
|
1040
|
+
bgColor = 'rgba(255,152,0,0.3)';
|
|
1041
|
+
borderColor = '#ff9800';
|
|
1042
|
+
tooltipFmt = ctx => '$' + ctx.parsed.y.toFixed(4);
|
|
1043
|
+
yFmt = v => '$' + v.toFixed(2);
|
|
1044
|
+
}
|
|
963
1045
|
|
|
964
1046
|
const existing = chartInstances['chart-daily-cost'];
|
|
965
1047
|
if (existing) {
|
|
966
1048
|
existing.data.labels = labels;
|
|
967
1049
|
existing.data.datasets[0].data = data;
|
|
1050
|
+
existing.data.datasets[0].label = label;
|
|
1051
|
+
existing.data.datasets[0].backgroundColor = bgColor;
|
|
1052
|
+
existing.data.datasets[0].borderColor = borderColor;
|
|
1053
|
+
existing.options.plugins.tooltip.callbacks.label = tooltipFmt;
|
|
1054
|
+
existing.options.scales.y.ticks.callback = yFmt;
|
|
968
1055
|
existing.update('none');
|
|
969
1056
|
return;
|
|
970
1057
|
}
|
|
@@ -976,10 +1063,10 @@ function renderDailyCostChart(costData) {
|
|
|
976
1063
|
data: {
|
|
977
1064
|
labels,
|
|
978
1065
|
datasets: [{
|
|
979
|
-
label
|
|
1066
|
+
label,
|
|
980
1067
|
data,
|
|
981
|
-
backgroundColor:
|
|
982
|
-
borderColor
|
|
1068
|
+
backgroundColor: bgColor,
|
|
1069
|
+
borderColor,
|
|
983
1070
|
borderWidth: 1,
|
|
984
1071
|
borderRadius: 3,
|
|
985
1072
|
}]
|
|
@@ -988,11 +1075,11 @@ function renderDailyCostChart(costData) {
|
|
|
988
1075
|
responsive: true,
|
|
989
1076
|
plugins: {
|
|
990
1077
|
legend: { display: false },
|
|
991
|
-
tooltip: { callbacks: { label:
|
|
1078
|
+
tooltip: { callbacks: { label: tooltipFmt } },
|
|
992
1079
|
},
|
|
993
1080
|
scales: {
|
|
994
1081
|
x: { ticks: { color: '#8b8fa3', font: { family: '"JetBrains Mono", monospace', size: 10 } } },
|
|
995
|
-
y: { ticks: { color: '#8b8fa3', font: { family: '"JetBrains Mono", monospace', size: 10 }, callback:
|
|
1082
|
+
y: { ticks: { color: '#8b8fa3', font: { family: '"JetBrains Mono", monospace', size: 10 }, callback: yFmt } },
|
|
996
1083
|
}
|
|
997
1084
|
}
|
|
998
1085
|
});
|
|
@@ -1009,26 +1096,34 @@ function renderProjectBreakdown(sessions) {
|
|
|
1009
1096
|
const byProject = {};
|
|
1010
1097
|
for (const s of sessions) {
|
|
1011
1098
|
const proj = s.project_path || 'Unknown';
|
|
1012
|
-
if (!byProject[proj]) byProject[proj] = 0;
|
|
1013
|
-
byProject[proj] += s.total_cost_usd || 0;
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1099
|
+
if (!byProject[proj]) byProject[proj] = { cost: 0, tokens: 0 };
|
|
1100
|
+
byProject[proj].cost += s.total_cost_usd || 0;
|
|
1101
|
+
byProject[proj].tokens += (s.total_input_tokens || 0) + (s.total_output_tokens || 0) + (s.total_cache_read_tokens || 0);
|
|
1102
|
+
}
|
|
1103
|
+
const isTokens = viewMode === 'tokens';
|
|
1104
|
+
const panelTitle = document.getElementById('project-panel-title');
|
|
1105
|
+
if (panelTitle) panelTitle.textContent = isTokens ? 'Tokens by Project' : 'Cost by Project';
|
|
1106
|
+
const sorted = Object.entries(byProject).sort((a, b) => (isTokens ? b[1].tokens - a[1].tokens : b[1].cost - a[1].cost));
|
|
1107
|
+
const maxVal = (isTokens ? sorted[0]?.[1].tokens : sorted[0]?.[1].cost) || 1;
|
|
1108
|
+
|
|
1109
|
+
el.innerHTML = sorted.slice(0, 10).map(([proj, vals]) => {
|
|
1110
|
+
const val = isTokens ? vals.tokens : vals.cost;
|
|
1111
|
+
const pct = Math.round(val / maxVal * 100);
|
|
1020
1112
|
return '<li class="project-item">' +
|
|
1021
1113
|
'<span class="project-name" title="' + escHtml(proj) + '">' + escHtml(basename(proj)) + '</span>' +
|
|
1022
1114
|
'<div class="project-bar-wrap"><div class="project-bar" style="width:' + pct + '%"></div></div>' +
|
|
1023
|
-
'<span class="project-cost">' + fmtCost(
|
|
1115
|
+
'<span class="project-cost">' + (isTokens ? fmtTokens(val) : fmtCost(val)) + '</span>' +
|
|
1024
1116
|
'</li>';
|
|
1025
1117
|
}).join('');
|
|
1026
1118
|
}
|
|
1027
1119
|
|
|
1028
1120
|
function renderSummaryStats(s) {
|
|
1029
1121
|
const grid = document.getElementById('summary-stats');
|
|
1122
|
+
const primary = viewMode === 'tokens'
|
|
1123
|
+
? { label: 'Total Tokens', value: fmtTokens(s.totalTokens) }
|
|
1124
|
+
: { label: 'Total Cost', value: fmtCost(s.totalCost) };
|
|
1030
1125
|
grid.innerHTML = [
|
|
1031
|
-
{ label:
|
|
1126
|
+
{ label: primary.label, value: primary.value, hero: true },
|
|
1032
1127
|
{ label: 'Total Sessions', value: fmtNum(s.totalSessions), hero: true },
|
|
1033
1128
|
{ label: 'Total Tasks', value: fmtNum(s.totalTasks), hero: true },
|
|
1034
1129
|
].map(c =>
|
|
@@ -1066,7 +1161,7 @@ function renderTaskTable(groups) {
|
|
|
1066
1161
|
return '<tr class="clickable" onclick="showTaskDetail(\'' + escHtml(g.tags).replace(/'/g, "\\'") + '\')">' +
|
|
1067
1162
|
'<td>' + pills + '</td>' +
|
|
1068
1163
|
'<td>' + fmtDuration(g.total_duration_ms) + '</td>' +
|
|
1069
|
-
'<td><span class="badge badge-cost">' +
|
|
1164
|
+
'<td><span class="badge badge-cost">' + fmtMetric(g.total_cost_usd, g.total_tokens) + '</span></td>' +
|
|
1070
1165
|
'<td>' + fmtNum(g.human_interventions) + '</td>' +
|
|
1071
1166
|
'<td title="' + fmtAbsolute(g.last_seen) + '">' + fmtRelative(g.last_seen) + '</td>' +
|
|
1072
1167
|
'</tr>';
|
|
@@ -1186,8 +1281,10 @@ async function loadTags() {
|
|
|
1186
1281
|
try {
|
|
1187
1282
|
const tasks = await fetchJson('/api/tasks');
|
|
1188
1283
|
if (!tasks.length) { allTagStats = []; renderTagTable([]); return; }
|
|
1284
|
+
const timeQs = timeQueryString();
|
|
1285
|
+
const timeSep = timeQs ? '&' + timeQs : '';
|
|
1189
1286
|
const statsList = await Promise.all(
|
|
1190
|
-
tasks.map(t => fetchJson('/api/tasks/stats?tags=' + encodeURIComponent(t.task) + '&mode=any')
|
|
1287
|
+
tasks.map(t => fetchJson('/api/tasks/stats?tags=' + encodeURIComponent(t.task) + '&mode=any' + timeSep)
|
|
1191
1288
|
.then(s => ({ ...s, tag: t.task, last_seen: t.last_tagged }))
|
|
1192
1289
|
.catch(() => ({ tag: t.task, turn_count: t.turn_count, human_interventions: 0, total_duration_ms: 0, total_cost_usd: 0, last_seen: t.last_tagged }))
|
|
1193
1290
|
)
|
|
@@ -1198,6 +1295,7 @@ async function loadTags() {
|
|
|
1198
1295
|
human_interventions: s.user_turns ?? s.human_interventions ?? 0,
|
|
1199
1296
|
total_duration_ms: s.total_duration_ms ?? 0,
|
|
1200
1297
|
total_cost_usd: s.total_cost_usd ?? 0,
|
|
1298
|
+
total_tokens: (s.total_input_tokens ?? 0) + (s.total_output_tokens ?? 0) + (s.total_cache_read_tokens ?? 0),
|
|
1201
1299
|
last_seen: s.last_seen,
|
|
1202
1300
|
}));
|
|
1203
1301
|
renderTagTable(sortData(allTagStats, sortState.tags));
|
|
@@ -1216,7 +1314,7 @@ function renderTagTable(stats) {
|
|
|
1216
1314
|
'<tr class="clickable" onclick="showTagDetail(\'' + escHtml(t.tag).replace(/'/g, "\\'") + '\')">' +
|
|
1217
1315
|
'<td><span class="tag-pill">' + escHtml(t.tag) + '</span></td>' +
|
|
1218
1316
|
'<td>' + fmtDuration(t.total_duration_ms) + '</td>' +
|
|
1219
|
-
'<td><span class="badge badge-cost">' +
|
|
1317
|
+
'<td><span class="badge badge-cost">' + fmtMetric(t.total_cost_usd, t.total_tokens) + '</span></td>' +
|
|
1220
1318
|
'<td>' + fmtNum(t.human_interventions) + '</td>' +
|
|
1221
1319
|
'<td title="' + fmtAbsolute(t.last_seen) + '">' + fmtRelative(t.last_seen) + '</td>' +
|
|
1222
1320
|
'</tr>'
|
|
@@ -1360,7 +1458,7 @@ async function showSession(id, returnTo) {
|
|
|
1360
1458
|
const [session, turns, subagents] = await Promise.all([
|
|
1361
1459
|
fetchJson('/api/sessions/' + id),
|
|
1362
1460
|
fetchJson('/api/sessions/' + id + '/turns'),
|
|
1363
|
-
fetchJson('/api/sessions/' + id + '/subagents'),
|
|
1461
|
+
fetchJson('/api/sessions/' + id + '/subagents').catch(() => []),
|
|
1364
1462
|
]);
|
|
1365
1463
|
|
|
1366
1464
|
const stats = [
|
|
@@ -1368,7 +1466,7 @@ async function showSession(id, returnTo) {
|
|
|
1368
1466
|
{ label: 'Project', value: '<span title="' + escHtml(session.project_path ?? '') + '">' + escHtml(basename(session.project_path)) + '</span>' },
|
|
1369
1467
|
{ label: 'Model', value: '<span style="font-family:var(--mono);font-size:13px">' + escHtml(session.model ?? '\u2014') + '</span>' },
|
|
1370
1468
|
{ label: 'Duration', value: fmtDuration(session.total_duration_ms) },
|
|
1371
|
-
{ label: '
|
|
1469
|
+
{ label: 'Prompts', value: session.user_turns ?? session.total_turns },
|
|
1372
1470
|
{ label: 'Input Tokens', value: fmtNum(session.total_input_tokens) },
|
|
1373
1471
|
{ label: 'Output Tokens', value: fmtNum(session.total_output_tokens) },
|
|
1374
1472
|
{ label: 'Cost', value: fmtCost(session.total_cost_usd) },
|
|
@@ -1535,8 +1633,8 @@ function renderSessionsTable(sessions) {
|
|
|
1535
1633
|
'<td' + projAttr + '>' + escHtml(proj) + '</td>' +
|
|
1536
1634
|
'<td title="' + fmtAbsolute(s.started_at) + '">' + fmtRelative(s.started_at) + '</td>' +
|
|
1537
1635
|
'<td>' + fmtDuration(s.total_duration_ms) + '</td>' +
|
|
1538
|
-
'<td>' + (s.total_turns ?? 0) + '</td>' +
|
|
1539
|
-
'<td><span class="badge badge-cost">' +
|
|
1636
|
+
'<td>' + (s.user_turns ?? s.total_turns ?? 0) + '</td>' +
|
|
1637
|
+
'<td><span class="badge badge-cost">' + fmtMetric(s.total_cost_usd, (s.total_input_tokens || 0) + (s.total_output_tokens || 0) + (s.total_cache_read_tokens || 0)) + '</span></td>' +
|
|
1540
1638
|
'<td style="font-family:var(--mono);font-size:11px;color:var(--text-dim)">' + escHtml(s.model ?? '\u2014') + '</td>' +
|
|
1541
1639
|
'</tr>';
|
|
1542
1640
|
}).join('');
|
package/src/storage/db.ts
CHANGED
|
@@ -126,6 +126,18 @@ function migrate(db: Database.Database): void {
|
|
|
126
126
|
try { db.exec(sql); } catch { /* column already exists */ }
|
|
127
127
|
}
|
|
128
128
|
db.exec(`CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id)`);
|
|
129
|
+
|
|
130
|
+
// Deduplicate otel_metrics and add unique constraint to match backend
|
|
131
|
+
try {
|
|
132
|
+
db.exec(`
|
|
133
|
+
DELETE FROM otel_metrics WHERE id NOT IN (
|
|
134
|
+
SELECT MIN(id) FROM otel_metrics
|
|
135
|
+
GROUP BY session_id, name, timestamp, json_extract(attributes, '$.type')
|
|
136
|
+
);
|
|
137
|
+
CREATE UNIQUE INDEX uq_otel_metrics_session_name_ts_type
|
|
138
|
+
ON otel_metrics(session_id, name, timestamp, json_extract(attributes, '$.type'));
|
|
139
|
+
`);
|
|
140
|
+
} catch { /* index already exists */ }
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
export type SessionRow = {
|