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
15 changes: 8 additions & 7 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,14 @@ cd AdaptiveRemote.Tests && dotnet test
- `Directory.Build.props`: Shared MSBuild properties and package references
- `CONTRIBUTING.md`: Detailed contribution guidelines (see this for full process)
- `version.json`: Nerdbank.GitVersioning configuration
- `AdaptiveRemote/Services/_doc_Services.md`: Living design & architecture notes for Services folder organization and API conventions
- `AdaptiveRemote/Services/Lifecycle/_doc_Lifecycle.md`: Living design & architecture notes for the Lifecycle subsystem
- `AdaptiveRemote/Services/Commands/_doc_Commands.md`: Living design & architecture notes for the Commands subsystem
- `AdaptiveRemote/Services/Broadlink/_doc_Broadlink.md`: Living design & architecture notes for the subsystem that handles IRCommands
- `AdaptiveRemote/Services/Conversation/_doc_Conversation.md`: Living design & architecture notes for the speech recognition and conversation subsystem
- `AdaptiveRemote/Mvvm/_doc_Mvvm.md`: Living design & architecture notes for the MVVM property change notification subsystem
- `AdaptiveRemote/Components/_doc_UI.md`: Living design & architecture notes for the UI subsystem
- `src/_doc_Projects.md`: High-level project organization and boundaries
- `src/AdaptiveRemote/Services/_doc_Services.md`: Living design & architecture notes for Services folder organization and API conventions
- `src/AdaptiveRemote/Services/Lifecycle/_doc_Lifecycle.md`: Living design & architecture notes for the Lifecycle subsystem
- `src/AdaptiveRemote/Services/Commands/_doc_Commands.md`: Living design & architecture notes for the Commands subsystem
- `src/AdaptiveRemote/Services/Broadlink/_doc_Broadlink.md`: Living design & architecture notes for the subsystem that handles IRCommands
- `src/AdaptiveRemote/Services/Conversation/_doc_Conversation.md`: Living design & architecture notes for the speech recognition and conversation subsystem
- `src/AdaptiveRemote/Mvvm/_doc_Mvvm.md`: Living design & architecture notes for the MVVM property change notification subsystem
- `src/AdaptiveRemote/Components/_doc_UI.md`: Living design & architecture notes for the UI subsystem

