Report UI issues with the evidence attached
Mark a problem on a captured screenshot and preserve feedback and UI structure together in your .NET Debug build.
Annotated feedback freezes a screenshot and registered visual trees before opening the native editor. A tester can draw on the screenshot, undo or clear marks, and add overall feedback text. The editor seals a versioned .ansightannotation bundle for the connected host.
Ansight.Annotations supports .NET Android, iOS, and Mac Catalyst apps. The Ansight and Ansight.Maui all-in-one packages include it and register annotation capture by default in Debug application builds. Release application builds hard-disable it. Call WithAnnotatedFeedback(...) when you need to customize screenshot or visual-tree capture.
Present the native editor
For a non-MAUI app, the all-in-one setup includes the Debug default:
using Ansight;
using Ansight.Annotations;
var options = Options.CreateBuilder()
.WithAnsightSdk()
.Build();
Runtime.InitializeAndActivate(options);
var result = await Annotate.PresentAsync();
For MAUI, UseAnsight also registers the Debug default. Configure it when needed:
using Ansight.Annotations;
using Ansight.Maui;
builder.UseAnsight<App>(ansight =>
{
ansight.WithAnnotatedFeedback();
});
A native Android app can pass its foreground Activity explicitly. This is recommended outside MAUI:
var result = await Annotate.PresentAsync(this);
If the app does not reference an all-in-one package, install the feature separately:
dotnet add package Ansight.Annotations
The native editor supports free draw, undo, clear, and overall feedback text. The host can infer approximate shapes from free-draw paths. The sealed bundle is sent over an active host session; if delivery is unavailable, the native outbox retains it and retries on reconnection.
Submit app-owned shapes and context
Annotate.CaptureAsync(request) lets an app-owned UI submit normalized shapes without opening the native editor:
var result = await Annotate.CaptureAsync(new AnnotationCaptureRequest
{
Feedback = "The total overlaps the action button.",
Shapes =
[
new AnnotationShape(AnnotationShapeKind.Rectangle, 0.62, 0.74, 0.31, 0.12)
]
});
Managed hooks run after evidence capture and before this managed bundle is sealed. They can add app context and artifacts:
using System.Text.Json.Nodes;
using Ansight.Annotations;
using Ansight.Artifacts;
sealed class FeedbackContextHook : IAnnotationCaptureHook
{
public ValueTask ContributeAsync(
AnnotationCaptureContext context,
CancellationToken cancellationToken)
{
context.AddCustomData("account", JsonValue.Create("example"));
context.AddArtifact(new AnnotationArtifact(
"Navigation state", "application/json", "navigation.json",
ArtifactPayload.FromText("{\"route\":\"/checkout\"}")));
return ValueTask.CompletedTask;
}
}
ansight.WithAnnotatedFeedback(annotations =>
{
annotations.AddHook(new FeedbackContextHook());
});
The native PresentAsync() path does not currently invoke managed hooks or managed offline sinks. The managed CaptureAsync(request) path can also send bundles to an active Offline Capture sink, which stores them under annotations/bundles and indexes them in annotations/index.jsonl.
Capture queries VisualTreeProviderRegistry at capture time. The built-in native source is always present; Ansight.Maui registers a maui source even when remote tools are disabled. Use WithEvidencePolicy(...) to deny individual evidence sources. Screenshot, tree, hook, artifact, outbox, and destination failures are isolated where possible.
Feedback is obsolete and forwards to Annotate for existing callers. Use Annotate for new code.