# dsh-cost-meter

> Provides DSH with DeepSeek session costs, official balance, budget and peak-valley pricing visualization. Supports OpenCode Go and multi-vendor Coding Plan quota queries with one-click official price sync.

## Metadata

- Author: [@Han-1413141](https://github.com/Han-1413141)
- Repo: <https://github.com/Han-1413141/dsh-cost-meter.git>
- GitHub: [Han-1413141/dsh-cost-meter](https://github.com/Han-1413141/dsh-cost-meter)
- Stars: 133
- Language: JavaScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `cost-tracking`, `deepseek`, `deepseek-api`, `deepseek-harness`, `dsh`, `dsh-plugin`, `dsh-plugins`, `harness`, `llm`, `plugins`, `token-usage`
- Forks: 8
- Open Issues: 0
- Last push: 2026-08-20T10:17:04.000Z
- Added: 2026-08-14T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:Han-1413141/dsh-cost-meter
```

## Wiki

## At a Glance
Real-time cost tracking for DeepSeek Harness: monitors current session and historical model call costs, official account balance, budget progress, and peak/off-peak pricing tiers. Optional integration with OpenCode Go subscription and multi-vendor Coding Plan quotas, with one-click sync from the official pricing page.

## Core Features
- **Real-time session cost accumulation**: Plugin captures input, cache read/write, output, and reasoning tokens for each model call, charging per the price list; badge position can be toggled between below the input area and the session title bar
- **Global ledger & history**: Daily aggregated costs, call counts, and session details, retaining the last N days (default 180); today/month/cumulative cards and Codex-style 26-week daily usage heatmap
- **Budget box & overspend alerts**: Rounded box at sidebar bottom shows budget, used percentage, today's cost, and cost-to-budget ratio; ≥80% turns yellow, ≥100% turns red, alerts only without blocking calls
- **Official account balance**: Calls official open platform balance API, reuses the same API Key from model requests; total balance / gifted / top-up breakdown shown in sidebar top or settings page, in-process cache expires per refresh interval
- **Multi-tier quota queries**: OpenCode Go rolling 5h / this week / this month usage percentages, overlaid with six vendor Coding Plan quotas (Anthropic Claude, Z.ai / 智谱, MiniMax, Kimi / Moonshot, OpenRouter, SiliconFlow)
- **One-click official price sync**: Scrapes official pricing page to parse base and peak/off-peak rates, auto-writes to price table while preserving historical prices; provides AI prompt document for third-party vendor price manual verification

## Technical Implementation
- **Language**: JavaScript (ESM, TypeScript not enabled; 5 `.js` source files under `lib/` + single-file browser bundle)
- **Key dependencies**: `zod` (config/state schema validation), `@deepseek-ai/dsh-credentials` (OpenCode Go / Coding Plan / balance Key parsing), `@deepseek-ai/dsh-home-paths` (ledger root directory resolution)
- **Architecture pattern**: dual-half host plugin. Host half intercepts model stream via `ctx.on('llm/stream', ...)` to capture usage blocks and write to ledger per price list; `ctx.inject(['sessionProjections'])` registers `costUsage` session projection (client prices by current price table); `ctx.provide('costMeter', service)` exposes ledger snapshot/config/refresh/sync/reset RPC, hand-written `typertRemote` binding to match Typert gateway validation. Client half is single-file bundle, injects into four slots: `conversation.composer.dock`, `conversation.session.header.actions`, `sidebar.footer.action`, `settings.section`; styles entirely based on `--dsw-*` theme variables following light/dark mode
- **Entry files**: host entry `lib/index.js` (`apply` / `name = 'cost-meter'`); client entry `lib/client.js`; mount declaration `cordis.patch.yml` (1 line Loader insertion in web profile) + `package.json#dsh.bundle.patch`

## Use Cases
When DSH users want a visible "ledger feel" for model spending — real-time view of current session and historical cost trends, setting monthly budgets with progress bar alerts, verifying official price tables in settings, checking OpenCode Go and multiple Coding Plan remaining quotas at a glance. This plugin consolidates all measurable dimensions into a single "Cost" settings section, eliminating the need to switch between multiple official consoles.

## Prerequisites & Compatibility
| Dependency | Minimum Version | Notes |
|---|---|---|
| DeepSeek Harness (DSH) | `0.1.0-rc.5` | `package.json#dshhub.compatibility.dsh` declares `>=0.1.0-rc.5` |
| Node.js | `>=20` | `package.json#dshhub.compatibility.node` declares `>=20` |
| Platform | Cross-platform | No native modules; ledger uses `node:fs` atomic writes, Key parsing reads pure text files like `~/.local/share/opencode/auth.json`, `~/.claude/.credentials.json` |
| Native modules | None | All third-party dependencies are pure JS (zod / dsh-credentials / dsh-home-paths) |
| Network | `api.deepseek.com` (balance), `api-docs.deepseek.com` (official pricing), `opencode.ai` (Go quota), six Coding Plan vendor endpoints | Balance strictly whitelist official domains, Keys not sent to other endpoints |

## Installation
```bash
dsh plugin --profile web add github:Han-1413141/dsh-cost-meter
```

## Configuration Options
Visualized editing by default in Settings → Cost all sections; below is the adjustable field overview (excerpt from `lib/store.js:27-95`, all fields validated by zod schema in `updateConfig` RPC and auto-saved instantly with 600ms debounce).

| Config | Type | Description | Default |
|---|---|---|---|
| `locale` | enum | UI language: auto (follow browser) / zh (Simplified Chinese) / en (English) | `auto` |
| `position` | enum | Session cost badge position: dock (below input area) / header (session title bar) / off (disabled) | `dock` |
| `sidebar` | boolean | Show today's cost at sidebar bottom | `true` |
| `currency` / `symbol` / `decimals` / `exchangeRate` | string / string / number(0-10) / number | Display currency and exchange rate (default CNY / ¥ / 4 digits / 7.2), ledger amounts always stored in USD | `CNY` / `¥` / `4` / `7.2` |
| `peakEnabled` | boolean | Enable peak/off-peak two-tier pricing (UTC 01:00–04:00 and 06:00–10:00 are peak periods, off-peak price = half of peak price) | `true` |
| `peakNotice` / `peakStyle` | boolean / enum | Prominent alert during high-price peak periods and period bar style (compact single-line / classic segmented capsule) | `true` / `compact` |
| `priceMatch` / `priceOverrides` / `priceTableDisplay` | enum / map / map | Unknown model auto-match strategy (auto strip suffix / prefix / family similarity, or exact only), manual match override, per-model whether to display directly in "Price Table" area | `auto` / `{}` / `{}` |
| `prices.models` / `prices.default` / `prices.providers` | map / entry / map | DeepSeek and third-party vendor price tables, three buckets (cacheHit/cacheMiss/output) or two-tier shorthand (input/output) both supported; peak/off-peak sub-tiers filled per DeepSeek model structure | Built-in DeepSeek price table + third-party catalog |
| `budget.enabled` / `amount` / `period` / `customStart` / `customEnd` / `detail` | boolean / number / enum / date / date / boolean | Budget box master switch and quota, period (day/month/all/custom), detail rows | `false` / `100` / `month` / `null` / `null` / `true` |
| `balance.display` / `refreshMinutes` | enum / number(1-1440) | Balance display position (sidebar / settings / both / off) and auto-refresh interval | `both` / `5` |
| `goQuota.enabled` / `display` / `refreshMinutes` / `apiKey` / `main` / `detail` | boolean / enum / number / string / enum / boolean | OpenCode Go subscription quota master switch, display position, refresh interval, Key (box main quota rolling 5h / weekly / monthly) | `true` / `both` / `15` / `""` / `rolling` / `true` |
| `corner.enabled` / `goRolling` / `goWeekly` / `goMonthly` / `budget` | boolean × 5 | Bottom-right (composer dock) four independent chips: rolling 5h / this week / this month / budget used % | `false` / `true` / `true` / `true` / `true` |
| `codingPlans.<provider>.enabled` / `display` / `refreshMinutes` / `apiKey` | boolean / enum / number / string | Six Coding Plan vendors (anthropic / zai / minimax / kimi / openrouter / siliconflow) independent enable, display position, refresh interval, Key | `false` / `settings` / `15` / `""` |
| `usage.position` | enum | Token usage statistics display position: cost (inside cost settings section) / general (general settings) / section (standalone section) | `cost` |
| `historyDays` | number(7-3650) | Ledger retention days | `180` |

## FAQ

**Q: Is the interface in Chinese or English? Can I switch?**

A: Simplified Chinese / English / follow browser (auto) three modes. Default follows browser (`zh*` → Chinese, others → English), detection result not persisted. Switch in Settings → Cost → Display Settings → Interface Language, entire UI takes effect instantly and auto-saves; balance returned by server and price sync prompts also display in current language.

**Q: I don't see balance in the sidebar after installation / display is abnormal. What should I do?**

A: Balance depends on DeepSeek API Key in DSH model settings; please configure Key in Settings → Models on first launch or export `DEEPSEEK_API_KEY`. Balance endpoint strictly only sends to official domain `api.deepseek.com`, balance query is rejected when baseURL points to non-official domain (model calls unaffected). Balance auto-refreshes every 5 minutes by default, can be disabled in Settings → Cost → Balance display position.

**Q: OpenCode Go or Coding Plan quotas disappear automatically / show "not enabled"?**

A: Go quota requires DSH credential store or env var `OPENCODE_GO_API_KEY`, unconfigured shows neutral hint in settings page, won't turn red. Open Settings → Cost → OpenCode Go panel to enable; unsubscribed can disable "Enable" switch. Similar for each Coding Plan: fill Key in corresponding panel or configure env var, disable "Enable" to stop.

**Q: How to sync the latest official prices? Will sync overwrite my custom prices?**

A: Click "Sync from Official Docs" in Settings → Cost → Data & Sync area, plugin scrapes official pricing page and writes after parsing. Only overwrites same-named model entries listed on official page, custom model entries unaffected; sync reports error and preserves original price table on parse failure, manual edit as fallback.

**Q: Will reaching 100% budget stop model calls?**

A: No. Budget and overspend alerts only notify without blocking calls; ≥80% turns yellow, ≥100% turns red and shows overspend badge in sidebar bottom budget box. Hard limit requires handling at model layer yourself.

**Q: Where is data stored? How to clear all history?**

A: Ledger file at `$DSH_HOME/storages/cost-meter/ledger.json`, retained per `historyDays` (default 180 days), max 200 session details per day; writes use temp file + atomic rename + 2s debounce. Clear: click "Clear All History" in Settings → Cost → Data & Sync; also can manually delete `ledger.json`.

**Q: How to uninstall?**

A: `dsh plugin --profile web remove dsh-cost-meter`, restart `dsh web`. Plugin doesn't introduce extra background processes or modify host files; ledger file remains at `$DSH_HOME/storages/cost-meter/ledger.json`, delete manually if needed.

**Q: Page doesn't change after installation/update?**

A: Must restart `dsh web` after plugin installation or update; plugin line, Typert manifest, and client bundle all scanned at startup; only refreshing browser won't reload server-side plugin.

## Getting Started Difficulty
Beginner — one `dsh plugin add` + restart `dsh web` shows cost panel in sidebar and settings; official price sync requires access to `api-docs.deepseek.com`. Advanced: read Price Table / Extend Price Table / Multi-provider Model Adaptation (see `docs/model-and-plan-adaptation.md`) and manually verify non-DeepSeek model prices per vendor.

## Known Issues & Limitations
- Official pricing page parsing depends on current page structure: after official redesign, "Sync from Official Docs" reports error and preserves original price table, manual edit as fallback
- Session badge estimates by current price tier: accurate cost based on ledger; historical call costs in ledger precisely recorded per price tier at call time
- Price sync only overwrites same-named model prices listed on official page: custom model entries unaffected
- Balance query enforces official domain whitelist: only `api.deepseek.com` accepted, balance query rejected when baseURL points to non-official domain, model requests unaffected
- OpenCode Go quota endpoint is `opencode.ai/zen/go/v1/usage` (community docs): when interface structure changes, settings shows error, can disable display in Display Settings
- Must restart `dsh web` after plugin install/update: plugin line, Typert manifest, and client bundle all scanned at startup
- Third-party Coding Plan partial balance only: Anthropic OAuth, Z.ai / 智谱, MiniMax Token Plan have verified usage endpoints; Kimi Code subscription weekly window / 5-hour window have no public API-Key-ized endpoint, currently displayed as PAYG balance window; 百炼 Coding Plan / OpenAI Codex / Gemini Code Assist / GitHub Copilot personal have no API-Key-ized usage endpoints, not integrated

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-cost-meter](https://deepseek-plugin.org/plugins/Han-1413141/dsh-cost-meter)
Wiki generated by AI (model: `MiniMax-M2.5`)
