Fix CalDAV sync stripping local_only flag on post-push updates
Details
After pushing a locally-modified CalDAV event to the server, the sync
service updated the local event (to set SyncState="synced" and store
the new ETag) without passing localOnly: true. This caused the Rust
storage layer to clear the local_only column via INSERT OR REPLACE
with local_only=FALSE (extracted from the JSON payload which had no
local_only field).
Once cleared, the event became eligible for cloud sync — pushing
CalDAV-sourced events to the cloud relay when the CalDAV server is
the actual source of truth.
Fixed all three UpdateEventAsync calls in PushEventToServer and
DeleteEventFromServer to pass localOnly: true.
Add Sign In button to update modal for expired sessions
Details
When the update download fails due to an expired token and refresh also
fails, the modal now shows a "Sign In" button that triggers the OAuth
PKCE flow directly from the update dialog. On successful auth, tokens
are persisted and the user can immediately retry the download without
navigating to Settings.
- Added SignInCommand to UpdateViewModel with full OAuth PKCE flow
- Updated UpdateModal.axaml auth notice: replaced "go to Settings" text
with an inline Sign In button + "Waiting for browser..." state
- Added IsAuthenticating property for button state management
Document local HTTP API endpoints in Tasks PLUGIN_CONTEXT.md
Details
Adds the IApiProvider section listing all 11 REST endpoints with methods,
paths, and descriptions for task and project CRUD via the local API.
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).
Add client-side token refresh fallback for update downloads
Details
When the access token is rejected during update download, the client now
silently attempts to refresh it via /api/auth/refresh using the stored
refresh token. On success, new tokens are persisted and the download
retries. On failure, the access token is cleared and the UI shows
"Session expired — please sign in again" instead of a generic error.
New: PrivStackApiClient.RefreshAccessTokenAsync() + RefreshTokenResponse DTO.
Get notified about new releases