Skip to content

Add Microsoft.Maui.AI.Navigation library with route-aware deep navigation#134

Draft
mattleibow wants to merge 29 commits into
mainfrom
mattleibow/garden-deep-navigation
Draft

Add Microsoft.Maui.AI.Navigation library with route-aware deep navigation#134
mattleibow wants to merge 29 commits into
mainfrom
mattleibow/garden-deep-navigation

Conversation

@mattleibow
Copy link
Copy Markdown
Member

@mattleibow mattleibow commented Apr 23, 2026

Summary

Adds Microsoft.Maui.AI.Navigation — a new package under AI Extensions for runtime Shell route discovery and template-aware navigation. Integrates it into the Garden sample, replacing hardcoded navigation tools with route-aware AI tools.

New package: Microsoft.Maui.AI.Navigation

A dependency-free MAUI library (no AI.Attributes dependency) that discovers Shell routes at runtime and provides template-style URI navigation.

ShellNavigationService

Method Purpose
GetRoutes() Walks the Shell hierarchy + reflects Routing.RegisterRoute entries to discover routes and [QueryProperty] parameters
GetCurrentRoute() Returns Shell.CurrentState.Location
NavigateAsync(route) Parses template-style URIs like //main/products/product/seed-tomato/review, splits into sequential GoToAsync calls with extracted query params
BuildRoute(base, segments, params) Constructs multi-segment routes with Shell dot-prefix convention
ParseRoute(uri) Internal: classifies segments as hierarchy/registered/inline-value and produces navigation steps

Template-style URIs

The AI writes clean URIs with parameter values inline in the path:

//main/products/product/seed-tomato         → product?sku=seed-tomato
//main/products/product/seed-tomato/review  → product?sku=..., then review?sku=...
//main/orders/order/ORD-00001               → order?orderId=ORD-00001
..                                          → go back

ParseRoute matches path segments against known routes, treats unknown segments after parameterized routes as inline parameter values, and produces sequential GoToAsync steps with proper query strings. The first step is absolute; subsequent steps are relative — so back-navigation (..) pops to the correct parent.

Tests

44 xUnit tests covering: query parameter discovery, BuildRoute, ParseRoute (hierarchy routes, inline params, nested routes, relative routes, explicit query strings, URL encoding, back-navigation stack correctness, parameter propagation, valid URI invariant).

Garden sample integration

  • AINavigationService — thin wrapper adding [ExportAIFunction] to ShellNavigationService, bridging AI.Attributes and the dependency-free library. Exposes get_routes, get_current_route, navigate.
  • Dynamic system promptChatViewModel.BuildSystemPrompt() calls GetRoutes() at session start and injects the discovered route table into the prompt. No hardcoded routes.
  • Simplified MainViewModel — removed navigate_to_page and dismiss_page AI tools (replaced by AINavigationService).
  • Updated AppShell — route registration comments now document the URI structure.
  • Updated MauiProgram — registers ShellNavigationService and AINavigationService as singletons.

Infrastructure

  • Added Microsoft.Maui.AI.Navigation to MauiLabs.slnx and AIExtensions.slnf
  • Updated src/AIExtensions/README.md with new package row
  • Updated root README.md with AI Navigation section
  • Updated Garden sample README.md with navigation tools and features
  • Added mattleibow/ai-annotations to ci-ai.yml triggers for stacked PR CI

