Fix GitHubIssueSource deserialization error for project-synced tasks
Details
Tasks created by GitHub Projects sync have SourceId pointing to a
github_project_source entity. When these tasks are updated locally,
PushTaskAsync tried to read the SourceId through GitHubIssueSourceService
(entity type github_issue_source), causing the Rust backend to return
the wrong entity type and triggering a JsonException on the required
repo_owner/repo_name fields.
Fix: Add ResolveIssueSourceAsync that detects project-sourced tasks
(SourceId == GitHubProjectSourceId custom field) and finds a matching
issue source by parsing the repo from SourceRef instead. This avoids
the entity type mismatch and also enables push for project-synced
tasks when a bidirectional issue source covers the same repo.
Add GitHub assignee editing in task detail panel
Details
Adds inline assignee management directly in the GitHub Issue metadata
section of the task detail panel. Users can add/remove GitHub usernames
which immediately pushes to GitHub via the existing OnTaskUpdated
auto-push callback — no need to navigate through menus or manually sync.
Changes:
- New TasksViewModel.GitHubAssignees.cs partial: ObservableCollection
for assignees, add/remove commands that update custom_fields and call
UpdateTask (triggering auto-push)
- TaskDetailPanel.axaml: assignee input + chip list in GitHub section
- TasksViewModel.cs: hook RefreshGitHubAssignees into OnSelectedTaskChanged
Push assignees and labels to GitHub on task update
Details
MapTaskToIssueRequest previously only pushed title, body, and state.
Assignee and label changes made locally were silently ignored, requiring
users to manually sync or edit on GitHub directly.
Now extracts github_assignees from custom_fields and reconstructs the
labels list from tags + priority field, so any local change to a
bidirectional GitHub-linked task immediately propagates assignees and
labels back to the issue.
Safety: assignees return null (omitted from PATCH) when no github_assignees
field exists. Labels return null when the task hasn't been pulled from
GitHub yet (no github_number in custom_fields), preventing accidental
label clearing on tasks that haven't been synced.
Fix GitHub sync not pushing task status changes to GitHub issues
Details
PushTaskAsync existed but was never called when tasks were updated locally.
Added an OnTaskUpdated callback to TaskService that fires after every
UpdateTask call. TasksPlugin subscribes to it during init and triggers
a background push for any GitHub-linked task (bidirectional sources only).
Includes a re-entrancy guard since PushTaskAsync itself calls UpdateTask
to save the updated SourceEtag.
Fix CalDAV sync token loss and conflict handling
Details
Two critical bugs that caused local edits to be overwritten by server:
1. Sync token was lost after every sync cycle. PullFromCalDavAsync
saved the token to the subscription, but SyncCalDavSubscriptionAsync
then called UpdateSubscriptionAsync with the original (stale) sub
object, overwriting the token with null. This forced a full fetch
on every sync, increasing the chance of overwrites. Fixed by
re-reading the subscription after pull/push before updating
LastSyncedAt.
2. On 412 Conflict (ETag mismatch), the push silently discarded the
local change by resetting SyncState to "synced". Now retries once
by fetching the fresh ETag from the server and re-attempting PUT.
If the retry also fails, keeps pending_push for next cycle.
Also added GetSubscriptionAsync to CalendarService for fresh reads.
Get notified about new releases