|
1 | 1 | # CLAUDE.md |
2 | 2 |
|
3 | | -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 3 | +## Project |
4 | 4 |
|
5 | | -## Cooauthor |
6 | | -Do not mention the AI provider/model as a cooauthor in the commit message or PR description. |
| 5 | +AiOverviewControl is a self-contained DankMaterialShell widget for AI quota, billing, authentication, and local usage telemetry. |
7 | 6 |
|
8 | | -## Project Overview |
| 7 | +Runtime: QML/Quickshell plus Bash helpers. Core dependencies: `bash`, `jq`, and `curl`. |
9 | 8 |
|
10 | | -DMS widget plugin that monitors AI provider quota health. Shows most-limited provider in DankBar pill; floating dashboard with per-provider cards. |
| 9 | +## Rules |
11 | 10 |
|
12 | | -**Runtime stack:** QML (Quickshell), bash helper scripts, optional `codexbar` CLI fallback. |
| 11 | +- Do not mention an AI provider/model as coauthor in commits or pull requests. |
| 12 | +- Keep provider failures isolated. |
| 13 | +- Never fabricate quota percentages for providers without a documented surface. |
| 14 | +- Prefer official CLI protocols and documented APIs; do not scrape authenticated dashboards. |
| 15 | +- Keep the plugin self-contained and preserve user settings during upgrades. |
13 | 16 |
|
14 | | -**Key dependencies:** `bash`, `node`, `jq`, `curl`. Optional: `codexbar`, `gh` (Copilot), `claude` CLI. |
| 17 | +## Data flow |
15 | 18 |
|
16 | | -## Key Files |
| 19 | +1. Widget runs `providers/get-provider-usage <providers> <copilot-helper>`. |
| 20 | +2. Dispatcher calls one local adapter per provider. |
| 21 | +3. Every result follows `{provider, source, usage, credits, error}`. |
| 22 | +4. Widget renders healthy and failed providers independently. |
| 23 | +5. Claude analytics run separately from the main dispatcher. |
17 | 24 |
|
18 | | -| File | Role | |
19 | | -|------|------| |
20 | | -| `AiOverviewControlWidget.qml` | DankBar pill, popout dashboard, QML data collection and normalization | |
21 | | -| `AiOverviewControlSettings.qml` | DMS settings UI | |
22 | | -| `providers/get-provider-usage` | Unified shell backend — dispatches per-provider, returns JSON array | |
23 | | -| `providers/get-copilot-usage` | GitHub Copilot bridge via `gh auth token` or env tokens | |
24 | | -| `providers/get-claude-usage` | Claude Code analytics from `~/.claude` JSONL logs + optional OAuth | |
25 | | -| `plugin.json` | Plugin metadata, capabilities, permissions | |
| 25 | +## Settings |
26 | 26 |
|
27 | | -## Data Flow |
| 27 | +`refreshInterval`, `providerSelection`, `showErrorProviders`, `pillMode`, `pillProviders`, `densityMode`, `costCurrency`, `showClaudeProjects`, `languageOverride`. |
28 | 28 |
|
29 | | -1. Widget calls `providers/get-provider-usage` with `providerSelection`, `sourceMode`, optional `codexbarPath`, optional Copilot helper path. |
30 | | -2. Script dispatches per provider — local bridges first, `codexbar` fallback for others. |
31 | | -3. Returns JSON array. Each item: `{ provider, source, usage, credits, error }`. |
32 | | -4. Widget normalizes and renders cards. Errors become isolated cards — do not suppress healthy providers. |
33 | | -5. Provider with highest `usedPercent` drives the compact DankBar indicator. |
34 | | -6. For `claude`, widget may also spawn `providers/get-claude-usage` for 5h/7d windows, token counts, cost estimates. |
35 | | - |
36 | | -## Provider Output Schema |
37 | | - |
38 | | -```text |
39 | | -provider / source / error |
40 | | -usage.identity.accountEmail |
41 | | -usage.primary / secondary / tertiary |
42 | | - usedPercent, windowMinutes, resetsAt, resetDescription, remaining, unlimited, hasQuota |
43 | | -credits.remaining |
44 | | -``` |
45 | | - |
46 | | -## Settings Keys |
47 | | - |
48 | | -`refreshInterval`, `codexbarPath`, `providerSelection`, `sourceMode`, `showErrorProviders` |
49 | | - |
50 | | -Stored in DMS settings store — never overwrite user preferences when updating plugin files. |
51 | | - |
52 | | -## Validation Commands |
| 29 | +## Validation |
53 | 30 |
|
54 | 31 | ```bash |
55 | | -# Lint QML |
56 | | -qmllint AiOverviewControlWidget.qml AiOverviewControlSettings.qml || true |
57 | | - |
58 | | -# Validate plugin metadata |
59 | 32 | jq . plugin.json |
| 33 | +bash -n providers/get-* |
| 34 | +shellcheck providers/get-* |
| 35 | +qmllint AiOverviewControlWidget.qml AiOverviewControlSettings.qml AiOverviewControlI18n.qml |
| 36 | +./providers/get-provider-health "codex,claude,copilot" | jq . |
| 37 | +./providers/get-codex-usage | jq . |
| 38 | +./providers/get-provider-usage "codex,claude,copilot" ./providers/get-copilot-usage | jq . |
| 39 | +``` |
60 | 40 |
|
61 | | -# Test data pipeline end-to-end |
62 | | -~/.config/DankMaterialShell/plugins/AiOverviewControl/providers/get-provider-usage \ |
63 | | - "$(command -v codexbar)" "codex,claude,copilot" "cli" \ |
64 | | - ~/.config/DankMaterialShell/plugins/AiOverviewControl/providers/get-copilot-usage |
65 | | - |
66 | | -# Test individual bridges |
67 | | -~/.config/DankMaterialShell/plugins/AiOverviewControl/providers/get-copilot-usage |
68 | | -~/.config/DankMaterialShell/plugins/AiOverviewControl/providers/get-claude-usage |
| 41 | +## Provider policy |
69 | 42 |
|
70 | | -# Test via codexbar fallback |
71 | | -codexbar usage --format json --provider codex --source cli |
72 | | -codexbar usage --format json --provider claude --source cli |
73 | | -``` |
| 43 | +See `docs/providers.md` for behavior and `docs/provider-verification.md` for upstream documentation links and evidence level. |
74 | 44 |
|
75 | 45 | ## Release |
76 | 46 |
|
77 | | -Releases trigger on `v*` tags. CI runs on push/PR to `main` (validates `plugin.json` + optional `qmllint`). |
| 47 | +Tag must match `plugin.json` and the changelog entry: |
78 | 48 |
|
79 | 49 | ```bash |
80 | | -git tag v1.x.y && git push origin v1.x.y |
| 50 | +git tag v1.x.y |
| 51 | +git push origin v1.x.y |
81 | 52 | ``` |
82 | | - |
83 | | -Artifacts: `AiOverviewControl-vX.Y.Z.zip` and `.tar.gz` built from `git ls-files`. |
84 | | - |
85 | | -## Provider Matrix |
86 | | - |
87 | | -| ID | Name | Source | Env vars required | API endpoint | |
88 | | -|----|------|--------|-------------------|--------------| |
89 | | -| `codex` | Codex | codexbar → 9router fallback | — | codexbar CLI | |
90 | | -| `claude` | Claude | OAuth local + JSONL | `~/.claude/.credentials.json` | `api.anthropic.com/api/oauth/usage` | |
91 | | -| `copilot` | Copilot | GitHub API | `gh auth login` or `COPILOT_GITHUB_TOKEN` | `api.github.com/copilot_internal/user` (AI Credits model since 2026-06-01: `entitlement`/`remaining`/`token_based_billing`) | |
92 | | -| `gemini` | Gemini | OAuth local or API key | `GEMINI_API_KEY` or `~/.gemini/oauth_creds.json` | Validates key only | |
93 | | -| `openrouter` | OpenRouter | REST API | `OPENROUTER_API_KEY` | `openrouter.ai/api/v1/auth/key` | |
94 | | -| `9router` | 9Router | SQLite local | — | `~/.9router/db/data.sqlite` | |
95 | | -| `deepseek` | DeepSeek | REST API | `DEEPSEEK_API_KEY` | `api.deepseek.com/user/balance` | |
96 | | -| `kimi` | Kimi | REST API | `MOONSHOT_API_KEY` or `KIMI_API_KEY` (opt. `MOONSHOT_API_BASE`) | `api.moonshot.ai` (global/USD) → `api.moonshot.cn` (China/CNY) fallback, `/v1/users/me/balance` | |
97 | | -| `mistral` | Mistral | API key validation only | `MISTRAL_API_KEY` | `api.mistral.ai/v1/models` (no quota endpoint) | |
98 | | -| `glm` | GLM/Zhipu | REST API | `GLM_API_KEY` or `ZHIPU_API_KEY` | `bigmodel.cn/api/monitor/usage/quota/limit` | |
99 | | -| `minimax` | MiniMax | REST API | `MINIMAX_API_KEY` | `minimax.io/v1/token_plan/remains` | |
100 | | -| `qwen` | Qwen | API key validation only | `DASHSCOPE_API_KEY` or `QWEN_API_KEY` | No quota endpoint — UI only | |
101 | | -| `nvidia` | NVIDIA NIM | API key validation only | `NVIDIA_API_KEY` | No quota endpoint — UI only | |
102 | | -| `cloudflare` | Cloudflare AI | REST API | `CLOUDFLARE_AI_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` | `api.cloudflare.com/v4/accounts/{id}/ai/usage` | |
103 | | -| `vertexai` | Vertex AI | gcloud OAuth | `gcloud auth login` | gcloud local auth check | |
104 | | -| `byteplus` | BytePlus Ark | API key validation only | `BYTEPLUS_API_KEY` or `ARK_API_KEY` | No quota endpoint — UI only | |
105 | | -| `ollama` | Ollama | Local HTTP | `OLLAMA_HOST` (default: localhost:11434) | `localhost:11434/api/tags` | |
106 | | -| `perplexity` | Perplexity | codexbar or note | — | No public quota endpoint | |
107 | | -| `cursor` | Cursor | codexbar or note | — | No public quota endpoint | |
108 | | -| `cline` | Cline | note | — | No REST endpoint | |
109 | | -| `opencode` | OpenCode | note | — | Proxy only, no billing | |
110 | | -| `kilo` | Kilo | codexbar or note | — | No public quota endpoint | |
111 | | -| `kiro` | Kiro | codexbar or note | — | No public quota endpoint | |
112 | | -| `warp` | Warp | codexbar or note | — | No public quota endpoint | |
113 | | -| `amp` | Amp | codexbar or note | — | No public quota endpoint | |
114 | | - |
115 | | -**Providers not implemented (no API, ToS issues):** Antigravity (Google, ToS violation risk). |
116 | | - |
117 | | -## Design Constraints |
118 | | - |
119 | | -- Plugin must be self-contained — no imports from other DMS plugins. |
120 | | -- Per-provider isolation: one provider failure must not hide others. |
121 | | -- New provider bridges must output `provider/source/usage/credits/error` schema. |
122 | | -- Collection timeout: 45 seconds. Exceeded → show timeout error, discard stale output. |
123 | | -- Follow DMS theme tokens and Quickshell UI patterns for visual consistency. |
124 | | - |
125 | | -## Design Context |
126 | | - |
127 | | -### Users |
128 | | -Power users and developers using Dank Material Shell as a daily desktop control surface. They need to glance at AI assistant quota health while switching between CLIs, editors, and providers. |
129 | | - |
130 | | -### Brand Personality |
131 | | -Refined, premium, calm. The interface should feel like a dependable shell instrument: compact, readable, and direct, without marketing-style decoration. |
132 | | - |
133 | | -### Aesthetic Direction |
134 | | -Dark, token-driven DMS styling with restrained provider accents. Prefer layered surfaces, precise spacing, and a premium control-surface feel that adapts from narrow popouts to larger desktop panels without hiding core actions. |
135 | | - |
136 | | -### Design Principles |
137 | | -- Make provider health scannable first, details second. |
138 | | -- Keep every dependency local to AiOverviewControl unless it is an explicit external CLI/API fallback. |
139 | | -- Use responsive component reflow instead of fixed desktop-only rows. |
140 | | -- Treat errors as actionable provider states, not global failure. |
141 | | -- Preserve DMS theme tokens and interaction patterns for consistency with the shell. |
142 | | -- Keep motion subtle, purposeful, and calm. |
0 commit comments