Skip to content

feat(client): add plans & quota sidebar panel, real-time session cost readout, and price table remote - #36

Closed
xer-on wants to merge 1 commit into
Mars-Sea:mainfrom
xer-on:main
Closed

xer-on wants to merge 1 commit into
Mars-Sea:mainfrom
xer-on:main

Conversation

@xer-on

@xer-on xer-on commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR introduces three major UI and client-side capability upgrades for the Command Code provider plugin:

  1. Plans & Quota Dashboard & Sidebar Footer Card: A dedicated footer action in the sidebar (sidebar.footer.action) that reveals current plan details, 5-hour and weekly quota depletion bars, monthly credit balances (limit - remaining), and token statistics, which opens a full dashboard in the center workspace column (main slot).
  2. In-Composer Real-time Session Cost Readout: An unobtrusive cost indicator injected into the composer dock (conversation.composer.dock) that decorates the official token-usage pill with session cost estimates in USD and adds per-token cost breakdown rows into the usage dialog.
  3. Vendored Model Pricing Catalog & Remote Contract: A new Host-side price table (commandcode/prices) exposing official per-token rates (input, output, cache-read, cache-write) in USD per million tokens, factoring in weekday peak/off-peak pricing schedules.

Key Features & Changes

1. Plans & Quota Sidebar Card & Center Dashboard

  • Sidebar Footer Card: Registers under sidebar.footer.action (order 1), placing it immediately above the Settings seat. Shows live status and opens the dashboard on click via ctx.layout.selectPanel().
  • Center Dashboard Panel: Registers in the layout's main slot as commandcode-panel. Renders:
    • Account plan badge and billing cycle end dates.
    • 5-hour and weekly quota usage progress bars with automatic reset timers.
    • Monthly credit consumption using the official CLI derivation formula (limit - remaining).
    • Purchased vs. free credit tile breakdown.
  • Throttled Auto-Refresh: Background refresher keeps quota and token statistics current without overwhelming the API gateway.
  • Pure / React-Free Controller: Implemented in src/client/panel.ts so view-model logic and formatting can be tested without a DOM.

2. In-Composer Session Cost & Dialog Breakdown

  • Non-Destructive Pill Injection: Rather than replacing the stock stats dock cell (which would break upstream i18n and formatting), src/client/session-cost-display.ts decorates the existing token-usage button pill with dollar figures (e.g. · $0.02).
  • Usage Dialog Breakdown: Uses a lightweight MutationObserver on document.body to match and inject cost lines directly into the token details dialog (Uncached input, Completion, Cache read, Cache write).
  • Strict Guardrails:
    • Only computes cost for sessions routed through the commandcode provider.
    • Never fabricates unpriced cache-write rates; leaves unpriced rates clearly indicated.
    • Renders invisible if unpriceable or unknown, avoiding misleading zero-dollar figures.

3. Model Pricing Remote (commandcode/prices)

  • Vendored Pricing Data: src/model-prices.ts defines official pricing rows matching Command Code docs in USD / 1M tokens.
  • Typert Gateway Contract: Declares the commandcode/prices endpoint in src/usage-wire.ts and wires it in src/usage-remote.ts.
  • Peak / Off-Peak Calculation: Accurately determines weekday peak windows and applies peak-rate overrides for time-of-day models.

Architectural Notes

  • Clean Decoupling: All new controllers (src/client/panel.ts, src/client/session-cost.ts, src/client/prices.ts) are decoupled from React and JSX.
  • Resilient Registration: Slot injections (main, sidebar.footer.action, conversation.composer.dock) are wrapped in defensive guards so individual surface failures cannot crash the entire plugin fiber.

Verification

  • Verified snapshot store subscription and disposal lifecycle.
  • Tested quota progress bar and depletion percentage calculations.
  • Tested session cost calculator across free models, flat-rate models, and time-of-day peak models.

@Mars-Sea

Copy link
Copy Markdown
Owner

Thanks for this — the three features are good work, and we want them.

