Skip to content

Update Factory usage metrics#515

Open
abyssbugg wants to merge 2 commits into
robinebers:mainfrom
abyssbugg:fix/factory-usage-metrics-20260525
Open

Update Factory usage metrics#515
abyssbugg wants to merge 2 commits into
robinebers:mainfrom
abyssbugg:fix/factory-usage-metrics-20260525

Conversation

@abyssbugg
Copy link
Copy Markdown

@abyssbugg abyssbugg commented May 27, 2026

Summary

  • Update Factory/Droid usage parsing to merge legacy subscription usage with Factory billing limits and compute usage endpoints.
  • Surface Extra Usage, 5-hour/weekly/monthly usage limits, Droid Core, Managed Computers, and legacy Standard token usage.
  • Add unsigned direct-distribution build flow for Get Golf/direct DMG distribution and bump app version to 0.6.16.

Validation

  • bun run test --run plugins/factory/plugin.test.js — 44 tests passed
  • bun run build — passed
  • bun run test --run — 62 files / 1074 tests passed
  • bun run build:direct — passed, produced release/Usage.app and release/Usage_0.6.16_aarch64.dmg
  • Local API runtime check returned Factory lines: Extra Usage, 5-hour usage, Weekly usage, Monthly usage, Droid Core, Managed Computers, Standard

Notes

Co-Authored-By: Oz oz-agent@warp.dev


Summary by cubic

Rebrands the app to Usage and upgrades Factory metrics by merging legacy token usage with billing limits and compute usage for clearer limits and resets. Adds Warp and Rovo Dev providers, a plist host API, a direct unsigned build flow, and bumps to 0.6.16.

  • New Features

    • Factory: merges legacy subscription usage with billing/compute; shows Extra Usage, 5-hour/weekly/monthly windows, Droid Core, Managed Computers, Standard.
    • New providers: warp (local macOS plist/sqlite) and rovo-dev (CLI log-backed).
    • Host API: host.plist.read() for XML/binary plist parsing.
    • UI: progress lines display “used” and “left” together for percent, money, and credits.
    • Build: bun run build:direct via scripts/build-direct.sh creates unsigned release/Usage.app and DMG.
  • Migration

    • App renamed to Usage: bundle id com.datamatics.usage, repo datamatics/usage-meter, logs at ~/Library/Logs/com.datamatics.usage.
    • Config path: ~/.usage/config.json (was ~/.openusage/config.json).
    • Plugin API: global changed to __usage_plugin; docs and schema updated.
    • Keychain services and User-Agent strings now use “Usage” (e.g., Usage-copilot).
    • Package renamed to usage-meter; app version is 0.6.16.
    • Direct builds are intentionally unsigned; notarization is not required for this path.

Written for commit d0db378. Summary will update on new commits. Review in cubic

abyssbugg and others added 2 commits May 25, 2026 12:51
Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Copilot AI review requested due to automatic review settings May 27, 2026 20:50
@github-actions github-actions Bot added rust Pull requests that update rust code core plugin docs ci labels May 27, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Rebrands the application from OpenUsage to Usage (including repo links/identifiers), updates the plugin runtime globals accordingly, and expands provider/plugin capabilities with new host APIs and new providers.

Changes:

  • Rename app/repo branding across UI, docs, tests, package metadata, and Tauri config (including bundle identifier + updater endpoints).
  • Update plugin runtime/global contracts (__openusage_*__usage_*) and update all bundled plugins + tests accordingly.
  • Add new host APIs (plist read, keychain delete), enhance several providers (Factory/Cursor/Amp/Antigravity), and add new providers (Warp, Rovo Dev).

Reviewed changes

