warp-task-master
Version:
BETA: Experimental Task Master fork with Warp AI integration and human-readable profile names. For production use, see task-master-ai.
10 lines (7 loc) • 120 kB
JavaScript
#!/usr/bin/env node
import{provider_registry_default as e}from"./ai-services-unified-Bp0J8TPk.js";import{COMPLEXITY_REPORT_FILE as t,CUSTOM_PROVIDERS_ARRAY as n,PRD_FILE as r,TASKMASTER_DOCS_DIR as i,TASKMASTER_TASKS_FILE as a,disableSilentMode as o,enableSilentMode as s,findTaskById as c,getCurrentTag as l,getDefaultNumTasks as u,getLogLevel as d,isSilentMode as f,readComplexityReport as p,readJSON as m,resolveComplexityReportOutputPath as h,resolveTag as g,writeJSON as _}from"./utils-Can7ymw4.js";import"./git-utils-TLODVPko.js";import{TASK_STATUS_OPTIONS as v,addDependency as y,add_subtask_default as b,add_task_default as x,analyze_task_complexity_default as S,checkProgressCapability as C,clear_subtasks_default as ee,createErrorResponse as w,createLogWrapper as T,expand_all_tasks_default as te,expand_task_default as ne,findComplexityReportPath as E,findTasksPath as D,find_next_task_default as re,fixDependenciesCommand as ie,generate_task_files_default as ae,getAvailableModelsList as oe,getModelConfiguration as se,handleApiResult as O,list_tasks_default as ce,moveTasksBetweenTags as le,move_task_default as ue,package_default as de,parse_prd_default as fe,performResearch as pe,removeDependency as me,remove_subtask_default as he,remove_task_default as ge,resolveComplexityReportPath as k,resolvePrdPath as _e,resolveProjectPath as ve,resolveTasksPath as A,response_language_default as ye,scopeDownTask as be,scopeUpTask as xe,setModel as Se,set_task_status_default as Ce,task_exists_default as we,update_subtask_by_id_default as Te,update_task_by_id_default as Ee,update_tasks_default as De,validateDependenciesCommand as Oe,withNormalizedProjectRoot as j}from"./task-manager-Cy89-0WA.js";import{BaseAIProvider as ke}from"./ai-providers-DH3IjRav.js";import{copyTag as Ae,createTag as je,createTagFromBranch as Me,deleteTag as Ne,renameTag as Pe,tags as Fe,useTag as Ie}from"./tag-management-BMInu0L6.js";import{RULES_ACTIONS as M,RULE_PROFILES as N,convertAllRulesToProfileRules as Le,getInstalledProfiles as Re,getRulesProfile as P,initializeProject as ze,isValidProfile as F,removeProfileRules as Be,wouldRemovalLeaveNoProfiles as Ve}from"./rules-actions-Btv3To_x.js";import I from"dotenv";import L from"path";import R from"chalk";import z from"fs";import{fileURLToPath as He}from"url";import{z as B}from"zod";import Ue from"os";import{FastMCP as We}from"fastmcp";const V={debug:0,info:1,warn:2,error:3,success:4},Ge=V[d().toLowerCase()]??V.info;function H(e,...t){if(f())return;let n={debug:R.gray(`[DEBUG]`),info:R.blue(`[INFO]`),warn:R.yellow(`[WARN]`),error:R.red(`[ERROR]`),success:R.green(`[SUCCESS]`)};if(V[e]!==void 0&&V[e]>=Ge){let r=n[e]||``,i=t;try{switch(e){case`error`:i=t.map(e=>typeof e==`string`?R.red(e):e);break;case`warn`:i=t.map(e=>typeof e==`string`?R.yellow(e):e);break;case`success`:i=t.map(e=>typeof e==`string`?R.green(e):e);break;case`info`:i=t.map(e=>typeof e==`string`?R.blue(e):e);break;case`debug`:i=t.map(e=>typeof e==`string`?R.gray(e):e);break}}catch(e){console.error(`Internal Logger Error applying chalk color:`,e),i=t}console.log(r,...i)}}function Ke(){let e=e=>(...t)=>H(e,...t);return{debug:e(`debug`),info:e(`info`),warn:e(`warn`),error:e(`error`),success:e(`success`),log:H}}var U=Ke();async function qe(e,t,n={}){let{tasksJsonPath:r,reportPath:i,status:a,withSubtasks:c,projectRoot:l,tag:u}=e,{session:d}=n;if(!r)return t.error(`listTasksDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};let f=a||`all`,p=c||!1,m=async()=>{try{s(),t.info(`Executing core listTasks function for path: ${r}, filter: ${f}, subtasks: ${p}`);let e=ce(r,f,i,p,`json`,{projectRoot:l,session:d,tag:u});return!e||!e.tasks?(t.error(`Invalid or empty response from listTasks core function`),{success:!1,error:{code:`INVALID_CORE_RESPONSE`,message:`Invalid or empty response from listTasks core function`}}):(t.info(`Core listTasks function retrieved ${e.tasks.length} tasks`),o(),{success:!0,data:e})}catch(e){return o(),t.error(`Core listTasks function failed: ${e.message}`),{success:!1,error:{code:`LIST_TASKS_CORE_ERROR`,message:e.message||`Failed to list tasks`}}}};try{let e=await m();return t.info(`listTasksDirect completed`),e}catch(e){return t.error(`Unexpected error during listTasks: ${e.message}`),console.error(e.stack),{success:!1,error:{code:`UNEXPECTED_ERROR`,message:e.message}}}}async function Je(e,t,n={}){let{session:r,reportProgress:i}=n,{input:c,output:l,numTasks:d,force:p,append:m,research:h,projectRoot:g,tag:_}=e,v=T(t);if(!g)return v.error(`parsePRDDirect requires a projectRoot argument.`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`projectRoot is required.`}};let y;if(c)try{y=_e({input:c,projectRoot:g},r)}catch(e){return v.error(`Error resolving PRD path: ${e.message}`),{success:!1,error:{code:`FILE_NOT_FOUND`,message:e.message}}}else return v.error(`parsePRDDirect called without input path`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`Input path is required`}};let b=l?L.isAbsolute(l)?l:L.resolve(g,l):ve(a,e)||L.resolve(g,a);if(!z.existsSync(y)){let e=`Input PRD file not found at resolved path: ${y}`;return v.error(e),{success:!1,error:{code:`FILE_NOT_FOUND`,message:e}}}let x=L.dirname(b);try{z.existsSync(x)||(v.info(`Creating output directory: ${x}`),z.mkdirSync(x,{recursive:!0}))}catch(e){let t=`Failed to create output directory ${x}: ${e.message}`;return v.error(t),{success:!1,error:{code:`DIRECTORY_CREATE_FAILED`,message:t}}}let S=u(g);d&&(S=typeof d==`string`?parseInt(d,10):d,(Number.isNaN(S)||S<0)&&(S=u(g),v.warn(`Invalid numTasks value: ${d}. Using default: ${S}`))),m&&(v.info(`Append mode enabled.`),p&&v.warn(`Both --force and --append flags were provided. --force takes precedence; append mode will be ignored.`)),h&&v.info(`Research mode enabled. Using Perplexity AI for enhanced PRD analysis.`),v.info(`Parsing PRD via direct function. Input: ${y}, Output: ${b}, NumTasks: ${S}, Force: ${p}, Append: ${m}, Research: ${h}, ProjectRoot: ${g}`);let C=f();C||s();try{let e=await fe(y,b,S,{session:r,mcpLog:v,projectRoot:g,tag:_,force:p,append:m,research:h,reportProgress:i,commandName:`parse-prd`,outputType:`mcp`},`json`);if(e&&e.success){let t=`Successfully parsed PRD and generated tasks in ${e.tasksPath}`;return v.success(t),{success:!0,data:{message:t,outputPath:e.tasksPath,telemetryData:e.telemetryData,tagInfo:e.tagInfo}}}else return v.error(`Core parsePRD function did not return a successful structure.`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e?.message||`Core function failed to parse PRD or returned unexpected result.`}}}catch(e){return v.error(`Error executing core parsePRD: ${e.message}`),{success:!1,error:{code:`PARSE_PRD_CORE_ERROR`,message:e.message||`Unknown error parsing PRD`}}}finally{!C&&f()&&o()}}async function Ye(e,t,n={}){let{session:r}=n,{from:i,prompt:a,research:c,tasksJsonPath:l,projectRoot:u,tag:d}=e,f=T(t);if(!u)return f.error(`updateTasksDirect requires a projectRoot argument.`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`projectRoot is required.`}};if(!i)return f.error(`updateTasksDirect called without from ID`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`Starting task ID (from) is required`}};if(!a)return f.error(`updateTasksDirect called without prompt`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`Update prompt is required`}};f.info(`Updating tasks via direct function. From: ${i}, Research: ${c}, File: ${l}, ProjectRoot: ${u}`),s();try{let e=await De(l,i,a,c,{session:r,mcpLog:f,projectRoot:u,tag:d},`json`);return e&&e.success&&Array.isArray(e.updatedTasks)?(f.success(`Successfully updated ${e.updatedTasks.length} tasks.`),{success:!0,data:{message:`Successfully updated ${e.updatedTasks.length} tasks.`,tasksPath:l,updatedCount:e.updatedTasks.length,telemetryData:e.telemetryData,tagInfo:e.tagInfo}}):(f.error(`Core updateTasks function did not return a successful structure.`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e?.message||`Core function failed to update tasks or returned unexpected result.`}})}catch(e){return f.error(`Error executing core updateTasks: ${e.message}`),{success:!1,error:{code:`UPDATE_TASKS_CORE_ERROR`,message:e.message||`Unknown error updating tasks`}}}finally{o()}}async function Xe(e,t,n={}){let{session:r}=n,{tasksJsonPath:i,id:a,prompt:c,research:l,append:u,projectRoot:d,tag:p}=e,m=T(t);try{if(m.info(`Updating task by ID via direct function. ID: ${a}, ProjectRoot: ${d}`),!i){let e=`tasksJsonPath is required but was not provided.`;return m.error(e),{success:!1,error:{code:`MISSING_ARGUMENT`,message:e}}}if(!a){let e=`No task ID specified. Please provide a task ID to update.`;return m.error(e),{success:!1,error:{code:`MISSING_TASK_ID`,message:e}}}if(!c){let e=`No prompt specified. Please provide a prompt with new information for the task update.`;return m.error(e),{success:!1,error:{code:`MISSING_PROMPT`,message:e}}}let e;if(typeof a==`string`){if(a.includes(`.`))e=a;else if(e=parseInt(a,10),Number.isNaN(e)){let e=`Invalid task ID: ${a}. Task ID must be a positive integer or subtask ID (e.g., "5.2").`;return m.error(e),{success:!1,error:{code:`INVALID_TASK_ID`,message:e}}}}else e=a;let t=i,n=l===!0;m.info(`Updating task with ID ${e} with prompt "${c}" and research: ${n}`);let h=f();h||s();try{let i=await Ee(t,e,c,n,{mcpLog:m,session:r,projectRoot:d,tag:p,commandName:`update-task`,outputType:`mcp`},`json`,u||!1);if(!i||i.updatedTask===null){let t=`Task ${e} was not updated (likely already completed).`;return m.info(t),{success:!0,data:{message:t,taskId:e,updated:!1,telemetryData:i?.telemetryData,tagInfo:i?.tagInfo}}}let a=`Successfully updated task with ID ${e} based on the prompt`;return m.success(a),{success:!0,data:{message:a,taskId:e,tasksPath:t,useResearch:n,updated:!0,updatedTask:i.updatedTask,telemetryData:i.telemetryData,tagInfo:i.tagInfo}}}catch(e){return m.error(`Error updating task by ID: ${e.message}`),{success:!1,error:{code:`UPDATE_TASK_CORE_ERROR`,message:e.message||`Unknown error updating task`}}}finally{!h&&f()&&o()}}catch(e){return m.error(`Setup error in updateTaskByIdDirect: ${e.message}`),f()&&o(),{success:!1,error:{code:`DIRECT_FUNCTION_SETUP_ERROR`,message:e.message||`Unknown setup error`}}}}async function Ze(e,t,n={}){let{session:r}=n,{tasksJsonPath:i,id:a,prompt:c,research:l,projectRoot:u,tag:d}=e,p=T(t);try{if(p.info(`Updating subtask by ID via direct function. ID: ${a}, ProjectRoot: ${u}`),!i){let e=`tasksJsonPath is required but was not provided.`;return p.error(e),{success:!1,error:{code:`MISSING_ARGUMENT`,message:e}}}if(!a||typeof a!=`string`||!a.includes(`.`)){let e=`Invalid subtask ID format. Must be in format "parentId.subtaskId" (e.g., "5.2").`;return p.error(e),{success:!1,error:{code:`INVALID_SUBTASK_ID`,message:e}}}if(!c){let e=`No prompt specified. Please provide the information to append.`;return p.error(e),{success:!1,error:{code:`MISSING_PROMPT`,message:e}}}let e=a;if(typeof e!=`string`&&typeof e!=`number`){let n=`Invalid subtask ID type: ${typeof e}. Subtask ID must be a string or number.`;return t.error(n),{success:!1,error:{code:`INVALID_SUBTASK_ID_TYPE`,message:n}}}let n=String(e);if(!n.includes(`.`)){let e=`Invalid subtask ID format: ${n}. Subtask ID must be in format "parentId.subtaskId" (e.g., "5.2").`;return t.error(e),{success:!1,error:{code:`INVALID_SUBTASK_ID_FORMAT`,message:e}}}let m=i,h=l===!0;t.info(`Updating subtask with ID ${n} with prompt "${c}" and research: ${h}`);let g=f();g||s();try{let e=await Te(m,n,c,h,{mcpLog:p,session:r,projectRoot:u,tag:d,commandName:`update-subtask`,outputType:`mcp`},`json`);if(!e||e.updatedSubtask===null){let e=`Subtask ${a} or its parent task not found.`;return p.error(e),{success:!1,error:{code:`SUBTASK_NOT_FOUND`,message:e}}}let t=`Successfully updated subtask with ID ${n}`;return p.success(t),{success:!0,data:{message:`Successfully updated subtask with ID ${n}`,subtaskId:n,parentId:n.split(`.`)[0],subtask:e.updatedSubtask,tasksPath:m,useResearch:h,telemetryData:e.telemetryData,tagInfo:e.tagInfo}}}catch(e){return p.error(`Error updating subtask by ID: ${e.message}`),{success:!1,error:{code:`UPDATE_SUBTASK_CORE_ERROR`,message:e.message||`Unknown error updating subtask`}}}finally{!g&&f()&&o()}}catch(e){return p.error(`Setup error in updateSubtaskByIdDirect: ${e.message}`),f()&&o(),{success:!1,error:{code:`DIRECT_FUNCTION_SETUP_ERROR`,message:e.message||`Unknown setup error`}}}}async function Qe(e,t){let{tasksJsonPath:n,outputDir:r,projectRoot:i,tag:a}=e;try{if(t.info(`Generating task files with args: ${JSON.stringify(e)}`),!n){let e=`tasksJsonPath is required but was not provided.`;return t.error(e),{success:!1,error:{code:`MISSING_ARGUMENT`,message:e}}}if(!r){let e=`outputDir is required but was not provided.`;return t.error(e),{success:!1,error:{code:`MISSING_ARGUMENT`,message:e}}}let c=n,l=r;t.info(`Generating task files from ${c} to ${l}`);try{s(),ae(c,l,{projectRoot:i,tag:a,mcpLog:t}),o()}catch(e){return o(),t.error(`Error in generateTaskFiles: ${e.message}`),{success:!1,error:{code:`GENERATE_FILES_ERROR`,message:e.message}}}return{success:!0,data:{message:`Successfully generated task files`,tasksPath:c,outputDir:l,taskFiles:`Individual task files have been generated in the output directory`}}}catch(e){return o(),t.error(`Error generating task files: ${e.message}`),{success:!1,error:{code:`GENERATE_TASKS_ERROR`,message:e.message||`Unknown error generating task files`}}}}async function W(e,t,n={}){let{tasksJsonPath:r,reportPath:i,projectRoot:a,tag:c}=e,{session:l}=n;if(!r)return t.error(`nextTaskDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};let u=async()=>{try{s(),t.info(`Finding next task from ${r}`);let e=m(r,a,c);if(!e||!e.tasks)return o(),{success:!1,error:{code:`INVALID_TASKS_FILE`,message:`No valid tasks found in ${r}`}};let n=p(i),l=re(e.tasks,n);if(!l)return t.info(`No eligible next task found. All tasks are either completed or have unsatisfied dependencies`),{success:!0,data:{message:`No eligible next task found. All tasks are either completed or have unsatisfied dependencies`,nextTask:null}};let u=typeof l.id==`string`&&l.id.includes(`.`),d=u?`subtask`:`task`,f=u?`Subtasks can be updated with timestamped details as you implement them. This is useful for tracking progress, marking milestones and insights (of successful or successive falures in attempting to implement the subtask). Research can be used when updating the subtask to collect up-to-date information, and can be helpful to solve a repeating problem the agent is unable to solve. It is a good idea to get-task the parent task to collect the overall context of the task, and to get-task the subtask to collect the specific details of the subtask.`:`Tasks can be updated to reflect a change in the direction of the task, or to reformulate the task per your prompt. Research can be used when updating the task to collect up-to-date information. It is best to update subtasks as you work on them, and to update the task for more high-level changes that may affect pending subtasks or the general direction of the task.`;return o(),t.info(`Successfully found next task ${l.id}: ${l.title}. Is subtask: ${u}`),{success:!0,data:{nextTask:l,isSubtask:u,nextSteps:`When ready to work on the ${d}, use set-status to set the status to "in progress" ${f}`}}}catch(e){return o(),t.error(`Error finding next task: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message||`Failed to find next task`}}}};try{let e=await u();return t.info(`nextTaskDirect completed.`),e}catch(e){return t.error(`Unexpected error during nextTask: ${e.message}`),{success:!1,error:{code:`UNEXPECTED_ERROR`,message:e.message}}}}async function $e(e,t,n={}){let{tasksJsonPath:r,id:i,status:a,complexityReportPath:c,projectRoot:l,tag:u}=e,{session:d}=n;try{if(t.info(`Setting task status with args: ${JSON.stringify(e)}`),!r){let e=`tasksJsonPath is required but was not provided.`;return t.error(e),{success:!1,error:{code:`MISSING_ARGUMENT`,message:e}}}if(!i){let e=`No task ID specified. Please provide a task ID to update.`;return t.error(e),{success:!1,error:{code:`MISSING_TASK_ID`,message:e}}}if(!a){let e=`No status specified. Please provide a new status value.`;return t.error(e),{success:!1,error:{code:`MISSING_STATUS`,message:e}}}let n=r,f=i,p=a;t.info(`Setting task ${f} status to "${p}"`),s();try{await Ce(n,f,p,{mcpLog:t,projectRoot:l,session:d,tag:u}),t.info(`Successfully set task ${f} status to ${p}`);let e={success:!0,data:{message:`Successfully updated task ${f} status to "${p}"`,taskId:f,status:p,tasksPath:n}};if(e.data.status===`done`)try{t.info(`Attempting to fetch next task for task ${f}`);let n=await W({tasksJsonPath:r,reportPath:c,projectRoot:l,tag:u},t,{session:d});n.success?(t.info(`Successfully retrieved next task: ${n.data.nextTask}`),e.data={...e.data,nextTask:n.data.nextTask,isNextSubtask:n.data.isSubtask,nextSteps:n.data.nextSteps}):t.warn(`Failed to retrieve next task: ${n.error?.message||`Unknown error`}`)}catch(e){t.error(`Error retrieving next task: ${e.message}`)}return e}catch(e){return t.error(`Error setting task status: ${e.message}`),{success:!1,error:{code:`SET_STATUS_ERROR`,message:e.message||`Unknown error setting task status`}}}finally{o()}}catch(e){return f()&&o(),t.error(`Error setting task status: ${e.message}`),{success:!1,error:{code:`SET_STATUS_ERROR`,message:e.message||`Unknown error setting task status`}}}}async function et(e,t){let{id:n,file:r,reportPath:i,status:a,projectRoot:o,tag:s}=e;t.info(`Showing task direct function. ID: ${n}, File: ${r}, Status Filter: ${a}, ProjectRoot: ${o}`);let l;try{l=D({projectRoot:o,file:r},t),t.info(`Resolved tasks path: ${l}`)}catch(e){return t.error(`Error finding tasks.json: ${e.message}`),{success:!1,error:{code:`TASKS_FILE_NOT_FOUND`,message:`Failed to find tasks.json: ${e.message}`}}}try{let e=m(l,o,s);if(!e||!e.tasks)return{success:!1,error:{code:`INVALID_TASKS_DATA`,message:`Invalid tasks data`}};let r=p(i),u=n.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);if(u.length===0)return{success:!1,error:{code:`INVALID_TASK_ID`,message:`No valid task IDs provided`}};if(u.length===1){let{task:n,originalSubtaskCount:i}=c(e.tasks,u[0],r,a);if(!n)return{success:!1,error:{code:`TASK_NOT_FOUND`,message:`Task or subtask with ID ${u[0]} not found`}};t.info(`Successfully retrieved task ${u[0]}.`);let o={...n};return i!==null&&(o._originalSubtaskCount=i,o._subtaskFilter=a),{success:!0,data:o}}let d=[],f=[];return u.forEach(t=>{let{task:n,originalSubtaskCount:i}=c(e.tasks,t,r,a);if(n){let e={...n};i!==null&&(e._originalSubtaskCount=i,e._subtaskFilter=a),d.push(e)}else f.push(t)}),t.info(`Successfully retrieved ${d.length} of ${u.length} requested tasks.`),{success:!0,data:{tasks:d,requestedIds:u,foundCount:d.length,notFoundIds:f,isMultiple:!0}}}catch(e){return t.error(`Error showing task ${n}: ${e.message}`),{success:!1,error:{code:`TASK_OPERATION_ERROR`,message:e.message}}}}async function tt(e,t,n={}){let{session:r}=n,{tasksJsonPath:i,id:a,num:c,research:l,prompt:u,force:d,projectRoot:p,tag:h,complexityReportPath:g}=e;if(t.info(`Session data in expandTaskDirect: ${JSON.stringify({hasSession:!!r,sessionKeys:r?Object.keys(r):[],roots:r?.roots,rootsStr:JSON.stringify(r?.roots)})}`),!i)return t.error(`expandTaskDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};let v=i;t.info(`[expandTaskDirect] Using tasksPath: ${v}`);let y=a?parseInt(a,10):null;if(!y)return t.error(`Task ID is required`),{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Task ID is required`}};let b=c?parseInt(c,10):void 0,x=l===!0,S=u||``,C=d===!0;try{t.info(`[expandTaskDirect] Expanding task ${y} into ${b||`default`} subtasks. Research: ${x}, Force: ${C}`),t.info(`[expandTaskDirect] Attempting to read JSON from: ${v}`);let e=m(v,p);if(t.info(`[expandTaskDirect] Result of readJSON: ${e?`Data read successfully`:`readJSON returned null or undefined`}`),!e||!e.tasks)return t.error(`[expandTaskDirect] readJSON failed or returned invalid data for path: ${v}`),{success:!1,error:{code:`INVALID_TASKS_FILE`,message:`No valid tasks found in ${v}. readJSON returned: ${JSON.stringify(e)}`}};t.info(`[expandTaskDirect] Searching for task ID ${y} in data`);let n=e.tasks.find(e=>e.id===y);if(t.info(`[expandTaskDirect] Task found: ${n?`Yes`:`No`}`),!n)return{success:!1,error:{code:`TASK_NOT_FOUND`,message:`Task with ID ${y} not found`}};if(n.status===`done`||n.status===`completed`)return{success:!1,error:{code:`TASK_COMPLETED`,message:`Task ${y} is already marked as ${n.status} and cannot be expanded`}};let i=n.subtasks&&n.subtasks.length>0;if(i&&!C)return t.info(`Task ${y} already has ${n.subtasks.length} subtasks. Use --force to overwrite.`),{success:!0,data:{message:`Task ${y} already has subtasks. Expansion skipped.`,task:n,subtasksAdded:0,hasExistingSubtasks:i}};i&&C&&(t.info(`Force flag set. Clearing existing subtasks for task ${y}.`),n.subtasks=[]),JSON.parse(JSON.stringify(n));let a=n.subtasks?n.subtasks.length:0;n.subtasks||(n.subtasks=[]),_(v,e,p,h);let c=T(t),l;try{l=f(),l||s();let e=await ne(v,y,b,x,S,{complexityReportPath:g,mcpLog:c,session:r,projectRoot:p,commandName:`expand-task`,outputType:`mcp`,tag:h},C);!l&&f()&&o();let n=m(v,p).tasks.find(e=>e.id===y),u=n.subtasks?n.subtasks.length-a:0;return t.info(`Successfully expanded task ${y} with ${u} new subtasks`),{success:!0,data:{task:e.task,subtasksAdded:u,hasExistingSubtasks:i,telemetryData:e.telemetryData,tagInfo:e.tagInfo}}}catch(e){return!l&&f()&&o(),t.error(`Error expanding task: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message||`Failed to expand task`}}}}catch(e){return t.error(`Error expanding task: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message||`Failed to expand task`}}}}async function nt(e,t,n={}){let{tasksJsonPath:r,prompt:i,dependencies:a,priority:c,research:l,projectRoot:u,tag:d}=e,{session:f}=n;s();let p=T(t);try{if(!r)return t.error(`addTaskDirect called without tasksJsonPath`),o(),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};let n=r,s=e.title&&e.description;if(!e.prompt&&!s)return t.error(`Missing required parameters: either prompt or title+description must be provided`),o(),{success:!1,error:{code:`MISSING_PARAMETER`,message:`Either the prompt parameter or both title and description parameters are required for adding a task`}};let m=Array.isArray(a)?a:a?String(a).split(`,`).map(e=>parseInt(e.trim(),10)):[],h=c||`medium`,g=null,_,v,y;if(s){g={title:e.title,description:e.description,details:e.details||``,testStrategy:e.testStrategy||``},t.info(`Adding new task manually with title: "${e.title}", dependencies: [${m.join(`, `)}], priority: ${c}`);let r=await x(n,null,m,h,{session:f,mcpLog:p,projectRoot:u,commandName:`add-task`,outputType:`mcp`,tag:d},`json`,g,!1);_=r.newTaskId,v=r.telemetryData,y=r.tagInfo}else{t.info(`Adding new task with prompt: "${i}", dependencies: [${m.join(`, `)}], priority: ${h}, research: ${l}`);let e=await x(n,i,m,h,{session:f,mcpLog:p,projectRoot:u,commandName:`add-task`,outputType:`mcp`,tag:d},`json`,null,l);_=e.newTaskId,v=e.telemetryData,y=e.tagInfo}return o(),{success:!0,data:{taskId:_,message:`Successfully added new task #${_}`,telemetryData:v,tagInfo:y}}}catch(e){return o(),t.error(`Error in addTaskDirect: ${e.message}`),{success:!1,error:{code:e.code||`ADD_TASK_ERROR`,message:e.message}}}}async function rt(e,t){let{tasksJsonPath:n,id:r,taskId:i,title:a,description:c,details:l,status:u,dependencies:d,skipGenerate:f,projectRoot:p,tag:m}=e;try{if(t.info(`Adding subtask with args: ${JSON.stringify(e)}`),!n)return t.error(`addSubtaskDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!r)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Parent task ID is required`}};if(!i&&!a)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Either taskId or title must be provided`}};let h=n,g=[];d&&(g=d.split(`,`).map(e=>e.includes(`.`)?e.trim():parseInt(e.trim(),10)));let _=i?parseInt(i,10):null,v=parseInt(r,10),y=!f;s();let x={projectRoot:p,tag:m};if(_){t.info(`Converting task ${_} to a subtask of ${v}`);let e=await b(h,v,_,null,y,x);return o(),{success:!0,data:{message:`Task ${_} successfully converted to a subtask of task ${v}`,subtask:e}}}else{t.info(`Creating new subtask for parent task ${v}`);let e=await b(h,v,null,{title:a,description:c||``,details:l||``,status:u||`pending`,dependencies:g},y,x);return o(),{success:!0,data:{message:`New subtask ${v}.${e.id} successfully created`,subtask:e}}}}catch(e){return o(),t.error(`Error in addSubtaskDirect: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message}}}}async function it(e,t){let{tasksJsonPath:n,id:r,convert:i,skipGenerate:a,projectRoot:c,tag:l}=e;try{if(s(),t.info(`Removing subtask with args: ${JSON.stringify(e)}`),!n)return t.error(`removeSubtaskDirect called without tasksJsonPath`),o(),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!r)return o(),{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Subtask ID is required and must be in format "parentId.subtaskId"`}};if(!r.includes(`.`))return o(),{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Invalid subtask ID format: ${r}. Expected format: "parentId.subtaskId"`}};let u=n,d=i===!0,f=!a;t.info(`Removing subtask ${r} (convertToTask: ${d}, generateFiles: ${f})`);let p=await he(u,r,d,f,{projectRoot:c,tag:l});return o(),d&&p?{success:!0,data:{message:`Subtask ${r} successfully converted to task #${p.id}`,task:p}}:{success:!0,data:{message:`Subtask ${r} successfully removed`}}}catch(e){return o(),t.error(`Error in removeSubtaskDirect: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message}}}}async function at(e,t,n={}){let{session:r}=n,{tasksJsonPath:i,outputPath:a,threshold:c,research:l,projectRoot:u,ids:d,from:p,to:m,tag:h}=e,g=T(t);try{if(t.info(`Analyzing task complexity with args: ${JSON.stringify(e)}`),!i)return t.error(`analyzeTaskComplexityDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!a)return t.error(`analyzeTaskComplexityDirect called without outputPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`outputPath is required`}};let n=i,_=a;if(t.info(`Analyzing task complexity from: ${n}`),t.info(`Output report will be saved to: ${_}`),d)t.info(`Analyzing specific task IDs: ${d}`);else if(p||m){let e=p===void 0?`first`:p,n=m===void 0?`last`:m;t.info(`Analyzing tasks in range: ${e} to ${n}`)}l&&t.info(`Using research role for complexity analysis`);let v={file:i,output:a,threshold:c,research:l===!0,projectRoot:u,id:d,from:p,to:m,tag:h},y=f();y||s();let b;try{b=await S(v,{session:r,mcpLog:g,commandName:`analyze-complexity`,outputType:`mcp`,projectRoot:u,tag:h}),b.report}catch(e){return t.error(`Error in analyzeTaskComplexity core function: ${e.message}`),!y&&f()&&o(),{success:!1,error:{code:`ANALYZE_CORE_ERROR`,message:`Error running core complexity analysis: ${e.message}`}}}finally{!y&&f()&&o()}if(!z.existsSync(_))return{success:!1,error:{code:`ANALYZE_REPORT_MISSING`,message:`Analysis completed but no report file was created at the expected path.`}};if(!b||!b.report||typeof b.report!=`object`)return t.error(`Core analysis function returned an invalid or undefined response.`),{success:!1,error:{code:`INVALID_CORE_RESPONSE`,message:`Core analysis function returned an invalid response.`}};try{let e=Array.isArray(b.report.complexityAnalysis)?b.report.complexityAnalysis:[],t=e.filter(e=>e.complexityScore>=8).length,n=e.filter(e=>e.complexityScore>=5&&e.complexityScore<8).length,r=e.filter(e=>e.complexityScore<5).length;return{success:!0,data:{message:`Task complexity analysis complete. Report saved to ${a}`,reportPath:a,reportSummary:{taskCount:e.length,highComplexityTasks:t,mediumComplexityTasks:n,lowComplexityTasks:r},fullReport:b.report,telemetryData:b.telemetryData,tagInfo:b.tagInfo}}}catch(e){return t.error(`Internal error processing report data: ${e.message}`),{success:!1,error:{code:`REPORT_PROCESS_ERROR`,message:`Internal error processing complexity report: ${e.message}`}}}}catch(e){return f()&&o(),t.error(`Error in analyzeTaskComplexityDirect setup: ${e.message}`),{success:!1,error:{code:`DIRECT_FUNCTION_SETUP_ERROR`,message:e.message}}}}async function ot(e,t){let{tasksJsonPath:n,id:r,all:i,tag:a,projectRoot:c}=e;try{if(t.info(`Clearing subtasks with args: ${JSON.stringify(e)}`),!n)return t.error(`clearSubtasksDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!r&&!i)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Either task IDs with id parameter or all parameter must be provided`}};let l=n;if(!z.existsSync(l))return{success:!1,error:{code:`FILE_NOT_FOUND_ERROR`,message:`Tasks file not found at ${l}`}};let u,d=m(l,c,a);if(!d||!d.tasks)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`No tasks found in tasks file: ${l}`}};let f=d.tag||a,p=d.tasks;if(i){if(t.info(`Clearing subtasks from all tasks in tag '${f}'`),p.length===0)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`No tasks found in tag context '${f}'`}};u=p.map(e=>e.id).join(`,`)}else u=r;t.info(`Clearing subtasks from tasks: ${u} in tag '${f}'`),s(),ee(l,u,{projectRoot:c,tag:f}),o();let h=m(l,c,f),g=u.split(`,`).map(e=>parseInt(e.trim(),10)),_=g.length,v=h.tasks||[],y=g.map(e=>{let t=v.find(t=>t.id===e);return t?{id:e,title:t.title}:{id:e,title:`Task not found`}});return{success:!0,data:{message:`Successfully cleared subtasks from ${_} task(s) in tag '${f}'`,tasksCleared:y,tag:f}}}catch(e){return o(),t.error(`Error in clearSubtasksDirect: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message}}}}async function st(e,t,n={}){let{session:r}=n,{tasksJsonPath:i,num:a,research:c,prompt:l,force:u,projectRoot:d,tag:f}=e,p=T(t);if(!i)return t.error(`expandAllTasksDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};s();try{t.info(`Calling core expandAllTasks with args: ${JSON.stringify({num:a,research:c,prompt:l,force:u,projectRoot:d,tag:f})}`);let e=await te(i,a?parseInt(a,10):void 0,c===!0,l||``,u===!0,{session:r,mcpLog:p,projectRoot:d,tag:f},`json`);return{success:!0,data:{message:`Expand all operation completed. Expanded: ${e.expandedCount}, Failed: ${e.failedCount}, Skipped: ${e.skippedCount}`,details:{expandedCount:e.expandedCount,failedCount:e.failedCount,skippedCount:e.skippedCount,tasksToExpand:e.tasksToExpand},telemetryData:e.telemetryData}}}catch(e){return t.error(`Error during core expandAllTasks execution: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message}}}finally{o()}}async function ct(e,t){let{tasksJsonPath:n,id:r,dependsOn:i,projectRoot:a,tag:c}=e;try{if(t.info(`Removing dependency with args: ${JSON.stringify(e)}`),!n)return t.error(`removeDependencyDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!r)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Task ID (id) is required`}};if(!i)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Dependency ID (dependsOn) is required`}};let l=n,u=r&&r.includes&&r.includes(`.`)?r:parseInt(r,10),d=i&&i.includes&&i.includes(`.`)?i:parseInt(i,10);return t.info(`Removing dependency: task ${u} no longer depends on ${d}`),s(),await me(l,u,d,{projectRoot:a,tag:c}),o(),{success:!0,data:{message:`Successfully removed dependency: Task ${u} no longer depends on ${d}`,taskId:u,dependencyId:d}}}catch(e){return o(),t.error(`Error in removeDependencyDirect: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message}}}}async function lt(e,t){let{tasksJsonPath:n,projectRoot:r,tag:i}=e;if(!n)return t.error(`validateDependenciesDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};try{t.info(`Validating dependencies in tasks: ${n}`);let e=n;return z.existsSync(e)?(s(),await Oe(e,{projectRoot:r,tag:i}),o(),{success:!0,data:{message:`Dependencies validated successfully`,tasksPath:e}}):{success:!1,error:{code:`FILE_NOT_FOUND`,message:`Tasks file not found at ${e}`}}}catch(e){return o(),t.error(`Error validating dependencies: ${e.message}`),{success:!1,error:{code:`VALIDATION_ERROR`,message:e.message}}}}async function ut(e,t){let{tasksJsonPath:n,projectRoot:r,tag:i}=e;try{if(t.info(`Fixing invalid dependencies in tasks: ${n}`),!n)return t.error(`fixDependenciesDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};let e=n;return z.existsSync(e)?(s(),await ie(e,{projectRoot:r,tag:i}),o(),{success:!0,data:{message:`Dependencies fixed successfully`,tasksPath:e,tag:i||`master`}}):{success:!1,error:{code:`FILE_NOT_FOUND`,message:`Tasks file not found at ${e}`}}}catch(e){return o(),t.error(`Error fixing dependencies: ${e.message}`),{success:!1,error:{code:`FIX_DEPENDENCIES_ERROR`,message:e.message}}}}async function dt(e,t){let{reportPath:n}=e;try{if(t.info(`Getting complexity report with args: ${JSON.stringify(e)}`),!n)return t.error(`complexityReportDirect called without reportPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`reportPath is required`}};t.info(`Looking for complexity report at: ${n}`),`${n}`;let r=async()=>{try{s();let e=p(n);return o(),e?{success:!0,data:{report:e,reportPath:n}}:(t.warn(`No complexity report found at ${n}`),{success:!1,error:{code:`FILE_NOT_FOUND_ERROR`,message:`No complexity report found at ${n}. Run 'analyze-complexity' first.`}})}catch(e){return o(),t.error(`Error reading complexity report: ${e.message}`),{success:!1,error:{code:`READ_ERROR`,message:e.message}}}};try{let e=await r();return t.info(`complexityReportDirect completed`),e}catch(e){return o(),t.error(`Unexpected error during complexityReport: ${e.message}`),{success:!1,error:{code:`UNEXPECTED_ERROR`,message:e.message}}}}catch(e){return o(),t.error(`Error in complexityReportDirect: ${e.message}`),{success:!1,error:{code:`UNEXPECTED_ERROR`,message:e.message}}}}async function ft(e,t){let{tasksJsonPath:n,id:r,dependsOn:i,tag:a,projectRoot:c}=e;try{if(t.info(`Adding dependency with args: ${JSON.stringify(e)}`),!n)return t.error(`addDependencyDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!r)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Task ID (id) is required`}};if(!i)return{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Dependency ID (dependsOn) is required`}};let l=n,u=r&&r.includes&&r.includes(`.`)?r:parseInt(r,10),d=i&&i.includes&&i.includes(`.`)?i:parseInt(i,10);return t.info(`Adding dependency: task ${u} will depend on ${d}`),s(),await y(l,u,d,{projectRoot:c,tag:a}),o(),{success:!0,data:{message:`Successfully added dependency: Task ${u} now depends on ${d}`,taskId:u,dependencyId:d}}}catch(e){return o(),t.error(`Error in addDependencyDirect: ${e.message}`),{success:!1,error:{code:`CORE_FUNCTION_ERROR`,message:e.message}}}}async function pt(e,t,n={}){let{tasksJsonPath:r,id:i,projectRoot:a,tag:c}=e,{session:l}=n;try{if(!r)return t.error(`removeTaskDirect called without tasksJsonPath`),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!i)return t.error(`Task ID is required`),{success:!1,error:{code:`INPUT_VALIDATION_ERROR`,message:`Task ID is required`}};let e=i.split(`,`).map(e=>e.trim());t.info(`Removing ${e.length} task(s) with ID(s): ${e.join(`, `)} from ${r}${c?` in tag '${c}'`:``}`);let n=m(r,a,c);if(!n||!n.tasks)return{success:!1,error:{code:`INVALID_TASKS_FILE`,message:`No valid tasks found in ${r}${c?` for tag '${c}'`:``}`}};let l=e.filter(e=>!we(n.tasks,e));if(l.length>0)return{success:!1,error:{code:`INVALID_TASK_ID`,message:`The following tasks were not found${c?` in tag '${c}'`:``}: ${l.join(`, `)}`}};s();try{let n=await ge(r,i,{projectRoot:a,tag:c});return n.success?(t.info(`Successfully removed ${n.removedTasks.length} task(s)`),{success:!0,data:{totalTasks:e.length,successful:n.removedTasks.length,failed:e.length-n.removedTasks.length,removedTasks:n.removedTasks,message:n.message,tasksPath:r,tag:c}}):{success:!1,error:{code:`REMOVE_TASK_ERROR`,message:n.error||`Failed to remove tasks`}}}finally{o()}}catch(e){return o(),t.error(`Unexpected error in removeTaskDirect: ${e.message}`),{success:!1,error:{code:`UNEXPECTED_ERROR`,message:e.message}}}}async function mt(e,t,n={}){let{session:r}=n,i=Ue.homedir();t.info(`Args received in direct function: ${JSON.stringify(e)}`);let a=e.projectRoot;if(!a||typeof a!=`string`||a===`/`||a===i)return t.error(`Invalid target directory received from tool layer: '${a}'`),{success:!1,error:{code:`INVALID_TARGET_DIRECTORY`,message:`Cannot initialize project: Invalid target directory '${a}' received. Please ensure a valid workspace/folder is open or specified.`,details:`Received args.projectRoot: ${e.projectRoot}`}};t.info(`Validated target directory for initialization: ${a}`);let c=process.cwd(),l,u=!1,d=null;t.info(`Temporarily changing CWD to ${a} for initialization.`),process.chdir(a),s();try{let n={addAliases:e.addAliases,initGit:e.initGit,storeTasksInGit:e.storeTasksInGit,skipInstall:e.skipInstall,yes:!0};Array.isArray(e.rules)&&e.rules.length>0?(n.rules=e.rules,n.rulesExplicitlyProvided=!0,t.info(`Including rules: ${e.rules.join(`, `)}`)):(n.rules=[`cursor`],n.rulesExplicitlyProvided=!0,t.info(`No rule profiles specified, defaulting to: Cursor`)),t.info(`Initializing project with options: ${JSON.stringify(n)}`),l={message:`Project initialized successfully.`,next_step:`Now that the project is initialized, the next step is to create the tasks by parsing a PRD. This will create the tasks folder and the initial task files (tasks folder will be created when parse-prd is run). The parse-prd tool will require a prd.txt file as input (typically found in .taskmaster/docs/ directory). You can create a prd.txt file by asking the user about their idea, and then using the .taskmaster/templates/example_prd.txt file as a template to generate a prd.txt file in .taskmaster/docs/. You may skip all of this if the user already has a prd.txt file. You can THEN use the parse-prd tool to create the tasks. So: step 1 after initialization is to create a prd.txt file in .taskmaster/docs/prd.txt or confirm the user already has one. Step 2 is to use the parse-prd tool to create the tasks. Do not bother looking for tasks after initialization, just use the parse-prd tool to create the tasks after creating a prd.txt from which to parse the tasks. You do NOT need to reinitialize the project to parse-prd.`,...await ze(n)},u=!0,t.info(`Project initialization completed successfully in ${a}.`)}catch(e){t.error(`Core initializeProject failed: ${e.message}`),d={code:`INITIALIZATION_FAILED`,message:`Core project initialization failed: ${e.message}`,details:e.stack},u=!1}finally{o(),t.info(`Restoring original CWD: ${c}`),process.chdir(c)}return u?{success:!0,data:l}:{success:!1,error:d}}const ht=[`main`,`research`,`fallback`];function gt(e){return n.find(t=>e[t])}async function _t(e,t){for(let n of ht){let r=`set${n.charAt(0).toUpperCase()+n.slice(1)}`;if(e[r]){let i=gt(e);return await Se(n,e[r],{...t,providerHint:i})}}return null}async function vt(e,t,r={}){let{session:i}=r,{projectRoot:a}=e,c=T(t);if(t.info(`Executing models_direct with args: ${JSON.stringify(e)}`),t.info(`Using project root: ${a}`),n.filter(t=>e[t]).length>1)return t.error(`Error: Cannot use multiple custom provider flags simultaneously.`),{success:!1,error:{code:`INVALID_ARGS`,message:`Cannot use multiple custom provider flags simultaneously. Choose only one: openrouter, ollama, bedrock, azure, or vertex.`}};try{s();try{return e.listAvailableModels===!0?await oe({session:i,mcpLog:c,projectRoot:a}):await _t(e,{session:i,mcpLog:c,projectRoot:a})||await se({session:i,mcpLog:c,projectRoot:a})}finally{o()}}catch(e){return t.error(`Error in models_direct: ${e.message}`),{success:!1,error:{code:`DIRECT_FUNCTION_ERROR`,message:e.message,details:e.stack}}}}async function G(e,t,n={}){let{session:r}=n,{projectRoot:i,tag:a}=e;if(!e.sourceId)return{success:!1,error:{message:`Source ID is required`,code:`MISSING_SOURCE_ID`}};if(!e.destinationId)return{success:!1,error:{message:`Destination ID is required`,code:`MISSING_DESTINATION_ID`}};try{let n=e.tasksJsonPath||e.file;if(!n){if(!e.projectRoot)return{success:!1,error:{message:`Project root is required if tasksJsonPath is not provided`,code:`MISSING_PROJECT_ROOT`}};n=D(e,t)}s();let r=e.generateFiles!==!1,c=await ue(n,e.sourceId,e.destinationId,r,{projectRoot:i,tag:a});return o(),{success:!0,data:{...c,message:`Successfully moved task/subtask ${e.sourceId} to ${e.destinationId}`}}}catch(e){return o(),t.error(`Failed to move task: ${e.message}`),{success:!1,error:{message:e.message,code:`MOVE_TASK_ERROR`}}}}async function K(e,t,n={}){let{session:r}=n,{projectRoot:i}=e;if(t.info(`moveTaskCrossTagDirect called with args: ${JSON.stringify(e)}`),!e.sourceIds)return{success:!1,error:{message:`Source IDs are required`,code:`MISSING_SOURCE_IDS`}};if(!e.sourceTag)return{success:!1,error:{message:`Source tag is required for cross-tag moves`,code:`MISSING_SOURCE_TAG`}};if(!e.targetTag)return{success:!1,error:{message:`Target tag is required for cross-tag moves`,code:`MISSING_TARGET_TAG`}};if(e.sourceTag===e.targetTag)return{success:!1,error:{message:`Source and target tags are the same ("${e.sourceTag}")`,code:`SAME_SOURCE_TARGET_TAG`,suggestions:[`Use different tags for cross-tag moves`,`Use within-tag move: task-master move --from=<id> --to=<id> --tag=<tag>`,`Check available tags: task-master tags`]}};try{let n=e.tasksJsonPath||e.file;if(!n){if(!e.projectRoot)return{success:!1,error:{message:`Project root is required if tasksJsonPath is not provided`,code:`MISSING_PROJECT_ROOT`}};n=D(e,t)}s();try{let t=e.sourceIds.split(`,`).map(e=>e.trim()),r={withDependencies:e.withDependencies||!1,ignoreDependencies:e.ignoreDependencies||!1};return{success:!0,data:{...await le(n,t,e.sourceTag,e.targetTag,r,{projectRoot:i}),message:`Successfully moved ${t.length} task(s) from "${e.sourceTag}" to "${e.targetTag}"`,moveOptions:r,sourceTag:e.sourceTag,targetTag:e.targetTag}}}finally{o()}}catch(e){t.error(`Failed to move tasks between tags: ${e.message}`),t.error(`Error code: ${e.code}, Error name: ${e.name}`);let n=`MOVE_TASK_CROSS_TAG_ERROR`,r=[];return e.code===`CROSS_TAG_DEPENDENCY_CONFLICTS`?(n=`CROSS_TAG_DEPENDENCY_CONFLICT`,r=[`Use --with-dependencies to move dependent tasks together`,`Use --ignore-dependencies to break cross-tag dependencies`,`Run task-master validate-dependencies to check for issues`,`Move dependencies first, then move the main task`]):e.code===`CANNOT_MOVE_SUBTASK`?(n=`SUBTASK_MOVE_RESTRICTION`,r=[`Promote subtask to full task first: task-master remove-subtask --id=<subtaskId> --convert`,`Move the parent task with all subtasks using --with-dependencies`]):e.code===`TASK_NOT_FOUND`||e.code===`INVALID_SOURCE_TAG`||e.code===`INVALID_TARGET_TAG`?(n=`TAG_OR_TASK_NOT_FOUND`,r=[`Check available tags: task-master tags`,`Verify task IDs exist: task-master list`,`Check task details: task-master show <id>`]):e.message.includes(`cross-tag dependency conflicts`)?(n=`CROSS_TAG_DEPENDENCY_CONFLICT`,r=[`Use --with-dependencies to move dependent tasks together`,`Use --ignore-dependencies to break cross-tag dependencies`,`Run task-master validate-dependencies to check for issues`,`Move dependencies first, then move the main task`]):e.message.includes(`Cannot move subtask`)?(n=`SUBTASK_MOVE_RESTRICTION`,r=[`Promote subtask to full task first: task-master remove-subtask --id=<subtaskId> --convert`,`Move the parent task with all subtasks using --with-dependencies`]):e.message.includes(`not found`)?(n=`TAG_OR_TASK_NOT_FOUND`,r=[`Check available tags: task-master tags`,`Verify task IDs exist: task-master list`,`Check task details: task-master show <id>`]):(e.code===`TASK_ALREADY_EXISTS`||e.message?.includes(`already exists in target tag`))&&(n=`TASK_ALREADY_EXISTS`,r=[`Choose a different target tag without conflicting IDs`,`Move a different set of IDs (avoid existing ones)`,`If needed, move within-tag to a new ID first, then cross-tag move`]),{success:!1,error:{message:e.message,code:n,suggestions:r}}}}async function yt(e,t,n={}){let{query:r,taskIds:i,filePaths:a,customContext:c,includeProjectTree:l=!1,detailLevel:u=`medium`,saveTo:d,saveToFile:f=!1,projectRoot:p,tag:m}=e,{session:h}=n;s();let g=T(t);try{if(!r||typeof r!=`string`||r.trim().length===0)return t.error(`Missing or invalid required parameter: query`),o(),{success:!1,error:{code:`MISSING_PARAMETER`,message:`The query parameter is required and must be a non-empty string`}};let e=i?i.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):[],n=a?a.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):[],s=[`low`,`medium`,`high`];if(!s.includes(u))return t.error(`Invalid detail level: ${u}`),o(),{success:!1,error:{code:`INVALID_PARAMETER`,message:`Detail level must be one of: ${s.join(`, `)}`}};t.info(`Performing research query: "${r.substring(0,100)}${r.length>100?`...`:``}", taskIds: [${e.join(`, `)}], filePaths: [${n.join(`, `)}], detailLevel: ${u}, includeProjectTree: ${l}, projectRoot: ${p}`);let _={taskIds:e,filePaths:n,customContext:c||``,includeProjectTree:l,detailLevel:u,projectRoot:p,tag:m,saveToFile:f},v={session:h,mcpLog:g,commandName:`research`,outputType:`mcp`},y=await pe(r.trim(),_,v,`json`,!1);if(d)try{let e=d.includes(`.`),n=`## Research Query: ${r.trim()}
**Detail Level:** ${y.detailLevel}
**Context Size:** ${y.contextSize} characters
**Timestamp:** ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}
### Results
${y.result}`;if(e){let{updateSubtaskById:e}=await import(`./update-subtask-by-id-BXInZy7k.js`),r=L.join(p,`.taskmaster`,`tasks`,`tasks.json`);await e(r,d,n,!1,{session:h,mcpLog:g,commandName:`research-save`,outputType:`mcp`,projectRoot:p,tag:m},`json`),t.info(`Research saved to subtask ${d}`)}else{let e=(await import(`./update-task-by-id-PYbW54AB.js`)).default,r=parseInt(d,10),i=L.join(p,`.taskmaster`,`tasks`,`tasks.json`);await e(i,r,n,!1,{session:h,mcpLog:g,commandName:`research-save`,outputType:`mcp`,projectRoot:p,tag:m},`json`,!0),t.info(`Research saved to task ${d}`)}}catch(e){t.warn(`Error saving research to task/subtask: ${e.message}`)}return o(),{success:!0,data:{query:y.query,result:y.result,contextSize:y.contextSize,contextTokens:y.contextTokens,tokenBreakdown:y.tokenBreakdown,systemPromptTokens:y.systemPromptTokens,userPromptTokens:y.userPromptTokens,totalInputTokens:y.totalInputTokens,detailLevel:y.detailLevel,telemetryData:y.telemetryData,tagInfo:y.tagInfo,savedFilePath:y.savedFilePath}}}catch(e){return o(),t.error(`Error in researchDirect: ${e.message}`),{success:!1,error:{code:e.code||`RESEARCH_ERROR`,message:e.message}}}}async function bt(e,t,n={}){let{tasksJsonPath:r,name:i,copyFromCurrent:a=!1,copyFromTag:c,fromBranch:l=!1,description:u,projectRoot:d}=e,{session:f}=n;s();let p=T(t);try{if(!r)return t.error(`addTagDirect called without tasksJsonPath`),o(),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(l){t.info(`Creating tag from current git branch`);let e=await import(`./git-utils-DxggEZwm.js`);if(!await e.isGitRepository(d))return t.error(`Not in a git repository`),o(),{success:!1,error:{code:`NOT_GIT_REPO`,message:`Not in a git repository. Cannot use fromBranch option.`}};let n=await e.getCurrentBranch(d);if(!n)return t.error(`Could not determine current git branch`),o(),{success:!1,error:{code:`NO_CURRENT_BRANCH`,message:`Could not determine current git branch.`}};let i={copyFromCurrent:a,copyFromTag:c,description:u||`Tag created from git branch "${n}"`},s=await Me(r,n,i,{session:f,mcpLog:p,projectRoot:d},`json`);return o(),{success:!0,data:{branchName:s.branchName,tagName:s.tagName,created:s.created,mappingUpdated:s.mappingUpdated,message:`Successfully created tag "${s.tagName}" from git branch "${s.branchName}"`}}}else{if(!i||typeof i!=`string`)return t.error(`Missing required parameter: name`),o(),{success:!1,error:{code:`MISSING_PARAMETER`,message:`Tag name is required and must be a string`}};t.info(`Creating new tag: ${i}`);let e=await je(r,i,{copyFromCurrent:a,copyFromTag:c,description:u},{session:f,mcpLog:p,projectRoot:d},`json`);return o(),{success:!0,data:{tagName:e.tagName,created:e.created,tasksCopied:e.tasksCopied,sourceTag:e.sourceTag,description:e.description,message:`Successfully created tag "${e.tagName}"`}}}}catch(e){return o(),t.error(`Error in addTagDirect: ${e.message}`),{success:!1,error:{code:e.code||`ADD_TAG_ERROR`,message:e.message}}}}async function xt(e,t,n={}){let{tasksJsonPath:r,name:i,yes:a=!1,projectRoot:c}=e,{session:l}=n;s();let u=T(t);try{if(!r)return t.error(`deleteTagDirect called without tasksJsonPath`),o(),{success:!1,error:{code:`MISSING_ARGUMENT`,message:`tasksJsonPath is required`}};if(!i||typeof i!=`string`)return t.error(`Missing required parameter: name`),o(),{success:!1,error:{code:`MISSING_PARAMETER`,message:`Tag name is required and must be a string`}};t.info(`Deleting tag: ${i}`);let e=await Ne(r,i,{yes:a},{session:l,mcpLog:u,projectRoot:c},`json`);return o(),{success:!0,data:{tagName:e.tagName,deleted:e.deleted,tasksDeleted:e.tasksDeleted,wasCurrentTag:e.wasCurrentTag,switchedToMaster:e.switchedToMaster,message:`Successfully deleted tag "${e.tagName}"`}}}catch(e){return o(),t.error(`Error in deleteTagDirect: ${e.message}`),{success:!1,error:{cod