fix: walk past an empty-string cursor in the legacy task refresh (#2220)

`ManagedRequestorTasksState.refresh()` drives the legacy `tasks/list` walk
itself, and both of its cursor tests were truthiness checks — so the fixed
adapter was never reached. `while (cursor)` ended the walk on a `""`
`nextCursor`, leaving the user-visible task list on page one, and
`cursor ? [...this.tasks, ...page] : page` would have replaced the
accumulated list rather than extended it had the walk continued.

Both now test `=== undefined`. The other four paged/managed stores already
did (`pagedToolsState`, `pagedPromptsState`, `pagedResourcesState`,
`pagedResourceTemplatesState`, `pagedRequestorTasksState`,
`managedSkillsState`); this was the last walk on the truthiness side.

Covered by a new case in `managedRequestorTasksState.test.ts` that paginates
`"" → "c2" → end` and asserts the cursor each call received, so a walk that
terminated correctly but re-requested page one still fails. Reverting either
guard on its own fails exactly that case.

Reported by Copilot on #2277.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EN2UfrkQZvtrviMtqURRm4
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-06 13:55:45 -04:00
commit 3b4eb447c9

View file

@ -181,7 +181,13 @@ export class ManagedRequestorTasksState extends TypedEventTarget<ManagedRequesto
? { ...t, status: "cancelled" as const }
: t,
);
this.tasks = cursor ? [...this.tasks, ...page] : page;
// `=== undefined`, not truthiness, on both the append test and the loop
// condition: a cursor is opaque and `""` is a legal value (#2220). Under
// a truthiness check an empty `nextCursor` ended the walk after page one
// AND made the next page replace the list rather than extend it — the
// user-visible task list silently stopping at four rows against a
// conforming server.
this.tasks = cursor === undefined ? page : [...this.tasks, ...page];
cursor = result.nextCursor;
pageCount++;
if (pageCount >= MAX_PAGES) {
@ -189,7 +195,7 @@ export class ManagedRequestorTasksState extends TypedEventTarget<ManagedRequesto
`Maximum pagination limit (${MAX_PAGES} pages) reached while listing requestor tasks`,
);
}
} while (cursor);
} while (cursor !== undefined);
this.dispatchTypedEvent("tasksChange", this.tasks);
return this.getTasks();
}