Copilot reviewed 102 out of 107 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/pages/settings.tsx Updates settings UI copy to new product name.
src/lib/tray-tooltip.ts Rebrands tray tooltip header text.
src/lib/tray-tooltip.test.ts Aligns tray tooltip expectations with new header text.
src/hooks/use-changelog.ts Points changelog fetch to new GitHub repo.
src/hooks/use-changelog.test.tsx Updates mocked URLs for new repo.
src/hooks/app/use-tray-icon.ts Rebrands default tray tooltip on restore.
src/components/side-nav.tsx Updates “Help” link to new repo issues.
src/components/side-nav.test.tsx Updates expectation for “Help” link.
src/components/provider-card.tsx Changes progress line rendering to show both used/left; removes displayMode influence.
src/components/provider-card.test.tsx Updates assertions for new used/left UI and bar semantics.
src/components/panel-footer.tsx Rebrands footer version display.
src/components/panel-footer.test.tsx Updates version button lookup to match new label.
src/components/changelog-dialog.tsx Centralizes GitHub repo URL and rebrands changelog links.
src/components/changelog-dialog.test.tsx Updates expected URLs to new repo.
src/components/about-dialog.tsx Rebrands About dialog content and repository links.
src/components/about-dialog.test.tsx Updates About dialog expectations and click behavior.
src/App.test.tsx Updates app-level About dialog flow assertions.
src-tauri/tauri.conf.json Renames product/bundle identifier, bumps version, updates updater endpoint + window title.
src-tauri/src/tray.rs Rebrands tray menu text and tooltip.
src-tauri/src/plugin_engine/runtime.rs Switches plugin global name from __openusage_plugin to __usage_plugin.
src-tauri/src/plugin_engine/host_api.rs Renames probe ctx global, adds plist API + keychain delete API, updates wrappers.
src-tauri/src/panel.rs Renames native panel types to new app name.
src-tauri/src/main.rs Updates entrypoint crate name (openusage_libusage_meter_lib).
src-tauri/src/local_http_api/cache.rs Rebrands temp dir naming in tests.
src-tauri/src/lib.rs Rebrands startup log line.
src-tauri/src/config.rs Changes proxy config path from ~/.openusage to ~/.usage.
src-tauri/build.rs Ensures bundled plugins placeholder dir/file exists during build.
src-tauri/Cargo.toml Renames crate/package, bumps version, adds plist dependency.
scripts/build-direct.sh Adds direct distribution build script (unsigned app + dmg).
plugins/zai/plugin.test.js Updates plugin registration global name in tests.
plugins/zai/plugin.js Updates plugin registration global name.
plugins/windsurf/plugin.test.js Updates plugin registration global name in tests.
plugins/windsurf/plugin.js Renames auth error marker + plugin registration global name.
plugins/warp/plugin.test.js Adds Warp provider tests (plist + sqlite).
plugins/warp/plugin.json Adds Warp provider manifest.
plugins/warp/plugin.js Adds Warp provider implementation using plist + sqlite.
plugins/warp/icon.svg Adds Warp provider icon.
plugins/test-helpers.js Adds mocked host.plist.read and rebrands test dirs.
plugins/synthetic/plugin.test.js Updates plugin registration global name in tests.
plugins/synthetic/plugin.js Updates plugin registration global name.
plugins/rovo-dev/plugin.test.js Adds Rovo Dev provider tests (log-backed).
plugins/rovo-dev/plugin.json Adds Rovo Dev provider manifest.
plugins/rovo-dev/plugin.js Adds Rovo Dev provider implementation (parses CLI logs).
plugins/rovo-dev/icon.svg Adds Rovo Dev provider icon.
plugins/perplexity/plugin.test.js Updates plugin registration global name in tests.
plugins/perplexity/plugin.js Rebrands User-Agent and plugin registration global name.
plugins/opencode-go/plugin.test.js Updates plugin registration global name in tests.
plugins/opencode-go/plugin.js Updates plugin registration global name.
plugins/mock/plugin.test.js Updates plugin registration global name in tests.
plugins/mock/plugin.js Updates plugin registration global name.
plugins/minimax/plugin.test.js Updates plugin registration global name in tests.
plugins/minimax/plugin.js Updates plugin registration global name.
plugins/kiro/plugin.test.js Updates plugin registration global name in tests.
plugins/kiro/plugin.js Rebrands User-Agent and plugin registration global name.
plugins/kimi/plugin.test.js Updates plugin registration global name in tests.
plugins/kimi/plugin.js Rebrands User-Agent and plugin registration global name.
plugins/jetbrains-ai-assistant/plugin.test.js Updates plugin registration global name in tests.
plugins/jetbrains-ai-assistant/plugin.js Updates plugin registration global name.
plugins/gemini/plugin.test.js Updates plugin registration global name in tests.
plugins/gemini/plugin.js Updates plugin registration global name.
plugins/factory/plugin.test.js Adds/updates tests for expanded Factory metrics + request method fallback.
plugins/factory/plugin.json Updates Factory manifest to include new UI lines/ordering.
plugins/factory/plugin.js Adds extended Factory metrics, supplemental fetches, headers, and better error extraction.
plugins/cursor/plugin.test.js Adds tests for team detection and request-usage fallback behavior.
plugins/cursor/plugin.js Adds bearer fallback for request usage and fixes team detection logic for zero pooled limit.
plugins/copilot/plugin.test.js Rebrands keychain service name and updates tests accordingly.
plugins/copilot/plugin.js Rebrands keychain service name, logs, and plugin registration global name.
plugins/codex/plugin.test.js Updates plugin registration global name in tests.
plugins/codex/plugin.js Rebrands User-Agent and plugin registration global name.
plugins/claude/plugin.test.js Updates plugin registration global name in tests.
plugins/claude/plugin.js Updates plugin registration global name.
plugins/antigravity/plugin.test.js Adds tests for unified oauth-token state fallback + renames plugin global.
plugins/antigravity/plugin.js Adds unified oauth-token reading and refactors sqlite state reads.
plugins/amp/plugin.test.js Adds tests for workspace balances + Amp Free disabled state.
plugins/amp/plugin.js Adds parsing for workspace balances and Amp Free disabled signal.
package.json Renames package and bumps version; adds build:direct script.
index.html Rebrands HTML title.
docs/proxy.md Rebrands docs and updates config path.
docs/providers/zai.md Rebrands copy and references.
docs/providers/warp.md Adds Warp provider documentation.
docs/providers/rovo-dev.md Adds Rovo Dev provider documentation.
docs/providers/opencode-go.md Rebrands references.
docs/providers/kiro.md Rebrands references.
docs/providers/jetbrains-ai-assistant.md Rebrands references.
docs/providers/factory.md Updates docs for new Factory response shapes and plan detection.
docs/providers/cursor.md Rebrands references.
docs/providers/copilot.md Rebrands keychain caching docs.
docs/providers/codex.md Rebrands references.
docs/providers/claude.md Rebrands references.
docs/plugins/schema.md Updates plugin registration global name in schema docs.
docs/plugins/api.md Documents new plist API and rebrands env caching note.
docs/local-http-api.md Rebrands local HTTP API docs.
docs/capture-logs.md Rebrands troubleshooting steps (paths, filenames, labels).
bun.lock Renames workspace name.
TRADEMARK.md Replaces prior trademark policy with new branding note.
SECURITY.md Rebrands security reporting info and updates advisory URL.
README.md Rewrites README for new name/features/providers and dev/build commands.
CONTRIBUTING.md Rebrands contributing guide and updates issue links/maintainers text.
.gitignore Ignores new build/release dirs and .worktrees/.
.github/ISSUE_TEMPLATE/new_provider.yml Rebrands issue template copy.
.github/ISSUE_TEMPLATE/feature_request.yml Rebrands issue template copy.
.github/ISSUE_TEMPLATE/config.yml Updates discussions link to new repo.
.github/ISSUE_TEMPLATE/bug_report.yml Rebrands issue template labels and steps.
.github/CODEOWNERS Updates default code owner(s).
.cursor/commands/pr-review.md Updates plugin global naming in review checklist.
.codex/environments/environment.toml Rebrands environment name.
Comments suppressed due to low confidence (8)