@mattleibow mattleibow changed the title Garden sample: deep navigation, product details, reviews, persistent order IDs Add Microsoft.Maui.AI.Navigation library and Garden deep navigation sample Apr 23, 2026
@mattleibow mattleibow marked this pull request as draft April 23, 2026 18:55
mattleibow added a commit that referenced this pull request Apr 23, 2026
Removed Microsoft.Maui.AI.Navigation library (belongs in PR #134).
Restored modal Shell routes for catalog, orders, and cart pages.
Navigation tools back on MainViewModel (navigate_to_page, dismiss_page).

All pages are now navigable via:
- Buttons: catalog items have Details/Add to Cart, orders tap to detail,
  product detail has Write Review and Add to Cart, order detail has
  Reorder and product taps
- AI tools: navigate_to_page('catalog'/'orders'/'cart'), dismiss_page()
- Back buttons on every modal page

Pages use relative Shell routes (product?sku=X, review?sku=X, order?orderId=X)
so they push on top of their parent modal naturally.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow mattleibow force-pushed the mattleibow/garden-deep-navigation branch from bb2c6c5 to 022e4a1 Compare April 23, 2026 22:54
@mattleibow mattleibow force-pushed the mattleibow/ai-annotations branch 5 times, most recently from 95722c3 to 5f2c661 Compare May 7, 2026 20:49
mattleibow and others added 11 commits May 11, 2026 18:11
Rebased onto latest main as a single commit.

Includes:
- Microsoft.Maui.AI.Attributes runtime library + source generator
- IncludeTools/ExcludeTools filtering on [AIToolSource]
- Assembly-wide auto-generated tool context
- Property getter/setter tool support
- 91 runtime tests + 116 generator tests
- Garden Shop sample with chat, catalog, orders, reviews, cart modes
- Expandable tool call details in chat UI
- CI workflow (ci-ai.yml) + AzDO official pipeline job
- NuGet package includes generator DLL in analyzers/ folder
- Unique CI version suffix (ci.YYYYMMDD.N)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tributes

Separate AI Attributes from the Essentials AI directory (src/AI/) so each
product has its own top-level folder:
- src/AIAttributes/ — AI Attributes library + source generator
- tests/AIAttributes/ — runtime and generator tests
- src/AI/ — reserved for Essentials AI

Update all ProjectReferences, solution filter, CI workflow, AzDO pipeline,
MauiLabs.slnx, and README paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename src/AIAttributes → src/AIExtensions and tests/AIAttributes →
tests/AIExtensions to reflect the broader scope of AI extension packages
(AI.Navigation will join AI.Attributes under src/AIExtensions/).

Rename sample folders and csproj files from AIAttributes.Sample.* to
AIExtensions.Sample.* and update all namespaces, project references,
CI paths, and documentation links.

Project/assembly names (Microsoft.Maui.AI.Attributes) are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…1 compat

Microsoft.Extensions.AI.OpenAI 10.4.1 requires OpenAI >= 2.9.1.
The EssentialsAI sample was pinned at 2.6.0, causing CS1705 on CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the reflection-based schema generation (GetMethod/GetProperty +
CreateFunctionJsonSchema) with per-parameter CreateJsonSchema calls that
use the source-generated JsonSerializerOptions. This eliminates all
MethodInfo/PropertyInfo lookups from the generated code.

Change AIToolMetadataServices to accept JsonTypeInfo<T> instead of
JsonSerializerOptions, making all argument deserialization AOT-safe.
The generator now emits the concrete JsonTypeInfo<T> expression for
each parameter.

Mark Microsoft.Maui.AI.Attributes with IsTrimmable=true and
IsAotCompatible=true — trim and AOT analyzers report zero warnings.

Key changes:
- Generator: emit per-parameter schema via AIJsonUtilities.CreateJsonSchema
  with explicit s_jsonOptions instead of reflection-based
  CreateFunctionJsonSchema(MethodInfo)
- Generator: emit s_jsonOptions field using AIJsonUtilities.DefaultOptions
- Generator: emit JsonTypeInfo<T> expressions for GetRequiredArg/GetOptionalArg
- AIToolMetadataServices: replace JsonSerializerOptions? parameter with
  JsonTypeInfo<T> for type-safe, trim-safe deserialization
- Runtime lib csproj: add IsTrimmable=true, IsAotCompatible=true
- Remove System.Reflection using from generated output

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The IsNullable flag incorrectly included '|| p.Type.IsReferenceType',
causing all reference-type parameters (e.g. 'string name') to be treated
as nullable. This meant non-nullable string parameters were never added
to the JSON schema 'required' array, making the schema tell the LLM the
param is optional while the runtime throws on missing values.

Fix: use only NullableAnnotation.Annotated to determine nullability,
matching C# nullable reference type semantics.

Add two new schema tests verifying required array contents for both
non-nullable reference types and value types.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…and conversions

- Add EnumParamService and CollectionParamService with tool contexts
- Add 9 schema tests (enum, collection, optional, no-params, void return, multi-param, DI exclusion, CancellationToken exclusion)
- Add 10 conversion edge case tests (enum, list, dict, DTO, JsonNode, nullable)
- Add EnumParameter and CollectionParameter generator inputs
- Add 4 generator compilation tests for enum/collection scenarios
- Add enum/collection to AllValidInputs_CompileCleanly theory

Test count: 110 runtime (was 93) + 122 generator (was 116) = 232 total

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Split the 1268-line AIToolContextGenerator.cs into focused files:
- Models.cs (88 lines) — pipeline value types (enums + records)
- Diagnostics.cs (74 lines) — diagnostic descriptors and factories
- SymbolAnalysis.cs (682 lines) — Roslyn symbol extraction + constants
- CodeEmitter.cs (312 lines) — source code generation + string helpers
- AIToolContextGenerator.cs (137 lines) — slim entry point with Initialize()

Pure structural refactor — generated output is byte-identical.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Gate user secrets embedding on Debug configuration only
- Dispose secrets.json stream with 'using' in MauiProgram.cs
- Uncomment NSPrivacyAccessedAPICategoryUserDefaults in privacy manifest
- Add pull_request types [opened, synchronize, reopened, edited] to ci-ai.yml
- Fix DIParameters README garbled sentence
- Use explicit SDK version in AzDO AI build job (not useGlobalJson)
- Pass actual argument name in AIToolMetadataServices exception
- Add clarifying comment on README Remove path in csproj

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow mattleibow force-pushed the mattleibow/ai-annotations branch from 5f2c661 to f302f4a Compare May 11, 2026 16:16
mattleibow and others added 3 commits May 11, 2026 18:38
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the fragile None Remove path — PackRepoRootReadme=false already
prevents Arcade from including the repo-root README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update CI workflow name, AzDO pipeline display names, README headers,
and sample descriptions to use 'AI Extensions' — reflecting the broader
product area that will include AI Navigation alongside AI Attributes.

Package/assembly names (Microsoft.Maui.AI.Attributes) unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow mattleibow force-pushed the mattleibow/garden-deep-navigation branch from 022e4a1 to 5b93a1b Compare May 11, 2026 16:58
mattleibow and others added 4 commits May 11, 2026 19:00
Make src/AIExtensions/README.md a concise landing page with a Packages
table that can grow as new packages join (e.g. AI.Navigation). Move the
code sample and detailed docs to the per-package NuGet README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t README

Restructure so future packages (e.g. AI Navigation) can be added as
sibling sub-headings under the AI Extensions section.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow and others added 2 commits May 11, 2026 19:09
Skip Xcode version validation repo-wide in Directory.Build.props.
Add warning comment on the embedded user-secrets target explaining
this is only acceptable for local-only developer samples.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ample

New library: Microsoft.Maui.AI.Navigation
- ShellNavigationService: runtime Shell route discovery, template-aware URI
  parsing (ParseRoute), multi-step GoToAsync navigation, BuildRoute helper
- Query parameter discovery via [QueryProperty] reflection on pages and VMs
- Package README with API docs, usage examples, and integration guide
- 44 xUnit tests covering query parameters, BuildRoute, ParseRoute, and
  back-navigation stack correctness

Garden sample updates:
- AINavigationService wrapper bridging ShellNavigationService to [ExportAIFunction]
- Replace hardcoded navigate_to_page/dismiss_page with route-aware navigate tool
- Dynamic system prompt with discovered route table and template-style examples
- Update csproj, MauiProgram, AppShell, ChatViewModel, MainViewModel

Infrastructure:
- Add AI.Navigation to MauiLabs.slnx and AIExtensions.slnf
- Add AI Navigation row to AIExtensions product README
- Add AI Navigation section to root README
- Update Garden sample README with navigation tools and features

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow mattleibow force-pushed the mattleibow/garden-deep-navigation branch from 5b93a1b to 1eb5968 Compare May 11, 2026 17:13
mattleibow and others added 2 commits May 11, 2026 19:15
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ate prompts

- Remove unused Title/Icon on ShellContent (tab bar is hidden)
- Add descriptive comments on routes in AppShell.xaml and .cs
- Document each AIToolSource pattern in GardenShopTools XML doc
- Replace generic suggestion prompts with more demonstrative ones

Cherry-picked from PR #134 — sample improvements independent of navigation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow mattleibow changed the title Add Microsoft.Maui.AI.Navigation library and Garden deep navigation sample Add Microsoft.Maui.AI.Navigation library with route-aware deep navigation May 11, 2026
mattleibow and others added 7 commits May 11, 2026 19:21
…mattleibow/garden-deep-navigation

# Conflicts:
#	samples/AIExtensions.Sample.Garden/AppShell.xaml.cs
#	samples/AIExtensions.Sample.Garden/ViewModels/Chat/ChatViewModel.cs
Replace ▼/▶ (U+25BC/25B6) expand/collapse toggle and › (U+203A)
list chevron with FluentIcons.ChevronDown/ChevronRight glyphs.
Unicode geometric symbols may not render on iOS with custom fonts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…appings

The previous codepoints (U+E76C, U+E70D) were Segoe Fluent Icons values,
not FluentSystemIcons-Filled. In this font:
- U+E76C = leaf_three (not chevron_right)
- U+E70D = heart_circle (not chevron_down)

Correct codepoints from the bundled font:
- U+F2B0 = ic_fluent_chevron_right_20_filled
- U+F2A3 = ic_fluent_chevron_down_20_filled

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add Android handler mapping to set BackgroundTintList to transparent,
matching the existing iOS/MacCatalyst border removal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis pushed a commit that referenced this pull request May 15, 2026
* Add Microsoft.Maui.AI.Attributes — source-generated AI tool bindings

Rebased onto latest main as a single commit.

Includes:
- Microsoft.Maui.AI.Attributes runtime library + source generator
- IncludeTools/ExcludeTools filtering on [AIToolSource]
- Assembly-wide auto-generated tool context
- Property getter/setter tool support
- 91 runtime tests + 116 generator tests
- Garden Shop sample with chat, catalog, orders, reviews, cart modes
- Expandable tool call details in chat UI
- CI workflow (ci-ai.yml) + AzDO official pipeline job
- NuGet package includes generator DLL in analyzers/ folder
- Unique CI version suffix (ci.YYYYMMDD.N)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move AI Attributes source to src/AIAttributes and tests to tests/AIAttributes

Separate AI Attributes from the Essentials AI directory (src/AI/) so each
product has its own top-level folder:
- src/AIAttributes/ — AI Attributes library + source generator
- tests/AIAttributes/ — runtime and generator tests
- src/AI/ — reserved for Essentials AI

Update all ProjectReferences, solution filter, CI workflow, AzDO pipeline,
MauiLabs.slnx, and README paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Restore src/AI/README.md from main

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Rename AIAttributes to AIExtensions across folders and samples

Rename src/AIAttributes → src/AIExtensions and tests/AIAttributes →
tests/AIExtensions to reflect the broader scope of AI extension packages
(AI.Navigation will join AI.Attributes under src/AIExtensions/).

Rename sample folders and csproj files from AIAttributes.Sample.* to
AIExtensions.Sample.* and update all namespaces, project references,
CI paths, and documentation links.

Project/assembly names (Microsoft.Maui.AI.Attributes) are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Bump OpenAI package to 2.9.1 for Microsoft.Extensions.AI.OpenAI 10.4.1 compat

Microsoft.Extensions.AI.OpenAI 10.4.1 requires OpenAI >= 2.9.1.
The EssentialsAI sample was pinned at 2.6.0, causing CS1705 on CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove runtime reflection from generated tools for AOT/trim safety

Replace the reflection-based schema generation (GetMethod/GetProperty +
CreateFunctionJsonSchema) with per-parameter CreateJsonSchema calls that
use the source-generated JsonSerializerOptions. This eliminates all
MethodInfo/PropertyInfo lookups from the generated code.

Change AIToolMetadataServices to accept JsonTypeInfo<T> instead of
JsonSerializerOptions, making all argument deserialization AOT-safe.
The generator now emits the concrete JsonTypeInfo<T> expression for
each parameter.

Mark Microsoft.Maui.AI.Attributes with IsTrimmable=true and
IsAotCompatible=true — trim and AOT analyzers report zero warnings.

Key changes:
- Generator: emit per-parameter schema via AIJsonUtilities.CreateJsonSchema
  with explicit s_jsonOptions instead of reflection-based
  CreateFunctionJsonSchema(MethodInfo)
- Generator: emit s_jsonOptions field using AIJsonUtilities.DefaultOptions
- Generator: emit JsonTypeInfo<T> expressions for GetRequiredArg/GetOptionalArg
- AIToolMetadataServices: replace JsonSerializerOptions? parameter with
  JsonTypeInfo<T> for type-safe, trim-safe deserialization
- Runtime lib csproj: add IsTrimmable=true, IsAotCompatible=true
- Remove System.Reflection using from generated output

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix non-nullable reference params missing from schema required array

The IsNullable flag incorrectly included '|| p.Type.IsReferenceType',
causing all reference-type parameters (e.g. 'string name') to be treated
as nullable. This meant non-nullable string parameters were never added
to the JSON schema 'required' array, making the schema tell the LLM the
param is optional while the runtime throws on missing values.

Fix: use only NullableAnnotation.Annotated to determine nullability,
matching C# nullable reference type semantics.

Add two new schema tests verifying required array contents for both
non-nullable reference types and value types.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add missing AI Attributes test cases for enums, collections, schema, and conversions

- Add EnumParamService and CollectionParamService with tool contexts
- Add 9 schema tests (enum, collection, optional, no-params, void return, multi-param, DI exclusion, CancellationToken exclusion)
- Add 10 conversion edge case tests (enum, list, dict, DTO, JsonNode, nullable)
- Add EnumParameter and CollectionParameter generator inputs
- Add 4 generator compilation tests for enum/collection scenarios
- Add enum/collection to AllValidInputs_CompileCleanly theory

Test count: 110 runtime (was 93) + 122 generator (was 116) = 232 total

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Refactor generator into separate files for maintainability

Split the 1268-line AIToolContextGenerator.cs into focused files:
- Models.cs (88 lines) — pipeline value types (enums + records)
- Diagnostics.cs (74 lines) — diagnostic descriptors and factories
- SymbolAnalysis.cs (682 lines) — Roslyn symbol extraction + constants
- CodeEmitter.cs (312 lines) — source code generation + string helpers
- AIToolContextGenerator.cs (137 lines) — slim entry point with Initialize()

Pure structural refactor — generated output is byte-identical.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Apply dotnet format

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review comments

- Gate user secrets embedding on Debug configuration only
- Dispose secrets.json stream with 'using' in MauiProgram.cs
- Uncomment NSPrivacyAccessedAPICategoryUserDefaults in privacy manifest
- Add pull_request types [opened, synchronize, reopened, edited] to ci-ai.yml
- Fix DIParameters README garbled sentence
- Use explicit SDK version in AzDO AI build job (not useGlobalJson)
- Pass actual argument name in AIToolMetadataServices exception
- Add clarifying comment on README Remove path in csproj

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert Debug-only gate on user secrets — sample app only

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Simplify csproj README packing to match EssentialsAI pattern

Remove the fragile None Remove path — PackRepoRootReadme=false already
prevents Arcade from including the repo-root README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Rename AI Attributes branding to AI Extensions across display names

Update CI workflow name, AzDO pipeline display names, README headers,
and sample descriptions to use 'AI Extensions' — reflecting the broader
product area that will include AI Navigation alongside AI Attributes.

Package/assembly names (Microsoft.Maui.AI.Attributes) unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Restructure AIExtensions README as product-area landing page

Make src/AIExtensions/README.md a concise landing page with a Packages
table that can grow as new packages join (e.g. AI.Navigation). Move the
code sample and detailed docs to the per-package NuGet README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Make AI Extensions a heading with AI Attributes as sub-heading in root README

Restructure so future packages (e.g. AI Navigation) can be added as
sibling sub-headings under the AI Extensions section.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Rename publishAINuget to publishAIExtensionsNuget in AzDO pipeline

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix link text in AIExtensions README

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add ValidateXcodeVersion=false and secrets warning comment

Skip Xcode version validation repo-wide in Directory.Build.props.
Add warning comment on the embedded user-secrets target explaining
this is only acceptable for local-only developer samples.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Improve Garden sample: clean up AppShell, document tool patterns, update prompts

- Remove unused Title/Icon on ShellContent (tab bar is hidden)
- Add descriptive comments on routes in AppShell.xaml and .cs
- Document each AIToolSource pattern in GardenShopTools XML doc
- Replace generic suggestion prompts with more demonstrative ones

Cherry-picked from PR #134 — sample improvements independent of navigation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Replace Unicode arrows with Fluent icons in Garden sample

Replace ▼/▶ (U+25BC/25B6) expand/collapse toggle and › (U+203A)
list chevron with FluentIcons.ChevronDown/ChevronRight glyphs.
Unicode geometric symbols may not render on iOS with custom fonts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix Fluent chevron codepoints — use actual FluentSystemIcons-Filled mappings

The previous codepoints (U+E76C, U+E70D) were Segoe Fluent Icons values,
not FluentSystemIcons-Filled. In this font:
- U+E76C = leaf_three (not chevron_right)
- U+E70D = heart_circle (not chevron_down)

Correct codepoints from the bundled font:
- U+F2B0 = ic_fluent_chevron_right_20_filled
- U+F2A3 = ic_fluent_chevron_down_20_filled

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove Android Entry underline in Garden chat input

Add Android handler mapping to set BackgroundTintList to transparent,
matching the existing iOS/MacCatalyst border removal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Move Entry border removal into ConfigureMauiHandlers builder chain

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix review issues: HasDetails binding, Xcode scope, dead diagnostic

- Fix ChatMessageViewModel: add [NotifyPropertyChangedFor(nameof(HasDetails))]
  to ToolResult so HasDetails updates when tool results arrive. Remove the
  incorrect OnPropertyChanged call on ChatViewModel that fired for a
  property it doesn't own.
- Scope ValidateXcodeVersion=false to the Garden sample only (was global).
- Remove dead MAUIAI005 diagnostic (IncludeAndExcludeBothSet) — by design,
  IncludeTools and ExcludeTools compose and are both allowed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Base automatically changed from mattleibow/ai-annotations to main May 15, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant