feat(tasks): linked tasks sync title and subtasks with their note in both directions
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 2m32s

Subtasks of a task linked to a note checkbox are tied 1:1 to checkboxes of that note
(subtasks[].blockId), wherever they are moved. ReconcileDocTaskLinks now carries tick, title and
subtasks from the note to the task and adopts new checkboxes directly under the task;
SyncTaskToDoc carries tick, title and subtasks to the note and adds checkboxes for new subtasks.
Deleting is not mirrored. Deepening a task ties its subtasks right away; saves without links keep
the server's links. The sync response reports taskLinks/subtaskLinks; the editor shows an
"Unteraufgabe" badge. v0.36.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-01 12:29:10 +01:00
1 parent f91926c208
commit 5a8922011d
20 files changed
+511 -53

No files matched your search

+7 -2
View File
@@ -133,6 +133,7 @@ export class DocSyncEngine {
private lockedByOthers: LeaseInfo[] = [];
private conflicts: Result[] = [];
private taskLinks = new Map<string, string>();
private subtaskLinks = new Map<string, string>();
private focused: string | null = null;
private activity = new Map<string, number>(); // blockId -> last edit/focus time
@@ -234,7 +235,7 @@ export class DocSyncEngine {
errorMessage: this.errorMessage,
role: this.role,
title: this.local.title,
blocks: toDocumentBlocks(this.local, this.docId, this.taskLinks),
blocks: toDocumentBlocks(this.local, this.docId, this.taskLinks, this.subtaskLinks),
pendingCount: this.pending.length + (this.inflight?.length || 0),
shared: this.shared,
sessions: this.sessions,
@@ -252,8 +253,9 @@ export class DocSyncEngine {
}
/** Task IDs of blocks linked to tasks (kept outside the synced tree). */
setTaskLinks(links: Map<string, string>): void {
setTaskLinks(links: Map<string, string>, subtaskLinks?: Map<string, string>): void {
this.taskLinks = new Map(links);
if (subtaskLinks) this.subtaskLinks = new Map(subtaskLinks);
this.emit();
}
@@ -562,6 +564,9 @@ export class DocSyncEngine {
this.role = res.role;
this.shared = res.shared;
this.sessions = res.sessions;
// The server reports the links after every sync, so badges follow subtasks it adopted or added
if (res.taskLinks) this.taskLinks = new Map(Object.entries(res.taskLinks));
if (res.subtaskLinks) this.subtaskLinks = new Map(Object.entries(res.subtaskLinks));
this.presence = res.presence || [];
this.lockedByOthers = res.leases?.others || [];