src-tauri/src/plugin_engine/runtime.rs:1

  • Switching the plugin entry global from __openusage_plugin to __usage_plugin is a hard breaking change for any out-of-tree plugins. To preserve compatibility (and allow a deprecation window), consider supporting both names: try __usage_plugin first, then fall back to __openusage_plugin with a warning.
    src-tauri/src/plugin_engine/host_api.rs:1
  • Similarly, renaming the injected probe context from __openusage_ctx to __usage_ctx will break plugins that access the global directly (or wrapper scripts expecting the old name). If backwards compatibility matters, set both globals to the same object (or keep the old one as an alias) and document a deprecation timeline.
    src-tauri/tauri.conf.json:1
  • Changing the Tauri identifier creates a different application from the OS perspective. This typically breaks in-place upgrades/auto-updater continuity, changes app data/log paths, and may orphan existing keychain entries/settings for current users. If the goal is to migrate existing installs, consider keeping the old identifier (or implementing a documented migration strategy) rather than changing it outright.
    src-tauri/src/plugin_engine/host_api.rs:1
  • The new host.plist.read(path) effectively gives plugins a structured reader for arbitrary plist files on disk (including binary plists). If plugins are not fully trusted, this expands the data-exfiltration surface beyond plain-text reads. Consider restricting this API to a safe allowlist of directories (e.g., ~/Library/Preferences/), or gating it behind a plugin permission model consistent with the rest of the host APIs.
    src-tauri/src/plugin_engine/host_api.rs:1
  • The delete command arguments omit the keychain account (-a <account>). In practice that can delete a different entry than the one your read/write paths target (which appear to be account-scoped elsewhere), or delete an unexpected matching item if multiple exist. Consider including the same account resolution used by the other keychain helpers so delete targets the same item consistently.
    src-tauri/src/plugin_engine/host_api.rs:1
  • Deleting a keychain item will often return a non-zero status when the item is already missing (a common/benign cleanup scenario). Throwing in that case can break recovery flows (e.g., clearing a stale token). Consider treating the standard 'item not found' error from security as a successful no-op, while still throwing for other failures.
    src/components/provider-card.tsx:1
  • This computes line.used / line.limit without handling line.limit <= 0. If a provider emits limit = 0 (or a malformed line), percent becomes Infinity and clamp01 will likely show 100% incorrectly. Consider explicitly handling non-positive limits (e.g., treat percent as 0, or render an indeterminate state) before dividing.
    src-tauri/src/plugin_engine/host_api.rs:1
  • A new host API surface (host.keychain.deleteGenericPassword) is introduced here, but there are tests shown for plist and existing keychain read/write behaviors—not for delete. Adding a unit test in this module that validates the generated security args (including account scoping) and the 'item not found' no-op behavior would help prevent regressions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 107 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="plugins/copilot/plugin.js">

