Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
331f9c2
Add aspire monitor TUI command (PoC)
Feb 9, 2026
1f00019
Suppress CS8002 strong name warning for Hex1b
Feb 9, 2026
60b0bfa
Use TableWidget for Resources and Parameters tabs
Feb 9, 2026
1b8a198
Add Aspire brand color theme and wrap app in ThemePanel
Feb 9, 2026
e89f66e
Set resource and parameter tables to Full render mode
Feb 9, 2026
0e1015f
Add keyboard row selection to resource and parameter tables
Feb 9, 2026
340c655
Add Actions column with start/stop/restart buttons
Feb 9, 2026
0ff0322
Replace drawer with resizable HSplitter for AppHost list
Feb 9, 2026
888a40c
Add animated pixel splash screen with Aspire logo
Feb 9, 2026
8ca9886
Make splash surface fill the entire terminal
Feb 9, 2026
4fff92d
Slow down splash animation and hold logo longer before transition
Feb 9, 2026
a8204a3
Add dissolve exit animation with braille particles, gravity, and bounce
Feb 9, 2026
f80872c
Fix edge pixel white bleed and extend dissolve/fall duration
Feb 9, 2026
678f8aa
Add AppHost discovery polling, offline detection, and notifications
Feb 9, 2026
5c12814
Fix reconnection: update stale connection and auto-reconnect selected…
Feb 9, 2026
56dbd35
Rework splash: braille whirlwind in → crossfade to half-blocks → melt
Feb 9, 2026
f5fe59e
Remove half-block animation phases, use braille throughout
Feb 9, 2026
89bbb2e
Refine theme: lighter purple focused borders, white-on-purple info bar
Feb 9, 2026
446aa54
Add resource console log panel with embedded terminal
Feb 9, 2026
ee4eaad
Use single DragBarPanel for log terminal only
Feb 9, 2026
6baedd2
Move drag bar above terminal: table in DragBarPanel, terminal fills b…
Feb 9, 2026
64bc5df
Add heart/broken heart icons to Health column based on status
Feb 9, 2026
b66922d
Add E2E test for aspire monitor command
Feb 9, 2026
7eb961c
Show waiting panel when no AppHosts are running
Feb 9, 2026
50ab1a9
Render resource URLs as clickable HyperlinkWidgets
Feb 9, 2026
89d13f4
Add hack reveal transition between splash and main TUI
Feb 9, 2026
609a106
Fix crash: skip NotificationPanel during reveal phase
Feb 9, 2026
d2cf25f
Fix hack reveal: remove stale Update(1,1) that reset cells every frame
Feb 9, 2026
19722ca
Make hack reveal react to streaming content updates
Feb 9, 2026
d8e3826
Fix reveal flickering: restore two-phase capture then reveal
Feb 9, 2026
aa9abc3
Enable Hex1b diagnostics on the monitor TUI
Feb 9, 2026
1a2d271
Force-enable Hex1b diagnostics in all build configurations
Feb 9, 2026
ee06daf
Update Hex1b packages to 0.79.0
Feb 11, 2026
fe51656
Add DragBarPanel for logs, PID in header, repo root discovery with wo…
Feb 12, 2026
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
6 changes: 3 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@
<PackageVersion Include="Grpc.AspNetCore" Version="2.71.0" />
<PackageVersion Include="Grpc.Net.ClientFactory" Version="2.71.0" />
<PackageVersion Include="Grpc.Tools" Version="2.72.0" />
<PackageVersion Include="Hex1b" Version="0.78.0" />
<PackageVersion Include="Hex1b.McpServer" Version="0.78.0" />
<PackageVersion Include="Hex1b.Tool" Version="0.78.0" />
<PackageVersion Include="Hex1b" Version="0.83.0" />
<PackageVersion Include="Hex1b.McpServer" Version="0.83.0" />
<PackageVersion Include="Hex1b.Tool" Version="0.83.0" />
<PackageVersion Include="Humanizer.Core" Version="2.14.1" />
<PackageVersion Include="KubernetesClient" Version="18.0.5" />
<PackageVersion Include="JsonPatch.Net" Version="3.3.0" />
Expand Down
15 changes: 14 additions & 1 deletion src/Aspire.Cli/Aspire.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<EnablePackageValidation>false</EnablePackageValidation>
<AssemblyName>aspire</AssemblyName>
<RootNamespace>Aspire.Cli</RootNamespace>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<NoWarn>$(NoWarn);CS1591;CS8002</NoWarn>
<PublishAot>true</PublishAot>
<OptimizationPreference>Size</OptimizationPreference>
<DefineConstants>$(DefineConstants);CLI</DefineConstants>
Expand Down Expand Up @@ -38,6 +38,7 @@

