exe-watcher 0.2.12 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +52 -33
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1660,7 +1660,8 @@ function emptyEntry(date) {
|
|
|
1660
1660
|
oneShotTurns: 0,
|
|
1661
1661
|
models: {},
|
|
1662
1662
|
categories: {},
|
|
1663
|
-
providers: {}
|
|
1663
|
+
providers: {},
|
|
1664
|
+
projects: {}
|
|
1664
1665
|
};
|
|
1665
1666
|
}
|
|
1666
1667
|
function emptyProviderBreakdown() {
|
|
@@ -1700,10 +1701,20 @@ function aggregateProjectsIntoDays(projects) {
|
|
|
1700
1701
|
}
|
|
1701
1702
|
return breakdown;
|
|
1702
1703
|
};
|
|
1704
|
+
const ensureProject = (date, projectName) => {
|
|
1705
|
+
const day = ensure(date);
|
|
1706
|
+
let project = day.projects[projectName];
|
|
1707
|
+
if (!project) {
|
|
1708
|
+
project = { cost: 0, sessions: 0 };
|
|
1709
|
+
day.projects[projectName] = project;
|
|
1710
|
+
}
|
|
1711
|
+
return project;
|
|
1712
|
+
};
|
|
1703
1713
|
for (const project of projects) {
|
|
1704
1714
|
for (const session of project.sessions) {
|
|
1705
1715
|
const sessionDate = dateKey(session.firstTimestamp);
|
|
1706
1716
|
ensure(sessionDate).sessions += 1;
|
|
1717
|
+
ensureProject(sessionDate, project.project).sessions += 1;
|
|
1707
1718
|
const providersSeenInSession = /* @__PURE__ */ new Set();
|
|
1708
1719
|
for (const turn of session.turns) {
|
|
1709
1720
|
if (turn.assistantCalls.length === 0) continue;
|
|
@@ -1748,6 +1759,7 @@ function aggregateProjectsIntoDays(projects) {
|
|
|
1748
1759
|
model.cacheReadTokens += call.usage.cacheReadInputTokens;
|
|
1749
1760
|
model.cacheWriteTokens += call.usage.cacheCreationInputTokens;
|
|
1750
1761
|
callDay.models[call.model] = model;
|
|
1762
|
+
ensureProject(callDate, project.project).cost += call.costUSD;
|
|
1751
1763
|
}
|
|
1752
1764
|
for (const [provider, calls] of callsByProvider) {
|
|
1753
1765
|
providersSeenInSession.add(provider);
|
|
@@ -3670,31 +3682,35 @@ function estimateAgentCosts(stats) {
|
|
|
3670
3682
|
}))
|
|
3671
3683
|
};
|
|
3672
3684
|
}
|
|
3673
|
-
function
|
|
3674
|
-
const aggregate = (
|
|
3685
|
+
function buildProjectSpendFromDays(selectedDays, days24h, days7d, days30d) {
|
|
3686
|
+
const aggregate = (days) => {
|
|
3675
3687
|
const byName = {};
|
|
3676
|
-
for (const
|
|
3677
|
-
const
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3688
|
+
for (const day of days) {
|
|
3689
|
+
for (const [projectName, totals] of Object.entries(day.projects)) {
|
|
3690
|
+
const name = cleanProjectName(projectName);
|
|
3691
|
+
if (!byName[name]) byName[name] = { cost: 0, sessions: 0 };
|
|
3692
|
+
byName[name].cost += totals.cost;
|
|
3693
|
+
byName[name].sessions += totals.sessions;
|
|
3694
|
+
}
|
|
3681
3695
|
}
|
|
3682
3696
|
return byName;
|
|
3683
3697
|
};
|
|
3684
|
-
const
|
|
3685
|
-
const
|
|
3686
|
-
const
|
|
3687
|
-
const
|
|
3698
|
+
const selected = aggregate(selectedDays);
|
|
3699
|
+
const d24 = aggregate(days24h);
|
|
3700
|
+
const d7 = aggregate(days7d);
|
|
3701
|
+
const d30 = aggregate(days30d);
|
|
3702
|
+
const allNames = /* @__PURE__ */ new Set([...Object.keys(selected), ...Object.keys(d24), ...Object.keys(d7), ...Object.keys(d30)]);
|
|
3688
3703
|
return Array.from(allNames).map((name) => ({
|
|
3689
3704
|
name,
|
|
3690
3705
|
cost24h: d24[name]?.cost ?? 0,
|
|
3691
3706
|
cost7d: d7[name]?.cost ?? 0,
|
|
3692
3707
|
cost30d: d30[name]?.cost ?? 0,
|
|
3693
|
-
|
|
3694
|
-
|
|
3708
|
+
selectedPeriodCost: selected[name]?.cost ?? 0,
|
|
3709
|
+
sessions: selected[name]?.sessions ?? d30[name]?.sessions ?? d7[name]?.sessions ?? d24[name]?.sessions ?? 0
|
|
3710
|
+
})).filter((d) => d.selectedPeriodCost > 0).sort((a, b) => b.selectedPeriodCost - a.selectedPeriodCost);
|
|
3695
3711
|
}
|
|
3696
3712
|
function cleanProjectName(dirName) {
|
|
3697
|
-
const base = dirName.replace(/--worktrees-.*$/, "");
|
|
3713
|
+
const base = dirName.replace(/--worktrees-.*$/, "").replace(/-\.worktrees-.*/, "").replace(/\/\.worktrees\/.*/, "");
|
|
3698
3714
|
const parts = base.split("-");
|
|
3699
3715
|
const usersIdx = parts.indexOf("Users");
|
|
3700
3716
|
if (usersIdx >= 0 && usersIdx + 2 < parts.length) {
|
|
@@ -3795,7 +3811,7 @@ import { createHash as createHash3, randomBytes as randomBytes5 } from "crypto";
|
|
|
3795
3811
|
import { existsSync as existsSync3 } from "fs";
|
|
3796
3812
|
import { mkdir as mkdir7, open as open5, readFile as readFile7, rename as rename6, unlink as unlink3 } from "fs/promises";
|
|
3797
3813
|
import { join as join16 } from "path";
|
|
3798
|
-
var DAILY_CACHE_VERSION =
|
|
3814
|
+
var DAILY_CACHE_VERSION = 5;
|
|
3799
3815
|
var DEFAULT_DAILY_CACHE_SCOPE = "global";
|
|
3800
3816
|
var DAILY_CACHE_FILENAME = "daily-cache.json";
|
|
3801
3817
|
function getCachePath3(scopeKey) {
|
|
@@ -7134,17 +7150,18 @@ program.command("status").description("Compact status output (today + week + mon
|
|
|
7134
7150
|
const parseTimeMs = Date.now() - parseStart;
|
|
7135
7151
|
const todayDays = aggregateProjectsIntoDays(todayProjects);
|
|
7136
7152
|
let daysCount = 0;
|
|
7153
|
+
let selectedPeriodDays = [];
|
|
7137
7154
|
{
|
|
7138
7155
|
const rangeStartStr = toDateString(periodInfo.range.start);
|
|
7139
7156
|
const rangeEndStr = toDateString(periodInfo.range.end);
|
|
7140
7157
|
const historicalDays = getDaysInRange(cache, rangeStartStr, yesterdayStr);
|
|
7141
7158
|
const todayOnly = todayDays.filter((d) => d.date > yesterdayStr && d.date <= rangeEndStr);
|
|
7142
|
-
|
|
7143
|
-
daysCount =
|
|
7159
|
+
selectedPeriodDays = [...historicalDays, ...todayOnly].sort((a, b) => a.date.localeCompare(b.date));
|
|
7160
|
+
daysCount = selectedPeriodDays.length;
|
|
7144
7161
|
if (isAllProviders) {
|
|
7145
|
-
currentData = buildPeriodDataFromDays(
|
|
7162
|
+
currentData = buildPeriodDataFromDays(selectedPeriodDays, periodInfo.label);
|
|
7146
7163
|
} else {
|
|
7147
|
-
const providerDays = filterDaysToProvider(
|
|
7164
|
+
const providerDays = filterDaysToProvider(selectedPeriodDays, pf);
|
|
7148
7165
|
currentData = buildPeriodDataFromDays(providerDays, periodInfo.label);
|
|
7149
7166
|
}
|
|
7150
7167
|
}
|
|
@@ -7257,19 +7274,21 @@ program.command("status").description("Compact status output (today + week + mon
|
|
|
7257
7274
|
}
|
|
7258
7275
|
let projectSpend = null;
|
|
7259
7276
|
try {
|
|
7260
|
-
const
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7277
|
+
const weekStartStr = toDateString(getDateRange2("week").range.start);
|
|
7278
|
+
const thirtyDayStartStr = toDateString(getDateRange2("30days").range.start);
|
|
7279
|
+
const todayOnlyDays = todayDays.filter((d) => d.date > yesterdayStr);
|
|
7280
|
+
const days7d = [
|
|
7281
|
+
...getDaysInRange(cache, weekStartStr, yesterdayStr),
|
|
7282
|
+
...todayOnlyDays
|
|
7283
|
+
].sort((a, b) => a.date.localeCompare(b.date));
|
|
7284
|
+
const days30d = [
|
|
7285
|
+
...getDaysInRange(cache, thirtyDayStartStr, yesterdayStr),
|
|
7286
|
+
...todayOnlyDays
|
|
7287
|
+
].sort((a, b) => a.date.localeCompare(b.date));
|
|
7288
|
+
projectSpend = buildProjectSpendFromDays(selectedPeriodDays, todayOnlyDays, days7d, days30d);
|
|
7271
7289
|
} catch {
|
|
7272
|
-
|
|
7290
|
+
const todayOnlyDays = todayDays.filter((d) => d.date > yesterdayStr);
|
|
7291
|
+
projectSpend = buildProjectSpendFromDays(selectedPeriodDays, todayOnlyDays, [], []);
|
|
7273
7292
|
}
|
|
7274
7293
|
const diagnostics = { daysCount, parseTimeMs, warnings };
|
|
7275
7294
|
const payload = buildMenubarPayload(currentData, providers, optimize, dailyHistory, agentStats, projectSpend, exeOsDetected, statsFileAge, diagnostics);
|
|
@@ -7569,7 +7588,7 @@ program.command("plan [action] [id]").description("Show or configure a subscript
|
|
|
7569
7588
|
console.log(` Config saved to ${getConfigFilePath()}
|
|
7570
7589
|
`);
|
|
7571
7590
|
});
|
|
7572
|
-
program.command("optimize").description("Find token waste and get exact fixes").option("-p, --period <period>", "Analysis period: today, week, 30days, month, all", "
|
|
7591
|
+
program.command("optimize").description("Find token waste and get exact fixes").option("-p, --period <period>", "Analysis period: today, week, 30days, month, all", "week").option("--provider <provider>", "Filter by provider: all, claude, codex, cursor", "all").action(async (opts) => {
|
|
7573
7592
|
await loadPricing();
|
|
7574
7593
|
const { range, label } = getDateRange2(opts.period);
|
|
7575
7594
|
const scanPromise = prewarmOptimizeScan(range);
|