Improve settings logs agent and renderer
PR and Push Build/Test / build-and-test (push) Successful in 8m13s

This commit is contained in:
2026-06-02 00:09:03 +02:00
parent 11c65ce669
commit e9825f5bf5
11 changed files with 1507 additions and 527 deletions
@@ -704,7 +704,7 @@ public sealed class WorkflowRulesEditorTests
public void MarkdownParserRecognizesRequestedInlineStyles()
{
var inlines = WorkflowRulesEditorMarkdown.ParseInline(
"Normal *italic* **bold** and `code`.");
"Normal *italic* **bold** ***both*** ~~gone~~ [docs](https://example.test) <https://auto.test> <test@example.com> ![logo](C:/tmp/logo.png) and `code`.");
Assert.Equal(
[
@@ -712,6 +712,30 @@ public sealed class WorkflowRulesEditorTests
new WorkflowRulesEditorMarkdownInline("italic", WorkflowRulesEditorMarkdownInlineStyle.Italic),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline("bold", WorkflowRulesEditorMarkdownInlineStyle.Bold),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline("both", WorkflowRulesEditorMarkdownInlineStyle.BoldItalic),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline("gone", WorkflowRulesEditorMarkdownInlineStyle.Strikethrough),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline(
"docs",
WorkflowRulesEditorMarkdownInlineStyle.Link,
"https://example.test"),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline(
"https://auto.test",
WorkflowRulesEditorMarkdownInlineStyle.Link,
"https://auto.test"),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline(
"test@example.com",
WorkflowRulesEditorMarkdownInlineStyle.Link,
"mailto:test@example.com"),
new WorkflowRulesEditorMarkdownInline(" ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline(
"logo",
WorkflowRulesEditorMarkdownInlineStyle.Image,
"C:/tmp/logo.png"),
new WorkflowRulesEditorMarkdownInline(" and ", WorkflowRulesEditorMarkdownInlineStyle.Normal),
new WorkflowRulesEditorMarkdownInline("code", WorkflowRulesEditorMarkdownInlineStyle.Code),
new WorkflowRulesEditorMarkdownInline(".", WorkflowRulesEditorMarkdownInlineStyle.Normal)
@@ -719,6 +743,138 @@ public sealed class WorkflowRulesEditorTests
inlines);
}
[Fact]
public void MarkdownParserRecognizesHeadingsBlockquotesAndCheckboxes()
{
var blocks = WorkflowRulesEditorMarkdown.Parse("""
# Main
## Detail
> quoted **line**
> second
- [x] done
- [ ] open
""");
Assert.Collection(
blocks,
block =>
{
var heading = Assert.IsType<WorkflowRulesEditorMarkdownHeading>(block);
Assert.Equal(1, heading.Level);
Assert.Equal("# Main", Assert.Single(heading.Inlines).Text);
},
block =>
{
var heading = Assert.IsType<WorkflowRulesEditorMarkdownHeading>(block);
Assert.Equal(2, heading.Level);
Assert.Equal("## Detail", Assert.Single(heading.Inlines).Text);
},
block =>
{
var quote = Assert.IsType<WorkflowRulesEditorMarkdownBlockQuote>(block);
Assert.Contains(quote.Inlines, inline => inline.Text.Contains("quoted", StringComparison.Ordinal));
Assert.Contains(quote.Inlines, inline => inline.Style == WorkflowRulesEditorMarkdownInlineStyle.Bold);
},
block =>
{
var tasks = Assert.IsType<WorkflowRulesEditorMarkdownTaskList>(block);
Assert.Collection(
tasks.Items,
item =>
{
Assert.True(item.IsChecked);
Assert.Equal("done", Assert.Single(item.Inlines).Text);
},
item =>
{
Assert.False(item.IsChecked);
Assert.Equal("open", Assert.Single(item.Inlines).Text);
});
});
}
[Fact]
public void MarkdownParserRecognizesStandaloneImageEmbeds()
{
var blocks = WorkflowRulesEditorMarkdown.Parse("""
Before
![Architecture diagram](C:/tmp/architecture.png)
After
""");
Assert.Collection(
blocks,
block => Assert.IsType<WorkflowRulesEditorMarkdownParagraph>(block),
block =>
{
var image = Assert.IsType<WorkflowRulesEditorMarkdownImage>(block);
Assert.Equal("Architecture diagram", image.AltText);
Assert.Equal("C:/tmp/architecture.png", image.Target);
},
block => Assert.IsType<WorkflowRulesEditorMarkdownParagraph>(block));
}
[Fact]
public void MarkdownLinkResolverFindsScreenshotAttachmentsUnderArtifactRoots()
{
var temp = Path.Combine(Path.GetTempPath(), "meeting-assistant-tests", Guid.NewGuid().ToString("N"));
try
{
var contextRoot = Path.Combine(temp, "Meetings", "Assistant Context");
var attachmentPath = Path.Combine(
contextRoot,
"2026",
"06",
"Attachments",
"20260601-120000-001.png");
Directory.CreateDirectory(Path.GetDirectoryName(attachmentPath)!);
File.WriteAllBytes(attachmentPath, [1, 2, 3]);
var resolver = new WorkflowRulesEditorMarkdownLinkResolver([contextRoot], [contextRoot]);
Assert.True(resolver.TryResolveImageUri("Attachments/20260601-120000-001.png", out var uri));
Assert.Equal(new Uri(attachmentPath), uri);
Assert.Equal(attachmentPath, resolver.ResolveOpenTarget("Attachments/20260601-120000-001.png"));
}
finally
{
if (Directory.Exists(temp))
{
Directory.Delete(temp, recursive: true);
}
}
}
[Fact]
public void MarkdownLinkResolverDoesNotCacheMissingFiles()
{
var temp = Path.Combine(Path.GetTempPath(), "meeting-assistant-tests", Guid.NewGuid().ToString("N"));
try
{
var contextRoot = Path.Combine(temp, "Meetings", "Assistant Context");
var attachmentPath = Path.Combine(contextRoot, "Attachments", "late.png");
var resolver = new WorkflowRulesEditorMarkdownLinkResolver([contextRoot], [contextRoot]);
Assert.False(resolver.TryResolveImageUri("Attachments/late.png", out _));
Directory.CreateDirectory(Path.GetDirectoryName(attachmentPath)!);
File.WriteAllBytes(attachmentPath, [1, 2, 3]);
Assert.True(resolver.TryResolveImageUri("Attachments/late.png", out var uri));
Assert.Equal(new Uri(attachmentPath), uri);
}
finally
{
if (Directory.Exists(temp))
{
Directory.Delete(temp, recursive: true);
}
}
}
[Fact]
public void MarkdownParserPreservesParagraphLineBreaks()
{