Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ follows [Semantic Versioning](https://semver.org/).

### Added

- Add opt-in Muse Code subscription allowance through the official CLI's
read-only `usage/read` protocol. Show session and weekly windows with the
original observation time. Do not send prompts or read CLI credentials.
Honor saved opt-in in headless reports, cancel reads when stopped, retain
observation time in JSON and keep allowance out of the shared archive for
compatibility with older app versions on rollback.
Muse.ai Desktop import and native/live validation remain pending.
- Show Grok Bot Desktop quota burn in percentage points per hour from recent
same-account readings. Collect for at least a minute, discard old/reset
observations and show an estimated run-out only when measured.
Expand Down Expand Up @@ -45,6 +52,11 @@ follows [Semantic Versioning](https://semver.org/).

### Fixed

- Read known Claude plan labels from the available tier fields without showing
internal identifiers or guessing a plan from an unrelated substring.
- Accept duplicate Claude Desktop cache entries when their eligible access
tokens are identical. Distinct matching tokens still require a clear login;
an ambiguous-token failure preserves the selected CLI source.
- Preload the tray usage window hidden after completed onboarding, before
connection recovery or provider collection. The first click reuses the loaded
renderer instead of starting its initial load.
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ through Settings → API connections with a saved legacy Admin key, a one-time
Admin key, or the bundled environment-only helper. Existing Keychain entries
are preserved; pasted keys are not saved. OpenRouter keeps its existing
account balance and aggregate activity integration.
Unreleased source adds opt-in [Muse Code CLI allowance](docs/DESKTOP-CONNECTIONS.md#muse-code-cli).
Muse.ai cloud/Desktop connection is separate and remains pending.
Build 54's Settings footer incorrectly says `0.2.41`; the packaged version is
`0.3.0-beta.1`. See [known beta limits](docs/BETA.md#known-limits).

Expand Down Expand Up @@ -72,7 +74,7 @@ fall back to compilation. See the [Swift installation guide](docs/swift/README.m

## Setup and data coverage

All nine provider adapters remain in the retained Swift and candidate source:
The original nine provider adapters remain in the retained Swift and candidate source:
Codex, Claude Code, Antigravity, OpenRouter, Grok, OpenCode Go, Cursor, Copilot
CLI and Gemini CLI. Their inputs and available measurements differ. The
[Swift provider matrix](docs/swift/README.md#provider-matrix) describes existing
Expand Down
31 changes: 31 additions & 0 deletions docs/DESKTOP-CONNECTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ below it to apply the choice. Existing profiles keep their current source.
Keychain prompt. The candidate requests account allowance using Desktop's
current access token. This interface can change and is not a documented
third-party consumer API contract.
Duplicate eligible cache entries with the same access token count as one
credential. Different matching tokens remain ambiguous; MeterUsage does not
choose the first token or the one with the latest expiry. An ambiguous-token
failure leaves the previously selected CLI source available. This handling has
synthetic fixture coverage; live cache compatibility remains unverified.
Alternatively, choose **Claude Code CLI** and **Use CLI** to read local Claude
Code activity. CLI allowance requires a companion usage file; this option
does not provide Claude website token history.
Expand Down Expand Up @@ -86,6 +91,32 @@ identify the cause of a live connection failure or prove that Claude Desktop
connection works. Packaged banner display, Keychain access, Desktop compatibility
and live allowance still require native acceptance.

## Muse Code CLI

Unreleased Electron source adds a separate **Muse Code** row in Settings.
Sign in with the [official CLI](https://dev.meta.ai/products/muse-code), then
choose **Use Muse Code CLI**. Collection starts disabled and the choice survives
relaunch. Headless JSON collection also honors this choice. **Stop Muse Code**
cancels active reads and clears the in-memory allowance without signing out the CLI.
Demo mode provides invented allowance and blocks the setup action. Isolated
Codex and Claude test profiles exclude this provider.

MeterUsage starts `muse serve`, initializes the official experimental MSP
surface and calls [`usage/read`](https://meta-models.github.io/muse-code-sdk/next/generated/msp/methods/usage-read/).
It never starts a model turn or opens CLI credentials. The method returns the
host's last observation, which can be absent. Missing data is unavailable,
never zero. An unsupported CLI must be upgraded separately. Cards show the
original observation time, session and weekly percentages, and reported resets.
They provide no local token history or cost estimate.
The JSON quota report includes `observed_at` for Muse Code, separate from the
report's `generated_at`. Muse allowance stays in memory and is excluded from the
shared quota archive, so older versions can still load other providers on rollback.

Muse.ai's cloud agent and Desktop app use a separate subscription and session.
The Muse Code connection does not provide Muse.ai allowance. Native Muse.ai
session import remains pending verification of its store and encryption schema.
Source tests do not prove native or live-provider behavior.

## Data coverage

Account allowance comes from the provider account service. It can reflect use
Expand Down
21 changes: 21 additions & 0 deletions docs/KB.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ Release documentation refresh: 2026-10-16; build 54 source review is unchanged.

## Product and source facts

- Electron Claude plan labels recognize known organization, seat and user tiers
in that order. An unknown higher-priority value permits a known fallback;
unknown-only metadata stays unavailable instead of exposing internal labels.
Claude Desktop treats identical eligible access tokens as one credential,
while distinct tokens remain ambiguous. Ambiguous-token Desktop connection
failures preserve selected CLI collection. These changes have synthetic fixture proof; live
Desktop compatibility remains separate.

- Unreleased Electron source adds opt-in Muse Code allowance with `muse serve`
and the official experimental MSP `usage/read` method. The source starts
disabled, reads no credential files and sends no model turn. It preserves
observation age and percentages, including provider values above 100, while
rejecting absent, expired or malformed observations. Settings, demo cards,
menu-bar/notch provider ordering and JSON quota reporting use the separate
`muse` provider. Saved opt-in also gates headless collection; stopping cancels
active reads and invalidates allowance. JSON includes `observed_at`, and
allowance stays in memory, outside the shared archive, to preserve rollback
compatibility. Muse.ai native session import remains unimplemented; no
verified native store path or schema is available. Native/live validation
remains separate. See [ADR 0033](adr/0033-muse-code-subscription-allowance.md).

- Unreleased Antigravity Desktop setup reuses the existing connection controls,
preferences, IPC and account-bound source. It requires one running same-user
desktop language server with a CSRF token and PID-owned IPv4 loopback port.
Expand Down
9 changes: 8 additions & 1 deletion docs/PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ cutover acceptance remain pending. See [ADR 0010](adr/0010-macos-typescript-elec
| Provider | Read or request | Retained data |
| --- | --- | --- |
| Codex | `codex app-server --listen stdio://` initializes the CLI and calls `account/rateLimits/read`. The CLI uses its own existing authentication. Local rollout headers, model context and cumulative token-ledger events are selected from `sessions/**/*.jsonl`. | Quota windows/groups, plan, balances, reset credits, timestamps, numeric tokens and model. Session paths become opaque IDs; workspace directories become basenames. |
| Muse Code, unreleased Electron source | Opt-in `muse serve` subprocess using existing official CLI authentication. MSP initialization enables experimental methods, then `usage/read` reads the host's last observation. No model session, prompt, login or logout is started. MeterUsage does not open Muse credential files. | Session and weekly allowance percentages, reset timestamps, session duration, a restricted tier identifier and the provider observation timestamp. Missing or expired observations remain unavailable. No token ledger, cost or Muse.ai allowance is inferred. |
| Claude | Local transcript usage fields under `projects/`, three tier keys from `.claude.json`, and optional companion quota JSON. | Numeric tokens/cost estimates, model, dates, project basename, plan tier and quota windows. Transcript message content and identifying tier metadata are skipped. |
| OpenRouter | Existing `OPENROUTER_API_KEY` or supported local key file for `/api/v1/key` and `/api/v1/credits`. An existing management key, with configured API-key fallback, is used for `/api/v1/activity`. | Aggregate usage, balances, limits, dates, request counts and token totals. |
| OpenCode Go | Existing `opencode-go` key in the local auth store for `https://opencode.ai/zen/go/v1/usage`. Read-only session SQL, with `opencode db --format json` fallback, selects tokens, cost, message counts, dates and directory. | Quota windows, numeric usage and project basename. No message bodies, prompts or tool arguments are selected. |
| Grok | Existing OIDC key from `.grok/auth.json`, re-read for each billing refresh, sent to `cli-chat-proxy.grok.com/v1/billing?format=credits`. Session `summary.json` files supply dates and message counts. | Allowance, period/reset, plan and session/count metadata. No chat-history content is decoded. |
| Antigravity | Existing agy container CLI `/usage`; numeric fields from conversation SQLite/protobuf stores, native first and container-volume fallback. Older stores use only history conversation ID/timestamp fields. | Model-group quota, numeric token totals, turn times and aggregate counts. Older history has unknown tokens. No prompt/tool payload or workspace text is decoded. |
| Cursor, Copilot, Gemini | Existing local quota/usage JSON candidates and local presence checks. | Snapshot quota windows when present. These readers do not fetch cloud quota or provide a token ledger. Presence alone never becomes a zero-usage reading. |

Muse Code allowance stays in memory and is not written to the shared quota
archive. This preserves archive compatibility with older app versions. Its
collection preference remains saved; allowance is read again after relaunch.

Codex and Claude additional accounts use separate user-selected configuration
directories. Enabled existing directories get distinct sources; an absent or
disabled directory is not polled. An additional Claude source never falls back
Expand Down Expand Up @@ -103,7 +108,9 @@ transport; do not run the helper interactively or record its output. The main
process decrypts `oauth:tokenCacheV2` from Claude Desktop's `config.json` and
reads only the active organization cookie from a read-only cookie database.
It selects account-scoped current access-token/expiry fields, skips refresh
tokens, and rejects ambiguous, legacy or expired entries. It never writes to
tokens, and rejects ambiguous, legacy or expired entries. Identical tokens in
eligible entries count as one credential; distinct tokens remain ambiguous.
It never writes to
Claude stores or rotates their tokens.

The access token authenticates a GET to
Expand Down
46 changes: 46 additions & 0 deletions docs/adr/0033-muse-code-subscription-allowance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# ADR 0033: Read Muse Code allowance through the official CLI

- Status: Source implementation; native and live-provider acceptance pending
- Date: 2026-10-17

Add an opt-in Electron provider named Muse Code with the internal key `muse`.
Keep it distinct from Muse.ai's cloud agent and Desktop subscription. Both
products have usage limits, but their credentials and allowances do not establish
a shared account or combined budget.

Reuse the bounded subprocess transport. Start the installed official
`muse serve`, initialize MSP with experimental methods enabled, then call
`usage/read`. Do not start a session or model turn, change authentication, read
credential files or add an SDK dependency. The official method supplies the
host's last observation without a model call.

Retain session and weekly percentages, reset times, session duration, a bounded
tier identifier and `observedAtMs`. Preserve percentages above 100 as the wire
contract permits them. Clamp display geometry independently. Reject missing,
expired and invalid values. Show the observation time so polling cannot make
an old observation appear newly measured. No token history or cost is inferred.

Settings exposes explicit start/stop actions. Existing preference validation,
provider ordering, cards, quota reporting and demo composition serve the new
provider. It remains excluded from isolated Codex/Claude live profiles. Stopping
collection does not sign the user out of Muse Code.
The saved choice also gates headless collection. Source removal cancels active
reads, and a later start uses a new source to reject results from the old one.
Clear in-memory allowance on each change. The schema-1 JSON report adds Muse Code's
`observed_at` without changing other providers. Keep Muse allowance in memory and
exclude it from the shared quota archive. Legacy Swift and Electron decoders
reject an archive containing an unknown provider, so writing Muse there would
discard all cached quota on rollback. Other providers keep their existing format
and reset-pacing state. Muse allowance is collected again after relaunch.

Muse.ai Desktop import needs independent evidence for the native session store,
active-account selection and encryption. Do not infer those from a bundle ID or
use Muse Code authentication as a substitute.

Verify with synthetic MSP subprocesses, numeric/projection tests, composition
and renderer checks, TypeScript checking and production bundling. Native app and
live-provider validation remain distinct gates.

References: [official product](https://dev.meta.ai/products/muse-code),
[`usage/read`](https://meta-models.github.io/muse-code-sdk/next/generated/msp/methods/usage-read/),
[usage window schema](https://meta-models.github.io/muse-code-sdk/next/generated/msp/types/subscriptionusagewindow/).
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ compatibility and acceptance requirements remain in force. The
| [0031](0031-grok-quota-burn.md) | Measure Grok Bot quota burn from recent same-account percentages without inventing token counts or cycle duration. | Source implementation; native and live rate acceptance separate |

| [0032](0032-one-time-api-setup.md) | Separate API setup from account connections and accept a one-time Admin key for explicit billing fetches, without saving credentials. | Source implementation; real billing acceptance pending |
| [0033](0033-muse-code-subscription-allowance.md) | Read opt-in Muse Code allowance through official MSP without a model turn; preserve observation age and keep Muse.ai separate. | Source implementation; native/live acceptance pending |
3 changes: 2 additions & 1 deletion docs/electron/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Usage. See [ADR 0023](../adr/0023-onboarding-source-choice.md).
| Grok Bot Desktop (Beta), unreleased source | Explicit consent reads the active account-bound encrypted Bot credential and requests allowance. | Native Keychain/store and endpoint compatibility remain unverified. Existing saved Cursor connections retain their source. |
| OpenCode Go local | **Use local OpenCode** enables local Go sessions without a sign-in or key. Existing Go authentication also supplies allowance. | Go sessions only. Other providers used through OpenCode are excluded. |
| Grok CLI (Beta) | Existing CLI authentication and local session summaries. | Consumer website/mobile sign-in is unsupported. Session/message counts do not establish token totals. |
| Muse Code CLI, unreleased source | Explicit **Use Muse Code CLI** enables read-only subscription observations through an existing official CLI. | Last-observed session/weekly allowance only. No local activity, token totals or Muse.ai cloud allowance. Native/live validation remains pending. |

**Use CLI** ends only MeterUsage-owned account state and waits for successful
cleanup before enabling local collection. Failed cleanup blocks the switch.
Expand All @@ -39,7 +40,7 @@ to local collection. See [desktop connections](../DESKTOP-CONNECTIONS.md) and

### Existing provider inputs

All nine adapters remain wired in [composition](../../src/main/composition.ts).
The original nine adapters and the unreleased Muse Code reader are wired in [composition](../../src/main/composition.ts).
The current source adds an OpenCode Go local setup action and Antigravity
Desktop connection. These changes are separate from the published build 54.

Expand Down
52 changes: 52 additions & 0 deletions docs/plans/cliproxy-hub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# CLIProxyAPI Hub connection

Status: Research complete; implementation needs an existing saved-history source.

## Goal and source contract

Connect MeterUsage to an existing CLIProxyAPI history source and show retained
token activity grouped by provider and upstream account. Keep proxy activity
separate from local transcripts and subscription allowance to avoid double
counting or assigning activity to an unrelated account.

CLIProxyAPI 8.0.35 exposes a usage queue that removes records when read. It does
not expose the legacy historical snapshot endpoints. This integration must not
consume that queue, change proxy configuration, or install a new collector.
A saved export or a documented history service must be identified first.

Sources: [v8 usage contract](https://help.router-for.me/management/apiv8#usage),
[v8.0.35 routes](https://github.com/router-for-me/CLIProxyAPI/blob/ae3ee3be303fb07fb8173279923413005bf32177/internal/api/server_management_v8.go),
[legacy snapshot format](https://github.com/router-for-me/CLIProxyAPI/blob/db63f9b5d60e643ca060901cfe67ffc5ce63ac63/internal/api/handlers/management/usage.go).

## Proposed minimum

1. Verify the saved source's format, retention and non-destructive read contract.
Do not advertise complete history where coverage is unknown.
2. Add one explicit Hub connection in Settings. For an authenticated HTTP source,
keep its management key in main-process memory and OS-backed encrypted
storage; fail closed without secure storage. Reject redirects and credentials
embedded in URLs. Source details must precede transport implementation.
3. Read one bounded snapshot per refresh. Join reported `auth_index` values to
projected provider metadata where the source supplies that mapping. Keep
unknown or ambiguous identities in an unattributed group; model aliases are
not evidence of a subscription account.
4. Publish only numeric usage, dates and reduced display labels. Never publish
client API keys, credential files, email addresses, raw errors or headers.
Request counts must remain requests rather than sessions or messages.
5. Reuse the account heatmap's unavailable-day handling. Use reported total
tokens when component counters can overlap. Replace snapshots rather than
adding repeated cumulative totals. Do not merge Hub and local token totals.

## Verification and limits

Synthetic checks must cover authentication failures, cancellation, source
replacement, payload limits, identity ambiguity, missing dates, snapshot reset,
overlapping token categories and repeated polling. Renderer checks must verify
provider/account labels, unavailable history and separate local/Hub scope.
Native secure storage and the actual history source need independent execution
proof before runtime support is claimed.

No Hub adapter or credential store is implemented by this plan. The existing
local Claude heatmap and Desktop allowance remain separate data sources. No
server deployment, queue consumer, provider login or app installation follows
from this plan.
Loading
Loading