agent-ecosystem/src/renderer/utils/pathNormalize.ts
iliya 051a727eb2 feat: implement diff view functionality with read-only and accept/reject capabilities
- Introduced a comprehensive implementation plan for the diff view feature, structured in four phases: MVP (read-only), accept/reject per hunk, per-task scoping, and enhanced features.
- Phase 1 includes a read-only diff view per agent, utilizing JSONL data to display file changes.
- Defined new types for file changes and review data, and established IPC channels for fetching member changes and reading file content.
- Developed backend services for extracting file changes and aggregating review data, alongside frontend components for displaying diffs and managing state.
- Subsequent phases will enhance the diff view with accept/reject functionality, task-specific change scoping, and improved user experience features.
2026-02-24 20:25:49 +02:00

61 lines
2.2 KiB
TypeScript

import type { GlobalTask } from '@shared/types';
export function normalizePath(p: string): string {
let s = p.replace(/\\/g, '/');
// Preserve root paths like "/" or "C:/"
if (s !== '/' && !/^[A-Za-z]:\/$/.test(s)) {
while (s.endsWith('/')) s = s.slice(0, -1);
}
return s.toLowerCase();
}
export interface TaskStatusCounts {
pending: number;
inProgress: number;
completed: number;
}
function incrementStatus(counts: TaskStatusCounts, status: string): TaskStatusCounts {
if (status === 'pending') return { ...counts, pending: counts.pending + 1 };
if (status === 'in_progress') return { ...counts, inProgress: counts.inProgress + 1 };
if (status === 'completed') return { ...counts, completed: counts.completed + 1 };
return counts;
}
/** Build a map of normalized project path -> task status counts */
export function buildTaskCountsByProject(tasks: GlobalTask[]): Map<string, TaskStatusCounts> {
const map = new Map<string, TaskStatusCounts>();
for (const task of tasks) {
if (!task.projectPath) continue;
const key = normalizePath(task.projectPath);
const counts = map.get(key) ?? { pending: 0, inProgress: 0, completed: 0 };
map.set(key, incrementStatus(counts, task.status));
}
return map;
}
/** Build a map of team name -> task status counts */
export function buildTaskCountsByTeam(tasks: GlobalTask[]): Map<string, TaskStatusCounts> {
const map = new Map<string, TaskStatusCounts>();
for (const task of tasks) {
const key = task.teamName;
const counts = map.get(key) ?? { pending: 0, inProgress: 0, completed: 0 };
map.set(key, incrementStatus(counts, task.status));
}
return map;
}
/** Build a map of owner name (lowercase) -> task status counts (ignores deleted). */
export function buildTaskCountsByOwner(
tasks: { owner?: string | null; status: string }[]
): Map<string, TaskStatusCounts> {
const map = new Map<string, TaskStatusCounts>();
for (const task of tasks) {
const owner = task.owner?.trim();
if (!owner || task.status === 'deleted') continue;
const key = owner.toLowerCase();
const counts = map.get(key) ?? { pending: 0, inProgress: 0, completed: 0 };
map.set(key, incrementStatus(counts, task.status));
}
return map;
}