<violation number="1" location="plugins/copilot/plugin.js:2">
P2: Keychain service rename from `OpenUsage-copilot` to `Usage-copilot` lacks a backward-compatible fallback read, which can break existing authenticated users who only have a token cached under the old service name. `clearCachedToken` also cannot clean up legacy entries.</violation>
</file>

<file name="scripts/build-direct.sh">

<violation number="1" location="scripts/build-direct.sh:16">
P2: DMG selection via `ls ... | head -n 1` can copy a stale artifact when multiple versioned DMGs accumulate in the target directory from previous builds</violation>
</file>

<file name="plugins/warp/plugin.js">

<violation number="1" location="plugins/warp/plugin.js:45">
P2: readPrefs returns first parseable plist without checking if it contains request-limit data, causing probe to throw prematurely when later plists might have valid data</violation>
</file>

Partial review: This PR has more than 100 files, so cubic reviewed the highest-priority files first.
For a deeper review of large PRs, comment @cubic-dev-ai ultrareview. Learn more.

Fix all with cubic | Re-trigger cubic

Comment thread plugins/copilot/plugin.js
@@ -1,5 +1,5 @@
(function () {
const KEYCHAIN_SERVICE = "OpenUsage-copilot";
const KEYCHAIN_SERVICE = "Usage-copilot";
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Keychain service rename from OpenUsage-copilot to Usage-copilot lacks a backward-compatible fallback read, which can break existing authenticated users who only have a token cached under the old service name. clearCachedToken also cannot clean up legacy entries.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/copilot/plugin.js, line 2:

<comment>Keychain service rename from `OpenUsage-copilot` to `Usage-copilot` lacks a backward-compatible fallback read, which can break existing authenticated users who only have a token cached under the old service name. `clearCachedToken` also cannot clean up legacy entries.</comment>

<file context>
@@ -1,5 +1,5 @@
 (function () {
-  const KEYCHAIN_SERVICE = "OpenUsage-copilot";
+  const KEYCHAIN_SERVICE = "Usage-copilot";
   const GH_KEYCHAIN_SERVICE = "gh:github.com";
   const USAGE_URL = "https://api.github.com/copilot_internal/user";
</file context>
Fix with Cubic

Comment thread scripts/build-direct.sh
CARGO_TARGET_DIR="$TARGET_DIR" ./node_modules/.bin/tauri build --no-sign --config '{"bundle":{"createUpdaterArtifacts":false}}' "$@"

APP_PATH="$TARGET_DIR/release/bundle/macos/Usage.app"
DMG_PATH="$(ls -1 "$TARGET_DIR"/release/bundle/dmg/Usage_*.dmg | head -n 1)"
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: DMG selection via ls ... | head -n 1 can copy a stale artifact when multiple versioned DMGs accumulate in the target directory from previous builds

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/build-direct.sh, line 16:

<comment>DMG selection via `ls ... | head -n 1` can copy a stale artifact when multiple versioned DMGs accumulate in the target directory from previous builds</comment>

<file context>
@@ -0,0 +1,24 @@
+CARGO_TARGET_DIR="$TARGET_DIR" ./node_modules/.bin/tauri build --no-sign --config '{"bundle":{"createUpdaterArtifacts":false}}' "$@"
+
+APP_PATH="$TARGET_DIR/release/bundle/macos/Usage.app"
+DMG_PATH="$(ls -1 "$TARGET_DIR"/release/bundle/dmg/Usage_*.dmg | head -n 1)"
+
+cp -R "$APP_PATH" "$OUTPUT_DIR/Usage.app"
</file context>
Fix with Cubic

Comment thread plugins/warp/plugin.js
@@ -0,0 +1,251 @@
(function () {
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: readPrefs returns first parseable plist without checking if it contains request-limit data, causing probe to throw prematurely when later plists might have valid data

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At plugins/warp/plugin.js, line 45:

<comment>readPrefs returns first parseable plist without checking if it contains request-limit data, causing probe to throw prematurely when later plists might have valid data</comment>

<file context>
@@ -0,0 +1,251 @@
+    return null
+  }
+
+  function readPrefs(ctx) {
+    let sawFile = false
+
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci core docs plugin rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants