feat: add Command Code plugin#441
Conversation
|
@codex review |
There was a problem hiding this comment.
Pull request overview
Adds a new Command Code provider plugin so OpenUsage can detect a local Command Code login, call the billing APIs, and surface monthly quota/plan usage alongside existing providers.
Changes:
- Adds a new
command-codeplugin with API/auth discovery, plan-limit mapping, and progress-line output. - Adds provider docs and README entry for Command Code.
- Adds unit tests covering auth, request handling, response parsing, and line generation.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
README.md |
Adds Command Code to the supported providers list. |
plugins/command-code/plugin.test.js |
Adds tests for auth discovery, API errors, parsing, and output formatting. |
plugins/command-code/plugin.json |
Defines the new plugin manifest, links, and overview lines. |
plugins/command-code/plugin.js |
Implements Command Code auth loading, API calls, and usage/progress line generation. |
plugins/command-code/icon.svg |
Adds the provider icon asset. |
docs/providers/command-code.md |
Documents setup, API sources, limits, reset behavior, and failure modes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ], | ||
| "lines": [ | ||
| { "type": "progress", "label": "Monthly Quota", "scope": "overview", "primaryOrder": 1 }, | ||
| { "type": "progress", "label": "Plan", "scope": "overview" } |
| resetsAt: ctx.util.toIso(resetsAtMs), | ||
| periodDurationMs: 30 * 24 * 3600 * 1000, |
| })) | ||
| } | ||
|
|
||
| return { plan: planId, lines: lines } |
| var line = result.lines[0] | ||
| expect(line.label).toBe("Go") | ||
| expect(line.used).toBe(7) | ||
| expect(line.limit).toBe(10) | ||
| expect(line.format.kind).toBe("dollars") | ||
| var pctLine = result.lines[1] | ||
| expect(pctLine.label).toBe("Monthly Quota") | ||
| expect(pctLine.used).toBe(70) | ||
| expect(pctLine.limit).toBe(100) | ||
| expect(pctLine.format.kind).toBe("percent") |
| - **Period:** subscription billing period (`currentPeriodEnd` from the API) | ||
| - **Resets at:** UTC midnight, 24h period duration displayed |
| var result = await plugin.probe(ctx) | ||
| var line = result.lines[0] | ||
| expect(line.resetsAt).toBeTruthy() | ||
| expect(line.periodDurationMs).toBe(30 * 24 * 3600 * 1000) |
| { | ||
| "schemaVersion": 1, | ||
| "id": "command-code", | ||
| "name": "CommandCode", |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c49cbdfc3a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| periodDurationMs: 30 * 24 * 3600 * 1000, | ||
| })) | ||
| lines.push(ctx.line.progress({ | ||
| label: formatPlanLabel(planId), |
There was a problem hiding this comment.
Emit stable 'Plan' label for the dollar progress line
Overview cards only render runtime lines whose labels match manifest overview labels; this plugin manifest declares Plan, but probe emits the dollar line with dynamic labels like Go/Pro/Teams Pro, so that line is filtered out in overview mode and users lose the primary dollar-usage metric there. Keep the runtime label stable (e.g., Plan) and move the human-friendly plan name to plan or subtitle text.
Useful? React with 👍 / 👎.
| if (planId && total > 0) { | ||
| lines.push(ctx.line.progress({ |
There was a problem hiding this comment.
Return a fallback line for unmapped plan IDs
The total > 0 gate means any new/unknown planId (or plans not in PLAN_LIMITS) returns zero lines even after successful API calls, and the runtime treats empty output as an error state (no lines returned). This makes the provider look broken for valid accounts on unsupported plan IDs instead of showing partial data or a clear unsupported-plan message.
Useful? React with 👍 / 👎.
|
@codex review again |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e38a47cc83
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var periodDurationMs = | ||
| new Date(subJson.data.currentPeriodEnd).getTime() - | ||
| new Date(subJson.data.currentPeriodStart).getTime(); | ||
| if (planId && total > 0) { |
There was a problem hiding this comment.
Return fallback usage line for unmapped plan IDs
When planId is not present in PLAN_LIMITS, total becomes 0 and this guard skips all output lines, so probe() returns lines: []. In the current runtime, empty lines are converted to an error line ("no lines returned" in src-tauri/src/plugin_engine/runtime.rs), which makes the plugin show an error for valid accounts on newly introduced/unknown plans. This means plan catalog changes on Command Code can silently break usage display until a code update.
Useful? React with 👍 / 👎.
| throw "Request failed (HTTP " + resp.status + "). Try again later."; | ||
| } | ||
|
|
||
| if (!json || !json.credits || typeof json.credits.monthlyCredits !== "number") { |
| var resetsAtMs = new Date(subJson.data.currentPeriodEnd).getTime(); | ||
|
|
||
| var lines = []; | ||
| var periodDurationMs = | ||
| new Date(subJson.data.currentPeriodEnd).getTime() - | ||
| new Date(subJson.data.currentPeriodStart).getTime(); |
|
|
||
| var lines = []; | ||
| var periodDurationMs = | ||
| new Date(subJson.data.currentPeriodEnd).getTime() - | ||
| new Date(subJson.data.currentPeriodStart).getTime(); | ||
| if (planId && total > 0) { | ||
| lines.push( | ||
| ctx.line.progress({ | ||
| label: "Monthly Quota", | ||
| used: Math.min(100, Math.max(0, Math.round((used / total) * 100))), | ||
| limit: 100, | ||
| format: { kind: "percent" }, | ||
| resetsAt: ctx.util.toIso(resetsAtMs), | ||
| periodDurationMs, | ||
| }), | ||
| ); | ||
| lines.push( | ||
| ctx.line.progress({ | ||
| label: formatPlanLabel(planId), | ||
| used: used, | ||
| limit: total, | ||
| format: { kind: "dollars" }, | ||
| resetsAt: ctx.util.toIso(resetsAtMs), | ||
| periodDurationMs, | ||
| }), | ||
| ); |
| expect(pctLine.format.kind).toBe("percent"); | ||
| }); | ||
|
|
||
| it("clamaps percent line to 100 when used exceeds total", async function () { |
| | Condition | Behavior | | ||
| |---|---| | ||
| | Secrets file missing | Plugin hidden | |
| | API returns 401/403 | Red error: `Session expired. Re-authenticate in CommandCode.` | | ||
| | API returns HTTP error | Red error with status code or detail message | | ||
| | Network failure | Red error: `Request failed. Check your connection.` | | ||
| | Unexpected response structure | Red error: `Could not parse usage data.` | |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@codex re-review just to be make sure |
| expect(pctLine.format.kind).toBe("percent"); | ||
| }); | ||
|
|
||
| it("clamaps percent line to 100 when used exceeds total", async function () { |
| describe("command plugin", function () { | ||
| beforeEach(function () { | ||
| delete globalThis.__openusage_plugin; | ||
| vi.resetModules(); | ||
| }); |
| async function probe(ctx) { | ||
| var apiKey = loadApiKey(ctx); | ||
| if (!apiKey) { | ||
| throw "CommandCode not installed. Install CommandCode to get started."; | ||
| } |
| var resetsAtMs = new Date(subJson.data.currentPeriodEnd).getTime(); | ||
|
|
||
| var lines = []; | ||
| var periodDurationMs = | ||
| new Date(subJson.data.currentPeriodEnd).getTime() - | ||
| new Date(subJson.data.currentPeriodStart).getTime(); | ||
| if (planId && total > 0) { | ||
| lines.push( | ||
| ctx.line.progress({ | ||
| label: "Monthly Quota", | ||
| used: Math.min(100, Math.max(0, Math.round((used / total) * 100))), | ||
| limit: 100, | ||
| format: { kind: "percent" }, | ||
| resetsAt: ctx.util.toIso(resetsAtMs), | ||
| periodDurationMs, | ||
| }), | ||
| ); | ||
| lines.push( | ||
| ctx.line.progress({ | ||
| label: formatPlanLabel(planId), | ||
| used: used, | ||
| limit: total, | ||
| format: { kind: "dollars" }, | ||
| resetsAt: ctx.util.toIso(resetsAtMs), | ||
| periodDurationMs, | ||
| }), | ||
| ); |
| var apiKey = loadApiKey(ctx); | ||
| if (!apiKey) { | ||
| throw "CommandCode not installed. Install CommandCode to get started."; | ||
| } |
| | API returns 401/403 | Red error: `Session expired. Re-authenticate in CommandCode.` | | ||
| | API returns HTTP error | Red error with status code or detail message | | ||
| | Network failure | Red error: `Request failed. Check your connection.` | | ||
| | Unexpected response structure | Red error: `Could not parse usage data.` | |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74d18aadc1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| var planId = subJson.data.planId; | ||
| var total = PLAN_LIMITS[planId] || 0; |
There was a problem hiding this comment.
Emit fallback usage line for unknown plan IDs
When planId is not in PLAN_LIMITS, total becomes 0, the if (planId && total > 0) block is skipped, and the plugin returns lines: []; runtime then converts that into an error line ("no lines returned" in src-tauri/src/plugin_engine/runtime.rs), so users on any new/renamed Command Code plan get a false failure despite successful API responses. Return at least one fallback line (or explicit unsupported-plan error) instead of an empty array.
Useful? React with 👍 / 👎.
| "version": "0.0.1", | ||
| "entry": "plugin.js", | ||
| "icon": "icon.svg", | ||
| "brandColor": "#575757", |
There was a problem hiding this comment.
Use Command Code official brand color in manifest
AGENTS.md (repo root) says plugin.json must use the provider’s real brandColor, but this value is set to neutral gray #575757 rather than Command Code’s published brand palette colors, so the provider is misbranded in UI and violates the project’s plugin requirement.
Useful? React with 👍 / 👎.
Description
Adds Command Code as a provider plugin with monthly quota and usage.
Related Issue
None
Type of Change
Testing
bun run buildand it succeededbun run testand all tests passbun tauri devScreenshots
Checklist
mainbranchSummary by cubic
Adds a new
command-codeprovider plugin that tracks monthly plan credits via the Command Code billing API. Shows monthly quota percent and dollar usage aligned to the subscription period.~/.commandcode/auth.json(apiKey); stays hidden if missing.GET https://api.commandcode.ai/alpha/billing/creditsandGET https://api.commandcode.ai/alpha/billing/subscriptions.currentPeriodStart/currentPeriodEndto setresetsAtandperiodDurationMs.docs/providers/command-code.md, updates README, and includes tests for auth, API calls, parsing, limits, labels, and period handling.Written for commit 74d18aa. Summary will update on new commits.