@task-mcp/shared 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Shared dashboard renderer for CLI and MCP server
3
+ * Provides consistent dashboard layout across all interfaces
4
+ */
5
+ import type { Task, Project, InboxItem } from "../schemas/index.js";
6
+ export interface DashboardStats {
7
+ total: number;
8
+ completed: number;
9
+ inProgress: number;
10
+ pending: number;
11
+ blocked: number;
12
+ cancelled: number;
13
+ byPriority: {
14
+ critical: number;
15
+ high: number;
16
+ medium: number;
17
+ low: number;
18
+ };
19
+ }
20
+ export interface DependencyMetrics {
21
+ readyToWork: number;
22
+ blockedByDependencies: number;
23
+ mostDependedOn?: {
24
+ id: string;
25
+ title: string;
26
+ dependentCount: number;
27
+ };
28
+ }
29
+ export interface DashboardData {
30
+ tasks: Task[];
31
+ projects: Project[];
32
+ inboxItems?: InboxItem[];
33
+ currentProject?: Project;
34
+ version?: string;
35
+ }
36
+ export declare function calculateStats(tasks: Task[]): DashboardStats;
37
+ export declare function calculateDependencyMetrics(tasks: Task[]): DependencyMetrics;
38
+ /**
39
+ * Render Status widget (progress, counts, priorities, dependencies)
40
+ */
41
+ export declare function renderStatusWidget(tasks: Task[], _projects: Project[]): string;
42
+ /**
43
+ * Render Next Actions widget (top ready tasks)
44
+ */
45
+ export declare function renderActionsWidget(tasks: Task[]): string;
46
+ /**
47
+ * Render Inbox widget (pending items)
48
+ */
49
+ export declare function renderInboxWidget(inboxItems: InboxItem[]): string | null;
50
+ /**
51
+ * Render Projects table
52
+ */
53
+ export declare function renderProjectsTable(projects: Project[], getProjectTasks: (projectId: string) => Task[]): string;
54
+ /**
55
+ * Render Tasks table for single project view
56
+ */
57
+ export declare function renderTasksTable(tasks: Task[], limit?: number): string;
58
+ export interface RenderDashboardOptions {
59
+ showBanner?: boolean;
60
+ showInbox?: boolean;
61
+ showProjects?: boolean;
62
+ showTasks?: boolean;
63
+ stripAnsiCodes?: boolean;
64
+ }
65
+ /**
66
+ * Render full dashboard (CLI and MCP compatible)
67
+ */
68
+ export declare function renderDashboard(data: DashboardData, getProjectTasks: (projectId: string) => Task[], options?: RenderDashboardOptions): string;
69
+ /**
70
+ * Render single project dashboard
71
+ */
72
+ export declare function renderProjectDashboard(project: Project, tasks: Task[], options?: {
73
+ stripAnsiCodes?: boolean;
74
+ version?: string;
75
+ }): string;
76
+ /**
77
+ * Render global dashboard (all projects)
78
+ */
79
+ export declare function renderGlobalDashboard(projects: Project[], allTasks: Task[], inboxItems: InboxItem[], getProjectTasks: (projectId: string) => Task[], options?: {
80
+ stripAnsiCodes?: boolean;
81
+ version?: string;
82
+ }): string;
83
+ //# sourceMappingURL=dashboard-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-renderer.d.ts","sourceRoot":"","sources":["../../src/utils/dashboard-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Shared dashboard renderer for CLI and MCP server
3
+ * Provides consistent dashboard layout across all interfaces
4
+ */
5
+ import { c, box, progressBar, table, icons, sideBySide, truncateStr, pad, banner, stripAnsi, } from "./terminal-ui.js";
6
+ // =============================================================================
7
+ // Statistics Calculators
8
+ // =============================================================================
9
+ export function calculateStats(tasks) {
10
+ const stats = {
11
+ total: tasks.length,
12
+ completed: 0,
13
+ inProgress: 0,
14
+ pending: 0,
15
+ blocked: 0,
16
+ cancelled: 0,
17
+ byPriority: { critical: 0, high: 0, medium: 0, low: 0 },
18
+ };
19
+ for (const task of tasks) {
20
+ switch (task.status) {
21
+ case "completed":
22
+ stats.completed++;
23
+ break;
24
+ case "in_progress":
25
+ stats.inProgress++;
26
+ break;
27
+ case "pending":
28
+ stats.pending++;
29
+ break;
30
+ case "blocked":
31
+ stats.blocked++;
32
+ break;
33
+ case "cancelled":
34
+ stats.cancelled++;
35
+ break;
36
+ }
37
+ const priority = task.priority ?? "medium";
38
+ if (priority in stats.byPriority) {
39
+ stats.byPriority[priority]++;
40
+ }
41
+ }
42
+ return stats;
43
+ }
44
+ export function calculateDependencyMetrics(tasks) {
45
+ const completedIds = new Set(tasks.filter((t) => t.status === "completed").map((t) => t.id));
46
+ let readyToWork = 0;
47
+ let blockedByDependencies = 0;
48
+ // Count dependents for each task
49
+ const dependentCounts = new Map();
50
+ for (const task of tasks) {
51
+ if (task.status === "completed" || task.status === "cancelled")
52
+ continue;
53
+ const deps = task.dependencies ?? [];
54
+ if (deps.length === 0) {
55
+ readyToWork++;
56
+ }
57
+ else {
58
+ const allSatisfied = deps.every((d) => completedIds.has(d.taskId));
59
+ if (allSatisfied) {
60
+ readyToWork++;
61
+ }
62
+ else {
63
+ blockedByDependencies++;
64
+ }
65
+ }
66
+ // Track dependent counts
67
+ for (const dep of deps) {
68
+ dependentCounts.set(dep.taskId, (dependentCounts.get(dep.taskId) ?? 0) + 1);
69
+ }
70
+ }
71
+ // Find most depended on task
72
+ let mostDependedOn;
73
+ let maxCount = 0;
74
+ for (const [taskId, count] of dependentCounts) {
75
+ if (count > maxCount) {
76
+ maxCount = count;
77
+ const task = tasks.find((t) => t.id === taskId);
78
+ if (task) {
79
+ mostDependedOn = {
80
+ id: taskId,
81
+ title: task.title,
82
+ dependentCount: count,
83
+ };
84
+ }
85
+ }
86
+ }
87
+ return { readyToWork, blockedByDependencies, mostDependedOn };
88
+ }
89
+ // =============================================================================
90
+ // Formatters
91
+ // =============================================================================
92
+ function formatPriority(priority) {
93
+ const colors = {
94
+ critical: c.red,
95
+ high: c.yellow,
96
+ medium: c.blue,
97
+ low: c.gray,
98
+ };
99
+ return (colors[priority] ?? c.gray)(priority);
100
+ }
101
+ function getTimeAgo(date) {
102
+ const now = new Date();
103
+ const diffMs = now.getTime() - date.getTime();
104
+ const diffMins = Math.floor(diffMs / 60000);
105
+ const diffHours = Math.floor(diffMins / 60);
106
+ const diffDays = Math.floor(diffHours / 24);
107
+ if (diffMins < 60)
108
+ return `${diffMins}m ago`;
109
+ if (diffHours < 24)
110
+ return `${diffHours}h ago`;
111
+ if (diffDays < 7)
112
+ return `${diffDays}d ago`;
113
+ return date.toLocaleDateString();
114
+ }
115
+ // =============================================================================
116
+ // Widget Renderers
117
+ // =============================================================================
118
+ /**
119
+ * Render Status widget (progress, counts, priorities, dependencies)
120
+ */
121
+ export function renderStatusWidget(tasks, _projects) {
122
+ const stats = calculateStats(tasks);
123
+ const depMetrics = calculateDependencyMetrics(tasks);
124
+ const today = getTodayTasks(tasks);
125
+ const overdue = getOverdueTasks(tasks);
126
+ const activeTasks = stats.total - stats.cancelled;
127
+ const percent = activeTasks > 0 ? Math.round((stats.completed / activeTasks) * 100) : 0;
128
+ const lines = [];
129
+ // Progress bar with fraction
130
+ const bar = progressBar(stats.completed, activeTasks, { width: 24 });
131
+ lines.push(`${bar} ${c.bold(`${percent}%`)} ${stats.completed}/${activeTasks} tasks`);
132
+ lines.push("");
133
+ // Status counts
134
+ lines.push(`${c.green("Done")}: ${stats.completed} ` +
135
+ `${c.blue("Progress")}: ${stats.inProgress} ` +
136
+ `${c.yellow("Pending")}: ${stats.pending} ` +
137
+ `${c.red("Blocked")}: ${stats.blocked}`);
138
+ // Schedule info
139
+ const scheduleInfo = [];
140
+ if (overdue.length > 0)
141
+ scheduleInfo.push(c.red(`Overdue: ${overdue.length}`));
142
+ if (today.length > 0)
143
+ scheduleInfo.push(c.yellow(`Today: ${today.length}`));
144
+ if (scheduleInfo.length > 0) {
145
+ lines.push(scheduleInfo.join(" "));
146
+ }
147
+ lines.push("");
148
+ // Priority breakdown
149
+ lines.push(`${c.red("Critical")}: ${stats.byPriority.critical} ` +
150
+ `${c.yellow("High")}: ${stats.byPriority.high} ` +
151
+ `${c.blue("Medium")}: ${stats.byPriority.medium} ` +
152
+ `${c.gray("Low")}: ${stats.byPriority.low}`);
153
+ // Dependencies summary
154
+ lines.push(`${c.green("Ready")}: ${depMetrics.readyToWork} ` +
155
+ `${c.red("Blocked")}: ${depMetrics.blockedByDependencies}` +
156
+ (depMetrics.mostDependedOn
157
+ ? ` ${c.dim("Bottleneck:")} ${truncateStr(depMetrics.mostDependedOn.title, 15)}`
158
+ : ""));
159
+ return box(lines.join("\n"), {
160
+ title: "Status",
161
+ borderColor: "cyan",
162
+ padding: 1,
163
+ });
164
+ }
165
+ /**
166
+ * Render Next Actions widget (top ready tasks)
167
+ */
168
+ export function renderActionsWidget(tasks) {
169
+ const lines = [];
170
+ // Get top 4 ready tasks sorted by priority
171
+ const readyTasks = tasks
172
+ .filter((t) => t.status === "pending" &&
173
+ (!t.dependencies || t.dependencies.length === 0))
174
+ .sort((a, b) => {
175
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
176
+ return ((priorityOrder[a.priority] ?? 2) - (priorityOrder[b.priority] ?? 2));
177
+ })
178
+ .slice(0, 4);
179
+ if (readyTasks.length > 0) {
180
+ for (const task of readyTasks) {
181
+ const deps = task.dependencies?.length ?? 0;
182
+ const depsInfo = deps > 0 ? `${deps} deps` : c.green("ready");
183
+ lines.push(`${c.cyan("→")} ${truncateStr(task.title, 24)}`);
184
+ lines.push(` ${formatPriority(task.priority)}, ${depsInfo}`);
185
+ }
186
+ }
187
+ else {
188
+ lines.push(c.dim("No tasks ready"));
189
+ }
190
+ return box(lines.join("\n"), {
191
+ title: "Next Actions",
192
+ borderColor: "green",
193
+ padding: 1,
194
+ });
195
+ }
196
+ /**
197
+ * Render Inbox widget (pending items)
198
+ */
199
+ export function renderInboxWidget(inboxItems) {
200
+ const pendingItems = inboxItems.filter((item) => item.status === "pending");
201
+ if (pendingItems.length === 0) {
202
+ return null;
203
+ }
204
+ const lines = [];
205
+ lines.push(`${c.yellow("Pending")}: ${pendingItems.length} items`);
206
+ lines.push("");
207
+ // Show up to 3 items
208
+ for (const item of pendingItems.slice(0, 3)) {
209
+ const date = new Date(item.capturedAt);
210
+ const ago = getTimeAgo(date);
211
+ const tags = item.tags?.length ? c.dim(` #${item.tags[0]}`) : "";
212
+ lines.push(`${c.yellow("○")} ${truncateStr(item.content, 40)}${tags}`);
213
+ lines.push(` ${c.dim(ago)}`);
214
+ }
215
+ if (pendingItems.length > 3) {
216
+ lines.push(c.gray(`+${pendingItems.length - 3} more`));
217
+ }
218
+ return box(lines.join("\n"), {
219
+ title: "Inbox",
220
+ borderColor: "yellow",
221
+ padding: 1,
222
+ });
223
+ }
224
+ /**
225
+ * Render Projects table
226
+ */
227
+ export function renderProjectsTable(projects, getProjectTasks) {
228
+ if (projects.length === 0) {
229
+ return c.gray("No projects found.");
230
+ }
231
+ const rows = [];
232
+ for (const project of projects.slice(0, 10)) {
233
+ const tasks = getProjectTasks(project.id);
234
+ const stats = calculateStats(tasks);
235
+ const depMetrics = calculateDependencyMetrics(tasks);
236
+ const activeTasks = stats.total - stats.cancelled;
237
+ const percent = activeTasks > 0
238
+ ? Math.round((stats.completed / activeTasks) * 100)
239
+ : 0;
240
+ // Create mini progress bar
241
+ const barWidth = 8;
242
+ const filled = Math.round((percent / 100) * barWidth);
243
+ const empty = barWidth - filled;
244
+ const miniBar = c.green("█".repeat(filled)) + c.gray("░".repeat(empty));
245
+ rows.push({
246
+ name: truncateStr(project.name, 20),
247
+ progress: `${miniBar} ${pad(String(percent) + "%", 4, "right")}`,
248
+ ready: depMetrics.readyToWork,
249
+ blocked: depMetrics.blockedByDependencies,
250
+ total: activeTasks,
251
+ });
252
+ }
253
+ const columns = [
254
+ { key: "name", header: "Project", width: 22 },
255
+ { key: "progress", header: "Progress", width: 16 },
256
+ { key: "total", header: "Tasks", width: 6, align: "right" },
257
+ {
258
+ key: "ready",
259
+ header: "Ready",
260
+ width: 6,
261
+ align: "right",
262
+ format: (v) => c.green(String(v)),
263
+ },
264
+ {
265
+ key: "blocked",
266
+ header: "Blocked",
267
+ width: 8,
268
+ align: "right",
269
+ format: (v) => (Number(v) > 0 ? c.red(String(v)) : c.gray(String(v))),
270
+ },
271
+ ];
272
+ return table(rows, columns);
273
+ }
274
+ /**
275
+ * Render Tasks table for single project view
276
+ */
277
+ export function renderTasksTable(tasks, limit = 10) {
278
+ const activeTasks = tasks.filter((t) => t.status !== "completed" && t.status !== "cancelled");
279
+ if (activeTasks.length === 0) {
280
+ return c.gray("No active tasks.");
281
+ }
282
+ const displayTasks = activeTasks.slice(0, limit);
283
+ const columns = [
284
+ { key: "title", header: "Title", width: 40 },
285
+ {
286
+ key: "status",
287
+ header: "Status",
288
+ width: 12,
289
+ format: (v) => {
290
+ const icon = icons[v] ?? icons.pending;
291
+ return `${icon} ${v}`;
292
+ },
293
+ },
294
+ {
295
+ key: "priority",
296
+ header: "Priority",
297
+ width: 10,
298
+ format: (v) => formatPriority(v),
299
+ },
300
+ ];
301
+ let result = table(displayTasks, columns);
302
+ if (activeTasks.length > limit) {
303
+ result += `\n${c.gray(`(+${activeTasks.length - limit} more tasks)`)}`;
304
+ }
305
+ return result;
306
+ }
307
+ // =============================================================================
308
+ // Date Helpers
309
+ // =============================================================================
310
+ function getTodayTasks(tasks) {
311
+ const today = new Date().toISOString().split("T")[0];
312
+ return tasks.filter((t) => t.dueDate === today &&
313
+ t.status !== "completed" &&
314
+ t.status !== "cancelled");
315
+ }
316
+ function getOverdueTasks(tasks) {
317
+ const today = new Date().toISOString().split("T")[0];
318
+ return tasks.filter((t) => t.dueDate &&
319
+ t.dueDate < today &&
320
+ t.status !== "completed" &&
321
+ t.status !== "cancelled");
322
+ }
323
+ /**
324
+ * Render full dashboard (CLI and MCP compatible)
325
+ */
326
+ export function renderDashboard(data, getProjectTasks, options = {}) {
327
+ const { showBanner = true, showInbox = true, showProjects = true, showTasks = true, stripAnsiCodes = false, } = options;
328
+ const { tasks, projects, inboxItems = [], currentProject, version } = data;
329
+ const lines = [];
330
+ // Banner
331
+ if (showBanner) {
332
+ lines.push("");
333
+ lines.push(banner("TASK MCP"));
334
+ lines.push("");
335
+ }
336
+ // Project info header
337
+ const projectInfo = currentProject
338
+ ? `${c.bold("Project:")} ${currentProject.name}`
339
+ : `${c.bold("All Projects")} (${projects.length} projects)`;
340
+ if (version) {
341
+ lines.push(c.dim(`v${version} ${projectInfo}`));
342
+ }
343
+ else {
344
+ lines.push(projectInfo);
345
+ }
346
+ lines.push("");
347
+ // Status + Actions widgets side by side
348
+ const statusWidget = renderStatusWidget(tasks, projects);
349
+ const actionsWidget = renderActionsWidget(tasks);
350
+ lines.push(sideBySide([statusWidget, actionsWidget], 2));
351
+ lines.push("");
352
+ // Inbox widget
353
+ if (showInbox && inboxItems.length > 0) {
354
+ const inboxWidget = renderInboxWidget(inboxItems);
355
+ if (inboxWidget) {
356
+ lines.push(inboxWidget);
357
+ lines.push("");
358
+ }
359
+ }
360
+ // Projects table (only for all-projects view)
361
+ if (showProjects && !currentProject && projects.length > 1) {
362
+ lines.push(c.bold("Projects"));
363
+ lines.push("");
364
+ lines.push(renderProjectsTable(projects, getProjectTasks));
365
+ lines.push("");
366
+ }
367
+ // Tasks table (for single project view)
368
+ if (showTasks && (currentProject || projects.length === 1)) {
369
+ const activeTasks = tasks.filter((t) => t.status !== "completed" && t.status !== "cancelled");
370
+ if (activeTasks.length > 0) {
371
+ lines.push(c.bold(`Tasks (${activeTasks.length})`));
372
+ lines.push("");
373
+ lines.push(renderTasksTable(tasks));
374
+ }
375
+ }
376
+ lines.push("");
377
+ const output = lines.join("\n");
378
+ return stripAnsiCodes ? stripAnsi(output) : output;
379
+ }
380
+ /**
381
+ * Render single project dashboard
382
+ */
383
+ export function renderProjectDashboard(project, tasks, options = {}) {
384
+ const data = {
385
+ tasks,
386
+ projects: [project],
387
+ currentProject: project,
388
+ version: options.version,
389
+ };
390
+ return renderDashboard(data, () => tasks, {
391
+ showBanner: true,
392
+ showInbox: false,
393
+ showProjects: false,
394
+ showTasks: true,
395
+ stripAnsiCodes: options.stripAnsiCodes,
396
+ });
397
+ }
398
+ /**
399
+ * Render global dashboard (all projects)
400
+ */
401
+ export function renderGlobalDashboard(projects, allTasks, inboxItems, getProjectTasks, options = {}) {
402
+ const data = {
403
+ tasks: allTasks,
404
+ projects,
405
+ inboxItems,
406
+ version: options.version,
407
+ };
408
+ return renderDashboard(data, getProjectTasks, {
409
+ showBanner: true,
410
+ showInbox: true,
411
+ showProjects: true,
412
+ showTasks: projects.length === 1,
413
+ stripAnsiCodes: options.stripAnsiCodes,
414
+ });
415
+ }
416
+ //# sourceMappingURL=dashboard-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-renderer.js","sourceRoot":"","sources":["../../src/utils/dashboard-renderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,CAAC,EACD,GAAG,EACH,WAAW,EACX,KAAK,EACL,KAAK,EACL,UAAU,EACV,WAAW,EACX,GAAG,EACH,MAAM,EACN,SAAS,GAEV,MAAM,kBAAkB,CAAC;AAuC1B,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,KAAK,GAAmB;QAC5B,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;KACxD,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,WAAW;gBACd,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClB,MAAM;YACR,KAAK,aAAa;gBAChB,KAAK,CAAC,UAAU,EAAE,CAAC;gBACnB,MAAM;YACR,KAAK,SAAS;gBACZ,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,MAAM;YACR,KAAK,SAAS;gBACZ,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,MAAM;YACR,KAAK,WAAW;gBACd,KAAK,CAAC,SAAS,EAAE,CAAC;gBAClB,MAAM;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC;QAC3C,IAAI,QAAQ,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACjC,KAAK,CAAC,UAAU,CAAC,QAAyC,CAAC,EAAE,CAAC;QAChE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAAa;IACtD,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC/D,CAAC;IAEF,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,qBAAqB,GAAG,CAAC,CAAC;IAE9B,iCAAiC;IACjC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAElD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW;YAAE,SAAS;QAEzE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,WAAW,EAAE,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACnE,IAAI,YAAY,EAAE,CAAC;gBACjB,WAAW,EAAE,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACN,qBAAqB,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,yBAAyB;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,eAAe,CAAC,GAAG,CACjB,GAAG,CAAC,MAAM,EACV,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,cAAmD,CAAC;IACxD,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,eAAe,EAAE,CAAC;QAC9C,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;YACrB,QAAQ,GAAG,KAAK,CAAC;YACjB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;YAChD,IAAI,IAAI,EAAE,CAAC;gBACT,cAAc,GAAG;oBACf,EAAE,EAAE,MAAM;oBACV,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,cAAc,EAAE,KAAK;iBACtB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,cAAc,EAAE,CAAC;AAChE,CAAC;AAED,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,SAAS,cAAc,CAAC,QAA0B;IAChD,MAAM,MAAM,GAA0C;QACpD,QAAQ,EAAE,CAAC,CAAC,GAAG;QACf,IAAI,EAAE,CAAC,CAAC,MAAM;QACd,MAAM,EAAE,CAAC,CAAC,IAAI;QACd,GAAG,EAAE,CAAC,CAAC,IAAI;KACZ,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,UAAU,CAAC,IAAU;IAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;IAE5C,IAAI,QAAQ,GAAG,EAAE;QAAE,OAAO,GAAG,QAAQ,OAAO,CAAC;IAC7C,IAAI,SAAS,GAAG,EAAE;QAAE,OAAO,GAAG,SAAS,OAAO,CAAC;IAC/C,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO,GAAG,QAAQ,OAAO,CAAC;IAC5C,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC;AACnC,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,SAAoB;IAEpB,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;IAClD,MAAM,OAAO,GACX,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1E,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,6BAA6B;IAC7B,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IACrE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,CAAC,SAAS,IAAI,WAAW,QAAQ,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,gBAAgB;IAChB,KAAK,CAAC,IAAI,CACR,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,SAAS,IAAI;QACxC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC,UAAU,IAAI;QAC9C,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,OAAO,IAAI;QAC5C,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAC1C,CAAC;IAEF,gBAAgB;IAChB,MAAM,YAAY,GAAG,EAAE,CAAC;IACxB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC/E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,qBAAqB;IACrB,KAAK,CAAC,IAAI,CACR,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,QAAQ,IAAI;QACpD,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI;QACjD,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI;QACnD,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,CAC9C,CAAC;IAEF,uBAAuB;IACvB,KAAK,CAAC,IAAI,CACR,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,UAAU,CAAC,WAAW,IAAI;QAChD,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,UAAU,CAAC,qBAAqB,EAAE;QAC1D,CAAC,UAAU,CAAC,cAAc;YACxB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE;YACjF,CAAC,CAAC,EAAE,CAAC,CACV,CAAC;IAEF,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC3B,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,MAAM;QACnB,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,2CAA2C;IAC3C,MAAM,UAAU,GAAG,KAAK;SACrB,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,MAAM,KAAK,SAAS;QACtB,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CACnD;SACA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,MAAM,aAAa,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAClE,OAAO,CACL,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CACpE,CAAC;IACJ,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEf,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC3B,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAuB;IACvD,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAE5E,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,YAAY,CAAC,MAAM,QAAQ,CAAC,CAAC;IACnE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,qBAAqB;IACrB,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QACvE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC3B,KAAK,EAAE,OAAO;QACd,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAmB,EACnB,eAA8C;IAE9C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,IAAI,GAMJ,EAAE,CAAC;IAET,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;QAClD,MAAM,OAAO,GACX,WAAW,GAAG,CAAC;YACb,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC;YACnD,CAAC,CAAC,CAAC,CAAC;QAER,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,CAAC,CAAC;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAChC,MAAM,OAAO,GACX,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAE1D,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACnC,QAAQ,EAAE,GAAG,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE;YAChE,KAAK,EAAE,UAAU,CAAC,WAAW;YAC7B,OAAO,EAAE,UAAU,CAAC,qBAAqB;YACzC,KAAK,EAAE,WAAW;SACnB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAkB;QAC7B,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;QAC7C,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE;QAClD,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE;QAC3D;YACE,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,OAAO;YACf,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SAClC;QACD;YACE,GAAG,EAAE,SAAS;YACd,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;SACtE;KACF,CAAC;IAEF,OAAO,KAAK,CAAC,IAA4C,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,QAAgB,EAAE;IAChE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,CAC5D,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEjD,MAAM,OAAO,GAAkB;QAC7B,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5C;YACE,GAAG,EAAE,QAAQ;YACb,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;gBACZ,MAAM,IAAI,GAAG,KAAK,CAAC,CAAmB,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC;gBACzD,OAAO,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;YACxB,CAAC;SACF;QACD;YACE,GAAG,EAAE,UAAU;YACf,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAqB,CAAC;SACrD;KACF,CAAC;IAEF,IAAI,MAAM,GAAG,KAAK,CAChB,YAAoD,EACpD,OAAO,CACR,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC,MAAM,GAAG,KAAK,cAAc,CAAC,EAAE,CAAC;IACzE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,MAAM,CACjB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,OAAO,KAAK,KAAK;QACnB,CAAC,CAAC,MAAM,KAAK,WAAW;QACxB,CAAC,CAAC,MAAM,KAAK,WAAW,CAC3B,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,MAAM,CACjB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,GAAG,KAAK;QACjB,CAAC,CAAC,MAAM,KAAK,WAAW;QACxB,CAAC,CAAC,MAAM,KAAK,WAAW,CAC3B,CAAC;AACJ,CAAC;AAcD;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAmB,EACnB,eAA8C,EAC9C,UAAkC,EAAE;IAEpC,MAAM,EACJ,UAAU,GAAG,IAAI,EACjB,SAAS,GAAG,IAAI,EAChB,YAAY,GAAG,IAAI,EACnB,SAAS,GAAG,IAAI,EAChB,cAAc,GAAG,KAAK,GACvB,GAAG,OAAO,CAAC;IAEZ,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,GAAG,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3E,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,SAAS;IACT,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,sBAAsB;IACtB,MAAM,WAAW,GAAG,cAAc;QAChC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,cAAc,CAAC,IAAI,EAAE;QAChD,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,QAAQ,CAAC,MAAM,YAAY,CAAC;IAE9D,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,wCAAwC;IACxC,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,eAAe;IACf,IAAI,SAAS,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,YAAY,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,wCAAwC;IACxC,IAAI,SAAS,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,CAC5D,CAAC;QACF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAgB,EAChB,KAAa,EACb,UAA0D,EAAE;IAE5D,MAAM,IAAI,GAAkB;QAC1B,KAAK;QACL,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,cAAc,EAAE,OAAO;QACvB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,OAAO,eAAe,CACpB,IAAI,EACJ,GAAG,EAAE,CAAC,KAAK,EACX;QACE,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,IAAI;QACf,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAmB,EACnB,QAAgB,EAChB,UAAuB,EACvB,eAA8C,EAC9C,UAA0D,EAAE;IAE5D,MAAM,IAAI,GAAkB;QAC1B,KAAK,EAAE,QAAQ;QACf,QAAQ;QACR,UAAU;QACV,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;IAEF,OAAO,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE;QAC5C,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;QAChC,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;AACL,CAAC"}
@@ -3,5 +3,6 @@ export { now, parseRelativeDate, formatDate, formatDisplayDate, isToday, isPastD
3
3
  export { parseTaskInput, parseInboxInput, parseInput, type ParseTarget, type ParsedInput } from "./natural-language.js";
4
4
  export { MAX_HIERARCHY_DEPTH, getTaskLevel, validateHierarchyDepth, getAncestorIds, getDescendantIds, getChildTasks, getRootTask, buildTaskTree, type TaskTreeNode, } from "./hierarchy.js";
5
5
  export { projectTask, projectTasks, projectTasksPaginated, projectProject, projectProjects, projectInboxItem, projectInboxItems, formatResponse, applyPagination, truncate, summarizeList, } from "./projection.js";
6
+ export { calculateStats, calculateDependencyMetrics, renderStatusWidget, renderActionsWidget, renderInboxWidget, renderProjectsTable, renderTasksTable, renderDashboard, renderProjectDashboard, renderGlobalDashboard, type DashboardStats, type DependencyMetrics, type DashboardData, type RenderDashboardOptions, } from "./dashboard-renderer.js";
6
7
  export { color, style, styled, c, BOX, box, drawBox, hline, stripAnsi, displayWidth, visibleLength, pad, padEnd, padStart, center, truncateStr, progressBar, type ProgressBarOptions, sideBySide, sideBySideArrays, type BoxOptions, table, renderTable, type TableColumn, statusColors, statusIcons, icons, formatStatus, priorityColors, formatPriority, formatDependencies, banner, } from "./terminal-ui.js";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,EAEd,cAAc,EACd,KAAK,kBAAkB,EACvB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACxH,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,KAAK,EACL,KAAK,EACL,MAAM,EACN,CAAC,EAED,GAAG,EACH,GAAG,EACH,OAAO,EACP,KAAK,EAEL,SAAS,EACT,YAAY,EACZ,aAAa,EACb,GAAG,EACH,MAAM,EACN,QAAQ,EACR,MAAM,EACN,WAAW,EAEX,WAAW,EACX,KAAK,kBAAkB,EAEvB,UAAU,EACV,gBAAgB,EAChB,KAAK,UAAU,EAEf,KAAK,EACL,WAAW,EACX,KAAK,WAAW,EAEhB,YAAY,EACZ,WAAW,EACX,KAAK,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB,EAElB,MAAM,GACP,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc,EAEd,cAAc,EACd,KAAK,kBAAkB,EACvB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACxH,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,EACb,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,aAAa,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAEL,KAAK,EACL,KAAK,EACL,MAAM,EACN,CAAC,EAED,GAAG,EACH,GAAG,EACH,OAAO,EACP,KAAK,EAEL,SAAS,EACT,YAAY,EACZ,aAAa,EACb,GAAG,EACH,MAAM,EACN,QAAQ,EACR,MAAM,EACN,WAAW,EAEX,WAAW,EACX,KAAK,kBAAkB,EAEvB,UAAU,EACV,gBAAgB,EAChB,KAAK,UAAU,EAEf,KAAK,EACL,WAAW,EACX,KAAK,WAAW,EAEhB,YAAY,EACZ,WAAW,EACX,KAAK,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB,EAElB,MAAM,GACP,MAAM,kBAAkB,CAAC"}
@@ -6,6 +6,8 @@ export { parseTaskInput, parseInboxInput, parseInput } from "./natural-language.
6
6
  export { MAX_HIERARCHY_DEPTH, getTaskLevel, validateHierarchyDepth, getAncestorIds, getDescendantIds, getChildTasks, getRootTask, buildTaskTree, } from "./hierarchy.js";
7
7
  // Projection utilities (token optimization)
8
8
  export { projectTask, projectTasks, projectTasksPaginated, projectProject, projectProjects, projectInboxItem, projectInboxItems, formatResponse, applyPagination, truncate, summarizeList, } from "./projection.js";
9
+ // Dashboard renderer
10
+ export { calculateStats, calculateDependencyMetrics, renderStatusWidget, renderActionsWidget, renderInboxWidget, renderProjectsTable, renderTasksTable, renderDashboard, renderProjectDashboard, renderGlobalDashboard, } from "./dashboard-renderer.js";
9
11
  // Terminal UI utilities
10
12
  export {
11
13
  // Colors and styles
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc;AACd,uDAAuD;AACvD,cAAc,EAEd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAsC,MAAM,uBAAuB,CAAC;AACxH,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,GAEd,MAAM,gBAAgB,CAAC;AAExB,4CAA4C;AAC5C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,wBAAwB;AACxB,OAAO;AACL,oBAAoB;AACpB,KAAK,EACL,KAAK,EACL,MAAM,EACN,CAAC;AACD,cAAc;AACd,GAAG,EACH,GAAG,EACH,OAAO,EACP,KAAK;AACL,mBAAmB;AACnB,SAAS,EACT,YAAY,EACZ,aAAa,EACb,GAAG,EACH,MAAM,EACN,QAAQ,EACR,MAAM,EACN,WAAW;AACX,eAAe;AACf,WAAW;AAEX,SAAS;AACT,UAAU,EACV,gBAAgB;AAEhB,SAAS;AACT,KAAK,EACL,WAAW;AAEX,aAAa;AACb,YAAY,EACZ,WAAW,EACX,KAAK,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB;AAClB,SAAS;AACT,MAAM,GACP,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,cAAc;AACd,uDAAuD;AACvD,cAAc,EAEd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAsC,MAAM,uBAAuB,CAAC;AACxH,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,GAEd,MAAM,gBAAgB,CAAC;AAExB,4CAA4C;AAC5C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,QAAQ,EACR,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,GAKtB,MAAM,yBAAyB,CAAC;AAEjC,wBAAwB;AACxB,OAAO;AACL,oBAAoB;AACpB,KAAK,EACL,KAAK,EACL,MAAM,EACN,CAAC;AACD,cAAc;AACd,GAAG,EACH,GAAG,EACH,OAAO,EACP,KAAK;AACL,mBAAmB;AACnB,SAAS,EACT,YAAY,EACZ,aAAa,EACb,GAAG,EACH,MAAM,EACN,QAAQ,EACR,MAAM,EACN,WAAW;AACX,eAAe;AACf,WAAW;AAEX,SAAS;AACT,UAAU,EACV,gBAAgB;AAEhB,SAAS;AACT,KAAK,EACL,WAAW;AAEX,aAAa;AACb,YAAY,EACZ,WAAW,EACX,KAAK,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB;AAClB,SAAS;AACT,MAAM,GACP,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@task-mcp/shared",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Shared utilities for task-mcp: types, algorithms, and natural language parsing",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -0,0 +1,606 @@
1
+ /**
2
+ * Shared dashboard renderer for CLI and MCP server
3
+ * Provides consistent dashboard layout across all interfaces
4
+ */
5
+
6
+ import type { Task, Project, InboxItem } from "../schemas/index.js";
7
+ import {
8
+ c,
9
+ box,
10
+ progressBar,
11
+ table,
12
+ icons,
13
+ sideBySide,
14
+ truncateStr,
15
+ pad,
16
+ banner,
17
+ stripAnsi,
18
+ type TableColumn,
19
+ } from "./terminal-ui.js";
20
+
21
+ // =============================================================================
22
+ // Types
23
+ // =============================================================================
24
+
25
+ export interface DashboardStats {
26
+ total: number;
27
+ completed: number;
28
+ inProgress: number;
29
+ pending: number;
30
+ blocked: number;
31
+ cancelled: number;
32
+ byPriority: {
33
+ critical: number;
34
+ high: number;
35
+ medium: number;
36
+ low: number;
37
+ };
38
+ }
39
+
40
+ export interface DependencyMetrics {
41
+ readyToWork: number;
42
+ blockedByDependencies: number;
43
+ mostDependedOn?: {
44
+ id: string;
45
+ title: string;
46
+ dependentCount: number;
47
+ } | undefined;
48
+ }
49
+
50
+ export interface DashboardData {
51
+ tasks: Task[];
52
+ projects: Project[];
53
+ inboxItems?: InboxItem[] | undefined;
54
+ currentProject?: Project | undefined;
55
+ version?: string | undefined;
56
+ }
57
+
58
+ // =============================================================================
59
+ // Statistics Calculators
60
+ // =============================================================================
61
+
62
+ export function calculateStats(tasks: Task[]): DashboardStats {
63
+ const stats: DashboardStats = {
64
+ total: tasks.length,
65
+ completed: 0,
66
+ inProgress: 0,
67
+ pending: 0,
68
+ blocked: 0,
69
+ cancelled: 0,
70
+ byPriority: { critical: 0, high: 0, medium: 0, low: 0 },
71
+ };
72
+
73
+ for (const task of tasks) {
74
+ switch (task.status) {
75
+ case "completed":
76
+ stats.completed++;
77
+ break;
78
+ case "in_progress":
79
+ stats.inProgress++;
80
+ break;
81
+ case "pending":
82
+ stats.pending++;
83
+ break;
84
+ case "blocked":
85
+ stats.blocked++;
86
+ break;
87
+ case "cancelled":
88
+ stats.cancelled++;
89
+ break;
90
+ }
91
+
92
+ const priority = task.priority ?? "medium";
93
+ if (priority in stats.byPriority) {
94
+ stats.byPriority[priority as keyof typeof stats.byPriority]++;
95
+ }
96
+ }
97
+
98
+ return stats;
99
+ }
100
+
101
+ export function calculateDependencyMetrics(tasks: Task[]): DependencyMetrics {
102
+ const completedIds = new Set(
103
+ tasks.filter((t) => t.status === "completed").map((t) => t.id)
104
+ );
105
+
106
+ let readyToWork = 0;
107
+ let blockedByDependencies = 0;
108
+
109
+ // Count dependents for each task
110
+ const dependentCounts = new Map<string, number>();
111
+
112
+ for (const task of tasks) {
113
+ if (task.status === "completed" || task.status === "cancelled") continue;
114
+
115
+ const deps = task.dependencies ?? [];
116
+ if (deps.length === 0) {
117
+ readyToWork++;
118
+ } else {
119
+ const allSatisfied = deps.every((d) => completedIds.has(d.taskId));
120
+ if (allSatisfied) {
121
+ readyToWork++;
122
+ } else {
123
+ blockedByDependencies++;
124
+ }
125
+ }
126
+
127
+ // Track dependent counts
128
+ for (const dep of deps) {
129
+ dependentCounts.set(
130
+ dep.taskId,
131
+ (dependentCounts.get(dep.taskId) ?? 0) + 1
132
+ );
133
+ }
134
+ }
135
+
136
+ // Find most depended on task
137
+ let mostDependedOn: DependencyMetrics["mostDependedOn"];
138
+ let maxCount = 0;
139
+
140
+ for (const [taskId, count] of dependentCounts) {
141
+ if (count > maxCount) {
142
+ maxCount = count;
143
+ const task = tasks.find((t) => t.id === taskId);
144
+ if (task) {
145
+ mostDependedOn = {
146
+ id: taskId,
147
+ title: task.title,
148
+ dependentCount: count,
149
+ };
150
+ }
151
+ }
152
+ }
153
+
154
+ return { readyToWork, blockedByDependencies, mostDependedOn };
155
+ }
156
+
157
+ // =============================================================================
158
+ // Formatters
159
+ // =============================================================================
160
+
161
+ function formatPriority(priority: Task["priority"]): string {
162
+ const colors: Record<string, (s: string) => string> = {
163
+ critical: c.red,
164
+ high: c.yellow,
165
+ medium: c.blue,
166
+ low: c.gray,
167
+ };
168
+ return (colors[priority] ?? c.gray)(priority);
169
+ }
170
+
171
+ function getTimeAgo(date: Date): string {
172
+ const now = new Date();
173
+ const diffMs = now.getTime() - date.getTime();
174
+ const diffMins = Math.floor(diffMs / 60000);
175
+ const diffHours = Math.floor(diffMins / 60);
176
+ const diffDays = Math.floor(diffHours / 24);
177
+
178
+ if (diffMins < 60) return `${diffMins}m ago`;
179
+ if (diffHours < 24) return `${diffHours}h ago`;
180
+ if (diffDays < 7) return `${diffDays}d ago`;
181
+ return date.toLocaleDateString();
182
+ }
183
+
184
+ // =============================================================================
185
+ // Widget Renderers
186
+ // =============================================================================
187
+
188
+ /**
189
+ * Render Status widget (progress, counts, priorities, dependencies)
190
+ */
191
+ export function renderStatusWidget(
192
+ tasks: Task[],
193
+ _projects: Project[]
194
+ ): string {
195
+ const stats = calculateStats(tasks);
196
+ const depMetrics = calculateDependencyMetrics(tasks);
197
+ const today = getTodayTasks(tasks);
198
+ const overdue = getOverdueTasks(tasks);
199
+ const activeTasks = stats.total - stats.cancelled;
200
+ const percent =
201
+ activeTasks > 0 ? Math.round((stats.completed / activeTasks) * 100) : 0;
202
+
203
+ const lines: string[] = [];
204
+
205
+ // Progress bar with fraction
206
+ const bar = progressBar(stats.completed, activeTasks, { width: 24 });
207
+ lines.push(`${bar} ${c.bold(`${percent}%`)} ${stats.completed}/${activeTasks} tasks`);
208
+ lines.push("");
209
+
210
+ // Status counts
211
+ lines.push(
212
+ `${c.green("Done")}: ${stats.completed} ` +
213
+ `${c.blue("Progress")}: ${stats.inProgress} ` +
214
+ `${c.yellow("Pending")}: ${stats.pending} ` +
215
+ `${c.red("Blocked")}: ${stats.blocked}`
216
+ );
217
+
218
+ // Schedule info
219
+ const scheduleInfo = [];
220
+ if (overdue.length > 0) scheduleInfo.push(c.red(`Overdue: ${overdue.length}`));
221
+ if (today.length > 0) scheduleInfo.push(c.yellow(`Today: ${today.length}`));
222
+ if (scheduleInfo.length > 0) {
223
+ lines.push(scheduleInfo.join(" "));
224
+ }
225
+
226
+ lines.push("");
227
+
228
+ // Priority breakdown
229
+ lines.push(
230
+ `${c.red("Critical")}: ${stats.byPriority.critical} ` +
231
+ `${c.yellow("High")}: ${stats.byPriority.high} ` +
232
+ `${c.blue("Medium")}: ${stats.byPriority.medium} ` +
233
+ `${c.gray("Low")}: ${stats.byPriority.low}`
234
+ );
235
+
236
+ // Dependencies summary
237
+ lines.push(
238
+ `${c.green("Ready")}: ${depMetrics.readyToWork} ` +
239
+ `${c.red("Blocked")}: ${depMetrics.blockedByDependencies}` +
240
+ (depMetrics.mostDependedOn
241
+ ? ` ${c.dim("Bottleneck:")} ${truncateStr(depMetrics.mostDependedOn.title, 15)}`
242
+ : "")
243
+ );
244
+
245
+ return box(lines.join("\n"), {
246
+ title: "Status",
247
+ borderColor: "cyan",
248
+ padding: 1,
249
+ });
250
+ }
251
+
252
+ /**
253
+ * Render Next Actions widget (top ready tasks)
254
+ */
255
+ export function renderActionsWidget(tasks: Task[]): string {
256
+ const lines: string[] = [];
257
+
258
+ // Get top 4 ready tasks sorted by priority
259
+ const readyTasks = tasks
260
+ .filter(
261
+ (t) =>
262
+ t.status === "pending" &&
263
+ (!t.dependencies || t.dependencies.length === 0)
264
+ )
265
+ .sort((a, b) => {
266
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
267
+ return (
268
+ (priorityOrder[a.priority] ?? 2) - (priorityOrder[b.priority] ?? 2)
269
+ );
270
+ })
271
+ .slice(0, 4);
272
+
273
+ if (readyTasks.length > 0) {
274
+ for (const task of readyTasks) {
275
+ const deps = task.dependencies?.length ?? 0;
276
+ const depsInfo = deps > 0 ? `${deps} deps` : c.green("ready");
277
+ lines.push(`${c.cyan("→")} ${truncateStr(task.title, 24)}`);
278
+ lines.push(` ${formatPriority(task.priority)}, ${depsInfo}`);
279
+ }
280
+ } else {
281
+ lines.push(c.dim("No tasks ready"));
282
+ }
283
+
284
+ return box(lines.join("\n"), {
285
+ title: "Next Actions",
286
+ borderColor: "green",
287
+ padding: 1,
288
+ });
289
+ }
290
+
291
+ /**
292
+ * Render Inbox widget (pending items)
293
+ */
294
+ export function renderInboxWidget(inboxItems: InboxItem[]): string | null {
295
+ const pendingItems = inboxItems.filter((item) => item.status === "pending");
296
+
297
+ if (pendingItems.length === 0) {
298
+ return null;
299
+ }
300
+
301
+ const lines: string[] = [];
302
+ lines.push(`${c.yellow("Pending")}: ${pendingItems.length} items`);
303
+ lines.push("");
304
+
305
+ // Show up to 3 items
306
+ for (const item of pendingItems.slice(0, 3)) {
307
+ const date = new Date(item.capturedAt);
308
+ const ago = getTimeAgo(date);
309
+ const tags = item.tags?.length ? c.dim(` #${item.tags[0]}`) : "";
310
+ lines.push(`${c.yellow("○")} ${truncateStr(item.content, 40)}${tags}`);
311
+ lines.push(` ${c.dim(ago)}`);
312
+ }
313
+
314
+ if (pendingItems.length > 3) {
315
+ lines.push(c.gray(`+${pendingItems.length - 3} more`));
316
+ }
317
+
318
+ return box(lines.join("\n"), {
319
+ title: "Inbox",
320
+ borderColor: "yellow",
321
+ padding: 1,
322
+ });
323
+ }
324
+
325
+ /**
326
+ * Render Projects table
327
+ */
328
+ export function renderProjectsTable(
329
+ projects: Project[],
330
+ getProjectTasks: (projectId: string) => Task[]
331
+ ): string {
332
+ if (projects.length === 0) {
333
+ return c.gray("No projects found.");
334
+ }
335
+
336
+ const rows: {
337
+ name: string;
338
+ progress: string;
339
+ ready: number;
340
+ blocked: number;
341
+ total: number;
342
+ }[] = [];
343
+
344
+ for (const project of projects.slice(0, 10)) {
345
+ const tasks = getProjectTasks(project.id);
346
+ const stats = calculateStats(tasks);
347
+ const depMetrics = calculateDependencyMetrics(tasks);
348
+ const activeTasks = stats.total - stats.cancelled;
349
+ const percent =
350
+ activeTasks > 0
351
+ ? Math.round((stats.completed / activeTasks) * 100)
352
+ : 0;
353
+
354
+ // Create mini progress bar
355
+ const barWidth = 8;
356
+ const filled = Math.round((percent / 100) * barWidth);
357
+ const empty = barWidth - filled;
358
+ const miniBar =
359
+ c.green("█".repeat(filled)) + c.gray("░".repeat(empty));
360
+
361
+ rows.push({
362
+ name: truncateStr(project.name, 20),
363
+ progress: `${miniBar} ${pad(String(percent) + "%", 4, "right")}`,
364
+ ready: depMetrics.readyToWork,
365
+ blocked: depMetrics.blockedByDependencies,
366
+ total: activeTasks,
367
+ });
368
+ }
369
+
370
+ const columns: TableColumn[] = [
371
+ { key: "name", header: "Project", width: 22 },
372
+ { key: "progress", header: "Progress", width: 16 },
373
+ { key: "total", header: "Tasks", width: 6, align: "right" },
374
+ {
375
+ key: "ready",
376
+ header: "Ready",
377
+ width: 6,
378
+ align: "right",
379
+ format: (v) => c.green(String(v)),
380
+ },
381
+ {
382
+ key: "blocked",
383
+ header: "Blocked",
384
+ width: 8,
385
+ align: "right",
386
+ format: (v) => (Number(v) > 0 ? c.red(String(v)) : c.gray(String(v))),
387
+ },
388
+ ];
389
+
390
+ return table(rows as unknown as Record<string, unknown>[], columns);
391
+ }
392
+
393
+ /**
394
+ * Render Tasks table for single project view
395
+ */
396
+ export function renderTasksTable(tasks: Task[], limit: number = 10): string {
397
+ const activeTasks = tasks.filter(
398
+ (t) => t.status !== "completed" && t.status !== "cancelled"
399
+ );
400
+
401
+ if (activeTasks.length === 0) {
402
+ return c.gray("No active tasks.");
403
+ }
404
+
405
+ const displayTasks = activeTasks.slice(0, limit);
406
+
407
+ const columns: TableColumn[] = [
408
+ { key: "title", header: "Title", width: 40 },
409
+ {
410
+ key: "status",
411
+ header: "Status",
412
+ width: 12,
413
+ format: (v) => {
414
+ const icon = icons[v as Task["status"]] ?? icons.pending;
415
+ return `${icon} ${v}`;
416
+ },
417
+ },
418
+ {
419
+ key: "priority",
420
+ header: "Priority",
421
+ width: 10,
422
+ format: (v) => formatPriority(v as Task["priority"]),
423
+ },
424
+ ];
425
+
426
+ let result = table(
427
+ displayTasks as unknown as Record<string, unknown>[],
428
+ columns
429
+ );
430
+
431
+ if (activeTasks.length > limit) {
432
+ result += `\n${c.gray(`(+${activeTasks.length - limit} more tasks)`)}`;
433
+ }
434
+
435
+ return result;
436
+ }
437
+
438
+ // =============================================================================
439
+ // Date Helpers
440
+ // =============================================================================
441
+
442
+ function getTodayTasks(tasks: Task[]): Task[] {
443
+ const today = new Date().toISOString().split("T")[0];
444
+ return tasks.filter(
445
+ (t) =>
446
+ t.dueDate === today &&
447
+ t.status !== "completed" &&
448
+ t.status !== "cancelled"
449
+ );
450
+ }
451
+
452
+ function getOverdueTasks(tasks: Task[]): Task[] {
453
+ const today = new Date().toISOString().split("T")[0] ?? "";
454
+ return tasks.filter(
455
+ (t) =>
456
+ t.dueDate &&
457
+ t.dueDate < today &&
458
+ t.status !== "completed" &&
459
+ t.status !== "cancelled"
460
+ );
461
+ }
462
+
463
+ // =============================================================================
464
+ // Full Dashboard Renderer
465
+ // =============================================================================
466
+
467
+ export interface RenderDashboardOptions {
468
+ showBanner?: boolean | undefined;
469
+ showInbox?: boolean | undefined;
470
+ showProjects?: boolean | undefined;
471
+ showTasks?: boolean | undefined;
472
+ stripAnsiCodes?: boolean | undefined;
473
+ }
474
+
475
+ /**
476
+ * Render full dashboard (CLI and MCP compatible)
477
+ */
478
+ export function renderDashboard(
479
+ data: DashboardData,
480
+ getProjectTasks: (projectId: string) => Task[],
481
+ options: RenderDashboardOptions = {}
482
+ ): string {
483
+ const {
484
+ showBanner = true,
485
+ showInbox = true,
486
+ showProjects = true,
487
+ showTasks = true,
488
+ stripAnsiCodes = false,
489
+ } = options;
490
+
491
+ const { tasks, projects, inboxItems = [], currentProject, version } = data;
492
+ const lines: string[] = [];
493
+
494
+ // Banner
495
+ if (showBanner) {
496
+ lines.push("");
497
+ lines.push(banner("TASK MCP"));
498
+ lines.push("");
499
+ }
500
+
501
+ // Project info header
502
+ const projectInfo = currentProject
503
+ ? `${c.bold("Project:")} ${currentProject.name}`
504
+ : `${c.bold("All Projects")} (${projects.length} projects)`;
505
+
506
+ if (version) {
507
+ lines.push(c.dim(`v${version} ${projectInfo}`));
508
+ } else {
509
+ lines.push(projectInfo);
510
+ }
511
+ lines.push("");
512
+
513
+ // Status + Actions widgets side by side
514
+ const statusWidget = renderStatusWidget(tasks, projects);
515
+ const actionsWidget = renderActionsWidget(tasks);
516
+ lines.push(sideBySide([statusWidget, actionsWidget], 2));
517
+ lines.push("");
518
+
519
+ // Inbox widget
520
+ if (showInbox && inboxItems.length > 0) {
521
+ const inboxWidget = renderInboxWidget(inboxItems);
522
+ if (inboxWidget) {
523
+ lines.push(inboxWidget);
524
+ lines.push("");
525
+ }
526
+ }
527
+
528
+ // Projects table (only for all-projects view)
529
+ if (showProjects && !currentProject && projects.length > 1) {
530
+ lines.push(c.bold("Projects"));
531
+ lines.push("");
532
+ lines.push(renderProjectsTable(projects, getProjectTasks));
533
+ lines.push("");
534
+ }
535
+
536
+ // Tasks table (for single project view)
537
+ if (showTasks && (currentProject || projects.length === 1)) {
538
+ const activeTasks = tasks.filter(
539
+ (t) => t.status !== "completed" && t.status !== "cancelled"
540
+ );
541
+ if (activeTasks.length > 0) {
542
+ lines.push(c.bold(`Tasks (${activeTasks.length})`));
543
+ lines.push("");
544
+ lines.push(renderTasksTable(tasks));
545
+ }
546
+ }
547
+
548
+ lines.push("");
549
+
550
+ const output = lines.join("\n");
551
+ return stripAnsiCodes ? stripAnsi(output) : output;
552
+ }
553
+
554
+ /**
555
+ * Render single project dashboard
556
+ */
557
+ export function renderProjectDashboard(
558
+ project: Project,
559
+ tasks: Task[],
560
+ options: { stripAnsiCodes?: boolean; version?: string } = {}
561
+ ): string {
562
+ const data: DashboardData = {
563
+ tasks,
564
+ projects: [project],
565
+ currentProject: project,
566
+ version: options.version,
567
+ };
568
+
569
+ return renderDashboard(
570
+ data,
571
+ () => tasks,
572
+ {
573
+ showBanner: true,
574
+ showInbox: false,
575
+ showProjects: false,
576
+ showTasks: true,
577
+ stripAnsiCodes: options.stripAnsiCodes,
578
+ }
579
+ );
580
+ }
581
+
582
+ /**
583
+ * Render global dashboard (all projects)
584
+ */
585
+ export function renderGlobalDashboard(
586
+ projects: Project[],
587
+ allTasks: Task[],
588
+ inboxItems: InboxItem[],
589
+ getProjectTasks: (projectId: string) => Task[],
590
+ options: { stripAnsiCodes?: boolean; version?: string } = {}
591
+ ): string {
592
+ const data: DashboardData = {
593
+ tasks: allTasks,
594
+ projects,
595
+ inboxItems,
596
+ version: options.version,
597
+ };
598
+
599
+ return renderDashboard(data, getProjectTasks, {
600
+ showBanner: true,
601
+ showInbox: true,
602
+ showProjects: true,
603
+ showTasks: projects.length === 1,
604
+ stripAnsiCodes: options.stripAnsiCodes,
605
+ });
606
+ }
@@ -46,6 +46,24 @@ export {
46
46
  summarizeList,
47
47
  } from "./projection.js";
48
48
 
49
+ // Dashboard renderer
50
+ export {
51
+ calculateStats,
52
+ calculateDependencyMetrics,
53
+ renderStatusWidget,
54
+ renderActionsWidget,
55
+ renderInboxWidget,
56
+ renderProjectsTable,
57
+ renderTasksTable,
58
+ renderDashboard,
59
+ renderProjectDashboard,
60
+ renderGlobalDashboard,
61
+ type DashboardStats,
62
+ type DependencyMetrics,
63
+ type DashboardData,
64
+ type RenderDashboardOptions,
65
+ } from "./dashboard-renderer.js";
66
+
49
67
  // Terminal UI utilities
50
68
  export {
51
69
  // Colors and styles