claude-simple-status 1.1.0 → 1.2.0
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 +9 -5
- package/package.json +2 -2
- package/statusline.mjs +16 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://nodejs.org/)
|
|
10
10
|
[]()
|
|
11
11
|
|
|
12
|
-
A simple, no-frills statusline for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) that shows what matters: **git branch, model, context usage, and
|
|
12
|
+
A simple, no-frills statusline for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) that shows what matters: **project name, git branch, model, context usage, quota, and API costs**.
|
|
13
13
|
|
|
14
14
|

|
|
15
15
|
|
|
@@ -19,8 +19,10 @@ A simple, no-frills statusline for [Claude Code](https://docs.anthropic.com/en/d
|
|
|
19
19
|
- **Cross-platform** — works on macOS, Linux, and Windows
|
|
20
20
|
- **Non-blocking** — returns cached data instantly, refreshes quota in the background
|
|
21
21
|
- **Color-coded** — green/orange/red percentages at a glance
|
|
22
|
-
- **
|
|
22
|
+
- **Project name** — bold uppercase project directory name so you never mix up sessions
|
|
23
23
|
- **Git-aware** — shows the current branch name in repos (cached 30s to reduce overhead)
|
|
24
|
+
- **API cost tracking** — pay-as-you-go API users see cumulative session cost instead of quota
|
|
25
|
+
- **Stale-aware** — shows `--` for quota values when cache is outdated, real values appear after first refresh
|
|
24
26
|
- **Timezone-smart** — quota reset time converted to your local timezone
|
|
25
27
|
|
|
26
28
|
If the quota API is unreachable, a red `ERR` indicator appears at the end and clears automatically once the connection recovers.
|
|
@@ -93,12 +95,14 @@ To uninstall, remove `~/.claude/statusline/` and the `"statusLine"` block from s
|
|
|
93
95
|
|
|
94
96
|
## How it works
|
|
95
97
|
|
|
96
|
-
1. Receives model/context info from Claude Code via stdin (JSON)
|
|
98
|
+
1. Receives model/context/cost info from Claude Code via stdin (JSON)
|
|
97
99
|
2. Reads cached quota data and returns immediately (never blocks the UI)
|
|
98
100
|
3. If the cache is stale (>2 minutes), refreshes from Anthropic's OAuth API in the background
|
|
99
101
|
4. Converts UTC reset time to your local timezone
|
|
100
102
|
5. Outputs a formatted statusline with ANSI colors
|
|
101
103
|
|
|
104
|
+
**Subscription users** see quota percentages and reset times. **API (pay-as-you-go) users** see cumulative session cost (e.g. `$4.72`) — calculated by Claude Code from actual token usage, no external pricing lookups needed.
|
|
105
|
+
|
|
102
106
|
Quota data is cached to the system temp directory and refreshed every 2 minutes. Since Claude Code calls the statusline on every message update, this avoids excessive API calls while keeping the data fresh.
|
|
103
107
|
|
|
104
108
|
## Troubleshooting
|
|
@@ -132,10 +136,10 @@ Remove-Item $env:TEMP\claude-statusline-quota.json
|
|
|
132
136
|
|
|
133
137
|
### [claude-rig](https://github.com/edimuj/claude-rig)
|
|
134
138
|
|
|
135
|
-
Run multiple isolated Claude Code configurations simultaneously — each with its own plugins, skills, MCP servers, and settings. When a session is launched through claude-rig, the active profile name appears in the statusline in bold magenta
|
|
139
|
+
Run multiple isolated Claude Code configurations simultaneously — each with its own plugins, skills, MCP servers, and settings. When a session is launched through claude-rig, the active profile name appears in the statusline in bold magenta:
|
|
136
140
|
|
|
137
141
|
```
|
|
138
|
-
|
|
142
|
+
MY-PROJECT [main] | minimal | Opus 4.6 | 12% | 14:30 | 5h:34% | 7d:12%
|
|
139
143
|
```
|
|
140
144
|
|
|
141
145
|
No configuration needed — claude-simple-status detects claude-rig automatically. Users not using claude-rig are unaffected.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-simple-status",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A simple statusline for Claude Code — git branch, model, context usage, and
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "A simple statusline for Claude Code — project name, git branch, model, context usage, quota, and API costs at a glance",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"claude-simple-status": "statusline.mjs"
|
package/statusline.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { readFileSync, writeFileSync, mkdirSync, rmdirSync, statSync, existsSync } from 'fs';
|
|
6
6
|
import { homedir, tmpdir } from 'os';
|
|
7
|
-
import { join } from 'path';
|
|
7
|
+
import { join, basename } from 'path';
|
|
8
8
|
import { spawn, execSync } from 'child_process';
|
|
9
9
|
|
|
10
10
|
// Handle --uninstall flag (workaround: npm doesn't run preuninstall for global packages)
|
|
@@ -30,6 +30,7 @@ const GREEN = '\x1b[0;32m';
|
|
|
30
30
|
const ORANGE = '\x1b[0;33m';
|
|
31
31
|
const RED = '\x1b[0;31m';
|
|
32
32
|
const CYAN = '\x1b[0;36m';
|
|
33
|
+
const WHITE_BOLD = '\x1b[1;37m';
|
|
33
34
|
const MAGENTA_BOLD = '\x1b[1;35m';
|
|
34
35
|
const YELLOW_BOLD = '\x1b[1;33m';
|
|
35
36
|
const RESET = '\x1b[0m';
|
|
@@ -198,10 +199,18 @@ async function main() {
|
|
|
198
199
|
// Parse Claude Code input
|
|
199
200
|
let model = 'Unknown';
|
|
200
201
|
let contextUsed = 0;
|
|
202
|
+
let totalCostUsd = null;
|
|
203
|
+
let projectName = null;
|
|
201
204
|
try {
|
|
202
205
|
const data = JSON.parse(input);
|
|
203
206
|
model = data.model?.display_name || 'Unknown';
|
|
204
207
|
contextUsed = data.context_window?.used_percentage || 0;
|
|
208
|
+
if (typeof data.cost?.total_cost_usd === 'number') {
|
|
209
|
+
totalCostUsd = data.cost.total_cost_usd;
|
|
210
|
+
}
|
|
211
|
+
if (data.workspace?.project_dir) {
|
|
212
|
+
projectName = basename(data.workspace.project_dir).toUpperCase();
|
|
213
|
+
}
|
|
205
214
|
} catch {}
|
|
206
215
|
|
|
207
216
|
// Get OAuth token
|
|
@@ -267,12 +276,17 @@ async function main() {
|
|
|
267
276
|
const branch = getGitBranch();
|
|
268
277
|
|
|
269
278
|
// Build output
|
|
270
|
-
|
|
279
|
+
const projectSegment = projectName
|
|
280
|
+
? `${WHITE_BOLD}${projectName}${branch ? ` ${YELLOW_BOLD}[${branch}]` : ''}${RESET}`
|
|
281
|
+
: (branch ? `${YELLOW_BOLD}${branch}${RESET}` : '');
|
|
282
|
+
let output = `${projectSegment ? `${projectSegment} | ` : ''}${rigProfile ? `${MAGENTA_BOLD}${rigProfile}${RESET} | ` : ''}${CYAN}${model}${RESET} | ${colorPct(contextUsed)}`;
|
|
271
283
|
if (token) {
|
|
272
284
|
output += ` | ${resetLocal} | 5h:${colorPct(fiveHourPct)} | 7d:${colorPct(sevenDayPct)}`;
|
|
273
285
|
if (hasError) {
|
|
274
286
|
output += ` | ${RED}ERR${RESET}`;
|
|
275
287
|
}
|
|
288
|
+
} else if (totalCostUsd !== null) {
|
|
289
|
+
output += ` | ${GREEN}$${totalCostUsd.toFixed(2)}${RESET}`;
|
|
276
290
|
}
|
|
277
291
|
|
|
278
292
|
process.stdout.write(output);
|