<ItemGroup>
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" />
<PackageReference Include="Hex1b" />
<PackageReference Include="Spectre.Console" />
<PackageReference Include="System.CommandLine" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" />
Expand Down Expand Up @@ -163,6 +164,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>McpCommandStrings.resx</DependentUpon>
</Compile>
<Compile Update="Resources\MonitorCommandStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MonitorCommandStrings.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -258,5 +264,12 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>McpCommandStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Resources\MonitorCommandStrings.resx">
<XlfSourceFormat>Resx</XlfSourceFormat>
<XlfOutputItem>EmbeddedResource</XlfOutputItem>
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>MonitorCommandStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
21 changes: 21 additions & 0 deletions src/Aspire.Cli/Backchannel/AppHostAuxiliaryBackchannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,27 @@ public async Task<CallToolResult> CallResourceMcpToolAsync(
cancellationToken).ConfigureAwait(false);
}

/// <inheritdoc />
public async Task<IAsyncEnumerable<BackchannelLogEntry>?> GetAppHostLogEntriesAsync(CancellationToken cancellationToken = default)
{
var rpc = EnsureConnected();

_logger?.LogDebug("Requesting AppHost log entries");

try
{
return await rpc.InvokeWithCancellationAsync<IAsyncEnumerable<BackchannelLogEntry>>(
"GetAppHostLogEntriesAsync",
[],
cancellationToken).ConfigureAwait(false);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_logger?.LogDebug(ex, "AppHost log streaming is not available. The AppHost may be running an older version.");
return null;
}
}

#region V2 API Methods

/// <summary>
Expand Down
6 changes: 6 additions & 0 deletions src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,10 @@
string status,
int timeoutSeconds,
CancellationToken cancellationToken = default);
/// Gets AppHost log entries streamed from the hosting process.
/// Returns null if the AppHost does not support log streaming.
/// </summary>

Check failure on line 138 in src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire (Build Linux)

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs#L138

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs(138,9): error CS1570: (NETCORE_ENGINEERING_TELEMETRY=Build) XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check failure on line 138 in src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire (Build Linux)

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs#L138

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs(138,9): error CS1570: (NETCORE_ENGINEERING_TELEMETRY=Build) XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check failure on line 138 in src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire (Build Linux)

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs#L138

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs(138,9): error CS1570: (NETCORE_ENGINEERING_TELEMETRY=Build) XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check failure on line 138 in src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs#L138

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs(138,9): error CS1570: (NETCORE_ENGINEERING_TELEMETRY=Build) XML comment has badly formed XML -- 'End tag was not expected at this location.'

Check failure on line 138 in src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs#L138

src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs(138,9): error CS1570: (NETCORE_ENGINEERING_TELEMETRY=Build) XML comment has badly formed XML -- 'End tag was not expected at this location.'
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>An async enumerable of log entries, or null if not supported.</returns>
Task<IAsyncEnumerable<BackchannelLogEntry>?> GetAppHostLogEntriesAsync(CancellationToken cancellationToken = default);
}
44 changes: 44 additions & 0 deletions src/Aspire.Cli/Commands/AtopCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.CommandLine;
using Aspire.Cli.Backchannel;
using Aspire.Cli.Configuration;
using Aspire.Cli.Interaction;
using Aspire.Cli.Resources;
using Aspire.Cli.Telemetry;
using Aspire.Cli.UI;
using Aspire.Cli.Utils;
using Microsoft.Extensions.Logging;

namespace Aspire.Cli.Commands;

