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 CHANGED
@@ -9,7 +9,7 @@
9
9
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org/)
10
10
  [![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey)]()
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 quota**.
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
  ![statusline screenshot](assets/statusline.png)
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
- - **Stale-aware** — shows `--` for quota values when cache is outdated, real values appear after first refresh
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 as the first segment:
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
- minimal | main | Opus 4.6 | 12% | 14:30 | 5h:34% | 7d:12%
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.1.0",
4
- "description": "A simple statusline for Claude Code — git branch, model, context usage, and quota at a glance",
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
- let output = `${rigProfile ? `${MAGENTA_BOLD}${rigProfile}${RESET} | ` : ''}${branch ? `${YELLOW_BOLD}${branch}${RESET} | ` : ''}${CYAN}${model}${RESET} | ${colorPct(contextUsed)}`;
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);