## Special Considerations
- **Windows-only:** Code cannot be built or tested on Linux/Mac environments
Expand Down
28 changes: 20 additions & 8 deletions AdaptiveRemote.sln
Original file line number Diff line number Diff line change
@@ -1,40 +1,52 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34723.18
# Visual Studio Version 18
VisualStudioVersion = 18.0.11217.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdaptiveRemote.App", "src\AdaptiveRemote.App\AdaptiveRemote.App.csproj", "{6C7C380B-D7A4-412E-8487-2AFC89EA802F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdaptiveRemote", "src\AdaptiveRemote\AdaptiveRemote.csproj", "{7BE31162-0D09-4F80-8CE5-978F7AECC1EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdaptiveRemote.Console", "src\AdaptiveRemote.Console\AdaptiveRemote.Console.csproj", "{345B73FC-07F9-490F-B566-2677D10B1834}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdaptiveRemote.Tests", "test\AdaptiveRemote.Tests\AdaptiveRemote.Tests.csproj", "{99181C45-EACC-45CE-87B3-20A4AA28E793}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdaptiveRemote.App.Tests", "test\AdaptiveRemote.App.Tests\AdaptiveRemote.App.Tests.csproj", "{99181C45-EACC-45CE-87B3-20A4AA28E793}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
CONTRIBUTING.md = CONTRIBUTING.md
Directory.Build.props = Directory.Build.props
README.md = README.md
Directory.Build.props = Directory.Build.Props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdaptiveRemote.Speech.Tests", "test\AdaptiveRemote.Speech.Tests\AdaptiveRemote.Speech.Tests.csproj", "{F00FC7B3-D7EA-4F1A-B8CE-9051E1611D96}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6C7C380B-D7A4-412E-8487-2AFC89EA802F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C7C380B-D7A4-412E-8487-2AFC89EA802F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C7C380B-D7A4-412E-8487-2AFC89EA802F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C7C380B-D7A4-412E-8487-2AFC89EA802F}.Release|Any CPU.Build.0 = Release|Any CPU
{7BE31162-0D09-4F80-8CE5-978F7AECC1EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7BE31162-0D09-4F80-8CE5-978F7AECC1EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7BE31162-0D09-4F80-8CE5-978F7AECC1EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7BE31162-0D09-4F80-8CE5-978F7AECC1EF}.Release|Any CPU.Build.0 = Release|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Release|Any CPU.Build.0 = Release|Any CPU
{345B73FC-07F9-490F-B566-2677D10B1834}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{345B73FC-07F9-490F-B566-2677D10B1834}.Debug|Any CPU.Build.0 = Debug|Any CPU
{345B73FC-07F9-490F-B566-2677D10B1834}.Release|Any CPU.ActiveCfg = Release|Any CPU
{345B73FC-07F9-490F-B566-2677D10B1834}.Release|Any CPU.Build.0 = Release|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99181C45-EACC-45CE-87B3-20A4AA28E793}.Release|Any CPU.Build.0 = Release|Any CPU
{F00FC7B3-D7EA-4F1A-B8CE-9051E1611D96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F00FC7B3-D7EA-4F1A-B8CE-9051E1611D96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F00FC7B3-D7EA-4F1A-B8CE-9051E1611D96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F00FC7B3-D7EA-4F1A-B8CE-9051E1611D96}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ from that directory or through Visual Studio's Test Explorer.
Design documentation
--------------------
Architecture and design notes are stored alongside implementations using `_doc_*.md` filenames so they surface at the top of each folder. See:
- `AdaptiveRemote/Services/_doc_Services.md`: Services folder organization and API conventions
- `AdaptiveRemote/Services/Lifecycle/_doc_Lifecycle.md`: Lifecycle subsystem
- `AdaptiveRemote/Services/Commands/_doc_Commands.md`: Remote control command model subsystem
- `AdaptiveRemote/Services/Broadlink/_doc_Broadlink.md`: Broadlink RM4 mini device driver for handling `IRCommand`
- `AdaptiveRemote/Services/Conversation/_doc_Conversation.md`: Speech recognition and conversation subsystem
- `AdaptiveRemote/Mvvm/_doc_Mvvm.md`: MVVM property change notification subsystem
- `AdaptiveRemote/Components/_doc_UI.md`: Visual user interface subsystem
- `src/_doc_Projects.md`: High-level project organization and boundaries
- `src/AdaptiveRemote/Services/_doc_Services.md`: Services folder organization and API conventions
- `src/AdaptiveRemote/Services/Lifecycle/_doc_Lifecycle.md`: Lifecycle subsystem
- `src/AdaptiveRemote/Services/Commands/_doc_Commands.md`: Remote control command model subsystem
- `src/AdaptiveRemote/Services/Broadlink/_doc_Broadlink.md`: Broadlink RM4 mini device driver for handling `IRCommand`
- `src/AdaptiveRemote/Services/Conversation/_doc_Conversation.md`: Speech recognition and conversation subsystem
- `src/AdaptiveRemote/Mvvm/_doc_Mvvm.md`: MVVM property change notification subsystem
- `src/AdaptiveRemote/Components/_doc_UI.md`: Visual user interface subsystem
49 changes: 49 additions & 0 deletions src/AdaptiveRemote.App/AdaptiveRemote.App.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>AdaptiveRemote</RootNamespace>
<UserSecretsId>e53e63d6-21f1-4896-85e5-7a4831aadbd2</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.2.0" />
<PackageReference Include="I8Beef.TiVo" Version="1.0.0.14" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.22" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.1" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.8.1" />
</ItemGroup>

<ItemGroup>
<Compile Update="Logging\LoggingMessages.Designer.cs">
<DependentUpon>LoggingMessages.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>

