Skip to content

Commit 1d050ae

Browse files
committed
fix: address self-review findings — type safety, validation, error handling
1 parent fe74988 commit 1d050ae

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

src/core/task-persistence/delegationMeta.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@ export async function readDelegationMeta({
7878
}
7979
}
8080

81+
// Validate value types to prevent corrupted files from propagating invalid data
82+
if (
83+
meta.status !== undefined &&
84+
meta.status !== null &&
85+
!["active", "delegated", "completed"].includes(meta.status as string)
86+
) {
87+
delete (meta as Record<string, unknown>).status
88+
}
89+
if (meta.childIds !== undefined && meta.childIds !== null && !Array.isArray(meta.childIds)) {
90+
delete (meta as Record<string, unknown>).childIds
91+
}
92+
for (const key of [
93+
"delegatedToId",
94+
"awaitingChildId",
95+
"completedByChildId",
96+
"completionResultSummary",
97+
] as const) {
98+
const val = meta[key]
99+
if (val !== undefined && val !== null && typeof val !== "string") {
100+
delete (meta as Record<string, unknown>)[key]
101+
}
102+
}
103+
81104
return meta
82105
} catch (error) {
83106
console.warn(

src/core/webview/ClineProvider.ts

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3434,32 +3434,29 @@ export class ClineProvider
34343434
})
34353435

34363436
// 4b) Persist child's initial status in globalState (saveClineMessages no longer writes status)
3437-
await this.updateTaskHistory({ id: child.taskId, status: "active" } as HistoryItem, { broadcast: false })
3437+
const { historyItem: childHistory } = await this.getTaskWithId(child.taskId)
3438+
await this.updateTaskHistory({ ...childHistory, status: "active" }, { broadcast: false })
34383439

34393440
// 5) Persist parent delegation metadata BEFORE the child starts writing.
3440-
try {
3441-
const { historyItem } = await this.getTaskWithId(parentTaskId)
3442-
const childIds = Array.from(new Set([...(historyItem.childIds ?? []), child.taskId]))
3443-
const updatedHistory: typeof historyItem = {
3444-
...historyItem,
3445-
status: "delegated",
3446-
delegatedToId: child.taskId,
3447-
awaitingChildId: child.taskId,
3448-
childIds,
3449-
}
3450-
await this.updateTaskHistory(updatedHistory)
3441+
// updateTaskHistory (globalState) is critical — without it, parent won't show as delegated
3442+
const { historyItem } = await this.getTaskWithId(parentTaskId)
3443+
const childIds = Array.from(new Set([...(historyItem.childIds ?? []), child.taskId]))
3444+
const updatedHistory = {
3445+
...historyItem,
3446+
status: "delegated" as const,
3447+
delegatedToId: child.taskId,
3448+
awaitingChildId: child.taskId,
3449+
childIds,
3450+
}
3451+
await this.updateTaskHistory(updatedHistory)
34513452

3452-
// Write delegation metadata to per-task file (cross-process-safe source of truth)
3453+
// Per-task file backup is non-critical — globalState is the primary source
3454+
try {
34533455
const globalStoragePath = this.contextProxy.globalStorageUri.fsPath
34543456
await saveDelegationMeta({
34553457
taskId: parentTaskId,
34563458
globalStoragePath,
3457-
meta: {
3458-
status: "delegated",
3459-
delegatedToId: child.taskId,
3460-
awaitingChildId: child.taskId,
3461-
childIds,
3462-
},
3459+
meta: { status: "delegated", delegatedToId: child.taskId, awaitingChildId: child.taskId, childIds },
34633460
})
34643461
await saveDelegationMeta({
34653462
taskId: child.taskId,
@@ -3468,9 +3465,7 @@ export class ClineProvider
34683465
})
34693466
} catch (err) {
34703467
this.log(
3471-
`[delegateParentAndOpenChild] Failed to persist parent metadata for ${parentTaskId} -> ${child.taskId}: ${
3472-
(err as Error)?.message ?? String(err)
3473-
}`,
3468+
`[delegateParentAndOpenChild] Non-critical: Failed to write delegation metadata files for ${parentTaskId} -> ${child.taskId}: ${(err as Error)?.message ?? String(err)}`,
34743469
)
34753470
}
34763471

0 commit comments

Comments
 (0)