Preserve recovery transcripts and add user-approved agent requests
PR and Push Build/Test / build-and-test (push) Successful in 12m0s

Append successful offline recovery with a duplicate-warning marker and retain failed replay sources. Offer newly available microphones through confirmation notifications.

Add project discovery metadata and blocking association approval, plus nonblocking workflow requests that start a separate settings-agent conversation. Include regression tests, OpenSpec changes, and verified local Release startup.
This commit is contained in:
2026-09-25 11:58:34 +02:00
parent e011e36ef7
commit 7b2bcd3631
50 changed files with 2188 additions and 113 deletions
@@ -3,6 +3,7 @@ namespace MeetingAssistant.Workflow;
public interface IWorkflowRulesEditorWindowService
{
void Show();
void ShowWithPrompt(string initialPrompt);
}
public sealed class NoopWorkflowRulesEditorWindowService : IWorkflowRulesEditorWindowService
@@ -18,4 +19,6 @@ public sealed class NoopWorkflowRulesEditorWindowService : IWorkflowRulesEditorW
{
logger.LogInformation("Workflow rules editor UI is only available on Windows");
}
public void ShowWithPrompt(string initialPrompt) => Show();
}
@@ -25,9 +25,11 @@ public sealed class WorkflowRulesEditorChatViewModel
public event EventHandler? Changed;
public async Task SendAsync(CancellationToken cancellationToken = default)
public Task SendAsync(CancellationToken cancellationToken = default) => SendPromptAsync(Draft, cancellationToken);
public async Task SendPromptAsync(string prompt, CancellationToken cancellationToken = default)
{
var prompt = Draft.Trim();
prompt = prompt.Trim();
if (string.IsNullOrWhiteSpace(prompt) || IsThinking)
{
return;
@@ -37,6 +37,26 @@ internal sealed class WpfWorkflowRulesEditorWindowService : IWorkflowRulesEditor
dispatcher?.BeginInvoke(ShowOnUiThread);
}
public void ShowWithPrompt(string initialPrompt)
{
EnsureUiThread();
dispatcher?.BeginInvoke(new Action(async () =>
{
try
{
var viewModel = services.GetRequiredService<WorkflowRulesEditorChatViewModel>();
var requestedWindow = new WorkflowRulesEditorWpfWindow(viewModel, linkResolver, () => { });
requestedWindow.Show();
requestedWindow.Activate();
await viewModel.SendPromptAsync(initialPrompt);
}
catch (Exception exception)
{
logger.LogError(exception, "Could not start settings agent for an approved workflow request");
}
}));
}
private void EnsureUiThread()
{
lock (sync)