@@ -5,6 +5,10 @@ import inquirer from "inquirer";
55import path from "node:path" ;
66import chalk from "chalk" ;
77import fs from "node:fs" ;
8+ import figures from "figures" ;
9+
10+ /* constants */
11+ import { MAX_TITLE_LENGTH } from "@/constants" ;
812
913/* extras */
1014import {
@@ -15,7 +19,7 @@ import {
1519
1620/* types */
1721import 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