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.
Files changed (3) hide show
  1. package/README.md +25 -28
  2. package/dist/cli.js +6334 -4462
  3. 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
- Silent background refresh runs every 30 seconds. Period/provider data is cached and prefetched so tab switching feels instant.
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
- │ CLI (Node.js / TypeScript) │ │ Menubar App (Swift / SwiftUI) │
213
- │ │ │ │
214
- │ Reads provider session files │ JSON │ Calls CLI with --format │
215
- │ Computes cost via LiteLLM rates ├─────►│ menubar-json │
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. All 5 periods are pre-fetched on launch for instant tab switching. Security: no shell injection — validated argv arrays are passed directly to child processes, not through a shell.
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
- 648 tests across 3 layers:
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
- npm test
232
+ npx vitest run
244
233
 
245
- # Run Swift tests
246
- cd mac && swift test
234
+ # Run native state and resource tests
235
+ swift test --package-path mac --filter ExeWatcherMenubarTests
247
236
 
248
- # Run UI tests
249
- cd mac && xcodebuild test -scheme ExeWatcherUITests
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) (auto-cached 24h). Handles input, output, cache write, cache read, and web search costs.
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 (v6) with atomic writes and cold-start/progressive 365-day backfill
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
- - 648-test suite across CLI, Swift state, and UI smoke layers
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