claude-simple-status 1.1.0 → 1.2.1

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,9 +9,11 @@
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
- ![statusline screenshot](assets/statusline.png)
14
+ ![statusline subscription](assets/statusline-subscription.png)
15
+
16
+ ![statusline api](assets/statusline-api.png)
15
17
 
16
18
  ## Features
17
19
 
@@ -19,8 +21,10 @@ A simple, no-frills statusline for [Claude Code](https://docs.anthropic.com/en/d
19
21
  - **Cross-platform** — works on macOS, Linux, and Windows
20
22
  - **Non-blocking** — returns cached data instantly, refreshes quota in the background
21
23
  - **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
24
+ - **Project name** — bold uppercase project directory name so you never mix up sessions
23
25
  - **Git-aware** — shows the current branch name in repos (cached 30s to reduce overhead)
26
+ - **API cost tracking** — pay-as-you-go API users see cumulative session cost instead of quota
27
+ - **Stale-aware** — shows `--` for quota values when cache is outdated, real values appear after first refresh
24
28
  - **Timezone-smart** — quota reset time converted to your local timezone
25
29
 
26
30
  If the quota API is unreachable, a red `ERR` indicator appears at the end and clears automatically once the connection recovers.
@@ -93,12 +97,14 @@ To uninstall, remove `~/.claude/statusline/` and the `"statusLine"` block from s
93
97
 
94
98
  ## How it works
95
99
 
96
- 1. Receives model/context info from Claude Code via stdin (JSON)
100
+ 1. Receives model/context/cost info from Claude Code via stdin (JSON)
97
101
  2. Reads cached quota data and returns immediately (never blocks the UI)
98
102
  3. If the cache is stale (>2 minutes), refreshes from Anthropic's OAuth API in the background
99
103
  4. Converts UTC reset time to your local timezone
100
104
  5. Outputs a formatted statusline with ANSI colors
101
105
 
106
+ **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.
107
+
102
108
  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
109
 
104
110
  ## Troubleshooting
@@ -132,10 +138,10 @@ Remove-Item $env:TEMP\claude-statusline-quota.json
132
138
 
133
139
  ### [claude-rig](https://github.com/edimuj/claude-rig)
134
140
 
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:
141
+ 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
142
 
137
143
  ```
138
- minimal | main | Opus 4.6 | 12% | 14:30 | 5h:34% | 7d:12%
144
+ MY-PROJECT [main] | minimal | Opus 4.6 | 12% | 14:30 | 5h:34% | 7d:12%
139
145
  ```
140
146
 
141
147
  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.1",
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
@@ -255,11 +264,11 @@ async function main() {
255
264
  hasError = errContent.length > 0;
256
265
  } catch {}
257
266
 
258
- // Get rig profile (claude-rig sets CLAUDE_CONFIG_DIR to ~/.claude-rig/profiles/<name>)
267
+ // Get rig name (claude-rig sets CLAUDE_CONFIG_DIR to ~/.claude-rig/rigs/<name>)
259
268
  const rigProfile = (() => {
260
269
  const configDir = process.env.CLAUDE_CONFIG_DIR;
261
270
  if (!configDir) return null;
262
- const match = configDir.match(/\.claude-rig\/profiles\/([^/]+)\/?$/);
271
+ const match = configDir.match(/\.claude-rig\/rigs\/([^/]+)\/?$/);
263
272
  return match ? match[1] : null;
264
273
  })();
265
274
 
@@ -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);