Skip to content

Commit 14ea8eb

Browse files
committed
Merge branch 'dev'
2 parents f4f0f2c + 18d4d85 commit 14ea8eb

6 files changed

Lines changed: 96 additions & 30 deletions

File tree

bun.lock

Lines changed: 4 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"commander": "^14.0.0",
7979
"execa": "^9.6.0",
8080
"figlet": "^1.8.1",
81+
"figures": "^6.1.0",
8182
"inquirer": "^9.2.15",
8283
"node-emoji": "^2.2.0",
8384
"ora": "^8.2.0",

src/@types/index.d.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1 @@
11
export type T_PackageManager = "npm" | "pnpm" | "bun";
2-
export type T_TaskStatus =
3-
| "todo"
4-
| "in-progress"
5-
| "done"
6-
| "blocked"
7-
| "pending";

src/@types/tasks.d.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,8 @@ export interface Task {
2525
subtasks: Subtask[];
2626
}
2727

28-
export enum Priority {
29-
High = "high",
30-
Low = "low",
31-
Medium = "medium",
32-
}
33-
34-
export enum Status {
35-
Pending = "pending",
36-
}
28+
export type Priority = "high" | "medium" | "low";
29+
export type Status = "todo" | "in-progress" | "done" | "blocked" | "pending";
3730

3831
export interface Subtask {
3932
id: number;

src/constants/index.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
/* types */
2-
import type { T_TaskStatus } from "@/@types";
3-
4-
// ===============================
5-
61
// dev
72
export const DEV_MODE = true;
83

@@ -12,10 +7,11 @@ export const PRD_PATH = DEV_MODE ? "docs/PRD-todo.md" : "docs/PRD.md";
127
export const TASKS_PATH = ".taskmaster/tasks/tasks.json";
138

149
// tasks
15-
export const TASKS_STATUSES: T_TaskStatus[] = [
10+
export const TASKS_STATUSES = [
1611
"todo",
1712
"in-progress",
1813
"done",
1914
"blocked",
2015
"pending",
2116
];
17+
export const MAX_TITLE_LENGTH = 50;

src/core/taskmaster/TaskMaster.ts

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import inquirer from "inquirer";
55
import path from "node:path";
66
import chalk from "chalk";
77
import fs from "node:fs";
8+
import figures from "figures";
9+
10+
/* constants */
11+
import { MAX_TITLE_LENGTH } from "@/constants";
812

913
/* extras */
1014
import {
@@ -15,7 +19,7 @@ import {
1519

1620
/* types */
1721
import type { T_PackageManager } from "@/@types/index";
18-
import type { I_Tasks } from "@/@types/tasks";
22+
import type { I_Tasks, Status, Priority } from "@/@types/tasks";
1923

2024
// ===============================
2125

@@ -223,6 +227,87 @@ export class TaskMaster {
223227
// Method for Task Listing and Viewing
224228
// ==============================================
225229

230+
// TODO: validate
231+
/**
232+
* @description Lists tasks in a visually formatted tree structure
233+
* @param tasks Tasks data to render
234+
* @param status Filter tasks by status (comma-separated values)
235+
* @param withSubtasks Whether to include subtasks in the output
236+
*/
237+
public async listQuickAsync(
238+
tasks: I_Tasks,
239+
status: string,
240+
withSubtasks = true,
241+
): Promise<string> {
242+
// Helper to truncate text with ellipsis
243+
const truncate = (text: string, maxLength: number): string =>
244+
text.length <= maxLength ? text : `${text.slice(0, maxLength - 1)}…`;
245+
246+
// Format status with icons and colors for all statuses
247+
const formatStatus = (status: Status): string => {
248+
const statusMap = {
249+
todo: { icon: figures.circle, color: chalk.gray },
250+
"in-progress": { icon: figures.play, color: chalk.yellow },
251+
done: { icon: figures.tick, color: chalk.green },
252+
blocked: { icon: figures.cross, color: chalk.red },
253+
pending: { icon: figures.ellipsis, color: chalk.gray },
254+
};
255+
256+
const config = statusMap[status] || {
257+
icon: figures.circle,
258+
color: chalk.gray,
259+
};
260+
return config.color(`${config.icon} ${status}`);
261+
};
262+
263+
// Format priority with colors
264+
const formatPriority = (priority: Priority): string => {
265+
const colorMap = {
266+
high: chalk.red.bold,
267+
medium: chalk.yellow.bold,
268+
low: chalk.cyan.bold,
269+
};
270+
271+
const colorFn = colorMap[priority] || chalk.white.bold;
272+
return colorFn(priority);
273+
};
274+
275+
// Parse status filter
276+
const statusFilters = status
277+
? status.split(",").map((s) => s.trim() as Status)
278+
: null;
279+
280+
// Build task tree output manually
281+
let output = `${chalk.bold.underline("📋 Liste des Tâches")}\n\n`;
282+
283+
for (const task of tasks.master.tasks) {
284+
// Skip task if status filter doesn't match
285+
if (statusFilters && !statusFilters.includes(task.status)) {
286+
continue;
287+
}
288+
289+
const title = truncate(task.title, MAX_TITLE_LENGTH);
290+
output +=
291+
`${chalk.bgGreen.bold(`#${task.id}`)} ${chalk.magenta(title)} ` +
292+
`[status: ${formatStatus(task.status)}] - ` +
293+
`[priority: ${formatPriority(task.priority)}]\n`;
294+
295+
if (withSubtasks && task.subtasks && task.subtasks.length > 0) {
296+
for (let i = 0; i < task.subtasks.length; i++) {
297+
const subtask = task.subtasks[i];
298+
const subTitle = truncate(subtask.title, MAX_TITLE_LENGTH);
299+
const hierarchicalId = `${task.id}.${i + 1}`;
300+
301+
output +=
302+
` ${chalk.dim("↳")} ${chalk.bold(`#${hierarchicalId}`)} ` +
303+
`${chalk.magenta(subTitle)} [status: ${formatStatus(subtask.status)}]\n`;
304+
}
305+
}
306+
}
307+
308+
return output;
309+
}
310+
226311
// TODO: in-progress
227312
/**
228313
* @description Lists tasks with optional status filtering and subtask display
@@ -241,7 +326,7 @@ export class TaskMaster {
241326
if (withSubtasks) args.push("--with-subtasks");
242327

243328
if (quickly) {
244-
console.log(tasks);
329+
console.log(await this.listQuickAsync(tasks, status, withSubtasks));
245330
} else {
246331
const oraOptions = {
247332
text: "Listing tasks...",

0 commit comments

Comments
 (0)