feat(KB-129): dashboard performance optimizations

- Fix SSE hook cleanup to prevent memory leaks and stale connections
- Cap agent log memory and optimize batch log processing
- Memoize Board, Column, and TaskCard with custom comparator to reduce re-renders
- Stabilize column task arrays and preserve pagination across live updates
- Add TaskCardBadge component for PR/issue state display
- Remove deprecated GitHub polling code and archive functionality from core store
This commit is contained in:
gsxdsm
2026-03-30 11:26:55 -07:00
parent d147428430
commit a7de078fef
21 changed files with 1269 additions and 276 deletions

View File

@@ -367,7 +367,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
return { ...task, prompt };
}
async listTasks(): Promise<Task[]> {
async listTasks(options?: { limit?: number; offset?: number }): Promise<Task[]> {
if (!existsSync(this.tasksDir)) return [];
const entries = await readdir(this.tasksDir, { withFileTypes: true });
@@ -383,13 +383,22 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
}
}
return tasks.sort((a, b) => {
const sorted = tasks.sort((a, b) => {
const cmp = a.createdAt.localeCompare(b.createdAt);
if (cmp !== 0) return cmp;
const aNum = parseInt(a.id.slice(a.id.lastIndexOf("-") + 1), 10) || 0;
const bNum = parseInt(b.id.slice(b.id.lastIndexOf("-") + 1), 10) || 0;
return aNum - bNum;
});
const offset = Math.max(0, options?.offset ?? 0);
const limit = options?.limit;
if (limit === undefined) {
return sorted.slice(offset);
}
return sorted.slice(offset, offset + Math.max(0, limit));
}
async moveTask(id: string, toColumn: Column): Promise<Task> {