feat: detect host operating system at startup and provide platform-specific guidance

This commit is contained in:
dh
2026-08-06 08:16:55 +02:00
parent 59ba70ca11
commit 13a70c2375
14 changed files with 312 additions and 2 deletions
+26
View File
@@ -0,0 +1,26 @@
namespace MeetingAssistant;
public enum HostOperatingSystemKind
{
Windows,
MacOS,
Unsupported
}
public sealed record HostOperatingSystem(HostOperatingSystemKind Kind)
{
public static HostOperatingSystem DetectCurrent()
{
if (OperatingSystem.IsWindows())
{
return new HostOperatingSystem(HostOperatingSystemKind.Windows);
}
if (OperatingSystem.IsMacOS())
{
return new HostOperatingSystem(HostOperatingSystemKind.MacOS);
}
return new HostOperatingSystem(HostOperatingSystemKind.Unsupported);
}
}
+1
View File
@@ -17,6 +17,7 @@ using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddProvider(new MeetingAssistantFileLoggerProvider());
builder.Services.Configure<MeetingAssistantOptions>(builder.Configuration.GetSection("MeetingAssistant"));
builder.Services.AddSingleton(HostOperatingSystem.DetectCurrent());
builder.Services.AddSingleton<ILaunchProfileOptionsProvider, ConfigurationLaunchProfileOptionsProvider>();
#if WINDOWS
builder.Services.AddSingleton<MicrophoneDeviceSelection>();
@@ -38,10 +38,14 @@ public sealed class WorkflowRulesEditorInstructionBuilder : IWorkflowRulesEditor
Explain the final change briefly after the tools finish.
""";
private readonly HostOperatingSystem hostOperatingSystem;
private readonly ILogger<WorkflowRulesEditorInstructionBuilder> logger;
public WorkflowRulesEditorInstructionBuilder(ILogger<WorkflowRulesEditorInstructionBuilder> logger)
public WorkflowRulesEditorInstructionBuilder(
HostOperatingSystem hostOperatingSystem,
ILogger<WorkflowRulesEditorInstructionBuilder> logger)
{
this.hostOperatingSystem = hostOperatingSystem;
this.logger = logger;
}
@@ -53,8 +57,10 @@ public sealed class WorkflowRulesEditorInstructionBuilder : IWorkflowRulesEditor
: editorOptions.InitialPrompt!;
var rulesPath = WorkflowRulesPathResolver.Resolve(options.Automation.RulesPath) ?? "<not configured>";
var docs = await ReadWorkflowDocsAsync(cancellationToken);
var platformGuidance = BuildPlatformGuidance(hostOperatingSystem);
return configuredPrompt.Trim() + Environment.NewLine + Environment.NewLine +
platformGuidance + Environment.NewLine + Environment.NewLine +
$"Configured workflow rules file: {rulesPath}" + Environment.NewLine + Environment.NewLine +
"Configuration tools can read and replace the local appsettings JSON file. Use read_config_docs for the configuration reference." + Environment.NewLine + Environment.NewLine +
"Log tools can read and search the current application-owned log file and four rotated older files under the temp log folder." + Environment.NewLine + Environment.NewLine +
@@ -69,6 +75,28 @@ public sealed class WorkflowRulesEditorInstructionBuilder : IWorkflowRulesEditor
"```";
}
private static string BuildPlatformGuidance(HostOperatingSystem operatingSystem)
{
var platformGuidance = operatingSystem.Kind switch
{
HostOperatingSystemKind.Windows => """
Detected host operating system: Windows.
Use Windows-native operational guidance: PowerShell and native Windows commands, Windows-style paths, Windows environment-variable conventions, Windows services and processes, and Task Manager. Do not use macOS-only commands or concepts.
""",
HostOperatingSystemKind.MacOS => """
Detected host operating system: macOS.
Use macOS-native operational guidance: zsh and native macOS commands, POSIX-style paths, macOS environment-variable conventions, launchd and LaunchAgents, application processes, and Activity Monitor. Do not use Windows-only commands or concepts.
""",
_ => """
Detected host operating system: unsupported.
Use portable .NET concepts. Do not assume Windows or macOS commands, paths, services, environment conventions, or desktop features.
"""
};
return platformGuidance + Environment.NewLine +
"Prefer the provided Meeting Assistant tools over shell commands when a matching tool exists. Operating-system detection selects appropriate guidance; it does not make unavailable integrations available.";
}
private async Task<string> ReadWorkflowDocsAsync(CancellationToken cancellationToken)
{
foreach (var path in RuntimeContentLocator.CandidateDocumentationPaths("meeting-workflow-engine.md"))