Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/AIUsageMonitor.Cli/Commands/ExportCommand.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
using System.CommandLine;
using System.Text.Json;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Models;
using AIUsageMonitor.Core.Providers.Claude.Models;
using AIUsageMonitor.Core.Services;
using Spectre.Console;
using System.CommandLine;
using System.Text.Json;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the "export" command for exporting usage data in JSON or CSV format. This command retrieves usage statistics and model distribution data from the provided <see cref="DataService"/> and outputs it to a specified file or standard output.
/// </summary>
public static class ExportCommand
{
/// <summary>
/// Creates a new instance of the "export" command with the specified <see cref="DataService"/>. The command supports options for specifying the output format (JSON or CSV) and the output file path. If no output file is specified, the data will be printed to standard output.
/// </summary>
/// <param name="dataService">The data service used to retrieve usage statistics and model distribution data.</param>
/// <returns>A configured <see cref="Command"/> instance for exporting usage data.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("export", "Export usage data");
Expand Down Expand Up @@ -58,6 +66,12 @@ public static Command Create(DataService dataService)
return command;
}

/// <summary>
/// Exports the usage data and model distribution to a CSV formatted string. The CSV includes daily activity statistics and model distribution details, with appropriate headers for each section.
/// </summary>
/// <param name="cache">The cached usage statistics to export.</param>
/// <param name="models">The model distribution data to export.</param>
/// <returns>A CSV formatted string representing the usage data and model distribution.</returns>
private static string ExportCsv(
StatsCache cache,
List<ModelDistribution> models)
Expand All @@ -78,4 +92,4 @@ private static string ExportCsv(

return sb.ToString();
}
}
}
8 changes: 8 additions & 0 deletions src/AIUsageMonitor.Cli/Commands/HoursCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the "hours" command, which shows the hourly activity distribution of AI usage. This command retrieves hourly activity data from the provided <see cref="DataService"/> and renders it using the <see cref="SpectreRenderer"/>.
/// </summary>
public static class HoursCommand
{
/// <summary>
/// Creates a new instance of the "hours" command with the specified <see cref="DataService"/>. The command retrieves hourly activity data and renders it using the <see cref="SpectreRenderer"/>.
/// </summary>
/// <param name="dataService">The data service used to retrieve hourly activity data.</param>
/// <returns>A configured <see cref="Command"/> instance for showing hourly activity distribution.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("hours", "Show hourly activity distribution");
Expand Down
10 changes: 9 additions & 1 deletion src/AIUsageMonitor.Cli/Commands/ModelsCommand.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
using System.CommandLine;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Services;
using System.CommandLine;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the command for displaying model usage distribution in the AI Usage Monitor CLI application.
/// </summary>
public static class ModelsCommand
{
/// <summary>
/// Creates a new instance of the "models" command, which shows the model usage distribution.
/// </summary>
/// <param name="dataService">The data service used to retrieve model usage data.</param>
/// <returns>A configured <see cref="Command"/> instance for showing model usage distribution.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("models", "Show model usage distribution");
Expand Down
10 changes: 9 additions & 1 deletion src/AIUsageMonitor.Cli/Commands/MonthCommand.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
using System.CommandLine;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Services;
using System.CommandLine;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the command to show the last 30 days summary of AI usage.
/// </summary>
public static class MonthCommand
{
/// <summary>
/// Creates a new instance of the MonthCommand.
/// </summary>
/// <param name="dataService">The data service used to retrieve AI usage data.</param>
/// <returns>A configured <see cref="Command"/> instance for showing the last 30 days summary of AI usage.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("month", "Show last 30 days summary");
Expand Down
10 changes: 9 additions & 1 deletion src/AIUsageMonitor.Cli/Commands/SessionsCommand.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
using System.CommandLine;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Services;
using System.CommandLine;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the command for displaying session statistics in the AI Usage Monitor CLI application.
/// </summary>
public static class SessionsCommand
{
/// <summary>
/// Creates a new instance of the "sessions" command, which displays session statistics.
/// </summary>
/// <param name="dataService">The data service used to retrieve session statistics.</param>
/// <returns>A configured <see cref="Command"/> instance for showing session statistics.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("sessions", "Show session statistics");
Expand Down
12 changes: 10 additions & 2 deletions src/AIUsageMonitor.Cli/Commands/TodayCommand.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
using System.CommandLine;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Services;
using Spectre.Console;
using System.CommandLine;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the "today" command in the CLI application, which shows today's usage summary.
/// </summary>
public static class TodayCommand
{
/// <summary>
/// Creates a new instance of the "today" command with the specified data service.
/// </summary>
/// <param name="dataService">The data service used to retrieve today's usage summary and recent activity.</param>
/// <returns>A configured <see cref="Command"/> instance for showing today's usage summary.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("today", "Show today's usage summary");
Expand Down Expand Up @@ -39,4 +47,4 @@ public static Command Create(DataService dataService)
});
return command;
}
}
}
12 changes: 10 additions & 2 deletions src/AIUsageMonitor.Cli/Commands/WatchCommand.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
using System.CommandLine;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Services;
using Spectre.Console;
using Spectre.Console.Rendering;
using System.CommandLine;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the "watch" command, which continuously refreshes a usage view at a fixed interval.
/// </summary>
public static class WatchCommand
{
/// <summary>
/// Creates the "watch" command with its options and action.
/// </summary>
/// <param name="dataService">The data service used to retrieve usage data for the specified view.</param>
/// <returns>A configured <see cref="Command"/> instance for continuously refreshing a usage view.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("watch", "Continuously refresh a usage view at a fixed interval");
Expand Down Expand Up @@ -79,4 +87,4 @@ await AnsiConsole.Live(initial)

return command;
}
}
}
10 changes: 9 additions & 1 deletion src/AIUsageMonitor.Cli/Commands/WeekCommand.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
using System.CommandLine;
using AIUsageMonitor.Cli.Rendering;
using AIUsageMonitor.Core.Services;
using System.CommandLine;

