Add IApiProvider implementation to Tasks plugin
Details
Reference implementation of the local HTTP API capability. Exposes 11
REST endpoints for task and project CRUD:
- GET/POST /api/v1/tasks — list/create tasks (supports ?status, ?project_id filters)
- GET/PATCH/DELETE /api/v1/tasks/{id} — get/update/delete task
- GET /api/v1/tasks/search?q= — search tasks
- GET/POST /api/v1/tasks/projects — list/create projects
- GET/PATCH/DELETE /api/v1/tasks/projects/{id} — get/update/delete project
All handlers use Host.Sdk.SendAsync() exclusively — pure SDK boundary.
Follows the existing partial class pattern (TasksPlugin.GraphData.cs,
TasksPlugin.Intents.cs).
Handle AI truncation in Tasks plugin, increase title token limit
Details
Tasks AI features now check AiResponse.WasTruncated to provide clear
user feedback instead of displaying garbled or partial AI output.
Changes:
- Title generation: reject truncated responses with clear status message,
increase MaxTokens from 48 to 128 (48 was too tight for titles)
- Description rewrite: accept content but warn "(may be truncated)"
- Q&A questions: reject truncated responses (JSON would be malformed)
- Q&A description: accept content but show truncation warning
Fix Tasks settings button not responding to clicks
Details
The settings cog button showed a tooltip on hover but clicking did nothing.
Root cause: AsyncRelayCommand's CanExecute returns false while a previous
execution is in-flight. If the RuleService SDK call during initialization
hung or took too long, OpenSettingsCommand would be permanently stuck in
"executing" state, silently rejecting all subsequent Execute calls.
Fix: Replace the Command binding with a Click handler in code-behind that
directly sets Settings.IsOpen and calls LoadSettingsDataAsync(), bypassing
the AsyncRelayCommand concurrency guard entirely. Also cleaned up debug
logging from previous investigation attempts.
Fix Tasks settings button permanently unclickable after first click
Details
Root cause: OpenSettingsAsync() awaited Settings.OpenCommand
.ExecuteAsync(), which is an AsyncRelayCommand with
AllowConcurrentExecutions=false (the default). Inside that command,
LoadAllAsync() calls RuleService.GetRulesAsync() → sdk.SendAsync().
If the SDK call hangs (never resolves), the command stays in
"executing" state forever. AsyncRelayCommand.CanExecute returns false
while executing, so the Button becomes permanently disabled — clicks
are silently ignored, but tooltip still works on hover.
Fix:
- Show the overlay immediately (IsOpen = true) before loading data
- Call LoadSettingsDataAsync() directly from the parent ViewModel
instead of going through Settings.OpenCommand, bypassing the
AsyncRelayCommand concurrency guard entirely
- Rename LoadAllAsync → LoadSettingsDataAsync (internal) so the parent
VM can call it directly
Migrate plugin modal overlays to ThemeShadowXl token
Details
Replace hardcoded BoxShadow="0 8 32 0 #60000000" in all four plugin
ModalOverlayTheme.axaml files (Tasks, Calendar, Notes, Email) with
{DynamicResource ThemeShadowXl} from the new elevation token system.
Get notified about new releases