agent-ecosystem/src/main/workers/task-change-worker.ts
Илия 11bb49c53e
feat(graph): force-directed agent graph visualization with kanban-zone task layout
Force-directed graph visualization for agent teams.

Package: @claude-teams/agent-graph (isolated workspace package)
- Space theme: bloom, particles, hex grid, depth stars
- Members as hexagonal nodes with breathing glow
- Tasks as pill cards in kanban columns (todo/wip/done/review/approved) per owner
- Message particles along edges (real-time only)
- Deterministic layout, Figma-style pan, scroll/pinch zoom
- Clean Architecture: ports/adapters/strategies, ES #private classes

Integration: features/agent-graph/ (adapter + overlay + tab)
- Full-screen overlay (Cmd+Shift+G) + Pin as Tab
- Graph button in Team section header
- Frustum culling, zero per-frame allocations, adaptive fps
- Performance overlay via ?perf query param

Also: CI runs on all PR branches, features/CLAUDE.md architecture guide
2026-03-28 12:03:42 +02:00

40 lines
1.2 KiB
TypeScript

import { parentPort } from 'node:worker_threads';
import { TaskBoundaryParser } from '@main/services/team/TaskBoundaryParser';
import { TaskChangeComputer } from '@main/services/team/TaskChangeComputer';
import { TeamMemberLogsFinder } from '@main/services/team/TeamMemberLogsFinder';
import type {
TaskChangeWorkerRequest,
TaskChangeWorkerResponse,
} from '@main/services/team/taskChangeWorkerTypes';
const logsFinder = new TeamMemberLogsFinder();
const boundaryParser = new TaskBoundaryParser();
const computer = new TaskChangeComputer(logsFinder, boundaryParser);
function postMessage(message: TaskChangeWorkerResponse): void {
parentPort?.postMessage(message);
}
parentPort?.on('message', async (message: TaskChangeWorkerRequest) => {
if (message?.op !== 'computeTaskChanges') {
postMessage({
id: message?.id ?? 'unknown',
ok: false,
error: `Unsupported task change worker op: ${String(message?.op)}`,
});
return;
}
try {
const result = await computer.computeTaskChanges(message.payload);
postMessage({ id: message.id, ok: true, result });
} catch (error) {
postMessage({
id: message.id,
ok: false,
error: error instanceof Error ? error.message : String(error),
});
}
});