Show a status line changedthird-party/claude-desktop/status-line
Nearest release: v2.1.322, published 16 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 10 Nov 2026 18:30 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 10 Nov 2026 18:37 UTC.
Upstream edited
Recorded here
Lines+36added
Lines−7removed
From line
13
where the diff opens
First seen
29 Oct 2026
this site's first read of the page
Recorded edits5to this page, all time
### Session cost in the status line input
The whole hunk
from line 13, old and new numbered
/
from line 13
1313> These cases are covered on other pages:
1414>
1515> * **A notice across the top of the app window, with no program to install**: set the [`banner`](https://claude.com/docs/third-party/claude-desktop/configuration#banner) key
16> * **A message that each user can close, on the start screen or in a dialog**: set the [`organizationAnnouncement`](https://claude.com/docs/third-party/claude-desktop/configuration#organizationannouncement) key
1617> * **Your own message when your gateway blocks a user at a spend limit**: see [Block requests at a spend limit](https://claude.com/docs/third-party/claude-desktop/gateway.md#block-requests-at-a-spend-limit)
1718
1819## Turn on the status line
from line 24
2324
2425Put the program where users can't change it. Claude Desktop runs it only from a location that meets these rules:
2526
26* **macOS and Linux**: root owns the file and every parent folder, with no write access for group or others
27* **macOS and Linux**: root owns the file and every parent folder, with no write access for group or others, and the path isn't under `/home`, `/net`, or `/Volumes`
2728* **Windows**: the file is under `Program Files` or `Program Files (x86)` on the drive where Windows is installed
2829
2930To try the [macOS and Linux sample](#sample-status-line-programs) on a test device, save it as `status-line` and run these commands in your terminal:
from line 80
7980
8081Claude Desktop starts the status line program with no arguments and no window, as the user who runs Claude Desktop.
8182
82* **File type**: on macOS and Linux, an executable file, such as a compiled program or a script that starts with `#!`. On Windows, an `.exe` file or a `.ps1`, `.cmd`, or `.bat` script.
83* **File type**: on macOS and Linux, an executable file, such as a compiled program or a script that starts with `#!`. Claude Desktop doesn't check the interpreter that a `#!` line names, so install it where users can't change it too. Python also runs code from the user's folders unless you start it with `-I`, for example `#!/usr/bin/python3 -I`. On Windows, an `.exe` file or a `.ps1`, `.cmd`, or `.bat` script.
8384
84* **Input**: one line of JSON on standard input, with the session ID and the model. A field with no value is left out, so handle a missing `model`.
85* **Input**: one line of JSON on standard input, with the session ID, the model, and the [session cost](#session-cost-in-the-status-line-input). A field with no value is left out, so handle a missing `model` or `cost`. Later versions can add fields, so ignore any that the program doesn't use. Don't build a file path from these values.
8586
8687 ```json theme={null}
87 {"session_id":"local_1f0c2a9e-7b3d-4c58-9a16-5e2d8b40c7f3","model":{"id":"claude-sonnet-4-5","display_name":"Claude Sonnet 4.5"}}
88 {"session_id":"local_1f0c2a9e-7b3d-4c58-9a16-5e2d8b40c7f3","model":{"id":"claude-sonnet-4-5","display_name":"Claude Sonnet 4.5"},"cost":{"total_cost_usd":1.24}}
8889 ```
8990
9091* **Output**: the first non-empty line of standard output, read as UTF-8, up to 200 characters. Markup and links show as plain text. A line wider than the message box ends in "…" and shows in full on hover.
from line 98
9798
9899* **Time limit**: 10 seconds, after which Claude Desktop stops the program and anything it started.
99100
101### Session cost in the status line input
102
103`cost.total_cost_usd` is the session's estimated cost so far. Claude Desktop sends it only while [`inferenceModelPricingEnabled`](https://claude.com/docs/third-party/claude-desktop/configuration#inferencemodelpricingenabled) is on and the session has an estimate. The value is a number in US dollars with up to six decimal places and no exponent. It's for display only and can differ from your provider's bill.
104
105* **Source**: Claude Desktop's own sum for the session, added up on the user's device. It covers Cowork, Chat, and Code sessions, including [Code sessions over SSH](https://claude.com/docs/third-party/claude-desktop/ssh-remote-sessions.md). With no status line set, the built-in "Session cost (estimate)" line above the message box shows the same sum.
106* **Models with no price**: a model ID that can't be matched to a Claude model, such as an opaque gateway alias, adds nothing. After you give that ID a rate in [`inferenceModelPricing`](https://claude.com/docs/third-party/claude-desktop/configuration#inferencemodelpricing), only its later usage counts. The input doesn't show that the sum is partial.
107* **Missing `cost`**: don't show \$0. Check for each of these causes:
108 * `inferenceModelPricingEnabled` is off
109 * The session has no priced estimate yet, such as before Claude Desktop records its first turn's cost or when it has used only models with no price
110 * Claude Desktop [couldn't read its usage ledger](#troubleshoot-a-missing-status-line), the local record of these estimates
111* **Scripts written for Claude Code**: [Claude Code's status line](https://code.claude.com/docs/en/statusline) always sends `cost`, among many other fields. Claude Desktop sends only the fields in the [sample input](#write-the-status-line-program), so check a script that you carry over for other fields and for a fallback to 0. Claude Desktop's sum can also differ from Claude Code's total, for example after `/clear`.
112
113This macOS and Linux script prints the cost. While `cost` is missing it prints nothing, so no line shows:
114
115```sh theme={null}
116#!/bin/sh
117# Prints, for example: Session cost (estimate): $1.24
118LC_ALL=C
119export LC_ALL
120cost=$(sed -n 's/.*"total_cost_usd":\([0-9.]*\).*/\1/p')
121[ -n "$cost" ] || exit 0
122printf 'Session cost (estimate): $%.2f\n' "$cost"
123```
124
100125### Status line scripts on Windows
101126
102127A `.ps1` script runs in Windows PowerShell, not PowerShell 7.
from line 189
164189
165190* A session opens
166191* Claude finishes a turn
192* A turn's result arrives
167193* The user picks another model
168194* The app regains focus
169195
170196There's no timer, so new data shows the next time one of these happens.
171197
198A turn's result closes the turn, and Claude Desktop doesn't add the turn to the [session cost](#session-cost-in-the-status-line-input) until the result arrives. That can be seconds after Claude's answer ends, for example when a [Stop hook](https://code.claude.com/docs/en/hooks#stop) runs first. The program can then run twice for the turn, and the first run's `cost` may not include the turn yet.
199
172200If the program exits with a code other than 0, prints nothing, or takes longer than 10 seconds, the line disappears and the user sees no error. The next successful run brings the line back.
173201
174202## Troubleshoot a missing status line
from line 209
181209 * **macOS and Linux**: code 127 means that a command the script runs wasn't found, so call each tool by its full path
182210 * **Windows**: a `.ps1` script that an [execution policy](#status-line-scripts-on-windows) blocks ends with code 1
183211* **`was stopped after 10 seconds`**: the program hit the [time limit](#write-the-status-line-program). On Windows, a `.ps1` script can be slow to start for a few minutes after a user first opens Claude Desktop, and a `.cmd` or `.exe` file starts faster. If the line appears after a later turn ends or the app regains focus, nothing needs fixing.
212* **`runs without the session's cost`**: Claude Desktop couldn't read its usage ledger, the local record of cost estimates, so the program ran with no `cost` in its input. The entry gives the cause. If `cost` comes back after a later turn ends or the app regains focus, nothing needs fixing.
184213* **No entry**: the program printed nothing, which isn't logged, or the key hasn't reached the app. Restart Claude Desktop and check [which configuration source applies](https://claude.com/docs/third-party/claude-desktop/configuration-format.md#which-configuration-source-applies-on-a-device).
185214
186215To see the program's own error messages, run it in a new terminal window with Claude Desktop's working directory and `PATH`:
from line 218
189218>
190219> ```bash theme={null}
191220> cd /
192> echo '{"session_id":"test"}' | env -i HOME="$HOME" PATH=/usr/bin:/bin:/usr/sbin:/sbin /opt/example/bin/status-line
221> echo '{"session_id":"test","cost":{"total_cost_usd":1.24}}' | env -i HOME="$HOME" PATH=/usr/bin:/bin:/usr/sbin:/sbin /opt/example/bin/status-line
193222> echo "exit code: $?"
194223> ```
195224
from line 230
201230> Set-Location "$env:SystemRoot\System32"
202231> $env:PATH = "$env:SystemRoot\System32;$env:SystemRoot;$env:SystemRoot\System32\WindowsPowerShell\v1.0"
203232> $env:PSModulePath = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\Modules;$env:SystemRoot\System32\WindowsPowerShell\v1.0\Modules"
204> '{"session_id":"test"}' | powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "C:\Program Files\Example\status-line.ps1"
233> '{"session_id":"test","cost":{"total_cost_usd":1.24}}' | powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "C:\Program Files\Example\status-line.ps1"
205234> "exit code: $LASTEXITCODE"
206235> ```
207236
No line in this hunk matches that.