usagemax 0.3.3 → 0.3.7

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 CHANGED
@@ -1,200 +1,231 @@
1
1
  # UsageMax CLI
2
2
 
3
- Connect aggregate coding-agent usage from every computer to one private UsageMax workspace.
3
+ Connect the AI usage history on a computer to one private UsageMax workspace.
4
+ The CLI is deliberately short-lived: it scans locally, uploads bounded
5
+ aggregates, and exits.
6
+
7
+ [UsageMax](https://usagemax.com) · [Account](https://usagemax.com/account) ·
8
+ [CLI documentation](https://usagemax.com/cli.md) ·
9
+ [API contract](https://usagemax.com/openapi.json) ·
10
+ [npm package](https://www.npmjs.com/package/usagemax) ·
11
+ [source repository](https://github.com/SYMBaiEX/usagemax/tree/main/packages/cli)
12
+
13
+ This package is the open-source `usagemax` command-line collector. It is not a
14
+ JavaScript or Python SDK and does not expose an import API. For programmatic
15
+ integrations, use the documented [OpenAPI contract](https://usagemax.com/openapi.json)
16
+ or the public [agent surfaces](https://usagemax.com/?mode=agent); the package
17
+ itself is intended to be invoked as a short-lived local process.
18
+
19
+ See the repository's [SDK and integration surface](../../docs/sdk-ecosystem.md)
20
+ for the supported client matrix. UsageMax does not advertise Python or Go
21
+ packages until they are separately reviewed and published.
22
+
23
+ ## Requirements
24
+
25
+ - Node.js 20 or newer
26
+ - Bun or npm
27
+ - A UsageMax account and one link code per computer or WSL distribution
4
28
 
5
29
  ## Quick start
6
30
 
7
- 1. Sign in at [usagemax.com/account](https://usagemax.com/account).
8
- 2. Choose **Link a computer** and copy the one-time command.
9
- 3. Run it in each operating-system environment that contains usage history:
31
+ ```bash
32
+ # Create a one-use code at https://usagemax.com/account.
33
+ bunx usagemax link UMX-XXXX-XXXX-XXXX-XXXX
34
+
35
+ # npm users can run the same one-shot command with npx.
36
+ npx --yes usagemax link UMX-XXXX-XXXX-XXXX-XXXX
37
+
38
+ # Preview, then upload changed local usage.
39
+ bunx usagemax sync --dry-run --explain
40
+ bunx usagemax sync
41
+ ```
42
+
43
+ The CLI checks npm's `latest` dist-tag at most twice per day and never replaces
44
+ itself silently. Run `usagemax update sync` to hand a command to the current
45
+ release without typing `@latest`, or set `USAGEMAX_AUTO_UPDATE=1` for an
46
+ explicit automatic handoff. Use `--no-update-check` or set
47
+ `USAGEMAX_DISABLE_UPDATE_CHECK=1` in offline environments. Interactive
48
+ terminals show a small stderr progress line; JSON,
49
+ quiet, CI, and scheduled runs remain machine-readable and quiet.
50
+
51
+ Agent-friendly checks can request JSON and keep the secret out of arguments and
52
+ logs. This example only inspects local source coverage:
10
53
 
11
54
  ```bash
12
- bunx usagemax@latest link UMX-XXXX-XXXX-XXXX-XXXX
55
+ set +x
56
+ bunx usagemax doctor --deep --json | jq '{complete, sources: [.sources[] | {name, status}]}'
13
57
  ```
14
58
 
15
- The link code expires after ten minutes and can be used once. Create a new code
16
- for each Mac, Windows PC, Linux computer, and WSL distribution. All linked
17
- collectors roll up into the same profile. When run inside WSL, UsageMax includes
18
- readable supported-provider homes under `/mnt/c/Users` automatically. Use the
19
- WSL collector as the single collector for that Windows PC instead of linking the
20
- same host history again from Windows.
59
+ The JSON shape is intended for local automation; unsupported or unavailable
60
+ sources remain explicitly reported rather than being inferred.
61
+
62
+ The link code expires after ten minutes and is consumed once. The account-side
63
+ computer name is retained. Pass `--name "Work laptop"` only when the current
64
+ CLI should explicitly override it.
21
65
 
22
- The CLI stores the resulting collector key in a user-only config file, then runs
23
- a one-shot full-history sync. Running it again, changing the display name, or
24
- relinking an installation does not create a second device: the private random
25
- installation identity remains stable.
66
+ Each installation gets a stable random ID and a new write-only collector key.
67
+ Relinking or renaming that installation rotates the key without creating a
68
+ second device. Do not link two installations to the same copied or
69
+ network-mounted log tree; cross-installation duplicate history is ambiguous.
26
70
 
27
71
  ## Commands
28
72
 
73
+ ```text
74
+ usagemax Sync changed local usage
75
+ usagemax link <code> [options] Link and sync a computer
76
+ usagemax sync [options] Reconcile local usage once
77
+ usagemax status Show local link state
78
+ usagemax doctor Check discovered sources
79
+ usagemax report [ccusage args] Run a local ccusage report
80
+ usagemax token status Diagnose a key piped on stdin
81
+ usagemax service install Opt into periodic OS checkpoints
82
+ usagemax service status|run|uninstall
83
+ usagemax unlink [--revoke] Remove local credentials
84
+ ```
85
+
86
+ Useful options:
87
+
29
88
  ```bash
30
- bunx usagemax # sync changed usage
31
- bunx usagemax sync # same as above
32
- bunx usagemax sync --full # reconcile all retained local history
33
- bunx usagemax sync --archives # one-time compressed-history recovery
34
- bunx usagemax sync --dry-run --explain
35
- # inspect the exact bounded plan; upload nothing
36
- bunx usagemax link UMX-… --no-sync # link without uploading yet
37
- bunx usagemax status # show link and last-sync state
38
- bunx usagemax doctor # metadata-only source check
39
- bunx usagemax doctor --deep --json # machine-readable retained-history audit
40
- bunx usagemax report # open ccusage's local daily report
41
- bunx usagemax report session --breakdown
42
- bunx usagemax unlink # remove the local collector key
43
- bunx usagemax unlink --revoke # disable future uploads, then remove locally
89
+ bunx usagemax sync --full # all retained local history
90
+ bunx usagemax sync --archives # one-time compressed-history recovery
91
+ bunx usagemax sync --restart # restart an expired saved upload
92
+ bunx usagemax status --remote --json # remote check; secret is never printed
93
+ bunx usagemax doctor --deep --json # parse and audit retained history
94
+ bunx usagemax link UMX-… --no-sync # link without uploading yet
44
95
  ```
45
96
 
97
+ ## Sources and coverage
98
+
46
99
  UsageMax pins [ccusage v20.0.20](https://github.com/ccusage/ccusage/releases/tag/v20.0.20)
47
- and supports all 16 adapters shipped in that release: Amp, Claude Code, Codebuff,
48
- Codex, GitHub Copilot CLI, Factory Droid, Gemini CLI, Goose, Grok Build, Hermes,
49
- Kilo Code, Kimi CLI, OpenClaw, OpenCode, Pi, and Qwen Code. Named Pi-format
50
- stores configured through ccusage are also discovered.
51
-
52
- The source inventory follows ccusage's environment overrides, including
53
- `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `OPENCODE_DATA_DIR`, `AMP_DATA_DIR`,
54
- `DROID_SESSIONS_DIR`, `CODEBUFF_DATA_DIR`, `HERMES_HOME`, `PI_AGENT_DIR`,
55
- `GOOSE_PATH_ROOT`, `OPENCLAW_DIR`, `KILO_DATA_DIR`, `KIMI_DATA_DIR`,
56
- `QWEN_DATA_DIR`, `COPILOT_OTEL_FILE_EXPORTER_PATH`, `GEMINI_DATA_DIR`, and
57
- `GROK_HOME`. It also follows XDG Claude configuration and Windows Goose storage.
58
-
59
- UsageMax also discovers Claude Desktop local-agent sessions, `.cc-mirror`,
60
- recognizable renamed Claude/Codex backup folders, and supported Windows homes
61
- from WSL. Discovery is bounded to known locations and immediate home entries;
62
- normal syncs do not crawl the whole disk.
63
- On a multi-user WSL host, automatic Windows-home discovery stays off unless
64
- there is exactly one provider-bearing profile; set `USAGEMAX_ADDITIONAL_HOME`
65
- to the intended mounted home explicitly.
66
-
67
- If `doctor` reports compressed provider archives, run `sync --archives` once.
68
- Recovery extracts only safe Claude `projects/*.jsonl` members into a private
69
- temporary directory, performs one full deduplicated reconciliation, and removes
70
- the temporary files before exit. Weekly and incremental syncs never unpack
71
- archives.
72
-
73
- Local files are only one coverage layer. Cursor, Windsurf, Aider, Continue,
74
- Cline, Roo Code, direct provider API traffic, hosted agents, and enterprise
75
- billing systems do not all expose a stable local token ledger. Capture those
76
- through UsageMax's native or OTLP endpoint, or through a future provider billing
77
- connector. UsageMax never invents usage that the source did not retain.
78
-
79
- ## Privacy, correctness, and load
80
-
81
- Interrupted uploads resume with `bunx usagemax sync`. Server upload runs expire
82
- after 30 idle days. If the server reports an expired run, use `sync --restart`:
83
- this preserves the last committed checkpoint and performs a fresh full scan.
84
- It never automatically replays an old authoritative deletion against newer data.
85
-
86
- - The sync payload contains aggregate token counts,
87
- model/provider names, costs, source names, dates, coverage state, and opaque
88
- SHA-256 session identities.
89
- - It does not upload prompts, completions, source code, file contents, project
90
- paths, or provider credentials.
91
- - Sync is one-shot. There is no resident scanner or high-frequency polling loop.
92
- - A successful previous parse with a complete, unchanged metadata inventory skips
93
- parsing and uploading again that day. Inventory stability is independent of
94
- deletion authority; a no-change result retains the previous partial coverage
95
- label. New sources, date rollover, explicit full/archive requests and weekly
96
- reconciliation still trigger the appropriate scan.
97
- - Normal changed syncs parse today or today plus yesterday. A bounded weekly
98
- full reconciliation catches restored files, parser changes, and older logs.
99
- - Full history scans retained local history from 2024 onward. Inventory success
100
- does not prove every file parsed. Until the parser certifies source/day coverage,
101
- uploads are marked partial and any row with a decreasing counter retains its
102
- entire previous vector. This includes explicit zeros and missing sources.
103
- Older checkpoints survive incremental windows. Authoritative corrections remain
104
- supported by the planner but are not claimed by this parser integration.
105
- Deleted or never-persisted usage requires a provider export.
106
- - Source totals that cannot be assigned to a model are retained as
107
- `unattributed` rather than silently discarded.
108
- - The collector key is written with user-only permissions where the operating
109
- system supports them.
110
- - The package contains no shared service credential or private deployment URL.
111
- It talks to the versioned `https://usagemax.com/api` contract. The random
112
- per-installation write token is the only local secret; the service stores only
113
- its hash and applies device binding, replay checks, payload caps, and quotas.
114
- - A private random installation ID survives collector rotation, relinking, and
115
- display-name changes. It is not a hardware fingerprint; the server stores only
116
- its SHA-256 hash. A local config lock prevents overlapping commands from
117
- overwriting pending runs; server receipts make repeated uploads idempotent.
118
- - The server, not the local checkpoint, owns the accounting baseline. A lost
119
- response or interrupted run can be retried without adding the same partition twice.
120
- - Do not point two different installations at the same copied or network-mounted
121
- log tree. Cross-installation copied-history deduplication is inherently
122
- ambiguous and intentionally not guessed.
123
-
124
- Use `USAGEMAX_CONFIG_DIR` to select another config directory. Development and
125
- self-hosted installations may set `USAGEMAX_LINK_ENDPOINT` before linking.
126
-
127
- ## Optional automatic sync
128
-
129
- Automatic sync is **off by default**. Install a persistent CLI first (a bunx/npx
130
- cache can disappear), link the computer if needed, then opt in:
100
+ and supports its 16 adapters: Amp, Claude Code, Codebuff, Codex, GitHub Copilot
101
+ CLI, Factory Droid, Gemini CLI, Goose, Grok Build, Hermes, Kilo Code, Kimi CLI,
102
+ OpenClaw, OpenCode, Pi, and Qwen Code. Named Pi-format stores are discovered as
103
+ well.
104
+
105
+ The collector follows the supported provider environment overrides and bounded
106
+ home locations. It recognizes Claude Desktop sessions, `.cc-mirror`, renamed
107
+ Claude/Codex backup folders, and supported Windows homes from WSL. In WSL, use
108
+ one collector for the Windows provider homes it can read instead of linking the
109
+ same history again from Windows.
110
+
111
+ Full scans catalog retained history from 2024 onward. `sync --archives` safely
112
+ extracts supported Claude JSONL members into a private temporary directory and
113
+ removes them after reconciliation. Normal runs do not crawl the whole disk or
114
+ unpack archives.
115
+
116
+ Cursor, Windsurf, Aider, Continue, Cline, Roo Code, hosted agents, and direct
117
+ provider API traffic may not leave a stable local token ledger. Use UsageMax's
118
+ native or OTLP/HTTP JSON contract, or a provider billing export, when local
119
+ evidence is unavailable. Unsupported usage is never guessed.
120
+
121
+ ## Safe collector diagnostics
122
+
123
+ An advanced key from **Advanced · custom telemetry collector** is a
124
+ `umx_` prefix followed by 64 lowercase hexadecimal characters. Pipe it through
125
+ stdin; never pass it as an argument or put it in a URL:
126
+
127
+ ```bash
128
+ set +x
129
+ printf '%s' "$USAGEMAX_COLLECTOR_TOKEN" \
130
+ | bunx usagemax token status \
131
+ --device-id "$USAGEMAX_INSTALLATION_ID" \
132
+ --json
133
+ ```
134
+
135
+ The `token status` command is included in CLI `0.3.7`. If a fresh environment
136
+ still has an older npm tag, run `usagemax update token status` or
137
+ `node packages/cli/src/cli.js token status` from this repository until the new
138
+ package is published.
139
+
140
+ The response is read-only and contains only status, type, scopes, profile/name,
141
+ activation state, and a binding result of `unbound`, `bound`, `matched`, or
142
+ `mismatch`. It never returns the token, hash, or raw authorized UUID.
143
+
144
+ For a numeric-only result suitable for a smoke check:
145
+
146
+ ```bash
147
+ set +x
148
+ printf '%s' "$USAGEMAX_COLLECTOR_TOKEN" \
149
+ | bunx usagemax token status \
150
+ --device-id "$USAGEMAX_INSTALLATION_ID" --json \
151
+ | jq -r '[.httpStatus, (if .ingestAuthorized then 1 else 0 end)] | @tsv'
152
+ ```
153
+
154
+ `200 1` is active and ingestion-authorized. `200 0` is recognized but blocked;
155
+ inspect `status` and `scopeStatus` in the unfiltered JSON. `409 0` is a device
156
+ binding mismatch. `401 0` means the format/key was rejected.
157
+
158
+ New advanced keys are active immediately and need no activation or propagation.
159
+ They bind on their first valid write. Linked CLI keys are bound during the link
160
+ exchange. A `401` means the key format is invalid or the key is unknown,
161
+ revoked, disabled, or from another deployment. A `409` means the supplied
162
+ installation does not match. A recognized key missing `telemetry:write` has
163
+ `status: scope_missing`, `scopeStatus: missing_telemetry_write`, and
164
+ `ingestAuthorized: false`.
165
+
166
+ For a write-path smoke check, the root README includes a `curl` request that
167
+ sends one `agent_state` event with all token counters and `costMicros` set to
168
+ zero. It is observability-only: `agent_state` does not update accounting, and
169
+ the probe may bind an otherwise unbound advanced key.
170
+
171
+ ## Privacy and resource use
172
+
173
+ The CLI uploads aggregate token counters, provider/model names, source names,
174
+ dates, cost provenance, coverage state, and opaque SHA-256 session identities.
175
+ It never uploads prompts, completions, source code, file contents, project
176
+ paths, tool payloads, or provider credentials.
177
+
178
+ Every sync is one-shot. A complete unchanged inventory can skip parsing and
179
+ uploading; date rollover, new sources, a weekly reconciliation, `--full`, or
180
+ `--archives` triggers the appropriate bounded scan. Decreases and deletions are
181
+ protected while coverage is incomplete.
182
+
183
+ Optional scheduling invokes the same process at low priority:
131
184
 
132
185
  ```bash
133
186
  bun install -g usagemax
134
187
  usagemax service install # approximately every 15 minutes
135
- usagemax service install --every 30 # change interval; 5–1440 minutes
136
- usagemax service status # scheduler reachability + last result
137
- usagemax service run # run now, respecting failure backoff
138
- usagemax service uninstall # stop future jobs; retain account/data
188
+ usagemax service install --every 30 # 5–1440 minutes
189
+ usagemax service status
190
+ usagemax service uninstall
139
191
  ```
140
192
 
141
- Uses a user LaunchAgent on macOS, a user systemd timer on Linux/WSL, and Task
142
- Scheduler on Windows. No admin/root access, resident daemon, file watcher,
143
- automatic package updates, or package downloads per run. Each job runs the normal
144
- incremental sync and exits. No-change runs skip parsing/uploading when the source
145
- inventory is complete and unchanged. The metadata inventory still costs disk I/O;
146
- an active or first/full-history scan costs more. This is periodic, not live telemetry.
147
-
148
- Schedules are spread by up to a minute. macOS/Linux jobs have reduced CPU/I/O
149
- priority. Windows jobs require a signed-in user and defer starting on battery.
150
- Jobs do not wake a sleeping computer. Linux needs a running systemd user manager;
151
- WSL must already be running with systemd enabled. UsageMax does not enable linger
152
- or keep a WSL distro alive. Missed intervals are not replayed as a backlog.
153
-
154
- The existing collector lock prevents overlapping uploads. Failures back off
155
- exponentially (up to six hours); manually running `usagemax sync` is available for
156
- diagnosis without waiting. `service-state.json` retains only the latest bounded
157
- status, timestamps, duration, and failure count, not raw logs or credentials.
158
- If a process was forcibly killed, inspect the PID reported by `sync` before
159
- removing its stale `collector.lock`; never delete `config.json` to retry.
160
-
161
- Re-run `service install` after upgrading/moving the CLI or changing source-path
162
- environment variables. Only an explicit allowlist of discovery settings is saved,
163
- not your shell's secrets. Jobs run from your home directory; repository-local
164
- `.ccusage/ccusage.json` configuration is not automatically used. Keep the runtime
165
- and global CLI installed. `service uninstall` leaves existing usage, link credentials,
166
- checkpoints, and last-run status intact; an in-flight sync may finish.
167
-
168
- ## Interrupted uploads and protocol 0.3.1
169
-
170
- Before uploading, the CLI saves the exact run, ordered request payloads and next
171
- checkpoint in the private config. `sync` resumes this journal before scanning new
172
- data. Local snapshots advance only after completion is acknowledged. A resumed
173
- command finishes the saved scan; run `sync` again to collect subsequent changes.
174
- `sync --dry-run` reports pending work without uploading. Do not delete config.json
175
- to retry a failed upload. A successful relink or unlink replaces/removes the local
176
- journal along with its credential.
177
-
178
- Network failures, malformed success responses, HTTP 429 and 5xx get at most five
179
- attempts per request with exponential jitter. Retry-After seconds and HTTP dates
180
- are honored up to 60 seconds; longer waits stop with an instruction to retry later.
181
- Only completion's `snapshot_run_incomplete` HTTP 409 is retried, because server
182
- cleanup can still be pending. Authentication, validation and other conflicts fail
183
- with an actionable message and retain the journal. JSON `accepted` is null for
184
- uploads because lost responses/replays cannot reliably reconstruct that count;
185
- `changedRows` is the local planned count, not a server accounting receipt.
186
-
187
- Each sorted source/day is sent as ordered chunks of at most 100 rows. Each has a
188
- unique partitionId, zero-based chunkIndex and shared chunkCount. The payload hash
189
- covers `{source, day, complete, pricingVersion, chunkIndex, chunkCount, rows}` in
190
- that order. `partitionCount` counts transmitted chunks. The server must accept
191
- this protocol, receipt replays, and finish omitted-row cleanup before completing
192
- an authoritative run.
193
-
194
- An abrupt process kill can leave `collector.lock` in the config directory. The
195
- next command reports the owner PID and exact path. Confirm that process has exited
196
- before removing only that lock file, then rerun sync. Never remove an active lock
197
- or the saved config to recover. Normal completion and handled failures release it.
198
-
199
- See the [collector coverage audit](../../docs/collector-coverage-audit.md) for
200
- the full support matrix and known boundaries.
193
+ The scheduler uses a user LaunchAgent on macOS, a user systemd timer on
194
+ Linux/WSL, and Task Scheduler on Windows. It does not install a resident
195
+ watcher, wake a sleeping computer, download packages per run, or replay missed
196
+ intervals. Failures back off for up to six hours and the collector lock prevents
197
+ overlapping syncs.
198
+
199
+ ## Recovery and checkpoints
200
+
201
+ Uploads are idempotent and resumable. Before network I/O, the CLI saves a
202
+ bounded journal containing the current run, ordered operations, and next
203
+ checkpoint in the user-only config directory. If a process or network request
204
+ fails, rerun:
205
+
206
+ ```bash
207
+ usagemax sync
208
+ ```
209
+
210
+ An expired run can be restarted with `sync --restart`; already accepted usage
211
+ remains safe. Do not delete `config.json` to retry a failed upload. See the
212
+ [operations runbook](https://github.com/SYMBaiEX/usagemax/blob/main/docs/operations-runbook.md)
213
+ for recovery guidance.
214
+
215
+ ## Development
216
+
217
+ From the repository root:
218
+
219
+ ```bash
220
+ bun install
221
+ bun run --cwd packages/cli test
222
+ bun run --cwd packages/cli pack:check # dry-run; lifecycle scripts disabled
223
+ ```
224
+
225
+ `pack:check` only inspects the local archive shape. It does not publish, contact
226
+ the npm registry, or establish that any registry tag contains this version.
227
+
228
+ The package is MIT-licensed. See the included [LICENSE](LICENSE), the
229
+ repository [LICENSE](https://github.com/SYMBaiEX/usagemax/blob/main/LICENSE),
230
+ [security policy](https://github.com/SYMBaiEX/usagemax/blob/main/SECURITY.md),
231
+ and [contributing guide](https://github.com/SYMBaiEX/usagemax/blob/main/CONTRIBUTING.md).
package/package.json CHANGED
@@ -1,7 +1,21 @@
1
1
  {
2
2
  "name": "usagemax",
3
- "version": "0.3.3",
3
+ "version": "0.3.7",
4
4
  "description": "Link local coding-agent usage to your UsageMax profile",
5
+ "keywords": [
6
+ "usagemax",
7
+ "ai-usage",
8
+ "usage-analytics",
9
+ "coding-agents",
10
+ "agent-usage",
11
+ "telemetry",
12
+ "observability",
13
+ "usage",
14
+ "ccusage",
15
+ "claude-code",
16
+ "codex",
17
+ "privacy"
18
+ ],
5
19
  "license": "MIT",
6
20
  "author": "UsageMax",
7
21
  "homepage": "https://usagemax.com",
@@ -24,6 +38,8 @@
24
38
  "src/installation.js",
25
39
  "src/sources.js",
26
40
  "src/transport.js",
41
+ "src/progress.js",
42
+ "src/updates.js",
27
43
  "src/resume.js",
28
44
  "src/service.js",
29
45
  "README.md",
@@ -37,7 +53,7 @@
37
53
  },
38
54
  "scripts": {
39
55
  "test": "node --test src/*.test.js",
40
- "pack:check": "npm pack --dry-run",
56
+ "pack:check": "npm pack --dry-run --ignore-scripts",
41
57
  "prepublishOnly": "npm test"
42
58
  },
43
59
  "dependencies": {