mochiapi-statusline 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -325
- package/dist/ccstatusline.js +81 -32
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -1,386 +1,175 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
_ _ _ _
|
|
5
|
-
___ ___ ___| |_ __ _| |_ _ _ ___| (_)_ __ ___
|
|
6
|
-
/ __/ __/ __| __/ _` | __| | | / __| | | '_ \ / _ \
|
|
7
|
-
| (_| (__\__ \ || (_| | |_| |_| \__ \ | | | | | __/
|
|
8
|
-
\___\___|___/\__\__,_|\__|\__,_|___/_|_|_| |_|\___|
|
|
9
|
-
|
|
10
|
-
</pre>
|
|
3
|
+
# mochiapi-statusline
|
|
11
4
|
|
|
12
|
-
|
|
5
|
+
**[MochiAPI](https://mochiapi.com) 用户的 Claude Code 状态栏。**
|
|
6
|
+
一条命令装好。终端里看模型、上下文、账户余额、今日花费。
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
[](https://www.npmjs.com/package/mochiapi-statusline)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://nodejs.org)
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
[](https://www.npmjs.com/package/ccstatusline)
|
|
19
|
-
[](https://github.com/sirmalloc/ccstatusline/blob/main/LICENSE)
|
|
20
|
-
[](https://nodejs.org)
|
|
21
|
-
[](https://packagephobia.com/result?p=ccstatusline)
|
|
22
|
-
[](https://github.com/sirmalloc/ccstatusline/graphs/commit-activity)
|
|
23
|
-
|
|
24
|
-
[](https://github.com/hesreallyhim/awesome-claude-code)
|
|
25
|
-
[](https://claudelog.com/)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-

|
|
12
|
+

|
|
29
13
|
|
|
30
14
|
</div>
|
|
31
|
-
<br />
|
|
32
15
|
|
|
33
|
-
|
|
34
|
-
> **This is the `mochiapi-statusline` fork** — a customized build of upstream [sirmalloc/ccstatusline](https://github.com/sirmalloc/ccstatusline) with a built-in **MochiAPI balance widget** plus a one-shot setup that wires Claude Code and the recommended Mochi three-line layout for you.
|
|
35
|
-
>
|
|
36
|
-
> **If you came here to use this fork, follow [MOCHIAPI.md](MOCHIAPI.md) — not the upstream instructions below.** The two commands you need:
|
|
37
|
-
>
|
|
38
|
-
> ```bash
|
|
39
|
-
> npm install -g github:Subaru486desuwa/mochiapi-statusline
|
|
40
|
-
> mochiapi-statusline --mochiapi-setup
|
|
41
|
-
> ```
|
|
42
|
-
>
|
|
43
|
-
> The rest of this README is upstream documentation and applies as-is to the underlying ccstatusline engine (widgets, TUI, themes, etc.) — keep reading if you want to customize beyond the defaults.
|
|
44
|
-
|
|
45
|
-
<br />
|
|
46
|
-
|
|
47
|
-
## 📚 Table of Contents
|
|
48
|
-
|
|
49
|
-
- [Recent Updates](#-recent-updates)
|
|
50
|
-
- [Features](#-features)
|
|
51
|
-
- [Localizations](#-localizations)
|
|
52
|
-
- [Quick Start](#-quick-start)
|
|
53
|
-
- [Windows Support](docs/WINDOWS.md)
|
|
54
|
-
- [Usage](docs/USAGE.md)
|
|
55
|
-
- [Development](docs/DEVELOPMENT.md)
|
|
56
|
-
- [Contributing](#-contributing)
|
|
57
|
-
- [License](#-license)
|
|
58
|
-
- [Related Projects](#-related-projects)
|
|
59
|
-
|
|
60
|
-
<br />
|
|
61
|
-
|
|
62
|
-
## 🆕 Recent Updates
|
|
63
|
-
|
|
64
|
-
### v2.2.13 - Weekly model usage, voice status, hooks, and docs
|
|
65
|
-
|
|
66
|
-
- **📊 Weekly Sonnet/Opus usage widgets** - Added separate weekly usage widgets for Sonnet and Opus API buckets, matching Claude Code's `/usage` model split.
|
|
67
|
-
- **🎤 Voice Status widget** - Added a widget that shows whether Claude Code voice input is enabled, with icon, text, word, and optional Nerd Font display modes.
|
|
68
|
-
- **📉 Timer short bars** - Block Timer, Block Reset Timer, and Weekly Reset Timer now support compact short-bar progress displays.
|
|
69
|
-
- **🔕 Quieter hook output** - Hook handling now suppresses no-op JSON output so non-status updates stay silent.
|
|
70
|
-
|
|
71
|
-
### v2.2.9 - v2.2.12 - GitLab support, reset timers, context, compaction, and git widgets
|
|
72
|
-
|
|
73
|
-
- **🦊 GitLab PR/MR support** - `Git Branch` and `Git PR/MR` now support GitHub, GitLab, and compatible self-hosted remotes, using `gh` or `glab` as appropriate.
|
|
74
|
-
- **🔄 Status line refresh interval** - Installed configs can set Claude Code's `statusLine.refreshInterval` from the TUI when Claude Code >=2.1.97 supports it.
|
|
75
|
-
- **🧭 Wrap-around TUI navigation** - Menu/list navigation and move/reorder modes now wrap at the first and last items.
|
|
76
|
-
- **📋 Clone widget shortcut** - Press `k` in the item editor to duplicate the selected widget, with fresh Powerline background color for cloned Powerline items.
|
|
77
|
-
- **📊 Short bar display modes** - Context percentage, Context Bar, Session Usage, Weekly Usage, Block Timer, and reset timer widgets can use compact bar variants.
|
|
78
|
-
- **⏱️ Usage time cursor** - Session Usage and Weekly Usage progress bars can show the elapsed time position within the current usage window.
|
|
79
|
-
- **🕒 Reset timer timestamps** - Block and Weekly Reset Timer widgets can show exact reset timestamps with compact formatting, 12/24-hour display, IANA time zones, and locale selection.
|
|
80
|
-
- **🪟 Context Window widget** - Added a `Context Window` widget for total model window size, keeping `Context Length` focused on current context usage.
|
|
81
|
-
- **🔁 Compaction Counter widget** - Added a `Compaction Counter` widget that tracks session context compactions, with icon/text/number formats, optional Nerd Font icon, and hide-when-zero behavior.
|
|
82
|
-
- **🧮 Git file status widgets** - Added `Git Staged Files`, `Git Unstaged Files`, `Git Untracked Files`, and `Git Clean Status` for file counts and clean/dirty state.
|
|
83
|
-
- **🏷️ Clear context percentage labels** - `Context %` and `Context % (usable)` now label rendered values as used or left when toggling used/remaining mode.
|
|
84
|
-
- **⚡ More Powerline caps** - The Powerline separator editor now supports more than three start/end caps.
|
|
85
|
-
- **🧠 Thinking Effort updates** - Added `xhigh`, show `default` when no effort is set, mark unknown future effort levels with `?`, and track live status JSON plus `/effort` command changes.
|
|
86
|
-
- **🧮 More accurate token counts** - Streaming duplicate JSONL entries are deduped so token widgets do not overcount live Claude Code output.
|
|
87
|
-
- **🏷️ Cleaner model display** - The Model widget strips trailing context suffixes like `(1M context)`; use `Context Window` when you want the total window size shown.
|
|
88
|
-
- **🧹 Cleaner empty-widget separators** - Manual separators now collapse around widgets that render empty, avoiding dangling separators when hide-when-empty widgets disappear.
|
|
89
|
-
- **🧱 More resilient Git helpers** - Git widgets handle missing or unusual git command output more defensively.
|
|
90
|
-
|
|
91
|
-
### v2.2.8 - Git widgets, smarter picker search, and minimalist mode
|
|
92
|
-
|
|
93
|
-
- **🔀 New Git PR widget** - Added a `Git PR` widget with clickable PR links plus optional status and title display for the current branch.
|
|
94
|
-
- **🧰 Major Git widget expansion** - Added `Git Status`, `Git Staged`, `Git Unstaged`, `Git Untracked`, `Git Ahead/Behind`, `Git Conflicts`, `Git SHA`, `Git Origin Owner`, `Git Origin Repo`, `Git Origin Owner/Repo`, `Git Upstream Owner`, `Git Upstream Repo`, `Git Upstream Owner/Repo`, `Git Is Fork`, `Git Worktree Mode`, `Git Worktree Name`, `Git Worktree Branch`, `Git Worktree Original Branch`, and `Custom Symbol`.
|
|
95
|
-
- **👤 Claude Account Email widget** - Added a session widget that reads the signed-in Claude account email from `~/.claude.json` while respecting `CLAUDE_CONFIG_DIR`.
|
|
96
|
-
- **🧼 Global Minimalist Mode** - Added a global toggle in `Global Overrides` that forces widgets into raw-value mode for a cleaner, label-free status line.
|
|
97
|
-
- **🔎 Smarter widget picker search** - The add/change widget picker now supports substring, initialism, and fuzzy matching, with ranked results and live match highlighting.
|
|
98
|
-
- **📏 Better terminal width detection** - Flex separators and right-alignment now work more reliably when ccstatusline is launched through wrapper processes or nested PTYs.
|
|
99
|
-
- **🎨 Powerline theme continuity** - Built-in Powerline themes can now continue colors cleanly across multiple status lines instead of restarting each line.
|
|
100
|
-
|
|
101
|
-
### v2.2.0 - v2.2.6 - Speed, widgets, links, and reliability updates
|
|
102
|
-
|
|
103
|
-
- **🚀 New Token Speed widgets** - Added three widgets: **Input Speed**, **Output Speed**, and **Total Speed**.
|
|
104
|
-
- Each speed widget supports a configurable window of `0-120` seconds in the widget editor (`w` key).
|
|
105
|
-
- `0` disables window mode and uses a full-session average speed.
|
|
106
|
-
- `1-120` calculates recent speed over the selected rolling window.
|
|
107
|
-
- **🧩 New Skills widget controls (v2.2.1)** - Added configurable Skills modes (last/count/list), optional hide-when-empty behavior, and list-size limiting with most-recent-first ordering.
|
|
108
|
-
- **🌐 Usage API proxy support (v2.2.2)** - Usage widgets honor the uppercase `HTTPS_PROXY` environment variable for their direct API call to Anthropic.
|
|
109
|
-
- **🧠 New Thinking Effort widget (v2.2.4)** - Added a widget that shows the current Claude Code thinking effort level.
|
|
110
|
-
- **🍎 Better macOS usage lookup reliability (v2.2.5)** - Improved reliability when loading usage API tokens on macOS.
|
|
111
|
-
- **⌨️ New Vim Mode widget (v2.2.5)** - Added a widget that shows the current vim mode, with ASCII and optional Nerd Font icon display.
|
|
112
|
-
- **🔗 Git widget link modes (v2.2.6)** - `Git Branch` can render clickable GitHub branch links, and `Git Root Dir` can render clickable IDE links for VS Code and Cursor.
|
|
113
|
-
- **🤝 Better subagent-aware speed reporting** - Token speed calculations continue to include referenced subagent activity so displayed speeds better reflect actual concurrent work.
|
|
114
|
-
|
|
115
|
-
<br />
|
|
116
|
-
<details>
|
|
117
|
-
<summary><b>Older updates (v2.1.10 and earlier)</b></summary>
|
|
118
|
-
|
|
119
|
-
### v2.1.0 - v2.1.10 - Usage widgets, links, new git insertions / deletions widgets, and reliability fixes
|
|
120
|
-
|
|
121
|
-
- **🧩 New Usage widgets (v2.1.0)** - Added **Session Usage**, **Weekly Usage**, **Block Reset Timer**, and **Context Bar** widgets.
|
|
122
|
-
- **📊 More accurate counts (v2.1.0)** - Usage/context widgets now use new statusline JSON metrics when available for more accurate token and context counts.
|
|
123
|
-
- **🪟 Windows empty file bug fix (v2.1.1)** - Fixed a Windows issue that could create an empty `c:\dev\null` file.
|
|
124
|
-
- **🔗 New Link widget (v2.1.3)** - Added a new **Link** widget with clickable OSC8 rendering, preview parity, and raw mode support.
|
|
125
|
-
- **➕ New Git Insertions widget (v2.1.4)** - Added a dedicated Git widget that shows only uncommitted insertions (e.g., `+42`).
|
|
126
|
-
- **➖ New Git Deletions widget (v2.1.4)** - Added a dedicated Git widget that shows only uncommitted deletions (e.g., `-10`).
|
|
127
|
-
- **🧠 Context format fallback fix (v2.1.6)** - When `context_window_size` is missing, context widgets now infer 1M models from long-context labels such as `[1m]` and `1M context` in model identifiers.
|
|
128
|
-
- **⏳ Weekly reset timer split (v2.1.7)** - Added a separate `Weekly Reset Timer` widget.
|
|
129
|
-
- **⚙️ Custom config file flag (v2.1.8)** - Added `--config <path>` support so ccstatusline can load/save settings from a custom file location.
|
|
130
|
-
- **🔣 Unicode separator hex input upgrade (v2.1.9)** - Powerline separator hex input now supports 4-6 digits (full Unicode code points up to `U+10FFFF`).
|
|
131
|
-
- **🌳 Bare repo worktree detection fix (v2.1.10)** - `Git Worktree` now correctly detects linked worktrees created from bare repositories.
|
|
132
|
-
|
|
133
|
-
### v2.0.26 - v2.0.29 - Performance, git internals, and workflow improvements
|
|
134
|
-
|
|
135
|
-
- **🧠 Memory Usage widget (v2.0.29)** - Added a new widget that shows current system memory usage (`Mem: used/total`).
|
|
136
|
-
- **⚡ Block timer cache (v2.0.28)** - Cache block timer metrics to reduce JSONL parsing on every render, with per-config hashed cache files and automatic 5-hour block invalidation.
|
|
137
|
-
- **🧱 Git widget command refactor (v2.0.28)** - Refactored git widgets to use shared git command helpers and expanded coverage for failure and edge-case tests.
|
|
138
|
-
- **🪟 Windows UTF-8 piped output fix (v2.0.28)** - Sets the Windows UTF-8 code page for piped status line rendering.
|
|
139
|
-
- **📁 Git Root Dir widget (v2.0.27)** - Added a new Git widget that shows the repository root directory name.
|
|
140
|
-
- **🏷️ Session Name widget (v2.0.26)** - Added a new widget that shows the current Claude Code session name from `/rename`.
|
|
141
|
-
- **🏠 Current Working Directory home abbreviation (v2.0.26)** - Added a `~` abbreviation option for CWD display in both preview and live rendering.
|
|
142
|
-
- **🧠 Context model suffix fix (v2.0.26)** - Context widgets now recognize the `[1m]` suffix across models, not just a single model path.
|
|
143
|
-
- **🧭 Widget picker UX updates (v2.0.26)** - Improved widget discovery/navigation and added clearer, safer clear-line behavior.
|
|
144
|
-
- **⌨️ TUI editor input fix (v2.0.26)** - Prevented shortcut/input leakage into widget editor flows.
|
|
145
|
-
- **📄 Repo docs update (v2.0.26)** - Migrated guidance from `CLAUDE.md` to `AGENTS.md` (with symlink compatibility).
|
|
146
|
-
|
|
147
|
-
### v2.0.16 - Add fish style path abbreviation toggle to Current Working Directory widget
|
|
16
|
+
---
|
|
148
17
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
- Fix miscalculation in the block timer
|
|
18
|
+
## 安装
|
|
152
19
|
|
|
153
|
-
|
|
20
|
+
要 **Node.js ≥ 14**。一条命令装包 + 跑交互式 setup:
|
|
154
21
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g mochiapi-statusline && mochiapi-statusline --mochiapi-setup
|
|
24
|
+
```
|
|
158
25
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-

