exe-watcher 0.2.53 → 0.2.54
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 +25 -28
- package/dist/cli.js +6334 -4462
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ A Swift/SwiftUI popover that lives in your menu bar. Today's spend is always vis
|
|
|
61
61
|
- **Capacity estimation** — Derives likely token limits from usage patterns when hard caps aren't published.
|
|
62
62
|
- **Multi-currency** — USD, GBP, EUR, JPY, AUD, CAD, CHF, CNY, SEK, NOK, DKK, NZD, SGD, HKD, KRW, INR, BRL.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
macOS pushes usage-log change notifications to Watcher; there is no repeating background usage scan. Rapid writes are combined, with at least two minutes of rest after a scan and longer after slow scans (nine times the scan duration). A failed notification gets at most two spaced retries before waiting for new data or a user action. Watcher also catches up on launch/wake and explicit user actions. Only one CLI child runs at a time, at low scheduling priority, with a 256 MiB V8 heap limit and a 60-second timeout. Historical and provider detail views load on demand. Failed scans retain the last successful total, including across app restarts on the same date; missing data after midnight displays a dash until a scan succeeds.
|
|
65
65
|
|
|
66
66
|
### Interactive TUI dashboard
|
|
67
67
|
|
|
@@ -207,22 +207,17 @@ The section appears automatically when exe-os is present and hides when it's not
|
|
|
207
207
|
|
|
208
208
|
Two components, loosely coupled via CLI output:
|
|
209
209
|
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
│ Daily cache (v6, atomic writes) │ │ @Observable state management │
|
|
217
|
-
│ 365-day historical backfill │ │ 30s cache TTL, prefetch on │
|
|
218
|
-
│ Lock serialization for safety │ │ launch, concurrent fetch │
|
|
219
|
-
│ │ │ guards │
|
|
220
|
-
└──────────────────────────────────┘ └─────────────────────────────────┘
|
|
210
|
+
```text
|
|
211
|
+
Provider usage files
|
|
212
|
+
↓
|
|
213
|
+
CLI: deduplicate → price tokens → cache daily totals → JSON
|
|
214
|
+
↓
|
|
215
|
+
macOS app: file notifications → one bounded CLI worker → menu bar
|
|
221
216
|
```
|
|
222
217
|
|
|
223
218
|
**CLI pipeline:** Parse provider session files from disk → deduplicate by message ID → compute cost per token type (input, output, cache write, cache read, web search) → aggregate by period, project, model, activity → output as TUI, JSON, or CSV.
|
|
224
219
|
|
|
225
|
-
**Menubar app:** Calls `exe-watcher status --format menubar-json --period <period> --provider <provider>` → decodes JSON → renders SwiftUI popover.
|
|
220
|
+
**Menubar app:** Calls `exe-watcher status --format menubar-json --period <period> --provider <provider>` → decodes JSON → renders SwiftUI popover. Usage-file notifications trigger coalesced refreshes, with catch-up on launch and wake. Period and provider views load when selected. A single CLI worker has memory, runtime, and output limits; failed scans preserve the last successful total. There is no periodic background usage scan. Security: no shell injection — validated argv arrays are passed directly to child processes, not through a shell.
|
|
226
221
|
|
|
227
222
|
**Deduplication** per provider: API message ID (Claude), cumulative token cross-check (Codex), conversation/timestamp (Cursor), session+message ID (OpenCode), responseId (Pi/OMP).
|
|
228
223
|
|
|
@@ -230,23 +225,17 @@ Two components, loosely coupled via CLI output:
|
|
|
230
225
|
|
|
231
226
|
## Test suite
|
|
232
227
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
| Layer | Framework | Count | What it covers |
|
|
236
|
-
|-------|-----------|-------|----------------|
|
|
237
|
-
| **CLI data integrity** | Vitest | 597 | Schema validation, provider sum consistency, period monotonicity, project spend accuracy, 365-day history, token sanity checks |
|
|
238
|
-
| **Swift state** | Swift Testing | 45 | Period windowing, cache isolation, prefetch logic, capacity estimation, CLI resolution, provider sum validation, JSON decode |
|
|
239
|
-
| **UI smoke** | Swift Testing + Accessibility | 6 | App launch, status item presence, popover display, period switching via macOS Accessibility APIs |
|
|
228
|
+
Tests cover CLI data integrity, native scheduling and resource limits, and optional macOS Accessibility smoke checks. CLI end-to-end tests use isolated usage fixtures.
|
|
240
229
|
|
|
241
230
|
```bash
|
|
242
231
|
# Run CLI tests
|
|
243
|
-
|
|
232
|
+
npx vitest run
|
|
244
233
|
|
|
245
|
-
# Run
|
|
246
|
-
|
|
234
|
+
# Run native state and resource tests
|
|
235
|
+
swift test --package-path mac --filter ExeWatcherMenubarTests
|
|
247
236
|
|
|
248
|
-
#
|
|
249
|
-
|
|
237
|
+
# UI smoke tests require macOS Accessibility access
|
|
238
|
+
swift test --package-path mac --filter ExeWatcherUITests
|
|
250
239
|
```
|
|
251
240
|
|
|
252
241
|
---
|
|
@@ -283,7 +272,15 @@ Starting points, not verdicts. A single experimental session with 60% cache hit
|
|
|
283
272
|
|
|
284
273
|
## How it works
|
|
285
274
|
|
|
286
|
-
Reads session data directly from disk. No wrapper, no proxy, no API keys needed. Pricing from [LiteLLM](https://github.com/BerriAI/litellm)
|
|
275
|
+
Reads session data directly from disk. No wrapper, no proxy, no API keys needed. Pricing refreshes every 24 hours from official OpenAI, Anthropic, MiniMax, Z.AI, Kimi and xAI pricing pages, supplemented by [LiteLLM](https://github.com/BerriAI/litellm). Official rates take precedence over reseller prices for unqualified model names. Offline use retains the last available catalog or the bundled rates verified October 1, 2026, with warnings when a refresh fails. Handles input, output, 5-minute and 1-hour cache writes, cache reads, long-context tiers, and recorded web search costs. Claude streaming records are reconciled by API message ID using cumulative token counters; final usage is counted once.
|
|
276
|
+
|
|
277
|
+
Both historical and current usage use the latest available per-model API list rates. This answers "what would these tokens cost via API at today's prices?" Historical totals are rebuilt when pricing changes; they do not reconstruct the price charged on each original date. JSON reports include `pricing` metadata with the basis, refresh timestamp and source URLs. Missing session details still make recovered history an estimate. Models without published token prices (including Codex Spark) retain their tokens and an explicit cost-exclusion warning, rather than inheriting another model's price or an old reported bill.
|
|
278
|
+
|
|
279
|
+
Switching Claude accounts does not filter usage: Watcher counts all retained sessions in the configured data directory and Claude Desktop account folders. Codex archived sessions also count. Add other Claude profile roots with `claudeConfigDirs` in `~/.config/exe-watcher/config.json`.
|
|
280
|
+
|
|
281
|
+
“All Time” includes the entire available history. To set the beginning of your coding journey, add `"historyStartDate": "2025-07-01"` to the same config. This defines the reporting window; it cannot recreate missing logs. Unknown model prices generate a warning while their tokens remain counted.
|
|
282
|
+
|
|
283
|
+
For unfiltered All Time Claude totals, Watcher also reconciles `stats-cache.json` cumulative model counters with retained logs through the snapshot's cutoff date. Only missing per-model/token counters are added. Recovered usage is separately identified as `historicalRecovery`: it has no fabricated dates, sessions, or projects, and uses standard API rates with 5-minute cache writes because TTL/speed metadata is unavailable. Daily charts show dated logs only. Project/provider sums include recovery only where attribution is known. Usage lost from both logs and cumulative counters remains unknown. These are API-equivalent estimates, not subscription charges or invoices.
|
|
287
284
|
|
|
288
285
|
**Environment variables:**
|
|
289
286
|
|
|
@@ -327,10 +324,10 @@ Watcher is forked from [codeburn](https://github.com/getagentseal/codeburn) by [
|
|
|
327
324
|
- 8 provider support (added Cursor Agent, Copilot, OMP, Pi, OpenCode)
|
|
328
325
|
- Native macOS menubar app with multi-period views, provider tabs, project spend, and subscription tracking
|
|
329
326
|
- Exe OS integration — per-agent spend and memory tracking for AI employee teams
|
|
330
|
-
- Daily cache system (
|
|
327
|
+
- Daily cache system (v8) with atomic writes and cold-start/progressive full-history backfill
|
|
331
328
|
- Capacity estimation from usage patterns
|
|
332
329
|
- Multi-currency support (17 currencies)
|
|
333
|
-
-
|
|
330
|
+
- Test coverage across CLI, Swift state, resource limits, and UI smoke layers
|
|
334
331
|
- Consolidated activity categories from 13 to 6
|
|
335
332
|
- Fixed double-counting bugs in the menubar JSON pipeline
|
|
336
333
|
- Performance: 7-day and 30-day queries from 2-5s down to ~1s via daily cache
|