The problem is the base, not the features. This branch was forked from a main that predates a few published fixes, so the diff carries two opposite things at once: ~2,900 lines of new code, and the removal of the #33/#34/#35 fixes plus the #37 image budget, along with src/commands.ts (the /commandcode dashboard), Config.lang, and the zh copy. As it stands the branch fails 21 of its own suite, including stream() replays reasoning blocks on the CLI transport, the tool-schema normalization tests and the parallel-image-carrier tests — all behaviours that shipped in 0.10.6. Merging it as-is would bring those regressions back.

So we did the rebase here instead and kept only the new work: #38 ports model-prices.ts, the plans & quota panel and the composer session-cost readout onto the current main, leaves adapter.ts / accounts.ts / sessions.ts / locales.ts / tui-settings.ts untouched, and keeps the settings page bilingual. Your commit is preserved as the git author of #38, and the design comments in the new modules are kept verbatim.

Four things had to change to make the new code work against the real package:

  • Package identity: REMOTE_PACKAGE (plus the update check and the CSS ids) reads @xer-on/dsh-commandcode-provider, but the package is @mars-sea/dsh-commandcode-provider. A Remote mounted under the fork name never resolves, so commandcode/prices would silently never arrive and the cost readout would never show a figure.
  • injectPanelCss() is called but never defined — it compiles (it is not a type error) and throws ReferenceError during apply(), which would have aborted the panel and the session-cost registrations.
  • UsageRemote.prices / the namespace member are now optional: a Host older than the feature mounts no such descriptor, so the absence has to read as "no prices" instead of calling an undefined method.
  • The panel and the readout need dsh 0.1.5+ — the layout's main slot is named conversation before that, and [data-composer-stats] / [data-session-stats-usage] are 0.1.5 markup. On an older engine both registrations silently do not happen, which is the behaviour we document.

We also added the tests the features did not have (price table ↔ catalog join, the pricing honesty rules, the panel projection and refresh loop, the one-shot price controller): 447 passing, typecheck and build clean.

Two points are open product decisions we would rather not make for you: the two surfaces are English-only by construction rather than via ctx.locale (kept as authored, documented in AGENTS.md), and sessionCostAmount()'s doc comment says amounts below a cent get four decimals while the implementation renders $0.0123 as $0.01 — we pinned the behaviour, not the comment.

Happy to keep this PR open if you would like to rebase it onto main yourself and compare; otherwise #38 supersedes it. Either way, thanks — the price-table extraction and the "decorate, don't replace the pill" decision are the parts that made this worth porting carefully.

Mars-Sea added a commit that referenced this pull request Sep 14, 2026
Ported from #36 by @xer-on, with the review fixes from #40 folded in: correct published rates and a sync script, per-request cost history instead of repricing cumulative tokens, Host-resolved credential availability, unreported-vs-zero balances, and the compatibility gate for the sidebar card.
@Mars-Sea

Copy link
Copy Markdown
Owner

Closing this as superseded — thank you @xer-on, the work itself shipped.

All three features from this PR are now on main, ported rather than merged:

  • the plans & quota sidebar card + dashboard
  • the composer session-cost readout
  • the vendored price table served over commandcode/prices

Why it was ported instead of merged

This branch is based on a main that predates the #33/#34/#35 fixes and the #37 image budget, so its diff does not only add the three features — it also reverts that work. On this head:

  • src/command-locales.ts is deleted entirely (−157) and Config.lang is gone
  • src/client/locales.ts loses 147 lines of zh copy
  • src/accounts.ts, src/tui-settings.ts, src/client/sessions.ts are rolled back

That is why the branch is CONFLICTING and why #38 re-applied only the new work on top of the current main, leaving every one of those files untouched. The port also carried several review fixes that this version did not have — the list is in #38 and #40.

Where it lives now

main at 2e03ffd. Your authorship is preserved: the feature commit in #38 keeps xer-on <rifat.rahman378@gmail.com> as its git author, and the CHANGELOG entries credit this PR and @xer-on by link.

The panel and the readout did need dsh 0.1.5 for the layout's keyed main seat, so the sidebar card is gated on the layout seam — on an older engine it is not registered at all rather than rendering a button that opens nothing.

@Mars-Sea Mars-Sea closed this Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants