@statforge/claudestat 1.6.1 → 1.8.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 +36 -3
- package/dashboard/dist/assets/AnalyticsView-DDGLDoCN.js +7 -0
- package/dashboard/dist/assets/HistoryView-DkPfrNrv.js +1 -0
- package/dashboard/dist/assets/LineChart-BOWYkkEW.js +2 -0
- package/dashboard/dist/assets/ProjectsView-VRoRiEL4.js +6 -0
- package/dashboard/dist/assets/SystemView-B2zbIxhY.js +1 -0
- package/dashboard/dist/assets/TopView-C2qdsy0Y.js +1 -0
- package/dashboard/dist/assets/index-CMhe3KaT.js +84 -0
- package/dashboard/dist/assets/shared-BbBtsdh1.js +1 -0
- package/dashboard/dist/assets/{vendor-lucide-Cym0q5l_.js → vendor-lucide-ClCW-axQ.js} +79 -64
- package/dashboard/dist/assets/{vendor-react-B_Jzs0gY.js → vendor-react-gHSHIE2L.js} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/dist/config.d.ts +7 -0
- package/dist/config.js +36 -0
- package/dist/daemon.js +113 -9
- package/dist/db.d.ts +87 -2
- package/dist/db.js +325 -65
- package/dist/doctor.js +21 -3
- package/dist/enricher.d.ts +3 -2
- package/dist/enricher.js +10 -5
- package/dist/export.d.ts +2 -1
- package/dist/export.js +41 -6
- package/dist/index.js +406 -20
- package/dist/insights.d.ts +1 -0
- package/dist/insights.js +26 -0
- package/dist/install.js +28 -1
- package/dist/intelligence.d.ts +66 -4
- package/dist/intelligence.js +205 -17
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +49 -0
- package/dist/notifier.d.ts +15 -0
- package/dist/notifier.js +26 -0
- package/dist/paths.d.ts +23 -0
- package/dist/paths.js +42 -0
- package/dist/pricing.d.ts +2 -0
- package/dist/pricing.js +12 -1
- package/dist/routes/events.js +136 -5
- package/dist/routes/helpers.d.ts +5 -0
- package/dist/routes/helpers.js +21 -1
- package/dist/routes/history.js +6 -2
- package/dist/routes/intents.d.ts +1 -0
- package/dist/routes/intents.js +155 -0
- package/dist/routes/misc.js +150 -4
- package/dist/routes/opencode-reader.js +39 -3
- package/dist/routes/projects.js +19 -1
- package/dist/routes/replay.d.ts +1 -0
- package/dist/routes/replay.js +29 -0
- package/dist/routes/reports.js +7 -0
- package/dist/routes/top.js +8 -1
- package/dist/service.js +11 -0
- package/dist/watchers/adapter.d.ts +1 -0
- package/dist/watchers/claude-code.d.ts +16 -1
- package/dist/watchers/claude-code.js +201 -76
- package/dist/watchers/opencode.d.ts +1 -0
- package/dist/watchers/opencode.js +152 -14
- package/hooks/event.js +44 -26
- package/package.json +1 -1
- package/dashboard/dist/assets/AnalyticsView-5bUM3UHp.js +0 -8
- package/dashboard/dist/assets/HistoryView-C-AsEqos.js +0 -1
- package/dashboard/dist/assets/ProjectsView-D9bZBdY2.js +0 -6
- package/dashboard/dist/assets/SystemView-DIYDCCF3.js +0 -1
- package/dashboard/dist/assets/TopView-DhdLpsiA.js +0 -1
- package/dashboard/dist/assets/index-DgbWvj42.js +0 -84
package/dist/enricher.js
CHANGED
|
@@ -15,7 +15,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
15
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
16
|
};
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
18
|
+
exports.getContextWindow = exports.getSessionPrompts = exports.getAllBlockCostsForSession = void 0;
|
|
19
19
|
exports.startEnricher = startEnricher;
|
|
20
20
|
exports.stopEnricher = stopEnricher;
|
|
21
21
|
exports.cleanupSession = cleanupSession;
|
|
@@ -30,11 +30,13 @@ require("./watchers/opencode");
|
|
|
30
30
|
require("./watchers/amp");
|
|
31
31
|
require("./watchers/droid");
|
|
32
32
|
require("./watchers/codebuff");
|
|
33
|
+
const db_1 = require("./db");
|
|
33
34
|
// Re-export Claude Code-specific utilities for routes/stream and routes/misc
|
|
34
35
|
var claude_code_1 = require("./watchers/claude-code");
|
|
35
36
|
Object.defineProperty(exports, "getAllBlockCostsForSession", { enumerable: true, get: function () { return claude_code_1.getAllBlockCostsForSession; } });
|
|
36
|
-
Object.defineProperty(exports, "getContextWindow", { enumerable: true, get: function () { return claude_code_1.getContextWindow; } });
|
|
37
37
|
Object.defineProperty(exports, "getSessionPrompts", { enumerable: true, get: function () { return claude_code_1.getSessionPrompts; } });
|
|
38
|
+
var pricing_1 = require("./pricing");
|
|
39
|
+
Object.defineProperty(exports, "getContextWindow", { enumerable: true, get: function () { return pricing_1.getContextWindow; } });
|
|
38
40
|
const prevContextBySession = new Map();
|
|
39
41
|
let watcher = null;
|
|
40
42
|
const pendingFiles = new Map();
|
|
@@ -90,7 +92,7 @@ function startEnricher(onUpdate, onCompact) {
|
|
|
90
92
|
console.log(`[enricher] Watching ${adapters.map(a => a.label).join(', ')}`);
|
|
91
93
|
watcher = chokidar_1.default.watch(watchPaths, {
|
|
92
94
|
persistent: true,
|
|
93
|
-
ignoreInitial:
|
|
95
|
+
ignoreInitial: false,
|
|
94
96
|
awaitWriteFinish: {
|
|
95
97
|
stabilityThreshold: 200,
|
|
96
98
|
pollInterval: 100,
|
|
@@ -119,16 +121,19 @@ function startEnricher(onUpdate, onCompact) {
|
|
|
119
121
|
watcher.on('add', handleFile);
|
|
120
122
|
// ─── Poll-based adapters (e.g. OpenCode SQLite) ─────────────────────────────
|
|
121
123
|
const POLL_INTERVAL_MS = 10000;
|
|
124
|
+
const POLL_LOOKBACK_MS = 7 * 24 * 60 * 60000; // backfill 7 days on first start
|
|
122
125
|
for (const adapter of adapters) {
|
|
123
126
|
if (!(0, adapter_1.isPollable)(adapter))
|
|
124
127
|
continue;
|
|
125
|
-
let lastPoll = Date.now();
|
|
128
|
+
let lastPoll = Date.now() - POLL_LOOKBACK_MS;
|
|
126
129
|
const interval = setInterval(async () => {
|
|
127
130
|
const since = lastPoll;
|
|
128
131
|
lastPoll = Date.now();
|
|
129
132
|
const sessions = await adapter.pollSessions(since);
|
|
130
|
-
for (const { sessionId, cost } of sessions) {
|
|
133
|
+
for (const { sessionId, cost, cwd } of sessions) {
|
|
131
134
|
onUpdate(sessionId, cost, adapter.name);
|
|
135
|
+
if (cwd)
|
|
136
|
+
db_1.dbOps.updateSessionProject(sessionId, cwd);
|
|
132
137
|
}
|
|
133
138
|
}, POLL_INTERVAL_MS);
|
|
134
139
|
interval.unref();
|
package/dist/export.d.ts
CHANGED
package/dist/export.js
CHANGED
|
@@ -5,9 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.runExport = runExport;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const os_1 = __importDefault(require("os"));
|
|
9
8
|
const path_1 = __importDefault(require("path"));
|
|
10
9
|
const db_1 = require("./db");
|
|
10
|
+
const MD_HEADERS = ['Date', 'Project', 'Cost (USD)', 'Input tokens', 'Output tokens', 'Efficiency', 'Loops'];
|
|
11
11
|
function parseDate(str, endOfDay = false) {
|
|
12
12
|
const ms = Date.parse(str);
|
|
13
13
|
if (isNaN(ms))
|
|
@@ -23,6 +23,23 @@ const CSV_HEADERS = [
|
|
|
23
23
|
'total_cost_usd', 'total_input_tokens', 'total_output_tokens',
|
|
24
24
|
'efficiency_score', 'loops_detected',
|
|
25
25
|
];
|
|
26
|
+
function parseSince(since) {
|
|
27
|
+
const match = since.match(/^(\d+)d$/);
|
|
28
|
+
if (!match)
|
|
29
|
+
throw new Error(`Invalid --since format: "${since}" — use e.g. "7d" or "30d"`);
|
|
30
|
+
return Date.now() - parseInt(match[1], 10) * 86400000;
|
|
31
|
+
}
|
|
32
|
+
function toMarkdownRow(r) {
|
|
33
|
+
return [
|
|
34
|
+
String(r.started_at).slice(0, 10),
|
|
35
|
+
r.project_path ? String(r.project_path).split('/').pop() ?? '—' : '—',
|
|
36
|
+
`$${Number(r.total_cost_usd).toFixed(4)}`,
|
|
37
|
+
String(r.total_input_tokens),
|
|
38
|
+
String(r.total_output_tokens),
|
|
39
|
+
`${r.efficiency_score}/100`,
|
|
40
|
+
String(r.loops_detected),
|
|
41
|
+
].map(v => v.replace(/\|/g, '\\|')).join(' | ');
|
|
42
|
+
}
|
|
26
43
|
function toRow(s) {
|
|
27
44
|
return {
|
|
28
45
|
id: s.id,
|
|
@@ -40,6 +57,10 @@ function runExport(opts) {
|
|
|
40
57
|
let fromMs;
|
|
41
58
|
let toMs;
|
|
42
59
|
try {
|
|
60
|
+
if (opts.since && !opts.from) {
|
|
61
|
+
const sinceMs = parseSince(opts.since);
|
|
62
|
+
opts.from = new Date(sinceMs).toISOString().slice(0, 10);
|
|
63
|
+
}
|
|
43
64
|
if (opts.from)
|
|
44
65
|
fromMs = parseDate(opts.from);
|
|
45
66
|
if (opts.to)
|
|
@@ -71,12 +92,26 @@ function runExport(opts) {
|
|
|
71
92
|
];
|
|
72
93
|
output = lines.join('\n') + '\n';
|
|
73
94
|
}
|
|
95
|
+
else if (opts.format === 'markdown') {
|
|
96
|
+
const separator = MD_HEADERS.map(() => '---').join(' | ');
|
|
97
|
+
const lines = [
|
|
98
|
+
MD_HEADERS.join(' | '),
|
|
99
|
+
separator,
|
|
100
|
+
...rows.map(toMarkdownRow),
|
|
101
|
+
];
|
|
102
|
+
output = lines.join('\n') + '\n';
|
|
103
|
+
}
|
|
74
104
|
else {
|
|
75
105
|
output = JSON.stringify(rows, null, 2) + '\n';
|
|
76
106
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
if (!opts.output) {
|
|
108
|
+
process.stdout.write(output);
|
|
109
|
+
console.error(`✓ Exported ${rows.length} session(s)`); // stderr para no contaminar stdout
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const dest = path_1.default.resolve(opts.output);
|
|
113
|
+
fs_1.default.mkdirSync(path_1.default.dirname(dest), { recursive: true });
|
|
114
|
+
fs_1.default.writeFileSync(dest, output);
|
|
115
|
+
console.log(`✓ Exported ${rows.length} session(s) → ${dest}`);
|
|
116
|
+
}
|
|
82
117
|
}
|