namespace AIUsageMonitor.Cli.Commands;

/// <summary>
/// Represents the "week" command that shows a summary of usage data for the last 7 days.
/// </summary>
public static class WeekCommand
{
/// <summary>
/// Creates a new instance of the "week" command.
/// </summary>
/// <param name="dataService">The data service used to retrieve usage data for the last 7 days.</param>
/// <returns>A configured <see cref="Command"/> instance for showing the last 7 days summary.</returns>
public static Command Create(DataService dataService)
{
var command = new Command("week", "Show last 7 days summary");
Expand Down
2 changes: 1 addition & 1 deletion src/AIUsageMonitor.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
{
AnsiConsole.MarkupLine($"[red]Fatal error: {ex.Message}[/]");
return 1;
}
}
19 changes: 15 additions & 4 deletions src/AIUsageMonitor.Cli/Rendering/ProgressReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@

namespace AIUsageMonitor.Cli.Rendering;

/// <summary>
/// Provides a utility for running a task with a progress bar in the console using Spectre.Console.
/// </summary>
public static class ProgressReporter
{
/// <summary>
/// Runs a task with a progress bar in the console.
/// </summary>
/// <typeparam name="T">The type of the result produced by the task.</typeparam>
/// <param name="description">A description of the task to be displayed in the progress bar.</param>
/// <param name="body">A function that performs the task and reports progress.</param>
/// <returns>The result produced by the task.</returns>
public static T Run<T>(string description, Func<IProgress<int>, T> body)
{
var result = default(T)!;
Expand All @@ -17,11 +27,12 @@ public static T Run<T>(string description, Func<IProgress<int>, T> body)
return result;
}

// System.Progress<T> marshals callbacks through the captured SynchronizationContext (or the
// thread pool if there is none), which would race with Spectre's render loop in a console app.
// Report synchronously on the calling thread instead so the progress bar updates in step.
/// <summary>
/// A private implementation of IProgress&lt;int&gt; that reports progress synchronously to a provided action.
/// </summary>
/// <param name="onReport">The action to be invoked when progress is reported.</param>
private sealed class SynchronousProgress(Action<int> onReport) : IProgress<int>
{
public void Report(int value) => onReport(value);
}
}
}
Loading
Loading