@hhsw2015/task-master-ai 0.43.9 → 0.43.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.
@@ -1,81 +1,81 @@
1
- import{a as e,i as t,l as n,n as r,t as i}from"./ai-services-unified-D_pA4zzB.js";import{$ as a,A as o,At as s,B as c,Bt as l,C as u,Ct as d,D as f,Dn as p,En as m,Jt as h,Kt as g,L as _,Lt as v,Mt as y,O as b,On as x,Ot as S,R as C,Rt as w,S as T,Tn as E,Tt as D,X as O,Xt as k,Y as A,Yt as j,Z as M,Zt as N,_ as P,_n as ee,a as te,an as ne,bt as re,cn as ie,ct as ae,dn as F,dt as oe,en as se,et as ce,f as le,fn as ue,ft as de,g as fe,gn as pe,gt as me,h as he,hn as ge,ht as _e,i as ve,it as ye,j as be,jn as xe,kn as Se,kt as Ce,ln as I,lt as we,mn as Te,mt as Ee,n as De,nn as Oe,o as ke,on as Ae,p as je,pn as Me,pt as Ne,q as Pe,rt as Fe,sn as Ie,tt as Le,un as Re,ut as ze,v as Be,vn as Ve,vt as L,w as He,wt as Ue,xn as R,yn as We,yt as z}from"./config-manager-Dn_JApjY.js";import Ge,{resolve as Ke}from"node:path";import B from"chalk";import*as qe from"fs";import V from"fs";import H from"path";import Je from"os";import Ye from"node:fs/promises";import Xe from"node:fs";import Ze from"node:os";import{z as U}from"zod";import{spawn as Qe}from"child_process";import{fileURLToPath as $e}from"url";import{FastMCP as et}from"fastmcp";import{smoothStream as tt}from"ai";import W from"boxen";import nt from"readline";import{Command as G}from"commander";import rt from"figlet";import it from"gradient-string";import at from"terminal-link";import{marked as ot}from"marked";import{markedTerminal as st}from"marked-terminal";import ct from"turndown";import K from"cli-table3";import q from"inquirer";import J from"ora";import lt from"open";import ut,{Separator as dt}from"@inquirer/search";import ft from"process";import pt from"https";import mt from"cli-progress";import ht from"http";import gt from"fuse.js";import _t from"ajv";import vt from"ajv-formats";import yt from"gpt-tokens";import{LRUCache as bt}from"lru-cache";import"@streamparser/json";function xt(e,t,n){return(n?.color?B[n.color]:B.cyan)(at(e,t,{fallback:(e,t)=>`${e} (${t})`}))}function St(e,t){return xt(e,e,t)}const Ct=it([`#00b4d8`,`#0077b6`,`#03045e`]);function wt(){return process.env.TM_HIDE_BANNER===`true`}function Tt(){return process.stdout.columns||80}function Et(e={}){if(wt())return;let{version:t}=e;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Ct(e))}catch{console.log(Ct(`=== Task Master ===`))}let n=xt(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`),r=B.dim(`by `)+B.cyan(n),i=t?t.replace(/^v/,``):``,a=`https://github.com/eyaltoledano/claude-task-master/releases/tag/task-master-ai%40${i}`,o=t?xt(`v${i}`,a,{color:`gray`}):``;if(o){let e=i.length+1,t=Tt(),n=Math.max(2,t-22-e-2);console.log(r+` `.repeat(n)+o)}else console.log(r);let s=xt(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(s)),console.log(``)}function Dt(){if(wt())return;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Ct(e))}catch{console.log(Ct(`=== Task Master ===`))}let e=xt(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`);console.log(B.dim(`by `)+B.cyan(e));let t=xt(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(t)),console.log(``)}function Ot(e){let{header:t,body:n,callToAction:r,footer:i,level:a=`warn`}=e,o=a===`info`?B.blue.bold:B.yellow.bold,s=a===`info`?`blue`:`yellow`,c=[o(t),...n.map(e=>B.white(e))];return r&&r.label&&r.action&&c.push(B.cyan(r.label)+`
1
+ import{a as e,i as t,l as n,n as r,t as i}from"./ai-services-unified-CEISDqFA.js";import{$ as a,A as o,At as s,B as c,Bt as l,C as u,Ct as d,D as f,Dn as p,En as m,Jt as h,Kt as g,L as _,Lt as v,Mt as y,O as b,Ot as x,R as S,Rt as C,S as w,Tn as T,Tt as E,X as D,Xt as O,Y as k,Yt as A,Z as j,Zt as M,_ as N,_n as P,a as ee,an as te,bt as ne,cn as re,ct as ie,dn as ae,dt as F,en as oe,et as se,f as ce,fn as le,ft as ue,g as de,gn as fe,gt as pe,h as me,hn as he,ht as ge,i as _e,it as ve,j as ye,kn as be,kt as xe,ln as I,lt as Se,mn as Ce,mt as we,n as Te,nn as Ee,o as De,on as Oe,p as ke,pn as Ae,pt as je,q as Me,rt as Ne,sn as Pe,tt as Fe,un as Ie,ut as Le,v as Re,vn as ze,vt as L,w as Be,wn as Ve,wt as He,xn as R,yn as Ue,yt as z}from"./config-manager-3pTgfD7M.js";import We,{resolve as Ge}from"node:path";import B from"chalk";import*as Ke from"fs";import V from"fs";import H from"path";import qe from"os";import Je from"node:fs";import{fileURLToPath as Ye}from"node:url";import Xe from"node:fs/promises";import Ze from"node:os";import{z as U}from"zod";import{spawn as Qe}from"child_process";import{fileURLToPath as $e}from"url";import{FastMCP as et}from"fastmcp";import{smoothStream as tt}from"ai";import W from"boxen";import nt from"readline";import{Command as G}from"commander";import rt from"figlet";import it from"gradient-string";import at from"terminal-link";import{marked as ot}from"marked";import{markedTerminal as st}from"marked-terminal";import ct from"turndown";import K from"cli-table3";import q from"inquirer";import J from"ora";import lt from"open";import ut,{Separator as dt}from"@inquirer/search";import ft from"process";import pt from"https";import mt from"cli-progress";import ht from"http";import gt from"fuse.js";import _t from"ajv";import vt from"ajv-formats";import yt from"gpt-tokens";import{LRUCache as bt}from"lru-cache";import"@streamparser/json";var xt=`@hhsw2015/task-master-ai`,St=`0.43.11`;function Ct(e,t,n){return(n?.color?B[n.color]:B.cyan)(at(e,t,{fallback:(e,t)=>`${e} (${t})`}))}function wt(e,t){return Ct(e,e,t)}const Tt=it([`#00b4d8`,`#0077b6`,`#03045e`]);function Et(){return process.env.TM_HIDE_BANNER===`true`}function Dt(){return process.stdout.columns||80}function Ot(e={}){if(Et())return;let{version:t}=e;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Tt(e))}catch{console.log(Tt(`=== Task Master ===`))}let n=Ct(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`),r=B.dim(`by `)+B.cyan(n),i=t?t.replace(/^v/,``):``,a=`https://github.com/eyaltoledano/claude-task-master/releases/tag/task-master-ai%40${i}`,o=t?Ct(`v${i}`,a,{color:`gray`}):``;if(o){let e=i.length+1,t=Dt(),n=Math.max(2,t-22-e-2);console.log(r+` `.repeat(n)+o)}else console.log(r);let s=Ct(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(s)),console.log(``)}function kt(){if(Et())return;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Tt(e))}catch{console.log(Tt(`=== Task Master ===`))}let e=Ct(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`);console.log(B.dim(`by `)+B.cyan(e));let t=Ct(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(t)),console.log(``)}function At(e){let{header:t,body:n,callToAction:r,footer:i,level:a=`warn`}=e,o=a===`info`?B.blue.bold:B.yellow.bold,s=a===`info`?`blue`:`yellow`,c=[o(t),...n.map(e=>B.white(e))];return r&&r.label&&r.action&&c.push(B.cyan(r.label)+`
2
2
  `+B.blue.underline(r.action)),i&&c.push(B.gray(i)),W(c.join(`
3
3
 
4
- `),{padding:1,borderColor:s,borderStyle:`round`,margin:{top:1,bottom:1}})}function kt(e,t=30,n){if(!n){let n=Math.round(e/100*t),r=t-n;return B.green(`█`).repeat(n)+B.gray(`░`).repeat(r)}let r=``,i=0;if(n.done&&n.done>0){let e=Math.round(n.done/100*t);e>0&&(r+=B.green(`█`).repeat(e),i+=e)}if(n.cancelled&&i<t){let e=Math.round(n.cancelled/100*t),a=Math.min(e,t-i);a>0&&(r+=B.gray(`█`).repeat(a),i+=a)}if(n.deferred&&i<t){let e=Math.round(n.deferred/100*t),a=Math.min(e,t-i);a>0&&(r+=B.gray(`█`).repeat(a),i+=a)}if(n[`in-progress`]&&i<t){let e=Math.round(n[`in-progress`]/100*t),a=Math.min(e,t-i);a>0&&(r+=B.blue(`█`).repeat(a),i+=a)}if(n.review&&i<t){let e=Math.round(n.review/100*t),a=Math.min(e,t-i);a>0&&(r+=B.magenta(`░`).repeat(a),i+=a)}if(n.pending&&i<t){let e=Math.round(n.pending/100*t),a=Math.min(e,t-i);a>0&&(r+=B.yellow(`░`).repeat(a),i+=a)}if(n.blocked&&i<t){let e=Math.round(n.blocked/100*t),a=Math.min(e,t-i);a>0&&(r+=B.red(`░`).repeat(a),i+=a)}return i<t&&(r+=B.yellow(`░`).repeat(t-i)),r}function At(e){let t={total:e.length,done:0,inProgress:0,pending:0,blocked:0,deferred:0,cancelled:0,review:0,completionPercentage:0,completedCount:0};return e.forEach(e=>{switch(e.status){case`done`:t.done++;break;case`in-progress`:t.inProgress++;break;case`pending`:t.pending++;break;case`blocked`:t.blocked++;break;case`deferred`:t.deferred++;break;case`cancelled`:t.cancelled++;break;case`review`:t.review=(t.review||0)+1;break}}),t.completedCount=e.filter(e=>We(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function jt(e){let t={total:0,done:0,inProgress:0,pending:0,blocked:0,deferred:0,cancelled:0,review:0,completionPercentage:0,completedCount:0},n=[];return e.forEach(e=>{e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{switch(t.total++,n.push(e),e.status){case`done`:t.done++;break;case`in-progress`:t.inProgress++;break;case`pending`:t.pending++;break;case`blocked`:t.blocked++;break;case`deferred`:t.deferred++;break;case`cancelled`:t.cancelled++;break;case`review`:t.review=(t.review||0)+1;break}})}),t.completedCount=n.filter(e=>We(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function Mt(e){let t=new Set(e.filter(e=>We(e.status)).map(e=>e.id)),n=e.filter(e=>!We(e.status)&&(!e.dependencies||e.dependencies.length===0)).length,r=e.filter(e=>!We(e.status)&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>t.has(e))).length,i=e.filter(e=>!We(e.status)&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>t.has(e))).length,a={};e.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{let t=String(e);a[t]=(a[t]||0)+1})});let o,s=0;for(let[e,t]of Object.entries(a))t>s&&(s=t,o=parseInt(e));let c=e.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0),l=e.length>0?c/e.length:0;return{tasksWithNoDeps:n,tasksReadyToWork:n+r,tasksBlockedByDeps:i,mostDependedOnTaskId:o,mostDependedOnCount:s,avgDependenciesPerTask:l}}function Nt(e){let t={critical:0,high:0,medium:0,low:0};return e.forEach(e=>{let n=e.priority||`medium`;t[n]++}),t}function Pt(e){return e.total===0?{}:{done:e.done/e.total*100,"in-progress":e.inProgress/e.total*100,pending:e.pending/e.total*100,blocked:e.blocked/e.total*100,deferred:e.deferred/e.total*100,cancelled:e.cancelled/e.total*100,review:(e.review||0)/e.total*100}}function Ft(e,t=!1){let n=[];t?n.push(`Completed: ${B.green(`${e.completedCount}/${e.total}`)}`):n.push(`Done: ${B.green(e.done)}`),n.push(`Cancelled: ${B.gray(e.cancelled)}`),n.push(`Deferred: ${B.gray(e.deferred)}`);let r=n.join(` `);n.length=0,n.push(`In Progress: ${B.blue(e.inProgress)}`),n.push(`Review: ${B.magenta(e.review||0)}`),n.push(`Pending: ${B.yellow(e.pending)}`),n.push(`Blocked: ${B.red(e.blocked)}`);let i=n.join(` `);return r+`
5
- `+i}function It(e,t,n){let r=Pt(e),i=Pt(t),a=kt(e.completionPercentage,30,r),o=kt(t.completionPercentage,30,i),s=`${e.completionPercentage}% ${e.completedCount}/${e.total}`,c=`${t.completionPercentage}% ${t.completedCount}/${t.total}`;return B.white.bold(`Project Dashboard`)+`
6
- Tasks Progress: ${a} ${B.yellow(s)}\n`+Ft(e,!1)+`
4
+ `),{padding:1,borderColor:s,borderStyle:`round`,margin:{top:1,bottom:1}})}function jt(e,t=30,n){if(!n){let n=Math.round(e/100*t),r=t-n;return B.green(`█`).repeat(n)+B.gray(`░`).repeat(r)}let r=``,i=0;if(n.done&&n.done>0){let e=Math.round(n.done/100*t);e>0&&(r+=B.green(`█`).repeat(e),i+=e)}if(n.cancelled&&i<t){let e=Math.round(n.cancelled/100*t),a=Math.min(e,t-i);a>0&&(r+=B.gray(`█`).repeat(a),i+=a)}if(n.deferred&&i<t){let e=Math.round(n.deferred/100*t),a=Math.min(e,t-i);a>0&&(r+=B.gray(`█`).repeat(a),i+=a)}if(n[`in-progress`]&&i<t){let e=Math.round(n[`in-progress`]/100*t),a=Math.min(e,t-i);a>0&&(r+=B.blue(`█`).repeat(a),i+=a)}if(n.review&&i<t){let e=Math.round(n.review/100*t),a=Math.min(e,t-i);a>0&&(r+=B.magenta(`░`).repeat(a),i+=a)}if(n.pending&&i<t){let e=Math.round(n.pending/100*t),a=Math.min(e,t-i);a>0&&(r+=B.yellow(`░`).repeat(a),i+=a)}if(n.blocked&&i<t){let e=Math.round(n.blocked/100*t),a=Math.min(e,t-i);a>0&&(r+=B.red(`░`).repeat(a),i+=a)}return i<t&&(r+=B.yellow(`░`).repeat(t-i)),r}function Mt(e){let t={total:e.length,done:0,inProgress:0,pending:0,blocked:0,deferred:0,cancelled:0,review:0,completionPercentage:0,completedCount:0};return e.forEach(e=>{switch(e.status){case`done`:t.done++;break;case`in-progress`:t.inProgress++;break;case`pending`:t.pending++;break;case`blocked`:t.blocked++;break;case`deferred`:t.deferred++;break;case`cancelled`:t.cancelled++;break;case`review`:t.review=(t.review||0)+1;break}}),t.completedCount=e.filter(e=>Ue(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function Nt(e){let t={total:0,done:0,inProgress:0,pending:0,blocked:0,deferred:0,cancelled:0,review:0,completionPercentage:0,completedCount:0},n=[];return e.forEach(e=>{e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{switch(t.total++,n.push(e),e.status){case`done`:t.done++;break;case`in-progress`:t.inProgress++;break;case`pending`:t.pending++;break;case`blocked`:t.blocked++;break;case`deferred`:t.deferred++;break;case`cancelled`:t.cancelled++;break;case`review`:t.review=(t.review||0)+1;break}})}),t.completedCount=n.filter(e=>Ue(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function Pt(e){let t=new Set(e.filter(e=>Ue(e.status)).map(e=>e.id)),n=e.filter(e=>!Ue(e.status)&&(!e.dependencies||e.dependencies.length===0)).length,r=e.filter(e=>!Ue(e.status)&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>t.has(e))).length,i=e.filter(e=>!Ue(e.status)&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>t.has(e))).length,a={};e.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{let t=String(e);a[t]=(a[t]||0)+1})});let o,s=0;for(let[e,t]of Object.entries(a))t>s&&(s=t,o=parseInt(e));let c=e.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0),l=e.length>0?c/e.length:0;return{tasksWithNoDeps:n,tasksReadyToWork:n+r,tasksBlockedByDeps:i,mostDependedOnTaskId:o,mostDependedOnCount:s,avgDependenciesPerTask:l}}function Ft(e){let t={critical:0,high:0,medium:0,low:0};return e.forEach(e=>{let n=e.priority||`medium`;t[n]++}),t}function It(e){return e.total===0?{}:{done:e.done/e.total*100,"in-progress":e.inProgress/e.total*100,pending:e.pending/e.total*100,blocked:e.blocked/e.total*100,deferred:e.deferred/e.total*100,cancelled:e.cancelled/e.total*100,review:(e.review||0)/e.total*100}}function Lt(e,t=!1){let n=[];t?n.push(`Completed: ${B.green(`${e.completedCount}/${e.total}`)}`):n.push(`Done: ${B.green(e.done)}`),n.push(`Cancelled: ${B.gray(e.cancelled)}`),n.push(`Deferred: ${B.gray(e.deferred)}`);let r=n.join(` `);n.length=0,n.push(`In Progress: ${B.blue(e.inProgress)}`),n.push(`Review: ${B.magenta(e.review||0)}`),n.push(`Pending: ${B.yellow(e.pending)}`),n.push(`Blocked: ${B.red(e.blocked)}`);let i=n.join(` `);return r+`
5
+ `+i}function Rt(e,t,n){let r=It(e),i=It(t),a=jt(e.completionPercentage,30,r),o=jt(t.completionPercentage,30,i),s=`${e.completionPercentage}% ${e.completedCount}/${e.total}`,c=`${t.completionPercentage}% ${t.completedCount}/${t.total}`;return B.white.bold(`Project Dashboard`)+`
6
+ Tasks Progress: ${a} ${B.yellow(s)}\n`+Lt(e,!1)+`
7
7
 
8
- Subtasks Progress: ${o} ${B.cyan(c)}\n`+Ft(t,!0)+`
8
+ Subtasks Progress: ${o} ${B.cyan(c)}\n`+Lt(t,!0)+`
9
9
 
10
10
  `+B.cyan.bold(`Priority Breakdown:`)+`
11
- ${B.red(`•`)} ${B.white(`High priority:`)} ${n.high}\n${B.yellow(`•`)} ${B.white(`Medium priority:`)} ${n.medium}\n${B.green(`•`)} ${B.white(`Low priority:`)} ${n.low}`}function Lt(e,t){return B.white.bold(`Dependency Status & Next Task`)+`
11
+ ${B.red(`•`)} ${B.white(`High priority:`)} ${n.high}\n${B.yellow(`•`)} ${B.white(`Medium priority:`)} ${n.medium}\n${B.green(`•`)} ${B.white(`Low priority:`)} ${n.low}`}function zt(e,t){return B.white.bold(`Dependency Status & Next Task`)+`
12
12
  `+B.cyan.bold(`Dependency Metrics:`)+`
13
13
  ${B.green(`•`)} ${B.white(`Tasks with no dependencies:`)} ${e.tasksWithNoDeps}\n${B.green(`•`)} ${B.white(`Tasks ready to work on:`)} ${e.tasksReadyToWork}\n${B.yellow(`•`)} ${B.white(`Tasks blocked by dependencies:`)} ${e.tasksBlockedByDeps}\n${B.magenta(`•`)} ${B.white(`Most depended-on task:`)} ${e.mostDependedOnTaskId?B.cyan(`#${e.mostDependedOnTaskId} (${e.mostDependedOnCount} dependents)`):B.gray(`None`)}\n${B.blue(`•`)} ${B.white(`Avg dependencies per task:`)} ${e.avgDependenciesPerTask.toFixed(1)}\n\n`+B.cyan.bold(`Next Task to Work On:`)+`
14
- ID: ${t?B.cyan(String(t.id)):B.gray(`N/A`)} - ${t?B.white.bold(t.title):B.yellow(`No task available`)}\nPriority: ${t?.priority||B.gray(`N/A`)} Dependencies: ${t?.dependencies?.length?B.cyan(t.dependencies.join(`, `)):B.gray(`None`)}\nComplexity: ${t?.complexity===void 0?B.gray(`N/A`):Sn(t.complexity)}`}function Rt(e,t,n,r,i){let a=It(e,t,n),o=Lt(r,i),s=process.stdout.columns||80;if(s>=104){let e=Math.floor(s/2),t=e-4,n=W(a,{padding:1,borderColor:`blue`,borderStyle:`round`,width:t,dimBorder:!1}),r=W(o,{padding:1,borderColor:`magenta`,borderStyle:`round`,width:t,dimBorder:!1}),i=n.split(`
14
+ ID: ${t?B.cyan(String(t.id)):B.gray(`N/A`)} - ${t?B.white.bold(t.title):B.yellow(`No task available`)}\nPriority: ${t?.priority||B.gray(`N/A`)} Dependencies: ${t?.dependencies?.length?B.cyan(t.dependencies.join(`, `)):B.gray(`None`)}\nComplexity: ${t?.complexity===void 0?B.gray(`N/A`):wn(t.complexity)}`}function Bt(e,t,n,r,i){let a=Rt(e,t,n),o=zt(r,i),s=process.stdout.columns||80;if(s>=104){let e=Math.floor(s/2),t=e-4,n=W(a,{padding:1,borderColor:`blue`,borderStyle:`round`,width:t,dimBorder:!1}),r=W(o,{padding:1,borderColor:`magenta`,borderStyle:`round`,width:t,dimBorder:!1}),i=n.split(`
15
15
  `),c=r.split(`
16
16
  `),l=Math.max(i.length,c.length),u=[];for(let t=0;t<l;t++){let n=t<i.length?i[t]:``,r=t<c.length?c[t]:``,a=n.padEnd(e,` `);u.push(a+r)}console.log(u.join(`
17
- `))}else{let e=W(a,{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:0,bottom:1}}),t=W(o,{padding:1,borderColor:`magenta`,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}}function zt(e={}){let{filePath:t,tag:n,storageType:r,briefInfo:i}=e;if(r===`api`&&i){let e=`🏷 Brief: ${B.cyan(i.briefName)} ${B.gray(`(${i.briefId})`)}`;if(console.log(e),i.webAppUrl&&i.orgSlug){let e=`${i.webAppUrl}/home/${i.orgSlug}/briefs/${i.briefId}/plan`;console.log(`Listing tasks from: ${St(e,{color:`gray`})}`)}else i.webAppUrl?(console.log(`Listing tasks from: ${B.dim(`${i.webAppUrl} (Brief: ${i.briefId})`)}`),console.log(B.yellow(`Tip: Run ${B.cyan(`tm context select`)} to set your organization and see the full URL`))):console.log(`Listing tasks from: ${B.dim(`API (Brief ID: ${i.briefId})`)}`)}else if(n){let e=``;if(e=n&&n!==`master`?`🏷 tag: ${B.cyan(n)}`:`🏷 tag: ${B.cyan(`master`)}`,console.log(e),t){let e=t.startsWith(`/`)?t:`${process.cwd()}/${t}`;console.log(`Listing tasks from: ${B.dim(e)}`)}}}const Bt=new ct({headingStyle:`atx`,codeBlockStyle:`fenced`,bulletListMarker:`-`});ot.use(st({code:e=>e.split(`
17
+ `))}else{let e=W(a,{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:0,bottom:1}}),t=W(o,{padding:1,borderColor:`magenta`,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}}function Vt(e={}){let{filePath:t,tag:n,storageType:r,briefInfo:i}=e;if(r===`api`&&i){let e=`🏷 Brief: ${B.cyan(i.briefName)} ${B.gray(`(${i.briefId})`)}`;if(console.log(e),i.webAppUrl&&i.orgSlug){let e=`${i.webAppUrl}/home/${i.orgSlug}/briefs/${i.briefId}/plan`;console.log(`Listing tasks from: ${wt(e,{color:`gray`})}`)}else i.webAppUrl?(console.log(`Listing tasks from: ${B.dim(`${i.webAppUrl} (Brief: ${i.briefId})`)}`),console.log(B.yellow(`Tip: Run ${B.cyan(`tm context select`)} to set your organization and see the full URL`))):console.log(`Listing tasks from: ${B.dim(`API (Brief ID: ${i.briefId})`)}`)}else if(n){let e=``;if(e=n&&n!==`master`?`🏷 tag: ${B.cyan(n)}`:`🏷 tag: ${B.cyan(`master`)}`,console.log(e),t){let e=t.startsWith(`/`)?t:`${process.cwd()}/${t}`;console.log(`Listing tasks from: ${B.dim(e)}`)}}}const Ht=new ct({headingStyle:`atx`,codeBlockStyle:`fenced`,bulletListMarker:`-`});ot.use(st({code:e=>e.split(`
18
18
  `).map(e=>` `+B.cyan(e)).join(`
19
- `),blockquote:B.gray.italic,html:B.gray,heading:B.white.bold,hr:B.gray,listitem:B.white,paragraph:B.white,strong:B.white.bold,em:B.white.italic,codespan:B.cyan,del:B.dim.strikethrough,link:B.blue,href:B.blue.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:120})),ot.setOptions({breaks:!0,gfm:!0});function Vt(e){if(!e)return``;let t=e.replace(/\\\\/g,`\\`).replace(/\\n/g,`
20
- `).replace(/\\t/g,` `).replace(/\\"/g,`"`);/<[^>]+>/.test(t)&&(t=Bt.turndown(t));let n=ot(t);return typeof n==`string`?n.trim():t}function Ht(e,t){if(!e){t?console.log(B.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`)):console.log(W(B.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`⚠️ NO TASKS AVAILABLE ⚠️`,titleAlignment:`center`}));return}let n=[];n.push(`🔥 ${B.hex(`#FF8800`).bold(`Next Task to Work On:`)} ${B.yellow(`#${e.id}`)}${B.hex(`#FF8800`).bold(` - ${e.title}`)}`),n.push(``);let r=[];if(e.priority){let t=e.priority===`high`?B.red:e.priority===`medium`?B.yellow:B.gray;r.push(`Priority: ${t.bold(e.priority)}`)}if(e.status){let t=e.status===`pending`?B.yellow(`○ pending`):e.status===`in-progress`?B.blue(`▶ in-progress`):B.gray(e.status);r.push(`Status: ${t}`)}n.push(r.join(` `));let i=!e.dependencies||e.dependencies.length===0?B.gray(`None`):B.cyan(e.dependencies.join(`, `));n.push(`Dependencies: ${i}`),typeof e.complexity==`number`&&n.push(`Complexity: ${Sn(e.complexity)}`),e.description&&(n.push(``),n.push(`Description: ${B.white(Vt(e.description))}`)),n.push(``),n.push(`${B.cyan(`Start working:`)} ${B.yellow(`task-master set-status --id=${e.id} --status=in-progress`)}`),n.push(`${B.cyan(`View details:`)} ${B.yellow(`task-master show ${e.id}`)}`),console.log(W(n.join(`
21
- `),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:`#FFA500`,title:B.hex(`#FFA500`)(`⚡ RECOMMENDED NEXT TASK ⚡`),titleAlignment:`center`,width:Cn(.97),fullscreen:!1}))}function Ut(e){if(`description`in e&&e.description)return e.description;if(`details`in e&&e.details)return e.details.split(`
22
- `)[0].split(`.`)[0]}function Wt(){let e=[`${B.cyan(`1.`)} Run ${B.yellow(`task-master next`)} to see what to work on next`,`${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks`,`${B.cyan(`3.`)} Run ${B.yellow(`task-master set-status --id=<id> --status=done`)} to mark a task as complete`];console.log(W(B.white.bold(`Suggested Next Steps:`)+`
19
+ `),blockquote:B.gray.italic,html:B.gray,heading:B.white.bold,hr:B.gray,listitem:B.white,paragraph:B.white,strong:B.white.bold,em:B.white.italic,codespan:B.cyan,del:B.dim.strikethrough,link:B.blue,href:B.blue.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:120})),ot.setOptions({breaks:!0,gfm:!0});function Ut(e){if(!e)return``;let t=e.replace(/\\\\/g,`\\`).replace(/\\n/g,`
20
+ `).replace(/\\t/g,` `).replace(/\\"/g,`"`);/<[^>]+>/.test(t)&&(t=Ht.turndown(t));let n=ot(t);return typeof n==`string`?n.trim():t}function Wt(e,t){if(!e){t?console.log(B.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`)):console.log(W(B.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`⚠️ NO TASKS AVAILABLE ⚠️`,titleAlignment:`center`}));return}let n=[];n.push(`🔥 ${B.hex(`#FF8800`).bold(`Next Task to Work On:`)} ${B.yellow(`#${e.id}`)}${B.hex(`#FF8800`).bold(` - ${e.title}`)}`),n.push(``);let r=[];if(e.priority){let t=e.priority===`high`?B.red:e.priority===`medium`?B.yellow:B.gray;r.push(`Priority: ${t.bold(e.priority)}`)}if(e.status){let t=e.status===`pending`?B.yellow(`○ pending`):e.status===`in-progress`?B.blue(`▶ in-progress`):B.gray(e.status);r.push(`Status: ${t}`)}n.push(r.join(` `));let i=!e.dependencies||e.dependencies.length===0?B.gray(`None`):B.cyan(e.dependencies.join(`, `));n.push(`Dependencies: ${i}`),typeof e.complexity==`number`&&n.push(`Complexity: ${wn(e.complexity)}`),e.description&&(n.push(``),n.push(`Description: ${B.white(Ut(e.description))}`)),n.push(``),n.push(`${B.cyan(`Start working:`)} ${B.yellow(`task-master set-status --id=${e.id} --status=in-progress`)}`),n.push(`${B.cyan(`View details:`)} ${B.yellow(`task-master show ${e.id}`)}`),console.log(W(n.join(`
21
+ `),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:`#FFA500`,title:B.hex(`#FFA500`)(`⚡ RECOMMENDED NEXT TASK ⚡`),titleAlignment:`center`,width:Tn(.97),fullscreen:!1}))}function Gt(e){if(`description`in e&&e.description)return e.description;if(`details`in e&&e.details)return e.details.split(`
22
+ `)[0].split(`.`)[0]}function Kt(){let e=[`${B.cyan(`1.`)} Run ${B.yellow(`task-master next`)} to see what to work on next`,`${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks`,`${B.cyan(`3.`)} Run ${B.yellow(`task-master set-status --id=<id> --status=done`)} to mark a task as complete`];console.log(W(B.white.bold(`Suggested Next Steps:`)+`
23
23
 
24
24
  `+e.join(`
25
- `),{padding:1,margin:{top:0,bottom:1},borderStyle:`round`,borderColor:`gray`,width:Cn(.97)}))}const Gt={research:`🔍`,design:`🎨`,development:`🔧`,testing:`🧪`,documentation:`📝`,review:`👀`};function Kt(e){switch(e){case`create`:return B.green(`✚ CREATE`);case`modify`:return B.yellow(`✎ MODIFY`);case`reference`:return B.blue(`👁 REFER `);default:return B.gray(` FILE `)}}function qt(e){return`${Gt[e]||`📋`} ${e}`}function Jt(e,t){console.log(W(B.white.bold(`Task: #${e} - ${t}`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`blue`,borderStyle:`round`}))}function Yt(e,t){let n=process.stdout.columns*.95||100,r=new K({head:[],style:{head:[],border:[`grey`]},colWidths:[Math.floor(n*.2),Math.floor(n*.8)],wordWrap:!0}),i=e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`None`,a=t||String(e.id),o=Vt(e.description||``),s=e.category?`${qt(e.category)}`:B.gray(`N/A`),c=e.skills&&e.skills.length>0?e.skills.map(e=>B.magenta(`[${e}]`)).join(` `):B.gray(`N/A`),l=[B.cyan(`ID:`),B.cyan(`Title:`),B.cyan(`Status:`),B.cyan(`Priority:`),B.cyan(`Dependencies:`),B.cyan(`Complexity:`),B.cyan(`Category:`),B.cyan(`Skills:`),B.cyan(`Description:`)].join(`
26
- `),u=[a,e.title,mn(e.status),bn(e.priority),i,typeof e.complexity==`number`?Sn(e.complexity):B.gray(`N/A`),s,c,o].join(`
27
- `);r.push([l,u]),console.log(r.toString())}function Xt(e){let t=process.stdout.columns*.95||100,n=Vt(e);console.log(W(B.white.bold(`Implementation Details:`)+`
25
+ `),{padding:1,margin:{top:0,bottom:1},borderStyle:`round`,borderColor:`gray`,width:Tn(.97)}))}const qt={research:`🔍`,design:`🎨`,development:`🔧`,testing:`🧪`,documentation:`📝`,review:`👀`};function Jt(e){switch(e){case`create`:return B.green(`✚ CREATE`);case`modify`:return B.yellow(`✎ MODIFY`);case`reference`:return B.blue(`👁 REFER `);default:return B.gray(` FILE `)}}function Yt(e){return`${qt[e]||`📋`} ${e}`}function Xt(e,t){console.log(W(B.white.bold(`Task: #${e} - ${t}`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`blue`,borderStyle:`round`}))}function Zt(e,t){let n=process.stdout.columns*.95||100,r=new K({head:[],style:{head:[],border:[`grey`]},colWidths:[Math.floor(n*.2),Math.floor(n*.8)],wordWrap:!0}),i=e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`None`,a=t||String(e.id),o=Ut(e.description||``),s=e.category?`${Yt(e.category)}`:B.gray(`N/A`),c=e.skills&&e.skills.length>0?e.skills.map(e=>B.magenta(`[${e}]`)).join(` `):B.gray(`N/A`),l=[B.cyan(`ID:`),B.cyan(`Title:`),B.cyan(`Status:`),B.cyan(`Priority:`),B.cyan(`Dependencies:`),B.cyan(`Complexity:`),B.cyan(`Category:`),B.cyan(`Skills:`),B.cyan(`Description:`)].join(`
26
+ `),u=[a,e.title,gn(e.status),Sn(e.priority),i,typeof e.complexity==`number`?wn(e.complexity):B.gray(`N/A`),s,c,o].join(`
27
+ `);r.push([l,u]),console.log(r.toString())}function Qt(e){let t=process.stdout.columns*.95||100,n=Ut(e);console.log(W(B.white.bold(`Implementation Details:`)+`
28
28
 
29
- `+n,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:t}))}function Zt(e){let t=process.stdout.columns*.95||100,n=Vt(e);console.log(W(B.white.bold(`Test Strategy:`)+`
29
+ `+n,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:t}))}function $t(e){let t=process.stdout.columns*.95||100,n=Ut(e);console.log(W(B.white.bold(`Test Strategy:`)+`
30
30
 
31
- `+n,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:t}))}function Qt(e,t,n){let r=process.stdout.columns*.95||100;console.log(W(B.magenta.bold(`Subtasks`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`magenta`,borderStyle:`round`,margin:{top:1,bottom:0}}));let i=new K({head:[B.magenta.bold(`ID`),B.magenta.bold(`Status`),B.magenta.bold(`Title`),B.magenta.bold(`Deps`)],style:{head:[],border:[`grey`]},colWidths:[Math.floor(r*.1),Math.floor(r*.15),Math.floor(r*.6),Math.floor(r*.15)],wordWrap:!0});e.forEach(e=>{let r=n===`file`&&t?`${t}.${e.id}`:String(e.id),a=e.dependencies&&e.dependencies.length>0?e.dependencies.join(`, `):`None`;i.push([r,mn(e.status),e.title,a])}),console.log(i.toString())}function $t(e){let t=process.stdout.columns*.95||100,n=e.map(e=>`${Kt(e.action)} ${B.white(e.path)}\n ${B.gray(e.description)}`).join(`
31
+ `+n,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:t}))}function en(e,t,n){let r=process.stdout.columns*.95||100;console.log(W(B.magenta.bold(`Subtasks`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`magenta`,borderStyle:`round`,margin:{top:1,bottom:0}}));let i=new K({head:[B.magenta.bold(`ID`),B.magenta.bold(`Status`),B.magenta.bold(`Title`),B.magenta.bold(`Deps`)],style:{head:[],border:[`grey`]},colWidths:[Math.floor(r*.1),Math.floor(r*.15),Math.floor(r*.6),Math.floor(r*.15)],wordWrap:!0});e.forEach(e=>{let r=n===`file`&&t?`${t}.${e.id}`:String(e.id),a=e.dependencies&&e.dependencies.length>0?e.dependencies.join(`, `):`None`;i.push([r,gn(e.status),e.title,a])}),console.log(i.toString())}function tn(e){let t=process.stdout.columns*.95||100,n=e.map(e=>`${Jt(e.action)} ${B.white(e.path)}\n ${B.gray(e.description)}`).join(`
32
32
 
33
33
  `);console.log(W(B.white.bold(`📂 Files to Touch:`)+`
34
34
 
35
- `+n,{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function en(e){let t=process.stdout.columns*.95||100,n=e.map(e=>`${B.cyan.bold(e.name)} → ${B.gray(e.location)}\n ↳ ${B.white(e.usage)}`).join(`
35
+ `+n,{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function nn(e){let t=process.stdout.columns*.95||100,n=e.map(e=>`${B.cyan.bold(e.name)} → ${B.gray(e.location)}\n ↳ ${B.white(e.usage)}`).join(`
36
36
 
37
37
  `);console.log(W(B.white.bold(`🔗 Leverage Existing Code:`)+`
38
38
 
39
- `+n,{padding:1,borderStyle:`round`,borderColor:`blue`,width:t}))}function tn(e){let t=process.stdout.columns*.95||100,n=``;e.included&&(n+=B.green.bold(`✅ In Scope:
39
+ `+n,{padding:1,borderStyle:`round`,borderColor:`blue`,width:t}))}function rn(e){let t=process.stdout.columns*.95||100,n=``;e.included&&(n+=B.green.bold(`✅ In Scope:
40
40
  `),n+=B.white(` `+e.included)),e.excluded&&(n&&(n+=`
41
41
 
42
42
  `),n+=B.red.bold(`⛔ Out of Scope:
43
43
  `),n+=B.gray(` `+e.excluded)),console.log(W(B.white.bold(`🎯 Scope Boundaries:`)+`
44
44
 
45
- `+n,{padding:1,borderStyle:`round`,borderColor:`magenta`,width:t}))}function nn(e){let t=process.stdout.columns*.95||100,n=e.map(e=>B.white(`☐ ${e}`)).join(`
45
+ `+n,{padding:1,borderStyle:`round`,borderColor:`magenta`,width:t}))}function an(e){let t=process.stdout.columns*.95||100,n=e.map(e=>B.white(`☐ ${e}`)).join(`
46
46
  `);console.log(W(B.white.bold(`✓ Acceptance Criteria:`)+`
47
47
 
48
- `+n,{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function rn(e){let t=process.stdout.columns*.95||100,n=e.map(e=>B.yellow(`▸ ${e}`)).join(`
48
+ `+n,{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function on(e){let t=process.stdout.columns*.95||100,n=e.map(e=>B.yellow(`▸ ${e}`)).join(`
49
49
  `);console.log(W(B.white.bold(`🔒 Technical Constraints:`)+`
50
50
 
51
- `+n,{padding:1,borderStyle:`round`,borderColor:`red`,width:t}))}function an(e){let t=process.stdout.columns*.95||100,n=Vt(e);console.log(W(B.white.bold(`📋 Implementation Approach:`)+`
51
+ `+n,{padding:1,borderStyle:`round`,borderColor:`red`,width:t}))}function sn(e){let t=process.stdout.columns*.95||100,n=Ut(e);console.log(W(B.white.bold(`📋 Implementation Approach:`)+`
52
52
 
53
- `+n,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:t}))}function on(e){let t=process.stdout.columns*.95||100,n=e.map(e=>B.white(`• ${e}`)).join(`
53
+ `+n,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:t}))}function cn(e){let t=process.stdout.columns*.95||100,n=e.map(e=>B.white(`• ${e}`)).join(`
54
54
  `);console.log(W(B.white.bold(`📐 Codebase Patterns:`)+`
55
55
 
56
- `+n,{padding:1,borderStyle:`round`,borderColor:`gray`,width:t}))}function sn(e){(e.relevantFiles||e.existingInfrastructure||e.scopeBoundaries||e.acceptanceCriteria||e.technicalConstraints||e.implementationApproach||e.codebasePatterns)&&(e.implementationApproach&&(console.log(),an(e.implementationApproach)),e.relevantFiles&&e.relevantFiles.length>0&&(console.log(),$t(e.relevantFiles)),e.existingInfrastructure&&e.existingInfrastructure.length>0&&(console.log(),en(e.existingInfrastructure)),e.codebasePatterns&&e.codebasePatterns.length>0&&(console.log(),on(e.codebasePatterns)),e.scopeBoundaries&&(console.log(),tn(e.scopeBoundaries)),e.technicalConstraints&&e.technicalConstraints.length>0&&(console.log(),rn(e.technicalConstraints)),e.acceptanceCriteria&&e.acceptanceCriteria.length>0&&(console.log(),nn(e.acceptanceCriteria)))}function cn(e){console.log(W(B.white.bold(`Suggested Actions:`)+`
56
+ `+n,{padding:1,borderStyle:`round`,borderColor:`gray`,width:t}))}function ln(e){(e.relevantFiles||e.existingInfrastructure||e.scopeBoundaries||e.acceptanceCriteria||e.technicalConstraints||e.implementationApproach||e.codebasePatterns)&&(e.implementationApproach&&(console.log(),sn(e.implementationApproach)),e.relevantFiles&&e.relevantFiles.length>0&&(console.log(),tn(e.relevantFiles)),e.existingInfrastructure&&e.existingInfrastructure.length>0&&(console.log(),nn(e.existingInfrastructure)),e.codebasePatterns&&e.codebasePatterns.length>0&&(console.log(),cn(e.codebasePatterns)),e.scopeBoundaries&&(console.log(),rn(e.scopeBoundaries)),e.technicalConstraints&&e.technicalConstraints.length>0&&(console.log(),on(e.technicalConstraints)),e.acceptanceCriteria&&e.acceptanceCriteria.length>0&&(console.log(),an(e.acceptanceCriteria)))}function un(e){console.log(W(B.white.bold(`Suggested Actions:`)+`
57
57
 
58
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master set-status --id=${e} --status=in-progress`)} to start working\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=${e}`)} to break down into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master update-task --id=${e} --prompt="..."`)} to update details`,{padding:1,margin:{top:1},borderStyle:`round`,borderColor:`green`,width:process.stdout.columns*.95||100}))}function ln(e,t){let{statusFilter:n,showSuggestedActions:r=!1,customHeader:i,headerColor:a=`blue`,originalTaskId:o,storageType:s}=t||{};if(i?console.log(W(B.white.bold(i),{padding:{top:0,bottom:0,left:1,right:1},borderColor:a,borderStyle:`round`,margin:{top:1}})):Jt(o||e.id,e.title),Yt(e,o),e.details&&(console.log(),Xt(e.details)),`testStrategy`in e&&e.testStrategy&&(console.log(),Zt(e.testStrategy)),sn(e),e.subtasks&&e.subtasks.length>0){let t=n?e.subtasks.filter(e=>e.status===n):e.subtasks;t.length===0&&n?(console.log(),console.log(B.gray(` No subtasks with status '${n}'`))):t.length>0&&(console.log(),Qt(t,e.id,s))}r&&(console.log(),cn(o||e.id))}function un(e){return e===`api`?`Hamster Studio`:`tasks.json`}function dn(e,t){let n=Ae(t),r=un(e);console.log(B.dim(`\nWatching ${r} for changes...`)),console.log(B.gray(`Last synced: ${n}`)),console.log(B.dim(`Press Ctrl+C to exit`))}function fn(e,t){let n=Ae(t),r=un(e);console.log(B.blue(`\nℹ ${r} updated at ${n}`))}const pn={done:{color:B.green,icon:`✓`,tableIcon:`✓`},pending:{color:B.yellow,icon:`○`,tableIcon:`○`},"in-progress":{color:B.hex(`#FFA500`),icon:`▶`,tableIcon:`▶`},deferred:{color:B.gray,icon:`x`,tableIcon:`x`},review:{color:B.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:B.gray,icon:`x`,tableIcon:`x`},blocked:{color:B.red,icon:`!`,tableIcon:`!`},completed:{color:B.green,icon:`✓`,tableIcon:`✓`}};function mn(e,t=!1){let n=pn[e]||{color:B.red,icon:`X`,tableIcon:`X`},r=t?n.tableIcon:n.icon;return n.color(`${r} ${e}`)}const hn={draft:{color:B.gray,icon:`○`,tableIcon:`○`},refining:{color:B.yellow,icon:`◐`,tableIcon:`◐`},aligned:{color:B.cyan,icon:`◎`,tableIcon:`◎`},delivering:{color:B.hex(`#FFA500`),icon:`▶`,tableIcon:`▶`},delivered:{color:B.blue,icon:`◆`,tableIcon:`◆`},done:{color:B.green,icon:`✓`,tableIcon:`✓`},archived:{color:B.gray,icon:`■`,tableIcon:`■`}};function gn(e){return hn[e.toLowerCase()]||{color:B.red,icon:`?`,tableIcon:`?`}}function _n(e){return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}function vn(e,t=!1){if(!e)return B.gray(`○ Unknown`);let n=gn(e),r=t?n.tableIcon:n.icon,i=_n(e);return n.color(`${r} ${i}`)}const yn={critical:B.red.bold,high:B.red,medium:B.yellow,low:B.gray};function bn(e){return(yn[e]||B.white)(e)}function xn(e){return e>=7?{color:B.hex(`#CC0000`),label:`High`}:e>=4?{color:B.hex(`#FF8800`),label:`Medium`}:{color:B.green,label:`Low`}}function Sn(e){let t=typeof e==`string`?Number(e.trim()):e;if(isNaN(t))return B.gray(`N/A`);let{color:n}=xn(t);return n(`● ${t}`)}function Cn(e=.9,t=40){let n=process.stdout.columns||80;return Math.max(Math.floor(n*e),t)}function wn(e,t){return e.length<=t?e:e.substring(0,t-3)+`...`}function Tn(e=`Task Master`){console.log(W(B.white.bold(e),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:`blue`,textAlignment:`center`}))}function En(e,t){let n=Cn();console.error(W(B.red.bold(`X Error: `)+B.white(e)+(t?`
58
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master set-status --id=${e} --status=in-progress`)} to start working\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=${e}`)} to break down into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master update-task --id=${e} --prompt="..."`)} to update details`,{padding:1,margin:{top:1},borderStyle:`round`,borderColor:`green`,width:process.stdout.columns*.95||100}))}function dn(e,t){let{statusFilter:n,showSuggestedActions:r=!1,customHeader:i,headerColor:a=`blue`,originalTaskId:o,storageType:s}=t||{};if(i?console.log(W(B.white.bold(i),{padding:{top:0,bottom:0,left:1,right:1},borderColor:a,borderStyle:`round`,margin:{top:1}})):Xt(o||e.id,e.title),Zt(e,o),e.details&&(console.log(),Qt(e.details)),`testStrategy`in e&&e.testStrategy&&(console.log(),$t(e.testStrategy)),ln(e),e.subtasks&&e.subtasks.length>0){let t=n?e.subtasks.filter(e=>e.status===n):e.subtasks;t.length===0&&n?(console.log(),console.log(B.gray(` No subtasks with status '${n}'`))):t.length>0&&(console.log(),en(t,e.id,s))}r&&(console.log(),un(o||e.id))}function fn(e){return e===`api`?`Hamster Studio`:`tasks.json`}function pn(e,t){let n=Oe(t),r=fn(e);console.log(B.dim(`\nWatching ${r} for changes...`)),console.log(B.gray(`Last synced: ${n}`)),console.log(B.dim(`Press Ctrl+C to exit`))}function mn(e,t){let n=Oe(t),r=fn(e);console.log(B.blue(`\nℹ ${r} updated at ${n}`))}const hn={done:{color:B.green,icon:`✓`,tableIcon:`✓`},pending:{color:B.yellow,icon:`○`,tableIcon:`○`},"in-progress":{color:B.hex(`#FFA500`),icon:`▶`,tableIcon:`▶`},deferred:{color:B.gray,icon:`x`,tableIcon:`x`},review:{color:B.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:B.gray,icon:`x`,tableIcon:`x`},blocked:{color:B.red,icon:`!`,tableIcon:`!`},completed:{color:B.green,icon:`✓`,tableIcon:`✓`}};function gn(e,t=!1){let n=hn[e]||{color:B.red,icon:`X`,tableIcon:`X`},r=t?n.tableIcon:n.icon;return n.color(`${r} ${e}`)}const _n={draft:{color:B.gray,icon:`○`,tableIcon:`○`},refining:{color:B.yellow,icon:`◐`,tableIcon:`◐`},aligned:{color:B.cyan,icon:`◎`,tableIcon:`◎`},delivering:{color:B.hex(`#FFA500`),icon:`▶`,tableIcon:`▶`},delivered:{color:B.blue,icon:`◆`,tableIcon:`◆`},done:{color:B.green,icon:`✓`,tableIcon:`✓`},archived:{color:B.gray,icon:`■`,tableIcon:`■`}};function vn(e){return _n[e.toLowerCase()]||{color:B.red,icon:`?`,tableIcon:`?`}}function yn(e){return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}function bn(e,t=!1){if(!e)return B.gray(`○ Unknown`);let n=vn(e),r=t?n.tableIcon:n.icon,i=yn(e);return n.color(`${r} ${i}`)}const xn={critical:B.red.bold,high:B.red,medium:B.yellow,low:B.gray};function Sn(e){return(xn[e]||B.white)(e)}function Cn(e){return e>=7?{color:B.hex(`#CC0000`),label:`High`}:e>=4?{color:B.hex(`#FF8800`),label:`Medium`}:{color:B.green,label:`Low`}}function wn(e){let t=typeof e==`string`?Number(e.trim()):e;if(isNaN(t))return B.gray(`N/A`);let{color:n}=Cn(t);return n(`● ${t}`)}function Tn(e=.9,t=40){let n=process.stdout.columns||80;return Math.max(Math.floor(n*e),t)}function En(e,t){return e.length<=t?e:e.substring(0,t-3)+`...`}function Dn(e=`Task Master`){console.log(W(B.white.bold(e),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:`blue`,textAlignment:`center`}))}function On(e,t){let n=Tn();console.error(W(B.red.bold(`X Error: `)+B.white(e)+(t?`
59
59
 
60
- `+B.gray(t):``),{padding:1,borderStyle:`round`,borderColor:`red`,width:n}))}const Y=En;function Dn(e){let t=Cn();console.log(W(B.green.bold(`√ `)+B.white(e),{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function On(e){let t=Cn();console.log(W(B.yellow.bold(`⚠️ `)+B.white(e),{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function kn(e){let t=Cn();console.log(W(B.blue.bold(`i `)+B.white(e),{padding:1,borderStyle:`round`,borderColor:`blue`,width:t}))}const An={0:[.1,.5,.2,.2],1:[.08,.4,.18,.14,.2],2:[.08,.35,.14,.11,.16,.16],3:[.07,.3,.12,.1,.14,.14,.1],4:[.12,.06,.2,.1,.1,.12,.12,.1]};function jn(e,t){let{showSubtasks:n=!1,showComplexity:r=!1,showDependencies:i=!0,showBlocks:a=!1,showTag:o=!1}=t||{},s=Cn(.9,100),c=(An[(o?1:0)+(i?1:0)+(a?1:0)+(r?1:0)]||An[4]).map(e=>Math.floor(s*e)),l=[],u=[],d=0;o&&(l.push(B.blue.bold(`Tag`)),u.push(c[d++])),l.push(B.blue.bold(`ID`),B.blue.bold(`Title`),B.blue.bold(`Status`),B.blue.bold(`Priority`)),u.push(...c.slice(d,d+4)),d+=4,i&&(l.push(B.blue.bold(`Dependencies`)),u.push(c[d++])),a&&(l.push(B.blue.bold(`Blocks`)),u.push(c[d++])),r&&(l.push(B.blue.bold(`Complexity`)),u.push(c[d]||12));let f=new K({head:l,style:{head:[],border:[]},colWidths:u,wordWrap:!0});return e.forEach(e=>{let t=[];o&&t.push(B.magenta(e.tagName||`-`));let s=o?2:1;if(t.push(B.cyan(e.id.toString()),wn(e.title,u[s]-3),mn(e.status,!0),bn(e.priority)),i&&(!e.dependencies||e.dependencies.length===0?t.push(B.gray(`-`)):t.push(B.cyan(e.dependencies.map(e=>String(e)).join(`, `)))),a)if(!e.blocks||e.blocks.length===0)t.push(B.gray(`-`));else{let n=e.blocks.join(`, `);t.push(We(e.status)?B.gray(n):B.yellow(n))}r&&(typeof e.complexity==`number`?t.push(Sn(e.complexity)):t.push(B.gray(`N/A`))),f.push(t),n&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{let t=[];o&&t.push(B.gray(`-`));let n=o?2:1;if(t.push(B.gray(` └─ ${e.id}`),B.gray(wn(e.title,u[n]-6)),B.gray(mn(e.status,!0)),B.gray(e.priority||`medium`)),i&&t.push(B.gray(e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`-`)),a&&t.push(B.gray(`-`)),r){let n=typeof e.complexity==`number`?Sn(e.complexity):`--`;t.push(B.gray(n))}f.push(t)})}),f.toString()}function Mn(e,t){if(!e){zt({tag:t.tag||`master`,storageType:t.storageType});return}let n=e.tasks.getStorageType(),r=e.auth.getStorageDisplayInfo(n);zt({tag:t.tag||`master`,filePath:r.filePath,storageType:r.storageType,briefInfo:r.briefInfo})}function Nn(){return process.env.DEBUG===`true`||process.env.DEBUG===`1`}function X(e,t={}){if(e?.getSanitizedDetails){let n=e.getSanitizedDetails();console.error(B.red(`\n${n.message}`)),(Nn()||t.forceStack)&&e.stack&&(console.error(B.gray(`
61
- Stack trace:`)),console.error(B.gray(e.stack)))}else if(e instanceof x)console.error(B.red(`\n${e.message}`)),(Nn()||t.forceStack)&&e.stack&&(console.error(B.gray(`
62
- Stack trace:`)),console.error(B.gray(e.stack)));else if(p(e)){let n=e.code,r=n&&m[n]||e.message;console.error(B.red(`\n${r}`)),(Nn()||t.forceStack)&&e.stack&&(console.error(B.gray(`
63
- Stack trace:`)),console.error(B.gray(e.stack)))}else{let n=e?.message??String(e);console.error(B.red(`\nError: ${n}`)),(Nn()||t.forceStack)&&e?.stack&&(console.error(B.gray(`
64
- Stack trace:`)),console.error(B.gray(e.stack)))}t.skipExit||process.exit(1)}function Z(e){return e?Ke(e):ie()}var Pn=class e extends G{tmCore;lastResult;constructor(e){super(e||`list`),this.description(`List tasks with optional filtering`).alias(`ls`).argument(`[status]`,`Filter by status (e.g., pending, done, in-progress) or "all" to show with subtasks`).option(`-s, --status <status>`,`Filter by status (fallback if not using positional)`).option(`-t, --tag <tag>`,`Filter by tag`).option(`--with-subtasks`,`Include subtasks in the output`).option(`-f, --format <format>`,`Output format (text, json, compact)`,`text`).option(`--json`,`Output in JSON format (shorthand for --format json)`).option(`-c, --compact`,`Output in compact format (shorthand for --format compact)`).option(`--no-header`,`Hide the command header`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).option(`-w, --watch`,`Watch for changes and update list automatically`).option(`--ready`,`Show only tasks ready to work on (dependencies satisfied)`).option(`--blocking`,`Show only tasks that block other tasks`).option(`--all-tags`,`Show tasks from all tags (combine with --ready for actionable tasks)`).action(async(e,t)=>{let n=e||t?.status,r=t?.withSubtasks||!1;e===`all`&&(n=void 0,r=!0);let i={...t,status:n,withSubtasks:r};await this.executeCommand(i)})}async executeCommand(e){try{if(this.validateOptions(e)||process.exit(1),await this.initializeCore(Z(e.project)),e.watch)await this.watchTasks(e);else{let t=e.allTags?await this.getTasksFromAllTags(e):await this.getTasks(e);this.setLastResult(t),e.silent||this.displayResults(t,e)}}catch(e){X(e)}}async watchTasks(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.getTasks(e),n=new Date;console.clear(),this.displayResults(t,e);let r=t.storageType;dn(r,n);let i;try{i=await this.tmCore.tasks.watch(async i=>{if(i.type===`change`)try{t=await this.getTasks(e),n=new Date,console.clear(),this.displayResults(t,e),fn(r,n),dn(r,n)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(B.yellow(`\nWarning: Failed to refresh tasks: ${t}`))}else i.type===`error`&&i.error&&console.error(B.red(`\n⚠ Watch error: ${i.error.message}`))},{tag:e.tag});let a=()=>{i?.unsubscribe(),process.exit(0)};process.on(`SIGINT`,a),process.on(`SIGTERM`,a),await new Promise(()=>{})}catch(e){throw console.error(B.red(`Watch mode error: ${e.message}`)),e}}validateOptions(e){if(e.format&&!pe.includes(e.format))return console.error(B.red(`Invalid format: ${e.format}`)),console.error(B.gray(`Valid formats: ${pe.join(`, `)}`)),!1;if(e.status){let t=e.status.split(`,`).map(e=>e.trim());for(let e of t)if(e!==`all`&&!Ve.includes(e))return console.error(B.red(`Invalid status: ${e}`)),console.error(B.gray(`Valid statuses: ${Ve.join(`, `)}`)),!1}return e.allTags&&e.watch?(console.error(B.red(`--all-tags cannot be used with --watch mode`)),console.error(B.gray(`Use --all-tags without --watch, or --watch without --all-tags`)),!1):!0}async initializeCore(e){this.tmCore||=await I({projectPath:e})}async getTasks(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=e.status&&e.status!==`all`?e.status.split(`,`).map(e=>e.trim()):void 0,n=e.ready||e.blocking,r=t&&!n?{status:t}:void 0,i=await this.tmCore.tasks.list({tag:e.tag,filter:r,includeSubtasks:e.withSubtasks}),{blocksMap:a,invalidDependencies:o}=j(i.tasks);this.displayInvalidDependencyWarnings(o);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[]}));return e.ready&&(s=N(s)),e.blocking&&(s=k(s)),t&&n&&(s=s.filter(e=>t.includes(e.status))),{...i,tasks:s,filtered:s.length}}async getTasksFromAllTags(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.tmCore.tasks.getTagsWithStats(),n=[],r=0,i=[];for(let a of t.tags){let t=a.name;try{let i=await this.tmCore.tasks.list({tag:t,includeSubtasks:e.withSubtasks});r+=i.tasks.length;let{blocksMap:a,invalidDependencies:o}=j(i.tasks);this.displayInvalidDependencyWarnings(o,t);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[],tagName:t})),c=e.ready?N(s):s;n.push(...c)}catch(e){let n=e instanceof Error?e.message:String(e);i.push({name:t,error:n});continue}}if(i.length>0&&(console.warn(B.yellow(`\nWarning: Could not fetch tasks from ${i.length} tag(s):`)),i.forEach(({name:e,error:t})=>{console.warn(B.gray(` ${e}: ${t}`))})),i.length===t.tags.length&&t.tags.length>0)throw Error(`Failed to fetch tasks from any tag. First error: ${i[0].error}`);let a=n;if(e.blocking&&(a=a.filter(e=>e.blocks.length>0)),e.status&&e.status!==`all`){let t=e.status.split(`,`).map(e=>e.trim());a=a.filter(e=>t.includes(e.status))}return{tasks:a,total:r,filtered:a.length,storageType:this.tmCore.tasks.getStorageType(),allTags:!0}}displayInvalidDependencyWarnings(e,t){if(e.length===0)return;let n=t?` (tag: ${t})`:``;console.warn(B.yellow(`\nWarning: ${e.length} invalid dependency reference(s) found${n}:`)),e.slice(0,5).forEach(({taskId:e,depId:t})=>{console.warn(B.gray(` Task ${e} depends on non-existent task ${t}`))}),e.length>5&&console.warn(B.gray(` ...and ${e.length-5} more`))}displayResults(e,t){let n=t.format||`text`;switch(t.json?n=`json`:t.compact&&(n=`compact`),n){case`json`:this.displayJson(e);break;case`compact`:this.displayCompact(e,t);break;case`text`:default:this.displayText(e,t);break}}displayJson(e){console.log(JSON.stringify({tasks:e.tasks,metadata:{total:e.total,filtered:e.filtered,tag:e.allTags?`all`:e.tag,storageType:e.storageType,allTags:e.allTags||!1}},null,2))}displayCompact(e,t){let{tasks:n,tag:r,storageType:i,allTags:a}=e;t.noHeader!==!0&&Mn(this.tmCore,{tag:a?`all tags`:r||`master`,storageType:i});for(let e of n){let n=ee[e.status],r=a&&`tagName`in e?B.magenta(`[${e.tagName}] `):``;if(console.log(`${r}${B.cyan(e.id)} ${n} ${e.title}`),t.withSubtasks&&e.subtasks?.length)for(let t of e.subtasks){let e=ee[t.status];console.log(` ${B.gray(String(t.id))} ${e} ${B.gray(t.title)}`)}}}displayText(e,t){let{tasks:n,tag:r,storageType:i,allTags:a}=e;if(t.noHeader!==!0&&Mn(this.tmCore,{tag:a?`all tags`:r||`master`,storageType:i}),n.length===0){On(`No tasks found matching the criteria.`);return}let o=At(n),s=jt(n),c=Mt(n),l=Nt(n),u=this.findNextTask(n),d=u?n.find(e=>String(e.id)===String(u.id)):void 0,f=t.ready||t.blocking||a;if(f||Rt(o,s,l,c,d),console.log(jn(n,{showSubtasks:t.withSubtasks,showDependencies:!0,showBlocks:!0,showComplexity:!0,showTag:a})),!f){if(d){let e=Ut(d);Ht({id:d.id,title:d.title,priority:d.priority,status:d.status,dependencies:d.dependencies,description:e,complexity:d.complexity})}Wt()}}setLastResult(e){this.lastResult=e}findNextTask(e){let t={critical:4,high:3,medium:2,low:1},n=new Set;e.forEach(e=>{We(e.status)&&n.add(String(e.id)),e.subtasks&&e.subtasks.forEach(t=>{We(t.status)&&n.add(`${e.id}.${t.id}`)})});let r=[];if(e.filter(e=>e.status===`in-progress`&&e.subtasks&&e.subtasks.length>0).forEach(e=>{e.subtasks.forEach(t=>{let i=(t.status||`pending`).toLowerCase();if(i!==`pending`&&i!==`in-progress`)return;let a=t.dependencies?.map(t=>typeof t==`string`&&t.includes(`.`)?t:`${e.id}.${t}`)??[];(a.length===0||a.every(e=>n.has(String(e))))&&r.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,priority:t.priority||e.priority||`medium`,dependencies:a.map(e=>String(e))})})}),r.length>0)return r.sort((e,n)=>{let r=t[e.priority||`medium`]??2,i=t[n.priority||`medium`]??2;if(i!==r)return i-r;let a=e.dependencies?.length||0,o=n.dependencies?.length||0;return a===o?String(e.id).localeCompare(String(n.id)):a-o}),r[0];let i=e.filter(e=>{let t=(e.status||`pending`).toLowerCase();if(t!==`pending`&&t!==`in-progress`)return!1;let r=e.dependencies||[];return r.length===0||r.every(e=>n.has(String(e)))});if(i.length===0)return;i.sort((e,n)=>{let r=t[e.priority||`medium`]??2,i=t[n.priority||`medium`]??2;if(i!==r)return i-r;let a=e.dependencies?.length||0,o=n.dependencies?.length||0;return a===o?Number(e.id)-Number(n.id):a-o});let a=i[0];return{id:a.id,title:a.title,priority:a.priority,dependencies:a.dependencies?.map(e=>String(e))}}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Fn=class e extends G{tmCore;lastResult;constructor(e){super(e||`show`),this.description(`Display detailed information about one or more tasks`).argument(`[id]`,`Task ID(s) to show (comma-separated for multiple)`).option(`-i, --id <id>`,`Task ID(s) to show (comma-separated for multiple)`).option(`-s, --status <status>`,`Filter subtasks by status`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`--json`,`Output in JSON format (shorthand for --format json)`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).action(async(e,t)=>{await this.executeCommand(e,t)})}async executeCommand(e,t){try{this.validateOptions(t)||process.exit(1),await this.initializeCore(Z(t.project));let n=e||t.id;n||(console.error(B.red(`Error: Please provide a task ID`)),process.exit(1));let r=n.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),i=[];for(let e of r){let t=Oe.safeParse(e);t.success||(console.error(B.red(`Invalid task ID: ${e}`),B.gray(`- ${t.error.issues[0]?.message}`)),process.exit(1)),i.push(t.data)}let a=i.length>1?await this.getMultipleTasks(i,t):await this.getSingleTask(i[0],t);this.setLastResult(a),t.silent||this.displayResults(a,t)}catch(e){X(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(B.red(`Invalid format: ${e.format}`)),console.error(B.gray(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await I({projectPath:e})}async getSingleTask(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=await this.tmCore.tasks.get(e),r=this.tmCore.tasks.getStorageType();return{task:n.task,found:n.task!==null,storageType:r,originalTaskId:n.isSubtask?e:void 0}}async getMultipleTasks(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=[],r=[];for(let t of e){let e=await this.tmCore.tasks.get(t);e.task?n.push(e.task):r.push(t)}return{tasks:n,notFound:r,storageType:this.tmCore.tasks.getStorageType()}}displayResults(e,t){switch(t.json?`json`:t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:`task`in e?this.displaySingleTask(e,t):this.displayMultipleTasks(e,t);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displaySingleTask(e,t){if(!e.found||!e.task){console.log(W(B.yellow(`Task not found!`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));return}let n=this.tmCore?.config.getActiveTag()||`master`;Mn(this.tmCore,{tag:n,storageType:e.storageType}),console.log(),ln(e.task,{statusFilter:t.status,showSuggestedActions:!0,originalTaskId:e.originalTaskId,storageType:e.storageType})}displayMultipleTasks(e,t){let n=this.tmCore?.config.getActiveTag()||`master`;if(Mn(this.tmCore,{tag:n,storageType:e.storageType}),e.notFound.length>0&&console.log(B.yellow(`\n⚠️ Not found: ${e.notFound.join(`, `)}`)),e.tasks.length===0){On(`No tasks found matching the criteria.`);return}console.log(B.blue.bold(`
60
+ `+B.gray(t):``),{padding:1,borderStyle:`round`,borderColor:`red`,width:n}))}const Y=On;function kn(e){let t=Tn();console.log(W(B.green.bold(`√ `)+B.white(e),{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function An(e){let t=Tn();console.log(W(B.yellow.bold(`⚠️ `)+B.white(e),{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function jn(e){let t=Tn();console.log(W(B.blue.bold(`i `)+B.white(e),{padding:1,borderStyle:`round`,borderColor:`blue`,width:t}))}const Mn={0:[.1,.5,.2,.2],1:[.08,.4,.18,.14,.2],2:[.08,.35,.14,.11,.16,.16],3:[.07,.3,.12,.1,.14,.14,.1],4:[.12,.06,.2,.1,.1,.12,.12,.1]};function Nn(e,t){let{showSubtasks:n=!1,showComplexity:r=!1,showDependencies:i=!0,showBlocks:a=!1,showTag:o=!1}=t||{},s=Tn(.9,100),c=(Mn[(o?1:0)+(i?1:0)+(a?1:0)+(r?1:0)]||Mn[4]).map(e=>Math.floor(s*e)),l=[],u=[],d=0;o&&(l.push(B.blue.bold(`Tag`)),u.push(c[d++])),l.push(B.blue.bold(`ID`),B.blue.bold(`Title`),B.blue.bold(`Status`),B.blue.bold(`Priority`)),u.push(...c.slice(d,d+4)),d+=4,i&&(l.push(B.blue.bold(`Dependencies`)),u.push(c[d++])),a&&(l.push(B.blue.bold(`Blocks`)),u.push(c[d++])),r&&(l.push(B.blue.bold(`Complexity`)),u.push(c[d]||12));let f=new K({head:l,style:{head:[],border:[]},colWidths:u,wordWrap:!0});return e.forEach(e=>{let t=[];o&&t.push(B.magenta(e.tagName||`-`));let s=o?2:1;if(t.push(B.cyan(e.id.toString()),En(e.title,u[s]-3),gn(e.status,!0),Sn(e.priority)),i&&(!e.dependencies||e.dependencies.length===0?t.push(B.gray(`-`)):t.push(B.cyan(e.dependencies.map(e=>String(e)).join(`, `)))),a)if(!e.blocks||e.blocks.length===0)t.push(B.gray(`-`));else{let n=e.blocks.join(`, `);t.push(Ue(e.status)?B.gray(n):B.yellow(n))}r&&(typeof e.complexity==`number`?t.push(wn(e.complexity)):t.push(B.gray(`N/A`))),f.push(t),n&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{let t=[];o&&t.push(B.gray(`-`));let n=o?2:1;if(t.push(B.gray(` └─ ${e.id}`),B.gray(En(e.title,u[n]-6)),B.gray(gn(e.status,!0)),B.gray(e.priority||`medium`)),i&&t.push(B.gray(e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`-`)),a&&t.push(B.gray(`-`)),r){let n=typeof e.complexity==`number`?wn(e.complexity):`--`;t.push(B.gray(n))}f.push(t)})}),f.toString()}function Pn(e,t){if(!e){Vt({tag:t.tag||`master`,storageType:t.storageType});return}let n=e.tasks.getStorageType(),r=e.auth.getStorageDisplayInfo(n);Vt({tag:t.tag||`master`,filePath:r.filePath,storageType:r.storageType,briefInfo:r.briefInfo})}function Fn(){return process.env.DEBUG===`true`||process.env.DEBUG===`1`}function X(e,t={}){if(e?.getSanitizedDetails){let n=e.getSanitizedDetails();console.error(B.red(`\n${n.message}`)),(Fn()||t.forceStack)&&e.stack&&(console.error(B.gray(`
61
+ Stack trace:`)),console.error(B.gray(e.stack)))}else if(e instanceof m)console.error(B.red(`\n${e.message}`)),(Fn()||t.forceStack)&&e.stack&&(console.error(B.gray(`
62
+ Stack trace:`)),console.error(B.gray(e.stack)));else if(T(e)){let n=e.code,r=n&&Ve[n]||e.message;console.error(B.red(`\n${r}`)),(Fn()||t.forceStack)&&e.stack&&(console.error(B.gray(`
63
+ Stack trace:`)),console.error(B.gray(e.stack)))}else{let n=e?.message??String(e);console.error(B.red(`\nError: ${n}`)),(Fn()||t.forceStack)&&e?.stack&&(console.error(B.gray(`
64
+ Stack trace:`)),console.error(B.gray(e.stack)))}t.skipExit||process.exit(1)}function Z(e){return e?Ge(e):re()}var In=class e extends G{tmCore;lastResult;constructor(e){super(e||`list`),this.description(`List tasks with optional filtering`).alias(`ls`).argument(`[status]`,`Filter by status (e.g., pending, done, in-progress) or "all" to show with subtasks`).option(`-s, --status <status>`,`Filter by status (fallback if not using positional)`).option(`-t, --tag <tag>`,`Filter by tag`).option(`--with-subtasks`,`Include subtasks in the output`).option(`-f, --format <format>`,`Output format (text, json, compact)`,`text`).option(`--json`,`Output in JSON format (shorthand for --format json)`).option(`-c, --compact`,`Output in compact format (shorthand for --format compact)`).option(`--no-header`,`Hide the command header`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).option(`-w, --watch`,`Watch for changes and update list automatically`).option(`--ready`,`Show only tasks ready to work on (dependencies satisfied)`).option(`--blocking`,`Show only tasks that block other tasks`).option(`--all-tags`,`Show tasks from all tags (combine with --ready for actionable tasks)`).action(async(e,t)=>{let n=e||t?.status,r=t?.withSubtasks||!1;e===`all`&&(n=void 0,r=!0);let i={...t,status:n,withSubtasks:r};await this.executeCommand(i)})}async executeCommand(e){try{if(this.validateOptions(e)||process.exit(1),await this.initializeCore(Z(e.project)),e.watch)await this.watchTasks(e);else{let t=e.allTags?await this.getTasksFromAllTags(e):await this.getTasks(e);this.setLastResult(t),e.silent||this.displayResults(t,e)}}catch(e){X(e)}}async watchTasks(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.getTasks(e),n=new Date;console.clear(),this.displayResults(t,e);let r=t.storageType;pn(r,n);let i;try{i=await this.tmCore.tasks.watch(async i=>{if(i.type===`change`)try{t=await this.getTasks(e),n=new Date,console.clear(),this.displayResults(t,e),mn(r,n),pn(r,n)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(B.yellow(`\nWarning: Failed to refresh tasks: ${t}`))}else i.type===`error`&&i.error&&console.error(B.red(`\n⚠ Watch error: ${i.error.message}`))},{tag:e.tag});let a=()=>{i?.unsubscribe(),process.exit(0)};process.on(`SIGINT`,a),process.on(`SIGTERM`,a),await new Promise(()=>{})}catch(e){throw console.error(B.red(`Watch mode error: ${e.message}`)),e}}validateOptions(e){if(e.format&&!fe.includes(e.format))return console.error(B.red(`Invalid format: ${e.format}`)),console.error(B.gray(`Valid formats: ${fe.join(`, `)}`)),!1;if(e.status){let t=e.status.split(`,`).map(e=>e.trim());for(let e of t)if(e!==`all`&&!ze.includes(e))return console.error(B.red(`Invalid status: ${e}`)),console.error(B.gray(`Valid statuses: ${ze.join(`, `)}`)),!1}return e.allTags&&e.watch?(console.error(B.red(`--all-tags cannot be used with --watch mode`)),console.error(B.gray(`Use --all-tags without --watch, or --watch without --all-tags`)),!1):!0}async initializeCore(e){this.tmCore||=await I({projectPath:e})}async getTasks(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=e.status&&e.status!==`all`?e.status.split(`,`).map(e=>e.trim()):void 0,n=e.ready||e.blocking,r=t&&!n?{status:t}:void 0,i=await this.tmCore.tasks.list({tag:e.tag,filter:r,includeSubtasks:e.withSubtasks}),{blocksMap:a,invalidDependencies:o}=A(i.tasks);this.displayInvalidDependencyWarnings(o);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[]}));return e.ready&&(s=M(s)),e.blocking&&(s=O(s)),t&&n&&(s=s.filter(e=>t.includes(e.status))),{...i,tasks:s,filtered:s.length}}async getTasksFromAllTags(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.tmCore.tasks.getTagsWithStats(),n=[],r=0,i=[];for(let a of t.tags){let t=a.name;try{let i=await this.tmCore.tasks.list({tag:t,includeSubtasks:e.withSubtasks});r+=i.tasks.length;let{blocksMap:a,invalidDependencies:o}=A(i.tasks);this.displayInvalidDependencyWarnings(o,t);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[],tagName:t})),c=e.ready?M(s):s;n.push(...c)}catch(e){let n=e instanceof Error?e.message:String(e);i.push({name:t,error:n});continue}}if(i.length>0&&(console.warn(B.yellow(`\nWarning: Could not fetch tasks from ${i.length} tag(s):`)),i.forEach(({name:e,error:t})=>{console.warn(B.gray(` ${e}: ${t}`))})),i.length===t.tags.length&&t.tags.length>0)throw Error(`Failed to fetch tasks from any tag. First error: ${i[0].error}`);let a=n;if(e.blocking&&(a=a.filter(e=>e.blocks.length>0)),e.status&&e.status!==`all`){let t=e.status.split(`,`).map(e=>e.trim());a=a.filter(e=>t.includes(e.status))}return{tasks:a,total:r,filtered:a.length,storageType:this.tmCore.tasks.getStorageType(),allTags:!0}}displayInvalidDependencyWarnings(e,t){if(e.length===0)return;let n=t?` (tag: ${t})`:``;console.warn(B.yellow(`\nWarning: ${e.length} invalid dependency reference(s) found${n}:`)),e.slice(0,5).forEach(({taskId:e,depId:t})=>{console.warn(B.gray(` Task ${e} depends on non-existent task ${t}`))}),e.length>5&&console.warn(B.gray(` ...and ${e.length-5} more`))}displayResults(e,t){let n=t.format||`text`;switch(t.json?n=`json`:t.compact&&(n=`compact`),n){case`json`:this.displayJson(e);break;case`compact`:this.displayCompact(e,t);break;case`text`:default:this.displayText(e,t);break}}displayJson(e){console.log(JSON.stringify({tasks:e.tasks,metadata:{total:e.total,filtered:e.filtered,tag:e.allTags?`all`:e.tag,storageType:e.storageType,allTags:e.allTags||!1}},null,2))}displayCompact(e,t){let{tasks:n,tag:r,storageType:i,allTags:a}=e;t.noHeader!==!0&&Pn(this.tmCore,{tag:a?`all tags`:r||`master`,storageType:i});for(let e of n){let n=P[e.status],r=a&&`tagName`in e?B.magenta(`[${e.tagName}] `):``;if(console.log(`${r}${B.cyan(e.id)} ${n} ${e.title}`),t.withSubtasks&&e.subtasks?.length)for(let t of e.subtasks){let e=P[t.status];console.log(` ${B.gray(String(t.id))} ${e} ${B.gray(t.title)}`)}}}displayText(e,t){let{tasks:n,tag:r,storageType:i,allTags:a}=e;if(t.noHeader!==!0&&Pn(this.tmCore,{tag:a?`all tags`:r||`master`,storageType:i}),n.length===0){An(`No tasks found matching the criteria.`);return}let o=Mt(n),s=Nt(n),c=Pt(n),l=Ft(n),u=this.findNextTask(n),d=u?n.find(e=>String(e.id)===String(u.id)):void 0,f=t.ready||t.blocking||a;if(f||Bt(o,s,l,c,d),console.log(Nn(n,{showSubtasks:t.withSubtasks,showDependencies:!0,showBlocks:!0,showComplexity:!0,showTag:a})),!f){if(d){let e=Gt(d);Wt({id:d.id,title:d.title,priority:d.priority,status:d.status,dependencies:d.dependencies,description:e,complexity:d.complexity})}Kt()}}setLastResult(e){this.lastResult=e}findNextTask(e){let t={critical:4,high:3,medium:2,low:1},n=new Set;e.forEach(e=>{Ue(e.status)&&n.add(String(e.id)),e.subtasks&&e.subtasks.forEach(t=>{Ue(t.status)&&n.add(`${e.id}.${t.id}`)})});let r=[];if(e.filter(e=>e.status===`in-progress`&&e.subtasks&&e.subtasks.length>0).forEach(e=>{e.subtasks.forEach(t=>{let i=(t.status||`pending`).toLowerCase();if(i!==`pending`&&i!==`in-progress`)return;let a=t.dependencies?.map(t=>typeof t==`string`&&t.includes(`.`)?t:`${e.id}.${t}`)??[];(a.length===0||a.every(e=>n.has(String(e))))&&r.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,priority:t.priority||e.priority||`medium`,dependencies:a.map(e=>String(e))})})}),r.length>0)return r.sort((e,n)=>{let r=t[e.priority||`medium`]??2,i=t[n.priority||`medium`]??2;if(i!==r)return i-r;let a=e.dependencies?.length||0,o=n.dependencies?.length||0;return a===o?String(e.id).localeCompare(String(n.id)):a-o}),r[0];let i=e.filter(e=>{let t=(e.status||`pending`).toLowerCase();if(t!==`pending`&&t!==`in-progress`)return!1;let r=e.dependencies||[];return r.length===0||r.every(e=>n.has(String(e)))});if(i.length===0)return;i.sort((e,n)=>{let r=t[e.priority||`medium`]??2,i=t[n.priority||`medium`]??2;if(i!==r)return i-r;let a=e.dependencies?.length||0,o=n.dependencies?.length||0;return a===o?Number(e.id)-Number(n.id):a-o});let a=i[0];return{id:a.id,title:a.title,priority:a.priority,dependencies:a.dependencies?.map(e=>String(e))}}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Ln=class e extends G{tmCore;lastResult;constructor(e){super(e||`show`),this.description(`Display detailed information about one or more tasks`).argument(`[id]`,`Task ID(s) to show (comma-separated for multiple)`).option(`-i, --id <id>`,`Task ID(s) to show (comma-separated for multiple)`).option(`-s, --status <status>`,`Filter subtasks by status`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`--json`,`Output in JSON format (shorthand for --format json)`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).action(async(e,t)=>{await this.executeCommand(e,t)})}async executeCommand(e,t){try{this.validateOptions(t)||process.exit(1),await this.initializeCore(Z(t.project));let n=e||t.id;n||(console.error(B.red(`Error: Please provide a task ID`)),process.exit(1));let r=n.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),i=[];for(let e of r){let t=Ee.safeParse(e);t.success||(console.error(B.red(`Invalid task ID: ${e}`),B.gray(`- ${t.error.issues[0]?.message}`)),process.exit(1)),i.push(t.data)}let a=i.length>1?await this.getMultipleTasks(i,t):await this.getSingleTask(i[0],t);this.setLastResult(a),t.silent||this.displayResults(a,t)}catch(e){X(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(B.red(`Invalid format: ${e.format}`)),console.error(B.gray(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await I({projectPath:e})}async getSingleTask(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=await this.tmCore.tasks.get(e),r=this.tmCore.tasks.getStorageType();return{task:n.task,found:n.task!==null,storageType:r,originalTaskId:n.isSubtask?e:void 0}}async getMultipleTasks(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=[],r=[];for(let t of e){let e=await this.tmCore.tasks.get(t);e.task?n.push(e.task):r.push(t)}return{tasks:n,notFound:r,storageType:this.tmCore.tasks.getStorageType()}}displayResults(e,t){switch(t.json?`json`:t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:`task`in e?this.displaySingleTask(e,t):this.displayMultipleTasks(e,t);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displaySingleTask(e,t){if(!e.found||!e.task){console.log(W(B.yellow(`Task not found!`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));return}let n=this.tmCore?.config.getActiveTag()||`master`;Pn(this.tmCore,{tag:n,storageType:e.storageType}),console.log(),dn(e.task,{statusFilter:t.status,showSuggestedActions:!0,originalTaskId:e.originalTaskId,storageType:e.storageType})}displayMultipleTasks(e,t){let n=this.tmCore?.config.getActiveTag()||`master`;if(Pn(this.tmCore,{tag:n,storageType:e.storageType}),e.notFound.length>0&&console.log(B.yellow(`\n⚠️ Not found: ${e.notFound.join(`, `)}`)),e.tasks.length===0){An(`No tasks found matching the criteria.`);return}console.log(B.blue.bold(`
65
65
  📋 Tasks:
66
- `)),console.log(jn(e.tasks,{showSubtasks:!0,showDependencies:!0}))}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},In=class e extends G{tmCore;lastResult;constructor(e){super(e||`next`),this.description(`Find the next available task to work on`).option(`-t, --tag <tag>`,`Filter by tag`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).action(async e=>{await this.executeCommand(e)})}async executeCommand(e){let t=!1;try{this.validateOptions(e),await this.initializeCore(Z(e.project));let t=await this.getNextTask(e);this.setLastResult(t),e.silent||this.displayResults(t,e)}catch(e){t=!0,X(e,{skipExit:!0})}finally{await this.cleanup()}t&&process.exit(1)}validateOptions(e){if(e.format&&![`text`,`json`].includes(e.format))throw Error(`Invalid format: ${e.format}. Valid formats are: text, json`)}async initializeCore(e){this.tmCore||=await I({projectPath:Ge.resolve(e)})}async getNextTask(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.tmCore.tasks.getNext(e.tag),n=this.tmCore.tasks.getStorageType(),r=e.tag||this.tmCore.config.getActiveTag(),i=await this.tmCore.tasks.list({tag:e.tag}),a=i&&i.tasks.length>0;return{task:t,found:t!==null,tag:r,storageType:n,hasAnyTasks:a}}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:this.displayText(e);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e){if(Mn(this.tmCore,{tag:e.tag||`master`,storageType:e.storageType}),!e.found||!e.task){e.hasAnyTasks?(console.log(B.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`)),console.log(`\n${B.dim(`Tip: Try`)} ${B.cyan(`task-master list`)} ${B.dim(`to see all tasks`)}`)):(console.log(W(B.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`⚠️ NO TASKS AVAILABLE ⚠️`,titleAlignment:`center`})),console.log(`\n${B.dim(`Tip: Create tasks with`)} ${B.cyan(`task-master parse-prd`)} ${B.dim(`or`)} ${B.cyan(`task-master add-task`)}`));return}let t=e.task;ln(t,{customHeader:`Next Task: #${t.id} - ${t.title}`,headerColor:`green`,showSuggestedActions:!0,storageType:e.storageType})}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Ln=class{interval=null;spinner=null;totalMs;constructor(e=Se){this.totalMs=e}start(){let e=Date.now()+this.totalMs,t=()=>{let t=Math.max(0,e-Date.now()),n=`${Math.floor(t/6e4)}:${Math.floor(t%6e4/1e3).toString().padStart(2,`0`)}`;this.spinner&&(this.spinner.text=`Waiting for authentication... ${B.cyan(n)} remaining`),t<=0&&this.interval&&clearInterval(this.interval)},n=`${Math.floor(this.totalMs/6e4)}:${Math.floor(this.totalMs%6e4/1e3).toString().padStart(2,`0`)}`;this.spinner=J({text:`Waiting for authentication... ${B.cyan(n)} remaining`,spinner:`dots`}).start(),this.interval=setInterval(t,1e3)}stop(e){this.interval&&=(clearInterval(this.interval),null),this.spinner&&=(e===`mfa`?this.spinner.stop():e===`success`?this.spinner.succeed(`Authentication successful!`):this.spinner.fail(`Authentication failed`),null)}cleanup(){this.interval&&=(clearInterval(this.interval),null),this.spinner&&=(this.spinner.stop(),null)}};function Rn(){console.log(B.yellow(`
66
+ `)),console.log(Nn(e.tasks,{showSubtasks:!0,showDependencies:!0}))}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Rn=class e extends G{tmCore;lastResult;constructor(e){super(e||`next`),this.description(`Find the next available task to work on`).option(`-t, --tag <tag>`,`Filter by tag`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).action(async e=>{await this.executeCommand(e)})}async executeCommand(e){let t=!1;try{this.validateOptions(e),await this.initializeCore(Z(e.project));let t=await this.getNextTask(e);this.setLastResult(t),e.silent||this.displayResults(t,e)}catch(e){t=!0,X(e,{skipExit:!0})}finally{await this.cleanup()}t&&process.exit(1)}validateOptions(e){if(e.format&&![`text`,`json`].includes(e.format))throw Error(`Invalid format: ${e.format}. Valid formats are: text, json`)}async initializeCore(e){this.tmCore||=await I({projectPath:We.resolve(e)})}async getNextTask(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.tmCore.tasks.getNext(e.tag),n=this.tmCore.tasks.getStorageType(),r=e.tag||this.tmCore.config.getActiveTag(),i=await this.tmCore.tasks.list({tag:e.tag}),a=i&&i.tasks.length>0;return{task:t,found:t!==null,tag:r,storageType:n,hasAnyTasks:a}}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:this.displayText(e);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e){if(Pn(this.tmCore,{tag:e.tag||`master`,storageType:e.storageType}),!e.found||!e.task){e.hasAnyTasks?(console.log(B.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`)),console.log(`\n${B.dim(`Tip: Try`)} ${B.cyan(`task-master list`)} ${B.dim(`to see all tasks`)}`)):(console.log(W(B.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`⚠️ NO TASKS AVAILABLE ⚠️`,titleAlignment:`center`})),console.log(`\n${B.dim(`Tip: Create tasks with`)} ${B.cyan(`task-master parse-prd`)} ${B.dim(`or`)} ${B.cyan(`task-master add-task`)}`));return}let t=e.task;dn(t,{customHeader:`Next Task: #${t.id} - ${t.title}`,headerColor:`green`,showSuggestedActions:!0,storageType:e.storageType})}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},zn=class{interval=null;spinner=null;totalMs;constructor(e=p){this.totalMs=e}start(){let e=Date.now()+this.totalMs,t=()=>{let t=Math.max(0,e-Date.now()),n=`${Math.floor(t/6e4)}:${Math.floor(t%6e4/1e3).toString().padStart(2,`0`)}`;this.spinner&&(this.spinner.text=`Waiting for authentication... ${B.cyan(n)} remaining`),t<=0&&this.interval&&clearInterval(this.interval)},n=`${Math.floor(this.totalMs/6e4)}:${Math.floor(this.totalMs%6e4/1e3).toString().padStart(2,`0`)}`;this.spinner=J({text:`Waiting for authentication... ${B.cyan(n)} remaining`,spinner:`dots`}).start(),this.interval=setInterval(t,1e3)}stop(e){this.interval&&=(clearInterval(this.interval),null),this.spinner&&=(e===`mfa`?this.spinner.stop():e===`success`?this.spinner.succeed(`Authentication successful!`):this.spinner.fail(`Authentication failed`),null)}cleanup(){this.interval&&=(clearInterval(this.interval),null),this.spinner&&=(this.spinner.stop(),null)}};function Bn(){console.log(B.yellow(`
67
67
  ⚠️ Multi-factor authentication is enabled on your account`)),console.log(B.white(` Please enter the 6-digit code from your authenticator app
68
- `))}async function zn(){try{return(await q.prompt([{type:`input`,name:`mfaCode`,message:`Enter your 6-digit MFA code:`,validate:e=>{let t=(e||``).trim();return t.length===0?`MFA code cannot be empty`:/^\d{6}$/.test(t)?!0:`MFA code must be exactly 6 digits (0-9)`}}])).mfaCode.trim()}catch(e){throw e.name===`ExitPromptError`||e.message?.includes(`force closed`)?(On(` MFA verification cancelled by user`),new x(`MFA verification cancelled`,`MFA_VERIFICATION_FAILED`)):e}}function Bn(){console.log(B.green(`
69
- ✓ MFA verification successful!`))}function Vn(e){e>0&&Y(`Invalid MFA code. Please try again.`)}function Hn(e){console.log(B.blue.bold(`
68
+ `))}async function Vn(){try{return(await q.prompt([{type:`input`,name:`mfaCode`,message:`Enter your 6-digit MFA code:`,validate:e=>{let t=(e||``).trim();return t.length===0?`MFA code cannot be empty`:/^\d{6}$/.test(t)?!0:`MFA code must be exactly 6 digits (0-9)`}}])).mfaCode.trim()}catch(e){throw e.name===`ExitPromptError`||e.message?.includes(`force closed`)?(An(` MFA verification cancelled by user`),new m(`MFA verification cancelled`,`MFA_VERIFICATION_FAILED`)):e}}function Hn(){console.log(B.green(`
69
+ ✓ MFA verification successful!`))}function Un(e){e>0&&Y(`Invalid MFA code. Please try again.`)}function Wn(e){console.log(B.blue.bold(`
70
70
  [auth] Browser Authentication
71
- `)),console.log(B.white(` Opening your browser to authenticate...`)),console.log(B.gray(` If the browser doesn't open, visit:`)),console.log(B.cyan.underline(` ${e}\n`))}function Un(){console.log(B.dim(` If you signed up, check your email to confirm your account.`)),console.log(B.dim(` The CLI will automatically detect when you log in.
72
- `))}function Wn(e={}){return{promptCallback:zn,options:{maxAttempts:e.maxAttempts??xe,onInvalidCode:e.onInvalidCode??Vn}}}async function Gn(e,t){Rn();let{promptCallback:n,options:r}=Wn(),i=await e(t,n,r);if(i.success&&i.credentials)return Bn(),i.credentials;throw new x(`MFA verification failed after ${i.attemptsUsed} attempts`,`MFA_VERIFICATION_FAILED`)}async function Kn(e){let t=new Ln(Se);try{return await e.authenticateWithOAuth({openBrowser:async e=>{await lt(e)},timeout:Se,onAuthUrl:e=>{Hn(e)},onWaitingForAuth:()=>{Un(),t.start()},onSuccess:()=>{t.stop(`success`)},onError:()=>{}})}catch(n){if(n instanceof x&&n.code===`MFA_REQUIRED`){if(t.stop(`mfa`),!n.mfaChallenge?.factorId)throw new x(`MFA challenge information missing`,`MFA_VERIFICATION_FAILED`);return Gn(e.verifyMFAWithRetry.bind(e),n.mfaChallenge.factorId)}throw t.stop(`failure`),n}finally{t.cleanup()}}async function qn(e,t={}){if(!await e.hasValidSession()){let{message:e=`This command requires you to be logged in to your Hamster account.`,footer:n,authCommand:r=`tm auth login`}=t;return console.log(Ot({header:`[!] Not logged in to Hamster`,body:[e],callToAction:{label:`To get started:`,action:r},footer:n})),!1}return!0}async function Jn(e,t){let n=J(`Fetching briefs...`).start();try{let r=await e.getBriefs(t);if(n.stop(),r.length===0)return On(`No briefs available in this organization`),{success:!1,message:`No briefs available`};let i=await ut({message:`Search for a brief:`,pageSize:15,source:async e=>{let t=e?.toLowerCase()||``,n={name:`(No brief - organization level)`,value:null,description:`Clear brief selection`},i=r.filter(e=>{if(!t)return!0;let n=e.document?.title||``,r=e.id.slice(0,8),i=e.id.slice(-8);return n.toLowerCase().includes(t)||e.id.toLowerCase().includes(t)||r.toLowerCase().includes(t)||i.toLowerCase().includes(t)}).reduce((e,t)=>{let n=t.status||`unknown`;return e[n]||(e[n]=[]),e[n].push(t),e},{}),a=[`delivering`,`aligned`,`refining`,`draft`,`delivered`,`done`,`archived`],o=[];for(let e of a){let t=i[e];if(!t||t.length===0)continue;let n=vn(e);o.push({type:`separator`,separator:`\n${n}`}),t.forEach(e=>{let t=e.document?.title||`Brief ${e.id.slice(-8)}`,n=e.id.slice(-8),r=e.document?.description||``,i=e.taskCount!==void 0&&e.taskCount>0?B.gray(` (${e.taskCount} ${e.taskCount===1?`task`:`tasks`})`):``,a=e.updatedAt?B.gray(` • ${ne(e.updatedAt)}`):``;o.push({name:` ${t}${i} ${B.gray(`(${n})`)}${a}`,value:e,description:r?B.gray(` ${r.slice(0,80)}`):void 0})})}let s=Object.keys(i).filter(e=>!a.includes(e));for(let e of s){let t=i[e];if(!t||t.length===0)continue;let n=vn(e);o.push({type:`separator`,separator:`\n${n}`}),t.forEach(e=>{let t=e.document?.title||`Brief ${e.id.slice(-8)}`,n=e.id.slice(-8),r=e.document?.description||``,i=e.taskCount!==void 0&&e.taskCount>0?B.gray(` (${e.taskCount} ${e.taskCount===1?`task`:`tasks`})`):``,a=e.updatedAt?B.gray(` • ${ne(e.updatedAt)}`):``;o.push({name:` ${t}${i} ${B.gray(`(${n})`)}${a}`,value:e,description:r?B.gray(` ${r.slice(0,80)}`):void 0})})}return[n,...o]}});if(i){let t=i.document?.title||`Brief ${i.id.slice(0,8)}`;return await e.updateContext({briefId:i.id,briefName:t,briefStatus:i.status,briefUpdatedAt:i.updatedAt}),Dn(`Selected brief: ${t}`),{success:!0,briefId:i.id,briefName:t,message:`Selected brief: ${t}`}}else return await e.updateContext({briefId:void 0,briefName:void 0,briefStatus:void 0,briefUpdatedAt:void 0}),Dn(`Cleared brief selection (organization level)`),{success:!0,message:`Cleared brief selection`}}catch(e){throw n.fail(`Failed to fetch briefs`),e}}async function Yn(e,t,n){let r;try{r=J(`Resolving brief...`),r.start();let i=await n.tasks.resolveBrief(t),a,o;try{let t=await e.getOrganization(i.accountId);a=t?.name,o=t?.slug}catch{}let s=i.document?.title||`Brief ${i.id.slice(0,8)}`;return await e.updateContext({orgId:i.accountId,orgName:a,orgSlug:o,briefId:i.id,briefName:s,briefStatus:i.status,briefUpdatedAt:i.updatedAt}),r.succeed(`Context set from brief`),console.log(B.gray(` Organization: ${a||i.accountId}\n Brief: ${s}`)),{success:!0,briefId:i.id,briefName:s,orgId:i.accountId,orgName:a,message:`Context set from brief`}}catch(e){try{r?.isSpinning&&r.stop()}catch{}throw e}}async function Xn(e,t={}){let{silent:n=!1,promptMessage:r,forceSelection:i=!1}=t;try{let t=e.getContext();if(t?.orgId&&!i)return{success:!0,orgId:t.orgId,orgName:t.orgName,orgSlug:t.orgSlug};let a=await e.getOrganizations();if(a.length===0)return Y(`No organizations available. Please create or join an organization first.`),{success:!1,message:`No organizations available`};if(a.length===1)return await e.updateContext({orgId:a[0].id,orgName:a[0].name,orgSlug:a[0].slug}),n||console.log(B.gray(` Auto-selected organization: ${a[0].name}`)),{success:!0,orgId:a[0].id,orgName:a[0].name,orgSlug:a[0].slug};!n&&!t?.orgId&&console.log(B.yellow(`No organization selected.`));let o=t?.orgId?a.findIndex(e=>e.id===t.orgId):0,s=await q.prompt([{type:`list`,name:`orgId`,message:r||`Select an organization:`,choices:a.map(e=>({name:e.id===t?.orgId?`${e.name} (current)`:e.name,value:e.id})),default:o>=0?o:0}]),c=a.find(e=>e.id===s.orgId);return c?(await e.updateContext({orgId:c.id,orgName:c.name,orgSlug:c.slug}),Dn(`Selected organization: ${c.name}`),{success:!0,orgId:c.id,orgName:c.name,orgSlug:c.slug}):{success:!1,message:`Failed to select organization`}}catch(e){let t=e instanceof Error?e.message:String(e);return Y(`Failed to select organization: ${t}`),{success:!1,message:t}}}var Zn=class e extends G{authManager;tmCore;lastResult;constructor(e){super(e||`context`),this.authManager=ge.getInstance(),this.description(`Manage workspace context (organization and brief selection)`),this.addOrgCommand(),this.addBriefCommand(),this.addClearCommand(),this.addSetCommand(),this.argument(`[briefOrUrl]`,`Brief ID or Hamster brief URL`),this.option(`--no-header`,`Suppress the header display`),this.action(async(e,t)=>{let n=t?.header!==!1;if(e&&e.trim().length>0){await this.executeSetFromBriefInput(e.trim(),n);return}await this.executeShow(n)})}addOrgCommand(){this.command(`org`).description(`Select an organization`).argument(`[orgId]`,`Organization ID or slug to select directly`).option(`--no-header`,`Suppress the header display`).action(async e=>{await this.executeSelectOrg(e)})}addBriefCommand(){this.command(`brief`).description(`Select a brief within the current organization`).argument(`[briefIdOrUrl]`,`Brief ID or Hamster URL to select directly`).option(`--no-header`,`Suppress the header display`).action(async e=>{await this.executeSelectBrief(e)})}addClearCommand(){this.command(`clear`).description(`Clear all context selections`).option(`--no-header`,`Suppress the header display`).action(async()=>{await this.executeClear()})}addSetCommand(){this.command(`set`).description(`Set context directly`).option(`--org <id>`,`Organization ID`).option(`--org-name <name>`,`Organization name`).option(`--brief <id>`,`Brief ID`).option(`--brief-name <name>`,`Brief name`).option(`--no-header`,`Suppress the header display`).action(async e=>{await this.executeSet(e)})}async executeShow(e=!0){try{let t=await this.displayContext(e);this.setLastResult(t)}catch(e){Y(`Failed to show context: ${e.message}`),process.exit(1)}}async displayContext(e=!0){if(!await qn(this.authManager,{message:`The "context" command requires you to be logged in to your Hamster account.`}))return{success:!1,action:`show`,message:`Not authenticated`};let t=this.authManager.getContext();if(e&&console.log(B.cyan(`
71
+ `)),console.log(B.white(` Opening your browser to authenticate...`)),console.log(B.gray(` If the browser doesn't open, visit:`)),console.log(B.cyan.underline(` ${e}\n`))}function Gn(){console.log(B.dim(` If you signed up, check your email to confirm your account.`)),console.log(B.dim(` The CLI will automatically detect when you log in.
72
+ `))}function Kn(e={}){return{promptCallback:Vn,options:{maxAttempts:e.maxAttempts??be,onInvalidCode:e.onInvalidCode??Un}}}async function qn(e,t){Bn();let{promptCallback:n,options:r}=Kn(),i=await e(t,n,r);if(i.success&&i.credentials)return Hn(),i.credentials;throw new m(`MFA verification failed after ${i.attemptsUsed} attempts`,`MFA_VERIFICATION_FAILED`)}async function Jn(e){let t=new zn(p);try{return await e.authenticateWithOAuth({openBrowser:async e=>{await lt(e)},timeout:p,onAuthUrl:e=>{Wn(e)},onWaitingForAuth:()=>{Gn(),t.start()},onSuccess:()=>{t.stop(`success`)},onError:()=>{}})}catch(n){if(n instanceof m&&n.code===`MFA_REQUIRED`){if(t.stop(`mfa`),!n.mfaChallenge?.factorId)throw new m(`MFA challenge information missing`,`MFA_VERIFICATION_FAILED`);return qn(e.verifyMFAWithRetry.bind(e),n.mfaChallenge.factorId)}throw t.stop(`failure`),n}finally{t.cleanup()}}async function Yn(e,t={}){if(!await e.hasValidSession()){let{message:e=`This command requires you to be logged in to your Hamster account.`,footer:n,authCommand:r=`tm auth login`}=t;return console.log(At({header:`[!] Not logged in to Hamster`,body:[e],callToAction:{label:`To get started:`,action:r},footer:n})),!1}return!0}async function Xn(e,t){let n=J(`Fetching briefs...`).start();try{let r=await e.getBriefs(t);if(n.stop(),r.length===0)return An(`No briefs available in this organization`),{success:!1,message:`No briefs available`};let i=await ut({message:`Search for a brief:`,pageSize:15,source:async e=>{let t=e?.toLowerCase()||``,n={name:`(No brief - organization level)`,value:null,description:`Clear brief selection`},i=r.filter(e=>{if(!t)return!0;let n=e.document?.title||``,r=e.id.slice(0,8),i=e.id.slice(-8);return n.toLowerCase().includes(t)||e.id.toLowerCase().includes(t)||r.toLowerCase().includes(t)||i.toLowerCase().includes(t)}).reduce((e,t)=>{let n=t.status||`unknown`;return e[n]||(e[n]=[]),e[n].push(t),e},{}),a=[`delivering`,`aligned`,`refining`,`draft`,`delivered`,`done`,`archived`],o=[];for(let e of a){let t=i[e];if(!t||t.length===0)continue;let n=bn(e);o.push({type:`separator`,separator:`\n${n}`}),t.forEach(e=>{let t=e.document?.title||`Brief ${e.id.slice(-8)}`,n=e.id.slice(-8),r=e.document?.description||``,i=e.taskCount!==void 0&&e.taskCount>0?B.gray(` (${e.taskCount} ${e.taskCount===1?`task`:`tasks`})`):``,a=e.updatedAt?B.gray(` • ${te(e.updatedAt)}`):``;o.push({name:` ${t}${i} ${B.gray(`(${n})`)}${a}`,value:e,description:r?B.gray(` ${r.slice(0,80)}`):void 0})})}let s=Object.keys(i).filter(e=>!a.includes(e));for(let e of s){let t=i[e];if(!t||t.length===0)continue;let n=bn(e);o.push({type:`separator`,separator:`\n${n}`}),t.forEach(e=>{let t=e.document?.title||`Brief ${e.id.slice(-8)}`,n=e.id.slice(-8),r=e.document?.description||``,i=e.taskCount!==void 0&&e.taskCount>0?B.gray(` (${e.taskCount} ${e.taskCount===1?`task`:`tasks`})`):``,a=e.updatedAt?B.gray(` • ${te(e.updatedAt)}`):``;o.push({name:` ${t}${i} ${B.gray(`(${n})`)}${a}`,value:e,description:r?B.gray(` ${r.slice(0,80)}`):void 0})})}return[n,...o]}});if(i){let t=i.document?.title||`Brief ${i.id.slice(0,8)}`;return await e.updateContext({briefId:i.id,briefName:t,briefStatus:i.status,briefUpdatedAt:i.updatedAt}),kn(`Selected brief: ${t}`),{success:!0,briefId:i.id,briefName:t,message:`Selected brief: ${t}`}}else return await e.updateContext({briefId:void 0,briefName:void 0,briefStatus:void 0,briefUpdatedAt:void 0}),kn(`Cleared brief selection (organization level)`),{success:!0,message:`Cleared brief selection`}}catch(e){throw n.fail(`Failed to fetch briefs`),e}}async function Zn(e,t,n){let r;try{r=J(`Resolving brief...`),r.start();let i=await n.tasks.resolveBrief(t),a,o;try{let t=await e.getOrganization(i.accountId);a=t?.name,o=t?.slug}catch{}let s=i.document?.title||`Brief ${i.id.slice(0,8)}`;return await e.updateContext({orgId:i.accountId,orgName:a,orgSlug:o,briefId:i.id,briefName:s,briefStatus:i.status,briefUpdatedAt:i.updatedAt}),r.succeed(`Context set from brief`),console.log(B.gray(` Organization: ${a||i.accountId}\n Brief: ${s}`)),{success:!0,briefId:i.id,briefName:s,orgId:i.accountId,orgName:a,message:`Context set from brief`}}catch(e){try{r?.isSpinning&&r.stop()}catch{}throw e}}async function Qn(e,t={}){let{silent:n=!1,promptMessage:r,forceSelection:i=!1}=t;try{let t=e.getContext();if(t?.orgId&&!i)return{success:!0,orgId:t.orgId,orgName:t.orgName,orgSlug:t.orgSlug};let a=await e.getOrganizations();if(a.length===0)return Y(`No organizations available. Please create or join an organization first.`),{success:!1,message:`No organizations available`};if(a.length===1)return await e.updateContext({orgId:a[0].id,orgName:a[0].name,orgSlug:a[0].slug}),n||console.log(B.gray(` Auto-selected organization: ${a[0].name}`)),{success:!0,orgId:a[0].id,orgName:a[0].name,orgSlug:a[0].slug};!n&&!t?.orgId&&console.log(B.yellow(`No organization selected.`));let o=t?.orgId?a.findIndex(e=>e.id===t.orgId):0,s=await q.prompt([{type:`list`,name:`orgId`,message:r||`Select an organization:`,choices:a.map(e=>({name:e.id===t?.orgId?`${e.name} (current)`:e.name,value:e.id})),default:o>=0?o:0}]),c=a.find(e=>e.id===s.orgId);return c?(await e.updateContext({orgId:c.id,orgName:c.name,orgSlug:c.slug}),kn(`Selected organization: ${c.name}`),{success:!0,orgId:c.id,orgName:c.name,orgSlug:c.slug}):{success:!1,message:`Failed to select organization`}}catch(e){let t=e instanceof Error?e.message:String(e);return Y(`Failed to select organization: ${t}`),{success:!1,message:t}}}var $n=class e extends G{authManager;tmCore;lastResult;constructor(e){super(e||`context`),this.authManager=he.getInstance(),this.description(`Manage workspace context (organization and brief selection)`),this.addOrgCommand(),this.addBriefCommand(),this.addClearCommand(),this.addSetCommand(),this.argument(`[briefOrUrl]`,`Brief ID or Hamster brief URL`),this.option(`--no-header`,`Suppress the header display`),this.action(async(e,t)=>{let n=t?.header!==!1;if(e&&e.trim().length>0){await this.executeSetFromBriefInput(e.trim(),n);return}await this.executeShow(n)})}addOrgCommand(){this.command(`org`).description(`Select an organization`).argument(`[orgId]`,`Organization ID or slug to select directly`).option(`--no-header`,`Suppress the header display`).action(async e=>{await this.executeSelectOrg(e)})}addBriefCommand(){this.command(`brief`).description(`Select a brief within the current organization`).argument(`[briefIdOrUrl]`,`Brief ID or Hamster URL to select directly`).option(`--no-header`,`Suppress the header display`).action(async e=>{await this.executeSelectBrief(e)})}addClearCommand(){this.command(`clear`).description(`Clear all context selections`).option(`--no-header`,`Suppress the header display`).action(async()=>{await this.executeClear()})}addSetCommand(){this.command(`set`).description(`Set context directly`).option(`--org <id>`,`Organization ID`).option(`--org-name <name>`,`Organization name`).option(`--brief <id>`,`Brief ID`).option(`--brief-name <name>`,`Brief name`).option(`--no-header`,`Suppress the header display`).action(async e=>{await this.executeSet(e)})}async executeShow(e=!0){try{let t=await this.displayContext(e);this.setLastResult(t)}catch(e){Y(`Failed to show context: ${e.message}`),process.exit(1)}}async displayContext(e=!0){if(!await Yn(this.authManager,{message:`The "context" command requires you to be logged in to your Hamster account.`}))return{success:!1,action:`show`,message:`Not authenticated`};let t=this.authManager.getContext();if(e&&console.log(B.cyan(`
73
73
  🌍 Workspace Context
74
74
  `)),t&&(t.orgId||t.briefId)){if((t.orgName||t.orgId)&&(console.log(B.green(`✓ Organization`)),t.orgName&&console.log(B.white(` ${t.orgName}`)),t.orgId&&console.log(B.gray(` ID: ${t.orgId}`))),t.briefName||t.briefId){if(console.log(B.green(`
75
- ✓ Brief`)),t.briefName&&t.briefId){let e=t.briefId.slice(-8);console.log(B.white(` ${t.briefName} `)+B.gray(`(${e})`))}else t.briefName?console.log(B.white(` ${t.briefName}`)):t.briefId&&console.log(B.gray(` ID: ${t.briefId}`));if(t.briefStatus){let e=vn(t.briefStatus);console.log(B.gray(` Status: `)+e)}if(t.briefUpdatedAt){let e=new Date(t.briefUpdatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});console.log(B.gray(` Updated: ${e}`))}}return t.updatedAt&&console.log(B.gray(`\n Last updated: ${new Date(t.updatedAt).toLocaleString()}`)),{success:!0,action:`show`,context:t,message:`Context loaded`}}else return console.log(B.yellow(`✗ No context selected`)),console.log(B.gray(`
76
- Run "tm context org" to select an organization`)),console.log(B.gray(` Run "tm context brief" to select a brief`)),{success:!0,action:`show`,message:`No context selected`}}async executeSelectOrg(e){try{await qn(this.authManager)||process.exit(1);let t=await this.selectOrganization(e);this.setLastResult(t),t.success||process.exit(1)}catch(e){Y(`Failed to select organization: ${e.message}`),process.exit(1)}}async selectOrganization(e){let t=J(`Fetching organizations...`).start();try{let n=await this.authManager.getOrganizations();if(t.stop(),n.length===0)return On(`No organizations available`),{success:!1,action:`select-org`,message:`No organizations available`};let r,i=e?.trim();if(i){let e=i.toLowerCase();if(r=n.find(t=>t.id===i||t.slug?.toLowerCase()===e||t.name.toLowerCase()===e),!r){let e=n.length,t=n.slice(0,5).map(e=>e.name).join(`, `),r=`Organization not found: ${i}\n`;return e<=5?r+=`Available organizations: ${t}`:(r+=`Available organizations (showing 5 of ${e}): ${t}`,r+=`
77
- Run "tm context org" to see all organizations and select interactively`),Y(r),{success:!1,action:`select-org`,message:`Organization not found: ${i}`}}}else r=(await q.prompt([{type:`list`,name:`selectedOrg`,message:`Select an organization:`,choices:n.map(e=>({name:e.name,value:e}))}])).selectedOrg;return await this.authManager.updateContext({orgId:r.id,orgName:r.name,orgSlug:r.slug,briefId:void 0,briefName:void 0}),Dn(`Selected organization: ${r.name}`),{success:!0,action:`select-org`,context:this.authManager.getContext()||void 0,message:`Selected organization: ${r.name}`}}catch(e){throw t.fail(`Failed to fetch organizations`),e}}async executeSelectBrief(e){try{if(await qn(this.authManager)||process.exit(1),e&&e.trim().length>0){await this.selectBriefDirectly(e.trim(),`select-brief`);return}let t=this.authManager.getContext();t?.orgId||(Y(`No organization selected. Run "tm context org" first.`),process.exit(1));let n=await Jn(this.authManager,t.orgId);this.setLastResult({success:n.success,action:`select-brief`,context:this.authManager.getContext()||void 0,message:n.message}),n.success||process.exit(1)}catch(e){Y(`Failed to select brief: ${e.message}`),process.exit(1)}}async executeClear(){try{await qn(this.authManager)||process.exit(1);let e=await this.clearContext();this.setLastResult(e),e.success||process.exit(1)}catch(e){Y(`Failed to clear context: ${e.message}`),process.exit(1)}}async clearContext(){try{return await this.authManager.clearContext(),Dn(`Context cleared`),{success:!0,action:`clear`,message:`Context cleared`}}catch(e){return Y(`Failed to clear context: ${e.message}`),{success:!1,action:`clear`,message:`Failed to clear context: ${e.message}`}}}async executeSet(e){try{await qn(this.authManager)||process.exit(1);let t=await this.setContext(e);this.setLastResult(t),t.success||process.exit(1)}catch(e){Y(`Failed to set context: ${e.message}`),process.exit(1)}}async initTmCore(){this.tmCore||=await I({projectPath:process.cwd()})}async selectBriefDirectly(e,t){await this.initTmCore();let n=await Yn(this.authManager,e,this.tmCore);this.setLastResult({success:n.success,action:t,context:this.authManager.getContext()||void 0,message:n.message}),n.success||process.exit(1)}async executeSetFromBriefInput(e,t=!0){try{await qn(this.authManager)||process.exit(1),await this.selectBriefDirectly(e,`set`)}catch(e){Y(`Failed to set context from brief: ${e.message}`),process.exit(1)}}async setContext(e){try{let t={};return e.org&&(t.orgId=e.org),e.orgName&&(t.orgName=e.orgName),e.brief&&(t.briefId=e.brief),e.briefName&&(t.briefName=e.briefName),Object.keys(t).length===0?(On(`No context options provided`),{success:!1,action:`set`,message:`No context options provided`}):(await this.authManager.updateContext(t),Dn(`Context updated`),(t.orgName||t.orgId)&&console.log(B.gray(` Organization: ${t.orgName||t.orgId}`)),(t.briefName||t.briefId)&&console.log(B.gray(` Brief: ${t.briefName||t.briefId}`)),{success:!0,action:`set`,context:this.authManager.getContext()||void 0,message:`Context updated`})}catch(e){return Y(`Failed to set context: ${e.message}`),{success:!1,action:`set`,message:`Failed to set context: ${e.message}`}}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}getContext(){return this.authManager.getContext()}async setupContextInteractive(){try{let e=await Xn(this.authManager,{promptMessage:`Select an organization:`});if(!e.success||!e.orgId)return{success:!1,orgSelected:!1,briefSelected:!1};let{selectBrief:t}=await q.prompt([{type:`confirm`,name:`selectBrief`,message:`Would you like to select a brief now?`,default:!0}]);return t?{success:!0,orgSelected:!0,briefSelected:(await Jn(this.authManager,e.orgId)).success}:{success:!0,orgSelected:!0,briefSelected:!1}}catch{return console.error(B.yellow(`
78
- Context setup encountered an error. You can set it up later with "tm context"`)),{success:!1,orgSelected:!1,briefSelected:!1}}}async cleanup(){}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Qn=class e extends G{authManager;lastResult;constructor(e){super(e||`auth`),this.authManager=ge.getInstance(),this.description(`Manage authentication with tryhamster.com`),this.addLoginCommand(),this.addLogoutCommand(),this.addStatusCommand(),this.addRefreshCommand(),this.action(()=>{this.help()})}addLoginCommand(){this.command(`login`).description(`Authenticate with tryhamster.com`).argument(`[token]`,`Authentication token (optional, for SSH/remote environments)`).option(`-y, --yes`,`Skip interactive prompts`).option(`--no-header`,`Suppress the Task Master header banner`).addHelpText(`after`,`
75
+ ✓ Brief`)),t.briefName&&t.briefId){let e=t.briefId.slice(-8);console.log(B.white(` ${t.briefName} `)+B.gray(`(${e})`))}else t.briefName?console.log(B.white(` ${t.briefName}`)):t.briefId&&console.log(B.gray(` ID: ${t.briefId}`));if(t.briefStatus){let e=bn(t.briefStatus);console.log(B.gray(` Status: `)+e)}if(t.briefUpdatedAt){let e=new Date(t.briefUpdatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});console.log(B.gray(` Updated: ${e}`))}}return t.updatedAt&&console.log(B.gray(`\n Last updated: ${new Date(t.updatedAt).toLocaleString()}`)),{success:!0,action:`show`,context:t,message:`Context loaded`}}else return console.log(B.yellow(`✗ No context selected`)),console.log(B.gray(`
76
+ Run "tm context org" to select an organization`)),console.log(B.gray(` Run "tm context brief" to select a brief`)),{success:!0,action:`show`,message:`No context selected`}}async executeSelectOrg(e){try{await Yn(this.authManager)||process.exit(1);let t=await this.selectOrganization(e);this.setLastResult(t),t.success||process.exit(1)}catch(e){Y(`Failed to select organization: ${e.message}`),process.exit(1)}}async selectOrganization(e){let t=J(`Fetching organizations...`).start();try{let n=await this.authManager.getOrganizations();if(t.stop(),n.length===0)return An(`No organizations available`),{success:!1,action:`select-org`,message:`No organizations available`};let r,i=e?.trim();if(i){let e=i.toLowerCase();if(r=n.find(t=>t.id===i||t.slug?.toLowerCase()===e||t.name.toLowerCase()===e),!r){let e=n.length,t=n.slice(0,5).map(e=>e.name).join(`, `),r=`Organization not found: ${i}\n`;return e<=5?r+=`Available organizations: ${t}`:(r+=`Available organizations (showing 5 of ${e}): ${t}`,r+=`
77
+ Run "tm context org" to see all organizations and select interactively`),Y(r),{success:!1,action:`select-org`,message:`Organization not found: ${i}`}}}else r=(await q.prompt([{type:`list`,name:`selectedOrg`,message:`Select an organization:`,choices:n.map(e=>({name:e.name,value:e}))}])).selectedOrg;return await this.authManager.updateContext({orgId:r.id,orgName:r.name,orgSlug:r.slug,briefId:void 0,briefName:void 0}),kn(`Selected organization: ${r.name}`),{success:!0,action:`select-org`,context:this.authManager.getContext()||void 0,message:`Selected organization: ${r.name}`}}catch(e){throw t.fail(`Failed to fetch organizations`),e}}async executeSelectBrief(e){try{if(await Yn(this.authManager)||process.exit(1),e&&e.trim().length>0){await this.selectBriefDirectly(e.trim(),`select-brief`);return}let t=this.authManager.getContext();t?.orgId||(Y(`No organization selected. Run "tm context org" first.`),process.exit(1));let n=await Xn(this.authManager,t.orgId);this.setLastResult({success:n.success,action:`select-brief`,context:this.authManager.getContext()||void 0,message:n.message}),n.success||process.exit(1)}catch(e){Y(`Failed to select brief: ${e.message}`),process.exit(1)}}async executeClear(){try{await Yn(this.authManager)||process.exit(1);let e=await this.clearContext();this.setLastResult(e),e.success||process.exit(1)}catch(e){Y(`Failed to clear context: ${e.message}`),process.exit(1)}}async clearContext(){try{return await this.authManager.clearContext(),kn(`Context cleared`),{success:!0,action:`clear`,message:`Context cleared`}}catch(e){return Y(`Failed to clear context: ${e.message}`),{success:!1,action:`clear`,message:`Failed to clear context: ${e.message}`}}}async executeSet(e){try{await Yn(this.authManager)||process.exit(1);let t=await this.setContext(e);this.setLastResult(t),t.success||process.exit(1)}catch(e){Y(`Failed to set context: ${e.message}`),process.exit(1)}}async initTmCore(){this.tmCore||=await I({projectPath:process.cwd()})}async selectBriefDirectly(e,t){await this.initTmCore();let n=await Zn(this.authManager,e,this.tmCore);this.setLastResult({success:n.success,action:t,context:this.authManager.getContext()||void 0,message:n.message}),n.success||process.exit(1)}async executeSetFromBriefInput(e,t=!0){try{await Yn(this.authManager)||process.exit(1),await this.selectBriefDirectly(e,`set`)}catch(e){Y(`Failed to set context from brief: ${e.message}`),process.exit(1)}}async setContext(e){try{let t={};return e.org&&(t.orgId=e.org),e.orgName&&(t.orgName=e.orgName),e.brief&&(t.briefId=e.brief),e.briefName&&(t.briefName=e.briefName),Object.keys(t).length===0?(An(`No context options provided`),{success:!1,action:`set`,message:`No context options provided`}):(await this.authManager.updateContext(t),kn(`Context updated`),(t.orgName||t.orgId)&&console.log(B.gray(` Organization: ${t.orgName||t.orgId}`)),(t.briefName||t.briefId)&&console.log(B.gray(` Brief: ${t.briefName||t.briefId}`)),{success:!0,action:`set`,context:this.authManager.getContext()||void 0,message:`Context updated`})}catch(e){return Y(`Failed to set context: ${e.message}`),{success:!1,action:`set`,message:`Failed to set context: ${e.message}`}}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}getContext(){return this.authManager.getContext()}async setupContextInteractive(){try{let e=await Qn(this.authManager,{promptMessage:`Select an organization:`});if(!e.success||!e.orgId)return{success:!1,orgSelected:!1,briefSelected:!1};let{selectBrief:t}=await q.prompt([{type:`confirm`,name:`selectBrief`,message:`Would you like to select a brief now?`,default:!0}]);return t?{success:!0,orgSelected:!0,briefSelected:(await Xn(this.authManager,e.orgId)).success}:{success:!0,orgSelected:!0,briefSelected:!1}}catch{return console.error(B.yellow(`
78
+ Context setup encountered an error. You can set it up later with "tm context"`)),{success:!1,orgSelected:!1,briefSelected:!1}}}async cleanup(){}static register(t,n){let r=new e(n);return t.addCommand(r),r}},er=class e extends G{authManager;lastResult;constructor(e){super(e||`auth`),this.authManager=he.getInstance(),this.description(`Manage authentication with tryhamster.com`),this.addLoginCommand(),this.addLogoutCommand(),this.addStatusCommand(),this.addRefreshCommand(),this.action(()=>{this.help()})}addLoginCommand(){this.command(`login`).description(`Authenticate with tryhamster.com`).argument(`[token]`,`Authentication token (optional, for SSH/remote environments)`).option(`-y, --yes`,`Skip interactive prompts`).option(`--no-header`,`Suppress the Task Master header banner`).addHelpText(`after`,`
79
79
  Examples:
80
80
  $ tm auth login # Browser-based OAuth flow (interactive)
81
81
  $ tm auth login <token> # Token-based authentication
@@ -85,93 +85,93 @@ Examples:
85
85
  🔐 Authentication Status
86
86
  `)),await this.authManager.hasValidSession()){let e=await this.authManager.getSession(),t=this.authManager.getContext(),n=this.authManager.getStoredContext();if(console.log(B.green(`✓ Authenticated`)),console.log(B.gray(` Email: ${n?.email||`N/A`}`)),console.log(B.gray(` User ID: ${n?.userId||`N/A`}`)),console.log(B.gray(` Token Type: standard`)),e?.expires_at){let t=new Date(e.expires_at*1e3),n=new Date,r=t.getTime()-n.getTime(),i=Math.floor(r/(1e3*60*60)),a=Math.floor(r/(1e3*60));r>0?i>0?console.log(B.gray(` Expires at: ${t.toLocaleString()} (${i} hours remaining)`)):console.log(B.gray(` Expires at: ${t.toLocaleString()} (${a} minutes remaining)`)):console.log(B.yellow(` Expired at: ${t.toLocaleString()}`))}return t&&(console.log(B.gray(`
87
87
  Context:`)),t.orgName&&console.log(B.gray(` Organization: ${t.orgName}`)),t.briefName&&console.log(B.gray(` Brief: ${t.briefName}`))),{success:!0,action:`status`,credentials:{token:e?.access_token||``,refreshToken:e?.refresh_token,userId:n?.userId||``,email:n?.email,expiresAt:e?.expires_at?new Date(e.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:n?.lastUpdated||new Date().toISOString(),selectedContext:t||void 0},message:`Authenticated`}}else return console.log(B.yellow(`✗ Not authenticated`)),console.log(B.gray(`
88
- Run "task-master auth login" to authenticate`)),{success:!1,action:`status`,message:`Not authenticated`}}async performLogout(){try{return await this.authManager.logout(),Dn(`Successfully logged out`),{success:!0,action:`logout`,message:`Successfully logged out`}}catch(e){let t=`Failed to logout: ${e.message}`;return Y(t),{success:!1,action:`logout`,message:t}}}async refreshToken(){let e=J(`Refreshing authentication token...`).start();try{let t=await this.authManager.refreshToken();return e.succeed(`Token refreshed successfully`),console.log(B.gray(` New expiration: ${t.expiresAt?new Date(t.expiresAt).toLocaleString():`Never`}`)),{success:!0,action:`refresh`,credentials:t,message:`Token refreshed successfully`}}catch(t){return e.fail(`Failed to refresh token`),t.code===`NO_REFRESH_TOKEN`?On(`No refresh token available. Please re-authenticate.`):Y(`Refresh failed: ${t.message}`),{success:!1,action:`refresh`,message:`Failed to refresh: ${t.message}`}}}async performInteractiveAuth(e,t=!0){if(t&&Tn(`Task Master Authentication`),await this.authManager.hasValidSession()&&!e){let{continueAuth:e}=await q.prompt([{type:`confirm`,name:`continueAuth`,message:`You are already authenticated. Do you want to re-authenticate?`,default:!1}]);if(!e){let e=await this.authManager.getAuthCredentials();return Dn(`Using existing authentication`),e&&(console.log(B.gray(` Email: ${e.email||`N/A`}`)),console.log(B.gray(` User ID: ${e.userId}`))),{success:!0,action:`login`,credentials:e||void 0,message:`Using existing authentication`}}}try{let t=await this.authenticateWithBrowser();if(console.log(B.gray(` Logged in as: ${t.email||t.userId}`)),e)console.log(B.gray(`
89
- Skipped interactive setup. Use "tm context" to configure later.`));else{console.log();try{let e=await new Zn().setupContextInteractive();e.success?e.orgSelected&&e.briefSelected?console.log(B.green(`✓ Workspace context configured successfully`)):e.orgSelected&&console.log(B.green(`✓ Organization selected`)):(console.log(B.yellow(`⚠️ Context setup was skipped or encountered issues`)),console.log(B.gray(` You can set up context later with "tm context"`)))}catch(e){console.log(B.yellow(`⚠️ Context setup encountered an error`)),console.log(B.gray(` You can set up context later with "tm context"`)),process.env.DEBUG&&console.error(B.gray(e.message))}}return{success:!0,action:`login`,credentials:t,message:`Authentication successful`}}catch(e){return X(e,{skipExit:!0}),{success:!1,action:`login`,message:`Authentication failed: ${e.message}`}}}async authenticateWithBrowser(){return Kn(this.authManager)}async authenticateWithToken(e){let t=J(`Verifying authentication token...`).start();try{let n=await this.authManager.authenticateWithCode(e);return t.succeed(`Successfully authenticated!`),n}catch(e){if(e instanceof x&&e.code===`MFA_REQUIRED`){if(t.stop(),!e.mfaChallenge?.factorId)throw new x(`MFA challenge information missing`,`MFA_VERIFICATION_FAILED`);return this.handleMFAVerification(e)}throw t.fail(`Authentication failed`),e}}async handleMFAVerification(e){if(!e.mfaChallenge?.factorId)throw new x(`MFA challenge information missing`,`MFA_VERIFICATION_FAILED`);return Gn(this.authManager.verifyMFAWithRetry.bind(this.authManager),e.mfaChallenge.factorId)}async performTokenAuth(e,t,n=!0){n&&Tn(`Task Master Authentication`);try{let n=await this.authenticateWithToken(e);if(console.log(B.gray(` Logged in as: ${n.email||n.userId}`)),t)console.log(B.gray(`
90
- Skipped interactive setup. Use "tm context" to configure later.`));else{console.log();try{let e=await new Zn().setupContextInteractive();e.success?e.orgSelected&&e.briefSelected?console.log(B.green(`✓ Workspace context configured successfully`)):e.orgSelected&&console.log(B.green(`✓ Organization selected`)):(console.log(B.yellow(`⚠️ Context setup was skipped or encountered issues`)),console.log(B.gray(` You can set up context later with "tm context"`)))}catch(e){console.log(B.yellow(`⚠️ Context setup encountered an error`)),console.log(B.gray(` You can set up context later with "tm context"`)),process.env.DEBUG&&console.error(B.gray(e.message))}}return{success:!0,action:`login`,credentials:n,message:`Authentication successful`}}catch(e){return X(e,{skipExit:!0}),{success:!1,action:`login`,message:`Authentication failed: ${e.message}`}}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async getCredentials(){return this.authManager.getAuthCredentials()}async cleanup(){}static register(t,n){let r=new e(n);return t.addCommand(r),r}},$n=class e extends G{tmCore;lastResult;constructor(e){super(e||`start`),this.description(`Start working on a task by launching a coding agent CLI with context`).argument(`[id]`,`Task ID to start working on`).option(`-i, --id <id>`,`Task ID to start working on`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).option(`--dry-run`,`Show what would be executed without launching the coding agent CLI`).option(`--force`,`Force start even if another task is already in-progress`).option(`-e, --executor <executor>`,`Execution backend (claude|codex)`).option(`--no-status-update`,`Do not automatically update task status to in-progress`).action(async(e,t)=>{await this.executeCommand(e,t)})}async executeCommand(e,t){let n=null;try{this.validateOptions(t)||process.exit(1),n=J(`Initializing Task Master...`).start(),await this.initializeCore(Z(t.project)),n.succeed(`Task Master initialized`);let r=this.resolveExecutor(t.executor),i=e||t.id||null;i||(n=J(`Finding next available task...`).start(),i=await this.performGetNextTask(),i?n.succeed(`Found next task: #${i}`):n.fail(`No available tasks found`)),i||(Y(`No task ID provided and no available tasks found`),process.exit(1)),t.dryRun||await this.showPreLaunchMessage(i,r),n=J(`Preparing task execution...`).start();let a=await this.performStartTask(i,t,r);a.started?n.succeed(t.dryRun?`Dry run completed`:`Task prepared - launching ${r}...`):n.fail(`Task execution failed`),!t.dryRun&&a.command&&(n&&!n.isSpinning&&console.log(),await this.executeChildProcess(a.command));let o={...a,storageType:this.tmCore?.tasks.getStorageType()};this.setLastResult(o),(t.dryRun||!a.started)&&this.displayResults(o,t)}catch(e){n&&n.fail(`Operation failed`),X(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(B.red(`Invalid format: ${e.format}`)),console.error(B.gray(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await I({projectPath:e})}async performGetNextTask(){if(!this.tmCore)throw Error(`TmCore not initialized`);return this.tmCore.tasks.getNextAvailable()}async showPreLaunchMessage(e,t){if(!this.tmCore)return;let{task:n,isSubtask:r}=await this.tmCore.tasks.get(e);if(n){let i=r?`Subtask #${e} - ${n.title}`:`Task #${n.id} - ${n.title}`;console.log(B.green(`🚀 Starting: `)+B.white.bold(i)),console.log(B.gray(`Launching ${t}...`)),console.log()}}async performStartTask(e,t,n){if(!this.tmCore)throw Error(`TmCore not initialized`);let r=null;!t.noStatusUpdate&&!t.dryRun&&(r=J(`Updating task status to in-progress...`).start());let i=await this.tmCore.tasks.start(e,{dryRun:t.dryRun,force:t.force,updateStatus:!t.noStatusUpdate,executor:n});if(r&&(i.started?r.succeed(`Task status updated`):r.warn(`Task status update skipped`)),!i)throw Error(`Failed to start task - core result is undefined`);return i}async executeChildProcess(e){return new Promise((t,n)=>{console.log(B.green(`🚀 Launching ${e.executable}...`)),console.log();let r=Qe(e.executable,e.args,{cwd:e.cwd,stdio:`inherit`,shell:!1});r.on(`close`,e=>{e===0?t():n(Error(`Process exited with code ${e}`))}),r.on(`error`,e=>{n(Error(`Failed to spawn process: ${e.message}`))});let i=()=>{r&&!r.killed&&r.kill(`SIGTERM`)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i),process.on(`exit`,i)})}resolveExecutor(e){let t=this.getConfiguredExecutor(),n=this.inferExecutorFromConfig(),r=e??process.env.TASKMASTER_EXECUTOR??t??n??`claude`,i=r.toLowerCase();if(i===`claude`||i===`codex`)return i;throw Error(`Invalid executor "${r}". Supported values: claude, codex.`)}getConfiguredExecutor(){if(!this.tmCore)return;let e=this.tmCore.config.getConfig().custom?.executor;return typeof e==`string`?e:void 0}inferExecutorFromConfig(){if(!this.tmCore)return;let e=this.tmCore.config.getConfig();if(this.isCodexProvider(e.aiProvider))return`codex`;let t=this.asObject(e.models);if(this.isCodexModelConfig(t?.main)||this.isNonEmptyObject(e.codexCli))return`codex`}isCodexModelConfig(e){if(typeof e==`string`)return this.isCodexModelId(e);let t=this.asObject(e);return t?this.isCodexProvider(t.provider)||this.isCodexModelId(t.modelId):!1}isCodexProvider(e){if(typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return t===`codex`||t===`codex-cli`||t===`codex-lb`}isCodexModelId(e){return typeof e==`string`&&e.toLowerCase().includes(`codex`)}asObject(e){if(typeof e==`object`&&e)return e}isNonEmptyObject(e){let t=this.asObject(e);return!!(t&&Object.keys(t).length>0)}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:this.displayTextResult(e,t);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayTextResult(e,t){if(!e.found||!e.task){console.log(W(B.yellow(`Task not found!`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));return}let n=e.task;if(t.dryRun){let t=`Dry Run: Starting Task #${n.id} - ${n.title}`;e.subtask&&e.subtaskId&&(t=`Dry Run: Starting Subtask #${n.id}.${e.subtaskId} - ${e.subtask.title}`),ln(n,{customHeader:t,headerColor:`yellow`,storageType:e.storageType});let r=e.command?.executable??`agent`;e.executionOutput&&(console.log(),console.log(W(B.white.bold(`${r.charAt(0).toUpperCase()}${r.slice(1)} Prompt:`)+`
88
+ Run "task-master auth login" to authenticate`)),{success:!1,action:`status`,message:`Not authenticated`}}async performLogout(){try{return await this.authManager.logout(),kn(`Successfully logged out`),{success:!0,action:`logout`,message:`Successfully logged out`}}catch(e){let t=`Failed to logout: ${e.message}`;return Y(t),{success:!1,action:`logout`,message:t}}}async refreshToken(){let e=J(`Refreshing authentication token...`).start();try{let t=await this.authManager.refreshToken();return e.succeed(`Token refreshed successfully`),console.log(B.gray(` New expiration: ${t.expiresAt?new Date(t.expiresAt).toLocaleString():`Never`}`)),{success:!0,action:`refresh`,credentials:t,message:`Token refreshed successfully`}}catch(t){return e.fail(`Failed to refresh token`),t.code===`NO_REFRESH_TOKEN`?An(`No refresh token available. Please re-authenticate.`):Y(`Refresh failed: ${t.message}`),{success:!1,action:`refresh`,message:`Failed to refresh: ${t.message}`}}}async performInteractiveAuth(e,t=!0){if(t&&Dn(`Task Master Authentication`),await this.authManager.hasValidSession()&&!e){let{continueAuth:e}=await q.prompt([{type:`confirm`,name:`continueAuth`,message:`You are already authenticated. Do you want to re-authenticate?`,default:!1}]);if(!e){let e=await this.authManager.getAuthCredentials();return kn(`Using existing authentication`),e&&(console.log(B.gray(` Email: ${e.email||`N/A`}`)),console.log(B.gray(` User ID: ${e.userId}`))),{success:!0,action:`login`,credentials:e||void 0,message:`Using existing authentication`}}}try{let t=await this.authenticateWithBrowser();if(console.log(B.gray(` Logged in as: ${t.email||t.userId}`)),e)console.log(B.gray(`
89
+ Skipped interactive setup. Use "tm context" to configure later.`));else{console.log();try{let e=await new $n().setupContextInteractive();e.success?e.orgSelected&&e.briefSelected?console.log(B.green(`✓ Workspace context configured successfully`)):e.orgSelected&&console.log(B.green(`✓ Organization selected`)):(console.log(B.yellow(`⚠️ Context setup was skipped or encountered issues`)),console.log(B.gray(` You can set up context later with "tm context"`)))}catch(e){console.log(B.yellow(`⚠️ Context setup encountered an error`)),console.log(B.gray(` You can set up context later with "tm context"`)),process.env.DEBUG&&console.error(B.gray(e.message))}}return{success:!0,action:`login`,credentials:t,message:`Authentication successful`}}catch(e){return X(e,{skipExit:!0}),{success:!1,action:`login`,message:`Authentication failed: ${e.message}`}}}async authenticateWithBrowser(){return Jn(this.authManager)}async authenticateWithToken(e){let t=J(`Verifying authentication token...`).start();try{let n=await this.authManager.authenticateWithCode(e);return t.succeed(`Successfully authenticated!`),n}catch(e){if(e instanceof m&&e.code===`MFA_REQUIRED`){if(t.stop(),!e.mfaChallenge?.factorId)throw new m(`MFA challenge information missing`,`MFA_VERIFICATION_FAILED`);return this.handleMFAVerification(e)}throw t.fail(`Authentication failed`),e}}async handleMFAVerification(e){if(!e.mfaChallenge?.factorId)throw new m(`MFA challenge information missing`,`MFA_VERIFICATION_FAILED`);return qn(this.authManager.verifyMFAWithRetry.bind(this.authManager),e.mfaChallenge.factorId)}async performTokenAuth(e,t,n=!0){n&&Dn(`Task Master Authentication`);try{let n=await this.authenticateWithToken(e);if(console.log(B.gray(` Logged in as: ${n.email||n.userId}`)),t)console.log(B.gray(`
90
+ Skipped interactive setup. Use "tm context" to configure later.`));else{console.log();try{let e=await new $n().setupContextInteractive();e.success?e.orgSelected&&e.briefSelected?console.log(B.green(`✓ Workspace context configured successfully`)):e.orgSelected&&console.log(B.green(`✓ Organization selected`)):(console.log(B.yellow(`⚠️ Context setup was skipped or encountered issues`)),console.log(B.gray(` You can set up context later with "tm context"`)))}catch(e){console.log(B.yellow(`⚠️ Context setup encountered an error`)),console.log(B.gray(` You can set up context later with "tm context"`)),process.env.DEBUG&&console.error(B.gray(e.message))}}return{success:!0,action:`login`,credentials:n,message:`Authentication successful`}}catch(e){return X(e,{skipExit:!0}),{success:!1,action:`login`,message:`Authentication failed: ${e.message}`}}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async getCredentials(){return this.authManager.getAuthCredentials()}async cleanup(){}static register(t,n){let r=new e(n);return t.addCommand(r),r}},tr=class e extends G{tmCore;lastResult;constructor(e){super(e||`start`),this.description(`Start working on a task by launching a coding agent CLI with context`).argument(`[id]`,`Task ID to start working on`).option(`-i, --id <id>`,`Task ID to start working on`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).option(`--dry-run`,`Show what would be executed without launching the coding agent CLI`).option(`--force`,`Force start even if another task is already in-progress`).option(`-e, --executor <executor>`,`Execution backend (claude|codex)`).option(`--no-status-update`,`Do not automatically update task status to in-progress`).action(async(e,t)=>{await this.executeCommand(e,t)})}async executeCommand(e,t){let n=null;try{this.validateOptions(t)||process.exit(1),n=J(`Initializing Task Master...`).start(),await this.initializeCore(Z(t.project)),n.succeed(`Task Master initialized`);let r=this.resolveExecutor(t.executor),i=e||t.id||null;i||(n=J(`Finding next available task...`).start(),i=await this.performGetNextTask(),i?n.succeed(`Found next task: #${i}`):n.fail(`No available tasks found`)),i||(Y(`No task ID provided and no available tasks found`),process.exit(1)),t.dryRun||await this.showPreLaunchMessage(i,r),n=J(`Preparing task execution...`).start();let a=await this.performStartTask(i,t,r);a.started?n.succeed(t.dryRun?`Dry run completed`:`Task prepared - launching ${r}...`):n.fail(`Task execution failed`),!t.dryRun&&a.command&&(n&&!n.isSpinning&&console.log(),await this.executeChildProcess(a.command));let o={...a,storageType:this.tmCore?.tasks.getStorageType()};this.setLastResult(o),(t.dryRun||!a.started)&&this.displayResults(o,t)}catch(e){n&&n.fail(`Operation failed`),X(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(B.red(`Invalid format: ${e.format}`)),console.error(B.gray(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await I({projectPath:e})}async performGetNextTask(){if(!this.tmCore)throw Error(`TmCore not initialized`);return this.tmCore.tasks.getNextAvailable()}async showPreLaunchMessage(e,t){if(!this.tmCore)return;let{task:n,isSubtask:r}=await this.tmCore.tasks.get(e);if(n){let i=r?`Subtask #${e} - ${n.title}`:`Task #${n.id} - ${n.title}`;console.log(B.green(`🚀 Starting: `)+B.white.bold(i)),console.log(B.gray(`Launching ${t}...`)),console.log()}}async performStartTask(e,t,n){if(!this.tmCore)throw Error(`TmCore not initialized`);let r=null;!t.noStatusUpdate&&!t.dryRun&&(r=J(`Updating task status to in-progress...`).start());let i=await this.tmCore.tasks.start(e,{dryRun:t.dryRun,force:t.force,updateStatus:!t.noStatusUpdate,executor:n});if(r&&(i.started?r.succeed(`Task status updated`):r.warn(`Task status update skipped`)),!i)throw Error(`Failed to start task - core result is undefined`);return i}async executeChildProcess(e){return new Promise((t,n)=>{console.log(B.green(`🚀 Launching ${e.executable}...`)),console.log();let r=Qe(e.executable,e.args,{cwd:e.cwd,stdio:`inherit`,shell:!1});r.on(`close`,e=>{e===0?t():n(Error(`Process exited with code ${e}`))}),r.on(`error`,e=>{n(Error(`Failed to spawn process: ${e.message}`))});let i=()=>{r&&!r.killed&&r.kill(`SIGTERM`)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i),process.on(`exit`,i)})}resolveExecutor(e){let t=this.getConfiguredExecutor(),n=this.inferExecutorFromConfig(),r=e??process.env.TASKMASTER_EXECUTOR??t??n??`claude`,i=r.toLowerCase();if(i===`claude`||i===`codex`)return i;throw Error(`Invalid executor "${r}". Supported values: claude, codex.`)}getConfiguredExecutor(){if(!this.tmCore)return;let e=this.tmCore.config.getConfig().custom?.executor;return typeof e==`string`?e:void 0}inferExecutorFromConfig(){if(!this.tmCore)return;let e=this.tmCore.config.getConfig();if(this.isCodexProvider(e.aiProvider))return`codex`;let t=this.asObject(e.models);if(this.isCodexModelConfig(t?.main)||this.isNonEmptyObject(e.codexCli))return`codex`}isCodexModelConfig(e){if(typeof e==`string`)return this.isCodexModelId(e);let t=this.asObject(e);return t?this.isCodexProvider(t.provider)||this.isCodexModelId(t.modelId):!1}isCodexProvider(e){if(typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return t===`codex`||t===`codex-cli`||t===`codex-lb`}isCodexModelId(e){return typeof e==`string`&&e.toLowerCase().includes(`codex`)}asObject(e){if(typeof e==`object`&&e)return e}isNonEmptyObject(e){let t=this.asObject(e);return!!(t&&Object.keys(t).length>0)}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:this.displayTextResult(e,t);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayTextResult(e,t){if(!e.found||!e.task){console.log(W(B.yellow(`Task not found!`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));return}let n=e.task;if(t.dryRun){let t=`Dry Run: Starting Task #${n.id} - ${n.title}`;e.subtask&&e.subtaskId&&(t=`Dry Run: Starting Subtask #${n.id}.${e.subtaskId} - ${e.subtask.title}`),dn(n,{customHeader:t,headerColor:`yellow`,storageType:e.storageType});let r=e.command?.executable??`agent`;e.executionOutput&&(console.log(),console.log(W(B.white.bold(`${r.charAt(0).toUpperCase()}${r.slice(1)} Prompt:`)+`
91
91
 
92
92
  `+e.executionOutput,{padding:1,borderStyle:`round`,borderColor:`cyan`,width:process.stdout.columns*.95||100}))),console.log(),console.log(W(B.yellow(`🔍 Dry run - ${r} would be launched with the above prompt`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`yellow`,borderStyle:`round`}))}else if(e.started){let t=`Task: #${n.id} - ${n.title}`,r=n.id;e.subtask&&e.subtaskId&&(t=`Subtask: #${n.id}.${e.subtaskId} - ${e.subtask.title}`,r=`${n.id}.${e.subtaskId}`),console.log(W(B.green.bold(`🎉 Task Session Complete!`)+`
93
93
 
94
94
  `+B.white(t)+`
95
95
 
96
96
  `+B.cyan(`Next steps:`)+`
97
- • Run ${B.yellow(`tm show `+n.id)} to review task details\n• Run ${B.yellow(`tm set-status --id=`+r+` --status=done`)} when complete\n• Run ${B.yellow(`tm next`)} to find the next available task\n• Run ${B.yellow(`tm start`)} to begin the next task`,{padding:1,borderStyle:`round`,borderColor:`green`,width:process.stdout.columns*.95||100,margin:{top:1}}))}else console.log(W(B.red(`❌ Failed to launch coding agent CLI`+(e.error?`\nError: ${e.error}`:``)),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`red`,borderStyle:`round`}));console.log(`\n${B.gray(`Storage: `+e.storageType)}`)}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}};const er=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`];var tr=class e extends G{tmCore;lastResult;constructor(e){super(e||`set-status`),this.description(`Update the status of one or more tasks`).alias(`status`).argument(`[id]`,`Task ID(s) - comma-separated for multiple (e.g., 1 or 1,1.1,2)`).argument(`[status]`,`Status - ${er.join(`, `)}`).option(`-i, --id <id>`,`Task ID(s) (fallback if not using positional)`).option(`-s, --status <status>`,`Status (fallback if not using positional)`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).action(async(e,t,n)=>{let r={...n,id:e||n?.id,status:t||n?.status};await this.executeCommand(r)})}async executeCommand(e){let t=!1;try{e.id||(console.error(B.red(`Error: Task ID is required`)),console.log(B.yellow(`Usage examples:
97
+ • Run ${B.yellow(`tm show `+n.id)} to review task details\n• Run ${B.yellow(`tm set-status --id=`+r+` --status=done`)} when complete\n• Run ${B.yellow(`tm next`)} to find the next available task\n• Run ${B.yellow(`tm start`)} to begin the next task`,{padding:1,borderStyle:`round`,borderColor:`green`,width:process.stdout.columns*.95||100,margin:{top:1}}))}else console.log(W(B.red(`❌ Failed to launch coding agent CLI`+(e.error?`\nError: ${e.error}`:``)),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`red`,borderStyle:`round`}));console.log(`\n${B.gray(`Storage: `+e.storageType)}`)}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}};const nr=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`];var rr=class e extends G{tmCore;lastResult;constructor(e){super(e||`set-status`),this.description(`Update the status of one or more tasks`).alias(`status`).argument(`[id]`,`Task ID(s) - comma-separated for multiple (e.g., 1 or 1,1.1,2)`).argument(`[status]`,`Status - ${nr.join(`, `)}`).option(`-i, --id <id>`,`Task ID(s) (fallback if not using positional)`).option(`-s, --status <status>`,`Status (fallback if not using positional)`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).option(`--silent`,`Suppress output (useful for programmatic usage)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).action(async(e,t,n)=>{let r={...n,id:e||n?.id,status:t||n?.status};await this.executeCommand(r)})}async executeCommand(e){let t=!1;try{e.id||(console.error(B.red(`Error: Task ID is required`)),console.log(B.yellow(`Usage examples:
98
98
  tm set-status 1 done
99
99
  tm set-status 1.2 in-progress
100
100
  tm set-status --id=1 --status=done`)),process.exit(1)),e.status||(console.error(B.red(`Error: Status is required`)),console.log(B.yellow(`Usage examples:
101
101
  tm set-status 1 done
102
102
  tm set-status 1,1.1 in-progress
103
- tm set-status --id=1 --status=done`)),process.exit(1)),er.includes(e.status)||(console.error(B.red(`Error: Invalid status "${e.status}". Valid options: ${er.join(`, `)}`)),process.exit(1)),this.tmCore=await I({projectPath:Z(e.project)});let n=e.id.split(`,`).map(e=>e.trim()),r=[];for(let e of n){let t=Oe.safeParse(e);t.success||(console.error(B.red(`Invalid task ID: ${e}`),B.gray(`- ${t.error.issues[0]?.message}`)),process.exit(1)),r.push(t.data)}let i=[];for(let n of r)try{let t=await this.tmCore.tasks.updateStatus(n,e.status);i.push({taskId:t.taskId,oldStatus:t.oldStatus,newStatus:t.newStatus})}catch(r){if(t=!0,e.format===`json`){let e=r?.getSanitizedDetails?r.getSanitizedDetails().message:r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:e,taskId:n,timestamp:new Date().toISOString()}))}else e.silent||(console.error(B.red(`\nFailed to update task ${n}:`)),X(r,{skipExit:!0}));break}this.lastResult={success:!0,updatedTasks:i,storageType:this.tmCore.tasks.getStorageType()},this.displayResults(this.lastResult,e)}catch(n){if(t=!0,e.format===`json`){let e=n instanceof Error?n.message:`Unknown error occurred`;console.log(JSON.stringify({success:!1,error:e}))}else e.silent||X(n,{skipExit:!0})}finally{this.tmCore}t&&process.exit(1)}displayResults(e,t){switch(t.format||`text`){case`json`:console.log(JSON.stringify(e,null,2));break;case`text`:default:t.silent||this.displayTextResults(e);break}}displayTextResults(e){if(e.updatedTasks.length===1){let t=e.updatedTasks[0];console.log(W(B.white.bold(`✅ Successfully updated task ${t.taskId}`)+`
103
+ tm set-status --id=1 --status=done`)),process.exit(1)),nr.includes(e.status)||(console.error(B.red(`Error: Invalid status "${e.status}". Valid options: ${nr.join(`, `)}`)),process.exit(1)),this.tmCore=await I({projectPath:Z(e.project)});let n=e.id.split(`,`).map(e=>e.trim()),r=[];for(let e of n){let t=Ee.safeParse(e);t.success||(console.error(B.red(`Invalid task ID: ${e}`),B.gray(`- ${t.error.issues[0]?.message}`)),process.exit(1)),r.push(t.data)}let i=[];for(let n of r)try{let t=await this.tmCore.tasks.updateStatus(n,e.status);i.push({taskId:t.taskId,oldStatus:t.oldStatus,newStatus:t.newStatus})}catch(r){if(t=!0,e.format===`json`){let e=r?.getSanitizedDetails?r.getSanitizedDetails().message:r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:e,taskId:n,timestamp:new Date().toISOString()}))}else e.silent||(console.error(B.red(`\nFailed to update task ${n}:`)),X(r,{skipExit:!0}));break}this.lastResult={success:!0,updatedTasks:i,storageType:this.tmCore.tasks.getStorageType()},this.displayResults(this.lastResult,e)}catch(n){if(t=!0,e.format===`json`){let e=n instanceof Error?n.message:`Unknown error occurred`;console.log(JSON.stringify({success:!1,error:e}))}else e.silent||X(n,{skipExit:!0})}finally{this.tmCore}t&&process.exit(1)}displayResults(e,t){switch(t.format||`text`){case`json`:console.log(JSON.stringify(e,null,2));break;case`text`:default:t.silent||this.displayTextResults(e);break}}displayTextResults(e){if(e.updatedTasks.length===1){let t=e.updatedTasks[0];console.log(W(B.white.bold(`✅ Successfully updated task ${t.taskId}`)+`
104
104
 
105
105
  ${B.blue(`From:`)} ${this.getStatusDisplay(t.oldStatus)}\n${B.blue(`To:`)} ${this.getStatusDisplay(t.newStatus)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}else console.log(W(B.white.bold(`✅ Successfully updated ${e.updatedTasks.length} tasks`)+`
106
106
 
107
107
  `+e.updatedTasks.map(e=>`${B.cyan(e.taskId)}: ${this.getStatusDisplay(e.oldStatus)} → ${this.getStatusDisplay(e.newStatus)}`).join(`
108
- `),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}getStatusDisplay(e){return({pending:B.yellow,"in-progress":B.blue,done:B.green,deferred:B.gray,cancelled:B.red,blocked:B.red,review:B.magenta,completed:B.green}[e]||B.white)(e)}getLastResult(){return this.lastResult}static register(t,n){let r=new e(n);return t.addCommand(r),r}};function nr(e){let t=[],n=[];return(!e.title||e.title.trim().length===0)&&t.push(`Task title is required`),e.id||t.push(`Task ID is required`),(!e.description||e.description.trim().length===0)&&n.push(`Task has no description`),e.status||n.push(`Task has no status, will default to "todo"`),e.priority||n.push(`Task has no priority, will default to "medium"`),e.title&&e.title.trim().length<5&&n.push(`Task title is very short`),e.title&&e.title.length>200&&n.push(`Task title is very long (>200 chars)`),{taskId:e.id,isValid:t.length===0,errors:t,warnings:n}}function rr(e){let t=e.map(nr),n=t.filter(e=>e.isValid).length,r=t.filter(e=>!e.isValid).length,i=[],a=[];for(let e of t){for(let t of e.errors)i.push(`Task ${e.taskId}: ${t}`);for(let t of e.warnings)a.push(`Task ${e.taskId}: ${t}`)}e.length===0&&i.push(`No tasks selected for export`);let o=ir(e);if(o.length>0)for(let e of o)a.push(`Circular dependency detected: ${e.join(` → `)}`);let s=ar(e);if(s.length>0)for(let{taskId:e,missingDep:t}of s)a.push(`Task ${e} depends on non-existent task ${t}`);return{isValid:r===0&&i.length===0,totalTasks:e.length,validTasks:n,invalidTasks:r,taskResults:t,errors:i,warnings:a}}function ir(e){let t=[],n=new Map(e.map(e=>[e.id,e]));function r(e,i,a){if(i.includes(e)){let n=i.indexOf(e);return t.push([...i.slice(n),e]),!0}if(a.has(e))return!1;a.add(e),i.push(e);let o=n.get(e);if(o?.dependencies)for(let e of o.dependencies)r(e,i,a);return i.pop(),!1}let i=new Set;for(let t of e)i.has(t.id)||r(t.id,[],i);return t}function ar(e){let t=new Set(e.map(e=>e.id)),n=[];for(let r of e)if(r.dependencies)for(let e of r.dependencies)t.has(e)||n.push({taskId:r.id,missingDep:e});return n}async function or(e,t={}){let{preselectAll:n=!0,showStatus:r=!0}=t;if(e.length===0)return console.log(B.yellow(`
108
+ `),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}getStatusDisplay(e){return({pending:B.yellow,"in-progress":B.blue,done:B.green,deferred:B.gray,cancelled:B.red,blocked:B.red,review:B.magenta,completed:B.green}[e]||B.white)(e)}getLastResult(){return this.lastResult}static register(t,n){let r=new e(n);return t.addCommand(r),r}};function ir(e){let t=[],n=[];return(!e.title||e.title.trim().length===0)&&t.push(`Task title is required`),e.id||t.push(`Task ID is required`),(!e.description||e.description.trim().length===0)&&n.push(`Task has no description`),e.status||n.push(`Task has no status, will default to "todo"`),e.priority||n.push(`Task has no priority, will default to "medium"`),e.title&&e.title.trim().length<5&&n.push(`Task title is very short`),e.title&&e.title.length>200&&n.push(`Task title is very long (>200 chars)`),{taskId:e.id,isValid:t.length===0,errors:t,warnings:n}}function ar(e){let t=e.map(ir),n=t.filter(e=>e.isValid).length,r=t.filter(e=>!e.isValid).length,i=[],a=[];for(let e of t){for(let t of e.errors)i.push(`Task ${e.taskId}: ${t}`);for(let t of e.warnings)a.push(`Task ${e.taskId}: ${t}`)}e.length===0&&i.push(`No tasks selected for export`);let o=or(e);if(o.length>0)for(let e of o)a.push(`Circular dependency detected: ${e.join(` → `)}`);let s=sr(e);if(s.length>0)for(let{taskId:e,missingDep:t}of s)a.push(`Task ${e} depends on non-existent task ${t}`);return{isValid:r===0&&i.length===0,totalTasks:e.length,validTasks:n,invalidTasks:r,taskResults:t,errors:i,warnings:a}}function or(e){let t=[],n=new Map(e.map(e=>[e.id,e]));function r(e,i,a){if(i.includes(e)){let n=i.indexOf(e);return t.push([...i.slice(n),e]),!0}if(a.has(e))return!1;a.add(e),i.push(e);let o=n.get(e);if(o?.dependencies)for(let e of o.dependencies)r(e,i,a);return i.pop(),!1}let i=new Set;for(let t of e)i.has(t.id)||r(t.id,[],i);return t}function sr(e){let t=new Set(e.map(e=>e.id)),n=[];for(let r of e)if(r.dependencies)for(let e of r.dependencies)t.has(e)||n.push({taskId:r.id,missingDep:e});return n}async function cr(e,t={}){let{preselectAll:n=!0,showStatus:r=!0}=t;if(e.length===0)return console.log(B.yellow(`
109
109
  No tasks available for export.
110
- `)),{selectedTasks:[],totalAvailable:0,cancelled:!1};let i=e.reduce((e,t)=>e+(t.subtasks?.length||0),0),a=i>0?`${e.length} tasks + ${i} subtasks available`:`${e.length} available`,o=sr(e,{preselectAll:n,showStatus:r});try{let{selectedTasks:t}=await q.prompt([{type:`checkbox`,name:`selectedTasks`,message:`Select tasks to export (${a}):`,choices:o,pageSize:12,loop:!1,validate:e=>e.length===0?`Please select at least one task`:!0}]);return{selectedTasks:t,totalAvailable:e.length,cancelled:!1}}catch(t){if(t.isTtyError||t.message?.includes(`User force closed`))return{selectedTasks:[],totalAvailable:e.length,cancelled:!0};throw t}}function sr(e,t){return e.map(e=>{let n=cr(e.status),r=e.title.length>45?e.title.substring(0,42)+`...`:e.title;return{name:`${B.cyan(e.id.padEnd(6))} ${n} ${r}`,value:e,checked:t.preselectAll,short:`${e.id}`}})}function cr(e){switch(e?.toLowerCase()){case`done`:case`completed`:return B.green(`✓`);case`in-progress`:case`in_progress`:return B.yellow(`◐`);case`blocked`:return B.red(`✗`);default:return B.gray(`○`)}}async function lr(e,t){let n=e.length,r=e.reduce((e,t)=>e+(t.subtasks?.length||0),0),i=n+r;console.log(``);let a=r>0?`${n} tasks + ${r} subtasks (${i} total)`:`${n} tasks`;console.log(B.white(` ${a} ready to export`));let o=rr(e);if(o.warnings.length>0){console.log(B.yellow(` ${o.warnings.length} warning(s):`));for(let e of o.warnings)console.log(B.gray(` - ${e}`))}if(!o.isValid)return console.log(``),console.log(B.red(` Cannot export: ${o.errors[0]}`)),!1;console.log(``);let{confirmed:s}=await q.prompt([{type:`confirm`,name:`confirmed`,message:`Continue?`,default:!0}]);return s}function ur(e){let t=e?B.cyan(` Exporting tag: ${B.white.bold(e)}`):``,n=[B.white.bold(`Exporting your tasks to Hamster`),``,B.gray(`Your tasks will live on Hamster where you can:`),B.white(` • Invite teammates to collaborate on the brief together`),B.white(` • Chat with AI alongside your team in real-time`),B.white(` • Draft, refine, align briefs and ship them faster together`),...t?[``,t]:[]].join(`
111
- `);console.log(W(n,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:1},borderStyle:`round`,borderColor:`cyan`,dimBorder:!0}))}async function dr(e={}){let t=new Te;if(await t.hasValidSession()){let e=ge.getInstance();if(e.getContext()?.orgId)return{authenticated:!0};let t=await Xn(e,{promptMessage:`Select an organization to continue:`});return t.success?{authenticated:!0}:{authenticated:!0,error:t.message||`Organization selection required`}}let n=e.actionName||`continue`,r=e.message||`You're not logged in. Log in to ${n}?`;if(console.log(``),console.log(B.yellow(`🔒 Authentication Required`)),console.log(``),!e.skipConfirmation){let{shouldLogin:e}=await q.prompt([{type:`confirm`,name:`shouldLogin`,message:r,default:!0}]);if(!e)return{authenticated:!1,cancelled:!0}}try{let e=await Kn(t);e.email&&console.log(B.gray(` Logged in as: ${e.email}`)),console.log(``);let n=await Xn(ge.getInstance(),{promptMessage:`Select an organization to continue:`});return n.success?{authenticated:!0,credentials:e}:{authenticated:!0,credentials:e,error:n.message||`Organization selection required`}}catch(e){return{authenticated:!1,error:e instanceof Error?e.message:String(e)}}}var fr=class e extends G{taskMasterCore;promptService;lastResult;constructor(e){super(e||`export`),this.description(`Export tasks to Hamster by creating a new brief from your local tasks`),this.option(`--tag <tag>`,`Export tasks from a specific tag (non-interactive)`),this.option(`--title <title>`,`Specify a title for the generated brief (non-interactive)`),this.option(`--description <description>`,`Specify a description for the generated brief (non-interactive)`),this.option(`-I, --invite`,`Prompt for email addresses to invite collaborators to the brief`),this.action(async e=>{await this.executeExport(e)})}async initializeServices(){if(!this.taskMasterCore)try{let e=Z();this.taskMasterCore=await I({projectPath:e}),this.promptService=new h(e)}catch(e){throw Error(`Failed to initialize services: ${e.message}`)}}async executeExport(e){try{let t=await dr({actionName:`export tasks to Hamster`});if(!t.authenticated){t.cancelled&&(this.lastResult={success:!1,action:`cancelled`,message:`User cancelled authentication`});return}if(await this.initializeServices(),this.taskMasterCore.auth.getContext()?.briefId){console.log(B.yellow(`
110
+ `)),{selectedTasks:[],totalAvailable:0,cancelled:!1};let i=e.reduce((e,t)=>e+(t.subtasks?.length||0),0),a=i>0?`${e.length} tasks + ${i} subtasks available`:`${e.length} available`,o=lr(e,{preselectAll:n,showStatus:r});try{let{selectedTasks:t}=await q.prompt([{type:`checkbox`,name:`selectedTasks`,message:`Select tasks to export (${a}):`,choices:o,pageSize:12,loop:!1,validate:e=>e.length===0?`Please select at least one task`:!0}]);return{selectedTasks:t,totalAvailable:e.length,cancelled:!1}}catch(t){if(t.isTtyError||t.message?.includes(`User force closed`))return{selectedTasks:[],totalAvailable:e.length,cancelled:!0};throw t}}function lr(e,t){return e.map(e=>{let n=ur(e.status),r=e.title.length>45?e.title.substring(0,42)+`...`:e.title;return{name:`${B.cyan(e.id.padEnd(6))} ${n} ${r}`,value:e,checked:t.preselectAll,short:`${e.id}`}})}function ur(e){switch(e?.toLowerCase()){case`done`:case`completed`:return B.green(`✓`);case`in-progress`:case`in_progress`:return B.yellow(`◐`);case`blocked`:return B.red(`✗`);default:return B.gray(`○`)}}async function dr(e,t){let n=e.length,r=e.reduce((e,t)=>e+(t.subtasks?.length||0),0),i=n+r;console.log(``);let a=r>0?`${n} tasks + ${r} subtasks (${i} total)`:`${n} tasks`;console.log(B.white(` ${a} ready to export`));let o=ar(e);if(o.warnings.length>0){console.log(B.yellow(` ${o.warnings.length} warning(s):`));for(let e of o.warnings)console.log(B.gray(` - ${e}`))}if(!o.isValid)return console.log(``),console.log(B.red(` Cannot export: ${o.errors[0]}`)),!1;console.log(``);let{confirmed:s}=await q.prompt([{type:`confirm`,name:`confirmed`,message:`Continue?`,default:!0}]);return s}function fr(e){let t=e?B.cyan(` Exporting tag: ${B.white.bold(e)}`):``,n=[B.white.bold(`Exporting your tasks to Hamster`),``,B.gray(`Your tasks will live on Hamster where you can:`),B.white(` • Invite teammates to collaborate on the brief together`),B.white(` • Chat with AI alongside your team in real-time`),B.white(` • Draft, refine, align briefs and ship them faster together`),...t?[``,t]:[]].join(`
111
+ `);console.log(W(n,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:1},borderStyle:`round`,borderColor:`cyan`,dimBorder:!0}))}async function pr(e={}){let t=new Ce;if(await t.hasValidSession()){let e=he.getInstance();if(e.getContext()?.orgId)return{authenticated:!0};let t=await Qn(e,{promptMessage:`Select an organization to continue:`});return t.success?{authenticated:!0}:{authenticated:!0,error:t.message||`Organization selection required`}}let n=e.actionName||`continue`,r=e.message||`You're not logged in. Log in to ${n}?`;if(console.log(``),console.log(B.yellow(`🔒 Authentication Required`)),console.log(``),!e.skipConfirmation){let{shouldLogin:e}=await q.prompt([{type:`confirm`,name:`shouldLogin`,message:r,default:!0}]);if(!e)return{authenticated:!1,cancelled:!0}}try{let e=await Jn(t);e.email&&console.log(B.gray(` Logged in as: ${e.email}`)),console.log(``);let n=await Qn(he.getInstance(),{promptMessage:`Select an organization to continue:`});return n.success?{authenticated:!0,credentials:e}:{authenticated:!0,credentials:e,error:n.message||`Organization selection required`}}catch(e){return{authenticated:!1,error:e instanceof Error?e.message:String(e)}}}var mr=class e extends G{taskMasterCore;promptService;lastResult;constructor(e){super(e||`export`),this.description(`Export tasks to Hamster by creating a new brief from your local tasks`),this.option(`--tag <tag>`,`Export tasks from a specific tag (non-interactive)`),this.option(`--title <title>`,`Specify a title for the generated brief (non-interactive)`),this.option(`--description <description>`,`Specify a description for the generated brief (non-interactive)`),this.option(`-I, --invite`,`Prompt for email addresses to invite collaborators to the brief`),this.action(async e=>{await this.executeExport(e)})}async initializeServices(){if(!this.taskMasterCore)try{let e=Z();this.taskMasterCore=await I({projectPath:e}),this.promptService=new h(e)}catch(e){throw Error(`Failed to initialize services: ${e.message}`)}}async executeExport(e){try{let t=await pr({actionName:`export tasks to Hamster`});if(!t.authenticated){t.cancelled&&(this.lastResult={success:!1,action:`cancelled`,message:`User cancelled authentication`});return}if(await this.initializeServices(),this.taskMasterCore.auth.getContext()?.briefId){console.log(B.yellow(`
112
112
  You are currently connected to a Hamster brief.`)),console.log(B.gray(` Tasks in this context already live on Hamster - export is unnecessary.
113
- `));let{wantsToExportDifferent:t}=await q.prompt([{type:`confirm`,name:`wantsToExportDifferent`,message:`Would you like to export a different tag from your local tasks.json?`,default:!0}]);if(!t){this.lastResult={success:!1,action:`cancelled`,message:`Export cancelled - already connected to brief`};return}await this.executeInteractiveTagSelection(e);return}e?.tag||e?.title||e?.description?(ur(e?.tag||`master`),await this.executeStandardExport(e)):await this.executeInteractiveTagSelection(e)}catch(e){X(e)}}async executeInteractiveTagSelection(e){try{let t=Z();if(!t){console.log(B.yellow(`
113
+ `));let{wantsToExportDifferent:t}=await q.prompt([{type:`confirm`,name:`wantsToExportDifferent`,message:`Would you like to export a different tag from your local tasks.json?`,default:!0}]);if(!t){this.lastResult={success:!1,action:`cancelled`,message:`Export cancelled - already connected to brief`};return}await this.executeInteractiveTagSelection(e);return}e?.tag||e?.title||e?.description?(fr(e?.tag||`master`),await this.executeStandardExport(e)):await this.executeInteractiveTagSelection(e)}catch(e){X(e)}}async executeInteractiveTagSelection(e){try{let t=Z();if(!t){console.log(B.yellow(`
114
114
  No project root found.
115
- `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root found`};return}let n=new F(t);await n.initialize();let r=await n.getTagsWithStats();if(!r.tags||r.tags.length===0){console.log(B.yellow(`
115
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root found`};return}let n=new ae(t);await n.initialize();let r=await n.getTagsWithStats();if(!r.tags||r.tags.length===0){console.log(B.yellow(`
116
116
  No local tags found in tasks.json.
117
117
  `)),this.lastResult={success:!1,action:`cancelled`,message:`No local tags available`};return}let i=await this.getExportedTags();if(r.tags.filter(e=>!i[e.name]).length===0){console.log(B.yellow(`
118
118
  All local tags have already been exported to Hamster.
119
119
  `)),console.log(B.gray(` Previously exported briefs:`));for(let e of r.tags)i[e.name]&&console.log(B.gray(` - ${e.name}: ${i[e.name].briefUrl}`));console.log(``),this.lastResult={success:!1,action:`cancelled`,message:`All tags already exported`};return}let a=[...r.tags].sort((e,t)=>{let n=!!i[e.name];return n===!!i[t.name]?e.isCurrent?-1:t.isCurrent?1:0:n?1:-1}).map(e=>{let t=!!i[e.name],n=`${e.taskCount} tasks, ${e.completedTasks} done`,r=e.isCurrent?B.cyan(` (current)`):``,a=t?B.gray(` [already exported]`):``;return{name:`${e.name}${r}${a} - ${B.gray(n)}`,value:e.name,short:e.name,checked:e.isCurrent&&!t,disabled:t?`already exported`:!1}}),{selectedTags:o}=await q.prompt([{type:`checkbox`,name:`selectedTags`,message:`Select tag(s) to export to Hamster (space to select, enter to confirm):`,choices:a,pageSize:12,validate:e=>e.length===0?`Please select at least one tag to export.`:!0}]);if(o.length===0){console.log(B.gray(`
120
120
  Export cancelled.
121
- `)),this.lastResult={success:!1,action:`cancelled`,message:`No tags selected`};return}let s=await Xn(ge.getInstance(),{promptMessage:`Select an organization to export to:`,forceSelection:!0});if(!s.success){console.log(B.gray(`
121
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`No tags selected`};return}let s=await Qn(he.getInstance(),{promptMessage:`Select an organization to export to:`,forceSelection:!0});if(!s.success){console.log(B.gray(`
122
122
  Export cancelled.
123
- `)),this.lastResult={success:!1,action:`cancelled`,message:s.message||`Organization selection cancelled`};return}if(o.length>1){await this.executeExportMultipleTags(o,e);return}let c=o[0];ur(c),await this.executeInteractiveExport({...e,tag:c})}catch(e){X(e)}}async executeStandardExport(e){let t;try{let n=Z();if(!n){console.log(B.yellow(`
123
+ `)),this.lastResult={success:!1,action:`cancelled`,message:s.message||`Organization selection cancelled`};return}if(o.length>1){await this.executeExportMultipleTags(o,e);return}let c=o[0];fr(c),await this.executeInteractiveExport({...e,tag:c})}catch(e){X(e)}}async executeStandardExport(e){let t;try{let n=Z();if(!n){console.log(B.yellow(`
124
124
  No project root found.
125
- `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root`};return}t=J(`Loading tasks...`).start();let r=new F(n);await r.initialize();let i=await r.loadTasks(e?.tag);if(t.succeed(`${i.length} tasks`),!i||i.length===0){console.log(B.yellow(`
125
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root`};return}t=J(`Loading tasks...`).start();let r=new ae(n);await r.initialize();let i=await r.loadTasks(e?.tag);if(t.succeed(`${i.length} tasks`),!i||i.length===0){console.log(B.yellow(`
126
126
  No tasks found to export.
127
127
  `)),this.lastResult={success:!1,action:`cancelled`,message:`No tasks found`};return}this.showTaskPreview(i);let a=[];e?.invite&&(a=await this.promptForInviteEmails()),t=J(`Creating brief and exporting tasks...`).start();let o=await this.taskMasterCore.integration.generateBriefFromTasks({tag:e?.tag,options:{generateTitle:!e?.title,generateDescription:!e?.description,title:e?.title,description:e?.description,preserveHierarchy:!0,preserveDependencies:!0}});if(o.success&&o.brief){t.succeed(`Export complete`),this.displaySuccessResult(o),await this.setContextToBrief(o.brief.url),a.length>0&&await this.sendInvitationsForBrief(o.brief.url,a),this.showInviteUrl(o.brief.url);let n=e?.tag||`master`;await this.trackExportedTag(n,o.brief.id,o.brief.url),await this.promptService?.recordAction(`export_attempt`,`accepted`)}else{t.fail(`Export failed`);let e=o.error?.message||`Unknown error occurred`;console.error(B.red(`\n${e}`)),o.error?.code&&console.error(B.gray(` Error code: ${o.error.code}`))}this.lastResult={success:o.success,action:`export`,result:o}}catch(e){throw t?.isSpinning&&t.fail(`Export failed`),e}}async executeInteractiveExport(e){let t;try{let n=Z();if(!n){console.log(B.yellow(`
128
128
  No project root found.
129
- `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root`};return}let r=new F(n);await r.initialize();let i=await r.loadTasks(e?.tag);if(!i||i.length===0){console.log(B.yellow(`
129
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root`};return}let r=new ae(n);await r.initialize();let i=await r.loadTasks(e?.tag);if(!i||i.length===0){console.log(B.yellow(`
130
130
  No tasks available for export in this tag.
131
- `)),this.lastResult={success:!1,action:`cancelled`,message:`No tasks available`};return}let a=await or(i.map(e=>({id:String(e.id),title:e.title,description:e.description,status:e.status,priority:e.priority,dependencies:e.dependencies?.map(String),subtasks:e.subtasks?.map(e=>({id:String(e.id),title:e.title,description:e.description,status:e.status,priority:e.priority}))})),{preselectAll:!0,showStatus:!0,showPriority:!0});if(a.cancelled||a.selectedTasks.length===0){console.log(B.yellow(`
131
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`No tasks available`};return}let a=await cr(i.map(e=>({id:String(e.id),title:e.title,description:e.description,status:e.status,priority:e.priority,dependencies:e.dependencies?.map(String),subtasks:e.subtasks?.map(e=>({id:String(e.id),title:e.title,description:e.description,status:e.status,priority:e.priority}))})),{preselectAll:!0,showStatus:!0,showPriority:!0});if(a.cancelled||a.selectedTasks.length===0){console.log(B.yellow(`
132
132
  Export cancelled.
133
- `)),this.lastResult={success:!1,action:`cancelled`,message:`User cancelled selection`};return}let o=rr(a.selectedTasks);if(!o.isValid){console.log(B.red(`
133
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`User cancelled selection`};return}let o=ar(a.selectedTasks);if(!o.isValid){console.log(B.red(`
134
134
  Cannot export due to validation errors:
135
- `));for(let e of o.errors)console.log(B.red(` - ${e}`));this.lastResult={success:!1,action:`validate`,message:`Validation failed`};return}if(!await lr(a.selectedTasks,{briefName:e?.title||`(will be generated)`})){console.log(B.yellow(`
135
+ `));for(let e of o.errors)console.log(B.red(` - ${e}`));this.lastResult={success:!1,action:`validate`,message:`Validation failed`};return}if(!await dr(a.selectedTasks,{briefName:e?.title||`(will be generated)`})){console.log(B.yellow(`
136
136
  Export cancelled.
137
137
  `)),this.lastResult={success:!1,action:`cancelled`,message:`User cancelled after preview`};return}let s=[],{wantsToInvite:c}=await q.prompt([{type:`confirm`,name:`wantsToInvite`,message:`Do you want to invite teammates to collaborate on these tasks together?`,default:!1}]);c&&(s=await this.promptForInviteEmails()),t=J(`Creating brief and exporting tasks...`).start();let l=await this.taskMasterCore.integration.generateBriefFromTasks({tag:e?.tag,options:{generateTitle:!e?.title,generateDescription:!e?.description,title:e?.title,description:e?.description,preserveHierarchy:!0,preserveDependencies:!0}});if(l.success&&l.brief){t.succeed(`Export complete`),this.displaySuccessResult(l),await this.setContextToBrief(l.brief.url),s.length>0&&await this.sendInvitationsForBrief(l.brief.url,s),this.showInviteUrl(l.brief.url);let n=e?.tag||`master`;await this.trackExportedTag(n,l.brief.id,l.brief.url),await this.promptService?.recordAction(`export_attempt`,`accepted`)}else{t.fail(`Export failed`);let e=l.error?.message||`Unknown error occurred`;console.error(B.red(`\n${e}`)),l.error?.code&&console.error(B.gray(` Error code: ${l.error.code}`))}this.lastResult={success:l.success,action:`export`,result:l}}catch(e){throw t?.isSpinning&&t.fail(`Export failed`),e}}async executeExportMultipleTags(e,t){console.log(``),console.log(B.cyan(` Exporting ${e.length} tags to Hamster...\n`));for(let t of e)console.log(B.gray(` - ${t}`));console.log(``);let n=[],{wantsToInvite:r}=await q.prompt([{type:`confirm`,name:`wantsToInvite`,message:`Do you want to invite teammates to collaborate on these tasks?`,default:!1}]);r&&(n=await this.promptForInviteEmails());let i=J(`Exporting ${e.length} tags...`).start(),a=Z();if(!a){console.log(B.yellow(`
138
138
  No project root found.
139
- `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root`};return}let o=new F(a);await o.initialize();let s=e.map(async e=>{try{let t=await o.loadTasks(e),n=t.length,r=t.reduce((e,t)=>e+(t.subtasks?.length||0),0),i=await this.taskMasterCore.integration.generateBriefFromTasks({tag:e,options:{generateTitle:!0,generateDescription:!0,preserveHierarchy:!0,preserveDependencies:!0}});return i.success&&i.brief?(await this.trackExportedTag(e,i.brief.id,i.brief.url),{tag:e,success:!0,brief:i.brief,parentTaskCount:n,subtaskCount:r}):{tag:e,success:!1,error:i.error?.message||`Unknown error`}}catch(t){return{tag:e,success:!1,error:t.message||`Export failed`}}}),c=await Promise.all(s);i.stop();let l=c.filter(e=>e.success),u=c.filter(e=>!e.success);if(console.log(``),l.length>0){console.log(B.green.bold(` ${l.length} tag(s) exported successfully:\n`));for(let e of l){if(console.log(B.white(` ${e.tag}`)),e.brief){console.log(B.gray(` ${e.brief.title}`)),console.log(` ${St(e.brief.url)}`);let t=e.parentTaskCount!==void 0&&e.subtaskCount!==void 0?`${e.parentTaskCount} tasks, ${e.subtaskCount} subtasks`:`${e.brief.taskCount} tasks`;console.log(B.gray(` ${t}`))}console.log(``)}}if(u.length>0){console.log(B.red.bold(` ${u.length} tag(s) failed:\n`));for(let e of u)console.log(B.red(` ${e.tag}: ${e.error}`));console.log(``)}if(l.length>0&&l[0].brief&&await this.setContextToBrief(l[0].brief.url),n.length>0&&l.length>0&&await this.sendInvitationsForBrief(l[0].brief.url,n),l.length>1){let e=l.map(e=>({name:`${e.tag} - ${e.brief?.title}`,value:e.brief?.url}));e.push({name:B.gray(`Skip`),value:`__skip__`});let{selectedBrief:t}=await q.prompt([{type:`list`,name:`selectedBrief`,message:`Which brief would you like to set as current context?`,choices:e}]);t!==`__skip__`&&await this.setContextToBrief(t)}this.lastResult={success:u.length===0,action:`export_multiple`,result:{successful:l,failed:u}}}showTaskPreview(e){console.log(B.cyan(`
139
+ `)),this.lastResult={success:!1,action:`cancelled`,message:`No project root`};return}let o=new ae(a);await o.initialize();let s=e.map(async e=>{try{let t=await o.loadTasks(e),n=t.length,r=t.reduce((e,t)=>e+(t.subtasks?.length||0),0),i=await this.taskMasterCore.integration.generateBriefFromTasks({tag:e,options:{generateTitle:!0,generateDescription:!0,preserveHierarchy:!0,preserveDependencies:!0}});return i.success&&i.brief?(await this.trackExportedTag(e,i.brief.id,i.brief.url),{tag:e,success:!0,brief:i.brief,parentTaskCount:n,subtaskCount:r}):{tag:e,success:!1,error:i.error?.message||`Unknown error`}}catch(t){return{tag:e,success:!1,error:t.message||`Export failed`}}}),c=await Promise.all(s);i.stop();let l=c.filter(e=>e.success),u=c.filter(e=>!e.success);if(console.log(``),l.length>0){console.log(B.green.bold(` ${l.length} tag(s) exported successfully:\n`));for(let e of l){if(console.log(B.white(` ${e.tag}`)),e.brief){console.log(B.gray(` ${e.brief.title}`)),console.log(` ${wt(e.brief.url)}`);let t=e.parentTaskCount!==void 0&&e.subtaskCount!==void 0?`${e.parentTaskCount} tasks, ${e.subtaskCount} subtasks`:`${e.brief.taskCount} tasks`;console.log(B.gray(` ${t}`))}console.log(``)}}if(u.length>0){console.log(B.red.bold(` ${u.length} tag(s) failed:\n`));for(let e of u)console.log(B.red(` ${e.tag}: ${e.error}`));console.log(``)}if(l.length>0&&l[0].brief&&await this.setContextToBrief(l[0].brief.url),n.length>0&&l.length>0&&await this.sendInvitationsForBrief(l[0].brief.url,n),l.length>1){let e=l.map(e=>({name:`${e.tag} - ${e.brief?.title}`,value:e.brief?.url}));e.push({name:B.gray(`Skip`),value:`__skip__`});let{selectedBrief:t}=await q.prompt([{type:`list`,name:`selectedBrief`,message:`Which brief would you like to set as current context?`,choices:e}]);t!==`__skip__`&&await this.setContextToBrief(t)}this.lastResult={success:u.length===0,action:`export_multiple`,result:{successful:l,failed:u}}}showTaskPreview(e){console.log(B.cyan(`
140
140
  Tasks to Export
141
- `));let t=e.slice(0,10);for(let e of t){let t=this.getStatusIcon(e.status);console.log(B.white(` ${t} [${e.id}] ${e.title}`))}e.length>10&&console.log(B.gray(` ... and ${e.length-10} more tasks`)),console.log(``)}displaySuccessResult(e){if(e.brief){if(console.log(``),console.log(B.green(` Done! `)+B.white.bold(e.brief.title)),console.log(B.gray(` ${e.brief.taskCount} tasks exported`)),console.log(``),console.log(` ${St(e.brief.url)}`),e.warnings&&e.warnings.length>0){console.log(``);for(let t of e.warnings)console.log(B.yellow(` Warning: ${t}`))}console.log(``)}}async promptForInviteEmails(){let{emails:e}=await q.prompt([{type:`input`,name:`emails`,message:`Enter email addresses to invite (comma-separated, max 10):`,validate:e=>{if(!e.trim())return!0;let t=e.split(`,`).map(e=>e.trim()).filter(Boolean);if(t.length>10)return`Maximum 10 email addresses allowed`;let n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,r=t.filter(e=>!n.test(e));return r.length>0?`Invalid email format: ${r.join(`, `)}`:!0}}]);return e.trim()?e.split(`,`).map(e=>e.trim()).filter(Boolean).slice(0,10):[]}displayInvitationResults(e){if(!(!e||e.length===0)){console.log(B.cyan(`
142
- Team Invitations:`));for(let t of e)switch(t.status){case`sent`:console.log(B.green(` ${t.email}: Invitation sent`));break;case`already_member`:console.log(B.gray(` ${t.email}: Already a team member`));break;case`already_invited`:console.log(B.yellow(` ${t.email}: Already invited (pending)`));break;case`error`:case`failed`:console.log(B.red(` ${t.email}: ${t.error||`Failed to invite`}`));break}}}showInviteUrl(e){let t=e.match(/^(https?:\/\/[^/]+)\/home\/([^/]+)\/briefs\//);if(t){let[,e,n]=t,r=`${e}/home/${n}/members`;console.log(B.gray(` Invite teammates: `)+St(r)+`
143
- `)}}async setContextToBrief(e){try{if(!this.taskMasterCore)return;(await Yn(ge.getInstance(),e,this.taskMasterCore)).success}catch{}}getStatusIcon(e){switch(e){case`done`:return B.green(`●`);case`in-progress`:case`in_progress`:return B.yellow(`◐`);case`blocked`:return B.red(`⊘`);default:return B.gray(`○`)}}getLastResult(){return this.lastResult}async cleanup(){}async getExportedTags(){let e=Z();if(!e)return{};let t=Ge.join(e,`.taskmaster`,`state.json`);try{let e=await Ye.readFile(t,`utf-8`);return JSON.parse(e).metadata?.exportedTags||{}}catch{return{}}}async sendInvitationsForBrief(e,t){if(!t.length||!this.taskMasterCore)return;let n=J(`Sending invitations...`).start();try{let e=(await this.taskMasterCore.auth.getContext())?.orgSlug;if(!e){n.fail(`Failed to send invitations: Organization context missing.`),console.error(B.red(`
141
+ `));let t=e.slice(0,10);for(let e of t){let t=this.getStatusIcon(e.status);console.log(B.white(` ${t} [${e.id}] ${e.title}`))}e.length>10&&console.log(B.gray(` ... and ${e.length-10} more tasks`)),console.log(``)}displaySuccessResult(e){if(e.brief){if(console.log(``),console.log(B.green(` Done! `)+B.white.bold(e.brief.title)),console.log(B.gray(` ${e.brief.taskCount} tasks exported`)),console.log(``),console.log(` ${wt(e.brief.url)}`),e.warnings&&e.warnings.length>0){console.log(``);for(let t of e.warnings)console.log(B.yellow(` Warning: ${t}`))}console.log(``)}}async promptForInviteEmails(){let{emails:e}=await q.prompt([{type:`input`,name:`emails`,message:`Enter email addresses to invite (comma-separated, max 10):`,validate:e=>{if(!e.trim())return!0;let t=e.split(`,`).map(e=>e.trim()).filter(Boolean);if(t.length>10)return`Maximum 10 email addresses allowed`;let n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,r=t.filter(e=>!n.test(e));return r.length>0?`Invalid email format: ${r.join(`, `)}`:!0}}]);return e.trim()?e.split(`,`).map(e=>e.trim()).filter(Boolean).slice(0,10):[]}displayInvitationResults(e){if(!(!e||e.length===0)){console.log(B.cyan(`
142
+ Team Invitations:`));for(let t of e)switch(t.status){case`sent`:console.log(B.green(` ${t.email}: Invitation sent`));break;case`already_member`:console.log(B.gray(` ${t.email}: Already a team member`));break;case`already_invited`:console.log(B.yellow(` ${t.email}: Already invited (pending)`));break;case`error`:case`failed`:console.log(B.red(` ${t.email}: ${t.error||`Failed to invite`}`));break}}}showInviteUrl(e){let t=e.match(/^(https?:\/\/[^/]+)\/home\/([^/]+)\/briefs\//);if(t){let[,e,n]=t,r=`${e}/home/${n}/members`;console.log(B.gray(` Invite teammates: `)+wt(r)+`
143
+ `)}}async setContextToBrief(e){try{if(!this.taskMasterCore)return;(await Zn(he.getInstance(),e,this.taskMasterCore)).success}catch{}}getStatusIcon(e){switch(e){case`done`:return B.green(`●`);case`in-progress`:case`in_progress`:return B.yellow(`◐`);case`blocked`:return B.red(`⊘`);default:return B.gray(`○`)}}getLastResult(){return this.lastResult}async cleanup(){}async getExportedTags(){let e=Z();if(!e)return{};let t=We.join(e,`.taskmaster`,`state.json`);try{let e=await Xe.readFile(t,`utf-8`);return JSON.parse(e).metadata?.exportedTags||{}}catch{return{}}}async sendInvitationsForBrief(e,t){if(!t.length||!this.taskMasterCore)return;let n=J(`Sending invitations...`).start();try{let e=(await this.taskMasterCore.auth.getContext())?.orgSlug;if(!e){n.fail(`Failed to send invitations: Organization context missing.`),console.error(B.red(`
144
144
  Please ensure you have an organization selected (tm auth status).
145
- `));return}let r=await this.taskMasterCore.integration.sendTeamInvitations(e,t,`member`);if(r.success&&r.invitations)n.succeed(`Invitations sent!`),this.displayInvitationResults(r.invitations);else{n.fail(`Failed to send invitations`);let e=r.error?.message||`Unknown error occurred`;console.error(B.red(`\n ${e}\n`))}}catch(e){n.fail(`Failed to send invitations`),console.error(B.red(`\n ${e.message}\n`))}}async trackExportedTag(e,t,n){let r=Z();if(!r)return;let i=Ge.join(r,`.taskmaster`,`state.json`);try{let r={};try{let e=await Ye.readFile(i,`utf-8`);r=JSON.parse(e)}catch{}r.metadata||={},r.metadata.exportedTags||(r.metadata.exportedTags={}),r.metadata.exportedTags[e]={briefId:t,briefUrl:n,exportedAt:new Date().toISOString()},r.lastUpdated=new Date().toISOString(),await Ye.writeFile(i,JSON.stringify(r,null,2),`utf-8`)}catch{}}static register(t,n){let r=new e(n);return t.addCommand(r),r}},pr=class e extends G{constructor(){super(`export-tag`),this.description(`Export a specific tag to Hamster (alias for: tm export --tag <tag>)`),this.argument(`<tag>`,`Name of the tag to export`),this.option(`--title <title>`,`Specify a title for the generated brief`),this.option(`--description <description>`,`Specify a description for the generated brief`),this.action(async(e,t)=>{await new fr().parseAsync([`node`,`export`,`--tag`,e,...t.title?[`--title`,t.title]:[],...t.description?[`--description`,t.description]:[]])})}static register(t){let n=new e;return t.addCommand(n),n}};function mr(e){return[`add-dependency`,`remove-dependency`,`validate-dependencies`,`fix-dependencies`].includes(e)?{header:`Hamster Manages Dependencies`,getBody:e=>[`Hamster handles dependencies for the ${B.blue(`"${e}"`)} Brief.`,`To manage dependencies manually, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}:e===`clear-subtasks`?{header:`Hamster Manages Subtasks`,getBody:e=>[`Hamster handles subtask management for the ${B.blue(`"${e}"`)} Brief.`,`To manage subtasks manually, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}:e===`models`?{header:`Hamster Manages AI Models`,getBody:e=>[`Hamster configures AI models automatically for the ${B.blue(`"${e}"`)} Brief.`,`To configure models manually, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}:{header:`Command Not Available in Hamster`,getBody:t=>[`The ${B.cyan(e)} command is managed by Hamster for the ${B.blue(`"${t}"`)} Brief.`,`To use this command, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}}async function hr(e,t){let n=typeof t==`string`?await I({projectPath:t}):t,r=await n.auth.guardCommand(e,n.tasks.getStorageType());if(r.isBlocked){let t=mr(e),n=r.briefName||`remote brief`;return console.log(Ot({header:t.header,body:t.getBody(n),footer:t.footer,level:`info`})),!0}return!1}function gr(){let e=ft.env.TM_PUBLIC_VERSION;return e&&e!==`unknown`?e:(console.warn(`Could not read version from TM_PUBLIC_VERSION, using fallback`),`0.0.0`)}function _r(e,t){let n=e=>{let[t,n=``]=e.split(`-`,2);return{nums:t.split(`.`).map(e=>Number.parseInt(e,10)||0),pre:n}},r=n(e),i=n(t),a=Math.max(r.nums.length,i.nums.length);for(let e=0;e<a;e++){let t=(r.nums[e]||0)-(i.nums[e]||0);if(t!==0)return t<0?-1:1}return r.pre&&!i.pre?-1:!r.pre&&i.pre?1:r.pre===i.pre?0:r.pre<i.pre?-1:1}async function vr(e){return new Promise(t=>{let n={hostname:`raw.githubusercontent.com`,path:`/eyaltoledano/claude-task-master/main/CHANGELOG.md`,method:`GET`,headers:{"User-Agent":`task-master-ai/${e}`}},r=pt.request(n,n=>{let r=``;n.on(`data`,e=>{r+=e}),n.on(`end`,()=>{try{if(n.statusCode!==200){t([]);return}t(yr(r,e))}catch{t([])}})});r.on(`error`,()=>{t([])}),r.setTimeout(3e3,()=>{r.destroy(),t([])}),r.end()})}function yr(e,t){try{if(!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/.test(t))return[];let n=RegExp(`## ${t.replace(/\./g,`\\.`)}\\s*\\n`,`i`),r=e.match(n);if(!r)return[];let i=r.index+r[0].length,a=e.indexOf(`
146
- ## `,i),o=(a>0?e.slice(i,a):e.slice(i)).match(/### Minor Changes\s*\n([\s\S]*?)(?=\n###|\n##|$)/i);if(!o)return[];let s=o[1],c=[],l=/^-\s+\[#\d+\][^\n]*?!\s+-\s+(.+?)$/gm,u;for(;(u=l.exec(s))!==null;){let e=u[1].trim();c.push(e)}return c}catch{return[]}}const br=()=>Ge.join(Ze.tmpdir(),`taskmaster-update-cache.json`);function xr(){try{let e=br();if(!Xe.existsSync(e))return null;let t=JSON.parse(Xe.readFileSync(e,`utf-8`));return Date.now()-t.timestamp>36e5?null:t}catch{return null}}function Sr(e,t){try{Xe.writeFileSync(br(),JSON.stringify({timestamp:Date.now(),latestVersion:e,highlights:t},null,2))}catch{}}function Cr(e){return new Promise(t=>{let n=pt.request({hostname:`registry.npmjs.org`,path:`/task-master-ai`,method:`GET`,headers:{Accept:`application/vnd.npm.install-v1+json`,"User-Agent":`task-master-ai/${e}`}},e=>{let n=``;e.on(`data`,e=>n+=e),e.on(`end`,()=>{try{if(e.statusCode!==200){t(null);return}t(JSON.parse(n)[`dist-tags`]?.latest||null)}catch{t(null)}})});n.on(`error`,()=>t(null)),n.setTimeout(3e3,()=>{n.destroy(),t(null)}),n.end()})}function wr(e,t,n){return{currentVersion:e,latestVersion:t,needsUpdate:_r(e,t)<0,highlights:n}}async function Tr(e){let t=e||gr(),n=xr();if(n)return wr(t,n.latestVersion,n.highlights);let r=await Cr(t);if(!r)return wr(t,t);let i=_r(t,r)<0?await vr(r):void 0;return Sr(r,i),wr(t,r,i)}function Er(e,t,n){let r=`${B.blue.bold(`Update Available!`)} ${B.dim(e)} → ${B.green(t)}`;if(n&&n.length>0){r+=`
145
+ `));return}let r=await this.taskMasterCore.integration.sendTeamInvitations(e,t,`member`);if(r.success&&r.invitations)n.succeed(`Invitations sent!`),this.displayInvitationResults(r.invitations);else{n.fail(`Failed to send invitations`);let e=r.error?.message||`Unknown error occurred`;console.error(B.red(`\n ${e}\n`))}}catch(e){n.fail(`Failed to send invitations`),console.error(B.red(`\n ${e.message}\n`))}}async trackExportedTag(e,t,n){let r=Z();if(!r)return;let i=We.join(r,`.taskmaster`,`state.json`);try{let r={};try{let e=await Xe.readFile(i,`utf-8`);r=JSON.parse(e)}catch{}r.metadata||={},r.metadata.exportedTags||(r.metadata.exportedTags={}),r.metadata.exportedTags[e]={briefId:t,briefUrl:n,exportedAt:new Date().toISOString()},r.lastUpdated=new Date().toISOString(),await Xe.writeFile(i,JSON.stringify(r,null,2),`utf-8`)}catch{}}static register(t,n){let r=new e(n);return t.addCommand(r),r}},hr=class e extends G{constructor(){super(`export-tag`),this.description(`Export a specific tag to Hamster (alias for: tm export --tag <tag>)`),this.argument(`<tag>`,`Name of the tag to export`),this.option(`--title <title>`,`Specify a title for the generated brief`),this.option(`--description <description>`,`Specify a description for the generated brief`),this.action(async(e,t)=>{await new mr().parseAsync([`node`,`export`,`--tag`,e,...t.title?[`--title`,t.title]:[],...t.description?[`--description`,t.description]:[]])})}static register(t){let n=new e;return t.addCommand(n),n}};function gr(e){return[`add-dependency`,`remove-dependency`,`validate-dependencies`,`fix-dependencies`].includes(e)?{header:`Hamster Manages Dependencies`,getBody:e=>[`Hamster handles dependencies for the ${B.blue(`"${e}"`)} Brief.`,`To manage dependencies manually, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}:e===`clear-subtasks`?{header:`Hamster Manages Subtasks`,getBody:e=>[`Hamster handles subtask management for the ${B.blue(`"${e}"`)} Brief.`,`To manage subtasks manually, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}:e===`models`?{header:`Hamster Manages AI Models`,getBody:e=>[`Hamster configures AI models automatically for the ${B.blue(`"${e}"`)} Brief.`,`To configure models manually, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}:{header:`Command Not Available in Hamster`,getBody:t=>[`The ${B.cyan(e)} command is managed by Hamster for the ${B.blue(`"${t}"`)} Brief.`,`To use this command, log out with ${B.cyan(`tm auth logout`)} and work locally.`],footer:`Switch between local and remote workflows anytime by logging in/out.`}}async function _r(e,t){let n=typeof t==`string`?await I({projectPath:t}):t,r=await n.auth.guardCommand(e,n.tasks.getStorageType());if(r.isBlocked){let t=gr(e),n=r.briefName||`remote brief`;return console.log(At({header:t.header,body:t.getBody(n),footer:t.footer,level:`info`})),!0}return!1}function vr(){let e=ft.env.TM_PUBLIC_VERSION;return e&&e!==`unknown`?e:(console.warn(`Could not read version from TM_PUBLIC_VERSION, using fallback`),`0.0.0`)}function yr(e,t){let n=e=>{let[t,n=``]=e.split(`-`,2);return{nums:t.split(`.`).map(e=>Number.parseInt(e,10)||0),pre:n}},r=n(e),i=n(t),a=Math.max(r.nums.length,i.nums.length);for(let e=0;e<a;e++){let t=(r.nums[e]||0)-(i.nums[e]||0);if(t!==0)return t<0?-1:1}return r.pre&&!i.pre?-1:!r.pre&&i.pre?1:r.pre===i.pre?0:r.pre<i.pre?-1:1}async function br(e){return new Promise(t=>{let n={hostname:`raw.githubusercontent.com`,path:`/eyaltoledano/claude-task-master/main/CHANGELOG.md`,method:`GET`,headers:{"User-Agent":`task-master-ai/${e}`}},r=pt.request(n,n=>{let r=``;n.on(`data`,e=>{r+=e}),n.on(`end`,()=>{try{if(n.statusCode!==200){t([]);return}t(xr(r,e))}catch{t([])}})});r.on(`error`,()=>{t([])}),r.setTimeout(3e3,()=>{r.destroy(),t([])}),r.end()})}function xr(e,t){try{if(!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/.test(t))return[];let n=RegExp(`## ${t.replace(/\./g,`\\.`)}\\s*\\n`,`i`),r=e.match(n);if(!r)return[];let i=r.index+r[0].length,a=e.indexOf(`
146
+ ## `,i),o=(a>0?e.slice(i,a):e.slice(i)).match(/### Minor Changes\s*\n([\s\S]*?)(?=\n###|\n##|$)/i);if(!o)return[];let s=o[1],c=[],l=/^-\s+\[#\d+\][^\n]*?!\s+-\s+(.+?)$/gm,u;for(;(u=l.exec(s))!==null;){let e=u[1].trim();c.push(e)}return c}catch{return[]}}const Sr=()=>We.join(Ze.tmpdir(),`taskmaster-update-cache.json`);function Cr(){try{let e=Sr();if(!Je.existsSync(e))return null;let t=JSON.parse(Je.readFileSync(e,`utf-8`));return Date.now()-t.timestamp>36e5?null:t}catch{return null}}function wr(e,t){try{Je.writeFileSync(Sr(),JSON.stringify({timestamp:Date.now(),latestVersion:e,highlights:t},null,2))}catch{}}function Tr(e){return new Promise(t=>{let n=pt.request({hostname:`registry.npmjs.org`,path:`/task-master-ai`,method:`GET`,headers:{Accept:`application/vnd.npm.install-v1+json`,"User-Agent":`task-master-ai/${e}`}},e=>{let n=``;e.on(`data`,e=>n+=e),e.on(`end`,()=>{try{if(e.statusCode!==200){t(null);return}t(JSON.parse(n)[`dist-tags`]?.latest||null)}catch{t(null)}})});n.on(`error`,()=>t(null)),n.setTimeout(3e3,()=>{n.destroy(),t(null)}),n.end()})}function Er(e,t,n){return{currentVersion:e,latestVersion:t,needsUpdate:yr(e,t)<0,highlights:n}}async function Dr(e){let t=e||vr(),n=Cr();if(n)return Er(t,n.latestVersion,n.highlights);let r=await Tr(t);if(!r)return Er(t,t);let i=yr(t,r)<0?await br(r):void 0;return wr(r,i),Er(t,r,i)}function Or(e,t,n){let r=`${B.blue.bold(`Update Available!`)} ${B.dim(e)} → ${B.green(t)}`;if(n&&n.length>0){r+=`
147
147
 
148
148
  `+B.bold(`What's New:`);for(let e of n)r+=`
149
149
  `+B.cyan(`• `)+e;r+=`
150
150
 
151
151
  Auto-updating to the latest version...`}else r+=`
152
152
 
153
- Auto-updating to the latest version with new features and bug fixes...`;let i=W(r,{padding:1,margin:{top:1,bottom:1},borderColor:`yellow`,borderStyle:`round`});console.log(i)}function Dr(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}async function Or(e){return new Promise(t=>{let n={hostname:`registry.npmjs.org`,path:`/task-master-ai/${e}`,method:`GET`,headers:{Accept:`application/json`,"User-Agent":`task-master-ai/${e}`}},r=pt.request(n,e=>{let n=``;e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{try{if(e.statusCode!==200){t(null);return}let r=JSON.parse(n),i=r.dist?.tarball,a=r.dist?.unpackedSize;if(!i){t(null);return}t({url:i,size:a||0})}catch{t(null)}})});r.on(`error`,()=>{t(null)}),r.setTimeout(1e4,()=>{r.destroy(),t(null)}),r.end()})}async function kr(e,t,n,r=5){return r<=0?(console.error(B.red(`Too many redirects`)),Promise.resolve(!1)):new Promise(i=>{let a=new URL(e),o={hostname:a.hostname,path:a.pathname,method:`GET`,headers:{"User-Agent":`task-master-ai/${n}`}},s=pt.request(o,e=>{if(e.statusCode===301||e.statusCode===302){let a=e.headers.location;if(a){kr(a,t,n,r-1).then(i).catch(()=>i(!1));return}i(!1);return}if(e.statusCode!==200){i(!1);return}let a=Number.parseInt(e.headers[`content-length`]||`0`,10),o=0,s=new mt.SingleBar({format:`${B.blue(`Downloading`)} ${B.cyan(`{bar}`)} {percentage}% | {downloaded}/{total}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},mt.Presets.shades_classic);a>0?s.start(a,0,{downloaded:Dr(0),total:Dr(a)}):console.log(B.blue(`Downloading task-master-ai@${n}...`));let c=V.createWriteStream(t);e.on(`data`,e=>{o+=e.length,a>0&&s.update(o,{downloaded:Dr(o),total:Dr(a)})}),e.pipe(c),c.on(`finish`,()=>{a>0&&s.stop(),c.close(()=>{console.log(B.green(`✓`)+B.dim(` Downloaded ${Dr(o)}`)),i(!0)})}),c.on(`error`,e=>{a>0&&s.stop(),console.error(B.red(`Download error:`),e.message),V.unlink(t,()=>{}),i(!1)})});s.on(`error`,e=>{console.error(B.red(`Request error:`),e.message),i(!1)}),s.setTimeout(12e4,()=>{s.destroy(),console.error(B.red(`Download timeout`)),i(!1)}),s.end()})}const Ar=[{name:`Extracting package`,weight:15},{name:`Resolving dependencies`,weight:25},{name:`Building dependency tree`,weight:20},{name:`Linking package`,weight:25},{name:`Finalizing installation`,weight:15}],jr=Ar.reduce((e,t)=>e+t.weight,0);function Mr(e){let t=e.toLowerCase();return t.includes(`extract`)||t.includes(`unpack`)?0:t.includes(`resolv`)||t.includes(`fetch`)?1:t.includes(`build`)||t.includes(`tree`)?2:t.includes(`link`)||t.includes(`bin`)?3:t.includes(`added`)||t.includes(`done`)?4:-1}function Nr(e,t){if(e<0||e>=Ar.length)return e>=Ar.length?100:0;let n=0;for(let t=0;t<e;t++)n+=Ar[t].weight;let r=Ar[e].weight*t/100;return Math.round((n+r)/jr*100)}async function Pr(e){let t=new mt.SingleBar({format:`${B.blue(`Installing`)} ${B.cyan(`{bar}`)} {percentage}% | {phase}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},mt.Presets.shades_classic);t.start(100,0,{phase:Ar[0].name});let n=0,r=0,i=Date.now(),a=setInterval(()=>{let e=Date.now()-i,a=1e4,o=0,s=0;for(let t=0;t<Ar.length;t++){let n=Ar[t].weight/jr*a;if(e<s+n){o=t;break}s+=n,o=t}o>n&&(n=o);let c=Ar.slice(0,n).reduce((e,t)=>e+t.weight,0)/jr*a,l=Ar[n].weight/jr*a,u=e-c,d=Math.min(u/l*100,95),f=Nr(n,d);f>r&&(r=f,t.update(r,{phase:Ar[n].name}))},100);return new Promise(i=>{let o=Qe(`npm`,[`install`,`-g`,e,`--no-fund`,`--no-audit`],{stdio:[`ignore`,`pipe`,`pipe`]}),s=``;o.stdout.on(`data`,e=>{let i=Mr(e.toString());if(i>n){n=i;let e=Nr(n,0);e>r&&(r=e,t.update(r,{phase:Ar[n].name}))}}),o.stderr.on(`data`,e=>{let i=e.toString();s+=i;let a=Mr(i);if(a>n){n=a;let e=Nr(n,0);e>r&&(r=e,t.update(r,{phase:Ar[n].name}))}}),o.on(`close`,n=>{if(clearInterval(a),t.update(100,{phase:`Complete`}),t.stop(),V.existsSync(e)&&V.unlink(e,()=>{}),n===0)console.log(B.green(`✔`)+B.green(` Update installed successfully`)),i(!0);else{if(console.log(B.red(`✖`)+B.red(` Installation failed`)),s){let e=s.split(`
153
+ Auto-updating to the latest version with new features and bug fixes...`;let i=W(r,{padding:1,margin:{top:1,bottom:1},borderColor:`yellow`,borderStyle:`round`});console.log(i)}function kr(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}async function Ar(e){return new Promise(t=>{let n={hostname:`registry.npmjs.org`,path:`/task-master-ai/${e}`,method:`GET`,headers:{Accept:`application/json`,"User-Agent":`task-master-ai/${e}`}},r=pt.request(n,e=>{let n=``;e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{try{if(e.statusCode!==200){t(null);return}let r=JSON.parse(n),i=r.dist?.tarball,a=r.dist?.unpackedSize;if(!i){t(null);return}t({url:i,size:a||0})}catch{t(null)}})});r.on(`error`,()=>{t(null)}),r.setTimeout(1e4,()=>{r.destroy(),t(null)}),r.end()})}async function jr(e,t,n,r=5){return r<=0?(console.error(B.red(`Too many redirects`)),Promise.resolve(!1)):new Promise(i=>{let a=new URL(e),o={hostname:a.hostname,path:a.pathname,method:`GET`,headers:{"User-Agent":`task-master-ai/${n}`}},s=pt.request(o,e=>{if(e.statusCode===301||e.statusCode===302){let a=e.headers.location;if(a){jr(a,t,n,r-1).then(i).catch(()=>i(!1));return}i(!1);return}if(e.statusCode!==200){i(!1);return}let a=Number.parseInt(e.headers[`content-length`]||`0`,10),o=0,s=new mt.SingleBar({format:`${B.blue(`Downloading`)} ${B.cyan(`{bar}`)} {percentage}% | {downloaded}/{total}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},mt.Presets.shades_classic);a>0?s.start(a,0,{downloaded:kr(0),total:kr(a)}):console.log(B.blue(`Downloading task-master-ai@${n}...`));let c=V.createWriteStream(t);e.on(`data`,e=>{o+=e.length,a>0&&s.update(o,{downloaded:kr(o),total:kr(a)})}),e.pipe(c),c.on(`finish`,()=>{a>0&&s.stop(),c.close(()=>{console.log(B.green(`✓`)+B.dim(` Downloaded ${kr(o)}`)),i(!0)})}),c.on(`error`,e=>{a>0&&s.stop(),console.error(B.red(`Download error:`),e.message),V.unlink(t,()=>{}),i(!1)})});s.on(`error`,e=>{console.error(B.red(`Request error:`),e.message),i(!1)}),s.setTimeout(12e4,()=>{s.destroy(),console.error(B.red(`Download timeout`)),i(!1)}),s.end()})}const Mr=[{name:`Extracting package`,weight:15},{name:`Resolving dependencies`,weight:25},{name:`Building dependency tree`,weight:20},{name:`Linking package`,weight:25},{name:`Finalizing installation`,weight:15}],Nr=Mr.reduce((e,t)=>e+t.weight,0);function Pr(e){let t=e.toLowerCase();return t.includes(`extract`)||t.includes(`unpack`)?0:t.includes(`resolv`)||t.includes(`fetch`)?1:t.includes(`build`)||t.includes(`tree`)?2:t.includes(`link`)||t.includes(`bin`)?3:t.includes(`added`)||t.includes(`done`)?4:-1}function Fr(e,t){if(e<0||e>=Mr.length)return e>=Mr.length?100:0;let n=0;for(let t=0;t<e;t++)n+=Mr[t].weight;let r=Mr[e].weight*t/100;return Math.round((n+r)/Nr*100)}async function Ir(e){let t=new mt.SingleBar({format:`${B.blue(`Installing`)} ${B.cyan(`{bar}`)} {percentage}% | {phase}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},mt.Presets.shades_classic);t.start(100,0,{phase:Mr[0].name});let n=0,r=0,i=Date.now(),a=setInterval(()=>{let e=Date.now()-i,a=1e4,o=0,s=0;for(let t=0;t<Mr.length;t++){let n=Mr[t].weight/Nr*a;if(e<s+n){o=t;break}s+=n,o=t}o>n&&(n=o);let c=Mr.slice(0,n).reduce((e,t)=>e+t.weight,0)/Nr*a,l=Mr[n].weight/Nr*a,u=e-c,d=Math.min(u/l*100,95),f=Fr(n,d);f>r&&(r=f,t.update(r,{phase:Mr[n].name}))},100);return new Promise(i=>{let o=Qe(`npm`,[`install`,`-g`,e,`--no-fund`,`--no-audit`],{stdio:[`ignore`,`pipe`,`pipe`]}),s=``;o.stdout.on(`data`,e=>{let i=Pr(e.toString());if(i>n){n=i;let e=Fr(n,0);e>r&&(r=e,t.update(r,{phase:Mr[n].name}))}}),o.stderr.on(`data`,e=>{let i=e.toString();s+=i;let a=Pr(i);if(a>n){n=a;let e=Fr(n,0);e>r&&(r=e,t.update(r,{phase:Mr[n].name}))}}),o.on(`close`,n=>{if(clearInterval(a),t.update(100,{phase:`Complete`}),t.stop(),V.existsSync(e)&&V.unlink(e,()=>{}),n===0)console.log(B.green(`✔`)+B.green(` Update installed successfully`)),i(!0);else{if(console.log(B.red(`✖`)+B.red(` Installation failed`)),s){let e=s.split(`
154
154
  `).filter(e=>e.includes(`ERR`)||e.includes(`error`)||e.includes(`WARN`)).join(`
155
- `).trim();e&&console.log(B.dim(`Error: ${e}`))}i(!1)}}),o.on(`error`,n=>{clearInterval(a),t.stop(),V.unlink(e,()=>{}),console.log(B.red(`✖`)+B.red(` Installation failed`)),console.log(B.red(`Error:`),n.message),i(!1)})})}async function Fr(e){let t=J({text:B.blue(`Updating task-master-ai to version ${B.green(e)}`),spinner:`dots`,color:`blue`}).start();return new Promise(n=>{let r=Qe(`npm`,[`install`,`-g`,`task-master-ai@${e}`,`--no-fund`,`--no-audit`,`--loglevel=warn`],{stdio:[`ignore`,`pipe`,`pipe`]}),i=``;r.stdout.on(`data`,()=>{t.text=B.blue(`Installing task-master-ai@${e}...`)}),r.stderr.on(`data`,e=>{i+=e.toString()}),r.on(`close`,r=>{r===0?(t.succeed(B.green(`Successfully updated to version ${B.bold(e)}`)),n(!0)):(t.fail(B.red(`Auto-update failed`)),console.log(B.cyan(`Please run manually: npm install -g task-master-ai@${e}`)),i&&console.log(B.dim(`Error: ${i.trim()}`)),n(!1))}),r.on(`error`,r=>{t.fail(B.red(`Auto-update failed`)),console.log(B.red(`Error:`),r.message),console.log(B.cyan(`Please run manually: npm install -g task-master-ai@${e}`)),n(!1)})})}async function Ir(e){if(ft.env.TASKMASTER_SKIP_AUTO_UPDATE===`1`||ft.env.CI||ft.env.NODE_ENV===`test`){let e=ft.env.TASKMASTER_SKIP_AUTO_UPDATE===`1`?`TASKMASTER_SKIP_AUTO_UPDATE=1`:ft.env.CI?`CI environment`:`NODE_ENV=test`;return console.log(B.dim(`Skipping auto-update (${e})`)),!1}let t=await Or(e);if(!t)return Fr(e);let n=Je.tmpdir(),r=H.join(n,`task-master-ai-${e}.tgz`);return await kr(t.url,r,e)?await Pr(r)?(console.log(B.green(`Successfully updated to version ${B.bold(e)}`)),!0):(console.log(B.cyan(`Please run manually: npm install -g task-master-ai@${e}`)),!1):(console.log(B.dim(`Falling back to npm install...`)),Fr(e))}function Lr(e){let t=e.slice(2);console.log(B.dim(`Restarting with updated version...
156
- `));let n=Qe(`task-master`,t,{stdio:`inherit`,detached:!1,shell:ft.platform===`win32`});n.on(`exit`,(e,t)=>{if(t){ft.kill(ft.pid,t);return}ft.exit(e??0)}),n.on(`error`,e=>{console.error(B.red(`Failed to restart with new version:`),e.message),console.log(B.yellow(`Please run your command again manually.`)),ft.exit(1)})}async function Rr(e,t,n=`falling back to file-based operation`){let r;try{r=await I({projectPath:e||process.cwd()})}catch(e){let r=e instanceof Error?e.message:String(e);return t(`warn`,`TmCore check failed, ${n}: ${r}`),{isApiStorage:!1,error:r}}return r.tasks.getStorageType()===`api`?{isApiStorage:!0,tmCore:r}:{isApiStorage:!1,tmCore:r}}async function zr(e){let{taskId:t,prompt:n,projectRoot:r,tag:i,appendMode:a=!1,useResearch:o=!1,metadata:s,isMCP:c=!1,outputFormat:l=`text`,report:u}=e,{isApiStorage:d,tmCore:f}=await Rr(r,u,`falling back to file-based update`);if(!d||!f)return null;u(`info`,`Delegating update to Hamster for task ${t}`);let p=a?`append`:`update`,m=!c&&l===`text`?J({text:`Updating ${t} on Hamster...`,color:`cyan`}).start():null;try{return await f.tasks.updateWithPrompt(String(t),n,i,{mode:p,useResearch:o,...s&&{metadata:s}}),m&&m.succeed(`Task updated on Hamster`),{success:!0,taskId:t,message:`Task updated via remote AI service`,telemetryData:null,tagInfo:null}}catch(e){throw m&&m.fail(`Update failed`),e}}async function Br(e){let{taskId:t,numSubtasks:n,useResearch:r=!1,additionalContext:i,force:a=!1,projectRoot:o,tag:s,isMCP:c=!1,outputFormat:l=`text`,report:u}=e,{isApiStorage:d,tmCore:f}=await Rr(o,u,`falling back to file-based expansion`);if(!d||!f)return null;if(u(`info`,`Delegating expansion to Hamster for task ${t}`),!c&&l===`text`){let e=process.env.TM_DEBUG===`1`&&i?`${i.substring(0,60)}${i.length>60?`...`:``}`:i?`[provided]`:`[none]`;console.log(W(B.blue.bold(`Expanding Task via Hamster`)+`
155
+ `).trim();e&&console.log(B.dim(`Error: ${e}`))}i(!1)}}),o.on(`error`,n=>{clearInterval(a),t.stop(),V.unlink(e,()=>{}),console.log(B.red(`✖`)+B.red(` Installation failed`)),console.log(B.red(`Error:`),n.message),i(!1)})})}async function Lr(e){let t=J({text:B.blue(`Updating task-master-ai to version ${B.green(e)}`),spinner:`dots`,color:`blue`}).start();return new Promise(n=>{let r=Qe(`npm`,[`install`,`-g`,`task-master-ai@${e}`,`--no-fund`,`--no-audit`,`--loglevel=warn`],{stdio:[`ignore`,`pipe`,`pipe`]}),i=``;r.stdout.on(`data`,()=>{t.text=B.blue(`Installing task-master-ai@${e}...`)}),r.stderr.on(`data`,e=>{i+=e.toString()}),r.on(`close`,r=>{r===0?(t.succeed(B.green(`Successfully updated to version ${B.bold(e)}`)),n(!0)):(t.fail(B.red(`Auto-update failed`)),console.log(B.cyan(`Please run manually: npm install -g task-master-ai@${e}`)),i&&console.log(B.dim(`Error: ${i.trim()}`)),n(!1))}),r.on(`error`,r=>{t.fail(B.red(`Auto-update failed`)),console.log(B.red(`Error:`),r.message),console.log(B.cyan(`Please run manually: npm install -g task-master-ai@${e}`)),n(!1)})})}async function Rr(e){if(ft.env.TASKMASTER_SKIP_AUTO_UPDATE===`1`||ft.env.CI||ft.env.NODE_ENV===`test`){let e=ft.env.TASKMASTER_SKIP_AUTO_UPDATE===`1`?`TASKMASTER_SKIP_AUTO_UPDATE=1`:ft.env.CI?`CI environment`:`NODE_ENV=test`;return console.log(B.dim(`Skipping auto-update (${e})`)),!1}let t=await Ar(e);if(!t)return Lr(e);let n=qe.tmpdir(),r=H.join(n,`task-master-ai-${e}.tgz`);return await jr(t.url,r,e)?await Ir(r)?(console.log(B.green(`Successfully updated to version ${B.bold(e)}`)),!0):(console.log(B.cyan(`Please run manually: npm install -g task-master-ai@${e}`)),!1):(console.log(B.dim(`Falling back to npm install...`)),Lr(e))}function zr(e){let t=e.slice(2);console.log(B.dim(`Restarting with updated version...
156
+ `));let n=Qe(`task-master`,t,{stdio:`inherit`,detached:!1,shell:ft.platform===`win32`});n.on(`exit`,(e,t)=>{if(t){ft.kill(ft.pid,t);return}ft.exit(e??0)}),n.on(`error`,e=>{console.error(B.red(`Failed to restart with new version:`),e.message),console.log(B.yellow(`Please run your command again manually.`)),ft.exit(1)})}async function Br(e,t,n=`falling back to file-based operation`){let r;try{r=await I({projectPath:e||process.cwd()})}catch(e){let r=e instanceof Error?e.message:String(e);return t(`warn`,`TmCore check failed, ${n}: ${r}`),{isApiStorage:!1,error:r}}return r.tasks.getStorageType()===`api`?{isApiStorage:!0,tmCore:r}:{isApiStorage:!1,tmCore:r}}async function Vr(e){let{taskId:t,prompt:n,projectRoot:r,tag:i,appendMode:a=!1,useResearch:o=!1,metadata:s,isMCP:c=!1,outputFormat:l=`text`,report:u}=e,{isApiStorage:d,tmCore:f}=await Br(r,u,`falling back to file-based update`);if(!d||!f)return null;u(`info`,`Delegating update to Hamster for task ${t}`);let p=a?`append`:`update`,m=!c&&l===`text`?J({text:`Updating ${t} on Hamster...`,color:`cyan`}).start():null;try{return await f.tasks.updateWithPrompt(String(t),n,i,{mode:p,useResearch:o,...s&&{metadata:s}}),m&&m.succeed(`Task updated on Hamster`),{success:!0,taskId:t,message:`Task updated via remote AI service`,telemetryData:null,tagInfo:null}}catch(e){throw m&&m.fail(`Update failed`),e}}async function Hr(e){let{taskId:t,numSubtasks:n,useResearch:r=!1,additionalContext:i,force:a=!1,projectRoot:o,tag:s,isMCP:c=!1,outputFormat:l=`text`,report:u}=e,{isApiStorage:d,tmCore:f}=await Br(o,u,`falling back to file-based expansion`);if(!d||!f)return null;if(u(`info`,`Delegating expansion to Hamster for task ${t}`),!c&&l===`text`){let e=process.env.TM_DEBUG===`1`&&i?`${i.substring(0,60)}${i.length>60?`...`:``}`:i?`[provided]`:`[none]`;console.log(W(B.blue.bold(`Expanding Task via Hamster`)+`
157
157
 
158
158
  `+B.white(`Task ID: ${t}`)+`
159
159
  `+B.white(`Subtasks: ${n||`auto`}`)+`
160
160
  `+B.white(`Use Research: ${r?`yes`:`no`}`)+`
161
161
  `+B.white(`Force: ${a?`yes`:`no`}`)+`
162
162
  `+B.white(`Context: ${e}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}))}let p=!c&&l===`text`?J({text:`Expanding task on Hamster...`,color:`cyan`}).start():null;try{let e=await f.tasks.expand(String(t),s,{numSubtasks:n,useResearch:r,additionalContext:i,force:a});if(p&&p.succeed(`Task expansion queued successfully`),l===`text`){let n=[B.green(`Successfully queued expansion for task ${t}`),``,B.white(`The task expansion has been queued on Hamster`),B.white(`Subtasks will be generated in the background.`)];e?.taskLink&&(n.push(``),n.push(B.white(`View task: `)+B.blue.underline(e.taskLink))),n.push(``),n.push(B.dim(`Or run: ${B.yellow(`task-master show ${t}`)}`)),console.log(W(n.join(`
163
- `),{padding:1,borderColor:`green`,borderStyle:`round`}))}return{success:!0,taskId:t,message:e?.message||`Task expansion queued via remote AI service`,telemetryData:null,tagInfo:null}}catch(e){throw p&&p.fail(`Expansion failed`),e}}async function Vr(e){let{projectRoot:t,isMCP:n=!1,outputFormat:r=`text`,report:i,skipTableDisplay:a=!1}=e,{isApiStorage:o,tmCore:s}=await Rr(t,i,`falling back to file-based tags`);if(!o||!s)return null;try{let e=await s.tasks.getTagsWithStats();if(e.tags.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:0),r===`text`&&!n&&!a)if(e.tags.length===0)console.log(W(B.yellow(`No tags found`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}}));else{let t=[B.cyan.bold(`Tag Name`),B.cyan.bold(`Status`),B.cyan.bold(`Updated`),B.cyan.bold(`Tasks`),B.cyan.bold(`Completed`)],n=Math.max(process.stdout.columns||120,80),r=Math.floor(n*.95),i=new K({head:t,colWidths:[.35,.25,.2,.1,.1].map((e,t)=>Math.max(Math.floor(r*e),t===0?20:8)),wordWrap:!0});e.tags.forEach(e=>{let t=[],n=e.briefId?e.briefId.slice(-8):`unknown`,r=e.isCurrent?`${B.green(`●`)} ${B.green.bold(e.name)} ${B.gray(`(current - ${n})`)}`:` ${e.name} ${B.gray(`(${n})`)}`;t.push(r),t.push(vn(e.status,!0));let a=e.updatedAt?new Date(e.updatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`}):B.gray(`N/A`);t.push(B.gray(a)),t.push(B.white(e.taskCount.toString())),t.push(B.green(e.completedTasks.toString())),i.push(t)}),console.log(i.toString())}return{success:!0,tags:e.tags,currentTag:e.currentTag,totalTags:e.totalTags,message:`Found ${e.totalTags} tag(s)`}}catch(e){throw e}}async function Hr(e){let{tagName:t,projectRoot:n,isMCP:r=!1,outputFormat:i=`text`,report:a}=e,{isApiStorage:o,tmCore:s}=await Rr(n,a,`falling back to file-based tag switching`);if(!o||!s)return null;a(`info`,`Switching to tag (brief) "${t}" in Hamster`),!r&&i===`text`&&console.log(W(B.blue.bold(`Switching Tag in Hamster`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let c=!r&&i===`text`?J({text:`Switching to tag "${t}"...`,color:`cyan`}).start():null;try{let e=s.auth.getContext()?.briefName||null;await s.tasks.switchTag(t);let n=s.auth.getContext(),a=n?.briefName||t,o=(await s.tasks.list()).tasks.length;if(c&&c.succeed(`Switched to tag "${a}"`),i===`text`&&!r){let t=n?.briefId?n.briefId.slice(-8):`unknown`;console.log(W(B.green.bold(`✓ Tag Switched Successfully`)+`
163
+ `),{padding:1,borderColor:`green`,borderStyle:`round`}))}return{success:!0,taskId:t,message:e?.message||`Task expansion queued via remote AI service`,telemetryData:null,tagInfo:null}}catch(e){throw p&&p.fail(`Expansion failed`),e}}async function Ur(e){let{projectRoot:t,isMCP:n=!1,outputFormat:r=`text`,report:i,skipTableDisplay:a=!1}=e,{isApiStorage:o,tmCore:s}=await Br(t,i,`falling back to file-based tags`);if(!o||!s)return null;try{let e=await s.tasks.getTagsWithStats();if(e.tags.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:0),r===`text`&&!n&&!a)if(e.tags.length===0)console.log(W(B.yellow(`No tags found`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}}));else{let t=[B.cyan.bold(`Tag Name`),B.cyan.bold(`Status`),B.cyan.bold(`Updated`),B.cyan.bold(`Tasks`),B.cyan.bold(`Completed`)],n=Math.max(process.stdout.columns||120,80),r=Math.floor(n*.95),i=new K({head:t,colWidths:[.35,.25,.2,.1,.1].map((e,t)=>Math.max(Math.floor(r*e),t===0?20:8)),wordWrap:!0});e.tags.forEach(e=>{let t=[],n=e.briefId?e.briefId.slice(-8):`unknown`,r=e.isCurrent?`${B.green(`●`)} ${B.green.bold(e.name)} ${B.gray(`(current - ${n})`)}`:` ${e.name} ${B.gray(`(${n})`)}`;t.push(r),t.push(bn(e.status,!0));let a=e.updatedAt?new Date(e.updatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`}):B.gray(`N/A`);t.push(B.gray(a)),t.push(B.white(e.taskCount.toString())),t.push(B.green(e.completedTasks.toString())),i.push(t)}),console.log(i.toString())}return{success:!0,tags:e.tags,currentTag:e.currentTag,totalTags:e.totalTags,message:`Found ${e.totalTags} tag(s)`}}catch(e){throw e}}async function Wr(e){let{tagName:t,projectRoot:n,isMCP:r=!1,outputFormat:i=`text`,report:a}=e,{isApiStorage:o,tmCore:s}=await Br(n,a,`falling back to file-based tag switching`);if(!o||!s)return null;a(`info`,`Switching to tag (brief) "${t}" in Hamster`),!r&&i===`text`&&console.log(W(B.blue.bold(`Switching Tag in Hamster`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let c=!r&&i===`text`?J({text:`Switching to tag "${t}"...`,color:`cyan`}).start():null;try{let e=s.auth.getContext()?.briefName||null;await s.tasks.switchTag(t);let n=s.auth.getContext(),a=n?.briefName||t,o=(await s.tasks.list()).tasks.length;if(c&&c.succeed(`Switched to tag "${a}"`),i===`text`&&!r){let t=n?.briefId?n.briefId.slice(-8):`unknown`;console.log(W(B.green.bold(`✓ Tag Switched Successfully`)+`
164
164
 
165
165
  `+(e?B.white(`Previous Tag: ${B.cyan(e)}\n`):``)+B.white(`Current Tag: ${B.green.bold(a)}`)+`
166
166
  `+B.gray(`Brief ID: ${t}`)+`
167
- `+B.white(`Available Tasks: ${B.yellow(o)}`),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:0}}))}return{success:!0,previousTag:e,currentTag:a,switched:!0,taskCount:o,message:`Successfully switched to tag "${a}"`}}catch(e){throw c&&c.fail(`Failed to switch tag`),e}}async function Ur(e){let{tagName:t,projectRoot:n,isMCP:r=!1,outputFormat:i=`text`,report:a}=e,{isApiStorage:o,tmCore:s}=await Rr(n,a,`falling back to file-based tag creation`);if(!o||!s)return null;let c=s.auth.getBriefCreationUrl();return c?(!r&&i===`text`&&console.log(Ot({header:`# Create a Brief in Hamster Studio`,body:[`Your tags are separate task lists. When connected to Hamster,
167
+ `+B.white(`Available Tasks: ${B.yellow(o)}`),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:0}}))}return{success:!0,previousTag:e,currentTag:a,switched:!0,taskCount:o,message:`Successfully switched to tag "${a}"`}}catch(e){throw c&&c.fail(`Failed to switch tag`),e}}async function Gr(e){let{tagName:t,projectRoot:n,isMCP:r=!1,outputFormat:i=`text`,report:a}=e,{isApiStorage:o,tmCore:s}=await Br(n,a,`falling back to file-based tag creation`);if(!o||!s)return null;let c=s.auth.getBriefCreationUrl();return c?(!r&&i===`text`&&console.log(At({header:`# Create a Brief in Hamster Studio`,body:[`Your tags are separate task lists. When connected to Hamster,
168
168
  task lists are attached to briefs.`,`Create a new brief and its task list will automatically be
169
169
  available when generated.`],callToAction:{label:`Visit:`,action:c},footer:`To access tasks for a specific brief, use:
170
170
  • tm briefs select <brief-name>
171
171
  • tm briefs select <brief-id>
172
- • tm briefs select (interactive)`})),{success:!0,message:`API storage detected. Please create tag "${t}" at: ${c}`,redirectUrl:c}):(a(`error`,`Could not generate brief creation URL. Please ensure you have selected an organization using "tm context org"`),{success:!1,message:`Failed to generate brief creation URL. Please ensure an organization is selected.`,redirectUrl:``})}function Wr(e,t=null){let n={high:3,medium:2,low:1},r=(e,t)=>typeof t==`string`&&t.includes(`.`)?t:`${e}.${t}`,i=new Set;e.forEach(e=>{(e.status===`done`||e.status===`completed`)&&i.add(String(e.id)),Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{(t.status===`done`||t.status===`completed`)&&i.add(`${e.id}.${t.id}`)})});let a=[];if(e.filter(e=>e.status===`in-progress`&&Array.isArray(e.subtasks)).forEach(e=>{e.subtasks.forEach(t=>{let n=(t.status||`pending`).toLowerCase();if(n!==`pending`&&n!==`in-progress`)return;let o=t.dependencies?.map(t=>r(e.id,t))??[];(o.length===0||o.every(e=>i.has(String(e))))&&a.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,status:t.status||`pending`,priority:t.priority||e.priority||`medium`,dependencies:o,parentId:e.id})})}),a.length>0){a.sort((e,t)=>{let r=n[e.priority]??2,i=n[t.priority]??2;if(i!==r)return i-r;if(e.dependencies.length!==t.dependencies.length)return e.dependencies.length-t.dependencies.length;let[a,o]=e.id.split(`.`).map(Number),[s,c]=t.id.split(`.`).map(Number);return a===s?o-c:a-s});let e=a[0];return e&&t&&Fe(e,t),e}let o=e.filter(e=>{let t=(e.status||`pending`).toLowerCase();return t!==`pending`&&t!==`in-progress`?!1:(e.dependencies??[]).every(e=>i.has(String(e)))});if(o.length===0)return null;let s=o.sort((e,t)=>{let r=n[e.priority||`medium`]??2,i=n[t.priority||`medium`]??2;if(i!==r)return i-r;let a=(e.dependencies??[]).length,o=(t.dependencies??[]).length;return a===o?e.id-t.id:a-o})[0];return s&&t&&Fe(s,t),s}var Gr=Wr;async function Kr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{copyFromCurrent:s=!1,copyFromTag:c,description:l}=n,u=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)},d=await Ur({tagName:t,projectRoot:o||ze(),isMCP:!!a,outputFormat:i,report:(e,...t)=>u[e](...t)});if(d){if(!d.success)throw Error(d.message||`Remote tag creation failed`);return d}try{if(!t||typeof t!=`string`)throw Error(`Tag name is required and must be a string`);if(!/^[a-zA-Z0-9_-]+$/.test(t))throw Error(`Tag name can only contain letters, numbers, hyphens, and underscores`);if([`master`,`main`,`default`].includes(t.toLowerCase()))throw Error(`"${t}" is a reserved tag name`);u.info(`Creating new tag: ${t}`);let n=D(e,o);if(!n)throw Error(`Could not read tasks file at ${e}`);let r;if(n._rawTaggedData)r=n._rawTaggedData;else if(n.tasks&&!n.master)r={master:{tasks:n.tasks,metadata:n.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks live here by default`}}};else{r={};for(let[e,t]of Object.entries(n))e!==`_rawTaggedData`&&e!==`tag`&&(r[e]=t)}if(r[t])throw Error(`Tag "${t}" already exists`);let a=[];if(s||c){let e=c||_e(o);a=me(r,e),c&&a.length===0&&u.warn(`Source tag "${c}" not found or has no tasks`),u.info(`Copying ${a.length} tasks from tag "${e}"`)}else u.info(`Creating empty tag (no tasks copied)`);r[t]={tasks:[...a],metadata:{created:new Date().toISOString(),updated:new Date().toISOString(),description:l||`Tag created on ${new Date().toLocaleDateString()}`}};let d={};for(let[e,t]of Object.entries(r))e!==`_rawTaggedData`&&(d[e]=t);return y(e,d,o),u.success(`Successfully created tag "${t}"`),i===`json`||i===`text`&&console.log(W(B.green.bold(`✓ Tag Created Successfully`)+`\n\nTag Name: ${B.cyan(t)}\nTasks Copied: ${B.yellow(a.length)}`+(s||c?`\nSource Tag: ${B.cyan(c||_e(o))}`:``)+(l?`\nDescription: ${B.gray(l)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tagName:t,created:!0,tasksCopied:a.length,sourceTag:s||c?c||_e(o):null,description:l||`Tag created on ${new Date().toLocaleDateString()}`}}catch(e){throw u.error(`Error creating tag: ${e.message}`),e}}async function qr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{yes:s=!1}=n,c=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Tag name is required and must be a string`);if(t===`master`)throw Error(`Cannot delete the "master" tag`);c.info(`Deleting tag: ${t}`);let n=D(e,o);if(!n)throw Error(`Could not read tasks file at ${e}`);let r;if(n._rawTaggedData)r=n._rawTaggedData;else if(n.tasks&&!n.master)r={master:{tasks:n.tasks,metadata:n.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks live here by default`}}};else{r={};for(let[e,t]of Object.entries(n))e!==`_rawTaggedData`&&e!==`tag`&&(r[e]=t)}if(!r[t])throw Error(`Tag "${t}" does not exist`);let a=_e(o)===t,l=me(r,t).length;if(!s&&l>0&&i===`text`){if(console.log(W(B.yellow.bold(`⚠ WARNING: Tag Deletion`)+`\n\nYou are about to delete tag "${B.cyan(t)}"\nThis will permanently delete ${B.red.bold(l)} tasks
172
+ • tm briefs select (interactive)`})),{success:!0,message:`API storage detected. Please create tag "${t}" at: ${c}`,redirectUrl:c}):(a(`error`,`Could not generate brief creation URL. Please ensure you have selected an organization using "tm context org"`),{success:!1,message:`Failed to generate brief creation URL. Please ensure an organization is selected.`,redirectUrl:``})}function Kr(e,t=null){let n={high:3,medium:2,low:1},r=(e,t)=>typeof t==`string`&&t.includes(`.`)?t:`${e}.${t}`,i=new Set;e.forEach(e=>{(e.status===`done`||e.status===`completed`)&&i.add(String(e.id)),Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{(t.status===`done`||t.status===`completed`)&&i.add(`${e.id}.${t.id}`)})});let a=[];if(e.filter(e=>e.status===`in-progress`&&Array.isArray(e.subtasks)).forEach(e=>{e.subtasks.forEach(t=>{let n=(t.status||`pending`).toLowerCase();if(n!==`pending`&&n!==`in-progress`)return;let o=t.dependencies?.map(t=>r(e.id,t))??[];(o.length===0||o.every(e=>i.has(String(e))))&&a.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,status:t.status||`pending`,priority:t.priority||e.priority||`medium`,dependencies:o,parentId:e.id})})}),a.length>0){a.sort((e,t)=>{let r=n[e.priority]??2,i=n[t.priority]??2;if(i!==r)return i-r;if(e.dependencies.length!==t.dependencies.length)return e.dependencies.length-t.dependencies.length;let[a,o]=e.id.split(`.`).map(Number),[s,c]=t.id.split(`.`).map(Number);return a===s?o-c:a-s});let e=a[0];return e&&t&&Ne(e,t),e}let o=e.filter(e=>{let t=(e.status||`pending`).toLowerCase();return t!==`pending`&&t!==`in-progress`?!1:(e.dependencies??[]).every(e=>i.has(String(e)))});if(o.length===0)return null;let s=o.sort((e,t)=>{let r=n[e.priority||`medium`]??2,i=n[t.priority||`medium`]??2;if(i!==r)return i-r;let a=(e.dependencies??[]).length,o=(t.dependencies??[]).length;return a===o?e.id-t.id:a-o})[0];return s&&t&&Ne(s,t),s}var qr=Kr;async function Jr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{copyFromCurrent:s=!1,copyFromTag:c,description:l}=n,u=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)},d=await Gr({tagName:t,projectRoot:o||Le(),isMCP:!!a,outputFormat:i,report:(e,...t)=>u[e](...t)});if(d){if(!d.success)throw Error(d.message||`Remote tag creation failed`);return d}try{if(!t||typeof t!=`string`)throw Error(`Tag name is required and must be a string`);if(!/^[a-zA-Z0-9_-]+$/.test(t))throw Error(`Tag name can only contain letters, numbers, hyphens, and underscores`);if([`master`,`main`,`default`].includes(t.toLowerCase()))throw Error(`"${t}" is a reserved tag name`);u.info(`Creating new tag: ${t}`);let n=E(e,o);if(!n)throw Error(`Could not read tasks file at ${e}`);let r;if(n._rawTaggedData)r=n._rawTaggedData;else if(n.tasks&&!n.master)r={master:{tasks:n.tasks,metadata:n.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks live here by default`}}};else{r={};for(let[e,t]of Object.entries(n))e!==`_rawTaggedData`&&e!==`tag`&&(r[e]=t)}if(r[t])throw Error(`Tag "${t}" already exists`);let a=[];if(s||c){let e=c||ge(o);a=pe(r,e),c&&a.length===0&&u.warn(`Source tag "${c}" not found or has no tasks`),u.info(`Copying ${a.length} tasks from tag "${e}"`)}else u.info(`Creating empty tag (no tasks copied)`);r[t]={tasks:[...a],metadata:{created:new Date().toISOString(),updated:new Date().toISOString(),description:l||`Tag created on ${new Date().toLocaleDateString()}`}};let d={};for(let[e,t]of Object.entries(r))e!==`_rawTaggedData`&&(d[e]=t);return y(e,d,o),u.success(`Successfully created tag "${t}"`),i===`json`||i===`text`&&console.log(W(B.green.bold(`✓ Tag Created Successfully`)+`\n\nTag Name: ${B.cyan(t)}\nTasks Copied: ${B.yellow(a.length)}`+(s||c?`\nSource Tag: ${B.cyan(c||ge(o))}`:``)+(l?`\nDescription: ${B.gray(l)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tagName:t,created:!0,tasksCopied:a.length,sourceTag:s||c?c||ge(o):null,description:l||`Tag created on ${new Date().toLocaleDateString()}`}}catch(e){throw u.error(`Error creating tag: ${e.message}`),e}}async function Yr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{yes:s=!1}=n,c=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Tag name is required and must be a string`);if(t===`master`)throw Error(`Cannot delete the "master" tag`);c.info(`Deleting tag: ${t}`);let n=E(e,o);if(!n)throw Error(`Could not read tasks file at ${e}`);let r;if(n._rawTaggedData)r=n._rawTaggedData;else if(n.tasks&&!n.master)r={master:{tasks:n.tasks,metadata:n.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks live here by default`}}};else{r={};for(let[e,t]of Object.entries(n))e!==`_rawTaggedData`&&e!==`tag`&&(r[e]=t)}if(!r[t])throw Error(`Tag "${t}" does not exist`);let a=ge(o)===t,l=pe(r,t).length;if(!s&&l>0&&i===`text`){if(console.log(W(B.yellow.bold(`⚠ WARNING: Tag Deletion`)+`\n\nYou are about to delete tag "${B.cyan(t)}"\nThis will permanently delete ${B.red.bold(l)} tasks
173
173
 
174
- This action cannot be undone!`,{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),!(await q.prompt([{type:`confirm`,name:`proceed`,message:`Are you sure you want to delete tag "${t}" and its ${l} tasks?`,default:!1}])).proceed)throw c.info(`Tag deletion cancelled by user`),Error(`Tag deletion cancelled`);if((await q.prompt([{type:`input`,name:`tagNameConfirm`,message:`To confirm deletion, please type the tag name "${t}":`,validate:e=>e===t?!0:`Please type exactly "${t}" to confirm deletion`}])).tagNameConfirm!==t)throw c.info(`Tag deletion cancelled - incorrect tag name confirmation`),Error(`Tag deletion cancelled`);c.info(`Double confirmation received, proceeding with deletion...`)}delete r[t],a&&(await $r(o,`master`),c.info(`Switched current tag to "master"`));let u={};for(let[e,t]of Object.entries(r))e!==`_rawTaggedData`&&(u[e]=t);return y(e,u,o),c.success(`Successfully deleted tag "${t}"`),i===`json`||i===`text`&&console.log(W(B.red.bold(`✓ Tag Deleted Successfully`)+`\n\nTag Name: ${B.cyan(t)}\nTasks Deleted: ${B.yellow(l)}`+(a?`\n${B.yellow(`⚠ Switched current tag to "master"`)}`:``),{padding:1,borderColor:`red`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tagName:t,deleted:!0,tasksDeleted:l,wasCurrentTag:a,switchedToMaster:a}}catch(e){throw c.error(`Error deleting tag: ${e.message}`),e}}async function Jr(e,t,n={}){let r=!1;try{let i;try{let t=V.statSync(e);i=t.birthtime<t.mtime?t.birthtime:t.mtime}catch{i=new Date}for(let[e,n]of Object.entries(t))e===`tasks`||e===`tag`||e===`_rawTaggedData`||!n||typeof n!=`object`||!Array.isArray(n.tasks)||(n.metadata||(n.metadata={},r=!0),n.metadata.created||(n.metadata.created=i.toISOString(),r=!0),n.metadata.description||(e===`master`?n.metadata.description=`Tasks live here by default`:n.metadata.description=`Tag created on ${new Date(n.metadata.created).toLocaleDateString()}`,r=!0),n.metadata.updated||(n.metadata.updated=n.metadata.created,r=!0));if(r){let r={};for(let[e,n]of Object.entries(t))e!==`_rawTaggedData`&&(r[e]=n);y(e,r,n.projectRoot)}}catch(e){(n.mcpLog||{warn:(...e)=>z(`warn`,...e)}).warn(`Could not enhance tag metadata: ${e.message}`)}return r}async function Yr(e,t={},n={},r=`text`){let{mcpLog:i,projectRoot:a}=n,{showTaskCounts:o=!0,showMetadata:c=!1,ready:l=!1}=t,u=i||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{u.info(`Listing available tags`);let t=await Vr({projectRoot:a,showMetadata:c,isMCP:!!i,outputFormat:r,report:(e,...t)=>{u[e]?u[e](...t):u.info(...t)}});if(t)return u.success(`Found ${t.totalTags} tags via API storage`),{tags:t.tags,currentTag:t.currentTag,totalTags:t.totalTags};u.info(`Using file storage for tags`);let d=D(e,a);if(!d)throw Error(`Could not read tasks file at ${e}`);let f=_e(a),p=d._rawTaggedData||d;await Jr(e,p,n);let m=[];for(let[e,t]of Object.entries(p)){if(e===`tasks`||e===`tag`||e===`_rawTaggedData`||!t||typeof t!=`object`||!Array.isArray(t.tasks))continue;let n=t.tasks||[],r=t.metadata||{},i=N(n.map(e=>({...e,blocks:[]})));m.push({name:e,isCurrent:e===f,completedTasks:n.filter(e=>We(e.status)).length,readyTasks:i.length,tasks:n||[],created:r.created||`Unknown`,description:r.description||`No description`})}m.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:e.name.localeCompare(t.name));let h=m;if(l&&(h=m.filter(e=>e.readyTasks>0),u.info(`Filtered to ${h.length} tags with ready tasks`)),u.success(`Found ${h.length} tags`),r===`json`)return{tags:h,currentTag:f,totalTags:h.length};if(r===`text`){if(h.length===0){let e=l?`No tags with ready tasks found`:`No tags found`;return console.log(W(B.yellow(e),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tags:[],currentTag:f,totalTags:0}}let e=[B.cyan.bold(`Tag Name`)];o&&(e.push(B.cyan.bold(`Tasks`)),e.push(B.cyan.bold(`Ready`)),e.push(B.cyan.bold(`Done`))),c&&(e.push(B.cyan.bold(`Created`)),e.push(B.cyan.bold(`Description`)));let t=Math.max(process.stdout.columns||120,80),n=Math.floor(t*.95),r;r=c?[.22,.08,.08,.08,.14,.38].map((e,t)=>Math.max(Math.floor(n*e),t===0?15:6)):[.6,.13,.13,.13].map((e,t)=>Math.max(Math.floor(n*e),t===0?20:8));let i=new K({head:e,colWidths:r,wordWrap:!0});h.forEach(e=>{let t=[],n=e.isCurrent?`${B.green(`●`)} ${B.green.bold(e.name)} ${B.gray(`(current)`)}`:` ${e.name}`;if(t.push(n),o&&(t.push(B.white(e.tasks.length.toString())),t.push(e.readyTasks>0?B.yellow(e.readyTasks.toString()):B.gray(`0`)),t.push(B.green(e.completedTasks.toString()))),c){let n=e.created===`Unknown`?`Unknown`:new Date(e.created).toLocaleDateString();t.push(B.gray(n)),t.push(B.gray(s(e.description,50)))}i.push(t)}),console.log(i.toString())}return{tags:h,currentTag:f,totalTags:h.length}}catch(e){throw u.error(`Error listing tags: ${e.message}`),e}}async function Xr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,s=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Tag name is required and must be a string`);s.info(`Switching to tag: ${t}`);let n=await Hr({tagName:t,projectRoot:o,isMCP:!!a,outputFormat:i,report:(e,...t)=>{s[e]?s[e](...t):s.info(...t)}});if(n)return s.success(`Successfully switched to tag "${t}" via API storage`),n;s.info(`Using file storage for tag switch`);let r=D(e,o);if(!r)throw Error(`Could not read tasks file at ${e}`);if(!(r._rawTaggedData||r)[t])throw Error(`Tag "${t}" does not exist`);let c=_e(o);await $r(o,t);let l=D(e,o,t),u=l&&l.tasks||[],d=u.length,f=Gr(u);if(s.success(`Successfully switched to tag "${t}"`),i===`json`)return{previousTag:c,currentTag:t,switched:!0,taskCount:d,nextTask:f};if(i===`text`){let e=``;e=f?`\nNext Task: ${B.cyan(`#${f.id}`)} - ${B.white(f.title)}`:`\nNext Task: ${B.gray(`No eligible tasks available`)}`,console.log(W(B.green.bold(`✓ Tag Switched Successfully`)+`\n\nPrevious Tag: ${B.cyan(c)}\nCurrent Tag: ${B.green.bold(t)}\nAvailable Tasks: ${B.yellow(d)}`+e,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))}return{previousTag:c,currentTag:t,switched:!0,taskCount:d,nextTask:f}}catch(e){throw s.error(`Error switching tag: ${e.message}`),e}}async function Zr(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,c=o||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Old tag name is required and must be a string`);if(!n||typeof n!=`string`)throw Error(`New tag name is required and must be a string`);if(!/^[a-zA-Z0-9_-]+$/.test(n))throw Error(`New tag name can only contain letters, numbers, hyphens, and underscores`);if(t===`master`)throw Error(`Cannot rename the "master" tag`);if([`master`,`main`,`default`].includes(n.toLowerCase()))throw Error(`"${n}" is a reserved tag name`);c.info(`Renaming tag from "${t}" to "${n}"`);let r=D(e,s);if(!r)throw Error(`Could not read tasks file at ${e}`);let i=r._rawTaggedData||r;if(!i[t])throw Error(`Tag "${t}" does not exist`);if(i[n])throw Error(`Tag "${n}" already exists`);let o=_e(s)===t;i[n]={...i[t]},i[n].metadata&&(i[n].metadata.renamed={from:t,date:new Date().toISOString()}),delete i[t],o&&(await $r(s,n),c.info(`Updated current tag reference to "${n}"`));let l={};for(let[e,t]of Object.entries(i))e!==`_rawTaggedData`&&(l[e]=t);y(e,l,s);let u=me(i,n).length;return c.success(`Successfully renamed tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(W(B.green.bold(`✓ Tag Renamed Successfully`)+`\n\nOld Name: ${B.cyan(t)}\nNew Name: ${B.green.bold(n)}\nTasks: ${B.yellow(u)}`+(o?`\n${B.green(`✓ Current tag updated`)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{oldName:t,newName:n,renamed:!0,taskCount:u,wasCurrentTag:o,isCurrentTag:o}}catch(e){throw c.error(`Error renaming tag: ${e.message}`),e}}async function Qr(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,{description:c}=r,l=o||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Source tag name is required and must be a string`);if(!n||typeof n!=`string`)throw Error(`Target tag name is required and must be a string`);if(!/^[a-zA-Z0-9_-]+$/.test(n))throw Error(`Target tag name can only contain letters, numbers, hyphens, and underscores`);if([`master`,`main`,`default`].includes(n.toLowerCase()))throw Error(`"${n}" is a reserved tag name`);l.info(`Copying tag from "${t}" to "${n}"`);let r=D(e,s);if(!r)throw Error(`Could not read tasks file at ${e}`);let i=r._rawTaggedData||r;if(!i[t])throw Error(`Source tag "${t}" does not exist`);if(i[n])throw Error(`Target tag "${n}" already exists`);let o=me(i,t);i[n]={tasks:JSON.parse(JSON.stringify(o)),metadata:{created:new Date().toISOString(),updated:new Date().toISOString(),description:c||`Copy of "${t}" created on ${new Date().toLocaleDateString()}`,copiedFrom:{tag:t,date:new Date().toISOString()}}};let u={};for(let[e,t]of Object.entries(i))e!==`_rawTaggedData`&&(u[e]=t);return y(e,u,s),l.success(`Successfully copied tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(W(B.green.bold(`✓ Tag Copied Successfully`)+`\n\nSource Tag: ${B.cyan(t)}\nTarget Tag: ${B.green.bold(n)}\nTasks Copied: ${B.yellow(o.length)}`+(c?`\nDescription: ${B.gray(c)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{sourceName:t,targetName:n,copied:!0,description:c||`Copy of "${t}" created on ${new Date().toLocaleDateString()}`}}catch(e){throw l.error(`Error copying tag: ${e.message}`),e}}async function $r(e,t){try{let n=H.join(e,`.taskmaster`,`state.json`),r={};if(V.existsSync(n)){let e=V.readFileSync(n,`utf8`);r=JSON.parse(e)}r.currentTag=t,r.lastSwitched=new Date().toISOString(),r.branchTagMapping||={},r.migrationNoticeShown===void 0&&(r.migrationNoticeShown=!1),V.writeFileSync(n,JSON.stringify(r,null,2),`utf8`)}catch(e){z(`warn`,`Could not update current tag in state.json: ${e.message}`)}}async function ei(e,t,n){try{let r=H.join(e,`.taskmaster`,`state.json`),i={};if(V.existsSync(r)){let e=V.readFileSync(r,`utf8`);i=JSON.parse(e)}i.branchTagMapping||={},i.branchTagMapping[t]=n,V.writeFileSync(r,JSON.stringify(i,null,2),`utf8`)}catch(e){z(`warn`,`Could not update branch-tag mapping: ${e.message}`)}}async function ti(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{copyFromCurrent:s,copyFromTag:c,description:l,autoSwitch:u}=n,{sanitizeBranchNameForTag:d,isValidBranchForTag:f}=await import(`./git-utils-PBP1PRVP.js`),p=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Branch name is required and must be a string`);if(!f(t))throw Error(`Branch "${t}" cannot be converted to a valid tag name`);let n=d(t);p.info(`Creating tag "${n}" from git branch "${t}"`);let a=await Kr(e,n,{copyFromCurrent:s,copyFromTag:c,description:l||`Tag created from git branch "${t}"`},r,i);return await ei(o,t,n),p.info(`Updated branch-tag mapping: ${t} -> ${n}`),u&&(await $r(o,n),p.info(`Automatically switched to tag "${n}"`)),i===`json`?{...a,branchName:t,tagName:n,mappingUpdated:!0,autoSwitched:u||!1}:{branchName:t,tagName:n,created:!0,mappingUpdated:!0,autoSwitched:u||!1}}catch(e){throw p.error(`Error creating tag from branch: ${e.message}`),e}}var ni=class e extends G{tmCore;lastResult;throwOnError=!1;constructor(e){super(e||`tags`),this.description(`Manage tags for task organization`).option(`--show-metadata`,`Show additional tag metadata`).option(`--ready`,`Show only tags with ready tasks available`),this.addListCommand(),this.addAddCommand(),this.addUseCommand(),this.addRemoveCommand(),this.addRenameCommand(),this.addCopyCommand(),this.action(async e=>{await this.executeList(e)})}addListCommand(){this.command(`list`).description(`List all tags with statistics (default action)`).option(`--show-metadata`,`Show additional tag metadata`).option(`--ready`,`Show only tags with ready tasks available`).addHelpText(`after`,`
174
+ This action cannot be undone!`,{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),!(await q.prompt([{type:`confirm`,name:`proceed`,message:`Are you sure you want to delete tag "${t}" and its ${l} tasks?`,default:!1}])).proceed)throw c.info(`Tag deletion cancelled by user`),Error(`Tag deletion cancelled`);if((await q.prompt([{type:`input`,name:`tagNameConfirm`,message:`To confirm deletion, please type the tag name "${t}":`,validate:e=>e===t?!0:`Please type exactly "${t}" to confirm deletion`}])).tagNameConfirm!==t)throw c.info(`Tag deletion cancelled - incorrect tag name confirmation`),Error(`Tag deletion cancelled`);c.info(`Double confirmation received, proceeding with deletion...`)}delete r[t],a&&(await ti(o,`master`),c.info(`Switched current tag to "master"`));let u={};for(let[e,t]of Object.entries(r))e!==`_rawTaggedData`&&(u[e]=t);return y(e,u,o),c.success(`Successfully deleted tag "${t}"`),i===`json`||i===`text`&&console.log(W(B.red.bold(`✓ Tag Deleted Successfully`)+`\n\nTag Name: ${B.cyan(t)}\nTasks Deleted: ${B.yellow(l)}`+(a?`\n${B.yellow(`⚠ Switched current tag to "master"`)}`:``),{padding:1,borderColor:`red`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tagName:t,deleted:!0,tasksDeleted:l,wasCurrentTag:a,switchedToMaster:a}}catch(e){throw c.error(`Error deleting tag: ${e.message}`),e}}async function Xr(e,t,n={}){let r=!1;try{let i;try{let t=V.statSync(e);i=t.birthtime<t.mtime?t.birthtime:t.mtime}catch{i=new Date}for(let[e,n]of Object.entries(t))e===`tasks`||e===`tag`||e===`_rawTaggedData`||!n||typeof n!=`object`||!Array.isArray(n.tasks)||(n.metadata||(n.metadata={},r=!0),n.metadata.created||(n.metadata.created=i.toISOString(),r=!0),n.metadata.description||(e===`master`?n.metadata.description=`Tasks live here by default`:n.metadata.description=`Tag created on ${new Date(n.metadata.created).toLocaleDateString()}`,r=!0),n.metadata.updated||(n.metadata.updated=n.metadata.created,r=!0));if(r){let r={};for(let[e,n]of Object.entries(t))e!==`_rawTaggedData`&&(r[e]=n);y(e,r,n.projectRoot)}}catch(e){(n.mcpLog||{warn:(...e)=>z(`warn`,...e)}).warn(`Could not enhance tag metadata: ${e.message}`)}return r}async function Zr(e,t={},n={},r=`text`){let{mcpLog:i,projectRoot:a}=n,{showTaskCounts:o=!0,showMetadata:c=!1,ready:l=!1}=t,u=i||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{u.info(`Listing available tags`);let t=await Ur({projectRoot:a,showMetadata:c,isMCP:!!i,outputFormat:r,report:(e,...t)=>{u[e]?u[e](...t):u.info(...t)}});if(t)return u.success(`Found ${t.totalTags} tags via API storage`),{tags:t.tags,currentTag:t.currentTag,totalTags:t.totalTags};u.info(`Using file storage for tags`);let d=E(e,a);if(!d)throw Error(`Could not read tasks file at ${e}`);let f=ge(a),p=d._rawTaggedData||d;await Xr(e,p,n);let m=[];for(let[e,t]of Object.entries(p)){if(e===`tasks`||e===`tag`||e===`_rawTaggedData`||!t||typeof t!=`object`||!Array.isArray(t.tasks))continue;let n=t.tasks||[],r=t.metadata||{},i=M(n.map(e=>({...e,blocks:[]})));m.push({name:e,isCurrent:e===f,completedTasks:n.filter(e=>Ue(e.status)).length,readyTasks:i.length,tasks:n||[],created:r.created||`Unknown`,description:r.description||`No description`})}m.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:e.name.localeCompare(t.name));let h=m;if(l&&(h=m.filter(e=>e.readyTasks>0),u.info(`Filtered to ${h.length} tags with ready tasks`)),u.success(`Found ${h.length} tags`),r===`json`)return{tags:h,currentTag:f,totalTags:h.length};if(r===`text`){if(h.length===0){let e=l?`No tags with ready tasks found`:`No tags found`;return console.log(W(B.yellow(e),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tags:[],currentTag:f,totalTags:0}}let e=[B.cyan.bold(`Tag Name`)];o&&(e.push(B.cyan.bold(`Tasks`)),e.push(B.cyan.bold(`Ready`)),e.push(B.cyan.bold(`Done`))),c&&(e.push(B.cyan.bold(`Created`)),e.push(B.cyan.bold(`Description`)));let t=Math.max(process.stdout.columns||120,80),n=Math.floor(t*.95),r;r=c?[.22,.08,.08,.08,.14,.38].map((e,t)=>Math.max(Math.floor(n*e),t===0?15:6)):[.6,.13,.13,.13].map((e,t)=>Math.max(Math.floor(n*e),t===0?20:8));let i=new K({head:e,colWidths:r,wordWrap:!0});h.forEach(e=>{let t=[],n=e.isCurrent?`${B.green(`●`)} ${B.green.bold(e.name)} ${B.gray(`(current)`)}`:` ${e.name}`;if(t.push(n),o&&(t.push(B.white(e.tasks.length.toString())),t.push(e.readyTasks>0?B.yellow(e.readyTasks.toString()):B.gray(`0`)),t.push(B.green(e.completedTasks.toString()))),c){let n=e.created===`Unknown`?`Unknown`:new Date(e.created).toLocaleDateString();t.push(B.gray(n)),t.push(B.gray(s(e.description,50)))}i.push(t)}),console.log(i.toString())}return{tags:h,currentTag:f,totalTags:h.length}}catch(e){throw u.error(`Error listing tags: ${e.message}`),e}}async function Qr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,s=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Tag name is required and must be a string`);s.info(`Switching to tag: ${t}`);let n=await Wr({tagName:t,projectRoot:o,isMCP:!!a,outputFormat:i,report:(e,...t)=>{s[e]?s[e](...t):s.info(...t)}});if(n)return s.success(`Successfully switched to tag "${t}" via API storage`),n;s.info(`Using file storage for tag switch`);let r=E(e,o);if(!r)throw Error(`Could not read tasks file at ${e}`);if(!(r._rawTaggedData||r)[t])throw Error(`Tag "${t}" does not exist`);let c=ge(o);await ti(o,t);let l=E(e,o,t),u=l&&l.tasks||[],d=u.length,f=qr(u);if(s.success(`Successfully switched to tag "${t}"`),i===`json`)return{previousTag:c,currentTag:t,switched:!0,taskCount:d,nextTask:f};if(i===`text`){let e=``;e=f?`\nNext Task: ${B.cyan(`#${f.id}`)} - ${B.white(f.title)}`:`\nNext Task: ${B.gray(`No eligible tasks available`)}`,console.log(W(B.green.bold(`✓ Tag Switched Successfully`)+`\n\nPrevious Tag: ${B.cyan(c)}\nCurrent Tag: ${B.green.bold(t)}\nAvailable Tasks: ${B.yellow(d)}`+e,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))}return{previousTag:c,currentTag:t,switched:!0,taskCount:d,nextTask:f}}catch(e){throw s.error(`Error switching tag: ${e.message}`),e}}async function $r(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,c=o||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Old tag name is required and must be a string`);if(!n||typeof n!=`string`)throw Error(`New tag name is required and must be a string`);if(!/^[a-zA-Z0-9_-]+$/.test(n))throw Error(`New tag name can only contain letters, numbers, hyphens, and underscores`);if(t===`master`)throw Error(`Cannot rename the "master" tag`);if([`master`,`main`,`default`].includes(n.toLowerCase()))throw Error(`"${n}" is a reserved tag name`);c.info(`Renaming tag from "${t}" to "${n}"`);let r=E(e,s);if(!r)throw Error(`Could not read tasks file at ${e}`);let i=r._rawTaggedData||r;if(!i[t])throw Error(`Tag "${t}" does not exist`);if(i[n])throw Error(`Tag "${n}" already exists`);let o=ge(s)===t;i[n]={...i[t]},i[n].metadata&&(i[n].metadata.renamed={from:t,date:new Date().toISOString()}),delete i[t],o&&(await ti(s,n),c.info(`Updated current tag reference to "${n}"`));let l={};for(let[e,t]of Object.entries(i))e!==`_rawTaggedData`&&(l[e]=t);y(e,l,s);let u=pe(i,n).length;return c.success(`Successfully renamed tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(W(B.green.bold(`✓ Tag Renamed Successfully`)+`\n\nOld Name: ${B.cyan(t)}\nNew Name: ${B.green.bold(n)}\nTasks: ${B.yellow(u)}`+(o?`\n${B.green(`✓ Current tag updated`)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{oldName:t,newName:n,renamed:!0,taskCount:u,wasCurrentTag:o,isCurrentTag:o}}catch(e){throw c.error(`Error renaming tag: ${e.message}`),e}}async function ei(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,{description:c}=r,l=o||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Source tag name is required and must be a string`);if(!n||typeof n!=`string`)throw Error(`Target tag name is required and must be a string`);if(!/^[a-zA-Z0-9_-]+$/.test(n))throw Error(`Target tag name can only contain letters, numbers, hyphens, and underscores`);if([`master`,`main`,`default`].includes(n.toLowerCase()))throw Error(`"${n}" is a reserved tag name`);l.info(`Copying tag from "${t}" to "${n}"`);let r=E(e,s);if(!r)throw Error(`Could not read tasks file at ${e}`);let i=r._rawTaggedData||r;if(!i[t])throw Error(`Source tag "${t}" does not exist`);if(i[n])throw Error(`Target tag "${n}" already exists`);let o=pe(i,t);i[n]={tasks:JSON.parse(JSON.stringify(o)),metadata:{created:new Date().toISOString(),updated:new Date().toISOString(),description:c||`Copy of "${t}" created on ${new Date().toLocaleDateString()}`,copiedFrom:{tag:t,date:new Date().toISOString()}}};let u={};for(let[e,t]of Object.entries(i))e!==`_rawTaggedData`&&(u[e]=t);return y(e,u,s),l.success(`Successfully copied tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(W(B.green.bold(`✓ Tag Copied Successfully`)+`\n\nSource Tag: ${B.cyan(t)}\nTarget Tag: ${B.green.bold(n)}\nTasks Copied: ${B.yellow(o.length)}`+(c?`\nDescription: ${B.gray(c)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{sourceName:t,targetName:n,copied:!0,description:c||`Copy of "${t}" created on ${new Date().toLocaleDateString()}`}}catch(e){throw l.error(`Error copying tag: ${e.message}`),e}}async function ti(e,t){try{let n=H.join(e,`.taskmaster`,`state.json`),r={};if(V.existsSync(n)){let e=V.readFileSync(n,`utf8`);r=JSON.parse(e)}r.currentTag=t,r.lastSwitched=new Date().toISOString(),r.branchTagMapping||={},r.migrationNoticeShown===void 0&&(r.migrationNoticeShown=!1),V.writeFileSync(n,JSON.stringify(r,null,2),`utf8`)}catch(e){z(`warn`,`Could not update current tag in state.json: ${e.message}`)}}async function ni(e,t,n){try{let r=H.join(e,`.taskmaster`,`state.json`),i={};if(V.existsSync(r)){let e=V.readFileSync(r,`utf8`);i=JSON.parse(e)}i.branchTagMapping||={},i.branchTagMapping[t]=n,V.writeFileSync(r,JSON.stringify(i,null,2),`utf8`)}catch(e){z(`warn`,`Could not update branch-tag mapping: ${e.message}`)}}async function ri(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{copyFromCurrent:s,copyFromTag:c,description:l,autoSwitch:u}=n,{sanitizeBranchNameForTag:d,isValidBranchForTag:f}=await import(`./git-utils-PBP1PRVP.js`),p=a||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};try{if(!t||typeof t!=`string`)throw Error(`Branch name is required and must be a string`);if(!f(t))throw Error(`Branch "${t}" cannot be converted to a valid tag name`);let n=d(t);p.info(`Creating tag "${n}" from git branch "${t}"`);let a=await Jr(e,n,{copyFromCurrent:s,copyFromTag:c,description:l||`Tag created from git branch "${t}"`},r,i);return await ni(o,t,n),p.info(`Updated branch-tag mapping: ${t} -> ${n}`),u&&(await ti(o,n),p.info(`Automatically switched to tag "${n}"`)),i===`json`?{...a,branchName:t,tagName:n,mappingUpdated:!0,autoSwitched:u||!1}:{branchName:t,tagName:n,created:!0,mappingUpdated:!0,autoSwitched:u||!1}}catch(e){throw p.error(`Error creating tag from branch: ${e.message}`),e}}var ii=class e extends G{tmCore;lastResult;throwOnError=!1;constructor(e){super(e||`tags`),this.description(`Manage tags for task organization`).option(`--show-metadata`,`Show additional tag metadata`).option(`--ready`,`Show only tags with ready tasks available`),this.addListCommand(),this.addAddCommand(),this.addUseCommand(),this.addRemoveCommand(),this.addRenameCommand(),this.addCopyCommand(),this.action(async e=>{await this.executeList(e)})}addListCommand(){this.command(`list`).description(`List all tags with statistics (default action)`).option(`--show-metadata`,`Show additional tag metadata`).option(`--ready`,`Show only tags with ready tasks available`).addHelpText(`after`,`
175
175
  Examples:
176
176
  $ tm tags # List all tags (default)
177
177
  $ tm tags list # List all tags (explicit)
@@ -203,7 +203,7 @@ Examples:
203
203
  Examples:
204
204
  $ tm tags copy sprint-1 sprint-2
205
205
  $ tm tags copy sprint-1 sprint-2 --description "Next sprint tasks"
206
- `).action(async(e,t,n)=>{await this.executeCopy(e,t,n)})}async initTmCore(){this.tmCore||=await I({projectPath:process.cwd()})}async executeList(e){try{await this.initTmCore();let{projectRoot:t,tasksPath:n}=Ie(),r=await Yr(n,{showTaskCounts:!0,showMetadata:e?.showMetadata||!1,ready:e?.ready||!1},{projectRoot:t},`text`);this.setLastResult({success:!0,action:`list`,tags:r.tags,currentTag:r.currentTag,message:`Found ${r.totalTags} tag(s)`})}catch(e){X(e),this.setLastResult({success:!1,action:`list`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeAdd(e,t){try{await this.initTmCore();let{projectRoot:n,tasksPath:r}=Ie();await Kr(r,e,{description:t?.description,copyFromTag:t?.copyFrom,fromBranch:t?.fromBranch},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`add`,message:`Created tag: ${e}`})}catch(e){X(e),this.setLastResult({success:!1,action:`add`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeUse(e){try{await this.initTmCore();let{projectRoot:t,tasksPath:n}=Ie(),r=await Xr(n,e,{},{projectRoot:t},`text`);this.setLastResult({success:!0,action:`use`,currentTag:r.currentTag,message:`Switched to tag: ${e}`})}catch(e){X(e),this.setLastResult({success:!1,action:`use`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeRemove(e,t){try{await this.initTmCore();let{projectRoot:n,tasksPath:r}=Ie();await qr(r,e,{yes:t?.yes||!1},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`remove`,message:`Removed tag: ${e}`})}catch(e){X(e),this.setLastResult({success:!1,action:`remove`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeRename(e,t){try{await this.initTmCore();let{projectRoot:n,tasksPath:r}=Ie();await Zr(r,e,t,{},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`rename`,message:`Renamed tag from "${e}" to "${t}"`})}catch(e){X(e),this.setLastResult({success:!1,action:`rename`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeCopy(e,t,n){try{await this.initTmCore();let{projectRoot:r,tasksPath:i}=Ie();await Qr(i,e,t,{description:n?.description},{projectRoot:r},`text`),this.setLastResult({success:!0,action:`copy`,message:`Copied tag from "${e}" to "${t}"`})}catch(e){X(e),this.setLastResult({success:!1,action:`copy`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}setThrowOnError(e){return this.throwOnError=e,this}handleError(e){if(this.throwOnError)throw e;process.exit(1)}static register(t,n){let r=new e(n);return t.addCommand(r),r}},ri=class e extends G{tmCore;authManager;lastResult;constructor(e){super(e||`briefs`),this.authManager=ge.getInstance(),this.description(`Manage briefs (API storage only)`),this.alias(`brief`),this.addListCommand(),this.addSelectCommand(),this.addCreateCommand(),this.argument(`[briefOrUrl]`,`Brief ID or Hamster brief URL`),this.action(async e=>{if(e&&e.trim().length>0){await this.executeSelectFromUrl(e.trim());return}await this.executeList()})}async checkAuth(){return qn(this.authManager,{message:`The "briefs" command requires you to be logged in to your Hamster account.`,footer:`Working locally instead?
206
+ `).action(async(e,t,n)=>{await this.executeCopy(e,t,n)})}async initTmCore(){this.tmCore||=await I({projectPath:process.cwd()})}async executeList(e){try{await this.initTmCore();let{projectRoot:t,tasksPath:n}=Pe(),r=await Zr(n,{showTaskCounts:!0,showMetadata:e?.showMetadata||!1,ready:e?.ready||!1},{projectRoot:t},`text`);this.setLastResult({success:!0,action:`list`,tags:r.tags,currentTag:r.currentTag,message:`Found ${r.totalTags} tag(s)`})}catch(e){X(e),this.setLastResult({success:!1,action:`list`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeAdd(e,t){try{await this.initTmCore();let{projectRoot:n,tasksPath:r}=Pe();await Jr(r,e,{description:t?.description,copyFromTag:t?.copyFrom,fromBranch:t?.fromBranch},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`add`,message:`Created tag: ${e}`})}catch(e){X(e),this.setLastResult({success:!1,action:`add`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeUse(e){try{await this.initTmCore();let{projectRoot:t,tasksPath:n}=Pe(),r=await Qr(n,e,{},{projectRoot:t},`text`);this.setLastResult({success:!0,action:`use`,currentTag:r.currentTag,message:`Switched to tag: ${e}`})}catch(e){X(e),this.setLastResult({success:!1,action:`use`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeRemove(e,t){try{await this.initTmCore();let{projectRoot:n,tasksPath:r}=Pe();await Yr(r,e,{yes:t?.yes||!1},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`remove`,message:`Removed tag: ${e}`})}catch(e){X(e),this.setLastResult({success:!1,action:`remove`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeRename(e,t){try{await this.initTmCore();let{projectRoot:n,tasksPath:r}=Pe();await $r(r,e,t,{},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`rename`,message:`Renamed tag from "${e}" to "${t}"`})}catch(e){X(e),this.setLastResult({success:!1,action:`rename`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}async executeCopy(e,t,n){try{await this.initTmCore();let{projectRoot:r,tasksPath:i}=Pe();await ei(i,e,t,{description:n?.description},{projectRoot:r},`text`),this.setLastResult({success:!0,action:`copy`,message:`Copied tag from "${e}" to "${t}"`})}catch(e){X(e),this.setLastResult({success:!1,action:`copy`,message:e.message}),this.handleError(e instanceof Error?e:Error(e.message||String(e)))}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}setThrowOnError(e){return this.throwOnError=e,this}handleError(e){if(this.throwOnError)throw e;process.exit(1)}static register(t,n){let r=new e(n);return t.addCommand(r),r}},ai=class e extends G{tmCore;authManager;lastResult;constructor(e){super(e||`briefs`),this.authManager=he.getInstance(),this.description(`Manage briefs (API storage only)`),this.alias(`brief`),this.addListCommand(),this.addSelectCommand(),this.addCreateCommand(),this.argument(`[briefOrUrl]`,`Brief ID or Hamster brief URL`),this.action(async e=>{if(e&&e.trim().length>0){await this.executeSelectFromUrl(e.trim());return}await this.executeList()})}async checkAuth(){return Yn(this.authManager,{message:`The "briefs" command requires you to be logged in to your Hamster account.`,footer:`Working locally instead?
207
207
  → Use "task-master tags" for local tag management.`,authCommand:`task-master auth login`})}addListCommand(){this.command(`list`).description(`List all briefs (default action)`).option(`--show-metadata`,`Show additional brief metadata`).addHelpText(`after`,`
208
208
  Examples:
209
209
  $ tm briefs # List all briefs (default)
@@ -228,27 +228,27 @@ Examples:
228
228
  $ tm briefs create my-new-brief # Redirect with suggested name
229
229
 
230
230
  Note: Briefs must be created through the Hamster Studio web interface.
231
- `).action(async e=>{await this.executeCreate(e)})}async initTmCore(){this.tmCore||=await I({projectPath:process.cwd()})}async executeList(e){try{await this.checkAuth()||process.exit(1);let t=await this.ensureOrgSelectedLocal();t||process.exit(1);let n=J(`Fetching briefs...`).start(),r=await this.authManager.getBriefs(t);n.stop();let i=this.authManager.getContext()?.briefId,a=r.map(e=>({name:e.document?.title||`Brief ${e.id.slice(-8)}`,isCurrent:e.id===i,taskCount:e.taskCount||0,completedTasks:0,statusBreakdown:{},created:e.createdAt,description:e.document?.description,status:e.status,briefId:e.id,updatedAt:e.updatedAt}));a.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:0),this.setLastResult({success:!0,action:`list`,briefs:a,currentBrief:i||null,message:`Found ${a.length} brief(s)`}),process.stdout.isTTY&&a.length>0?await this.promptBriefSelection(a):a.length===0?On(`No briefs found in this organization`):this.displayBriefsTable(a,e?.showMetadata)}catch(e){Y(`Failed to list briefs: ${e.message}`),this.setLastResult({success:!1,action:`list`,message:e.message}),process.exit(1)}}async ensureOrgSelectedLocal(){let e=await Xn(this.authManager);return e.success&&e.orgId||null}displayBriefsTable(e,t){let r=n(`cli-table3`),i=Math.max(process.stdout.columns||120,80),a=Math.floor(i*.95),o=[.35,.25,.2,.1,.1].map((e,t)=>Math.max(Math.floor(a*e),t===0?20:8)),s=new r({head:[B.cyan.bold(`Brief Name`),B.cyan.bold(`Status`),B.cyan.bold(`Updated`),B.cyan.bold(`Tasks`),B.cyan.bold(`Completed`)],colWidths:o,wordWrap:!0});e.forEach(e=>{let t=e.briefId?e.briefId.slice(-8):`unknown`,n=e.isCurrent?`${B.green(`●`)} ${B.green.bold(e.name)} ${B.gray(`(current - ${t})`)}`:` ${e.name} ${B.gray(`(${t})`)}`,r=e.updatedAt?new Date(e.updatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`}):B.gray(`N/A`);s.push([n,vn(e.status,!0),B.gray(r),B.white(String(e.taskCount||0)),B.green(String(e.completedTasks||0))])}),console.log(s.toString())}formatBriefAsTableRow(e,t){let n=e.briefId?e.briefId.slice(-8):`unknown`,r=e.isCurrent,i=r?B.green(`●`):` `,a=r?`(current)`:`(${n})`,o=t.name-4-a.length,s=e.name;s.length>o&&(s=s.substring(0,o-1)+`…`);let c=r?B.green.bold(s):s,l=r?B.gray(`(current)`):B.gray(`(${n})`),u=2+s.length+1+a.length,d=Math.max(0,t.name-u),f=`${i} ${c} ${l}${` `.repeat(d)}`,p=vn(e.status,!0),m=(e.status||`unknown`).length+2,h=Math.max(0,t.status-m),g=`${p}${` `.repeat(h)}`,_=e.updatedAt?new Date(e.updatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`}):`N/A`;return`${f} ${g} ${B.gray(_.padEnd(t.updated))} ${B.white(String(e.taskCount||0).padStart(t.tasks))} ${B.green(String(e.completedTasks||0).padStart(t.done))}`}async promptBriefSelection(e){try{if(!this.authManager.getContext()?.orgId)return;let t=Math.max(process.stdout.columns||120,80),n=Math.floor(t*.95),r={name:Math.floor(n*.42),status:Math.floor(n*.14),updated:Math.floor(n*.16),tasks:6,done:6},i=B.cyan.bold(`Brief Name`.padEnd(r.name))+B.cyan.bold(`Status`.padEnd(r.status))+B.cyan.bold(`Updated`.padEnd(r.updated))+B.cyan.bold(`Tasks`.padStart(r.tasks+2))+B.cyan.bold(`Done`.padStart(r.done+2)),a=B.gray(`─`.repeat(n)),o=[new q.Separator(i),new q.Separator(a)];e.forEach(e=>{o.push({name:this.formatBriefAsTableRow(e,r),value:e.briefId||e.name,short:e.name})}),o.push(new q.Separator(a)),o.push({name:B.dim(` (Cancel - keep current selection)`),value:null,short:`Cancelled`});let s=!1,c=(e,t)=>{t&&t.name===`escape`&&(s=!0,process.stdin.emit(`keypress`,``,{name:`c`,ctrl:!0}))};process.stdin.isTTY&&(nt.emitKeypressEvents(process.stdin),process.stdin.on(`keypress`,c));let l;try{l=await q.prompt([{type:`list`,name:`selectedBrief`,message:`Select a brief:`,choices:o,pageSize:Math.min(e.length+5,20),loop:!1}])}finally{process.stdin.isTTY&&process.stdin.removeListener(`keypress`,c)}if(s)return;if(l.selectedBrief&&l.selectedBrief!==null){let t=e.find(e=>e.briefId===l.selectedBrief||e.name===l.selectedBrief);t&&(await this.authManager.updateContext({briefId:t.briefId||void 0,briefName:t.name,briefStatus:t.status||void 0,briefUpdatedAt:t.updatedAt||void 0}),Dn(`Selected brief: ${t.name}`),this.setLastResult({success:!0,action:`select`,currentBrief:t.briefId||t.name,message:`Selected brief: ${t.name}`}))}}catch(e){if(e.isTtyError)return;console.error(B.yellow(`\nNote: Could not prompt for brief selection: ${e.message}`))}}async executeSelect(e){try{if(await this.authManager.hasValidSession()||(Y(`Not authenticated. Run "tm auth login" first.`),process.exit(1)),e&&e.trim().length>0){await this.executeSelectFromUrl(e.trim());return}let t=this.authManager.getContext();t?.orgId||(En(`No organization selected. Run "tm context org" first.`),process.exit(1));let n=await Jn(this.authManager,t.orgId);this.setLastResult({success:n.success,action:`select`,currentBrief:n.briefId,message:n.message}),n.success||process.exit(1)}catch(e){En(`Failed to select brief: ${e.message}`),this.setLastResult({success:!1,action:`select`,message:e.message}),process.exit(1)}}async executeSelectFromUrl(e){try{await this.authManager.hasValidSession()||(Y(`Not authenticated. Run "tm auth login" first.`),process.exit(1)),await this.initTmCore();let t=await Yn(this.authManager,e,this.tmCore);this.setLastResult({success:t.success,action:`select`,currentBrief:t.briefId,message:t.message}),t.success||process.exit(1)}catch(e){En(`Failed to select brief: ${e.message}`),this.setLastResult({success:!1,action:`select`,message:e.message}),process.exit(1)}}async executeCreate(e){try{await this.checkAuth()||process.exit(1);let t=await Ur({tagName:e||`new-brief`,projectRoot:process.cwd(),report:(e,...t)=>{let n=t[0];e===`error`?Y(n):e===`warn`?On(n):e===`info`&&kn(n)}});if(!t)throw Error(`Failed to get brief creation URL`);this.setLastResult({success:t.success,action:`create`,message:t.message}),t.success||process.exit(1)}catch(e){En(`Failed to create brief: ${e.message}`),this.setLastResult({success:!1,action:`create`,message:e.message}),process.exit(1)}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}static register(t,n){let r=new e(n);return t.addCommand(r),r}},ii=class e extends G{tmCore;constructor(e){super(e||`loop`),this.description(`Run coding agent CLI in a loop, one task per iteration`).option(`-n, --iterations <number>`,`Maximum iterations`).option(`-p, --prompt <preset|path>`,`Preset name (${Re.join(`, `)}) or path to custom prompt file`,`default`).option(`--progress-file <path>`,`Path to progress log file`,`.taskmaster/progress.txt`).option(`-t, --tag <tag>`,`Only work on tasks with this tag`).option(`--project <path>`,`Project root directory (auto-detected if not provided)`).option(`--sandbox`,`Enable sandbox mode (Docker for Claude, native sandbox for Codex)`).option(`-e, --executor <executor>`,`Execution backend (claude|codex)`).option(`--no-output`,`Exclude full executor output from iteration results`).option(`-v, --verbose`,`Show executor's work in real-time`).action(e=>this.execute(e))}async execute(e){let t=e.prompt||`default`,n=e.progressFile||`.taskmaster/progress.txt`;try{this.tmCore=await I({projectPath:Ge.resolve(Z(e.project))});let r=this.resolveExecutor(e.executor),i=t===`default`?await this.tmCore.tasks.getCount(`pending`,e.tag):void 0,a=this.tmCore.loop.resolveIterations({userIterations:e.iterations?parseInt(e.iterations,10):void 0,preset:t,pendingTaskCount:i});if(this.validateIterations(String(a)),Mn(this.tmCore,{tag:e.tag||`master`,storageType:this.tmCore.tasks.getStorageType()}),e.sandbox&&(r===`claude`?this.handleSandboxAuth(r):console.log(B.dim(`Using Codex native sandbox mode (workspace-write) for loop execution.`))),console.log(B.cyan(`Starting Task Master Loop...`)),console.log(B.dim(`Preset: ${t}`)),console.log(B.dim(`Max iterations: ${a}`)),console.log(B.dim(`Mode: ${e.sandbox?r===`codex`?`Codex sandbox (workspace-write)`:`Docker sandbox (Claude)`:r===`codex`?`Codex CLI`:`Claude CLI`}`)),t===`default`){let t=await this.tmCore.tasks.getNext(e.tag);t?console.log(B.white(`Next task to work on: ${B.white(t.id)} - ${t.title}`)):console.log(B.yellow(`No pending tasks found`))}console.log();let o=this.tmCore.auth.getContext()?.briefName,s={iterations:a,prompt:t,progressFile:n,tag:e.tag,executor:r,sandbox:e.sandbox,includeOutput:e.output??!0,verbose:e.verbose??!1,brief:o,callbacks:this.createOutputCallbacks()},c=await this.tmCore.loop.run(s);this.displayResult(c)}catch(e){X(e,{skipExit:!0}),process.exit(1)}}handleSandboxAuth(e){console.log(B.dim(`Checking sandbox auth...`));let t=this.tmCore.loop.checkSandboxAuth(e);if(t.error)throw Error(t.error);if(t.ready){console.log(B.green(`✓ Sandbox ready`));return}console.log(B.yellow(`Sandbox needs authentication. Starting interactive session...`)),console.log(B.dim(`Please complete auth, then Ctrl+C to continue.
231
+ `).action(async e=>{await this.executeCreate(e)})}async initTmCore(){this.tmCore||=await I({projectPath:process.cwd()})}async executeList(e){try{await this.checkAuth()||process.exit(1);let t=await this.ensureOrgSelectedLocal();t||process.exit(1);let n=J(`Fetching briefs...`).start(),r=await this.authManager.getBriefs(t);n.stop();let i=this.authManager.getContext()?.briefId,a=r.map(e=>({name:e.document?.title||`Brief ${e.id.slice(-8)}`,isCurrent:e.id===i,taskCount:e.taskCount||0,completedTasks:0,statusBreakdown:{},created:e.createdAt,description:e.document?.description,status:e.status,briefId:e.id,updatedAt:e.updatedAt}));a.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:0),this.setLastResult({success:!0,action:`list`,briefs:a,currentBrief:i||null,message:`Found ${a.length} brief(s)`}),process.stdout.isTTY&&a.length>0?await this.promptBriefSelection(a):a.length===0?An(`No briefs found in this organization`):this.displayBriefsTable(a,e?.showMetadata)}catch(e){Y(`Failed to list briefs: ${e.message}`),this.setLastResult({success:!1,action:`list`,message:e.message}),process.exit(1)}}async ensureOrgSelectedLocal(){let e=await Qn(this.authManager);return e.success&&e.orgId||null}displayBriefsTable(e,t){let r=n(`cli-table3`),i=Math.max(process.stdout.columns||120,80),a=Math.floor(i*.95),o=[.35,.25,.2,.1,.1].map((e,t)=>Math.max(Math.floor(a*e),t===0?20:8)),s=new r({head:[B.cyan.bold(`Brief Name`),B.cyan.bold(`Status`),B.cyan.bold(`Updated`),B.cyan.bold(`Tasks`),B.cyan.bold(`Completed`)],colWidths:o,wordWrap:!0});e.forEach(e=>{let t=e.briefId?e.briefId.slice(-8):`unknown`,n=e.isCurrent?`${B.green(`●`)} ${B.green.bold(e.name)} ${B.gray(`(current - ${t})`)}`:` ${e.name} ${B.gray(`(${t})`)}`,r=e.updatedAt?new Date(e.updatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`}):B.gray(`N/A`);s.push([n,bn(e.status,!0),B.gray(r),B.white(String(e.taskCount||0)),B.green(String(e.completedTasks||0))])}),console.log(s.toString())}formatBriefAsTableRow(e,t){let n=e.briefId?e.briefId.slice(-8):`unknown`,r=e.isCurrent,i=r?B.green(`●`):` `,a=r?`(current)`:`(${n})`,o=t.name-4-a.length,s=e.name;s.length>o&&(s=s.substring(0,o-1)+`…`);let c=r?B.green.bold(s):s,l=r?B.gray(`(current)`):B.gray(`(${n})`),u=2+s.length+1+a.length,d=Math.max(0,t.name-u),f=`${i} ${c} ${l}${` `.repeat(d)}`,p=bn(e.status,!0),m=(e.status||`unknown`).length+2,h=Math.max(0,t.status-m),g=`${p}${` `.repeat(h)}`,_=e.updatedAt?new Date(e.updatedAt).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`}):`N/A`;return`${f} ${g} ${B.gray(_.padEnd(t.updated))} ${B.white(String(e.taskCount||0).padStart(t.tasks))} ${B.green(String(e.completedTasks||0).padStart(t.done))}`}async promptBriefSelection(e){try{if(!this.authManager.getContext()?.orgId)return;let t=Math.max(process.stdout.columns||120,80),n=Math.floor(t*.95),r={name:Math.floor(n*.42),status:Math.floor(n*.14),updated:Math.floor(n*.16),tasks:6,done:6},i=B.cyan.bold(`Brief Name`.padEnd(r.name))+B.cyan.bold(`Status`.padEnd(r.status))+B.cyan.bold(`Updated`.padEnd(r.updated))+B.cyan.bold(`Tasks`.padStart(r.tasks+2))+B.cyan.bold(`Done`.padStart(r.done+2)),a=B.gray(`─`.repeat(n)),o=[new q.Separator(i),new q.Separator(a)];e.forEach(e=>{o.push({name:this.formatBriefAsTableRow(e,r),value:e.briefId||e.name,short:e.name})}),o.push(new q.Separator(a)),o.push({name:B.dim(` (Cancel - keep current selection)`),value:null,short:`Cancelled`});let s=!1,c=(e,t)=>{t&&t.name===`escape`&&(s=!0,process.stdin.emit(`keypress`,``,{name:`c`,ctrl:!0}))};process.stdin.isTTY&&(nt.emitKeypressEvents(process.stdin),process.stdin.on(`keypress`,c));let l;try{l=await q.prompt([{type:`list`,name:`selectedBrief`,message:`Select a brief:`,choices:o,pageSize:Math.min(e.length+5,20),loop:!1}])}finally{process.stdin.isTTY&&process.stdin.removeListener(`keypress`,c)}if(s)return;if(l.selectedBrief&&l.selectedBrief!==null){let t=e.find(e=>e.briefId===l.selectedBrief||e.name===l.selectedBrief);t&&(await this.authManager.updateContext({briefId:t.briefId||void 0,briefName:t.name,briefStatus:t.status||void 0,briefUpdatedAt:t.updatedAt||void 0}),kn(`Selected brief: ${t.name}`),this.setLastResult({success:!0,action:`select`,currentBrief:t.briefId||t.name,message:`Selected brief: ${t.name}`}))}}catch(e){if(e.isTtyError)return;console.error(B.yellow(`\nNote: Could not prompt for brief selection: ${e.message}`))}}async executeSelect(e){try{if(await this.authManager.hasValidSession()||(Y(`Not authenticated. Run "tm auth login" first.`),process.exit(1)),e&&e.trim().length>0){await this.executeSelectFromUrl(e.trim());return}let t=this.authManager.getContext();t?.orgId||(On(`No organization selected. Run "tm context org" first.`),process.exit(1));let n=await Xn(this.authManager,t.orgId);this.setLastResult({success:n.success,action:`select`,currentBrief:n.briefId,message:n.message}),n.success||process.exit(1)}catch(e){On(`Failed to select brief: ${e.message}`),this.setLastResult({success:!1,action:`select`,message:e.message}),process.exit(1)}}async executeSelectFromUrl(e){try{await this.authManager.hasValidSession()||(Y(`Not authenticated. Run "tm auth login" first.`),process.exit(1)),await this.initTmCore();let t=await Zn(this.authManager,e,this.tmCore);this.setLastResult({success:t.success,action:`select`,currentBrief:t.briefId,message:t.message}),t.success||process.exit(1)}catch(e){On(`Failed to select brief: ${e.message}`),this.setLastResult({success:!1,action:`select`,message:e.message}),process.exit(1)}}async executeCreate(e){try{await this.checkAuth()||process.exit(1);let t=await Gr({tagName:e||`new-brief`,projectRoot:process.cwd(),report:(e,...t)=>{let n=t[0];e===`error`?Y(n):e===`warn`?An(n):e===`info`&&jn(n)}});if(!t)throw Error(`Failed to get brief creation URL`);this.setLastResult({success:t.success,action:`create`,message:t.message}),t.success||process.exit(1)}catch(e){On(`Failed to create brief: ${e.message}`),this.setLastResult({success:!1,action:`create`,message:e.message}),process.exit(1)}}setLastResult(e){this.lastResult=e}getLastResult(){return this.lastResult}static register(t,n){let r=new e(n);return t.addCommand(r),r}},oi=class e extends G{tmCore;constructor(e){super(e||`loop`),this.description(`Run coding agent CLI in a loop, one task per iteration`).option(`-n, --iterations <number>`,`Maximum iterations`).option(`-p, --prompt <preset|path>`,`Preset name (${Ie.join(`, `)}) or path to custom prompt file`,`default`).option(`--progress-file <path>`,`Path to progress log file`,`.taskmaster/progress.txt`).option(`-t, --tag <tag>`,`Only work on tasks with this tag`).option(`--project <path>`,`Project root directory (auto-detected if not provided)`).option(`--sandbox`,`Enable sandbox mode (Docker for Claude, native sandbox for Codex)`).option(`-e, --executor <executor>`,`Execution backend (claude|codex)`).option(`--no-output`,`Exclude full executor output from iteration results`).option(`-v, --verbose`,`Show executor's work in real-time`).action(e=>this.execute(e))}async execute(e){let t=e.prompt||`default`,n=e.progressFile||`.taskmaster/progress.txt`;try{this.tmCore=await I({projectPath:We.resolve(Z(e.project))});let r=this.resolveExecutor(e.executor),i=t===`default`?await this.tmCore.tasks.getCount(`pending`,e.tag):void 0,a=this.tmCore.loop.resolveIterations({userIterations:e.iterations?parseInt(e.iterations,10):void 0,preset:t,pendingTaskCount:i});if(this.validateIterations(String(a)),Pn(this.tmCore,{tag:e.tag||`master`,storageType:this.tmCore.tasks.getStorageType()}),e.sandbox&&(r===`claude`?this.handleSandboxAuth(r):console.log(B.dim(`Using Codex native sandbox mode (workspace-write) for loop execution.`))),console.log(B.cyan(`Starting Task Master Loop...`)),console.log(B.dim(`Preset: ${t}`)),console.log(B.dim(`Max iterations: ${a}`)),console.log(B.dim(`Mode: ${e.sandbox?r===`codex`?`Codex sandbox (workspace-write)`:`Docker sandbox (Claude)`:r===`codex`?`Codex CLI`:`Claude CLI`}`)),t===`default`){let t=await this.tmCore.tasks.getNext(e.tag);t?console.log(B.white(`Next task to work on: ${B.white(t.id)} - ${t.title}`)):console.log(B.yellow(`No pending tasks found`))}console.log();let o=this.tmCore.auth.getContext()?.briefName,s={iterations:a,prompt:t,progressFile:n,tag:e.tag,executor:r,sandbox:e.sandbox,includeOutput:e.output??!0,verbose:e.verbose??!1,brief:o,callbacks:this.createOutputCallbacks()},c=await this.tmCore.loop.run(s);this.displayResult(c)}catch(e){X(e,{skipExit:!0}),process.exit(1)}}handleSandboxAuth(e){console.log(B.dim(`Checking sandbox auth...`));let t=this.tmCore.loop.checkSandboxAuth(e);if(t.error)throw Error(t.error);if(t.ready){console.log(B.green(`✓ Sandbox ready`));return}console.log(B.yellow(`Sandbox needs authentication. Starting interactive session...`)),console.log(B.dim(`Please complete auth, then Ctrl+C to continue.
232
232
  `));let n=this.tmCore.loop.runInteractiveAuth(e);if(!n.success)throw Error(n.error||`Interactive authentication failed`);console.log(B.green(`✓ Auth complete
233
- `))}resolveExecutor(e){let t=this.getConfiguredExecutor(),n=this.inferExecutorFromConfig(),r=e??process.env.TASKMASTER_EXECUTOR??t??n??`claude`,i=r.toLowerCase();if(i===`claude`||i===`codex`)return i;throw Error(`Invalid executor "${r}". Supported values: claude, codex.`)}getConfiguredExecutor(){let e=this.tmCore.config.getConfig().custom?.executor;return typeof e==`string`?e:void 0}inferExecutorFromConfig(){let e=this.tmCore.config.getConfig();if(this.isCodexProvider(e.aiProvider))return`codex`;let t=this.asObject(e.models);if(this.isCodexModelConfig(t?.main)||this.isNonEmptyObject(e.codexCli))return`codex`}isCodexModelConfig(e){if(typeof e==`string`)return this.isCodexModelId(e);let t=this.asObject(e);return t?this.isCodexProvider(t.provider)||this.isCodexModelId(t.modelId):!1}isCodexProvider(e){if(typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return t===`codex`||t===`codex-cli`||t===`codex-lb`}isCodexModelId(e){return typeof e==`string`&&e.toLowerCase().includes(`codex`)}asObject(e){if(typeof e==`object`&&e)return e}isNonEmptyObject(e){let t=this.asObject(e);return!!(t&&Object.keys(t).length>0)}validateIterations(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw Error(`Invalid iterations: ${e}. Must be a positive integer.`)}createOutputCallbacks(){return{onIterationStart:(e,t)=>{console.log(),console.log(B.cyan(`━━━ Iteration ${e} of ${t} ━━━`))},onText:e=>{console.log(e)},onToolUse:e=>{console.log(B.dim(` → ${e}`))},onError:(e,t)=>{t===`warning`?console.error(B.yellow(`[Loop Warning] ${e}`)):console.error(B.red(`[Loop Error] ${e}`))},onStderr:(e,t)=>{process.stderr.write(B.dim(`[Iteration ${e}] `)+t)},onOutput:e=>{console.log(e)},onIterationEnd:e=>{let t=e.status===`success`?B.green:e.status===`error`?B.red:B.yellow;console.log(t(` Iteration ${e.iteration} completed: ${e.status}`))}}}displayResult(e){console.log(),console.log(B.bold(`Loop Complete`)),console.log(B.dim(`─`.repeat(40))),console.log(`Total iterations: ${e.totalIterations}`),console.log(`Tasks completed: ${e.tasksCompleted}`),console.log(`Final status: ${this.formatStatus(e.finalStatus)}`),e.errorMessage&&console.log(B.red(`Error: ${e.errorMessage}`))}formatStatus(e){return{all_complete:B.green(`All tasks complete`),max_iterations:B.yellow(`Max iterations reached`),blocked:B.red(`Blocked`),error:B.red(`Error`)}[e]}static register(t,n){let r=new e(n);return t.addCommand(r),r}},ai=class{constructor(e){this.useJson=e}output(e){this.useJson?console.log(JSON.stringify(e,null,2)):this.outputText(e)}outputText(e){for(let[t,n]of Object.entries(e))typeof n==`object`&&n?(console.log(B.cyan(`${t}:`)),this.outputObject(n,` `)):console.log(B.white(`${t}: ${n}`))}outputObject(e,t){for(let[n,r]of Object.entries(e))typeof r==`object`&&r?(console.log(B.cyan(`${t}${n}:`)),this.outputObject(r,t+` `)):console.log(B.gray(`${t}${n}: ${r}`))}error(e,t){if(this.useJson)console.error(JSON.stringify({error:e,...t},null,2));else if(console.error(B.red(`Error: ${e}`)),t)for(let[e,n]of Object.entries(t))console.error(B.gray(` ${e}: ${n}`))}success(e,t){this.useJson?console.log(JSON.stringify({success:!0,message:e,...t},null,2)):(console.log(B.green(`✓ ${e}`)),t&&this.output(t))}warning(e){this.useJson?console.warn(JSON.stringify({warning:e},null,2)):console.warn(B.yellow(`⚠️ ${e}`))}info(e){this.useJson||console.log(B.blue(`ℹ ${e}`))}},oi=class extends G{constructor(){super(`abort`),this.description(`Abort the current TDD workflow and clean up state`).option(`-f, --force`,`Force abort without confirmation`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:``},r=new ai(e.json||t?.json||!1);try{let i=Z(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await I({projectPath:i});if(!await a.workflow.hasWorkflow()){r.warning(`No active workflow to abort`);return}await a.workflow.resume();let o=a.workflow.getStatus();if(!n.force&&!n.json){let{confirmed:e}=await q.prompt([{type:`confirm`,name:`confirmed`,message:`This will abort the workflow for task ${o.taskId}. Progress: ${o.progress?.completed||0}/${o.progress?.total||0} subtasks completed. Continue?`,default:!1}]);if(!e){r.info(`Abort cancelled`);return}}await a.workflow.abort(),r.success(`Workflow aborted`,{taskId:o.taskId,branchName:o.branchName,progress:o.progress,lastSubtask:o.currentSubtask?{id:o.currentSubtask.id,title:o.currentSubtask.title}:null,note:`Branch and commits remain. Clean up manually if needed.`})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},si=class extends G{constructor(){super(`commit`),this.description(`Create a commit for the completed GREEN phase`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new ai(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});await t.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await t.workflow.resume();let i=t.workflow.getStatus(),a=t.workflow.getContext();i.tddPhase!==`COMMIT`&&(r.error(`Not in COMMIT phase`,{currentPhase:i.tddPhase||i.phase,suggestion:`Complete RED and GREEN phases first`}),process.exit(1)),i.currentSubtask||(r.error(`No current subtask`),process.exit(1));let o=new Me(e);await o.ensureGitRepository(),await o.hasStagedChanges()||(r.info(`No staged changes, staging all changes...`),await o.stageFiles([`.`]));let s=await o.getStatus(),c=[...s.staged,...s.modified],l=new ue,u=a.lastTestResults,d=l.generateMessage({type:`feat`,description:i.currentSubtask.title,changedFiles:c,taskId:i.taskId,phase:i.tddPhase,tag:a.metadata.tag||void 0,testsPassing:u?.passed,testsFailing:u?.failed,coveragePercent:void 0});await o.createCommit(d,{metadata:{taskId:i.taskId,subtaskId:i.currentSubtask.id,phase:`COMMIT`,tddCycle:`complete`}});let f=await o.getLastCommit(),p=await t.workflow.commit(),m=p.phase===`COMPLETE`;r.success(`Commit created`,{commitHash:f.hash.substring(0,7),message:d.split(`
234
- `)[0],subtask:{id:i.currentSubtask.id,title:i.currentSubtask.title},progress:p.progress,nextAction:m?`All subtasks complete. Run: autopilot status`:`Start next subtask with RED phase`})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},ci=class extends G{constructor(){super(`complete`),this.description(`Complete the current TDD phase with result validation`).option(`-r, --results <json>`,`Test results JSON (with total, passed, failed, skipped)`).option(`-c, --coverage <percent>`,`Coverage percentage`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new ai(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});await t.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await t.workflow.resume();let i=t.workflow.getStatus(),a=i.tddPhase,o=i.currentSubtask;if(a||(r.error(`Not in a TDD phase`,{phase:i.phase}),process.exit(1)),a===`RED`||a===`GREEN`){n.results||(r.error(`Test results required for RED/GREEN phase`,{usage:`--results '{"total":10,"passed":9,"failed":1,"skipped":0}'`}),process.exit(1));let e;try{let t=JSON.parse(n.results);e={total:t.total||0,passed:t.passed||0,failed:t.failed||0,skipped:t.skipped||0,phase:a}}catch(e){r.error(`Invalid test results JSON`,{error:e.message}),process.exit(1)}a===`RED`&&e.failed===0&&(r.error(`RED phase validation failed`,{reason:`At least one test must be failing`,actual:{passed:e.passed,failed:e.failed}}),process.exit(1)),a===`GREEN`&&e.failed!==0&&(r.error(`GREEN phase validation failed`,{reason:`All tests must pass`,actual:{passed:e.passed,failed:e.failed}}),process.exit(1));let i=await t.workflow.completePhase(e);a===`RED`?r.success(`RED phase completed`,{nextPhase:i.tddPhase||`GREEN`,testResults:e,subtask:o?.title}):r.success(`GREEN phase completed`,{nextPhase:i.tddPhase||`COMMIT`,testResults:e,subtask:o?.title,suggestion:`Run: autopilot commit`})}else a===`COMMIT`&&(r.error(`Use "autopilot commit" to complete COMMIT phase`),process.exit(1))}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},li=class extends G{constructor(){super(`finalize`),this.description(`Finalize and complete the workflow. Validates working tree is clean.`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:``},r=new ai(e.json||t?.json||!1);try{let i=Z(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await I({projectPath:i});await a.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await a.workflow.resume();let o=a.workflow.getStatus();o.phase!==`FINALIZE`&&(r.error(`Cannot finalize: workflow is in ${o.phase} phase`,{suggestion:`Complete all subtasks first`}),process.exit(1)),r.info(`Validating working tree and finalizing workflow...`);let s=await a.workflow.finalize();r.success(`Workflow completed`,{taskId:s.taskId,phase:s.phase,branchName:s.branchName,progress:s.progress})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},ui=class extends G{constructor(){super(`next`),this.description(`Get the next action to perform in the TDD workflow`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:``},r=new ai(e.json||t?.json||!1);try{let i=Z(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await I({projectPath:i});await a.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await a.workflow.resume();let o=a.workflow.getStatus(),s=a.workflow.getNextAction(),c=a.workflow.getContext(),l=this.resolveExecutor(a,n.executor),u=o.phase,d=o.tddPhase,f=o.currentSubtask;if(u===`COMPLETE`){r.success(`Workflow complete`,{message:`All subtasks have been completed`,taskId:o.taskId});return}let p=await this.buildExecutionHint(a,o.taskId,o.phase,o.tddPhase,o.currentSubtask?.id,l),m=p?.command?`${s.nextSteps}\n\nLaunch coding agent:\n${p.command}`:s.nextSteps,h={action:s.action,description:s.description,phase:u,tddPhase:d,taskId:o.taskId,branchName:o.branchName,subtask:f?{id:f.id,title:f.title,attempts:f.attempts}:null,nextSteps:m,lastTestResults:c.lastTestResults,execution:p??{executor:l}};n.json?r.output(h):r.success(`Next action`,h)}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}async buildExecutionHint(e,t,n,r,i,a){if(n!==`SUBTASK_LOOP`||!i)return null;if(r!==`RED`&&r!==`GREEN`)return{executor:a};let o=this.composeWorkItemId(t,i),s=await e.tasks.start(o,{dryRun:!0,force:!0,updateStatus:!1,executor:a});return{executor:a,workItemId:o,command:s.command?this.buildShellCommand(s.command.executable,s.command.args):void 0}}composeWorkItemId(e,t){let n=String(t);return n.includes(`.`)?n:`${e}.${n}`}buildShellCommand(e,t){return[e,...t.map(e=>this.shellEscapeArg(e))].join(` `)}shellEscapeArg(e){return e?`'${e.replace(/'/g,`'"'"'`)}'`:`''`}resolveExecutor(e,t){let n=this.getConfiguredExecutor(e),r=this.inferExecutorFromConfig(e),i=t??process.env.TASKMASTER_EXECUTOR??n??r??`claude`,a=i.toLowerCase();if(a===`claude`||a===`codex`)return a;throw Error(`Invalid executor "${i}". Supported values: claude, codex.`)}getConfiguredExecutor(e){let t=e.config.getConfig().custom?.executor;return typeof t==`string`?t:void 0}inferExecutorFromConfig(e){let t=e.config.getConfig();if(this.isCodexProvider(t.aiProvider))return`codex`;let n=this.asObject(t.models);if(this.isCodexModelConfig(n?.main)||this.isNonEmptyObject(t.codexCli))return`codex`}isCodexModelConfig(e){if(typeof e==`string`)return this.isCodexModelId(e);let t=this.asObject(e);return t?this.isCodexProvider(t.provider)||this.isCodexModelId(t.modelId):!1}isCodexProvider(e){if(typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return t===`codex`||t===`codex-cli`||t===`codex-lb`}isCodexModelId(e){return typeof e==`string`&&e.toLowerCase().includes(`codex`)}asObject(e){if(typeof e==`object`&&e)return e}isNonEmptyObject(e){let t=this.asObject(e);return!!(t&&Object.keys(t).length>0)}},di=class extends G{constructor(){super(`resume`),this.description(`Resume a previously started TDD workflow`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new ai(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});await t.workflow.hasWorkflow()||(r.error(`No workflow state found`,{suggestion:`Start a new workflow with: autopilot start <taskId>`}),process.exit(1)),r.info(`Loading workflow state...`);let i=await t.workflow.resume();r.success(`Workflow resumed`,{taskId:i.taskId,phase:i.phase,tddPhase:i.tddPhase,branchName:i.branchName,progress:i.progress,currentSubtask:i.currentSubtask?{id:i.currentSubtask.id,title:i.currentSubtask.title,attempts:i.currentSubtask.attempts}:null})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},fi=class extends G{constructor(){super(`start`),this.description(`Initialize and start a new TDD workflow for a task`).argument(`<taskId>`,`Task ID to start workflow for`).option(`-f, --force`,`Force start even if workflow state exists`).option(`--max-attempts <number>`,`Maximum attempts per subtask`,`3`).action(async(e,t)=>{await this.execute(e,t)})}async execute(e,t){let n=this.parent?.opts(),r={...n,...t,projectRoot:Z(t.projectRoot||n?.projectRoot)},i=new ai(r.json||!1);try{let t=se.safeParse(e);t.success||(i.error(`Invalid task ID format`,{taskId:e,error:t.error.issues[0]?.message}),process.exit(1));let n=t.data,a=r.projectRoot,o=await I({projectPath:a});await o.workflow.hasWorkflow()&&!r.force&&(i.error(`Workflow state already exists. Use --force to overwrite or resume with "autopilot resume"`),process.exit(1));let s=o.config.getActiveTag(),c=o.auth.getContext()?.orgSlug;i.info(`Loading task ${n}...`);let{task:l}=await o.tasks.get(n);l||(i.error(`Task not found`,{taskId:n}),process.exit(1)),(!l.subtasks||l.subtasks.length===0)&&(i.error(`Task has no subtasks. Expand task first.`,{taskId:n,suggestion:`Run: task-master expand --id=${n}`}),process.exit(1));let u=parseInt(r.maxAttempts||`3`,10);i.info(`Starting TDD workflow...`);let d=await o.workflow.start({taskId:n,taskTitle:l.title,subtasks:l.subtasks.map(e=>({id:e.id,title:e.title,status:e.status,maxAttempts:u})),maxAttempts:u,force:r.force,tag:s,orgSlug:c});i.success(`TDD workflow started`,{taskId:d.taskId,title:l.title,phase:d.phase,tddPhase:d.tddPhase,branchName:d.branchName,subtasks:l.subtasks.length,currentSubtask:d.currentSubtask?.title})}catch(e){i.error(e.message),r.verbose&&console.error(e.stack),process.exit(1)}}},pi=class extends G{constructor(){super(`status`),this.description(`Show current TDD workflow status and progress`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new ai(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});if(!await t.workflow.hasWorkflow()){n.json?r.output({active:!1,message:`No active workflow`}):(r.info(`No active workflow`),console.log(`Start a workflow with: autopilot start <taskId>`));return}await t.workflow.resume();let i=t.workflow.getStatus(),a=t.workflow.getContext(),o={taskId:i.taskId,phase:i.phase,tddPhase:i.tddPhase,branchName:i.branchName,progress:i.progress,currentSubtask:i.currentSubtask?{id:i.currentSubtask.id,title:i.currentSubtask.title,attempts:i.currentSubtask.attempts,maxAttempts:i.currentSubtask.maxAttempts}:null,subtasks:a.subtasks.map(e=>({id:e.id,title:e.title,status:e.status,attempts:e.attempts})),errors:a.errors&&a.errors.length>0?a.errors:void 0,metadata:a.metadata};n.json?r.output(o):r.success(`Workflow status`,o)}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},mi=class e extends G{constructor(){super(`autopilot`),this.description(`AI agent orchestration for TDD workflow execution`).alias(`ap`).option(`--json`,`Output in JSON format for machine parsing`).option(`-v, --verbose`,`Enable verbose output`).option(`-e, --executor <executor>`,`Execution backend (claude|codex)`).option(`-p, --project-root <path>`,`Project root directory (auto-detected if not specified)`),this.registerSubcommands()}registerSubcommands(){this.addCommand(new fi),this.addCommand(new di),this.addCommand(new ui),this.addCommand(new ci),this.addCommand(new si),this.addCommand(new pi),this.addCommand(new li),this.addCommand(new oi)}static register(t){let n=new e;return t.addCommand(n),n}},hi=class e extends G{tmCore;lastResult;constructor(e){super(e||`generate`),this.description(`Generate individual task files from tasks.json`).option(`-t, --tag <tag>`,`Tag context for task operations`).option(`-o, --output <dir>`,`Output directory for generated files (defaults to .taskmaster/tasks)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).action(async e=>{await this.executeCommand(e)})}async executeCommand(e){let t=!1;try{this.validateOptions(e);let t=Z(e.project);await this.initializeCore(t);let n=await this.generateFiles(t,e);this.lastResult=n,this.displayResults(n,e)}catch(e){t=!0,X(e,{skipExit:!0})}finally{await this.cleanup()}t&&process.exit(1)}validateOptions(e){if(e.format&&![`text`,`json`].includes(e.format))throw Error(`Invalid format: ${e.format}. Valid formats are: text, json`)}async initializeCore(e){this.tmCore||=await I({projectPath:Ge.resolve(e)})}async generateFiles(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=t.output?Ge.resolve(e,t.output):void 0;return this.tmCore.tasks.generateTaskFiles({tag:t.tag,outputDir:n})}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:this.displayText(e,t);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e,t){if(this.tmCore){let e=this.tmCore.tasks.getStorageType(),n=t.tag||this.tmCore.config.getActiveTag();Mn(this.tmCore,{tag:n,storageType:e})}if(!e.success){console.log(W(B.red(`Error: ${e.error||`Unknown error`}`),{padding:1,borderStyle:`round`,borderColor:`red`,title:`❌ GENERATION FAILED`,titleAlignment:`center`}));return}if(e.count===0){console.log(W(B.yellow(`No tasks found to generate files for.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`⚠️ NO TASKS`,titleAlignment:`center`}));return}let n=`${B.green(`✓`)} Generated ${B.cyan(e.count)} task file(s)`;n+=`\n\n${B.dim(`Output directory:`)} ${e.directory}`,e.orphanedFilesRemoved>0&&(n+=`\n${B.dim(`Orphaned files removed:`)} ${e.orphanedFilesRemoved}`),console.log(W(n,{padding:1,borderStyle:`round`,borderColor:`green`,title:`📄 TASK FILES GENERATED`,titleAlignment:`center`}))}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},gi=class e extends G{authCommand;constructor(e){super(e||`login`),this.authCommand=new Qn,this.description(`Login to Hamster (alias for "auth login")`),this.argument(`[token]`,`Authentication token (optional, for SSH/remote environments)`),this.option(`-y, --yes`,`Skip interactive prompts`),this.addHelpText(`after`,`
233
+ `))}resolveExecutor(e){let t=this.getConfiguredExecutor(),n=this.inferExecutorFromConfig(),r=e??process.env.TASKMASTER_EXECUTOR??t??n??`claude`,i=r.toLowerCase();if(i===`claude`||i===`codex`)return i;throw Error(`Invalid executor "${r}". Supported values: claude, codex.`)}getConfiguredExecutor(){let e=this.tmCore.config.getConfig().custom?.executor;return typeof e==`string`?e:void 0}inferExecutorFromConfig(){let e=this.tmCore.config.getConfig();if(this.isCodexProvider(e.aiProvider))return`codex`;let t=this.asObject(e.models);if(this.isCodexModelConfig(t?.main)||this.isNonEmptyObject(e.codexCli))return`codex`}isCodexModelConfig(e){if(typeof e==`string`)return this.isCodexModelId(e);let t=this.asObject(e);return t?this.isCodexProvider(t.provider)||this.isCodexModelId(t.modelId):!1}isCodexProvider(e){if(typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return t===`codex`||t===`codex-cli`||t===`codex-lb`}isCodexModelId(e){return typeof e==`string`&&e.toLowerCase().includes(`codex`)}asObject(e){if(typeof e==`object`&&e)return e}isNonEmptyObject(e){let t=this.asObject(e);return!!(t&&Object.keys(t).length>0)}validateIterations(e){let t=Number(e);if(!Number.isInteger(t)||t<1)throw Error(`Invalid iterations: ${e}. Must be a positive integer.`)}createOutputCallbacks(){return{onIterationStart:(e,t)=>{console.log(),console.log(B.cyan(`━━━ Iteration ${e} of ${t} ━━━`))},onText:e=>{console.log(e)},onToolUse:e=>{console.log(B.dim(` → ${e}`))},onError:(e,t)=>{t===`warning`?console.error(B.yellow(`[Loop Warning] ${e}`)):console.error(B.red(`[Loop Error] ${e}`))},onStderr:(e,t)=>{process.stderr.write(B.dim(`[Iteration ${e}] `)+t)},onOutput:e=>{console.log(e)},onIterationEnd:e=>{let t=e.status===`success`?B.green:e.status===`error`?B.red:B.yellow;console.log(t(` Iteration ${e.iteration} completed: ${e.status}`))}}}displayResult(e){console.log(),console.log(B.bold(`Loop Complete`)),console.log(B.dim(`─`.repeat(40))),console.log(`Total iterations: ${e.totalIterations}`),console.log(`Tasks completed: ${e.tasksCompleted}`),console.log(`Final status: ${this.formatStatus(e.finalStatus)}`),e.errorMessage&&console.log(B.red(`Error: ${e.errorMessage}`))}formatStatus(e){return{all_complete:B.green(`All tasks complete`),max_iterations:B.yellow(`Max iterations reached`),blocked:B.red(`Blocked`),error:B.red(`Error`)}[e]}static register(t,n){let r=new e(n);return t.addCommand(r),r}},si=class{constructor(e){this.useJson=e}output(e){this.useJson?console.log(JSON.stringify(e,null,2)):this.outputText(e)}outputText(e){for(let[t,n]of Object.entries(e))typeof n==`object`&&n?(console.log(B.cyan(`${t}:`)),this.outputObject(n,` `)):console.log(B.white(`${t}: ${n}`))}outputObject(e,t){for(let[n,r]of Object.entries(e))typeof r==`object`&&r?(console.log(B.cyan(`${t}${n}:`)),this.outputObject(r,t+` `)):console.log(B.gray(`${t}${n}: ${r}`))}error(e,t){if(this.useJson)console.error(JSON.stringify({error:e,...t},null,2));else if(console.error(B.red(`Error: ${e}`)),t)for(let[e,n]of Object.entries(t))console.error(B.gray(` ${e}: ${n}`))}success(e,t){this.useJson?console.log(JSON.stringify({success:!0,message:e,...t},null,2)):(console.log(B.green(`✓ ${e}`)),t&&this.output(t))}warning(e){this.useJson?console.warn(JSON.stringify({warning:e},null,2)):console.warn(B.yellow(`⚠️ ${e}`))}info(e){this.useJson||console.log(B.blue(`ℹ ${e}`))}},ci=class extends G{constructor(){super(`abort`),this.description(`Abort the current TDD workflow and clean up state`).option(`-f, --force`,`Force abort without confirmation`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:``},r=new si(e.json||t?.json||!1);try{let i=Z(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await I({projectPath:i});if(!await a.workflow.hasWorkflow()){r.warning(`No active workflow to abort`);return}await a.workflow.resume();let o=a.workflow.getStatus();if(!n.force&&!n.json){let{confirmed:e}=await q.prompt([{type:`confirm`,name:`confirmed`,message:`This will abort the workflow for task ${o.taskId}. Progress: ${o.progress?.completed||0}/${o.progress?.total||0} subtasks completed. Continue?`,default:!1}]);if(!e){r.info(`Abort cancelled`);return}}await a.workflow.abort(),r.success(`Workflow aborted`,{taskId:o.taskId,branchName:o.branchName,progress:o.progress,lastSubtask:o.currentSubtask?{id:o.currentSubtask.id,title:o.currentSubtask.title}:null,note:`Branch and commits remain. Clean up manually if needed.`})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},li=class extends G{constructor(){super(`commit`),this.description(`Create a commit for the completed GREEN phase`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new si(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});await t.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await t.workflow.resume();let i=t.workflow.getStatus(),a=t.workflow.getContext();i.tddPhase!==`COMMIT`&&(r.error(`Not in COMMIT phase`,{currentPhase:i.tddPhase||i.phase,suggestion:`Complete RED and GREEN phases first`}),process.exit(1)),i.currentSubtask||(r.error(`No current subtask`),process.exit(1));let o=new Ae(e);await o.ensureGitRepository(),await o.hasStagedChanges()||(r.info(`No staged changes, staging all changes...`),await o.stageFiles([`.`]));let s=await o.getStatus(),c=[...s.staged,...s.modified],l=new le,u=a.lastTestResults,d=l.generateMessage({type:`feat`,description:i.currentSubtask.title,changedFiles:c,taskId:i.taskId,phase:i.tddPhase,tag:a.metadata.tag||void 0,testsPassing:u?.passed,testsFailing:u?.failed,coveragePercent:void 0});await o.createCommit(d,{metadata:{taskId:i.taskId,subtaskId:i.currentSubtask.id,phase:`COMMIT`,tddCycle:`complete`}});let f=await o.getLastCommit(),p=await t.workflow.commit(),m=p.phase===`COMPLETE`;r.success(`Commit created`,{commitHash:f.hash.substring(0,7),message:d.split(`
234
+ `)[0],subtask:{id:i.currentSubtask.id,title:i.currentSubtask.title},progress:p.progress,nextAction:m?`All subtasks complete. Run: autopilot status`:`Start next subtask with RED phase`})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},ui=class extends G{constructor(){super(`complete`),this.description(`Complete the current TDD phase with result validation`).option(`-r, --results <json>`,`Test results JSON (with total, passed, failed, skipped)`).option(`-c, --coverage <percent>`,`Coverage percentage`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new si(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});await t.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await t.workflow.resume();let i=t.workflow.getStatus(),a=i.tddPhase,o=i.currentSubtask;if(a||(r.error(`Not in a TDD phase`,{phase:i.phase}),process.exit(1)),a===`RED`||a===`GREEN`){n.results||(r.error(`Test results required for RED/GREEN phase`,{usage:`--results '{"total":10,"passed":9,"failed":1,"skipped":0}'`}),process.exit(1));let e;try{let t=JSON.parse(n.results);e={total:t.total||0,passed:t.passed||0,failed:t.failed||0,skipped:t.skipped||0,phase:a}}catch(e){r.error(`Invalid test results JSON`,{error:e.message}),process.exit(1)}a===`RED`&&e.failed===0&&(r.error(`RED phase validation failed`,{reason:`At least one test must be failing`,actual:{passed:e.passed,failed:e.failed}}),process.exit(1)),a===`GREEN`&&e.failed!==0&&(r.error(`GREEN phase validation failed`,{reason:`All tests must pass`,actual:{passed:e.passed,failed:e.failed}}),process.exit(1));let i=await t.workflow.completePhase(e);a===`RED`?r.success(`RED phase completed`,{nextPhase:i.tddPhase||`GREEN`,testResults:e,subtask:o?.title}):r.success(`GREEN phase completed`,{nextPhase:i.tddPhase||`COMMIT`,testResults:e,subtask:o?.title,suggestion:`Run: autopilot commit`})}else a===`COMMIT`&&(r.error(`Use "autopilot commit" to complete COMMIT phase`),process.exit(1))}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},di=class extends G{constructor(){super(`finalize`),this.description(`Finalize and complete the workflow. Validates working tree is clean.`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:``},r=new si(e.json||t?.json||!1);try{let i=Z(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await I({projectPath:i});await a.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await a.workflow.resume();let o=a.workflow.getStatus();o.phase!==`FINALIZE`&&(r.error(`Cannot finalize: workflow is in ${o.phase} phase`,{suggestion:`Complete all subtasks first`}),process.exit(1)),r.info(`Validating working tree and finalizing workflow...`);let s=await a.workflow.finalize();r.success(`Workflow completed`,{taskId:s.taskId,phase:s.phase,branchName:s.branchName,progress:s.progress})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},fi=class extends G{constructor(){super(`next`),this.description(`Get the next action to perform in the TDD workflow`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:``},r=new si(e.json||t?.json||!1);try{let i=Z(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await I({projectPath:i});await a.workflow.hasWorkflow()||(r.error(`No active workflow`,{suggestion:`Start a workflow with: autopilot start <taskId>`}),process.exit(1)),await a.workflow.resume();let o=a.workflow.getStatus(),s=a.workflow.getNextAction(),c=a.workflow.getContext(),l=this.resolveExecutor(a,n.executor),u=o.phase,d=o.tddPhase,f=o.currentSubtask;if(u===`COMPLETE`){r.success(`Workflow complete`,{message:`All subtasks have been completed`,taskId:o.taskId});return}let p=await this.buildExecutionHint(a,o.taskId,o.phase,o.tddPhase,o.currentSubtask?.id,l),m=p?.command?`${s.nextSteps}\n\nLaunch coding agent:\n${p.command}`:s.nextSteps,h={action:s.action,description:s.description,phase:u,tddPhase:d,taskId:o.taskId,branchName:o.branchName,subtask:f?{id:f.id,title:f.title,attempts:f.attempts}:null,nextSteps:m,lastTestResults:c.lastTestResults,execution:p??{executor:l}};n.json?r.output(h):r.success(`Next action`,h)}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}async buildExecutionHint(e,t,n,r,i,a){if(n!==`SUBTASK_LOOP`||!i)return null;if(r!==`RED`&&r!==`GREEN`)return{executor:a};let o=this.composeWorkItemId(t,i),s=await e.tasks.start(o,{dryRun:!0,force:!0,updateStatus:!1,executor:a});return{executor:a,workItemId:o,command:s.command?this.buildShellCommand(s.command.executable,s.command.args):void 0}}composeWorkItemId(e,t){let n=String(t);return n.includes(`.`)?n:`${e}.${n}`}buildShellCommand(e,t){return[e,...t.map(e=>this.shellEscapeArg(e))].join(` `)}shellEscapeArg(e){return e?`'${e.replace(/'/g,`'"'"'`)}'`:`''`}resolveExecutor(e,t){let n=this.getConfiguredExecutor(e),r=this.inferExecutorFromConfig(e),i=t??process.env.TASKMASTER_EXECUTOR??n??r??`claude`,a=i.toLowerCase();if(a===`claude`||a===`codex`)return a;throw Error(`Invalid executor "${i}". Supported values: claude, codex.`)}getConfiguredExecutor(e){let t=e.config.getConfig().custom?.executor;return typeof t==`string`?t:void 0}inferExecutorFromConfig(e){let t=e.config.getConfig();if(this.isCodexProvider(t.aiProvider))return`codex`;let n=this.asObject(t.models);if(this.isCodexModelConfig(n?.main)||this.isNonEmptyObject(t.codexCli))return`codex`}isCodexModelConfig(e){if(typeof e==`string`)return this.isCodexModelId(e);let t=this.asObject(e);return t?this.isCodexProvider(t.provider)||this.isCodexModelId(t.modelId):!1}isCodexProvider(e){if(typeof e!=`string`)return!1;let t=e.trim().toLowerCase();return t===`codex`||t===`codex-cli`||t===`codex-lb`}isCodexModelId(e){return typeof e==`string`&&e.toLowerCase().includes(`codex`)}asObject(e){if(typeof e==`object`&&e)return e}isNonEmptyObject(e){let t=this.asObject(e);return!!(t&&Object.keys(t).length>0)}},pi=class extends G{constructor(){super(`resume`),this.description(`Resume a previously started TDD workflow`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new si(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});await t.workflow.hasWorkflow()||(r.error(`No workflow state found`,{suggestion:`Start a new workflow with: autopilot start <taskId>`}),process.exit(1)),r.info(`Loading workflow state...`);let i=await t.workflow.resume();r.success(`Workflow resumed`,{taskId:i.taskId,phase:i.phase,tddPhase:i.tddPhase,branchName:i.branchName,progress:i.progress,currentSubtask:i.currentSubtask?{id:i.currentSubtask.id,title:i.currentSubtask.title,attempts:i.currentSubtask.attempts}:null})}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},mi=class extends G{constructor(){super(`start`),this.description(`Initialize and start a new TDD workflow for a task`).argument(`<taskId>`,`Task ID to start workflow for`).option(`-f, --force`,`Force start even if workflow state exists`).option(`--max-attempts <number>`,`Maximum attempts per subtask`,`3`).action(async(e,t)=>{await this.execute(e,t)})}async execute(e,t){let n=this.parent?.opts(),r={...n,...t,projectRoot:Z(t.projectRoot||n?.projectRoot)},i=new si(r.json||!1);try{let t=oe.safeParse(e);t.success||(i.error(`Invalid task ID format`,{taskId:e,error:t.error.issues[0]?.message}),process.exit(1));let n=t.data,a=r.projectRoot,o=await I({projectPath:a});await o.workflow.hasWorkflow()&&!r.force&&(i.error(`Workflow state already exists. Use --force to overwrite or resume with "autopilot resume"`),process.exit(1));let s=o.config.getActiveTag(),c=o.auth.getContext()?.orgSlug;i.info(`Loading task ${n}...`);let{task:l}=await o.tasks.get(n);l||(i.error(`Task not found`,{taskId:n}),process.exit(1)),(!l.subtasks||l.subtasks.length===0)&&(i.error(`Task has no subtasks. Expand task first.`,{taskId:n,suggestion:`Run: task-master expand --id=${n}`}),process.exit(1));let u=parseInt(r.maxAttempts||`3`,10);i.info(`Starting TDD workflow...`);let d=await o.workflow.start({taskId:n,taskTitle:l.title,subtasks:l.subtasks.map(e=>({id:e.id,title:e.title,status:e.status,maxAttempts:u})),maxAttempts:u,force:r.force,tag:s,orgSlug:c});i.success(`TDD workflow started`,{taskId:d.taskId,title:l.title,phase:d.phase,tddPhase:d.tddPhase,branchName:d.branchName,subtasks:l.subtasks.length,currentSubtask:d.currentSubtask?.title})}catch(e){i.error(e.message),r.verbose&&console.error(e.stack),process.exit(1)}}},hi=class extends G{constructor(){super(`status`),this.description(`Show current TDD workflow status and progress`).action(async e=>{await this.execute(e)})}async execute(e){let t=this.parent?.opts(),n={...t,...e,projectRoot:Z(e.projectRoot||t?.projectRoot)},r=new si(n.json||!1);try{let e=n.projectRoot,t=await I({projectPath:e});if(!await t.workflow.hasWorkflow()){n.json?r.output({active:!1,message:`No active workflow`}):(r.info(`No active workflow`),console.log(`Start a workflow with: autopilot start <taskId>`));return}await t.workflow.resume();let i=t.workflow.getStatus(),a=t.workflow.getContext(),o={taskId:i.taskId,phase:i.phase,tddPhase:i.tddPhase,branchName:i.branchName,progress:i.progress,currentSubtask:i.currentSubtask?{id:i.currentSubtask.id,title:i.currentSubtask.title,attempts:i.currentSubtask.attempts,maxAttempts:i.currentSubtask.maxAttempts}:null,subtasks:a.subtasks.map(e=>({id:e.id,title:e.title,status:e.status,attempts:e.attempts})),errors:a.errors&&a.errors.length>0?a.errors:void 0,metadata:a.metadata};n.json?r.output(o):r.success(`Workflow status`,o)}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},gi=class e extends G{constructor(){super(`autopilot`),this.description(`AI agent orchestration for TDD workflow execution`).alias(`ap`).option(`--json`,`Output in JSON format for machine parsing`).option(`-v, --verbose`,`Enable verbose output`).option(`-e, --executor <executor>`,`Execution backend (claude|codex)`).option(`-p, --project-root <path>`,`Project root directory (auto-detected if not specified)`),this.registerSubcommands()}registerSubcommands(){this.addCommand(new mi),this.addCommand(new pi),this.addCommand(new fi),this.addCommand(new ui),this.addCommand(new li),this.addCommand(new hi),this.addCommand(new di),this.addCommand(new ci)}static register(t){let n=new e;return t.addCommand(n),n}},_i=class e extends G{tmCore;lastResult;constructor(e){super(e||`generate`),this.description(`Generate individual task files from tasks.json`).option(`-t, --tag <tag>`,`Tag context for task operations`).option(`-o, --output <dir>`,`Output directory for generated files (defaults to .taskmaster/tasks)`).option(`-p, --project <path>`,`Project root directory (auto-detected if not provided)`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).action(async e=>{await this.executeCommand(e)})}async executeCommand(e){let t=!1;try{this.validateOptions(e);let t=Z(e.project);await this.initializeCore(t);let n=await this.generateFiles(t,e);this.lastResult=n,this.displayResults(n,e)}catch(e){t=!0,X(e,{skipExit:!0})}finally{await this.cleanup()}t&&process.exit(1)}validateOptions(e){if(e.format&&![`text`,`json`].includes(e.format))throw Error(`Invalid format: ${e.format}. Valid formats are: text, json`)}async initializeCore(e){this.tmCore||=await I({projectPath:We.resolve(e)})}async generateFiles(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=t.output?We.resolve(e,t.output):void 0;return this.tmCore.tasks.generateTaskFiles({tag:t.tag,outputDir:n})}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;case`text`:default:this.displayText(e,t);break}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e,t){if(this.tmCore){let e=this.tmCore.tasks.getStorageType(),n=t.tag||this.tmCore.config.getActiveTag();Pn(this.tmCore,{tag:n,storageType:e})}if(!e.success){console.log(W(B.red(`Error: ${e.error||`Unknown error`}`),{padding:1,borderStyle:`round`,borderColor:`red`,title:`❌ GENERATION FAILED`,titleAlignment:`center`}));return}if(e.count===0){console.log(W(B.yellow(`No tasks found to generate files for.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`⚠️ NO TASKS`,titleAlignment:`center`}));return}let n=`${B.green(`✓`)} Generated ${B.cyan(e.count)} task file(s)`;n+=`\n\n${B.dim(`Output directory:`)} ${e.directory}`,e.orphanedFilesRemoved>0&&(n+=`\n${B.dim(`Orphaned files removed:`)} ${e.orphanedFilesRemoved}`),console.log(W(n,{padding:1,borderStyle:`round`,borderColor:`green`,title:`📄 TASK FILES GENERATED`,titleAlignment:`center`}))}getLastResult(){return this.lastResult}async cleanup(){this.tmCore&&=void 0}static register(t,n){let r=new e(n);return t.addCommand(r),r}},vi=class e extends G{authCommand;constructor(e){super(e||`login`),this.authCommand=new er,this.description(`Login to Hamster (alias for "auth login")`),this.argument(`[token]`,`Authentication token (optional, for SSH/remote environments)`),this.option(`-y, --yes`,`Skip interactive prompts`),this.addHelpText(`after`,`
235
235
  Examples:
236
236
  $ tm login # Browser-based OAuth flow (interactive)
237
237
  $ tm login <token> # Token-based authentication
238
238
  $ tm login <token> -y # Non-interactive token auth (for scripts)
239
- `),this.action(async(e,t)=>{await this.authCommand.executeLogin(e,t?.yes,!0)})}static register(t){let n=new e;return t.addCommand(n),n}},_i=class e extends G{authCommand;constructor(e){super(e||`logout`),this.authCommand=new Qn,this.description(`Logout from Hamster (alias for "auth logout")`),this.addHelpText(`after`,`
239
+ `),this.action(async(e,t)=>{await this.authCommand.executeLogin(e,t?.yes,!0)})}static register(t){let n=new e;return t.addCommand(n),n}},yi=class e extends G{authCommand;constructor(e){super(e||`logout`),this.authCommand=new er,this.description(`Logout from Hamster (alias for "auth logout")`),this.addHelpText(`after`,`
240
240
  Examples:
241
241
  $ tm logout # Clear credentials and logout
242
- `),this.action(async()=>{await this.authCommand.executeLogout()})}static register(t){let n=new e;return t.addCommand(n),n}},vi=class{static commands=[{name:`list`,description:`List all tasks with filtering and status overview`,commandClass:Pn,category:`task`},{name:`show`,description:`Display detailed information about a specific task`,commandClass:Fn,category:`task`},{name:`next`,description:`Find the next available task to work on`,commandClass:In,category:`task`},{name:`start`,description:`Start working on a task with a coding agent CLI`,commandClass:$n,category:`task`},{name:`set-status`,description:`Update the status of one or more tasks`,commandClass:tr,category:`task`},{name:`export`,description:`Export tasks to Hamster by creating a new brief`,commandClass:fr,category:`task`},{name:`export-tag`,description:`Export a specific tag to Hamster`,commandClass:pr,category:`task`},{name:`autopilot`,description:`AI agent orchestration for TDD workflow (start, resume, next, complete, commit, status, abort)`,commandClass:mi,category:`development`},{name:`loop`,description:`Run coding agent CLI in a loop, one task per iteration`,commandClass:ii,category:`development`},{name:`auth`,description:`Manage authentication with tryhamster.com`,commandClass:Qn,category:`auth`},{name:`login`,description:`Login to Hamster (alias for "auth login")`,commandClass:gi,category:`auth`},{name:`logout`,description:`Logout from Hamster (alias for "auth logout")`,commandClass:_i,category:`auth`},{name:`context`,description:`Manage workspace context (organization/brief)`,commandClass:Zn,category:`auth`},{name:`tags`,description:`Manage tags for task organization`,commandClass:ni,category:`task`},{name:`briefs`,description:`Manage briefs (Hamster only)`,commandClass:ri,category:`task`},{name:`generate`,description:`Generate individual task files from tasks.json`,commandClass:hi,category:`utility`}];static registerAll(e){for(let t of this.commands)this.registerCommand(e,t)}static registerByCategory(e,t){let n=this.commands.filter(e=>e.category===t);for(let t of n)this.registerCommand(e,t)}static registerByName(e,t){let n=this.commands.find(e=>e.name===t);if(n)this.registerCommand(e,n);else throw Error(`Command '${t}' not found in registry`)}static registerCommand(e,t){let n=t.commandClass;if(n.registerOn)n.registerOn(e);else if(n.register)n.register(e);else{let t=new n;e.addCommand(t)}}static getCommandNames(){return this.commands.map(e=>e.name)}static getCommandsByCategory(e){return this.commands.filter(t=>t.category===e)}static addCommand(e){if(this.commands.some(t=>t.name===e.name))throw Error(`Command '${e.name}' already exists in registry`);this.commands.push(e)}static removeCommand(e){let t=this.commands.findIndex(t=>t.name===e);return t>=0?(this.commands.splice(t,1),!0):!1}static getCommand(e){return this.commands.find(t=>t.name===e)}static hasCommand(e){return this.commands.some(t=>t.name===e)}static getFormattedCommandList(){let e={task:`Task Management`,auth:`Authentication & Context`,utility:`Utilities`,development:`Development`},t=``;for(let[n,r]of Object.entries(e)){let e=this.getCommandsByCategory(n);if(e.length>0){t+=`\n${r}:\n`;for(let n of e)t+=` ${n.name.padEnd(20)} ${n.description}\n`}}return t}};function yi(e){vi.registerAll(e)}async function bi(){return new Promise(e=>{let t=pt.request({hostname:`openrouter.ai`,path:`/api/v1/models`,method:`GET`,headers:{Accept:`application/json`}},t=>{let n=``;t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{if(t.statusCode===200)try{e({success:!0,data:JSON.parse(n).data||[]})}catch{e({success:!1,error:`Failed to parse OpenRouter response`})}else e({success:!1,error:`OpenRouter API returned status ${t.statusCode}`})})});t.on(`error`,t=>{e({success:!1,error:`Failed to fetch OpenRouter models: ${t.message}`})}),t.end()})}async function xi(e=`http://localhost:11434/api`){return new Promise(t=>{try{let n=new URL(e),r=n.protocol===`https:`,i=n.port||(r?443:80),a=n.pathname.endsWith(`/`)?n.pathname.slice(0,-1):n.pathname,o={hostname:n.hostname,port:parseInt(String(i),10),path:`${a}/tags`,method:`GET`,headers:{Accept:`application/json`}},s=(r?pt:ht).request(o,e=>{let n=``;e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{if(e.statusCode===200)try{t({success:!0,data:JSON.parse(n).models||[]})}catch{t({success:!1,error:`Failed to parse Ollama response`})}else t({success:!1,error:`Ollama API returned status ${e.statusCode}`})})});s.on(`error`,e=>{t({success:!1,error:`Failed to connect to Ollama: ${e.message}`})}),s.end()}catch(e){t({success:!1,error:`Invalid Ollama base URL: ${e instanceof Error?e.message:`Unknown error`}`})}})}async function Si(e){let t=await bi();return!t.success||!t.data?!1:t.data.some(t=>t.id===e)}async function Ci(e,t){let n=await xi(t);return!n.success||!n.data?!1:n.data.some(t=>t.model===e)}const wi=`The configuration file is missing. Run "task-master init" to create it.`;function Ti(){return new Promise(e=>{let t=pt.request({hostname:`openrouter.ai`,path:`/api/v1/models`,method:`GET`,headers:{Accept:`application/json`}},t=>{let n=``;t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{if(t.statusCode===200)try{e(JSON.parse(n).data||[])}catch(t){console.error(`Error parsing OpenRouter response:`,t),e(null)}else console.error(`OpenRouter API request failed with status code: ${t.statusCode}`),e(null)})});t.on(`error`,t=>{console.error(`Error fetching OpenRouter models:`,t),e(null)}),t.end()})}function Ei(e=`http://localhost:11434/api`){return new Promise(t=>{try{let n=new URL(e),r=n.protocol===`https:`,i=n.port||(r?443:80),a=n.pathname.endsWith(`/`)?n.pathname.slice(0,-1):n.pathname,o={hostname:n.hostname,port:parseInt(i,10),path:`${a}/tags`,method:`GET`,headers:{Accept:`application/json`}},s=(r?pt:ht).request(o,e=>{let n=``;e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{if(e.statusCode===200)try{t(JSON.parse(n).models||[])}catch(e){console.error(`Error parsing Ollama response:`,e),t(null)}else console.error(`Ollama API request failed with status code: ${e.statusCode}`),t(null)})});s.on(`error`,e=>{console.error(`Error fetching Ollama models:`,e),t(null)}),s.end()}catch(e){console.error(`Error parsing Ollama base URL:`,e),t(null)}})}async function Di(e={}){let{mcpLog:t,projectRoot:n,session:r}=e,i=(e,...n)=>{t&&typeof t[e]==`function`&&t[e](...n)};if(!n)throw Error(`Project root is required but not found.`);let a=O(null,{projectRoot:n}),s=c(n);if(z(`debug`,`Checking for config file using findConfigPath, found: ${a}`),z(`debug`,`Checking config file using isConfigFilePresent(), exists: ${s}`),!s)throw Error(wi);try{let e=u(n),t=T(n),i=ke(`main`,n),a=be(n),s=o(n),c=ke(`research`,n),l=Be(n),d=P(n),f=ke(`fallback`,n),p=C(e,r,n),m=He(e,n),h=C(a,r,n),g=He(a,n),_=l?C(l,r,n):!0,v=l?He(l,n):!0,y=ve(n),b=y.find(e=>e.id===t),x=y.find(e=>e.id===s),S=d?y.find(e=>e.id===d):null;return{success:!0,data:{activeModels:{main:{provider:e,modelId:t,baseURL:i,sweScore:b?.swe_score||null,cost:b?.cost_per_1m_tokens||null,keyStatus:{cli:p,mcp:m}},research:{provider:a,modelId:s,baseURL:c,sweScore:x?.swe_score||null,cost:x?.cost_per_1m_tokens||null,keyStatus:{cli:h,mcp:g}},fallback:l?{provider:l,modelId:d,baseURL:f,sweScore:S?.swe_score||null,cost:S?.cost_per_1m_tokens||null,keyStatus:{cli:_,mcp:v}}:null},message:`Successfully retrieved current model configuration`}}}catch(e){return i(`error`,`Error getting model configuration: ${e.message}`),{success:!1,error:{code:`CONFIG_ERROR`,message:e.message}}}}async function Oi(e={}){let{mcpLog:t,projectRoot:n}=e,r=(e,...n)=>{t&&typeof t[e]==`function`&&t[e](...n)};if(!n)throw Error(`Project root is required but not found.`);let i=O(null,{projectRoot:n}),a=c(n);if(z(`debug`,`Checking for config file using findConfigPath, found: ${i}`),z(`debug`,`Checking config file using isConfigFilePresent(), exists: ${a}`),!a)throw Error(wi);try{let e=ve(n);if(!e||e.length===0)return{success:!0,data:{models:[],message:`No available models found`}};[T(n),o(n),P(n)].filter(Boolean);let t=e.map(e=>({provider:e.provider||`N/A`,modelId:e.id,sweScore:e.swe_score||null,cost:e.cost_per_1m_tokens||null,allowedRoles:e.allowed_roles||[]}));return{success:!0,data:{models:t,message:`Successfully retrieved ${t.length} available models`}}}catch(e){return r(`error`,`Error getting available models: ${e.message}`),{success:!1,error:{code:`MODELS_LIST_ERROR`,message:e.message}}}}async function ki(e,t,n={}){let{mcpLog:r,projectRoot:i,providerHint:a,baseURL:o}=n,s=o,l=(e,...t)=>{r&&typeof r[e]==`function`&&r[e](...t)};if(!i)throw Error(`Project root is required but not found.`);let d=O(null,{projectRoot:i}),f=c(i);if(z(`debug`,`Checking for config file using findConfigPath, found: ${d}`),z(`debug`,`Checking config file using isConfigFilePresent(), exists: ${f}`),!f)throw Error(wi);if(![`main`,`research`,`fallback`].includes(e))return{success:!1,error:{code:`INVALID_ROLE`,message:`Invalid role: ${e}. Must be one of: main, research, fallback.`}};if(typeof t!=`string`||t.trim()===``)return{success:!1,error:{code:`INVALID_MODEL_ID`,message:`Invalid model ID: ${t}. Must be a non-empty string.`}};try{let n=ve(i),r=le(i),c=null,d=null,f;if(f=a?n.find(e=>e.id===t&&e.provider===a):n.find(e=>e.id===t),a)if(f&&f.provider===a)c=a,l(`info`,`Model ${t} found internally with provider ${c}.`);else if(a===R.OPENROUTER){l(`info`,`Checking OpenRouter for ${t} (as hinted)...`);let e=await Ti();if(e&&e.some(e=>e.id===t))c=R.OPENROUTER,d=t.endsWith(`:free`)?`Warning: OpenRouter free model '${t}' selected. Free models have significant limitations including lower context windows, reduced rate limits, and may not support advanced features like tool_use. Consider using the paid version '${t.replace(`:free`,``)}' for full functionality.`:`Warning: Custom OpenRouter model '${t}' set. This model is not officially validated by Taskmaster and may not function as expected.`,l(`warn`,d);else throw Error(`Model ID "${t}" not found in the live OpenRouter model list. Please verify the ID and ensure it's available on OpenRouter.`)}else if(a===R.OLLAMA){l(`info`,`Checking Ollama for ${t} (as hinted)...`);let n;e===`main`?n=u(i):e===`research`?n=be(i):e===`fallback`&&(n=Be(i));let r=n===R.OLLAMA?ke(e,i):null,a=o||r||`http://localhost:11434/api`,f=await Ei(a);if(f===null)throw Error(`Unable to connect to Ollama server at ${a}. Please ensure Ollama is running and try again.`);if(f.some(e=>e.model===t))c=R.OLLAMA,d=`Warning: Custom Ollama model '${t}' set. Ensure your Ollama server is running and has pulled this model. Taskmaster cannot guarantee compatibility.`,l(`warn`,d),s=a;else{let e=`${a}/tags`;throw Error(`Model ID "${t}" not found in the Ollama instance. Please verify the model is pulled and available. You can check available models with: curl ${e}`)}}else if(a===R.BEDROCK)c=R.BEDROCK,d=`Warning: Custom Bedrock model '${t}' set. Please ensure the model ID is valid and accessible in your AWS account.`,l(`warn`,d);else if(a===R.CLAUDE_CODE){c=R.CLAUDE_CODE;let e=n.filter(e=>e.provider===`claude-code`).find(e=>e.id===t);e?(f=e,l(`info`,`Setting Claude Code model '${t}'.`)):(d=`Warning: Claude Code model '${t}' not found in supported models. Setting without validation.`,l(`warn`,d))}else if(a===R.AZURE){c=R.AZURE;let n;e===`main`?n=u(i):e===`research`?n=be(i):e===`fallback`&&(n=Be(i));let r=n===R.AZURE?ke(e,i):null,a=o||r;if(!a)throw Error(`Base URL is required for Azure providers. Please provide a baseURL or set global.azureBaseURL in config.`);d=`Warning: Custom Azure model '${t}' set with base URL '${a}'. Please ensure the model deployment is valid and accessible in your Azure account.`,l(`warn`,d),s=a}else if(a===R.VERTEX)c=R.VERTEX,d=`Warning: Custom Vertex AI model '${t}' set. Please ensure the model is valid and accessible in your Google Cloud project.`,l(`warn`,d);else if(a===R.GEMINI_CLI){c=R.GEMINI_CLI;let e=n.filter(e=>e.provider===`gemini-cli`).find(e=>e.id===t);e?(f=e,l(`info`,`Setting Gemini CLI model '${t}'.`)):(d=`Warning: Gemini CLI model '${t}' not found in supported models. Setting without validation.`,l(`warn`,d))}else if(a===R.CODEX_CLI){c=R.CODEX_CLI;let e=n.filter(e=>e.provider===`codex-cli`).find(e=>e.id===t);e?(f=e,l(`info`,`Setting Codex CLI model '${t}'.`)):(d=`Warning: Codex CLI model '${t}' not found in supported models. Setting without validation.`,l(`warn`,d))}else if(a===R.LMSTUDIO){c=R.LMSTUDIO;let n;e===`main`?n=u(i):e===`research`?n=be(i):e===`fallback`&&(n=Be(i));let r=n===R.LMSTUDIO?ke(e,i):null,a=o||r||`http://localhost:1234/v1`;d=`Warning: Custom LM Studio model '${t}' set with base URL '${a}'. Please ensure LM Studio server is running and has loaded this model. Taskmaster cannot guarantee compatibility.`,l(`warn`,d),s=a}else if(a===R.OPENAI_COMPATIBLE){c=R.OPENAI_COMPATIBLE;let n;e===`main`?n=u(i):e===`research`?n=be(i):e===`fallback`&&(n=Be(i));let r=n===R.OPENAI_COMPATIBLE?ke(e,i):null,a=o||r;if(!a)throw Error(`Base URL is required for OpenAI-compatible providers. Please provide a baseURL.`);d=`Warning: Custom OpenAI-compatible model '${t}' set with base URL '${a}'. Taskmaster cannot guarantee compatibility. Ensure your API endpoint follows the OpenAI API specification.`,l(`warn`,d),s=a}else throw Error(`Invalid provider hint received: ${a}`);else if(f)c=f.provider,l(`info`,`Model ${t} found internally with provider ${c}.`);else return{success:!1,error:{code:`MODEL_NOT_FOUND_NO_HINT`,message:`Model ID "${t}" not found in Taskmaster's supported models. If this is a custom model, please specify the provider using --openrouter, --ollama, --bedrock, --azure, --vertex, --lmstudio, --openai-compatible, --gemini-cli, or --codex-cli.`}};if(!c)return{success:!1,error:{code:`PROVIDER_UNDETERMINED`,message:`Could not determine the provider for model ID "${t}".`}};if(r.models[e]={...r.models[e],provider:c,modelId:t},s&&(c===R.OPENAI_COMPATIBLE||c===R.LMSTUDIO||c===R.OLLAMA||c===R.AZURE)?r.models[e].baseURL=s:delete r.models[e].baseURL,f&&f.max_tokens&&(r.models[e].maxTokens=f.max_tokens),!Pe(r,i))return{success:!1,error:{code:`CONFIG_WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}};let p=`Successfully set ${e} model to ${t} (Provider: ${c})`;return l(`info`,p),{success:!0,data:{role:e,provider:c,modelId:t,message:p,warning:d}}}catch(t){return l(`error`,`Error setting ${e} model: ${t.message}`),{success:!1,error:{code:`SET_MODEL_ERROR`,message:t.message}}}}async function Ai(e={}){let{mcpLog:t,projectRoot:n,session:r}=e,i=(e,...n)=>{t&&typeof t[e]==`function`&&t[e](...n)};try{let e=De().filter(e=>e.toLowerCase()!==`ollama`).map(e=>({provider:e,cli:C(e,r,n),mcp:He(e,n)}));return i(`info`,`Successfully generated API key status report.`),{success:!0,data:{report:e,message:`API key status report generated.`}}}catch(e){return i(`error`,`Error generating API key status report: ${e.message}`),{success:!1,error:{code:`API_KEY_STATUS_ERROR`,message:e.message}}}}async function ji(e){return Di(e)}async function Mi(e,t,n){return ki(e,t,n)}function Ni(e){return le(e)}function Pi(e,t){return Pe(e,t)}function Fi(){return ve()}function Ii(e){return te(e)??``}const Li={OPENROUTER:{id:`__CUSTOM_OPENROUTER__`,name:`* Custom OpenRouter model`,provider:R.OPENROUTER,promptMessage:e=>`Enter the custom OpenRouter Model ID for the ${e} role:`,validate:async e=>{let t=await Si(e);return t||console.error(B.red(`Error: Model ID "${e}" not found in the live OpenRouter model list. Please check the ID.`)),t}},OLLAMA:{id:`__CUSTOM_OLLAMA__`,name:`* Custom Ollama model`,provider:R.OLLAMA,requiresBaseURL:!0,defaultBaseURL:`http://localhost:11434/api`,promptMessage:e=>`Enter the custom Ollama Model ID for the ${e} role:`,validate:async(e,t)=>{let n=t||`http://localhost:11434/api`,r=await Ci(e,n);return r||(console.error(B.red(`Error: Model ID "${e}" not found in the Ollama instance. Please verify the model is pulled and available.`)),console.log(B.yellow(`You can check available models with: curl ${n}/tags`))),r}},BEDROCK:{id:`__CUSTOM_BEDROCK__`,name:`* Custom Bedrock model`,provider:R.BEDROCK,promptMessage:e=>`Enter the custom Bedrock Model ID for the ${e} role (e.g., anthropic.claude-3-sonnet-20240229-v1:0):`,checkEnvVars:()=>((!process.env.AWS_ACCESS_KEY_ID||!process.env.AWS_SECRET_ACCESS_KEY)&&console.warn(B.yellow(`Warning: AWS_ACCESS_KEY_ID and/or AWS_SECRET_ACCESS_KEY environment variables are missing. Will fallback to system configuration (ex: aws config files or ec2 instance profiles).`)),!0)},AZURE:{id:`__CUSTOM_AZURE__`,name:`* Custom Azure OpenAI model`,provider:R.AZURE,requiresBaseURL:!0,promptMessage:e=>`Enter the Azure deployment name for the ${e} role (e.g., gpt-4o):`,checkEnvVars:()=>process.env.AZURE_OPENAI_API_KEY?!0:(console.error(B.red(`Error: AZURE_OPENAI_API_KEY environment variable is missing. Please set it before using Azure models.`)),!1)},VERTEX:{id:`__CUSTOM_VERTEX__`,name:`* Custom Vertex model`,provider:R.VERTEX,promptMessage:e=>`Enter the custom Vertex AI Model ID for the ${e} role (e.g., gemini-1.5-pro-002):`,checkEnvVars:()=>!process.env.GOOGLE_API_KEY&&!process.env.GOOGLE_APPLICATION_CREDENTIALS?(console.error(B.red(`Error: Either GOOGLE_API_KEY or GOOGLE_APPLICATION_CREDENTIALS environment variable is required. Please set one before using custom Vertex models.`)),!1):!0},LMSTUDIO:{id:`__CUSTOM_LMSTUDIO__`,name:`* Custom LMStudio model`,provider:R.LMSTUDIO,requiresBaseURL:!0,defaultBaseURL:`http://localhost:1234/v1`,promptMessage:e=>`Enter the custom LM Studio Model ID for the ${e} role:`,checkEnvVars:()=>(console.log(B.blue(`Note: LM Studio runs locally. Make sure the LM Studio server is running.`)),!0)},OPENAI_COMPATIBLE:{id:`__CUSTOM_OPENAI_COMPATIBLE__`,name:`* Custom OpenAI-compatible model`,provider:R.OPENAI_COMPATIBLE,promptMessage:e=>`Enter the custom OpenAI-compatible Model ID for the ${e} role:`,requiresBaseURL:!0,checkEnvVars:()=>(console.log(B.blue(`Note: This will configure a generic OpenAI-compatible provider. Make sure your API endpoint is accessible.`)),!0)}};async function Ri(e,t,n=null,r){let i=Object.entries(Li).find(([t,n])=>n.id===e);if(!i)return console.error(B.red(`Unknown custom provider: ${e}`)),{modelId:null,provider:null,success:!1};let a=i[1];if(a.checkEnvVars&&!a.checkEnvVars())return{modelId:null,provider:null,success:!1};let o=null;if(a.requiresBaseURL){let e;e=n?.provider===a.provider&&n?.baseURL?n.baseURL:a.provider===R.AZURE&&r?Ii(r)||``:a.defaultBaseURL||``,o=(await q.prompt([{type:`input`,name:`baseURL`,message:`Enter the base URL for the ${t} role:`,default:e,validate:e=>{if(!e||e.trim()===``)return`Base URL is required for ${a.provider} providers`;try{return new URL(e),!0}catch{return`Please enter a valid URL`}}}])).baseURL}let{customId:s}=await q.prompt([{type:`input`,name:`customId`,message:a.promptMessage(t)}]);if(!s)return console.log(B.yellow(`No custom ID entered. Skipping role.`)),{modelId:null,provider:null,success:!0};if(a.validate){if(!await a.validate(s,o||void 0))return{modelId:null,provider:null,success:!1}}else console.log(B.blue(`Custom ${a.provider} model "${s}" will be used. No validation performed.`));return{modelId:s,provider:a.provider,baseURL:o,success:!0}}function zi(){return Object.values(Li).map(e=>({name:e.name,value:e.id,short:e.name}))}function Bi(e,t,n=!1){let r=t[e],i=Fi().filter(e=>!!e.provider).reduce((e,t)=>(e[t.provider]||(e[t.provider]=[]),e[t.provider].push(t),e),{}),a=[],o={name:`⏹ Cancel Model Setup`,value:`__CANCEL__`,short:`Cancel`},s=r?.modelId&&r?.provider?{name:`✔ No change to current ${e} model (${r.provider}/${r.modelId})`,value:`__NO_CHANGE__`,short:`No change`}:null;s&&a.push(s),a.push(o);let c=Object.entries(i).flatMap(([t,n])=>n.filter(t=>t.allowed_roles&&t.allowed_roles.includes(e)).map(e=>{let n=e.name||e.id;return{name:`${t} / ${n} ${e.cost_per_1m_tokens?B.gray(`($${e.cost_per_1m_tokens.input.toFixed(2)} input | $${e.cost_per_1m_tokens.output.toFixed(2)} output)`):``}`,value:{id:e.id,provider:t},short:`${t}/${n}`}})).filter(e=>e!==null),l=-1;r?.modelId&&r?.provider&&(l=c.findIndex(e=>typeof e.value==`object`&&e.value!==null&&`id`in e.value&&e.value.id===r.modelId&&e.value.provider===r.provider));let u=zi(),d=a.length,f,p;if(n){f=[...a,new dt(`
242
+ `),this.action(async()=>{await this.authCommand.executeLogout()})}static register(t){let n=new e;return t.addCommand(n),n}},bi=class{static commands=[{name:`list`,description:`List all tasks with filtering and status overview`,commandClass:In,category:`task`},{name:`show`,description:`Display detailed information about a specific task`,commandClass:Ln,category:`task`},{name:`next`,description:`Find the next available task to work on`,commandClass:Rn,category:`task`},{name:`start`,description:`Start working on a task with a coding agent CLI`,commandClass:tr,category:`task`},{name:`set-status`,description:`Update the status of one or more tasks`,commandClass:rr,category:`task`},{name:`export`,description:`Export tasks to Hamster by creating a new brief`,commandClass:mr,category:`task`},{name:`export-tag`,description:`Export a specific tag to Hamster`,commandClass:hr,category:`task`},{name:`autopilot`,description:`AI agent orchestration for TDD workflow (start, resume, next, complete, commit, status, abort)`,commandClass:gi,category:`development`},{name:`loop`,description:`Run coding agent CLI in a loop, one task per iteration`,commandClass:oi,category:`development`},{name:`auth`,description:`Manage authentication with tryhamster.com`,commandClass:er,category:`auth`},{name:`login`,description:`Login to Hamster (alias for "auth login")`,commandClass:vi,category:`auth`},{name:`logout`,description:`Logout from Hamster (alias for "auth logout")`,commandClass:yi,category:`auth`},{name:`context`,description:`Manage workspace context (organization/brief)`,commandClass:$n,category:`auth`},{name:`tags`,description:`Manage tags for task organization`,commandClass:ii,category:`task`},{name:`briefs`,description:`Manage briefs (Hamster only)`,commandClass:ai,category:`task`},{name:`generate`,description:`Generate individual task files from tasks.json`,commandClass:_i,category:`utility`}];static registerAll(e){for(let t of this.commands)this.registerCommand(e,t)}static registerByCategory(e,t){let n=this.commands.filter(e=>e.category===t);for(let t of n)this.registerCommand(e,t)}static registerByName(e,t){let n=this.commands.find(e=>e.name===t);if(n)this.registerCommand(e,n);else throw Error(`Command '${t}' not found in registry`)}static registerCommand(e,t){let n=t.commandClass;if(n.registerOn)n.registerOn(e);else if(n.register)n.register(e);else{let t=new n;e.addCommand(t)}}static getCommandNames(){return this.commands.map(e=>e.name)}static getCommandsByCategory(e){return this.commands.filter(t=>t.category===e)}static addCommand(e){if(this.commands.some(t=>t.name===e.name))throw Error(`Command '${e.name}' already exists in registry`);this.commands.push(e)}static removeCommand(e){let t=this.commands.findIndex(t=>t.name===e);return t>=0?(this.commands.splice(t,1),!0):!1}static getCommand(e){return this.commands.find(t=>t.name===e)}static hasCommand(e){return this.commands.some(t=>t.name===e)}static getFormattedCommandList(){let e={task:`Task Management`,auth:`Authentication & Context`,utility:`Utilities`,development:`Development`},t=``;for(let[n,r]of Object.entries(e)){let e=this.getCommandsByCategory(n);if(e.length>0){t+=`\n${r}:\n`;for(let n of e)t+=` ${n.name.padEnd(20)} ${n.description}\n`}}return t}};function xi(e){bi.registerAll(e)}async function Si(){return new Promise(e=>{let t=pt.request({hostname:`openrouter.ai`,path:`/api/v1/models`,method:`GET`,headers:{Accept:`application/json`}},t=>{let n=``;t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{if(t.statusCode===200)try{e({success:!0,data:JSON.parse(n).data||[]})}catch{e({success:!1,error:`Failed to parse OpenRouter response`})}else e({success:!1,error:`OpenRouter API returned status ${t.statusCode}`})})});t.on(`error`,t=>{e({success:!1,error:`Failed to fetch OpenRouter models: ${t.message}`})}),t.end()})}async function Ci(e=`http://localhost:11434/api`){return new Promise(t=>{try{let n=new URL(e),r=n.protocol===`https:`,i=n.port||(r?443:80),a=n.pathname.endsWith(`/`)?n.pathname.slice(0,-1):n.pathname,o={hostname:n.hostname,port:parseInt(String(i),10),path:`${a}/tags`,method:`GET`,headers:{Accept:`application/json`}},s=(r?pt:ht).request(o,e=>{let n=``;e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{if(e.statusCode===200)try{t({success:!0,data:JSON.parse(n).models||[]})}catch{t({success:!1,error:`Failed to parse Ollama response`})}else t({success:!1,error:`Ollama API returned status ${e.statusCode}`})})});s.on(`error`,e=>{t({success:!1,error:`Failed to connect to Ollama: ${e.message}`})}),s.end()}catch(e){t({success:!1,error:`Invalid Ollama base URL: ${e instanceof Error?e.message:`Unknown error`}`})}})}async function wi(e){let t=await Si();return!t.success||!t.data?!1:t.data.some(t=>t.id===e)}async function Ti(e,t){let n=await Ci(t);return!n.success||!n.data?!1:n.data.some(t=>t.model===e)}const Ei=`The configuration file is missing. Run "task-master init" to create it.`;function Di(){return new Promise(e=>{let t=pt.request({hostname:`openrouter.ai`,path:`/api/v1/models`,method:`GET`,headers:{Accept:`application/json`}},t=>{let n=``;t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{if(t.statusCode===200)try{e(JSON.parse(n).data||[])}catch(t){console.error(`Error parsing OpenRouter response:`,t),e(null)}else console.error(`OpenRouter API request failed with status code: ${t.statusCode}`),e(null)})});t.on(`error`,t=>{console.error(`Error fetching OpenRouter models:`,t),e(null)}),t.end()})}function Oi(e=`http://localhost:11434/api`){return new Promise(t=>{try{let n=new URL(e),r=n.protocol===`https:`,i=n.port||(r?443:80),a=n.pathname.endsWith(`/`)?n.pathname.slice(0,-1):n.pathname,o={hostname:n.hostname,port:parseInt(i,10),path:`${a}/tags`,method:`GET`,headers:{Accept:`application/json`}},s=(r?pt:ht).request(o,e=>{let n=``;e.on(`data`,e=>{n+=e}),e.on(`end`,()=>{if(e.statusCode===200)try{t(JSON.parse(n).models||[])}catch(e){console.error(`Error parsing Ollama response:`,e),t(null)}else console.error(`Ollama API request failed with status code: ${e.statusCode}`),t(null)})});s.on(`error`,e=>{console.error(`Error fetching Ollama models:`,e),t(null)}),s.end()}catch(e){console.error(`Error parsing Ollama base URL:`,e),t(null)}})}async function ki(e={}){let{mcpLog:t,projectRoot:n,session:r}=e,i=(e,...n)=>{t&&typeof t[e]==`function`&&t[e](...n)};if(!n)throw Error(`Project root is required but not found.`);let a=D(null,{projectRoot:n}),s=c(n);if(z(`debug`,`Checking for config file using findConfigPath, found: ${a}`),z(`debug`,`Checking config file using isConfigFilePresent(), exists: ${s}`),!s)throw Error(Ei);try{let e=u(n),t=w(n),i=De(`main`,n),a=ye(n),s=o(n),c=De(`research`,n),l=Re(n),d=N(n),f=De(`fallback`,n),p=S(e,r,n),m=Be(e,n),h=S(a,r,n),g=Be(a,n),_=l?S(l,r,n):!0,v=l?Be(l,n):!0,y=_e(n),b=y.find(e=>e.id===t),x=y.find(e=>e.id===s),C=d?y.find(e=>e.id===d):null;return{success:!0,data:{activeModels:{main:{provider:e,modelId:t,baseURL:i,sweScore:b?.swe_score||null,cost:b?.cost_per_1m_tokens||null,keyStatus:{cli:p,mcp:m}},research:{provider:a,modelId:s,baseURL:c,sweScore:x?.swe_score||null,cost:x?.cost_per_1m_tokens||null,keyStatus:{cli:h,mcp:g}},fallback:l?{provider:l,modelId:d,baseURL:f,sweScore:C?.swe_score||null,cost:C?.cost_per_1m_tokens||null,keyStatus:{cli:_,mcp:v}}:null},message:`Successfully retrieved current model configuration`}}}catch(e){return i(`error`,`Error getting model configuration: ${e.message}`),{success:!1,error:{code:`CONFIG_ERROR`,message:e.message}}}}async function Ai(e={}){let{mcpLog:t,projectRoot:n}=e,r=(e,...n)=>{t&&typeof t[e]==`function`&&t[e](...n)};if(!n)throw Error(`Project root is required but not found.`);let i=D(null,{projectRoot:n}),a=c(n);if(z(`debug`,`Checking for config file using findConfigPath, found: ${i}`),z(`debug`,`Checking config file using isConfigFilePresent(), exists: ${a}`),!a)throw Error(Ei);try{let e=_e(n);if(!e||e.length===0)return{success:!0,data:{models:[],message:`No available models found`}};[w(n),o(n),N(n)].filter(Boolean);let t=e.map(e=>({provider:e.provider||`N/A`,modelId:e.id,sweScore:e.swe_score||null,cost:e.cost_per_1m_tokens||null,allowedRoles:e.allowed_roles||[]}));return{success:!0,data:{models:t,message:`Successfully retrieved ${t.length} available models`}}}catch(e){return r(`error`,`Error getting available models: ${e.message}`),{success:!1,error:{code:`MODELS_LIST_ERROR`,message:e.message}}}}async function ji(e,t,n={}){let{mcpLog:r,projectRoot:i,providerHint:a,baseURL:o}=n,s=o,l=(e,...t)=>{r&&typeof r[e]==`function`&&r[e](...t)};if(!i)throw Error(`Project root is required but not found.`);let d=D(null,{projectRoot:i}),f=c(i);if(z(`debug`,`Checking for config file using findConfigPath, found: ${d}`),z(`debug`,`Checking config file using isConfigFilePresent(), exists: ${f}`),!f)throw Error(Ei);if(![`main`,`research`,`fallback`].includes(e))return{success:!1,error:{code:`INVALID_ROLE`,message:`Invalid role: ${e}. Must be one of: main, research, fallback.`}};if(typeof t!=`string`||t.trim()===``)return{success:!1,error:{code:`INVALID_MODEL_ID`,message:`Invalid model ID: ${t}. Must be a non-empty string.`}};try{let n=_e(i),r=ce(i),c=null,d=null,f;if(f=a?n.find(e=>e.id===t&&e.provider===a):n.find(e=>e.id===t),a)if(f&&f.provider===a)c=a,l(`info`,`Model ${t} found internally with provider ${c}.`);else if(a===R.OPENROUTER){l(`info`,`Checking OpenRouter for ${t} (as hinted)...`);let e=await Di();if(e&&e.some(e=>e.id===t))c=R.OPENROUTER,d=t.endsWith(`:free`)?`Warning: OpenRouter free model '${t}' selected. Free models have significant limitations including lower context windows, reduced rate limits, and may not support advanced features like tool_use. Consider using the paid version '${t.replace(`:free`,``)}' for full functionality.`:`Warning: Custom OpenRouter model '${t}' set. This model is not officially validated by Taskmaster and may not function as expected.`,l(`warn`,d);else throw Error(`Model ID "${t}" not found in the live OpenRouter model list. Please verify the ID and ensure it's available on OpenRouter.`)}else if(a===R.OLLAMA){l(`info`,`Checking Ollama for ${t} (as hinted)...`);let n;e===`main`?n=u(i):e===`research`?n=ye(i):e===`fallback`&&(n=Re(i));let r=n===R.OLLAMA?De(e,i):null,a=o||r||`http://localhost:11434/api`,f=await Oi(a);if(f===null)throw Error(`Unable to connect to Ollama server at ${a}. Please ensure Ollama is running and try again.`);if(f.some(e=>e.model===t))c=R.OLLAMA,d=`Warning: Custom Ollama model '${t}' set. Ensure your Ollama server is running and has pulled this model. Taskmaster cannot guarantee compatibility.`,l(`warn`,d),s=a;else{let e=`${a}/tags`;throw Error(`Model ID "${t}" not found in the Ollama instance. Please verify the model is pulled and available. You can check available models with: curl ${e}`)}}else if(a===R.BEDROCK)c=R.BEDROCK,d=`Warning: Custom Bedrock model '${t}' set. Please ensure the model ID is valid and accessible in your AWS account.`,l(`warn`,d);else if(a===R.CLAUDE_CODE){c=R.CLAUDE_CODE;let e=n.filter(e=>e.provider===`claude-code`).find(e=>e.id===t);e?(f=e,l(`info`,`Setting Claude Code model '${t}'.`)):(d=`Warning: Claude Code model '${t}' not found in supported models. Setting without validation.`,l(`warn`,d))}else if(a===R.AZURE){c=R.AZURE;let n;e===`main`?n=u(i):e===`research`?n=ye(i):e===`fallback`&&(n=Re(i));let r=n===R.AZURE?De(e,i):null,a=o||r;if(!a)throw Error(`Base URL is required for Azure providers. Please provide a baseURL or set global.azureBaseURL in config.`);d=`Warning: Custom Azure model '${t}' set with base URL '${a}'. Please ensure the model deployment is valid and accessible in your Azure account.`,l(`warn`,d),s=a}else if(a===R.VERTEX)c=R.VERTEX,d=`Warning: Custom Vertex AI model '${t}' set. Please ensure the model is valid and accessible in your Google Cloud project.`,l(`warn`,d);else if(a===R.GEMINI_CLI){c=R.GEMINI_CLI;let e=n.filter(e=>e.provider===`gemini-cli`).find(e=>e.id===t);e?(f=e,l(`info`,`Setting Gemini CLI model '${t}'.`)):(d=`Warning: Gemini CLI model '${t}' not found in supported models. Setting without validation.`,l(`warn`,d))}else if(a===R.CODEX_CLI){c=R.CODEX_CLI;let e=n.filter(e=>e.provider===`codex-cli`).find(e=>e.id===t);e?(f=e,l(`info`,`Setting Codex CLI model '${t}'.`)):(d=`Warning: Codex CLI model '${t}' not found in supported models. Setting without validation.`,l(`warn`,d))}else if(a===R.LMSTUDIO){c=R.LMSTUDIO;let n;e===`main`?n=u(i):e===`research`?n=ye(i):e===`fallback`&&(n=Re(i));let r=n===R.LMSTUDIO?De(e,i):null,a=o||r||`http://localhost:1234/v1`;d=`Warning: Custom LM Studio model '${t}' set with base URL '${a}'. Please ensure LM Studio server is running and has loaded this model. Taskmaster cannot guarantee compatibility.`,l(`warn`,d),s=a}else if(a===R.OPENAI_COMPATIBLE){c=R.OPENAI_COMPATIBLE;let n;e===`main`?n=u(i):e===`research`?n=ye(i):e===`fallback`&&(n=Re(i));let r=n===R.OPENAI_COMPATIBLE?De(e,i):null,a=o||r;if(!a)throw Error(`Base URL is required for OpenAI-compatible providers. Please provide a baseURL.`);d=`Warning: Custom OpenAI-compatible model '${t}' set with base URL '${a}'. Taskmaster cannot guarantee compatibility. Ensure your API endpoint follows the OpenAI API specification.`,l(`warn`,d),s=a}else throw Error(`Invalid provider hint received: ${a}`);else if(f)c=f.provider,l(`info`,`Model ${t} found internally with provider ${c}.`);else return{success:!1,error:{code:`MODEL_NOT_FOUND_NO_HINT`,message:`Model ID "${t}" not found in Taskmaster's supported models. If this is a custom model, please specify the provider using --openrouter, --ollama, --bedrock, --azure, --vertex, --lmstudio, --openai-compatible, --gemini-cli, or --codex-cli.`}};if(!c)return{success:!1,error:{code:`PROVIDER_UNDETERMINED`,message:`Could not determine the provider for model ID "${t}".`}};if(r.models[e]={...r.models[e],provider:c,modelId:t},s&&(c===R.OPENAI_COMPATIBLE||c===R.LMSTUDIO||c===R.OLLAMA||c===R.AZURE)?r.models[e].baseURL=s:delete r.models[e].baseURL,f&&f.max_tokens&&(r.models[e].maxTokens=f.max_tokens),!Me(r,i))return{success:!1,error:{code:`CONFIG_WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}};let p=`Successfully set ${e} model to ${t} (Provider: ${c})`;return l(`info`,p),{success:!0,data:{role:e,provider:c,modelId:t,message:p,warning:d}}}catch(t){return l(`error`,`Error setting ${e} model: ${t.message}`),{success:!1,error:{code:`SET_MODEL_ERROR`,message:t.message}}}}async function Mi(e={}){let{mcpLog:t,projectRoot:n,session:r}=e,i=(e,...n)=>{t&&typeof t[e]==`function`&&t[e](...n)};try{let e=Te().filter(e=>e.toLowerCase()!==`ollama`).map(e=>({provider:e,cli:S(e,r,n),mcp:Be(e,n)}));return i(`info`,`Successfully generated API key status report.`),{success:!0,data:{report:e,message:`API key status report generated.`}}}catch(e){return i(`error`,`Error generating API key status report: ${e.message}`),{success:!1,error:{code:`API_KEY_STATUS_ERROR`,message:e.message}}}}async function Ni(e){return ki(e)}async function Pi(e,t,n){return ji(e,t,n)}function Fi(e){return ce(e)}function Ii(e,t){return Me(e,t)}function Li(){return _e()}function Ri(e){return ee(e)??``}const zi={OPENROUTER:{id:`__CUSTOM_OPENROUTER__`,name:`* Custom OpenRouter model`,provider:R.OPENROUTER,promptMessage:e=>`Enter the custom OpenRouter Model ID for the ${e} role:`,validate:async e=>{let t=await wi(e);return t||console.error(B.red(`Error: Model ID "${e}" not found in the live OpenRouter model list. Please check the ID.`)),t}},OLLAMA:{id:`__CUSTOM_OLLAMA__`,name:`* Custom Ollama model`,provider:R.OLLAMA,requiresBaseURL:!0,defaultBaseURL:`http://localhost:11434/api`,promptMessage:e=>`Enter the custom Ollama Model ID for the ${e} role:`,validate:async(e,t)=>{let n=t||`http://localhost:11434/api`,r=await Ti(e,n);return r||(console.error(B.red(`Error: Model ID "${e}" not found in the Ollama instance. Please verify the model is pulled and available.`)),console.log(B.yellow(`You can check available models with: curl ${n}/tags`))),r}},BEDROCK:{id:`__CUSTOM_BEDROCK__`,name:`* Custom Bedrock model`,provider:R.BEDROCK,promptMessage:e=>`Enter the custom Bedrock Model ID for the ${e} role (e.g., anthropic.claude-3-sonnet-20240229-v1:0):`,checkEnvVars:()=>((!process.env.AWS_ACCESS_KEY_ID||!process.env.AWS_SECRET_ACCESS_KEY)&&console.warn(B.yellow(`Warning: AWS_ACCESS_KEY_ID and/or AWS_SECRET_ACCESS_KEY environment variables are missing. Will fallback to system configuration (ex: aws config files or ec2 instance profiles).`)),!0)},AZURE:{id:`__CUSTOM_AZURE__`,name:`* Custom Azure OpenAI model`,provider:R.AZURE,requiresBaseURL:!0,promptMessage:e=>`Enter the Azure deployment name for the ${e} role (e.g., gpt-4o):`,checkEnvVars:()=>process.env.AZURE_OPENAI_API_KEY?!0:(console.error(B.red(`Error: AZURE_OPENAI_API_KEY environment variable is missing. Please set it before using Azure models.`)),!1)},VERTEX:{id:`__CUSTOM_VERTEX__`,name:`* Custom Vertex model`,provider:R.VERTEX,promptMessage:e=>`Enter the custom Vertex AI Model ID for the ${e} role (e.g., gemini-1.5-pro-002):`,checkEnvVars:()=>!process.env.GOOGLE_API_KEY&&!process.env.GOOGLE_APPLICATION_CREDENTIALS?(console.error(B.red(`Error: Either GOOGLE_API_KEY or GOOGLE_APPLICATION_CREDENTIALS environment variable is required. Please set one before using custom Vertex models.`)),!1):!0},LMSTUDIO:{id:`__CUSTOM_LMSTUDIO__`,name:`* Custom LMStudio model`,provider:R.LMSTUDIO,requiresBaseURL:!0,defaultBaseURL:`http://localhost:1234/v1`,promptMessage:e=>`Enter the custom LM Studio Model ID for the ${e} role:`,checkEnvVars:()=>(console.log(B.blue(`Note: LM Studio runs locally. Make sure the LM Studio server is running.`)),!0)},OPENAI_COMPATIBLE:{id:`__CUSTOM_OPENAI_COMPATIBLE__`,name:`* Custom OpenAI-compatible model`,provider:R.OPENAI_COMPATIBLE,promptMessage:e=>`Enter the custom OpenAI-compatible Model ID for the ${e} role:`,requiresBaseURL:!0,checkEnvVars:()=>(console.log(B.blue(`Note: This will configure a generic OpenAI-compatible provider. Make sure your API endpoint is accessible.`)),!0)}};async function Bi(e,t,n=null,r){let i=Object.entries(zi).find(([t,n])=>n.id===e);if(!i)return console.error(B.red(`Unknown custom provider: ${e}`)),{modelId:null,provider:null,success:!1};let a=i[1];if(a.checkEnvVars&&!a.checkEnvVars())return{modelId:null,provider:null,success:!1};let o=null;if(a.requiresBaseURL){let e;e=n?.provider===a.provider&&n?.baseURL?n.baseURL:a.provider===R.AZURE&&r?Ri(r)||``:a.defaultBaseURL||``,o=(await q.prompt([{type:`input`,name:`baseURL`,message:`Enter the base URL for the ${t} role:`,default:e,validate:e=>{if(!e||e.trim()===``)return`Base URL is required for ${a.provider} providers`;try{return new URL(e),!0}catch{return`Please enter a valid URL`}}}])).baseURL}let{customId:s}=await q.prompt([{type:`input`,name:`customId`,message:a.promptMessage(t)}]);if(!s)return console.log(B.yellow(`No custom ID entered. Skipping role.`)),{modelId:null,provider:null,success:!0};if(a.validate){if(!await a.validate(s,o||void 0))return{modelId:null,provider:null,success:!1}}else console.log(B.blue(`Custom ${a.provider} model "${s}" will be used. No validation performed.`));return{modelId:s,provider:a.provider,baseURL:o,success:!0}}function Vi(){return Object.values(zi).map(e=>({name:e.name,value:e.id,short:e.name}))}function Hi(e,t,n=!1){let r=t[e],i=Li().filter(e=>!!e.provider).reduce((e,t)=>(e[t.provider]||(e[t.provider]=[]),e[t.provider].push(t),e),{}),a=[],o={name:`⏹ Cancel Model Setup`,value:`__CANCEL__`,short:`Cancel`},s=r?.modelId&&r?.provider?{name:`✔ No change to current ${e} model (${r.provider}/${r.modelId})`,value:`__NO_CHANGE__`,short:`No change`}:null;s&&a.push(s),a.push(o);let c=Object.entries(i).flatMap(([t,n])=>n.filter(t=>t.allowed_roles&&t.allowed_roles.includes(e)).map(e=>{let n=e.name||e.id;return{name:`${t} / ${n} ${e.cost_per_1m_tokens?B.gray(`($${e.cost_per_1m_tokens.input.toFixed(2)} input | $${e.cost_per_1m_tokens.output.toFixed(2)} output)`):``}`,value:{id:e.id,provider:t},short:`${t}/${n}`}})).filter(e=>e!==null),l=-1;r?.modelId&&r?.provider&&(l=c.findIndex(e=>typeof e.value==`object`&&e.value!==null&&`id`in e.value&&e.value.id===r.modelId&&e.value.provider===r.provider));let u=Vi(),d=a.length,f,p;if(n){f=[...a,new dt(`
243
243
  ── Standard Models ──`),{name:`⚪ None (disable)`,value:null,short:`None`},...c,new dt(`
244
244
  ── Custom Providers ──`),...u];let e=d+1;p=l===-1?e:l+d+2}else f=[...a,new dt(`
245
245
  ── Standard Models ──`),...c,new dt(`
246
- ── Custom Providers ──`),...u],p=l===-1?s?1:0:l+d+1;return(p<0||p>=f.length)&&(p=0,console.warn(`Warning: Could not determine default model for role '${e}'. Defaulting to 'Cancel'.`)),{choices:f,default:p}}function Vi(e,t){return(t=``)=>{let n=e.filter(e=>{if(e instanceof dt)return!0;let n=e;return`${n.name||``} ${typeof n.value==`object`&&n.value!==null&&`id`in n.value?n.value.id:``}`.toLowerCase().includes(t.toLowerCase())});return Promise.resolve(n.map(e=>{if(e instanceof dt)return e;let t=e;return{name:t.name,value:t.value,short:t.short}}))}}function Hi(){console.log(B.cyan(`
246
+ ── Custom Providers ──`),...u],p=l===-1?s?1:0:l+d+1;return(p<0||p>=f.length)&&(p=0,console.warn(`Warning: Could not determine default model for role '${e}'. Defaulting to 'Cancel'.`)),{choices:f,default:p}}function Ui(e,t){return(t=``)=>{let n=e.filter(e=>{if(e instanceof dt)return!0;let n=e;return`${n.name||``} ${typeof n.value==`object`&&n.value!==null&&`id`in n.value?n.value.id:``}`.toLowerCase().includes(t.toLowerCase())});return Promise.resolve(n.map(e=>{if(e instanceof dt)return e;let t=e;return{name:t.name,value:t.value,short:t.short}}))}}function Wi(){console.log(B.cyan(`
247
247
  🎯 Interactive Model Setup`)),console.log(B.gray(`━`.repeat(50))),console.log(B.yellow(`💡 Navigation tips:`)),console.log(B.gray(` • Type to search and filter options`)),console.log(B.gray(` • Use ↑↓ arrow keys to navigate results`)),console.log(B.gray(` • Standard models are listed first, custom providers at bottom`)),console.log(B.gray(` • Press Enter to select
248
- `))}async function Ui(e,t){return await ut({message:`Select the ${{main:`main model for generation/updates`,research:`research model`,fallback:`fallback model (optional)`}[e]}:`,source:Vi(t.choices,t.default),pageSize:15})}function Wi(e){return typeof e==`string`?Object.values(Li).some(t=>t.id===e):!1}async function Gi(e,t,n,r){let i=n?.modelId??null,a=n?.provider??null,o=n?.baseURL??null;if(t===`__CANCEL__`)return console.log(B.yellow(`\nSetup canceled during ${e} model selection.`)),{success:!1,modified:!1};if(t===`__NO_CHANGE__`)return console.log(B.gray(`No change selected for ${e} model.`)),{success:!0,modified:!1};let s=null,c=null,l=null;if(Wi(t)){let i=await Ri(t,e,n,r);if(!i.success)return{success:!1,modified:!1};if(!i.modelId)return{success:!0,modified:!1};s=i.modelId,c=i.provider,l=i.baseURL||null}else if(t&&typeof t==`object`&&`id`in t)s=t.id,c=t.provider;else if(t===null&&e===`fallback`)s=null,c=null;else if(t)return console.error(B.red(`Internal Error: Unexpected selection value for ${e}: ${JSON.stringify(t)}`)),{success:!1,modified:!1};if(s===i&&(c??null)===a&&(l??null)===o)return{success:!0,modified:!1};if(s){let t=await Mi(e,s,{projectRoot:r,providerHint:c||void 0,baseURL:l||void 0});return t.success?(console.log(B.blue(`Set ${e} model: ${t.data?.provider} / ${t.data?.modelId}`)),t.data?.warning&&console.log(B.yellow(t.data?.warning)),{success:!0,modified:!0}):(console.error(B.red(`Error setting ${e} model: ${t.error?.message||`Unknown`}`)),{success:!1,modified:!1})}else if(e===`fallback`){let e=Ni(r);return e?.models?.fallback?.modelId?(e.models.fallback={...e.models.fallback,provider:void 0,modelId:void 0},Pi(e,r)?(console.log(B.blue(`Fallback model disabled.`)),{success:!0,modified:!0}):(console.error(B.red(`Failed to disable fallback model in config file.`)),{success:!1,modified:!1})):(console.log(B.blue(`Fallback model was already disabled.`)),{success:!0,modified:!1})}return{success:!0,modified:!1}}async function Ki(e){e||(console.error(B.red(`Error: Could not determine project root for interactive setup.`)),process.exit(1));let t=await ji({projectRoot:e}),n=t.success&&t.data?{main:t.data.activeModels.main?{modelId:t.data.activeModels.main.modelId,provider:t.data.activeModels.main.provider,baseURL:t.data.activeModels.main.baseURL}:null,research:t.data.activeModels.research?{modelId:t.data.activeModels.research.modelId,provider:t.data.activeModels.research.provider,baseURL:t.data.activeModels.research.baseURL}:null,fallback:t.data.activeModels.fallback?{modelId:t.data.activeModels.fallback.modelId,provider:t.data.activeModels.fallback.provider,baseURL:t.data.activeModels.fallback.baseURL}:null}:{main:null,research:null,fallback:null};!t.success&&t.error?.code!==`CONFIG_MISSING`&&console.warn(B.yellow(`Warning: Could not load current model configuration: ${t.error?.message||`Unknown error`}. Proceeding with defaults.`));let r=Bi(`main`,n),i=Bi(`research`,n),a=Bi(`fallback`,n,!0);Hi();let o=await Ui(`main`,r);if(o===`__CANCEL__`)return!1;let s=await Ui(`research`,i);if(s===`__CANCEL__`)return!1;let c=await Ui(`fallback`,a);if(c===`__CANCEL__`)return!1;let l=!0,u=!1,d=await Gi(`main`,o,n.main,e);d.success||(l=!1),d.modified&&(u=!0);let f=await Gi(`research`,s,n.research,e);f.success||(l=!1),f.modified&&(u=!0);let p=await Gi(`fallback`,c,n.fallback,e);return p.success||(l=!1),p.modified&&(u=!0),l&&u?console.log(B.green.bold(`
248
+ `))}async function Gi(e,t){return await ut({message:`Select the ${{main:`main model for generation/updates`,research:`research model`,fallback:`fallback model (optional)`}[e]}:`,source:Ui(t.choices,t.default),pageSize:15})}function Ki(e){return typeof e==`string`?Object.values(zi).some(t=>t.id===e):!1}async function qi(e,t,n,r){let i=n?.modelId??null,a=n?.provider??null,o=n?.baseURL??null;if(t===`__CANCEL__`)return console.log(B.yellow(`\nSetup canceled during ${e} model selection.`)),{success:!1,modified:!1};if(t===`__NO_CHANGE__`)return console.log(B.gray(`No change selected for ${e} model.`)),{success:!0,modified:!1};let s=null,c=null,l=null;if(Ki(t)){let i=await Bi(t,e,n,r);if(!i.success)return{success:!1,modified:!1};if(!i.modelId)return{success:!0,modified:!1};s=i.modelId,c=i.provider,l=i.baseURL||null}else if(t&&typeof t==`object`&&`id`in t)s=t.id,c=t.provider;else if(t===null&&e===`fallback`)s=null,c=null;else if(t)return console.error(B.red(`Internal Error: Unexpected selection value for ${e}: ${JSON.stringify(t)}`)),{success:!1,modified:!1};if(s===i&&(c??null)===a&&(l??null)===o)return{success:!0,modified:!1};if(s){let t=await Pi(e,s,{projectRoot:r,providerHint:c||void 0,baseURL:l||void 0});return t.success?(console.log(B.blue(`Set ${e} model: ${t.data?.provider} / ${t.data?.modelId}`)),t.data?.warning&&console.log(B.yellow(t.data?.warning)),{success:!0,modified:!0}):(console.error(B.red(`Error setting ${e} model: ${t.error?.message||`Unknown`}`)),{success:!1,modified:!1})}else if(e===`fallback`){let e=Fi(r);return e?.models?.fallback?.modelId?(e.models.fallback={...e.models.fallback,provider:void 0,modelId:void 0},Ii(e,r)?(console.log(B.blue(`Fallback model disabled.`)),{success:!0,modified:!0}):(console.error(B.red(`Failed to disable fallback model in config file.`)),{success:!1,modified:!1})):(console.log(B.blue(`Fallback model was already disabled.`)),{success:!0,modified:!1})}return{success:!0,modified:!1}}async function Ji(e){e||(console.error(B.red(`Error: Could not determine project root for interactive setup.`)),process.exit(1));let t=await Ni({projectRoot:e}),n=t.success&&t.data?{main:t.data.activeModels.main?{modelId:t.data.activeModels.main.modelId,provider:t.data.activeModels.main.provider,baseURL:t.data.activeModels.main.baseURL}:null,research:t.data.activeModels.research?{modelId:t.data.activeModels.research.modelId,provider:t.data.activeModels.research.provider,baseURL:t.data.activeModels.research.baseURL}:null,fallback:t.data.activeModels.fallback?{modelId:t.data.activeModels.fallback.modelId,provider:t.data.activeModels.fallback.provider,baseURL:t.data.activeModels.fallback.baseURL}:null}:{main:null,research:null,fallback:null};!t.success&&t.error?.code!==`CONFIG_MISSING`&&console.warn(B.yellow(`Warning: Could not load current model configuration: ${t.error?.message||`Unknown error`}. Proceeding with defaults.`));let r=Hi(`main`,n),i=Hi(`research`,n),a=Hi(`fallback`,n,!0);Wi();let o=await Gi(`main`,r);if(o===`__CANCEL__`)return!1;let s=await Gi(`research`,i);if(s===`__CANCEL__`)return!1;let c=await Gi(`fallback`,a);if(c===`__CANCEL__`)return!1;let l=!0,u=!1,d=await qi(`main`,o,n.main,e);d.success||(l=!1),d.modified&&(u=!0);let f=await qi(`research`,s,n.research,e);f.success||(l=!1),f.modified&&(u=!0);let p=await qi(`fallback`,c,n.fallback,e);return p.success||(l=!1),p.modified&&(u=!0),l&&u?console.log(B.green.bold(`
249
249
  Model setup complete!`)):l&&!u?console.log(B.yellow(`
250
250
  No changes made to model configuration.`)):console.error(B.red(`
251
- Errors occurred during model selection. Please review and try again.`)),l}const qi=[`pending`,`done`,`in-progress`,`review`,`deferred`,`cancelled`];function Ji(e){return qi.includes(e)}function Yi(){return E||`unknown`}async function Xi(e,t,n=null,r=null,i=!1,a={}){let{projectRoot:o,tag:s}=a;try{z(`info`,`Adding subtask to parent task ${t}...`);let i=D(e,o,s);if(!i||!i.tasks)throw Error(`Invalid or missing tasks file at ${e}`);let a=parseInt(t,10),c=i.tasks.find(e=>e.id===a);if(!c)throw Error(`Parent task with ID ${a} not found`);c.subtasks||=[];let l;if(n!==null){let e=parseInt(n,10),t=i.tasks.findIndex(t=>t.id===e);if(t===-1)throw Error(`Task with ID ${e} not found`);let r=i.tasks[t];if(r.parentTaskId)throw Error(`Task ${e} is already a subtask of task ${r.parentTaskId}`);if(e===a)throw Error(`Cannot make a task a subtask of itself`);if(Ja(i.tasks,c,e))throw Error(`Cannot create circular dependency: task ${a} is already a subtask or dependent of task ${e}`);let o=(c.subtasks.length>0?Math.max(...c.subtasks.map(e=>e.id)):0)+1;l={...r,id:o,parentTaskId:a},c.subtasks.push(l),i.tasks.splice(t,1),z(`info`,`Converted task ${e} to subtask ${a}.${o}`)}else if(r){let e=(c.subtasks.length>0?Math.max(...c.subtasks.map(e=>e.id)):0)+1;l={id:e,title:r.title,description:r.description||``,details:r.details||``,status:r.status||`pending`,dependencies:r.dependencies||[],parentTaskId:a},c.subtasks.push(l),z(`info`,`Created new subtask ${a}.${e}`)}else throw Error(`Either existingTaskId or newSubtaskData must be provided`);return y(e,i,o,s),l}catch(e){throw z(`error`,`Error adding subtask: ${e.message}`),e}}var Zi=Xi;const Qi=[`high`,`medium`,`low`],$i=`medium`;function ea(e){return Qi.includes(e?.toLowerCase())}function ta(e){if(!e)return null;let t=e.toLowerCase();return ea(t)?t:null}const na=U.object({title:U.string().describe(`Clear, concise title for the task`),description:U.string().describe(`A one or two sentence description of the task`),details:U.string().describe(`In-depth implementation details, considerations, and guidance`),testStrategy:U.string().describe(`Detailed approach for verifying task completion`),dependencies:U.array(U.number()).nullable().describe(`Array of task IDs that this task depends on (must be completed before this task can start)`)}).strict(),ra=U.object({taskId:U.number().int().positive(),taskTitle:U.string(),complexityScore:U.number().min(1).max(10),recommendedSubtasks:U.number().int().nonnegative(),expansionPrompt:U.string(),reasoning:U.string()}).strict(),ia=U.object({complexityAnalysis:U.array(ra)}).strict(),aa=U.enum([`pending`,`in-progress`,`blocked`,`done`,`cancelled`,`deferred`]),oa=U.object({id:U.number().int().positive(),title:U.string().min(1).max(200),description:U.string().min(1),status:aa,dependencies:U.array(U.union([U.number().int().positive(),U.string()])),priority:U.enum([`low`,`medium`,`high`,`critical`]).nullable(),details:U.string().nullable(),testStrategy:U.string().nullable()}).strict(),sa=U.object({id:U.number().int().positive(),title:U.string().min(5).max(200),description:U.string().min(10),dependencies:U.array(U.number().int().positive()),details:U.string().min(20),status:U.enum([`pending`,`done`,`completed`]),testStrategy:U.string().nullable()}).strict(),ca=U.object({subtasks:U.array(sa)}).strict(),la=U.object({id:U.number().int().positive(),title:U.string().min(1),description:U.string().min(1),details:U.string().nullable(),testStrategy:U.string().nullable(),priority:U.enum([`high`,`medium`,`low`]).nullable(),dependencies:U.array(U.number().int().positive()).nullable(),status:U.string().nullable()}).strict(),ua=U.object({tasks:U.array(la)}).strict(),da=U.object({subtask:sa}).strict(),fa=oa.extend({subtasks:U.array(sa).nullable()}).strict(),pa=U.object({tasks:U.array(fa)}).strict(),ma=U.object({task:fa}),ha={"update-tasks":pa,"expand-task":ca,"analyze-complexity":ia,"update-subtask-by-id":da,"update-task-by-id":ma,"add-task":na,"parse-prd":ua};var ga={id:`add-task`,version:`1.0.0`,description:`Generate a new task based on description`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`task-creation`,`generation`]},parameters:{prompt:{type:`string`,required:!0,description:`User's task description`},newTaskId:{type:`number`,required:!0,description:`ID for the new task`},existingTasks:{type:`array`,description:`List of existing tasks for context`},gatheredContext:{type:`string`,description:`Context gathered from codebase analysis`},contextFromArgs:{type:`string`,description:`Additional context from manual args`},priority:{type:`string`,default:`medium`,enum:[`high`,`medium`,`low`],description:`Task priority`},dependencies:{type:`array`,description:`Task dependency IDs`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are a helpful assistant that creates well-structured tasks for a software development project. Generate a single new task based on the user's description, adhering strictly to the provided JSON schema.
251
+ Errors occurred during model selection. Please review and try again.`)),l}const Yi=[`pending`,`done`,`in-progress`,`review`,`deferred`,`cancelled`];function Xi(e){return Yi.includes(e)}const Zi=`unknown`;function Qi(e){if(!e||typeof e!=`object`)return!1;let t=e.bin;return!t||typeof t!=`object`?!1:Object.prototype.hasOwnProperty.call(t,`task-master`)||Object.prototype.hasOwnProperty.call(t,`task-master-ai`)}function $i(e){try{return JSON.parse(Je.readFileSync(e,`utf8`))}catch{return null}}function ea(e=We.dirname(Ye(import.meta.url))){let t=e;for(;;){let e=We.join(t,`package.json`);if(Je.existsSync(e)&&Qi($i(e)))return e;let n=We.dirname(t);if(n===t)return null;t=n}}function ta(){let e=ea();if(!e)return process.env.npm_package_version||Zi;let t=$i(e);if(!t||typeof t.version!=`string`)return process.env.npm_package_version||Zi;let n=t.version.trim();return n.length>0?n:process.env.npm_package_version||Zi}async function na(e,t,n=null,r=null,i=!1,a={}){let{projectRoot:o,tag:s}=a;try{z(`info`,`Adding subtask to parent task ${t}...`);let i=E(e,o,s);if(!i||!i.tasks)throw Error(`Invalid or missing tasks file at ${e}`);let a=parseInt(t,10),c=i.tasks.find(e=>e.id===a);if(!c)throw Error(`Parent task with ID ${a} not found`);c.subtasks||=[];let l;if(n!==null){let e=parseInt(n,10),t=i.tasks.findIndex(t=>t.id===e);if(t===-1)throw Error(`Task with ID ${e} not found`);let r=i.tasks[t];if(r.parentTaskId)throw Error(`Task ${e} is already a subtask of task ${r.parentTaskId}`);if(e===a)throw Error(`Cannot make a task a subtask of itself`);if(eo(i.tasks,c,e))throw Error(`Cannot create circular dependency: task ${a} is already a subtask or dependent of task ${e}`);let o=(c.subtasks.length>0?Math.max(...c.subtasks.map(e=>e.id)):0)+1;l={...r,id:o,parentTaskId:a},c.subtasks.push(l),i.tasks.splice(t,1),z(`info`,`Converted task ${e} to subtask ${a}.${o}`)}else if(r){let e=(c.subtasks.length>0?Math.max(...c.subtasks.map(e=>e.id)):0)+1;l={id:e,title:r.title,description:r.description||``,details:r.details||``,status:r.status||`pending`,dependencies:r.dependencies||[],parentTaskId:a},c.subtasks.push(l),z(`info`,`Created new subtask ${a}.${e}`)}else throw Error(`Either existingTaskId or newSubtaskData must be provided`);return y(e,i,o,s),l}catch(e){throw z(`error`,`Error adding subtask: ${e.message}`),e}}var ra=na;const ia=[`high`,`medium`,`low`],aa=`medium`;function oa(e){return ia.includes(e?.toLowerCase())}function sa(e){if(!e)return null;let t=e.toLowerCase();return oa(t)?t:null}const ca=U.object({title:U.string().describe(`Clear, concise title for the task`),description:U.string().describe(`A one or two sentence description of the task`),details:U.string().describe(`In-depth implementation details, considerations, and guidance`),testStrategy:U.string().describe(`Detailed approach for verifying task completion`),dependencies:U.array(U.number()).nullable().describe(`Array of task IDs that this task depends on (must be completed before this task can start)`)}).strict(),la=U.object({taskId:U.number().int().positive(),taskTitle:U.string(),complexityScore:U.number().min(1).max(10),recommendedSubtasks:U.number().int().nonnegative(),expansionPrompt:U.string(),reasoning:U.string()}).strict(),ua=U.object({complexityAnalysis:U.array(la)}).strict(),da=U.enum([`pending`,`in-progress`,`blocked`,`done`,`cancelled`,`deferred`]),fa=U.object({id:U.number().int().positive(),title:U.string().min(1).max(200),description:U.string().min(1),status:da,dependencies:U.array(U.union([U.number().int().positive(),U.string()])),priority:U.enum([`low`,`medium`,`high`,`critical`]).nullable(),details:U.string().nullable(),testStrategy:U.string().nullable()}).strict(),pa=U.object({id:U.number().int().positive(),title:U.string().min(5).max(200),description:U.string().min(10),dependencies:U.array(U.number().int().positive()),details:U.string().min(20),status:U.enum([`pending`,`done`,`completed`]),testStrategy:U.string().nullable()}).strict(),ma=U.object({subtasks:U.array(pa)}).strict(),ha=U.object({id:U.number().int().positive(),title:U.string().min(1),description:U.string().min(1),details:U.string().nullable(),testStrategy:U.string().nullable(),priority:U.enum([`high`,`medium`,`low`]).nullable(),dependencies:U.array(U.number().int().positive()).nullable(),status:U.string().nullable()}).strict(),ga=U.object({tasks:U.array(ha)}).strict(),_a=U.object({subtask:pa}).strict(),va=fa.extend({subtasks:U.array(pa).nullable()}).strict(),ya=U.object({tasks:U.array(va)}).strict(),ba=U.object({task:va}),xa={"update-tasks":ya,"expand-task":ma,"analyze-complexity":ua,"update-subtask-by-id":_a,"update-task-by-id":ba,"add-task":ca,"parse-prd":ga};var Sa={id:`add-task`,version:`1.0.0`,description:`Generate a new task based on description`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`task-creation`,`generation`]},parameters:{prompt:{type:`string`,required:!0,description:`User's task description`},newTaskId:{type:`number`,required:!0,description:`ID for the new task`},existingTasks:{type:`array`,description:`List of existing tasks for context`},gatheredContext:{type:`string`,description:`Context gathered from codebase analysis`},contextFromArgs:{type:`string`,description:`Additional context from manual args`},priority:{type:`string`,default:`medium`,enum:[`high`,`medium`,`low`],description:`Task priority`},dependencies:{type:`array`,description:`Task dependency IDs`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are a helpful assistant that creates well-structured tasks for a software development project. Generate a single new task based on the user's description, adhering strictly to the provided JSON schema.
252
252
 
253
253
  IMPORTANT: Your response MUST be a JSON object with the following structure (no wrapper property, just these fields directly):
254
254
  {
@@ -308,7 +308,7 @@ Project Root: {{projectRoot}}
308
308
  }
309
309
 
310
310
  Make sure the details and test strategy are comprehensive and specific{{#if useResearch}}, incorporating current best practices from your research{{/if}}. DO NOT include the task ID in the title.
311
- {{#if contextFromArgs}}{{contextFromArgs}}{{/if}}`}}},_a={id:`analyze-complexity`,version:`1.0.0`,description:`Analyze task complexity and generate expansion recommendations`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`analysis`,`complexity`,`expansion`,`recommendations`]},parameters:{tasks:{type:`array`,required:!0,description:`Array of tasks to analyze`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},threshold:{type:`number`,default:5,min:1,max:10,description:`Complexity threshold for expansion recommendation`},useResearch:{type:`boolean`,default:!1,description:`Use research mode for deeper analysis`},hasCodebaseAnalysis:{type:`boolean`,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an expert software architect and project manager analyzing task complexity. Your analysis should consider implementation effort, technical challenges, dependencies, and testing requirements.
311
+ {{#if contextFromArgs}}{{contextFromArgs}}{{/if}}`}}},Ca={id:`analyze-complexity`,version:`1.0.0`,description:`Analyze task complexity and generate expansion recommendations`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`analysis`,`complexity`,`expansion`,`recommendations`]},parameters:{tasks:{type:`array`,required:!0,description:`Array of tasks to analyze`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},threshold:{type:`number`,default:5,min:1,max:10,description:`Complexity threshold for expansion recommendation`},useResearch:{type:`boolean`,default:!1,description:`Use research mode for deeper analysis`},hasCodebaseAnalysis:{type:`boolean`,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an expert software architect and project manager analyzing task complexity. Your analysis should consider implementation effort, technical challenges, dependencies, and testing requirements.
312
312
 
313
313
  IMPORTANT: For each task, provide an analysis object with ALL of the following fields:
314
314
  - taskId: The ID of the task being analyzed (positive integer)
@@ -346,7 +346,7 @@ Tasks:
346
346
 
347
347
  {{gatheredContext}}
348
348
  {{/if}}
349
- `}}},va={id:`expand-task`,version:`1.0.0`,description:`Break down a task into detailed subtasks`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`expansion`,`subtasks`,`breakdown`]},parameters:{subtaskCount:{type:`number`,required:!0,description:`Number of subtasks to generate`},task:{type:`object`,required:!0,description:`The task to expand`},nextSubtaskId:{type:`number`,required:!0,description:`Starting ID for new subtasks`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},expansionPrompt:{type:`string`,required:!1,description:`Expansion prompt from complexity report`},additionalContext:{type:`string`,required:!1,default:``,description:`Additional context for task expansion`},complexityReasoningContext:{type:`string`,required:!1,default:``,description:`Complexity analysis reasoning context`},gatheredContext:{type:`string`,required:!1,default:``,description:`Gathered project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{"complexity-report":{condition:`expansionPrompt`,system:`You are an AI assistant helping with task breakdown. Generate {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} subtasks based on the provided prompt and context.
349
+ `}}},wa={id:`expand-task`,version:`1.0.0`,description:`Break down a task into detailed subtasks`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`expansion`,`subtasks`,`breakdown`]},parameters:{subtaskCount:{type:`number`,required:!0,description:`Number of subtasks to generate`},task:{type:`object`,required:!0,description:`The task to expand`},nextSubtaskId:{type:`number`,required:!0,description:`Starting ID for new subtasks`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},expansionPrompt:{type:`string`,required:!1,description:`Expansion prompt from complexity report`},additionalContext:{type:`string`,required:!1,default:``,description:`Additional context for task expansion`},complexityReasoningContext:{type:`string`,required:!1,default:``,description:`Complexity analysis reasoning context`},gatheredContext:{type:`string`,required:!1,default:``,description:`Gathered project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{"complexity-report":{condition:`expansionPrompt`,system:`You are an AI assistant helping with task breakdown. Generate {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} subtasks based on the provided prompt and context.
350
350
 
351
351
  IMPORTANT: Your response MUST be a JSON object with a "subtasks" property containing an array of subtask objects. Each subtask must include ALL of the following fields:
352
352
  - id: MUST be sequential integers starting EXACTLY from {{nextSubtaskId}}. First subtask id={{nextSubtaskId}}, second id={{nextSubtaskId}}+1, etc. DO NOT use any other numbering pattern!
@@ -458,7 +458,7 @@ Complexity Analysis Reasoning: {{complexityReasoningContext}}{{/if}}{{#if gather
458
458
 
459
459
  {{gatheredContext}}{{/if}}
460
460
 
461
- CRITICAL: You MUST use sequential IDs starting from {{nextSubtaskId}}. The first subtask MUST have id={{nextSubtaskId}}, the second MUST have id={{nextSubtaskId}}+1, and so on. Do NOT use parent task ID in subtask numbering!`}}},ya={id:`parse-prd`,version:`1.0.0`,description:`Parse a Product Requirements Document into structured tasks`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`prd`,`parsing`,`initialization`]},parameters:{numTasks:{type:`number`,required:!0,description:`Target number of tasks to generate`},nextId:{type:`number`,required:!0,description:`Starting ID for tasks`},research:{type:`boolean`,default:!1,description:`Enable research mode for latest best practices`},prdContent:{type:`string`,required:!0,description:`Content of the PRD file`},prdPath:{type:`string`,required:!0,description:`Path to the PRD file`},defaultTaskPriority:{type:`string`,required:!1,default:`medium`,enum:[`high`,`medium`,`low`],description:`Default priority for generated tasks`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant specialized in analyzing Product Requirements Documents (PRDs) and generating a structured, logically ordered, dependency-aware and sequenced list of development tasks in JSON format.{{#if research}}
461
+ CRITICAL: You MUST use sequential IDs starting from {{nextSubtaskId}}. The first subtask MUST have id={{nextSubtaskId}}, the second MUST have id={{nextSubtaskId}}+1, and so on. Do NOT use parent task ID in subtask numbering!`}}},Ta={id:`parse-prd`,version:`1.0.0`,description:`Parse a Product Requirements Document into structured tasks`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`prd`,`parsing`,`initialization`]},parameters:{numTasks:{type:`number`,required:!0,description:`Target number of tasks to generate`},nextId:{type:`number`,required:!0,description:`Starting ID for tasks`},research:{type:`boolean`,default:!1,description:`Enable research mode for latest best practices`},prdContent:{type:`string`,required:!0,description:`Content of the PRD file`},prdPath:{type:`string`,required:!0,description:`Path to the PRD file`},defaultTaskPriority:{type:`string`,required:!1,default:`medium`,enum:[`high`,`medium`,`low`],description:`Default priority for generated tasks`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant specialized in analyzing Product Requirements Documents (PRDs) and generating a structured, logically ordered, dependency-aware and sequenced list of development tasks in JSON format.{{#if research}}
462
462
  Before breaking down the PRD into tasks, you will:
463
463
  1. Research and analyze the latest technologies, libraries, frameworks, and best practices that would be appropriate for this project
464
464
  2. Identify any potential technical challenges, security concerns, or scalability issues not explicitly mentioned in the PRD without discarding any explicit requirements or going overboard with complexity -- always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches
@@ -522,7 +522,7 @@ Remember to thoroughly research current best practices and technologies before t
522
522
 
523
523
  {{prdContent}}
524
524
 
525
- IMPORTANT: Your response must be a JSON object with a "tasks" property containing an array of task objects. You may optionally include a "metadata" object. Do not include any other properties.`}}},ba={id:`research`,version:`1.0.0`,description:`Perform AI-powered research with project context`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`research`,`context-aware`,`information-gathering`]},parameters:{query:{type:`string`,required:!0,description:`Research query`},gatheredContext:{type:`string`,default:``,description:`Gathered project context`},detailLevel:{type:`string`,enum:[`low`,`medium`,`high`],default:`medium`,description:`Level of detail for the response`},projectInfo:{type:`object`,description:`Project information`,properties:{root:{type:`string`,description:`Project root path`},taskCount:{type:`number`,description:`Number of related tasks`},fileCount:{type:`number`,description:`Number of related files`}}}},prompts:{default:{system:`You are an expert AI research assistant helping with a software development project. You have access to project context including tasks, files, and project structure.
525
+ IMPORTANT: Your response must be a JSON object with a "tasks" property containing an array of task objects. You may optionally include a "metadata" object. Do not include any other properties.`}}},Ea={id:`research`,version:`1.0.0`,description:`Perform AI-powered research with project context`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`research`,`context-aware`,`information-gathering`]},parameters:{query:{type:`string`,required:!0,description:`Research query`},gatheredContext:{type:`string`,default:``,description:`Gathered project context`},detailLevel:{type:`string`,enum:[`low`,`medium`,`high`],default:`medium`,description:`Level of detail for the response`},projectInfo:{type:`object`,description:`Project information`,properties:{root:{type:`string`,description:`Project root path`},taskCount:{type:`number`,description:`Number of related tasks`},fileCount:{type:`number`,description:`Number of related files`}}}},prompts:{default:{system:`You are an expert AI research assistant helping with a software development project. You have access to project context including tasks, files, and project structure.
526
526
 
527
527
  Your role is to provide comprehensive, accurate, and actionable research responses based on the user's query and the provided project context.
528
528
  {{#if (eq detailLevel "low")}}
@@ -572,7 +572,7 @@ Your role is to provide comprehensive, accurate, and actionable research respons
572
572
 
573
573
  # Instructions
574
574
 
575
- Please research and provide a {{detailLevel}}-detail response to the query above. Consider the project context provided and make your response as relevant and actionable as possible for this specific project.`}}},xa={id:`update-subtask`,version:`1.0.0`,description:`Append information to a subtask by generating only new content`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`subtask`,`append`,`logging`]},parameters:{parentTask:{type:`object`,required:!0,description:`The parent task context`},prevSubtask:{type:`object`,required:!1,description:`The previous subtask if any`},nextSubtask:{type:`object`,required:!1,description:`The next subtask if any`},currentDetails:{type:`string`,required:!0,default:`(No existing details)`,description:`Current subtask details`},updatePrompt:{type:`string`,required:!0,description:`User request for what to add`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update a subtask. You will be provided with the subtask's existing details, context about its parent and sibling tasks, and a user request string.{{#if useResearch}} You have access to current best practices and latest technical information to provide research-backed updates.{{/if}}
575
+ Please research and provide a {{detailLevel}}-detail response to the query above. Consider the project context provided and make your response as relevant and actionable as possible for this specific project.`}}},Da={id:`update-subtask`,version:`1.0.0`,description:`Append information to a subtask by generating only new content`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`subtask`,`append`,`logging`]},parameters:{parentTask:{type:`object`,required:!0,description:`The parent task context`},prevSubtask:{type:`object`,required:!1,description:`The previous subtask if any`},nextSubtask:{type:`object`,required:!1,description:`The next subtask if any`},currentDetails:{type:`string`,required:!0,default:`(No existing details)`,description:`Current subtask details`},updatePrompt:{type:`string`,required:!0,description:`User request for what to add`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update a subtask. You will be provided with the subtask's existing details, context about its parent and sibling tasks, and a user request string.{{#if useResearch}} You have access to current best practices and latest technical information to provide research-backed updates.{{/if}}
576
576
 
577
577
  Your Goal: Based *only* on the user's request and all the provided context (including existing details if relevant to the request), GENERATE the new text content that should be added to the subtask's details.
578
578
  Focus *only* on generating the substance of the update.
@@ -616,7 +616,7 @@ User Request: "{{updatePrompt}}"
616
616
  # Additional Project Context
617
617
 
618
618
  {{gatheredContext}}
619
- {{/if}}`}}},Sa={id:`update-task`,version:`1.0.0`,description:`Update a single task with new information, supporting full updates and append mode`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`single-task`,`modification`,`append`]},parameters:{task:{type:`object`,required:!0,description:`The task to update`},taskJson:{type:`string`,required:!0,description:`JSON string representation of the task`},updatePrompt:{type:`string`,required:!0,description:`Description of changes to apply`},appendMode:{type:`boolean`,default:!1,description:`Whether to append to details or do full update`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},currentDetails:{type:`string`,default:`(No existing details)`,description:`Current task details for context`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update a software development task based on new context.{{#if useResearch}} You have access to current best practices and latest technical information to provide research-backed updates.{{/if}}
619
+ {{/if}}`}}},Oa={id:`update-task`,version:`1.0.0`,description:`Update a single task with new information, supporting full updates and append mode`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`single-task`,`modification`,`append`]},parameters:{task:{type:`object`,required:!0,description:`The task to update`},taskJson:{type:`string`,required:!0,description:`JSON string representation of the task`},updatePrompt:{type:`string`,required:!0,description:`Description of changes to apply`},appendMode:{type:`boolean`,default:!1,description:`Whether to append to details or do full update`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},currentDetails:{type:`string`,default:`(No existing details)`,description:`Current task details for context`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update a software development task based on new context.{{#if useResearch}} You have access to current best practices and latest technical information to provide research-backed updates.{{/if}}
620
620
  You will be given a task and a prompt describing changes or new implementation details.
621
621
  Your job is to update the task to reflect these changes, while preserving its basic structure.
622
622
 
@@ -714,7 +714,7 @@ Based on the User Request and all the Task Context (including current task detai
714
714
  # Additional Project Context
715
715
 
716
716
  {{gatheredContext}}
717
- {{/if}}`}}},Ca={id:`update-tasks`,version:`1.0.0`,description:`Update multiple tasks based on new context or changes`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`bulk`,`context-change`]},parameters:{tasks:{type:`array`,required:!0,description:`Array of tasks to update`},updatePrompt:{type:`string`,required:!0,description:`Description of changes to apply`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},projectContext:{type:`string`,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update software development tasks based on new context.
717
+ {{/if}}`}}},ka={id:`update-tasks`,version:`1.0.0`,description:`Update multiple tasks based on new context or changes`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`bulk`,`context-change`]},parameters:{tasks:{type:`array`,required:!0,description:`Array of tasks to update`},updatePrompt:{type:`string`,required:!0,description:`Description of changes to apply`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},projectContext:{type:`string`,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update software development tasks based on new context.
718
718
  You will be given a set of tasks and a prompt describing changes or new implementation details.
719
719
  Your job is to update the tasks to reflect these changes, while preserving their basic structure.
720
720
 
@@ -756,14 +756,14 @@ IMPORTANT: In the tasks above, any subtasks with "status": "done" or "status": "
756
756
 
757
757
  {{projectContext}}{{/if}}
758
758
 
759
- IMPORTANT: Your response must be a JSON object with a single property named "tasks" containing the updated array of tasks.`}}},wa={$schema:`http://json-schema.org/draft-07/schema#`,$id:`https://github.com/eyaltoledano/claude-task-master/blob/main/src/prompts/schemas/prompt-template.schema.json`,version:`1.0.0`,title:`Task Master Prompt Template`,description:`Schema for Task Master AI prompt template files`,type:`object`,required:[`id`,`version`,`description`,`prompts`],properties:{id:{type:`string`,pattern:`^[a-z0-9-]+$`,description:`Unique identifier for the prompt template`},version:{type:`string`,pattern:`^\\d+\\.\\d+\\.\\d+$`,description:`Semantic version of the prompt template`},description:{type:`string`,minLength:1,description:`Brief description of what this prompt does`},metadata:{$ref:`#/definitions/metadata`},parameters:{type:`object`,additionalProperties:{$ref:`#/definitions/parameter`}},prompts:{type:`object`,properties:{default:{$ref:`#/definitions/promptVariant`}},additionalProperties:{$ref:`#/definitions/conditionalPromptVariant`}}},definitions:{parameter:{type:`object`,required:[`type`,`description`],properties:{type:{type:`string`,enum:[`string`,`number`,`boolean`,`array`,`object`]},description:{type:`string`,minLength:1},required:{type:`boolean`,default:!1},default:{description:`Default value for optional parameters`},enum:{type:`array`,description:`Valid values for string parameters`},pattern:{type:`string`,description:`Regular expression pattern for string validation`},minimum:{type:`number`,description:`Minimum value for number parameters`},maximum:{type:`number`,description:`Maximum value for number parameters`}}},promptVariant:{type:`object`,required:[`system`,`user`],properties:{system:{type:`string`,minLength:1},user:{type:`string`,minLength:1}}},conditionalPromptVariant:{allOf:[{$ref:`#/definitions/promptVariant`},{type:`object`,properties:{condition:{type:`string`,description:`JavaScript expression for variant selection`}}}]},metadata:{type:`object`,properties:{author:{type:`string`},created:{type:`string`,format:`date-time`},updated:{type:`string`,format:`date-time`},tags:{type:`array`,items:{type:`string`}},category:{type:`string`,enum:[`task`,`analysis`,`research`,`parsing`,`update`,`expansion`]}}}}},Ta=class{constructor(){this.prompts=new Map([[`analyze-complexity`,_a],[`expand-task`,va],[`add-task`,ga],[`research`,ba],[`parse-prd`,ya],[`update-task`,Sa],[`update-tasks`,Ca],[`update-subtask`,xa]]),this.cache=new Map,this.setupValidation()}setupValidation(){this.ajv=new _t({allErrors:!0,strict:!1}),vt(this.ajv);try{this.validatePrompt=this.ajv.compile(wa),z(`debug`,`✓ JSON schema validation enabled`)}catch(e){z(`warn`,`⚠ Schema validation disabled: ${e.message}`),this.validatePrompt=()=>!0}}loadPrompt(e,t={},n=null){try{let r=`${e}-${JSON.stringify(t)}-${n}`;if(this.cache.has(r))return this.cache.get(r);let i=this.loadTemplate(e);this.validatePrompt&&this.validatePrompt!==!0&&this.validateParameters(i,t);let a=n?{...i.prompts[n],name:n}:this.selectVariant(i,t),o={systemPrompt:this.renderTemplate(a.system,t),userPrompt:this.renderTemplate(a.user,t),metadata:{templateId:i.id,version:i.version,variant:a.name||`default`,parameters:t}};return this.cache.set(r,o),o}catch(t){throw z(`error`,`Failed to load prompt ${e}: ${t.message}`),t}}loadTemplate(e){let t=this.prompts.get(e);if(!t)throw Error(`Prompt template '${e}' not found`);if(this.validatePrompt&&this.validatePrompt!==!0){if(!this.validatePrompt(t)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}}else if(!t.id||!t.prompts||!t.prompts.default)throw Error(`Invalid template structure: missing required fields (id, prompts.default)`);return t}validateParameters(e,t){if(!e.parameters)return;let n=[];for(let[r,i]of Object.entries(e.parameters)){let e=t[r];if(i.required&&e===void 0){n.push(`Required parameter '${r}' missing`);continue}e!==void 0&&(this.validateParameterType(e,i.type)||n.push(`Parameter '${r}' expected ${i.type}, got ${typeof e}`),i.enum&&!i.enum.includes(e)&&n.push(`Parameter '${r}' must be one of: ${i.enum.join(`, `)}`),i.pattern&&typeof e==`string`&&(new RegExp(i.pattern).test(e)||n.push(`Parameter '${r}' does not match required pattern: ${i.pattern}`)),typeof e==`number`&&(i.minimum!==void 0&&e<i.minimum&&n.push(`Parameter '${r}' must be >= ${i.minimum}`),i.maximum!==void 0&&e>i.maximum&&n.push(`Parameter '${r}' must be <= ${i.maximum}`)))}if(n.length>0)throw Error(`Parameter validation failed: ${n.join(`; `)}`)}validateParameterType(e,t){switch(t){case`string`:return typeof e==`string`;case`number`:return typeof e==`number`;case`boolean`:return typeof e==`boolean`;case`array`:return Array.isArray(e);case`object`:return typeof e==`object`&&!!e&&!Array.isArray(e);default:return!0}}selectVariant(e,t){for(let[n,r]of Object.entries(e.prompts))if(n!==`default`&&r.condition&&this.evaluateCondition(r.condition,t))return{...r,name:n};return{...e.prompts.default,name:`default`}}evaluateCondition(e,t){try{let n={...t};return Function(...Object.keys(n),`return ${e}`)(...Object.values(n))}catch{return z(`warn`,`Failed to evaluate condition: ${e}`),!1}}renderTemplate(e,t){let n=e;return n=n.replace(/\(eq\s+(\w+(?:\.\w+)*)\s+"([^"]+)"\)/g,(e,n,r)=>this.getNestedValue(t,n)===r?`true`:`false`),n=n.replace(/\(not\s+(\w+(?:\.\w+)*)\)/g,(e,n)=>this.getNestedValue(t,n)?`false`:`true`),n=n.replace(/\(gt\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>parseFloat(r)?`true`:`false`}),n=n.replace(/\(gte\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>=parseFloat(r)?`true`:`false`}),n=n.replace(/\{\{#if\s+([^}]+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g,(e,n,r,i=``)=>{let a;return a=n===`true`?!0:n===`false`?!1:this.getNestedValue(t,n),a?r:i}),n=n.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return Array.isArray(i)?i.map((e,n)=>{let a={...t,...e,"@index":n,"@first":n===0,"@last":n===i.length-1};return this.renderTemplate(r,a)}).join(``):``}),n=n.replace(/\{\{\{json\s+(\w+(?:\.\w+)*)\}\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:JSON.stringify(r,null,2)}),n=n.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:r}),n}getNestedValue(e,t){return t.split(`.`).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,e)}validateAllPrompts(){let e={total:0,errors:[],valid:[]};for(let[t,n]of this.prompts.entries()){e.total++;try{if(this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(n)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}e.valid.push(t)}catch(n){e.errors.push(`${t}: ${n.message}`)}}return e}listPrompts(){let e=[];for(let[t,n]of this.prompts.entries())try{e.push({id:n.id,description:n.description,version:n.version,parameters:n.parameters,tags:n.metadata?.tags||[]})}catch(e){z(`warn`,`Failed to process template ${t}: ${e.message}`)}return e}validateTemplate(e){try{let t;if(typeof e==`string`){if(t=this.prompts.get(e),!t)return{valid:!1,error:`Template '${e}' not found`}}else t=e;for(let e of[`id`,`version`,`description`,`prompts`])if(!t[e])return{valid:!1,error:`Missing required field: ${e}`};if(!t.prompts.default)return{valid:!1,error:`Missing default prompt variant`};for(let[e,n]of Object.entries(t.prompts))if(!n.system||!n.user)return{valid:!1,error:`Variant '${e}' missing system or user prompt`};return this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(t)?{valid:!1,error:`Schema validation failed: ${this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `)}`}:{valid:!0}}catch(e){return{valid:!1,error:e.message}}}};let Ea=null;function Da(){return Ea||=new Ta,Ea}const{encode:Oa}=yt;var ka=class{constructor(e,t){this.projectRoot=e,this.tasksPath=H.join(e,`.taskmaster`,`tasks`,`tasks.json`),this.tag=t,this.allTasks=this._loadAllTasks()}_loadAllTasks(){try{return D(this.tasksPath,this.projectRoot,this.tag)?.tasks||[]}catch(e){return console.warn(`Warning: Could not load tasks for ContextGatherer: ${e.message}`),[]}}countTokens(e){if(!e||typeof e!=`string`)return 0;try{return Oa(e).length}catch{return Math.ceil(e.length/4)}}async gather(e={}){let{tasks:t=[],files:n=[],customContext:r=``,includeProjectTree:i=!1,format:a=`research`,includeTokenCounts:o=!1,semanticQuery:s,maxSemanticResults:c=10,dependencyTasks:l=[]}=e,u=[],d=new Set(t.map(String)),f=null,p=null;if(o&&(p={total:0,customContext:null,tasks:[],files:[],projectTree:null}),s&&this.allTasks.length>0){let e=this._performSemanticSearch(s,c);f=e.analysisData,e.tasks.forEach(e=>{d.add(String(e.id))})}if(l.length>0&&this._buildDependencyGraphs(l).allRelatedTaskIds.forEach(e=>d.add(String(e))),r&&r.trim()){let e=this._formatCustomContext(r,a);u.push(e),o&&(p.customContext={tokens:this.countTokens(e),characters:e.length},p.total+=p.customContext.tokens)}if(d.size>0){let e=await this._gatherTaskContext(Array.from(d),a,o);if(e.context&&(u.push(e.context),o&&e.breakdown)){p.tasks=e.breakdown;let t=e.breakdown.reduce((e,t)=>e+t.tokens,0);p.total+=t}}if(n.length>0){let e=await this._gatherFileContext(n,a,o);if(e.context&&(u.push(e.context),o&&e.breakdown)){p.files=e.breakdown;let t=e.breakdown.reduce((e,t)=>e+t.tokens,0);p.total+=t}}if(i){let e=await this._gatherProjectTreeContext(a,o);e.context&&(u.push(e.context),o&&e.breakdown&&(p.projectTree=e.breakdown,p.total+=e.breakdown.tokens))}let m={context:this._joinContextSections(u,a),analysisData:f,contextSections:u.length,finalTaskIds:Array.from(d)};return o&&(m.tokenBreakdown=p),m}_performSemanticSearch(e,t){let n=new gt(this.allTasks.map(e=>{let t=e.dependencies?.length>0?e.dependencies.map(e=>this.allTasks.find(t=>t.id===e)?.title).filter(Boolean).join(` `):``;return{...e,dependencyTitles:t}}),{includeScore:!0,threshold:.4,keys:[{name:`title`,weight:1.5},{name:`description`,weight:2},{name:`details`,weight:3},{name:`dependencyTitles`,weight:.5}],shouldSort:!0,useExtendedSearch:!0,limit:50}),r=e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3),i=n.search(e),a=[];for(let e of r)if(e.length>5){let t=n.search(e);t.length>0&&a.push(...t)}let o=[...i];for(let e of a)o.some(t=>t.item.id===e.item.id)||o.push(e);let s=o.filter(e=>e.score<.25).map(e=>e.item),c=o.filter(e=>e.score>=.25&&e.score<.4).map(e=>e.item),l=[...this.allTasks].sort((e,t)=>t.id-e.id).slice(0,5),u=[...s];for(let e of c)u.some(t=>t.id===e.id)||u.push(e);for(let e of l)u.some(t=>t.id===e.id)||u.push(e);return{tasks:u.slice(0,t),analysisData:{highRelevance:s,mediumRelevance:c,recentTasks:l,allRelevantTasks:u}}}_buildDependencyContext(e){let{allRelatedTaskIds:t,graphs:n,depthMap:r}=this._buildDependencyGraphs(e);if(t.size===0)return``;let i=Array.from(t).map(e=>this.allTasks.find(t=>t.id===e)).filter(Boolean).sort((e,t)=>(r.get(e.id)||0)-(r.get(t.id)||0)),a=i.slice(0,8),o=`\nThis task relates to a dependency structure with ${i.length} related tasks in the chain.`,c=this.allTasks.filter(t=>e.includes(t.id));c.length>0&&(o+=`\n\nDirect dependencies:\n${c.map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
759
+ IMPORTANT: Your response must be a JSON object with a single property named "tasks" containing the updated array of tasks.`}}},Aa={$schema:`http://json-schema.org/draft-07/schema#`,$id:`https://github.com/eyaltoledano/claude-task-master/blob/main/src/prompts/schemas/prompt-template.schema.json`,version:`1.0.0`,title:`Task Master Prompt Template`,description:`Schema for Task Master AI prompt template files`,type:`object`,required:[`id`,`version`,`description`,`prompts`],properties:{id:{type:`string`,pattern:`^[a-z0-9-]+$`,description:`Unique identifier for the prompt template`},version:{type:`string`,pattern:`^\\d+\\.\\d+\\.\\d+$`,description:`Semantic version of the prompt template`},description:{type:`string`,minLength:1,description:`Brief description of what this prompt does`},metadata:{$ref:`#/definitions/metadata`},parameters:{type:`object`,additionalProperties:{$ref:`#/definitions/parameter`}},prompts:{type:`object`,properties:{default:{$ref:`#/definitions/promptVariant`}},additionalProperties:{$ref:`#/definitions/conditionalPromptVariant`}}},definitions:{parameter:{type:`object`,required:[`type`,`description`],properties:{type:{type:`string`,enum:[`string`,`number`,`boolean`,`array`,`object`]},description:{type:`string`,minLength:1},required:{type:`boolean`,default:!1},default:{description:`Default value for optional parameters`},enum:{type:`array`,description:`Valid values for string parameters`},pattern:{type:`string`,description:`Regular expression pattern for string validation`},minimum:{type:`number`,description:`Minimum value for number parameters`},maximum:{type:`number`,description:`Maximum value for number parameters`}}},promptVariant:{type:`object`,required:[`system`,`user`],properties:{system:{type:`string`,minLength:1},user:{type:`string`,minLength:1}}},conditionalPromptVariant:{allOf:[{$ref:`#/definitions/promptVariant`},{type:`object`,properties:{condition:{type:`string`,description:`JavaScript expression for variant selection`}}}]},metadata:{type:`object`,properties:{author:{type:`string`},created:{type:`string`,format:`date-time`},updated:{type:`string`,format:`date-time`},tags:{type:`array`,items:{type:`string`}},category:{type:`string`,enum:[`task`,`analysis`,`research`,`parsing`,`update`,`expansion`]}}}}},ja=class{constructor(){this.prompts=new Map([[`analyze-complexity`,Ca],[`expand-task`,wa],[`add-task`,Sa],[`research`,Ea],[`parse-prd`,Ta],[`update-task`,Oa],[`update-tasks`,ka],[`update-subtask`,Da]]),this.cache=new Map,this.setupValidation()}setupValidation(){this.ajv=new _t({allErrors:!0,strict:!1}),vt(this.ajv);try{this.validatePrompt=this.ajv.compile(Aa),z(`debug`,`✓ JSON schema validation enabled`)}catch(e){z(`warn`,`⚠ Schema validation disabled: ${e.message}`),this.validatePrompt=()=>!0}}loadPrompt(e,t={},n=null){try{let r=`${e}-${JSON.stringify(t)}-${n}`;if(this.cache.has(r))return this.cache.get(r);let i=this.loadTemplate(e);this.validatePrompt&&this.validatePrompt!==!0&&this.validateParameters(i,t);let a=n?{...i.prompts[n],name:n}:this.selectVariant(i,t),o={systemPrompt:this.renderTemplate(a.system,t),userPrompt:this.renderTemplate(a.user,t),metadata:{templateId:i.id,version:i.version,variant:a.name||`default`,parameters:t}};return this.cache.set(r,o),o}catch(t){throw z(`error`,`Failed to load prompt ${e}: ${t.message}`),t}}loadTemplate(e){let t=this.prompts.get(e);if(!t)throw Error(`Prompt template '${e}' not found`);if(this.validatePrompt&&this.validatePrompt!==!0){if(!this.validatePrompt(t)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}}else if(!t.id||!t.prompts||!t.prompts.default)throw Error(`Invalid template structure: missing required fields (id, prompts.default)`);return t}validateParameters(e,t){if(!e.parameters)return;let n=[];for(let[r,i]of Object.entries(e.parameters)){let e=t[r];if(i.required&&e===void 0){n.push(`Required parameter '${r}' missing`);continue}e!==void 0&&(this.validateParameterType(e,i.type)||n.push(`Parameter '${r}' expected ${i.type}, got ${typeof e}`),i.enum&&!i.enum.includes(e)&&n.push(`Parameter '${r}' must be one of: ${i.enum.join(`, `)}`),i.pattern&&typeof e==`string`&&(new RegExp(i.pattern).test(e)||n.push(`Parameter '${r}' does not match required pattern: ${i.pattern}`)),typeof e==`number`&&(i.minimum!==void 0&&e<i.minimum&&n.push(`Parameter '${r}' must be >= ${i.minimum}`),i.maximum!==void 0&&e>i.maximum&&n.push(`Parameter '${r}' must be <= ${i.maximum}`)))}if(n.length>0)throw Error(`Parameter validation failed: ${n.join(`; `)}`)}validateParameterType(e,t){switch(t){case`string`:return typeof e==`string`;case`number`:return typeof e==`number`;case`boolean`:return typeof e==`boolean`;case`array`:return Array.isArray(e);case`object`:return typeof e==`object`&&!!e&&!Array.isArray(e);default:return!0}}selectVariant(e,t){for(let[n,r]of Object.entries(e.prompts))if(n!==`default`&&r.condition&&this.evaluateCondition(r.condition,t))return{...r,name:n};return{...e.prompts.default,name:`default`}}evaluateCondition(e,t){try{let n={...t};return Function(...Object.keys(n),`return ${e}`)(...Object.values(n))}catch{return z(`warn`,`Failed to evaluate condition: ${e}`),!1}}renderTemplate(e,t){let n=e;return n=n.replace(/\(eq\s+(\w+(?:\.\w+)*)\s+"([^"]+)"\)/g,(e,n,r)=>this.getNestedValue(t,n)===r?`true`:`false`),n=n.replace(/\(not\s+(\w+(?:\.\w+)*)\)/g,(e,n)=>this.getNestedValue(t,n)?`false`:`true`),n=n.replace(/\(gt\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>parseFloat(r)?`true`:`false`}),n=n.replace(/\(gte\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>=parseFloat(r)?`true`:`false`}),n=n.replace(/\{\{#if\s+([^}]+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g,(e,n,r,i=``)=>{let a;return a=n===`true`?!0:n===`false`?!1:this.getNestedValue(t,n),a?r:i}),n=n.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return Array.isArray(i)?i.map((e,n)=>{let a={...t,...e,"@index":n,"@first":n===0,"@last":n===i.length-1};return this.renderTemplate(r,a)}).join(``):``}),n=n.replace(/\{\{\{json\s+(\w+(?:\.\w+)*)\}\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:JSON.stringify(r,null,2)}),n=n.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:r}),n}getNestedValue(e,t){return t.split(`.`).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,e)}validateAllPrompts(){let e={total:0,errors:[],valid:[]};for(let[t,n]of this.prompts.entries()){e.total++;try{if(this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(n)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}e.valid.push(t)}catch(n){e.errors.push(`${t}: ${n.message}`)}}return e}listPrompts(){let e=[];for(let[t,n]of this.prompts.entries())try{e.push({id:n.id,description:n.description,version:n.version,parameters:n.parameters,tags:n.metadata?.tags||[]})}catch(e){z(`warn`,`Failed to process template ${t}: ${e.message}`)}return e}validateTemplate(e){try{let t;if(typeof e==`string`){if(t=this.prompts.get(e),!t)return{valid:!1,error:`Template '${e}' not found`}}else t=e;for(let e of[`id`,`version`,`description`,`prompts`])if(!t[e])return{valid:!1,error:`Missing required field: ${e}`};if(!t.prompts.default)return{valid:!1,error:`Missing default prompt variant`};for(let[e,n]of Object.entries(t.prompts))if(!n.system||!n.user)return{valid:!1,error:`Variant '${e}' missing system or user prompt`};return this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(t)?{valid:!1,error:`Schema validation failed: ${this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `)}`}:{valid:!0}}catch(e){return{valid:!1,error:e.message}}}};let Ma=null;function Na(){return Ma||=new ja,Ma}const{encode:Pa}=yt;var Fa=class{constructor(e,t){this.projectRoot=e,this.tasksPath=H.join(e,`.taskmaster`,`tasks`,`tasks.json`),this.tag=t,this.allTasks=this._loadAllTasks()}_loadAllTasks(){try{return E(this.tasksPath,this.projectRoot,this.tag)?.tasks||[]}catch(e){return console.warn(`Warning: Could not load tasks for ContextGatherer: ${e.message}`),[]}}countTokens(e){if(!e||typeof e!=`string`)return 0;try{return Pa(e).length}catch{return Math.ceil(e.length/4)}}async gather(e={}){let{tasks:t=[],files:n=[],customContext:r=``,includeProjectTree:i=!1,format:a=`research`,includeTokenCounts:o=!1,semanticQuery:s,maxSemanticResults:c=10,dependencyTasks:l=[]}=e,u=[],d=new Set(t.map(String)),f=null,p=null;if(o&&(p={total:0,customContext:null,tasks:[],files:[],projectTree:null}),s&&this.allTasks.length>0){let e=this._performSemanticSearch(s,c);f=e.analysisData,e.tasks.forEach(e=>{d.add(String(e.id))})}if(l.length>0&&this._buildDependencyGraphs(l).allRelatedTaskIds.forEach(e=>d.add(String(e))),r&&r.trim()){let e=this._formatCustomContext(r,a);u.push(e),o&&(p.customContext={tokens:this.countTokens(e),characters:e.length},p.total+=p.customContext.tokens)}if(d.size>0){let e=await this._gatherTaskContext(Array.from(d),a,o);if(e.context&&(u.push(e.context),o&&e.breakdown)){p.tasks=e.breakdown;let t=e.breakdown.reduce((e,t)=>e+t.tokens,0);p.total+=t}}if(n.length>0){let e=await this._gatherFileContext(n,a,o);if(e.context&&(u.push(e.context),o&&e.breakdown)){p.files=e.breakdown;let t=e.breakdown.reduce((e,t)=>e+t.tokens,0);p.total+=t}}if(i){let e=await this._gatherProjectTreeContext(a,o);e.context&&(u.push(e.context),o&&e.breakdown&&(p.projectTree=e.breakdown,p.total+=e.breakdown.tokens))}let m={context:this._joinContextSections(u,a),analysisData:f,contextSections:u.length,finalTaskIds:Array.from(d)};return o&&(m.tokenBreakdown=p),m}_performSemanticSearch(e,t){let n=new gt(this.allTasks.map(e=>{let t=e.dependencies?.length>0?e.dependencies.map(e=>this.allTasks.find(t=>t.id===e)?.title).filter(Boolean).join(` `):``;return{...e,dependencyTitles:t}}),{includeScore:!0,threshold:.4,keys:[{name:`title`,weight:1.5},{name:`description`,weight:2},{name:`details`,weight:3},{name:`dependencyTitles`,weight:.5}],shouldSort:!0,useExtendedSearch:!0,limit:50}),r=e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3),i=n.search(e),a=[];for(let e of r)if(e.length>5){let t=n.search(e);t.length>0&&a.push(...t)}let o=[...i];for(let e of a)o.some(t=>t.item.id===e.item.id)||o.push(e);let s=o.filter(e=>e.score<.25).map(e=>e.item),c=o.filter(e=>e.score>=.25&&e.score<.4).map(e=>e.item),l=[...this.allTasks].sort((e,t)=>t.id-e.id).slice(0,5),u=[...s];for(let e of c)u.some(t=>t.id===e.id)||u.push(e);for(let e of l)u.some(t=>t.id===e.id)||u.push(e);return{tasks:u.slice(0,t),analysisData:{highRelevance:s,mediumRelevance:c,recentTasks:l,allRelevantTasks:u}}}_buildDependencyContext(e){let{allRelatedTaskIds:t,graphs:n,depthMap:r}=this._buildDependencyGraphs(e);if(t.size===0)return``;let i=Array.from(t).map(e=>this.allTasks.find(t=>t.id===e)).filter(Boolean).sort((e,t)=>(r.get(e.id)||0)-(r.get(t.id)||0)),a=i.slice(0,8),o=`\nThis task relates to a dependency structure with ${i.length} related tasks in the chain.`,c=this.allTasks.filter(t=>e.includes(t.id));c.length>0&&(o+=`\n\nDirect dependencies:\n${c.map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
760
760
  `)}`);let l=i.filter(t=>!e.includes(t.id));l.length>0&&(o+=`\n\nIndirect dependencies (dependencies of dependencies):\n${l.slice(0,5).map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
761
761
  `)}`,l.length>5&&(o+=`\n- ... and ${l.length-5} more indirect dependencies`)),o+=`
762
762
 
763
763
  Detailed information about dependencies:`;for(let t of a){let n=e.includes(t.id)?` [DIRECT DEPENDENCY]`:``;o+=`\n\n------ Task ${t.id}${n}: ${t.title} ------\n`,o+=`Description: ${t.description}\n`,t.dependencies?.length&&(o+=`Dependencies: ${t.dependencies.join(`, `)}\n`),t.details&&(o+=`Implementation Details: ${s(t.details,400)}\n`)}return n.length>0&&(o+=`
764
764
 
765
765
  Dependency Chain Visualization:`,o+=n.map(e=>this._formatDependencyChain(e)).join(``)),o}_buildDependencyGraphs(e){let t=new Set,n=new Map,r=[];for(let i of e){let e=this._buildDependencyGraph(i,t,n);e&&r.push(e)}return{allRelatedTaskIds:t,graphs:r,depthMap:n}}_buildDependencyGraph(e,t,n,r=0){if(t.has(e)||r>5)return null;let i=this.allTasks.find(t=>t.id===e);if(!i)return null;t.add(e),(!n.has(e)||r<n.get(e))&&n.set(e,r);let a=i.dependencies?.map(e=>this._buildDependencyGraph(e,t,n,r+1)).filter(Boolean)||[];return{...i,dependencies:a}}_formatDependencyChain(e,t=``,n=!0,r=0){if(r>3)return``;let i=`${t}${n?`└── `:`├── `}Task ${e.id}: ${e.title}`;if(e.dependencies?.length){let a=t+(n?` `:`│ `);i+=e.dependencies.map((t,n)=>this._formatDependencyChain(t,a,n===e.dependencies.length-1,r+1)).join(``)}return`
766
- `+i}_parseTaskIds(e){let t=[];for(let n of e)if(n.includes(`.`)){let[e,r]=n.split(`.`);t.push({type:`subtask`,parentId:parseInt(e,10),subtaskId:parseInt(r,10),fullId:n})}else t.push({type:`task`,taskId:parseInt(n,10),fullId:n});return t}async _gatherTaskContext(e,t,n=!1){try{if(!this.allTasks||this.allTasks.length===0)return{context:null,breakdown:[]};let r=this._parseTaskIds(e),i=[],a=[];for(let e of r){let r=null,o=null;if(e.type===`task`){let i=oe(this.allTasks,e.taskId);i.task&&(r=this._formatTaskForContext(i.task,t),o={id:e.fullId,type:`task`,title:i.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}else if(e.type===`subtask`){let i=oe(this.allTasks,e.parentId);if(i.task&&i.task.subtasks){let a=i.task.subtasks.find(t=>t.id===e.subtaskId);a&&(r=this._formatSubtaskForContext(a,i.task,t),o={id:e.fullId,type:`subtask`,title:a.title,parentTitle:i.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}}r&&o&&(i.push(r),n&&a.push(o))}return i.length===0?{context:null,breakdown:[]}:{context:this._formatTaskContextSection(i,t),breakdown:n?a:[]}}catch(e){return console.warn(`Warning: Could not gather task context: ${e.message}`),{context:null,breakdown:[]}}}_formatTaskForContext(e,t){let n=[];if(n.push(`**Task ${e.id}: ${e.title}**`),n.push(`Description: ${e.description}`),n.push(`Status: ${e.status||`pending`}`),n.push(`Priority: ${e.priority||`medium`}`),e.dependencies&&e.dependencies.length>0&&n.push(`Dependencies: ${e.dependencies.join(`, `)}`),e.details){let t=s(e.details,500);n.push(`Implementation Details: ${t}`)}if(e.testStrategy){let t=s(e.testStrategy,300);n.push(`Test Strategy: ${t}`)}return e.subtasks&&e.subtasks.length>0&&n.push(`Subtasks: ${e.subtasks.length} subtasks defined`),n.join(`
766
+ `+i}_parseTaskIds(e){let t=[];for(let n of e)if(n.includes(`.`)){let[e,r]=n.split(`.`);t.push({type:`subtask`,parentId:parseInt(e,10),subtaskId:parseInt(r,10),fullId:n})}else t.push({type:`task`,taskId:parseInt(n,10),fullId:n});return t}async _gatherTaskContext(e,t,n=!1){try{if(!this.allTasks||this.allTasks.length===0)return{context:null,breakdown:[]};let r=this._parseTaskIds(e),i=[],a=[];for(let e of r){let r=null,o=null;if(e.type===`task`){let i=F(this.allTasks,e.taskId);i.task&&(r=this._formatTaskForContext(i.task,t),o={id:e.fullId,type:`task`,title:i.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}else if(e.type===`subtask`){let i=F(this.allTasks,e.parentId);if(i.task&&i.task.subtasks){let a=i.task.subtasks.find(t=>t.id===e.subtaskId);a&&(r=this._formatSubtaskForContext(a,i.task,t),o={id:e.fullId,type:`subtask`,title:a.title,parentTitle:i.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}}r&&o&&(i.push(r),n&&a.push(o))}return i.length===0?{context:null,breakdown:[]}:{context:this._formatTaskContextSection(i,t),breakdown:n?a:[]}}catch(e){return console.warn(`Warning: Could not gather task context: ${e.message}`),{context:null,breakdown:[]}}}_formatTaskForContext(e,t){let n=[];if(n.push(`**Task ${e.id}: ${e.title}**`),n.push(`Description: ${e.description}`),n.push(`Status: ${e.status||`pending`}`),n.push(`Priority: ${e.priority||`medium`}`),e.dependencies&&e.dependencies.length>0&&n.push(`Dependencies: ${e.dependencies.join(`, `)}`),e.details){let t=s(e.details,500);n.push(`Implementation Details: ${t}`)}if(e.testStrategy){let t=s(e.testStrategy,300);n.push(`Test Strategy: ${t}`)}return e.subtasks&&e.subtasks.length>0&&n.push(`Subtasks: ${e.subtasks.length} subtasks defined`),n.join(`
767
767
  `)}_formatSubtaskForContext(e,t,n){let r=[];if(r.push(`**Subtask ${t.id}.${e.id}: ${e.title}**`),r.push(`Parent Task: ${t.title}`),r.push(`Description: ${e.description}`),r.push(`Status: ${e.status||`pending`}`),e.dependencies&&e.dependencies.length>0&&r.push(`Dependencies: ${e.dependencies.join(`, `)}`),e.details){let t=s(e.details,500);r.push(`Implementation Details: ${t}`)}return r.join(`
768
768
  `)}async _gatherFileContext(e,t,n=!1){let r=[],i=[];for(let a of e)try{let e=H.isAbsolute(a)?a:H.join(this.projectRoot,a);if(!V.existsSync(e))continue;let o=V.statSync(e);if(!o.isFile()||o.size>50*1024)continue;let s=V.readFileSync(e,`utf-8`),c=H.relative(this.projectRoot,e),l={path:c,size:o.size,content:s,lastModified:o.mtime};if(r.push(l),n){let e=this._formatSingleFileForContext(l,t);i.push({path:c,sizeKB:Math.round(o.size/1024),tokens:this.countTokens(e),characters:e.length})}}catch(e){console.warn(`Warning: Could not read file ${a}: ${e.message}`)}return r.length===0?{context:null,breakdown:[]}:{context:this._formatFileContextSection(r,t),breakdown:n?i:[]}}async _gatherProjectTreeContext(e,t=!1){try{let n=this._generateFileTree(this.projectRoot,5),r=this._formatProjectTreeSection(n,e);return{context:r,breakdown:t?{tokens:this.countTokens(r),characters:r.length,fileCount:n.fileCount||0,dirCount:n.dirCount||0}:null}}catch(e){return console.warn(`Warning: Could not generate project tree: ${e.message}`),{context:null,breakdown:null}}}_formatSingleFileForContext(e,t){return`${`**File: ${e.path}** (${Math.round(e.size/1024)}KB)`}\n\n${`\`\`\`\n${e.content}\n\`\`\``}`}_generateFileTree(e,t,n=0){let r=[`.git`,`node_modules`,`.env`,`coverage`,`dist`,`build`],i=[`.DS_Store`,`.env`,`.env.local`,`.env.production`];if(n>=t)return null;try{let a=V.readdirSync(e),o={name:H.basename(e),type:`directory`,children:[],fileCount:0,dirCount:0};for(let s of a){if(r.includes(s)||i.includes(s))continue;let a=H.join(e,s),c=V.statSync(a);if(c.isDirectory()){if(o.dirCount++,n<t-1){let e=this._generateFileTree(a,t,n+1);e&&o.children.push(e)}}else o.fileCount++,o.children.push({name:s,type:`file`,size:c.size})}return o}catch{return null}}_formatCustomContext(e,t){switch(t){case`research`:return`## Additional Context\n\n${e}`;case`chat`:return`**Additional Context:**\n${e}`;case`system-prompt`:return`Additional context: ${e}`;default:return e}}_formatTaskContextSection(e,t){switch(t){case`research`:return`## Task Context\n\n${e.join(`
769
769
 
@@ -790,7 +790,7 @@ Dependency Chain Visualization:`,o+=n.map(e=>this._formatDependencyChain(e)).joi
790
790
 
791
791
  `);case`system-prompt`:return e.join(` `);default:return e.join(`
792
792
 
793
- `)}}},Aa=ka;function ja(e){let t=[];for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&e[n]&&Array.isArray(e[n].tasks)&&(t=t.concat(e[n].tasks));return t}async function Ma(e,t,n=[],r=null,a={},o=`text`,c=null,l=!1){let{session:u,mcpLog:f,projectRoot:p,commandName:m,outputType:h,tag:g}=a,v=!!f,b=v?f:{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)},x=r||he(p)||$i;if(r){let e=ta(r);e?x=e:(o===`text`&&z(`warn`,`Invalid priority "${r}". Using default priority "${$i}".`),x=$i)}b.info(`Adding new task with prompt: "${t}", Priority: ${x}, Dependencies: ${n.join(`, `)||`None`}, Research: ${l}, ProjectRoot: ${p}`),g&&b.info(`Using tag context: ${g}`);let S=null,C=null,w=(e,t=`info`)=>{f?f[t](e):o===`text`&&z(t,e)};function T(e,t,n=new Set,r=new Map,i=0){if(n.has(t))return null;let a=e.find(e=>e.id===t);if(!a)return null;n.add(t),(!r.has(t)||i<r.get(t))&&r.set(t,i);let o=[];if(a.dependencies&&a.dependencies.length>0)for(let t of a.dependencies){let a=T(e,t,n,r,i+1);a&&o.push(a)}return{id:a.id,title:a.title,description:a.description,status:a.status,dependencies:o}}try{let r=D(e,p,g);r&&r._rawTaggedData&&(r=r._rawTaggedData),r||=(w(`tasks.json not found or invalid. Initializing new structure.`,`info`),{master:{tasks:[],metadata:{created:new Date().toISOString(),description:`Default tasks context`}}}),r&&Array.isArray(r.tasks)&&!r._rawTaggedData&&(w(`Legacy format detected. Migrating to tagged format...`,`info`),r={master:{tasks:r.tasks,metadata:r.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for master context`}}},ae(r.master,{description:`Tasks for master context`}),d(e),re(e),w(`Successfully migrated to tagged format.`,`success`));let a=g;if(!r[a])throw w(`Tag "${a}" does not exist. Please create it first using the 'add-tag' command.`,`error`),Error(`Tag "${a}" not found.`);r[a].tasks||(r[a].tasks=[]),r[a].metadata||(r[a].metadata={created:new Date().toISOString(),updated:new Date().toISOString(),description:``});let f=ja(r),b=r[a].tasks,E=(b.length>0?Math.max(...b.map(e=>e.id)):0)+1;o===`text`&&console.log(W(B.white.bold(`Creating New Task #${E}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let O=n.filter(e=>{let t=parseInt(e,10);return Number.isNaN(t)||!f.some(e=>e.id===t)});O.length>0&&(w(`The following dependencies do not exist or are invalid: ${O.join(`, `)}`,`warn`),w(`Removing invalid dependencies...`,`info`),n=n.filter(e=>!O.includes(e)));let k=n.map(e=>parseInt(e,10)),A=[],j=new Set,M=new Map;for(let e of k){let t=T(f,e,new Set,M);t&&A.push(t)}for(let[e,t]of M.entries())j.add(e);let N;if(c){if(w(`Using manually provided task data`,`info`),N=c,w(`DEBUG: Taking MANUAL task data path.`,`debug`),!N.title||typeof N.title!=`string`||!N.description||typeof N.description!=`string`)throw Error(`Manual task data must include at least a title and description.`)}else{w(`DEBUG: Taking AI task generation path.`,`debug`),w(`Generating task data with AI with prompt:\n${t}`,`info`);let e=await new Aa(p,g).gather({semanticQuery:t,dependencyTasks:k,format:`research`}),n=e.context,r=e.analysisData;o===`text`&&r&&Cl(r,t,n.length);let a=``;c?.title&&(a+=`\n- Suggested Title: "${c.title}"`),c?.description&&(a+=`\n- Suggested Description: "${c.description}"`),c?.details&&(a+=`\n- Additional Details Context: "${c.details}"`),c?.testStrategy&&(a+=`\n- Additional Test Strategy Context: "${c.testStrategy}"`);let{systemPrompt:s,userPrompt:d}=await Da().loadPrompt(`add-task`,{prompt:t,newTaskId:E,existingTasks:f,gatheredContext:n,contextFromArgs:a,useResearch:l,priority:x,dependencies:k,hasCodebaseAnalysis:_(l,p,u),projectRoot:p});o===`text`&&(S=sl(`Generating new task with ${l?`Research`:`Main`} AI... \n`));try{let e=l?`research`:`main`;if(w(`DEBUG: Calling generateObjectService...`,`debug`),C=await i({role:e,session:u,projectRoot:p,schema:ha[`add-task`],objectName:`newTaskData`,systemPrompt:s,prompt:d,commandName:m||`add-task`,outputType:h||(v?`mcp`:`cli`)}),w(`DEBUG: generateObjectService returned successfully.`,`debug`),!C||!C.mainResult)throw Error(`AI service did not return the expected object structure.`);if(C.mainResult.title&&C.mainResult.description)N=C.mainResult;else if(C.mainResult.object&&C.mainResult.object.title&&C.mainResult.object.description)N=C.mainResult.object;else throw Error(`AI service did not return a valid task object.`);w(`Successfully generated task data from AI.`,`success`),S&&=(cl(S,`Task generated successfully`),null)}catch(e){throw S&&=(ll(S,`AI generation failed`),null),w(`DEBUG: generateObjectService caught error: ${e.message}`,`debug`),w(`Error generating task with AI: ${e.message}`,`error`),e}finally{w(`DEBUG: generateObjectService finally block reached.`,`debug`),S&&$(S)}}let P={id:E,title:N.title,description:N.description,details:N.details||``,testStrategy:N.testStrategy||``,status:`pending`,dependencies:N.dependencies?.length?N.dependencies:k,priority:x,subtasks:[]};if(N.dependencies?.length&&(N.dependencies.every(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&f.some(e=>e.id===t)})||(w(`AI suggested invalid dependencies. Filtering them out...`,`warn`),P.dependencies=N.dependencies.filter(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&f.some(e=>e.id===t)}))),r[a].tasks.push(P),ae(r[a],{description:`Tasks for ${a} context`}),w(`DEBUG: Writing tasks.json...`,`debug`),y(e,r,p,a),w(`DEBUG: tasks.json written.`,`debug`),o===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Description`)],colWidths:[5,30,50]});e.push([P.id,s(P.title,27),s(P.description,47)]),console.log(B.green(`✓ New task created successfully:`)),console.log(e.toString());let t=e=>{switch(e?.toLowerCase()){case`high`:return`red`;case`low`:return`gray`;default:return`yellow`}},n=P.dependencies.filter(e=>!k.includes(e)),r=k.filter(e=>!P.dependencies.includes(e)),i={};P.dependencies.forEach(e=>{let t=f.find(t=>t.id===e);t&&(i[e]=s(t.title,30))});let a=``;P.dependencies.length>0?(a=B.white(`Dependencies:`)+`
793
+ `)}}},Ia=Fa;function La(e){let t=[];for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&e[n]&&Array.isArray(e[n].tasks)&&(t=t.concat(e[n].tasks));return t}async function Ra(e,t,n=[],r=null,a={},o=`text`,c=null,l=!1){let{session:u,mcpLog:f,projectRoot:p,commandName:m,outputType:h,tag:g}=a,v=!!f,b=v?f:{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)},x=r||me(p)||aa;if(r){let e=sa(r);e?x=e:(o===`text`&&z(`warn`,`Invalid priority "${r}". Using default priority "${aa}".`),x=aa)}b.info(`Adding new task with prompt: "${t}", Priority: ${x}, Dependencies: ${n.join(`, `)||`None`}, Research: ${l}, ProjectRoot: ${p}`),g&&b.info(`Using tag context: ${g}`);let S=null,C=null,w=(e,t=`info`)=>{f?f[t](e):o===`text`&&z(t,e)};function T(e,t,n=new Set,r=new Map,i=0){if(n.has(t))return null;let a=e.find(e=>e.id===t);if(!a)return null;n.add(t),(!r.has(t)||i<r.get(t))&&r.set(t,i);let o=[];if(a.dependencies&&a.dependencies.length>0)for(let t of a.dependencies){let a=T(e,t,n,r,i+1);a&&o.push(a)}return{id:a.id,title:a.title,description:a.description,status:a.status,dependencies:o}}try{let r=E(e,p,g);r&&r._rawTaggedData&&(r=r._rawTaggedData),r||=(w(`tasks.json not found or invalid. Initializing new structure.`,`info`),{master:{tasks:[],metadata:{created:new Date().toISOString(),description:`Default tasks context`}}}),r&&Array.isArray(r.tasks)&&!r._rawTaggedData&&(w(`Legacy format detected. Migrating to tagged format...`,`info`),r={master:{tasks:r.tasks,metadata:r.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for master context`}}},ie(r.master,{description:`Tasks for master context`}),d(e),ne(e),w(`Successfully migrated to tagged format.`,`success`));let a=g;if(!r[a])throw w(`Tag "${a}" does not exist. Please create it first using the 'add-tag' command.`,`error`),Error(`Tag "${a}" not found.`);r[a].tasks||(r[a].tasks=[]),r[a].metadata||(r[a].metadata={created:new Date().toISOString(),updated:new Date().toISOString(),description:``});let f=La(r),b=r[a].tasks,D=(b.length>0?Math.max(...b.map(e=>e.id)):0)+1;o===`text`&&console.log(W(B.white.bold(`Creating New Task #${D}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let O=n.filter(e=>{let t=parseInt(e,10);return Number.isNaN(t)||!f.some(e=>e.id===t)});O.length>0&&(w(`The following dependencies do not exist or are invalid: ${O.join(`, `)}`,`warn`),w(`Removing invalid dependencies...`,`info`),n=n.filter(e=>!O.includes(e)));let k=n.map(e=>parseInt(e,10)),A=[],j=new Set,M=new Map;for(let e of k){let t=T(f,e,new Set,M);t&&A.push(t)}for(let[e,t]of M.entries())j.add(e);let N;if(c){if(w(`Using manually provided task data`,`info`),N=c,w(`DEBUG: Taking MANUAL task data path.`,`debug`),!N.title||typeof N.title!=`string`||!N.description||typeof N.description!=`string`)throw Error(`Manual task data must include at least a title and description.`)}else{w(`DEBUG: Taking AI task generation path.`,`debug`),w(`Generating task data with AI with prompt:\n${t}`,`info`);let e=await new Ia(p,g).gather({semanticQuery:t,dependencyTasks:k,format:`research`}),n=e.context,r=e.analysisData;o===`text`&&r&&kl(r,t,n.length);let a=``;c?.title&&(a+=`\n- Suggested Title: "${c.title}"`),c?.description&&(a+=`\n- Suggested Description: "${c.description}"`),c?.details&&(a+=`\n- Additional Details Context: "${c.details}"`),c?.testStrategy&&(a+=`\n- Additional Test Strategy Context: "${c.testStrategy}"`);let{systemPrompt:s,userPrompt:d}=await Na().loadPrompt(`add-task`,{prompt:t,newTaskId:D,existingTasks:f,gatheredContext:n,contextFromArgs:a,useResearch:l,priority:x,dependencies:k,hasCodebaseAnalysis:_(l,p,u),projectRoot:p});o===`text`&&(S=pl(`Generating new task with ${l?`Research`:`Main`} AI... \n`));try{let e=l?`research`:`main`;if(w(`DEBUG: Calling generateObjectService...`,`debug`),C=await i({role:e,session:u,projectRoot:p,schema:xa[`add-task`],objectName:`newTaskData`,systemPrompt:s,prompt:d,commandName:m||`add-task`,outputType:h||(v?`mcp`:`cli`)}),w(`DEBUG: generateObjectService returned successfully.`,`debug`),!C||!C.mainResult)throw Error(`AI service did not return the expected object structure.`);if(C.mainResult.title&&C.mainResult.description)N=C.mainResult;else if(C.mainResult.object&&C.mainResult.object.title&&C.mainResult.object.description)N=C.mainResult.object;else throw Error(`AI service did not return a valid task object.`);w(`Successfully generated task data from AI.`,`success`),S&&=(ml(S,`Task generated successfully`),null)}catch(e){throw S&&=(hl(S,`AI generation failed`),null),w(`DEBUG: generateObjectService caught error: ${e.message}`,`debug`),w(`Error generating task with AI: ${e.message}`,`error`),e}finally{w(`DEBUG: generateObjectService finally block reached.`,`debug`),S&&$(S)}}let P={id:D,title:N.title,description:N.description,details:N.details||``,testStrategy:N.testStrategy||``,status:`pending`,dependencies:N.dependencies?.length?N.dependencies:k,priority:x,subtasks:[]};if(N.dependencies?.length&&(N.dependencies.every(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&f.some(e=>e.id===t)})||(w(`AI suggested invalid dependencies. Filtering them out...`,`warn`),P.dependencies=N.dependencies.filter(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&f.some(e=>e.id===t)}))),r[a].tasks.push(P),ie(r[a],{description:`Tasks for ${a} context`}),w(`DEBUG: Writing tasks.json...`,`debug`),y(e,r,p,a),w(`DEBUG: tasks.json written.`,`debug`),o===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Description`)],colWidths:[5,30,50]});e.push([P.id,s(P.title,27),s(P.description,47)]),console.log(B.green(`✓ New task created successfully:`)),console.log(e.toString());let t=e=>{switch(e?.toLowerCase()){case`high`:return`red`;case`low`:return`gray`;default:return`yellow`}},n=P.dependencies.filter(e=>!k.includes(e)),r=k.filter(e=>!P.dependencies.includes(e)),i={};P.dependencies.forEach(e=>{let t=f.find(t=>t.id===e);t&&(i[e]=s(t.title,30))});let a=``;P.dependencies.length>0?(a=B.white(`Dependencies:`)+`
794
794
  `,P.dependencies.forEach(e=>{let t=n.includes(e)?B.yellow(` (AI suggested)`):``;a+=B.white(` - ${e}: ${i[e]||`Unknown task`}${t}`)+`
795
795
  `})):a=B.white(`Dependencies: None`)+`
796
796
  `,r.length>0&&(a+=B.gray(`
@@ -800,61 +800,61 @@ User-specified dependencies that were not used:`)+`
800
800
  `+B.white.bold(`Dependency Analysis:`)+`
801
801
  `,n.length>0&&(o+=B.green(`AI identified ${n.length} additional dependencies`)+`
802
802
  `),r.length>0&&(o+=B.yellow(`AI excluded ${r.length} user-provided dependencies`)+`
803
- `)),console.log(W(B.white.bold(`Task ${E} Created Successfully`)+`
803
+ `)),console.log(W(B.white.bold(`Task ${D} Created Successfully`)+`
804
804
 
805
805
  `+B.white(`Title: ${P.title}`)+`
806
- `+B.white(`Status: ${dl(P.status)}`)+`
806
+ `+B.white(`Status: ${_l(P.status)}`)+`
807
807
  `+B.white(`Priority: ${B[t(P.priority)](P.priority)}`)+`
808
808
 
809
809
  `+a+o+`
810
810
  `+B.white.bold(`Next Steps:`)+`
811
- `+B.cyan(`1. Run ${B.yellow(`task-master show ${E}`)} to see complete task details`)+`
812
- `+B.cyan(`2. Run ${B.yellow(`task-master set-status --id=${E} --status=in-progress`)} to start working on it`)+`
813
- `+B.cyan(`3. Run ${B.yellow(`task-master expand --id=${E}`)} to break it down into subtasks`),{padding:1,borderColor:`green`,borderStyle:`round`})),C&&C.telemetryData&&(h===`cli`||h===`text`)&&Sl(C.telemetryData,`cli`)}return w(`DEBUG: Returning new task ID: ${E} and telemetry.`,`debug`),{newTaskId:E,telemetryData:C?C.telemetryData:null,tagInfo:C?C.tagInfo:null}}catch(e){throw S&&$(S),w(`Error adding task: ${e.message}`,`error`),o===`text`&&console.error(B.red(`Error: ${e.message}`)),e}}var Na=Ma;const Pa={research:{threshold:.5,limit:20,keys:[{name:`title`,weight:2},{name:`description`,weight:1},{name:`details`,weight:.5},{name:`dependencyTitles`,weight:.5}]},addTask:{threshold:.4,limit:15,keys:[{name:`title`,weight:2},{name:`description`,weight:1.5},{name:`details`,weight:.8},{name:`dependencyTitles`,weight:.5}]},default:{threshold:.4,limit:15,keys:[{name:`title`,weight:2},{name:`description`,weight:1.5},{name:`details`,weight:1},{name:`dependencyTitles`,weight:.5}]}},Fa=[{pattern:/(command|cli|flag)/i,label:`CLI commands`},{pattern:/(task|subtask|add)/i,label:`Task management`},{pattern:/(dependency|depend)/i,label:`Dependency handling`},{pattern:/(AI|model|prompt|research)/i,label:`AI integration`},{pattern:/(UI|display|show|interface)/i,label:`User interface`},{pattern:/(schedule|time|cron)/i,label:`Scheduling`},{pattern:/(config|setting|option)/i,label:`Configuration`},{pattern:/(test|testing|spec)/i,label:`Testing`},{pattern:/(auth|login|user)/i,label:`Authentication`},{pattern:/(database|db|data)/i,label:`Data management`},{pattern:/(api|endpoint|route)/i,label:`API development`},{pattern:/(deploy|build|release)/i,label:`Deployment`},{pattern:/(security|auth|login|user)/i,label:`Security`},{pattern:/.*/,label:`Other`}],Ia={high:.25,medium:.4,low:.6};var La=class{constructor(e,t=`default`){this.tasks=e,this.config=Pa[t]||Pa.default,this.searchableTasks=this._prepareSearchableTasks(e),this.fuse=new gt(this.searchableTasks,{includeScore:!0,threshold:this.config.threshold,keys:this.config.keys,shouldSort:!0,useExtendedSearch:!0,limit:this.config.limit})}_prepareSearchableTasks(e){return e.map(t=>{let n=t.dependencies?.length>0?t.dependencies.map(t=>{let n=e.find(e=>e.id===t);return n?n.title:``}).filter(e=>e).join(` `):``;return{...t,dependencyTitles:n}})}_extractPromptWords(e){return e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3)}findRelevantTasks(e,t={}){let{maxResults:n=8,includeRecent:r=!0,includeCategoryMatches:i=!0}=t,a=this._extractPromptWords(e),o=this.fuse.search(e),s=[];for(let e of a)if(e.length>5){let t=this.fuse.search(e);t.length>0&&s.push(...t)}let c=[...o];for(let e of s)c.some(t=>t.item.id===e.item.id)||c.push(e);let l=c.filter(e=>e.score<Ia.high).map(e=>({...e.item,score:e.score})),u=c.filter(e=>e.score>=Ia.high&&e.score<Ia.medium).map(e=>({...e.item,score:e.score})),d=c.filter(e=>e.score>=Ia.medium&&e.score<Ia.low).map(e=>({...e.item,score:e.score})),f=r?[...this.tasks].sort((e,t)=>t.id-e.id).slice(0,5):[],p=[],m=null;i&&(m=Fa.find(t=>t.pattern.test(e)),p=m?this.tasks.filter(e=>m.pattern.test(e.title)||m.pattern.test(e.description)||e.details&&m.pattern.test(e.details)).slice(0,3):[]);let h=[...l];for(let e of u)h.some(t=>t.id===e.id)||h.push(e);for(let e of d)h.some(t=>t.id===e.id)||h.push(e);for(let e of p)h.some(t=>t.id===e.id)||h.push(e);for(let e of f)h.some(t=>t.id===e.id)||h.push(e);let g=h.slice(0,n);return{results:g,breakdown:{highRelevance:l,mediumRelevance:u,lowRelevance:d,categoryTasks:p,recentTasks:f,promptCategory:m,promptWords:a},metadata:{totalSearched:this.tasks.length,fuzzyMatches:o.length,wordMatches:s.length,finalCount:g.length}}}getTaskIds(e){return e.results.map(e=>e.id.toString())}getTaskIdsWithSubtasks(e,t=!1){let n=[];for(let r of e.results)if(n.push(r.id.toString()),t&&r.subtasks&&r.subtasks.length>0)for(let e of r.subtasks)n.push(`${r.id}.${e.id}`);return n}formatSearchSummary(e,t={}){let{includeScores:n=!1,includeBreakdown:r=!1}=t,{results:i,breakdown:a,metadata:o}=e,s=`Found ${i.length} relevant tasks from ${o.totalSearched} total tasks`;if(r&&a){let e=[];a.highRelevance.length>0&&e.push(`${a.highRelevance.length} high relevance`),a.mediumRelevance.length>0&&e.push(`${a.mediumRelevance.length} medium relevance`),a.lowRelevance.length>0&&e.push(`${a.lowRelevance.length} low relevance`),a.categoryTasks.length>0&&e.push(`${a.categoryTasks.length} category matches`),e.length>0&&(s+=` (${e.join(`, `)})`),a.promptCategory&&(s+=`\nCategory detected: ${a.promptCategory.label}`)}return s}};async function Ra(e,t={}){let{session:n,mcpLog:r}=t,a=e.file||w,o=parseFloat(e.threshold||`5`),s=e.research||!1,c=e.projectRoot,l=e.tag,u=e.id?e.id.split(`,`).map(e=>parseInt(e.trim(),10)).filter(e=>!Number.isNaN(e)):null,d=e.from===void 0?null:parseInt(e.from,10),f=e.to===void 0?null:parseInt(e.to,10),p=r?`json`:`text`,m=(e,t=`info`)=>{r?r[t](e):!L()&&p===`text`&&z(t,e)},h=Le(e.output,{projectRoot:c,tag:l},m);p===`text`&&console.log(B.blue(`Analyzing task complexity and generating expansion recommendations...`));try{m(`Reading tasks from ${a}...`,`info`);let t,g=0,v=null;if(e._filteredTasksData){if(t=e._filteredTasksData,g=e._originalTaskCount||t.tasks.length,!e._originalTaskCount)try{v=D(a,c,l),v&&v.tasks&&(g=v.tasks.length)}catch(e){z(`warn`,`Could not read original tasks file: ${e.message}`)}}else{if(v=D(a,c,l),!v||!v.tasks||!Array.isArray(v.tasks)||v.tasks.length===0)throw Error(`No tasks found in the tasks file`);g=v.tasks.length;let e=[`pending`,`blocked`,`in-progress`],n=v.tasks.filter(t=>e.includes(t.status?.toLowerCase()||`pending`));if(u&&u.length>0){if(m(`Filtering tasks by specific IDs: ${u.join(`, `)}`,`info`),n=n.filter(e=>u.includes(e.id)),p===`text`){if(n.length===0&&u.length>0)console.log(B.yellow(`Warning: No active tasks found with IDs: ${u.join(`, `)}`));else if(n.length<u.length){let e=n.map(e=>e.id),t=u.filter(t=>!e.includes(t));console.log(B.yellow(`Warning: Some requested task IDs were not found or are not active: ${t.join(`, `)}`))}}}else if(d!==null||f!==null){let e=d===null?1:d,t=f===null?Math.max(...v.tasks.map(e=>e.id)):f;m(`Filtering tasks by ID range: ${e} to ${t}`,`info`),n=n.filter(n=>n.id>=e&&n.id<=t),p===`text`&&n.length===0&&console.log(B.yellow(`Warning: No active tasks found in range: ${e}-${t}`))}t={...v,tasks:n,_originalTaskCount:g}}let y=``;if(v&&v.tasks.length>0)try{let e=new ka(c,l),n=new La(Ne(v.tasks),`analyze-complexity`),r=t.tasks.map(e=>`${e.title} ${e.description}`).join(` `),i=n.findRelevantTasks(r,{maxResults:10}),a=n.getTaskIds(i);a.length>0&&(y=(await e.gather({tasks:a,format:`research`})).context||``)}catch(e){m(`Could not gather additional context: ${e.message}`,`warn`)}let x=g-t.tasks.length;if(m(`Found ${g} total tasks in the task file.`,`info`),u||d!==null||f!==null){let e=u?`Analyzing ${t.tasks.length} tasks with specific IDs: ${u.join(`, `)}`:`Analyzing ${t.tasks.length} tasks in range: ${d||1} to ${f||`end`}`;m(e,`info`),p===`text`&&console.log(B.blue(e))}else if(x>0){let e=`Skipping ${x} tasks marked as done/cancelled/deferred. Analyzing ${t.tasks.length} active tasks.`;m(e,`info`),p===`text`&&console.log(B.yellow(e))}let S=null,C=new Map;try{V.existsSync(h)&&(S=JSON.parse(V.readFileSync(h,`utf8`)),m(`Found existing complexity report at ${h}`,`info`),S&&S.complexityAnalysis&&Array.isArray(S.complexityAnalysis)&&(S.complexityAnalysis.forEach(e=>{C.set(e.taskId,e)}),m(`Existing report contains ${S.complexityAnalysis.length} task analyses`,`info`)))}catch(e){m(`Warning: Could not read existing report: ${e.message}`,`warn`),S=null,C.clear()}if(t.tasks.length===0){if(S&&(u||d!==null||f!==null))return m(`No matching tasks found for analysis. Keeping existing report.`,`info`),p===`text`&&console.log(B.yellow(`No matching tasks found for analysis. Keeping existing report.`)),{report:S,telemetryData:null};let e={meta:{generatedAt:new Date().toISOString(),tasksAnalyzed:0,thresholdScore:o,projectName:b(n),usedResearch:s},complexityAnalysis:S?.complexityAnalysis||[]};return m(`Writing complexity report to ${h}...`,`info`),V.writeFileSync(h,JSON.stringify(e,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`&&(console.log(B.green(`Task complexity analysis complete. Report written to ${h}`)),console.log(`
811
+ `+B.cyan(`1. Run ${B.yellow(`task-master show ${D}`)} to see complete task details`)+`
812
+ `+B.cyan(`2. Run ${B.yellow(`task-master set-status --id=${D} --status=in-progress`)} to start working on it`)+`
813
+ `+B.cyan(`3. Run ${B.yellow(`task-master expand --id=${D}`)} to break it down into subtasks`),{padding:1,borderColor:`green`,borderStyle:`round`})),C&&C.telemetryData&&(h===`cli`||h===`text`)&&Ol(C.telemetryData,`cli`)}return w(`DEBUG: Returning new task ID: ${D} and telemetry.`,`debug`),{newTaskId:D,telemetryData:C?C.telemetryData:null,tagInfo:C?C.tagInfo:null}}catch(e){throw S&&$(S),w(`Error adding task: ${e.message}`,`error`),o===`text`&&console.error(B.red(`Error: ${e.message}`)),e}}var za=Ra;const Ba={research:{threshold:.5,limit:20,keys:[{name:`title`,weight:2},{name:`description`,weight:1},{name:`details`,weight:.5},{name:`dependencyTitles`,weight:.5}]},addTask:{threshold:.4,limit:15,keys:[{name:`title`,weight:2},{name:`description`,weight:1.5},{name:`details`,weight:.8},{name:`dependencyTitles`,weight:.5}]},default:{threshold:.4,limit:15,keys:[{name:`title`,weight:2},{name:`description`,weight:1.5},{name:`details`,weight:1},{name:`dependencyTitles`,weight:.5}]}},Va=[{pattern:/(command|cli|flag)/i,label:`CLI commands`},{pattern:/(task|subtask|add)/i,label:`Task management`},{pattern:/(dependency|depend)/i,label:`Dependency handling`},{pattern:/(AI|model|prompt|research)/i,label:`AI integration`},{pattern:/(UI|display|show|interface)/i,label:`User interface`},{pattern:/(schedule|time|cron)/i,label:`Scheduling`},{pattern:/(config|setting|option)/i,label:`Configuration`},{pattern:/(test|testing|spec)/i,label:`Testing`},{pattern:/(auth|login|user)/i,label:`Authentication`},{pattern:/(database|db|data)/i,label:`Data management`},{pattern:/(api|endpoint|route)/i,label:`API development`},{pattern:/(deploy|build|release)/i,label:`Deployment`},{pattern:/(security|auth|login|user)/i,label:`Security`},{pattern:/.*/,label:`Other`}],Ha={high:.25,medium:.4,low:.6};var Ua=class{constructor(e,t=`default`){this.tasks=e,this.config=Ba[t]||Ba.default,this.searchableTasks=this._prepareSearchableTasks(e),this.fuse=new gt(this.searchableTasks,{includeScore:!0,threshold:this.config.threshold,keys:this.config.keys,shouldSort:!0,useExtendedSearch:!0,limit:this.config.limit})}_prepareSearchableTasks(e){return e.map(t=>{let n=t.dependencies?.length>0?t.dependencies.map(t=>{let n=e.find(e=>e.id===t);return n?n.title:``}).filter(e=>e).join(` `):``;return{...t,dependencyTitles:n}})}_extractPromptWords(e){return e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3)}findRelevantTasks(e,t={}){let{maxResults:n=8,includeRecent:r=!0,includeCategoryMatches:i=!0}=t,a=this._extractPromptWords(e),o=this.fuse.search(e),s=[];for(let e of a)if(e.length>5){let t=this.fuse.search(e);t.length>0&&s.push(...t)}let c=[...o];for(let e of s)c.some(t=>t.item.id===e.item.id)||c.push(e);let l=c.filter(e=>e.score<Ha.high).map(e=>({...e.item,score:e.score})),u=c.filter(e=>e.score>=Ha.high&&e.score<Ha.medium).map(e=>({...e.item,score:e.score})),d=c.filter(e=>e.score>=Ha.medium&&e.score<Ha.low).map(e=>({...e.item,score:e.score})),f=r?[...this.tasks].sort((e,t)=>t.id-e.id).slice(0,5):[],p=[],m=null;i&&(m=Va.find(t=>t.pattern.test(e)),p=m?this.tasks.filter(e=>m.pattern.test(e.title)||m.pattern.test(e.description)||e.details&&m.pattern.test(e.details)).slice(0,3):[]);let h=[...l];for(let e of u)h.some(t=>t.id===e.id)||h.push(e);for(let e of d)h.some(t=>t.id===e.id)||h.push(e);for(let e of p)h.some(t=>t.id===e.id)||h.push(e);for(let e of f)h.some(t=>t.id===e.id)||h.push(e);let g=h.slice(0,n);return{results:g,breakdown:{highRelevance:l,mediumRelevance:u,lowRelevance:d,categoryTasks:p,recentTasks:f,promptCategory:m,promptWords:a},metadata:{totalSearched:this.tasks.length,fuzzyMatches:o.length,wordMatches:s.length,finalCount:g.length}}}getTaskIds(e){return e.results.map(e=>e.id.toString())}getTaskIdsWithSubtasks(e,t=!1){let n=[];for(let r of e.results)if(n.push(r.id.toString()),t&&r.subtasks&&r.subtasks.length>0)for(let e of r.subtasks)n.push(`${r.id}.${e.id}`);return n}formatSearchSummary(e,t={}){let{includeScores:n=!1,includeBreakdown:r=!1}=t,{results:i,breakdown:a,metadata:o}=e,s=`Found ${i.length} relevant tasks from ${o.totalSearched} total tasks`;if(r&&a){let e=[];a.highRelevance.length>0&&e.push(`${a.highRelevance.length} high relevance`),a.mediumRelevance.length>0&&e.push(`${a.mediumRelevance.length} medium relevance`),a.lowRelevance.length>0&&e.push(`${a.lowRelevance.length} low relevance`),a.categoryTasks.length>0&&e.push(`${a.categoryTasks.length} category matches`),e.length>0&&(s+=` (${e.join(`, `)})`),a.promptCategory&&(s+=`\nCategory detected: ${a.promptCategory.label}`)}return s}};async function Wa(e,t={}){let{session:n,mcpLog:r}=t,a=e.file||C,o=parseFloat(e.threshold||`5`),s=e.research||!1,c=e.projectRoot,l=e.tag,u=e.id?e.id.split(`,`).map(e=>parseInt(e.trim(),10)).filter(e=>!Number.isNaN(e)):null,d=e.from===void 0?null:parseInt(e.from,10),f=e.to===void 0?null:parseInt(e.to,10),p=r?`json`:`text`,m=(e,t=`info`)=>{r?r[t](e):!L()&&p===`text`&&z(t,e)},h=Fe(e.output,{projectRoot:c,tag:l},m);p===`text`&&console.log(B.blue(`Analyzing task complexity and generating expansion recommendations...`));try{m(`Reading tasks from ${a}...`,`info`);let t,g=0,v=null;if(e._filteredTasksData){if(t=e._filteredTasksData,g=e._originalTaskCount||t.tasks.length,!e._originalTaskCount)try{v=E(a,c,l),v&&v.tasks&&(g=v.tasks.length)}catch(e){z(`warn`,`Could not read original tasks file: ${e.message}`)}}else{if(v=E(a,c,l),!v||!v.tasks||!Array.isArray(v.tasks)||v.tasks.length===0)throw Error(`No tasks found in the tasks file`);g=v.tasks.length;let e=[`pending`,`blocked`,`in-progress`],n=v.tasks.filter(t=>e.includes(t.status?.toLowerCase()||`pending`));if(u&&u.length>0){if(m(`Filtering tasks by specific IDs: ${u.join(`, `)}`,`info`),n=n.filter(e=>u.includes(e.id)),p===`text`){if(n.length===0&&u.length>0)console.log(B.yellow(`Warning: No active tasks found with IDs: ${u.join(`, `)}`));else if(n.length<u.length){let e=n.map(e=>e.id),t=u.filter(t=>!e.includes(t));console.log(B.yellow(`Warning: Some requested task IDs were not found or are not active: ${t.join(`, `)}`))}}}else if(d!==null||f!==null){let e=d===null?1:d,t=f===null?Math.max(...v.tasks.map(e=>e.id)):f;m(`Filtering tasks by ID range: ${e} to ${t}`,`info`),n=n.filter(n=>n.id>=e&&n.id<=t),p===`text`&&n.length===0&&console.log(B.yellow(`Warning: No active tasks found in range: ${e}-${t}`))}t={...v,tasks:n,_originalTaskCount:g}}let y=``;if(v&&v.tasks.length>0)try{let e=new Fa(c,l),n=new Ua(je(v.tasks),`analyze-complexity`),r=t.tasks.map(e=>`${e.title} ${e.description}`).join(` `),i=n.findRelevantTasks(r,{maxResults:10}),a=n.getTaskIds(i);a.length>0&&(y=(await e.gather({tasks:a,format:`research`})).context||``)}catch(e){m(`Could not gather additional context: ${e.message}`,`warn`)}let x=g-t.tasks.length;if(m(`Found ${g} total tasks in the task file.`,`info`),u||d!==null||f!==null){let e=u?`Analyzing ${t.tasks.length} tasks with specific IDs: ${u.join(`, `)}`:`Analyzing ${t.tasks.length} tasks in range: ${d||1} to ${f||`end`}`;m(e,`info`),p===`text`&&console.log(B.blue(e))}else if(x>0){let e=`Skipping ${x} tasks marked as done/cancelled/deferred. Analyzing ${t.tasks.length} active tasks.`;m(e,`info`),p===`text`&&console.log(B.yellow(e))}let S=null,C=new Map;try{V.existsSync(h)&&(S=JSON.parse(V.readFileSync(h,`utf8`)),m(`Found existing complexity report at ${h}`,`info`),S&&S.complexityAnalysis&&Array.isArray(S.complexityAnalysis)&&(S.complexityAnalysis.forEach(e=>{C.set(e.taskId,e)}),m(`Existing report contains ${S.complexityAnalysis.length} task analyses`,`info`)))}catch(e){m(`Warning: Could not read existing report: ${e.message}`,`warn`),S=null,C.clear()}if(t.tasks.length===0){if(S&&(u||d!==null||f!==null))return m(`No matching tasks found for analysis. Keeping existing report.`,`info`),p===`text`&&console.log(B.yellow(`No matching tasks found for analysis. Keeping existing report.`)),{report:S,telemetryData:null};let e={meta:{generatedAt:new Date().toISOString(),tasksAnalyzed:0,thresholdScore:o,projectName:b(n),usedResearch:s},complexityAnalysis:S?.complexityAnalysis||[]};return m(`Writing complexity report to ${h}...`,`info`),V.writeFileSync(h,JSON.stringify(e,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`&&(console.log(B.green(`Task complexity analysis complete. Report written to ${h}`)),console.log(`
814
814
  Complexity Analysis Summary:`),console.log(`----------------------------`),console.log(`Tasks in input file: ${g}`),console.log(`Tasks successfully analyzed: 0`),console.log(`High complexity tasks: 0`),console.log(`Medium complexity tasks: 0`),console.log(`Low complexity tasks: 0`),console.log(`Sum verification: 0 (should equal 0)`),console.log(`Research-backed analysis: ${s?`Yes`:`No`}`),console.log(`\nSee ${h} for the full report and expansion commands.`),console.log(W(B.white.bold(`Suggested Next Steps:`)+`
815
815
 
816
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master complexity-report`)} to review detailed findings\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down complex tasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))),{report:e,telemetryData:null}}let w=Da(),T={tasks:t.tasks,gatheredContext:y||``,useResearch:s,hasCodebaseAnalysis:_(s,c,n),projectRoot:c||``},{systemPrompt:E,userPrompt:O}=await w.loadPrompt(`analyze-complexity`,T,`default`),k=null;p===`text`&&(k=sl(`${s?`Researching`:`Analyzing`} the complexity of your tasks with AI...\n`));let A=null,j=null;try{A=await i({prompt:O,systemPrompt:E,role:s?`research`:`main`,session:n,projectRoot:c,schema:ha[`analyze-complexity`],objectName:`complexityAnalysis`,commandName:`analyze-complexity`,outputType:r?`mcp`:`cli`}),k&&=($(k),null),p===`text`&&(nt.clearLine(process.stdout,0),nt.cursorTo(process.stdout,0),console.log(B.green(`AI service call complete.`))),j=A.mainResult?.complexityAnalysis,m(`Received ${j.length} complexity analyses from AI.`,`info`);let e=t.tasks.map(e=>e.id),a=j.map(e=>e.taskId),l=e.filter(e=>!a.includes(e));if(l.length>0){m(`Missing analysis for ${l.length} tasks: ${l.join(`, `)}`,`warn`),p===`text`&&console.log(B.yellow(`Missing analysis for ${l.length} tasks: ${l.join(`, `)}`));for(let e of l){let n=t.tasks.find(t=>t.id===e);n&&(m(`Adding default analysis for task ${e}`,`info`),j.push({taskId:e,taskTitle:n.title,complexityScore:5,recommendedSubtasks:3,expansionPrompt:`Break down this task with a focus on ${n.title.toLowerCase()}.`,reasoning:`Automatically added due to missing analysis in AI response.`}))}}let u=[];if(S&&Array.isArray(S.complexityAnalysis)){let e=new Set(j.map(e=>e.taskId)),n=new Set(t.tasks.map(e=>e.id)),r=S.complexityAnalysis.filter(t=>!e.has(t.taskId)&&n.has(t.taskId));u=[...r,...j],m(`Merged ${j.length} new analyses with ${r.length} existing entries from current tag`,`info`)}else u=j;let d={meta:{generatedAt:new Date().toISOString(),tasksAnalyzed:t.tasks.length,totalTasks:g,analysisCount:u.length,thresholdScore:o,projectName:b(n),usedResearch:s},complexityAnalysis:u};if(m(`Writing complexity report to ${h}...`,`info`),V.writeFileSync(h,JSON.stringify(d,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`){console.log(B.green(`Task complexity analysis complete. Report written to ${h}`));let e=j.filter(e=>e.complexityScore>=8).length,t=j.filter(e=>e.complexityScore>=5&&e.complexityScore<8).length,r=j.filter(e=>e.complexityScore<5).length,i=j.length;console.log(`
816
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master complexity-report`)} to review detailed findings\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down complex tasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))),{report:e,telemetryData:null}}let w=Na(),T={tasks:t.tasks,gatheredContext:y||``,useResearch:s,hasCodebaseAnalysis:_(s,c,n),projectRoot:c||``},{systemPrompt:D,userPrompt:O}=await w.loadPrompt(`analyze-complexity`,T,`default`),k=null;p===`text`&&(k=pl(`${s?`Researching`:`Analyzing`} the complexity of your tasks with AI...\n`));let A=null,j=null;try{A=await i({prompt:O,systemPrompt:D,role:s?`research`:`main`,session:n,projectRoot:c,schema:xa[`analyze-complexity`],objectName:`complexityAnalysis`,commandName:`analyze-complexity`,outputType:r?`mcp`:`cli`}),k&&=($(k),null),p===`text`&&(nt.clearLine(process.stdout,0),nt.cursorTo(process.stdout,0),console.log(B.green(`AI service call complete.`))),j=A.mainResult?.complexityAnalysis,m(`Received ${j.length} complexity analyses from AI.`,`info`);let e=t.tasks.map(e=>e.id),a=j.map(e=>e.taskId),l=e.filter(e=>!a.includes(e));if(l.length>0){m(`Missing analysis for ${l.length} tasks: ${l.join(`, `)}`,`warn`),p===`text`&&console.log(B.yellow(`Missing analysis for ${l.length} tasks: ${l.join(`, `)}`));for(let e of l){let n=t.tasks.find(t=>t.id===e);n&&(m(`Adding default analysis for task ${e}`,`info`),j.push({taskId:e,taskTitle:n.title,complexityScore:5,recommendedSubtasks:3,expansionPrompt:`Break down this task with a focus on ${n.title.toLowerCase()}.`,reasoning:`Automatically added due to missing analysis in AI response.`}))}}let u=[];if(S&&Array.isArray(S.complexityAnalysis)){let e=new Set(j.map(e=>e.taskId)),n=new Set(t.tasks.map(e=>e.id)),r=S.complexityAnalysis.filter(t=>!e.has(t.taskId)&&n.has(t.taskId));u=[...r,...j],m(`Merged ${j.length} new analyses with ${r.length} existing entries from current tag`,`info`)}else u=j;let d={meta:{generatedAt:new Date().toISOString(),tasksAnalyzed:t.tasks.length,totalTasks:g,analysisCount:u.length,thresholdScore:o,projectName:b(n),usedResearch:s},complexityAnalysis:u};if(m(`Writing complexity report to ${h}...`,`info`),V.writeFileSync(h,JSON.stringify(d,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`){console.log(B.green(`Task complexity analysis complete. Report written to ${h}`));let e=j.filter(e=>e.complexityScore>=8).length,t=j.filter(e=>e.complexityScore>=5&&e.complexityScore<8).length,r=j.filter(e=>e.complexityScore<5).length,i=j.length;console.log(`
817
817
  Current Analysis Summary:`),console.log(`----------------------------`),console.log(`Tasks analyzed in this run: ${i}`),console.log(`High complexity tasks: ${e}`),console.log(`Medium complexity tasks: ${t}`),console.log(`Low complexity tasks: ${r}`),S&&(console.log(`
818
818
  Updated Report Summary:`),console.log(`----------------------------`),console.log(`Total analyses in report: ${u.length}`),console.log(`Analyses from previous runs: ${u.length-i}`),console.log(`New/updated analyses: ${i}`)),console.log(`Research-backed analysis: ${s?`Yes`:`No`}`),console.log(`\nSee ${h} for the full report and expansion commands.`),console.log(W(B.white.bold(`Suggested Next Steps:`)+`
819
819
 
820
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master complexity-report`)} to review detailed findings\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down complex tasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),je(n)&&console.debug(B.gray(`Final analysis object: ${JSON.stringify(d,null,2)}`)),A.telemetryData&&Sl(A.telemetryData,`cli`)}return{report:d,telemetryData:A?.telemetryData,tagInfo:A?.tagInfo}}catch(e){throw k&&$(k),m(`Error during AI service call: ${e.message}`,`error`),p===`text`&&(console.error(B.red(`Error during AI service call: ${e.message}`)),e.message.includes(`API key`)&&(console.log(B.yellow(`
821
- Please ensure your API keys are correctly configured in .env or ~/.taskmaster/.env`)),console.log(B.yellow(`Run 'task-master models --setup' if needed.`)))),e}}catch(e){if(m(`Error analyzing task complexity: ${e.message}`,`error`),p===`text`)console.error(B.red(`Error analyzing task complexity: ${e.message}`)),je(n)&&console.error(e),process.exit(1);else throw e}}var za=Ra;function Ba(e,t,n={}){let{projectRoot:r,tag:i}=n;z(`info`,`Reading tasks from ${e}...`);let a=D(e,r,i);(!a||!a.tasks)&&(z(`error`,`No valid tasks found.`),process.exit(1)),L()||console.log(W(B.white.bold(`Clearing Subtasks`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let o=t.split(`,`).map(e=>e.trim()),c=0,l=new K({head:[B.cyan.bold(`Task ID`),B.cyan.bold(`Task Title`),B.cyan.bold(`Subtasks Cleared`)],colWidths:[10,50,20],style:{head:[],border:[]}});o.forEach(e=>{let t=parseInt(e,10);if(Number.isNaN(t)){z(`error`,`Invalid task ID: ${e}`);return}let n=a.tasks.find(e=>e.id===t);if(!n){z(`error`,`Task ${t} not found`);return}if(!n.subtasks||n.subtasks.length===0){z(`info`,`Task ${t} has no subtasks to clear`),l.push([t.toString(),s(n.title,47),B.yellow(`No subtasks`)]);return}let r=n.subtasks.length;n.subtasks=[],c++,z(`info`,`Cleared ${r} subtasks from task ${t}`),l.push([t.toString(),s(n.title,47),B.green(`${r} subtasks cleared`)])}),c>0?(y(e,a,r,i),L()||(console.log(W(B.white.bold(`Subtask Clearing Summary:`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:`blue`,borderStyle:`round`})),console.log(l.toString())),L()||(console.log(W(B.green(`Successfully cleared subtasks from ${B.bold(c)} task(s)`),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),console.log(W(B.white.bold(`Next Steps:`)+`
820
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master complexity-report`)} to review detailed findings\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down complex tasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),ke(n)&&console.debug(B.gray(`Final analysis object: ${JSON.stringify(d,null,2)}`)),A.telemetryData&&Ol(A.telemetryData,`cli`)}return{report:d,telemetryData:A?.telemetryData,tagInfo:A?.tagInfo}}catch(e){throw k&&$(k),m(`Error during AI service call: ${e.message}`,`error`),p===`text`&&(console.error(B.red(`Error during AI service call: ${e.message}`)),e.message.includes(`API key`)&&(console.log(B.yellow(`
821
+ Please ensure your API keys are correctly configured in .env or ~/.taskmaster/.env`)),console.log(B.yellow(`Run 'task-master models --setup' if needed.`)))),e}}catch(e){if(m(`Error analyzing task complexity: ${e.message}`,`error`),p===`text`)console.error(B.red(`Error analyzing task complexity: ${e.message}`)),ke(n)&&console.error(e),process.exit(1);else throw e}}var Ga=Wa;function Ka(e,t,n={}){let{projectRoot:r,tag:i}=n;z(`info`,`Reading tasks from ${e}...`);let a=E(e,r,i);(!a||!a.tasks)&&(z(`error`,`No valid tasks found.`),process.exit(1)),L()||console.log(W(B.white.bold(`Clearing Subtasks`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let o=t.split(`,`).map(e=>e.trim()),c=0,l=new K({head:[B.cyan.bold(`Task ID`),B.cyan.bold(`Task Title`),B.cyan.bold(`Subtasks Cleared`)],colWidths:[10,50,20],style:{head:[],border:[]}});o.forEach(e=>{let t=parseInt(e,10);if(Number.isNaN(t)){z(`error`,`Invalid task ID: ${e}`);return}let n=a.tasks.find(e=>e.id===t);if(!n){z(`error`,`Task ${t} not found`);return}if(!n.subtasks||n.subtasks.length===0){z(`info`,`Task ${t} has no subtasks to clear`),l.push([t.toString(),s(n.title,47),B.yellow(`No subtasks`)]);return}let r=n.subtasks.length;n.subtasks=[],c++,z(`info`,`Cleared ${r} subtasks from task ${t}`),l.push([t.toString(),s(n.title,47),B.green(`${r} subtasks cleared`)])}),c>0?(y(e,a,r,i),L()||(console.log(W(B.white.bold(`Subtask Clearing Summary:`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:`blue`,borderStyle:`round`})),console.log(l.toString())),L()||(console.log(W(B.green(`Successfully cleared subtasks from ${B.bold(c)} task(s)`),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),console.log(W(B.white.bold(`Next Steps:`)+`
822
822
 
823
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to generate new subtasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master list --with-subtasks`)} to verify changes`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})))):L()||console.log(W(B.yellow(`No subtasks were cleared`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}var Va=Ba;function Ha(e,t){let n=!!e,r=e||{info:e=>!L()&&z(`info`,e),warn:e=>!L()&&z(`warn`,e),error:e=>!L()&&z(`error`,e),debug:e=>!L()&&je(t)&&z(`debug`,e)};return{logger:r,report:(e,...t)=>{n?typeof r[e]==`function`?r[e](...t):r.info(...t):L()||z(e,...t)},isMCP:n}}async function Ua(e,t,n,r=!1,a=``,o={},s=!1){let{session:c,mcpLog:l,projectRoot:u,tag:d,complexityReportPath:f}=o,p=l?`json`:`text`,m=u||ze(e),{logger:h,report:g,isMCP:v}=Ha(l,c);v&&h.info(`expandTask called with context: session=${!!c}`);try{let o=await Br({taskId:t,numSubtasks:n,useResearch:r,additionalContext:a,force:s,projectRoot:m,tag:d,isMCP:v,outputFormat:p,report:g});if(o)return o;h.info(`Reading tasks from ${e}`);let l=D(e,m,d);if(!l||!l.tasks)throw Error(`Invalid tasks data in ${e}`);let u=l.tasks.findIndex(e=>e.id===parseInt(t,10));if(u===-1)throw Error(`Task ${t} not found`);let b=l.tasks[u];h.info(`Expanding task ${t}: ${b.title}${r?` with research`:``}`),s&&Array.isArray(b.subtasks)&&b.subtasks.length>0&&(h.info(`Force flag set. Clearing existing ${b.subtasks.length} subtasks for task ${t}.`),b.subtasks=[]);let x=``;try{let e=new ka(m,d),n=new La(Ne(l.tasks),`expand-task`),r=`${b.title} ${b.description}`,i=n.findRelevantTasks(r,{maxResults:5,includeSelf:!0}),a=n.getTaskIds(i),o=[...new Set([t.toString(),...a])];o.length>0&&(x=(await e.gather({tasks:o,format:`research`})).context||``)}catch(e){h.warn(`Could not gather context: ${e.message}`)}let S,C=``,w=null;h.info(`Looking for complexity report at: ${f}${d===`master`?``:` (tag-specific for '${d}')`}`);try{V.existsSync(f)?(w=D(f)?.complexityAnalysis?.find(e=>e.taskId===b.id),w?(h.info(`Found complexity analysis for task ${b.id}: Score ${w.complexityScore}`),w.reasoning&&(C=`\nComplexity Analysis Reasoning: ${w.reasoning}`)):h.info(`No complexity analysis found for task ${b.id} in report.`)):h.info(`Complexity report not found at ${f}. Skipping complexity check.`)}catch(e){h.warn(`Could not read or parse complexity report: ${e.message}. Proceeding without it.`)}let T=parseInt(n,10);!Number.isNaN(T)&&T>=0?(S=T,h.info(`Using explicitly provided subtask count: ${S}`)):w?.recommendedSubtasks?(S=parseInt(w.recommendedSubtasks,10),h.info(`Using subtask count from complexity report: ${S}`)):(S=fe(c),h.info(`Using default number of subtasks: ${S}`)),(Number.isNaN(S)||S<0)&&(h.warn(`Invalid subtask count determined (${S}), defaulting to 3.`),S=3);let E=(b.subtasks?.length||0)+1,O=Da(),k=_(r,m,c),A=``;(a||C)&&(A=`\n\n${a}${C}`.trim()),x&&(A=`${A}\n\n# Project Context\n\n${x}`.trim());let j;w?.expansionPrompt&&(typeof w.expansionPrompt==`string`?j=w.expansionPrompt:typeof w.expansionPrompt==`object`&&w.expansionPrompt.text&&(j=w.expansionPrompt.text));let M=x;typeof x==`object`&&x&&(M=x.data?x.data:x.text?x.text:JSON.stringify(x));let N={task:b,subtaskCount:S,nextSubtaskId:E,additionalContext:a,complexityReasoningContext:C,gatheredContext:M||``,useResearch:r,expansionPrompt:j||void 0,hasCodebaseAnalysis:k,projectRoot:m||``},P=`default`;j?(P=`complexity-report`,h.info(`Using expansion prompt from complexity report for task ${b.id}.`)):r?(P=`research`,h.info(`Using research variant for task ${b.id}.`)):h.info(`Using standard prompt generation for task ${b.id}.`);let{systemPrompt:ee,userPrompt:te}=O.loadPrompt(`expand-task`,N,P);h.debug(`Selected variant: ${P}`),h.debug(`Prompt params passed: ${JSON.stringify(N,null,2)}`),h.debug(`System prompt (first 500 chars): ${ee.substring(0,500)}...`),h.debug(`User prompt (first 500 chars): ${te.substring(0,500)}...`);let ne=[],re=null;p===`text`&&(re=sl(`Generating ${S||`appropriate number of`} subtasks...\n`));let ie=null;try{ie=await i({prompt:te,systemPrompt:ee,role:r?`research`:`main`,session:c,projectRoot:m,schema:ha[`expand-task`],objectName:`subtasks`,commandName:`expand-task`,outputType:p});let e=ie?.mainResult;if(!e||!Array.isArray(e.subtasks))throw Error(`AI response did not include a valid subtasks array.`);ne=e.subtasks.map(e=>({...e,dependencies:e.dependencies??[],status:e.status??`pending`,testStrategy:e.testStrategy??null})),h.info(`Received ${ne.length} subtasks from AI.`)}catch(e){throw re&&$(re),h.error(`Error during AI call or parsing for task ${t}: ${e.message}`,`error`),e}finally{re&&$(re)}return Array.isArray(b.subtasks)||(b.subtasks=[]),b.subtasks.push(...ne),l.tasks[u]=b,y(e,l,m,d),p===`text`&&ie&&ie.telemetryData&&Sl(ie.telemetryData,`cli`),{task:b,telemetryData:ie?.telemetryData,tagInfo:ie?.tagInfo}}catch(e){throw h.error(`Error expanding task ${t}: ${e.message}`,`error`),p===`text`&&je(c)&&console.error(e),e}}var Wa=Ua;async function Ga(e,t,n=!1,r=``,i=!1,a={},o=`text`){let{session:s,mcpLog:c,projectRoot:l,tag:u,complexityReportPath:d}=a,f=!!c,p=l||ze();if(!p)throw Error(`Could not determine project root directory`);let m=c||(o===`json`?{info:e=>{},warn:e=>{},error:e=>console.error(`ERROR: ${e}`),debug:e=>{}}:{info:e=>!L()&&z(`info`,e),warn:e=>!L()&&z(`warn`,e),error:e=>!L()&&z(`error`,e),debug:e=>!L()&&je(s)&&z(`debug`,e)}),h=null,g=0,_=0,v=0,y=[];!f&&o===`text`&&(h=sl(`Analyzing tasks for expansion...`));try{m.info(`Reading tasks from ${e}`);let s=D(e,p,u);if(!s||!s.tasks)throw Error(`Invalid tasks data in ${e}`);let c=s.tasks.filter(e=>(e.status===`pending`||e.status===`in-progress`)&&(!e.subtasks||e.subtasks.length===0||i));if(v=c.length,m.info(`Found ${v} tasks eligible for expansion.`),h&&$(h,`Analysis complete.`),v===0)return m.info(`No tasks eligible for expansion.`),{success:!0,expandedCount:0,failedCount:0,skippedCount:0,tasksToExpand:0,telemetryData:y,message:`No tasks eligible for expansion.`};for(let l of c){let c=null;!f&&o===`text`&&(c=sl(`Expanding task ${l.id}...`));try{let o=await Wa(e,l.id,t,n,r,{...a,projectRoot:p,tag:s.tag||u,complexityReportPath:d},i);g++,o&&o.telemetryData&&y.push(o.telemetryData),c&&$(c,`Task ${l.id} expanded.`),m.info(`Successfully expanded task ${l.id}.`)}catch(e){_++,c&&$(c,`Failed to expand task ${l.id}.`,!1),m.error(`Failed to expand task ${l.id}: ${e.message}`)}}m.info(`Expansion complete: ${g} expanded, ${_} failed.`);let l=ye(y,`expand-all-tasks`);if(o===`text`){let e=`${B.white.bold(`Expansion Summary:`)}\n\n${B.cyan(`-`)} Attempted: ${B.bold(v)}\n${B.green(`-`)} Expanded: ${B.bold(g)}\n${B.gray(`-`)} Skipped: ${B.bold(0)}\n${B.red(`-`)} Failed: ${B.bold(_)}`;console.log(W(e,{padding:1,margin:{top:1},borderColor:_>0?`red`:`green`,borderStyle:`round`}))}return o===`text`&&l&&Sl(l,`cli`),{success:!0,expandedCount:g,failedCount:_,skippedCount:0,tasksToExpand:v,telemetryData:l}}catch(e){throw h&&$(h,`Error.`,!1),m.error(`Error during expand all operation: ${e.message}`),!f&&je(s)&&console.error(e),e}}var Ka=Ga;function qa(e,t,n){if(t.parentTaskId===n||t.dependencies&&t.dependencies.includes(n))return!0;if(t.dependencies)for(let r of t.dependencies){let t=e.find(e=>e.id===r);if(t&&qa(e,t,n))return!0}if(t.subtasks){for(let r of t.subtasks)if(qa(e,r,n))return!0}return!1}var Ja=qa;async function Ya(e,t,n=null,r=!1,i=`text`,a={}){let{projectRoot:o,tag:c}=a;try{let a;try{let e=await(await I({projectPath:o||process.cwd()})).tasks.list({tag:c});a={tasks:e.tasks},z(`debug`,`Loaded ${e.tasks.length} tasks via tm-core (${e.storageType} storage)`)}catch(t){z(`warn`,`TmCore failed, falling back to legacy readJSON: ${t.message}`),a=D(e,o,c)}if(!a||!a.tasks)throw Error(`No valid tasks found in ${e}`);let l=Ue(n);l&&l.complexityAnalysis&&a.tasks.forEach(e=>Fe(e,l));let u;if(t&&t.toLowerCase()!==`all`){let e=t.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0);u=a.tasks.filter(t=>t.status&&e.includes(t.status.toLowerCase()))}else u=a.tasks;let d=a.tasks.length,f=a.tasks.filter(e=>e.status===`done`||e.status===`completed`).length,p=d>0?f/d*100:0,m=f,h=a.tasks.filter(e=>e.status===`in-progress`).length,g=a.tasks.filter(e=>e.status===`pending`).length,_=a.tasks.filter(e=>e.status===`blocked`).length,v=a.tasks.filter(e=>e.status===`deferred`).length,y=a.tasks.filter(e=>e.status===`cancelled`).length,b=a.tasks.filter(e=>e.status===`review`).length,x=0,S=0,C=0,w=0,T=0,E=0,O=0,k=0;a.tasks.forEach(e=>{e.subtasks&&e.subtasks.length>0&&(x+=e.subtasks.length,S+=e.subtasks.filter(e=>e.status===`done`||e.status===`completed`).length,C+=e.subtasks.filter(e=>e.status===`in-progress`).length,w+=e.subtasks.filter(e=>e.status===`pending`).length,T+=e.subtasks.filter(e=>e.status===`blocked`).length,E+=e.subtasks.filter(e=>e.status===`deferred`).length,O+=e.subtasks.filter(e=>e.status===`cancelled`).length,k+=e.subtasks.filter(e=>e.status===`review`).length)});let A=x>0?S/x*100:0,j=new Set(a.tasks.filter(e=>e.status===`done`||e.status===`completed`).map(e=>e.id)),M=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&(!e.dependencies||e.dependencies.length===0)).length,N=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>j.has(e))).length,P=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>j.has(e))).length,ee=M+N,te={};a.tasks.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{te[e]=(te[e]||0)+1})});let ne=null,re=0;for(let[e,t]of Object.entries(te))t>re&&(re=t,ne=parseInt(e));let ie=ne===null?null:a.tasks.find(e=>e.id===ne),ae=a.tasks.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0)/a.tasks.length,F=Gr(a.tasks,l);if(i===`json`)return{tasks:u.map(e=>{let{details:t,...n}=e;return n.subtasks&&Array.isArray(n.subtasks)&&(n.subtasks=n.subtasks.map(e=>{let{details:t,...n}=e;return n})),n}),filter:t||`all`,stats:{total:d,completed:m,inProgress:h,pending:g,blocked:_,deferred:v,cancelled:y,review:b,completionPercentage:p,subtasks:{total:x,completed:S,inProgress:C,pending:w,blocked:T,deferred:E,cancelled:O,completionPercentage:A}}};if(i===`markdown-readme`)return Za(a,u,{totalTasks:d,completedTasks:f,completionPercentage:p,doneCount:m,inProgressCount:h,pendingCount:g,blockedCount:_,deferredCount:v,cancelledCount:y,totalSubtasks:x,completedSubtasks:S,subtaskCompletionPercentage:A,inProgressSubtasks:C,pendingSubtasks:w,blockedSubtasks:T,deferredSubtasks:E,cancelledSubtasks:O,reviewSubtasks:k,tasksWithNoDeps:M,tasksReadyToWork:ee,tasksWithUnsatisfiedDeps:P,mostDependedOnTask:ie,mostDependedOnTaskId:ne,maxDependents:re,avgDependenciesPerTask:ae,complexityReport:l,withSubtasks:r,nextItem:F});if(i===`compact`)return to(u,r);let oe={"in-progress":d>0?h/d*100:0,pending:d>0?g/d*100:0,blocked:d>0?_/d*100:0,deferred:d>0?v/d*100:0,cancelled:d>0?y/d*100:0,review:d>0?b/d*100:0},se={"in-progress":x>0?C/x*100:0,pending:x>0?w/x*100:0,blocked:x>0?T/x*100:0,deferred:x>0?E/x*100:0,cancelled:x>0?O/x*100:0,review:x>0?k/x*100:0},ce=ul(p,30,oe),le=ul(A,30,se),ue;try{ue=process.stdout.columns}catch{z(`debug`,`Could not determine terminal width, using default`)}ue||=80,ue=Math.max(ue,80);let de=B.white.bold(`Project Dashboard`)+`
824
- Tasks Progress: ${B.greenBright(ce)} ${p.toFixed(0)}%\nDone: ${B.green(m)} In Progress: ${B.blue(h)} Pending: ${B.yellow(g)} Blocked: ${B.red(_)} Deferred: ${B.gray(v)} Cancelled: ${B.gray(y)}\n\nSubtasks Progress: ${B.cyan(le)} ${A.toFixed(0)}%\nCompleted: ${B.green(S)}/${x} In Progress: ${B.blue(C)} Pending: ${B.yellow(w)} Blocked: ${B.red(T)} Deferred: ${B.gray(E)} Cancelled: ${B.gray(O)}\n\n`+B.cyan.bold(`Priority Breakdown:`)+`
823
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to generate new subtasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master list --with-subtasks`)} to verify changes`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})))):L()||console.log(W(B.yellow(`No subtasks were cleared`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}var qa=Ka;function Ja(e,t){let n=!!e,r=e||{info:e=>!L()&&z(`info`,e),warn:e=>!L()&&z(`warn`,e),error:e=>!L()&&z(`error`,e),debug:e=>!L()&&ke(t)&&z(`debug`,e)};return{logger:r,report:(e,...t)=>{n?typeof r[e]==`function`?r[e](...t):r.info(...t):L()||z(e,...t)},isMCP:n}}async function Ya(e,t,n,r=!1,a=``,o={},s=!1){let{session:c,mcpLog:l,projectRoot:u,tag:d,complexityReportPath:f}=o,p=l?`json`:`text`,m=u||Le(e),{logger:h,report:g,isMCP:v}=Ja(l,c);v&&h.info(`expandTask called with context: session=${!!c}`);try{let o=await Hr({taskId:t,numSubtasks:n,useResearch:r,additionalContext:a,force:s,projectRoot:m,tag:d,isMCP:v,outputFormat:p,report:g});if(o)return o;h.info(`Reading tasks from ${e}`);let l=E(e,m,d);if(!l||!l.tasks)throw Error(`Invalid tasks data in ${e}`);let u=l.tasks.findIndex(e=>e.id===parseInt(t,10));if(u===-1)throw Error(`Task ${t} not found`);let b=l.tasks[u];h.info(`Expanding task ${t}: ${b.title}${r?` with research`:``}`),s&&Array.isArray(b.subtasks)&&b.subtasks.length>0&&(h.info(`Force flag set. Clearing existing ${b.subtasks.length} subtasks for task ${t}.`),b.subtasks=[]);let x=``;try{let e=new Fa(m,d),n=new Ua(je(l.tasks),`expand-task`),r=`${b.title} ${b.description}`,i=n.findRelevantTasks(r,{maxResults:5,includeSelf:!0}),a=n.getTaskIds(i),o=[...new Set([t.toString(),...a])];o.length>0&&(x=(await e.gather({tasks:o,format:`research`})).context||``)}catch(e){h.warn(`Could not gather context: ${e.message}`)}let S,C=``,w=null;h.info(`Looking for complexity report at: ${f}${d===`master`?``:` (tag-specific for '${d}')`}`);try{V.existsSync(f)?(w=E(f)?.complexityAnalysis?.find(e=>e.taskId===b.id),w?(h.info(`Found complexity analysis for task ${b.id}: Score ${w.complexityScore}`),w.reasoning&&(C=`\nComplexity Analysis Reasoning: ${w.reasoning}`)):h.info(`No complexity analysis found for task ${b.id} in report.`)):h.info(`Complexity report not found at ${f}. Skipping complexity check.`)}catch(e){h.warn(`Could not read or parse complexity report: ${e.message}. Proceeding without it.`)}let T=parseInt(n,10);!Number.isNaN(T)&&T>=0?(S=T,h.info(`Using explicitly provided subtask count: ${S}`)):w?.recommendedSubtasks?(S=parseInt(w.recommendedSubtasks,10),h.info(`Using subtask count from complexity report: ${S}`)):(S=de(c),h.info(`Using default number of subtasks: ${S}`)),(Number.isNaN(S)||S<0)&&(h.warn(`Invalid subtask count determined (${S}), defaulting to 3.`),S=3);let D=(b.subtasks?.length||0)+1,O=Na(),k=_(r,m,c),A=``;(a||C)&&(A=`\n\n${a}${C}`.trim()),x&&(A=`${A}\n\n# Project Context\n\n${x}`.trim());let j;w?.expansionPrompt&&(typeof w.expansionPrompt==`string`?j=w.expansionPrompt:typeof w.expansionPrompt==`object`&&w.expansionPrompt.text&&(j=w.expansionPrompt.text));let M=x;typeof x==`object`&&x&&(M=x.data?x.data:x.text?x.text:JSON.stringify(x));let N={task:b,subtaskCount:S,nextSubtaskId:D,additionalContext:a,complexityReasoningContext:C,gatheredContext:M||``,useResearch:r,expansionPrompt:j||void 0,hasCodebaseAnalysis:k,projectRoot:m||``},P=`default`;j?(P=`complexity-report`,h.info(`Using expansion prompt from complexity report for task ${b.id}.`)):r?(P=`research`,h.info(`Using research variant for task ${b.id}.`)):h.info(`Using standard prompt generation for task ${b.id}.`);let{systemPrompt:ee,userPrompt:te}=O.loadPrompt(`expand-task`,N,P);h.debug(`Selected variant: ${P}`),h.debug(`Prompt params passed: ${JSON.stringify(N,null,2)}`),h.debug(`System prompt (first 500 chars): ${ee.substring(0,500)}...`),h.debug(`User prompt (first 500 chars): ${te.substring(0,500)}...`);let ne=[],re=null;p===`text`&&(re=pl(`Generating ${S||`appropriate number of`} subtasks...\n`));let ie=null;try{ie=await i({prompt:te,systemPrompt:ee,role:r?`research`:`main`,session:c,projectRoot:m,schema:xa[`expand-task`],objectName:`subtasks`,commandName:`expand-task`,outputType:p});let e=ie?.mainResult;if(!e||!Array.isArray(e.subtasks))throw Error(`AI response did not include a valid subtasks array.`);ne=e.subtasks.map(e=>({...e,dependencies:e.dependencies??[],status:e.status??`pending`,testStrategy:e.testStrategy??null})),h.info(`Received ${ne.length} subtasks from AI.`)}catch(e){throw re&&$(re),h.error(`Error during AI call or parsing for task ${t}: ${e.message}`,`error`),e}finally{re&&$(re)}return Array.isArray(b.subtasks)||(b.subtasks=[]),b.subtasks.push(...ne),l.tasks[u]=b,y(e,l,m,d),p===`text`&&ie&&ie.telemetryData&&Ol(ie.telemetryData,`cli`),{task:b,telemetryData:ie?.telemetryData,tagInfo:ie?.tagInfo}}catch(e){throw h.error(`Error expanding task ${t}: ${e.message}`,`error`),p===`text`&&ke(c)&&console.error(e),e}}var Xa=Ya;async function Za(e,t,n=!1,r=``,i=!1,a={},o=`text`){let{session:s,mcpLog:c,projectRoot:l,tag:u,complexityReportPath:d}=a,f=!!c,p=l||Le();if(!p)throw Error(`Could not determine project root directory`);let m=c||(o===`json`?{info:e=>{},warn:e=>{},error:e=>console.error(`ERROR: ${e}`),debug:e=>{}}:{info:e=>!L()&&z(`info`,e),warn:e=>!L()&&z(`warn`,e),error:e=>!L()&&z(`error`,e),debug:e=>!L()&&ke(s)&&z(`debug`,e)}),h=null,g=0,_=0,v=0,y=[];!f&&o===`text`&&(h=pl(`Analyzing tasks for expansion...`));try{m.info(`Reading tasks from ${e}`);let s=E(e,p,u);if(!s||!s.tasks)throw Error(`Invalid tasks data in ${e}`);let c=s.tasks.filter(e=>(e.status===`pending`||e.status===`in-progress`)&&(!e.subtasks||e.subtasks.length===0||i));if(v=c.length,m.info(`Found ${v} tasks eligible for expansion.`),h&&$(h,`Analysis complete.`),v===0)return m.info(`No tasks eligible for expansion.`),{success:!0,expandedCount:0,failedCount:0,skippedCount:0,tasksToExpand:0,telemetryData:y,message:`No tasks eligible for expansion.`};for(let l of c){let c=null;!f&&o===`text`&&(c=pl(`Expanding task ${l.id}...`));try{let o=await Xa(e,l.id,t,n,r,{...a,projectRoot:p,tag:s.tag||u,complexityReportPath:d},i);g++,o&&o.telemetryData&&y.push(o.telemetryData),c&&$(c,`Task ${l.id} expanded.`),m.info(`Successfully expanded task ${l.id}.`)}catch(e){_++,c&&$(c,`Failed to expand task ${l.id}.`,!1),m.error(`Failed to expand task ${l.id}: ${e.message}`)}}m.info(`Expansion complete: ${g} expanded, ${_} failed.`);let l=ve(y,`expand-all-tasks`);if(o===`text`){let e=`${B.white.bold(`Expansion Summary:`)}\n\n${B.cyan(`-`)} Attempted: ${B.bold(v)}\n${B.green(`-`)} Expanded: ${B.bold(g)}\n${B.gray(`-`)} Skipped: ${B.bold(0)}\n${B.red(`-`)} Failed: ${B.bold(_)}`;console.log(W(e,{padding:1,margin:{top:1},borderColor:_>0?`red`:`green`,borderStyle:`round`}))}return o===`text`&&l&&Ol(l,`cli`),{success:!0,expandedCount:g,failedCount:_,skippedCount:0,tasksToExpand:v,telemetryData:l}}catch(e){throw h&&$(h,`Error.`,!1),m.error(`Error during expand all operation: ${e.message}`),!f&&ke(s)&&console.error(e),e}}var Qa=Za;function $a(e,t,n){if(t.parentTaskId===n||t.dependencies&&t.dependencies.includes(n))return!0;if(t.dependencies)for(let r of t.dependencies){let t=e.find(e=>e.id===r);if(t&&$a(e,t,n))return!0}if(t.subtasks){for(let r of t.subtasks)if($a(e,r,n))return!0}return!1}var eo=$a;async function to(e,t,n=null,r=!1,i=`text`,a={}){let{projectRoot:o,tag:c}=a;try{let a;try{let e=await(await I({projectPath:o||process.cwd()})).tasks.list({tag:c});a={tasks:e.tasks},z(`debug`,`Loaded ${e.tasks.length} tasks via tm-core (${e.storageType} storage)`)}catch(t){z(`warn`,`TmCore failed, falling back to legacy readJSON: ${t.message}`),a=E(e,o,c)}if(!a||!a.tasks)throw Error(`No valid tasks found in ${e}`);let l=He(n);l&&l.complexityAnalysis&&a.tasks.forEach(e=>Ne(e,l));let u;if(t&&t.toLowerCase()!==`all`){let e=t.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0);u=a.tasks.filter(t=>t.status&&e.includes(t.status.toLowerCase()))}else u=a.tasks;let d=a.tasks.length,f=a.tasks.filter(e=>e.status===`done`||e.status===`completed`).length,p=d>0?f/d*100:0,m=f,h=a.tasks.filter(e=>e.status===`in-progress`).length,g=a.tasks.filter(e=>e.status===`pending`).length,_=a.tasks.filter(e=>e.status===`blocked`).length,v=a.tasks.filter(e=>e.status===`deferred`).length,y=a.tasks.filter(e=>e.status===`cancelled`).length,b=a.tasks.filter(e=>e.status===`review`).length,x=0,S=0,C=0,w=0,T=0,D=0,O=0,k=0;a.tasks.forEach(e=>{e.subtasks&&e.subtasks.length>0&&(x+=e.subtasks.length,S+=e.subtasks.filter(e=>e.status===`done`||e.status===`completed`).length,C+=e.subtasks.filter(e=>e.status===`in-progress`).length,w+=e.subtasks.filter(e=>e.status===`pending`).length,T+=e.subtasks.filter(e=>e.status===`blocked`).length,D+=e.subtasks.filter(e=>e.status===`deferred`).length,O+=e.subtasks.filter(e=>e.status===`cancelled`).length,k+=e.subtasks.filter(e=>e.status===`review`).length)});let A=x>0?S/x*100:0,j=new Set(a.tasks.filter(e=>e.status===`done`||e.status===`completed`).map(e=>e.id)),M=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&(!e.dependencies||e.dependencies.length===0)).length,N=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>j.has(e))).length,P=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>j.has(e))).length,ee=M+N,te={};a.tasks.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{te[e]=(te[e]||0)+1})});let ne=null,re=0;for(let[e,t]of Object.entries(te))t>re&&(re=t,ne=parseInt(e));let ie=ne===null?null:a.tasks.find(e=>e.id===ne),ae=a.tasks.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0)/a.tasks.length,F=qr(a.tasks,l);if(i===`json`)return{tasks:u.map(e=>{let{details:t,...n}=e;return n.subtasks&&Array.isArray(n.subtasks)&&(n.subtasks=n.subtasks.map(e=>{let{details:t,...n}=e;return n})),n}),filter:t||`all`,stats:{total:d,completed:m,inProgress:h,pending:g,blocked:_,deferred:v,cancelled:y,review:b,completionPercentage:p,subtasks:{total:x,completed:S,inProgress:C,pending:w,blocked:T,deferred:D,cancelled:O,completionPercentage:A}}};if(i===`markdown-readme`)return ro(a,u,{totalTasks:d,completedTasks:f,completionPercentage:p,doneCount:m,inProgressCount:h,pendingCount:g,blockedCount:_,deferredCount:v,cancelledCount:y,totalSubtasks:x,completedSubtasks:S,subtaskCompletionPercentage:A,inProgressSubtasks:C,pendingSubtasks:w,blockedSubtasks:T,deferredSubtasks:D,cancelledSubtasks:O,reviewSubtasks:k,tasksWithNoDeps:M,tasksReadyToWork:ee,tasksWithUnsatisfiedDeps:P,mostDependedOnTask:ie,mostDependedOnTaskId:ne,maxDependents:re,avgDependenciesPerTask:ae,complexityReport:l,withSubtasks:r,nextItem:F});if(i===`compact`)return so(u,r);let oe={"in-progress":d>0?h/d*100:0,pending:d>0?g/d*100:0,blocked:d>0?_/d*100:0,deferred:d>0?v/d*100:0,cancelled:d>0?y/d*100:0,review:d>0?b/d*100:0},se={"in-progress":x>0?C/x*100:0,pending:x>0?w/x*100:0,blocked:x>0?T/x*100:0,deferred:x>0?D/x*100:0,cancelled:x>0?O/x*100:0,review:x>0?k/x*100:0},ce=gl(p,30,oe),le=gl(A,30,se),ue;try{ue=process.stdout.columns}catch{z(`debug`,`Could not determine terminal width, using default`)}ue||=80,ue=Math.max(ue,80);let de=B.white.bold(`Project Dashboard`)+`
824
+ Tasks Progress: ${B.greenBright(ce)} ${p.toFixed(0)}%\nDone: ${B.green(m)} In Progress: ${B.blue(h)} Pending: ${B.yellow(g)} Blocked: ${B.red(_)} Deferred: ${B.gray(v)} Cancelled: ${B.gray(y)}\n\nSubtasks Progress: ${B.cyan(le)} ${A.toFixed(0)}%\nCompleted: ${B.green(S)}/${x} In Progress: ${B.blue(C)} Pending: ${B.yellow(w)} Blocked: ${B.red(T)} Deferred: ${B.gray(D)} Cancelled: ${B.gray(O)}\n\n`+B.cyan.bold(`Priority Breakdown:`)+`
825
825
  ${B.red(`•`)} ${B.white(`High priority:`)} ${a.tasks.filter(e=>e.priority===`high`).length}\n${B.yellow(`•`)} ${B.white(`Medium priority:`)} ${a.tasks.filter(e=>e.priority===`medium`).length}\n${B.green(`•`)} ${B.white(`Low priority:`)} ${a.tasks.filter(e=>e.priority===`low`).length}`,fe=B.white.bold(`Dependency Status & Next Task`)+`
826
826
  `+B.cyan.bold(`Dependency Metrics:`)+`
827
827
  ${B.green(`•`)} ${B.white(`Tasks with no dependencies:`)} ${M}\n${B.green(`•`)} ${B.white(`Tasks ready to work on:`)} ${ee}\n${B.yellow(`•`)} ${B.white(`Tasks blocked by dependencies:`)} ${P}\n${B.magenta(`•`)} ${B.white(`Most depended-on task:`)} ${ie?B.cyan(`#${ne} (${re} dependents)`):B.gray(`None`)}\n${B.blue(`•`)} ${B.white(`Avg dependencies per task:`)} ${ae.toFixed(1)}\n\n`+B.cyan.bold(`Next Task to Work On:`)+`
828
828
  ID: ${B.cyan(F?F.id:`N/A`)} - ${F?B.white.bold(s(F.title,40)):B.yellow(`No task available`)}
829
- Priority: ${F?B.white(F.priority||`medium`):``} Dependencies: ${F?fl(F.dependencies,a.tasks,!0,l):``}
830
- Complexity: ${F&&F.complexityScore?ml(F.complexityScore):B.gray(`N/A`)}`;if(ue>=104){let e=ue,t=Math.floor(e/2),n=t-4,r=W(de,{padding:1,borderColor:`blue`,borderStyle:`round`,width:n,dimBorder:!1}),i=W(fe,{padding:1,borderColor:`magenta`,borderStyle:`round`,width:n,dimBorder:!1}),a=r.split(`
829
+ Priority: ${F?B.white(F.priority||`medium`):``} Dependencies: ${F?vl(F.dependencies,a.tasks,!0,l):``}
830
+ Complexity: ${F&&F.complexityScore?bl(F.complexityScore):B.gray(`N/A`)}`;if(ue>=104){let e=ue,t=Math.floor(e/2),n=t-4,r=W(de,{padding:1,borderColor:`blue`,borderStyle:`round`,width:n,dimBorder:!1}),i=W(fe,{padding:1,borderColor:`magenta`,borderStyle:`round`,width:n,dimBorder:!1}),a=r.split(`
831
831
  `),o=i.split(`
832
832
  `),s=Math.max(a.length,o.length),c=[];for(let e=0;e<s;e++){let n=e<a.length?a[e]:``,r=e<o.length?o[e]:``,i=n.trimEnd().padEnd(t,` `);c.push(i+r)}console.log(c.join(`
833
- `))}else{let e=W(de,{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:0,bottom:1}}),t=W(fe,{padding:1,borderColor:`magenta`,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}if(u.length===0){console.log(W(t?B.yellow(`No tasks with status '${t}' found`):B.yellow(`No tasks found`),{padding:1,borderColor:`yellow`,borderStyle:`round`}));return}let pe=r?10:7,me=100-pe-15-12-20-10,he=ue-10,ge=Math.floor(he*(pe/100)),_e=Math.floor(he*(15/100)),ve=Math.floor(he*(12/100)),ye=Math.floor(he*(20/100)),be=Math.floor(he*(10/100)),xe=Math.floor(he*(me/100)),Se=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`),B.cyan.bold(`Priority`),B.cyan.bold(`Dependencies`),B.cyan.bold(`Complexity`)],colWidths:[ge,xe,_e,ve,ye,be],style:{head:[],border:[],compact:!1},wordWrap:!0,wrapOnWordBoundary:!0});u.forEach(e=>{let t=`None`;t=e.dependencies&&e.dependencies.length>0?fl(e.dependencies,a.tasks,!0,l):B.gray(`None`);let n=e.title.replace(/\n/g,` `),i={high:B.red,medium:B.yellow,low:B.gray}[e.priority||`medium`]||B.white,o=dl(e.status,!0);Se.push([e.id.toString(),s(n,xe-3),o,i(s(e.priority||`medium`,ve-2)),t,e.complexityScore?ml(e.complexityScore):B.gray(`N/A`)]),r&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(t=>{let n=`None`;t.dependencies&&t.dependencies.length>0&&(n=t.dependencies.map(t=>{if(typeof t==`number`&&t<100){let n=e.subtasks.find(e=>e.id===t);if(n){let r=n.status===`done`||n.status===`completed`,i=n.status===`in-progress`;return r?B.green.bold(`${e.id}.${t}`):i?B.hex(`#FFA500`).bold(`${e.id}.${t}`):B.red.bold(`${e.id}.${t}`)}}let n=a.tasks.find(e=>e.id===t);if(n){Fe(n,l);let e=n.status===`done`||n.status===`completed`,r=n.status===`in-progress`;return e?B.green.bold(`${t}`):r?B.hex(`#FFA500`).bold(`${t}`):B.red.bold(`${t}`)}return B.cyan(t.toString())}).join(`, `)||B.gray(`None`)),Se.push([`${e.id}.${t.id}`,B.dim(`└─ ${s(t.title,xe-5)}`),dl(t.status,!0),B.dim(`-`),n,t.complexityScore?B.gray(`${t.complexityScore}`):B.gray(`N/A`)])})});try{console.log(Se.toString())}catch(e){z(`error`,`Error rendering table: ${e.message}`),console.log(B.yellow(`
834
- Falling back to simple task list due to terminal width constraints:`)),u.forEach(e=>{console.log(`${B.cyan(e.id)}: ${B.white(e.title)} - ${dl(e.status)}`)})}t&&(console.log(B.yellow(`\nFiltered by status: ${t}`)),console.log(B.yellow(`Showing ${u.length} of ${d} tasks`)));let Ce={high:B.red.bold,medium:B.yellow,low:B.gray};if(F){let e=``,t=a.tasks.find(e=>String(e.id)===String(F.id));t&&t.subtasks&&t.subtasks.length>0&&(e=`\n\n${B.white.bold(`Subtasks:`)}\n`,e+=t.subtasks.map(e=>{Fe(e,l);let n=e.status||`pending`,r={done:B.green,completed:B.green,pending:B.yellow,"in-progress":B.blue,deferred:B.gray,blocked:B.red,cancelled:B.gray}[n.toLowerCase()]||B.white;return`${B.cyan(`${t.id}.${e.id}`)} [${r(n)}] ${e.title}`}).join(`
833
+ `))}else{let e=W(de,{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:0,bottom:1}}),t=W(fe,{padding:1,borderColor:`magenta`,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}if(u.length===0){console.log(W(t?B.yellow(`No tasks with status '${t}' found`):B.yellow(`No tasks found`),{padding:1,borderColor:`yellow`,borderStyle:`round`}));return}let pe=r?10:7,me=100-pe-15-12-20-10,he=ue-10,ge=Math.floor(he*(pe/100)),_e=Math.floor(he*(15/100)),ve=Math.floor(he*(12/100)),ye=Math.floor(he*(20/100)),be=Math.floor(he*(10/100)),xe=Math.floor(he*(me/100)),Se=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`),B.cyan.bold(`Priority`),B.cyan.bold(`Dependencies`),B.cyan.bold(`Complexity`)],colWidths:[ge,xe,_e,ve,ye,be],style:{head:[],border:[],compact:!1},wordWrap:!0,wrapOnWordBoundary:!0});u.forEach(e=>{let t=`None`;t=e.dependencies&&e.dependencies.length>0?vl(e.dependencies,a.tasks,!0,l):B.gray(`None`);let n=e.title.replace(/\n/g,` `),i={high:B.red,medium:B.yellow,low:B.gray}[e.priority||`medium`]||B.white,o=_l(e.status,!0);Se.push([e.id.toString(),s(n,xe-3),o,i(s(e.priority||`medium`,ve-2)),t,e.complexityScore?bl(e.complexityScore):B.gray(`N/A`)]),r&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(t=>{let n=`None`;t.dependencies&&t.dependencies.length>0&&(n=t.dependencies.map(t=>{if(typeof t==`number`&&t<100){let n=e.subtasks.find(e=>e.id===t);if(n){let r=n.status===`done`||n.status===`completed`,i=n.status===`in-progress`;return r?B.green.bold(`${e.id}.${t}`):i?B.hex(`#FFA500`).bold(`${e.id}.${t}`):B.red.bold(`${e.id}.${t}`)}}let n=a.tasks.find(e=>e.id===t);if(n){Ne(n,l);let e=n.status===`done`||n.status===`completed`,r=n.status===`in-progress`;return e?B.green.bold(`${t}`):r?B.hex(`#FFA500`).bold(`${t}`):B.red.bold(`${t}`)}return B.cyan(t.toString())}).join(`, `)||B.gray(`None`)),Se.push([`${e.id}.${t.id}`,B.dim(`└─ ${s(t.title,xe-5)}`),_l(t.status,!0),B.dim(`-`),n,t.complexityScore?B.gray(`${t.complexityScore}`):B.gray(`N/A`)])})});try{console.log(Se.toString())}catch(e){z(`error`,`Error rendering table: ${e.message}`),console.log(B.yellow(`
834
+ Falling back to simple task list due to terminal width constraints:`)),u.forEach(e=>{console.log(`${B.cyan(e.id)}: ${B.white(e.title)} - ${_l(e.status)}`)})}t&&(console.log(B.yellow(`\nFiltered by status: ${t}`)),console.log(B.yellow(`Showing ${u.length} of ${d} tasks`)));let Ce={high:B.red.bold,medium:B.yellow,low:B.gray};if(F){let e=``,t=a.tasks.find(e=>String(e.id)===String(F.id));t&&t.subtasks&&t.subtasks.length>0&&(e=`\n\n${B.white.bold(`Subtasks:`)}\n`,e+=t.subtasks.map(e=>{Ne(e,l);let n=e.status||`pending`,r={done:B.green,completed:B.green,pending:B.yellow,"in-progress":B.blue,deferred:B.gray,blocked:B.red,cancelled:B.gray}[n.toLowerCase()]||B.white;return`${B.cyan(`${t.id}.${e.id}`)} [${r(n)}] ${e.title}`}).join(`
835
835
  `)),console.log(W(B.hex(`#FF8800`).bold(`🔥 Next Task to Work On: #${F.id} - ${F.title}`)+`
836
836
 
837
- ${B.white(`Priority:`)} ${Ce[F.priority||`medium`](F.priority||`medium`)} ${B.white(`Status:`)} ${dl(F.status,!0)}\n${B.white(`Dependencies:`)} ${F.dependencies&&F.dependencies.length>0?fl(F.dependencies,a.tasks,!0,l):B.gray(`None`)}\n\n${B.white(`Description:`)} ${Xa(F,a.tasks)}`+e+`
837
+ ${B.white(`Priority:`)} ${Ce[F.priority||`medium`](F.priority||`medium`)} ${B.white(`Status:`)} ${_l(F.status,!0)}\n${B.white(`Dependencies:`)} ${F.dependencies&&F.dependencies.length>0?vl(F.dependencies,a.tasks,!0,l):B.gray(`None`)}\n\n${B.white(`Description:`)} ${no(F,a.tasks)}`+e+`
838
838
 
839
839
  ${B.cyan(`Start working:`)} ${B.yellow(`task-master set-status --id=${F.id} --status=in-progress`)}\n${B.cyan(`View details:`)} ${B.yellow(`task-master show ${F.id}`)}`,{padding:{left:2,right:2,top:1,bottom:1},borderColor:`#FF8800`,borderStyle:`round`,margin:{top:1,bottom:1},title:`⚡ RECOMMENDED NEXT TASK ⚡`,titleAlignment:`center`,width:ue-4,fullscreen:!1}))}else console.log(W(B.hex(`#FF8800`).bold(`No eligible next task found`)+`
840
840
 
841
841
  All pending tasks have dependencies that are not yet completed, or all tasks are done.`,{padding:1,borderColor:`#FF8800`,borderStyle:`round`,margin:{top:1,bottom:1},title:`⚡ NEXT TASK ⚡`,titleAlignment:`center`,width:ue-4}));console.log(W(B.white.bold(`Suggested Next Steps:`)+`
842
842
 
843
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master next`)} to see what to work on next\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master set-status --id=<id> --status=done`)} to mark a task as complete`,{padding:1,borderColor:`gray`,borderStyle:`round`,margin:{top:1}}))}catch(e){if(z(`error`,`Error listing tasks: ${e.message}`),i===`json`)throw{code:`TASK_LIST_ERROR`,message:e.message,details:e.stack};console.error(B.red(`Error: ${e.message}`)),process.exit(1)}}function Xa(e,t){if(!e)return`N/A`;if(e.parentId){let n=t.find(t=>t.id===e.parentId);return n?.subtasks?.find(t=>`${n.id}.${t.id}`===e.id)?.description||`No description available.`}else return t.find(t=>String(t.id)===String(e.id))?.description||`No description available.`}function Za(e,t,n){let{totalTasks:r,completedTasks:i,completionPercentage:a,doneCount:o,inProgressCount:s,pendingCount:c,blockedCount:l,deferredCount:u,cancelledCount:d,totalSubtasks:f,completedSubtasks:p,subtaskCompletionPercentage:m,inProgressSubtasks:h,pendingSubtasks:g,blockedSubtasks:_,deferredSubtasks:v,cancelledSubtasks:y,tasksWithNoDeps:b,tasksReadyToWork:x,tasksWithUnsatisfiedDeps:S,mostDependedOnTask:C,mostDependedOnTaskId:w,maxDependents:T,avgDependenciesPerTask:E,complexityReport:D,withSubtasks:O,nextItem:k}=n,A=``,j=(e,t=20)=>{let n=Math.round(e/100*t),r=t-n;return`█`.repeat(n)+`░`.repeat(r)},M=j(a,20),N=j(m,20);A+=`| Project Dashboard | |
843
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master next`)} to see what to work on next\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master set-status --id=<id> --status=done`)} to mark a task as complete`,{padding:1,borderColor:`gray`,borderStyle:`round`,margin:{top:1}}))}catch(e){if(z(`error`,`Error listing tasks: ${e.message}`),i===`json`)throw{code:`TASK_LIST_ERROR`,message:e.message,details:e.stack};console.error(B.red(`Error: ${e.message}`)),process.exit(1)}}function no(e,t){if(!e)return`N/A`;if(e.parentId){let n=t.find(t=>t.id===e.parentId);return n?.subtasks?.find(t=>`${n.id}.${t.id}`===e.id)?.description||`No description available.`}else return t.find(t=>String(t.id)===String(e.id))?.description||`No description available.`}function ro(e,t,n){let{totalTasks:r,completedTasks:i,completionPercentage:a,doneCount:o,inProgressCount:s,pendingCount:c,blockedCount:l,deferredCount:u,cancelledCount:d,totalSubtasks:f,completedSubtasks:p,subtaskCompletionPercentage:m,inProgressSubtasks:h,pendingSubtasks:g,blockedSubtasks:_,deferredSubtasks:v,cancelledSubtasks:y,tasksWithNoDeps:b,tasksReadyToWork:x,tasksWithUnsatisfiedDeps:S,mostDependedOnTask:C,mostDependedOnTaskId:w,maxDependents:T,avgDependenciesPerTask:E,complexityReport:D,withSubtasks:O,nextItem:k}=n,A=``,j=(e,t=20)=>{let n=Math.round(e/100*t),r=t-n;return`█`.repeat(n)+`░`.repeat(r)},M=j(a,20),N=j(m,20);A+=`| Project Dashboard | |
844
844
  `,A+=`| :- |:-|
845
845
  `,A+=`| Task Progress | ${M} ${Math.round(a)}% |\n`,A+=`| Done | ${o} |\n`,A+=`| In Progress | ${s} |\n`,A+=`| Pending | ${c} |\n`,A+=`| Deferred | ${u} |\n`,A+=`| Cancelled | ${d} |\n`,A+=`|-|-|
846
846
  `,A+=`| Subtask Progress | ${N} ${Math.round(m)}% |\n`,A+=`| Completed | ${p} |\n`,A+=`| In Progress | ${h} |\n`,A+=`| Pending | ${g} |\n`,A+=`
847
847
 
848
848
  `,A+=`| ID | Title | Status | Priority | Dependencies | Complexity |
849
849
  `,A+=`| :- | :- | :- | :- | :- | :- |
850
- `;let P=e=>{switch(e){case`done`:case`completed`:return`✓&nbsp;done`;case`in-progress`:return`►&nbsp;in-progress`;case`pending`:return`○&nbsp;pending`;case`blocked`:return`⭕&nbsp;blocked`;case`deferred`:return`x&nbsp;deferred`;case`cancelled`:return`x&nbsp;cancelled`;case`review`:return`?&nbsp;review`;default:return e||`pending`}},ee=(e,t)=>!e||e.length===0?`None`:e.map(e=>(t.find(t=>t.id===e),e.toString())).join(`, `);return t.forEach(t=>{let n=t.title,r=P(t.status),i=t.priority||`medium`,a=ee(t.dependencies,e.tasks),o=t.complexityScore?`● ${t.complexityScore}`:`N/A`;A+=`| ${t.id} | ${n} | ${r} | ${i} | ${a} | ${o} |\n`,O&&t.subtasks&&t.subtasks.length>0&&t.subtasks.forEach(n=>{let r=`${n.title}`,i=P(n.status),a=ee(n.dependencies,e.tasks),o=n.complexityScore?n.complexityScore.toString():`N/A`;A+=`| ${t.id}.${n.id} | ${r} | ${i} | - | ${a} | ${o} |\n`})}),A}function Qa(e){if(!e||e.length===0)return``;if(e.length>5){let t=e.slice(0,5).join(`,`),n=e.length-5;return` → ${B.cyan(t)}${B.gray(`... (+`+n+` more)`)}`}else return` → ${B.cyan(e.join(`,`))}`}function $a(e,t=50){let n=e.status||`pending`,r=e.priority||`medium`,i=s(e.title||`Untitled`,t),a=dl(n,!0),o={high:B.red,medium:B.yellow,low:B.gray}[r]||B.white,c=Qa(e.dependencies);return`${B.cyan(e.id)} ${a} ${B.white(i)} ${o(`(`+r+`)`)}${c}`}function eo(e,t,n=47){let r=e.status||`pending`,i=s(e.title||`Untitled`,n),a=dl(r,!0),o=Qa(e.dependencies);return` ${B.cyan(t+`.`+e.id)} ${a} ${B.dim(i)}${o}`}function to(e,t){if(e.length===0){console.log(`No tasks found`);return}let n=[];e.forEach(e=>{n.push($a(e)),t&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(t=>{n.push(eo(t,e.id))})}),console.log(n.join(`
851
- `))}var no=Ya;new class{constructor(e={}){this.config={maxCacheSize:e.maxCacheSize||1e3,ttl:e.ttl||1e3*60*5,maxContextSize:e.maxContextSize||4e3},this.cache=new bt({max:this.config.maxCacheSize,ttl:this.config.ttl,updateAgeOnGet:!0}),this.stats={hits:0,misses:0,invalidations:0}}async getContext(e,t={}){let n=this._getCacheKey(e,t),r=this.cache.get(n);if(r)return this.stats.hits++,r;this.stats.misses++;let i={id:e,metadata:{...t,created:new Date().toISOString()}};return this.cache.set(n,i),i}async updateContext(e,t){let n=await this.getContext(e);Object.assign(n.metadata,t);let r=this._getCacheKey(e,n.metadata);return this.cache.set(r,n),n}invalidateContext(e,t={}){let n=this._getCacheKey(e,t);this.cache.delete(n),this.stats.invalidations++}getCachedData(e){let t=this.cache.get(e);if(t!==void 0)return this.stats.hits++,t;this.stats.misses++}setCachedData(e,t){this.cache.set(e,t)}invalidateCacheKey(e){this.cache.delete(e),this.stats.invalidations++}getStats(){return{hits:this.stats.hits,misses:this.stats.misses,invalidations:this.stats.invalidations,size:this.cache.size,maxSize:this.config.maxCacheSize,ttl:this.config.ttl}}_getCacheKey(e,t){return`${e}:${JSON.stringify(t)}`}};const ro={info:()=>{},warn:()=>{},error:()=>{},debug:()=>{},success:()=>{}};function io(e,t=ro){let n=e?.file,r=e?.projectRoot;if(n&&H.isAbsolute(n))return n;let i=r?ce(r):null;if(n&&i)return H.resolve(i,n);if(i){let e=a(n,{projectRoot:i},t);if(e===null&&!n){let e=H.join(i,`.taskmaster`,`tasks`,`tasks.json`);return t?.info?.(`Core findTasksPath returned null, using default path: ${e}`),e}return e}return a(n,null,t)}function ao(e,t=ro){let n=e?.input,r=e?.projectRoot;if(n&&H.isAbsolute(n))return n;let i=r?ce(r):null;return n&&i?H.resolve(i,n):i?M(n,{projectRoot:i},t):M(n,null,t)}function oo(e,t=ro){let n=e?.complexityReport,r=e?.projectRoot,i=e?.tag;if(n&&H.isAbsolute(n))return n;let a=r?ce(r):null;return n&&a?H.resolve(a,n):a?A(n,{projectRoot:a,tag:i},t):A(n,null,t)}function so(e,t){if(!t?.projectRoot)throw Error(`projectRoot is required in args to resolve project paths`);let n=ce(t.projectRoot);return H.isAbsolute(e)?e:H.resolve(n,e)}function co(e,t=ro){return io(e,t)}function lo(e,t=ro){return oo(e,t)}function uo(e,t,n=ro){return Le(e,t,n)}$e(import.meta.url);function fo(e){return{info:(t,...n)=>e.info(t,...n),warn:(t,...n)=>e.warn(t,...n),error:(t,...n)=>e.error(t,...n),debug:(t,...n)=>e.debug?e.debug(t,...n):null,success:(t,...n)=>e.info(t,...n)}}const po=$e(import.meta.url);H.dirname(po);const mo=fo({info:e=>console.log(B.blue(`ℹ`),e),warn:e=>console.log(B.yellow(`⚠`),e),error:e=>console.error(B.red(`✗`),e),success:e=>console.log(B.green(`✓`),e)});async function ho(e={}){let t=ze()||process.cwd();mo.info(`Starting migration in: ${t}`);let n=H.join(t,`.taskmaster`);if(V.existsSync(n)&&!e.force){mo.warn(`.taskmaster directory already exists. Use --force to overwrite or skip migration.`);return}let r=go(t);if(r.length===0){mo.info(`No files to migrate. Project may already be using the new structure.`);return}mo.info(`Migration plan:`);for(let t of r){let n=e.dryRun?`Would move`:`Will move`;mo.info(` ${n}: ${t.from} → ${t.to}`)}if(e.dryRun){mo.info(`Dry run complete. Use --dry-run=false to perform actual migration.`);return}if(!e.yes){let e=(await import(`readline`)).createInterface({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(`Proceed with migration? (y/N): `,t)});if(e.close(),t.toLowerCase()!==`y`&&t.toLowerCase()!==`yes`){mo.info(`Migration cancelled.`);return}}try{await _o(t,r,e),mo.success(`Migration completed successfully!`),mo.info(`You can now use the new .taskmaster directory structure.`),e.cleanup||mo.info(`Old files were preserved. Use --cleanup to remove them after verification.`)}catch(e){throw mo.error(`Migration failed: ${e.message}`),e}}function go(e){let t=[],n=H.join(e,`tasks`);if(V.existsSync(n)){let e=V.readdirSync(n);for(let n of e)t.push({from:H.join(`tasks`,n),to:H.join(`.taskmaster`,`tasks`,n),type:`task`})}let r=H.join(e,`scripts`);if(V.existsSync(r)){let e=V.readdirSync(r);for(let n of e){let e=H.join(r,n);if(V.statSync(e).isFile()){let e,r=n.toLowerCase();if(r.includes(`example`)||r.includes(`template`)||r.includes(`boilerplate`)||r.includes(`sample`))e=H.join(`.taskmaster`,`templates`,n);else if(r.includes(`complexity`)&&r.includes(`report`)&&r.endsWith(`.json`))e=H.join(`.taskmaster`,`reports`,n);else if(r.includes(`prd`)||r.endsWith(`.md`)||r.endsWith(`.txt`))e=H.join(`.taskmaster`,`docs`,n);else{mo.warn(`Skipping migration of '${n}' - uncertain categorization. You may need to move this manually.`);continue}t.push({from:H.join(`scripts`,n),to:e,type:`script`})}}}let i=H.join(e,v);return V.existsSync(i)&&t.push({from:v,to:l,type:`config`}),t}async function _o(e,t,n){let r=H.join(e,`.taskmaster`);V.existsSync(r)||V.mkdirSync(r,{recursive:!0});let i=new Set;for(let e of t){let t=H.dirname(e.to);i.add(t)}for(let t of i){let n=H.join(e,t);V.existsSync(n)||(V.mkdirSync(n,{recursive:!0}),mo.info(`Created directory: ${t}`))}if(n.backup){let t=H.join(e,`.taskmaster-migration-backup`);mo.info(`Creating backup in: ${t}`),V.existsSync(t)&&V.rmSync(t,{recursive:!0,force:!0}),V.mkdirSync(t,{recursive:!0})}for(let r of t){let t=H.join(e,r.from),i=H.join(e,r.to);if(!V.existsSync(t)){mo.warn(`Source file not found: ${r.from}`);continue}if(n.backup){let n=H.join(e,`.taskmaster-migration-backup`,r.from),i=H.dirname(n);V.existsSync(i)||V.mkdirSync(i,{recursive:!0}),V.copyFileSync(t,n)}let a=H.dirname(i);V.existsSync(a)||V.mkdirSync(a,{recursive:!0}),V.copyFileSync(t,i),mo.info(`Migrated: ${r.from} → ${r.to}`),n.cleanup&&V.unlinkSync(t)}if(n.cleanup)for(let t of[`tasks`,`scripts`]){let n=H.join(e,t);if(V.existsSync(n))try{V.readdirSync(n).length===0&&(V.rmdirSync(n),mo.info(`Removed empty directory: ${t}`))}catch{}}}function vo(e,t,n={}){return Ce(e,t,{...n,direction:`forward`,logger:{warn:console.warn}})}var yo=class extends Error{constructor(e,t,n={}){super(t),this.name=`MoveTaskError`,this.code=e,this.data=n}};const bo={CROSS_TAG_DEPENDENCY_CONFLICTS:`CROSS_TAG_DEPENDENCY_CONFLICTS`,CANNOT_MOVE_SUBTASK:`CANNOT_MOVE_SUBTASK`,SOURCE_TARGET_TAGS_SAME:`SOURCE_TARGET_TAGS_SAME`,TASK_NOT_FOUND:`TASK_NOT_FOUND`,SUBTASK_NOT_FOUND:`SUBTASK_NOT_FOUND`,PARENT_TASK_NOT_FOUND:`PARENT_TASK_NOT_FOUND`,PARENT_TASK_NO_SUBTASKS:`PARENT_TASK_NO_SUBTASKS`,DESTINATION_TASK_NOT_FOUND:`DESTINATION_TASK_NOT_FOUND`,TASK_ALREADY_EXISTS:`TASK_ALREADY_EXISTS`,INVALID_TASKS_FILE:`INVALID_TASKS_FILE`,ID_COUNT_MISMATCH:`ID_COUNT_MISMATCH`,INVALID_SOURCE_TAG:`INVALID_SOURCE_TAG`,INVALID_TARGET_TAG:`INVALID_TARGET_TAG`};function xo(e){if(e==null)return e;if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`){let t=e.trim();if(t===``)return null;let n=t.includes(`.`)?t.split(`.`)[0]:t,r=parseInt(n,10);return Number.isFinite(r)?r:null}return null}async function So(e,t,n,r=!1,i={}){let{projectRoot:a,tag:o}=i,s=t.split(`,`).map(e=>e.trim()),c=n.split(`,`).map(e=>e.trim());if(s.length!==c.length)throw new yo(bo.ID_COUNT_MISMATCH,`Number of source IDs (${s.length}) must match number of destination IDs (${c.length})`);if(s.length>1){let t=[];for(let n=0;n<s.length;n++){let r=await So(e,s[n],c[n],!1,i);t.push(r)}return{message:`Successfully moved ${s.length} tasks/subtasks`,moves:t}}let l=D(e,a,o);if(l&&l._rawTaggedData&&(l=l._rawTaggedData),!l||!l[o]||!Array.isArray(l[o].tasks))throw new yo(bo.INVALID_TASKS_FILE,`Invalid tasks file or tag "${o}" not found at ${e}`);let u=l[o].tasks;z(`info`,`Moving task/subtask ${t} to ${n} (tag: ${o})`);let d=t.includes(`.`),f=n.includes(`.`),p;return p=d&&f?Co(u,t,n):d&&!f?wo(u,t,n):!d&&f?To(u,t,n):Eo(u,t,n),l[o].tasks=u,y(e,l,i.projectRoot,o),p}function Co(e,t,n){let[r,i]=t.split(`.`).map(e=>parseInt(e,10)),[a,o]=n.split(`.`).map(e=>parseInt(e,10)),s=e.find(e=>e.id===r),c=e.find(e=>e.id===a);if(!s)throw new yo(bo.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!c)throw new yo(bo.PARENT_TASK_NOT_FOUND,`Destination parent task with ID ${a} not found`);s.subtasks||=[],c.subtasks||=[];let l=s.subtasks.findIndex(e=>e.id===i);if(l===-1)throw new yo(bo.SUBTASK_NOT_FOUND,`Source subtask ${t} not found`);let u=s.subtasks[l];if(r===a)if(c.subtasks.length>0){let e=c.subtasks.findIndex(e=>e.id===o);if(e!==-1){s.subtasks.splice(l,1);let t=l<e?e-1:e;c.subtasks.splice(t+1,0,u)}else s.subtasks.splice(l,1),c.subtasks.push(u)}else s.subtasks.splice(l,1),c.subtasks.push(u);else Do(u,s,l,c,o);return{message:`Moved subtask ${t} to ${n}`,movedItem:u}}function wo(e,t,n){let[r,i]=t.split(`.`).map(e=>parseInt(e,10)),a=parseInt(n,10),o=e.find(e=>e.id===r);if(!o)throw new yo(bo.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!o.subtasks)throw new yo(bo.PARENT_TASK_NO_SUBTASKS,`Source parent task ${r} has no subtasks`);let s=o.subtasks.findIndex(e=>e.id===i);if(s===-1)throw new yo(bo.SUBTASK_NOT_FOUND,`Source subtask ${t} not found`);let c=o.subtasks[s];if(e.find(e=>e.id===a))throw new yo(bo.TASK_ALREADY_EXISTS,`Cannot move to existing task ID ${a}. Choose a different ID or use subtask destination.`);let l={id:a,title:c.title,description:c.description,status:c.status||`pending`,dependencies:c.dependencies||[],priority:c.priority||`medium`,details:c.details||``,testStrategy:c.testStrategy||``,subtasks:[]};o.subtasks.splice(s,1);let u=e.findIndex(e=>e.id>a);return u===-1?e.push(l):e.splice(u,0,l),{message:`Converted subtask ${t} to task ${n}`,movedItem:l}}function To(e,t,n){let r=parseInt(t,10),[i,a]=n.split(`.`).map(e=>parseInt(e,10)),o=e.findIndex(e=>e.id===r),s=e.find(e=>e.id===i);if(o===-1)throw new yo(bo.TASK_NOT_FOUND,`Source task with ID ${r} not found`);if(!s)throw new yo(bo.PARENT_TASK_NOT_FOUND,`Destination parent task with ID ${i} not found`);let c=e[o];s.subtasks||=[];let l={id:a,title:c.title,description:c.description,status:c.status||`pending`,dependencies:c.dependencies||[],details:c.details||``,testStrategy:c.testStrategy||``},u=-1;s.subtasks.length>0&&(u=s.subtasks.findIndex(e=>e.id===a),u===-1&&(u=s.subtasks.length-1));let d=u===-1?0:u+1;return s.subtasks.splice(d,0,l),e.splice(o,1),{message:`Converted task ${t} to subtask ${n}`,movedItem:l}}function Eo(e,t,n){let r=parseInt(t,10),i=parseInt(n,10),a=e.findIndex(e=>e.id===r);if(a===-1)throw new yo(bo.TASK_NOT_FOUND,`Source task with ID ${r} not found`);let o=e[a],s=e.findIndex(e=>e.id===i);if(s!==-1)throw e[s],new yo(bo.TASK_ALREADY_EXISTS,`Task with ID ${i} already exists. Use a different destination ID.`);return Oo(e,a,o,i)}function Do(e,t,n,r,i){let a=parseInt(i,10),o={...e,id:a};r.subtasks||=[];let s=-1;r.subtasks.length>0&&(s=r.subtasks.findIndex(e=>e.id===a),s===-1&&(s=r.subtasks.length-1));let c=s===-1?0:s+1;return r.subtasks.splice(c,0,o),t.subtasks.splice(n,1),o}function Oo(e,t,n,r){let i=e.findIndex(e=>e.id===r),a={...n,id:r};e.forEach(e=>{if(e.dependencies&&e.dependencies.includes(n.id)){let t=e.dependencies.indexOf(n.id);e.dependencies[t]=r}e.subtasks&&e.subtasks.forEach(e=>{if(e.dependencies&&e.dependencies.includes(n.id)){let t=e.dependencies.indexOf(n.id);e.dependencies[t]=r}})}),Array.isArray(a.subtasks)&&a.subtasks.forEach(e=>{Array.isArray(e.dependencies)&&(e.dependencies=e.dependencies.map(e=>{if(typeof e==`string`&&e.includes(`.`)){let[t,i]=e.split(`.`);if(parseInt(t,10)===n.id)return`${r}.${i}`}return e}))}),e.splice(t,1);let o=t<i?i-1:i;return o>=0&&o<e.length?e[o]=a:e.push(a),z(`info`,`Moved task ${n.id} to new ID ${r}`),{message:`Moved task ${n.id} to new ID ${r}`,movedItem:a}}function ko(e){let t=[];for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&e[n]&&Array.isArray(e[n].tasks)){let r=e[n].tasks.map(e=>({...e,tag:n}));t=t.concat(r)}return t}async function Ao(e,t,n,r,i){let{projectRoot:a}=i,o=D(e,a,n);if(o&&o._rawTaggedData&&(o=o._rawTaggedData),!o||!o[n]||!Array.isArray(o[n].tasks))throw new yo(bo.INVALID_SOURCE_TAG,`Source tag "${n}" not found or invalid`);o[r]||(o[r]={tasks:[]},z(`info`,`Created new tag "${r}"`));let s=t.map(e=>String(e)),c=o[n].tasks.filter(e=>{let t=String(e.id);return s.includes(t)});return t.forEach(e=>{Hl(e,n,r)}),{rawData:o,sourceTasks:c}}async function jo(e){let{rawData:t,sourceTasks:n}=e;return{rawData:t,sourceTasks:n,allTasks:ko(t)}}async function Mo(e,t,n,r,i,a){let{withDependencies:o=!1,ignoreDependencies:s=!1}=n,c=Array.isArray(t)?t.filter(e=>e&&e.tag===i):[];if(o){let t=vo(e,c,{maxDepth:100,includeSelf:!1}),n=new Set(c.map(e=>typeof e.id==`string`?parseInt(e.id,10):e.id)),i=t.filter(e=>{let t=xo(e);return Number.isFinite(t)&&n.has(t)}),a=[...new Set([...r,...i])];return z(`info`,`Moving ${a.length} tasks (including dependencies): ${a.join(`, `)}`),{tasksToMove:a,dependencyResolution:{type:`with-dependencies`,dependentTasks:i}}}let l=Vl(e,i,a,t);if(l.length>0){if(s)return e.forEach(e=>{let n=c,r=Array.isArray(t)?t.filter(e=>e&&e.tag===a):[];e.dependencies=e.dependencies.filter(e=>{let t=xo(e);return Number.isFinite(t)&&n.some(e=>e.id===t)?!1:(Number.isFinite(t)&&r.some(e=>e.id===t),!0)})}),z(`warn`,`Removed ${l.length} cross-tag dependencies`),{tasksToMove:r,dependencyResolution:{type:`ignored-dependencies`,conflicts:l}};throw new yo(bo.CROSS_TAG_DEPENDENCY_CONFLICTS,`Cannot move tasks: ${l.length} cross-tag dependency conflicts found`,{conflicts:l,sourceTag:i,targetTag:a,taskIds:r})}return{tasksToMove:r,dependencyResolution:{type:`no-conflicts`}}}async function No(e,t,n,r,i,a){let{projectRoot:o}=i,s=[];for(let i of e){let e=typeof i==`string`?parseInt(i,10):i,a=r[t].tasks.findIndex(t=>t.id===e);if(a===-1)throw new yo(bo.TASK_NOT_FOUND,`Task ${i} not found in source tag "${t}"`);let o=r[t].tasks[a];if(r[n].tasks.findIndex(t=>t.id===e)!==-1)throw new yo(bo.TASK_ALREADY_EXISTS,`Task ${i} already exists in target tag "${n}"`,{conflictingId:e,targetTag:n,suggestions:[`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`]});r[t].tasks.splice(a,1);let c=Io(o,t,n);r[n].tasks.push(c),s.push({id:i,fromTag:t,toTag:n}),z(`info`,`Moved task ${i} from "${t}" to "${n}"`)}return{rawData:r,movedTasks:s}}async function Po(e,t,n,r,i,a){let{projectRoot:o}=n,{rawData:s,movedTasks:c}=e;y(t,s,o,null);let l={message:`Successfully moved ${c.length} tasks from "${r}" to "${i}"`,movedTasks:c};return a&&a.type===`ignored-dependencies`&&(l.tips=[`Run "task-master validate-dependencies" to check for dependency issues.`,`Run "task-master fix-dependencies" to automatically repair dangling dependencies.`]),l}async function Fo(e,t,n,r,i={},a={}){let{rawData:o,sourceTasks:s,allTasks:c}=await jo(await Ao(e,t,n,r,a)),{tasksToMove:l,dependencyResolution:u}=await Mo(s,c,i,t,n,r);return await Po(await No(l,n,r,o,a,e),e,a,n,r,u)}function Io(e,t,n){return e.tag=n,e.metadata||={},e.metadata.moveHistory||(e.metadata.moveHistory=[]),e.metadata.moveHistory.push({fromTag:t,toTag:n,timestamp:new Date().toISOString()}),e}var Lo=So,Ro=class e extends Error{constructor(t,n){super(t),this.name=`StreamingError`,this.code=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}};const zo={NOT_ASYNC_ITERABLE:`STREAMING_NOT_SUPPORTED`,STREAM_PROCESSING_FAILED:`STREAM_PROCESSING_FAILED`,STREAM_NOT_ITERABLE:`STREAM_NOT_ITERABLE`,BUFFER_SIZE_EXCEEDED:`BUFFER_SIZE_EXCEEDED`};var Bo=class e{static async withTimeout(e,t,n=`Operation`){let r,i=new Promise((e,i)=>{r=setTimeout(()=>{i(new Ro(`${n} timed out after ${t/1e3} seconds`,zo.STREAM_PROCESSING_FAILED))},t)});try{let t=await Promise.race([e,i]);return clearTimeout(r),t}catch(e){throw clearTimeout(r),e}}static async withSoftTimeout(e,t,n=void 0){let r,i=new Promise(e=>{r=setTimeout(()=>{e(n)},t)});try{let t=await Promise.race([e,i]);return clearTimeout(r),t}catch{return clearTimeout(r),n}}static createController(t,n=`Operation`){return{timeoutMs:t,operationName:n,async wrap(r,i=null){let a=i?`${n} - ${i}`:n;return e.withTimeout(r,t,a)},async wrapSoft(n,r=void 0){return e.withSoftTimeout(n,t,r)}}}static isTimeoutError(e){return e instanceof Ro&&e.code===zo.STREAM_PROCESSING_FAILED&&e.message.includes(`timed out`)}},Vo=class e{constructor(e,t=`ms`){this.milliseconds=this._toMilliseconds(e,t)}static milliseconds(t){return new e(t,`ms`)}static seconds(t){return new e(t,`s`)}static minutes(t){return new e(t,`m`)}static hours(t){return new e(t,`h`)}get seconds(){return this.milliseconds/1e3}get minutes(){return this.milliseconds/6e4}get hours(){return this.milliseconds/36e5}toString(){return this.milliseconds<1e3?`${this.milliseconds}ms`:this.milliseconds<6e4?`${this.seconds}s`:this.milliseconds<36e5?`${Math.floor(this.minutes)}m ${Math.floor(this.seconds%60)}s`:`${Math.floor(this.hours)}h ${Math.floor(this.minutes%60)}m`}_toMilliseconds(e,t){return e*({ms:1,s:1e3,m:6e4,h:36e5}[t]||1)}};const Ho=U.object({id:U.number(),title:U.string().min(1),description:U.string().min(1),details:U.string(),testStrategy:U.string(),priority:U.enum(Qi),dependencies:U.array(U.number()),status:U.string()}),Uo=U.object({tasks:U.array(Ho),metadata:U.union([U.object({projectName:U.string(),totalTasks:U.number(),sourceFile:U.string(),generatedAt:U.string()}).strict(),U.null()]).default(null)});var Wo=class{constructor(e,t,n,r={}){this.prdPath=e,this.tasksPath=t,this.numTasks=n,this.force=r.force||!1,this.append=r.append||!1,this.research=r.research||!1,this.reportProgress=r.reportProgress,this.mcpLog=r.mcpLog,this.session=r.session,this.projectRoot=r.projectRoot,this.tag=r.tag,this.streamingTimeout=r.streamingTimeout||Vo.seconds(180).milliseconds,this.targetTag=this.tag||_e(this.projectRoot)||`master`,this.isMCP=!!this.mcpLog,this.outputFormat=this.isMCP&&!this.reportProgress?`json`:`text`,this.useStreaming=!1}hasCodebaseAnalysis(){return _(this.research,this.projectRoot,this.session)}},Go=class{constructor(e,t){this.isMCP=!!e,this.outputFormat=this.isMCP&&!t?`json`:`text`,this.logFn=e||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)}}report(e,t=`info`){this.logFn&&typeof this.logFn[t]==`function`?this.logFn[t](e):!L()&&this.outputFormat===`text`&&z(t,e)}};function Ko(e){return`${Math.floor(e/60)}m ${Math.floor(e%60).toString().padStart(2,`0`)}s`}const qo={BAR_WIDTH:40,TABLE_COL_WIDTHS:[28,50],DEFAULT_MODEL:`Default`,DEFAULT_TEMPERATURE:.7},Q={HIGH:`high`,MEDIUM:`medium`,LOW:`low`},Jo={[Q.HIGH]:`#CC0000`,[Q.MEDIUM]:`#FF8800`,[Q.LOW]:`#FFCC00`},Yo={main:{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0},borderColor:`blue`,borderStyle:`round`},summary:{padding:{top:1,right:1,bottom:1,left:1},borderColor:`blue`,borderStyle:`round`,margin:{top:1,right:1,bottom:1,left:0}},warning:{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}},nextSteps:{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,right:0,bottom:1,left:0}}};function Xo({prdFilePath:e,outputPath:t,numTasks:n,model:r,temperature:i,append:a,research:o}){let s=a?`Appending`:`Generating`,c=`Model: ${r} | Temperature: ${i}`;return o&&(c+=` | ${B.cyan.bold(`🔬 Research Mode`)}`),B.bold(`🤖 Parsing PRD and ${s} Tasks`)+`
850
+ `;let P=e=>{switch(e){case`done`:case`completed`:return`✓&nbsp;done`;case`in-progress`:return`►&nbsp;in-progress`;case`pending`:return`○&nbsp;pending`;case`blocked`:return`⭕&nbsp;blocked`;case`deferred`:return`x&nbsp;deferred`;case`cancelled`:return`x&nbsp;cancelled`;case`review`:return`?&nbsp;review`;default:return e||`pending`}},ee=(e,t)=>!e||e.length===0?`None`:e.map(e=>(t.find(t=>t.id===e),e.toString())).join(`, `);return t.forEach(t=>{let n=t.title,r=P(t.status),i=t.priority||`medium`,a=ee(t.dependencies,e.tasks),o=t.complexityScore?`● ${t.complexityScore}`:`N/A`;A+=`| ${t.id} | ${n} | ${r} | ${i} | ${a} | ${o} |\n`,O&&t.subtasks&&t.subtasks.length>0&&t.subtasks.forEach(n=>{let r=`${n.title}`,i=P(n.status),a=ee(n.dependencies,e.tasks),o=n.complexityScore?n.complexityScore.toString():`N/A`;A+=`| ${t.id}.${n.id} | ${r} | ${i} | - | ${a} | ${o} |\n`})}),A}function io(e){if(!e||e.length===0)return``;if(e.length>5){let t=e.slice(0,5).join(`,`),n=e.length-5;return` → ${B.cyan(t)}${B.gray(`... (+`+n+` more)`)}`}else return` → ${B.cyan(e.join(`,`))}`}function ao(e,t=50){let n=e.status||`pending`,r=e.priority||`medium`,i=s(e.title||`Untitled`,t),a=_l(n,!0),o={high:B.red,medium:B.yellow,low:B.gray}[r]||B.white,c=io(e.dependencies);return`${B.cyan(e.id)} ${a} ${B.white(i)} ${o(`(`+r+`)`)}${c}`}function oo(e,t,n=47){let r=e.status||`pending`,i=s(e.title||`Untitled`,n),a=_l(r,!0),o=io(e.dependencies);return` ${B.cyan(t+`.`+e.id)} ${a} ${B.dim(i)}${o}`}function so(e,t){if(e.length===0){console.log(`No tasks found`);return}let n=[];e.forEach(e=>{n.push(ao(e)),t&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(t=>{n.push(oo(t,e.id))})}),console.log(n.join(`
851
+ `))}var co=to;new class{constructor(e={}){this.config={maxCacheSize:e.maxCacheSize||1e3,ttl:e.ttl||1e3*60*5,maxContextSize:e.maxContextSize||4e3},this.cache=new bt({max:this.config.maxCacheSize,ttl:this.config.ttl,updateAgeOnGet:!0}),this.stats={hits:0,misses:0,invalidations:0}}async getContext(e,t={}){let n=this._getCacheKey(e,t),r=this.cache.get(n);if(r)return this.stats.hits++,r;this.stats.misses++;let i={id:e,metadata:{...t,created:new Date().toISOString()}};return this.cache.set(n,i),i}async updateContext(e,t){let n=await this.getContext(e);Object.assign(n.metadata,t);let r=this._getCacheKey(e,n.metadata);return this.cache.set(r,n),n}invalidateContext(e,t={}){let n=this._getCacheKey(e,t);this.cache.delete(n),this.stats.invalidations++}getCachedData(e){let t=this.cache.get(e);if(t!==void 0)return this.stats.hits++,t;this.stats.misses++}setCachedData(e,t){this.cache.set(e,t)}invalidateCacheKey(e){this.cache.delete(e),this.stats.invalidations++}getStats(){return{hits:this.stats.hits,misses:this.stats.misses,invalidations:this.stats.invalidations,size:this.cache.size,maxSize:this.config.maxCacheSize,ttl:this.config.ttl}}_getCacheKey(e,t){return`${e}:${JSON.stringify(t)}`}};const lo={info:()=>{},warn:()=>{},error:()=>{},debug:()=>{},success:()=>{}};function uo(e,t=lo){let n=e?.file,r=e?.projectRoot;if(n&&H.isAbsolute(n))return n;let i=r?se(r):null;if(n&&i)return H.resolve(i,n);if(i){let e=a(n,{projectRoot:i},t);if(e===null&&!n){let e=H.join(i,`.taskmaster`,`tasks`,`tasks.json`);return t?.info?.(`Core findTasksPath returned null, using default path: ${e}`),e}return e}return a(n,null,t)}function fo(e,t=lo){let n=e?.input,r=e?.projectRoot;if(n&&H.isAbsolute(n))return n;let i=r?se(r):null;return n&&i?H.resolve(i,n):i?j(n,{projectRoot:i},t):j(n,null,t)}function po(e,t=lo){let n=e?.complexityReport,r=e?.projectRoot,i=e?.tag;if(n&&H.isAbsolute(n))return n;let a=r?se(r):null;return n&&a?H.resolve(a,n):a?k(n,{projectRoot:a,tag:i},t):k(n,null,t)}function mo(e,t){if(!t?.projectRoot)throw Error(`projectRoot is required in args to resolve project paths`);let n=se(t.projectRoot);return H.isAbsolute(e)?e:H.resolve(n,e)}function ho(e,t=lo){return uo(e,t)}function go(e,t=lo){return po(e,t)}function _o(e,t,n=lo){return Fe(e,t,n)}$e(import.meta.url);function vo(e){return{info:(t,...n)=>e.info(t,...n),warn:(t,...n)=>e.warn(t,...n),error:(t,...n)=>e.error(t,...n),debug:(t,...n)=>e.debug?e.debug(t,...n):null,success:(t,...n)=>e.info(t,...n)}}const yo=$e(import.meta.url);H.dirname(yo);const bo=vo({info:e=>console.log(B.blue(`ℹ`),e),warn:e=>console.log(B.yellow(`⚠`),e),error:e=>console.error(B.red(`✗`),e),success:e=>console.log(B.green(`✓`),e)});async function xo(e={}){let t=Le()||process.cwd();bo.info(`Starting migration in: ${t}`);let n=H.join(t,`.taskmaster`);if(V.existsSync(n)&&!e.force){bo.warn(`.taskmaster directory already exists. Use --force to overwrite or skip migration.`);return}let r=So(t);if(r.length===0){bo.info(`No files to migrate. Project may already be using the new structure.`);return}bo.info(`Migration plan:`);for(let t of r){let n=e.dryRun?`Would move`:`Will move`;bo.info(` ${n}: ${t.from} → ${t.to}`)}if(e.dryRun){bo.info(`Dry run complete. Use --dry-run=false to perform actual migration.`);return}if(!e.yes){let e=(await import(`readline`)).createInterface({input:process.stdin,output:process.stdout}),t=await new Promise(t=>{e.question(`Proceed with migration? (y/N): `,t)});if(e.close(),t.toLowerCase()!==`y`&&t.toLowerCase()!==`yes`){bo.info(`Migration cancelled.`);return}}try{await Co(t,r,e),bo.success(`Migration completed successfully!`),bo.info(`You can now use the new .taskmaster directory structure.`),e.cleanup||bo.info(`Old files were preserved. Use --cleanup to remove them after verification.`)}catch(e){throw bo.error(`Migration failed: ${e.message}`),e}}function So(e){let t=[],n=H.join(e,`tasks`);if(V.existsSync(n)){let e=V.readdirSync(n);for(let n of e)t.push({from:H.join(`tasks`,n),to:H.join(`.taskmaster`,`tasks`,n),type:`task`})}let r=H.join(e,`scripts`);if(V.existsSync(r)){let e=V.readdirSync(r);for(let n of e){let e=H.join(r,n);if(V.statSync(e).isFile()){let e,r=n.toLowerCase();if(r.includes(`example`)||r.includes(`template`)||r.includes(`boilerplate`)||r.includes(`sample`))e=H.join(`.taskmaster`,`templates`,n);else if(r.includes(`complexity`)&&r.includes(`report`)&&r.endsWith(`.json`))e=H.join(`.taskmaster`,`reports`,n);else if(r.includes(`prd`)||r.endsWith(`.md`)||r.endsWith(`.txt`))e=H.join(`.taskmaster`,`docs`,n);else{bo.warn(`Skipping migration of '${n}' - uncertain categorization. You may need to move this manually.`);continue}t.push({from:H.join(`scripts`,n),to:e,type:`script`})}}}let i=H.join(e,v);return V.existsSync(i)&&t.push({from:v,to:l,type:`config`}),t}async function Co(e,t,n){let r=H.join(e,`.taskmaster`);V.existsSync(r)||V.mkdirSync(r,{recursive:!0});let i=new Set;for(let e of t){let t=H.dirname(e.to);i.add(t)}for(let t of i){let n=H.join(e,t);V.existsSync(n)||(V.mkdirSync(n,{recursive:!0}),bo.info(`Created directory: ${t}`))}if(n.backup){let t=H.join(e,`.taskmaster-migration-backup`);bo.info(`Creating backup in: ${t}`),V.existsSync(t)&&V.rmSync(t,{recursive:!0,force:!0}),V.mkdirSync(t,{recursive:!0})}for(let r of t){let t=H.join(e,r.from),i=H.join(e,r.to);if(!V.existsSync(t)){bo.warn(`Source file not found: ${r.from}`);continue}if(n.backup){let n=H.join(e,`.taskmaster-migration-backup`,r.from),i=H.dirname(n);V.existsSync(i)||V.mkdirSync(i,{recursive:!0}),V.copyFileSync(t,n)}let a=H.dirname(i);V.existsSync(a)||V.mkdirSync(a,{recursive:!0}),V.copyFileSync(t,i),bo.info(`Migrated: ${r.from} → ${r.to}`),n.cleanup&&V.unlinkSync(t)}if(n.cleanup)for(let t of[`tasks`,`scripts`]){let n=H.join(e,t);if(V.existsSync(n))try{V.readdirSync(n).length===0&&(V.rmdirSync(n),bo.info(`Removed empty directory: ${t}`))}catch{}}}function wo(e,t,n={}){return xe(e,t,{...n,direction:`forward`,logger:{warn:console.warn}})}var To=class extends Error{constructor(e,t,n={}){super(t),this.name=`MoveTaskError`,this.code=e,this.data=n}};const Eo={CROSS_TAG_DEPENDENCY_CONFLICTS:`CROSS_TAG_DEPENDENCY_CONFLICTS`,CANNOT_MOVE_SUBTASK:`CANNOT_MOVE_SUBTASK`,SOURCE_TARGET_TAGS_SAME:`SOURCE_TARGET_TAGS_SAME`,TASK_NOT_FOUND:`TASK_NOT_FOUND`,SUBTASK_NOT_FOUND:`SUBTASK_NOT_FOUND`,PARENT_TASK_NOT_FOUND:`PARENT_TASK_NOT_FOUND`,PARENT_TASK_NO_SUBTASKS:`PARENT_TASK_NO_SUBTASKS`,DESTINATION_TASK_NOT_FOUND:`DESTINATION_TASK_NOT_FOUND`,TASK_ALREADY_EXISTS:`TASK_ALREADY_EXISTS`,INVALID_TASKS_FILE:`INVALID_TASKS_FILE`,ID_COUNT_MISMATCH:`ID_COUNT_MISMATCH`,INVALID_SOURCE_TAG:`INVALID_SOURCE_TAG`,INVALID_TARGET_TAG:`INVALID_TARGET_TAG`};function Do(e){if(e==null)return e;if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`){let t=e.trim();if(t===``)return null;let n=t.includes(`.`)?t.split(`.`)[0]:t,r=parseInt(n,10);return Number.isFinite(r)?r:null}return null}async function Oo(e,t,n,r=!1,i={}){let{projectRoot:a,tag:o}=i,s=t.split(`,`).map(e=>e.trim()),c=n.split(`,`).map(e=>e.trim());if(s.length!==c.length)throw new To(Eo.ID_COUNT_MISMATCH,`Number of source IDs (${s.length}) must match number of destination IDs (${c.length})`);if(s.length>1){let t=[];for(let n=0;n<s.length;n++){let r=await Oo(e,s[n],c[n],!1,i);t.push(r)}return{message:`Successfully moved ${s.length} tasks/subtasks`,moves:t}}let l=E(e,a,o);if(l&&l._rawTaggedData&&(l=l._rawTaggedData),!l||!l[o]||!Array.isArray(l[o].tasks))throw new To(Eo.INVALID_TASKS_FILE,`Invalid tasks file or tag "${o}" not found at ${e}`);let u=l[o].tasks;z(`info`,`Moving task/subtask ${t} to ${n} (tag: ${o})`);let d=t.includes(`.`),f=n.includes(`.`),p;return p=d&&f?ko(u,t,n):d&&!f?Ao(u,t,n):!d&&f?jo(u,t,n):Mo(u,t,n),l[o].tasks=u,y(e,l,i.projectRoot,o),p}function ko(e,t,n){let[r,i]=t.split(`.`).map(e=>parseInt(e,10)),[a,o]=n.split(`.`).map(e=>parseInt(e,10)),s=e.find(e=>e.id===r),c=e.find(e=>e.id===a);if(!s)throw new To(Eo.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!c)throw new To(Eo.PARENT_TASK_NOT_FOUND,`Destination parent task with ID ${a} not found`);s.subtasks||=[],c.subtasks||=[];let l=s.subtasks.findIndex(e=>e.id===i);if(l===-1)throw new To(Eo.SUBTASK_NOT_FOUND,`Source subtask ${t} not found`);let u=s.subtasks[l];if(r===a)if(c.subtasks.length>0){let e=c.subtasks.findIndex(e=>e.id===o);if(e!==-1){s.subtasks.splice(l,1);let t=l<e?e-1:e;c.subtasks.splice(t+1,0,u)}else s.subtasks.splice(l,1),c.subtasks.push(u)}else s.subtasks.splice(l,1),c.subtasks.push(u);else No(u,s,l,c,o);return{message:`Moved subtask ${t} to ${n}`,movedItem:u}}function Ao(e,t,n){let[r,i]=t.split(`.`).map(e=>parseInt(e,10)),a=parseInt(n,10),o=e.find(e=>e.id===r);if(!o)throw new To(Eo.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!o.subtasks)throw new To(Eo.PARENT_TASK_NO_SUBTASKS,`Source parent task ${r} has no subtasks`);let s=o.subtasks.findIndex(e=>e.id===i);if(s===-1)throw new To(Eo.SUBTASK_NOT_FOUND,`Source subtask ${t} not found`);let c=o.subtasks[s];if(e.find(e=>e.id===a))throw new To(Eo.TASK_ALREADY_EXISTS,`Cannot move to existing task ID ${a}. Choose a different ID or use subtask destination.`);let l={id:a,title:c.title,description:c.description,status:c.status||`pending`,dependencies:c.dependencies||[],priority:c.priority||`medium`,details:c.details||``,testStrategy:c.testStrategy||``,subtasks:[]};o.subtasks.splice(s,1);let u=e.findIndex(e=>e.id>a);return u===-1?e.push(l):e.splice(u,0,l),{message:`Converted subtask ${t} to task ${n}`,movedItem:l}}function jo(e,t,n){let r=parseInt(t,10),[i,a]=n.split(`.`).map(e=>parseInt(e,10)),o=e.findIndex(e=>e.id===r),s=e.find(e=>e.id===i);if(o===-1)throw new To(Eo.TASK_NOT_FOUND,`Source task with ID ${r} not found`);if(!s)throw new To(Eo.PARENT_TASK_NOT_FOUND,`Destination parent task with ID ${i} not found`);let c=e[o];s.subtasks||=[];let l={id:a,title:c.title,description:c.description,status:c.status||`pending`,dependencies:c.dependencies||[],details:c.details||``,testStrategy:c.testStrategy||``},u=-1;s.subtasks.length>0&&(u=s.subtasks.findIndex(e=>e.id===a),u===-1&&(u=s.subtasks.length-1));let d=u===-1?0:u+1;return s.subtasks.splice(d,0,l),e.splice(o,1),{message:`Converted task ${t} to subtask ${n}`,movedItem:l}}function Mo(e,t,n){let r=parseInt(t,10),i=parseInt(n,10),a=e.findIndex(e=>e.id===r);if(a===-1)throw new To(Eo.TASK_NOT_FOUND,`Source task with ID ${r} not found`);let o=e[a],s=e.findIndex(e=>e.id===i);if(s!==-1)throw e[s],new To(Eo.TASK_ALREADY_EXISTS,`Task with ID ${i} already exists. Use a different destination ID.`);return Po(e,a,o,i)}function No(e,t,n,r,i){let a=parseInt(i,10),o={...e,id:a};r.subtasks||=[];let s=-1;r.subtasks.length>0&&(s=r.subtasks.findIndex(e=>e.id===a),s===-1&&(s=r.subtasks.length-1));let c=s===-1?0:s+1;return r.subtasks.splice(c,0,o),t.subtasks.splice(n,1),o}function Po(e,t,n,r){let i=e.findIndex(e=>e.id===r),a={...n,id:r};e.forEach(e=>{if(e.dependencies&&e.dependencies.includes(n.id)){let t=e.dependencies.indexOf(n.id);e.dependencies[t]=r}e.subtasks&&e.subtasks.forEach(e=>{if(e.dependencies&&e.dependencies.includes(n.id)){let t=e.dependencies.indexOf(n.id);e.dependencies[t]=r}})}),Array.isArray(a.subtasks)&&a.subtasks.forEach(e=>{Array.isArray(e.dependencies)&&(e.dependencies=e.dependencies.map(e=>{if(typeof e==`string`&&e.includes(`.`)){let[t,i]=e.split(`.`);if(parseInt(t,10)===n.id)return`${r}.${i}`}return e}))}),e.splice(t,1);let o=t<i?i-1:i;return o>=0&&o<e.length?e[o]=a:e.push(a),z(`info`,`Moved task ${n.id} to new ID ${r}`),{message:`Moved task ${n.id} to new ID ${r}`,movedItem:a}}function Fo(e){let t=[];for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&e[n]&&Array.isArray(e[n].tasks)){let r=e[n].tasks.map(e=>({...e,tag:n}));t=t.concat(r)}return t}async function Io(e,t,n,r,i){let{projectRoot:a}=i,o=E(e,a,n);if(o&&o._rawTaggedData&&(o=o._rawTaggedData),!o||!o[n]||!Array.isArray(o[n].tasks))throw new To(Eo.INVALID_SOURCE_TAG,`Source tag "${n}" not found or invalid`);o[r]||(o[r]={tasks:[]},z(`info`,`Created new tag "${r}"`));let s=t.map(e=>String(e)),c=o[n].tasks.filter(e=>{let t=String(e.id);return s.includes(t)});return t.forEach(e=>{Jl(e,n,r)}),{rawData:o,sourceTasks:c}}async function Lo(e){let{rawData:t,sourceTasks:n}=e;return{rawData:t,sourceTasks:n,allTasks:Fo(t)}}async function Ro(e,t,n,r,i,a){let{withDependencies:o=!1,ignoreDependencies:s=!1}=n,c=Array.isArray(t)?t.filter(e=>e&&e.tag===i):[];if(o){let t=wo(e,c,{maxDepth:100,includeSelf:!1}),n=new Set(c.map(e=>typeof e.id==`string`?parseInt(e.id,10):e.id)),i=t.filter(e=>{let t=Do(e);return Number.isFinite(t)&&n.has(t)}),a=[...new Set([...r,...i])];return z(`info`,`Moving ${a.length} tasks (including dependencies): ${a.join(`, `)}`),{tasksToMove:a,dependencyResolution:{type:`with-dependencies`,dependentTasks:i}}}let l=ql(e,i,a,t);if(l.length>0){if(s)return e.forEach(e=>{let n=c,r=Array.isArray(t)?t.filter(e=>e&&e.tag===a):[];e.dependencies=e.dependencies.filter(e=>{let t=Do(e);return Number.isFinite(t)&&n.some(e=>e.id===t)?!1:(Number.isFinite(t)&&r.some(e=>e.id===t),!0)})}),z(`warn`,`Removed ${l.length} cross-tag dependencies`),{tasksToMove:r,dependencyResolution:{type:`ignored-dependencies`,conflicts:l}};throw new To(Eo.CROSS_TAG_DEPENDENCY_CONFLICTS,`Cannot move tasks: ${l.length} cross-tag dependency conflicts found`,{conflicts:l,sourceTag:i,targetTag:a,taskIds:r})}return{tasksToMove:r,dependencyResolution:{type:`no-conflicts`}}}async function zo(e,t,n,r,i,a){let{projectRoot:o}=i,s=[];for(let i of e){let e=typeof i==`string`?parseInt(i,10):i,a=r[t].tasks.findIndex(t=>t.id===e);if(a===-1)throw new To(Eo.TASK_NOT_FOUND,`Task ${i} not found in source tag "${t}"`);let o=r[t].tasks[a];if(r[n].tasks.findIndex(t=>t.id===e)!==-1)throw new To(Eo.TASK_ALREADY_EXISTS,`Task ${i} already exists in target tag "${n}"`,{conflictingId:e,targetTag:n,suggestions:[`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`]});r[t].tasks.splice(a,1);let c=Ho(o,t,n);r[n].tasks.push(c),s.push({id:i,fromTag:t,toTag:n}),z(`info`,`Moved task ${i} from "${t}" to "${n}"`)}return{rawData:r,movedTasks:s}}async function Bo(e,t,n,r,i,a){let{projectRoot:o}=n,{rawData:s,movedTasks:c}=e;y(t,s,o,null);let l={message:`Successfully moved ${c.length} tasks from "${r}" to "${i}"`,movedTasks:c};return a&&a.type===`ignored-dependencies`&&(l.tips=[`Run "task-master validate-dependencies" to check for dependency issues.`,`Run "task-master fix-dependencies" to automatically repair dangling dependencies.`]),l}async function Vo(e,t,n,r,i={},a={}){let{rawData:o,sourceTasks:s,allTasks:c}=await Lo(await Io(e,t,n,r,a)),{tasksToMove:l,dependencyResolution:u}=await Ro(s,c,i,t,n,r);return await Bo(await zo(l,n,r,o,a,e),e,a,n,r,u)}function Ho(e,t,n){return e.tag=n,e.metadata||={},e.metadata.moveHistory||(e.metadata.moveHistory=[]),e.metadata.moveHistory.push({fromTag:t,toTag:n,timestamp:new Date().toISOString()}),e}var Uo=Oo,Wo=class e extends Error{constructor(t,n){super(t),this.name=`StreamingError`,this.code=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}};const Go={NOT_ASYNC_ITERABLE:`STREAMING_NOT_SUPPORTED`,STREAM_PROCESSING_FAILED:`STREAM_PROCESSING_FAILED`,STREAM_NOT_ITERABLE:`STREAM_NOT_ITERABLE`,BUFFER_SIZE_EXCEEDED:`BUFFER_SIZE_EXCEEDED`};var Ko=class e{static async withTimeout(e,t,n=`Operation`){let r,i=new Promise((e,i)=>{r=setTimeout(()=>{i(new Wo(`${n} timed out after ${t/1e3} seconds`,Go.STREAM_PROCESSING_FAILED))},t)});try{let t=await Promise.race([e,i]);return clearTimeout(r),t}catch(e){throw clearTimeout(r),e}}static async withSoftTimeout(e,t,n=void 0){let r,i=new Promise(e=>{r=setTimeout(()=>{e(n)},t)});try{let t=await Promise.race([e,i]);return clearTimeout(r),t}catch{return clearTimeout(r),n}}static createController(t,n=`Operation`){return{timeoutMs:t,operationName:n,async wrap(r,i=null){let a=i?`${n} - ${i}`:n;return e.withTimeout(r,t,a)},async wrapSoft(n,r=void 0){return e.withSoftTimeout(n,t,r)}}}static isTimeoutError(e){return e instanceof Wo&&e.code===Go.STREAM_PROCESSING_FAILED&&e.message.includes(`timed out`)}},qo=class e{constructor(e,t=`ms`){this.milliseconds=this._toMilliseconds(e,t)}static milliseconds(t){return new e(t,`ms`)}static seconds(t){return new e(t,`s`)}static minutes(t){return new e(t,`m`)}static hours(t){return new e(t,`h`)}get seconds(){return this.milliseconds/1e3}get minutes(){return this.milliseconds/6e4}get hours(){return this.milliseconds/36e5}toString(){return this.milliseconds<1e3?`${this.milliseconds}ms`:this.milliseconds<6e4?`${this.seconds}s`:this.milliseconds<36e5?`${Math.floor(this.minutes)}m ${Math.floor(this.seconds%60)}s`:`${Math.floor(this.hours)}h ${Math.floor(this.minutes%60)}m`}_toMilliseconds(e,t){return e*({ms:1,s:1e3,m:6e4,h:36e5}[t]||1)}};const Jo=U.object({id:U.number(),title:U.string().min(1),description:U.string().min(1),details:U.string(),testStrategy:U.string(),priority:U.enum(ia),dependencies:U.array(U.number()),status:U.string()}),Yo=U.object({tasks:U.array(Jo),metadata:U.union([U.object({projectName:U.string(),totalTasks:U.number(),sourceFile:U.string(),generatedAt:U.string()}).strict(),U.null()]).default(null)});var Xo=class{constructor(e,t,n,r={}){this.prdPath=e,this.tasksPath=t,this.numTasks=n,this.force=r.force||!1,this.append=r.append||!1,this.research=r.research||!1,this.reportProgress=r.reportProgress,this.mcpLog=r.mcpLog,this.session=r.session,this.projectRoot=r.projectRoot,this.tag=r.tag,this.streamingTimeout=r.streamingTimeout||qo.seconds(180).milliseconds,this.targetTag=this.tag||ge(this.projectRoot)||`master`,this.isMCP=!!this.mcpLog,this.outputFormat=this.isMCP&&!this.reportProgress?`json`:`text`,this.useStreaming=!1}hasCodebaseAnalysis(){return _(this.research,this.projectRoot,this.session)}},Zo=class{constructor(e,t){this.isMCP=!!e,this.outputFormat=this.isMCP&&!t?`json`:`text`,this.logFn=e||{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)}}report(e,t=`info`){this.logFn&&typeof this.logFn[t]==`function`?this.logFn[t](e):!L()&&this.outputFormat===`text`&&z(t,e)}};function Qo(e){return`${Math.floor(e/60)}m ${Math.floor(e%60).toString().padStart(2,`0`)}s`}const $o={BAR_WIDTH:40,TABLE_COL_WIDTHS:[28,50],DEFAULT_MODEL:`Default`,DEFAULT_TEMPERATURE:.7},Q={HIGH:`high`,MEDIUM:`medium`,LOW:`low`},es={[Q.HIGH]:`#CC0000`,[Q.MEDIUM]:`#FF8800`,[Q.LOW]:`#FFCC00`},ts={main:{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0},borderColor:`blue`,borderStyle:`round`},summary:{padding:{top:1,right:1,bottom:1,left:1},borderColor:`blue`,borderStyle:`round`,margin:{top:1,right:1,bottom:1,left:0}},warning:{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}},nextSteps:{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,right:0,bottom:1,left:0}}};function ns({prdFilePath:e,outputPath:t,numTasks:n,model:r,temperature:i,append:a,research:o}){let s=a?`Appending`:`Generating`,c=`Model: ${r} | Temperature: ${i}`;return o&&(c+=` | ${B.cyan.bold(`🔬 Research Mode`)}`),B.bold(`🤖 Parsing PRD and ${s} Tasks`)+`
852
852
  `+B.dim(c)+`
853
853
 
854
854
  `+B.blue(`Input: ${e}`)+`
855
855
  `+B.blue(`Output: ${t}`)+`
856
- `+B.blue(`Tasks to ${a?`Append`:`Generate`}: ${n}`)}function Zo(e){console.log(W(e,Yo.main))}function Qo(e,t){console.log(B.yellow.bold(`📝 Append mode`)+` - Adding to ${e} existing tasks (next ID: ${t})`)}function $o(e){let t=B.red.bold(`⚠️ Force flag enabled`);return e?`${t} - Will overwrite if conflicts occur`:`${t} - Overwriting existing tasks`}function es({prdFilePath:e,outputPath:t,numTasks:n,model:r=qo.DEFAULT_MODEL,temperature:i=qo.DEFAULT_TEMPERATURE,append:a=!1,research:o=!1,force:s=!1,existingTasks:c=[],nextId:l=1}){if(!e||typeof e!=`string`||e.trim()===``)throw Error(`prdFilePath is required and must be a non-empty string`);if(!t||typeof t!=`string`||t.trim()===``)throw Error(`outputPath is required and must be a non-empty string`);Zo(Xo({prdFilePath:e,outputPath:t,numTasks:n,model:r,temperature:i,append:a,research:o})),(a||s)&&(a&&Qo(c.length,l),s&&console.log($o(a)),console.log())}function ts(e,t){let n={};return Object.values(Q).forEach(r=>{let i=e[r]||0;n[r]={count:i,percentage:t>0?Math.round(i/t*100):0}}),n}function ns(e,t){let n=qo.BAR_WIDTH,r={};if(t===0)return Object.values(Q).forEach(e=>{r[e]=0}),r;let i={};Object.values(Q).forEach(r=>{i[r]=e[r].count/t*n}),Object.values(Q).forEach(e=>{r[e]=Math.floor(i[e])}),Object.values(Q).forEach(t=>{e[t].count>0&&r[t]===0&&(r[t]=1)});let a=n-Object.values(r).reduce((e,t)=>e+t,0);if(a>0){let e=Object.values(Q).map(e=>({priority:e,decimal:i[e]-Math.floor(i[e])})).sort((e,t)=>t.decimal-e.decimal);for(let t=0;t<a&&t<e.length;t++)r[e[t].priority]++}return r}function rs(e){let t=``;t+=B.hex(Jo[Q.HIGH])(`█`.repeat(e[Q.HIGH])),t+=B.hex(Jo[Q.MEDIUM])(`█`.repeat(e[Q.MEDIUM])),t+=B.yellow(`█`.repeat(e[Q.LOW]));let n=Object.values(e).reduce((e,t)=>e+t,0);return n<qo.BAR_WIDTH&&(t+=B.gray(`░`.repeat(qo.BAR_WIDTH-n))),t}function is(e){let t=[];return Object.entries(Q).forEach(([n,r])=>{let i=e[r],a=r===Q.HIGH?B.hex(Jo[Q.HIGH]):r===Q.MEDIUM?B.hex(Jo[Q.MEDIUM]):B.yellow,o=n.charAt(0)+n.slice(1).toLowerCase();t.push(`${a.bold(i.count)} ${a(o)} (${i.percentage}%)`)}),[B.cyan(`Priority distribution:`),t.join(` · `)]}function as(e){let{totalTasks:t,taskPriorities:n={},prdFilePath:r,outputPath:i,elapsedTime:a,usedFallback:o=!1,actionVerb:s=`generated`}=e,c=Ko(a),l=new K({chars:{top:``,"top-mid":``,"top-left":``,"top-right":``,bottom:``,"bottom-mid":``,"bottom-left":``,"bottom-right":``,left:``,"left-mid":``,mid:``,"mid-mid":``,right:``,"right-mid":``,middle:` `},style:{border:[],"padding-left":2},colWidths:qo.TABLE_COL_WIDTHS});if(l.push([B.cyan(`Total tasks ${s}:`),B.bold(t)],[B.cyan(`Processing time:`),B.bold(c)]),n&&Object.keys(n).length>0){let e=ts(n,t),r=is(e);l.push(r);let i=rs(ns(e,t));l.push([B.cyan(`Distribution:`),i])}l.push([B.cyan(`PRD source:`),B.italic(r)],[B.cyan(`Tasks file:`),B.italic(i)]),o&&l.push([B.yellow(`Fallback parsing:`),B.yellow(`✓ Used fallback parsing`)]);let u=[B.bold.underline(`PRD Parsing Complete - Tasks ${s.charAt(0).toUpperCase()+s.slice(1)}`),``,l.toString()].join(`
857
- `);console.log(W(u,Yo.summary)),o&&os(),ss()}function os(){let e=B.yellow.bold(`⚠️ Fallback Parsing Used`)+`
856
+ `+B.blue(`Tasks to ${a?`Append`:`Generate`}: ${n}`)}function rs(e){console.log(W(e,ts.main))}function is(e,t){console.log(B.yellow.bold(`📝 Append mode`)+` - Adding to ${e} existing tasks (next ID: ${t})`)}function as(e){let t=B.red.bold(`⚠️ Force flag enabled`);return e?`${t} - Will overwrite if conflicts occur`:`${t} - Overwriting existing tasks`}function os({prdFilePath:e,outputPath:t,numTasks:n,model:r=$o.DEFAULT_MODEL,temperature:i=$o.DEFAULT_TEMPERATURE,append:a=!1,research:o=!1,force:s=!1,existingTasks:c=[],nextId:l=1}){if(!e||typeof e!=`string`||e.trim()===``)throw Error(`prdFilePath is required and must be a non-empty string`);if(!t||typeof t!=`string`||t.trim()===``)throw Error(`outputPath is required and must be a non-empty string`);rs(ns({prdFilePath:e,outputPath:t,numTasks:n,model:r,temperature:i,append:a,research:o})),(a||s)&&(a&&is(c.length,l),s&&console.log(as(a)),console.log())}function ss(e,t){let n={};return Object.values(Q).forEach(r=>{let i=e[r]||0;n[r]={count:i,percentage:t>0?Math.round(i/t*100):0}}),n}function cs(e,t){let n=$o.BAR_WIDTH,r={};if(t===0)return Object.values(Q).forEach(e=>{r[e]=0}),r;let i={};Object.values(Q).forEach(r=>{i[r]=e[r].count/t*n}),Object.values(Q).forEach(e=>{r[e]=Math.floor(i[e])}),Object.values(Q).forEach(t=>{e[t].count>0&&r[t]===0&&(r[t]=1)});let a=n-Object.values(r).reduce((e,t)=>e+t,0);if(a>0){let e=Object.values(Q).map(e=>({priority:e,decimal:i[e]-Math.floor(i[e])})).sort((e,t)=>t.decimal-e.decimal);for(let t=0;t<a&&t<e.length;t++)r[e[t].priority]++}return r}function ls(e){let t=``;t+=B.hex(es[Q.HIGH])(`█`.repeat(e[Q.HIGH])),t+=B.hex(es[Q.MEDIUM])(`█`.repeat(e[Q.MEDIUM])),t+=B.yellow(`█`.repeat(e[Q.LOW]));let n=Object.values(e).reduce((e,t)=>e+t,0);return n<$o.BAR_WIDTH&&(t+=B.gray(`░`.repeat($o.BAR_WIDTH-n))),t}function us(e){let t=[];return Object.entries(Q).forEach(([n,r])=>{let i=e[r],a=r===Q.HIGH?B.hex(es[Q.HIGH]):r===Q.MEDIUM?B.hex(es[Q.MEDIUM]):B.yellow,o=n.charAt(0)+n.slice(1).toLowerCase();t.push(`${a.bold(i.count)} ${a(o)} (${i.percentage}%)`)}),[B.cyan(`Priority distribution:`),t.join(` · `)]}function ds(e){let{totalTasks:t,taskPriorities:n={},prdFilePath:r,outputPath:i,elapsedTime:a,usedFallback:o=!1,actionVerb:s=`generated`}=e,c=Qo(a),l=new K({chars:{top:``,"top-mid":``,"top-left":``,"top-right":``,bottom:``,"bottom-mid":``,"bottom-left":``,"bottom-right":``,left:``,"left-mid":``,mid:``,"mid-mid":``,right:``,"right-mid":``,middle:` `},style:{border:[],"padding-left":2},colWidths:$o.TABLE_COL_WIDTHS});if(l.push([B.cyan(`Total tasks ${s}:`),B.bold(t)],[B.cyan(`Processing time:`),B.bold(c)]),n&&Object.keys(n).length>0){let e=ss(n,t),r=us(e);l.push(r);let i=ls(cs(e,t));l.push([B.cyan(`Distribution:`),i])}l.push([B.cyan(`PRD source:`),B.italic(r)],[B.cyan(`Tasks file:`),B.italic(i)]),o&&l.push([B.yellow(`Fallback parsing:`),B.yellow(`✓ Used fallback parsing`)]);let u=[B.bold.underline(`PRD Parsing Complete - Tasks ${s.charAt(0).toUpperCase()+s.slice(1)}`),``,l.toString()].join(`
857
+ `);console.log(W(u,ts.summary)),o&&fs(),ps()}function fs(){let e=B.yellow.bold(`⚠️ Fallback Parsing Used`)+`
858
858
 
859
859
  `+B.white(`The system used fallback parsing to complete task generation.`)+`
860
860
  `+B.white(`This typically happens when streaming JSON parsing is incomplete.`)+`
@@ -862,22 +862,22 @@ ${B.cyan(`1.`)} Run ${B.yellow(`task-master next`)} to see what to work on next\
862
862
  `+B.white(`• Reviewing task completeness`)+`
863
863
  `+B.white(`• Checking for any missing details`)+`
864
864
 
865
- `+B.white(`This is normal and usually doesn't indicate any issues.`);console.log(W(e,Yo.warning))}function ss(){let e=B.white.bold(`Next Steps:`)+`
865
+ `+B.white(`This is normal and usually doesn't indicate any issues.`);console.log(W(e,ts.warning))}function ps(){let e=B.white.bold(`Next Steps:`)+`
866
866
 
867
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master analyze-complexity`)} to analyze task complexity`;console.log(W(e,Yo.nextSteps))}function cs(e){return Math.ceil(e.length/4)}function ls(e){let t=V.readFileSync(e,`utf8`);if(!t)throw Error(`Input file ${e} is empty or could not be read.`);return t}function us(e,t){let n=[],r=1;if(!V.existsSync(e))return{existingTasks:n,nextId:r};try{let i=V.readFileSync(e,`utf8`),a=JSON.parse(i);a[t]?.tasks&&Array.isArray(a[t].tasks)&&(n=a[t].tasks,n.length>0&&(r=Math.max(...n.map(e=>e.id||0))+1))}catch{return{existingTasks:[],nextId:1}}return{existingTasks:n,nextId:r}}function ds({existingTasks:e,targetTag:t,append:n,force:r,isMCP:i,logger:a}){if(!(e.length>0)){a.report(`Tag '${t}' is empty or doesn't exist. Creating/updating tag with new tasks.`,`info`);return}if(n){a.report(`Append mode enabled. Found ${e.length} existing tasks in tag '${t}'.`,`info`);return}if(!r){let n=`Tag '${t}' already contains ${e.length} tasks. Use --force to overwrite or --append to add to existing tasks.`;if(a.report(n,`error`),i)throw Error(n);console.error(B.red(n)),process.exit(1)}a.report(`Force flag enabled. Overwriting existing tasks in tag '${t}'.`,`debug`)}function fs(e,t,n,r){ps(e,t);let i=t,a=new Map,o=e.map(e=>{let t=i++;return a.set(e.id,t),{...e,id:t,status:e.status||`pending`,priority:e.priority||r,dependencies:Array.isArray(e.dependencies)?e.dependencies:[],subtasks:e.subtasks||[],title:e.title||``,description:e.description||``,details:e.details||``,testStrategy:e.testStrategy||``}});return o.forEach(e=>{e.dependencies=e.dependencies.map(e=>a.get(e)).filter(t=>t!=null&&t<e.id&&(oe(n,t)||o.some(e=>e.id===t)))}),o}function ps(e,t=1){if(!Array.isArray(e)||e.length===0)return;let n=e.map(e=>e.id);if(n.some(e=>!Number.isInteger(e)||e<1))throw Error(`PRD tasks must use sequential positive integer IDs starting at 1.`);let r=new Set(n);if(r.size!==n.length)throw Error(`PRD task IDs must be unique and sequential starting at 1.`);let i=[...r].sort((e,t)=>e-t),a=i[0];if(a!==1&&a!==t)throw Error(`PRD task IDs must start at 1 or ${t} and be sequential.`);for(let e=0;e<i.length;e+=1)if(i[e]!==a+e)throw Error(`PRD task IDs must be a contiguous sequence starting at ${a}.`)}function ms(e,t,n,r){let i=H.dirname(e);V.existsSync(i)||V.mkdirSync(i,{recursive:!0});let a={};if(V.existsSync(e))try{let t=V.readFileSync(e,`utf8`);a=JSON.parse(t)}catch{a={}}a[n]={tasks:t,metadata:{created:a[n]?.metadata?.created||new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for ${n} context`}},ae(a[n],{description:`Tasks for ${n} context`}),V.writeFileSync(e,JSON.stringify(a,null,2)),r.report(`Successfully saved ${t.length} tasks to ${e}`,`debug`)}async function hs(e,t,n){let r=Da(),i=he(e.projectRoot)||`medium`;return r.loadPrompt(`parse-prd`,{research:e.research,numTasks:e.numTasks,nextId:n,prdContent:t,prdPath:e.prdPath,defaultTaskPriority:i,hasCodebaseAnalysis:e.hasCodebaseAnalysis(),projectRoot:e.projectRoot||``})}async function gs({task:e,currentCount:t,totalTasks:n,estimatedTokens:r,progressTracker:i,reportProgress:a,priorityMap:o,defaultPriority:s,estimatedInputTokens:c}){let l=e.priority||s,u=o[l]||o.medium;if(i&&(i.addTaskLine(t,e.title,l),r&&i.updateTokens(c,r)),a)try{let i=r?Math.floor(r/n):0;await a({progress:t,total:n,message:`${u} Task ${t}/${n} - ${e.title} | ~Output: ${i} tokens`})}catch{}}async function _s({processedTasks:e,nextId:t,summary:n,prdPath:r,tasksPath:i,usedFallback:a,aiServiceResponse:o}){let s=(()=>{if(!Array.isArray(e)||e.length===0)return`task_${String(t).padStart(3,`0`)}.txt`;let n=e[0].id,r=e[e.length-1].id;return e.length===1?`task_${String(n).padStart(3,`0`)}.txt`:`task_${String(n).padStart(3,`0`)}.txt -> task_${String(r).padStart(3,`0`)}.txt`})();as({totalTasks:e.length,taskPriorities:n.taskPriorities,prdFilePath:r,outputPath:i,elapsedTime:n.elapsedTime,usedFallback:a,taskFilesGenerated:s,actionVerb:n.actionVerb}),o?.telemetryData&&(o.mainResult?.usage&&await Bo.withSoftTimeout(o.mainResult.usage,1e3,void 0),Sl(o.telemetryData,`cli`))}function vs({processedTasks:e,research:t,finalTasks:n,tasksPath:r,aiServiceResponse:i}){console.log(W(B.green(`Successfully generated ${e.length} new tasks${t?` with research-backed analysis`:``}. Total tasks in ${r}: ${n.length}`),{padding:1,borderColor:`green`,borderStyle:`round`})),console.log(W(B.white.bold(`Next Steps:`)+`
867
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master analyze-complexity`)} to analyze task complexity`;console.log(W(e,ts.nextSteps))}function ms(e){return Math.ceil(e.length/4)}function hs(e){let t=V.readFileSync(e,`utf8`);if(!t)throw Error(`Input file ${e} is empty or could not be read.`);return t}function gs(e,t){let n=[],r=1;if(!V.existsSync(e))return{existingTasks:n,nextId:r};try{let i=V.readFileSync(e,`utf8`),a=JSON.parse(i);a[t]?.tasks&&Array.isArray(a[t].tasks)&&(n=a[t].tasks,n.length>0&&(r=Math.max(...n.map(e=>e.id||0))+1))}catch{return{existingTasks:[],nextId:1}}return{existingTasks:n,nextId:r}}function _s({existingTasks:e,targetTag:t,append:n,force:r,isMCP:i,logger:a}){if(!(e.length>0)){a.report(`Tag '${t}' is empty or doesn't exist. Creating/updating tag with new tasks.`,`info`);return}if(n){a.report(`Append mode enabled. Found ${e.length} existing tasks in tag '${t}'.`,`info`);return}if(!r){let n=`Tag '${t}' already contains ${e.length} tasks. Use --force to overwrite or --append to add to existing tasks.`;if(a.report(n,`error`),i)throw Error(n);console.error(B.red(n)),process.exit(1)}a.report(`Force flag enabled. Overwriting existing tasks in tag '${t}'.`,`debug`)}function vs(e,t,n,r){ys(e,t);let i=t,a=new Map,o=e.map(e=>{let t=i++;return a.set(e.id,t),{...e,id:t,status:e.status||`pending`,priority:e.priority||r,dependencies:Array.isArray(e.dependencies)?e.dependencies:[],subtasks:e.subtasks||[],title:e.title||``,description:e.description||``,details:e.details||``,testStrategy:e.testStrategy||``}});return o.forEach(e=>{e.dependencies=e.dependencies.map(e=>a.get(e)).filter(t=>t!=null&&t<e.id&&(F(n,t)||o.some(e=>e.id===t)))}),o}function ys(e,t=1){if(!Array.isArray(e)||e.length===0)return;let n=e.map(e=>e.id);if(n.some(e=>!Number.isInteger(e)||e<1))throw Error(`PRD tasks must use sequential positive integer IDs starting at 1.`);let r=new Set(n);if(r.size!==n.length)throw Error(`PRD task IDs must be unique and sequential starting at 1.`);let i=[...r].sort((e,t)=>e-t),a=i[0];if(a!==1&&a!==t)throw Error(`PRD task IDs must start at 1 or ${t} and be sequential.`);for(let e=0;e<i.length;e+=1)if(i[e]!==a+e)throw Error(`PRD task IDs must be a contiguous sequence starting at ${a}.`)}function bs(e,t,n,r){let i=H.dirname(e);V.existsSync(i)||V.mkdirSync(i,{recursive:!0});let a={};if(V.existsSync(e))try{let t=V.readFileSync(e,`utf8`);a=JSON.parse(t)}catch{a={}}a[n]={tasks:t,metadata:{created:a[n]?.metadata?.created||new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for ${n} context`}},ie(a[n],{description:`Tasks for ${n} context`}),V.writeFileSync(e,JSON.stringify(a,null,2)),r.report(`Successfully saved ${t.length} tasks to ${e}`,`debug`)}async function xs(e,t,n){let r=Na(),i=me(e.projectRoot)||`medium`;return r.loadPrompt(`parse-prd`,{research:e.research,numTasks:e.numTasks,nextId:n,prdContent:t,prdPath:e.prdPath,defaultTaskPriority:i,hasCodebaseAnalysis:e.hasCodebaseAnalysis(),projectRoot:e.projectRoot||``})}async function Ss({task:e,currentCount:t,totalTasks:n,estimatedTokens:r,progressTracker:i,reportProgress:a,priorityMap:o,defaultPriority:s,estimatedInputTokens:c}){let l=e.priority||s,u=o[l]||o.medium;if(i&&(i.addTaskLine(t,e.title,l),r&&i.updateTokens(c,r)),a)try{let i=r?Math.floor(r/n):0;await a({progress:t,total:n,message:`${u} Task ${t}/${n} - ${e.title} | ~Output: ${i} tokens`})}catch{}}async function Cs({processedTasks:e,nextId:t,summary:n,prdPath:r,tasksPath:i,usedFallback:a,aiServiceResponse:o}){let s=(()=>{if(!Array.isArray(e)||e.length===0)return`task_${String(t).padStart(3,`0`)}.txt`;let n=e[0].id,r=e[e.length-1].id;return e.length===1?`task_${String(n).padStart(3,`0`)}.txt`:`task_${String(n).padStart(3,`0`)}.txt -> task_${String(r).padStart(3,`0`)}.txt`})();ds({totalTasks:e.length,taskPriorities:n.taskPriorities,prdFilePath:r,outputPath:i,elapsedTime:n.elapsedTime,usedFallback:a,taskFilesGenerated:s,actionVerb:n.actionVerb}),o?.telemetryData&&(o.mainResult?.usage&&await Ko.withSoftTimeout(o.mainResult.usage,1e3,void 0),Ol(o.telemetryData,`cli`))}function ws({processedTasks:e,research:t,finalTasks:n,tasksPath:r,aiServiceResponse:i}){console.log(W(B.green(`Successfully generated ${e.length} new tasks${t?` with research-backed analysis`:``}. Total tasks in ${r}: ${n.length}`),{padding:1,borderColor:`green`,borderStyle:`round`})),console.log(W(B.white.bold(`Next Steps:`)+`
868
868
 
869
- ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&Sl(i.telemetryData,`cli`)}async function ys(e,t){let n=new Go(e.mcpLog,e.reportProgress),{systemPrompt:r,userPrompt:a}=t,o=cs(r+a),s=null;e.outputFormat===`text`&&!e.isMCP&&(s=J(`Parsing PRD and generating tasks...
870
- `).start());try{n.report(`Calling AI service to generate tasks from PRD${e.research?` with research-backed analysis`:``}...`,`info`);let t=await i({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Uo,objectName:`tasks_data`,systemPrompt:r,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),c=null;if(t?.mainResult&&(typeof t.mainResult==`object`&&t.mainResult!==null&&`tasks`in t.mainResult?c=t.mainResult:typeof t.mainResult.object==`object`&&t.mainResult.object!==null&&`tasks`in t.mainResult.object&&(c=t.mainResult.object)),!c||!Array.isArray(c.tasks))throw Error(`AI service returned unexpected data structure after validation.`);return s&&s.succeed(`Tasks generated successfully!`),{parsedTasks:c.tasks,aiServiceResponse:t,estimatedInputTokens:o}}catch(e){throw s&&s.fail(`Error parsing PRD: ${e.message}`),e}}const[bs,xs,Ss]=Qi,Cs=new Map;var ws=class{constructor(e,t,n,r=null){this.name=e,this.levels=t,this.colors=n,this.thresholds=r}getColor(e){return this.colors[e]||B.gray}getLevelFromScore(e){if(!this.thresholds)throw Error(`${this.name} does not support score-based levels`);return e>=7?this.levels[0]:e<=3?this.levels[2]:this.levels[1]}};const Ts={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},Es=new ws(`priority`,[bs,xs,Ss],{[bs]:B.hex(`#CC0000`),[xs]:B.hex(`#FF8800`),[Ss]:B.yellow});function Ds(e,t){let n=Ts.cli.filled,r=Ts.cli.empty,i=``;for(let a=0;a<3;a++)a<e?i+=t(n):i+=B.white(r);return i}function Os(e,t){return 3-t.indexOf(e)}function ks(e,t){if(Cs.has(e))return Cs.get(e);let n=t();return Cs.set(e,n),n}function As(){return ks(`mcp-priority-all`,()=>({[bs]:Ts.mcp.high,[xs]:Ts.mcp.medium,[Ss]:Ts.mcp.low}))}function js(){return ks(`cli-priority-all`,()=>{let e={};return Es.levels.forEach(t=>{e[t]=Ds(Os(t,Es.levels),Es.getColor(t))}),e})}function Ms(){return ks(`statusbar-priority-all`,()=>{let e={};return Es.levels.forEach((t,n)=>{let r=n===0?Ts.statusBar.high:n===1?Ts.statusBar.medium:Ts.statusBar.low;e[t]=Es.getColor(t)(r)}),e})}function Ns(){return{[bs]:Es.colors[bs],[xs]:Es.colors[xs],[Ss]:Es.colors[Ss]}}function Ps(e=!1){return e?As():js()}function Fs(e,t=!1){let n=Ps(t);return n[e]||n[xs]}new ws(`complexity`,[`high`,`medium`,`low`],{high:B.hex(`#CC0000`),medium:B.hex(`#FF8800`),low:B.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const Is={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},Ls={shades_classic:mt.Presets.shades_classic,shades_grey:mt.Presets.shades_grey,rect:mt.Presets.rect,legacy:mt.Presets.legacy},Rs=new class{constructor(e={},t=Ls.shades_classic){this.defaultOptions={...Is,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function zs(e={}){return Rs.createMultiBar(e)}var Bs=class{constructor(e={}){this.numUnits=e.numUnits||1,this.unitName=e.unitName||`unit`,this.startTime=null,this.completedUnits=0,this.tokensIn=0,this.tokensOut=0,this.isEstimate=!0,this.bestAvgTimePerUnit=null,this.lastEstimateTime=null,this.lastEstimateSeconds=0,this.multibar=null,this.timeTokensBar=null,this.progressBar=null,this._timerInterval=null,this.isStarted=!1,this.isFinished=!1,this._initializeCustomProperties(e)}_initializeCustomProperties(e){}get unitNamePlural(){return`${this.unitName}s`}start(){this.isStarted||this.isFinished||(this.isStarted=!0,this.startTime=Date.now(),this.multibar=zs(),this.timeTokensBar=this.multibar.create(1,0,{},{format:this._getTimeTokensBarFormat(),barsize:1,hideCursor:!0,clearOnComplete:!1}),this.progressBar=this.multibar.create(this.numUnits,0,{},{format:this._getProgressBarFormat(),barCompleteChar:`█`,barIncompleteChar:`░`}),this._updateTimeTokensBar(),this.progressBar.update(0,{[this.unitNamePlural]:`0/${this.numUnits}`}),this._timerInterval=setInterval(()=>this._updateTimeTokensBar(),1e3),this._setupCustomUI())}_setupCustomUI(){}_getTimeTokensBarFormat(){return`{clock} {elapsed} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`${this.unitName.charAt(0).toUpperCase()+this.unitName.slice(1)}s {${this.unitNamePlural}} |{bar}| {percentage}%`}updateTokens(e,t,n=!1){this.tokensIn=e||0,this.tokensOut=t||0,this.isEstimate=n,this._updateTimeTokensBar()}_updateTimeTokensBar(){if(!this.timeTokensBar||this.isFinished)return;let e=this._formatElapsedTime(),t=this._estimateRemainingTime(),n=this.isEstimate?`~ Tokens (I/O)`:`Tokens (I/O)`;this.timeTokensBar.update(1,{clock:`⏱️`,elapsed:e,in:this.tokensIn,out:this.tokensOut,remaining:t,tokensLabel:n,...this._getCustomTimeTokensPayload()})}_getCustomTimeTokensPayload(){return{}}_formatElapsedTime(){if(!this.startTime)return`0m 00s`;let e=Math.floor((Date.now()-this.startTime)/1e3);return`${Math.floor(e/60)}m ${(e%60).toString().padStart(2,`0`)}s`}_estimateRemainingTime(){let e=this._getProgressFraction();if(e>=1)return`~0s`;let t=Date.now(),n=(t-this.startTime)/1e3;if(e===0)return`~calculating...`;let r=n/e;(this.bestAvgTimePerUnit===null||r<this.bestAvgTimePerUnit)&&(this.bestAvgTimePerUnit=r);let i=this.numUnits*(1-e),a=Math.ceil(i*this.bestAvgTimePerUnit);if(this.lastEstimateTime){let e=Math.floor((t-this.lastEstimateTime)/1e3),n=Math.max(0,this.lastEstimateSeconds-e);if(n===0)return`~0s`;a=Math.min(a,n)}return this.lastEstimateTime=t,this.lastEstimateSeconds=a,`~${this._formatDuration(a)}`}_getProgressFraction(){return this.completedUnits/this.numUnits}_formatDuration(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return t<60?n>0?`${t}m ${n}s`:`${t}m`:`${Math.floor(t/60)}h ${t%60}m`}getElapsedTime(){return this.startTime?Date.now()-this.startTime:0}stop(){this.isFinished||(this.isFinished=!0,this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar&&(this._updateTimeTokensBar(),this.multibar.stop()),this.cleanup())}getSummary(){return{completedUnits:this.completedUnits,elapsedTime:this.getElapsedTime()}}cleanup(){if(this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar){try{this.multibar.stop()}catch{}this.multibar=null}this.timeTokensBar=null,this.progressBar=null,this.isStarted=!1,this.isFinished=!0,this._performCustomCleanup()}_performCustomCleanup(){}},Vs=class{constructor(e){if(!e)throw Error(`Multibar instance is required`);this.multibar=e}createBar(e,t={}){if(typeof e!=`string`)throw Error(`Format must be a string`);let n=this.multibar.create(1,1,{},{format:e,barsize:1,hideCursor:!0,clearOnComplete:!1});return n.update(1,t),n}createHeader(e,t){this.createBar(t),this.createBar(e),this.createBar(t)}createRow(e,t){if(!t||typeof t!=`object`)throw Error(`Payload must be an object`);return this.createBar(e,t)}createBorder(e){return this.createBar(e)}};function Hs(e,t,n){new Vs(e).createHeader(t,n)}function Us(e,t,n){new Vs(e).createRow(t,n)}function Ws(e,t){new Vs(e).createBorder(t)}js();const Gs=Ms();Ns();const Ks={DEBOUNCE_DELAY:100,MAX_TITLE_LENGTH:57,TRUNCATED_LENGTH:54,TASK_ID_PAD_START:3,TASK_ID_PAD_END:4,PRIORITY_PAD_END:3,VALID_PRIORITIES:[`high`,`medium`,`low`],DEFAULT_PRIORITY:`medium`};var qs=class{constructor(e=Ks.DEBOUNCE_DELAY){this.delay=e,this.pendingTimeout=null}debounce(e){this.clear(),this.pendingTimeout=setTimeout(()=>{e(),this.pendingTimeout=null},this.delay)}clear(){this.pendingTimeout&&=(clearTimeout(this.pendingTimeout),null)}hasPending(){return this.pendingTimeout!==null}},Js=class{constructor(){this.priorities={high:0,medium:0,low:0}}increment(e){let t=this.normalize(e);return this.priorities[t]++,t}normalize(e){let t=e?e.toLowerCase():Ks.DEFAULT_PRIORITY;return Ks.VALID_PRIORITIES.includes(t)?t:Ks.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Ys=class{static formatTitle(e,t){return e?e.length>Ks.MAX_TITLE_LENGTH?e.substring(0,Ks.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return Fs(e,!1).padEnd(Ks.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(Ks.TASK_ID_PAD_START,` `).padEnd(Ks.TASK_ID_PAD_END,` `)}},Xs=class extends Bs{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new Js,this.debouncer=new qs,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${Gs.high} {high} ${Gs.medium} {medium} ${Gs.low} {low} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`Tasks {tasks} |{bar}| {percentage}%`}_getCustomTimeTokensPayload(){return this.priorityManager.getCounts()}addTaskLine(e,t,n=`medium`){if(!this.multibar||this.isFinished)return;this._ensureHeaderShown();let r=this._updateTaskCounters(e,n);this._updateTimeTokensBar(),this.debouncer.debounce(()=>{this._updateProgressDisplay(e,t,r)})}_ensureHeaderShown(){this.headerShown||(this.headerShown=!0,Hs(this.multibar,` TASK | PRI | TITLE`,`------+-----+----------------------------------------------------------------`))}_updateTaskCounters(e,t){let n=this.priorityManager.increment(t);return this.completedUnits=e,n}_updateProgressDisplay(e,t,n){this.progressBar.update(this.completedUnits,{tasks:`${this.completedUnits}/${this.numUnits}`});let r=Ys.formatTitle(t,e),i=Ys.formatPriority(n),a=Ys.formatTaskId(e);Us(this.multibar,` ${a} | ${i} | {title}`,{title:r}),Ws(this.multibar,`------+-----+----------------------------------------------------------------`),this._updateTimeTokensBar()}finish(){this.debouncer.hasPending()&&(this.debouncer.clear(),this._updateTimeTokensBar()),this.cleanup(),super.finish()}_performCustomCleanup(){this.debouncer.clear()}getSummary(){return{...super.getSummary(),taskPriorities:this.priorityManager.getCounts(),actionVerb:this.append?`appended`:`generated`}}};function Zs(e={}){return new Xs(e)}async function Qs(e,t,n){let r=$s(e,t,n);await tc(e,n,r.estimatedInputTokens);let i=await nc(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await rc(e,n),s=await ic(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(ec(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-DYXlveV4.js`),{getUserId:n}=await import(`./config-manager-BiA1Lh9-.js`),a=n(e.projectRoot);if(a&&i.providerName&&i.modelId)try{let n=await t({userId:a,commandName:`parse-prd`,providerName:i.providerName,modelId:i.modelId,inputTokens:s.usage.promptTokens||0,outputTokens:s.usage.completionTokens||0,outputType:e.isMCP?`mcp`:`cli`});n&&(i.telemetryData=n)}catch(e){r.logger.report(`Failed to log telemetry: ${e.message}`,`debug`)}}return mc(s,i,r.estimatedInputTokens,a)}function $s(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new Go(e.mcpLog,e.reportProgress),estimatedInputTokens:cs(r+i),defaultPriority:he(e.projectRoot)||`medium`}}function ec(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function tc(e,t,n){e.reportProgress&&await e.reportProgress({progress:0,total:t,message:`Starting PRD analysis (Input: ${n} tokens)${e.research?` with research`:``}...`})}async function nc(e,n,r){let{systemPrompt:i,userPrompt:a}=n;return await Bo.withTimeout(t({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Uo,systemPrompt:i,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),r,`Streaming operation`)}async function rc(e,t){let n=Ps(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Zs({numUnits:t,unitName:`task`,append:e.append});let n=e.research?o():T(),i=f(e.research?`research`:`main`);es({prdFilePath:e.prdPath,outputPath:e.tasksPath,numTasks:t,append:e.append,research:e.research,force:e.force,existingTasks:[],nextId:1,model:n||`Default`,temperature:i?.temperature||.7}),r.start()}return{progressTracker:r,priorityMap:n}}async function ic(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:Uo},numTasks:r,progressTracker:i,priorityMap:a,defaultPriority:o,estimatedInputTokens:s,prompt:u,systemPrompt:l};try{let t={lastPartialObject:null,taskCount:0,estimatedOutputTokens:0,usage:null};if(await ac(e.partialObjectStream,t,d),e.usage)try{t.usage=await e.usage}catch(e){c.report(`Failed to get usage data: ${e.message}`,`debug`)}return lc(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await pc(d,c)}}async function ac(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=cs(JSON.stringify(r))),await oc(r,t,n)}async function oc(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await sc(e.tasks,t.taskCount,r,t.estimatedOutputTokens,n),t.taskCount=r):n.progressTracker&&t.estimatedOutputTokens>0&&n.progressTracker.updateTokens(n.estimatedInputTokens,t.estimatedOutputTokens,!0)}async function sc(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await gs({task:t,currentCount:a+1,totalTasks:i.numTasks,estimatedTokens:r,progressTracker:i.progressTracker,reportProgress:i.config.reportProgress,priorityMap:i.priorityMap,defaultPriority:i.defaultPriority,estimatedInputTokens:i.estimatedInputTokens}):await cc(a+1,r,i)}}async function cc(e,t,n){let{progressTracker:r,config:i,numTasks:a,defaultPriority:o,estimatedInputTokens:s}=n;r&&(r.addTaskLine(e,`Generating task ${e}...`,o),r.updateTokens(s,t,!0)),i.reportProgress&&!r&&await i.reportProgress({progress:e,total:a,message:`Generating task ${e}/${a}...`})}async function lc(e,t){let{lastPartialObject:n,estimatedOutputTokens:r,taskCount:i,usage:a}=e;if(!n?.tasks||!Array.isArray(n.tasks))throw Error(`No tasks generated from streamObject`);let o=a?.completionTokens||r,s=a?.promptTokens||t.estimatedInputTokens;return t.progressTracker&&await uc(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function uc(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?dc(e,a,o):await fc(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function dc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&t.addTaskLine(r+1,i.title,i.priority||n)}}async function fc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await gs({task:i,currentCount:r+1,totalTasks:n.numTasks,estimatedTokens:t,progressTracker:n.progressTracker,reportProgress:n.config.reportProgress,priorityMap:n.priorityMap,defaultPriority:n.defaultPriority,estimatedInputTokens:n.estimatedInputTokens})}}async function pc(e,t){if(t.report(`Using generateObject fallback for PRD parsing`,`info`),e.progressTracker)for(let t=0;t<e.numTasks;t++)e.progressTracker.addTaskLine(t+1,`Generating task ${t+1}...`,e.defaultPriority),e.progressTracker.updateTokens(e.estimatedInputTokens,0,!0);let n=await i({role:e.config.research?`research`:`main`,commandName:`parse-prd`,prompt:e.prompt,systemPrompt:e.systemPrompt,schema:e.config.schema,outputFormat:e.config.outputFormat||`text`,projectRoot:e.config.projectRoot,session:e.config.session}),r=n?.mainResult||n;if(r&&Array.isArray(r.tasks)&&(r.tasks=r.tasks.map(e=>({...e,dependencies:e.dependencies??[],priority:e.priority??null,details:e.details??null,testStrategy:e.testStrategy??null}))),r&&Array.isArray(r.tasks)){if(e.progressTracker){for(let t=0;t<r.tasks.length;t++){let n=r.tasks[t];n&&n.title&&e.progressTracker.addTaskLine(t+1,n.title,n.priority||e.defaultPriority)}let t=n.telemetryData?.outputTokens||cs(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||cs(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function mc(e,t,n,r){let i=null;if(r&&(i=r.getSummary(),r.cleanup()),e.usage&&t){let n=e.usage;t.usage||={promptTokens:n.promptTokens||0,completionTokens:n.completionTokens||0,totalTokens:n.totalTokens||0}}return{parsedTasks:e.parsedTasks,aiServiceResponse:t,estimatedInputTokens:e.actualInputTokens||n,estimatedOutputTokens:e.estimatedOutputTokens,usedFallback:e.usedFallback,progressTracker:r,summary:i}}async function hc(e,t,n){let r=new Go(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let{existingTasks:i,nextId:a}=us(e.tasksPath,e.targetTag);ds({existingTasks:i,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let o=await t(e,await hs(e,ls(e.prdPath),a),e.numTasks),s=he(e.projectRoot)||`medium`,c=fs(o.parsedTasks,a,i,s),l=e.append?[...i,...c]:c;return ms(e.tasksPath,l,e.targetTag,r),await gc(e,o,c,l,a,n),{success:!0,tasksPath:e.tasksPath,telemetryData:o.aiServiceResponse?.telemetryData,tagInfo:o.aiServiceResponse?.tagInfo}}catch(t){throw r.report(`Error parsing PRD: ${t.message}`,`error`),e.isMCP||(console.error(B.red(`Error: ${t.message}`)),je(e.projectRoot)&&console.error(t)),t}}async function gc(e,t,n,r,i,a){let{aiServiceResponse:o,estimatedInputTokens:s,estimatedOutputTokens:c}=t;if(e.reportProgress){let t=o?.telemetryData&&(o.telemetryData.inputTokens>0||o.telemetryData.outputTokens>0),n;if(t){let e=o.telemetryData.totalCost||0,t=o.telemetryData.currency||`USD`;n=`✅ Task Generation Completed | Tokens (I/O): ${o.telemetryData.inputTokens}/${o.telemetryData.outputTokens} | Cost: ${t===`USD`?`$`:t}${e.toFixed(4)}`}else n=`✅ Task Generation Completed | ~Tokens (I/O): ${s}/${a?c:`unknown`} | Cost: ~$0.00`;await e.reportProgress({progress:e.numTasks,total:e.numTasks,message:n})}e.outputFormat===`text`&&!e.isMCP&&(a&&t.summary?await _s({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||vs({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function _c(e,t,n,r={}){return hc(new Wo(e,t,n,r),Qs,!0)}async function vc(e,t,n,r={}){return hc(new Wo(e,t,n,r),ys,!1)}async function yc(e,t,n,r={}){let i=new Wo(e,t,n,r);if(i.useStreaming)try{return await _c(e,t,n,r)}catch(a){if(a instanceof Ro||a.code===zo.NOT_ASYNC_ITERABLE||a.code===zo.STREAM_PROCESSING_FAILED||a.code===zo.STREAM_NOT_ITERABLE||Bo.isTimeoutError(a)){let o=new Go(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(B.yellow(`⚠️ Streaming operation ${a.message.includes(`timed out`)?`timed out`:`failed`}. Falling back to non-streaming mode...`)):o.report(`Streaming failed (${a.message}), falling back to non-streaming mode...`,`warn`),await vc(e,t,n,r)}else throw a}else return await vc(e,t,n,r)}var bc=yc;async function xc(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{z(`info`,`Removing subtask ${t}...`);let r=D(e,a,o);if(!r||!r.tasks)throw Error(`Invalid or missing tasks file at ${e}`);if(!t.includes(`.`))throw Error(`Invalid subtask ID format: ${t}. Expected format: "parentId.subtaskId"`);let[i,s]=t.split(`.`),c=parseInt(i,10),l=parseInt(s,10),u=r.tasks.find(e=>e.id===c);if(!u)throw Error(`Parent task with ID ${c} not found`);if(!u.subtasks||u.subtasks.length===0)throw Error(`Parent task ${c} has no subtasks`);let d=u.subtasks.findIndex(e=>e.id===l);if(d===-1)throw Error(`Subtask ${t} not found`);let f={...u.subtasks[d]};u.subtasks.splice(d,1),u.subtasks.length===0&&(u.subtasks=void 0);let p=null;if(n){z(`info`,`Converting subtask ${t} to a standalone task...`);let e=Math.max(...r.tasks.map(e=>e.id))+1;p={id:e,title:f.title,description:f.description||``,details:f.details||``,status:f.status||`pending`,dependencies:f.dependencies||[],priority:u.priority||`medium`},p.dependencies.includes(c)||p.dependencies.push(c),r.tasks.push(p),z(`info`,`Created new task ${e} from subtask ${t}`)}else z(`info`,`Subtask ${t} deleted`);return y(e,r,a,o),p}catch(e){throw z(`error`,`Error removing subtask: ${e.message}`),e}}var Sc=xc;function Cc(e,t){if(typeof t==`string`&&t.includes(`.`)){let n=t.split(`.`);if(n.length!==2||!n[0]||!n[1]){let n=parseInt(t,10);return e.some(e=>e.id===n)}let[r,i]=n,a=parseInt(r,10),o=parseInt(i,10),s=e.find(e=>e.id===a);return s&&s.subtasks&&s.subtasks.some(e=>e.id===o)}let n=parseInt(t,10);return e.some(e=>e.id===n)}var wc=Cc;async function Tc(e,t,n={}){let{projectRoot:r,tag:i}=n,a={success:!0,messages:[],errors:[],removedTasks:[]},o=t.split(`,`).map(e=>e.trim()).filter(Boolean);if(o.length===0)return a.success=!1,a.errors.push(`No valid task IDs provided.`),a;try{let t=D(e,r,i);if(!t)throw Error(`Could not read tasks file at ${e}`);let n=t._rawTaggedData||t;if(!n[i]||!n[i].tasks)throw Error(`Tag '${i}' not found or has no tasks.`);let s=n[i].tasks,c=[];for(let e of o){if(!wc(s,e)){let t=`Task with ID ${e} in tag '${i}' not found or already removed.`;a.errors.push(t),a.success=!1;continue}try{if(typeof e==`string`&&e.includes(`.`)){let[t,n]=e.split(`.`).map(e=>parseInt(e,10)),r=s.find(e=>e.id===t);if(!r||!r.subtasks)throw Error(`Parent task ${t} or its subtasks not found for subtask ${e}`);let o=r.subtasks.findIndex(e=>e.id===n);if(o===-1)throw Error(`Subtask ${n} not found in parent task ${t}`);let c={...r.subtasks[o],parentTaskId:t};a.removedTasks.push(c),r.subtasks.splice(o,1),a.messages.push(`Successfully removed subtask ${e} from tag '${i}'`)}else{let t=parseInt(e,10),n=s.findIndex(e=>e.id===t);if(n===-1)throw Error(`Task with ID ${e} not found in tag '${i}'`);let r=s[n];a.removedTasks.push(r),c.push(t),s.splice(n,1),a.messages.push(`Successfully removed task ${e} from tag '${i}'`)}}catch(t){let n=`Error processing ID ${e}: ${t.message}`;a.errors.push(n),a.success=!1,z(`warn`,n)}}if(a.removedTasks.length>0){let t=new Set(o.map(e=>typeof e==`string`&&e.includes(`.`)?e:parseInt(e,10)));for(let e in n[i].tasks=s,n)Object.prototype.hasOwnProperty.call(n,e)&&n[e]&&n[e].tasks&&n[e].tasks.forEach(e=>{e.dependencies&&=e.dependencies.filter(e=>!t.has(e)),e.subtasks&&e.subtasks.forEach(n=>{n.dependencies&&=n.dependencies.filter(n=>!t.has(`${e.id}.${n}`)&&!t.has(n))})});y(e,n,r,i);for(let t of c){let n=H.join(H.dirname(e),`task_${t.toString().padStart(3,`0`)}.txt`);if(qe.existsSync(n))try{qe.unlinkSync(n),a.messages.push(`Deleted task file: ${n}`)}catch(e){let t=`Failed to delete task file ${n}: ${e.message}`;a.errors.push(t),a.success=!1,z(`warn`,t)}}}else a.errors.length===0&&a.messages.push(`No tasks found matching the provided IDs.`);let l=a.messages.join(`
869
+ ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&Ol(i.telemetryData,`cli`)}async function Ts(e,t){let n=new Zo(e.mcpLog,e.reportProgress),{systemPrompt:r,userPrompt:a}=t,o=ms(r+a),s=null;e.outputFormat===`text`&&!e.isMCP&&(s=J(`Parsing PRD and generating tasks...
870
+ `).start());try{n.report(`Calling AI service to generate tasks from PRD${e.research?` with research-backed analysis`:``}...`,`info`);let t=await i({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Yo,objectName:`tasks_data`,systemPrompt:r,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),c=null;if(t?.mainResult&&(typeof t.mainResult==`object`&&t.mainResult!==null&&`tasks`in t.mainResult?c=t.mainResult:typeof t.mainResult.object==`object`&&t.mainResult.object!==null&&`tasks`in t.mainResult.object&&(c=t.mainResult.object)),!c||!Array.isArray(c.tasks))throw Error(`AI service returned unexpected data structure after validation.`);return s&&s.succeed(`Tasks generated successfully!`),{parsedTasks:c.tasks,aiServiceResponse:t,estimatedInputTokens:o}}catch(e){throw s&&s.fail(`Error parsing PRD: ${e.message}`),e}}const[Es,Ds,Os]=ia,ks=new Map;var As=class{constructor(e,t,n,r=null){this.name=e,this.levels=t,this.colors=n,this.thresholds=r}getColor(e){return this.colors[e]||B.gray}getLevelFromScore(e){if(!this.thresholds)throw Error(`${this.name} does not support score-based levels`);return e>=7?this.levels[0]:e<=3?this.levels[2]:this.levels[1]}};const js={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},Ms=new As(`priority`,[Es,Ds,Os],{[Es]:B.hex(`#CC0000`),[Ds]:B.hex(`#FF8800`),[Os]:B.yellow});function Ns(e,t){let n=js.cli.filled,r=js.cli.empty,i=``;for(let a=0;a<3;a++)a<e?i+=t(n):i+=B.white(r);return i}function Ps(e,t){return 3-t.indexOf(e)}function Fs(e,t){if(ks.has(e))return ks.get(e);let n=t();return ks.set(e,n),n}function Is(){return Fs(`mcp-priority-all`,()=>({[Es]:js.mcp.high,[Ds]:js.mcp.medium,[Os]:js.mcp.low}))}function Ls(){return Fs(`cli-priority-all`,()=>{let e={};return Ms.levels.forEach(t=>{e[t]=Ns(Ps(t,Ms.levels),Ms.getColor(t))}),e})}function Rs(){return Fs(`statusbar-priority-all`,()=>{let e={};return Ms.levels.forEach((t,n)=>{let r=n===0?js.statusBar.high:n===1?js.statusBar.medium:js.statusBar.low;e[t]=Ms.getColor(t)(r)}),e})}function zs(){return{[Es]:Ms.colors[Es],[Ds]:Ms.colors[Ds],[Os]:Ms.colors[Os]}}function Bs(e=!1){return e?Is():Ls()}function Vs(e,t=!1){let n=Bs(t);return n[e]||n[Ds]}new As(`complexity`,[`high`,`medium`,`low`],{high:B.hex(`#CC0000`),medium:B.hex(`#FF8800`),low:B.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const Hs={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},Us={shades_classic:mt.Presets.shades_classic,shades_grey:mt.Presets.shades_grey,rect:mt.Presets.rect,legacy:mt.Presets.legacy},Ws=new class{constructor(e={},t=Us.shades_classic){this.defaultOptions={...Hs,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function Gs(e={}){return Ws.createMultiBar(e)}var Ks=class{constructor(e={}){this.numUnits=e.numUnits||1,this.unitName=e.unitName||`unit`,this.startTime=null,this.completedUnits=0,this.tokensIn=0,this.tokensOut=0,this.isEstimate=!0,this.bestAvgTimePerUnit=null,this.lastEstimateTime=null,this.lastEstimateSeconds=0,this.multibar=null,this.timeTokensBar=null,this.progressBar=null,this._timerInterval=null,this.isStarted=!1,this.isFinished=!1,this._initializeCustomProperties(e)}_initializeCustomProperties(e){}get unitNamePlural(){return`${this.unitName}s`}start(){this.isStarted||this.isFinished||(this.isStarted=!0,this.startTime=Date.now(),this.multibar=Gs(),this.timeTokensBar=this.multibar.create(1,0,{},{format:this._getTimeTokensBarFormat(),barsize:1,hideCursor:!0,clearOnComplete:!1}),this.progressBar=this.multibar.create(this.numUnits,0,{},{format:this._getProgressBarFormat(),barCompleteChar:`█`,barIncompleteChar:`░`}),this._updateTimeTokensBar(),this.progressBar.update(0,{[this.unitNamePlural]:`0/${this.numUnits}`}),this._timerInterval=setInterval(()=>this._updateTimeTokensBar(),1e3),this._setupCustomUI())}_setupCustomUI(){}_getTimeTokensBarFormat(){return`{clock} {elapsed} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`${this.unitName.charAt(0).toUpperCase()+this.unitName.slice(1)}s {${this.unitNamePlural}} |{bar}| {percentage}%`}updateTokens(e,t,n=!1){this.tokensIn=e||0,this.tokensOut=t||0,this.isEstimate=n,this._updateTimeTokensBar()}_updateTimeTokensBar(){if(!this.timeTokensBar||this.isFinished)return;let e=this._formatElapsedTime(),t=this._estimateRemainingTime(),n=this.isEstimate?`~ Tokens (I/O)`:`Tokens (I/O)`;this.timeTokensBar.update(1,{clock:`⏱️`,elapsed:e,in:this.tokensIn,out:this.tokensOut,remaining:t,tokensLabel:n,...this._getCustomTimeTokensPayload()})}_getCustomTimeTokensPayload(){return{}}_formatElapsedTime(){if(!this.startTime)return`0m 00s`;let e=Math.floor((Date.now()-this.startTime)/1e3);return`${Math.floor(e/60)}m ${(e%60).toString().padStart(2,`0`)}s`}_estimateRemainingTime(){let e=this._getProgressFraction();if(e>=1)return`~0s`;let t=Date.now(),n=(t-this.startTime)/1e3;if(e===0)return`~calculating...`;let r=n/e;(this.bestAvgTimePerUnit===null||r<this.bestAvgTimePerUnit)&&(this.bestAvgTimePerUnit=r);let i=this.numUnits*(1-e),a=Math.ceil(i*this.bestAvgTimePerUnit);if(this.lastEstimateTime){let e=Math.floor((t-this.lastEstimateTime)/1e3),n=Math.max(0,this.lastEstimateSeconds-e);if(n===0)return`~0s`;a=Math.min(a,n)}return this.lastEstimateTime=t,this.lastEstimateSeconds=a,`~${this._formatDuration(a)}`}_getProgressFraction(){return this.completedUnits/this.numUnits}_formatDuration(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return t<60?n>0?`${t}m ${n}s`:`${t}m`:`${Math.floor(t/60)}h ${t%60}m`}getElapsedTime(){return this.startTime?Date.now()-this.startTime:0}stop(){this.isFinished||(this.isFinished=!0,this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar&&(this._updateTimeTokensBar(),this.multibar.stop()),this.cleanup())}getSummary(){return{completedUnits:this.completedUnits,elapsedTime:this.getElapsedTime()}}cleanup(){if(this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar){try{this.multibar.stop()}catch{}this.multibar=null}this.timeTokensBar=null,this.progressBar=null,this.isStarted=!1,this.isFinished=!0,this._performCustomCleanup()}_performCustomCleanup(){}},qs=class{constructor(e){if(!e)throw Error(`Multibar instance is required`);this.multibar=e}createBar(e,t={}){if(typeof e!=`string`)throw Error(`Format must be a string`);let n=this.multibar.create(1,1,{},{format:e,barsize:1,hideCursor:!0,clearOnComplete:!1});return n.update(1,t),n}createHeader(e,t){this.createBar(t),this.createBar(e),this.createBar(t)}createRow(e,t){if(!t||typeof t!=`object`)throw Error(`Payload must be an object`);return this.createBar(e,t)}createBorder(e){return this.createBar(e)}};function Js(e,t,n){new qs(e).createHeader(t,n)}function Ys(e,t,n){new qs(e).createRow(t,n)}function Xs(e,t){new qs(e).createBorder(t)}Ls();const Zs=Rs();zs();const Qs={DEBOUNCE_DELAY:100,MAX_TITLE_LENGTH:57,TRUNCATED_LENGTH:54,TASK_ID_PAD_START:3,TASK_ID_PAD_END:4,PRIORITY_PAD_END:3,VALID_PRIORITIES:[`high`,`medium`,`low`],DEFAULT_PRIORITY:`medium`};var $s=class{constructor(e=Qs.DEBOUNCE_DELAY){this.delay=e,this.pendingTimeout=null}debounce(e){this.clear(),this.pendingTimeout=setTimeout(()=>{e(),this.pendingTimeout=null},this.delay)}clear(){this.pendingTimeout&&=(clearTimeout(this.pendingTimeout),null)}hasPending(){return this.pendingTimeout!==null}},ec=class{constructor(){this.priorities={high:0,medium:0,low:0}}increment(e){let t=this.normalize(e);return this.priorities[t]++,t}normalize(e){let t=e?e.toLowerCase():Qs.DEFAULT_PRIORITY;return Qs.VALID_PRIORITIES.includes(t)?t:Qs.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},tc=class{static formatTitle(e,t){return e?e.length>Qs.MAX_TITLE_LENGTH?e.substring(0,Qs.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return Vs(e,!1).padEnd(Qs.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(Qs.TASK_ID_PAD_START,` `).padEnd(Qs.TASK_ID_PAD_END,` `)}},nc=class extends Ks{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new ec,this.debouncer=new $s,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${Zs.high} {high} ${Zs.medium} {medium} ${Zs.low} {low} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`Tasks {tasks} |{bar}| {percentage}%`}_getCustomTimeTokensPayload(){return this.priorityManager.getCounts()}addTaskLine(e,t,n=`medium`){if(!this.multibar||this.isFinished)return;this._ensureHeaderShown();let r=this._updateTaskCounters(e,n);this._updateTimeTokensBar(),this.debouncer.debounce(()=>{this._updateProgressDisplay(e,t,r)})}_ensureHeaderShown(){this.headerShown||(this.headerShown=!0,Js(this.multibar,` TASK | PRI | TITLE`,`------+-----+----------------------------------------------------------------`))}_updateTaskCounters(e,t){let n=this.priorityManager.increment(t);return this.completedUnits=e,n}_updateProgressDisplay(e,t,n){this.progressBar.update(this.completedUnits,{tasks:`${this.completedUnits}/${this.numUnits}`});let r=tc.formatTitle(t,e),i=tc.formatPriority(n),a=tc.formatTaskId(e);Ys(this.multibar,` ${a} | ${i} | {title}`,{title:r}),Xs(this.multibar,`------+-----+----------------------------------------------------------------`),this._updateTimeTokensBar()}finish(){this.debouncer.hasPending()&&(this.debouncer.clear(),this._updateTimeTokensBar()),this.cleanup(),super.finish()}_performCustomCleanup(){this.debouncer.clear()}getSummary(){return{...super.getSummary(),taskPriorities:this.priorityManager.getCounts(),actionVerb:this.append?`appended`:`generated`}}};function rc(e={}){return new nc(e)}async function ic(e,t,n){let r=ac(e,t,n);await sc(e,n,r.estimatedInputTokens);let i=await cc(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await lc(e,n),s=await uc(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(oc(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-BpfeMi5b.js`),{getUserId:n}=await import(`./config-manager-CgVZwH7E.js`),a=n(e.projectRoot);if(a&&i.providerName&&i.modelId)try{let n=await t({userId:a,commandName:`parse-prd`,providerName:i.providerName,modelId:i.modelId,inputTokens:s.usage.promptTokens||0,outputTokens:s.usage.completionTokens||0,outputType:e.isMCP?`mcp`:`cli`});n&&(i.telemetryData=n)}catch(e){r.logger.report(`Failed to log telemetry: ${e.message}`,`debug`)}}return bc(s,i,r.estimatedInputTokens,a)}function ac(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new Zo(e.mcpLog,e.reportProgress),estimatedInputTokens:ms(r+i),defaultPriority:me(e.projectRoot)||`medium`}}function oc(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function sc(e,t,n){e.reportProgress&&await e.reportProgress({progress:0,total:t,message:`Starting PRD analysis (Input: ${n} tokens)${e.research?` with research`:``}...`})}async function cc(e,n,r){let{systemPrompt:i,userPrompt:a}=n;return await Ko.withTimeout(t({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Yo,systemPrompt:i,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),r,`Streaming operation`)}async function lc(e,t){let n=Bs(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=rc({numUnits:t,unitName:`task`,append:e.append});let n=e.research?o():w(),i=f(e.research?`research`:`main`);os({prdFilePath:e.prdPath,outputPath:e.tasksPath,numTasks:t,append:e.append,research:e.research,force:e.force,existingTasks:[],nextId:1,model:n||`Default`,temperature:i?.temperature||.7}),r.start()}return{progressTracker:r,priorityMap:n}}async function uc(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:Yo},numTasks:r,progressTracker:i,priorityMap:a,defaultPriority:o,estimatedInputTokens:s,prompt:u,systemPrompt:l};try{let t={lastPartialObject:null,taskCount:0,estimatedOutputTokens:0,usage:null};if(await dc(e.partialObjectStream,t,d),e.usage)try{t.usage=await e.usage}catch(e){c.report(`Failed to get usage data: ${e.message}`,`debug`)}return hc(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await yc(d,c)}}async function dc(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=ms(JSON.stringify(r))),await fc(r,t,n)}async function fc(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await pc(e.tasks,t.taskCount,r,t.estimatedOutputTokens,n),t.taskCount=r):n.progressTracker&&t.estimatedOutputTokens>0&&n.progressTracker.updateTokens(n.estimatedInputTokens,t.estimatedOutputTokens,!0)}async function pc(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await Ss({task:t,currentCount:a+1,totalTasks:i.numTasks,estimatedTokens:r,progressTracker:i.progressTracker,reportProgress:i.config.reportProgress,priorityMap:i.priorityMap,defaultPriority:i.defaultPriority,estimatedInputTokens:i.estimatedInputTokens}):await mc(a+1,r,i)}}async function mc(e,t,n){let{progressTracker:r,config:i,numTasks:a,defaultPriority:o,estimatedInputTokens:s}=n;r&&(r.addTaskLine(e,`Generating task ${e}...`,o),r.updateTokens(s,t,!0)),i.reportProgress&&!r&&await i.reportProgress({progress:e,total:a,message:`Generating task ${e}/${a}...`})}async function hc(e,t){let{lastPartialObject:n,estimatedOutputTokens:r,taskCount:i,usage:a}=e;if(!n?.tasks||!Array.isArray(n.tasks))throw Error(`No tasks generated from streamObject`);let o=a?.completionTokens||r,s=a?.promptTokens||t.estimatedInputTokens;return t.progressTracker&&await gc(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function gc(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?_c(e,a,o):await vc(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function _c(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&t.addTaskLine(r+1,i.title,i.priority||n)}}async function vc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await Ss({task:i,currentCount:r+1,totalTasks:n.numTasks,estimatedTokens:t,progressTracker:n.progressTracker,reportProgress:n.config.reportProgress,priorityMap:n.priorityMap,defaultPriority:n.defaultPriority,estimatedInputTokens:n.estimatedInputTokens})}}async function yc(e,t){if(t.report(`Using generateObject fallback for PRD parsing`,`info`),e.progressTracker)for(let t=0;t<e.numTasks;t++)e.progressTracker.addTaskLine(t+1,`Generating task ${t+1}...`,e.defaultPriority),e.progressTracker.updateTokens(e.estimatedInputTokens,0,!0);let n=await i({role:e.config.research?`research`:`main`,commandName:`parse-prd`,prompt:e.prompt,systemPrompt:e.systemPrompt,schema:e.config.schema,outputFormat:e.config.outputFormat||`text`,projectRoot:e.config.projectRoot,session:e.config.session}),r=n?.mainResult||n;if(r&&Array.isArray(r.tasks)&&(r.tasks=r.tasks.map(e=>({...e,dependencies:e.dependencies??[],priority:e.priority??null,details:e.details??null,testStrategy:e.testStrategy??null}))),r&&Array.isArray(r.tasks)){if(e.progressTracker){for(let t=0;t<r.tasks.length;t++){let n=r.tasks[t];n&&n.title&&e.progressTracker.addTaskLine(t+1,n.title,n.priority||e.defaultPriority)}let t=n.telemetryData?.outputTokens||ms(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||ms(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function bc(e,t,n,r){let i=null;if(r&&(i=r.getSummary(),r.cleanup()),e.usage&&t){let n=e.usage;t.usage||={promptTokens:n.promptTokens||0,completionTokens:n.completionTokens||0,totalTokens:n.totalTokens||0}}return{parsedTasks:e.parsedTasks,aiServiceResponse:t,estimatedInputTokens:e.actualInputTokens||n,estimatedOutputTokens:e.estimatedOutputTokens,usedFallback:e.usedFallback,progressTracker:r,summary:i}}async function xc(e,t,n){let r=new Zo(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let{existingTasks:i,nextId:a}=gs(e.tasksPath,e.targetTag);_s({existingTasks:i,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let o=await t(e,await xs(e,hs(e.prdPath),a),e.numTasks),s=me(e.projectRoot)||`medium`,c=vs(o.parsedTasks,a,i,s),l=e.append?[...i,...c]:c;return bs(e.tasksPath,l,e.targetTag,r),await Sc(e,o,c,l,a,n),{success:!0,tasksPath:e.tasksPath,telemetryData:o.aiServiceResponse?.telemetryData,tagInfo:o.aiServiceResponse?.tagInfo}}catch(t){throw r.report(`Error parsing PRD: ${t.message}`,`error`),e.isMCP||(console.error(B.red(`Error: ${t.message}`)),ke(e.projectRoot)&&console.error(t)),t}}async function Sc(e,t,n,r,i,a){let{aiServiceResponse:o,estimatedInputTokens:s,estimatedOutputTokens:c}=t;if(e.reportProgress){let t=o?.telemetryData&&(o.telemetryData.inputTokens>0||o.telemetryData.outputTokens>0),n;if(t){let e=o.telemetryData.totalCost||0,t=o.telemetryData.currency||`USD`;n=`✅ Task Generation Completed | Tokens (I/O): ${o.telemetryData.inputTokens}/${o.telemetryData.outputTokens} | Cost: ${t===`USD`?`$`:t}${e.toFixed(4)}`}else n=`✅ Task Generation Completed | ~Tokens (I/O): ${s}/${a?c:`unknown`} | Cost: ~$0.00`;await e.reportProgress({progress:e.numTasks,total:e.numTasks,message:n})}e.outputFormat===`text`&&!e.isMCP&&(a&&t.summary?await Cs({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||ws({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function Cc(e,t,n,r={}){return xc(new Xo(e,t,n,r),ic,!0)}async function wc(e,t,n,r={}){return xc(new Xo(e,t,n,r),Ts,!1)}async function Tc(e,t,n,r={}){let i=new Xo(e,t,n,r);if(i.useStreaming)try{return await Cc(e,t,n,r)}catch(a){if(a instanceof Wo||a.code===Go.NOT_ASYNC_ITERABLE||a.code===Go.STREAM_PROCESSING_FAILED||a.code===Go.STREAM_NOT_ITERABLE||Ko.isTimeoutError(a)){let o=new Zo(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(B.yellow(`⚠️ Streaming operation ${a.message.includes(`timed out`)?`timed out`:`failed`}. Falling back to non-streaming mode...`)):o.report(`Streaming failed (${a.message}), falling back to non-streaming mode...`,`warn`),await wc(e,t,n,r)}else throw a}else return await wc(e,t,n,r)}var Ec=Tc;async function Dc(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{z(`info`,`Removing subtask ${t}...`);let r=E(e,a,o);if(!r||!r.tasks)throw Error(`Invalid or missing tasks file at ${e}`);if(!t.includes(`.`))throw Error(`Invalid subtask ID format: ${t}. Expected format: "parentId.subtaskId"`);let[i,s]=t.split(`.`),c=parseInt(i,10),l=parseInt(s,10),u=r.tasks.find(e=>e.id===c);if(!u)throw Error(`Parent task with ID ${c} not found`);if(!u.subtasks||u.subtasks.length===0)throw Error(`Parent task ${c} has no subtasks`);let d=u.subtasks.findIndex(e=>e.id===l);if(d===-1)throw Error(`Subtask ${t} not found`);let f={...u.subtasks[d]};u.subtasks.splice(d,1),u.subtasks.length===0&&(u.subtasks=void 0);let p=null;if(n){z(`info`,`Converting subtask ${t} to a standalone task...`);let e=Math.max(...r.tasks.map(e=>e.id))+1;p={id:e,title:f.title,description:f.description||``,details:f.details||``,status:f.status||`pending`,dependencies:f.dependencies||[],priority:u.priority||`medium`},p.dependencies.includes(c)||p.dependencies.push(c),r.tasks.push(p),z(`info`,`Created new task ${e} from subtask ${t}`)}else z(`info`,`Subtask ${t} deleted`);return y(e,r,a,o),p}catch(e){throw z(`error`,`Error removing subtask: ${e.message}`),e}}var Oc=Dc;function kc(e,t){if(typeof t==`string`&&t.includes(`.`)){let n=t.split(`.`);if(n.length!==2||!n[0]||!n[1]){let n=parseInt(t,10);return e.some(e=>e.id===n)}let[r,i]=n,a=parseInt(r,10),o=parseInt(i,10),s=e.find(e=>e.id===a);return s&&s.subtasks&&s.subtasks.some(e=>e.id===o)}let n=parseInt(t,10);return e.some(e=>e.id===n)}var Ac=kc;async function jc(e,t,n={}){let{projectRoot:r,tag:i}=n,a={success:!0,messages:[],errors:[],removedTasks:[]},o=t.split(`,`).map(e=>e.trim()).filter(Boolean);if(o.length===0)return a.success=!1,a.errors.push(`No valid task IDs provided.`),a;try{let t=E(e,r,i);if(!t)throw Error(`Could not read tasks file at ${e}`);let n=t._rawTaggedData||t;if(!n[i]||!n[i].tasks)throw Error(`Tag '${i}' not found or has no tasks.`);let s=n[i].tasks,c=[];for(let e of o){if(!Ac(s,e)){let t=`Task with ID ${e} in tag '${i}' not found or already removed.`;a.errors.push(t),a.success=!1;continue}try{if(typeof e==`string`&&e.includes(`.`)){let[t,n]=e.split(`.`).map(e=>parseInt(e,10)),r=s.find(e=>e.id===t);if(!r||!r.subtasks)throw Error(`Parent task ${t} or its subtasks not found for subtask ${e}`);let o=r.subtasks.findIndex(e=>e.id===n);if(o===-1)throw Error(`Subtask ${n} not found in parent task ${t}`);let c={...r.subtasks[o],parentTaskId:t};a.removedTasks.push(c),r.subtasks.splice(o,1),a.messages.push(`Successfully removed subtask ${e} from tag '${i}'`)}else{let t=parseInt(e,10),n=s.findIndex(e=>e.id===t);if(n===-1)throw Error(`Task with ID ${e} not found in tag '${i}'`);let r=s[n];a.removedTasks.push(r),c.push(t),s.splice(n,1),a.messages.push(`Successfully removed task ${e} from tag '${i}'`)}}catch(t){let n=`Error processing ID ${e}: ${t.message}`;a.errors.push(n),a.success=!1,z(`warn`,n)}}if(a.removedTasks.length>0){let t=new Set(o.map(e=>typeof e==`string`&&e.includes(`.`)?e:parseInt(e,10)));for(let e in n[i].tasks=s,n)Object.prototype.hasOwnProperty.call(n,e)&&n[e]&&n[e].tasks&&n[e].tasks.forEach(e=>{e.dependencies&&=e.dependencies.filter(e=>!t.has(e)),e.subtasks&&e.subtasks.forEach(n=>{n.dependencies&&=n.dependencies.filter(n=>!t.has(`${e.id}.${n}`)&&!t.has(n))})});y(e,n,r,i);for(let t of c){let n=H.join(H.dirname(e),`task_${t.toString().padStart(3,`0`)}.txt`);if(Ke.existsSync(n))try{Ke.unlinkSync(n),a.messages.push(`Deleted task file: ${n}`)}catch(e){let t=`Failed to delete task file ${n}: ${e.message}`;a.errors.push(t),a.success=!1,z(`warn`,t)}}}else a.errors.length===0&&a.messages.push(`No tasks found matching the provided IDs.`);let l=a.messages.join(`
871
871
  `),u=a.errors.join(`
872
- `);return{success:a.success,message:l||`No tasks were removed.`,error:u||null,removedTasks:a.removedTasks}}catch(e){return z(`error`,`Error removing tasks: ${e.message}`),{success:!1,message:``,error:`Operation failed: ${e.message}`,removedTasks:[]}}}var Ec=Tc;ot.use(st({code:e=>e.split(`
872
+ `);return{success:a.success,message:l||`No tasks were removed.`,error:u||null,removedTasks:a.removedTasks}}catch(e){return z(`error`,`Error removing tasks: ${e.message}`),{success:!1,message:``,error:`Operation failed: ${e.message}`,removedTasks:[]}}}var Mc=jc;ot.use(st({code:e=>e.split(`
873
873
  `).map(e=>` `+B.cyan(e)).join(`
874
- `),blockquote:B.gray.italic,html:B.gray,heading:B.white.bold,hr:B.gray,listitem:B.white,paragraph:B.white,strong:B.white.bold,em:B.white.italic,codespan:B.cyan,del:B.dim.strikethrough,link:B.blue,href:B.blue.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:100})),ot.setOptions({breaks:!0,gfm:!0});async function Dc(t,n={},i={},a=`text`,o=!0){let{taskIds:s=[],filePaths:c=[],customContext:l=``,includeProjectTree:u=!1,detailLevel:d=`medium`,projectRoot:f,tag:p,saveToFile:m=!1}=n,{session:h,mcpLog:g,commandName:_=`research`,outputType:v=`cli`}=i,y=!!g,b=f||ze();if(!b)throw Error(`Could not determine project root directory`);let x=y?g:{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};a===`text`&&console.log(W(B.cyan.bold(`🔍 AI Research Query`),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));try{let f=new ka(b,p),g=[...s],S=[];try{let e=await D(H.join(b,`.taskmaster`,`tasks`,`tasks.json`),b,p);if(e&&e.tasks&&e.tasks.length>0){let n=new La(Ne(e.tasks),`research`),r=n.findRelevantTasks(t,{maxResults:8,includeRecent:!0,includeCategoryMatches:!0});S=n.getTaskIds(r);let i=S.filter(e=>!g.includes(e));if(g=[...g,...i],a===`text`&&g.length>0){let e=g.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());if(s.length>0){let e=s.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());if(console.log(B.gray(`Provided tasks: `)+B.cyan(e.join(`, `))),i.length>0){let e=i.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());console.log(B.gray(`+ Auto-discovered related tasks: `)+B.cyan(e.join(`, `)))}}else console.log(B.gray(`Auto-discovered relevant tasks: `)+B.cyan(e.join(`, `)))}}}catch(e){x.debug(`Could not auto-discover tasks: ${e.message}`)}let C=await f.gather({tasks:g,files:c,customContext:l,includeProjectTree:u,format:`research`,includeTokenCounts:!0}),w=C.context,T=C.tokenBreakdown,E=Da(),O={query:t,gatheredContext:w||``,detailLevel:d,projectInfo:{root:b,taskCount:g.length,fileCount:c.length}},{systemPrompt:k,userPrompt:A}=await E.loadPrompt(`research`,O),j=f.countTokens(k),M=f.countTokens(A),N=j+M;a===`text`&&Oc(T,j,M),a!==`text`&&x.info(`Calling AI service with research role, context size: ${T.total} tokens (${w.length} characters)`);let P,ee=``;try{if(a===`text`){console.log(B.cyan(`
874
+ `),blockquote:B.gray.italic,html:B.gray,heading:B.white.bold,hr:B.gray,listitem:B.white,paragraph:B.white,strong:B.white.bold,em:B.white.italic,codespan:B.cyan,del:B.dim.strikethrough,link:B.blue,href:B.blue.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:100})),ot.setOptions({breaks:!0,gfm:!0});async function Nc(t,n={},i={},a=`text`,o=!0){let{taskIds:s=[],filePaths:c=[],customContext:l=``,includeProjectTree:u=!1,detailLevel:d=`medium`,projectRoot:f,tag:p,saveToFile:m=!1}=n,{session:h,mcpLog:g,commandName:_=`research`,outputType:v=`cli`}=i,y=!!g,b=f||Le();if(!b)throw Error(`Could not determine project root directory`);let x=y?g:{info:(...e)=>z(`info`,...e),warn:(...e)=>z(`warn`,...e),error:(...e)=>z(`error`,...e),debug:(...e)=>z(`debug`,...e),success:(...e)=>z(`success`,...e)};a===`text`&&console.log(W(B.cyan.bold(`🔍 AI Research Query`),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));try{let f=new Fa(b,p),g=[...s],S=[];try{let e=await E(H.join(b,`.taskmaster`,`tasks`,`tasks.json`),b,p);if(e&&e.tasks&&e.tasks.length>0){let n=new Ua(je(e.tasks),`research`),r=n.findRelevantTasks(t,{maxResults:8,includeRecent:!0,includeCategoryMatches:!0});S=n.getTaskIds(r);let i=S.filter(e=>!g.includes(e));if(g=[...g,...i],a===`text`&&g.length>0){let e=g.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());if(s.length>0){let e=s.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());if(console.log(B.gray(`Provided tasks: `)+B.cyan(e.join(`, `))),i.length>0){let e=i.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());console.log(B.gray(`+ Auto-discovered related tasks: `)+B.cyan(e.join(`, `)))}}else console.log(B.gray(`Auto-discovered relevant tasks: `)+B.cyan(e.join(`, `)))}}}catch(e){x.debug(`Could not auto-discover tasks: ${e.message}`)}let C=await f.gather({tasks:g,files:c,customContext:l,includeProjectTree:u,format:`research`,includeTokenCounts:!0}),w=C.context,T=C.tokenBreakdown,D=Na(),O={query:t,gatheredContext:w||``,detailLevel:d,projectInfo:{root:b,taskCount:g.length,fileCount:c.length}},{systemPrompt:k,userPrompt:A}=await D.loadPrompt(`research`,O),j=f.countTokens(k),M=f.countTokens(A),N=j+M;a===`text`&&Pc(T,j,M),a!==`text`&&x.info(`Calling AI service with research role, context size: ${T.total} tokens (${w.length} characters)`);let P,ee=``;try{if(a===`text`){console.log(B.cyan(`
875
875
  🔍 Researching with AI...
876
876
  `)),P=await e({role:`research`,session:h,projectRoot:b,systemPrompt:k,prompt:A,commandName:_,outputType:v,experimental_transform:tt({delayInMs:15,chunking:`word`})});for await(let e of P.mainResult.textStream){ee+=e;let t=``;for(let n=0;n<e.length;n++){if(e.slice(n).startsWith(`<think>`)){n+=6;continue}if(e.slice(n).startsWith(`</think>`)){n+=7;continue}t+=e[n]}t&&process.stdout.write(B.gray.dim(t))}if(console.log(`
877
877
  `),P.mainResult.usage){let e=await P.mainResult.usage,t=e.promptTokens||e.inputTokens||0,n=e.completionTokens||e.outputTokens||0,r=e.totalTokens||t+n;P.telemetryData={...P.telemetryData,inputTokens:t,outputTokens:n,totalTokens:r}}let n=process.stdout.columns||80,r=Math.min(n-4,120),i=W(B.green.bold(`Research Results`)+`
878
878
 
879
879
  `+B.gray(`Query: `)+B.white(t)+`
880
- `+B.gray(`Detail Level: `)+B.cyan(d),{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0},borderStyle:`round`,borderColor:`green`,width:r});console.log(i);let a=ee.replace(/<think>[\s\S]*?<\/think>/g,``).trim(),o=W((await ot.parse(a)).trim(),{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`white`,width:r});console.log(o)}else P=await r({role:`research`,session:h,projectRoot:b,systemPrompt:k,prompt:A,commandName:_,outputType:v}),ee=P.mainResult}catch(e){throw e}let te=P.telemetryData,ne=P.tagInfo,re={interactiveSaveOccurred:!1};if(a===`text`&&(te&&Sl(te,`cli`),o&&!y&&(re=await kc(n,i,a,b,x,t,ee))),m&&y){let e=await jc([{question:t,answer:ee,type:`initial`,timestamp:new Date().toISOString()}],b,i,x);return{query:t,result:ee,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:j,userPromptTokens:M,totalInputTokens:N,detailLevel:d,telemetryData:te,tagInfo:ne,savedFilePath:e,interactiveSaveOccurred:!1}}return x.success(`Research query completed successfully`),{query:t,result:ee,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:j,userPromptTokens:M,totalInputTokens:N,detailLevel:d,telemetryData:te,tagInfo:ne,interactiveSaveOccurred:re?.interactiveSaveOccurred||!1}}catch(e){throw x.error(`Research query failed: ${e.message}`),a===`text`&&console.error(B.red(`\n❌ Research failed: ${e.message}`)),e}}function Oc(e,t,n){let r=[];if(e.customContext&&r.push(B.cyan(`Custom: `)+B.yellow(e.customContext.tokens.toLocaleString())),e.tasks&&e.tasks.length>0){let t=e.tasks.reduce((e,t)=>e+t.tokens,0),n=e.tasks.map(e=>{let t=e.title.length>30?e.title.substring(0,30)+`...`:e.title;return` ${B.gray(e.id)} ${B.white(t)} ${B.yellow(e.tokens.toLocaleString())} tokens`}).join(`
880
+ `+B.gray(`Detail Level: `)+B.cyan(d),{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0},borderStyle:`round`,borderColor:`green`,width:r});console.log(i);let a=ee.replace(/<think>[\s\S]*?<\/think>/g,``).trim(),o=W((await ot.parse(a)).trim(),{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`white`,width:r});console.log(o)}else P=await r({role:`research`,session:h,projectRoot:b,systemPrompt:k,prompt:A,commandName:_,outputType:v}),ee=P.mainResult}catch(e){throw e}let te=P.telemetryData,ne=P.tagInfo,re={interactiveSaveOccurred:!1};if(a===`text`&&(te&&Ol(te,`cli`),o&&!y&&(re=await Fc(n,i,a,b,x,t,ee))),m&&y){let e=await Lc([{question:t,answer:ee,type:`initial`,timestamp:new Date().toISOString()}],b,i,x);return{query:t,result:ee,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:j,userPromptTokens:M,totalInputTokens:N,detailLevel:d,telemetryData:te,tagInfo:ne,savedFilePath:e,interactiveSaveOccurred:!1}}return x.success(`Research query completed successfully`),{query:t,result:ee,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:j,userPromptTokens:M,totalInputTokens:N,detailLevel:d,telemetryData:te,tagInfo:ne,interactiveSaveOccurred:re?.interactiveSaveOccurred||!1}}catch(e){throw x.error(`Research query failed: ${e.message}`),a===`text`&&console.error(B.red(`\n❌ Research failed: ${e.message}`)),e}}function Pc(e,t,n){let r=[];if(e.customContext&&r.push(B.cyan(`Custom: `)+B.yellow(e.customContext.tokens.toLocaleString())),e.tasks&&e.tasks.length>0){let t=e.tasks.reduce((e,t)=>e+t.tokens,0),n=e.tasks.map(e=>{let t=e.title.length>30?e.title.substring(0,30)+`...`:e.title;return` ${B.gray(e.id)} ${B.white(t)} ${B.yellow(e.tokens.toLocaleString())} tokens`}).join(`
881
881
  `);r.push(B.cyan(`Tasks: `)+B.yellow(t.toLocaleString())+B.gray(` (${e.tasks.length} items)`)+`
882
882
  `+n)}if(e.files&&e.files.length>0){let t=e.files.reduce((e,t)=>e+t.tokens,0),n=e.files.map(e=>{let t=e.path.length>40?`...`+e.path.substring(e.path.length-37):e.path;return` ${B.gray(t)} ${B.yellow(e.tokens.toLocaleString())} tokens ${B.gray(`(${e.sizeKB}KB)`)}`}).join(`
883
883
  `);r.push(B.cyan(`Files: `)+B.yellow(t.toLocaleString())+B.gray(` (${e.files.length} files)`)+`
@@ -885,9 +885,9 @@ ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(
885
885
  `);if(r.push(B.cyan(`Prompts: `)+B.yellow(i.toLocaleString())+B.gray(` (generated)`)+`
886
886
  `+a),r.length>0){let e=W(r.join(`
887
887
 
888
- `),{title:B.blue.bold(`Context Analysis`),titleAlignment:`left`,padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`blue`});console.log(e)}}async function kc(e,t,n,r,i,a,o){let s=!1;try{let{readJSON:c}=await import(`./utils-CtCI5DEr.js`);(await import(`./update-task-by-id-mhULzJWi.js`)).default;let{updateSubtaskById:l}=await import(`./update-subtask-by-id-OR7LPqsO.js`),u=[{question:a,answer:o,type:`initial`,timestamp:new Date().toISOString()}];for(;;){let{action:a}=await q.prompt([{type:`list`,name:`action`,message:`What would you like to do next?`,choices:[{name:`Ask a follow-up question`,value:`followup`},{name:`Save to file`,value:`savefile`},{name:`Save to task/subtask`,value:`save`},{name:`Quit`,value:`quit`}],pageSize:4}]);if(a===`quit`)break;if(a===`savefile`){await jc(u,r,t,i);continue}if(a===`save`){await Ac(u,r,t,i)&&(s=!0);continue}if(a===`followup`){let{followUpQuery:r}=await q.prompt([{type:`input`,name:`followUpQuery`,message:`Enter your follow-up question:`,validate:e=>!e||e.trim().length===0?`Please enter a valid question.`:!0}]);if(!r||r.trim().length===0)continue;console.log(`
888
+ `),{title:B.blue.bold(`Context Analysis`),titleAlignment:`left`,padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`blue`});console.log(e)}}async function Fc(e,t,n,r,i,a,o){let s=!1;try{let{readJSON:c}=await import(`./utils-Dr4DuQDO.js`);(await import(`./update-task-by-id-D_HOOs3f.js`)).default;let{updateSubtaskById:l}=await import(`./update-subtask-by-id-B5uMpDq6.js`),u=[{question:a,answer:o,type:`initial`,timestamp:new Date().toISOString()}];for(;;){let{action:a}=await q.prompt([{type:`list`,name:`action`,message:`What would you like to do next?`,choices:[{name:`Ask a follow-up question`,value:`followup`},{name:`Save to file`,value:`savefile`},{name:`Save to task/subtask`,value:`save`},{name:`Quit`,value:`quit`}],pageSize:4}]);if(a===`quit`)break;if(a===`savefile`){await Lc(u,r,t,i);continue}if(a===`save`){await Ic(u,r,t,i)&&(s=!0);continue}if(a===`followup`){let{followUpQuery:r}=await q.prompt([{type:`input`,name:`followUpQuery`,message:`Enter your follow-up question:`,validate:e=>!e||e.trim().length===0?`Please enter a valid question.`:!0}]);if(!r||r.trim().length===0)continue;console.log(`
889
889
  `+B.gray(`─`.repeat(60))+`
890
- `);let i=Pc(u),a={...e,taskIds:[],customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},o=await Dc(r.trim(),a,t,n,!1);u.push({question:r.trim(),answer:o.result,type:`followup`,timestamp:new Date().toISOString()})}}}catch(e){i.debug(`Follow-up questions not available: ${e.message}`)}return{interactiveSaveOccurred:s}}async function Ac(e,t,n,r){try{let{readJSON:r}=await import(`./utils-CtCI5DEr.js`),i=(await import(`./update-task-by-id-mhULzJWi.js`)).default,{updateSubtaskById:a}=await import(`./update-subtask-by-id-OR7LPqsO.js`),{taskId:o}=await q.prompt([{type:`input`,name:`taskId`,message:`Enter task ID (e.g., "15" for task or "15.2" for subtask):`,validate:e=>{if(!e||e.trim().length===0)return`Please enter a task ID.`;let t=e.trim();return/^\d+(\.\d+)?$/.test(t)?!0:`Invalid format. Use "15" for task or "15.2" for subtask.`}}]),s=o.trim(),c=Nc(e),l=s.includes(`.`),u=H.join(t,`.taskmaster`,`tasks`,`tasks.json`);if(!V.existsSync(u)){console.log(B.red(`❌ Tasks file not found. Please run task-master init first.`));return}let d=r(u,t,n.tag);if(!d||!d.tasks){console.log(B.red(`❌ No valid tasks found.`));return}if(l){let[e,t]=s.split(`.`).map(e=>parseInt(e,10)),r=d.tasks.find(t=>t.id===e);if(!r){console.log(B.red(`❌ Parent task ${e} not found.`));return}if(!r.subtasks||!r.subtasks.find(e=>e.id===t)){console.log(B.red(`❌ Subtask ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to subtask...`)),await a(u,s,c,!1,n,`text`),console.log(B.green(`✅ Research conversation saved to subtask ${s}`))}else{let e=parseInt(s,10);if(!d.tasks.find(t=>t.id===e)){console.log(B.red(`❌ Task ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to task...`)),await i(u,e,c,!1,n,`text`,!0),console.log(B.green(`✅ Research conversation saved to task ${s}`))}return!0}catch(e){return console.log(B.red(`❌ Error saving conversation: ${e.message}`)),r.error(`Error saving conversation: ${e.message}`),!1}}async function jc(e,t,n,r){try{let n=H.join(t,`.taskmaster`,`docs`,`research`);V.existsSync(n)||V.mkdirSync(n,{recursive:!0});let i=e[0]?.question||`research-query`,a=`${new Date().toISOString().split(`T`)[0]}_${i.toLowerCase().replace(/[^a-z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50).replace(/^-+|-+$/g,``)}.md`,o=H.join(n,a),s=Mc(e,i);V.writeFileSync(o,s,`utf8`);let c=H.relative(t,o);return console.log(B.green(`✅ Research saved to: ${B.cyan(c)}`)),r.success(`Research conversation saved to ${c}`),o}catch(e){throw console.log(B.red(`❌ Error saving research file: ${e.message}`)),r.error(`Error saving research file: ${e.message}`),e}}function Mc(e,t){let n=new Date().toISOString(),r=`---
890
+ `);let i=Bc(u),a={...e,taskIds:[],customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},o=await Nc(r.trim(),a,t,n,!1);u.push({question:r.trim(),answer:o.result,type:`followup`,timestamp:new Date().toISOString()})}}}catch(e){i.debug(`Follow-up questions not available: ${e.message}`)}return{interactiveSaveOccurred:s}}async function Ic(e,t,n,r){try{let{readJSON:r}=await import(`./utils-Dr4DuQDO.js`),i=(await import(`./update-task-by-id-D_HOOs3f.js`)).default,{updateSubtaskById:a}=await import(`./update-subtask-by-id-B5uMpDq6.js`),{taskId:o}=await q.prompt([{type:`input`,name:`taskId`,message:`Enter task ID (e.g., "15" for task or "15.2" for subtask):`,validate:e=>{if(!e||e.trim().length===0)return`Please enter a task ID.`;let t=e.trim();return/^\d+(\.\d+)?$/.test(t)?!0:`Invalid format. Use "15" for task or "15.2" for subtask.`}}]),s=o.trim(),c=zc(e),l=s.includes(`.`),u=H.join(t,`.taskmaster`,`tasks`,`tasks.json`);if(!V.existsSync(u)){console.log(B.red(`❌ Tasks file not found. Please run task-master init first.`));return}let d=r(u,t,n.tag);if(!d||!d.tasks){console.log(B.red(`❌ No valid tasks found.`));return}if(l){let[e,t]=s.split(`.`).map(e=>parseInt(e,10)),r=d.tasks.find(t=>t.id===e);if(!r){console.log(B.red(`❌ Parent task ${e} not found.`));return}if(!r.subtasks||!r.subtasks.find(e=>e.id===t)){console.log(B.red(`❌ Subtask ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to subtask...`)),await a(u,s,c,!1,n,`text`),console.log(B.green(`✅ Research conversation saved to subtask ${s}`))}else{let e=parseInt(s,10);if(!d.tasks.find(t=>t.id===e)){console.log(B.red(`❌ Task ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to task...`)),await i(u,e,c,!1,n,`text`,!0),console.log(B.green(`✅ Research conversation saved to task ${s}`))}return!0}catch(e){return console.log(B.red(`❌ Error saving conversation: ${e.message}`)),r.error(`Error saving conversation: ${e.message}`),!1}}async function Lc(e,t,n,r){try{let n=H.join(t,`.taskmaster`,`docs`,`research`);V.existsSync(n)||V.mkdirSync(n,{recursive:!0});let i=e[0]?.question||`research-query`,a=`${new Date().toISOString().split(`T`)[0]}_${i.toLowerCase().replace(/[^a-z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50).replace(/^-+|-+$/g,``)}.md`,o=H.join(n,a),s=Rc(e,i);V.writeFileSync(o,s,`utf8`);let c=H.relative(t,o);return console.log(B.green(`✅ Research saved to: ${B.cyan(c)}`)),r.success(`Research conversation saved to ${c}`),o}catch(e){throw console.log(B.red(`❌ Error saving research file: ${e.message}`)),r.error(`Error saving research file: ${e.message}`),e}}function Rc(e,t){let n=new Date().toISOString(),r=`---
891
891
  title: Research Session
892
892
  query: "${t}"
893
893
  date: ${new Date().toLocaleDateString()}
@@ -900,10 +900,10 @@ exchanges: ${e.length}
900
900
 
901
901
  `;return e.forEach((t,n)=>{t.type===`initial`?r+=`## Initial Query\n\n**Question:** ${t.question}\n\n**Response:**\n\n${t.answer}\n\n`:r+=`## Follow-up ${n}\n\n**Question:** ${t.question}\n\n**Response:**\n\n${t.answer}\n\n`,n<e.length-1&&(r+=`---
902
902
 
903
- `)}),r+=`\n---\n\n*Generated by Task Master Research Command* \n*Timestamp: ${n}*\n`,r}function Nc(e){new Date().toISOString();let t=`## Research Session - ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}\n\n`;return e.forEach((n,r)=>{n.type===`initial`?(t+=`**Initial Query:** ${n.question}\n\n`,t+=`**Response:** ${n.answer}\n\n`):(t+=`**Follow-up ${r}:** ${n.question}\n\n`,t+=`**Response:** ${n.answer}\n\n`),r<e.length-1&&(t+=`---
903
+ `)}),r+=`\n---\n\n*Generated by Task Master Research Command* \n*Timestamp: ${n}*\n`,r}function zc(e){new Date().toISOString();let t=`## Research Session - ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}\n\n`;return e.forEach((n,r)=>{n.type===`initial`?(t+=`**Initial Query:** ${n.question}\n\n`,t+=`**Response:** ${n.answer}\n\n`):(t+=`**Follow-up ${r}:** ${n.question}\n\n`,t+=`**Response:** ${n.answer}\n\n`),r<e.length-1&&(t+=`---
904
904
 
905
- `)}),t}function Pc(e){if(e.length===0)return``;let t=[`--- Conversation History ---`];return e.forEach((e,n)=>{let r=e.type===`initial`?`Initial Question`:`Follow-up ${n}`,i=e.type===`initial`?`Initial Answer`:`Answer ${n}`;t.push(`\n${r}: ${e.question}`),t.push(`${i}: ${e.answer}`)}),t.join(`
906
- `)}const Fc=[`light`,`regular`,`heavy`],Ic=[`done`,`in-progress`,`review`,`cancelled`,`deferred`,`blocked`],Lc=[`pending`];function Rc(e){return Fc.includes(e)}async function zc(e,t,n){let{projectRoot:r,tag:i,session:a}=n;try{let n={tasks:[e],metadata:{analyzedAt:new Date().toISOString()}},o=A(null,{projectRoot:r,tag:i},null);if(!o)return z(`warn`,`No complexity report found - cannot re-analyze complexity`),null;await za({file:t,output:o,id:e.id.toString(),projectRoot:r,tag:i,_filteredTasksData:n,_originalTaskCount:1},{session:a});let s=Ue(o);if(s){let t=de(s,e.id);if(t)return z(`info`,`Re-analyzed task ${e.id} complexity: ${t.complexityScore}/10`),t.complexityScore}return z(`warn`,`Could not find updated complexity analysis for task ${e.id}`),null}catch(e){return z(`error`,`Failed to re-analyze task complexity: ${e.message}`),null}}function Bc(e,t){let{projectRoot:n,tag:r}=t;try{let t=A(null,{projectRoot:n,tag:r},null);if(!t)return null;let i=Ue(t);if(!i)return null;let a=de(i,e);return a?a.complexityScore:null}catch(e){return z(`debug`,`Could not read current complexity score: ${e.message}`),null}}async function Vc(e,t,n,r,a=`regular`,o=null){let{projectRoot:s,tag:c,session:l}=n;if(!e.subtasks||!Array.isArray(e.subtasks)||e.subtasks.length===0)return{updatedTask:e,regenerated:!1,preserved:0,generated:0};let u=e.subtasks.filter(e=>Ic.includes(e.status)),d=e.subtasks.filter(e=>Lc.includes(e.status));if(d.length===0)return{updatedTask:e,regenerated:!1,preserved:u.length,generated:0};let f,p=u.length,m=d.length,h=o?Math.max(.5,o/10):1,g=o?` (original complexity: ${o}/10)`:``;if(r===`up`)if(a===`light`){let e=Math.max(5,p+Math.ceil(m*1.1));f=Math.ceil(e*(.8+.4*h))}else if(a===`regular`){let e=Math.max(6,p+Math.ceil(m*1.3));f=Math.ceil(e*(.8+.4*h))}else{let e=Math.max(8,p+Math.ceil(m*1.6));f=Math.ceil(e*(.8+.6*h))}else{let e=o>=8?.7:o>=6?.85:1;if(a===`light`){let t=Math.max(3,p+Math.ceil(m*.8));f=Math.ceil(t*e)}else if(a===`regular`){let t=Math.max(3,p+Math.ceil(m*.5));f=Math.ceil(t*e)}else{let e=o>=9?.3:o>=7?.5:.7,t=Math.max(2,p+Math.ceil(m*.25));f=Math.max(1,Math.ceil(t*e))}}z(`debug`,`Complexity-aware subtask calculation${g}: ${m} pending -> target ${f} total`),z(`debug`,`Complexity-aware calculation${g}: ${m} pending -> ${f} total subtasks (${a} ${r})`);let _=Math.max(1,f-p);try{let t=`Based on this updated task, generate ${_} NEW subtasks that reflect the ${r===`up`?`increased`:`decreased`} complexity level:
905
+ `)}),t}function Bc(e){if(e.length===0)return``;let t=[`--- Conversation History ---`];return e.forEach((e,n)=>{let r=e.type===`initial`?`Initial Question`:`Follow-up ${n}`,i=e.type===`initial`?`Initial Answer`:`Answer ${n}`;t.push(`\n${r}: ${e.question}`),t.push(`${i}: ${e.answer}`)}),t.join(`
906
+ `)}const Vc=[`light`,`regular`,`heavy`],Hc=[`done`,`in-progress`,`review`,`cancelled`,`deferred`,`blocked`],Uc=[`pending`];function Wc(e){return Vc.includes(e)}async function Gc(e,t,n){let{projectRoot:r,tag:i,session:a}=n;try{let n={tasks:[e],metadata:{analyzedAt:new Date().toISOString()}},o=k(null,{projectRoot:r,tag:i},null);if(!o)return z(`warn`,`No complexity report found - cannot re-analyze complexity`),null;await Ga({file:t,output:o,id:e.id.toString(),projectRoot:r,tag:i,_filteredTasksData:n,_originalTaskCount:1},{session:a});let s=He(o);if(s){let t=ue(s,e.id);if(t)return z(`info`,`Re-analyzed task ${e.id} complexity: ${t.complexityScore}/10`),t.complexityScore}return z(`warn`,`Could not find updated complexity analysis for task ${e.id}`),null}catch(e){return z(`error`,`Failed to re-analyze task complexity: ${e.message}`),null}}function Kc(e,t){let{projectRoot:n,tag:r}=t;try{let t=k(null,{projectRoot:n,tag:r},null);if(!t)return null;let i=He(t);if(!i)return null;let a=ue(i,e);return a?a.complexityScore:null}catch(e){return z(`debug`,`Could not read current complexity score: ${e.message}`),null}}async function qc(e,t,n,r,a=`regular`,o=null){let{projectRoot:s,tag:c,session:l}=n;if(!e.subtasks||!Array.isArray(e.subtasks)||e.subtasks.length===0)return{updatedTask:e,regenerated:!1,preserved:0,generated:0};let u=e.subtasks.filter(e=>Hc.includes(e.status)),d=e.subtasks.filter(e=>Uc.includes(e.status));if(d.length===0)return{updatedTask:e,regenerated:!1,preserved:u.length,generated:0};let f,p=u.length,m=d.length,h=o?Math.max(.5,o/10):1,g=o?` (original complexity: ${o}/10)`:``;if(r===`up`)if(a===`light`){let e=Math.max(5,p+Math.ceil(m*1.1));f=Math.ceil(e*(.8+.4*h))}else if(a===`regular`){let e=Math.max(6,p+Math.ceil(m*1.3));f=Math.ceil(e*(.8+.4*h))}else{let e=Math.max(8,p+Math.ceil(m*1.6));f=Math.ceil(e*(.8+.6*h))}else{let e=o>=8?.7:o>=6?.85:1;if(a===`light`){let t=Math.max(3,p+Math.ceil(m*.8));f=Math.ceil(t*e)}else if(a===`regular`){let t=Math.max(3,p+Math.ceil(m*.5));f=Math.ceil(t*e)}else{let e=o>=9?.3:o>=7?.5:.7,t=Math.max(2,p+Math.ceil(m*.25));f=Math.max(1,Math.ceil(t*e))}}z(`debug`,`Complexity-aware subtask calculation${g}: ${m} pending -> target ${f} total`),z(`debug`,`Complexity-aware calculation${g}: ${m} pending -> ${f} total subtasks (${a} ${r})`);let _=Math.max(1,f-p);try{let t=`Based on this updated task, generate ${_} NEW subtasks that reflect the ${r===`up`?`increased`:`decreased`} complexity level:
907
907
 
908
908
  **Task Title**: ${e.title}
909
909
  **Task Description**: ${e.description}
@@ -950,7 +950,7 @@ IMPORTANT:
950
950
  - The 'id' field must be a NUMBER, not a string!
951
951
  - Dependencies must be strings, not numbers!
952
952
 
953
- Ensure the JSON is valid and properly formatted.`,s=U.object({subtasks:U.array(U.object({id:U.int().positive(),title:U.string().min(5),description:U.string().min(10),dependencies:U.array(U.string()),details:U.string().min(20),status:U.string(),testStrategy:U.string()}))}),c=(await i({role:n.research?`research`:`main`,session:n.session,systemPrompt:`You are an expert project manager who creates task breakdowns that match complexity levels.`,prompt:t,schema:s,objectName:`subtask_regeneration`,commandName:n.commandName||`subtask-regen-${r}`,outputType:n.outputType||`cli`})).mainResult.subtasks||[];Hc(c);let l=c.map(e=>({...e,status:e.status||`pending`,testStrategy:e.testStrategy||``})),d=u.reduce((e,t)=>Math.max(e,t.id||0),0)+1,f=new Map,m=l.map(e=>{let t=e.id,n=d++;return f.set(t,n),{...e,id:n}}).map(t=>({...t,dependencies:(t.dependencies||[]).map(t=>{if(typeof t!=`string`||!t.startsWith(`${e.id}.`))return t;let[,n]=t.split(`.`),r=Number.parseInt(n,10),i=f.get(r);return i?`${e.id}.${i}`:t})}));return e.subtasks=[...u,...m],{updatedTask:e,regenerated:!0,preserved:u.length,generated:m.length}}catch(t){return z(`warn`,`Failed to regenerate subtasks for task ${e.id}: ${t.message}`),{updatedTask:e,regenerated:!1,preserved:u.length,generated:0,error:t.message}}}function Hc(e){if(!Array.isArray(e)||e.length===0)return;let t=e.map(e=>e.id);if(t.some(e=>!Number.isInteger(e)||e<1))throw Error(`Generated subtask ids must be positive integers`);let n=new Set(t);if(n.size!==t.length)throw Error(`Generated subtasks must have unique ids`);let r=[...n].sort((e,t)=>e-t);for(let e=0;e<r.length;e+=1)if(r[e]!==e+1)throw Error(`Generated subtask ids must be sequential starting from 1`)}function Uc(e,t,n,r){let i=t===`up`,a={light:i?`minor enhancements`:`slight simplifications`,regular:i?`moderate complexity increases`:`moderate simplifications`,heavy:i?`significant complexity additions`:`major simplifications`},o=`You are tasked with adjusting the complexity of a task.
953
+ Ensure the JSON is valid and properly formatted.`,s=U.object({subtasks:U.array(U.object({id:U.int().positive(),title:U.string().min(5),description:U.string().min(10),dependencies:U.array(U.string()),details:U.string().min(20),status:U.string(),testStrategy:U.string()}))}),c=(await i({role:n.research?`research`:`main`,session:n.session,systemPrompt:`You are an expert project manager who creates task breakdowns that match complexity levels.`,prompt:t,schema:s,objectName:`subtask_regeneration`,commandName:n.commandName||`subtask-regen-${r}`,outputType:n.outputType||`cli`})).mainResult.subtasks||[];Jc(c);let l=c.map(e=>({...e,status:e.status||`pending`,testStrategy:e.testStrategy||``})),d=u.reduce((e,t)=>Math.max(e,t.id||0),0)+1,f=new Map,m=l.map(e=>{let t=e.id,n=d++;return f.set(t,n),{...e,id:n}}).map(t=>({...t,dependencies:(t.dependencies||[]).map(t=>{if(typeof t!=`string`||!t.startsWith(`${e.id}.`))return t;let[,n]=t.split(`.`),r=Number.parseInt(n,10),i=f.get(r);return i?`${e.id}.${i}`:t})}));return e.subtasks=[...u,...m],{updatedTask:e,regenerated:!0,preserved:u.length,generated:m.length}}catch(t){return z(`warn`,`Failed to regenerate subtasks for task ${e.id}: ${t.message}`),{updatedTask:e,regenerated:!1,preserved:u.length,generated:0,error:t.message}}}function Jc(e){if(!Array.isArray(e)||e.length===0)return;let t=e.map(e=>e.id);if(t.some(e=>!Number.isInteger(e)||e<1))throw Error(`Generated subtask ids must be positive integers`);let n=new Set(t);if(n.size!==t.length)throw Error(`Generated subtasks must have unique ids`);let r=[...n].sort((e,t)=>e-t);for(let e=0;e<r.length;e+=1)if(r[e]!==e+1)throw Error(`Generated subtask ids must be sequential starting from 1`)}function Yc(e,t,n,r){let i=t===`up`,a={light:i?`minor enhancements`:`slight simplifications`,regular:i?`moderate complexity increases`:`moderate simplifications`,heavy:i?`significant complexity additions`:`major simplifications`},o=`You are tasked with adjusting the complexity of a task.
954
954
 
955
955
  CURRENT TASK:
956
956
  Title: ${e.title}
@@ -979,63 +979,63 @@ Return a JSON object with the updated task containing these fields:
979
979
  - testStrategy: Updated test strategy
980
980
  - priority: Task priority ('low', 'medium', or 'high')
981
981
 
982
- Ensure the JSON is valid and properly formatted.`,o}async function Wc(e,t,n,r,a){let o=Uc(e,t,n,r),s=U.object({title:U.string().min(1).describe(`Updated task title reflecting scope adjustment`),description:U.string().min(1).describe(`Updated task description with adjusted scope`),details:U.string().min(1).describe(`Updated implementation details with adjusted complexity`),testStrategy:U.string().min(1).describe(`Updated testing approach for the adjusted scope`),priority:U.enum([`low`,`medium`,`high`]).describe(`Task priority level`)}),c=await i({role:a.research?`research`:`main`,session:a.session,systemPrompt:`You are an expert software project manager who helps adjust task complexity while maintaining clarity and actionability.`,prompt:o,schema:s,objectName:`updated_task`,commandName:a.commandName||`scope-${t}`,outputType:a.outputType||`cli`}),l=c.mainResult,u={...l,priority:l.priority||e.priority||`medium`};return{updatedTask:{...e,...u},telemetryData:c.telemetryData}}async function Gc(e,t,n=`regular`,r=null,i={},a=`text`){if(!Rc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${Fc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=D(e,o,s),l=c?.tasks||[];for(let e of t)if(!wc(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=oe(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&z(`info`,`Scoping up task ${f}: ${t.title}`);let p=Bc(f,i);p&&a===`text`&&z(`info`,`Original complexity: ${p}/10`);let m=await Wc(t,`up`,n,r,i),h=await Vc(m.updatedTask,e,i,`up`,n,p);a===`text`&&h.regenerated&&z(`info`,`Regenerated ${h.generated} pending subtasks (preserved ${h.preserved} completed)`);let g=c.tasks.findIndex(e=>e.id===f);if(g!==-1&&(c.tasks[g]=h.updatedTask,u.push(h.updatedTask)),i.session&&p)try{y(e,c,o,s);let t=await zc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;z(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&z(`warn`,`Could not re-analyze complexity: ${e.message}`)}m.telemetryData&&(d?(d.inputTokens+=m.telemetryData.inputTokens||0,d.outputTokens+=m.telemetryData.outputTokens||0,d.totalTokens+=m.telemetryData.totalTokens||0,d.totalCost+=m.telemetryData.totalCost||0):d={...m.telemetryData})}return y(e,c,o,s),a===`text`&&z(`info`,`Successfully scoped up ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function Kc(e,t,n=`regular`,r=null,i={},a=`text`){if(!Rc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${Fc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=D(e,o,s),l=c?.tasks||[];for(let e of t)if(!wc(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=oe(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&z(`info`,`Scoping down task ${f}: ${t.title}`);let p=Bc(f,i);p&&a===`text`&&z(`info`,`Original complexity: ${p}/10`);let m=await Wc(t,`down`,n,r,i),h=await Vc(m.updatedTask,e,i,`down`,n,p);a===`text`&&h.regenerated&&z(`info`,`Regenerated ${h.generated} pending subtasks (preserved ${h.preserved} completed)`);let g=c.tasks.findIndex(e=>e.id===f);if(g!==-1&&(c.tasks[g]=h.updatedTask,u.push(h.updatedTask)),i.session&&p)try{y(e,c,o,s);let t=await zc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;z(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&z(`warn`,`Could not re-analyze complexity: ${e.message}`)}m.telemetryData&&(d?(d.inputTokens+=m.telemetryData.inputTokens||0,d.outputTokens+=m.telemetryData.outputTokens||0,d.totalTokens+=m.telemetryData.totalTokens||0,d.totalCost+=m.telemetryData.totalCost||0):d={...m.telemetryData})}return y(e,c,o,s),a===`text`&&z(`info`,`Successfully scoped down ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function qc(e,t,n,r,i=!0){if(!Ji(n))throw Error(`Error: Invalid status value: ${n}. Use one of: ${TASK_STATUS_OPTIONS.join(`, `)}`);if(t.includes(`.`)){let[e,a]=t.split(`.`).map(e=>parseInt(e,10)),o=r.tasks.find(t=>t.id===e);if(!o)throw Error(`Parent task ${e} not found`);if(!o.subtasks)throw Error(`Parent task ${e} has no subtasks`);let s=o.subtasks.find(e=>e.id===a);if(!s)throw Error(`Subtask ${a} not found in parent task ${e}`);let c=s.status||`pending`;s.status=n,z(`info`,`Updated subtask ${e}.${a} status from '${c}' to '${n}'`),(n.toLowerCase()===`done`||n.toLowerCase()===`completed`)&&o.subtasks.every(e=>e.status===`done`||e.status===`completed`)&&o.status!==`done`&&o.status!==`completed`&&i&&(console.log(B.yellow(`All subtasks of parent task ${e} are now marked as done.`)),console.log(B.yellow(`Consider updating the parent task status with: task-master set-status --id=${e} --status=done`)))}else{let e=parseInt(t,10),i=r.tasks.find(t=>t.id===e);if(!i)throw Error(`Task ${e} not found`);let a=i.status||`pending`;if(i.status=n,z(`info`,`Updated task ${e} status from '${a}' to '${n}'`),(n.toLowerCase()===`done`||n.toLowerCase()===`completed`)&&i.subtasks&&i.subtasks.length>0){let e=i.subtasks.filter(e=>e.status!==`done`&&e.status!==`completed`);e.length>0&&(z(`info`,`Also marking ${e.length} subtasks as '${n}'`),e.forEach(e=>{e.status=n}))}}}var Jc=qc;async function Yc(e,t,n,r={}){let{projectRoot:i,tag:a}=r;try{if(!Ji(n))throw Error(`Error: Invalid status value: ${n}. Use one of: ${qi.join(`, `)}`);let o=!!r?.mcpLog;o||console.log(W(B.white.bold(`Updating Task Status to: ${n}`),{padding:1,borderColor:`blue`,borderStyle:`round`})),z(`info`,`Reading tasks from ${e}...`);let s=D(e,i,a);if(s&&s._rawTaggedData&&(s=s._rawTaggedData),!s||!s[a]||!Array.isArray(s[a].tasks))throw Error(`Invalid tasks file or tag "${a}" not found at ${e}`);let c={tasks:s[a].tasks,tag:a,_rawTaggedData:s};if(!c||!c.tasks)throw Error(`No valid tasks found in ${e}`);let l=t.split(`,`).map(e=>e.trim()),u=[];for(let t of l){let r=`unknown`;if(t.includes(`.`)){let[e,n]=t.split(`.`).map(e=>parseInt(e,10)),i=c.tasks.find(t=>t.id===e);i?.subtasks&&(r=i.subtasks.find(e=>e.id===n)?.status||`pending`)}else{let e=parseInt(t,10);r=c.tasks.find(t=>t.id===e)?.status||`pending`}await Jc(e,t,n,c,!o),u.push({id:t,oldStatus:r,newStatus:n})}if(s[a].tasks=c.tasks,ae(s[a],{description:`Tasks for ${a} context`}),y(e,s,i,a),z(`info`,`Validating dependencies after status update...`),Pl(c.tasks),!o)for(let e of u){let{id:t,oldStatus:n,newStatus:r}=e;console.log(W(B.white.bold(`Successfully updated task ${t} status:`)+`
983
- From: ${B.yellow(n)}\nTo: ${B.green(r)}`,{padding:1,borderColor:`green`,borderStyle:`round`}))}return{success:!0,updatedTasks:u.map(({id:e,oldStatus:t,newStatus:n})=>({id:e,oldStatus:t,newStatus:n}))}}catch(e){if(z(`error`,`Error setting task status: ${e.message}`),!r?.mcpLog)console.error(B.red(`Error: ${e.message}`)),je(r?.session)&&console.error(e),process.exit(1);else throw e}}var Xc=Yc;async function Zc(e,t,n,i=!1,a={},o=a.mcpLog?`json`:`text`){let{session:c,mcpLog:l,projectRoot:u,tag:d,metadata:f}=a,p=l||z,m=!!l,h=(e,...t)=>{m?typeof p[e]==`function`?p[e](...t):p.info(...t):L()||p(e,...t)},g=null;try{if(h(`info`,`Updating subtask ${t} with prompt: "${n}"`),!t||typeof t!=`string`)throw Error(`Subtask ID cannot be empty.`);if((!n||typeof n!=`string`||n.trim()===``)&&!f)throw Error(`Prompt cannot be empty unless metadata is provided. Please provide context for the subtask update or metadata to merge.`);let a=u||ze();if(!a)throw Error(`Could not determine project root directory`);let l=await zr({taskId:t,prompt:n,projectRoot:a,tag:d,appendMode:!0,useResearch:i,metadata:f,isMCP:m,outputFormat:o,report:h});if(l)return{updatedSubtask:{id:t},telemetryData:l.telemetryData,tagInfo:l.tagInfo};if(!t.includes(`.`))throw Error(`Invalid subtask ID format: ${t}. In solo mode, subtask ID must be in format "parentId.subtaskId" (e.g., "5.2").`);if(!V.existsSync(e))throw Error(`Tasks file not found at path: ${e}`);let p=D(e,a,d);if(!p||!p.tasks)throw Error(`No valid tasks found in ${e}. The file may be corrupted or have an invalid format.`);let[v,b]=t.split(`.`),x=parseInt(v,10),S=parseInt(b,10);if(Number.isNaN(x)||x<=0||Number.isNaN(S)||S<=0)throw Error(`Invalid subtask ID format: ${t}. Both parent ID and subtask ID must be positive integers.`);let C=p.tasks.find(e=>e.id===x);if(!C)throw Error(`Parent task with ID ${x} not found. Please verify the task ID and try again.`);if(!C.subtasks||!Array.isArray(C.subtasks))throw Error(`Parent task ${x} has no subtasks.`);let w=C.subtasks.findIndex(e=>e.id===S);if(w===-1)throw Error(`Subtask with ID ${t} not found. Please verify the subtask ID and try again.`);let T=C.subtasks[w];if(f&&(!n||n.trim()===``))return h(`info`,`Metadata-only update for subtask ${t}`),T.metadata={...T.metadata||{},...f},C.subtasks[w]=T,y(e,p,a,d),h(`success`,`Successfully updated metadata for subtask ${t}`),{updatedSubtask:T,telemetryData:null,tagInfo:{tag:d}};let E=``;try{let e=new ka(a,d),r=new La(Ne(p.tasks),`update-subtask`),i=`${C.title} ${T.title} ${n}`,o=r.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=r.getTaskIds(o),c=[...new Set([t.toString(),...s])];c.length>0&&(E=(await e.gather({tasks:c,format:`research`})).context||``)}catch(e){h(`warn`,`Could not gather context: ${e.message}`)}if(o===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`)],colWidths:[10,55,10]});e.push([t,s(T.title,52),dl(T.status)]),console.log(W(B.white.bold(`Updating Subtask #${t}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),g=sl(i?`Updating subtask with research...`:`Updating subtask...`)}let O=``,k=``,A=null;try{let e={id:C.id,title:C.title},t=w>0?{id:`${C.id}.${C.subtasks[w-1].id}`,title:C.subtasks[w-1].title,status:C.subtasks[w-1].status}:void 0,s=w<C.subtasks.length-1?{id:`${C.id}.${C.subtasks[w+1].id}`,title:C.subtasks[w+1].title,status:C.subtasks[w+1].status}:void 0,l=Da(),u={parentTask:e,prevSubtask:t,nextSubtask:s,currentDetails:T.details||`(No existing details)`,updatePrompt:n,useResearch:i,gatheredContext:E||``,hasCodebaseAnalysis:_(i,a,c),projectRoot:a},d=i?`research`:`default`,{systemPrompt:f,userPrompt:p}=await l.loadPrompt(`update-subtask`,u,d),v=i?`research`:`main`;h(`info`,`Using AI text service with role: ${v}`),A=await r({prompt:p,systemPrompt:f,role:v,session:c,projectRoot:a,maxRetries:2,commandName:`update-subtask`,outputType:m?`mcp`:`cli`}),A&&A.mainResult&&typeof A.mainResult==`string`?O=A.mainResult:(O=``,h(`warn`,`AI service response did not contain expected text string.`)),o===`text`&&g&&($(g),g=null)}catch(e){throw h(`error`,`AI service call failed: ${e.message}`),o===`text`&&g&&($(g),g=null),e}if(O&&O.trim()){let e=new Date().toISOString(),t=`<info added on ${e}>\n${O.trim()}\n</info added on ${e}>`;k=t,T.details=(T.details?T.details+`
984
- `:``)+t}else h(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),k=`No new details were added by the AI.`;let j=C.subtasks[w];return f&&(j.metadata={...j.metadata||{},...f}),o===`text`&&je(c)&&console.log(`>>> DEBUG: Subtask details AFTER AI update:`,j.details),j.description&&n.length<100&&(o===`text`&&je(c)&&console.log(`>>> DEBUG: Subtask description BEFORE append:`,j.description),j.description+=` [Updated: ${new Date().toLocaleDateString()}]`,o===`text`&&je(c)&&console.log(`>>> DEBUG: Subtask description AFTER append:`,j.description)),o===`text`&&je(c)&&console.log(`>>> DEBUG: About to call writeJSON with updated data...`),y(e,p,a,d),o===`text`&&je(c)&&console.log(`>>> DEBUG: writeJSON call completed.`),h(`success`,`Successfully updated subtask ${t}`),o===`text`&&(g&&=($(g),null),console.log(W(B.green(`Successfully updated subtask #${t}`)+`
982
+ Ensure the JSON is valid and properly formatted.`,o}async function Xc(e,t,n,r,a){let o=Yc(e,t,n,r),s=U.object({title:U.string().min(1).describe(`Updated task title reflecting scope adjustment`),description:U.string().min(1).describe(`Updated task description with adjusted scope`),details:U.string().min(1).describe(`Updated implementation details with adjusted complexity`),testStrategy:U.string().min(1).describe(`Updated testing approach for the adjusted scope`),priority:U.enum([`low`,`medium`,`high`]).describe(`Task priority level`)}),c=await i({role:a.research?`research`:`main`,session:a.session,systemPrompt:`You are an expert software project manager who helps adjust task complexity while maintaining clarity and actionability.`,prompt:o,schema:s,objectName:`updated_task`,commandName:a.commandName||`scope-${t}`,outputType:a.outputType||`cli`}),l=c.mainResult,u={...l,priority:l.priority||e.priority||`medium`};return{updatedTask:{...e,...u},telemetryData:c.telemetryData}}async function Zc(e,t,n=`regular`,r=null,i={},a=`text`){if(!Wc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${Vc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=E(e,o,s),l=c?.tasks||[];for(let e of t)if(!Ac(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=F(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&z(`info`,`Scoping up task ${f}: ${t.title}`);let p=Kc(f,i);p&&a===`text`&&z(`info`,`Original complexity: ${p}/10`);let m=await Xc(t,`up`,n,r,i),h=await qc(m.updatedTask,e,i,`up`,n,p);a===`text`&&h.regenerated&&z(`info`,`Regenerated ${h.generated} pending subtasks (preserved ${h.preserved} completed)`);let g=c.tasks.findIndex(e=>e.id===f);if(g!==-1&&(c.tasks[g]=h.updatedTask,u.push(h.updatedTask)),i.session&&p)try{y(e,c,o,s);let t=await Gc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;z(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&z(`warn`,`Could not re-analyze complexity: ${e.message}`)}m.telemetryData&&(d?(d.inputTokens+=m.telemetryData.inputTokens||0,d.outputTokens+=m.telemetryData.outputTokens||0,d.totalTokens+=m.telemetryData.totalTokens||0,d.totalCost+=m.telemetryData.totalCost||0):d={...m.telemetryData})}return y(e,c,o,s),a===`text`&&z(`info`,`Successfully scoped up ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function Qc(e,t,n=`regular`,r=null,i={},a=`text`){if(!Wc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${Vc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=E(e,o,s),l=c?.tasks||[];for(let e of t)if(!Ac(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=F(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&z(`info`,`Scoping down task ${f}: ${t.title}`);let p=Kc(f,i);p&&a===`text`&&z(`info`,`Original complexity: ${p}/10`);let m=await Xc(t,`down`,n,r,i),h=await qc(m.updatedTask,e,i,`down`,n,p);a===`text`&&h.regenerated&&z(`info`,`Regenerated ${h.generated} pending subtasks (preserved ${h.preserved} completed)`);let g=c.tasks.findIndex(e=>e.id===f);if(g!==-1&&(c.tasks[g]=h.updatedTask,u.push(h.updatedTask)),i.session&&p)try{y(e,c,o,s);let t=await Gc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;z(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&z(`warn`,`Could not re-analyze complexity: ${e.message}`)}m.telemetryData&&(d?(d.inputTokens+=m.telemetryData.inputTokens||0,d.outputTokens+=m.telemetryData.outputTokens||0,d.totalTokens+=m.telemetryData.totalTokens||0,d.totalCost+=m.telemetryData.totalCost||0):d={...m.telemetryData})}return y(e,c,o,s),a===`text`&&z(`info`,`Successfully scoped down ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function $c(e,t,n,r,i=!0){if(!Xi(n))throw Error(`Error: Invalid status value: ${n}. Use one of: ${TASK_STATUS_OPTIONS.join(`, `)}`);if(t.includes(`.`)){let[e,a]=t.split(`.`).map(e=>parseInt(e,10)),o=r.tasks.find(t=>t.id===e);if(!o)throw Error(`Parent task ${e} not found`);if(!o.subtasks)throw Error(`Parent task ${e} has no subtasks`);let s=o.subtasks.find(e=>e.id===a);if(!s)throw Error(`Subtask ${a} not found in parent task ${e}`);let c=s.status||`pending`;s.status=n,z(`info`,`Updated subtask ${e}.${a} status from '${c}' to '${n}'`),(n.toLowerCase()===`done`||n.toLowerCase()===`completed`)&&o.subtasks.every(e=>e.status===`done`||e.status===`completed`)&&o.status!==`done`&&o.status!==`completed`&&i&&(console.log(B.yellow(`All subtasks of parent task ${e} are now marked as done.`)),console.log(B.yellow(`Consider updating the parent task status with: task-master set-status --id=${e} --status=done`)))}else{let e=parseInt(t,10),i=r.tasks.find(t=>t.id===e);if(!i)throw Error(`Task ${e} not found`);let a=i.status||`pending`;if(i.status=n,z(`info`,`Updated task ${e} status from '${a}' to '${n}'`),(n.toLowerCase()===`done`||n.toLowerCase()===`completed`)&&i.subtasks&&i.subtasks.length>0){let e=i.subtasks.filter(e=>e.status!==`done`&&e.status!==`completed`);e.length>0&&(z(`info`,`Also marking ${e.length} subtasks as '${n}'`),e.forEach(e=>{e.status=n}))}}}var el=$c;async function tl(e,t,n,r={}){let{projectRoot:i,tag:a}=r;try{if(!Xi(n))throw Error(`Error: Invalid status value: ${n}. Use one of: ${Yi.join(`, `)}`);let o=!!r?.mcpLog;o||console.log(W(B.white.bold(`Updating Task Status to: ${n}`),{padding:1,borderColor:`blue`,borderStyle:`round`})),z(`info`,`Reading tasks from ${e}...`);let s=E(e,i,a);if(s&&s._rawTaggedData&&(s=s._rawTaggedData),!s||!s[a]||!Array.isArray(s[a].tasks))throw Error(`Invalid tasks file or tag "${a}" not found at ${e}`);let c={tasks:s[a].tasks,tag:a,_rawTaggedData:s};if(!c||!c.tasks)throw Error(`No valid tasks found in ${e}`);let l=t.split(`,`).map(e=>e.trim()),u=[];for(let t of l){let r=`unknown`;if(t.includes(`.`)){let[e,n]=t.split(`.`).map(e=>parseInt(e,10)),i=c.tasks.find(t=>t.id===e);i?.subtasks&&(r=i.subtasks.find(e=>e.id===n)?.status||`pending`)}else{let e=parseInt(t,10);r=c.tasks.find(t=>t.id===e)?.status||`pending`}await el(e,t,n,c,!o),u.push({id:t,oldStatus:r,newStatus:n})}if(s[a].tasks=c.tasks,ie(s[a],{description:`Tasks for ${a} context`}),y(e,s,i,a),z(`info`,`Validating dependencies after status update...`),Bl(c.tasks),!o)for(let e of u){let{id:t,oldStatus:n,newStatus:r}=e;console.log(W(B.white.bold(`Successfully updated task ${t} status:`)+`
983
+ From: ${B.yellow(n)}\nTo: ${B.green(r)}`,{padding:1,borderColor:`green`,borderStyle:`round`}))}return{success:!0,updatedTasks:u.map(({id:e,oldStatus:t,newStatus:n})=>({id:e,oldStatus:t,newStatus:n}))}}catch(e){if(z(`error`,`Error setting task status: ${e.message}`),!r?.mcpLog)console.error(B.red(`Error: ${e.message}`)),ke(r?.session)&&console.error(e),process.exit(1);else throw e}}var nl=tl;async function rl(e,t,n,i=!1,a={},o=a.mcpLog?`json`:`text`){let{session:c,mcpLog:l,projectRoot:u,tag:d,metadata:f}=a,p=l||z,m=!!l,h=(e,...t)=>{m?typeof p[e]==`function`?p[e](...t):p.info(...t):L()||p(e,...t)},g=null;try{if(h(`info`,`Updating subtask ${t} with prompt: "${n}"`),!t||typeof t!=`string`)throw Error(`Subtask ID cannot be empty.`);if((!n||typeof n!=`string`||n.trim()===``)&&!f)throw Error(`Prompt cannot be empty unless metadata is provided. Please provide context for the subtask update or metadata to merge.`);let a=u||Le();if(!a)throw Error(`Could not determine project root directory`);let l=await Vr({taskId:t,prompt:n,projectRoot:a,tag:d,appendMode:!0,useResearch:i,metadata:f,isMCP:m,outputFormat:o,report:h});if(l)return{updatedSubtask:{id:t},telemetryData:l.telemetryData,tagInfo:l.tagInfo};if(!t.includes(`.`))throw Error(`Invalid subtask ID format: ${t}. In solo mode, subtask ID must be in format "parentId.subtaskId" (e.g., "5.2").`);if(!V.existsSync(e))throw Error(`Tasks file not found at path: ${e}`);let p=E(e,a,d);if(!p||!p.tasks)throw Error(`No valid tasks found in ${e}. The file may be corrupted or have an invalid format.`);let[v,b]=t.split(`.`),x=parseInt(v,10),S=parseInt(b,10);if(Number.isNaN(x)||x<=0||Number.isNaN(S)||S<=0)throw Error(`Invalid subtask ID format: ${t}. Both parent ID and subtask ID must be positive integers.`);let C=p.tasks.find(e=>e.id===x);if(!C)throw Error(`Parent task with ID ${x} not found. Please verify the task ID and try again.`);if(!C.subtasks||!Array.isArray(C.subtasks))throw Error(`Parent task ${x} has no subtasks.`);let w=C.subtasks.findIndex(e=>e.id===S);if(w===-1)throw Error(`Subtask with ID ${t} not found. Please verify the subtask ID and try again.`);let T=C.subtasks[w];if(f&&(!n||n.trim()===``))return h(`info`,`Metadata-only update for subtask ${t}`),T.metadata={...T.metadata||{},...f},C.subtasks[w]=T,y(e,p,a,d),h(`success`,`Successfully updated metadata for subtask ${t}`),{updatedSubtask:T,telemetryData:null,tagInfo:{tag:d}};let D=``;try{let e=new Fa(a,d),r=new Ua(je(p.tasks),`update-subtask`),i=`${C.title} ${T.title} ${n}`,o=r.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=r.getTaskIds(o),c=[...new Set([t.toString(),...s])];c.length>0&&(D=(await e.gather({tasks:c,format:`research`})).context||``)}catch(e){h(`warn`,`Could not gather context: ${e.message}`)}if(o===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`)],colWidths:[10,55,10]});e.push([t,s(T.title,52),_l(T.status)]),console.log(W(B.white.bold(`Updating Subtask #${t}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),g=pl(i?`Updating subtask with research...`:`Updating subtask...`)}let O=``,k=``,A=null;try{let e={id:C.id,title:C.title},t=w>0?{id:`${C.id}.${C.subtasks[w-1].id}`,title:C.subtasks[w-1].title,status:C.subtasks[w-1].status}:void 0,s=w<C.subtasks.length-1?{id:`${C.id}.${C.subtasks[w+1].id}`,title:C.subtasks[w+1].title,status:C.subtasks[w+1].status}:void 0,l=Na(),u={parentTask:e,prevSubtask:t,nextSubtask:s,currentDetails:T.details||`(No existing details)`,updatePrompt:n,useResearch:i,gatheredContext:D||``,hasCodebaseAnalysis:_(i,a,c),projectRoot:a},d=i?`research`:`default`,{systemPrompt:f,userPrompt:p}=await l.loadPrompt(`update-subtask`,u,d),v=i?`research`:`main`;h(`info`,`Using AI text service with role: ${v}`),A=await r({prompt:p,systemPrompt:f,role:v,session:c,projectRoot:a,maxRetries:2,commandName:`update-subtask`,outputType:m?`mcp`:`cli`}),A&&A.mainResult&&typeof A.mainResult==`string`?O=A.mainResult:(O=``,h(`warn`,`AI service response did not contain expected text string.`)),o===`text`&&g&&($(g),g=null)}catch(e){throw h(`error`,`AI service call failed: ${e.message}`),o===`text`&&g&&($(g),g=null),e}if(O&&O.trim()){let e=new Date().toISOString(),t=`<info added on ${e}>\n${O.trim()}\n</info added on ${e}>`;k=t,T.details=(T.details?T.details+`
984
+ `:``)+t}else h(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),k=`No new details were added by the AI.`;let j=C.subtasks[w];return f&&(j.metadata={...j.metadata||{},...f}),o===`text`&&ke(c)&&console.log(`>>> DEBUG: Subtask details AFTER AI update:`,j.details),j.description&&n.length<100&&(o===`text`&&ke(c)&&console.log(`>>> DEBUG: Subtask description BEFORE append:`,j.description),j.description+=` [Updated: ${new Date().toLocaleDateString()}]`,o===`text`&&ke(c)&&console.log(`>>> DEBUG: Subtask description AFTER append:`,j.description)),o===`text`&&ke(c)&&console.log(`>>> DEBUG: About to call writeJSON with updated data...`),y(e,p,a,d),o===`text`&&ke(c)&&console.log(`>>> DEBUG: writeJSON call completed.`),h(`success`,`Successfully updated subtask ${t}`),o===`text`&&(g&&=($(g),null),console.log(W(B.green(`Successfully updated subtask #${t}`)+`
985
985
 
986
986
  `+B.white.bold(`Title:`)+` `+j.title+`
987
987
 
988
988
  `+B.white.bold(`Newly Added Snippet:`)+`
989
- `+B.white(k),{padding:1,borderColor:`green`,borderStyle:`round`}))),o===`text`&&A.telemetryData&&Sl(A.telemetryData,`cli`),{updatedSubtask:j,telemetryData:A.telemetryData,tagInfo:A.tagInfo}}catch(e){if(o===`text`&&g&&($(g),g=null),h(`error`,`Error updating subtask: ${e.message}`),o===`text`)console.error(B.red(`Error: ${e.message}`)),e.message?.includes(`ANTHROPIC_API_KEY`)?(console.log(B.yellow(`
989
+ `+B.white(k),{padding:1,borderColor:`green`,borderStyle:`round`}))),o===`text`&&A.telemetryData&&Ol(A.telemetryData,`cli`),{updatedSubtask:j,telemetryData:A.telemetryData,tagInfo:A.tagInfo}}catch(e){if(o===`text`&&g&&($(g),g=null),h(`error`,`Error updating subtask: ${e.message}`),o===`text`)console.error(B.red(`Error: ${e.message}`)),e.message?.includes(`ANTHROPIC_API_KEY`)?(console.log(B.yellow(`
990
990
  To fix this issue, set your Anthropic API key:`)),console.log(` export ANTHROPIC_API_KEY=your_api_key_here`)):e.message?.includes(`PERPLEXITY_API_KEY`)?(console.log(B.yellow(`
991
991
  To fix this issue:`)),console.log(` 1. Set your Perplexity API key: export PERPLEXITY_API_KEY=your_api_key_here`),console.log(` 2. Or run without the research flag: task-master update-subtask --id=<id> --prompt="..."`)):e.message?.includes(`overloaded`)?(console.log(B.yellow(`
992
992
  AI model overloaded, and fallback failed or was unavailable:`)),console.log(` 1. Try again in a few minutes.`),console.log(` 2. Ensure PERPLEXITY_API_KEY is set for fallback.`)):e.message?.includes(`not found`)?(console.log(B.yellow(`
993
993
  To fix this issue:`)),console.log(` 1. Run task-master list --with-subtasks to see all available subtask IDs`),console.log(` 2. Use a valid subtask ID with the --id parameter in format "parentId.subtaskId"`)):(e.message?.includes(`empty stream response`)||e.message?.includes(`AI did not return a valid text string`))&&console.log(B.yellow(`
994
- The AI model returned an empty or invalid response. This might be due to the prompt or API issues. Try rephrasing or trying again later.`)),je(c)&&console.error(e);else throw e;return null}}var Qc=Zc;async function $c(e,t,n,a=!1,o={},c=`text`,l=!1){let{session:u,mcpLog:d,projectRoot:f,tag:p,metadata:m}=o,{report:h,isMCP:g}=Ha(d,u);try{if(h(`info`,`Updating single task ${t} with prompt: "${n}"`),t==null||String(t).trim()===``)throw Error(`Task ID cannot be empty.`);if((!n||typeof n!=`string`||n.trim()===``)&&!m)throw Error(`Prompt cannot be empty unless metadata is provided for update.`);let o=f||ze();if(!o)throw Error(`Could not determine project root directory`);a&&!C(`perplexity`,u)&&(h(`warn`,`Perplexity research requested but API key not set. Falling back.`),c===`text`&&console.log(B.yellow(`Perplexity AI not available. Falling back to main AI.`)),a=!1);let d=await zr({taskId:t,prompt:n,projectRoot:o,tag:p,appendMode:l,useResearch:a,metadata:m,isMCP:g,outputFormat:c,report:h});if(d)return d;if(!V.existsSync(e))throw Error(`Tasks file not found: ${e}`);let v=D(e,o,p);if(!v||!v.tasks)throw Error(`No valid tasks found in ${e}.`);let b=String(t).trim();if(!/^\d+$/.test(b))throw Error(`For file storage, taskId must be a positive integer. Use update-subtask-by-id for IDs like "1.2", or run in API storage for display IDs (e.g., "HAM-123").`);let x=Number(b),S=v.tasks.findIndex(e=>e.id===x);if(S===-1)throw h(`error`,`Task with ID ${x} not found`),Error(`Task with ID ${x} not found.`);let w=v.tasks[S];if(w.status===`done`||w.status===`completed`)return h(`warn`,`Task ${t} is already marked as done and cannot be updated`),c===`text`&&console.log(W(B.yellow(`Task ${t} is already marked as ${w.status} and cannot be updated.`)+`
994
+ The AI model returned an empty or invalid response. This might be due to the prompt or API issues. Try rephrasing or trying again later.`)),ke(c)&&console.error(e);else throw e;return null}}var il=rl;async function al(e,t,n,a=!1,o={},c=`text`,l=!1){let{session:u,mcpLog:d,projectRoot:f,tag:p,metadata:m}=o,{report:h,isMCP:g}=Ja(d,u);try{if(h(`info`,`Updating single task ${t} with prompt: "${n}"`),t==null||String(t).trim()===``)throw Error(`Task ID cannot be empty.`);if((!n||typeof n!=`string`||n.trim()===``)&&!m)throw Error(`Prompt cannot be empty unless metadata is provided for update.`);let o=f||Le();if(!o)throw Error(`Could not determine project root directory`);a&&!S(`perplexity`,u)&&(h(`warn`,`Perplexity research requested but API key not set. Falling back.`),c===`text`&&console.log(B.yellow(`Perplexity AI not available. Falling back to main AI.`)),a=!1);let d=await Vr({taskId:t,prompt:n,projectRoot:o,tag:p,appendMode:l,useResearch:a,metadata:m,isMCP:g,outputFormat:c,report:h});if(d)return d;if(!V.existsSync(e))throw Error(`Tasks file not found: ${e}`);let v=E(e,o,p);if(!v||!v.tasks)throw Error(`No valid tasks found in ${e}.`);let b=String(t).trim();if(!/^\d+$/.test(b))throw Error(`For file storage, taskId must be a positive integer. Use update-subtask-by-id for IDs like "1.2", or run in API storage for display IDs (e.g., "HAM-123").`);let x=Number(b),C=v.tasks.findIndex(e=>e.id===x);if(C===-1)throw h(`error`,`Task with ID ${x} not found`),Error(`Task with ID ${x} not found.`);let w=v.tasks[C];if(w.status===`done`||w.status===`completed`)return h(`warn`,`Task ${t} is already marked as done and cannot be updated`),c===`text`&&console.log(W(B.yellow(`Task ${t} is already marked as ${w.status} and cannot be updated.`)+`
995
995
 
996
996
  `+B.white(`Completed tasks are locked to maintain consistency. To modify a completed task, you must first:`)+`
997
997
  `+B.white(`1. Change its status to "pending" or "in-progress"`)+`
998
- `+B.white(`2. Then run the update-task command`),{padding:1,borderColor:`yellow`,borderStyle:`round`})),null;if(m&&(!n||n.trim()===``))return h(`info`,`Metadata-only update for task ${t}`),w.metadata={...w.metadata||{},...m},v.tasks[S]=w,y(e,v,o,p),h(`success`,`Successfully updated metadata for task ${t}`),{updatedTask:w,telemetryData:null,tagInfo:{tag:p}};let T=``;try{let e=new ka(o,p),r=new La(Ne(v.tasks),`update-task`),i=`${w.title} ${w.description} ${n}`,a=r.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=r.getTaskIds(a),c=[...new Set([t.toString(),...s])];c.length>0&&(T=(await e.gather({tasks:c,format:`research`})).context||``)}catch(e){h(`warn`,`Could not gather context: ${e.message}`)}if(c===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`)],colWidths:[5,60,10]});e.push([w.id,s(w.title,57),dl(w.status)]),console.log(W(B.white.bold(`Updating Task #${t}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(W(B.cyan.bold(`How Completed Subtasks Are Handled:`)+`
998
+ `+B.white(`2. Then run the update-task command`),{padding:1,borderColor:`yellow`,borderStyle:`round`})),null;if(m&&(!n||n.trim()===``))return h(`info`,`Metadata-only update for task ${t}`),w.metadata={...w.metadata||{},...m},v.tasks[C]=w,y(e,v,o,p),h(`success`,`Successfully updated metadata for task ${t}`),{updatedTask:w,telemetryData:null,tagInfo:{tag:p}};let T=``;try{let e=new Fa(o,p),r=new Ua(je(v.tasks),`update-task`),i=`${w.title} ${w.description} ${n}`,a=r.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=r.getTaskIds(a),c=[...new Set([t.toString(),...s])];c.length>0&&(T=(await e.gather({tasks:c,format:`research`})).context||``)}catch(e){h(`warn`,`Could not gather context: ${e.message}`)}if(c===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`)],colWidths:[5,60,10]});e.push([w.id,s(w.title,57),_l(w.status)]),console.log(W(B.white.bold(`Updating Task #${t}`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(W(B.cyan.bold(`How Completed Subtasks Are Handled:`)+`
999
999
 
1000
1000
  `+B.white(`• Subtasks marked as "done" or "completed" will be preserved
1001
1001
  `)+B.white(`• New subtasks will build upon what has already been completed
1002
1002
  `)+B.white(`• If completed work needs revision, a new subtask will be created instead of modifying done items
1003
- `)+B.white(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}))}let E=Da(),O={task:w,taskJson:JSON.stringify(w,null,2),updatePrompt:n,appendMode:l,useResearch:a,currentDetails:w.details||`(No existing details)`,gatheredContext:T||``,hasCodebaseAnalysis:_(a,o,u),projectRoot:o},k=l?`append`:a?`research`:`default`;h(`info`,`Loading prompt template with variant: ${k}, appendMode: ${l}, useResearch: ${a}`);let A,j;try{let e=E.loadPrompt(`update-task`,O,k);h(`info`,`Prompt result type: ${typeof e}, keys: ${e?Object.keys(e).join(`, `):`null`}`),A=e.systemPrompt,j=e.userPrompt,h(`info`,`Loaded prompts - systemPrompt length: ${A?.length}, userPrompt length: ${j?.length}`)}catch(e){throw h(`error`,`Failed to load prompt template: ${e.message}`),Error(`Failed to load prompt template: ${e.message}`)}if(!A||!j)throw Error(`Failed to load prompts: systemPrompt=${!!A}, userPrompt=${!!j}`);let M=null,N=null;!g&&c===`text`&&(M=sl(a?`Updating task with research...
1003
+ `)+B.white(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}))}let D=Na(),O={task:w,taskJson:JSON.stringify(w,null,2),updatePrompt:n,appendMode:l,useResearch:a,currentDetails:w.details||`(No existing details)`,gatheredContext:T||``,hasCodebaseAnalysis:_(a,o,u),projectRoot:o},k=l?`append`:a?`research`:`default`;h(`info`,`Loading prompt template with variant: ${k}, appendMode: ${l}, useResearch: ${a}`);let A,j;try{let e=D.loadPrompt(`update-task`,O,k);h(`info`,`Prompt result type: ${typeof e}, keys: ${e?Object.keys(e).join(`, `):`null`}`),A=e.systemPrompt,j=e.userPrompt,h(`info`,`Loaded prompts - systemPrompt length: ${A?.length}, userPrompt length: ${j?.length}`)}catch(e){throw h(`error`,`Failed to load prompt template: ${e.message}`),Error(`Failed to load prompt template: ${e.message}`)}if(!A||!j)throw Error(`Failed to load prompts: systemPrompt=${!!A}, userPrompt=${!!j}`);let M=null,N=null;!g&&c===`text`&&(M=pl(a?`Updating task with research...
1004
1004
  `:`Updating task...
1005
- `));try{let s=a?`research`:`main`;if(N=l?await r({role:s,session:u,projectRoot:o,systemPrompt:A,prompt:j,commandName:`update-task`,outputType:g?`mcp`:`cli`}):await i({role:s,session:u,projectRoot:o,systemPrompt:A,prompt:j,schema:ha[`update-task-by-id`],objectName:`task`,commandName:`update-task`,outputType:g?`mcp`:`cli`}),M&&$(M,`AI update complete.`),l){let r=N.mainResult,i=``;if(r&&r.trim()){let e=new Date().toISOString(),t=`<info added on ${e}>\n${r.trim()}\n</info added on ${e}>`;i=t,w.details=(w.details?w.details+`
1006
- `:``)+t}else h(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),i=`No new details were added by the AI.`;return n.length<100&&w.description&&(w.description+=` [Updated: ${new Date().toLocaleDateString()}]`),m&&(w.metadata={...w.metadata||{},...m}),v.tasks[S]=w,y(e,v,o,p),h(`success`,`Successfully appended to task ${t}`),c===`text`&&console.log(W(B.green(`Successfully appended to task #${t}`)+`
1005
+ `));try{let s=a?`research`:`main`;if(N=l?await r({role:s,session:u,projectRoot:o,systemPrompt:A,prompt:j,commandName:`update-task`,outputType:g?`mcp`:`cli`}):await i({role:s,session:u,projectRoot:o,systemPrompt:A,prompt:j,schema:xa[`update-task-by-id`],objectName:`task`,commandName:`update-task`,outputType:g?`mcp`:`cli`}),M&&$(M,`AI update complete.`),l){let r=N.mainResult,i=``;if(r&&r.trim()){let e=new Date().toISOString(),t=`<info added on ${e}>\n${r.trim()}\n</info added on ${e}>`;i=t,w.details=(w.details?w.details+`
1006
+ `:``)+t}else h(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),i=`No new details were added by the AI.`;return n.length<100&&w.description&&(w.description+=` [Updated: ${new Date().toLocaleDateString()}]`),m&&(w.metadata={...w.metadata||{},...m}),v.tasks[C]=w,y(e,v,o,p),h(`success`,`Successfully appended to task ${t}`),c===`text`&&console.log(W(B.green(`Successfully appended to task #${t}`)+`
1007
1007
 
1008
1008
  `+B.white.bold(`Title:`)+` `+w.title+`
1009
1009
 
1010
1010
  `+B.white.bold(`Newly Added Content:`)+`
1011
- `+B.white(i),{padding:1,borderColor:`green`,borderStyle:`round`})),c===`text`&&N.telemetryData&&Sl(N.telemetryData,`cli`),{updatedTask:w,telemetryData:N.telemetryData,tagInfo:N.tagInfo}}let d=N.mainResult?.task;if(!d||typeof d!=`object`)throw Error(`Received invalid task object from AI.`);let f={...d,dependencies:d.dependencies??[],priority:d.priority??null,details:d.details??null,testStrategy:d.testStrategy??null};if(!f.title||!f.description)throw Error(`Updated task missing required fields.`);if(f.id!==t&&(h(`warn`,`AI changed task ID. Restoring original ID ${t}.`),f.id=t),f.status!==w.status&&!n.toLowerCase().includes(`status`)&&(h(`warn`,`AI changed task status. Restoring original status '${w.status}'.`),f.status=w.status),f.subtasks&&Array.isArray(f.subtasks)){let e=1;f.subtasks=f.subtasks.map(t=>{let n=w.subtasks?.find(e=>String(e.id)===String(t.id)||t.title&&e.title===t.title),r={...t,id:e,dependencies:Array.isArray(t.dependencies)?t.dependencies.map(e=>typeof e==`string`?parseInt(e,10):e).filter(t=>!Number.isNaN(t)&&t>=1&&t<e):[],status:t.status||`pending`,testStrategy:t.testStrategy??null,...n?.metadata&&{metadata:n.metadata}};return e++,r}),h(`info`,`Fixed ${f.subtasks.length} subtask IDs to be sequential numeric IDs.`)}if(w.subtasks?.length>0)if(!f.subtasks)h(`warn`,`Subtasks removed by AI. Restoring original subtasks.`),f.subtasks=w.subtasks;else{w.subtasks.filter(e=>e.status===`done`||e.status===`completed`).forEach(e=>{let t=f.subtasks.find(t=>t.id===e.id);(!t||JSON.stringify(t)!==JSON.stringify(e))&&(h(`warn`,`Completed subtask ${e.id} was modified or removed. Restoring.`),f.subtasks=f.subtasks.filter(t=>t.id!==e.id),f.subtasks.push(e))});let e=new Set;f.subtasks=f.subtasks.filter(t=>e.has(t.id)?(h(`warn`,`Duplicate subtask ID ${t.id} removed.`),!1):(e.add(t.id),!0))}return(w.metadata||m)&&(f.metadata={...w.metadata||{},...m||{}}),v.tasks[S]=f,y(e,v,o,p),h(`success`,`Successfully updated task ${t}`),c===`text`&&N.telemetryData&&Sl(N.telemetryData,`cli`),{updatedTask:f,telemetryData:N.telemetryData,tagInfo:N.tagInfo}}catch(e){throw M&&$(M),h(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&h(`error`,`Please ensure API keys are configured correctly.`),e}}catch(e){throw h(`error`,`Error updating task: ${e.message}`),c===`text`&&(console.error(B.red(`Error: ${e.message}`)),je(u)&&console.error(e),process.exit(1)),e}}var el=$c;async function tl(e,t,n,r=!1,a={},o=`text`){let{session:c,mcpLog:l,projectRoot:u,tag:d}=a,f=l||z,p=!!l;p?f.info(`updateTasks called with context: session=${!!c}`):f(`info`,`updateTasks called`);try{p?f.info(`Updating tasks from ID ${t}`):f(`info`,`Updating tasks from ID ${t} with prompt: "${n}"`);let a=u||ze();if(!a)throw Error(`Could not determine project root directory`);let l=D(e,a,d);if(!l||!l.tasks)throw Error(`No valid tasks found in ${e}`);let m=l.tasks.filter(e=>e.id>=t&&e.status!==`done`);if(m.length===0){p?f.info(`No tasks to update (ID >= ${t} and not 'done').`):f(`info`,`No tasks to update (ID >= ${t} and not 'done').`),o===`text`&&console.log();return}let h=``;try{let e=new ka(a,d),t=new La(Ne(l.tasks),`update`),r=t.findRelevantTasks(n,{maxResults:5,includeSelf:!0}),i=t.getTaskIds(r),o=m.map(e=>e.id.toString()),s=[...new Set([...o,...i])];s.length>0&&(h=(await e.gather({tasks:s,format:`research`})).context||``)}catch(e){f(`warn`,`Could not gather additional context: ${e.message}`)}if(o===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`)],colWidths:[5,70,20]});m.forEach(t=>{e.push([t.id,s(t.title,57),dl(t.status)])}),console.log(W(B.white.bold(`Updating ${m.length} tasks`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(W(B.cyan.bold(`How Completed Subtasks Are Handled:`)+`
1011
+ `+B.white(i),{padding:1,borderColor:`green`,borderStyle:`round`})),c===`text`&&N.telemetryData&&Ol(N.telemetryData,`cli`),{updatedTask:w,telemetryData:N.telemetryData,tagInfo:N.tagInfo}}let d=N.mainResult?.task;if(!d||typeof d!=`object`)throw Error(`Received invalid task object from AI.`);let f={...d,dependencies:d.dependencies??[],priority:d.priority??null,details:d.details??null,testStrategy:d.testStrategy??null};if(!f.title||!f.description)throw Error(`Updated task missing required fields.`);if(f.id!==t&&(h(`warn`,`AI changed task ID. Restoring original ID ${t}.`),f.id=t),f.status!==w.status&&!n.toLowerCase().includes(`status`)&&(h(`warn`,`AI changed task status. Restoring original status '${w.status}'.`),f.status=w.status),f.subtasks&&Array.isArray(f.subtasks)){let e=1;f.subtasks=f.subtasks.map(t=>{let n=w.subtasks?.find(e=>String(e.id)===String(t.id)||t.title&&e.title===t.title),r={...t,id:e,dependencies:Array.isArray(t.dependencies)?t.dependencies.map(e=>typeof e==`string`?parseInt(e,10):e).filter(t=>!Number.isNaN(t)&&t>=1&&t<e):[],status:t.status||`pending`,testStrategy:t.testStrategy??null,...n?.metadata&&{metadata:n.metadata}};return e++,r}),h(`info`,`Fixed ${f.subtasks.length} subtask IDs to be sequential numeric IDs.`)}if(w.subtasks?.length>0)if(!f.subtasks)h(`warn`,`Subtasks removed by AI. Restoring original subtasks.`),f.subtasks=w.subtasks;else{w.subtasks.filter(e=>e.status===`done`||e.status===`completed`).forEach(e=>{let t=f.subtasks.find(t=>t.id===e.id);(!t||JSON.stringify(t)!==JSON.stringify(e))&&(h(`warn`,`Completed subtask ${e.id} was modified or removed. Restoring.`),f.subtasks=f.subtasks.filter(t=>t.id!==e.id),f.subtasks.push(e))});let e=new Set;f.subtasks=f.subtasks.filter(t=>e.has(t.id)?(h(`warn`,`Duplicate subtask ID ${t.id} removed.`),!1):(e.add(t.id),!0))}return(w.metadata||m)&&(f.metadata={...w.metadata||{},...m||{}}),v.tasks[C]=f,y(e,v,o,p),h(`success`,`Successfully updated task ${t}`),c===`text`&&N.telemetryData&&Ol(N.telemetryData,`cli`),{updatedTask:f,telemetryData:N.telemetryData,tagInfo:N.tagInfo}}catch(e){throw M&&$(M),h(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&h(`error`,`Please ensure API keys are configured correctly.`),e}}catch(e){throw h(`error`,`Error updating task: ${e.message}`),c===`text`&&(console.error(B.red(`Error: ${e.message}`)),ke(u)&&console.error(e),process.exit(1)),e}}var ol=al;async function sl(e,t,n,r=!1,a={},o=`text`){let{session:c,mcpLog:l,projectRoot:u,tag:d}=a,f=l||z,p=!!l;p?f.info(`updateTasks called with context: session=${!!c}`):f(`info`,`updateTasks called`);try{p?f.info(`Updating tasks from ID ${t}`):f(`info`,`Updating tasks from ID ${t} with prompt: "${n}"`);let a=u||Le();if(!a)throw Error(`Could not determine project root directory`);let l=E(e,a,d);if(!l||!l.tasks)throw Error(`No valid tasks found in ${e}`);let m=l.tasks.filter(e=>e.id>=t&&e.status!==`done`);if(m.length===0){p?f.info(`No tasks to update (ID >= ${t} and not 'done').`):f(`info`,`No tasks to update (ID >= ${t} and not 'done').`),o===`text`&&console.log();return}let h=``;try{let e=new Fa(a,d),t=new Ua(je(l.tasks),`update`),r=t.findRelevantTasks(n,{maxResults:5,includeSelf:!0}),i=t.getTaskIds(r),o=m.map(e=>e.id.toString()),s=[...new Set([...o,...i])];s.length>0&&(h=(await e.gather({tasks:s,format:`research`})).context||``)}catch(e){f(`warn`,`Could not gather additional context: ${e.message}`)}if(o===`text`){let e=new K({head:[B.cyan.bold(`ID`),B.cyan.bold(`Title`),B.cyan.bold(`Status`)],colWidths:[5,70,20]});m.forEach(t=>{e.push([t.id,s(t.title,57),_l(t.status)])}),console.log(W(B.white.bold(`Updating ${m.length} tasks`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(W(B.cyan.bold(`How Completed Subtasks Are Handled:`)+`
1012
1012
 
1013
1013
  `+B.white(`• Subtasks marked as "done" or "completed" will be preserved
1014
1014
  `)+B.white(`• New subtasks will build upon what has already been completed
1015
1015
  `)+B.white(`• If completed work needs revision, a new subtask will be created instead of modifying done items
1016
- `)+B.white(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}))}let{systemPrompt:g,userPrompt:v}=await Da().loadPrompt(`update-tasks`,{tasks:m,updatePrompt:n,useResearch:r,projectContext:h,hasCodebaseAnalysis:_(r,a,c),projectRoot:a}),b=null,x=null;!p&&o===`text`&&(b=sl(`Updating tasks with AI...
1017
- `));try{x=await i({role:r?`research`:`main`,session:c,projectRoot:a,systemPrompt:g,prompt:v,schema:ha[`update-tasks`],objectName:`tasks`,commandName:`update-tasks`,outputType:p?`mcp`:`cli`}),b&&$(b,`AI update complete.`);let t=x.mainResult.tasks.map(e=>({...e,dependencies:e.dependencies??[],priority:e.priority??null,details:e.details??null,testStrategy:e.testStrategy??null,subtasks:e.subtasks?e.subtasks.map(e=>({...e,dependencies:e.dependencies??[],status:e.status??`pending`,testStrategy:e.testStrategy??null})):null}));if(!Array.isArray(t))throw Error(`Parsed AI response for updated tasks was not an array.`);p?f.info(`Received ${t.length} updated tasks from AI.`):f(`info`,`Received ${t.length} updated tasks from AI.`);let n=new Map(t.map(e=>[e.id,e])),s=0;return l.tasks.forEach((e,t)=>{if(n.has(e.id)){let r=n.get(e.id);l.tasks[t]={...e,...r,subtasks:r.subtasks===void 0?e.subtasks:r.subtasks},s++}}),p?f.info(`Applied updates to ${s} tasks in the dataset.`):f(`info`,`Applied updates to ${s} tasks in the dataset.`),y(e,l,a,d),p?f.info(`Successfully updated ${s} tasks in ${e}`):f(`success`,`Successfully updated ${s} tasks in ${e}`),o===`text`&&x.telemetryData&&Sl(x.telemetryData,`cli`),{success:!0,updatedTasks:t,telemetryData:x.telemetryData,tagInfo:x.tagInfo}}catch(e){throw b&&$(b),p?f.error(`Error during AI service call: ${e.message}`):f(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&(p?f.error(`Please ensure API keys are configured correctly in .env or mcp.json.`):f(`error`,`Please ensure API keys are configured correctly in .env or mcp.json.`)),e}finally{b&&$(b)}}catch(e){if(p?f.error(`Error updating tasks: ${e.message}`):f(`error`,`Error updating tasks: ${e.message}`),o===`text`)console.error(B.red(`Error: ${e.message}`)),je(c)&&console.error(e),process.exit(1);else throw e}}var nl=tl;const rl=it([`#fb8b24`,`#e36414`,`#9a031e`]);function il(e){L()||!e||!e._migrationHappened||console.log(W(B.white.bold(`FYI: `)+B.gray(`Taskmaster now supports separate task lists per tag. `)+B.cyan(`Use the --tag flag to create/read/update/filter tasks by tag.`),{padding:{top:0,bottom:0,left:2,right:2},borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}))}async function al(e,t={}){if(L())return;let{skipIfMaster:n=!1,dim:r=!1,storageType:i,briefInfo:a}=t;if(n&&e===`master`)return;if(!i||!a)try{let t=ge.getInstance().getContext();t&&t.briefId?(i=`api`,a={briefId:t.briefId,briefName:t.briefName||e}):i=`file`}catch(e){z(`debug`,`Failed to detect storage type: ${e.message}`),i=`file`}i!==`api`&&i!==`file`&&(i=`file`);let o;o=i===`api`&&a?`[brief] ${B.cyan(a.briefName)} ${B.gray(`(${a.briefId})`)}`:r?B.gray(`[tag] ${e}`):B.dim(`[tag] `)+B.cyan(e),console.log(o)}function ol(){L()||Et({version:Yi(),projectName:b(null)})}function sl(e){return L()?null:J({text:e,color:`cyan`}).start()}function $(e){e&&typeof e.stop==`function`&&e.stop()}function cl(e,t=null){e&&typeof e.succeed==`function`&&(t?e.succeed(t):e.succeed())}function ll(e,t=null){e&&typeof e.fail==`function`&&(t?e.fail(t):e.fail())}function ul(e,t=30,n=null){let r=n?Math.min(100,e+(n.deferred||0)+(n.cancelled||0)):e,i=Math.round(e*t/100),a=Math.round(r*t/100),o=a-i,s=t-a,c;c=e<25?B.red:e<50?B.hex(`#FFA500`):e<75?B.yellow:e<100?B.green:B.hex(`#006400`);let l=c(`█`.repeat(i)),u=B.gray(`█`.repeat(o)),d=``;if(n&&s>0){let e={pending:B.yellow,"in-progress":B.hex(`#FFA500`),blocked:B.red,review:B.magenta},t=Object.entries(n).filter(([e])=>![`deferred`,`cancelled`,`done`,`completed`].includes(e)).reduce((e,[t,n])=>e+n,0);if(t<=0)d=B.gray(`░`.repeat(s));else{let r=0;for(let[i,a]of Object.entries(n)){if([`deferred`,`cancelled`,`done`,`completed`].includes(i))continue;let n=Math.round(a/t*s),o=Math.min(n,s-r),c=e[i]||B.gray;d+=c(`░`.repeat(o)),r+=o}r<s&&(d+=B.gray(`░`.repeat(s-r)))}}else d=B.gray(`░`.repeat(s));let f=e===100?B.hex(`#006400`):r===100?B.gray:c;return`${l}${u}${d} ${f(`${r.toFixed(0)}%`)}`}function dl(e,t=!1){if(!e)return B.gray(`❓ unknown`);let n={done:{color:B.green,icon:`✓`,tableIcon:`✓`},completed:{color:B.green,icon:`✓`,tableIcon:`✓`},pending:{color:B.yellow,icon:`○`,tableIcon:`⏱`},"in-progress":{color:B.hex(`#FFA500`),icon:`🔄`,tableIcon:`►`},deferred:{color:B.gray,icon:`x`,tableIcon:`⏱`},blocked:{color:B.red,icon:`!`,tableIcon:`✗`},review:{color:B.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:B.gray,icon:`❌`,tableIcon:`x`}}[e.toLowerCase()]||{color:B.red,icon:`❌`,tableIcon:`✗`};if(t){let t={done:`✓`,completed:`✓`,pending:`○`,"in-progress":`►`,deferred:`x`,blocked:`!`,review:`?`}[e.toLowerCase()]||`x`;return n.color(`${t} ${e}`)}return n.color(`${n.icon} ${e}`)}function fl(e,t,n=!1,r=null){return!e||!Array.isArray(e)||e.length===0?n?B.gray(`None`):`None`:e.map(e=>{let i=e.toString();if(i.includes(`.`)){let a=i.split(`.`);if(a.length!==2||!a[0]||!a[1]){let a=oe(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let o=a.status||`pending`,s=o.toLowerCase()===`done`||o.toLowerCase()===`completed`,c=o.toLowerCase()===`in-progress`;return n?s?B.green.bold(i):c?B.yellow.bold(i):B.red.bold(i):i}let[o,s]=a.map(e=>parseInt(e,10)),c=t.find(e=>e.id===o);if(!c||!c.subtasks)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let l=c.subtasks.find(e=>e.id===s);if(!l)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let u=l.status||`pending`,d=u.toLowerCase()===`done`||u.toLowerCase()===`completed`,f=u.toLowerCase()===`in-progress`;return n?d?B.green.bold(i):f?B.hex(`#FFA500`).bold(i):B.red.bold(i):i}let a=oe(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let o=a.status||`pending`,s=o.toLowerCase()===`done`||o.toLowerCase()===`completed`,c=o.toLowerCase()===`in-progress`;return n?s?B.green.bold(i):c?B.yellow.bold(i):B.red.bold(i):i}).join(`, `)}function pl(){let e=process.stdout.columns||100;console.log(W(B.white.bold(`Task Master CLI`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}})),[{title:`Project Setup & Configuration`,color:`blue`,commands:[{name:`init`,args:`[--name=<name>] [--description=<desc>] [-y]`,desc:`Initialize a new project with Task Master structure`},{name:`models`,args:``,desc:`View current AI model configuration and available models`},{name:`models --setup`,args:``,desc:`Run interactive setup to configure AI models`},{name:`models --set-main`,args:`<model_id>`,desc:`Set the primary model for task generation`},{name:`models --set-research`,args:`<model_id>`,desc:`Set the model for research operations`},{name:`models --set-fallback`,args:`<model_id>`,desc:`Set the fallback model (optional)`}]},{title:`Task Generation`,color:`cyan`,commands:[{name:`parse-prd`,args:`--input=<file.txt> [--num-tasks=10]`,desc:`Generate tasks from a PRD document`},{name:`generate`,args:``,desc:`Create individual task files from tasks.json`}]},{title:`Task Management`,color:`green`,commands:[{name:`list`,args:`[<status>|all] [-s <status>] [-t <tag>]`,desc:`List all tasks - use "all" to show with subtasks`},{name:`list`,args:`[--with-subtasks] [-f <format>] [--json] [-c]`,desc:`Options: format (text/json/compact), subtasks`},{name:`list`,args:`[-w] [--ready] [--blocking] [--all-tags]`,desc:`Options: watch mode, ready/blocking filters, all tags`},{name:`set-status`,args:`<id> <status>`,desc:`Update task status (${qi.join(`, `)})`},{name:`sync-readme`,args:`[--with-subtasks] [--status=<status>]`,desc:`Export tasks to README.md with professional formatting`},{name:`update`,args:`--from=<id> --prompt="<context>"`,desc:`Update multiple tasks based on new requirements`},{name:`update-task`,args:`<id> <prompt...>`,desc:`Update a single task (no quotes needed for multi-word prompts)`},{name:`update-subtask`,args:`--id=<parentId.subtaskId> --prompt="<context>"`,desc:`Append additional information to a subtask`},{name:`add-task`,args:`--prompt="<text>" [--dependencies=<ids>] [--priority=<priority>]`,desc:`Add a new task using AI`},{name:`remove-task`,args:`--id=<id> [-y]`,desc:`Permanently remove a task or subtask`}]},{title:`Subtask Management`,color:`yellow`,commands:[{name:`add-subtask`,args:`--parent=<id> --title="<title>" [--description="<desc>"]`,desc:`Add a new subtask to a parent task`},{name:`add-subtask`,args:`--parent=<id> --task-id=<id>`,desc:`Convert an existing task into a subtask`},{name:`remove-subtask`,args:`--id=<parentId.subtaskId> [--convert]`,desc:`Remove a subtask (optionally convert to standalone task)`},{name:`clear-subtasks`,args:`--id=<id>`,desc:`Remove all subtasks from specified tasks`},{name:`clear-subtasks --all`,args:``,desc:`Remove subtasks from all tasks`}]},{title:`Task Analysis & Breakdown`,color:`magenta`,commands:[{name:`analyze-complexity`,args:`[--research] [--threshold=5]`,desc:`Analyze tasks and generate expansion recommendations`},{name:`complexity-report`,args:`[--file=<path>]`,desc:`Display the complexity analysis report`},{name:`expand`,args:`--id=<id> [--num=5] [--research] [--prompt="<context>"]`,desc:`Break down tasks into detailed subtasks`},{name:`expand --all`,args:`[--force] [--research]`,desc:`Expand all pending tasks with subtasks`},{name:`research`,args:`"<prompt>" [-i=<task_ids>] [-f=<file_paths>] [-c="<context>"] [--tree] [-s=<save_file>] [-d=<detail_level>]`,desc:`Perform AI-powered research queries with project context`}]},{title:`Task Navigation & Viewing`,color:`cyan`,commands:[{name:`next`,args:``,desc:`Show the next task to work on based on dependencies`},{name:`show`,args:`<id>`,desc:`Display detailed information about a specific task`}]},{title:`Tag Management`,color:`magenta`,commands:[{name:`tags`,args:`[list] [--show-metadata] [--ready]`,desc:`List all available tags with task counts`},{name:`tags add`,args:`<name> [--description <desc>] [--copy-from <tag>]`,desc:`Create a new tag (--from-branch for git branch name)`},{name:`tags use`,args:`<name>`,desc:`Switch to a different tag context`},{name:`tags remove`,args:`<name> [-y]`,desc:`Delete an existing tag and all its tasks`},{name:`tags rename`,args:`<oldName> <newName>`,desc:`Rename an existing tag`},{name:`tags copy`,args:`<source> <target> [--description <desc>]`,desc:`Copy a tag with all its tasks`}]},{title:`Dependency Management`,color:`blue`,commands:[{name:`add-dependency`,args:`--id=<id> --depends-on=<id>`,desc:`Add a dependency to a task`},{name:`remove-dependency`,args:`--id=<id> --depends-on=<id>`,desc:`Remove a dependency from a task`},{name:`validate-dependencies`,args:``,desc:`Identify invalid dependencies without fixing them`},{name:`fix-dependencies`,args:``,desc:`Fix invalid dependencies automatically`}]}].forEach(t=>{console.log(W(B[t.color].bold(t.title),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:t.color,borderStyle:`round`}));let n=new K({colWidths:[Math.max(25,Math.floor(e*.2)),Math.max(40,Math.floor(e*.35)),Math.max(45,Math.floor(e*.45)-10)],chars:{top:``,"top-mid":``,"top-left":``,"top-right":``,bottom:``,"bottom-mid":``,"bottom-left":``,"bottom-right":``,left:``,"left-mid":``,mid:``,"mid-mid":``,right:``,"right-mid":``,middle:` `},style:{border:[],"padding-left":4},wordWrap:!0});t.commands.forEach((e,t)=>{n.push([`${B.yellow.bold(e.name)}${B.reset(``)}`,`${B.white(e.args)}${B.reset(``)}`,`${B.dim(e.desc)}${B.reset(``)}`])}),console.log(n.toString()),console.log(``)}),console.log(W(B.cyan.bold(`Configuration`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:`cyan`,borderStyle:`round`}));let t=e||process.stdout.columns||100,n=new K({colWidths:[Math.max(30,Math.floor(t*.25)),Math.max(50,Math.floor(t*.45)),Math.max(30,Math.floor(t*.3)-10)],chars:{top:``,"top-mid":``,"top-left":``,"top-right":``,bottom:``,"bottom-mid":``,"bottom-left":``,"bottom-right":``,left:``,"left-mid":``,mid:``,"mid-mid":``,right:``,"right-mid":``,middle:` `},style:{border:[],"padding-left":4},wordWrap:!0});n.push([`${B.yellow(l)}${B.reset(``)}`,`${B.white(`AI model configuration file (project root)`)}${B.reset(``)}`,`${B.dim(`Managed by models cmd`)}${B.reset(``)}`],[`${B.yellow(`API Keys (.env)`)}${B.reset(``)}`,`${B.white(`API keys for AI providers (ANTHROPIC_API_KEY, etc.)`)}${B.reset(``)}`,`${B.dim(`Required in .env file`)}${B.reset(``)}`],[`${B.yellow(`MCP Keys (mcp.json)`)}${B.reset(``)}`,`${B.white(`API keys for Cursor integration`)}${B.reset(``)}`,`${B.dim(`Required in .cursor/`)}${B.reset(``)}`]),console.log(n.toString()),console.log(``),console.log(W(B.white.bold(`Quick Start:`)+`
1016
+ `)+B.white(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}))}let{systemPrompt:g,userPrompt:v}=await Na().loadPrompt(`update-tasks`,{tasks:m,updatePrompt:n,useResearch:r,projectContext:h,hasCodebaseAnalysis:_(r,a,c),projectRoot:a}),b=null,x=null;!p&&o===`text`&&(b=pl(`Updating tasks with AI...
1017
+ `));try{x=await i({role:r?`research`:`main`,session:c,projectRoot:a,systemPrompt:g,prompt:v,schema:xa[`update-tasks`],objectName:`tasks`,commandName:`update-tasks`,outputType:p?`mcp`:`cli`}),b&&$(b,`AI update complete.`);let t=x.mainResult.tasks.map(e=>({...e,dependencies:e.dependencies??[],priority:e.priority??null,details:e.details??null,testStrategy:e.testStrategy??null,subtasks:e.subtasks?e.subtasks.map(e=>({...e,dependencies:e.dependencies??[],status:e.status??`pending`,testStrategy:e.testStrategy??null})):null}));if(!Array.isArray(t))throw Error(`Parsed AI response for updated tasks was not an array.`);p?f.info(`Received ${t.length} updated tasks from AI.`):f(`info`,`Received ${t.length} updated tasks from AI.`);let n=new Map(t.map(e=>[e.id,e])),s=0;return l.tasks.forEach((e,t)=>{if(n.has(e.id)){let r=n.get(e.id);l.tasks[t]={...e,...r,subtasks:r.subtasks===void 0?e.subtasks:r.subtasks},s++}}),p?f.info(`Applied updates to ${s} tasks in the dataset.`):f(`info`,`Applied updates to ${s} tasks in the dataset.`),y(e,l,a,d),p?f.info(`Successfully updated ${s} tasks in ${e}`):f(`success`,`Successfully updated ${s} tasks in ${e}`),o===`text`&&x.telemetryData&&Ol(x.telemetryData,`cli`),{success:!0,updatedTasks:t,telemetryData:x.telemetryData,tagInfo:x.tagInfo}}catch(e){throw b&&$(b),p?f.error(`Error during AI service call: ${e.message}`):f(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&(p?f.error(`Please ensure API keys are configured correctly in .env or mcp.json.`):f(`error`,`Please ensure API keys are configured correctly in .env or mcp.json.`)),e}finally{b&&$(b)}}catch(e){if(p?f.error(`Error updating tasks: ${e.message}`):f(`error`,`Error updating tasks: ${e.message}`),o===`text`)console.error(B.red(`Error: ${e.message}`)),ke(c)&&console.error(e),process.exit(1);else throw e}}var cl=sl;const ll=it([`#fb8b24`,`#e36414`,`#9a031e`]);function ul(e){L()||!e||!e._migrationHappened||console.log(W(B.white.bold(`FYI: `)+B.gray(`Taskmaster now supports separate task lists per tag. `)+B.cyan(`Use the --tag flag to create/read/update/filter tasks by tag.`),{padding:{top:0,bottom:0,left:2,right:2},borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}))}async function dl(e,t={}){if(L())return;let{skipIfMaster:n=!1,dim:r=!1,storageType:i,briefInfo:a}=t;if(n&&e===`master`)return;if(!i||!a)try{let t=he.getInstance().getContext();t&&t.briefId?(i=`api`,a={briefId:t.briefId,briefName:t.briefName||e}):i=`file`}catch(e){z(`debug`,`Failed to detect storage type: ${e.message}`),i=`file`}i!==`api`&&i!==`file`&&(i=`file`);let o;o=i===`api`&&a?`[brief] ${B.cyan(a.briefName)} ${B.gray(`(${a.briefId})`)}`:r?B.gray(`[tag] ${e}`):B.dim(`[tag] `)+B.cyan(e),console.log(o)}function fl(){L()||Ot({version:ta(),projectName:b(null)})}function pl(e){return L()?null:J({text:e,color:`cyan`}).start()}function $(e){e&&typeof e.stop==`function`&&e.stop()}function ml(e,t=null){e&&typeof e.succeed==`function`&&(t?e.succeed(t):e.succeed())}function hl(e,t=null){e&&typeof e.fail==`function`&&(t?e.fail(t):e.fail())}function gl(e,t=30,n=null){let r=n?Math.min(100,e+(n.deferred||0)+(n.cancelled||0)):e,i=Math.round(e*t/100),a=Math.round(r*t/100),o=a-i,s=t-a,c;c=e<25?B.red:e<50?B.hex(`#FFA500`):e<75?B.yellow:e<100?B.green:B.hex(`#006400`);let l=c(`█`.repeat(i)),u=B.gray(`█`.repeat(o)),d=``;if(n&&s>0){let e={pending:B.yellow,"in-progress":B.hex(`#FFA500`),blocked:B.red,review:B.magenta},t=Object.entries(n).filter(([e])=>![`deferred`,`cancelled`,`done`,`completed`].includes(e)).reduce((e,[t,n])=>e+n,0);if(t<=0)d=B.gray(`░`.repeat(s));else{let r=0;for(let[i,a]of Object.entries(n)){if([`deferred`,`cancelled`,`done`,`completed`].includes(i))continue;let n=Math.round(a/t*s),o=Math.min(n,s-r),c=e[i]||B.gray;d+=c(`░`.repeat(o)),r+=o}r<s&&(d+=B.gray(`░`.repeat(s-r)))}}else d=B.gray(`░`.repeat(s));let f=e===100?B.hex(`#006400`):r===100?B.gray:c;return`${l}${u}${d} ${f(`${r.toFixed(0)}%`)}`}function _l(e,t=!1){if(!e)return B.gray(`❓ unknown`);let n={done:{color:B.green,icon:`✓`,tableIcon:`✓`},completed:{color:B.green,icon:`✓`,tableIcon:`✓`},pending:{color:B.yellow,icon:`○`,tableIcon:`⏱`},"in-progress":{color:B.hex(`#FFA500`),icon:`🔄`,tableIcon:`►`},deferred:{color:B.gray,icon:`x`,tableIcon:`⏱`},blocked:{color:B.red,icon:`!`,tableIcon:`✗`},review:{color:B.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:B.gray,icon:`❌`,tableIcon:`x`}}[e.toLowerCase()]||{color:B.red,icon:`❌`,tableIcon:`✗`};if(t){let t={done:`✓`,completed:`✓`,pending:`○`,"in-progress":`►`,deferred:`x`,blocked:`!`,review:`?`}[e.toLowerCase()]||`x`;return n.color(`${t} ${e}`)}return n.color(`${n.icon} ${e}`)}function vl(e,t,n=!1,r=null){return!e||!Array.isArray(e)||e.length===0?n?B.gray(`None`):`None`:e.map(e=>{let i=e.toString();if(i.includes(`.`)){let a=i.split(`.`);if(a.length!==2||!a[0]||!a[1]){let a=F(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let o=a.status||`pending`,s=o.toLowerCase()===`done`||o.toLowerCase()===`completed`,c=o.toLowerCase()===`in-progress`;return n?s?B.green.bold(i):c?B.yellow.bold(i):B.red.bold(i):i}let[o,s]=a.map(e=>parseInt(e,10)),c=t.find(e=>e.id===o);if(!c||!c.subtasks)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let l=c.subtasks.find(e=>e.id===s);if(!l)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let u=l.status||`pending`,d=u.toLowerCase()===`done`||u.toLowerCase()===`completed`,f=u.toLowerCase()===`in-progress`;return n?d?B.green.bold(i):f?B.hex(`#FFA500`).bold(i):B.red.bold(i):i}let a=F(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?B.red(`${i} (Not found)`):`${i} (Not found)`;let o=a.status||`pending`,s=o.toLowerCase()===`done`||o.toLowerCase()===`completed`,c=o.toLowerCase()===`in-progress`;return n?s?B.green.bold(i):c?B.yellow.bold(i):B.red.bold(i):i}).join(`, `)}function yl(){let e=process.stdout.columns||100;console.log(W(B.white.bold(`Task Master CLI`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}})),[{title:`Project Setup & Configuration`,color:`blue`,commands:[{name:`init`,args:`[--name=<name>] [--description=<desc>] [-y]`,desc:`Initialize a new project with Task Master structure`},{name:`models`,args:``,desc:`View current AI model configuration and available models`},{name:`models --setup`,args:``,desc:`Run interactive setup to configure AI models`},{name:`models --set-main`,args:`<model_id>`,desc:`Set the primary model for task generation`},{name:`models --set-research`,args:`<model_id>`,desc:`Set the model for research operations`},{name:`models --set-fallback`,args:`<model_id>`,desc:`Set the fallback model (optional)`}]},{title:`Task Generation`,color:`cyan`,commands:[{name:`parse-prd`,args:`--input=<file.txt> [--num-tasks=10]`,desc:`Generate tasks from a PRD document`},{name:`generate`,args:``,desc:`Create individual task files from tasks.json`}]},{title:`Task Management`,color:`green`,commands:[{name:`list`,args:`[<status>|all] [-s <status>] [-t <tag>]`,desc:`List all tasks - use "all" to show with subtasks`},{name:`list`,args:`[--with-subtasks] [-f <format>] [--json] [-c]`,desc:`Options: format (text/json/compact), subtasks`},{name:`list`,args:`[-w] [--ready] [--blocking] [--all-tags]`,desc:`Options: watch mode, ready/blocking filters, all tags`},{name:`set-status`,args:`<id> <status>`,desc:`Update task status (${Yi.join(`, `)})`},{name:`sync-readme`,args:`[--with-subtasks] [--status=<status>]`,desc:`Export tasks to README.md with professional formatting`},{name:`update`,args:`--from=<id> --prompt="<context>"`,desc:`Update multiple tasks based on new requirements`},{name:`update-task`,args:`<id> <prompt...>`,desc:`Update a single task (no quotes needed for multi-word prompts)`},{name:`update-subtask`,args:`--id=<parentId.subtaskId> --prompt="<context>"`,desc:`Append additional information to a subtask`},{name:`add-task`,args:`--prompt="<text>" [--dependencies=<ids>] [--priority=<priority>]`,desc:`Add a new task using AI`},{name:`remove-task`,args:`--id=<id> [-y]`,desc:`Permanently remove a task or subtask`}]},{title:`Subtask Management`,color:`yellow`,commands:[{name:`add-subtask`,args:`--parent=<id> --title="<title>" [--description="<desc>"]`,desc:`Add a new subtask to a parent task`},{name:`add-subtask`,args:`--parent=<id> --task-id=<id>`,desc:`Convert an existing task into a subtask`},{name:`remove-subtask`,args:`--id=<parentId.subtaskId> [--convert]`,desc:`Remove a subtask (optionally convert to standalone task)`},{name:`clear-subtasks`,args:`--id=<id>`,desc:`Remove all subtasks from specified tasks`},{name:`clear-subtasks --all`,args:``,desc:`Remove subtasks from all tasks`}]},{title:`Task Analysis & Breakdown`,color:`magenta`,commands:[{name:`analyze-complexity`,args:`[--research] [--threshold=5]`,desc:`Analyze tasks and generate expansion recommendations`},{name:`complexity-report`,args:`[--file=<path>]`,desc:`Display the complexity analysis report`},{name:`expand`,args:`--id=<id> [--num=5] [--research] [--prompt="<context>"]`,desc:`Break down tasks into detailed subtasks`},{name:`expand --all`,args:`[--force] [--research]`,desc:`Expand all pending tasks with subtasks`},{name:`research`,args:`"<prompt>" [-i=<task_ids>] [-f=<file_paths>] [-c="<context>"] [--tree] [-s=<save_file>] [-d=<detail_level>]`,desc:`Perform AI-powered research queries with project context`}]},{title:`Task Navigation & Viewing`,color:`cyan`,commands:[{name:`next`,args:``,desc:`Show the next task to work on based on dependencies`},{name:`show`,args:`<id>`,desc:`Display detailed information about a specific task`}]},{title:`Tag Management`,color:`magenta`,commands:[{name:`tags`,args:`[list] [--show-metadata] [--ready]`,desc:`List all available tags with task counts`},{name:`tags add`,args:`<name> [--description <desc>] [--copy-from <tag>]`,desc:`Create a new tag (--from-branch for git branch name)`},{name:`tags use`,args:`<name>`,desc:`Switch to a different tag context`},{name:`tags remove`,args:`<name> [-y]`,desc:`Delete an existing tag and all its tasks`},{name:`tags rename`,args:`<oldName> <newName>`,desc:`Rename an existing tag`},{name:`tags copy`,args:`<source> <target> [--description <desc>]`,desc:`Copy a tag with all its tasks`}]},{title:`Dependency Management`,color:`blue`,commands:[{name:`add-dependency`,args:`--id=<id> --depends-on=<id>`,desc:`Add a dependency to a task`},{name:`remove-dependency`,args:`--id=<id> --depends-on=<id>`,desc:`Remove a dependency from a task`},{name:`validate-dependencies`,args:``,desc:`Identify invalid dependencies without fixing them`},{name:`fix-dependencies`,args:``,desc:`Fix invalid dependencies automatically`}]}].forEach(t=>{console.log(W(B[t.color].bold(t.title),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:t.color,borderStyle:`round`}));let n=new K({colWidths:[Math.max(25,Math.floor(e*.2)),Math.max(40,Math.floor(e*.35)),Math.max(45,Math.floor(e*.45)-10)],chars:{top:``,"top-mid":``,"top-left":``,"top-right":``,bottom:``,"bottom-mid":``,"bottom-left":``,"bottom-right":``,left:``,"left-mid":``,mid:``,"mid-mid":``,right:``,"right-mid":``,middle:` `},style:{border:[],"padding-left":4},wordWrap:!0});t.commands.forEach((e,t)=>{n.push([`${B.yellow.bold(e.name)}${B.reset(``)}`,`${B.white(e.args)}${B.reset(``)}`,`${B.dim(e.desc)}${B.reset(``)}`])}),console.log(n.toString()),console.log(``)}),console.log(W(B.cyan.bold(`Configuration`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:`cyan`,borderStyle:`round`}));let t=e||process.stdout.columns||100,n=new K({colWidths:[Math.max(30,Math.floor(t*.25)),Math.max(50,Math.floor(t*.45)),Math.max(30,Math.floor(t*.3)-10)],chars:{top:``,"top-mid":``,"top-left":``,"top-right":``,bottom:``,"bottom-mid":``,"bottom-left":``,"bottom-right":``,left:``,"left-mid":``,mid:``,"mid-mid":``,right:``,"right-mid":``,middle:` `},style:{border:[],"padding-left":4},wordWrap:!0});n.push([`${B.yellow(l)}${B.reset(``)}`,`${B.white(`AI model configuration file (project root)`)}${B.reset(``)}`,`${B.dim(`Managed by models cmd`)}${B.reset(``)}`],[`${B.yellow(`API Keys (.env)`)}${B.reset(``)}`,`${B.white(`API keys for AI providers (ANTHROPIC_API_KEY, etc.)`)}${B.reset(``)}`,`${B.dim(`Required in .env file`)}${B.reset(``)}`],[`${B.yellow(`MCP Keys (mcp.json)`)}${B.reset(``)}`,`${B.white(`API keys for Cursor integration`)}${B.reset(``)}`,`${B.dim(`Required in .cursor/`)}${B.reset(``)}`]),console.log(n.toString()),console.log(``),console.log(W(B.white.bold(`Quick Start:`)+`
1018
1018
 
1019
1019
  `+B.cyan(`1. Create Project: `)+B.white(`task-master init`)+`
1020
1020
  `+B.cyan(`2. Setup Models: `)+B.white(`task-master models --setup`)+`
1021
1021
  `+B.cyan(`3. Parse PRD: `)+B.white(`task-master parse-prd --input=<prd-file>`)+`
1022
1022
  `+B.cyan(`4. List Tasks: `)+B.white(`task-master list`)+`
1023
- `+B.cyan(`5. Find Next Task: `)+B.white(`task-master next`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1},width:Math.min(t-10,100)}))}function ml(e){return e<=3?B.green(`● ${e}`):e<=6?B.yellow(`● ${e}`):B.red(`● ${e}`)}async function hl(e){if(!V.existsSync(e)){console.log(W(B.yellow(`No complexity report found at ${e}\n\n`)+`Would you like to generate one now?`,{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=nt.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(B.cyan(`Generate complexity report? (y/n): `),e)});if(t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`){console.log(B.blue(`Generating complexity report...`));let t=g;return V.existsSync(t)?(await za({output:e,research:!1,file:t}),hl(e)):(console.error(`❌ No tasks.json file found. Please run "task-master init" or create a tasks.json file.`),null)}else{console.log(B.yellow(`Report generation cancelled.`));return}}let t;try{t=JSON.parse(V.readFileSync(e,`utf8`))}catch(e){z(`error`,`Error reading complexity report: ${e.message}`);return}console.log(W(B.white.bold(`Task Complexity Analysis Report`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let n=new K({style:{head:[],border:[],"padding-top":0,"padding-bottom":0,compact:!0},chars:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``},colWidths:[20,50]});n.push([B.cyan.bold(`Generated:`),new Date(t.meta.generatedAt).toLocaleString()],[B.cyan.bold(`Tasks Analyzed:`),t.meta.tasksAnalyzed],[B.cyan.bold(`Threshold Score:`),t.meta.thresholdScore],[B.cyan.bold(`Project:`),t.meta.projectName],[B.cyan.bold(`Research-backed:`),t.meta.usedResearch?`Yes`:`No`]),console.log(n.toString());let r=[...t.complexityAnalysis].sort((e,t)=>t.complexityScore-e.complexityScore),i=r.filter(e=>e.complexityScore>=t.meta.thresholdScore),a=r.filter(e=>e.complexityScore<t.meta.thresholdScore),o=[0,0,0];r.forEach(e=>{e.complexityScore<5?o[0]++:e.complexityScore<8?o[1]++:o[2]++});let c=Math.round(o[0]/r.length*100),l=Math.round(o[1]/r.length*100),u=Math.round(o[2]/r.length*100);console.log(W(B.white.bold(`Complexity Distribution
1023
+ `+B.cyan(`5. Find Next Task: `)+B.white(`task-master next`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1},width:Math.min(t-10,100)}))}function bl(e){return e<=3?B.green(`● ${e}`):e<=6?B.yellow(`● ${e}`):B.red(`● ${e}`)}async function xl(e){if(!V.existsSync(e)){console.log(W(B.yellow(`No complexity report found at ${e}\n\n`)+`Would you like to generate one now?`,{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=nt.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(B.cyan(`Generate complexity report? (y/n): `),e)});if(t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`){console.log(B.blue(`Generating complexity report...`));let t=g;return V.existsSync(t)?(await Ga({output:e,research:!1,file:t}),xl(e)):(console.error(`❌ No tasks.json file found. Please run "task-master init" or create a tasks.json file.`),null)}else{console.log(B.yellow(`Report generation cancelled.`));return}}let t;try{t=JSON.parse(V.readFileSync(e,`utf8`))}catch(e){z(`error`,`Error reading complexity report: ${e.message}`);return}console.log(W(B.white.bold(`Task Complexity Analysis Report`),{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let n=new K({style:{head:[],border:[],"padding-top":0,"padding-bottom":0,compact:!0},chars:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``},colWidths:[20,50]});n.push([B.cyan.bold(`Generated:`),new Date(t.meta.generatedAt).toLocaleString()],[B.cyan.bold(`Tasks Analyzed:`),t.meta.tasksAnalyzed],[B.cyan.bold(`Threshold Score:`),t.meta.thresholdScore],[B.cyan.bold(`Project:`),t.meta.projectName],[B.cyan.bold(`Research-backed:`),t.meta.usedResearch?`Yes`:`No`]),console.log(n.toString());let r=[...t.complexityAnalysis].sort((e,t)=>t.complexityScore-e.complexityScore),i=r.filter(e=>e.complexityScore>=t.meta.thresholdScore),a=r.filter(e=>e.complexityScore<t.meta.thresholdScore),o=[0,0,0];r.forEach(e=>{e.complexityScore<5?o[0]++:e.complexityScore<8?o[1]++:o[2]++});let c=Math.round(o[0]/r.length*100),l=Math.round(o[1]/r.length*100),u=Math.round(o[2]/r.length*100);console.log(W(B.white.bold(`Complexity Distribution
1024
1024
 
1025
- `)+`${B.green.bold(`Low (1-4):`)} ${o[0]} tasks (${c}%)\n${B.yellow.bold(`Medium (5-7):`)} ${o[1]} tasks (${l}%)\n${B.red.bold(`High (8-10):`)} ${o[2]} tasks (${u}%)`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));let d=process.stdout.columns||100,f=Math.floor(d*.25),p=d-12-f-8-8-10,m=new K({head:[B.yellow.bold(`ID`),B.yellow.bold(`Title`),B.yellow.bold(`Score`),B.yellow.bold(`Subtasks`),B.yellow.bold(`Expansion Command`)],colWidths:[12,f,8,8,p],style:{head:[],border:[]},wordWrap:!0,wrapOnWordBoundary:!0});if(i.forEach(e=>{let t=`task-master expand --id=${e.taskId} --num=${e.recommendedSubtasks}${e.expansionPrompt?` --prompt="${e.expansionPrompt}"`:``}`;m.push([e.taskId,s(e.taskTitle,f-3),ml(e.complexityScore),e.recommendedSubtasks,B.cyan(t)])}),console.log(m.toString()),a.length>0){console.log(W(B.green.bold(`Simple Tasks (${a.length})`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:`green`,borderStyle:`round`}));let e=new K({head:[B.green.bold(`ID`),B.green.bold(`Title`),B.green.bold(`Score`),B.green.bold(`Reasoning`)],colWidths:[5,40,8,50],style:{head:[],border:[]}});a.forEach(t=>{e.push([t.taskId,s(t.taskTitle,37),ml(t.complexityScore),s(t.reasoning,47)])}),console.log(e.toString())}console.log(W(B.white.bold(`Suggested Actions:`)+`
1025
+ `)+`${B.green.bold(`Low (1-4):`)} ${o[0]} tasks (${c}%)\n${B.yellow.bold(`Medium (5-7):`)} ${o[1]} tasks (${l}%)\n${B.red.bold(`High (8-10):`)} ${o[2]} tasks (${u}%)`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));let d=process.stdout.columns||100,f=Math.floor(d*.25),p=d-12-f-8-8-10,m=new K({head:[B.yellow.bold(`ID`),B.yellow.bold(`Title`),B.yellow.bold(`Score`),B.yellow.bold(`Subtasks`),B.yellow.bold(`Expansion Command`)],colWidths:[12,f,8,8,p],style:{head:[],border:[]},wordWrap:!0,wrapOnWordBoundary:!0});if(i.forEach(e=>{let t=`task-master expand --id=${e.taskId} --num=${e.recommendedSubtasks}${e.expansionPrompt?` --prompt="${e.expansionPrompt}"`:``}`;m.push([e.taskId,s(e.taskTitle,f-3),bl(e.complexityScore),e.recommendedSubtasks,B.cyan(t)])}),console.log(m.toString()),a.length>0){console.log(W(B.green.bold(`Simple Tasks (${a.length})`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:`green`,borderStyle:`round`}));let e=new K({head:[B.green.bold(`ID`),B.green.bold(`Title`),B.green.bold(`Score`),B.green.bold(`Reasoning`)],colWidths:[5,40,8,50],style:{head:[],border:[]}});a.forEach(t=>{e.push([t.taskId,s(t.taskTitle,37),bl(t.complexityScore),s(t.reasoning,47)])}),console.log(e.toString())}console.log(W(B.white.bold(`Suggested Actions:`)+`
1026
1026
 
1027
- ${B.cyan(`1.`)} Expand all complex tasks: ${B.yellow(`task-master expand --all`)}\n${B.cyan(`2.`)} Expand a specific task: ${B.yellow(`task-master expand --id=<id>`)}\n${B.cyan(`3.`)} Regenerate with research: ${B.yellow(`task-master analyze-complexity --research`)}`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))}async function gl(e){console.log(W(B.yellow(`It looks like you've already generated tasks for this project.
1028
- `)+B.yellow(`Executing this command will overwrite any existing tasks.`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=nt.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(B.cyan(`Are you sure you wish to continue? (y/N): `),e)});return t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`}function _l(e){if(!e||e.length===0){console.log(B.yellow(`No API key status information available.`));return}let t=new K({head:[B.cyan(`Provider`),B.cyan(`CLI Key (.env)`),B.cyan(`MCP Key (mcp.json)`)],colWidths:[15,20,25],chars:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``}});e.forEach(({provider:e,cli:n,mcp:r})=>{let i=n?B.green(`✅ Found`):B.red(`❌ Missing`),a=r?B.green(`✅ Found`):B.red(`❌ Missing`),o=e.charAt(0).toUpperCase()+e.slice(1);t.push([o,i,a])}),console.log(B.bold(`
1029
- 🔑 API Key Status:`)),console.log(t.toString()),console.log(B.gray(` Note: Some providers (e.g., Azure, Ollama) may require additional endpoint configuration in ${l}.`))}const vl=(e,t)=>{if(e==null||e<=0)return`N/A`;let n=`${(e*100).toFixed(1)}%`,r=[...t.map(e=>e.sweScore).filter(e=>e!=null&&e>0)].sort((e,t)=>t-e),i=r.length,a=B.gray(`☆☆☆`);if(i>0){let t=Math.max(0,Math.floor(i/3)-1),n=Math.max(0,Math.floor(2*i/3)-1);a=e>=r[t]?B.yellow(`★★★`):e>=r[n]?B.yellow(`★★`)+B.gray(`☆`):B.yellow(`★`)+B.gray(`☆☆`)}return`${n} ${a}`},yl=e=>{if(!e)return`N/A`;if(e.input===0&&e.output===0)return B.green(`Free`);let t=e=>{if(e==null)return`N/A`;let t=Number.isInteger(e);return`$${e.toFixed(t?0:2)}`};return`${t(e.input)} in, ${t(e.output)} out`};function bl(e,t=[]){console.log(B.cyan.bold(`
1030
- Active Model Configuration:`));let n=e.activeModels,r=new K({head:[`Role`,`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>B.cyan.bold(e)),colWidths:[10,14,30,18,20],style:{head:[`cyan`,`bold`]}});r.push([B.white(`Main`),n.main.provider,n.main.modelId,vl(n.main.sweScore,t),yl(n.main.cost)]),r.push([B.white(`Research`),n.research.provider,n.research.modelId,vl(n.research.sweScore,t),yl(n.research.cost)]),n.fallback&&n.fallback.provider&&n.fallback.modelId?r.push([B.white(`Fallback`),n.fallback.provider,n.fallback.modelId,vl(n.fallback.sweScore,t),yl(n.fallback.cost)]):r.push([B.white(`Fallback`),B.gray(`-`),B.gray(`(Not Set)`),B.gray(`-`),B.gray(`-`)]),console.log(r.toString())}function xl(e){if(!e||e.length===0){console.log(B.gray(`
1027
+ ${B.cyan(`1.`)} Expand all complex tasks: ${B.yellow(`task-master expand --all`)}\n${B.cyan(`2.`)} Expand a specific task: ${B.yellow(`task-master expand --id=<id>`)}\n${B.cyan(`3.`)} Regenerate with research: ${B.yellow(`task-master analyze-complexity --research`)}`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))}async function Sl(e){console.log(W(B.yellow(`It looks like you've already generated tasks for this project.
1028
+ `)+B.yellow(`Executing this command will overwrite any existing tasks.`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=nt.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(B.cyan(`Are you sure you wish to continue? (y/N): `),e)});return t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`}function Cl(e){if(!e||e.length===0){console.log(B.yellow(`No API key status information available.`));return}let t=new K({head:[B.cyan(`Provider`),B.cyan(`CLI Key (.env)`),B.cyan(`MCP Key (mcp.json)`)],colWidths:[15,20,25],chars:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``}});e.forEach(({provider:e,cli:n,mcp:r})=>{let i=n?B.green(`✅ Found`):B.red(`❌ Missing`),a=r?B.green(`✅ Found`):B.red(`❌ Missing`),o=e.charAt(0).toUpperCase()+e.slice(1);t.push([o,i,a])}),console.log(B.bold(`
1029
+ 🔑 API Key Status:`)),console.log(t.toString()),console.log(B.gray(` Note: Some providers (e.g., Azure, Ollama) may require additional endpoint configuration in ${l}.`))}const wl=(e,t)=>{if(e==null||e<=0)return`N/A`;let n=`${(e*100).toFixed(1)}%`,r=[...t.map(e=>e.sweScore).filter(e=>e!=null&&e>0)].sort((e,t)=>t-e),i=r.length,a=B.gray(`☆☆☆`);if(i>0){let t=Math.max(0,Math.floor(i/3)-1),n=Math.max(0,Math.floor(2*i/3)-1);a=e>=r[t]?B.yellow(`★★★`):e>=r[n]?B.yellow(`★★`)+B.gray(`☆`):B.yellow(`★`)+B.gray(`☆☆`)}return`${n} ${a}`},Tl=e=>{if(!e)return`N/A`;if(e.input===0&&e.output===0)return B.green(`Free`);let t=e=>{if(e==null)return`N/A`;let t=Number.isInteger(e);return`$${e.toFixed(t?0:2)}`};return`${t(e.input)} in, ${t(e.output)} out`};function El(e,t=[]){console.log(B.cyan.bold(`
1030
+ Active Model Configuration:`));let n=e.activeModels,r=new K({head:[`Role`,`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>B.cyan.bold(e)),colWidths:[10,14,30,18,20],style:{head:[`cyan`,`bold`]}});r.push([B.white(`Main`),n.main.provider,n.main.modelId,wl(n.main.sweScore,t),Tl(n.main.cost)]),r.push([B.white(`Research`),n.research.provider,n.research.modelId,wl(n.research.sweScore,t),Tl(n.research.cost)]),n.fallback&&n.fallback.provider&&n.fallback.modelId?r.push([B.white(`Fallback`),n.fallback.provider,n.fallback.modelId,wl(n.fallback.sweScore,t),Tl(n.fallback.cost)]):r.push([B.white(`Fallback`),B.gray(`-`),B.gray(`(Not Set)`),B.gray(`-`),B.gray(`-`)]),console.log(r.toString())}function Dl(e){if(!e||e.length===0){console.log(B.gray(`
1031
1031
  (No other models available or all are configured)`));return}console.log(B.cyan.bold(`
1032
- Other Available Models:`));let t=new K({head:[`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>B.cyan.bold(e)),colWidths:[15,40,18,25],style:{head:[`cyan`,`bold`]}});e.forEach(n=>{t.push([n.provider,n.modelId,vl(n.sweScore,e),yl(n.cost)])}),console.log(t.toString()),console.log(W(B.white.bold(`Next Steps:`)+`
1032
+ Other Available Models:`));let t=new K({head:[`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>B.cyan.bold(e)),colWidths:[15,40,18,25],style:{head:[`cyan`,`bold`]}});e.forEach(n=>{t.push([n.provider,n.modelId,wl(n.sweScore,e),Tl(n.cost)])}),console.log(t.toString()),console.log(W(B.white.bold(`Next Steps:`)+`
1033
1033
  `+B.cyan(`1. Set main model: ${B.yellow(`task-master models --set-main <model_id>`)}`)+`
1034
1034
  `+B.cyan(`2. Set research model: ${B.yellow(`task-master models --set-research <model_id>`)}`)+`
1035
1035
  `+B.cyan(`3. Set fallback model: ${B.yellow(`task-master models --set-fallback <model_id>`)}`)+`
1036
1036
  `+B.cyan(`4. Run interactive setup: ${B.yellow(`task-master models --setup`)}`)+`
1037
- `+B.cyan(`5. Use custom ollama/openrouter models: ${B.yellow(`task-master models --openrouter|ollama --set-main|research|fallback <model_id>`)}`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}function Sl(e,t=`cli`){if(t!==`cli`&&t!==`text`||!e||L())return;let{modelUsed:n,providerName:r,inputTokens:i,outputTokens:a,totalTokens:o,totalCost:s,commandName:c,isUnknownCost:l}=e,u=B.bold.blue(`AI Usage Summary:`)+`
1038
- `;u+=B.gray(` Command: ${c}\n`),u+=B.gray(` Provider: ${r}\n`),u+=B.gray(` Model: ${n}\n`),u+=B.gray(` Tokens: ${o} (Input: ${i}, Output: ${a})\n`);let d=l?`Unknown`:`$${s.toFixed(6)}`;u+=B.gray(` Est. Cost: ${d}`),console.log(W(u,{padding:1,margin:{top:1},borderColor:`blue`,borderStyle:`round`,title:`💡 Telemetry`,titleAlignment:`center`}))}function Cl(e,t,n){if(L()||!e)return;let{highRelevance:r,mediumRelevance:i,recentTasks:a,allRelevantTasks:o}=e,c=B.white.bold(`Context Analysis`)+`
1037
+ `+B.cyan(`5. Use custom ollama/openrouter models: ${B.yellow(`task-master models --openrouter|ollama --set-main|research|fallback <model_id>`)}`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}function Ol(e,t=`cli`){if(t!==`cli`&&t!==`text`||!e||L())return;let{modelUsed:n,providerName:r,inputTokens:i,outputTokens:a,totalTokens:o,totalCost:s,commandName:c,isUnknownCost:l}=e,u=B.bold.blue(`AI Usage Summary:`)+`
1038
+ `;u+=B.gray(` Command: ${c}\n`),u+=B.gray(` Provider: ${r}\n`),u+=B.gray(` Model: ${n}\n`),u+=B.gray(` Tokens: ${o} (Input: ${i}, Output: ${a})\n`);let d=l?`Unknown`:`$${s.toFixed(6)}`;u+=B.gray(` Est. Cost: ${d}`),console.log(W(u,{padding:1,margin:{top:1},borderColor:`blue`,borderStyle:`round`,title:`💡 Telemetry`,titleAlignment:`center`}))}function kl(e,t,n){if(L()||!e)return;let{highRelevance:r,mediumRelevance:i,recentTasks:a,allRelevantTasks:o}=e,c=B.white.bold(`Context Analysis`)+`
1039
1039
 
1040
1040
  `;c+=B.gray(`Query: `)+B.white(`"${t}"`)+`
1041
1041
  `,c+=B.gray(`Context size: `)+B.cyan(`${n.toLocaleString()} characters`)+`
@@ -1052,27 +1052,27 @@ Other Available Models:`));let t=new K({head:[`Provider`,`Model ID`,`SWE Score`,
1052
1052
  `);let l=a.filter(e=>!r.some(t=>t.id===e.id)&&!i.some(t=>t.id===e.id));l.length>0&&(c+=B.cyan.bold(`🕒 Recent Tasks (for context):`)+`
1053
1053
  `,l.slice(0,2).forEach(e=>{c+=B.cyan(` • Task ${e.id}: ${s(e.title,50)}`)+`
1054
1054
  `}),l.length>2&&(c+=B.cyan(` • ... and ${l.length-2} more recent tasks`)+`
1055
- `)),console.log(W(c,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0},borderStyle:`round`,borderColor:`blue`,title:B.blue(`🔍 Context Gathering`),titleAlignment:`center`}))}function wl(e,t,n,r){console.log(B.red(`\n❌ Cannot move tasks from "${t}" to "${n}"`)),console.log(B.yellow(`
1055
+ `)),console.log(W(c,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0},borderStyle:`round`,borderColor:`blue`,title:B.blue(`🔍 Context Gathering`),titleAlignment:`center`}))}function Al(e,t,n,r){console.log(B.red(`\n❌ Cannot move tasks from "${t}" to "${n}"`)),console.log(B.yellow(`
1056
1056
  Cross-tag dependency conflicts detected:`)),e.length>0&&e.forEach(e=>{console.log(` • ${e.message}`)}),console.log(B.cyan(`
1057
- Resolution options:`)),console.log(` 1. Move with dependencies: task-master move --from=${r} --from-tag=${t} --to-tag=${n} --with-dependencies`),console.log(` 2. Break dependencies: task-master move --from=${r} --from-tag=${t} --to-tag=${n} --ignore-dependencies`),console.log(` 3. Validate and fix dependencies: task-master validate-dependencies && task-master fix-dependencies`),e.length>0&&console.log(` 4. Move dependencies first: task-master move --from=${e.map(e=>e.dependencyId).join(`,`)} --from-tag=${e[0].dependencyTag} --to-tag=${n}`)}function Tl(e){return e===null?`null`:e===void 0?`undefined`:e===``?`(empty)`:Ee(e)||`unknown`}function El(e,t,n){let r=Tl(e),i=e||`unknown`,a=i;if(i.includes(`.`)){let e=i.split(`.`);e.length===2&&e[0]&&e[1]?a=e[0]:(console.log(B.yellow(`\n⚠️ Warning: Unexpected taskId format "${i}". Using as-is for command suggestions.`)),a=i)}console.log(B.red(`\n❌ Cannot move subtask ${r} directly between tags`)),console.log(B.yellow(`
1057
+ Resolution options:`)),console.log(` 1. Move with dependencies: task-master move --from=${r} --from-tag=${t} --to-tag=${n} --with-dependencies`),console.log(` 2. Break dependencies: task-master move --from=${r} --from-tag=${t} --to-tag=${n} --ignore-dependencies`),console.log(` 3. Validate and fix dependencies: task-master validate-dependencies && task-master fix-dependencies`),e.length>0&&console.log(` 4. Move dependencies first: task-master move --from=${e.map(e=>e.dependencyId).join(`,`)} --from-tag=${e[0].dependencyTag} --to-tag=${n}`)}function jl(e){return e===null?`null`:e===void 0?`undefined`:e===``?`(empty)`:we(e)||`unknown`}function Ml(e,t,n){let r=jl(e),i=e||`unknown`,a=i;if(i.includes(`.`)){let e=i.split(`.`);e.length===2&&e[0]&&e[1]?a=e[0]:(console.log(B.yellow(`\n⚠️ Warning: Unexpected taskId format "${i}". Using as-is for command suggestions.`)),a=i)}console.log(B.red(`\n❌ Cannot move subtask ${r} directly between tags`)),console.log(B.yellow(`
1058
1058
  Subtask movement restriction:`)),console.log(` • Subtasks cannot be moved directly between tags`),console.log(` • They must be promoted to full tasks first`),console.log(` • Source tag: "${t}"`),console.log(` • Target tag: "${n}"`),console.log(B.cyan(`
1059
- Resolution options:`)),console.log(` 1. Promote subtask to full task: task-master remove-subtask --id=${r} --convert`),console.log(` 2. Then move the promoted task: task-master move --from=${a} --from-tag=${t} --to-tag=${n}`),console.log(` 3. Or move the parent task with all subtasks: task-master move --from=${a} --from-tag=${t} --to-tag=${n} --with-dependencies`)}function Dl(e,t,n){console.log(B.red(`
1059
+ Resolution options:`)),console.log(` 1. Promote subtask to full task: task-master remove-subtask --id=${r} --convert`),console.log(` 2. Then move the promoted task: task-master move --from=${a} --from-tag=${t} --to-tag=${n}`),console.log(` 3. Or move the parent task with all subtasks: task-master move --from=${a} --from-tag=${t} --to-tag=${n} --with-dependencies`)}function Nl(e,t,n){console.log(B.red(`
1060
1060
  ❌ Invalid tag combination`)),console.log(B.yellow(`
1061
1061
  Error details:`)),console.log(` • Source tag: "${e}"`),console.log(` • Target tag: "${t}"`),console.log(` • Reason: ${n}`),console.log(B.cyan(`
1062
- Resolution options:`)),console.log(` 1. Use different tags for cross-tag moves`),console.log(` 2. Use within-tag move: task-master move --from=<id> --to=<id> --tag=${e}`),console.log(` 3. Check available tags: task-master tags`)}function Ol(e=`general`){let t={"before-move":[`💡 Tip: Run "task-master validate-dependencies" to check for dependency issues before moving tasks`,`💡 Tip: Use "task-master fix-dependencies" to automatically resolve common dependency problems`,`💡 Tip: Consider using --with-dependencies flag to move dependent tasks together`],"after-error":[`🔧 Quick fix: Run "task-master validate-dependencies" to identify specific issues`,`🔧 Quick fix: Use "task-master fix-dependencies" to automatically resolve problems`,`🔧 Quick fix: Check "task-master show <id>" to see task dependencies before moving`],general:[`💡 Use "task-master validate-dependencies" to check for dependency issues`,`💡 Use "task-master fix-dependencies" to automatically resolve problems`,`💡 Use "task-master show <id>" to view task dependencies`,`💡 Use --with-dependencies flag to move dependent tasks together`]},n=t[e]||t.general;console.log(B.cyan(`
1063
- Helpful hints:`)),new Set(n).forEach(e=>{console.log(` ${e}`)})}var kl=class extends Error{constructor(e,t,n={}){super(t),this.name=`DependencyError`,this.code=e,this.data=n}};const Al={CANNOT_MOVE_SUBTASK:`CANNOT_MOVE_SUBTASK`,INVALID_TASK_ID:`INVALID_TASK_ID`,INVALID_SOURCE_TAG:`INVALID_SOURCE_TAG`,INVALID_TARGET_TAG:`INVALID_TARGET_TAG`};async function jl(e,t,n,r={}){z(`info`,`Adding dependency ${n} to task ${t}...`);let i=D(e,r.projectRoot,r.tag);(!i||!i.tasks)&&(z(`error`,`No valid tasks found in tasks.json`),process.exit(1));let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=Ee(n);S(i.tasks,o)||(z(`error`,`Dependency target ${o} does not exist in tasks.json`),process.exit(1));let s=null;if(typeof a==`string`&&a.includes(`.`)){let[e,t]=a.split(`.`).map(e=>parseInt(e,10)),n=i.tasks.find(t=>t.id===e);n||(z(`error`,`Parent task ${e} not found.`),process.exit(1)),n.subtasks||(z(`error`,`Parent task ${e} has no subtasks.`),process.exit(1)),s=n.subtasks.find(e=>e.id===t),s||(z(`error`,`Subtask ${a} not found.`),process.exit(1))}else s=i.tasks.find(e=>e.id===a),s||(z(`error`,`Task ${a} not found.`),process.exit(1));if(s.dependencies||=[],s.dependencies.some(e=>String(e)===String(o))){z(`warn`,`Dependency ${o} already exists in task ${a}.`);return}String(a)===String(o)&&(z(`error`,`Task ${a} cannot depend on itself.`),process.exit(1));let c=!1;if(typeof a==`string`&&typeof o==`string`&&a.includes(`.`)&&o.includes(`.`)){let[e]=a.split(`.`),[t]=o.split(`.`);c=a===o,z(`debug`,`Adding dependency between subtasks: ${a} depends on ${o}`),z(`debug`,`Parent IDs: ${e} and ${t}, Self-dependency check: ${c}`)}c&&(z(`error`,`Subtask ${a} cannot depend on itself.`),process.exit(1));let l=[a];Nl(i.tasks,o,l)?(z(`error`,`Cannot add dependency ${o} to task ${a} as it would create a circular dependency.`),process.exit(1)):(s.dependencies.push(o),s.dependencies.sort((e,t)=>{if(typeof e==`number`&&typeof t==`number`)return e-t;if(typeof e==`string`&&typeof t==`string`){let[n,r]=e.split(`.`).map(Number),[i,a]=t.split(`.`).map(Number);return n===i?r-a:n-i}else if(typeof e==`number`)return-1;else return 1}),y(e,i,r.projectRoot,r.tag),z(`success`,`Added dependency ${o} to task ${a}`),L()||console.log(W(B.green(`Successfully added dependency:
1062
+ Resolution options:`)),console.log(` 1. Use different tags for cross-tag moves`),console.log(` 2. Use within-tag move: task-master move --from=<id> --to=<id> --tag=${e}`),console.log(` 3. Check available tags: task-master tags`)}function Pl(e=`general`){let t={"before-move":[`💡 Tip: Run "task-master validate-dependencies" to check for dependency issues before moving tasks`,`💡 Tip: Use "task-master fix-dependencies" to automatically resolve common dependency problems`,`💡 Tip: Consider using --with-dependencies flag to move dependent tasks together`],"after-error":[`🔧 Quick fix: Run "task-master validate-dependencies" to identify specific issues`,`🔧 Quick fix: Use "task-master fix-dependencies" to automatically resolve problems`,`🔧 Quick fix: Check "task-master show <id>" to see task dependencies before moving`],general:[`💡 Use "task-master validate-dependencies" to check for dependency issues`,`💡 Use "task-master fix-dependencies" to automatically resolve problems`,`💡 Use "task-master show <id>" to view task dependencies`,`💡 Use --with-dependencies flag to move dependent tasks together`]},n=t[e]||t.general;console.log(B.cyan(`
1063
+ Helpful hints:`)),new Set(n).forEach(e=>{console.log(` ${e}`)})}var Fl=class extends Error{constructor(e,t,n={}){super(t),this.name=`DependencyError`,this.code=e,this.data=n}};const Il={CANNOT_MOVE_SUBTASK:`CANNOT_MOVE_SUBTASK`,INVALID_TASK_ID:`INVALID_TASK_ID`,INVALID_SOURCE_TAG:`INVALID_SOURCE_TAG`,INVALID_TARGET_TAG:`INVALID_TARGET_TAG`};async function Ll(e,t,n,r={}){z(`info`,`Adding dependency ${n} to task ${t}...`);let i=E(e,r.projectRoot,r.tag);(!i||!i.tasks)&&(z(`error`,`No valid tasks found in tasks.json`),process.exit(1));let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=we(n);x(i.tasks,o)||(z(`error`,`Dependency target ${o} does not exist in tasks.json`),process.exit(1));let s=null;if(typeof a==`string`&&a.includes(`.`)){let[e,t]=a.split(`.`).map(e=>parseInt(e,10)),n=i.tasks.find(t=>t.id===e);n||(z(`error`,`Parent task ${e} not found.`),process.exit(1)),n.subtasks||(z(`error`,`Parent task ${e} has no subtasks.`),process.exit(1)),s=n.subtasks.find(e=>e.id===t),s||(z(`error`,`Subtask ${a} not found.`),process.exit(1))}else s=i.tasks.find(e=>e.id===a),s||(z(`error`,`Task ${a} not found.`),process.exit(1));if(s.dependencies||=[],s.dependencies.some(e=>String(e)===String(o))){z(`warn`,`Dependency ${o} already exists in task ${a}.`);return}String(a)===String(o)&&(z(`error`,`Task ${a} cannot depend on itself.`),process.exit(1));let c=!1;if(typeof a==`string`&&typeof o==`string`&&a.includes(`.`)&&o.includes(`.`)){let[e]=a.split(`.`),[t]=o.split(`.`);c=a===o,z(`debug`,`Adding dependency between subtasks: ${a} depends on ${o}`),z(`debug`,`Parent IDs: ${e} and ${t}, Self-dependency check: ${c}`)}c&&(z(`error`,`Subtask ${a} cannot depend on itself.`),process.exit(1));let l=[a];zl(i.tasks,o,l)?(z(`error`,`Cannot add dependency ${o} to task ${a} as it would create a circular dependency.`),process.exit(1)):(s.dependencies.push(o),s.dependencies.sort((e,t)=>{if(typeof e==`number`&&typeof t==`number`)return e-t;if(typeof e==`string`&&typeof t==`string`){let[n,r]=e.split(`.`).map(Number),[i,a]=t.split(`.`).map(Number);return n===i?r-a:n-i}else if(typeof e==`number`)return-1;else return 1}),y(e,i,r.projectRoot,r.tag),z(`success`,`Added dependency ${o} to task ${a}`),L()||console.log(W(B.green(`Successfully added dependency:
1064
1064
 
1065
- `)+`Task ${B.bold(a)} now depends on ${B.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),z(`info`,`Task files regenerated with updated dependencies.`))}async function Ml(e,t,n,r={}){z(`info`,`Removing dependency ${n} from task ${t}...`);let i=D(e,r.projectRoot,r.tag);(!i||!i.tasks)&&(z(`error`,`No valid tasks found.`),process.exit(1));let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=Ee(n),s=null,c=!1;if(typeof a==`string`&&a.includes(`.`)){let[e,t]=a.split(`.`).map(e=>parseInt(e,10)),n=i.tasks.find(t=>t.id===e);n||(z(`error`,`Parent task ${e} not found.`),process.exit(1)),n.subtasks||(z(`error`,`Parent task ${e} has no subtasks.`),process.exit(1)),s=n.subtasks.find(e=>e.id===t),c=!0,s||(z(`error`,`Subtask ${a} not found.`),process.exit(1))}else s=i.tasks.find(e=>e.id===a),s||(z(`error`,`Task ${a} not found.`),process.exit(1));if(!s.dependencies||s.dependencies.length===0){z(`info`,`Task ${a} has no dependencies, nothing to remove.`);return}let l=String(o),u=s.dependencies.findIndex(e=>{if(String(e)===l)return!0;if(typeof e==`number`&&e<100&&c){let[t]=a.split(`.`);if(`${t}.${e}`===l)return!0}return!1});if(u===-1){z(`info`,`Task ${a} does not depend on ${o}, no changes made.`);return}s.dependencies.splice(u,1),y(e,i,r.projectRoot,r.tag),z(`success`,`Removed dependency: Task ${a} no longer depends on ${o}`),L()||console.log(W(B.green(`Successfully removed dependency:
1065
+ `)+`Task ${B.bold(a)} now depends on ${B.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),z(`info`,`Task files regenerated with updated dependencies.`))}async function Rl(e,t,n,r={}){z(`info`,`Removing dependency ${n} from task ${t}...`);let i=E(e,r.projectRoot,r.tag);(!i||!i.tasks)&&(z(`error`,`No valid tasks found.`),process.exit(1));let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=we(n),s=null,c=!1;if(typeof a==`string`&&a.includes(`.`)){let[e,t]=a.split(`.`).map(e=>parseInt(e,10)),n=i.tasks.find(t=>t.id===e);n||(z(`error`,`Parent task ${e} not found.`),process.exit(1)),n.subtasks||(z(`error`,`Parent task ${e} has no subtasks.`),process.exit(1)),s=n.subtasks.find(e=>e.id===t),c=!0,s||(z(`error`,`Subtask ${a} not found.`),process.exit(1))}else s=i.tasks.find(e=>e.id===a),s||(z(`error`,`Task ${a} not found.`),process.exit(1));if(!s.dependencies||s.dependencies.length===0){z(`info`,`Task ${a} has no dependencies, nothing to remove.`);return}let l=String(o),u=s.dependencies.findIndex(e=>{if(String(e)===l)return!0;if(typeof e==`number`&&e<100&&c){let[t]=a.split(`.`);if(`${t}.${e}`===l)return!0}return!1});if(u===-1){z(`info`,`Task ${a} does not depend on ${o}, no changes made.`);return}s.dependencies.splice(u,1),y(e,i,r.projectRoot,r.tag),z(`success`,`Removed dependency: Task ${a} no longer depends on ${o}`),L()||console.log(W(B.green(`Successfully removed dependency:
1066
1066
 
1067
- `)+`Task ${B.bold(a)} no longer depends on ${B.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}function Nl(e,t,n=[]){let r=String(t);if(n.some(e=>String(e)===r))return!0;let i=null,a=null;if(r.includes(`.`)){let[t,n]=r.split(`.`).map(Number),o=e.find(e=>e.id===t);a=t,o&&o.subtasks&&(i=o.subtasks.find(e=>e.id===n))}else{let t=parseInt(r,10);i=e.find(e=>e.id===t||String(e.id)===r)}if(!i||!i.dependencies||i.dependencies.length===0)return!1;let o=[...n,r];return i.dependencies.some(t=>{let n=String(t);return typeof t==`number`&&a!==null&&(n=`${a}.${t}`),Nl(e,n,o)})}function Pl(e){let t=[];return e.forEach(n=>{n.dependencies&&(n.dependencies.forEach(r=>{if(String(r)===String(n.id)){t.push({type:`self`,taskId:n.id,message:`Task ${n.id} depends on itself`});return}S(e,r)||t.push({type:`missing`,taskId:n.id,dependencyId:r,message:`Task ${n.id} depends on non-existent task ${r}`})}),Nl(e,n.id)&&t.push({type:`circular`,taskId:n.id,message:`Task ${n.id} is part of a circular dependency chain`}),n.subtasks&&n.subtasks.length>0&&n.subtasks.forEach(r=>{if(!r.dependencies)return;let i=`${n.id}.${r.id}`;r.dependencies.forEach(n=>{if(String(n)===String(i)||typeof n==`number`&&n===r.id){t.push({type:`self`,taskId:i,message:`Subtask ${i} depends on itself`});return}S(e,n)||t.push({type:`missing`,taskId:i,dependencyId:n,message:`Subtask ${i} depends on non-existent task/subtask ${n}`})}),Nl(e,i)&&t.push({type:`circular`,taskId:i,message:`Subtask ${i} is part of a circular dependency chain`})}))}),{valid:t.length===0,issues:t}}async function Fl(e,t={}){let{context:n={}}=t;z(`info`,`Checking for invalid dependencies in task files...`);let r=D(e,n.projectRoot,n.tag);(!r||!r.tasks)&&(z(`error`,`No valid tasks found in tasks.json`),process.exit(1));let i=r.tasks.length,a=0;r.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&(a+=e.subtasks.length)}),z(`info`,`Analyzing dependencies for ${i} tasks and ${a} subtasks...`);try{let e=Pl(r.tasks);e.valid?(z(`success`,`No invalid dependencies found - all dependencies are valid`),L()||console.log(W(B.green(`All Dependencies Are Valid
1067
+ `)+`Task ${B.bold(a)} no longer depends on ${B.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}function zl(e,t,n=[]){let r=String(t);if(n.some(e=>String(e)===r))return!0;let i=null,a=null;if(r.includes(`.`)){let[t,n]=r.split(`.`).map(Number),o=e.find(e=>e.id===t);a=t,o&&o.subtasks&&(i=o.subtasks.find(e=>e.id===n))}else{let t=parseInt(r,10);i=e.find(e=>e.id===t||String(e.id)===r)}if(!i||!i.dependencies||i.dependencies.length===0)return!1;let o=[...n,r];return i.dependencies.some(t=>{let n=String(t);return typeof t==`number`&&a!==null&&(n=`${a}.${t}`),zl(e,n,o)})}function Bl(e){let t=[];return e.forEach(n=>{n.dependencies&&(n.dependencies.forEach(r=>{if(String(r)===String(n.id)){t.push({type:`self`,taskId:n.id,message:`Task ${n.id} depends on itself`});return}x(e,r)||t.push({type:`missing`,taskId:n.id,dependencyId:r,message:`Task ${n.id} depends on non-existent task ${r}`})}),zl(e,n.id)&&t.push({type:`circular`,taskId:n.id,message:`Task ${n.id} is part of a circular dependency chain`}),n.subtasks&&n.subtasks.length>0&&n.subtasks.forEach(r=>{if(!r.dependencies)return;let i=`${n.id}.${r.id}`;r.dependencies.forEach(n=>{if(String(n)===String(i)||typeof n==`number`&&n===r.id){t.push({type:`self`,taskId:i,message:`Subtask ${i} depends on itself`});return}x(e,n)||t.push({type:`missing`,taskId:i,dependencyId:n,message:`Subtask ${i} depends on non-existent task/subtask ${n}`})}),zl(e,i)&&t.push({type:`circular`,taskId:i,message:`Subtask ${i} is part of a circular dependency chain`})}))}),{valid:t.length===0,issues:t}}async function Vl(e,t={}){let{context:n={}}=t;z(`info`,`Checking for invalid dependencies in task files...`);let r=E(e,n.projectRoot,n.tag);(!r||!r.tasks)&&(z(`error`,`No valid tasks found in tasks.json`),process.exit(1));let i=r.tasks.length,a=0;r.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&(a+=e.subtasks.length)}),z(`info`,`Analyzing dependencies for ${i} tasks and ${a} subtasks...`);try{let e=Bl(r.tasks);e.valid?(z(`success`,`No invalid dependencies found - all dependencies are valid`),L()||console.log(W(B.green(`All Dependencies Are Valid
1068
1068
 
1069
- `)+`${B.cyan(`Tasks checked:`)} ${i}\n${B.cyan(`Subtasks checked:`)} ${a}\n${B.cyan(`Total dependencies verified:`)} ${Il(r.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(z(`error`,`Dependency validation failed. Found ${e.issues.length} issue(s):`),e.issues.forEach(e=>{let t=` [${e.type.toUpperCase()}] Task ${e.taskId}: ${e.message}`;e.dependencyId&&(t+=` (Dependency: ${e.dependencyId})`),z(`error`,t)}),L()||console.log(W(B.red(`Dependency Validation FAILED
1069
+ `)+`${B.cyan(`Tasks checked:`)} ${i}\n${B.cyan(`Subtasks checked:`)} ${a}\n${B.cyan(`Total dependencies verified:`)} ${Hl(r.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(z(`error`,`Dependency validation failed. Found ${e.issues.length} issue(s):`),e.issues.forEach(e=>{let t=` [${e.type.toUpperCase()}] Task ${e.taskId}: ${e.message}`;e.dependencyId&&(t+=` (Dependency: ${e.dependencyId})`),z(`error`,t)}),L()||console.log(W(B.red(`Dependency Validation FAILED
1070
1070
 
1071
- `)+`${B.cyan(`Tasks checked:`)} ${i}\n${B.cyan(`Subtasks checked:`)} ${a}\n${B.red(`Issues found:`)} ${e.issues.length}`,{padding:1,borderColor:`red`,borderStyle:`round`,margin:{top:1,bottom:1}})))}catch(e){z(`error`,`Error validating dependencies:`,e),process.exit(1)}}function Il(e){let t=0;return e.forEach(e=>{e.dependencies&&Array.isArray(e.dependencies)&&(t+=e.dependencies.length),e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(e=>{e.dependencies&&Array.isArray(e.dependencies)&&(t+=e.dependencies.length)})}),t}async function Ll(e,t={}){let{context:n={}}=t;z(`info`,`Checking for and fixing invalid dependencies in tasks.json...`);try{let t=D(e,n.projectRoot,n.tag);(!t||!t.tasks)&&(z(`error`,`No valid tasks found in tasks.json`),process.exit(1));let r=JSON.parse(JSON.stringify(t)),i={nonExistentDependenciesRemoved:0,selfDependenciesRemoved:0,duplicateDependenciesRemoved:0,circularDependenciesFixed:0,tasksFixed:0,subtasksFixed:0};t.tasks.forEach(e=>{if(e.dependencies&&Array.isArray(e.dependencies)){let t=new Set,n=e.dependencies.length;e.dependencies=e.dependencies.filter(n=>{let r=String(n);return t.has(r)?(z(`info`,`Removing duplicate dependency from task ${e.id}: ${n}`),i.duplicateDependenciesRemoved++,!1):(t.add(r),!0)}),e.dependencies.length<n&&i.tasksFixed++}e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let n=new Set,r=t.dependencies.length;t.dependencies=t.dependencies.filter(r=>{let a=String(r);return typeof r==`number`&&r<100&&(a=`${e.id}.${r}`),n.has(a)?(z(`info`,`Removing duplicate dependency from subtask ${e.id}.${t.id}: ${r}`),i.duplicateDependenciesRemoved++,!1):(n.add(a),!0)}),t.dependencies.length<r&&i.subtasksFixed++}})});let a=new Set(t.tasks.map(e=>e.id)),o=new Set;t.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{o.add(`${e.id}.${t.id}`)})}),t.tasks.forEach(e=>{if(e.dependencies&&Array.isArray(e.dependencies)){let t=e.dependencies.length;e.dependencies=e.dependencies.filter(t=>{if(typeof t==`string`&&t.includes(`.`))return o.has(t)?!0:(z(`info`,`Removing invalid subtask dependency from task ${e.id}: ${t} (subtask does not exist)`),i.nonExistentDependenciesRemoved++,!1);{let n=typeof t==`string`?parseInt(t,10):t;return a.has(n)?!0:(z(`info`,`Removing invalid task dependency from task ${e.id}: ${t} (task does not exist)`),i.nonExistentDependenciesRemoved++,!1)}}),e.dependencies.length<t&&i.tasksFixed++}e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let n=t.dependencies.length,r=`${e.id}.${t.id}`;t.dependencies.some(e=>typeof e==`string`&&e.includes(`.`)?e===r:typeof e==`number`&&e<100?e===t.id:!1)&&(t.dependencies=t.dependencies.filter(t=>(typeof t==`number`&&t<100?`${e.id}.${t}`:String(t))===r?(z(`info`,`Removing self-dependency from subtask ${r}`),i.selfDependenciesRemoved++,!1):!0)),t.dependencies=t.dependencies.filter(t=>{if(typeof t==`string`&&t.includes(`.`))return o.has(t)?!0:(z(`info`,`Removing invalid subtask dependency from subtask ${r}: ${t} (subtask does not exist)`),i.nonExistentDependenciesRemoved++,!1);let n=typeof t==`number`?t:parseInt(t,10);if(n<100){let t=`${e.id}.${n}`;return o.has(t)?!0:(z(`info`,`Removing invalid subtask dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}return a.has(n)?!0:(z(`info`,`Removing invalid task dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}),t.dependencies.length<n&&i.subtasksFixed++}})}),z(`info`,`Checking for circular dependencies...`);let s=new Map;t.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{let n=`${e.id}.${t.id}`;if(t.dependencies&&Array.isArray(t.dependencies)){let r=t.dependencies.map(t=>typeof t==`string`&&t.includes(`.`)?t:typeof t==`number`&&t<100?`${e.id}.${t}`:String(t));s.set(n,r)}else s.set(n,[])})});for(let[e,n]of s.entries()){let n=we(e,s,new Set,new Set);if(n.length>0){let[r,a]=e.split(`.`).map(e=>Number(e)),o=t.tasks.find(e=>e.id===r);if(o&&o.subtasks){let t=o.subtasks.find(e=>e.id===a);if(t&&t.dependencies){let a=t.dependencies.length,o=n.map(e=>{if(e.includes(`.`)){let[t,n]=e.split(`.`).map(e=>Number(e));return t===r?n:e}return Number(e)});t.dependencies=t.dependencies.filter(t=>{let n=typeof t==`number`&&t<100?`${r}.${t}`:String(t);return o.includes(t)||o.includes(n)?(z(`info`,`Breaking circular dependency: Removing ${n} from subtask ${e}`),i.circularDependenciesFixed++,!1):!0}),t.dependencies.length<a&&i.subtasksFixed++}}}}JSON.stringify(t)===JSON.stringify(r)?z(`info`,`No changes needed to fix dependencies`):(y(e,t,n.projectRoot,n.tag),z(`success`,`Fixed dependency issues in tasks.json`),z(`info`,`Regenerating task files to reflect dependency changes...`));let c=i.nonExistentDependenciesRemoved+i.selfDependenciesRemoved+i.duplicateDependenciesRemoved+i.circularDependenciesFixed;L()||(c>0?(z(`success`,`Fixed ${c} dependency issues in total!`),console.log(W(B.green(`Dependency Fixes Summary:
1071
+ `)+`${B.cyan(`Tasks checked:`)} ${i}\n${B.cyan(`Subtasks checked:`)} ${a}\n${B.red(`Issues found:`)} ${e.issues.length}`,{padding:1,borderColor:`red`,borderStyle:`round`,margin:{top:1,bottom:1}})))}catch(e){z(`error`,`Error validating dependencies:`,e),process.exit(1)}}function Hl(e){let t=0;return e.forEach(e=>{e.dependencies&&Array.isArray(e.dependencies)&&(t+=e.dependencies.length),e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(e=>{e.dependencies&&Array.isArray(e.dependencies)&&(t+=e.dependencies.length)})}),t}async function Ul(e,t={}){let{context:n={}}=t;z(`info`,`Checking for and fixing invalid dependencies in tasks.json...`);try{let t=E(e,n.projectRoot,n.tag);(!t||!t.tasks)&&(z(`error`,`No valid tasks found in tasks.json`),process.exit(1));let r=JSON.parse(JSON.stringify(t)),i={nonExistentDependenciesRemoved:0,selfDependenciesRemoved:0,duplicateDependenciesRemoved:0,circularDependenciesFixed:0,tasksFixed:0,subtasksFixed:0};t.tasks.forEach(e=>{if(e.dependencies&&Array.isArray(e.dependencies)){let t=new Set,n=e.dependencies.length;e.dependencies=e.dependencies.filter(n=>{let r=String(n);return t.has(r)?(z(`info`,`Removing duplicate dependency from task ${e.id}: ${n}`),i.duplicateDependenciesRemoved++,!1):(t.add(r),!0)}),e.dependencies.length<n&&i.tasksFixed++}e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let n=new Set,r=t.dependencies.length;t.dependencies=t.dependencies.filter(r=>{let a=String(r);return typeof r==`number`&&r<100&&(a=`${e.id}.${r}`),n.has(a)?(z(`info`,`Removing duplicate dependency from subtask ${e.id}.${t.id}: ${r}`),i.duplicateDependenciesRemoved++,!1):(n.add(a),!0)}),t.dependencies.length<r&&i.subtasksFixed++}})});let a=new Set(t.tasks.map(e=>e.id)),o=new Set;t.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{o.add(`${e.id}.${t.id}`)})}),t.tasks.forEach(e=>{if(e.dependencies&&Array.isArray(e.dependencies)){let t=e.dependencies.length;e.dependencies=e.dependencies.filter(t=>{if(typeof t==`string`&&t.includes(`.`))return o.has(t)?!0:(z(`info`,`Removing invalid subtask dependency from task ${e.id}: ${t} (subtask does not exist)`),i.nonExistentDependenciesRemoved++,!1);{let n=typeof t==`string`?parseInt(t,10):t;return a.has(n)?!0:(z(`info`,`Removing invalid task dependency from task ${e.id}: ${t} (task does not exist)`),i.nonExistentDependenciesRemoved++,!1)}}),e.dependencies.length<t&&i.tasksFixed++}e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let n=t.dependencies.length,r=`${e.id}.${t.id}`;t.dependencies.some(e=>typeof e==`string`&&e.includes(`.`)?e===r:typeof e==`number`&&e<100?e===t.id:!1)&&(t.dependencies=t.dependencies.filter(t=>(typeof t==`number`&&t<100?`${e.id}.${t}`:String(t))===r?(z(`info`,`Removing self-dependency from subtask ${r}`),i.selfDependenciesRemoved++,!1):!0)),t.dependencies=t.dependencies.filter(t=>{if(typeof t==`string`&&t.includes(`.`))return o.has(t)?!0:(z(`info`,`Removing invalid subtask dependency from subtask ${r}: ${t} (subtask does not exist)`),i.nonExistentDependenciesRemoved++,!1);let n=typeof t==`number`?t:parseInt(t,10);if(n<100){let t=`${e.id}.${n}`;return o.has(t)?!0:(z(`info`,`Removing invalid subtask dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}return a.has(n)?!0:(z(`info`,`Removing invalid task dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}),t.dependencies.length<n&&i.subtasksFixed++}})}),z(`info`,`Checking for circular dependencies...`);let s=new Map;t.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{let n=`${e.id}.${t.id}`;if(t.dependencies&&Array.isArray(t.dependencies)){let r=t.dependencies.map(t=>typeof t==`string`&&t.includes(`.`)?t:typeof t==`number`&&t<100?`${e.id}.${t}`:String(t));s.set(n,r)}else s.set(n,[])})});for(let[e,n]of s.entries()){let n=Se(e,s,new Set,new Set);if(n.length>0){let[r,a]=e.split(`.`).map(e=>Number(e)),o=t.tasks.find(e=>e.id===r);if(o&&o.subtasks){let t=o.subtasks.find(e=>e.id===a);if(t&&t.dependencies){let a=t.dependencies.length,o=n.map(e=>{if(e.includes(`.`)){let[t,n]=e.split(`.`).map(e=>Number(e));return t===r?n:e}return Number(e)});t.dependencies=t.dependencies.filter(t=>{let n=typeof t==`number`&&t<100?`${r}.${t}`:String(t);return o.includes(t)||o.includes(n)?(z(`info`,`Breaking circular dependency: Removing ${n} from subtask ${e}`),i.circularDependenciesFixed++,!1):!0}),t.dependencies.length<a&&i.subtasksFixed++}}}}JSON.stringify(t)===JSON.stringify(r)?z(`info`,`No changes needed to fix dependencies`):(y(e,t,n.projectRoot,n.tag),z(`success`,`Fixed dependency issues in tasks.json`),z(`info`,`Regenerating task files to reflect dependency changes...`));let c=i.nonExistentDependenciesRemoved+i.selfDependenciesRemoved+i.duplicateDependenciesRemoved+i.circularDependenciesFixed;L()||(c>0?(z(`success`,`Fixed ${c} dependency issues in total!`),console.log(W(B.green(`Dependency Fixes Summary:
1072
1072
 
1073
1073
  `)+`${B.cyan(`Invalid dependencies removed:`)} ${i.nonExistentDependenciesRemoved}\n${B.cyan(`Self-dependencies removed:`)} ${i.selfDependenciesRemoved}\n${B.cyan(`Duplicate dependencies removed:`)} ${i.duplicateDependenciesRemoved}\n${B.cyan(`Circular dependencies fixed:`)} ${i.circularDependenciesFixed}\n\n${B.cyan(`Tasks fixed:`)} ${i.tasksFixed}\n${B.cyan(`Subtasks fixed:`)} ${i.subtasksFixed}\n`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(z(`success`,`No dependency issues found - all dependencies are valid`),console.log(W(B.green(`All Dependencies Are Valid
1074
1074
 
1075
- `)+`${B.cyan(`Tasks checked:`)} ${t.tasks.length}\n${B.cyan(`Total dependencies verified:`)} ${Il(t.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))))}catch(e){z(`error`,`Error in fix-dependencies command:`,e),process.exit(1)}}function Rl(e,t,n,r=!1){let i=parseInt(e,10),a=n.find(e=>e.id===i);if(a&&a.subtasks&&Array.isArray(a.subtasks)){let n=a.subtasks.find(e=>r?String(e.id)===String(t):e.id===t);if(n)return{...n,id:`${e}.${n.id}`}}return null}function zl(e,t,n){if(!e)return null;let r=String(e),i=null;if(i=n.find(e=>String(e.id)===r),!i&&r.includes(`.`)){let[e,t]=r.split(`.`);i=Rl(e,t,n,!0)}if(!i&&!isNaN(e)){let r=parseInt(e,10);if(t&&typeof t==`string`&&t.includes(`.`)){let[e]=t.split(`.`);i=Rl(e,r,n,!1)}}return i}function Bl(e,t,n){let r=[];return!Array.isArray(e.dependencies)||e.dependencies.length===0||e.dependencies.filter(e=>e!=null).forEach(i=>{let a=zl(i,e.id,n);a&&a.tag!==t&&r.push({taskId:e.id,dependencyId:i,dependencyTag:a.tag,message:`Task ${e.id} depends on ${i} (in ${a.tag})`})}),r}function Vl(e,t,n,r){if(!Array.isArray(e))throw Error(`Source tasks parameter must be an array`);if(!t||typeof t!=`string`)throw Error(`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw Error(`Target tag must be a valid string`);if(!Array.isArray(r))throw Error(`All tasks parameter must be an array`);let i=[];return e.forEach(e=>{if(!e||typeof e!=`object`||!Array.isArray(e.dependencies)||e.dependencies.length===0)return;let t=Bl(e,n,r);i.push(...t)}),i}function Hl(e,t,n){if(!e||typeof e!=`string`)throw new kl(Al.INVALID_TASK_ID,`Task ID must be a valid string`);if(!t||typeof t!=`string`)throw new kl(Al.INVALID_SOURCE_TAG,`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw new kl(Al.INVALID_TARGET_TAG,`Target tag must be a valid string`);if(e.includes(`.`))throw new kl(Al.CANNOT_MOVE_SUBTASK,`Cannot move subtask ${e} directly between tags.
1075
+ `)+`${B.cyan(`Tasks checked:`)} ${t.tasks.length}\n${B.cyan(`Total dependencies verified:`)} ${Hl(t.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))))}catch(e){z(`error`,`Error in fix-dependencies command:`,e),process.exit(1)}}function Wl(e,t,n,r=!1){let i=parseInt(e,10),a=n.find(e=>e.id===i);if(a&&a.subtasks&&Array.isArray(a.subtasks)){let n=a.subtasks.find(e=>r?String(e.id)===String(t):e.id===t);if(n)return{...n,id:`${e}.${n.id}`}}return null}function Gl(e,t,n){if(!e)return null;let r=String(e),i=null;if(i=n.find(e=>String(e.id)===r),!i&&r.includes(`.`)){let[e,t]=r.split(`.`);i=Wl(e,t,n,!0)}if(!i&&!isNaN(e)){let r=parseInt(e,10);if(t&&typeof t==`string`&&t.includes(`.`)){let[e]=t.split(`.`);i=Wl(e,r,n,!1)}}return i}function Kl(e,t,n){let r=[];return!Array.isArray(e.dependencies)||e.dependencies.length===0||e.dependencies.filter(e=>e!=null).forEach(i=>{let a=Gl(i,e.id,n);a&&a.tag!==t&&r.push({taskId:e.id,dependencyId:i,dependencyTag:a.tag,message:`Task ${e.id} depends on ${i} (in ${a.tag})`})}),r}function ql(e,t,n,r){if(!Array.isArray(e))throw Error(`Source tasks parameter must be an array`);if(!t||typeof t!=`string`)throw Error(`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw Error(`Target tag must be a valid string`);if(!Array.isArray(r))throw Error(`All tasks parameter must be an array`);let i=[];return e.forEach(e=>{if(!e||typeof e!=`object`||!Array.isArray(e.dependencies)||e.dependencies.length===0)return;let t=Kl(e,n,r);i.push(...t)}),i}function Jl(e,t,n){if(!e||typeof e!=`string`)throw new Fl(Il.INVALID_TASK_ID,`Task ID must be a valid string`);if(!t||typeof t!=`string`)throw new Fl(Il.INVALID_SOURCE_TAG,`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw new Fl(Il.INVALID_TARGET_TAG,`Target tag must be a valid string`);if(e.includes(`.`))throw new Fl(Il.CANNOT_MOVE_SUBTASK,`Cannot move subtask ${e} directly between tags.
1076
1076
 
1077
1077
  First promote it to a full task using:
1078
- task-master remove-subtask --id=${e} --convert`,{taskId:e,sourceTag:t,targetTag:n})}export{Zi as $,Dc as A,co as B,el as C,Kn as Ct,Kc as D,Jc as E,Fo as F,io as G,oo as H,Lo as I,Ka as J,no as K,ho as L,wc as M,Sc as N,Gc as O,bc as P,Na as Q,fo as R,nl as S,Xn as St,Xc as T,Dt as Tt,ao as U,uo as V,so as W,Va as X,Wa as Y,za as Z,il as _,Lr as _t,gl as a,ki as at,$ as b,Tr as bt,xl as c,Kr as ct,al as d,Zr as dt,Yi as et,Ol as f,$r as ft,El as g,Gr as gt,bl as h,Xr as ht,Fl as i,Di as it,Ec as j,Rc as k,hl as l,ti as lt,Dl as m,ei as mt,Ll as n,Ai as nt,_l as o,yi as ot,pl as p,Yr as pt,Ja as q,Ml as r,Oi as rt,ol as s,Qr as st,jl as t,Ki as tt,wl as u,qr as ut,dl as v,Ir as vt,Qc as w,X as wt,rl as x,hr as xt,sl as y,Er as yt,lo as z};
1078
+ task-master remove-subtask --id=${e} --convert`,{taskId:e,sourceTag:t,targetTag:n})}export{ra as $,Nc as A,ho as B,ol as C,Jn as Ct,Qc as D,St as Dt,el as E,xt as Et,Vo as F,uo as G,po as H,Uo as I,Qa as J,co as K,xo as L,Ac as M,Oc as N,Zc as O,Ec as P,za as Q,vo as R,cl as S,Qn as St,nl as T,kt as Tt,fo as U,_o as V,mo as W,qa as X,Xa as Y,Ga as Z,ul as _,zr as _t,Sl as a,ji as at,$ as b,Dr as bt,Dl as c,Jr as ct,dl as d,$r as dt,ta as et,Pl as f,ti as ft,Ml as g,qr as gt,El as h,Qr as ht,Vl as i,ki as it,Mc as j,Wc as k,xl as l,ri as lt,Nl as m,ni as mt,Ul as n,Mi as nt,Cl as o,xi as ot,yl as p,Zr as pt,eo as q,Rl as r,Ai as rt,fl as s,ei as st,Ll as t,Ji as tt,Al as u,Yr as ut,_l as v,Rr as vt,il as w,X as wt,ll as x,_r as xt,pl as y,Or as yt,go as z};