internal sealed class AtopCommand : BaseCommand
{
private readonly IAuxiliaryBackchannelMonitor _backchannelMonitor;
private readonly ILogger<AtopCommand> _logger;

public AtopCommand(
IInteractionService interactionService,
IAuxiliaryBackchannelMonitor backchannelMonitor,
IFeatures features,
ICliUpdateNotifier updateNotifier,
CliExecutionContext executionContext,
AspireCliTelemetry telemetry,
ILogger<AtopCommand> logger)
: base("atop", MonitorCommandStrings.Description, features, updateNotifier, executionContext, interactionService, telemetry)
{
_backchannelMonitor = backchannelMonitor;
_logger = logger;
}

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
{
using var activity = Telemetry.StartDiagnosticActivity(Name);

var tui = new AspireAtopTui(_backchannelMonitor, _logger);
await tui.RunAsync(cancellationToken).ConfigureAwait(false);

return ExitCodeConstants.Success;
}
}
7 changes: 7 additions & 0 deletions src/Aspire.Cli/Commands/RootCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@
DocsCommand docsCommand,
SdkCommand sdkCommand,
SetupCommand setupCommand,
MonitorCommand monitorCommand,

Check failure on line 133 in src/Aspire.Cli/Commands/RootCommand.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire (Build Linux)

src/Aspire.Cli/Commands/RootCommand.cs#L133

src/Aspire.Cli/Commands/RootCommand.cs(133,9): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'MonitorCommand' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 133 in src/Aspire.Cli/Commands/RootCommand.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire (Build Linux)

src/Aspire.Cli/Commands/RootCommand.cs#L133

src/Aspire.Cli/Commands/RootCommand.cs(133,9): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'MonitorCommand' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 133 in src/Aspire.Cli/Commands/RootCommand.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire

src/Aspire.Cli/Commands/RootCommand.cs#L133

src/Aspire.Cli/Commands/RootCommand.cs(133,9): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'MonitorCommand' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 133 in src/Aspire.Cli/Commands/RootCommand.cs

View check run for this annotation

Azure Pipelines / dotnet.aspire

src/Aspire.Cli/Commands/RootCommand.cs#L133

src/Aspire.Cli/Commands/RootCommand.cs(133,9): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'MonitorCommand' could not be found (are you missing a using directive or an assembly reference?)
AtopCommand atopCommand,
ExtensionInternalCommand extensionInternalCommand,
IFeatures featureFlags,
IInteractionService interactionService)
Expand Down Expand Up @@ -220,5 +222,10 @@
Subcommands.Add(sdkCommand);
}

if (featureFlags.IsFeatureEnabled(KnownFeatures.MonitorCommandEnabled, false))
{
Subcommands.Add(atopCommand);
}

}
}
8 changes: 7 additions & 1 deletion src/Aspire.Cli/KnownFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ internal static class KnownFeatures
public static string ExperimentalPolyglotPython => "experimentalPolyglot:python";
public static string DotNetSdkInstallationEnabled => "dotnetSdkInstallationEnabled";
public static string RunningInstanceDetectionEnabled => "runningInstanceDetectionEnabled";
public static string MonitorCommandEnabled => "monitorCommandEnabled";

private static readonly Dictionary<string, FeatureMetadata> s_featureMetadata = new()
{
Expand Down Expand Up @@ -112,7 +113,12 @@ internal static class KnownFeatures
[RunningInstanceDetectionEnabled] = new(
RunningInstanceDetectionEnabled,
"Enable or disable detection of already running Aspire instances to prevent conflicts",
DefaultValue: true)
DefaultValue: true),

[MonitorCommandEnabled] = new(
MonitorCommandEnabled,
"Enable or disable the 'aspire atop' command for launching a TUI to monitor running AppHosts and resources",
DefaultValue: false)
};

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Aspire.Cli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ internal static async Task<IHost> BuildApplicationAsync(string[] args, Dictionar
builder.Services.AddTransient<SdkGenerateCommand>();
builder.Services.AddTransient<SdkDumpCommand>();
builder.Services.AddTransient<SetupCommand>();
builder.Services.AddTransient<MonitorCommand>();
builder.Services.AddTransient<AtopCommand>();
builder.Services.AddTransient<RootCommand>();
builder.Services.AddTransient<ExtensionInternalCommand>();

Expand Down
114 changes: 114 additions & 0 deletions src/Aspire.Cli/Resources/MonitorCommandStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading