diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..5051114 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,81 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract version from tag + id: version + run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + + - name: Build source archives + run: | + PROJECT="claude-statusline-${{ steps.version.outputs.VERSION }}" + + # Files to include in the release archives + INCLUDE=( + statusline.js + fetch-usage.js + install.sh + install.ps1 + install_wizard.py + package.json + requirements.txt + README.md + CHANGELOG.md + LICENSE + .gitattributes + claude_usage_widget/__init__.py + claude_usage_widget/__main__.py + claude_usage_widget/app.py + claude_usage_widget/config.py + claude_usage_widget/fetcher.py + claude_usage_widget/menu.py + claude_usage_widget/renderer.py + ) + + mkdir -p "dist/${PROJECT}/claude_usage_widget" + + for f in "${INCLUDE[@]}"; do + [ -f "$f" ] && cp "$f" "dist/${PROJECT}/$f" + done + + # tar.gz for Linux / macOS + tar -czf "dist/${PROJECT}.tar.gz" -C dist "${PROJECT}" + + # zip for Windows + cd dist && zip -r "${PROJECT}.zip" "${PROJECT}" && cd .. + + - name: Create release and upload assets + env: + TAG: ${{ github.ref_name }} + VERSION: ${{ steps.version.outputs.VERSION }} + TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITEA_URL: ${{ github.server_url }} + REPO: ${{ github.repository }} + run: | + API="${GITEA_URL}/api/v1/repos/${REPO}" + + # Create the release + RELEASE_ID=$(curl -s -X POST "${API}/releases" \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\",\"body\":\"See [CHANGELOG.md](CHANGELOG.md) for details.\",\"draft\":false,\"prerelease\":false}" \ + | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") + + # Upload archives + for file in dist/claude-statusline-${VERSION}.tar.gz dist/claude-statusline-${VERSION}.zip; do + FILENAME=$(basename "$file") + curl -s -X POST "${API}/releases/${RELEASE_ID}/assets?name=${FILENAME}" \ + -H "Authorization: token ${TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@${file}" + done diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9578c3d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). + +## [0.2.0] — 2026-02-26 + +First tagged release. Includes the CLI statusline, standalone usage fetcher, cross-platform desktop widget, and installer wizard. + +### Added +- **CLI Statusline** — headless status bar for Claude Code showing context window and token usage as text progress bars +- **Usage Fetcher** — standalone Node.js cron job that fetches token usage from the Claude API and writes a shared JSON cache +- **Desktop Widget** — cross-platform system tray icon (pystray) with circular progress bar, Claude starburst logo, and color-coded usage severity +- **Installer Wizard** — interactive Python installer (`install_wizard.py`) with platform detection, component selection, cron/autostart setup, and session key configuration +- **Windows support** — PowerShell installer wrapper (`install.ps1`) and Windows-compatible paths +- **Session expiry warning** — statusline shows a warning when the session key is about to expire + +### Fixed +- CRLF line ending issues on cross-platform installs +- Tray icon visibility — switched to Claude orange with full opacity at larger size +- Block comment syntax error in cron example + +[0.2.0]: https://git.davoryn.de/calic/claude-statusline/releases/tag/v0.2.0 diff --git a/README.md b/README.md index 42d84a6..865c77a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,24 @@ -# claude-statusline +

claude-statusline

-Monitor your Claude API usage — as a **CLI statusline** on headless servers or a **system tray widget** on desktop machines. +

+ Monitor your Claude API usage — as a CLI statusline or a system tray widget +

+ +

+ Node.js 18+ + Python 3.9+ + Platform: Linux | macOS | Windows + MIT License +
+ Releases +

+ +--- + +## Overview Both components share the same session key and fetcher logic. Install one or both depending on your setup. -## Components - ### CLI Statusline (Node.js) A headless-friendly status bar for Claude Code. Shows context window utilization and token usage as text progress bars, piped into the Claude Code statusline slot. @@ -24,30 +37,28 @@ Cross-platform system tray icon that shows the 5-hour usage window as a circular ## Topology -``` - claude.ai API - | - ┌────────────┴────────────┐ - | | - fetch-usage.js claude_usage_widget/ - (cron, Node.js) fetcher.py thread - | (Python, urllib) - | | - └────────┬────────────────┘ - v - /tmp/claude_usage.json - (shared cache) - ┌────────┴────────────────┐ - | | - statusline.js claude_usage_widget/ - (Claude Code) app.py (pystray) - | | - v v - Claude Code System tray icon - status bar + right-click menu +```mermaid +graph TD + API["claude.ai API"] + FetchJS["fetch-usage.js
(cron / Node.js)"] + FetchPy["fetcher.py thread
(Python / urllib)"] + Cache["/tmp/claude_usage.json
(shared cache)"] + SL["statusline.js
(Claude Code)"] + Widget["app.py
(pystray tray icon)"] + CC["Claude Code status bar"] + Tray["System tray icon
+ right-click menu"] + SK["~/.config/claude-statusline/session-key"] - Shared: ~/.config/claude-statusline/session-key - /tmp/claude_usage.json + API --> FetchJS + API --> FetchPy + FetchJS --> Cache + FetchPy --> Cache + Cache --> SL + Cache --> Widget + SL --> CC + Widget --> Tray + SK -.->|auth| FetchJS + SK -.->|auth| FetchPy ``` Only one fetcher needs to run. Either `fetch-usage.js` (via cron) or the widget's built-in fetcher thread writes to the shared cache at `/tmp/claude_usage.json`. Both consumers read from it: @@ -59,23 +70,58 @@ If both fetchers happen to run, they write the same format — last writer wins, ## Installation -Run the installer and follow the wizard: +### Quick Install (from release) + +Download the latest archive from the [Releases page](https://git.davoryn.de/calic/claude-statusline/releases) for your platform: + +| Platform | Download | Install | +|----------|----------|---------| +| **Linux** | `.tar.gz` source archive | Extract, then `bash install.sh` | +| **macOS** | `.tar.gz` source archive | Extract, then `bash install.sh` | +| **Windows** | `.zip` source archive | Extract, then run `install.ps1` (see [Windows Quick Start](#windows-quick-start) below) | + +> **Planned:** Native installers (`.deb`, `.msi`) are on the roadmap. For now, releases contain source archives. + +### Developer Install (from source) + +Clone the repository and run the installer wizard: **Linux / macOS:** ```bash +git clone https://git.davoryn.de/calic/claude-statusline.git +cd claude-statusline bash install.sh ``` **Windows (PowerShell):** ```powershell +git clone https://git.davoryn.de/calic/claude-statusline.git +cd claude-statusline powershell -ExecutionPolicy Bypass -File install.ps1 ``` -The wizard will: -1. Ask which components to install (CLI statusline, desktop widget, or both) -2. Guide you through session key setup -3. Configure autostart (widget) or cron (CLI fetcher) as applicable -4. Set up the Claude Code statusline integration +### What the wizard does + +1. Asks which components to install (CLI statusline, desktop widget, or both) +2. Guides you through session key setup +3. Configures autostart (widget) or cron (CLI fetcher) as applicable +4. Sets up the Claude Code statusline integration + +### Windows Quick Start + +If you're new to the command line, follow these steps: + +1. Go to the [Releases page](https://git.davoryn.de/calic/claude-statusline/releases) and download the latest `.zip` file +2. Extract the zip to any folder (e.g. `C:\Users\YourName\claude-statusline`) +3. Open the extracted folder in File Explorer +4. Right-click `install.ps1` and select **Run with PowerShell** + - If you see a security prompt, choose **Run anyway** or **Open** + - Alternatively, open PowerShell manually and run: + ```powershell + powershell -ExecutionPolicy Bypass -File install.ps1 + ``` +5. The wizard will walk you through component selection and session key setup +6. To find your session key, see [Session Key](#session-key) below ### Prerequisites @@ -87,11 +133,26 @@ The wizard will: ## Session Key -Both components authenticate via a session cookie from claude.ai: +Both components authenticate via a session cookie from claude.ai. + +```mermaid +sequenceDiagram + participant User + participant Browser + participant Installer + participant Config + + User->>Browser: Log into claude.ai + User->>Browser: DevTools → Cookies → sessionKey + User->>Installer: Paste session key when prompted + Installer->>Config: ~/.config/claude-statusline/session-key +``` + +**Step by step:** 1. Log into [claude.ai](https://claude.ai) in any browser -2. Open DevTools → Application → Cookies → `claude.ai` -3. Copy the value of the `sessionKey` cookie (starts with `sk-ant-`) +2. Open DevTools (press `F12`), go to **Application** → **Cookies** → `https://claude.ai` +3. Copy the value of the `sessionKey` cookie (it starts with `sk-ant-`) 4. The installer will prompt you to enter it, or set it manually: ```bash @@ -142,6 +203,15 @@ The tray icon arc color indicates usage severity at 10% increments: | 80–90% | Deep orange | | 90–100% | Red | +## Releases + +Tagged releases are published on [Gitea](https://git.davoryn.de/calic/claude-statusline/releases) following semver (`v0.2.0`, `v0.3.0`, etc.). Each release includes per-OS source archives. + +**Planned future additions:** +- `.deb` package for Debian/Ubuntu +- `.msi` / `.exe` installer for Windows +- Homebrew tap for macOS + ## Project Structure ```