feat(ui): Bilder aus der Zwischenablage ins interaktive Terminal einfuegen

Ctrl+V mit einem Bild in der Zwischenablage schreibt es als temporaeres
PNG unter ~/.claudeDo/tmp/ und fuegt den Pfad in den Composer ein, genau
wie ein Datei-Drop -- Claude liest die Datei selbst. Text-Paste laeuft
unveraendert ueber den bestehenden bracketed-paste-Pfad.

Avalonia 12.0.4 liest Clipboard-Bitmaps bereits selbst (IClipboard.
TryGetDataAsync + AsyncDataTransferExtensions.TryGetBitmapAsync), kein
Win32-P/Invoke noetig. Alte Tmp-Dateien (>24h) werden beim App-Start
aufgeraeumt (ClaudeDo.App/Program.cs), keine eigene Aufraeum-Infrastruktur.
This commit is contained in:
Mika Kuns
2026-09-16 15:43:38 +02:00
committed by mika kuns
parent 4ff5383b35
commit 56161e4e9b
4 changed files with 145 additions and 3 deletions
@@ -0,0 +1,52 @@
using ClaudeDo.Ui.Services;
namespace ClaudeDo.Ui.Tests.Services;
public class ClipboardImageTempStoreTests : IDisposable
{
private readonly string _dir;
public ClipboardImageTempStoreTests()
{
_dir = Path.Combine(Path.GetTempPath(), "ClaudeDo.Ui.Tests-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(_dir);
}
public void Dispose() { try { Directory.Delete(_dir, true); } catch { } }
[Fact]
public void NewPngPath_IsUniqueAndUnderTheGivenDir()
{
var now = new DateTime(2026, 9, 16, 10, 30, 0, DateTimeKind.Utc);
var a = ClipboardImageTempStore.NewPngPath(_dir, now);
var b = ClipboardImageTempStore.NewPngPath(_dir, now);
Assert.NotEqual(a, b);
Assert.Equal(_dir, Path.GetDirectoryName(a));
Assert.Equal(".png", Path.GetExtension(a));
}
[Fact]
public void DeleteOlderThan_RemovesOnlyFilesPastTheMaxAge()
{
var now = DateTime.UtcNow;
var oldFile = Path.Combine(_dir, "old.png");
var freshFile = Path.Combine(_dir, "fresh.png");
File.WriteAllText(oldFile, "x");
File.WriteAllText(freshFile, "x");
File.SetLastWriteTimeUtc(oldFile, now - TimeSpan.FromHours(25));
File.SetLastWriteTimeUtc(freshFile, now - TimeSpan.FromHours(1));
ClipboardImageTempStore.DeleteOlderThan(_dir, TimeSpan.FromHours(24), now);
Assert.False(File.Exists(oldFile));
Assert.True(File.Exists(freshFile));
}
[Fact]
public void DeleteOlderThan_NonExistentDir_DoesNotThrow()
{
ClipboardImageTempStore.DeleteOlderThan(Path.Combine(_dir, "missing"), TimeSpan.FromHours(24), DateTime.UtcNow);
}
}