diff --git a/CLAUDE.md b/CLAUDE.md index 859af98..2c11aae 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,10 +6,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - Build: `dotnet build AIUsageMonitor.slnx` - Run CLI (binary name is `aimon`): `dotnet run --project src/AIUsageMonitor.Cli -- ` - - Commands: `today`, `week`, `month`, `models`, `sessions`, `hours`, `export` + - Commands: `today`, `week`, `month`, `models`, `sessions`, `hours`, `watch`, `export` + - `watch` takes a sub-view (`today|week|models|sessions|hours`) and refreshes it on an interval - `export` supports `--format json|csv` and `--output ` (defaults to stdout, JSON) - Run WPF app (Windows-only): `dotnet run --project src/AIUsageMonitor.WPF` - Run tests: `dotnet test AIUsageMonitor.slnx` + - Single test: `dotnet test tests/AIUsageMonitor.Core.Tests --filter "FullyQualifiedName~MethodName"` +- Versioning is via MinVer, driven by `v*` git tags (prefix `v`); no manual version bumps in project files. ## Architecture @@ -40,3 +43,7 @@ DI is wired through `ServiceCollectionExtensions.AddClaudeUsageCore()`, which re ### WPF `DashboardViewModel` polls `DataService` on a `DispatcherTimer` (once per minute) and renders daily/model/hourly series via LiveChartsCore, using CommunityToolkit.Mvvm for the MVVM plumbing. + +### Releases + +Pushing a `v*` tag (see `.github/workflows/ci.yml`) builds self-contained CLI binaries for win-x64/linux-x64/osx-x64/osx-arm64, attaches them to a GitHub release (marked pre-release for prerelease tags), and publishes the `aimon` dotnet tool to NuGet. The NuGet publish job runs on `ubuntu` specifically to avoid a `pwsh` glob issue. diff --git a/README.md b/README.md index 68d6f27..5e8b1d6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # AIUsageMonitor +[![CI](https://github.com/coldhighsun/AIUsageMonitor/actions/workflows/ci.yml/badge.svg)](https://github.com/coldhighsun/AIUsageMonitor/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![.NET](https://img.shields.io/badge/.NET-10.0-512BD4?logo=dotnet&logoColor=white)](https://dotnet.microsoft.com/) +[![GitHub release](https://img.shields.io/github/v/release/coldhighsun/AIUsageMonitor?logo=github)](https://github.com/coldhighsun/AIUsageMonitor/releases/latest) +[![GitHub Release Downloads](https://img.shields.io/github/downloads/coldhighsun/AIUsageMonitor/total?logo=github&label=release%20downloads)](https://github.com/coldhighsun/AIUsageMonitor/releases) +[![NuGet Tool Downloads](https://img.shields.io/nuget/dt/AIUsageMonitor.Cli?logo=nuget&label=nuget%20downloads)](https://www.nuget.org/packages/AIUsageMonitor.Cli) [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20cross--platform%20CLI-0078D6?logo=windows&logoColor=white)](#projects) [![GitHub last commit](https://img.shields.io/github/last-commit/coldhighsun/AIUsageMonitor)](https://github.com/coldhighsun/AIUsageMonitor/commits/main) -[![GitHub stars](https://img.shields.io/github/stars/coldhighsun/AIUsageMonitor?style=flat)](https://github.com/coldhighsun/AIUsageMonitor/stargazers) -[![GitHub issues](https://img.shields.io/github/issues/coldhighsun/AIUsageMonitor)](https://github.com/coldhighsun/AIUsageMonitor/issues) -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md) [English](#english) | [中文](#chinese) diff --git a/src/AIUsageMonitor.Cli/AIUsageMonitor.Cli.csproj b/src/AIUsageMonitor.Cli/AIUsageMonitor.Cli.csproj index 413dc99..233e1a0 100644 --- a/src/AIUsageMonitor.Cli/AIUsageMonitor.Cli.csproj +++ b/src/AIUsageMonitor.Cli/AIUsageMonitor.Cli.csproj @@ -33,6 +33,7 @@ https://github.com/coldhighsun/AIUsageMonitor MIT README.md + claude;claude-code;anthropic;cli;usage;analytics;dotnet-tool;tokens;cost diff --git a/src/AIUsageMonitor.Cli/Rendering/SpectreRenderer.cs b/src/AIUsageMonitor.Cli/Rendering/SpectreRenderer.cs index 6e65eb5..0209b81 100644 --- a/src/AIUsageMonitor.Cli/Rendering/SpectreRenderer.cs +++ b/src/AIUsageMonitor.Cli/Rendering/SpectreRenderer.cs @@ -23,7 +23,7 @@ public static IRenderable BuildDailySummary(DailySummary summary) return table; } - var chart = new BarChart().Label("[bold]Tokens by Model[/]").Width(80).UseValueFormatter(v => ((long)v).ToString("N0")); + var chart = new BarChart().Label("[bold]Tokens by Model[/]").Width(80).UseValueFormatter(v => FormatTokens((long)v)); var colorIndex = 0; var colors = new[] { Color.Blue, Color.Green, Color.Yellow, Color.Red, Color.Purple, Color.Orange1, Color.Cyan1 }; foreach (var (model, tokens) in summary.TokensByModel.OrderByDescending(x => x.Value)) @@ -51,7 +51,7 @@ public static IRenderable BuildPeriodSummary(PeriodSummary summary) return table; } - var chart = new BarChart().Label("[bold]Daily Tokens[/]").Width(80).UseValueFormatter(v => ((long)v).ToString("N0")); + var chart = new BarChart().Label("[bold]Daily Tokens[/]").Width(80).UseValueFormatter(v => FormatTokens((long)v)); var colorIndex = 0; foreach (var day in summary.DailyBreakdown) { @@ -115,7 +115,7 @@ public static IRenderable BuildSessionStats(SessionStats stats) public static IRenderable BuildHourlyActivity(List hours) { - var chart = new BarChart().Label("[bold]Tokens by Hour[/]").Width(80).UseValueFormatter(v => ((long)v).ToString("N0")); + var chart = new BarChart().Label("[bold]Tokens by Hour[/]").Width(80).UseValueFormatter(v => FormatTokens((long)v)); var colorIndex = 0; foreach (var h in hours) { @@ -127,7 +127,7 @@ public static IRenderable BuildHourlyActivity(List hours) public static IRenderable BuildHourlyTokenChart(List buckets) { - var chart = new BarChart().Label("[bold]Tokens by Hour[/]").Width(80).UseValueFormatter(v => ((long)v).ToString("N0")); + var chart = new BarChart().Label("[bold]Tokens by Hour[/]").Width(80).UseValueFormatter(v => FormatTokens((long)v)); var colorIndex = 0; foreach (var bucket in buckets) { diff --git a/src/AIUsageMonitor.WPF/ViewModels/DashboardViewModel.cs b/src/AIUsageMonitor.WPF/ViewModels/DashboardViewModel.cs index ca41a0e..60ab32d 100644 --- a/src/AIUsageMonitor.WPF/ViewModels/DashboardViewModel.cs +++ b/src/AIUsageMonitor.WPF/ViewModels/DashboardViewModel.cs @@ -139,7 +139,7 @@ private void BuildHourlyChart(List hours) HourlyYAxes = [ - new() { Labeler = value => value.ToString("N0") } + new() { Labeler = value => FormatTokens((long)value) } ]; }