<ItemGroup>
<Content Update="wwwroot\css\app.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\css\app.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Logging\LoggingMessages.resx">
<LastGenOutput>LoggingMessages.Designer.cs</LastGenOutput>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using AdaptiveRemote.Configuration;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace AdaptiveRemote;
Expand All @@ -9,7 +8,6 @@ public static class AppHostBuilderExtensions
{
public static IHostBuilder ConfigureApp(this IHostBuilder hostBuilder)
=> hostBuilder
.AddBlazorUI()
.ConfigureTelemetry()
.AddRemoteServices()
.AddBroadlinkSupport()
Expand All @@ -30,13 +28,10 @@ public static IHostBuilder ConfigureAppSettings(this IHostBuilder hostBuilder, s
// to publish telemetry to.
// ["telemetry:Publish"] = "True"
});
config.AddUserSecrets<App>();
config.AddUserSecrets<UserSecretsKey>();
config.AddCommandLine(args);
});

private static IHostBuilder AddBlazorUI(this IHostBuilder hostBuilder)
{
return hostBuilder.ConfigureServices(services => services
.AddWpfBlazorWebView());
}
// This class is used to locate the user secrets assembly for this project.
private class UserSecretsKey { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ internal static IServiceCollection AddConversationServices(this IServiceCollecti
.AddScopedLifecycleService<ConversationController>()
.AddScoped<ISpeechRecognition, SpeechRecognition>()
.AddScoped<ISpeechSynthesis, SpeechSynthesis>()
.AddScoped<IGrammarProvider, StaticGrammarProvider>()
.AddScoped<ConversationStateMachine>()
.AddSingleton<ISpeechSynthesizer, SpeechSynthesizerWrapper>()
.AddSingleton<ISpeechRecognitionEngine, SpeechRecognitionEngineWrapper>()
.AddSingleton<IAudioConfigurationService, DefaultDeviceAudioConfiguration>()
.AddSingleton<IListeningController, ListeningController>()
.AddScoped(GetConversationViewModel);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ internal static IHostBuilder AddRemoteServices(this IHostBuilder builder)

internal static IServiceCollection AddRemoteServices(this IServiceCollection services)
=> services
.AddSingleton<IApplicationScopeFactory, BlazorWindowScopeFactory>()
.AddHostedService<ApplicationLifecycle>()
.AddScopedLifecycleService<LifecycleCommandService>()
.AddScoped<IRemoteDefinitionService, StaticCommandGroupProvider>()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using AdaptiveRemote.Models;
using AdaptiveRemote.Utilities;
using Azure.Identity;
using Azure.Identity;
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Expand Down
9 changes: 9 additions & 0 deletions src/AdaptiveRemote.App/GlobalAttributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Resources;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("AdaptiveRemote.App.Tests")]
[assembly: InternalsVisibleTo("AdaptiveRemote.Speech.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

[assembly: NeutralResourcesLanguage("en-US")]
11 changes: 11 additions & 0 deletions src/AdaptiveRemote.App/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Usage", "CA2254:Template should be a static expression",
Justification = "Error templates are coming from a resource file. They are static expressions, I'm just collecting them there.")]
[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance",
Justification = "Return types are cast to interfaces for future compatibility.")]
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace AdaptiveRemote.Logging;

internal static class ILoggerExtensions
public static class ILoggerExtensions
{
private static readonly IReadOnlyDictionary<Message, string> LoggingMessages = InitializeLoggingMessages();

Expand Down Expand Up @@ -33,7 +33,7 @@ private static string ToMessageText(this Message message)

private static IReadOnlyDictionary<Message, string> InitializeLoggingMessages()
{
System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static;
System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static;
return Enum.GetValues<Message>()
.Select(x => (key: x, value: typeof(LoggingMessages).GetProperty(x.ToString(), flags)?.GetValue(null)))
.Where(x => x.value is not null)
Expand Down
Loading