11/* libs */
22import inquirer from "inquirer" ;
33import path from "node:path" ;
4- import chalk from "chalk" ;
54
65/* constants */
7- import { PRD_PATH , TASKS_PATH , TASKS_STATUSES } from "@/constants" ;
6+ import { TASKS_PATH , TASKS_STATUSES } from "@/constants" ;
87
98/* core */
109import { TaskMaster } from "@/core/taskmaster/TaskMaster" ;
@@ -13,6 +12,19 @@ import { restartAsync } from "@/core/restart";
1312/* utils */
1413import { existsAsync } from "@/utils/extras" ;
1514
15+ /* asks */
16+ import {
17+ askOverwriteConfirmation ,
18+ askPrdPath ,
19+ askNumTasksToGenerate ,
20+ askAdvancedResearchConfirmation ,
21+ askTaskTag ,
22+ askDecompositionConfirmation ,
23+ askStatusSelection ,
24+ askDisplayOptions ,
25+ askTaskIdInput ,
26+ } from "@/core/taskmaster/asks" ;
27+
1628/* prompt */
1729import {
1830 tmaiInitMenu_prompt ,
@@ -32,7 +44,6 @@ const tmai = new TaskMaster({
3244 isTestMode : false ,
3345} ) ;
3446
35- /******* be6e15c7-9970-4578-baf6-d31421004679 *******/
3647// TODO: done
3748export async function tmaiInitAsync ( ) {
3849 const choice = await inquirer . prompt ( tmaiInitMenu_prompt ) ;
@@ -56,67 +67,16 @@ export async function tmaiGenAsync() {
5667 const tasksJsonPath = path . join ( ".taskmaster" , "tasks" , "tasks.json" ) ;
5768
5869 if ( await existsAsync ( tasksJsonPath ) ) {
59- const { overwrite } = await inquirer . prompt ( {
60- type : "confirm" ,
61- name : "overwrite" ,
62- message : chalk . bgYellow (
63- "tasks.json already exists. Do you want to overwrite it?" ,
64- ) ,
65- } ) ;
66-
70+ const overwrite = await askOverwriteConfirmation ( ) ;
6771 if ( ! overwrite ) {
6872 return restartAsync ( ) ;
6973 }
7074 }
7175
72- const { prdPath } = await inquirer . prompt ( {
73- type : "input" ,
74- name : "prdPath" ,
75- message : "Enter the path to your PRD file:" ,
76- default : PRD_PATH ,
77- validate : ( input ) => {
78- const regex = / ^ [ \w \s / ] + (?: \. (?: t x t | m d ) ) $ / ;
79- if ( ! regex . test ( input ) ) {
80- return "Please enter a valid PRD file with .txt or .md extension and without special characters, except for /" ;
81- }
82- return true ;
83- } ,
84- } ) ;
85-
86- const { numTasksToGenerate } = await inquirer . prompt ( {
87- type : "number" ,
88- name : "numTasksToGenerate" ,
89- message : "Enter the number of tasks to generate:" ,
90- validate : ( input ) => {
91- const num = Number ( input ) ;
92- if ( Number . isNaN ( num ) || num < 3 || num > 30 ) {
93- return "Please enter a valid number between 3 and 30" ;
94- }
95- return true ;
96- } ,
97- default : 10 ,
98- } ) ;
99-
100- const { allowAdvancedResearch } = await inquirer . prompt ( {
101- type : "confirm" ,
102- name : "allowAdvancedResearch" ,
103- message : "Allow advanced research for task generation ?" ,
104- default : false ,
105- } ) ;
106-
107- const { tag } = await inquirer . prompt ( {
108- type : "input" ,
109- name : "tag" ,
110- message : "Enter a tag for the tasks:" ,
111- default : "master" ,
112- validate : ( input ) => {
113- const regex = / ^ [ a - z 0 - 9 _ ] + $ / ;
114- if ( ! regex . test ( input ) ) {
115- return "Please enter a valid tag with only lowercase letters, numbers, and underscores (_)." ;
116- }
117- return true ;
118- } ,
119- } ) ;
76+ const prdPath = await askPrdPath ( ) ;
77+ const numTasksToGenerate = await askNumTasksToGenerate ( ) ;
78+ const allowAdvancedResearch = await askAdvancedResearchConfirmation ( ) ;
79+ const tag = await askTaskTag ( ) ;
12080
12181 await tmai . parseAsync (
12282 prdPath ,
@@ -128,20 +88,14 @@ export async function tmaiGenAsync() {
12888 } else if ( choice . tmaiGenDecMenu === "tmai-gen" ) {
12989 await tmai . genAsync ( ) ;
13090 } else if ( choice . tmaiGenDecMenu === "tmai-dec" ) {
131- const { confirmDecomposition } = await inquirer . prompt ( {
132- type : "confirm" ,
133- name : "confirmDecomposition" ,
134- message : chalk . yellow (
135- "Confirm that you want to expand all tasks? This action will decompose every task into smaller subtasks and may increase the total number of tasks to manage." ,
136- ) ,
137- default : false ,
138- } ) ;
91+ const confirmDecomposition = await askDecompositionConfirmation ( ) ;
13992 if ( ! confirmDecomposition ) {
14093 console . log ( "Decomposition of tasks cancelled!" ) ;
14194 return restartAsync ( ) ;
14295 }
14396
144- await tmai . decomposeAsync ( ) ;
97+ const tag = await askTaskTag ( ) ;
98+ await tmai . decomposeAsync ( tag ) ;
14599 }
146100
147101 await restartAsync ( ) ;
@@ -156,52 +110,14 @@ export async function tmaiManageAsync() {
156110 case "tmai-listnav" : {
157111 const { tmaiListNavMenu } = await inquirer . prompt ( tmaiListNavMenu_prompt ) ;
158112 if ( tmaiListNavMenu === "tmai-list" ) {
159- const { status : validatedStatus } = await inquirer . prompt ( [
160- {
161- type : "checkbox" ,
162- name : "status" ,
163- message : "Select task statuses:" ,
164- choices : TASKS_STATUSES . map ( ( status ) => ( {
165- name : status ,
166- value : status ,
167- } ) ) ,
168- validate : ( input ) => {
169- if ( ! input . length ) return "At least one status is required" ;
170- return true ;
171- } ,
172- filter : ( input ) => input . join ( "," ) ,
173- } ,
174- ] ) ;
175- const { quickly, withSubtasks } = await inquirer . prompt ( [
176- {
177- type : "confirm" ,
178- name : "quickly" ,
179- message : "Show tasks quickly ?" ,
180- default : true ,
181- } ,
182- {
183- type : "confirm" ,
184- name : "withSubtasks" ,
185- message : "Show with subtasks ?" ,
186- default : true ,
187- } ,
188- ] ) ;
113+ const validatedStatus = await askStatusSelection ( ) ;
114+ const { quickly, withSubtasks } = await askDisplayOptions ( ) ;
189115 await tmai . listAsync ( tasks , validatedStatus , quickly , withSubtasks ) ;
190116 } else if ( tmaiListNavMenu === "tmai-show" ) {
191117 console . log (
192118 await tmai . listQuickAsync ( tasks , TASKS_STATUSES . join ( "," ) , true ) ,
193119 ) ;
194- const { taskId } = await inquirer . prompt ( {
195- type : "input" ,
196- name : "taskId" ,
197- message : "Enter the task ID:" ,
198- validate : ( input ) => {
199- if ( ! input || ! / ^ ( \d + ) ( \. \d + ) * $ / . test ( input ) ) {
200- return "Invalid task ID. Must be an integer or hierarchical ID (e.g. 1, 2.1, 5.1.1)" ;
201- }
202- return true ;
203- } ,
204- } ) ;
120+ const taskId = await askTaskIdInput ( ) ;
205121 await tmai . showAsync ( taskId ) ;
206122 } else if ( tmaiListNavMenu === "tmai-next" ) {
207123 await tmai . nextAsync ( ) ;
0 commit comments