|
|
26
|
+
bash / zsh / fish / PowerShell 7+ / cmd.exe 都能跑,`&&` 把装包和 setup 串起来。
|
|
162
27
|
|
|
163
|
-
|
|
28
|
+
> **Windows PowerShell 5.1**(Win10 默认)不支持 `&&`,分两步:
|
|
29
|
+
> ```powershell
|
|
30
|
+
> npm install -g mochiapi-statusline
|
|
31
|
+
> mochiapi-statusline --mochiapi-setup
|
|
32
|
+
> ```
|
|
164
33
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
### v2.0.10 - Git Updates
|
|
34
|
+
先去 <https://mochiapi.com/dashboard> 复制 token,setup 会让你粘贴。`--mochiapi-setup` 做四件事:
|
|
168
35
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-

|
|
175
|
-
|
|
176
|
-
- **🎯 Widget Alignment** - Auto-align widgets across multiple status lines in Powerline mode for a clean, columnar layout (toggle with 'a' in Powerline Setup)
|
|
36
|
+
1. token + base URL → `~/.config/mochiapi-statusline/config.json`(Windows 是 `%APPDATA%\mochiapi-statusline\config.json`)
|
|
37
|
+
2. 探测一次 balance 接口,确认 token 有效
|
|
38
|
+
3. 把推荐的 **Mochi 两行 Powerline 布局**写入 `~/.config/ccstatusline/settings.json`(已有布局会把 Mochi 计费行追加进去)
|
|
39
|
+
4. 把 Claude Code 的 `~/.claude/settings.json` 里 `statusLine.command` 指向 `mochiapi-statusline`
|
|
177
40
|
|
|
178
|
-
|
|
41
|
+
开一个新的 Claude Code 会话,状态栏就有了。
|
|
179
42
|
|
|
180
|
-
|
|
43
|
+
> **Windows + Powerline**:默认布局用 Nerd Font 字形做分隔符,没装会看到 `?` 方块。装一个并设为终端字体:
|
|
44
|
+
>
|
|
45
|
+
> ```powershell
|
|
46
|
+
> winget install DEVCOM.JetBrainsMonoNerdFont
|
|
47
|
+
> ```
|
|
181
48
|
|
|
182
|
-
|
|
183
|
-
- Set the number of path segments to show (e.g., show only last 2 segments: `.../Personal/ccstatusline`)
|
|
184
|
-
- Supports raw value mode for compact display
|
|
185
|
-
- Automatically truncates long paths with ellipsis
|
|
186
|
-
- **💰 Session Cost Widget** - Track your Claude Code session costs (requires Claude Code 1.0.85+)
|
|
187
|
-
- Displays total session cost in USD
|
|
188
|
-
- Supports raw value mode (shows just `$X.YZ` vs `Cost: $X.YZ`)
|
|
189
|
-
- Real-time cost tracking from Claude Code session data
|
|
190
|
-
- Note: Cost may not update properly when using `/resume` (Claude Code limitation)
|
|
191
|
-
- **🐛 Bug Fixes**
|
|
192
|
-
- Fixed Block Timer calculations for accurate time tracking across block boundaries
|
|
193
|
-
- Improved widget editor stability with proper Ctrl+S handling
|
|
194
|
-
- Enhanced cursor display in numeric input fields
|
|
49
|
+
`dist/ccstatusline.js` 预构建产物直接打进 npm tarball,包不声明 `prepare` / `postinstall`,安装时不会跑本地构建,bundle 好的 binary 直接落地。
|
|
195
50
|
|
|
196
|
-
###
|
|
51
|
+
### 备用安装源
|
|
197
52
|
|
|
198
|
-
|
|
53
|
+
只在 npm registry 被墙、或者想跟 `main` HEAD 而不是 tag 发布时用:
|
|
199
54
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- Two progress bar styles: full width (32 chars) or compact (16 chars)
|
|
204
|
-
- Automatically detects block boundaries from transcript timestamps
|
|
55
|
+
```bash
|
|
56
|
+
# 跟踪 main HEAD(滚动,无版本锁定)
|
|
57
|
+
npm install -g github:Subaru486desuwa/mochiapi-statusline
|
|
205
58
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- **🎨 Built-in Themes** - Multiple pre-configured themes that you can copy and customize
|
|
209
|
-
- **🌈 Advanced Color Support** - Basic (16), 256-color (with custom ANSI codes), and truecolor (with hex codes) modes
|
|
210
|
-
- **🔗 Widget Merging** - Merge multiple widgets together with or without padding for seamless designs
|
|
211
|
-
- **📦 Easy Installation** - Install directly with `npx` or `bunx` - no global package needed
|
|
212
|
-
- **🔤 Custom Separators** - Add multiple Powerline separators with custom hex codes for font support
|
|
213
|
-
- **🚀 Auto Font Install** - Automatic Powerline font installation with user consent
|
|
59
|
+
# 锁到特定 git tag
|
|
60
|
+
npm install -g github:Subaru486desuwa/mochiapi-statusline#v0.1.1
|
|
214
61
|
|
|
215
|
-
|
|
62
|
+
# Tarball 直装(下载最小,等价于 github: 简写)
|
|
63
|
+
npm install -g https://github.com/Subaru486desuwa/mochiapi-statusline/archive/refs/heads/main.tar.gz
|
|
64
|
+
```
|
|
216
65
|
|
|
217
|
-
|
|
66
|
+
## 默认布局长这样
|
|
218
67
|
|
|
219
|
-
|
|
68
|
+
两行 Powerline,Mochi 配色(图中是实际效果):
|
|
220
69
|
|
|
221
|
-
-
|
|
222
|
-
-
|
|
223
|
-
- **⚡ Powerline Support** - Beautiful Powerline-style rendering with arrow separators, caps, and custom fonts
|
|
224
|
-
- **📐 Multi-line Support** - Configure multiple independent status lines
|
|
225
|
-
- **🖥️ Interactive TUI** - Built-in configuration interface using React/Ink
|
|
226
|
-
- **🔎 Fast Widget Picker** - Add/change widgets by category with search and ranked matching
|
|
227
|
-
- **⚙️ Global Options** - Apply consistent formatting across all widgets (padding, separators, bold, minimalist mode, and color overrides)
|
|
228
|
-
- **🚀 Cross-platform** - Works seamlessly with both Bun and Node.js
|
|
229
|
-
- **🔧 Flexible Configuration** - Supports custom Claude Code config directory via `CLAUDE_CONFIG_DIR` environment variable
|
|
230
|
-
- **📏 Smart Width Detection** - Automatically adapts to terminal width with flex separators
|
|
231
|
-
- **⚡ Zero Config** - Sensible defaults that work out of the box
|
|
70
|
+
- **第一行** — `模型 / Opus 4.7 (1M context) / 上下文 / 50.7k`,仓库内追加 `<分支> / <改动>`,仓库外自动隐藏
|
|
71
|
+
- **第二行** — `用户余额 / $98.43 / 今日消耗 / $11.66 / TPS / 6.4 t/s`(MochiAPI 账户余额 + 今日花费 + token 输出速率)
|
|
232
72
|
|
|
233
|
-
|
|
73
|
+
数值后面带 `*` 表示缓存值比 `2 × refreshIntervalSec`(默认 60 秒)旧,通常是瞬时网络抖动,后台 refresher 在重试。widget 继续显示上一次成功值。
|
|
234
74
|
|
|
235
|
-
|
|
75
|
+
`mochiapi-subscription` widget(三合一:`余额 $X.XX · 今日 $Y.YY · 订阅 $Z.ZZ/∞`)仍然可用,只是不在默认布局——大多数 MochiAPI 中转用户订阅是 `∞`,没意义。需要的话 TUI 里手动加。
|
|
236
76
|
|
|
237
|
-
|
|
77
|
+
## MochiAPI 自带的 widget
|
|
238
78
|
|
|
239
|
-
|
|
79
|
+
三个 widget 共用一次 `/api/user/dashboard/balance` 请求的缓存:
|
|
240
80
|
|
|
241
|
-
|
|
81
|
+
| Widget 类型 | 渲染 | 默认色 |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `mochiapi-balance` | 账户剩余余额 — `$X.XX` 或 `∞`(无限账户) | cyan |
|
|
84
|
+
| `mochiapi-daily-spend` | 今日花费 — `$X.XX` | magenta |
|
|
85
|
+
| `mochiapi-subscription` | `余额 $X.XX · 今日 $Y.YY · 订阅 $Z.ZZ/∞`(不在默认布局) | cyan |
|
|
242
86
|
|
|
243
|
-
|
|
87
|
+
缓存通过 detached 子进程每 `refreshIntervalSec`(默认 30 秒)刷新一次。
|
|
244
88
|
|
|
245
|
-
|
|
89
|
+
## CLI
|
|
246
90
|
|
|
247
91
|
```bash
|
|
248
|
-
#
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
# Or with Bun (faster)
|
|
252
|
-
bunx -y ccstatusline@latest
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
<br />
|
|
256
|
-
<details>
|
|
257
|
-
<summary><b>Configure ccstatusline</b></summary>
|
|
258
|
-
|
|
259
|
-
The interactive configuration tool provides a terminal UI where you can:
|
|
260
|
-
- Configure multiple separate status lines
|
|
261
|
-
- Add/remove/reorder status line widgets
|
|
262
|
-
- Customize colors for each widget
|
|
263
|
-
- Configure flex separator behavior
|
|
264
|
-
- Configure Claude Code status line refresh interval when supported
|
|
265
|
-
- Edit custom text widgets
|
|
266
|
-
- Install/uninstall to Claude Code settings
|
|
267
|
-
- Preview your status line in real-time
|
|
268
|
-
|
|
269
|
-
> 💡 **Tip:** Your settings are automatically saved to `~/.config/ccstatusline/settings.json`
|
|
270
|
-
|
|
271
|
-
> 🔧 **Custom Claude Config:** If your Claude Code configuration is in a non-standard location, set the `CLAUDE_CONFIG_DIR` environment variable:
|
|
272
|
-
> ```bash
|
|
273
|
-
> # Linux/macOS
|
|
274
|
-
> export CLAUDE_CONFIG_DIR=/custom/path/to/.claude
|
|
275
|
-
> ```
|
|
92
|
+
# 再跑一次交互式 setup
|
|
93
|
+
mochiapi-statusline --mochiapi-setup
|
|
276
94
|
|
|
277
|
-
|
|
95
|
+
# 非交互(CI / 脚本)
|
|
96
|
+
MOCHIAPI_TOKEN=sk-xxxx MOCHIAPI_BASE_URL=https://mochiapi.com \
|
|
97
|
+
mochiapi-statusline --mochiapi-setup
|
|
278
98
|
|
|
279
|
-
|
|
99
|
+
# 只写 mochi 配置,不动 ccstatusline / Claude Code 设置
|
|
100
|
+
mochiapi-statusline --mochiapi-setup --skip-statusline --skip-claude-wire
|
|
280
101
|
|
|
281
|
-
|
|
102
|
+
# 手动刷一次余额缓存(后台每 30 秒也会自动刷)
|
|
103
|
+
mochiapi-statusline --mochiapi-refresh
|
|
282
104
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
When you install from the TUI, ccstatusline writes a `statusLine` command object to your Claude Code settings:
|
|
287
|
-
|
|
288
|
-
```json
|
|
289
|
-
{
|
|
290
|
-
"statusLine": {
|
|
291
|
-
"type": "command",
|
|
292
|
-
"command": "npx -y ccstatusline@latest",
|
|
293
|
-
"padding": 0,
|
|
294
|
-
"refreshInterval": 10
|
|
295
|
-
}
|
|
296
|
-
}
|
|
105
|
+
# 启动 TUI 调整 widget / 颜色 / 布局 / Powerline
|
|
106
|
+
mochiapi-statusline
|
|
297
107
|
```
|
|
298
108
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
Other supported command values are:
|
|
302
|
-
- `bunx -y ccstatusline@latest`
|
|
303
|
-
- `ccstatusline` (for self-managed/global installs)
|
|
304
|
-
|
|
305
|
-
</details>
|
|
306
|
-
|
|
307
|
-
## 🤝 Contributing
|
|
308
|
-
|
|
309
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
310
|
-
|
|
311
|
-
1. Fork the repository
|
|
312
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
313
|
-
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
314
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
315
|
-
5. Open a Pull Request
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
## Support
|
|
319
|
-
|
|
320
|
-
If ccstatusline is useful to you, consider buying me a coffee:
|
|
321
|
-
|
|
322
|
-
<a href="https://www.buymeacoffee.com/sirmalloc" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
|
|
109
|
+
## 升级 / 卸载
|
|
323
110
|
|
|
111
|
+
```bash
|
|
112
|
+
# 升级到最新发布版本
|
|
113
|
+
npm install -g mochiapi-statusline@latest
|
|
324
114
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
## 👤 Author
|
|
331
|
-
|
|
332
|
-
**Matthew Breedlove**
|
|
333
|
-
|
|
334
|
-
- GitHub: [@sirmalloc](https://github.com/sirmalloc)
|
|
115
|
+
# 卸载
|
|
116
|
+
npm uninstall -g mochiapi-statusline
|
|
117
|
+
```
|
|
335
118
|
|
|
119
|
+
## 文件位置
|
|
336
120
|
|
|
337
|
-
|
|
121
|
+
| | macOS / Linux | Windows |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| MochiAPI token + baseUrl | `~/.config/mochiapi-statusline/config.json` | `%APPDATA%\mochiapi-statusline\config.json` |
|
|
124
|
+
| 余额缓存 | `~/.cache/mochiapi-statusline/balance.json` | `%LOCALAPPDATA%\mochiapi-statusline\cache\balance.json` |
|
|
125
|
+
| 状态栏布局 | `~/.config/ccstatusline/settings.json` | `%USERPROFILE%\.config\ccstatusline\settings.json` |
|
|
126
|
+
| Claude Code | `~/.claude/settings.json` | `%USERPROFILE%\.claude\settings.json` |
|
|
338
127
|
|
|
339
|
-
|
|
340
|
-
- [ccusage](https://github.com/ryoppippi/ccusage) - Track and display Claude Code usage metrics.
|
|
341
|
-
- [codachi](https://github.com/vincent-k2026/codachi) - A tamagotchi-style statusline pet that grows with your context window.
|
|
342
|
-
- [AIWatch](https://ai-watch.dev) - Live status monitor for 30+ AI APIs and apps; pairs with a Custom Command widget to surface provider outages in your status line.
|
|
128
|
+
token 配置和布局配置是**两个不同的文件**:改鉴权动第一个,改显示哪些 widget 动第二个(或者跑 TUI)。
|
|
343
129
|
|
|
130
|
+
## 排错
|
|
344
131
|
|
|
345
|
-
|
|
132
|
+
| 状态栏显示 | 含义 | 处理 |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `Mochi: cfg?` | 找不到 `config.json` | 重新跑 `mochiapi-statusline --mochiapi-setup` |
|
|
135
|
+
| `Mochi: ...` | 缓存还没填 | 跑 `mochiapi-statusline --mochiapi-refresh`,或等 30 秒 |
|
|
136
|
+
| `$X.XX*`(末尾 `*`) | 缓存陈旧 | 通常瞬时上游问题,后台 refresher 会自动重试 |
|
|
137
|
+
| 分隔符显示成 `?` | 终端没用 Nerd Font | 装 Nerd Font 并设为终端字体 |
|
|
346
138
|
|
|
347
|
-
|
|
348
|
-
- Powered by [Ink](https://github.com/vadimdemedes/ink) for the terminal UI
|
|
349
|
-
- Made with ❤️ for the Claude Code community
|
|
139
|
+
不启动 Claude Code 也能渲染一次看看效果:
|
|
350
140
|
|
|
351
|
-
|
|
141
|
+
```bash
|
|
142
|
+
echo '{"session_id":"test","model":{"id":"claude-sonnet-4-6","display_name":"Sonnet 4.6 (1M context)"},"workspace":{"current_dir":".","project_dir":"."},"cost":{"total_cost_usd":0},"transcript_path":"/tmp/nonexistent","output_style":{"name":"default"}}' \
|
|
143
|
+
| mochiapi-statusline
|
|
144
|
+
```
|
|
352
145
|
|
|
353
|
-
##
|
|
146
|
+
## 接口契约
|
|
354
147
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=sirmalloc/ccstatusline&type=Timeline" />
|
|
359
|
-
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=sirmalloc/ccstatusline&type=Timeline" />
|
|
360
|
-
</picture>
|
|
361
|
-
</a>
|
|
148
|
+
| 路径 | 返回 |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `GET ${baseUrl}/api/user/dashboard/balance` | 账户字段 + 今日花费(一次请求喂三个 widget) |
|
|
362
151
|
|
|
363
|
-
|
|
152
|
+
Bearer 鉴权(`Authorization: Bearer sk-...`),不用 cookie,不用 session。
|
|
364
153
|
|
|
365
|
-
|
|
154
|
+
从响应里读的字段:
|
|
366
155
|
|
|
367
|
-
|
|
156
|
+
| API 字段 | 用途 |
|
|
157
|
+
|---|---|
|
|
158
|
+
| 直接余额字段(`user_balance_usd` / `user_remain_quota_usd` / `balance_usd` 等,存在时) | 余额 widget(首选路径) |
|
|
159
|
+
| `data.user_quota_usd` − `data.user_used_quota_usd` | 余额 widget(直接字段缺失时的回退) |
|
|
160
|
+
| `data.today_used_quota_usd` | 今日花费 widget |
|
|
161
|
+
| `data.token_remain_quota_usd` + `data.token_unlimited` | 订阅 widget |
|
|
368
162
|
|
|
369
|
-
|
|
370
|
-
[](https://github.com/sirmalloc/ccstatusline/network/members)
|
|
371
|
-
[](https://github.com/sirmalloc/ccstatusline/watchers)
|
|
163
|
+
## 致谢
|
|
372
164
|
|
|
373
|
-
[
|
|
374
|
-
[](https://www.npmjs.com/package/ccstatusline)
|
|
375
|
-
[](https://github.com/sirmalloc/ccstatusline/blob/main/LICENSE)
|
|
376
|
-
[](https://bun.sh)
|
|
165
|
+
底层状态栏引擎 fork 自 [sirmalloc/ccstatusline](https://github.com/sirmalloc/ccstatusline)(MIT,© Matthew Breedlove)。MochiAPI 部分的增量只有:
|
|
377
166
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
167
|
+
- `mochiapi-balance` / `mochiapi-daily-spend` / `mochiapi-subscription` 三个 widget
|
|
168
|
+
- `--mochiapi-setup` / `--mochiapi-refresh` 两个 CLI flag
|
|
169
|
+
- 一键 setup(写 config + 写布局 + 接 Claude Code `statusLine.command`)
|
|
381
170
|
|
|
382
|
-
|
|
171
|
+
其余的 TUI、主题、布局、Powerline 渲染、20 多个其它 widget 全部是上游代码,深度自定义照样适用上游的 TUI。
|
|
383
172
|
|
|
384
|
-
|
|
173
|
+
## License
|
|
385
174
|
|
|
386
|
-
|
|
175
|
+
MIT — 见 [LICENSE](LICENSE) 和 [NOTICE](NOTICE)。
|
package/dist/ccstatusline.js
CHANGED
|
@@ -1362,8 +1362,9 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
1362
1362
|
|
|
1363
1363
|
// node_modules/react/index.js
|
|
1364
1364
|
var require_react = __commonJS((exports, module) => {
|
|
1365
|
+
var react_development = __toESM(require_react_development());
|
|
1365
1366
|
if (false) {} else {
|
|
1366
|
-
module.exports =
|
|
1367
|
+
module.exports = react_development;
|
|
1367
1368
|
}
|
|
1368
1369
|
});
|
|
1369
1370
|
|
|
@@ -3848,8 +3849,9 @@ var require_scheduler_development = __commonJS((exports) => {
|
|
|
3848
3849
|
|
|
3849
3850
|
// node_modules/react-reconciler/node_modules/scheduler/index.js
|
|
3850
3851
|
var require_scheduler = __commonJS((exports, module) => {
|
|
3852
|
+
var scheduler_development = __toESM(require_scheduler_development());
|
|
3851
3853
|
if (false) {} else {
|
|
3852
|
-
module.exports =
|
|
3854
|
+
module.exports = scheduler_development;
|
|
3853
3855
|
}
|
|
3854
3856
|
});
|
|
3855
3857
|
|
|
@@ -37056,8 +37058,9 @@ React keys must be passed directly to JSX without using spread:
|
|
|
37056
37058
|
|
|
37057
37059
|
// node_modules/react/jsx-runtime.js
|
|
37058
37060
|
var require_jsx_runtime = __commonJS((exports, module) => {
|
|
37061
|
+
var react_jsx_runtime_development = __toESM(require_react_jsx_runtime_development());
|
|
37059
37062
|
if (false) {} else {
|
|
37060
|
-
module.exports =
|
|
37063
|
+
module.exports = react_jsx_runtime_development;
|
|
37061
37064
|
}
|
|
37062
37065
|
});
|
|
37063
37066
|
|
|
@@ -55891,6 +55894,15 @@ function getModelContextIdentifier(model) {
|
|
|
55891
55894
|
}
|
|
55892
55895
|
return id ?? displayName;
|
|
55893
55896
|
}
|
|
55897
|
+
function lookupKnownModelWindow(modelIdentifier) {
|
|
55898
|
+
const id = modelIdentifier.toLowerCase();
|
|
55899
|
+
for (const { pattern, windowSize } of KNOWN_MODEL_CONTEXT_WINDOWS) {
|
|
55900
|
+
if (id.includes(pattern)) {
|
|
55901
|
+
return windowSize;
|
|
55902
|
+
}
|
|
55903
|
+
}
|
|
55904
|
+
return null;
|
|
55905
|
+
}
|
|
55894
55906
|
function getContextConfig(modelIdentifier, contextWindowSize) {
|
|
55895
55907
|
const statusWindowSize = toValidWindowSize(contextWindowSize);
|
|
55896
55908
|
if (statusWindowSize !== null) {
|
|
@@ -55913,9 +55925,26 @@ function getContextConfig(modelIdentifier, contextWindowSize) {
|
|
|
55913
55925
|
usableTokens: Math.floor(inferredWindowSize * USABLE_CONTEXT_RATIO)
|
|
55914
55926
|
};
|
|
55915
55927
|
}
|
|
55928
|
+
const knownWindowSize = lookupKnownModelWindow(modelIdentifier);
|
|
55929
|
+
if (knownWindowSize !== null) {
|
|
55930
|
+
return {
|
|
55931
|
+
maxTokens: knownWindowSize,
|
|
55932
|
+
usableTokens: Math.floor(knownWindowSize * USABLE_CONTEXT_RATIO)
|
|
55933
|
+
};
|
|
55934
|
+
}
|
|
55916
55935
|
return defaultConfig;
|
|
55917
55936
|
}
|
|
55918
|
-
var DEFAULT_CONTEXT_WINDOW_SIZE = 200000, USABLE_CONTEXT_RATIO = 0.8;
|
|
55937
|
+
var DEFAULT_CONTEXT_WINDOW_SIZE = 200000, USABLE_CONTEXT_RATIO = 0.8, KNOWN_MODEL_CONTEXT_WINDOWS;
|
|
55938
|
+
var init_model_context = __esm(() => {
|
|
55939
|
+
KNOWN_MODEL_CONTEXT_WINDOWS = [
|
|
55940
|
+
{ pattern: "glm-4.6", windowSize: 200000 },
|
|
55941
|
+
{ pattern: "glm-4.5", windowSize: 128000 },
|
|
55942
|
+
{ pattern: "glm-4", windowSize: 128000 },
|
|
55943
|
+
{ pattern: "kimi-k2", windowSize: 256000 },
|
|
55944
|
+
{ pattern: "qwen3-coder", windowSize: 256000 },
|
|
55945
|
+
{ pattern: "deepseek", windowSize: 128000 }
|
|
55946
|
+
];
|
|
55947
|
+
});
|
|
55919
55948
|
|
|
55920
55949
|
// src/utils/context-percentage.ts
|
|
55921
55950
|
function calculateContextPercentageMetrics(context) {
|
|
@@ -55939,7 +55968,9 @@ function calculateContextPercentageMetrics(context) {
|
|
|
55939
55968
|
function calculateContextPercentage(context) {
|
|
55940
55969
|
return calculateContextPercentageMetrics(context)?.usedPercentage ?? 0;
|
|
55941
55970
|
}
|
|
55942
|
-
var init_context_percentage = () => {
|
|
55971
|
+
var init_context_percentage = __esm(() => {
|
|
55972
|
+
init_model_context();
|
|
55973
|
+
});
|
|
55943
55974
|
|
|
55944
55975
|
// src/utils/terminal.ts
|
|
55945
55976
|
import { execSync } from "child_process";
|
|
@@ -56044,7 +56075,7 @@ function getTerminalWidth() {
|
|
|
56044
56075
|
function canDetectTerminalWidth() {
|
|
56045
56076
|
return probeTerminalWidth() !== null;
|
|
56046
56077
|
}
|
|
56047
|
-
var __dirname = "
|
|
56078
|
+
var __dirname = "/Volumes/ExtremeSSD/Developer/mochiapi/statusline/src/utils", PACKAGE_VERSION = "0.1.2";
|
|
56048
56079
|
var init_terminal = () => {};
|
|
56049
56080
|
|
|
56050
56081
|
// src/utils/renderer.ts
|
|
@@ -56870,6 +56901,7 @@ class ContextWindowWidget {
|
|
|
56870
56901
|
}
|
|
56871
56902
|
}
|
|
56872
56903
|
var init_ContextWindow = __esm(async () => {
|
|
56904
|
+
init_model_context();
|
|
56873
56905
|
await init_renderer2();
|
|
56874
56906
|
});
|
|
56875
56907
|
|
|
@@ -57425,6 +57457,7 @@ class ContextPercentageUsableWidget {
|
|
|
57425
57457
|
}
|
|
57426
57458
|
}
|
|
57427
57459
|
var init_ContextPercentageUsable = __esm(() => {
|
|
57460
|
+
init_model_context();
|
|
57428
57461
|
init_context_inverse();
|
|
57429
57462
|
init_context_slider();
|
|
57430
57463
|
});
|
|
@@ -57820,8 +57853,9 @@ React keys must be passed directly to JSX without using spread:
|
|
|
57820
57853
|
|
|
57821
57854
|
// node_modules/react/jsx-dev-runtime.js
|
|
57822
57855
|
var require_jsx_dev_runtime = __commonJS((exports, module) => {
|
|
57856
|
+
var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development());
|
|
57823
57857
|
if (false) {} else {
|
|
57824
|
-
module.exports =
|
|
57858
|
+
module.exports = react_jsx_dev_runtime_development;
|
|
57825
57859
|
}
|
|
57826
57860
|
});
|
|
57827
57861
|
|
|
@@ -65958,6 +65992,7 @@ class ContextBarWidget {
|
|
|
65958
65992
|
}
|
|
65959
65993
|
}
|
|
65960
65994
|
var init_ContextBar = __esm(async () => {
|
|
65995
|
+
init_model_context();
|
|
65961
65996
|
init_usage_display();
|
|
65962
65997
|
await init_usage();
|
|
65963
65998
|
});
|
|
@@ -67110,16 +67145,17 @@ function localDateKey(now2 = Date.now()) {
|
|
|
67110
67145
|
const day = `${d.getDate()}`.padStart(2, "0");
|
|
67111
67146
|
return `${y}-${m}-${day}`;
|
|
67112
67147
|
}
|
|
67113
|
-
function estimateTodayUsedUsd(
|
|
67114
|
-
if (
|
|
67115
|
-
return null;
|
|
67116
|
-
const prevTotal = typeof prev.tokenTotalUsedUsd === "number" ? prev.tokenTotalUsedUsd : null;
|
|
67117
|
-
if (prevTotal === null)
|
|
67148
|
+
function estimateTodayUsedUsd(currentTokenUsd, prev, todayKey, currentAccountUsedUsd = null) {
|
|
67149
|
+
if (!prev)
|
|
67118
67150
|
return null;
|
|
67119
67151
|
const prevDate = prev.tokenTotalUsedLocalDate ?? localDateKey(prev.fetchedAt);
|
|
67120
67152
|
if (prevDate !== todayKey)
|
|
67121
67153
|
return null;
|
|
67122
|
-
|
|
67154
|
+
if (currentTokenUsd !== null && typeof prev.tokenTotalUsedUsd === "number")
|
|
67155
|
+
return Math.max(0, currentTokenUsd - prev.tokenTotalUsedUsd);
|
|
67156
|
+
if (currentAccountUsedUsd !== null && typeof prev.accountUsedUsd === "number")
|
|
67157
|
+
return Math.max(0, currentAccountUsedUsd - prev.accountUsedUsd);
|
|
67158
|
+
return null;
|
|
67123
67159
|
}
|
|
67124
67160
|
function emptyCache(now2, ok) {
|
|
67125
67161
|
return {
|
|
@@ -67135,27 +67171,30 @@ function emptyCache(now2, ok) {
|
|
|
67135
67171
|
tokenTotalUsedLocalDate: null
|
|
67136
67172
|
};
|
|
67137
67173
|
}
|
|
67138
|
-
|
|
67174
|
+
function quotaToUsd(quota) {
|
|
67175
|
+
return quota === null ? null : quota / NEWAPI_QUOTA_PER_USD;
|
|
67176
|
+
}
|
|
67177
|
+
function cacheFromTokenUsage(resp, now2, prev) {
|
|
67139
67178
|
const d = dataObject(resp);
|
|
67140
|
-
const
|
|
67179
|
+
const tokenUnlimited = toBool(d.unlimited_quota) ?? toBool(d.token_unlimited);
|
|
67180
|
+
const totalUsedQuotaUsd = quotaToUsd(toNum(d.total_used));
|
|
67181
|
+
const totalGrantedQuotaUsd = quotaToUsd(toNum(d.total_granted));
|
|
67182
|
+
const totalAvailableQuotaUsd = quotaToUsd(toNum(d.total_available));
|
|
67183
|
+
const totalUsedUsd = firstNum(d.total_usd_used, d.token_total_usd_used, d.total_used_usd) ?? totalUsedQuotaUsd;
|
|
67184
|
+
const accountUsedUsdForEstimate = firstNum(d.user_used_quota_usd, d.user_usd_used);
|
|
67141
67185
|
const todayKey = localDateKey(now2);
|
|
67142
|
-
const todayUsedUsd = firstNum(d.today_used_quota_usd, d.today_usd_used, d.today_used_usd) ?? estimateTodayUsedUsd(totalUsedUsd, prev, todayKey);
|
|
67143
|
-
|
|
67144
|
-
|
|
67145
|
-
try {
|
|
67146
|
-
const dashResp = await httpGet(`${cfg.baseUrl}/api/user/dashboard/balance`, cfg.token);
|
|
67147
|
-
return await cacheFromDashboard(cfg, dashResp, now2);
|
|
67148
|
-
} catch {}
|
|
67149
|
-
}
|
|
67186
|
+
const todayUsedUsd = firstNum(d.today_used_quota_usd, d.today_usd_used, d.today_used_usd) ?? estimateTodayUsedUsd(totalUsedUsd, prev, todayKey, accountUsedUsdForEstimate);
|
|
67187
|
+
const limitedTokenQuotaFallback = tokenUnlimited === true ? null : totalGrantedQuotaUsd;
|
|
67188
|
+
const limitedTokenRemainFallback = tokenUnlimited === true ? null : totalAvailableQuotaUsd;
|
|
67150
67189
|
return {
|
|
67151
67190
|
fetchedAt: now2,
|
|
67152
67191
|
ok: true,
|
|
67153
|
-
directBalanceUsd,
|
|
67154
|
-
accountQuotaUsd: firstNum(d.user_quota_usd, d.user_total_quota_usd),
|
|
67192
|
+
directBalanceUsd: firstNum(d.user_usd_available, d.user_available_usd, d.user_balance_usd, d.user_remain_quota_usd, d.user_remaining_quota_usd, d.remain_balance, d.remaining_balance, d.balance_usd, d.balance),
|
|
67193
|
+
accountQuotaUsd: firstNum(d.user_quota_usd, d.user_total_quota_usd) ?? limitedTokenQuotaFallback,
|
|
67155
67194
|
accountUsedUsd: firstNum(d.user_used_quota_usd, d.user_usd_used),
|
|
67156
67195
|
todayUsedUsd,
|
|
67157
|
-
tokenRemainUsd: firstNum(d.total_usd_available, d.token_remain_quota_usd, d.token_remaining_quota_usd, d.token_available_usd),
|
|
67158
|
-
tokenUnlimited
|
|
67196
|
+
tokenRemainUsd: firstNum(d.total_usd_available, d.token_remain_quota_usd, d.token_remaining_quota_usd, d.token_available_usd) ?? limitedTokenRemainFallback,
|
|
67197
|
+
tokenUnlimited,
|
|
67159
67198
|
tokenTotalUsedUsd: totalUsedUsd,
|
|
67160
67199
|
tokenTotalUsedLocalDate: totalUsedUsd === null ? null : todayKey
|
|
67161
67200
|
};
|
|
@@ -67199,7 +67238,7 @@ async function fetchBalance(cfg, previousCache) {
|
|
|
67199
67238
|
const errors3 = [];
|
|
67200
67239
|
try {
|
|
67201
67240
|
const resp = await httpGet(`${cfg.baseUrl}/api/usage/token/`, cfg.token);
|
|
67202
|
-
return
|
|
67241
|
+
return cacheFromTokenUsage(resp, now2, prev);
|
|
67203
67242
|
} catch (e) {
|
|
67204
67243
|
errors3.push(`/api/usage/token/: ${e instanceof Error ? e.message : String(e)}`);
|
|
67205
67244
|
}
|
|
@@ -67253,7 +67292,10 @@ function viewFromCache(cache3, cfg) {
|
|
|
67253
67292
|
const quota = cache3.accountQuotaUsd;
|
|
67254
67293
|
const used = cache3.accountUsedUsd;
|
|
67255
67294
|
const tokenRemain = cache3.tokenRemainUsd;
|
|
67256
|
-
const
|
|
67295
|
+
const accountSentinelUnlimited = typeof quota === "number" && quota >= UNLIMITED_THRESHOLD;
|
|
67296
|
+
const hasAccountSignal = typeof quota === "number" || typeof used === "number" || typeof cache3.directBalanceUsd === "number";
|
|
67297
|
+
const tokenFallbackUnlimited = !hasAccountSignal && cache3.tokenUnlimited === true;
|
|
67298
|
+
const unlimited = accountSentinelUnlimited || tokenFallbackUnlimited;
|
|
67257
67299
|
let balanceUsd = null;
|
|
67258
67300
|
if (typeof cache3.directBalanceUsd === "number") {
|
|
67259
67301
|
balanceUsd = cache3.directBalanceUsd;
|
|
@@ -67284,7 +67326,7 @@ async function refreshCli() {
|
|
|
67284
67326
|
const cache3 = await fetchBalance(cfg);
|
|
67285
67327
|
writeCache2(cache3);
|
|
67286
67328
|
}
|
|
67287
|
-
var DEFAULT_BASE_URL = "https://mochiapi.com", DEFAULT_INTERVAL = 30, UNLIMITED_THRESHOLD = 1e7, MOCHI_CONFIG_PATH, MOCHI_CACHE_PATH;
|
|
67329
|
+
var DEFAULT_BASE_URL = "https://mochiapi.com", DEFAULT_INTERVAL = 30, UNLIMITED_THRESHOLD = 1e7, NEWAPI_QUOTA_PER_USD = 500000, MOCHI_CONFIG_PATH, MOCHI_CACHE_PATH;
|
|
67288
67330
|
var init_mochiapi = __esm(() => {
|
|
67289
67331
|
MOCHI_CONFIG_PATH = join4(getMochiConfigDir(), "config.json");
|
|
67290
67332
|
MOCHI_CACHE_PATH = join4(getMochiCacheDir(), "balance.json");
|
|
@@ -67329,7 +67371,14 @@ class MochiApiBalanceWidget {
|
|
|
67329
67371
|
const view = viewFromCache(cache3, cfg);
|
|
67330
67372
|
if (!view)
|
|
67331
67373
|
return labeled ? "Mochi: ..." : "...";
|
|
67332
|
-
|
|
67374
|
+
let body;
|
|
67375
|
+
if (view.balanceUsd !== null) {
|
|
67376
|
+
body = fmtUsd(view.balanceUsd);
|
|
67377
|
+
} else if (view.unlimited) {
|
|
67378
|
+
body = "∞";
|
|
67379
|
+
} else {
|
|
67380
|
+
body = "?";
|
|
67381
|
+
}
|
|
67333
67382
|
const decorated = view.stale ? `${body}*` : body;
|
|
67334
67383
|
return labeled ? `Mochi: ${decorated}` : decorated;
|
|
67335
67384
|
}
|
|
@@ -67438,7 +67487,7 @@ class MochiApiSubscriptionWidget {
|
|
|
67438
67487
|
const view = viewFromCache(cache3, cfg);
|
|
67439
67488
|
if (!view)
|
|
67440
67489
|
return labeled ? "Mochi: ..." : "...";
|
|
67441
|
-
const balance = view.balanceUsd
|
|
67490
|
+
const balance = view.balanceUsd !== null ? fmtUsd3(view.balanceUsd) : view.unlimited ? "∞" : "?";
|
|
67442
67491
|
const today = view.todayUsedUsd === null ? "?" : fmtUsd3(view.todayUsedUsd);
|
|
67443
67492
|
const subscription = view.tokenUnlimited === true ? "∞" : view.tokenRemainUsd === null ? "?" : fmtUsd3(view.tokenRemainUsd);
|
|
67444
67493
|
const body = `余额 ${balance} · 今日 ${today} · 订阅 ${subscription}`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mochiapi-statusline",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Claude Code status line for MochiAPI users — account balance, today's spend, model, context, and git in your terminal",
|
|
5
5
|
"module": "src/ccstatusline.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
"postbuild": "bun run scripts/replace-version.ts",
|
|
17
17
|
"example": "cat scripts/payload.example.json | bun start",
|
|
18
18
|
"lint": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0",
|
|
19
|
-
"lint:fix": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0 --fix"
|
|
20
|
-
"docs": "typedoc",
|
|
21
|
-
"docs:clean": "rm -rf typedoc"
|
|
19
|
+
"lint:fix": "bun tsc --noEmit && eslint . --config eslint.config.js --max-warnings=0 --fix"
|
|
22
20
|
},
|
|
23
21
|
"devDependencies": {
|
|
24
22
|
"@eslint/js": "^10.0.1",
|