taskgraph-ai 0.52.10 → 0.52.12

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.
Files changed (31) hide show
  1. package/README.md +1 -1
  2. package/dist/ai-services-unified-BuoDs5zU.js +1 -0
  3. package/dist/ai-services-unified-D8LfWQ4S.js +3 -0
  4. package/dist/commands-Brsl3ZyL.js +210 -0
  5. package/dist/config-manager-BxNrtquR.js +1 -0
  6. package/dist/config-manager-CkwCWw53.js +1 -0
  7. package/dist/{dependency-manager-LkUwzM2z.js → dependency-manager-DRkIU6DR.js} +250 -259
  8. package/dist/{init-B49CMAIZ.js → init-Cp1ZIvlh.js} +2 -2
  9. package/dist/mcp-server.js +2 -2
  10. package/dist/research-Cf8YeyqJ.js +1 -0
  11. package/dist/{response-language-Jp4uf0oe.js → response-language-BhegpO-l.js} +1 -1
  12. package/dist/response-language-CvMcnuEd.js +1 -0
  13. package/dist/src-BaM893RS.js +207 -0
  14. package/dist/{tag-management-CvZXMHgF.js → tag-management-DILdqQSS.js} +1 -1
  15. package/dist/{task-manager-BIsjBszD.js → task-manager-L39eOUEz.js} +1 -1
  16. package/dist/taskgraph.js +1 -1
  17. package/dist/update-subtask-by-id-Dlk8IQru.js +1 -0
  18. package/dist/update-task-by-id-C1xnfWPp.js +1 -0
  19. package/dist/utils-CvXyXTNj.js +1 -0
  20. package/package.json +5 -5
  21. package/dist/ai-services-unified-BFMXenH4.js +0 -3
  22. package/dist/ai-services-unified-D-zQeZm3.js +0 -1
  23. package/dist/commands-WPzx09Df.js +0 -231
  24. package/dist/config-manager-BOVIL1tN.js +0 -1
  25. package/dist/config-manager-Cf_jF2P3.js +0 -1
  26. package/dist/research-BmsT25pv.js +0 -1
  27. package/dist/response-language-CtxJQ0Ac.js +0 -1
  28. package/dist/src-ZFNFV1Cv.js +0 -207
  29. package/dist/update-subtask-by-id-Dncsj7jm.js +0 -1
  30. package/dist/update-task-by-id-BomuFTXv.js +0 -1
  31. package/dist/utils-9HKKyDq7.js +0 -1
@@ -1,102 +1,96 @@
1
- import{a as e,i as t,n,o as r,r as i,t as a}from"./ai-services-unified-BFMXenH4.js";import{C as o,S as s,a as c,c as l,d as u,f as d,h as f,i as p,m,n as h,o as g,p as _,r as v,s as y,t as b,u as x,v as S,y as C}from"./src-ZFNFV1Cv.js";import{$ as w,A as T,B as E,C as ee,Dt as D,G as O,J as k,K as A,M as te,N as j,Nt as M,Q as ne,R as re,T as ie,V as ae,X as oe,Y as se,Z as N,_t as P,a as ce,bt as le,c as ue,ct as F,d as de,dt as fe,ft as pe,g as me,gt as he,h as ge,ht as I,l as _e,m as ve,n as ye,nt as L,o as R,ot as be,p as xe,pt as z,q as Se,rt as Ce,st as we,tt as B,u as Te,v as Ee,vt as De,xt as V,y as Oe,yt as ke}from"./config-manager-BOVIL1tN.js";import"./response-language-Jp4uf0oe.js";import H from"chalk";import U,{resolve as Ae}from"node:path";import W from"path";import{spawn as je}from"child_process";import{z as G}from"zod";import Me from"node:fs";import Ne from"node:os";import K,*as Pe from"fs";import q from"boxen";import Fe from"readline";import{Argument as Ie,Command as J}from"commander";import Le from"figlet";import Re from"gradient-string";import ze from"terminal-link";import{marked as Be}from"marked";import{markedTerminal as Ve}from"marked-terminal";import He from"turndown";import Y from"cli-table3";import Ue from"ora";import We from"process";import Ge from"https";import Ke from"os";import qe from"cli-progress";import Je from"inquirer";import Ye,{Separator as Xe}from"@inquirer/search";import Ze from"fuse.js";import{APICallError as Qe,smoothStream as $e}from"ai";import et from"ajv";import tt from"ajv-formats";import nt from"gpt-tokens";import"@streamparser/json";function rt(e,t,n){return(n?.color?H[n.color]:H.cyan)(ze(e,t,{fallback:(e,t)=>n?.textOnlyFallback?e:`${e} (${t})`}))}function it(e,t){return rt(e,e,t)}function at(e,t){return rt(e,t,{color:`cyan`})}function ot(){return ze.isSupported}const st=Re(he);function ct(){return process.env.TM_HIDE_BANNER===`true`}function lt(){return process.stdout.columns||80}function ut(e={}){if(ct())return;let{version:t}=e;try{let e=Le.textSync(`TaskGraph`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(st(e))}catch{console.log(st(`=== TaskGraph ===`))}let n=`x.com/stephennmiller_`,r=rt(n,`https://x.com/stephennmiller_`,{textOnlyFallback:!0}),i=H.dim(`by `)+H.cyan(r),a=t?t.replace(/^v/,``):``,o=`https://github.com/stephennmiller/taskgraph-ai/releases/tag/taskgraph-ai%40${a}`,s=t?rt(`v${a}`,o,{color:`dim`,textOnlyFallback:!0}):``;if(s){let e=`by ${n}`.length,t=a.length+1,r=lt()-e-t-1;r>=2?console.log(i+` `.repeat(r)+s):(console.log(i),console.log(s))}else console.log(i);console.log(``)}function dt(){if(ct())return;try{let e=Le.textSync(`TaskGraph`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(st(e))}catch{console.log(st(`=== TaskGraph ===`))}let e=rt(`x.com/stephennmiller_`,`https://x.com/stephennmiller_`,{textOnlyFallback:!0});console.log(H.dim(`by `)+H.cyan(e)),console.log(``)}function ft(e){let{header:t,body:n,callToAction:r,footer:i,level:a=`warn`}=e,o=a===`info`?V.heading:H.yellow.bold,s=a===`info`?P:`yellow`,c=[o(t),...n.map(e=>V.text(e))];r&&r.label&&r.action&&c.push(H.cyan(r.label)+`
2
- `+V.brand.underline(r.action)),i&&c.push(V.muted(i));let l=c.join(`
3
-
4
- `);return q(l,{padding:1,borderColor:s,borderStyle:`round`,margin:{top:1,bottom:1}})}const X={done:H.green(`█`),cancelled:V.muted(`─`),deferred:V.muted(`─`),inProgress:V.active(`▓`),review:H.magenta(`▒`),pending:H.yellow(`░`),blocked:H.red(`!`)};function pt(e,t=30,n){if(!n){let n=Math.round(e/100*t),r=t-n;return X.done.repeat(n)+V.muted(`░`).repeat(r)}let r=``,i=0,a=[[n.done,X.done],[n.cancelled,X.cancelled],[n.deferred,X.deferred],[n[`in-progress`],X.inProgress],[n.review,X.review],[n.pending,X.pending],[n.blocked,X.blocked]];for(let[e,n]of a){if(!e||i>=t)continue;let a=Math.min(Math.round(e/100*t),t-i);a>0&&(r+=n.repeat(a),i+=a)}return i<t&&(r+=X.pending.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}}),t.completedCount=e.filter(e=>m(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function ht(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}})}),t.completedCount=n.filter(e=>m(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function gt(e){let t=new Set(e.filter(e=>m(e.status)).map(e=>e.id)),n=e.filter(e=>!m(e.status)&&(!e.dependencies||e.dependencies.length===0)).length,r=e.filter(e=>!m(e.status)&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>t.has(e))).length,i=e.filter(e=>!m(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 _t(e){let t={critical:0,high:0,medium:0,low:0};return e.forEach(e=>{let n=e.priority||`medium`;t[n]++}),t}function vt(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 yt(e,t=!1,n=!1){let r=[];t?r.push(`${X.done} Completed: ${H.green(`${e.completedCount}/${e.total}`)}`):r.push(`${X.done} Done: ${H.green(e.done)}`),r.push(`${X.cancelled} Cancelled: ${V.muted(e.cancelled)}`),r.push(`${X.deferred} Deferred: ${V.muted(e.deferred)}`);let i=e=>n?e.slice(0,2).join(` `)+(e.length>2?`
5
- `+e.slice(2).join(` `):``):e.join(` `),a=i(r);return r.length=0,r.push(`${X.inProgress} In Progress: ${V.active(e.inProgress)}`),r.push(`${X.review} Review: ${H.magenta(e.review||0)}`),r.push(`${X.pending} Pending: ${H.yellow(e.pending)}`),r.push(`${X.blocked} Blocked: ${H.red(e.blocked)}`),a+`
6
- `+i(r)}function bt(e,t,n,r=!1){let i=vt(e),a=vt(t),o=r?16:30,s=pt(e.completionPercentage,o,i),c=pt(t.completionPercentage,o,a),l=`${e.completionPercentage}% ${e.completedCount}/${e.total}`,u=`${t.completionPercentage}% ${t.completedCount}/${t.total}`;return H.bold(`Project Dashboard`)+`
7
- Tasks Progress: ${s} ${H.yellow(l)}\n`+yt(e,!1,r)+`
8
-
9
- Subtasks Progress: ${c} ${H.cyan(u)}\n`+yt(t,!0,r)+`
10
-
11
- `+H.cyan.bold(`Priority Breakdown:`)+`
12
- ${H.red(`•`)} ${V.text(`High priority:`)} ${n.high}\n${H.yellow(`•`)} ${V.text(`Medium priority:`)} ${n.medium}\n${H.green(`•`)} ${V.text(`Low priority:`)} ${n.low}`}function xt(e,t){return H.bold(`Dependency Status & Next Task`)+`
13
- `+H.cyan.bold(`Dependency Metrics:`)+`
14
- ${H.green(`•`)} ${V.text(`Tasks with no dependencies:`)} ${e.tasksWithNoDeps}\n${H.green(`•`)} ${V.text(`Tasks ready to work on:`)} ${e.tasksReadyToWork}\n${H.yellow(`•`)} ${V.text(`Tasks blocked by dependencies:`)} ${e.tasksBlockedByDeps}\n${V.accent(`•`)} ${V.text(`Most depended-on task:`)} ${e.mostDependedOnTaskId?H.cyan(`#${e.mostDependedOnTaskId} (${e.mostDependedOnCount} dependents)`):V.muted(`None`)}\n${V.brand(`•`)} ${V.text(`Avg dependencies per task:`)} ${e.avgDependenciesPerTask.toFixed(1)}\n\n`+H.cyan.bold(`Next Task:`)+`
15
- ID: ${t?H.cyan(String(t.id)):V.muted(`N/A`)} - ${t?H.bold(t.title):H.yellow(`No task available`)}\nPriority: ${t?.priority||V.muted(`N/A`)} Dependencies: ${t?.dependencies?.length?H.cyan(t.dependencies.join(`, `)):V.muted(`None`)}\nComplexity: ${t?.complexity===void 0?V.muted(`N/A`):bn(t.complexity)}`}function St(e,t,n,r,i){let a=process.stdout.columns||80,o=a>=120,s=Math.floor(a/2),c=s-4,l=bt(e,t,n,(o?c:a)-8<60),u=xt(r,i);if(o){let e=q(l,{padding:1,borderColor:P,borderStyle:`round`,width:c,dimBorder:!1}),t=q(u,{padding:1,borderColor:P,borderStyle:`round`,width:c,dimBorder:!1}),n=e.split(`
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"./ai-services-unified-D8LfWQ4S.js";import{C as o,S as s,a as c,c as l,d as u,f as d,h as f,i as p,m,n as h,o as g,p as _,r as v,s as y,t as b,u as x,v as S,y as C}from"./src-BaM893RS.js";import{$ as w,A as T,B as E,C as ee,Dt as D,G as O,J as k,K as A,M as te,N as j,Nt as M,Q as ne,R as re,T as ie,V as ae,X as oe,Y as se,Z as N,_t as P,a as ce,bt as le,c as ue,ct as F,d as de,dt as fe,ft as pe,g as me,gt as he,h as ge,ht as I,l as _e,m as ve,n as ye,nt as L,o as be,ot as xe,p as Se,pt as R,q as Ce,rt as we,st as Te,tt as z,u as Ee,v as De,vt as Oe,xt as B,y as ke,yt as Ae}from"./config-manager-BxNrtquR.js";import"./response-language-BhegpO-l.js";import V from"chalk";import H,{resolve as je}from"node:path";import U from"path";import{spawn as Me}from"child_process";import{z as W}from"zod";import Ne from"node:fs";import Pe from"node:os";import G,*as Fe from"fs";import K from"boxen";import Ie from"readline";import{Argument as Le,Command as q}from"commander";import Re from"figlet";import ze from"gradient-string";import Be from"terminal-link";import{marked as Ve}from"marked";import{markedTerminal as He}from"marked-terminal";import Ue from"turndown";import J from"cli-table3";import We from"ora";import Ge from"process";import Ke from"https";import qe from"os";import Je from"cli-progress";import Ye from"inquirer";import Xe,{Separator as Ze}from"@inquirer/search";import Qe from"fuse.js";import{APICallError as $e,smoothStream as et}from"ai";import tt from"ajv";import nt from"ajv-formats";import rt from"gpt-tokens";import"@streamparser/json";function it(){return process.env.DEBUG===`true`||process.env.DEBUG===`1`}const at=/* @__PURE__ */ new Set([`UNKNOWN_ERROR`,`INTERNAL_ERROR`,`STORAGE_ERROR`]),ot={TASK_NOT_FOUND:"Run `taskgraph list` to see task IDs",JSON_PARSE_ERROR:`Nothing was changed; fix the file or restore it from version control`};function st(e,t){let n=e;for(;n?.cause&&typeof n.code==`string`&&at.has(n.code);)n=n.cause;let r=ft(typeof n?.getUserMessage==`function`?n.getUserMessage():typeof n?.getSanitizedDetails==`function`?n.getSanitizedDetails().message:n?.message??String(n));return{message:r,hint:t??dt(r,n?.code)}}const ct=/\bsubtask (\d+)\.\d+ not found\b/i,lt=/\btask\b(?!\s+file).*\bnot found\b/i,ut=/^tag\b.*\bnot found\b/i;function dt(e,t){if(t&&ot[t])return ot[t];let n=ct.exec(e);if(n)return`Run \`taskgraph show ${n[1]}\` to see its subtasks`;if(lt.test(e))return ot.TASK_NOT_FOUND;if(ut.test(e))return"Run `taskgraph tags` to see your tags"}function ft(e){return e.trim().replace(/^(error:\s*)+/i,``).replace(/\.$/,``).replace(/\b(task|subtask) with ID "?([\d.]+)"?/gi,`$1 $2`).replace(/^(source |parent )+task\b/i,`Task`).replace(/\bdoes not exist$/i,`not found`)}function pt({message:e,hint:t}){let n=`${V.red(`✗`)} ${e}`;if(t){let e=t.split(/`([^`]+)`/).map((e,t)=>t%2==1?B.brand(e):B.muted(e)).join(``);n+=`\n ${e}`}return n}function mt(e,t){let[n=``,...r]=e.trim().split(`
2
+ `),i=n.replace(/^error:\s*/i,``).replace(/^option '(?:-\w, )?(--[\w-]+)[^']*' argument missing$/i,`$1 needs a value`),a=i.charAt(0).toUpperCase()+i.slice(1),o=/\(Did you mean (.+?)\?\)/.exec(r.join(` `))?.[1],s;return/^unknown command/i.test(i)?s=o?`Did you mean \`taskgraph ${o}\`?`:"Run `taskgraph --help` to see all commands":o?s=`Did you mean \`${o}\`?`:t&&(s=`Run \`taskgraph ${t} --help\` to see its options`),pt({message:ft(a),hint:s})}function ht(e,t){console.error(`\n${pt({message:ft(e),hint:t})}`)}function Y(e,t={}){console.error(`\n${pt(st(e,t.hint))}`),(it()||t.forceStack)&&e?.stack&&(console.error(B.muted(`
3
+ Stack trace:`)),console.error(B.muted(e.stack))),t.skipExit||process.exit(1)}function gt(e,t,n){return(n?.color?V[n.color]:V.cyan)(Be(e,t,{fallback:(e,t)=>n?.textOnlyFallback?e:`${e} (${t})`}))}function _t(e,t){return gt(e,e,t)}function vt(e,t){return gt(e,t,{color:`cyan`})}function yt(){return Be.isSupported}const bt=ze(he);function xt(){return process.env.TM_HIDE_BANNER===`true`}function St(){return process.stdout.columns||80}function Ct(e={}){if(xt())return;let{version:t}=e;try{let e=Re.textSync(`TaskGraph`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(bt(e))}catch{console.log(bt(`=== TaskGraph ===`))}let n=`x.com/stephennmiller_`,r=gt(n,`https://x.com/stephennmiller_`,{textOnlyFallback:!0}),i=V.dim(`by `)+V.cyan(r),a=t?t.replace(/^v/,``):``,o=`https://github.com/stephennmiller/taskgraph-ai/releases/tag/taskgraph-ai%40${a}`,s=t?gt(`v${a}`,o,{color:`dim`,textOnlyFallback:!0}):``;if(s){let e=`by ${n}`.length,t=a.length+1,r=St()-e-t-1;r>=2?console.log(i+` `.repeat(r)+s):(console.log(i),console.log(s))}else console.log(i);console.log(``)}function wt(){if(xt())return;try{let e=Re.textSync(`TaskGraph`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(bt(e))}catch{console.log(bt(`=== TaskGraph ===`))}let e=gt(`x.com/stephennmiller_`,`https://x.com/stephennmiller_`,{textOnlyFallback:!0});console.log(V.dim(`by `)+V.cyan(e)),console.log(``)}function Tt(e){let{header:t,body:n,callToAction:r,footer:i,level:a=`warn`}=e,o=a===`info`?B.heading:V.yellow.bold,s=a===`info`?P:`yellow`,c=[o(t),...n.map(e=>B.text(e))];r&&r.label&&r.action&&c.push(V.cyan(r.label)+`
4
+ `+B.brand.underline(r.action)),i&&c.push(B.muted(i));let l=c.join(`
5
+
6
+ `);return K(l,{padding:1,borderColor:s,borderStyle:`round`,margin:{top:1,bottom:1}})}const X={done:V.green(`█`),cancelled:B.muted(`─`),deferred:B.muted(`─`),inProgress:B.active(`▓`),review:V.magenta(`▒`),pending:V.yellow(`░`),blocked:V.red(`!`)};function Et(e,t=30,n){if(!n){let n=Math.round(e/100*t),r=t-n;return X.done.repeat(n)+B.muted(`░`).repeat(r)}let r=``,i=0,a=[[n.done,X.done],[n.cancelled,X.cancelled],[n.deferred,X.deferred],[n[`in-progress`],X.inProgress],[n.review,X.review],[n.pending,X.pending],[n.blocked,X.blocked]];for(let[e,n]of a){if(!e||i>=t)continue;let a=Math.min(Math.round(e/100*t),t-i);a>0&&(r+=n.repeat(a),i+=a)}return i<t&&(r+=X.pending.repeat(t-i)),r}function Dt(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}}),t.completedCount=e.filter(e=>m(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function Ot(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}})}),t.completedCount=n.filter(e=>m(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function kt(e){let t=new Set(e.filter(e=>m(e.status)).map(e=>e.id)),n=e.filter(e=>!m(e.status)&&(!e.dependencies||e.dependencies.length===0)).length,r=e.filter(e=>!m(e.status)&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>t.has(e))).length,i=e.filter(e=>!m(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 At(e){let t={critical:0,high:0,medium:0,low:0};return e.forEach(e=>{let n=e.priority||`medium`;t[n]++}),t}function jt(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 Mt(e,t=!1,n=!1){let r=[];t?r.push(`${X.done} Completed: ${V.green(`${e.completedCount}/${e.total}`)}`):r.push(`${X.done} Done: ${V.green(e.done)}`),r.push(`${X.cancelled} Cancelled: ${B.muted(e.cancelled)}`),r.push(`${X.deferred} Deferred: ${B.muted(e.deferred)}`);let i=e=>n?e.slice(0,2).join(` `)+(e.length>2?`
7
+ `+e.slice(2).join(` `):``):e.join(` `),a=i(r);return r.length=0,r.push(`${X.inProgress} In Progress: ${B.active(e.inProgress)}`),r.push(`${X.review} Review: ${V.magenta(e.review||0)}`),r.push(`${X.pending} Pending: ${V.yellow(e.pending)}`),r.push(`${X.blocked} Blocked: ${V.red(e.blocked)}`),a+`
8
+ `+i(r)}function Nt(e,t,n,r=!1){let i=jt(e),a=jt(t),o=r?16:30,s=Et(e.completionPercentage,o,i),c=Et(t.completionPercentage,o,a),l=`${e.completionPercentage}% ${e.completedCount}/${e.total}`,u=`${t.completionPercentage}% ${t.completedCount}/${t.total}`;return V.bold(`Project Dashboard`)+`
9
+ Tasks Progress: ${s} ${V.yellow(l)}\n`+Mt(e,!1,r)+`
10
+
11
+ Subtasks Progress: ${c} ${V.cyan(u)}\n`+Mt(t,!0,r)+`
12
+
13
+ `+V.cyan.bold(`Priority Breakdown:`)+`
14
+ ${V.red(`•`)} ${B.text(`High priority:`)} ${n.high}\n${V.yellow(`•`)} ${B.text(`Medium priority:`)} ${n.medium}\n${V.green(`•`)} ${B.text(`Low priority:`)} ${n.low}`}function Pt(e,t){return V.bold(`Dependency Status & Next Task`)+`
15
+ `+V.cyan.bold(`Dependency Metrics:`)+`
16
+ ${V.green(`•`)} ${B.text(`Tasks with no dependencies:`)} ${e.tasksWithNoDeps}\n${V.green(`•`)} ${B.text(`Tasks ready to work on:`)} ${e.tasksReadyToWork}\n${V.yellow(`•`)} ${B.text(`Tasks blocked by dependencies:`)} ${e.tasksBlockedByDeps}\n${B.accent(`•`)} ${B.text(`Most depended-on task:`)} ${e.mostDependedOnTaskId?V.cyan(`#${e.mostDependedOnTaskId} (${e.mostDependedOnCount} dependents)`):B.muted(`None`)}\n${B.brand(`•`)} ${B.text(`Avg dependencies per task:`)} ${e.avgDependenciesPerTask.toFixed(1)}\n\n`+V.cyan.bold(`Next Task:`)+`
17
+ ID: ${t?V.cyan(String(t.id)):B.muted(`N/A`)} - ${t?V.bold(t.title):V.yellow(`No task available`)}\nPriority: ${t?.priority||B.muted(`N/A`)} Dependencies: ${t?.dependencies?.length?V.cyan(t.dependencies.join(`, `)):B.muted(`None`)}\nComplexity: ${t?.complexity===void 0?B.muted(`N/A`):Nn(t.complexity)}`}function Ft(e,t,n,r,i){let a=process.stdout.columns||80,o=a>=120,s=Math.floor(a/2),c=s-4,l=Nt(e,t,n,(o?c:a)-8<60),u=Pt(r,i);if(o){let e=K(l,{padding:1,borderColor:P,borderStyle:`round`,width:c,dimBorder:!1}),t=K(u,{padding:1,borderColor:P,borderStyle:`round`,width:c,dimBorder:!1}),n=e.split(`
16
18
  `),r=t.split(`
17
19
  `),i=Math.max(n.length,r.length),a=[];for(let e=0;e<i;e++){let t=e<n.length?n[e]:``,i=e<r.length?r[e]:``,o=t.padEnd(s,` `);a.push(o+i)}console.log(a.join(`
18
- `))}else{let e=q(l,{padding:1,borderColor:P,borderStyle:`round`,margin:{top:0,bottom:1}}),t=q(u,{padding:1,borderColor:P,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}}const Ct={done:{color:H.green,icon:`✓`,tableIcon:`✓`},pending:{color:H.yellow,icon:`○`,tableIcon:`○`},"in-progress":{color:V.active,icon:`▶`,tableIcon:`▶`},deferred:{color:V.muted,icon:`–`,tableIcon:`–`},review:{color:H.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:V.muted,icon:`x`,tableIcon:`x`},blocked:{color:H.red,icon:`!`,tableIcon:`!`},completed:{color:H.green,icon:`✓`,tableIcon:`✓`}};function wt(e){let t=Ct[e];return t?t.color(t.icon):H.red(`X`)}function Tt(e,t=!1){let n=Ct[e]||{color:H.red,icon:`X`,tableIcon:`X`},r=t?n.tableIcon:n.icon;return n.color(`${r} ${e}`)}function Et(e=.9,t=40){let n=process.stdout.columns||80;return Math.max(Math.floor(n*e),t)}function Dt(){let e=process.stdout.columns;return e?Math.floor(e*.95):100}function Ot(e,t,n=20){let r=e=>e.reduce((e,t)=>e+(t.width===`flex`?n:t.width),0)+e.length+1,i=[...t],a=[],o=t.filter(e=>e.dropOrder!==void 0).sort((e,t)=>(e.dropOrder??0)-(t.dropOrder??0));for(let t of o){if(r(i)<=e)break;i=i.filter(e=>e!==t),a.push(t.key)}let s=i.reduce((e,t)=>e+(t.width===`flex`?0:t.width),0),c=Math.max(n,e-s-i.length-1);return{keys:i.map(e=>e.key),widths:i.map(e=>e.width===`flex`?c:e.width),hidden:a}}function kt(e,t){return e.length<=t?e:e.substring(0,t-3)+`...`}function At(e,t,n=30){if(t===0)return V.muted(`No tasks`);let r=Math.round(e/t*100),i=Math.round(e/t*n),a=n-i;return`${H.green(`█`).repeat(i)+V.muted(`░`).repeat(a)} ${H.cyan(`${r}%`)} (${e}/${t})`}const jt=[[`done`,`done`],[`in-progress`,`in progress`],[`review`,`review`],[`pending`,`pending`],[`blocked`,`blocked`],[`deferred`,`deferred`],[`cancelled`,`cancelled`]],Mt=e=>e.replace(/\x1b\[[0-9;]*m/g,``).length;function Nt(e,t={}){let n=t.width??100,r=t.nextId?String(t.nextId):null,i=r?.split(`.`)[0],a=[],o=/* @__PURE__ */ new Set,s=(e,t)=>{o.add(e.status);let a=e.id===i,s=[];e.alsoNeeds.length&&s.push(`needs ${e.alsoNeeds.join(`, `)}`);let c=e.missing.length?H.yellow(` · missing ${e.missing.join(`, `)}`):``,l=(s.length?V.muted(` · ${s.join(` · `)}`):``)+c+(a?V.brand.bold(r===i?` ← next`:` ← next: ${r}`):``),u=`${t}${wt(e.status)} ${V.brand(e.id)} `,d=Math.max(12,n-Mt(u)-Mt(l)),f=kt(e.title,d);return u+(a||e.status===`in-progress`?H.bold(f):e.status===`done`||e.status===`cancelled`?V.muted(f):f)+l},c=(e,t,n)=>{a.push(s(e,t+V.muted(n?`└─ `:`├─ `)));let r=t+V.muted(n?` `:`│ `);e.children.forEach((t,n)=>c(t,r,n===e.children.length-1))};if(e.roots.forEach((t,n)=>{let r=e.roots[n-1];r&&(r.children.length||t.children.length)&&a.push(``),a.push(s(t,``)),t.children.forEach((e,n)=>c(e,``,n===t.children.length-1))}),e.cyclic.length){a.push(``,H.yellow(`⚠ These tasks depend on each other in a loop:`));for(let t of e.cyclic)a.push(s(t,` `));let t=new Set(e.cyclic.map(e=>e.id)),n=e.cyclic[0],r=n.alsoNeeds.find(e=>t.has(e));r&&a.push(V.muted(` Break it with `)+V.brand(`taskgraph remove-dependency --id=${n.id} --depends-on=${r}`))}let l=jt.filter(([e])=>o.has(e)).map(([e,t])=>`${wt(e)} ${V.muted(t)}`).join(` `);return l&&a.push(``,l),a}function Pt(e={}){let{filePath:t,tag:n}=e;if(n&&(console.log(`tag: ${H.cyan(n)}`),t)){let e=t.startsWith(`/`)?t:`${process.cwd()}/${t}`;console.log(`Listing tasks from: ${H.dim(e)}`)}}const Ft=new He({headingStyle:`atx`,codeBlockStyle:`fenced`,bulletListMarker:`-`});Be.use(Ve({code:e=>e.split(`
19
- `).map(e=>` `+H.cyan(e)).join(`
20
- `),blockquote:V.muted.italic,html:V.muted,heading:V.text.bold,hr:V.muted,listitem:V.text,paragraph:V.text,strong:V.text.bold,em:V.text.italic,codespan:H.cyan,del:H.dim.strikethrough,link:V.brand,href:V.brand.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:120})),Be.setOptions({breaks:!0,gfm:!0});function It(e){if(!e)return``;let t=e.replace(/\\\\/g,`\\`).replace(/\\n/g,`
21
- `).replace(/\\t/g,` `).replace(/\\"/g,`"`);/<[^>]+>/.test(t)&&(t=Ft.turndown(t));let n=Be(t);return typeof n==`string`?n.trim():t}function Lt(e,t,n){let r=String(e),i=r.includes(`.`),a=i?{command:`taskgraph update-subtask --id=${r} --prompt="..."`,description:`to log progress notes`}:{command:`taskgraph update-task --id=${r} --prompt="..."`,description:`to update details`},o=!i&&!n?[{command:`taskgraph expand --id=${r}`,description:`to break down into subtasks`}]:[];switch(t){case`in-progress`:return[a,{command:`taskgraph set-status --id=${r} --status=done`,description:`when it is finished`},...o];case`review`:return[{command:`taskgraph set-status --id=${r} --status=done`,description:`once the review passes`},{command:`taskgraph set-status --id=${r} --status=in-progress`,description:`if it needs more work`}];case`done`:case`completed`:case`cancelled`:return[{command:`taskgraph next`,description:`to find the next task to work on`}];case`blocked`:case`deferred`:return[{command:`taskgraph set-status --id=${r} --status=pending`,description:`when it is ready to pick up again`},a];default:return[{command:`taskgraph set-status --id=${r} --status=in-progress`,description:`to start working`},...o,a]}}function Rt(e){switch(e){case`create`:return H.green(`✚ CREATE`);case`modify`:return H.yellow(`✎ MODIFY`);case`reference`:return V.brand(`◇ REFER `);default:return V.muted(` FILE `)}}function zt(e){return e}function Bt(e,t){console.log(q(H.bold(`Task: #${e} - ${t}`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:P,borderStyle:`round`}))}function Vt(e,t){let n=Dt(),r=new Y({head:[],style:{head:[],border:le},colWidths:Ot(n,[{key:`label`,width:16},{key:`value`,width:`flex`}]).widths,wordWrap:!0}),i=e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`None`,a=t||String(e.id),o=It(e.description||``),s=e.category?`${zt(e.category)}`:V.muted(`N/A`),c=e.skills&&e.skills.length>0?e.skills.map(e=>V.accent(`[${e}]`)).join(` `):V.muted(`N/A`),l=[H.cyan(`ID:`),H.cyan(`Title:`),H.cyan(`Status:`),H.cyan(`Priority:`),H.cyan(`Dependencies:`),H.cyan(`Complexity:`),H.cyan(`Category:`),H.cyan(`Skills:`),H.cyan(`Description:`)].join(`
22
- `),u=[a,e.title,Tt(e.status),vn(e.priority),i,typeof e.complexity==`number`?bn(e.complexity):V.muted(`N/A`),s,c,o].join(`
23
- `);r.push([l,u]),console.log(r.toString())}function Ht(e){let t=Dt(),n=It(e);console.log(q(H.bold(`Implementation Details:`)+`
20
+ `))}else{let e=K(l,{padding:1,borderColor:P,borderStyle:`round`,margin:{top:0,bottom:1}}),t=K(u,{padding:1,borderColor:P,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}}const It={done:{color:V.green,icon:`✓`,tableIcon:`✓`},pending:{color:V.yellow,icon:`○`,tableIcon:`○`},"in-progress":{color:B.active,icon:`▶`,tableIcon:`▶`},deferred:{color:B.muted,icon:`–`,tableIcon:`–`},review:{color:V.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:B.muted,icon:`x`,tableIcon:`x`},blocked:{color:V.red,icon:`!`,tableIcon:`!`},completed:{color:V.green,icon:`✓`,tableIcon:`✓`}};function Lt(e){let t=It[e];return t?t.color(t.icon):V.red(`X`)}function Rt(e,t=!1){let n=It[e]||{color:V.red,icon:`X`,tableIcon:`X`},r=t?n.tableIcon:n.icon;return n.color(`${r} ${e}`)}function zt(e=.9,t=40){let n=process.stdout.columns||80;return Math.max(Math.floor(n*e),t)}function Bt(){let e=process.stdout.columns;return e?Math.floor(e*.95):100}function Vt(e,t,n=20){let r=e=>e.reduce((e,t)=>e+(t.width===`flex`?n:t.width),0)+e.length+1,i=[...t],a=[],o=t.filter(e=>e.dropOrder!==void 0).sort((e,t)=>(e.dropOrder??0)-(t.dropOrder??0));for(let t of o){if(r(i)<=e)break;i=i.filter(e=>e!==t),a.push(t.key)}let s=i.reduce((e,t)=>e+(t.width===`flex`?0:t.width),0),c=Math.max(n,e-s-i.length-1);return{keys:i.map(e=>e.key),widths:i.map(e=>e.width===`flex`?c:e.width),hidden:a}}function Ht(e,t){return e.length<=t?e:e.substring(0,t-3)+`...`}function Ut(e,t,n=30){if(t===0)return B.muted(`No tasks`);let r=Math.round(e/t*100),i=Math.round(e/t*n),a=n-i;return`${V.green(`█`).repeat(i)+B.muted(`░`).repeat(a)} ${V.cyan(`${r}%`)} (${e}/${t})`}const Wt=[[`done`,`done`],[`in-progress`,`in progress`],[`review`,`review`],[`pending`,`pending`],[`blocked`,`blocked`],[`deferred`,`deferred`],[`cancelled`,`cancelled`]],Gt=e=>e.replace(/\x1b\[[0-9;]*m/g,``).length;function Kt(e,t={}){let n=t.width??100,r=t.nextId?String(t.nextId):null,i=r?.split(`.`)[0],a=[],o=/* @__PURE__ */ new Set,s=(e,t)=>{o.add(e.status);let a=e.id===i,s=[];e.alsoNeeds.length&&s.push(`needs ${e.alsoNeeds.join(`, `)}`);let c=e.missing.length?V.yellow(` · missing ${e.missing.join(`, `)}`):``,l=(s.length?B.muted(` · ${s.join(` · `)}`):``)+c+(a?B.brand.bold(r===i?` ← next`:` ← next: ${r}`):``),u=`${t}${Lt(e.status)} ${B.brand(e.id)} `,d=Math.max(12,n-Gt(u)-Gt(l)),f=Ht(e.title,d);return u+(a||e.status===`in-progress`?V.bold(f):e.status===`done`||e.status===`cancelled`?B.muted(f):f)+l},c=(e,t,n)=>{a.push(s(e,t+B.muted(n?`└─ `:`├─ `)));let r=t+B.muted(n?` `:`│ `);e.children.forEach((t,n)=>c(t,r,n===e.children.length-1))};if(e.roots.forEach((t,n)=>{let r=e.roots[n-1];r&&(r.children.length||t.children.length)&&a.push(``),a.push(s(t,``)),t.children.forEach((e,n)=>c(e,``,n===t.children.length-1))}),e.cyclic.length){a.push(``,V.yellow(`⚠ These tasks depend on each other in a loop:`));for(let t of e.cyclic)a.push(s(t,` `));let t=new Set(e.cyclic.map(e=>e.id)),n=e.cyclic[0],r=n.alsoNeeds.find(e=>t.has(e));r&&a.push(B.muted(` Break it with `)+B.brand(`taskgraph remove-dependency --id=${n.id} --depends-on=${r}`))}let l=Wt.filter(([e])=>o.has(e)).map(([e,t])=>`${Lt(e)} ${B.muted(t)}`).join(` `);return l&&a.push(``,l),a}function qt(e={}){let{filePath:t,tag:n}=e;if(n&&(console.log(`tag: ${V.cyan(n)}`),t)){let e=t.startsWith(`/`)?t:`${process.cwd()}/${t}`;console.log(`Listing tasks from: ${V.dim(e)}`)}}const Jt=new Ue({headingStyle:`atx`,codeBlockStyle:`fenced`,bulletListMarker:`-`});Ve.use(He({code:e=>e.split(`
21
+ `).map(e=>` `+V.cyan(e)).join(`
22
+ `),blockquote:B.muted.italic,html:B.muted,heading:B.text.bold,hr:B.muted,listitem:B.text,paragraph:B.text,strong:B.text.bold,em:B.text.italic,codespan:V.cyan,del:V.dim.strikethrough,link:B.brand,href:B.brand.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:120})),Ve.setOptions({breaks:!0,gfm:!0});function Yt(e){if(!e)return``;let t=e.replace(/\\\\/g,`\\`).replace(/\\n/g,`
23
+ `).replace(/\\t/g,` `).replace(/\\"/g,`"`);/<[^>]+>/.test(t)&&(t=Jt.turndown(t));let n=Ve(t);return typeof n==`string`?n.trim():t}function Xt(e,t,n){let r=String(e),i=r.includes(`.`),a=i?{command:`taskgraph update-subtask --id=${r} --prompt="..."`,description:`to log progress notes`}:{command:`taskgraph update-task --id=${r} --prompt="..."`,description:`to update details`},o=!i&&!n?[{command:`taskgraph expand --id=${r}`,description:`to break down into subtasks`}]:[];switch(t){case`in-progress`:return[a,{command:`taskgraph set-status --id=${r} --status=done`,description:`when it is finished`},...o];case`review`:return[{command:`taskgraph set-status --id=${r} --status=done`,description:`once the review passes`},{command:`taskgraph set-status --id=${r} --status=in-progress`,description:`if it needs more work`}];case`done`:case`completed`:case`cancelled`:return[{command:`taskgraph next`,description:`to find the next task to work on`}];case`blocked`:case`deferred`:return[{command:`taskgraph set-status --id=${r} --status=pending`,description:`when it is ready to pick up again`},a];default:return[{command:`taskgraph set-status --id=${r} --status=in-progress`,description:`to start working`},...o,a]}}function Zt(e){switch(e){case`create`:return V.green(`✚ CREATE`);case`modify`:return V.yellow(`✎ MODIFY`);case`reference`:return B.brand(`◇ REFER `);default:return B.muted(` FILE `)}}function Qt(e){return e}function $t(e,t){console.log(K(V.bold(`Task: #${e} - ${t}`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:P,borderStyle:`round`}))}function en(e,t){let n=Bt(),r=new J({head:[],style:{head:[],border:le},colWidths:Vt(n,[{key:`label`,width:16},{key:`value`,width:`flex`}]).widths,wordWrap:!0}),i=e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`None`,a=t||String(e.id),o=Yt(e.description||``),s=e.category?`${Qt(e.category)}`:B.muted(`N/A`),c=e.skills&&e.skills.length>0?e.skills.map(e=>B.accent(`[${e}]`)).join(` `):B.muted(`N/A`),l=[V.cyan(`ID:`),V.cyan(`Title:`),V.cyan(`Status:`),V.cyan(`Priority:`),V.cyan(`Dependencies:`),V.cyan(`Complexity:`),V.cyan(`Category:`),V.cyan(`Skills:`),V.cyan(`Description:`)].join(`
24
+ `),u=[a,e.title,Rt(e.status),jn(e.priority),i,typeof e.complexity==`number`?Nn(e.complexity):B.muted(`N/A`),s,c,o].join(`
25
+ `);r.push([l,u]),console.log(r.toString())}function tn(e){let t=Bt(),n=Yt(e);console.log(K(V.bold(`Implementation Details:`)+`
24
26
 
25
- `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function Ut(e){let t=Dt(),n=It(e);console.log(q(H.bold(`Test Strategy:`)+`
27
+ `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function nn(e){let t=Bt(),n=Yt(e);console.log(K(V.bold(`Test Strategy:`)+`
26
28
 
27
- `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function Wt(e,t){let n=Dt();console.log(q(V.heading(`Subtasks`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}}));let r=new Y({head:[V.heading(`ID`),V.heading(`Status`),V.heading(`Title`),V.heading(`Deps`)],style:{head:[],border:le},colWidths:Ot(n,[{key:`id`,width:10},{key:`status`,width:15},{key:`title`,width:`flex`},{key:`deps`,width:8}]).widths,wordWrap:!0});e.forEach(e=>{let n=t?`${t}.${e.id}`:String(e.id),i=e.dependencies&&e.dependencies.length>0?e.dependencies.join(`, `):`None`;r.push([n,Tt(e.status),e.title,i])}),console.log(r.toString())}function Gt(e){let t=Dt(),n=e.map(e=>`${Rt(e.action)} ${V.text(e.path)}\n ${V.muted(e.description)}`).join(`
29
+ `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function rn(e,t){let n=Bt();console.log(K(B.heading(`Subtasks`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}}));let r=new J({head:[B.heading(`ID`),B.heading(`Status`),B.heading(`Title`),B.heading(`Deps`)],style:{head:[],border:le},colWidths:Vt(n,[{key:`id`,width:10},{key:`status`,width:15},{key:`title`,width:`flex`},{key:`deps`,width:8}]).widths,wordWrap:!0});e.forEach(e=>{let n=t?`${t}.${e.id}`:String(e.id),i=e.dependencies&&e.dependencies.length>0?e.dependencies.join(`, `):`None`;r.push([n,Rt(e.status),e.title,i])}),console.log(r.toString())}function an(e){let t=Bt(),n=e.map(e=>`${Zt(e.action)} ${B.text(e.path)}\n ${B.muted(e.description)}`).join(`
28
30
 
29
- `);console.log(q(H.bold(`Files to Touch:`)+`
31
+ `);console.log(K(V.bold(`Files to Touch:`)+`
30
32
 
31
- `+n,{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function Kt(e){let t=Dt(),n=e.map(e=>`${H.cyan.bold(e.name)} → ${V.muted(e.location)}\n ↳ ${V.text(e.usage)}`).join(`
33
+ `+n,{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function on(e){let t=Bt(),n=e.map(e=>`${V.cyan.bold(e.name)} → ${B.muted(e.location)}\n ↳ ${B.text(e.usage)}`).join(`
32
34
 
33
- `);console.log(q(H.bold(`Leverage Existing Code:`)+`
35
+ `);console.log(K(V.bold(`Leverage Existing Code:`)+`
34
36
 
35
- `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function qt(e){let t=Dt(),n=``;e.included&&(n+=H.green.bold(`✓ In Scope:
36
- `),n+=V.text(` `+e.included)),e.excluded&&(n&&(n+=`
37
+ `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function sn(e){let t=Bt(),n=``;e.included&&(n+=V.green.bold(`✓ In Scope:
38
+ `),n+=B.text(` `+e.included)),e.excluded&&(n&&(n+=`
37
39
 
38
- `),n+=H.red.bold(`✗ Out of Scope:
39
- `),n+=V.muted(` `+e.excluded)),console.log(q(H.bold(`Scope Boundaries:`)+`
40
+ `),n+=V.red.bold(`✗ Out of Scope:
41
+ `),n+=B.muted(` `+e.excluded)),console.log(K(V.bold(`Scope Boundaries:`)+`
40
42
 
41
- `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function Jt(e){let t=Dt(),n=e.map(e=>V.text(`☐ ${e}`)).join(`
42
- `);console.log(q(H.bold(`Acceptance Criteria:`)+`
43
+ `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function cn(e){let t=Bt(),n=e.map(e=>B.text(`☐ ${e}`)).join(`
44
+ `);console.log(K(V.bold(`Acceptance Criteria:`)+`
43
45
 
44
- `+n,{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function Yt(e){let t=Dt(),n=e.map(e=>H.yellow(`▸ ${e}`)).join(`
45
- `);console.log(q(H.bold(`Technical Constraints:`)+`
46
+ `+n,{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function ln(e){let t=Bt(),n=e.map(e=>V.yellow(`▸ ${e}`)).join(`
47
+ `);console.log(K(V.bold(`Technical Constraints:`)+`
46
48
 
47
- `+n,{padding:1,borderStyle:`round`,borderColor:`red`,width:t}))}function Xt(e){let t=Dt(),n=It(e);console.log(q(H.bold(`Implementation Approach:`)+`
49
+ `+n,{padding:1,borderStyle:`round`,borderColor:`red`,width:t}))}function un(e){let t=Bt(),n=Yt(e);console.log(K(V.bold(`Implementation Approach:`)+`
48
50
 
49
- `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function Zt(e){let t=Dt(),n=e.map(e=>V.text(`• ${e}`)).join(`
50
- `);console.log(q(H.bold(`Codebase Patterns:`)+`
51
+ `+n,{padding:1,borderStyle:`round`,borderColor:P,width:t}))}function dn(e){let t=Bt(),n=e.map(e=>B.text(`• ${e}`)).join(`
52
+ `);console.log(K(V.bold(`Codebase Patterns:`)+`
51
53
 
52
- `+n,{padding:1,borderStyle:`round`,...ke,width:t}))}function Qt(e,t){let n=``;e&&(n+=V.muted(`Category: `)+H.cyan(`[${zt(e)}]`)),t&&t.length>0&&(n&&(n+=` `),n+=V.muted(`Skills: `)+t.map(e=>V.accent(`[${e}]`)).join(` `)),n&&console.log(`
53
- `+n)}function $t(e){(e.relevantFiles||e.existingInfrastructure||e.scopeBoundaries||e.acceptanceCriteria||e.technicalConstraints||e.implementationApproach||e.codebasePatterns)&&(e.implementationApproach&&(console.log(),Xt(e.implementationApproach)),e.relevantFiles&&e.relevantFiles.length>0&&(console.log(),Gt(e.relevantFiles)),e.existingInfrastructure&&e.existingInfrastructure.length>0&&(console.log(),Kt(e.existingInfrastructure)),e.codebasePatterns&&e.codebasePatterns.length>0&&(console.log(),Zt(e.codebasePatterns)),e.scopeBoundaries&&(console.log(),qt(e.scopeBoundaries)),e.technicalConstraints&&e.technicalConstraints.length>0&&(console.log(),Yt(e.technicalConstraints)),e.acceptanceCriteria&&e.acceptanceCriteria.length>0&&(console.log(),Jt(e.acceptanceCriteria)))}function en(e,t,n=!1){let r=Lt(e,t,n).map((e,t)=>`${H.cyan(`${t+1}.`)} Run ${H.yellow(e.command)} ${e.description}`);console.log(q(H.bold(`Suggested Actions:`)+`
54
+ `+n,{padding:1,borderStyle:`round`,...Ae,width:t}))}function fn(e,t){let n=``;e&&(n+=B.muted(`Category: `)+V.cyan(`[${Qt(e)}]`)),t&&t.length>0&&(n&&(n+=` `),n+=B.muted(`Skills: `)+t.map(e=>B.accent(`[${e}]`)).join(` `)),n&&console.log(`
55
+ `+n)}function pn(e){(e.relevantFiles||e.existingInfrastructure||e.scopeBoundaries||e.acceptanceCriteria||e.technicalConstraints||e.implementationApproach||e.codebasePatterns)&&(e.implementationApproach&&(console.log(),un(e.implementationApproach)),e.relevantFiles&&e.relevantFiles.length>0&&(console.log(),an(e.relevantFiles)),e.existingInfrastructure&&e.existingInfrastructure.length>0&&(console.log(),on(e.existingInfrastructure)),e.codebasePatterns&&e.codebasePatterns.length>0&&(console.log(),dn(e.codebasePatterns)),e.scopeBoundaries&&(console.log(),sn(e.scopeBoundaries)),e.technicalConstraints&&e.technicalConstraints.length>0&&(console.log(),ln(e.technicalConstraints)),e.acceptanceCriteria&&e.acceptanceCriteria.length>0&&(console.log(),cn(e.acceptanceCriteria)))}function mn(e,t,n=!1){let r=Xt(e,t,n).map((e,t)=>`${V.cyan(`${t+1}.`)} Run ${V.yellow(e.command)} ${e.description}`);console.log(K(V.bold(`Suggested Actions:`)+`
54
56
 
55
57
  `+r.join(`
56
- `),{padding:1,margin:{top:1},borderStyle:`round`,borderColor:`green`,width:Dt()}))}function tn(e,t){let{statusFilter:n,showSuggestedActions:r=!1,customHeader:i,headerColor:a=P,originalTaskId:o}=t||{};if(i?console.log(q(H.bold(i),{padding:{top:0,bottom:0,left:1,right:1},borderColor:a,borderStyle:`round`,margin:{top:1}})):Bt(o||e.id,e.title),Vt(e,o),e.details&&(console.log(),Ht(e.details)),`testStrategy`in e&&e.testStrategy&&(console.log(),Ut(e.testStrategy)),$t(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(V.muted(` No subtasks with status '${n}'`))):t.length>0&&(console.log(),Wt(t,e.id))}r&&(console.log(),en(o||e.id,e.status,!!(e.subtasks&&e.subtasks.length>0)))}function nn(e,t){if(!e){console.log(t?H.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`):q(H.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`No tasks available`,titleAlignment:`center`}));return}let n=[];n.push(`${V.heading(`Next task:`)} ${H.yellow(`#${e.id}`)}${V.heading(` - ${e.title}`)}`),n.push(``);let r=[];if(e.priority){let t=e.priority===`high`?H.red:e.priority===`medium`?H.yellow:V.muted;r.push(`Priority: ${t.bold(e.priority)}`)}if(e.status){let t=e.status===`pending`?H.yellow(`○ pending`):e.status===`in-progress`?V.brand(`▶ in-progress`):V.muted(e.status);r.push(`Status: ${t}`)}n.push(r.join(` `));let i=!e.dependencies||e.dependencies.length===0?V.muted(`None`):H.cyan(e.dependencies.join(`, `));n.push(`Dependencies: ${i}`),typeof e.complexity==`number`&&n.push(`Complexity: ${bn(e.complexity)}`),e.description&&(n.push(``),n.push(`Description: ${V.text(It(e.description))}`)),n.push(``);for(let t of Lt(e.id,e.status,!0).slice(0,2))n.push(`${H.cyan(`Next step:`)} ${H.yellow(t.command)} ${V.muted(t.description)}`);n.push(`${H.cyan(`View details:`)} ${H.yellow(`taskgraph show ${e.id}`)}`),console.log(q(n.join(`
57
- `),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:P,title:V.heading(`Next task`),titleAlignment:`center`,width:Et(.97),fullscreen:!1}))}function rn(e){if(`description`in e&&e.description)return e.description;if(`details`in e&&e.details)return e.details.split(`
58
- `)[0].split(`.`)[0]}const an=[`⠋`,`⠙`,`⠹`,`⠸`,`⠼`,`⠴`,`⠦`,`⠧`,`⠇`,`⠏`];function on(e=H.hex(De.accent)){return{interval:80,frames:an.map(t=>e(t))}}function sn(e={}){let t=Ue({...typeof e==`string`?{text:e}:e,spinner:on(),color:!1}),n=e=>n=>t.stopAndPersist({symbol:e,text:n});return t.succeed=n(H.green(`✓`)),t.fail=n(H.red(`✗`)),t.warn=n(H.yellow(`⚠`)),t}function cn(e,t=!1){let n=e?.tasks?.length??0;return t?n:Math.max(0,n-1)}function ln(e){let t=Math.max(0,Math.floor(e/1e3));return`${Math.floor(t/60)}:${String(t%60).padStart(2,`0`)}`}function un(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/60),r=t%60;return n===0?`${r}s`:r?`${n}m ${r}s`:`${n}m`}function dn(e,t){let n=e.replace(/\s+/g,` `).trim();return n.length>t?`${n.slice(0,t-1).trimEnd()}…`:n}var fn=class{options;spinner;ticker;startedAt=0;printed=0;current;interactive;constructor(e){this.options={numTasks:e.numTasks||0,startId:e.startId??1,stream:e.stream??process.stdout,now:e.now??Date.now,prdName:e.prdName},this.interactive=!!this.options.stream.isTTY}start(){return this.startedAt=this.options.now(),this.interactive?(this.spinner=sn({text:this.statusText(),stream:this.options.stream}).start(),this.ticker=setInterval(()=>this.refresh(),1e3),this.ticker.unref?.()):this.write(`${this.statusText()}\n`),this}update(e){this.current=e,this.printCompleted(cn(e)),this.refresh()}succeed(e){e&&(this.current=e),this.printCompleted(cn(this.current,!0));let t=this.printed,n=un(this.options.now()-this.startedAt),r=`${t} ${t===1?`task`:`tasks`} in ${n}`;this.stop(),this.write(`${H.green(`✓`)} ${H.bold(r)}\n`)}fail(e){this.stop(),this.write(`${H.red(`✗`)} ${e}\n`)}stop(){this.ticker&&clearInterval(this.ticker),this.ticker=void 0,this.spinner?.stop(),this.spinner=void 0}get printedCount(){return this.printed}printCompleted(e){let t=this.current?.tasks??[];for(;this.printed<e;){let e=t[this.printed],n=this.options.startId+this.printed,r=dn(e?.title??``,Math.max(20,this.columns-7));this.persist(`${H.green(`✓`)} ${V.brand(String(n).padEnd(3))}${r}`),this.printed++}}persist(e){this.spinner?(this.spinner.clear(),this.write(`${e}\n`),this.spinner.render()):this.write(`${e}\n`)}refresh(){this.spinner&&(this.spinner.text=this.statusText())}statusText(){let{numTasks:e,prdName:t}=this.options,n=this.current?.tasks?.length??0,r;if(n===0)r=e?`Reading ${t} and planning ${e} tasks`:`Reading ${t} and planning tasks`;else{let t=e?` of ${e}`:``,i=this.current?.tasks?.[n-1]?.title;r=`Writing task ${n}${t}`;let a=this.columns-2-r.length-3-2-6;i&&a>=12&&(r+=V.muted(` · ${dn(i,a)}`))}return`${r} ${V.muted(this.elapsed())}`}get columns(){return this.options.stream.columns||80}elapsed(){return ln(this.options.now()-this.startedAt)}write(e){this.options.stream.write(e)}};function pn(){let e=[`${H.cyan(`1.`)} Run ${H.yellow(`taskgraph next`)} to see what to work on next`,`${H.cyan(`2.`)} Run ${H.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks`,`${H.cyan(`3.`)} Run ${H.yellow(`taskgraph set-status --id=<id> --status=done`)} to mark a task as complete`];console.log(q(H.bold(`Suggested Next Steps:`)+`
58
+ `),{padding:1,margin:{top:1},borderStyle:`round`,borderColor:`green`,width:Bt()}))}function hn(e,t){let{statusFilter:n,showSuggestedActions:r=!1,customHeader:i,headerColor:a=P,originalTaskId:o}=t||{};if(i?console.log(K(V.bold(i),{padding:{top:0,bottom:0,left:1,right:1},borderColor:a,borderStyle:`round`,margin:{top:1}})):$t(o||e.id,e.title),en(e,o),e.details&&(console.log(),tn(e.details)),`testStrategy`in e&&e.testStrategy&&(console.log(),nn(e.testStrategy)),pn(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.muted(` No subtasks with status '${n}'`))):t.length>0&&(console.log(),rn(t,e.id))}r&&(console.log(),mn(o||e.id,e.status,!!(e.subtasks&&e.subtasks.length>0)))}function gn(e,t){if(!e){console.log(t?V.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`):K(V.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.heading(`Next task:`)} ${V.yellow(`#${e.id}`)}${B.heading(` - ${e.title}`)}`),n.push(``);let r=[];if(e.priority){let t=e.priority===`high`?V.red:e.priority===`medium`?V.yellow:B.muted;r.push(`Priority: ${t.bold(e.priority)}`)}if(e.status){let t=e.status===`pending`?V.yellow(`○ pending`):e.status===`in-progress`?B.brand(`▶ in-progress`):B.muted(e.status);r.push(`Status: ${t}`)}n.push(r.join(` `));let i=!e.dependencies||e.dependencies.length===0?B.muted(`None`):V.cyan(e.dependencies.join(`, `));n.push(`Dependencies: ${i}`),typeof e.complexity==`number`&&n.push(`Complexity: ${Nn(e.complexity)}`),e.description&&(n.push(``),n.push(`Description: ${B.text(Yt(e.description))}`)),n.push(``);for(let t of Xt(e.id,e.status,!0).slice(0,2))n.push(`${V.cyan(`Next step:`)} ${V.yellow(t.command)} ${B.muted(t.description)}`);n.push(`${V.cyan(`View details:`)} ${V.yellow(`taskgraph show ${e.id}`)}`),console.log(K(n.join(`
59
+ `),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:P,title:B.heading(`Next task`),titleAlignment:`center`,width:zt(.97),fullscreen:!1}))}function _n(e){if(`description`in e&&e.description)return e.description;if(`details`in e&&e.details)return e.details.split(`
60
+ `)[0].split(`.`)[0]}const vn=[`⠋`,`⠙`,`⠹`,`⠸`,`⠼`,`⠴`,`⠦`,`⠧`,`⠇`,`⠏`];function yn(e=V.hex(Oe.accent)){return{interval:80,frames:vn.map(t=>e(t))}}function bn(e={}){let t=We({...typeof e==`string`?{text:e}:e,spinner:yn(),color:!1}),n=e=>n=>t.stopAndPersist({symbol:e,text:n});return t.succeed=n(V.green(`✓`)),t.fail=n(V.red(`✗`)),t.warn=n(V.yellow(`⚠`)),t}function xn(e,t=!1){let n=e?.tasks?.length??0;return t?n:Math.max(0,n-1)}function Sn(e){let t=Math.max(0,Math.floor(e/1e3));return`${Math.floor(t/60)}:${String(t%60).padStart(2,`0`)}`}function Cn(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/60),r=t%60;return n===0?`${r}s`:r?`${n}m ${r}s`:`${n}m`}function wn(e,t){let n=e.replace(/\s+/g,` `).trim();return n.length>t?`${n.slice(0,t-1).trimEnd()}…`:n}var Tn=class{options;spinner;ticker;startedAt=0;printed=0;current;interactive;constructor(e){this.options={numTasks:e.numTasks||0,startId:e.startId??1,stream:e.stream??process.stdout,now:e.now??Date.now,prdName:e.prdName},this.interactive=!!this.options.stream.isTTY}start(){return this.startedAt=this.options.now(),this.interactive?(this.spinner=bn({text:this.statusText(),stream:this.options.stream}).start(),this.ticker=setInterval(()=>this.refresh(),1e3),this.ticker.unref?.()):this.write(`${this.statusText()}\n`),this}update(e){this.current=e,this.printCompleted(xn(e)),this.refresh()}succeed(e){e&&(this.current=e),this.printCompleted(xn(this.current,!0));let t=this.printed,n=Cn(this.options.now()-this.startedAt),r=`${t} ${t===1?`task`:`tasks`} in ${n}`;this.stop(),this.write(`${V.green(`✓`)} ${V.bold(r)}\n`)}fail(e){this.stop(),this.write(`${V.red(`✗`)} ${e}\n`)}stop(){this.ticker&&clearInterval(this.ticker),this.ticker=void 0,this.spinner?.stop(),this.spinner=void 0}get printedCount(){return this.printed}printCompleted(e){let t=this.current?.tasks??[];for(;this.printed<e;){let e=t[this.printed],n=this.options.startId+this.printed,r=wn(e?.title??``,Math.max(20,this.columns-7));this.persist(`${V.green(`✓`)} ${B.brand(String(n).padEnd(3))}${r}`),this.printed++}}persist(e){this.spinner?(this.spinner.clear(),this.write(`${e}\n`),this.spinner.render()):this.write(`${e}\n`)}refresh(){this.spinner&&(this.spinner.text=this.statusText())}statusText(){let{numTasks:e,prdName:t}=this.options,n=this.current?.tasks?.length??0,r;if(n===0)r=e?`Reading ${t} and planning ${e} tasks`:`Reading ${t} and planning tasks`;else{let t=e?` of ${e}`:``,i=this.current?.tasks?.[n-1]?.title;r=`Writing task ${n}${t}`;let a=this.columns-2-r.length-3-2-6;i&&a>=12&&(r+=B.muted(` · ${wn(i,a)}`))}return`${r} ${B.muted(this.elapsed())}`}get columns(){return this.options.stream.columns||80}elapsed(){return Sn(this.options.now()-this.startedAt)}write(e){this.options.stream.write(e)}};function En(){let e=[`${V.cyan(`1.`)} Run ${V.yellow(`taskgraph next`)} to see what to work on next`,`${V.cyan(`2.`)} Run ${V.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks`,`${V.cyan(`3.`)} Run ${V.yellow(`taskgraph set-status --id=<id> --status=done`)} to mark a task as complete`];console.log(K(V.bold(`Suggested Next Steps:`)+`
59
61
 
60
62
  `+e.join(`
61
- `),{padding:1,margin:{top:0,bottom:1},borderStyle:`round`,...ke,width:Et(.97)}))}const mn=`tasks.json`;function hn(e){let t=g(e);console.log(H.dim(`\nWatching ${mn} for changes...`)),console.log(V.muted(`Last synced: ${t}`)),console.log(H.dim(`Press Ctrl+C to exit`))}function gn(e){let t=g(e);console.log(V.brand(`\nℹ ${mn} updated at ${t}`))}const _n={critical:H.red.bold,high:H.red,medium:H.yellow,low:V.muted};function vn(e){return(_n[e]||V.text)(e)}function yn(e){return e>=7?{color:H.red,label:`High`}:e>=4?{color:H.yellow,label:`Medium`}:{color:H.green,label:`Low`}}function bn(e){let t=typeof e==`string`?Number(e.trim()):e;if(isNaN(t))return V.muted(`N/A`);let{color:n}=yn(t);return n(`● ${t}`)}function xn(e){if(typeof e!=`number`)return V.muted(`N/A`);let{color:t,label:n}=yn(e);return t(`${e}/10 (${n})`)}const Sn=(e,t)=>Math.round(e).toLocaleString(t);function Cn(e,t=`USD`,n){let r=(e,r)=>{try{return new Intl.NumberFormat(n,{style:`currency`,currency:t,...r}).format(e)}catch{return`${t} ${e.toFixed(2)}`}};return e<.01?`<${r(.01,{maximumFractionDigits:2})}`:e<1?r(e,{maximumSignificantDigits:3}):r(e,{maximumFractionDigits:2,minimumFractionDigits:2})}function wn(e,t){if(!e)return null;let n=e.inputTokens??0,r=e.outputTokens??0,i=e.totalTokens||n+r;if(!i)return null;let a=[],o=e.modelUsed;o&&a.push(o===`Multiple`?`several models`:o),a.push(`${Sn(i,t)} ${i===1?`token`:`tokens`} (${Sn(n,t)} in, ${Sn(r,t)} out)`);let s=e.cachedInputTokens??0;return n>0&&s/n>=.01&&a.push(`${Math.round(s/n*100)}% cached`),!e.isUnknownCost&&(e.totalCost??0)>0&&a.push(`~${Cn(e.totalCost,e.currency,t)}`),a.join(` · `)}function Tn(e,t){if(!e||e.length===0)return V.muted(`none`);let n=new Map(t.map(e=>[e.id.toString(),e]));return e.map(e=>{let t=n.get(e.toString());return t?`${e}${t.status===`done`?`✓`:t.status===`in-progress`?`►`:`○`}`:H.red(`${e} (not found)`)}).join(`, `)}function En(e=`TaskGraph`){console.log(q(H.bold(e),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:P,textAlignment:`center`}))}function Dn(e,t){let n=Et();console.error(q(H.red.bold(`X Error: `)+V.text(e)+(t?`
63
+ `),{padding:1,margin:{top:0,bottom:1},borderStyle:`round`,...Ae,width:zt(.97)}))}const Dn=`tasks.json`;function On(e){let t=g(e);console.log(V.dim(`\nWatching ${Dn} for changes...`)),console.log(B.muted(`Last synced: ${t}`)),console.log(V.dim(`Press Ctrl+C to exit`))}function kn(e){let t=g(e);console.log(B.brand(`\nℹ ${Dn} updated at ${t}`))}const An={critical:V.red.bold,high:V.red,medium:V.yellow,low:B.muted};function jn(e){return(An[e]||B.text)(e)}function Mn(e){return e>=7?{color:V.red,label:`High`}:e>=4?{color:V.yellow,label:`Medium`}:{color:V.green,label:`Low`}}function Nn(e){let t=typeof e==`string`?Number(e.trim()):e;if(isNaN(t))return B.muted(`N/A`);let{color:n}=Mn(t);return n(`● ${t}`)}function Pn(e){if(typeof e!=`number`)return B.muted(`N/A`);let{color:t,label:n}=Mn(e);return t(`${e}/10 (${n})`)}const Fn=(e,t)=>Math.round(e).toLocaleString(t);function In(e,t=`USD`,n){let r=(e,r)=>{try{return new Intl.NumberFormat(n,{style:`currency`,currency:t,...r}).format(e)}catch{return`${t} ${e.toFixed(2)}`}};return e<.01?`<${r(.01,{maximumFractionDigits:2})}`:e<1?r(e,{maximumSignificantDigits:3}):r(e,{maximumFractionDigits:2,minimumFractionDigits:2})}function Ln(e,t){if(!e)return null;let n=e.inputTokens??0,r=e.outputTokens??0,i=e.totalTokens||n+r;if(!i)return null;let a=[],o=e.modelUsed;o&&a.push(o===`Multiple`?`several models`:o),a.push(`${Fn(i,t)} ${i===1?`token`:`tokens`} (${Fn(n,t)} in, ${Fn(r,t)} out)`);let s=e.cachedInputTokens??0;return n>0&&s/n>=.01&&a.push(`${Math.round(s/n*100)}% cached`),!e.isUnknownCost&&(e.totalCost??0)>0&&a.push(`~${In(e.totalCost,e.currency,t)}`),a.join(` · `)}function Rn(e,t){if(!e||e.length===0)return B.muted(`none`);let n=new Map(t.map(e=>[e.id.toString(),e]));return e.map(e=>{let t=n.get(e.toString());return t?`${e}${t.status===`done`?`✓`:t.status===`in-progress`?`►`:`○`}`:V.red(`${e} (not found)`)}).join(`, `)}function zn(e=`TaskGraph`){console.log(K(V.bold(e),{padding:1,margin:{top:1,bottom:1},borderStyle:`round`,borderColor:P,textAlignment:`center`}))}function Bn(e,t){let n=zt();console.error(K(V.red.bold(`X Error: `)+B.text(e)+(t?`
62
64
 
63
- `+V.muted(t):``),{padding:1,borderStyle:`round`,borderColor:`red`,width:n}))}const On=Dn;function kn(e){let t=Et();console.log(q(H.green.bold(`√ `)+V.text(e),{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function An(e){let t=Et();console.log(q(H.yellow.bold(`⚠ `)+V.text(e),{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function jn(e){let t=Et();console.log(q(V.brand.bold(`i `)+V.text(e),{padding:1,borderStyle:`round`,borderColor:P,width:t}))}const Mn=[{key:`tag`,header:`Tag`,width:12},{key:`id`,header:`ID`,width:10},{key:`title`,header:`Title`,width:`flex`},{key:`status`,header:`Status`,width:15},{key:`priority`,header:`Priority`,width:10},{key:`dependencies`,header:`Dependencies`,width:14,dropOrder:3},{key:`blocks`,header:`Blocks`,width:10,dropOrder:0},{key:`complexity`,header:`Complexity`,width:12,dropOrder:1}];function Nn(e,t){let{showSubtasks:n=!1,showComplexity:r=!1,showDependencies:i=!0,showBlocks:a=!1,showTag:o=!1}=t||{},s={tag:o,dependencies:i,blocks:a,complexity:r},c=Mn.filter(e=>s[e.key]??!0),l=Ot(Dt(),c),u=e=>l.widths[l.keys.indexOf(e)],d=new Y({head:l.keys.map(e=>V.brand.bold(Mn.find(t=>t.key===e)?.header??e)),style:{head:[],border:[]},colWidths:l.widths,wordWrap:!0}),f=e=>l.keys.map(t=>e[t]??``);e.forEach(e=>{let t=e.blocks?.join(`, `)??``;d.push(f({tag:V.accent(e.tagName||`-`),id:H.cyan(e.id.toString()),title:kt(e.title,u(`title`)-3),status:Tt(e.status,!0),priority:vn(e.priority),dependencies:!e.dependencies||e.dependencies.length===0?V.muted(`-`):H.cyan(e.dependencies.map(e=>String(e)).join(`, `)),blocks:t?m(e.status)?V.muted(t):H.yellow(t):V.muted(`-`),complexity:typeof e.complexity==`number`?bn(e.complexity):V.muted(`N/A`)})),n&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{d.push(f({tag:V.muted(`-`),id:V.muted(` └─ ${e.id}`),title:V.muted(kt(e.title,u(`title`)-6)),status:V.muted(Tt(e.status,!0)),priority:V.muted(e.priority||`medium`),dependencies:V.muted(e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`-`),blocks:V.muted(`-`),complexity:V.muted(typeof e.complexity==`number`?bn(e.complexity):`--`)}))})});let p=l.hidden.length>0?`
64
- `+V.muted(`Hidden to fit width: ${l.hidden.map(e=>Mn.find(t=>t.key===e)?.header).join(`, `)}`):``;return d.toString()+p}var Pn=/* @__PURE__ */ r({BANNER_GRADIENT:()=>he,BORDER_COLOR:()=>P,BRAND_COLORS:()=>De,MUTED_BOX_BORDER:()=>ke,ParsePrdProgress:()=>fn,TABLE_BORDER:()=>le,brandSpinner:()=>on,calculateDependencyStatistics:()=>gt,calculateSubtaskStatistics:()=>ht,calculateTaskStatistics:()=>mt,completedTaskCount:()=>cn,createLink:()=>rt,createProgressBar:()=>At,createSpinner:()=>sn,createTaskLink:()=>at,createTaskTable:()=>Nn,createUrlLink:()=>it,displayAcceptanceCriteria:()=>Jt,displayAsciiBanner:()=>ut,displayBanner:()=>En,displayCardBox:()=>ft,displayCodebasePatterns:()=>Zt,displayDashboards:()=>St,displayDependencyDashboard:()=>xt,displayError:()=>On,displayErrorBox:()=>Dn,displayExistingInfrastructure:()=>Kt,displayHeader:()=>Pt,displayImplementationApproach:()=>Xt,displayImplementationDetails:()=>Ht,displayImplementationMetadata:()=>$t,displayInfo:()=>jn,displayInitBanner:()=>dt,displayProjectDashboard:()=>bt,displayRecommendedNextTask:()=>nn,displayRelevantFiles:()=>Gt,displayScopeBoundaries:()=>qt,displaySkillsAndCategory:()=>Qt,displaySubtasks:()=>Wt,displaySuccess:()=>kn,displaySuggestedActions:()=>en,displaySuggestedNextSteps:()=>pn,displaySyncMessage:()=>gn,displayTaskDetails:()=>tn,displayTaskHeader:()=>Bt,displayTaskProperties:()=>Vt,displayTechnicalConstraints:()=>Yt,displayTestStrategy:()=>Ut,displayWarning:()=>An,displayWatchFooter:()=>hn,formatCost:()=>Cn,formatDependenciesWithStatus:()=>Tn,formatDuration:()=>un,formatElapsed:()=>ln,formatStatusLine:()=>yt,formatUsageLine:()=>wn,getBoxWidth:()=>Et,getComplexityWithColor:()=>bn,getComplexityWithScore:()=>xn,getPriorityBreakdown:()=>_t,getPriorityWithColor:()=>vn,getStatusWithColor:()=>Tt,getSuggestedActions:()=>Lt,getTaskDescription:()=>rn,renderDependencyTree:()=>Nt,supportsLinks:()=>ot,theme:()=>V,truncate:()=>kt});const Fn=U.join(`.taskgraph`,`tasks`,`tasks.json`);function In(e){Pt({tag:e.tag||`master`,filePath:Fn})}function Ln(){return process.env.DEBUG===`true`||process.env.DEBUG===`1`}function Z(e,t={}){if(e?.getSanitizedDetails){let n=e.getSanitizedDetails();console.error(H.red(`\n${n.message}`)),(Ln()||t.forceStack)&&e.stack&&(console.error(V.muted(`
65
- Stack trace:`)),console.error(V.muted(e.stack)))}else{let n=e?.message??String(e);console.error(H.red(`\nError: ${n}`)),(Ln()||t.forceStack)&&e?.stack&&(console.error(V.muted(`
66
- Stack trace:`)),console.error(V.muted(e.stack)))}t.skipExit||process.exit(1)}function Rn(e){return e?Ae(e):l()}var zn=class e extends J{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(Rn(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){Z(e)}}async watchTasks(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.getTasks(e),n=/* @__PURE__ */ new Date;console.clear(),this.displayResults(t,e),hn(n);let r;try{r=await this.tmCore.tasks.watch(async r=>{if(r.type===`change`)try{t=await this.getTasks(e),n=/* @__PURE__ */ new Date,console.clear(),this.displayResults(t,e),gn(n),hn(n)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(H.yellow(`\nWarning: Failed to refresh tasks: ${t}`))}else r.type===`error`&&r.error&&console.error(H.red(`\n⚠ Watch error: ${r.error.message}`))},{tag:e.tag});let i=()=>{r?.unsubscribe(),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i),await new Promise(()=>{})}catch(e){throw console.error(H.red(`Watch mode error: ${e.message}`)),e}}validateOptions(e){if(e.format&&!u.includes(e.format))return console.error(H.red(`Invalid format: ${e.format}`)),console.error(V.muted(`Valid formats: ${u.join(`, `)}`)),!1;if(e.status){let t=e.status.split(`,`).map(e=>e.trim());for(let e of t)if(e!==`all`&&!_.includes(e))return console.error(H.red(`Invalid status: ${e}`)),console.error(V.muted(`Valid statuses: ${_.join(`, `)}`)),!1}return e.allTags&&e.watch?(console.error(H.red(`--all-tags cannot be used with --watch mode`)),console.error(V.muted(`Use --all-tags without --watch, or --watch without --all-tags`)),!1):!0}async initializeCore(e){this.tmCore||=await x({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}=b(i.tasks);this.displayInvalidDependencyWarnings(o);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[]}));return e.ready&&(s=v(s)),e.blocking&&(s=h(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}=b(i.tasks);this.displayInvalidDependencyWarnings(o,t);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[],tagName:t})),c=e.ready?v(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(H.yellow(`\nWarning: Could not fetch tasks from ${i.length} tag(s):`)),i.forEach(({name:e,error:t})=>{console.warn(V.muted(` ${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,allTags:!0}}displayInvalidDependencyWarnings(e,t){if(e.length===0)return;let n=t?` (tag: ${t})`:``;console.warn(H.yellow(`\nWarning: ${e.length} invalid dependency reference(s) found${n}:`)),e.slice(0,5).forEach(({taskId:e,depId:t})=>{console.warn(V.muted(` Task ${e} depends on non-existent task ${t}`))}),e.length>5&&console.warn(V.muted(` ...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;default:this.displayText(e,t)}}displayJson(e){console.log(JSON.stringify({tasks:e.tasks,metadata:{total:e.total,filtered:e.filtered,tag:e.allTags?`all`:e.tag,allTags:e.allTags||!1}},null,2))}displayCompact(e,t){let{tasks:n,tag:r,allTags:i}=e;t.noHeader!==!0&&In({tag:i?`all tags`:r||`master`});for(let e of n){let n=d[e.status],r=i&&`tagName`in e?V.accent(`[${e.tagName}] `):``;if(console.log(`${r}${H.cyan(e.id)} ${n} ${e.title}`),t.withSubtasks&&e.subtasks?.length)for(let t of e.subtasks){let e=d[t.status];console.log(` ${V.muted(String(t.id))} ${e} ${V.muted(t.title)}`)}}}displayText(e,t){let{tasks:n,tag:r,allTags:i}=e;if(t.noHeader!==!0&&In({tag:i?`all tags`:r||`master`}),n.length===0){An(`No tasks found matching the criteria.`);return}let a=mt(n),o=ht(n),s=gt(n),c=_t(n),l=this.findNextTask(n),u=l?n.find(e=>String(e.id)===String(l.id)):void 0,d=t.ready||t.blocking||i;if(d||St(a,o,c,s,u),console.log(Nn(n,{showSubtasks:t.withSubtasks,showDependencies:!0,showBlocks:!0,showComplexity:!0,showTag:i})),!d){if(u){let e=rn(u);nn({id:u.id,title:u.title,priority:u.priority,status:u.status,dependencies:u.dependencies,description:e,complexity:u.complexity})}pn()}}setLastResult(e){this.lastResult=e}findNextTask(e){let t={critical:4,high:3,medium:2,low:1},n=/* @__PURE__ */ new Set;e.forEach(e=>{m(e.status)&&n.add(String(e.id)),e.subtasks&&e.subtasks.forEach(t=>{m(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}},Bn=class e extends J{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(Rn(t.project));let n=e||t.id;n||(console.error(H.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=c.safeParse(e);t.success||(console.error(H.red(`Invalid task ID: ${e}`),V.muted(`- ${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){Z(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(H.red(`Invalid format: ${e.format}`)),console.error(V.muted(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await x({projectPath:e})}async getSingleTask(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=await this.tmCore.tasks.get(e);return{task:n.task,found:n.task!==null,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}}displayResults(e,t){switch(t.json?`json`:t.format||`text`){case`json`:this.displayJson(e);break;default:`task`in e?this.displaySingleTask(e,t):this.displayMultipleTasks(e,t)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displaySingleTask(e,t){!e.found||!e.task?console.log(q(H.yellow(`Task not found!`),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`yellow`,borderStyle:`round`,margin:{top:1}})):(In({tag:this.tmCore?.config.getActiveTag()||`master`}),console.log(),tn(e.task,{statusFilter:t.status,showSuggestedActions:!0,originalTaskId:e.originalTaskId}))}displayMultipleTasks(e,t){In({tag:this.tmCore?.config.getActiveTag()||`master`}),e.notFound.length>0&&console.log(H.yellow(`\n⚠ Not found: ${e.notFound.join(`, `)}`)),e.tasks.length===0?An(`No tasks found matching the criteria.`):(console.log(V.brand.bold(`
65
+ `+B.muted(t):``),{padding:1,borderStyle:`round`,borderColor:`red`,width:n}))}const Vn=Bn;function Hn(e){let t=zt();console.log(K(V.green.bold(`√ `)+B.text(e),{padding:1,borderStyle:`round`,borderColor:`green`,width:t}))}function Un(e){let t=zt();console.log(K(V.yellow.bold(`⚠ `)+B.text(e),{padding:1,borderStyle:`round`,borderColor:`yellow`,width:t}))}function Wn(e){let t=zt();console.log(K(B.brand.bold(`i `)+B.text(e),{padding:1,borderStyle:`round`,borderColor:P,width:t}))}const Gn=[{key:`tag`,header:`Tag`,width:12},{key:`id`,header:`ID`,width:10},{key:`title`,header:`Title`,width:`flex`},{key:`status`,header:`Status`,width:15},{key:`priority`,header:`Priority`,width:10},{key:`dependencies`,header:`Dependencies`,width:14,dropOrder:3},{key:`blocks`,header:`Blocks`,width:10,dropOrder:0},{key:`complexity`,header:`Complexity`,width:12,dropOrder:1}];function Kn(e,t){let{showSubtasks:n=!1,showComplexity:r=!1,showDependencies:i=!0,showBlocks:a=!1,showTag:o=!1}=t||{},s={tag:o,dependencies:i,blocks:a,complexity:r},c=Gn.filter(e=>s[e.key]??!0),l=Vt(Bt(),c),u=e=>l.widths[l.keys.indexOf(e)],d=new J({head:l.keys.map(e=>B.brand.bold(Gn.find(t=>t.key===e)?.header??e)),style:{head:[],border:[]},colWidths:l.widths,wordWrap:!0}),f=e=>l.keys.map(t=>e[t]??``);e.forEach(e=>{let t=e.blocks?.join(`, `)??``;d.push(f({tag:B.accent(e.tagName||`-`),id:V.cyan(e.id.toString()),title:Ht(e.title,u(`title`)-3),status:Rt(e.status,!0),priority:jn(e.priority),dependencies:!e.dependencies||e.dependencies.length===0?B.muted(`-`):V.cyan(e.dependencies.map(e=>String(e)).join(`, `)),blocks:t?m(e.status)?B.muted(t):V.yellow(t):B.muted(`-`),complexity:typeof e.complexity==`number`?Nn(e.complexity):B.muted(`N/A`)})),n&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{d.push(f({tag:B.muted(`-`),id:B.muted(` └─ ${e.id}`),title:B.muted(Ht(e.title,u(`title`)-6)),status:B.muted(Rt(e.status,!0)),priority:B.muted(e.priority||`medium`),dependencies:B.muted(e.dependencies&&e.dependencies.length>0?e.dependencies.map(e=>String(e)).join(`, `):`-`),blocks:B.muted(`-`),complexity:B.muted(typeof e.complexity==`number`?Nn(e.complexity):`--`)}))})});let p=l.hidden.length>0?`
66
+ `+B.muted(`Hidden to fit width: ${l.hidden.map(e=>Gn.find(t=>t.key===e)?.header).join(`, `)}`):``;return d.toString()+p}var qn=/* @__PURE__ */ r({BANNER_GRADIENT:()=>he,BORDER_COLOR:()=>P,BRAND_COLORS:()=>Oe,MUTED_BOX_BORDER:()=>Ae,ParsePrdProgress:()=>Tn,TABLE_BORDER:()=>le,brandSpinner:()=>yn,calculateDependencyStatistics:()=>kt,calculateSubtaskStatistics:()=>Ot,calculateTaskStatistics:()=>Dt,completedTaskCount:()=>xn,createLink:()=>gt,createProgressBar:()=>Ut,createSpinner:()=>bn,createTaskLink:()=>vt,createTaskTable:()=>Kn,createUrlLink:()=>_t,displayAcceptanceCriteria:()=>cn,displayAsciiBanner:()=>Ct,displayBanner:()=>zn,displayCardBox:()=>Tt,displayCodebasePatterns:()=>dn,displayDashboards:()=>Ft,displayDependencyDashboard:()=>Pt,displayError:()=>Vn,displayErrorBox:()=>Bn,displayExistingInfrastructure:()=>on,displayHeader:()=>qt,displayImplementationApproach:()=>un,displayImplementationDetails:()=>tn,displayImplementationMetadata:()=>pn,displayInfo:()=>Wn,displayInitBanner:()=>wt,displayProjectDashboard:()=>Nt,displayRecommendedNextTask:()=>gn,displayRelevantFiles:()=>an,displayScopeBoundaries:()=>sn,displaySkillsAndCategory:()=>fn,displaySubtasks:()=>rn,displaySuccess:()=>Hn,displaySuggestedActions:()=>mn,displaySuggestedNextSteps:()=>En,displaySyncMessage:()=>kn,displayTaskDetails:()=>hn,displayTaskHeader:()=>$t,displayTaskProperties:()=>en,displayTechnicalConstraints:()=>ln,displayTestStrategy:()=>nn,displayWarning:()=>Un,displayWatchFooter:()=>On,formatCost:()=>In,formatDependenciesWithStatus:()=>Rn,formatDuration:()=>Cn,formatElapsed:()=>Sn,formatStatusLine:()=>Mt,formatUsageLine:()=>Ln,getBoxWidth:()=>zt,getComplexityWithColor:()=>Nn,getComplexityWithScore:()=>Pn,getPriorityBreakdown:()=>At,getPriorityWithColor:()=>jn,getStatusWithColor:()=>Rt,getSuggestedActions:()=>Xt,getTaskDescription:()=>_n,renderDependencyTree:()=>Kt,supportsLinks:()=>yt,theme:()=>B,truncate:()=>Ht});const Jn=H.join(`.taskgraph`,`tasks`,`tasks.json`);function Yn(e){qt({tag:e.tag||`master`,filePath:Jn})}function Z(e){return e?je(e):l()}var Xn=class e extends q{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){Y(e)}}async watchTasks(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.getTasks(e),n=/* @__PURE__ */ new Date;console.clear(),this.displayResults(t,e),On(n);let r;try{r=await this.tmCore.tasks.watch(async r=>{if(r.type===`change`)try{t=await this.getTasks(e),n=/* @__PURE__ */ new Date,console.clear(),this.displayResults(t,e),kn(n),On(n)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(V.yellow(`\nWarning: Failed to refresh tasks: ${t}`))}else r.type===`error`&&r.error&&console.error(V.red(`\n⚠ Watch error: ${r.error.message}`))},{tag:e.tag});let i=()=>{r?.unsubscribe(),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i),await new Promise(()=>{})}catch(e){throw console.error(V.red(`Watch mode error: ${e.message}`)),e}}validateOptions(e){if(e.format&&!u.includes(e.format))return console.error(V.red(`Invalid format: ${e.format}`)),console.error(B.muted(`Valid formats: ${u.join(`, `)}`)),!1;if(e.status){let t=e.status.split(`,`).map(e=>e.trim());for(let e of t)if(e!==`all`&&!_.includes(e))return console.error(V.red(`Invalid status: ${e}`)),console.error(B.muted(`Valid statuses: ${_.join(`, `)}`)),!1}return e.allTags&&e.watch?(console.error(V.red(`--all-tags cannot be used with --watch mode`)),console.error(B.muted(`Use --all-tags without --watch, or --watch without --all-tags`)),!1):!0}async initializeCore(e){this.tmCore||=await x({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}=b(i.tasks);this.displayInvalidDependencyWarnings(o);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[]}));return e.ready&&(s=v(s)),e.blocking&&(s=h(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}=b(i.tasks);this.displayInvalidDependencyWarnings(o,t);let s=i.tasks.map(e=>({...e,blocks:a.get(String(e.id))||[],tagName:t})),c=e.ready?v(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(V.yellow(`\nWarning: Could not fetch tasks from ${i.length} tag(s):`)),i.forEach(({name:e,error:t})=>{console.warn(B.muted(` ${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,allTags:!0}}displayInvalidDependencyWarnings(e,t){if(e.length===0)return;let n=t?` (tag: ${t})`:``;console.warn(V.yellow(`\nWarning: ${e.length} invalid dependency reference(s) found${n}:`)),e.slice(0,5).forEach(({taskId:e,depId:t})=>{console.warn(B.muted(` Task ${e} depends on non-existent task ${t}`))}),e.length>5&&console.warn(B.muted(` ...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;default:this.displayText(e,t)}}displayJson(e){console.log(JSON.stringify({tasks:e.tasks,metadata:{total:e.total,filtered:e.filtered,tag:e.allTags?`all`:e.tag,allTags:e.allTags||!1}},null,2))}displayCompact(e,t){let{tasks:n,tag:r,allTags:i}=e;t.noHeader!==!0&&Yn({tag:i?`all tags`:r||`master`});for(let e of n){let n=d[e.status],r=i&&`tagName`in e?B.accent(`[${e.tagName}] `):``;if(console.log(`${r}${V.cyan(e.id)} ${n} ${e.title}`),t.withSubtasks&&e.subtasks?.length)for(let t of e.subtasks){let e=d[t.status];console.log(` ${B.muted(String(t.id))} ${e} ${B.muted(t.title)}`)}}}displayText(e,t){let{tasks:n,tag:r,allTags:i}=e;if(t.noHeader!==!0&&Yn({tag:i?`all tags`:r||`master`}),n.length===0){Un(`No tasks found matching the criteria.`);return}let a=Dt(n),o=Ot(n),s=kt(n),c=At(n),l=this.findNextTask(n),u=l?n.find(e=>String(e.id)===String(l.id)):void 0,d=t.ready||t.blocking||i;if(d||Ft(a,o,c,s,u),console.log(Kn(n,{showSubtasks:t.withSubtasks,showDependencies:!0,showBlocks:!0,showComplexity:!0,showTag:i})),!d){if(u){let e=_n(u);gn({id:u.id,title:u.title,priority:u.priority,status:u.status,dependencies:u.dependencies,description:e,complexity:u.complexity})}En()}}setLastResult(e){this.lastResult=e}findNextTask(e){let t={critical:4,high:3,medium:2,low:1},n=/* @__PURE__ */ new Set;e.forEach(e=>{m(e.status)&&n.add(String(e.id)),e.subtasks&&e.subtasks.forEach(t=>{m(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}},Zn=class e extends q{tmCore;lastResult;requestedId;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||(ht(`Missing task ID`,"Try `taskgraph show 3`"),process.exit(1));let r=n.split(`,`).map(e=>e.trim()).filter(e=>e.length>0),i=[];for(let e of r){let t=c.safeParse(e);t.success||(ht(`"${e}" isn't a task ID`,"Use a number like `3`, or `3.1` for a subtask"),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){Y(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(V.red(`Invalid format: ${e.format}`)),console.error(B.muted(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await x({projectPath:e})}async getSingleTask(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);this.requestedId=e;let n=await this.tmCore.tasks.get(e);return{task:n.task,found:n.task!==null,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}}displayResults(e,t){switch(t.json?`json`:t.format||`text`){case`json`:this.displayJson(e),`found`in e&&!e.found&&(process.exitCode=1);break;default:`task`in e?this.displaySingleTask(e,t):this.displayMultipleTasks(e,t)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displaySingleTask(e,t){if(!e.found||!e.task){let t=e.originalTaskId??this.requestedId??``,n=t.includes(`.`)?t.split(`.`)[0]:void 0;ht(`${n?`Subtask`:`Task`} ${t} not found`,n?`Run \`taskgraph show ${n}\` to see its subtasks`:"Run `taskgraph list` to see task IDs"),process.exitCode=1}else Yn({tag:this.tmCore?.config.getActiveTag()||`master`}),console.log(),hn(e.task,{statusFilter:t.status,showSuggestedActions:!0,originalTaskId:e.originalTaskId})}displayMultipleTasks(e,t){Yn({tag:this.tmCore?.config.getActiveTag()||`master`}),e.notFound.length>0&&console.log(V.yellow(`\n⚠ Not found: ${e.notFound.join(`, `)}`)),e.tasks.length===0?Un(`No tasks found matching the criteria.`):(console.log(B.brand.bold(`
67
67
  Tasks:
68
- `)),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}},Vn=class e extends J{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(Rn(e.project));let t=await this.getNextTask(e);this.setLastResult(t),e.silent||this.displayResults(t,e)}catch(e){t=!0,Z(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){if(!this.tmCore){let t=U.resolve(e);this.tmCore=await x({projectPath:t})}}async getNextTask(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.tmCore.tasks.getNext(e.tag),n=e.tag||this.tmCore.config.getActiveTag(),r=await this.tmCore.tasks.list({tag:e.tag}),i=r&&r.tasks.length>0;return{task:t,found:t!==null,tag:n,hasAnyTasks:i}}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;default:this.displayText(e)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e){if(In({tag:e.tag||`master`}),!e.found||!e.task){e.hasAnyTasks?(console.log(H.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`)),console.log(`\n${H.dim(`Tip: Try`)} ${H.cyan(`taskgraph list`)} ${H.dim(`to see all tasks`)}`)):(console.log(q(H.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`No tasks available`,titleAlignment:`center`})),console.log(`\n${H.dim(`Tip: Create tasks with`)} ${H.cyan(`taskgraph parse-prd`)} ${H.dim(`or`)} ${H.cyan(`taskgraph add-task`)}`));return}let t=e.task;tn(t,{customHeader:`Next Task: #${t.id} - ${t.title}`,headerColor:`green`,showSuggestedActions:!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}},Hn=class e extends J{tmCore;constructor(e){super(e||`graph`),this.description(`Show tasks as a dependency tree`).option(`-i, --id <id>`,`Show only this task and what depends on it`).option(`-t, --tag <tag>`,`Use a specific tag`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).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{if(e.format&&![`text`,`json`].includes(e.format))throw Error(`Invalid format: ${e.format}. Valid formats are: text, json`);let t=U.resolve(Rn(e.project));this.tmCore=await x({projectPath:t});let n=await this.tmCore.tasks.getDependencyTree({tag:e.tag,rootId:e.id}),r=await this.tmCore.tasks.getNext(e.tag),i={...n,tag:e.tag||this.tmCore.config.getActiveTag(),nextId:r?String(r.id):null};e.format===`json`?console.log(JSON.stringify(i,null,2)):this.displayText(i)}catch(e){t=!0,Z(e,{skipExit:!0})}finally{this.tmCore=void 0}t&&process.exit(1)}displayText(e){if(In({tag:e.tag}),e.total===0){console.log(H.yellow(`No tasks yet.`)),console.log(`${V.muted(`Create some with`)} ${V.brand(`taskgraph parse-prd`)} ${V.muted(`or`)} ${V.brand(`taskgraph add-task`)}`);return}console.log();let t=Nt(e,{nextId:e.nextId,width:Dt()});console.log(t.join(`
69
- `))}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Un=class e extends J{tmCore;lastResult;constructor(e){super(e||`start`),this.description(`Start working on a task by launching claude-code 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 claude-code`).option(`--force`,`Force start even if another task is already in-progress`).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=sn(`Initializing TaskGraph...`).start(),await this.initializeCore(Rn(t.project)),n.succeed(`TaskGraph initialized`);let r=e||t.id||null;r||(n=sn(`Finding next available task...`).start(),r=await this.performGetNextTask(),r?n.succeed(`Found next task: #${r}`):n.fail(`No available tasks found`)),r||(On(`No task ID provided and no available tasks found`),process.exit(1)),t.dryRun||await this.showPreLaunchMessage(r),n=sn(`Preparing task execution...`).start();let i=await this.performStartTask(r,t);i.started?n.succeed(t.dryRun?`Dry run completed`:`Task prepared - launching Claude...`):n.fail(`Task execution failed`),!t.dryRun&&i.command&&(n&&!n.isSpinning&&console.log(),await this.executeChildProcess(i.command));let a=i;this.setLastResult(a),(t.dryRun||!i.started)&&this.displayResults(a,t)}catch(e){n&&n.fail(`Operation failed`),Z(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(H.red(`Invalid format: ${e.format}`)),console.error(V.muted(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await x({projectPath:e})}async performGetNextTask(){if(!this.tmCore)throw Error(`TmCore not initialized`);return this.tmCore.tasks.getNextAvailable()}async showPreLaunchMessage(e){if(!this.tmCore)return;let{task:t,isSubtask:n}=await this.tmCore.tasks.get(e);if(t){let r=n?`Subtask #${e} - ${t.title}`:`Task #${t.id} - ${t.title}`;console.log(H.green(`Starting: `)+H.bold(r)),console.log(V.muted(`Launching Claude Code...`)),console.log()}}async performStartTask(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=null;!t.noStatusUpdate&&!t.dryRun&&(n=sn(`Updating task status to in-progress...`).start());let r=await this.tmCore.tasks.start(e,{dryRun:t.dryRun,force:t.force,updateStatus:!t.noStatusUpdate});if(n&&(r.started?n.succeed(`Task status updated`):n.warn(`Task status update skipped`)),!r)throw Error(`Failed to start task - core result is undefined`);return r}async executeChildProcess(e){return new Promise((t,n)=>{console.log(H.green(`Launching Claude Code…`)),console.log();let r=je(e.executable,e.args,{cwd:e.cwd,stdio:`inherit`,shell:!1});r.on(`close`,e=>{e===0?t():n(/* @__PURE__ */ Error(`Process exited with code ${e}`))}),r.on(`error`,e=>{n(/* @__PURE__ */ 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)})}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;default:this.displayTextResult(e,t)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayTextResult(e,t){if(!e.found||!e.task){console.log(q(H.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}`),tn(n,{customHeader:t,headerColor:`yellow`}),e.executionOutput&&(console.log(),console.log(q(H.bold(`Claude-Code Prompt:`)+`
68
+ `)),console.log(Kn(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}},Qn=class e extends q{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,Y(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){if(!this.tmCore){let t=H.resolve(e);this.tmCore=await x({projectPath:t})}}async getNextTask(e){if(!this.tmCore)throw Error(`TmCore not initialized`);let t=await this.tmCore.tasks.getNext(e.tag),n=e.tag||this.tmCore.config.getActiveTag(),r=await this.tmCore.tasks.list({tag:e.tag}),i=r&&r.tasks.length>0;return{task:t,found:t!==null,tag:n,hasAnyTasks:i}}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;default:this.displayText(e)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e){if(Yn({tag:e.tag||`master`}),!e.found||!e.task){e.hasAnyTasks?(console.log(V.yellow(`✓ All tasks are either completed, blocked by dependencies, or in progress.`)),console.log(`\n${V.dim(`Tip: Try`)} ${V.cyan(`taskgraph list`)} ${V.dim(`to see all tasks`)}`)):(console.log(K(V.yellow(`No tasks found in this project.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`No tasks available`,titleAlignment:`center`})),console.log(`\n${V.dim(`Tip: Create tasks with`)} ${V.cyan(`taskgraph parse-prd`)} ${V.dim(`or`)} ${V.cyan(`taskgraph add-task`)}`));return}let t=e.task;hn(t,{customHeader:`Next Task: #${t.id} - ${t.title}`,headerColor:`green`,showSuggestedActions:!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}},$n=class e extends q{tmCore;constructor(e){super(e||`graph`),this.description(`Show tasks as a dependency tree`).option(`-i, --id <id>`,`Show only this task and what depends on it`).option(`-t, --tag <tag>`,`Use a specific tag`).option(`-f, --format <format>`,`Output format (text, json)`,`text`).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{if(e.format&&![`text`,`json`].includes(e.format))throw Error(`Invalid format: ${e.format}. Valid formats are: text, json`);let t=H.resolve(Z(e.project));this.tmCore=await x({projectPath:t});let n=await this.tmCore.tasks.getDependencyTree({tag:e.tag,rootId:e.id}),r=await this.tmCore.tasks.getNext(e.tag),i={...n,tag:e.tag||this.tmCore.config.getActiveTag(),nextId:r?String(r.id):null};e.format===`json`?console.log(JSON.stringify(i,null,2)):this.displayText(i)}catch(e){t=!0,Y(e,{skipExit:!0})}finally{this.tmCore=void 0}t&&process.exit(1)}displayText(e){if(Yn({tag:e.tag}),e.total===0){console.log(V.yellow(`No tasks yet.`)),console.log(`${B.muted(`Create some with`)} ${B.brand(`taskgraph parse-prd`)} ${B.muted(`or`)} ${B.brand(`taskgraph add-task`)}`);return}console.log();let t=Kt(e,{nextId:e.nextId,width:Bt()});console.log(t.join(`
69
+ `))}static register(t,n){let r=new e(n);return t.addCommand(r),r}},er=class e extends q{tmCore;lastResult;constructor(e){super(e||`start`),this.description(`Start working on a task by launching claude-code 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 claude-code`).option(`--force`,`Force start even if another task is already in-progress`).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=bn(`Initializing TaskGraph...`).start(),await this.initializeCore(Z(t.project)),n.succeed(`TaskGraph initialized`);let r=e||t.id||null;r||(n=bn(`Finding next available task...`).start(),r=await this.performGetNextTask(),r?n.succeed(`Found next task: #${r}`):n.fail(`No available tasks found`)),r||(Vn(`No task ID provided and no available tasks found`),process.exit(1)),t.dryRun||await this.showPreLaunchMessage(r),n=bn(`Preparing task execution...`).start();let i=await this.performStartTask(r,t);i.started?n.succeed(t.dryRun?`Dry run completed`:`Task prepared - launching Claude...`):n.fail(`Task execution failed`),!t.dryRun&&i.command&&(n&&!n.isSpinning&&console.log(),await this.executeChildProcess(i.command));let a=i;this.setLastResult(a),(t.dryRun||!i.started)&&this.displayResults(a,t)}catch(e){n&&n.fail(`Operation failed`),Y(e)}}validateOptions(e){return e.format&&![`text`,`json`].includes(e.format)?(console.error(V.red(`Invalid format: ${e.format}`)),console.error(B.muted(`Valid formats: text, json`)),!1):!0}async initializeCore(e){this.tmCore||=await x({projectPath:e})}async performGetNextTask(){if(!this.tmCore)throw Error(`TmCore not initialized`);return this.tmCore.tasks.getNextAvailable()}async showPreLaunchMessage(e){if(!this.tmCore)return;let{task:t,isSubtask:n}=await this.tmCore.tasks.get(e);if(t){let r=n?`Subtask #${e} - ${t.title}`:`Task #${t.id} - ${t.title}`;console.log(V.green(`Starting: `)+V.bold(r)),console.log(B.muted(`Launching Claude Code...`)),console.log()}}async performStartTask(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=null;!t.noStatusUpdate&&!t.dryRun&&(n=bn(`Updating task status to in-progress...`).start());let r=await this.tmCore.tasks.start(e,{dryRun:t.dryRun,force:t.force,updateStatus:!t.noStatusUpdate});if(n&&(r.started?n.succeed(`Task status updated`):n.warn(`Task status update skipped`)),!r)throw Error(`Failed to start task - core result is undefined`);return r}async executeChildProcess(e){return new Promise((t,n)=>{console.log(V.green(`Launching Claude Code…`)),console.log();let r=Me(e.executable,e.args,{cwd:e.cwd,stdio:`inherit`,shell:!1});r.on(`close`,e=>{e===0?t():n(/* @__PURE__ */ Error(`Process exited with code ${e}`))}),r.on(`error`,e=>{n(/* @__PURE__ */ 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)})}displayResults(e,t){switch(t.format||`text`){case`json`:this.displayJson(e);break;default:this.displayTextResult(e,t)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayTextResult(e,t){if(!e.found||!e.task){console.log(K(V.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}`),hn(n,{customHeader:t,headerColor:`yellow`}),e.executionOutput&&(console.log(),console.log(K(V.bold(`Claude-Code Prompt:`)+`
70
70
 
71
- `+e.executionOutput,{padding:1,borderStyle:`round`,borderColor:P,width:process.stdout.columns*.95||100}))),console.log(),console.log(q(H.yellow(`Dry run - claude-code 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(q(H.green.bold(`✓ Task session complete`)+`
71
+ `+e.executionOutput,{padding:1,borderStyle:`round`,borderColor:P,width:process.stdout.columns*.95||100}))),console.log(),console.log(K(V.yellow(`Dry run - claude-code 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(K(V.green.bold(`✓ Task session complete`)+`
72
72
 
73
- `+V.text(t)+`
73
+ `+B.text(t)+`
74
74
 
75
- `+H.cyan(`Next steps:`)+`
76
- • Run ${H.yellow(`tm show `+n.id)} to review task details\n• Run ${H.yellow(`tm set-status --id=`+r+` --status=done`)} when complete\n• Run ${H.yellow(`tm next`)} to find the next available task\n• Run ${H.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(q(H.red(`✗ Failed to launch claude-code`+(e.error?`\nError: ${e.error}`:``)),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`red`,borderStyle:`round`}))}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 Wn=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`];var Gn=class e extends J{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 - ${Wn.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(H.red(`Error: Task ID is required`)),console.log(H.yellow(`Usage examples:
77
- tm set-status 1 done
78
- tm set-status 1.2 in-progress
79
- tm set-status --id=1 --status=done`)),process.exit(1)),e.status||(console.error(H.red(`Error: Status is required`)),console.log(H.yellow(`Usage examples:
80
- tm set-status 1 done
81
- tm set-status 1,1.1 in-progress
82
- tm set-status --id=1 --status=done`)),process.exit(1)),Wn.includes(e.status)||(console.error(H.red(`Error: Invalid status "${e.status}". Valid options: ${Wn.join(`, `)}`)),process.exit(1)),this.tmCore=await x({projectPath:Rn(e.project)});let n=e.id.split(`,`).map(e=>e.trim()),r=[];for(let e of n){let t=c.safeParse(e);t.success||(console.error(H.red(`Invalid task ID: ${e}`),V.muted(`- ${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:(/* @__PURE__ */ new Date()).toISOString()}))}else e.silent||(console.error(H.red(`\nFailed to update task ${n}:`)),Z(r,{skipExit:!0}));break}this.lastResult={success:!0,updatedTasks:i},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||Z(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;default:t.silent||this.displayTextResults(e)}}displayTextResults(e){if(e.updatedTasks.length===1){let t=e.updatedTasks[0];console.log(q(H.bold(`✓ Updated task ${t.taskId}`)+`
75
+ `+V.cyan(`Next steps:`)+`
76
+ • Run ${V.yellow(`tm show `+n.id)} to review task details\n• Run ${V.yellow(`tm set-status --id=`+r+` --status=done`)} when complete\n• Run ${V.yellow(`tm next`)} to find the next available task\n• Run ${V.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(K(V.red(`✗ Failed to launch claude-code`+(e.error?`\nError: ${e.error}`:``)),{padding:{top:0,bottom:0,left:1,right:1},borderColor:`red`,borderStyle:`round`}))}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 tr=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`];var nr=class e extends q{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 - ${tr.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||(ht(`Missing task ID`,"Try `taskgraph set-status --id=3 --status=done`"),process.exit(1)),e.status||(ht(`Missing status`,`Try \`taskgraph set-status --id=${e.id} --status=done\``),process.exit(1)),tr.includes(e.status)||(ht(`"${e.status}" isn't a status`,`Use one of: ${tr.join(`, `)}`),process.exit(1)),this.tmCore=await x({projectPath:Z(e.project)});let n=e.id.split(`,`).map(e=>e.trim()),r=[];for(let e of n){let t=c.safeParse(e);t.success||(ht(`"${e}" isn't a task ID`,"Use a number like `3`, or `3.1` for a subtask"),process.exit(1)),r.push(t.data)}let i=[],a;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:(/* @__PURE__ */ new Date()).toISOString()}))}else a=r;break}this.lastResult={success:!t,updatedTasks:i},(i.length>0&&!(t&&e.format===`json`)||!t)&&this.displayResults(this.lastResult,e),a!==void 0&&!e.silent&&Y(a,{skipExit:!0})}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||Y(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;default:t.silent||this.displayTextResults(e)}}displayTextResults(e){if(e.updatedTasks.length===1){let t=e.updatedTasks[0];console.log(K(V.bold(`✓ Updated task ${t.taskId}`)+`
83
77
 
84
- ${V.brand(`From:`)} ${this.getStatusDisplay(t.oldStatus)}\n${V.brand(`To:`)} ${this.getStatusDisplay(t.newStatus)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}else console.log(q(H.bold(`✓ Updated ${e.updatedTasks.length} tasks`)+`
78
+ ${B.brand(`From:`)} ${this.getStatusDisplay(t.oldStatus)}\n${B.brand(`To:`)} ${this.getStatusDisplay(t.newStatus)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}else console.log(K(V.bold(`✓ Updated ${e.updatedTasks.length} tasks`)+`
85
79
 
86
- `+e.updatedTasks.map(e=>`${H.cyan(e.taskId)}: ${this.getStatusDisplay(e.oldStatus)} → ${this.getStatusDisplay(e.newStatus)}`).join(`
87
- `),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}getStatusDisplay(e){return({pending:H.yellow,"in-progress":V.brand,done:H.green,deferred:V.muted,cancelled:H.red,blocked:H.red,review:H.magenta,completed:H.green}[e]||V.text)(e)}getLastResult(){return this.lastResult}static register(t,n){let r=new e(n);return t.addCommand(r),r}};const Kn=`taskgraph-ai`,qn=`stephennmiller/taskgraph-ai`;function Jn(e,t,n){let r=`${V.brand.bold(`Update Available!`)} ${H.dim(e)} → ${H.green(t)}`;if(n&&n.length>0){r+=`
80
+ `+e.updatedTasks.map(e=>`${V.cyan(e.taskId)}: ${this.getStatusDisplay(e.oldStatus)} → ${this.getStatusDisplay(e.newStatus)}`).join(`
81
+ `),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}}))}getStatusDisplay(e){return({pending:V.yellow,"in-progress":B.brand,done:V.green,deferred:B.muted,cancelled:V.red,blocked:V.red,review:V.magenta,completed:V.green}[e]||B.text)(e)}getLastResult(){return this.lastResult}static register(t,n){let r=new e(n);return t.addCommand(r),r}};const rr=`taskgraph-ai`,ir=`stephennmiller/taskgraph-ai`;function ar(e,t,n){let r=`${B.brand.bold(`Update Available!`)} ${V.dim(e)} → ${V.green(t)}`;if(n&&n.length>0){r+=`
88
82
 
89
- `+H.bold(`What's New:`);for(let e of n)r+=`
90
- `+H.cyan(`• `)+e;r+=`
83
+ `+V.bold(`What's New:`);for(let e of n)r+=`
84
+ `+V.cyan(`• `)+e;r+=`
91
85
 
92
86
  Auto-updating to the latest version...`}else r+=`
93
87
 
94
- Auto-updating to the latest version with new features and bug fixes...`;let i=q(r,{padding:1,margin:{top:1,bottom:1},borderColor:`yellow`,borderStyle:`round`});console.log(i)}function Yn(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}async function Xn(e){return new Promise(t=>{let n={hostname:`registry.npmjs.org`,path:`/${Kn}/${e}`,method:`GET`,headers:{Accept:`application/json`,"User-Agent":`${Kn}/${e}`}},r=Ge.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 Zn(e,t,n,r=5){return r<=0?(console.error(H.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":`${Kn}/${n}`}},s=Ge.request(o,e=>{if(e.statusCode===301||e.statusCode===302){let a=e.headers.location;if(a){Zn(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 qe.SingleBar({format:`${V.brand(`Downloading`)} ${H.cyan(`{bar}`)} {percentage}% | {downloaded}/{total}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},qe.Presets.shades_classic);a>0?s.start(a,0,{downloaded:Yn(0),total:Yn(a)}):console.log(V.brand(`Downloading ${Kn}@${n}...`));let c=K.createWriteStream(t);e.on(`data`,e=>{o+=e.length,a>0&&s.update(o,{downloaded:Yn(o),total:Yn(a)})}),e.pipe(c),c.on(`finish`,()=>{a>0&&s.stop(),c.close(()=>{console.log(H.green(`✓`)+H.dim(` Downloaded ${Yn(o)}`)),i(!0)})}),c.on(`error`,e=>{a>0&&s.stop(),console.error(H.red(`Download error:`),e.message),K.unlink(t,()=>{}),i(!1)})});s.on(`error`,e=>{console.error(H.red(`Request error:`),e.message),i(!1)}),s.setTimeout(12e4,()=>{s.destroy(),console.error(H.red(`Download timeout`)),i(!1)}),s.end()})}const Qn=[{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}],$n=Qn.reduce((e,t)=>e+t.weight,0);function er(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 tr(e,t){if(e<0||e>=Qn.length)return e>=Qn.length?100:0;let n=0;for(let t=0;t<e;t++)n+=Qn[t].weight;let r=Qn[e].weight*t/100;return Math.round((n+r)/$n*100)}async function nr(e){let t=new qe.SingleBar({format:`${V.brand(`Installing`)} ${H.cyan(`{bar}`)} {percentage}% | {phase}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},qe.Presets.shades_classic);t.start(100,0,{phase:Qn[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<Qn.length;t++){let n=Qn[t].weight/$n*a;if(e<s+n){o=t;break}s+=n,o=t}o>n&&(n=o);let c=Qn.slice(0,n).reduce((e,t)=>e+t.weight,0)/$n*a,l=Qn[n].weight/$n*a,u=e-c,d=Math.min(u/l*100,95),f=tr(n,d);f>r&&(r=f,t.update(r,{phase:Qn[n].name}))},100);return new Promise(i=>{let o=je(`npm`,[`install`,`-g`,e,`--no-fund`,`--no-audit`],{stdio:[`ignore`,`pipe`,`pipe`]}),s=``;o.stdout.on(`data`,e=>{let i=er(e.toString());if(i>n){n=i;let e=tr(n,0);e>r&&(r=e,t.update(r,{phase:Qn[n].name}))}}),o.stderr.on(`data`,e=>{let i=e.toString();s+=i;let a=er(i);if(a>n){n=a;let e=tr(n,0);e>r&&(r=e,t.update(r,{phase:Qn[n].name}))}}),o.on(`close`,n=>{if(clearInterval(a),t.update(100,{phase:`Complete`}),t.stop(),K.existsSync(e)&&K.unlink(e,()=>{}),n===0)console.log(H.green(`✓`)+H.green(` Update installed successfully`)),i(!0);else{if(console.log(H.red(`✗`)+H.red(` Installation failed`)),s){let e=s.split(`
88
+ Auto-updating to the latest version with new features and bug fixes...`;let i=K(r,{padding:1,margin:{top:1,bottom:1},borderColor:`yellow`,borderStyle:`round`});console.log(i)}function or(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}async function sr(e){return new Promise(t=>{let n={hostname:`registry.npmjs.org`,path:`/${rr}/${e}`,method:`GET`,headers:{Accept:`application/json`,"User-Agent":`${rr}/${e}`}},r=Ke.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 cr(e,t,n,r=5){return r<=0?(console.error(V.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":`${rr}/${n}`}},s=Ke.request(o,e=>{if(e.statusCode===301||e.statusCode===302){let a=e.headers.location;if(a){cr(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 Je.SingleBar({format:`${B.brand(`Downloading`)} ${V.cyan(`{bar}`)} {percentage}% | {downloaded}/{total}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},Je.Presets.shades_classic);a>0?s.start(a,0,{downloaded:or(0),total:or(a)}):console.log(B.brand(`Downloading ${rr}@${n}...`));let c=G.createWriteStream(t);e.on(`data`,e=>{o+=e.length,a>0&&s.update(o,{downloaded:or(o),total:or(a)})}),e.pipe(c),c.on(`finish`,()=>{a>0&&s.stop(),c.close(()=>{console.log(V.green(`✓`)+V.dim(` Downloaded ${or(o)}`)),i(!0)})}),c.on(`error`,e=>{a>0&&s.stop(),console.error(V.red(`Download error:`),e.message),G.unlink(t,()=>{}),i(!1)})});s.on(`error`,e=>{console.error(V.red(`Request error:`),e.message),i(!1)}),s.setTimeout(12e4,()=>{s.destroy(),console.error(V.red(`Download timeout`)),i(!1)}),s.end()})}const lr=[{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}],ur=lr.reduce((e,t)=>e+t.weight,0);function dr(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>=lr.length)return e>=lr.length?100:0;let n=0;for(let t=0;t<e;t++)n+=lr[t].weight;let r=lr[e].weight*t/100;return Math.round((n+r)/ur*100)}async function pr(e){let t=new Je.SingleBar({format:`${B.brand(`Installing`)} ${V.cyan(`{bar}`)} {percentage}% | {phase}`,barCompleteChar:`█`,barIncompleteChar:`░`,hideCursor:!0,clearOnComplete:!0},Je.Presets.shades_classic);t.start(100,0,{phase:lr[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<lr.length;t++){let n=lr[t].weight/ur*a;if(e<s+n){o=t;break}s+=n,o=t}o>n&&(n=o);let c=lr.slice(0,n).reduce((e,t)=>e+t.weight,0)/ur*a,l=lr[n].weight/ur*a,u=e-c,d=Math.min(u/l*100,95),f=fr(n,d);f>r&&(r=f,t.update(r,{phase:lr[n].name}))},100);return new Promise(i=>{let o=Me(`npm`,[`install`,`-g`,e,`--no-fund`,`--no-audit`],{stdio:[`ignore`,`pipe`,`pipe`]}),s=``;o.stdout.on(`data`,e=>{let i=dr(e.toString());if(i>n){n=i;let e=fr(n,0);e>r&&(r=e,t.update(r,{phase:lr[n].name}))}}),o.stderr.on(`data`,e=>{let i=e.toString();s+=i;let a=dr(i);if(a>n){n=a;let e=fr(n,0);e>r&&(r=e,t.update(r,{phase:lr[n].name}))}}),o.on(`close`,n=>{if(clearInterval(a),t.update(100,{phase:`Complete`}),t.stop(),G.existsSync(e)&&G.unlink(e,()=>{}),n===0)console.log(V.green(`✓`)+V.green(` Update installed successfully`)),i(!0);else{if(console.log(V.red(`✗`)+V.red(` Installation failed`)),s){let e=s.split(`
95
89
  `).filter(e=>e.includes(`ERR`)||e.includes(`error`)||e.includes(`WARN`)).join(`
96
- `).trim();e&&console.log(H.dim(`Error: ${e}`))}i(!1)}}),o.on(`error`,n=>{clearInterval(a),t.stop(),K.unlink(e,()=>{}),console.log(H.red(`✗`)+H.red(` Installation failed`)),console.log(H.red(`Error:`),n.message),i(!1)})})}async function rr(e){let t=sn(V.brand(`Updating ${Kn} to version ${H.green(e)}`)).start();return new Promise(n=>{let r=je(`npm`,[`install`,`-g`,`${Kn}@${e}`,`--no-fund`,`--no-audit`,`--loglevel=warn`],{stdio:[`ignore`,`pipe`,`pipe`]}),i=``;r.stdout.on(`data`,()=>{t.text=V.brand(`Installing ${Kn}@${e}...`)}),r.stderr.on(`data`,e=>{i+=e.toString()}),r.on(`close`,r=>{r===0?(t.succeed(H.green(`Successfully updated to version ${H.bold(e)}`)),n(!0)):(t.fail(H.red(`Auto-update failed`)),console.log(H.cyan(`Please run manually: npm install -g ${Kn}@${e}`)),i&&console.log(H.dim(`Error: ${i.trim()}`)),n(!1))}),r.on(`error`,r=>{t.fail(H.red(`Auto-update failed`)),console.log(H.red(`Error:`),r.message),console.log(H.cyan(`Please run manually: npm install -g ${Kn}@${e}`)),n(!1)})})}async function ir(e){if(We.env.TASKGRAPH_SKIP_AUTO_UPDATE===`1`||We.env.CI||We.env.NODE_ENV===`test`){let e=We.env.TASKGRAPH_SKIP_AUTO_UPDATE===`1`?`TASKGRAPH_SKIP_AUTO_UPDATE=1`:We.env.CI?`CI environment`:`NODE_ENV=test`;return console.log(H.dim(`Skipping auto-update (${e})`)),!1}let t=await Xn(e);if(!t)return rr(e);let n=Ke.tmpdir(),r=W.join(n,`${Kn}-${e}.tgz`);return await Zn(t.url,r,e)?await nr(r)?(console.log(H.green(`Successfully updated to version ${H.bold(e)}`)),!0):(console.log(H.cyan(`Please run manually: npm install -g ${Kn}@${e}`)),!1):(console.log(H.dim(`Falling back to npm install...`)),rr(e))}function ar(e){let t=e.slice(2);console.log(H.dim(`Restarting with updated version...
97
- `));let n=je(`taskgraph`,t,{stdio:`inherit`,detached:!1,shell:We.platform===`win32`});n.on(`exit`,(e,t)=>{t?We.kill(We.pid,t):We.exit(e??0)}),n.on(`error`,e=>{console.error(H.red(`Failed to restart with new version:`),e.message),console.log(H.yellow(`Please run your command again manually.`)),We.exit(1)})}function or(e,t=null){let n={high:3,medium:2,low:1},r=(e,t)=>typeof t==`string`&&t.includes(`.`)?t:`${e}.${t}`,i=/* @__PURE__ */ 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&&E(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&&E(s,t),s}async function sr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{copyFromCurrent:s=!1,copyFromTag:c,description:l}=n,u=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)};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=F(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:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ 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||ne(o);a=w(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:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:l||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`}};let d={};for(let[e,t]of Object.entries(r))e!==`_rawTaggedData`&&(d[e]=t);return I(e,d,o),u.success(`Successfully created tag "${t}"`),i===`json`||i===`text`&&console.log(q(H.green.bold(`✓ Tag Created Successfully`)+`\n\nTag Name: ${H.cyan(t)}\nTasks Copied: ${H.yellow(a.length)}`+(s||c?`\nSource Tag: ${H.cyan(c||ne(o))}`:``)+(l?`\nDescription: ${V.muted(l)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tagName:t,created:!0,tasksCopied:a.length,sourceTag:s||c?c||ne(o):null,description:l||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`}}catch(e){throw u.error(`Error creating tag: ${e.message}`),e}}async function cr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{yes:s=!1}=n,c=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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=F(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:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ 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=ne(o)===t,l=w(r,t).length;if(!s&&l>0&&i===`text`){if(console.log(q(H.yellow.bold(`⚠ WARNING: Tag Deletion`)+`\n\nYou are about to delete tag "${H.cyan(t)}"\nThis will permanently delete ${H.red.bold(l)} tasks
90
+ `).trim();e&&console.log(V.dim(`Error: ${e}`))}i(!1)}}),o.on(`error`,n=>{clearInterval(a),t.stop(),G.unlink(e,()=>{}),console.log(V.red(`✗`)+V.red(` Installation failed`)),console.log(V.red(`Error:`),n.message),i(!1)})})}async function mr(e){let t=bn(B.brand(`Updating ${rr} to version ${V.green(e)}`)).start();return new Promise(n=>{let r=Me(`npm`,[`install`,`-g`,`${rr}@${e}`,`--no-fund`,`--no-audit`,`--loglevel=warn`],{stdio:[`ignore`,`pipe`,`pipe`]}),i=``;r.stdout.on(`data`,()=>{t.text=B.brand(`Installing ${rr}@${e}...`)}),r.stderr.on(`data`,e=>{i+=e.toString()}),r.on(`close`,r=>{r===0?(t.succeed(V.green(`Successfully updated to version ${V.bold(e)}`)),n(!0)):(t.fail(V.red(`Auto-update failed`)),console.log(V.cyan(`Please run manually: npm install -g ${rr}@${e}`)),i&&console.log(V.dim(`Error: ${i.trim()}`)),n(!1))}),r.on(`error`,r=>{t.fail(V.red(`Auto-update failed`)),console.log(V.red(`Error:`),r.message),console.log(V.cyan(`Please run manually: npm install -g ${rr}@${e}`)),n(!1)})})}async function hr(e){if(Ge.env.TASKGRAPH_SKIP_AUTO_UPDATE===`1`||Ge.env.CI||Ge.env.NODE_ENV===`test`){let e=Ge.env.TASKGRAPH_SKIP_AUTO_UPDATE===`1`?`TASKGRAPH_SKIP_AUTO_UPDATE=1`:Ge.env.CI?`CI environment`:`NODE_ENV=test`;return console.log(V.dim(`Skipping auto-update (${e})`)),!1}let t=await sr(e);if(!t)return mr(e);let n=qe.tmpdir(),r=U.join(n,`${rr}-${e}.tgz`);return await cr(t.url,r,e)?await pr(r)?(console.log(V.green(`Successfully updated to version ${V.bold(e)}`)),!0):(console.log(V.cyan(`Please run manually: npm install -g ${rr}@${e}`)),!1):(console.log(V.dim(`Falling back to npm install...`)),mr(e))}function gr(e){let t=e.slice(2);console.log(V.dim(`Restarting with updated version...
91
+ `));let n=Me(`taskgraph`,t,{stdio:`inherit`,detached:!1,shell:Ge.platform===`win32`});n.on(`exit`,(e,t)=>{t?Ge.kill(Ge.pid,t):Ge.exit(e??0)}),n.on(`error`,e=>{console.error(V.red(`Failed to restart with new version:`),e.message),console.log(V.yellow(`Please run your command again manually.`)),Ge.exit(1)})}function _r(e,t=null){let n={high:3,medium:2,low:1},r=(e,t)=>typeof t==`string`&&t.includes(`.`)?t:`${e}.${t}`,i=/* @__PURE__ */ 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&&E(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&&E(s,t),s}async function vr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,{copyFromCurrent:s=!1,copyFromTag:c,description:l}=n,u=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)};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=F(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:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ 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||ne(o);a=w(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:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:l||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`}};let d={};for(let[e,t]of Object.entries(r))e!==`_rawTaggedData`&&(d[e]=t);return I(e,d,o),u.success(`Successfully created tag "${t}"`),i===`json`||i===`text`&&console.log(K(V.green.bold(`✓ Tag Created Successfully`)+`\n\nTag Name: ${V.cyan(t)}\nTasks Copied: ${V.yellow(a.length)}`+(s||c?`\nSource Tag: ${V.cyan(c||ne(o))}`:``)+(l?`\nDescription: ${B.muted(l)}`:``),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tagName:t,created:!0,tasksCopied:a.length,sourceTag:s||c?c||ne(o):null,description:l||`Tag created on ${(/* @__PURE__ */ 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)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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=F(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:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ 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=ne(o)===t,l=w(r,t).length;if(!s&&l>0&&i===`text`){if(console.log(K(V.yellow.bold(`⚠ WARNING: Tag Deletion`)+`\n\nYou are about to delete tag "${V.cyan(t)}"\nThis will permanently delete ${V.red.bold(l)} tasks
98
92
 
99
- This action cannot be undone!`,{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),!(await Je.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 Je.prompt([{type:`input`,name:`tagNameConfirm`,message:`To confirm deletion, please type the tag name "${t}":`,validate:e=>e===t||`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 mr(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 I(e,u,o),c.success(`Successfully deleted tag "${t}"`),i===`json`||i===`text`&&console.log(q(H.red.bold(`✓ Tag Deleted Successfully`)+`\n\nTag Name: ${H.cyan(t)}\nTasks Deleted: ${H.yellow(l)}`+(a?`\n${H.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 lr(e,t,n={}){let r=!1;try{let i;try{let t=K.statSync(e);i=t.birthtime<t.mtime?t.birthtime:t.mtime}catch{i=/* @__PURE__ */ 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);I(e,r,n.projectRoot)}}catch(e){(n.mcpLog||{warn:(...e)=>L(`warn`,...e)}).warn(`Could not enhance tag metadata: ${e.message}`)}return r}async function ur(e,t={},n={},r=`text`){let{mcpLog:i,projectRoot:a}=n,{showTaskCounts:o=!0,showMetadata:s=!1,ready:c=!1}=t,l=i||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)};try{l.info(`Listing available tags`),l.info(`Using file storage for tags`);let t=F(e,a);if(!t)throw Error(`Could not read tasks file at ${e}`);let i=ne(a),u=t._rawTaggedData||t;await lr(e,u,n);let d=[];for(let[e,t]of Object.entries(u)){if(e===`tasks`||e===`tag`||e===`_rawTaggedData`||!t||typeof t!=`object`||!Array.isArray(t.tasks))continue;let n=t.tasks||[],r=t.metadata||{},a=n.map(e=>({...e,blocks:[]})),o=v(a);d.push({name:e,isCurrent:e===i,completedTasks:n.filter(e=>m(e.status)).length,readyTasks:o.length,tasks:n||[],created:r.created||`Unknown`,description:r.description||`No description`})}d.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:e.name.localeCompare(t.name));let f=d;if(c&&(f=d.filter(e=>e.readyTasks>0),l.info(`Filtered to ${f.length} tags with ready tasks`)),l.success(`Found ${f.length} tags`),r===`json`)return{tags:f,currentTag:i,totalTags:f.length};if(r===`text`){if(f.length===0){let e=c?`No tags with ready tasks found`:`No tags found`;return console.log(q(H.yellow(e),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tags:[],currentTag:i,totalTags:0}}let e=[H.cyan.bold(`Tag Name`)];o&&(e.push(H.cyan.bold(`Tasks`)),e.push(H.cyan.bold(`Ready`)),e.push(H.cyan.bold(`Done`))),s&&(e.push(H.cyan.bold(`Created`)),e.push(H.cyan.bold(`Description`)));let t=Math.max(process.stdout.columns||120,80),n=Math.floor(t*.95),r;r=s?[.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 a=new Y({head:e,colWidths:r,wordWrap:!0,style:{border:le}});f.forEach(e=>{let t=[],n=e.isCurrent?`${H.green(`●`)} ${H.green.bold(e.name)} ${V.muted(`(current)`)}`:` ${e.name}`;if(t.push(n),o&&(t.push(V.text(e.tasks.length.toString())),t.push(e.readyTasks>0?H.yellow(e.readyTasks.toString()):V.muted(`0`)),t.push(H.green(e.completedTasks.toString()))),s){let n=e.created===`Unknown`?`Unknown`:new Date(e.created).toLocaleDateString();t.push(V.muted(n)),t.push(V.muted(z(e.description,50)))}a.push(t)}),console.log(a.toString())}return{tags:f,currentTag:i,totalTags:f.length}}catch(e){throw l.error(`Error listing tags: ${e.message}`),e}}async function dr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,s=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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}`),s.info(`Using file storage for tag switch`);let n=F(e,o);if(!n)throw Error(`Could not read tasks file at ${e}`);if(!(n._rawTaggedData||n)[t])throw Error(`Tag "${t}" does not exist`);let r=ne(o);await mr(o,t);let a=F(e,o,t),c=a&&a.tasks||[],l=c.length,u=or(c);if(s.success(`Successfully switched to tag "${t}"`),i===`json`)return{previousTag:r,currentTag:t,switched:!0,taskCount:l,nextTask:u};if(i===`text`){let e=``;e=u?`\nNext Task: ${H.cyan(`#${u.id}`)} - ${V.text(u.title)}`:`\nNext Task: ${V.muted(`No eligible tasks available`)}`,console.log(q(H.green.bold(`✓ Tag Switched Successfully`)+`\n\nPrevious Tag: ${H.cyan(r)}\nCurrent Tag: ${H.green.bold(t)}\nAvailable Tasks: ${H.yellow(l)}`+e,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))}return{previousTag:r,currentTag:t,switched:!0,taskCount:l,nextTask:u}}catch(e){throw s.error(`Error switching tag: ${e.message}`),e}}async function fr(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,c=o||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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=F(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=ne(s)===t;i[n]={...i[t]},i[n].metadata&&(i[n].metadata.renamed={from:t,date:(/* @__PURE__ */ new Date()).toISOString()}),delete i[t],o&&(await mr(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);I(e,l,s);let u=w(i,n).length;return c.success(`Successfully renamed tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(q(H.green.bold(`✓ Tag Renamed Successfully`)+`\n\nOld Name: ${H.cyan(t)}\nNew Name: ${H.green.bold(n)}\nTasks: ${H.yellow(u)}`+(o?`\n${H.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 pr(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,{description:c}=r,l=o||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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=F(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=w(i,t);i[n]={tasks:JSON.parse(JSON.stringify(o)),metadata:{created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:c||`Copy of "${t}" created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,copiedFrom:{tag:t,date:(/* @__PURE__ */ new Date()).toISOString()}}};let u={};for(let[e,t]of Object.entries(i))e!==`_rawTaggedData`&&(u[e]=t);return I(e,u,s),l.success(`Successfully copied tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(q(H.green.bold(`✓ Tag Copied Successfully`)+`\n\nSource Tag: ${H.cyan(t)}\nTarget Tag: ${H.green.bold(n)}\nTasks Copied: ${H.yellow(o.length)}`+(c?`\nDescription: ${V.muted(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 ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`}}catch(e){throw l.error(`Error copying tag: ${e.message}`),e}}async function mr(e,t){try{let n=W.join(e,`.taskgraph`,`state.json`),r={};if(K.existsSync(n)){let e=K.readFileSync(n,`utf8`);r=JSON.parse(e)}r.currentTag=t,r.lastSwitched=(/* @__PURE__ */ new Date()).toISOString(),r.branchTagMapping||(r.branchTagMapping={}),r.migrationNoticeShown===void 0&&(r.migrationNoticeShown=!1),K.writeFileSync(n,JSON.stringify(r,null,2),`utf8`)}catch(e){L(`warn`,`Could not update current tag in state.json: ${e.message}`)}}async function hr(e,t,n){try{let r=W.join(e,`.taskgraph`,`state.json`),i={};if(K.existsSync(r)){let e=K.readFileSync(r,`utf8`);i=JSON.parse(e)}i.branchTagMapping||(i.branchTagMapping={}),i.branchTagMapping[t]=n,K.writeFileSync(r,JSON.stringify(i,null,2),`utf8`)}catch(e){L(`warn`,`Could not update branch-tag mapping: ${e.message}`)}}async function gr(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-BezpEZd4.js`),p=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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 sr(e,n,{copyFromCurrent:s,copyFromTag:c,description:l||`Tag created from git branch "${t}"`},r,i);return await hr(o,t,n),p.info(`Updated branch-tag mapping: ${t} -> ${n}`),u&&(await mr(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 _r=class e extends J{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`,`
93
+ This action cannot be undone!`,{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),!(await Ye.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 Ye.prompt([{type:`input`,name:`tagNameConfirm`,message:`To confirm deletion, please type the tag name "${t}":`,validate:e=>e===t||`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 Tr(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 I(e,u,o),c.success(`Successfully deleted tag "${t}"`),i===`json`||i===`text`&&console.log(K(V.red.bold(`✓ Tag Deleted Successfully`)+`\n\nTag Name: ${V.cyan(t)}\nTasks Deleted: ${V.yellow(l)}`+(a?`\n${V.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 br(e,t,n={}){let r=!1;try{let i;try{let t=G.statSync(e);i=t.birthtime<t.mtime?t.birthtime:t.mtime}catch{i=/* @__PURE__ */ 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);I(e,r,n.projectRoot)}}catch(e){(n.mcpLog||{warn:(...e)=>L(`warn`,...e)}).warn(`Could not enhance tag metadata: ${e.message}`)}return r}async function xr(e,t={},n={},r=`text`){let{mcpLog:i,projectRoot:a}=n,{showTaskCounts:o=!0,showMetadata:s=!1,ready:c=!1}=t,l=i||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)};try{l.info(`Listing available tags`),l.info(`Using file storage for tags`);let t=F(e,a);if(!t)throw Error(`Could not read tasks file at ${e}`);let i=ne(a),u=t._rawTaggedData||t;await br(e,u,n);let d=[];for(let[e,t]of Object.entries(u)){if(e===`tasks`||e===`tag`||e===`_rawTaggedData`||!t||typeof t!=`object`||!Array.isArray(t.tasks))continue;let n=t.tasks||[],r=t.metadata||{},a=n.map(e=>({...e,blocks:[]})),o=v(a);d.push({name:e,isCurrent:e===i,completedTasks:n.filter(e=>m(e.status)).length,readyTasks:o.length,tasks:n||[],created:r.created||`Unknown`,description:r.description||`No description`})}d.sort((e,t)=>e.isCurrent?-1:t.isCurrent?1:e.name.localeCompare(t.name));let f=d;if(c&&(f=d.filter(e=>e.readyTasks>0),l.info(`Filtered to ${f.length} tags with ready tasks`)),l.success(`Found ${f.length} tags`),r===`json`)return{tags:f,currentTag:i,totalTags:f.length};if(r===`text`){if(f.length===0){let e=c?`No tags with ready tasks found`:`No tags found`;return console.log(K(V.yellow(e),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1,bottom:1}})),{tags:[],currentTag:i,totalTags:0}}let e=[V.cyan.bold(`Tag Name`)];o&&(e.push(V.cyan.bold(`Tasks`)),e.push(V.cyan.bold(`Ready`)),e.push(V.cyan.bold(`Done`))),s&&(e.push(V.cyan.bold(`Created`)),e.push(V.cyan.bold(`Description`)));let t=Math.max(process.stdout.columns||120,80),n=Math.floor(t*.95),r;r=s?[.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 a=new J({head:e,colWidths:r,wordWrap:!0,style:{border:le}});f.forEach(e=>{let t=[],n=e.isCurrent?`${V.green(`●`)} ${V.green.bold(e.name)} ${B.muted(`(current)`)}`:` ${e.name}`;if(t.push(n),o&&(t.push(B.text(e.tasks.length.toString())),t.push(e.readyTasks>0?V.yellow(e.readyTasks.toString()):B.muted(`0`)),t.push(V.green(e.completedTasks.toString()))),s){let n=e.created===`Unknown`?`Unknown`:new Date(e.created).toLocaleDateString();t.push(B.muted(n)),t.push(B.muted(R(e.description,50)))}a.push(t)}),console.log(a.toString())}return{tags:f,currentTag:i,totalTags:f.length}}catch(e){throw l.error(`Error listing tags: ${e.message}`),e}}async function Sr(e,t,n={},r={},i=`text`){let{mcpLog:a,projectRoot:o}=r,s=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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}`),s.info(`Using file storage for tag switch`);let n=F(e,o);if(!n)throw Error(`Could not read tasks file at ${e}`);if(!(n._rawTaggedData||n)[t])throw Error(`Tag "${t}" does not exist`);let r=ne(o);await Tr(o,t);let a=F(e,o,t),c=a&&a.tasks||[],l=c.length,u=_r(c);if(s.success(`Successfully switched to tag "${t}"`),i===`json`)return{previousTag:r,currentTag:t,switched:!0,taskCount:l,nextTask:u};if(i===`text`){let e=``;e=u?`\nNext Task: ${V.cyan(`#${u.id}`)} - ${B.text(u.title)}`:`\nNext Task: ${B.muted(`No eligible tasks available`)}`,console.log(K(V.green.bold(`✓ Tag Switched Successfully`)+`\n\nPrevious Tag: ${V.cyan(r)}\nCurrent Tag: ${V.green.bold(t)}\nAvailable Tasks: ${V.yellow(l)}`+e,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))}return{previousTag:r,currentTag:t,switched:!0,taskCount:l,nextTask:u}}catch(e){throw a&&s.error(`Error switching tag: ${e.message}`),e}}async function Cr(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,c=o||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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=F(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=ne(s)===t;i[n]={...i[t]},i[n].metadata&&(i[n].metadata.renamed={from:t,date:(/* @__PURE__ */ new Date()).toISOString()}),delete i[t],o&&(await Tr(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);I(e,l,s);let u=w(i,n).length;return c.success(`Successfully renamed tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(K(V.green.bold(`✓ Tag Renamed Successfully`)+`\n\nOld Name: ${V.cyan(t)}\nNew Name: ${V.green.bold(n)}\nTasks: ${V.yellow(u)}`+(o?`\n${V.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 wr(e,t,n,r={},i={},a=`text`){let{mcpLog:o,projectRoot:s}=i,{description:c}=r,l=o||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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=F(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=w(i,t);i[n]={tasks:JSON.parse(JSON.stringify(o)),metadata:{created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:c||`Copy of "${t}" created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,copiedFrom:{tag:t,date:(/* @__PURE__ */ new Date()).toISOString()}}};let u={};for(let[e,t]of Object.entries(i))e!==`_rawTaggedData`&&(u[e]=t);return I(e,u,s),l.success(`Successfully copied tag from "${t}" to "${n}"`),a===`json`||a===`text`&&console.log(K(V.green.bold(`✓ Tag Copied Successfully`)+`\n\nSource Tag: ${V.cyan(t)}\nTarget Tag: ${V.green.bold(n)}\nTasks Copied: ${V.yellow(o.length)}`+(c?`\nDescription: ${B.muted(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 ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`}}catch(e){throw l.error(`Error copying tag: ${e.message}`),e}}async function Tr(e,t){try{let n=U.join(e,`.taskgraph`,`state.json`),r={};if(G.existsSync(n)){let e=G.readFileSync(n,`utf8`);r=JSON.parse(e)}r.currentTag=t,r.lastSwitched=(/* @__PURE__ */ new Date()).toISOString(),r.branchTagMapping||(r.branchTagMapping={}),r.migrationNoticeShown===void 0&&(r.migrationNoticeShown=!1),G.writeFileSync(n,JSON.stringify(r,null,2),`utf8`)}catch(e){L(`warn`,`Could not update current tag in state.json: ${e.message}`)}}async function Er(e,t,n){try{let r=U.join(e,`.taskgraph`,`state.json`),i={};if(G.existsSync(r)){let e=G.readFileSync(r,`utf8`);i=JSON.parse(e)}i.branchTagMapping||(i.branchTagMapping={}),i.branchTagMapping[t]=n,G.writeFileSync(r,JSON.stringify(i,null,2),`utf8`)}catch(e){L(`warn`,`Could not update branch-tag mapping: ${e.message}`)}}async function Dr(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-BezpEZd4.js`),p=a||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`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 vr(e,n,{copyFromCurrent:s,copyFromTag:c,description:l||`Tag created from git branch "${t}"`},r,i);return await Er(o,t,n),p.info(`Updated branch-tag mapping: ${t} -> ${n}`),u&&(await Tr(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 Or=class e extends q{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`,`
100
94
  Examples:
101
95
  $ tm tags # List all tags (default)
102
96
  $ tm tags list # List all tags (explicit)
@@ -124,11 +118,11 @@ Examples:
124
118
  Examples:
125
119
  $ tm tags copy sprint-1 sprint-2
126
120
  $ tm tags copy sprint-1 sprint-2 --description "Next sprint tasks"
127
- `).action(async(e,t,n)=>{await this.executeCopy(e,t,n)})}async initTmCore(){this.tmCore||=await x({projectPath:process.cwd()})}async executeList(e){try{await this.initTmCore();let{projectRoot:t,tasksPath:n}=y(),r=await ur(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){Z(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}=y();await sr(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){Z(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}=y(),r=await dr(n,e,{},{projectRoot:t},`text`);this.setLastResult({success:!0,action:`use`,currentTag:r.currentTag,message:`Switched to tag: ${e}`})}catch(e){Z(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}=y();await cr(r,e,{yes:t?.yes||!1},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`remove`,message:`Removed tag: ${e}`})}catch(e){Z(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}=y();await fr(r,e,t,{},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`rename`,message:`Renamed tag from "${e}" to "${t}"`})}catch(e){Z(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}=y();await pr(i,e,t,{description:n?.description},{projectRoot:r},`text`),this.setLastResult({success:!0,action:`copy`,message:`Copied tag from "${e}" to "${t}"`})}catch(e){Z(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}},vr=class e extends J{tmCore;constructor(e){super(e||`loop`),this.description(`Run Claude Code in a loop, one task per iteration`).option(`-n, --iterations <number>`,`Maximum iterations`).option(`-p, --prompt <preset|path>`,`Preset name (${C.join(`, `)}) or path to custom prompt file`,`default`).option(`--progress-file <path>`,`Path to progress log file`,`.taskgraph/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`,`Run Claude in Docker sandbox mode`).option(`--no-output`,`Exclude full Claude output from iteration results`).option(`-v, --verbose`,`Show Claude's work in real-time`).action(e=>this.execute(e))}async execute(e){let t=e.prompt||`default`,n=e.progressFile||`.taskgraph/progress.txt`;try{let r=U.resolve(Rn(e.project));this.tmCore=await x({projectPath:r});let 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)),In({tag:e.tag||`master`}),e.sandbox&&this.handleSandboxAuth(),console.log(H.cyan(`Starting TaskGraph Loop...`)),console.log(H.dim(`Preset: ${t}`)),console.log(H.dim(`Max iterations: ${a}`)),console.log(H.dim(`Mode: ${e.sandbox?`Docker sandbox`:`Claude CLI`}`)),t==="default"){let t=await this.tmCore.tasks.getNext(e.tag);console.log(t?V.text(`Next task to work on: ${V.text(t.id)} - ${t.title}`):H.yellow(`No pending tasks found`))}console.log();let o={iterations:a,prompt:t,progressFile:n,tag:e.tag,sandbox:e.sandbox,includeOutput:e.output??!0,verbose:e.verbose??!1,callbacks:this.createOutputCallbacks()},s=await this.tmCore.loop.run(o);this.displayResult(s)}catch(e){Z(e,{skipExit:!0}),process.exit(1)}}handleSandboxAuth(){console.log(H.dim(`Checking sandbox auth...`));let e=this.tmCore.loop.checkSandboxAuth();if(e.error)throw Error(e.error);if(e.ready){console.log(H.green(`✓ Sandbox ready`));return}console.log(H.yellow(`Sandbox needs authentication. Starting interactive session...`)),console.log(H.dim(`Please complete auth, then Ctrl+C to continue.
128
- `));let t=this.tmCore.loop.runInteractiveAuth();if(!t.success)throw Error(t.error||`Interactive authentication failed`);console.log(H.green(`✓ Auth complete
129
- `))}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(H.cyan(`━━━ Iteration ${e} of ${t} ━━━`))},onText:e=>{console.log(e)},onToolUse:e=>{console.log(H.dim(` → ${e}`))},onError:(e,t)=>{console.error(t===`warning`?H.yellow(`[Loop Warning] ${e}`):H.red(`[Loop Error] ${e}`))},onStderr:(e,t)=>{process.stderr.write(H.dim(`[Iteration ${e}] `)+t)},onOutput:e=>{console.log(e)},onIterationEnd:e=>{let t=e.status===`success`?H.green:e.status===`error`?H.red:H.yellow;console.log(t(` Iteration ${e.iteration} completed: ${e.status}`))}}}displayResult(e){console.log(),console.log(H.bold(`Loop Complete`)),console.log(H.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(H.red(`Error: ${e.errorMessage}`))}formatStatus(e){return{all_complete:H.green(`All tasks complete`),max_iterations:H.yellow(`Max iterations reached`),blocked:H.red(`Blocked`),error:H.red(`Error`)}[e]}static register(t,n){let r=new e(n);return t.addCommand(r),r}};function yr(e,t={}){let n=t.home??Ne.homedir(),r=t.env??process.env,i=t.platform??process.platform;switch(e){case`zsh`:return{script:U.join(n,`.taskgraph-completion.zsh`),rc:U.join(r.ZDOTDIR||n,`.zshrc`)};case`bash`:{let e=U.join(n,`.bash_profile`),t=i===`darwin`&&Me.existsSync(e)?e:U.join(n,`.bashrc`);return{script:U.join(n,`.taskgraph-completion.bash`),rc:t}}case`fish`:return{script:U.join(r.XDG_CONFIG_HOME||U.join(n,`.config`),`fish`,`completions`,`taskgraph.fish`)}}}function br(e,t=Ne.homedir()){return e===t||e.startsWith(t+U.sep)?`~${e.slice(t.length)}`:e}function xr(e,t,n={}){let r=n.home??Ne.homedir(),i=yr(e,n),a=Me.existsSync(i.script);if(Me.mkdirSync(U.dirname(i.script),{recursive:!0}),Me.writeFileSync(i.script,t),!i.rc)return{...i,replaced:a,rcUpdated:!1};let o=i.script.startsWith(r+U.sep)?`$HOME${i.script.slice(r.length)}`:i.script,s=Me.existsSync(i.rc)?Me.readFileSync(i.rc,`utf8`):``;if(s.includes(o)||s.includes(i.script))return{...i,replaced:a,rcUpdated:!1};let c=s===``||s.endsWith(`
121
+ `).action(async(e,t,n)=>{await this.executeCopy(e,t,n)})}async initTmCore(){this.tmCore||=await x({projectPath:process.cwd()})}async executeList(e){try{await this.initTmCore();let{projectRoot:t,tasksPath:n}=y(),r=await xr(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){Y(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}=y();await vr(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){Y(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}=y(),r=await Sr(n,e,{},{projectRoot:t},`text`);this.setLastResult({success:!0,action:`use`,currentTag:r.currentTag,message:`Switched to tag: ${e}`})}catch(e){Y(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}=y();await yr(r,e,{yes:t?.yes||!1},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`remove`,message:`Removed tag: ${e}`})}catch(e){Y(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}=y();await Cr(r,e,t,{},{projectRoot:n},`text`),this.setLastResult({success:!0,action:`rename`,message:`Renamed tag from "${e}" to "${t}"`})}catch(e){Y(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}=y();await wr(i,e,t,{description:n?.description},{projectRoot:r},`text`),this.setLastResult({success:!0,action:`copy`,message:`Copied tag from "${e}" to "${t}"`})}catch(e){Y(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}},kr=class e extends q{tmCore;constructor(e){super(e||`loop`),this.description(`Run Claude Code in a loop, one task per iteration`).option(`-n, --iterations <number>`,`Maximum iterations`).option(`-p, --prompt <preset|path>`,`Preset name (${C.join(`, `)}) or path to custom prompt file`,`default`).option(`--progress-file <path>`,`Path to progress log file`,`.taskgraph/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`,`Run Claude in Docker sandbox mode`).option(`--no-output`,`Exclude full Claude output from iteration results`).option(`-v, --verbose`,`Show Claude's work in real-time`).action(e=>this.execute(e))}async execute(e){let t=e.prompt||`default`,n=e.progressFile||`.taskgraph/progress.txt`;try{let r=H.resolve(Z(e.project));this.tmCore=await x({projectPath:r});let 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)),Yn({tag:e.tag||`master`}),e.sandbox&&this.handleSandboxAuth(),console.log(V.cyan(`Starting TaskGraph Loop...`)),console.log(V.dim(`Preset: ${t}`)),console.log(V.dim(`Max iterations: ${a}`)),console.log(V.dim(`Mode: ${e.sandbox?`Docker sandbox`:`Claude CLI`}`)),t==="default"){let t=await this.tmCore.tasks.getNext(e.tag);console.log(t?B.text(`Next task to work on: ${B.text(t.id)} - ${t.title}`):V.yellow(`No pending tasks found`))}console.log();let o={iterations:a,prompt:t,progressFile:n,tag:e.tag,sandbox:e.sandbox,includeOutput:e.output??!0,verbose:e.verbose??!1,callbacks:this.createOutputCallbacks()},s=await this.tmCore.loop.run(o);this.displayResult(s)}catch(e){Y(e,{skipExit:!0}),process.exit(1)}}handleSandboxAuth(){console.log(V.dim(`Checking sandbox auth...`));let e=this.tmCore.loop.checkSandboxAuth();if(e.error)throw Error(e.error);if(e.ready){console.log(V.green(`✓ Sandbox ready`));return}console.log(V.yellow(`Sandbox needs authentication. Starting interactive session...`)),console.log(V.dim(`Please complete auth, then Ctrl+C to continue.
122
+ `));let t=this.tmCore.loop.runInteractiveAuth();if(!t.success)throw Error(t.error||`Interactive authentication failed`);console.log(V.green(`✓ Auth complete
123
+ `))}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(V.cyan(`━━━ Iteration ${e} of ${t} ━━━`))},onText:e=>{console.log(e)},onToolUse:e=>{console.log(V.dim(` → ${e}`))},onError:(e,t)=>{console.error(t===`warning`?V.yellow(`[Loop Warning] ${e}`):V.red(`[Loop Error] ${e}`))},onStderr:(e,t)=>{process.stderr.write(V.dim(`[Iteration ${e}] `)+t)},onOutput:e=>{console.log(e)},onIterationEnd:e=>{let t=e.status===`success`?V.green:e.status===`error`?V.red:V.yellow;console.log(t(` Iteration ${e.iteration} completed: ${e.status}`))}}}displayResult(e){console.log(),console.log(V.bold(`Loop Complete`)),console.log(V.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(V.red(`Error: ${e.errorMessage}`))}formatStatus(e){return{all_complete:V.green(`All tasks complete`),max_iterations:V.yellow(`Max iterations reached`),blocked:V.red(`Blocked`),error:V.red(`Error`)}[e]}static register(t,n){let r=new e(n);return t.addCommand(r),r}};function Ar(e,t={}){let n=t.home??Pe.homedir(),r=t.env??process.env,i=t.platform??process.platform;switch(e){case`zsh`:return{script:H.join(n,`.taskgraph-completion.zsh`),rc:H.join(r.ZDOTDIR||n,`.zshrc`)};case`bash`:{let e=H.join(n,`.bash_profile`),t=i===`darwin`&&Ne.existsSync(e)?e:H.join(n,`.bashrc`);return{script:H.join(n,`.taskgraph-completion.bash`),rc:t}}case`fish`:return{script:H.join(r.XDG_CONFIG_HOME||H.join(n,`.config`),`fish`,`completions`,`taskgraph.fish`)}}}function jr(e,t=Pe.homedir()){return e===t||e.startsWith(t+H.sep)?`~${e.slice(t.length)}`:e}function Mr(e,t,n={}){let r=n.home??Pe.homedir(),i=Ar(e,n),a=Ne.existsSync(i.script);if(Ne.mkdirSync(H.dirname(i.script),{recursive:!0}),Ne.writeFileSync(i.script,t),!i.rc)return{...i,replaced:a,rcUpdated:!1};let o=i.script.startsWith(r+H.sep)?`$HOME${i.script.slice(r.length)}`:i.script,s=Ne.existsSync(i.rc)?Ne.readFileSync(i.rc,`utf8`):``;if(s.includes(o)||s.includes(i.script))return{...i,replaced:a,rcUpdated:!1};let c=s===``||s.endsWith(`
130
124
  `)?``:`
131
- `;return Me.appendFileSync(i.rc,`${c}\n# TaskGraph Tab completion\n[ -f "${o}" ] && source "${o}"\n`),{...i,replaced:a,rcUpdated:!0}}function Sr(e){return JSON.stringify(e).replace(/'/g,`\\u0027`).replace(/\\\\/g,`\\u005c`).replace(/`/g,`\\u0060`)}function Cr(e){return`var SPEC = ${Sr(e)};\n
125
+ `;return Ne.appendFileSync(i.rc,`${c}\n# TaskGraph Tab completion\n[ -f "${o}" ] && source "${o}"\n`),{...i,replaced:a,rcUpdated:!0}}function Nr(e){return JSON.stringify(e).replace(/'/g,`\\u0027`).replace(/\\\\/g,`\\u005c`).replace(/`/g,`\\u0060`)}function Pr(e){return`var SPEC = ${Nr(e)};\n
132
126
  var fs = require("fs");
133
127
  var path = require("path");
134
128
  var args = process.argv.slice(1);
@@ -334,8 +328,8 @@ if (!arg && cmd.args.length && cmd.args[cmd.args.length - 1].variadic) {
334
328
  if (arg && arg.value.kind !== "none") completeValue(arg.value, cur, "");
335
329
  if (!arg && cur === "") completeOptions(cmd, cur, used);
336
330
  emit("values", "", "", "values", []);
337
- `}const wr=[`bash`,`zsh`,`fish`];function Tr(e){return wr.includes(e)}function Er(e=process.env.SHELL){let t=(e||``).split(`/`).pop()||``;return Tr(t)?t:void 0}function Dr(e){switch(e){case`bash`:return[`taskgraph completion bash > ~/.taskgraph-completion.bash`,`echo 'source ~/.taskgraph-completion.bash' >> ~/.bashrc`];case`zsh`:return[`taskgraph completion zsh > ~/.taskgraph-completion.zsh`,`echo 'source ~/.taskgraph-completion.zsh' >> ~/.zshrc`];case`fish`:return[`mkdir -p ~/.config/fish/completions`,`taskgraph completion fish > ~/.config/fish/completions/taskgraph.fish`]}}function Or(e,t){return[`# TaskGraph completion for ${e} (taskgraph ${t})`,`# Install or update with: taskgraph completion --install`,`# Run that again after upgrading TaskGraph.`].join(`
338
- `)}function kr(e){return`__taskgraph_program='${e}'
331
+ `}const Fr=[`bash`,`zsh`,`fish`];function Ir(e){return Fr.includes(e)}function Lr(e=process.env.SHELL){let t=(e||``).split(`/`).pop()||``;return Ir(t)?t:void 0}function Rr(e){switch(e){case`bash`:return[`taskgraph completion bash > ~/.taskgraph-completion.bash`,`echo 'source ~/.taskgraph-completion.bash' >> ~/.bashrc`];case`zsh`:return[`taskgraph completion zsh > ~/.taskgraph-completion.zsh`,`echo 'source ~/.taskgraph-completion.zsh' >> ~/.zshrc`];case`fish`:return[`mkdir -p ~/.config/fish/completions`,`taskgraph completion fish > ~/.config/fish/completions/taskgraph.fish`]}}function zr(e,t){return[`# TaskGraph completion for ${e} (taskgraph ${t})`,`# Install or update with: taskgraph completion --install`,`# Run that again after upgrading TaskGraph.`].join(`
332
+ `)}function Br(e){return`__taskgraph_program='${e}'
339
333
 
340
334
  _taskgraph() {
341
335
  local cur="\${COMP_WORDS[COMP_CWORD]}" line i
@@ -369,7 +363,7 @@ complete -F _taskgraph taskgraph
369
363
  if alias tm >/dev/null 2>&1; then
370
364
  complete -F _taskgraph tm
371
365
  fi
372
- `}function Ar(e){return`__taskgraph_program='${e}'
366
+ `}function Vr(e){return`__taskgraph_program='${e}'
373
367
 
374
368
  _taskgraph() {
375
369
  local -a out items
@@ -405,7 +399,7 @@ else
405
399
  (( $+functions[compdef] )) || { autoload -Uz compinit && compinit }
406
400
  compdef _taskgraph taskgraph
407
401
  fi
408
- `}function jr(e){return`set -g __taskgraph_program '${e}'
402
+ `}function Hr(e){return`set -g __taskgraph_program '${e}'
409
403
 
410
404
  function __taskgraph_complete
411
405
  set -l tokens (commandline -opc)
@@ -435,17 +429,17 @@ function __taskgraph_complete
435
429
  end
436
430
 
437
431
  complete -c taskgraph -f -k -a '(__taskgraph_complete)'
438
- `}function Mr(e,t,n=`unknown`){let r=Cr(t);if(r.includes(`'`)||r.includes(`\\\\`))throw Error(`Completion program cannot be quoted for the shell`);let i={bash:kr,zsh:Ar,fish:jr}[e](r);return`${e===`zsh`?`#compdef taskgraph
439
- `:``}${Or(e,n)}\n\n${i}`}const Nr=[`pending`,`in-progress`,`done`,`review`,`blocked`,`deferred`,`cancelled`],Pr=[`high`,`medium`,`low`],Fr=/* @__PURE__ */ new Set([`id`,`ids`,`taskid`,`task-id`,`parent`,`dependencies`]),Ir=/* @__PURE__ */ new Set([`tag`,`tagname`,`oldname`,`sourcename`,`source`,`name`]),Lr=/* @__PURE__ */ new Set([`--tag`,`--from-tag`,`--to-tag`,`--copy-from`]),Rr=/* @__PURE__ */ new Set([`--from`,`--to`,`--save-to`]),zr=/* @__PURE__ */ new Set([`file`,`files`,`paths`]),Br=/* @__PURE__ */ new Set([`dir`,`path`]),Vr=/* @__PURE__ */ new Set([`add`,`add-tag`]);function Hr(e){let t=e.match(/[<[]([^>\]]+?)(?:\.\.\.)?[>\]]/);return t?t[1].toLowerCase():void 0}function Ur(e,t,n){if(t?.length)return{kind:`choices`,choices:[...t]};let r=n.long;return r===`--status`||e===`status`?{kind:`choices`,choices:Nr}:r===`--priority`||e===`priority`?{kind:`choices`,choices:Pr}:r===`--format`||e===`format`?{kind:`choices`,choices:[`text`,`json`]}:r&&Lr.has(r)?{kind:`tags`}:r&&Rr.has(r)?{kind:`ids`}:r===`--project`||r===`--project-root`||r===`--output`?{kind:r===`--output`?`files`:`dirs`}:e?Fr.has(e)?{kind:`ids`}:Ir.has(e)?Vr.has(n.command)?{kind:`none`}:{kind:`tags`}:zr.has(e)?{kind:`files`}:Br.has(e)?{kind:`dirs`}:{kind:`none`}:{kind:`none`}}function Wr(e,t){let n=e.required||e.optional;return{short:e.short,long:e.long,description:Kr(e.description),value:n?Ur(Hr(e.flags),e.argChoices,{long:e.long,command:t}):void 0,...e.optional?{optional:!0}:{},...e.variadic?{variadic:!0}:{}}}function Gr(e,t){return{name:e.name(),variadic:e.variadic,value:Ur(e.name().toLowerCase(),e.argChoices,{command:t})}}function Kr(e){let t=(e||``).split(`
440
- `)[0].trim().replace(/^(.+?[.!?])\s.*$/,`$1`).replace(/\.$/,``);if(t.length<=60)return t;let n=t.slice(0,59),r=n.lastIndexOf(` `);return`${(r>30?n.slice(0,r):n).replace(/[\s,;:(]+$/,``)}…`}function qr(e){return!!e._hidden||/^\[deprecated\]/i.test(e.description())}function Jr(e){let t=e=>{let n=e.name(),r=e.options.filter(e=>!e.hidden).map(e=>Wr(e,n));return r.some(e=>e.long===`--help`)||r.push({short:`-h`,long:`--help`,description:`Show help`}),{name:n,aliases:e.aliases(),description:Kr(e.description()),options:r,args:e.registeredArguments.map(e=>Gr(e,n)),commands:e.commands.filter(e=>!qr(e)).map(t)}};return t(e)}var Yr=class e extends J{constructor(e){super(e||`completion`),this.description(`Set up Tab completion for bash, zsh or fish`).addArgument(new Ie(`[shell]`,`Shell to complete for (default: yours)`).choices(wr)).option(`--install`,`Install it and load it from your shell startup file`).option(`--script`,`Print the script even when writing to a terminal`).addHelpText(`after`,[``,`Examples:`,` taskgraph completion --install # set it up for your shell`,` taskgraph completion zsh > ~/.taskgraph-completion.zsh`].join(`
441
- `)).action((e,t)=>{this.executeCommand(e,t)})}executeCommand(e,t){try{let n=e??this.detectedShell();t.install?this.install(n):process.stdout.isTTY&&!t.script?this.displayInstructions(n,!e):process.stdout.write(this.script(n))}catch(e){Z(e,{skipExit:!0}),process.exit(1)}}detectedShell(){let e=Er();if(!e)throw Error(`Couldn't tell which shell you use. Name it: taskgraph completion <${wr.join(`|`)}>`);return e}script(e){let t=this;for(;t.parent;)t=t.parent;return Mr(e,Jr(t),t.version()||`unknown`)}install(e){let t=xr(e,this.script(e)),n=H.green(`✓`);console.log(),console.log(`${n} ${t.replaced?`Updated`:`Wrote`} ${V.brand(br(t.script))}`),t.rc&&t.rcUpdated?console.log(`${n} Loaded it from ${V.brand(br(t.rc))}`):t.rc&&console.log(`${n} ${V.brand(br(t.rc))} ${V.muted(`already loads it`)}`),console.log(),console.log(`Open a new terminal, then try ${V.brand(`taskgraph show <Tab>`)}`),console.log(V.muted(`Run this again after upgrading TaskGraph to pick up new commands.`))}displayInstructions(e,t){let n=yr(e),r=n.rc?`Writes ${br(n.script)} and loads it from ${br(n.rc)}.`:`Writes ${br(n.script)}.`;console.log(),console.log(H.bold(`Tab completion for ${e}`)),console.log(),console.log(` ${V.brand(`taskgraph completion --install`)}`),console.log(` ${V.muted(r)}`),console.log(),console.log(V.muted(`Or by hand:`));for(let t of Dr(e))console.log(` ${t}`);if(t){let t=wr.filter(t=>t!==e).join(`|`);console.log(),console.log(V.muted(`Not using ${e}? Name your shell: taskgraph completion <${t}> --install`))}}static register(t,n){let r=new e(n);return t.addCommand(r),r}},Xr=class{useJson;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(H.cyan(`${t}:`)),this.outputObject(n,` `)):console.log(V.text(`${t}: ${n}`))}outputObject(e,t){for(let[n,r]of Object.entries(e))typeof r==`object`&&r?(console.log(H.cyan(`${t}${n}:`)),this.outputObject(r,t+` `)):console.log(V.muted(`${t}${n}: ${r}`))}error(e,t){if(this.useJson)console.error(JSON.stringify({error:e,...t},null,2));else if(console.error(H.red(`Error: ${e}`)),t)for(let[e,n]of Object.entries(t))console.error(V.muted(` ${e}: ${n}`))}success(e,t){this.useJson?console.log(JSON.stringify({success:!0,message:e,...t},null,2)):(console.log(H.green(`✓ ${e}`)),t&&this.output(t))}warning(e){this.useJson?console.warn(JSON.stringify({warning:e},null,2)):console.warn(H.yellow(`⚠ ${e}`))}info(e){this.useJson||console.log(V.brand(`ℹ ${e}`))}},Zr=class extends J{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 Xr(e.json||t?.json||!1);try{let i=Rn(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await x({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 Je.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)}}},Qr=class extends J{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:Rn(e.projectRoot||t?.projectRoot)},r=new Xr(n.json||!1);try{let e=n.projectRoot,t=await x({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 c=new o(e);await c.ensureGitRepository(),await c.hasStagedChanges()||(r.info(`No staged changes, staging all changes...`),await c.stageFiles([`.`]));let l=await c.getStatus(),u=[...l.staged,...l.modified],d=new s,f=a.lastTestResults,p=d.generateMessage({type:`feat`,description:i.currentSubtask.title,changedFiles:u,taskId:i.taskId,phase:i.tddPhase,tag:a.metadata.tag||void 0,testsPassing:f?.passed,testsFailing:f?.failed,coveragePercent:void 0});await c.createCommit(p,{metadata:{taskId:i.taskId,subtaskId:i.currentSubtask.id,phase:`COMMIT`,tddCycle:`complete`}});let m=await c.getLastCommit(),h=await t.workflow.commit(),g=h.phase===`COMPLETE`;r.success(`Commit created`,{commitHash:m.hash.substring(0,7),message:p.split(`
442
- `)[0],subtask:{id:i.currentSubtask.id,title:i.currentSubtask.title},progress:h.progress,nextAction:g?`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)}}},$r=class extends J{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:Rn(e.projectRoot||t?.projectRoot)},r=new Xr(n.json||!1);try{let e=n.projectRoot,t=await x({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)}}},ei=class extends J{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 Xr(e.json||t?.json||!1);try{let i=Rn(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await x({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)}}},ti=class extends J{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 Xr(e.json||t?.json||!1);try{let i=Rn(e.projectRoot||t?.projectRoot);n={...n,projectRoot:i};let a=await x({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=o.phase,u=o.tddPhase,d=o.currentSubtask;if(l===`COMPLETE`){r.success(`Workflow complete`,{message:`All subtasks have been completed`,taskId:o.taskId});return}let f={action:s.action,description:s.description,phase:l,tddPhase:u,taskId:o.taskId,branchName:o.branchName,subtask:d?{id:d.id,title:d.title,attempts:d.attempts}:null,nextSteps:s.nextSteps,lastTestResults:c.lastTestResults};n.json?r.output(f):r.success(`Next action`,f)}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},ni=class extends J{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:Rn(e.projectRoot||t?.projectRoot)},r=new Xr(n.json||!1);try{let e=n.projectRoot,t=await x({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)}}},ri=class extends J{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:Rn(t.projectRoot||n?.projectRoot)},i=new Xr(r.json||!1);try{let t=p.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 x({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();i.info(`Loading task ${n}...`);let{task:c}=await o.tasks.get(n);c||(i.error(`Task not found`,{taskId:n}),process.exit(1)),(!c.subtasks||c.subtasks.length===0)&&(i.error(`Task has no subtasks. Expand task first.`,{taskId:n,suggestion:`Run: taskgraph expand --id=${n}`}),process.exit(1));let l=parseInt(r.maxAttempts||`3`,10);i.info(`Starting TDD workflow...`);let u=await o.workflow.start({taskId:n,taskTitle:c.title,subtasks:c.subtasks.map(e=>({id:e.id,title:e.title,status:e.status,maxAttempts:l})),maxAttempts:l,force:r.force,tag:s});i.success(`TDD workflow started`,{taskId:u.taskId,title:c.title,phase:u.phase,tddPhase:u.tddPhase,branchName:u.branchName,subtasks:c.subtasks.length,currentSubtask:u.currentSubtask?.title})}catch(e){i.error(e.message),r.verbose&&console.error(e.stack),process.exit(1)}}},ii=class extends J{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:Rn(e.projectRoot||t?.projectRoot)},r=new Xr(n.json||!1);try{let e=n.projectRoot,t=await x({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)}}},ai=class e extends J{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(`-p, --project-root <path>`,`Project root directory (auto-detected if not specified)`),this.registerSubcommands()}registerSubcommands(){this.addCommand(new ri),this.addCommand(new ni),this.addCommand(new ti),this.addCommand(new $r),this.addCommand(new Qr),this.addCommand(new ii),this.addCommand(new ei),this.addCommand(new Zr)}static register(t){let n=new e;return t.addCommand(n),n}},oi=class e extends J{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 .taskgraph/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=Rn(e.project);await this.initializeCore(t);let n=await this.generateFiles(t,e);this.lastResult=n,this.displayResults(n,e)}catch(e){t=!0,Z(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){if(!this.tmCore){let t=U.resolve(e);this.tmCore=await x({projectPath:t})}}async generateFiles(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=t.output?U.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;default:this.displayText(e,t)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e,t){if(this.tmCore&&In({tag:t.tag||this.tmCore.config.getActiveTag()}),!e.success){console.log(q(H.red(`Error: ${e.error||`Unknown error`}`),{padding:1,borderStyle:`round`,borderColor:`red`,title:`Generation failed`,titleAlignment:`center`}));return}if(e.count===0){console.log(q(H.yellow(`No tasks found to generate files for.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`No tasks`,titleAlignment:`center`}));return}let n=`${H.green(`✓`)} Generated ${H.cyan(e.count)} task file(s)`;n+=`\n\n${H.dim(`Output directory:`)} ${e.directory}`,e.orphanedFilesRemoved>0&&(n+=`\n${H.dim(`Orphaned files removed:`)} ${e.orphanedFilesRemoved}`),console.log(q(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}};const si={create:H.green,update:H.yellow,skip:V.muted,close:H.red};function ci(e){let t={create:0,update:0,skip:0,close:0};for(let n of e.steps)t[n.action]++;return t}function li(e){let t=ci(e);return t.create+t.update+t.close>0}function ui(e){let t=si[e.action](e.action.padEnd(6)),n=e.issueNumber?` -> #${e.issueNumber}`:``,r=e.reason?V.muted(` (${e.reason})`):``;return` ${t} [${e.tag}] ${e.taskId} ${e.title}${n}${r}`}function di(e){let t=ci(e),n=[H.bold(`Plan for ${e.repo}`),` ${t.create} to create, ${t.update} to update, ${t.skip} unchanged, ${t.close} to close`];for(let t of e.steps.filter(e=>e.action!==`skip`))n.push(ui(t));if(e.orphans.length>0){n.push(``,H.yellow(`${e.orphans.length} open issue(s) have no local task (pass --close-orphans to close them):`));for(let t of e.orphans)n.push(` #${t.issueNumber} ${t.title}`)}return n.join(`
443
- `)}function fi(e){let t=e.dryRun?`would be `:``;return[H.bold(e.dryRun?`Dry run, nothing written`:`Push complete`),` ${t}created ${e.created}, ${t}updated ${e.updated}, unchanged ${e.skipped}, ${t}closed ${e.closed}`].join(`
444
- `)}const pi={apply:H.green,sync:V.muted,conflict:H.red,skip:V.muted};function mi(e){let t={apply:0,sync:0,conflict:0,skip:0};for(let n of e.steps)t[n.action]++;return t}function hi(e){let t=mi(e);return t.apply+t.sync>0}function gi(e){return mi(e).apply>0}function _i(e){let t=pi[e.action](e.action.padEnd(8)),n=e.action===`conflict`?`local ${e.from}, GitHub ${e.to}`:`${e.from} -> ${e.to}`,r=e.issueNumber?` (#${e.issueNumber})`:``;return` ${t} [${e.tag}] ${e.taskId} ${e.title}${r} ${V.muted(n)}`}function vi(e){let t=mi(e),n=[H.bold(`Pull plan for ${e.repo}`),` ${t.apply} to update, ${t.sync} already in sync, ${t.conflict} conflict(s), ${t.skip} unchanged or skipped`];for(let t of e.steps.filter(e=>e.action!==`skip`))n.push(_i(t));return t.conflict>0&&n.push(``,H.yellow(`${t.conflict} task(s) changed on both sides and keep their local status. Run \`taskgraph github push\` to overwrite GitHub with it.`)),n.join(`
445
- `)}function yi(e){let t=e.dryRun?`would be `:``;return[H.bold(e.dryRun?`Dry run, nothing written`:`Pull complete`),` ${t}updated ${e.applied}, ${t}marked in sync ${e.synced}, conflicts ${e.conflicts}, skipped ${e.skipped}`].join(`
446
- `)}function bi(e){let t=e.ghAvailable?H.green(`available and signed in`):H.red("not available (install gh and run `gh auth login`)");return[H.bold(`GitHub`),` gh CLI: ${t}`,` repo: ${e.repo??V.muted(`not detected (use --repo owner/name)`)}`,` linked: ${e.linkedTasks} task(s)`,` unlinked: ${e.unlinkedTasks} task(s)`].join(`
447
- `)}function xi(e){return[`Unlinked task ${e.taskId} [${e.tag}] from issue #${e.issueNumber} (${e.url}).`,V.muted(`The issue was not changed. If it still carries its taskgraph marker, the next push will link it again.`)].join(`
448
- `)}var Si=class extends J{tmCore;constructor(e){super(e||`github`),this.description(`Push tasks to GitHub Issues and pull issue status back`),this.addStatusCommand(),this.addPushCommand(),this.addPullCommand(),this.addUnlinkCommand()}addStatusCommand(){this.command(`status`).description(`Show gh availability, target repo and linked task counts`).option(`--repo <owner/name>`,`Repository to check`).option(`-p, --project <path>`,`Project root directory`).option(`--json`,`Output as JSON`).action(e=>this.guard(e,()=>this.runStatus(e)))}addPushCommand(){this.command(`push`).description(`Create or update GitHub issues for tasks`).option(`--tag <name>`,`Tag to push (default: the active tag)`).option(`--all-tags`,`Push every tag`).option(`--id <ids>`,`Only push these task ids, comma separated`).option(`--dry-run`,`Show the plan without writing anything`).option(`-y, --yes`,`Write without asking for confirmation`).option(`--repo <owner/name>`,`Repository (default: detected via gh)`).option(`--include-details`,`Include task details in issue bodies`).option(`--close-orphans`,`Close open issues whose task is gone`).option(`-p, --project <path>`,`Project root directory`).option(`--json`,`Output as JSON (requires --yes or --dry-run)`).addHelpText(`after`,`
432
+ `}function Ur(e,t,n=`unknown`){let r=Pr(t);if(r.includes(`'`)||r.includes(`\\\\`))throw Error(`Completion program cannot be quoted for the shell`);let i={bash:Br,zsh:Vr,fish:Hr}[e](r);return`${e===`zsh`?`#compdef taskgraph
433
+ `:``}${zr(e,n)}\n\n${i}`}const Wr=[`pending`,`in-progress`,`done`,`review`,`blocked`,`deferred`,`cancelled`],Gr=[`high`,`medium`,`low`],Kr=/* @__PURE__ */ new Set([`id`,`ids`,`taskid`,`task-id`,`parent`,`dependencies`]),qr=/* @__PURE__ */ new Set([`tag`,`tagname`,`oldname`,`sourcename`,`source`,`name`]),Jr=/* @__PURE__ */ new Set([`--tag`,`--from-tag`,`--to-tag`,`--copy-from`]),Yr=/* @__PURE__ */ new Set([`--from`,`--to`,`--save-to`]),Xr=/* @__PURE__ */ new Set([`file`,`files`,`paths`]),Zr=/* @__PURE__ */ new Set([`dir`,`path`]),Qr=/* @__PURE__ */ new Set([`add`,`add-tag`]);function $r(e){let t=e.match(/[<[]([^>\]]+?)(?:\.\.\.)?[>\]]/);return t?t[1].toLowerCase():void 0}function ei(e,t,n){if(t?.length)return{kind:`choices`,choices:[...t]};let r=n.long;return r===`--status`||e===`status`?{kind:`choices`,choices:Wr}:r===`--priority`||e===`priority`?{kind:`choices`,choices:Gr}:r===`--format`||e===`format`?{kind:`choices`,choices:[`text`,`json`]}:r&&Jr.has(r)?{kind:`tags`}:r&&Yr.has(r)?{kind:`ids`}:r===`--project`||r===`--project-root`||r===`--output`?{kind:r===`--output`?`files`:`dirs`}:e?Kr.has(e)?{kind:`ids`}:qr.has(e)?Qr.has(n.command)?{kind:`none`}:{kind:`tags`}:Xr.has(e)?{kind:`files`}:Zr.has(e)?{kind:`dirs`}:{kind:`none`}:{kind:`none`}}function ti(e,t){let n=e.required||e.optional;return{short:e.short,long:e.long,description:ri(e.description),value:n?ei($r(e.flags),e.argChoices,{long:e.long,command:t}):void 0,...e.optional?{optional:!0}:{},...e.variadic?{variadic:!0}:{}}}function ni(e,t){return{name:e.name(),variadic:e.variadic,value:ei(e.name().toLowerCase(),e.argChoices,{command:t})}}function ri(e){let t=(e||``).split(`
434
+ `)[0].trim().replace(/^(.+?[.!?])\s.*$/,`$1`).replace(/\.$/,``);if(t.length<=60)return t;let n=t.slice(0,59),r=n.lastIndexOf(` `);return`${(r>30?n.slice(0,r):n).replace(/[\s,;:(]+$/,``)}…`}function ii(e){return!!e._hidden||/^\[deprecated\]/i.test(e.description())}function ai(e){let t=e=>{let n=e.name(),r=e.options.filter(e=>!e.hidden).map(e=>ti(e,n));return r.some(e=>e.long===`--help`)||r.push({short:`-h`,long:`--help`,description:`Show help`}),{name:n,aliases:e.aliases(),description:ri(e.description()),options:r,args:e.registeredArguments.map(e=>ni(e,n)),commands:e.commands.filter(e=>!ii(e)).map(t)}};return t(e)}var oi=class e extends q{constructor(e){super(e||`completion`),this.description(`Set up Tab completion for bash, zsh or fish`).addArgument(new Le(`[shell]`,`Shell to complete for (default: yours)`).choices(Fr)).option(`--install`,`Install it and load it from your shell startup file`).option(`--script`,`Print the script even when writing to a terminal`).addHelpText(`after`,[``,`Examples:`,` taskgraph completion --install # set it up for your shell`,` taskgraph completion zsh > ~/.taskgraph-completion.zsh`].join(`
435
+ `)).action((e,t)=>{this.executeCommand(e,t)})}executeCommand(e,t){try{let n=e??this.detectedShell();t.install?this.install(n):process.stdout.isTTY&&!t.script?this.displayInstructions(n,!e):process.stdout.write(this.script(n))}catch(e){Y(e,{skipExit:!0}),process.exit(1)}}detectedShell(){let e=Lr();if(!e)throw Error(`Couldn't tell which shell you use. Name it: taskgraph completion <${Fr.join(`|`)}>`);return e}script(e){let t=this;for(;t.parent;)t=t.parent;return Ur(e,ai(t),t.version()||`unknown`)}install(e){let t=Mr(e,this.script(e)),n=V.green(`✓`);console.log(),console.log(`${n} ${t.replaced?`Updated`:`Wrote`} ${B.brand(jr(t.script))}`),t.rc&&t.rcUpdated?console.log(`${n} Loaded it from ${B.brand(jr(t.rc))}`):t.rc&&console.log(`${n} ${B.brand(jr(t.rc))} ${B.muted(`already loads it`)}`),console.log(),console.log(`Open a new terminal, then try ${B.brand(`taskgraph show <Tab>`)}`),console.log(B.muted(`Run this again after upgrading TaskGraph to pick up new commands.`))}displayInstructions(e,t){let n=Ar(e),r=n.rc?`Writes ${jr(n.script)} and loads it from ${jr(n.rc)}.`:`Writes ${jr(n.script)}.`;console.log(),console.log(V.bold(`Tab completion for ${e}`)),console.log(),console.log(` ${B.brand(`taskgraph completion --install`)}`),console.log(` ${B.muted(r)}`),console.log(),console.log(B.muted(`Or by hand:`));for(let t of Rr(e))console.log(` ${t}`);if(t){let t=Fr.filter(t=>t!==e).join(`|`);console.log(),console.log(B.muted(`Not using ${e}? Name your shell: taskgraph completion <${t}> --install`))}}static register(t,n){let r=new e(n);return t.addCommand(r),r}},si=class{useJson;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(V.cyan(`${t}:`)),this.outputObject(n,` `)):console.log(B.text(`${t}: ${n}`))}outputObject(e,t){for(let[n,r]of Object.entries(e))typeof r==`object`&&r?(console.log(V.cyan(`${t}${n}:`)),this.outputObject(r,t+` `)):console.log(B.muted(`${t}${n}: ${r}`))}error(e,t){if(this.useJson)console.error(JSON.stringify({error:e,...t},null,2));else if(console.error(V.red(`Error: ${e}`)),t)for(let[e,n]of Object.entries(t))console.error(B.muted(` ${e}: ${n}`))}success(e,t){this.useJson?console.log(JSON.stringify({success:!0,message:e,...t},null,2)):(console.log(V.green(`✓ ${e}`)),t&&this.output(t))}warning(e){this.useJson?console.warn(JSON.stringify({warning:e},null,2)):console.warn(V.yellow(`⚠ ${e}`))}info(e){this.useJson||console.log(B.brand(`ℹ ${e}`))}},ci=class extends q{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 x({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 Ye.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 q{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 x({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 c=new o(e);await c.ensureGitRepository(),await c.hasStagedChanges()||(r.info(`No staged changes, staging all changes...`),await c.stageFiles([`.`]));let l=await c.getStatus(),u=[...l.staged,...l.modified],d=new s,f=a.lastTestResults,p=d.generateMessage({type:`feat`,description:i.currentSubtask.title,changedFiles:u,taskId:i.taskId,phase:i.tddPhase,tag:a.metadata.tag||void 0,testsPassing:f?.passed,testsFailing:f?.failed,coveragePercent:void 0});await c.createCommit(p,{metadata:{taskId:i.taskId,subtaskId:i.currentSubtask.id,phase:`COMMIT`,tddCycle:`complete`}});let m=await c.getLastCommit(),h=await t.workflow.commit(),g=h.phase===`COMPLETE`;r.success(`Commit created`,{commitHash:m.hash.substring(0,7),message:p.split(`
436
+ `)[0],subtask:{id:i.currentSubtask.id,title:i.currentSubtask.title},progress:h.progress,nextAction:g?`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 q{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 x({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 q{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 x({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 q{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 x({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=o.phase,u=o.tddPhase,d=o.currentSubtask;if(l===`COMPLETE`){r.success(`Workflow complete`,{message:`All subtasks have been completed`,taskId:o.taskId});return}let f={action:s.action,description:s.description,phase:l,tddPhase:u,taskId:o.taskId,branchName:o.branchName,subtask:d?{id:d.id,title:d.title,attempts:d.attempts}:null,nextSteps:s.nextSteps,lastTestResults:c.lastTestResults};n.json?r.output(f):r.success(`Next action`,f)}catch(e){r.error(e.message),n.verbose&&console.error(e.stack),process.exit(1)}}},pi=class extends q{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 x({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 q{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=p.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 x({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();i.info(`Loading task ${n}...`);let{task:c}=await o.tasks.get(n);c||(i.error(`Task not found`,{taskId:n}),process.exit(1)),(!c.subtasks||c.subtasks.length===0)&&(i.error(`Task has no subtasks. Expand task first.`,{taskId:n,suggestion:`Run: taskgraph expand --id=${n}`}),process.exit(1));let l=parseInt(r.maxAttempts||`3`,10);i.info(`Starting TDD workflow...`);let u=await o.workflow.start({taskId:n,taskTitle:c.title,subtasks:c.subtasks.map(e=>({id:e.id,title:e.title,status:e.status,maxAttempts:l})),maxAttempts:l,force:r.force,tag:s});i.success(`TDD workflow started`,{taskId:u.taskId,title:c.title,phase:u.phase,tddPhase:u.tddPhase,branchName:u.branchName,subtasks:c.subtasks.length,currentSubtask:u.currentSubtask?.title})}catch(e){i.error(e.message),r.verbose&&console.error(e.stack),process.exit(1)}}},hi=class extends q{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 x({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 q{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(`-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 q{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 .taskgraph/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,Y(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){if(!this.tmCore){let t=H.resolve(e);this.tmCore=await x({projectPath:t})}}async generateFiles(e,t){if(!this.tmCore)throw Error(`TmCore not initialized`);let n=t.output?H.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;default:this.displayText(e,t)}}displayJson(e){console.log(JSON.stringify(e,null,2))}displayText(e,t){if(this.tmCore&&Yn({tag:t.tag||this.tmCore.config.getActiveTag()}),!e.success){console.log(K(V.red(`Error: ${e.error||`Unknown error`}`),{padding:1,borderStyle:`round`,borderColor:`red`,title:`Generation failed`,titleAlignment:`center`}));return}if(e.count===0){console.log(K(V.yellow(`No tasks found to generate files for.`),{padding:1,borderStyle:`round`,borderColor:`yellow`,title:`No tasks`,titleAlignment:`center`}));return}let n=`${V.green(`✓`)} Generated ${V.cyan(e.count)} task file(s)`;n+=`\n\n${V.dim(`Output directory:`)} ${e.directory}`,e.orphanedFilesRemoved>0&&(n+=`\n${V.dim(`Orphaned files removed:`)} ${e.orphanedFilesRemoved}`),console.log(K(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}};const vi={create:V.green,update:V.yellow,skip:B.muted,close:V.red};function yi(e){let t={create:0,update:0,skip:0,close:0};for(let n of e.steps)t[n.action]++;return t}function bi(e){let t=yi(e);return t.create+t.update+t.close>0}function xi(e){let t=vi[e.action](e.action.padEnd(6)),n=e.issueNumber?` -> #${e.issueNumber}`:``,r=e.reason?B.muted(` (${e.reason})`):``;return` ${t} [${e.tag}] ${e.taskId} ${e.title}${n}${r}`}function Si(e){let t=yi(e),n=[V.bold(`Plan for ${e.repo}`),` ${t.create} to create, ${t.update} to update, ${t.skip} unchanged, ${t.close} to close`];for(let t of e.steps.filter(e=>e.action!==`skip`))n.push(xi(t));if(e.orphans.length>0){n.push(``,V.yellow(`${e.orphans.length} open issue(s) have no local task (pass --close-orphans to close them):`));for(let t of e.orphans)n.push(` #${t.issueNumber} ${t.title}`)}return n.join(`
437
+ `)}function Ci(e){let t=e.dryRun?`would be `:``;return[V.bold(e.dryRun?`Dry run, nothing written`:`Push complete`),` ${t}created ${e.created}, ${t}updated ${e.updated}, unchanged ${e.skipped}, ${t}closed ${e.closed}`].join(`
438
+ `)}const wi={apply:V.green,sync:B.muted,conflict:V.red,skip:B.muted};function Ti(e){let t={apply:0,sync:0,conflict:0,skip:0};for(let n of e.steps)t[n.action]++;return t}function Ei(e){let t=Ti(e);return t.apply+t.sync>0}function Di(e){return Ti(e).apply>0}function Oi(e){let t=wi[e.action](e.action.padEnd(8)),n=e.action===`conflict`?`local ${e.from}, GitHub ${e.to}`:`${e.from} -> ${e.to}`,r=e.issueNumber?` (#${e.issueNumber})`:``;return` ${t} [${e.tag}] ${e.taskId} ${e.title}${r} ${B.muted(n)}`}function ki(e){let t=Ti(e),n=[V.bold(`Pull plan for ${e.repo}`),` ${t.apply} to update, ${t.sync} already in sync, ${t.conflict} conflict(s), ${t.skip} unchanged or skipped`];for(let t of e.steps.filter(e=>e.action!==`skip`))n.push(Oi(t));return t.conflict>0&&n.push(``,V.yellow(`${t.conflict} task(s) changed on both sides and keep their local status. Run \`taskgraph github push\` to overwrite GitHub with it.`)),n.join(`
439
+ `)}function Ai(e){let t=e.dryRun?`would be `:``;return[V.bold(e.dryRun?`Dry run, nothing written`:`Pull complete`),` ${t}updated ${e.applied}, ${t}marked in sync ${e.synced}, conflicts ${e.conflicts}, skipped ${e.skipped}`].join(`
440
+ `)}function ji(e){let t=e.ghAvailable?V.green(`available and signed in`):V.red("not available (install gh and run `gh auth login`)");return[V.bold(`GitHub`),` gh CLI: ${t}`,` repo: ${e.repo??B.muted(`not detected (use --repo owner/name)`)}`,` linked: ${e.linkedTasks} task(s)`,` unlinked: ${e.unlinkedTasks} task(s)`].join(`
441
+ `)}function Mi(e){return[`Unlinked task ${e.taskId} [${e.tag}] from issue #${e.issueNumber} (${e.url}).`,B.muted(`The issue was not changed. If it still carries its taskgraph marker, the next push will link it again.`)].join(`
442
+ `)}var Ni=class extends q{tmCore;constructor(e){super(e||`github`),this.description(`Push tasks to GitHub Issues and pull issue status back`),this.addStatusCommand(),this.addPushCommand(),this.addPullCommand(),this.addUnlinkCommand()}addStatusCommand(){this.command(`status`).description(`Show gh availability, target repo and linked task counts`).option(`--repo <owner/name>`,`Repository to check`).option(`-p, --project <path>`,`Project root directory`).option(`--json`,`Output as JSON`).action(e=>this.guard(e,()=>this.runStatus(e)))}addPushCommand(){this.command(`push`).description(`Create or update GitHub issues for tasks`).option(`--tag <name>`,`Tag to push (default: the active tag)`).option(`--all-tags`,`Push every tag`).option(`--id <ids>`,`Only push these task ids, comma separated`).option(`--dry-run`,`Show the plan without writing anything`).option(`-y, --yes`,`Write without asking for confirmation`).option(`--repo <owner/name>`,`Repository (default: detected via gh)`).option(`--include-details`,`Include task details in issue bodies`).option(`--close-orphans`,`Close open issues whose task is gone`).option(`-p, --project <path>`,`Project root directory`).option(`--json`,`Output as JSON (requires --yes or --dry-run)`).addHelpText(`after`,`
449
443
  Examples:
450
444
  $ taskgraph github push --dry-run # Preview the active tag
451
445
  $ taskgraph github push --all-tags -y # Push every tag without asking
@@ -457,16 +451,16 @@ A task that changed on both sides keeps its local status and is reported.
457
451
  Examples:
458
452
  $ taskgraph github pull --dry-run # Preview the active tag
459
453
  $ taskgraph github pull -y # Update tasks without asking
460
- `).action(e=>this.guard(e,()=>this.runPull(e)))}addUnlinkCommand(){this.command(`unlink`).description(`Forget the GitHub issue a task is linked to`).argument(`<id>`,`Task id`).option(`--tag <name>`,`Tag the task lives in`).option(`-p, --project <path>`,`Project root directory`).option(`--json`,`Output as JSON`).action((e,t)=>this.guard(t,()=>this.runUnlink(e,t)))}async guard(e,t){let n=!1;try{await this.initializeCore(e),await t()}catch(e){n=!0,Z(e,{skipExit:!0})}finally{await this.tmCore?.close()}n&&process.exit(1)}async initializeCore(e){if(!this.tmCore){let t=U.resolve(Rn(e.project));this.tmCore=await x({projectPath:t})}}core(){if(!this.tmCore)throw Error(`TmCore not initialized`);return this.tmCore}async runStatus(e){let t=await this.core().github.status({repo:e.repo});console.log(e.json?JSON.stringify(t,null,2):bi(t))}async runPush(e){let t=this.core(),n={repo:e.repo,tag:e.tag,allTags:e.allTags,taskIds:e.id,includeDetails:e.includeDetails,closeOrphans:e.closeOrphans};if(e.dryRun){let r=await t.github.push({...n,dryRun:!0});this.print(e,r,[di(r.plan),fi(r)]);return}let r=await t.github.planPush(n);if(!li(r)){let i=await t.github.push({...n,dryRun:!0});this.print(e,{...i,dryRun:!1},[di(r),`GitHub is already up to date.`]);return}if(!e.yes){if(e.json||!this.isInteractive())throw Error(`Refusing to write to GitHub without confirmation. Pass --yes to proceed or --dry-run to preview.`);if(console.log(di(r)),!await this.confirm(`Write these changes to ${r.repo}?`)){console.log(`Cancelled. Nothing was written.`);return}}let i=await t.github.push({...n,dryRun:!1});this.print(e,i,[...e.yes?[di(i.plan)]:[],fi(i)])}async runPull(e){let t=this.core(),n={repo:e.repo,tag:e.tag,allTags:e.allTags,taskIds:e.id};if(e.dryRun){let r=await t.github.pull({...n,dryRun:!0});this.print(e,r,[vi(r.plan),yi(r)]);return}let r=await t.github.planPull(n);if(!hi(r)){let i=await t.github.pull({...n,dryRun:!0});this.print(e,{...i,dryRun:!1},[vi(r),`Task statuses are already up to date.`]);return}if(gi(r)&&!e.yes){if(e.json||!this.isInteractive())throw Error(`Refusing to change tasks without confirmation. Pass --yes to proceed or --dry-run to preview.`);if(console.log(vi(r)),!await this.confirm(`Update these task statuses?`)){console.log(`Cancelled. Nothing was changed.`);return}}let i=await t.github.pull({...n,dryRun:!1});this.print(e,i,[...e.yes?[vi(i.plan)]:[],yi(i)])}async runUnlink(e,t){let n=await this.core().github.unlink(e,{tag:t.tag});console.log(t.json?JSON.stringify(n,null,2):xi(n))}print(e,t,n){console.log(e.json?JSON.stringify(t,null,2):n.join(`
454
+ `).action(e=>this.guard(e,()=>this.runPull(e)))}addUnlinkCommand(){this.command(`unlink`).description(`Forget the GitHub issue a task is linked to`).argument(`<id>`,`Task id`).option(`--tag <name>`,`Tag the task lives in`).option(`-p, --project <path>`,`Project root directory`).option(`--json`,`Output as JSON`).action((e,t)=>this.guard(t,()=>this.runUnlink(e,t)))}async guard(e,t){let n=!1;try{await this.initializeCore(e),await t()}catch(e){n=!0,Y(e,{skipExit:!0})}finally{await this.tmCore?.close()}n&&process.exit(1)}async initializeCore(e){if(!this.tmCore){let t=H.resolve(Z(e.project));this.tmCore=await x({projectPath:t})}}core(){if(!this.tmCore)throw Error(`TmCore not initialized`);return this.tmCore}async runStatus(e){let t=await this.core().github.status({repo:e.repo});console.log(e.json?JSON.stringify(t,null,2):ji(t))}async runPush(e){let t=this.core(),n={repo:e.repo,tag:e.tag,allTags:e.allTags,taskIds:e.id,includeDetails:e.includeDetails,closeOrphans:e.closeOrphans};if(e.dryRun){let r=await t.github.push({...n,dryRun:!0});this.print(e,r,[Si(r.plan),Ci(r)]);return}let r=await t.github.planPush(n);if(!bi(r)){let i=await t.github.push({...n,dryRun:!0});this.print(e,{...i,dryRun:!1},[Si(r),`GitHub is already up to date.`]);return}if(!e.yes){if(e.json||!this.isInteractive())throw Error(`Refusing to write to GitHub without confirmation. Pass --yes to proceed or --dry-run to preview.`);if(console.log(Si(r)),!await this.confirm(`Write these changes to ${r.repo}?`)){console.log(`Cancelled. Nothing was written.`);return}}let i=await t.github.push({...n,dryRun:!1});this.print(e,i,[...e.yes?[Si(i.plan)]:[],Ci(i)])}async runPull(e){let t=this.core(),n={repo:e.repo,tag:e.tag,allTags:e.allTags,taskIds:e.id};if(e.dryRun){let r=await t.github.pull({...n,dryRun:!0});this.print(e,r,[ki(r.plan),Ai(r)]);return}let r=await t.github.planPull(n);if(!Ei(r)){let i=await t.github.pull({...n,dryRun:!0});this.print(e,{...i,dryRun:!1},[ki(r),`Task statuses are already up to date.`]);return}if(Di(r)&&!e.yes){if(e.json||!this.isInteractive())throw Error(`Refusing to change tasks without confirmation. Pass --yes to proceed or --dry-run to preview.`);if(console.log(ki(r)),!await this.confirm(`Update these task statuses?`)){console.log(`Cancelled. Nothing was changed.`);return}}let i=await t.github.pull({...n,dryRun:!1});this.print(e,i,[...e.yes?[ki(i.plan)]:[],Ai(i)])}async runUnlink(e,t){let n=await this.core().github.unlink(e,{tag:t.tag});console.log(t.json?JSON.stringify(n,null,2):Mi(n))}print(e,t,n){console.log(e.json?JSON.stringify(t,null,2):n.join(`
461
455
 
462
- `))}isInteractive(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}async confirm(e){let{proceed:t}=await Je.prompt([{type:`confirm`,name:`proceed`,message:e,default:!1}]);return t}},Ci=class{static commands=[{name:`list`,description:`List all tasks with filtering and status overview`,commandClass:zn,category:`task`},{name:`show`,description:`Display detailed information about a specific task`,commandClass:Bn,category:`task`},{name:`next`,description:`Find the next available task to work on`,commandClass:Vn,category:`task`},{name:`graph`,description:`Show tasks as a dependency tree`,commandClass:Hn,category:`task`},{name:`start`,description:`Start working on a task with claude-code`,commandClass:Un,category:`task`},{name:`set-status`,description:`Update the status of one or more tasks`,commandClass:Gn,category:`task`},{name:`autopilot`,description:`AI agent orchestration for TDD workflow (start, resume, next, complete, commit, status, abort)`,commandClass:ai,category:`development`},{name:`loop`,description:`Run Claude Code in a loop, one task per iteration`,commandClass:vr,category:`development`},{name:`tags`,description:`Manage tags for task organization`,commandClass:_r,category:`task`},{name:`generate`,description:`Generate individual task files from tasks.json`,commandClass:oi,category:`utility`},{name:`github`,description:`Push tasks to GitHub Issues (status, push, unlink)`,commandClass:Si,category:`utility`},{name:`completion`,description:`Set up Tab completion for bash, zsh or fish`,commandClass:Yr,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)}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`,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 wi(e){Ci.registerAll(e)}const Ti=[`main`,`research`,`fallback`];function Ei(e){if(!e)throw Error(`Project root is required but not found.`);let t=j(null,{projectRoot:e}),n=ie(e);if(L(`debug`,`Checking for config file using findConfigPath, found: ${t}`),L(`debug`,`Checking config file using isConfigFilePresent(), exists: ${n}`),!n)throw Error(`The configuration file is missing. Run "taskgraph init" to create it.`)}function Di(e){return(t,...n)=>{e&&typeof e[t]==`function`&&e[t](...n)}}async function Oi(e={}){let{mcpLog:t,projectRoot:n}=e,r=Di(t);Ei(n);try{let e=ye(n),t=(t,n)=>{let r=e.find(e=>e.id===n&&e.provider===t);return{provider:t,modelId:n,sweScore:r?.swe_score||null,cost:r?.cost_per_1m_tokens||null}},r=de(n);return{success:!0,data:{activeModels:{main:t(ve(n),xe(n)),research:t(Oe(n),Ee(n)),fallback:r?t(r,Te(n)):null},message:`Successfully retrieved current model configuration`}}}catch(e){return r(`error`,`Error getting model configuration: ${e.message}`),{success:!1,error:{code:`CONFIG_ERROR`,message:e.message}}}}async function ki(e={}){let{mcpLog:t,projectRoot:n}=e,r=Di(t);Ei(n);try{let e=ye(n).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:e,message:e.length?`Successfully retrieved ${e.length} available models`:`No available models found`}}}catch(e){return r(`error`,`Error getting available models: ${e.message}`),{success:!1,error:{code:`MODELS_LIST_ERROR`,message:e.message}}}}async function Ai(e,t,n={}){let{mcpLog:r,projectRoot:i}=n,a=Di(r);if(Ei(i),!Ti.includes(e))return{success:!1,error:{code:`INVALID_ROLE`,message:`Invalid role: ${e}. Must be one of: ${Ti.join(`, `)}.`}};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=f.CLAUDE_CODE,r=ye(i).filter(e=>e.provider===n),o=r.find(e=>e.id===t);if(!o)return{success:!1,error:{code:`MODEL_NOT_FOUND`,message:`Model ID "${t}" is not supported. TaskGraph uses Claude Code; valid models: ${r.map(e=>e.id).join(`, `)}.`}};let s=ce(i);if(s.models[e]={...s.models[e],provider:n,modelId:t},delete s.models[e].baseURL,o.max_tokens&&(s.models[e].maxTokens=o.max_tokens),!T(s,i))return{success:!1,error:{code:`CONFIG_WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}};let c=`Successfully set ${e} model to ${t} (Provider: ${n})`;return a(`info`,c),{success:!0,data:{role:e,provider:n,modelId:t,message:c}}}catch(t){return a(`error`,`Error setting ${e} model: ${t.message}`),{success:!1,error:{code:`SET_MODEL_ERROR`,message:t.message}}}}async function ji(e){return Oi(e)}async function Mi(e,t,n){return Ai(e,t,n)}function Ni(){return ye()}function Pi(e,t,n=!1){let r=t[e],i=Ni().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?V.muted(`($${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=a.length,d,f;if(n){d=[...a,new Xe(`
463
- ── Claude Code Models ──`),{name:`○ None (disable)`,value:null,short:`None`},...c];let e=u+1;f=l===-1?e:l+u+2}else d=[...a,new Xe(`
464
- ── Claude Code Models ──`),...c],f=l===-1?+!!s:l+u+1;return(f<0||f>=d.length)&&(f=0,console.warn(`Warning: Could not determine default model for role '${e}'. Defaulting to 'Cancel'.`)),{choices:d,default:f}}function Fi(e,t){return(t=``)=>{let n=e.filter(e=>{if(e instanceof Xe)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 Xe)return e;let t=e;return{name:t.name,value:t.value,short:t.short}}))}}function Ii(){console.log(H.cyan(`
465
- Interactive model setup`)),console.log(V.muted(`━`.repeat(50))),console.log(H.yellow(`Navigation tips:`)),console.log(V.muted(` • Type to search and filter options`)),console.log(V.muted(` • Use ↑↓ arrow keys to navigate results`)),console.log(V.muted(` • Press Enter to select
466
- `))}async function Li(e,t){return await Ye({message:`Select the ${{main:`main model for generation/updates`,research:`research model`,fallback:`fallback model (optional)`}[e]}:`,source:Fi(t.choices,t.default),pageSize:15})}async function Ri(e,t,n,r){let i=n?.modelId??null,a=n?.provider??null;if(t===`__CANCEL__`)return console.log(H.yellow(`\nSetup canceled during ${e} model selection.`)),{success:!1,modified:!1};if(t===`__NO_CHANGE__`)return console.log(V.muted(`No change selected for ${e} model.`)),{success:!0,modified:!1};let o=null,s=null;if(t&&typeof t==`object`&&`id`in t)o=t.id,s=t.provider;else if(t)return console.error(H.red(`Internal Error: Unexpected selection value for ${e}: ${JSON.stringify(t)}`)),{success:!1,modified:!1};if(o===i&&(s??null)===a)return{success:!0,modified:!1};if(o){let t=await Mi(e,o,{projectRoot:r,providerHint:s||void 0});return t.success?(console.log(V.brand(`Set ${e} model: ${t.data?.provider} / ${t.data?.modelId}`)),{success:!0,modified:!0}):(console.error(H.red(`Error setting ${e} model: ${t.error?.message||`Unknown`}`)),{success:!1,modified:!1})}return{success:!0,modified:!1}}async function zi(e){e||(console.error(H.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}:null,research:t.data.activeModels.research?{modelId:t.data.activeModels.research.modelId,provider:t.data.activeModels.research.provider}:null,fallback:t.data.activeModels.fallback?{modelId:t.data.activeModels.fallback.modelId,provider:t.data.activeModels.fallback.provider}:null}:{main:null,research:null,fallback:null};!t.success&&t.error?.code!==`CONFIG_MISSING`&&console.warn(H.yellow(`Warning: Could not load current model configuration: ${t.error?.message||`Unknown error`}. Proceeding with defaults.`));let r=Pi(`main`,n),i=Pi(`research`,n),a=Pi(`fallback`,n);Ii();let o=await Li(`main`,r);if(o===`__CANCEL__`)return!1;let s=await Li(`research`,i);if(s===`__CANCEL__`)return!1;let c=await Li(`fallback`,a);if(c===`__CANCEL__`)return!1;let l=!0,u=!1,d=await Ri(`main`,o,n.main,e);d.success||(l=!1),d.modified&&(u=!0);let f=await Ri(`research`,s,n.research,e);f.success||(l=!1),f.modified&&(u=!0);let p=await Ri(`fallback`,c,n.fallback,e);return p.success||(l=!1),p.modified&&(u=!0),l&&u?console.log(H.green.bold(`
467
- Model setup complete!`)):l&&!u?console.log(H.yellow(`
468
- No changes made to model configuration.`)):console.error(H.red(`
469
- Errors occurred during model selection. Please review and try again.`)),l}const Bi=[`pending`,`done`,`in-progress`,`review`,`deferred`,`cancelled`];function Vi(e){return Bi.includes(e)}function Hi(){return S||`unknown`}async function Ui(e,t,n=null,r=null,i=!1,a={}){let{projectRoot:o,tag:s}=a;try{L(`info`,`Adding subtask to parent task ${t}...`);let i=F(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),L(`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),L(`info`,`Created new subtask ${a}.${e}`)}else throw Error(`Either existingTaskId or newSubtaskData must be provided`);return I(e,i,o,s),l}catch(e){throw L(`error`,`Error adding subtask: ${e.message}`),e}}const Wi=[`high`,`medium`,`low`],Gi=`medium`;function Ki(e){return Wi.includes(e?.toLowerCase())}function qi(e){if(!e)return null;let t=e.toLowerCase();return Ki(t)?t:null}const Ji=G.object({title:G.string().describe(`Clear, concise title for the task`),description:G.string().describe(`A one or two sentence description of the task`),details:G.string().describe(`In-depth implementation details, considerations, and guidance`),testStrategy:G.string().describe(`Detailed approach for verifying task completion`),dependencies:G.array(G.number()).nullable().describe(`Array of task IDs that this task depends on (must be completed before this task can start)`)}).strict(),Yi=G.object({taskId:G.number().int().positive(),taskTitle:G.string(),complexityScore:G.number().min(1).max(10),recommendedSubtasks:G.number().int().nonnegative(),expansionPrompt:G.string(),reasoning:G.string()}).strict(),Xi=G.object({complexityAnalysis:G.array(Yi)}).strict(),Zi=G.enum([`pending`,`in-progress`,`blocked`,`done`,`cancelled`,`deferred`]),Qi=G.object({id:G.number().int().positive(),title:G.string().min(1).max(200),description:G.string().min(1),status:Zi,dependencies:G.array(G.union([G.number().int().positive(),G.string()])),priority:G.enum([`low`,`medium`,`high`,`critical`]).nullable(),details:G.string().nullable(),testStrategy:G.string().nullable()}).strict(),$i=G.object({id:G.number().int().positive(),title:G.string().min(5).max(200),description:G.string().min(10),dependencies:G.array(G.number().int().positive()),details:G.string().min(20),status:G.enum([`pending`,`done`,`completed`]),testStrategy:G.string().nullable()}).strict(),ea=G.object({subtasks:G.array($i)}).strict(),ta=G.object({id:G.number().int().positive(),title:G.string().min(1),description:G.string().min(1),details:G.string().nullable(),testStrategy:G.string().nullable(),priority:G.enum([`high`,`medium`,`low`]).nullable(),dependencies:G.array(G.number().int().positive()).nullable(),status:G.string().nullable()}).strict(),na=G.object({tasks:G.array(ta)}).strict(),ra=G.object({subtask:$i}).strict(),ia=Qi.extend({subtasks:G.array($i).nullable()}).strict(),aa={"update-tasks":G.object({tasks:G.array(ia)}).strict(),"expand-task":ea,"analyze-complexity":Xi,"update-subtask-by-id":ra,"update-task-by-id":G.object({task:ia}),"add-task":Ji,"parse-prd":na};var oa={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.
456
+ `))}isInteractive(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}async confirm(e){let{proceed:t}=await Ye.prompt([{type:`confirm`,name:`proceed`,message:e,default:!1}]);return t}},Pi=class{static commands=[{name:`list`,description:`List all tasks with filtering and status overview`,commandClass:Xn,category:`task`},{name:`show`,description:`Display detailed information about a specific task`,commandClass:Zn,category:`task`},{name:`next`,description:`Find the next available task to work on`,commandClass:Qn,category:`task`},{name:`graph`,description:`Show tasks as a dependency tree`,commandClass:$n,category:`task`},{name:`start`,description:`Start working on a task with claude-code`,commandClass:er,category:`task`},{name:`set-status`,description:`Update the status of one or more tasks`,commandClass:nr,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 Claude Code in a loop, one task per iteration`,commandClass:kr,category:`development`},{name:`tags`,description:`Manage tags for task organization`,commandClass:Or,category:`task`},{name:`generate`,description:`Generate individual task files from tasks.json`,commandClass:_i,category:`utility`},{name:`github`,description:`Push tasks to GitHub Issues (status, push, unlink)`,commandClass:Ni,category:`utility`},{name:`completion`,description:`Set up Tab completion for bash, zsh or fish`,commandClass:oi,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)}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`,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 Fi(e){Pi.registerAll(e)}const Ii=[`main`,`research`,`fallback`];function Li(e){if(!e)throw Error(`Project root is required but not found.`);let t=j(null,{projectRoot:e}),n=ie(e);if(L(`debug`,`Checking for config file using findConfigPath, found: ${t}`),L(`debug`,`Checking config file using isConfigFilePresent(), exists: ${n}`),!n)throw Error(`The configuration file is missing. Run "taskgraph init" to create it.`)}function Ri(e){return(t,...n)=>{e&&typeof e[t]==`function`&&e[t](...n)}}async function zi(e={}){let{mcpLog:t,projectRoot:n}=e,r=Ri(t);Li(n);try{let e=ye(n),t=(t,n)=>{let r=e.find(e=>e.id===n&&e.provider===t);return{provider:t,modelId:n,sweScore:r?.swe_score||null,cost:r?.cost_per_1m_tokens||null}},r=de(n);return{success:!0,data:{activeModels:{main:t(ve(n),Se(n)),research:t(ke(n),De(n)),fallback:r?t(r,Ee(n)):null},message:`Successfully retrieved current model configuration`}}}catch(e){return r(`error`,`Error getting model configuration: ${e.message}`),{success:!1,error:{code:`CONFIG_ERROR`,message:e.message}}}}async function Bi(e={}){let{mcpLog:t,projectRoot:n}=e,r=Ri(t);Li(n);try{let e=ye(n).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:e,message:e.length?`Successfully retrieved ${e.length} available models`:`No available models found`}}}catch(e){return r(`error`,`Error getting available models: ${e.message}`),{success:!1,error:{code:`MODELS_LIST_ERROR`,message:e.message}}}}async function Vi(e,t,n={}){let{mcpLog:r,projectRoot:i}=n,a=Ri(r);if(Li(i),!Ii.includes(e))return{success:!1,error:{code:`INVALID_ROLE`,message:`Invalid role: ${e}. Must be one of: ${Ii.join(`, `)}.`}};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=f.CLAUDE_CODE,r=ye(i).filter(e=>e.provider===n),o=r.find(e=>e.id===t);if(!o)return{success:!1,error:{code:`MODEL_NOT_FOUND`,message:`Model ID "${t}" is not supported. TaskGraph uses Claude Code; valid models: ${r.map(e=>e.id).join(`, `)}.`}};let s=ce(i);if(s.models[e]={...s.models[e],provider:n,modelId:t},delete s.models[e].baseURL,o.max_tokens&&(s.models[e].maxTokens=o.max_tokens),!T(s,i))return{success:!1,error:{code:`CONFIG_WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}};let c=`Successfully set ${e} model to ${t} (Provider: ${n})`;return a(`info`,c),{success:!0,data:{role:e,provider:n,modelId:t,message:c}}}catch(t){return a(`error`,`Error setting ${e} model: ${t.message}`),{success:!1,error:{code:`SET_MODEL_ERROR`,message:t.message}}}}async function Hi(e){return zi(e)}async function Ui(e,t,n){return Vi(e,t,n)}function Wi(){return ye()}function Gi(e,t,n=!1){let r=t[e],i=Wi().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.muted(`($${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=a.length,d,f;if(n){d=[...a,new Ze(`
457
+ ── Claude Code Models ──`),{name:`○ None (disable)`,value:null,short:`None`},...c];let e=u+1;f=l===-1?e:l+u+2}else d=[...a,new Ze(`
458
+ ── Claude Code Models ──`),...c],f=l===-1?+!!s:l+u+1;return(f<0||f>=d.length)&&(f=0,console.warn(`Warning: Could not determine default model for role '${e}'. Defaulting to 'Cancel'.`)),{choices:d,default:f}}function Ki(e,t){return(t=``)=>{let n=e.filter(e=>{if(e instanceof Ze)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 Ze)return e;let t=e;return{name:t.name,value:t.value,short:t.short}}))}}function qi(){console.log(V.cyan(`
459
+ Interactive model setup`)),console.log(B.muted(`━`.repeat(50))),console.log(V.yellow(`Navigation tips:`)),console.log(B.muted(` • Type to search and filter options`)),console.log(B.muted(` • Use ↑↓ arrow keys to navigate results`)),console.log(B.muted(` • Press Enter to select
460
+ `))}async function Ji(e,t){return await Xe({message:`Select the ${{main:`main model for generation/updates`,research:`research model`,fallback:`fallback model (optional)`}[e]}:`,source:Ki(t.choices,t.default),pageSize:15})}async function Yi(e,t,n,r){let i=n?.modelId??null,a=n?.provider??null;if(t===`__CANCEL__`)return console.log(V.yellow(`\nSetup canceled during ${e} model selection.`)),{success:!1,modified:!1};if(t===`__NO_CHANGE__`)return console.log(B.muted(`No change selected for ${e} model.`)),{success:!0,modified:!1};let o=null,s=null;if(t&&typeof t==`object`&&`id`in t)o=t.id,s=t.provider;else if(t)return console.error(V.red(`Internal Error: Unexpected selection value for ${e}: ${JSON.stringify(t)}`)),{success:!1,modified:!1};if(o===i&&(s??null)===a)return{success:!0,modified:!1};if(o){let t=await Ui(e,o,{projectRoot:r,providerHint:s||void 0});return t.success?(console.log(B.brand(`Set ${e} model: ${t.data?.provider} / ${t.data?.modelId}`)),{success:!0,modified:!0}):(console.error(V.red(`Error setting ${e} model: ${t.error?.message||`Unknown`}`)),{success:!1,modified:!1})}return{success:!0,modified:!1}}async function Xi(e){e||(console.error(V.red(`Error: Could not determine project root for interactive setup.`)),process.exit(1));let t=await Hi({projectRoot:e}),n=t.success&&t.data?{main:t.data.activeModels.main?{modelId:t.data.activeModels.main.modelId,provider:t.data.activeModels.main.provider}:null,research:t.data.activeModels.research?{modelId:t.data.activeModels.research.modelId,provider:t.data.activeModels.research.provider}:null,fallback:t.data.activeModels.fallback?{modelId:t.data.activeModels.fallback.modelId,provider:t.data.activeModels.fallback.provider}:null}:{main:null,research:null,fallback:null};!t.success&&t.error?.code!==`CONFIG_MISSING`&&console.warn(V.yellow(`Warning: Could not load current model configuration: ${t.error?.message||`Unknown error`}. Proceeding with defaults.`));let r=Gi(`main`,n),i=Gi(`research`,n),a=Gi(`fallback`,n);qi();let o=await Ji(`main`,r);if(o===`__CANCEL__`)return!1;let s=await Ji(`research`,i);if(s===`__CANCEL__`)return!1;let c=await Ji(`fallback`,a);if(c===`__CANCEL__`)return!1;let l=!0,u=!1,d=await Yi(`main`,o,n.main,e);d.success||(l=!1),d.modified&&(u=!0);let f=await Yi(`research`,s,n.research,e);f.success||(l=!1),f.modified&&(u=!0);let p=await Yi(`fallback`,c,n.fallback,e);return p.success||(l=!1),p.modified&&(u=!0),l&&u?console.log(V.green.bold(`
461
+ Model setup complete!`)):l&&!u?console.log(V.yellow(`
462
+ No changes made to model configuration.`)):console.error(V.red(`
463
+ Errors occurred during model selection. Please review and try again.`)),l}const Zi=[`pending`,`done`,`in-progress`,`review`,`deferred`,`cancelled`];function Qi(e){return Zi.includes(e)}function $i(){return S||`unknown`}async function ea(e,t,n=null,r=null,i=!1,a={}){let{projectRoot:o,tag:s}=a;try{L(`info`,`Adding subtask to parent task ${t}...`);let i=F(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(Ha(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),L(`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),L(`info`,`Created new subtask ${a}.${e}`)}else throw Error(`Either existingTaskId or newSubtaskData must be provided`);return I(e,i,o,s),l}catch(e){throw L(`debug`,`Error adding subtask: ${e.message}`),e}}const ta=[`high`,`medium`,`low`],na=`medium`;function ra(e){return ta.includes(e?.toLowerCase())}function ia(e){if(!e)return null;let t=e.toLowerCase();return ra(t)?t:null}const aa=W.object({title:W.string().describe(`Clear, concise title for the task`),description:W.string().describe(`A one or two sentence description of the task`),details:W.string().describe(`In-depth implementation details, considerations, and guidance`),testStrategy:W.string().describe(`Detailed approach for verifying task completion`),dependencies:W.array(W.number()).nullable().describe(`Array of task IDs that this task depends on (must be completed before this task can start)`)}).strict(),oa=W.object({taskId:W.number().int().positive(),taskTitle:W.string(),complexityScore:W.number().min(1).max(10),recommendedSubtasks:W.number().int().nonnegative(),expansionPrompt:W.string(),reasoning:W.string()}).strict(),sa=W.object({complexityAnalysis:W.array(oa)}).strict(),ca=W.enum([`pending`,`in-progress`,`blocked`,`done`,`cancelled`,`deferred`]),la=W.object({id:W.number().int().positive(),title:W.string().min(1).max(200),description:W.string().min(1),status:ca,dependencies:W.array(W.union([W.number().int().positive(),W.string()])),priority:W.enum([`low`,`medium`,`high`,`critical`]).nullable(),details:W.string().nullable(),testStrategy:W.string().nullable()}).strict(),ua=W.object({id:W.number().int().positive(),title:W.string().min(5).max(200),description:W.string().min(10),dependencies:W.array(W.number().int().positive()),details:W.string().min(20),status:W.enum([`pending`,`done`,`completed`]),testStrategy:W.string().nullable()}).strict(),da=W.object({subtasks:W.array(ua)}).strict(),fa=W.object({id:W.number().int().positive(),title:W.string().min(1),description:W.string().min(1),details:W.string().nullable(),testStrategy:W.string().nullable(),priority:W.enum([`high`,`medium`,`low`]).nullable(),dependencies:W.array(W.number().int().positive()).nullable(),status:W.string().nullable()}).strict(),pa=W.object({tasks:W.array(fa)}).strict(),ma=W.object({subtask:ua}).strict(),ha=la.extend({subtasks:W.array(ua).nullable()}).strict(),ga={"update-tasks":W.object({tasks:W.array(ha)}).strict(),"expand-task":da,"analyze-complexity":sa,"update-subtask-by-id":ma,"update-task-by-id":W.object({task:ha}),"add-task":aa,"parse-prd":pa};var _a={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.
470
464
 
471
465
  IMPORTANT: Your response MUST be a JSON object with the following structure (no wrapper property, just these fields directly):
472
466
  {
@@ -526,7 +520,7 @@ Project Root: {{projectRoot}}
526
520
  }
527
521
 
528
522
  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.
529
- {{#if contextFromArgs}}{{contextFromArgs}}{{/if}}`}}},sa={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.
523
+ {{#if contextFromArgs}}{{contextFromArgs}}{{/if}}`}}},va={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.
530
524
 
531
525
  IMPORTANT: For each task, provide an analysis object with ALL of the following fields:
532
526
  - taskId: The ID of the task being analyzed (positive integer)
@@ -564,7 +558,7 @@ Tasks:
564
558
 
565
559
  {{gatheredContext}}
566
560
  {{/if}}
567
- `}}},ca={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.
561
+ `}}},ya={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.
568
562
 
569
563
  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:
570
564
  - 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!
@@ -676,7 +670,7 @@ Complexity Analysis Reasoning: {{complexityReasoningContext}}{{/if}}{{#if gather
676
670
 
677
671
  {{gatheredContext}}{{/if}}
678
672
 
679
- 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!`}}},la={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}}
673
+ 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!`}}},ba={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}}
680
674
  Before breaking down the PRD into tasks, you will:
681
675
  1. Research and analyze the latest technologies, libraries, frameworks, and best practices that would be appropriate for this project
682
676
  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
@@ -740,7 +734,7 @@ Remember to thoroughly research current best practices and technologies before t
740
734
 
741
735
  {{prdContent}}
742
736
 
743
- 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.`}}},ua={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.
737
+ 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.`}}},xa={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.
744
738
 
745
739
  Your role is to provide comprehensive, accurate, and actionable research responses based on the user's query and the provided project context.
746
740
  {{#if (eq detailLevel "low")}}
@@ -790,7 +784,7 @@ Your role is to provide comprehensive, accurate, and actionable research respons
790
784
 
791
785
  # Instructions
792
786
 
793
- 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}}
787
+ 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.`}}},Sa={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}}
794
788
 
795
789
  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.
796
790
  Focus *only* on generating the substance of the update.
@@ -834,7 +828,7 @@ User Request: "{{updatePrompt}}"
834
828
  # Additional Project Context
835
829
 
836
830
  {{gatheredContext}}
837
- {{/if}}`}}},fa={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}}
831
+ {{/if}}`}}},Ca={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}}
838
832
  You will be given a task and a prompt describing changes or new implementation details.
839
833
  Your job is to update the task to reflect these changes, while preserving its basic structure.
840
834
 
@@ -932,7 +926,7 @@ Based on the User Request and all the Task Context (including current task detai
932
926
  # Additional Project Context
933
927
 
934
928
  {{gatheredContext}}
935
- {{/if}}`}}},pa={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.
929
+ {{/if}}`}}},wa={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.
936
930
  You will be given a set of tasks and a prompt describing changes or new implementation details.
937
931
  Your job is to update the tasks to reflect these changes, while preserving their basic structure.
938
932
 
@@ -974,16 +968,16 @@ IMPORTANT: In the tasks above, any subtasks with "status": "done" or "status": "
974
968
 
975
969
  {{projectContext}}{{/if}}
976
970
 
977
- IMPORTANT: Your response must be a JSON object with a single property named "tasks" containing the updated array of tasks.`}}},ma={$schema:`http://json-schema.org/draft-07/schema#`,$id:`https://github.com/stephennmiller/taskgraph-ai/blob/main/src/prompts/schemas/prompt-template.schema.json`,version:`1.0.0`,title:`TaskGraph Prompt Template`,description:`Schema for TaskGraph 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`]}}}}},ha=class{constructor(){this.prompts=/* @__PURE__ */ new Map([[`analyze-complexity`,sa],[`expand-task`,ca],[`add-task`,oa],[`research`,ua],[`parse-prd`,la],[`update-task`,fa],[`update-tasks`,pa],[`update-subtask`,da]]),this.cache=/* @__PURE__ */ new Map,this.setupValidation()}setupValidation(){this.ajv=new et({allErrors:!0,strict:!1}),tt(this.ajv);try{this.validatePrompt=this.ajv.compile(ma),L(`debug`,`✓ JSON schema validation enabled`)}catch(e){L(`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 L(`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];i.required&&e===void 0?n.push(`Required parameter '${r}' missing`):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 L(`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`||n!==`false`&&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){L(`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 ga=null;function _a(){return ga||=new ha,ga}const{encode:va}=nt;var ya=class{constructor(e,t){this.projectRoot=e,this.tasksPath=W.join(e,`.taskgraph`,`tasks`,`tasks.json`),this.tag=t,this.allTasks=this._loadAllTasks()}_loadAllTasks(){try{return F(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 va(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=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}}),r=new Ze(n,{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}),i=e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3),a=r.search(e),o=[];for(let e of i)if(e.length>5){let t=r.search(e);t.length>0&&o.push(...t)}let s=[...a];for(let e of o)s.some(t=>t.item.id===e.item.id)||s.push(e);let c=s.filter(e=>e.score<.25).map(e=>e.item),l=s.filter(e=>e.score>=.25&&e.score<.4).map(e=>e.item),u=[...this.allTasks].sort((e,t)=>t.id-e.id).slice(0,5),d=[...c];for(let e of l)d.some(t=>t.id===e.id)||d.push(e);for(let e of u)d.some(t=>t.id===e.id)||d.push(e);return{tasks:d.slice(0,t),analysisData:{highRelevance:c,mediumRelevance:l,recentTasks:u,allRelevantTasks:d}}}_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.`,s=this.allTasks.filter(t=>e.includes(t.id));s.length>0&&(o+=`\n\nDirect dependencies:\n${s.map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
971
+ IMPORTANT: Your response must be a JSON object with a single property named "tasks" containing the updated array of tasks.`}}},Ta={$schema:`http://json-schema.org/draft-07/schema#`,$id:`https://github.com/stephennmiller/taskgraph-ai/blob/main/src/prompts/schemas/prompt-template.schema.json`,version:`1.0.0`,title:`TaskGraph Prompt Template`,description:`Schema for TaskGraph 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`]}}}}},Ea=class{constructor(){this.prompts=/* @__PURE__ */ new Map([[`analyze-complexity`,va],[`expand-task`,ya],[`add-task`,_a],[`research`,xa],[`parse-prd`,ba],[`update-task`,Ca],[`update-tasks`,wa],[`update-subtask`,Sa]]),this.cache=/* @__PURE__ */ new Map,this.setupValidation()}setupValidation(){this.ajv=new tt({allErrors:!0,strict:!1}),nt(this.ajv);try{this.validatePrompt=this.ajv.compile(Ta),L(`debug`,`✓ JSON schema validation enabled`)}catch(e){L(`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 L(`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];i.required&&e===void 0?n.push(`Required parameter '${r}' missing`):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 L(`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`||n!==`false`&&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){L(`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 Da=null;function Oa(){return Da||=new Ea,Da}const{encode:ka}=rt;var Aa=class{constructor(e,t){this.projectRoot=e,this.tasksPath=U.join(e,`.taskgraph`,`tasks`,`tasks.json`),this.tag=t,this.allTasks=this._loadAllTasks()}_loadAllTasks(){try{return F(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 ka(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=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}}),r=new Qe(n,{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}),i=e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3),a=r.search(e),o=[];for(let e of i)if(e.length>5){let t=r.search(e);t.length>0&&o.push(...t)}let s=[...a];for(let e of o)s.some(t=>t.item.id===e.item.id)||s.push(e);let c=s.filter(e=>e.score<.25).map(e=>e.item),l=s.filter(e=>e.score>=.25&&e.score<.4).map(e=>e.item),u=[...this.allTasks].sort((e,t)=>t.id-e.id).slice(0,5),d=[...c];for(let e of l)d.some(t=>t.id===e.id)||d.push(e);for(let e of u)d.some(t=>t.id===e.id)||d.push(e);return{tasks:d.slice(0,t),analysisData:{highRelevance:c,mediumRelevance:l,recentTasks:u,allRelevantTasks:d}}}_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.`,s=this.allTasks.filter(t=>e.includes(t.id));s.length>0&&(o+=`\n\nDirect dependencies:\n${s.map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
978
972
  `)}`);let c=i.filter(t=>!e.includes(t.id));c.length>0&&(o+=`\n\nIndirect dependencies (dependencies of dependencies):\n${c.slice(0,5).map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
979
973
  `)}`,c.length>5&&(o+=`\n- ... and ${c.length-5} more indirect dependencies`)),o+=`
980
974
 
981
- 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: ${z(t.details,400)}\n`)}return n.length>0&&(o+=`
975
+ 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: ${R(t.details,400)}\n`)}return n.length>0&&(o+=`
982
976
 
983
977
  Dependency Chain Visualization:`,o+=n.map(e=>this._formatDependencyChain(e)).join(``)),o}_buildDependencyGraphs(e){let t=/* @__PURE__ */ new Set,n=/* @__PURE__ */ 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`
984
- `+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=k(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=k(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=z(e.details,500);n.push(`Implementation Details: ${t}`)}if(e.testStrategy){let t=z(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(`
985
- `)}_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=z(e.details,500);r.push(`Implementation Details: ${t}`)}return r.join(`
986
- `)}async _gatherFileContext(e,t,n=!1){let r=[],i=[];for(let a of e)try{let e=W.isAbsolute(a)?a:W.join(this.projectRoot,a);if(!K.existsSync(e))continue;let o=K.statSync(e);if(!o.isFile()||o.size>51200)continue;let s=K.readFileSync(e,`utf-8`),c=W.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=K.readdirSync(e),o={name:W.basename(e),type:`directory`,children:[],fileCount:0,dirCount:0};for(let s of a){if(r.includes(s)||i.includes(s))continue;let a=W.join(e,s),c=K.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(`
978
+ `+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=k(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=k(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=R(e.details,500);n.push(`Implementation Details: ${t}`)}if(e.testStrategy){let t=R(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(`
979
+ `)}_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=R(e.details,500);r.push(`Implementation Details: ${t}`)}return r.join(`
980
+ `)}async _gatherFileContext(e,t,n=!1){let r=[],i=[];for(let a of e)try{let e=U.isAbsolute(a)?a:U.join(this.projectRoot,a);if(!G.existsSync(e))continue;let o=G.statSync(e);if(!o.isFile()||o.size>51200)continue;let s=G.readFileSync(e,`utf-8`),c=U.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=G.readdirSync(e),o={name:U.basename(e),type:`directory`,children:[],fileCount:0,dirCount:0};for(let s of a){if(r.includes(s)||i.includes(s))continue;let a=U.join(e,s),c=G.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(`
987
981
 
988
982
  ---
989
983
 
@@ -1008,105 +1002,105 @@ Dependency Chain Visualization:`,o+=n.map(e=>this._formatDependencyChain(e)).joi
1008
1002
 
1009
1003
  `);case`system-prompt`:return e.join(` `);default:return e.join(`
1010
1004
 
1011
- `)}}};function ba(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 xa(e,t,n=[],r=null,i={},o=`text`,s=null,c=!1){let{session:l,mcpLog:u,projectRoot:d,commandName:f,outputType:p,tag:m}=i,h=!!u,g=h?u:{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)},_=r||ue(d)||`medium`;if(r){let e=qi(r);e?_=e:(o===`text`&&L(`warn`,`Invalid priority "${r}". Using default priority "${Gi}".`),_=Gi)}g.info(`Adding new task with prompt: "${t}", Priority: ${_}, Dependencies: ${n.join(`, `)||`None`}, Research: ${c}, ProjectRoot: ${d}`),m&&g.info(`Using tag context: ${m}`);let v=null,y=null,b=(e,t=`info`)=>{u?u[t](e):o===`text`&&L(t,e)};function x(e,t,n=/* @__PURE__ */ new Set,r=/* @__PURE__ */ 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=x(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=F(e,d,m);r&&r._rawTaggedData&&(r=r._rawTaggedData),r||=(b(`tasks.json not found or invalid. Initializing new structure.`,`info`),{master:{tasks:[],metadata:{created:(/* @__PURE__ */ new Date()).toISOString(),description:`Default tasks context`}}}),r&&Array.isArray(r.tasks)&&!r._rawTaggedData&&(b(`Legacy format detected. Migrating to tagged format...`,`info`),r={master:{tasks:r.tasks,metadata:r.metadata||{created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:`Tasks for master context`}}},O(r.master,{description:`Tasks for master context`}),be(e),Ce(e),b(`Successfully migrated to tagged format.`,`success`));let i=m;if(!r[i])throw b(`Tag "${i}" does not exist. Please create it first using the 'add-tag' command.`,`error`),Error(`Tag "${i}" not found.`);r[i].tasks||(r[i].tasks=[]),r[i].metadata||(r[i].metadata={created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:``});let u=ba(r),g=r[i].tasks,S=(g.length>0?Math.max(...g.map(e=>e.id)):0)+1;o===`text`&&console.log(q(V.text.bold(`Creating New Task #${S}`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}));let C=n.filter(e=>{let t=parseInt(e,10);return Number.isNaN(t)||!u.some(e=>e.id===t)});C.length>0&&(b(`The following dependencies do not exist or are invalid: ${C.join(`, `)}`,`warn`),b(`Removing invalid dependencies...`,`info`),n=n.filter(e=>!C.includes(e)));let w=n.map(e=>parseInt(e,10)),T=[],E=/* @__PURE__ */ new Set,D=/* @__PURE__ */ new Map;for(let e of w){let t=x(u,e,/* @__PURE__ */ new Set,D);t&&T.push(t)}for(let[e,t]of D.entries())E.add(e);let k;if(s){if(b(`Using manually provided task data`,`info`),k=s,b(`DEBUG: Taking MANUAL task data path.`,`debug`),!k.title||typeof k.title!=`string`||!k.description||typeof k.description!=`string`)throw Error(`Manual task data must include at least a title and description.`)}else{b(`DEBUG: Taking AI task generation path.`,`debug`),b(`Generating task data with AI with prompt:\n${t}`,`info`);let e=await new ya(d,m).gather({semanticQuery:t,dependencyTasks:w,format:`research`}),n=e.context,r=e.analysisData;o===`text`&&r&&Kc(r,t,n.length);let i=``;s?.title&&(i+=`\n- Suggested Title: "${s.title}"`),s?.description&&(i+=`\n- Suggested Description: "${s.description}"`),s?.details&&(i+=`\n- Additional Details Context: "${s.details}"`),s?.testStrategy&&(i+=`\n- Additional Test Strategy Context: "${s.testStrategy}"`);let{systemPrompt:g,userPrompt:x}=await _a().loadPrompt(`add-task`,{prompt:t,newTaskId:S,existingTasks:u,gatheredContext:n,contextFromArgs:i,useResearch:c,priority:_,dependencies:w,hasCodebaseAnalysis:ee(c,d,l),projectRoot:d});o===`text`&&(v=Ac(`Generating new task with ${c?`Research`:`Main`} AI... \n`));try{let e=c?`research`:`main`;if(b(`DEBUG: Calling generateObjectService...`,`debug`),y=await a({role:e,session:l,projectRoot:d,schema:aa[`add-task`],objectName:`newTaskData`,systemPrompt:g,prompt:x,commandName:f||`add-task`,outputType:p||(h?`mcp`:`cli`)}),b(`DEBUG: generateObjectService returned successfully.`,`debug`),!y||!y.mainResult)throw Error(`AI service did not return the expected object structure.`);if(y.mainResult.title&&y.mainResult.description)k=y.mainResult;else if(y.mainResult.object&&y.mainResult.object.title&&y.mainResult.object.description)k=y.mainResult.object;else throw Error(`AI service did not return a valid task object.`);b(`Successfully generated task data from AI.`,`success`),v&&=(Mc(v,`Task generated successfully`),null)}catch(e){throw v&&=(Nc(v,`AI generation failed`),null),b(`DEBUG: generateObjectService caught error: ${e.message}`,`debug`),b(`Error generating task with AI: ${e.message}`,`error`),e}finally{b(`DEBUG: generateObjectService finally block reached.`,`debug`),v&&$(v)}}let A={id:S,title:k.title,description:k.description,details:k.details||``,testStrategy:k.testStrategy||``,status:`pending`,dependencies:k.dependencies?.length?k.dependencies:w,priority:_,subtasks:[]};if(k.dependencies?.length&&(k.dependencies.every(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&u.some(e=>e.id===t)})||(b(`AI suggested invalid dependencies. Filtering them out...`,`warn`),A.dependencies=k.dependencies.filter(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&u.some(e=>e.id===t)}))),r[i].tasks.push(A),O(r[i],{description:`Tasks for ${i} context`}),b(`DEBUG: Writing tasks.json...`,`debug`),I(e,r,d,i),b(`DEBUG: tasks.json written.`,`debug`),o===`text`){let e=new Y({head:[H.cyan.bold(`ID`),H.cyan.bold(`Title`),H.cyan.bold(`Description`)],colWidths:[5,30,50],style:{border:le}});e.push([A.id,z(A.title,27),z(A.description,47)]),console.log(H.green(`✓ New task created successfully:`)),console.log(e.toString());let t=e=>{switch(e?.toLowerCase()){case`high`:return`red`;case`low`:return`dim`;default:return`yellow`}},n=A.dependencies.filter(e=>!w.includes(e)),r=w.filter(e=>!A.dependencies.includes(e)),i={};A.dependencies.forEach(e=>{let t=u.find(t=>t.id===e);t&&(i[e]=z(t.title,30))});let a=``;A.dependencies.length>0?(a=V.text(`Dependencies:`)+`
1012
- `,A.dependencies.forEach(e=>{let t=n.includes(e)?H.yellow(` (AI suggested)`):``;a+=V.text(` - ${e}: ${i[e]||`Unknown task`}${t}`)+`
1013
- `})):a=V.text(`Dependencies: None`)+`
1014
- `,r.length>0&&(a+=V.muted(`
1005
+ `)}}};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,i={},o=`text`,s=null,c=!1){let{session:l,mcpLog:u,projectRoot:d,commandName:f,outputType:p,tag:m}=i,h=!!u,g=h?u:{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)},_=r||ue(d)||`medium`;if(r){let e=ia(r);e?_=e:(o===`text`&&L(`warn`,`Invalid priority "${r}". Using default priority "${na}".`),_=na)}g.info(`Adding new task with prompt: "${t}", Priority: ${_}, Dependencies: ${n.join(`, `)||`None`}, Research: ${c}, ProjectRoot: ${d}`),m&&g.info(`Using tag context: ${m}`);let v=null,y=null,b=(e,t=`info`)=>{u?u[t](e):o===`text`&&L(t,e)};function x(e,t,n=/* @__PURE__ */ new Set,r=/* @__PURE__ */ 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=x(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=F(e,d,m);r&&r._rawTaggedData&&(r=r._rawTaggedData),r||=(b(`tasks.json not found or invalid. Initializing new structure.`,`info`),{master:{tasks:[],metadata:{created:(/* @__PURE__ */ new Date()).toISOString(),description:`Default tasks context`}}}),r&&Array.isArray(r.tasks)&&!r._rawTaggedData&&(b(`Legacy format detected. Migrating to tagged format...`,`info`),r={master:{tasks:r.tasks,metadata:r.metadata||{created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:`Tasks for master context`}}},O(r.master,{description:`Tasks for master context`}),xe(e),we(e),b(`Successfully migrated to tagged format.`,`success`));let i=m;if(!r[i])throw b(`Tag "${i}" does not exist. Please create it first using the 'add-tag' command.`,`error`),Error(`Tag "${i}" not found.`);r[i].tasks||(r[i].tasks=[]),r[i].metadata||(r[i].metadata={created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:``});let u=ja(r),g=r[i].tasks,S=(g.length>0?Math.max(...g.map(e=>e.id)):0)+1;o===`text`&&console.log(K(B.text.bold(`Creating New Task #${S}`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}));let C=n.filter(e=>{let t=parseInt(e,10);return Number.isNaN(t)||!u.some(e=>e.id===t)});C.length>0&&(b(`The following dependencies do not exist or are invalid: ${C.join(`, `)}`,`warn`),b(`Removing invalid dependencies...`,`info`),n=n.filter(e=>!C.includes(e)));let w=n.map(e=>parseInt(e,10)),T=[],E=/* @__PURE__ */ new Set,D=/* @__PURE__ */ new Map;for(let e of w){let t=x(u,e,/* @__PURE__ */ new Set,D);t&&T.push(t)}for(let[e,t]of D.entries())E.add(e);let k;if(s){if(b(`Using manually provided task data`,`info`),k=s,b(`DEBUG: Taking MANUAL task data path.`,`debug`),!k.title||typeof k.title!=`string`||!k.description||typeof k.description!=`string`)throw Error(`Manual task data must include at least a title and description.`)}else{b(`DEBUG: Taking AI task generation path.`,`debug`),b(`Generating task data with AI with prompt:\n${t}`,`info`);let e=await new Aa(d,m).gather({semanticQuery:t,dependencyTasks:w,format:`research`}),n=e.context,r=e.analysisData;o===`text`&&r&&rl(r,t,n.length);let i=``;s?.title&&(i+=`\n- Suggested Title: "${s.title}"`),s?.description&&(i+=`\n- Suggested Description: "${s.description}"`),s?.details&&(i+=`\n- Additional Details Context: "${s.details}"`),s?.testStrategy&&(i+=`\n- Additional Test Strategy Context: "${s.testStrategy}"`);let{systemPrompt:g,userPrompt:x}=await Oa().loadPrompt(`add-task`,{prompt:t,newTaskId:S,existingTasks:u,gatheredContext:n,contextFromArgs:i,useResearch:c,priority:_,dependencies:w,hasCodebaseAnalysis:ee(c,d,l),projectRoot:d});o===`text`&&(v=Vc(`Generating new task with ${c?`Research`:`Main`} AI... \n`));try{let e=c?`research`:`main`;if(b(`DEBUG: Calling generateObjectService...`,`debug`),y=await a({role:e,session:l,projectRoot:d,schema:ga[`add-task`],objectName:`newTaskData`,systemPrompt:g,prompt:x,commandName:f||`add-task`,outputType:p||(h?`mcp`:`cli`)}),b(`DEBUG: generateObjectService returned successfully.`,`debug`),!y||!y.mainResult)throw Error(`AI service did not return the expected object structure.`);if(y.mainResult.title&&y.mainResult.description)k=y.mainResult;else if(y.mainResult.object&&y.mainResult.object.title&&y.mainResult.object.description)k=y.mainResult.object;else throw Error(`AI service did not return a valid task object.`);b(`Successfully generated task data from AI.`,`success`),v&&=(Uc(v,`Task generated successfully`),null)}catch(e){throw v&&=(Wc(v,`AI generation failed`),null),b(`DEBUG: generateObjectService caught error: ${e.message}`,`debug`),b(`Error generating task with AI: ${e.message}`,`error`),e}finally{b(`DEBUG: generateObjectService finally block reached.`,`debug`),v&&$(v)}}let A={id:S,title:k.title,description:k.description,details:k.details||``,testStrategy:k.testStrategy||``,status:`pending`,dependencies:k.dependencies?.length?k.dependencies:w,priority:_,subtasks:[]};if(k.dependencies?.length&&(k.dependencies.every(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&u.some(e=>e.id===t)})||(b(`AI suggested invalid dependencies. Filtering them out...`,`warn`),A.dependencies=k.dependencies.filter(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&u.some(e=>e.id===t)}))),r[i].tasks.push(A),O(r[i],{description:`Tasks for ${i} context`}),b(`DEBUG: Writing tasks.json...`,`debug`),I(e,r,d,i),b(`DEBUG: tasks.json written.`,`debug`),o===`text`){let e=new J({head:[V.cyan.bold(`ID`),V.cyan.bold(`Title`),V.cyan.bold(`Description`)],colWidths:[5,30,50],style:{border:le}});e.push([A.id,R(A.title,27),R(A.description,47)]),console.log(V.green(`✓ New task created successfully:`)),console.log(e.toString());let t=e=>{switch(e?.toLowerCase()){case`high`:return`red`;case`low`:return`dim`;default:return`yellow`}},n=A.dependencies.filter(e=>!w.includes(e)),r=w.filter(e=>!A.dependencies.includes(e)),i={};A.dependencies.forEach(e=>{let t=u.find(t=>t.id===e);t&&(i[e]=R(t.title,30))});let a=``;A.dependencies.length>0?(a=B.text(`Dependencies:`)+`
1006
+ `,A.dependencies.forEach(e=>{let t=n.includes(e)?V.yellow(` (AI suggested)`):``;a+=B.text(` - ${e}: ${i[e]||`Unknown task`}${t}`)+`
1007
+ `})):a=B.text(`Dependencies: None`)+`
1008
+ `,r.length>0&&(a+=B.muted(`
1015
1009
  User-specified dependencies that were not used:`)+`
1016
- `,r.forEach(e=>{let t=u.find(t=>t.id===e),n=t?z(t.title,30):`Unknown task`;a+=V.muted(` - ${e}: ${n}`)+`
1010
+ `,r.forEach(e=>{let t=u.find(t=>t.id===e),n=t?R(t.title,30):`Unknown task`;a+=B.muted(` - ${e}: ${n}`)+`
1017
1011
  `}));let o=``;(n.length>0||r.length>0)&&(o=`
1018
- `+V.text.bold(`Dependency Analysis:`)+`
1019
- `,n.length>0&&(o+=H.green(`AI identified ${n.length} additional dependencies`)+`
1020
- `),r.length>0&&(o+=H.yellow(`AI excluded ${r.length} user-provided dependencies`)+`
1021
- `)),console.log(q(V.text.bold(`Task ${S} Created Successfully`)+`
1012
+ `+B.text.bold(`Dependency Analysis:`)+`
1013
+ `,n.length>0&&(o+=V.green(`AI identified ${n.length} additional dependencies`)+`
1014
+ `),r.length>0&&(o+=V.yellow(`AI excluded ${r.length} user-provided dependencies`)+`
1015
+ `)),console.log(K(B.text.bold(`Task ${S} Created Successfully`)+`
1022
1016
 
1023
- `+V.text(`Title: ${A.title}`)+`
1024
- `+V.text(`Status: ${Fc(A.status)}`)+`
1025
- `+V.text(`Priority: ${H[t(A.priority)](A.priority)}`)+`
1017
+ `+B.text(`Title: ${A.title}`)+`
1018
+ `+B.text(`Status: ${Kc(A.status)}`)+`
1019
+ `+B.text(`Priority: ${V[t(A.priority)](A.priority)}`)+`
1026
1020
 
1027
1021
  `+a+o+`
1028
- `+V.text.bold(`Next Steps:`)+`
1029
- `+H.cyan(`1. Run ${H.yellow(`taskgraph show ${S}`)} to see complete task details`)+`
1030
- `+H.cyan(`2. Run ${H.yellow(`taskgraph set-status --id=${S} --status=in-progress`)} to start working on it`)+`
1031
- `+H.cyan(`3. Run ${H.yellow(`taskgraph expand --id=${S}`)} to break it down into subtasks`),{padding:1,borderColor:`green`,borderStyle:`round`})),y&&y.telemetryData&&(p===`cli`||p===`text`)&&Gc(y.telemetryData,`cli`)}return b(`DEBUG: Returning new task ID: ${S} and telemetry.`,`debug`),{newTaskId:S,telemetryData:y?y.telemetryData:null,tagInfo:y?y.tagInfo:null}}catch(e){throw v&&$(v),b(`Error adding task: ${e.message}`,`error`),o===`text`&&console.error(H.red(`Error: ${e.message}`)),e}}const Sa={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}]}},Ca=[{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`}],wa={high:.25,medium:.4,low:.6};var Ta=class{constructor(e,t=`default`){this.tasks=e,this.config=Sa[t]||Sa.default,this.searchableTasks=this._prepareSearchableTasks(e),this.fuse=new Ze(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<wa.high).map(e=>({...e.item,score:e.score})),u=c.filter(e=>e.score>=wa.high&&e.score<wa.medium).map(e=>({...e.item,score:e.score})),d=c.filter(e=>e.score>=wa.medium&&e.score<wa.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=Ca.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 Ea(e,t={}){let{session:n,mcpLog:r}=t,i=e.file||`.taskgraph/tasks/tasks.json`,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):!B()&&p===`text`&&L(t,e)},h=re(e.output,{projectRoot:c,tag:l},m);p===`text`&&console.log(V.brand(`Analyzing task complexity and generating expansion recommendations...`));try{m(`Reading tasks from ${i}...`,`info`);let t,g=0,_=null;if(e._filteredTasksData){if(t=e._filteredTasksData,g=e._originalTaskCount||t.tasks.length,!e._originalTaskCount)try{_=F(i,c,l),_&&_.tasks&&(g=_.tasks.length)}catch(e){L(`warn`,`Could not read original tasks file: ${e.message}`)}}else{if(_=F(i,c,l),!_||!_.tasks||!Array.isArray(_.tasks)||_.tasks.length===0)throw Error(`No tasks found in the tasks file`);g=_.tasks.length;let e=[`pending`,`blocked`,`in-progress`],n=_.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(H.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(H.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(..._.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(H.yellow(`Warning: No active tasks found in range: ${e}-${t}`))}t={..._,tasks:n,_originalTaskCount:g}}let v=``;if(_&&_.tasks.length>0)try{let e=new ya(c,l),n=new Ta(oe(_.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&&(v=(await e.gather({tasks:a,format:`research`})).context||``)}catch(e){m(`Could not gather additional context: ${e.message}`,`warn`)}let y=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(V.brand(e))}else if(y>0){let e=`Skipping ${y} tasks marked as done/cancelled/deferred. Analyzing ${t.tasks.length} active tasks.`;m(e,`info`),p===`text`&&console.log(H.yellow(e))}let b=null,x=/* @__PURE__ */ new Map;try{K.existsSync(h)&&(b=JSON.parse(K.readFileSync(h,`utf8`)),m(`Found existing complexity report at ${h}`,`info`),b&&b.complexityAnalysis&&Array.isArray(b.complexityAnalysis)&&(b.complexityAnalysis.forEach(e=>{x.set(e.taskId,e)}),m(`Existing report contains ${b.complexityAnalysis.length} task analyses`,`info`)))}catch(e){m(`Warning: Could not read existing report: ${e.message}`,`warn`),b=null,x.clear()}if(t.tasks.length===0){if(b&&(u||d!==null||f!==null))return m(`No matching tasks found for analysis. Keeping existing report.`,`info`),p===`text`&&console.log(H.yellow(`No matching tasks found for analysis. Keeping existing report.`)),{report:b,telemetryData:null};let e={meta:{generatedAt:(/* @__PURE__ */ new Date()).toISOString(),tasksAnalyzed:0,thresholdScore:o,projectName:me(n),usedResearch:s},complexityAnalysis:b?.complexityAnalysis||[]};return m(`Writing complexity report to ${h}...`,`info`),K.writeFileSync(h,JSON.stringify(e,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`&&(console.log(H.green(`Task complexity analysis complete. Report written to ${h}`)),console.log(`
1032
- 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(q(V.text.bold(`Suggested Next Steps:`)+`
1022
+ `+B.text.bold(`Next Steps:`)+`
1023
+ `+V.cyan(`1. Run ${V.yellow(`taskgraph show ${S}`)} to see complete task details`)+`
1024
+ `+V.cyan(`2. Run ${V.yellow(`taskgraph set-status --id=${S} --status=in-progress`)} to start working on it`)+`
1025
+ `+V.cyan(`3. Run ${V.yellow(`taskgraph expand --id=${S}`)} to break it down into subtasks`),{padding:1,borderColor:`green`,borderStyle:`round`})),y&&y.telemetryData&&(p===`cli`||p===`text`)&&nl(y.telemetryData,`cli`)}return b(`DEBUG: Returning new task ID: ${S} and telemetry.`,`debug`),{newTaskId:S,telemetryData:y?y.telemetryData:null,tagInfo:y?y.tagInfo:null}}catch(e){throw v&&$(v),o!==`text`&&b(`Error adding task: ${e.message}`,`error`),e}}const Na={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}]}},Pa=[{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`}],Fa={high:.25,medium:.4,low:.6};var Ia=class{constructor(e,t=`default`){this.tasks=e,this.config=Na[t]||Na.default,this.searchableTasks=this._prepareSearchableTasks(e),this.fuse=new Qe(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<Fa.high).map(e=>({...e.item,score:e.score})),u=c.filter(e=>e.score>=Fa.high&&e.score<Fa.medium).map(e=>({...e.item,score:e.score})),d=c.filter(e=>e.score>=Fa.medium&&e.score<Fa.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=Pa.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 La(e,t={}){let{session:n,mcpLog:r}=t,i=e.file||`.taskgraph/tasks/tasks.json`,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):!z()&&p===`text`&&L(t,e)},h=re(e.output,{projectRoot:c,tag:l},m);p===`text`&&console.log(B.brand(`Analyzing task complexity and generating expansion recommendations...`));try{m(`Reading tasks from ${i}...`,`info`);let t,g=0,_=null;if(e._filteredTasksData){if(t=e._filteredTasksData,g=e._originalTaskCount||t.tasks.length,!e._originalTaskCount)try{_=F(i,c,l),_&&_.tasks&&(g=_.tasks.length)}catch(e){L(`warn`,`Could not read original tasks file: ${e.message}`)}}else{if(_=F(i,c,l),!_||!_.tasks||!Array.isArray(_.tasks)||_.tasks.length===0)throw Error(`No tasks found in the tasks file`);g=_.tasks.length;let e=[`pending`,`blocked`,`in-progress`],n=_.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(V.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(V.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(..._.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(V.yellow(`Warning: No active tasks found in range: ${e}-${t}`))}t={..._,tasks:n,_originalTaskCount:g}}let v=``;if(_&&_.tasks.length>0)try{let e=new Aa(c,l),n=new Ia(oe(_.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&&(v=(await e.gather({tasks:a,format:`research`})).context||``)}catch(e){m(`Could not gather additional context: ${e.message}`,`warn`)}let y=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.brand(e))}else if(y>0){let e=`Skipping ${y} tasks marked as done/cancelled/deferred. Analyzing ${t.tasks.length} active tasks.`;m(e,`info`),p===`text`&&console.log(V.yellow(e))}let b=null,x=/* @__PURE__ */ new Map;try{G.existsSync(h)&&(b=JSON.parse(G.readFileSync(h,`utf8`)),m(`Found existing complexity report at ${h}`,`info`),b&&b.complexityAnalysis&&Array.isArray(b.complexityAnalysis)&&(b.complexityAnalysis.forEach(e=>{x.set(e.taskId,e)}),m(`Existing report contains ${b.complexityAnalysis.length} task analyses`,`info`)))}catch(e){m(`Warning: Could not read existing report: ${e.message}`,`warn`),b=null,x.clear()}if(t.tasks.length===0){if(b&&(u||d!==null||f!==null))return m(`No matching tasks found for analysis. Keeping existing report.`,`info`),p===`text`&&console.log(V.yellow(`No matching tasks found for analysis. Keeping existing report.`)),{report:b,telemetryData:null};let e={meta:{generatedAt:(/* @__PURE__ */ new Date()).toISOString(),tasksAnalyzed:0,thresholdScore:o,projectName:me(n),usedResearch:s},complexityAnalysis:b?.complexityAnalysis||[]};return m(`Writing complexity report to ${h}...`,`info`),G.writeFileSync(h,JSON.stringify(e,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`&&(console.log(V.green(`Task complexity analysis complete. Report written to ${h}`)),console.log(`
1026
+ 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(K(B.text.bold(`Suggested Next Steps:`)+`
1033
1027
 
1034
- ${H.cyan(`1.`)} Run ${H.yellow(`taskgraph complexity-report`)} to review detailed findings\n${H.cyan(`2.`)} Run ${H.yellow(`taskgraph expand --id=<id>`)} to break down complex tasks\n${H.cyan(`3.`)} Run ${H.yellow(`taskgraph expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))),{report:e,telemetryData:null}}let S=_a(),C={tasks:t.tasks,gatheredContext:v||``,useResearch:s,hasCodebaseAnalysis:ee(s,c,n),projectRoot:c||``},{systemPrompt:w,userPrompt:T}=await S.loadPrompt(`analyze-complexity`,C,`default`),E=null;p===`text`&&(E=Ac(`${s?`Researching`:`Analyzing`} the complexity of your tasks with AI...\n`));let D=null,O=null;try{D=await a({prompt:T,systemPrompt:w,role:s?`research`:`main`,session:n,projectRoot:c,schema:aa[`analyze-complexity`],objectName:`complexityAnalysis`,commandName:`analyze-complexity`,outputType:r?`mcp`:`cli`}),E&&=($(E),null),p===`text`&&(Fe.clearLine(process.stdout,0),Fe.cursorTo(process.stdout,0),console.log(H.green(`AI service call complete.`))),O=D.mainResult?.complexityAnalysis,m(`Received ${O.length} complexity analyses from AI.`,`info`);let e=t.tasks.map(e=>e.id),i=O.map(e=>e.taskId),l=e.filter(e=>!i.includes(e));if(l.length>0){m(`Missing analysis for ${l.length} tasks: ${l.join(`, `)}`,`warn`),p===`text`&&console.log(H.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`),O.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(b&&Array.isArray(b.complexityAnalysis)){let e=new Set(O.map(e=>e.taskId)),n=new Set(t.tasks.map(e=>e.id)),r=b.complexityAnalysis.filter(t=>!e.has(t.taskId)&&n.has(t.taskId));u=[...r,...O],m(`Merged ${O.length} new analyses with ${r.length} existing entries from current tag`,`info`)}else u=O;let d={meta:{generatedAt:(/* @__PURE__ */ new Date()).toISOString(),tasksAnalyzed:t.tasks.length,totalTasks:g,analysisCount:u.length,thresholdScore:o,projectName:me(n),usedResearch:s},complexityAnalysis:u};if(m(`Writing complexity report to ${h}...`,`info`),K.writeFileSync(h,JSON.stringify(d,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`){console.log(H.green(`Task complexity analysis complete. Report written to ${h}`));let e=O.filter(e=>e.complexityScore>=8).length,t=O.filter(e=>e.complexityScore>=5&&e.complexityScore<8).length,r=O.filter(e=>e.complexityScore<5).length,i=O.length;console.log(`
1028
+ ${V.cyan(`1.`)} Run ${V.yellow(`taskgraph complexity-report`)} to review detailed findings\n${V.cyan(`2.`)} Run ${V.yellow(`taskgraph expand --id=<id>`)} to break down complex tasks\n${V.cyan(`3.`)} Run ${V.yellow(`taskgraph expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))),{report:e,telemetryData:null}}let S=Oa(),C={tasks:t.tasks,gatheredContext:v||``,useResearch:s,hasCodebaseAnalysis:ee(s,c,n),projectRoot:c||``},{systemPrompt:w,userPrompt:T}=await S.loadPrompt(`analyze-complexity`,C,`default`),E=null;p===`text`&&(E=Vc(`${s?`Researching`:`Analyzing`} the complexity of your tasks with AI...\n`));let D=null,O=null;try{D=await a({prompt:T,systemPrompt:w,role:s?`research`:`main`,session:n,projectRoot:c,schema:ga[`analyze-complexity`],objectName:`complexityAnalysis`,commandName:`analyze-complexity`,outputType:r?`mcp`:`cli`}),E&&=($(E),null),p===`text`&&(Ie.clearLine(process.stdout,0),Ie.cursorTo(process.stdout,0),console.log(V.green(`AI service call complete.`))),O=D.mainResult?.complexityAnalysis,m(`Received ${O.length} complexity analyses from AI.`,`info`);let e=t.tasks.map(e=>e.id),i=O.map(e=>e.taskId),l=e.filter(e=>!i.includes(e));if(l.length>0){m(`Missing analysis for ${l.length} tasks: ${l.join(`, `)}`,`warn`),p===`text`&&console.log(V.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`),O.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(b&&Array.isArray(b.complexityAnalysis)){let e=new Set(O.map(e=>e.taskId)),n=new Set(t.tasks.map(e=>e.id)),r=b.complexityAnalysis.filter(t=>!e.has(t.taskId)&&n.has(t.taskId));u=[...r,...O],m(`Merged ${O.length} new analyses with ${r.length} existing entries from current tag`,`info`)}else u=O;let d={meta:{generatedAt:(/* @__PURE__ */ new Date()).toISOString(),tasksAnalyzed:t.tasks.length,totalTasks:g,analysisCount:u.length,thresholdScore:o,projectName:me(n),usedResearch:s},complexityAnalysis:u};if(m(`Writing complexity report to ${h}...`,`info`),G.writeFileSync(h,JSON.stringify(d,null,` `),`utf8`),m(`Task complexity analysis complete. Report written to ${h}`,`success`),p===`text`){console.log(V.green(`Task complexity analysis complete. Report written to ${h}`));let e=O.filter(e=>e.complexityScore>=8).length,t=O.filter(e=>e.complexityScore>=5&&e.complexityScore<8).length,r=O.filter(e=>e.complexityScore<5).length,i=O.length;console.log(`
1035
1029
  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}`),b&&(console.log(`
1036
- 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(q(V.text.bold(`Suggested Next Steps:`)+`
1037
-
1038
- ${H.cyan(`1.`)} Run ${H.yellow(`taskgraph complexity-report`)} to review detailed findings\n${H.cyan(`2.`)} Run ${H.yellow(`taskgraph expand --id=<id>`)} to break down complex tasks\n${H.cyan(`3.`)} Run ${H.yellow(`taskgraph expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),R(n)&&console.debug(V.muted(`Final analysis object: ${JSON.stringify(d,null,2)}`)),D.telemetryData&&Gc(D.telemetryData,`cli`)}return{report:d,telemetryData:D?.telemetryData,tagInfo:D?.tagInfo}}catch(e){throw E&&$(E),m(`Error during AI service call: ${e.message}`,`error`),p===`text`&&(console.error(H.red(`Error during AI service call: ${e.message}`)),e.message.includes(`API key`)&&(console.log(H.yellow(`
1039
- Please ensure your API keys are correctly configured in .env or ~/.taskgraph/.env`)),console.log(H.yellow(`Run 'taskgraph models --setup' if needed.`)))),e}}catch(e){if(m(`Error analyzing task complexity: ${e.message}`,`error`),p===`text`)console.error(H.red(`Error analyzing task complexity: ${e.message}`)),R(n)&&console.error(e),process.exit(1);else throw e}}function Da(e,t,n={}){let{projectRoot:r,tag:i}=n;L(`info`,`Reading tasks from ${e}...`);let a=F(e,r,i);(!a||!a.tasks)&&(L(`error`,`No valid tasks found.`),process.exit(1)),B()||console.log(q(V.text.bold(`Clearing Subtasks`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}));let o=t.split(`,`).map(e=>e.trim()),s=0,c=new Y({head:[H.cyan.bold(`Task ID`),H.cyan.bold(`Task Title`),H.cyan.bold(`Subtasks Cleared`)],colWidths:[10,50,20],style:{head:[],border:[]}});o.forEach(e=>{let t=parseInt(e,10);if(Number.isNaN(t)){L(`error`,`Invalid task ID: ${e}`);return}let n=a.tasks.find(e=>e.id===t);if(!n){L(`error`,`Task ${t} not found`);return}if(!n.subtasks||n.subtasks.length===0){L(`info`,`Task ${t} has no subtasks to clear`),c.push([t.toString(),z(n.title,47),H.yellow(`No subtasks`)]);return}let r=n.subtasks.length;n.subtasks=[],s++,L(`info`,`Cleared ${r} subtasks from task ${t}`),c.push([t.toString(),z(n.title,47),H.green(`${r} subtasks cleared`)])}),s>0?(I(e,a,r,i),B()||(console.log(q(V.text.bold(`Subtask Clearing Summary:`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:P,borderStyle:`round`})),console.log(c.toString())),B()||(console.log(q(H.green(`Successfully cleared subtasks from ${H.bold(s)} task(s)`),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),console.log(q(V.text.bold(`Next Steps:`)+`
1040
-
1041
- ${H.cyan(`1.`)} Run ${H.yellow(`taskgraph expand --id=<id>`)} to generate new subtasks\n${H.cyan(`2.`)} Run ${H.yellow(`taskgraph list --with-subtasks`)} to verify changes`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})))):B()||console.log(q(H.yellow(`No subtasks were cleared`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}function Oa(e,t){let n=!!e,r=e||{info:e=>!B()&&L(`info`,e),warn:e=>!B()&&L(`warn`,e),error:e=>!B()&&L(`error`,e),debug:e=>!B()&&R(t)&&L(`debug`,e)};return{logger:r,report:(e,...t)=>{n?typeof r[e]==`function`?r[e](...t):r.info(...t):B()||L(e,...t)},isMCP:n}}async function ka(e,t,n,r=!1,i=``,o={},s=!1){let{session:c,mcpLog:l,projectRoot:u,tag:d,complexityReportPath:f}=o,p=l?`json`:`text`,m=u||Se(e),{logger:h,report:g,isMCP:_}=Oa(l,c);_&&h.info(`expandTask called with context: session=${!!c}`);try{h.info(`Reading tasks from ${e}`);let o=F(e,m,d);if(!o||!o.tasks)throw Error(`Invalid tasks data in ${e}`);let l=o.tasks.findIndex(e=>e.id===parseInt(t,10));if(l===-1)throw Error(`Task ${t} not found`);let u=o.tasks[l];h.info(`Expanding task ${t}: ${u.title}${r?` with research`:``}`),s&&Array.isArray(u.subtasks)&&u.subtasks.length>0&&(h.info(`Force flag set. Clearing existing ${u.subtasks.length} subtasks for task ${t}.`),u.subtasks=[]);let g=``;try{let e=new ya(m,d),n=new Ta(oe(o.tasks),`expand-task`),r=`${u.title} ${u.description}`,i=n.findRelevantTasks(r,{maxResults:5,includeSelf:!0}),a=n.getTaskIds(i),s=[.../* @__PURE__ */ new Set([t.toString(),...a])];s.length>0&&(g=(await e.gather({tasks:s,format:`research`})).context||``)}catch(e){h.warn(`Could not gather context: ${e.message}`)}let _,v=``,y=null;h.info(`Looking for complexity report at: ${f}${d===`master`?``:` (tag-specific for '${d}')`}`);try{K.existsSync(f)?(y=F(f)?.complexityAnalysis?.find(e=>e.taskId===u.id),y?(h.info(`Found complexity analysis for task ${u.id}: Score ${y.complexityScore}`),y.reasoning&&(v=`\nComplexity Analysis Reasoning: ${y.reasoning}`)):h.info(`No complexity analysis found for task ${u.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 b=parseInt(n,10);if(!Number.isNaN(b)&&b>=0)_=b,h.info(`Using explicitly provided subtask count: ${_}`);else if(y?.recommendedSubtasks!=null){if(_=parseInt(y.recommendedSubtasks,10),h.info(`Using subtask count from complexity report: ${_}`),_===0)return h.info(`Complexity report recommends no expansion for task ${t}. Skipping.`),{task:u,skipped:!0}}else _=_e(c),h.info(`Using default number of subtasks: ${_}`);(Number.isNaN(_)||_<0)&&(h.warn(`Invalid subtask count determined (${_}), defaulting to 3.`),_=3);let x=(u.subtasks?.length||0)+1,S=_a(),C=ee(r,m,c),w=``;(i||v)&&(w=`\n\n${i}${v}`.trim()),g&&(w=`${w}\n\n# Project Context\n\n${g}`.trim());let T;y?.expansionPrompt&&(typeof y.expansionPrompt==`string`?T=y.expansionPrompt:typeof y.expansionPrompt==`object`&&y.expansionPrompt.text&&(T=y.expansionPrompt.text));let E=g;typeof g==`object`&&g&&(E=g.data?g.data:g.text?g.text:JSON.stringify(g));let D={task:u,subtaskCount:_,nextSubtaskId:x,additionalContext:i,complexityReasoningContext:v,gatheredContext:E||``,useResearch:r,expansionPrompt:T||void 0,hasCodebaseAnalysis:C,projectRoot:m||``},O=`default`;T?(O=`complexity-report`,h.info(`Using expansion prompt from complexity report for task ${u.id}.`)):r?(O=`research`,h.info(`Using research variant for task ${u.id}.`)):h.info(`Using standard prompt generation for task ${u.id}.`);let{systemPrompt:k,userPrompt:A}=S.loadPrompt(`expand-task`,D,O);h.debug(`Selected variant: ${O}`),h.debug(`Prompt params passed: ${JSON.stringify(D,null,2)}`),h.debug(`System prompt (first 500 chars): ${k.substring(0,500)}...`),h.debug(`User prompt (first 500 chars): ${A.substring(0,500)}...`);let te=[],j=null;p===`text`&&(j=Ac(`Generating ${_||`appropriate number of`} subtasks...\n`));let M=null;try{M=await a({prompt:A,systemPrompt:k,role:r?`research`:`main`,session:c,projectRoot:m,schema:aa[`expand-task`],objectName:`subtasks`,commandName:`expand-task`,outputType:p});let e=M?.mainResult;if(!e||!Array.isArray(e.subtasks))throw Error(`AI response did not include a valid subtasks array.`);te=e.subtasks.map(e=>({...e,dependencies:e.dependencies??[],status:e.status??`pending`,testStrategy:e.testStrategy??null})),h.info(`Received ${te.length} subtasks from AI.`)}catch(e){throw j&&$(j),h.error(`Error during AI call or parsing for task ${t}: ${e.message}`,`error`),e}finally{j&&$(j)}return Array.isArray(u.subtasks)||(u.subtasks=[]),u.subtasks.push(...te),o.tasks[l]=u,I(e,o,m,d),p===`text`&&M&&M.telemetryData&&Gc(M.telemetryData,`cli`),{task:u,telemetryData:M?.telemetryData,tagInfo:M?.tagInfo}}catch(e){throw h.error(`Error expanding task ${t}: ${e.message}`,`error`),p===`text`&&R(c)&&console.error(e),e}}async function Aa(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||Se();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=>!B()&&L(`info`,e),warn:e=>!B()&&L(`warn`,e),error:e=>!B()&&L(`error`,e),debug:e=>!B()&&R(s)&&L(`debug`,e)}),h=null,g=0,_=0,v=0,y=0,b=[];!f&&o===`text`&&(h=Ac(`Analyzing tasks for expansion...`));try{m.info(`Reading tasks from ${e}`);let s=F(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(y=c.length,m.info(`Found ${y} tasks eligible for expansion.`),h&&$(h,`Analysis complete.`),y===0)return m.info(`No tasks eligible for expansion.`),{success:!0,expandedCount:0,failedCount:0,skippedCount:0,tasksToExpand:0,telemetryData:b,message:`No tasks eligible for expansion.`};for(let l of c){let c=null;!f&&o===`text`&&(c=Ac(`Expanding task ${l.id}...`));try{let o=await ka(e,l.id,t,n,r,{...a,projectRoot:p,tag:s.tag||u,complexityReportPath:d},i);if(o?.skipped){v++,c&&$(c,`Task ${l.id} skipped (no expansion recommended).`),m.info(`Skipped task ${l.id}: complexity report recommends no expansion.`);continue}g++,o&&o.telemetryData&&b.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, ${v} skipped, ${_} failed.`);let l=ae(b,`expand-all-tasks`);if(o===`text`){let e=`${V.text.bold(`Expansion Summary:`)}\n\n${H.cyan(`-`)} Attempted: ${H.bold(y)}\n${H.green(`-`)} Expanded: ${H.bold(g)}\n${V.muted(`-`)} Skipped: ${H.bold(v)}\n${H.red(`-`)} Failed: ${H.bold(_)}`;console.log(q(e,{padding:1,margin:{top:1},borderColor:_>0?`red`:`green`,borderStyle:`round`}))}return o===`text`&&l&&Gc(l,`cli`),{success:!0,expandedCount:g,failedCount:_,skippedCount:v,tasksToExpand:y,telemetryData:l}}catch(e){throw h&&$(h,`Error.`,!1),m.error(`Error during expand all operation: ${e.message}`),!f&&R(s)&&console.error(e),e}}function ja(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&&ja(e,t,n))return!0}if(t.subtasks){for(let r of t.subtasks)if(ja(e,r,n))return!0}return!1}async function Ma(e,t,n=null,r=!1,i=`text`,a={}){let{projectRoot:o,tag:s}=a;try{let a;try{let e=await(await x({projectPath:o||process.cwd()})).tasks.list({tag:s});a={tasks:e.tasks},L(`debug`,`Loaded ${e.tasks.length} tasks via tm-core`)}catch(t){L(`warn`,`TmCore failed, falling back to legacy readJSON: ${t.message}`),a=F(e,o,s)}if(!a||!a.tasks)throw Error(`No valid tasks found in ${e}`);let c=we(n);c&&c.complexityAnalysis&&a.tasks.forEach(e=>E(e,c));let l;if(t&&t.toLowerCase()!==`all`){let e=t.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0);l=a.tasks.filter(t=>t.status&&e.includes(t.status.toLowerCase()))}else l=a.tasks;let u=a.tasks.length,d=a.tasks.filter(e=>e.status===`done`||e.status===`completed`).length,f=u>0?d/u*100:0,p=d,m=a.tasks.filter(e=>e.status===`in-progress`).length,h=a.tasks.filter(e=>e.status===`pending`).length,g=a.tasks.filter(e=>e.status===`blocked`).length,_=a.tasks.filter(e=>e.status===`deferred`).length,v=a.tasks.filter(e=>e.status===`cancelled`).length,y=a.tasks.filter(e=>e.status===`review`).length,b=0,S=0,C=0,w=0,T=0,ee=0,D=0,O=0;a.tasks.forEach(e=>{e.subtasks&&e.subtasks.length>0&&(b+=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,ee+=e.subtasks.filter(e=>e.status===`deferred`).length,D+=e.subtasks.filter(e=>e.status===`cancelled`).length,O+=e.subtasks.filter(e=>e.status===`review`).length)});let k=b>0?S/b*100:0,A=new Set(a.tasks.filter(e=>e.status===`done`||e.status===`completed`).map(e=>e.id)),te=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&(!e.dependencies||e.dependencies.length===0)).length,j=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>A.has(e))).length,M=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>A.has(e))).length,ne=te+j,re={};a.tasks.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{re[e]=(re[e]||0)+1})});let ie=null,ae=0;for(let[e,t]of Object.entries(re))t>ae&&(ae=t,ie=parseInt(e));let oe=ie===null?null:a.tasks.find(e=>e.id===ie),se=a.tasks.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0)/a.tasks.length,N=or(a.tasks,c);if(i===`json`)return{tasks:l.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:u,completed:p,inProgress:m,pending:h,blocked:g,deferred:_,cancelled:v,review:y,completionPercentage:f,subtasks:{total:b,completed:S,inProgress:C,pending:w,blocked:T,deferred:ee,cancelled:D,completionPercentage:k}}};if(i===`markdown-readme`)return Pa(a,l,{totalTasks:u,completedTasks:d,completionPercentage:f,doneCount:p,inProgressCount:m,pendingCount:h,blockedCount:g,deferredCount:_,cancelledCount:v,totalSubtasks:b,completedSubtasks:S,subtaskCompletionPercentage:k,inProgressSubtasks:C,pendingSubtasks:w,blockedSubtasks:T,deferredSubtasks:ee,cancelledSubtasks:D,reviewSubtasks:O,tasksWithNoDeps:te,tasksReadyToWork:ne,tasksWithUnsatisfiedDeps:M,mostDependedOnTask:oe,mostDependedOnTaskId:ie,maxDependents:ae,avgDependenciesPerTask:se,complexityReport:c,withSubtasks:r,nextItem:N});if(i===`compact`)return Ra(l,r);let P={"in-progress":u>0?m/u*100:0,pending:u>0?h/u*100:0,blocked:u>0?g/u*100:0,deferred:u>0?_/u*100:0,cancelled:u>0?v/u*100:0,review:u>0?y/u*100:0},ce={"in-progress":b>0?C/b*100:0,pending:b>0?w/b*100:0,blocked:b>0?T/b*100:0,deferred:b>0?ee/b*100:0,cancelled:b>0?D/b*100:0,review:b>0?O/b*100:0},le=Pc(f,30,P),ue=Pc(k,30,ce),de;try{de=process.stdout.columns}catch{L(`debug`,`Could not determine terminal width, using default`)}de||=80,de=Math.max(de,80);let fe=H.bold(`Project Dashboard`)+`
1042
- Tasks Progress: ${H.greenBright(le)} ${f.toFixed(0)}%\n${H.green(`█`)} Done: ${H.green(p)} ${H.cyan(`▓`)} In Progress: ${H.cyan(m)} ${H.yellow(`░`)} Pending: ${H.yellow(h)} ${H.red(`!`)} Blocked: ${H.red(g)} ${Q.muted(`─`)} Deferred: ${Q.muted(_)} ${Q.muted(`─`)} Cancelled: ${Q.muted(v)}\n\nSubtasks Progress: ${H.cyan(ue)} ${k.toFixed(0)}%\n${H.green(`█`)} Completed: ${H.green(S)}/${b} ${H.cyan(`▓`)} In Progress: ${H.cyan(C)} ${H.yellow(`░`)} Pending: ${H.yellow(w)} ${H.red(`!`)} Blocked: ${H.red(T)} ${Q.muted(`─`)} Deferred: ${Q.muted(ee)} ${Q.muted(`─`)} Cancelled: ${Q.muted(D)}\n\n`+H.cyan.bold(`Priority Breakdown:`)+`
1043
- ${H.red(`•`)} ${H.reset(`High priority:`)} ${a.tasks.filter(e=>e.priority===`high`).length}\n${H.yellow(`•`)} ${H.reset(`Medium priority:`)} ${a.tasks.filter(e=>e.priority===`medium`).length}\n${H.green(`•`)} ${H.reset(`Low priority:`)} ${a.tasks.filter(e=>e.priority===`low`).length}`,pe=H.bold(`Dependency Status & Next Task`)+`
1044
- `+H.cyan.bold(`Dependency Metrics:`)+`
1045
- ${H.green(`•`)} ${H.reset(`Tasks with no dependencies:`)} ${te}\n${H.green(`•`)} ${H.reset(`Tasks ready to work on:`)} ${ne}\n${H.yellow(`•`)} ${H.reset(`Tasks blocked by dependencies:`)} ${M}\n${H.magenta(`•`)} ${H.reset(`Most depended-on task:`)} ${oe?H.cyan(`#${ie} (${ae} dependents)`):Q.muted(`None`)}\n${H.cyan(`•`)} ${H.reset(`Avg dependencies per task:`)} ${se.toFixed(1)}\n\n`+H.cyan.bold(`Next Task:`)+`
1046
- ID: ${H.cyan(N?N.id:`N/A`)} - ${N?H.bold(z(N.title,40)):H.yellow(`No task available`)}
1047
- Priority: ${N?H.reset(N.priority||`medium`):``} Dependencies: ${N?Ic(N.dependencies,a.tasks,!0,c):``}
1048
- Complexity: ${N&&N.complexityScore?Rc(N.complexityScore):Q.muted(`N/A`)}`;if(de>=104){let e=Math.floor(de/2),t=e-4,n=q(fe,{padding:1,borderColor:wc,borderStyle:`round`,width:t,dimBorder:!1}),r=q(pe,{padding:1,borderColor:`magenta`,borderStyle:`round`,width:t,dimBorder:!1}),i=n.split(`
1030
+ 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(K(B.text.bold(`Suggested Next Steps:`)+`
1031
+
1032
+ ${V.cyan(`1.`)} Run ${V.yellow(`taskgraph complexity-report`)} to review detailed findings\n${V.cyan(`2.`)} Run ${V.yellow(`taskgraph expand --id=<id>`)} to break down complex tasks\n${V.cyan(`3.`)} Run ${V.yellow(`taskgraph expand --all`)} to expand all pending tasks based on complexity`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),be(n)&&console.debug(B.muted(`Final analysis object: ${JSON.stringify(d,null,2)}`)),D.telemetryData&&nl(D.telemetryData,`cli`)}return{report:d,telemetryData:D?.telemetryData,tagInfo:D?.tagInfo}}catch(e){throw E&&$(E),m(`Error during AI service call: ${e.message}`,`error`),p===`text`&&(console.error(V.red(`Error during AI service call: ${e.message}`)),e.message.includes(`API key`)&&(console.log(V.yellow(`
1033
+ Please ensure your API keys are correctly configured in .env or ~/.taskgraph/.env`)),console.log(V.yellow(`Run 'taskgraph models --setup' if needed.`)))),e}}catch(e){if(m(`Error analyzing task complexity: ${e.message}`,`error`),p===`text`)console.error(V.red(`Error analyzing task complexity: ${e.message}`)),be(n)&&console.error(e),process.exit(1);else throw e}}function Ra(e,t,n={}){let{projectRoot:r,tag:i}=n;L(`info`,`Reading tasks from ${e}...`);let a=F(e,r,i);(!a||!a.tasks)&&(L(`error`,`No valid tasks found.`),process.exit(1)),z()||console.log(K(B.text.bold(`Clearing Subtasks`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}));let o=t.split(`,`).map(e=>e.trim()),s=0,c=new J({head:[V.cyan.bold(`Task ID`),V.cyan.bold(`Task Title`),V.cyan.bold(`Subtasks Cleared`)],colWidths:[10,50,20],style:{head:[],border:[]}});o.forEach(e=>{let t=parseInt(e,10);if(Number.isNaN(t)){L(`error`,`Invalid task ID: ${e}`);return}let n=a.tasks.find(e=>e.id===t);if(!n){L(`error`,`Task ${t} not found`);return}if(!n.subtasks||n.subtasks.length===0){L(`info`,`Task ${t} has no subtasks to clear`),c.push([t.toString(),R(n.title,47),V.yellow(`No subtasks`)]);return}let r=n.subtasks.length;n.subtasks=[],s++,L(`info`,`Cleared ${r} subtasks from task ${t}`),c.push([t.toString(),R(n.title,47),V.green(`${r} subtasks cleared`)])}),s>0?(I(e,a,r,i),z()||(console.log(K(B.text.bold(`Subtask Clearing Summary:`),{padding:{left:2,right:2,top:0,bottom:0},margin:{top:1,bottom:0},borderColor:P,borderStyle:`round`})),console.log(c.toString())),z()||(console.log(K(V.green(`Successfully cleared subtasks from ${V.bold(s)} task(s)`),{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),console.log(K(B.text.bold(`Next Steps:`)+`
1034
+
1035
+ ${V.cyan(`1.`)} Run ${V.yellow(`taskgraph expand --id=<id>`)} to generate new subtasks\n${V.cyan(`2.`)} Run ${V.yellow(`taskgraph list --with-subtasks`)} to verify changes`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})))):z()||console.log(K(V.yellow(`No subtasks were cleared`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}function za(e,t){let n=!!e,r=e||{info:e=>!z()&&L(`info`,e),warn:e=>!z()&&L(`warn`,e),error:e=>!z()&&L(`error`,e),debug:e=>!z()&&be(t)&&L(`debug`,e)};return{logger:r,report:(e,...t)=>{n?typeof r[e]==`function`?r[e](...t):r.info(...t):z()||L(e,...t)},isMCP:n}}async function Ba(e,t,n,r=!1,i=``,o={},s=!1){let{session:c,mcpLog:l,projectRoot:u,tag:d,complexityReportPath:f}=o,p=l?`json`:`text`,m=u||Ce(e),{logger:h,report:g,isMCP:_}=za(l,c);_&&h.info(`expandTask called with context: session=${!!c}`);try{h.info(`Reading tasks from ${e}`);let o=F(e,m,d);if(!o||!o.tasks)throw Error(`Invalid tasks data in ${e}`);let l=o.tasks.findIndex(e=>e.id===parseInt(t,10));if(l===-1)throw Error(`Task ${t} not found`);let u=o.tasks[l];h.info(`Expanding task ${t}: ${u.title}${r?` with research`:``}`),s&&Array.isArray(u.subtasks)&&u.subtasks.length>0&&(h.info(`Force flag set. Clearing existing ${u.subtasks.length} subtasks for task ${t}.`),u.subtasks=[]);let g=``;try{let e=new Aa(m,d),n=new Ia(oe(o.tasks),`expand-task`),r=`${u.title} ${u.description}`,i=n.findRelevantTasks(r,{maxResults:5,includeSelf:!0}),a=n.getTaskIds(i),s=[.../* @__PURE__ */ new Set([t.toString(),...a])];s.length>0&&(g=(await e.gather({tasks:s,format:`research`})).context||``)}catch(e){h.warn(`Could not gather context: ${e.message}`)}let _,v=``,y=null;h.info(`Looking for complexity report at: ${f}${d===`master`?``:` (tag-specific for '${d}')`}`);try{G.existsSync(f)?(y=F(f)?.complexityAnalysis?.find(e=>e.taskId===u.id),y?(h.info(`Found complexity analysis for task ${u.id}: Score ${y.complexityScore}`),y.reasoning&&(v=`\nComplexity Analysis Reasoning: ${y.reasoning}`)):h.info(`No complexity analysis found for task ${u.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 b=parseInt(n,10);if(!Number.isNaN(b)&&b>=0)_=b,h.info(`Using explicitly provided subtask count: ${_}`);else if(y?.recommendedSubtasks!=null){if(_=parseInt(y.recommendedSubtasks,10),h.info(`Using subtask count from complexity report: ${_}`),_===0)return h.info(`Complexity report recommends no expansion for task ${t}. Skipping.`),{task:u,skipped:!0}}else _=_e(c),h.info(`Using default number of subtasks: ${_}`);(Number.isNaN(_)||_<0)&&(h.warn(`Invalid subtask count determined (${_}), defaulting to 3.`),_=3);let x=(u.subtasks?.length||0)+1,S=Oa(),C=ee(r,m,c),w=``;(i||v)&&(w=`\n\n${i}${v}`.trim()),g&&(w=`${w}\n\n# Project Context\n\n${g}`.trim());let T;y?.expansionPrompt&&(typeof y.expansionPrompt==`string`?T=y.expansionPrompt:typeof y.expansionPrompt==`object`&&y.expansionPrompt.text&&(T=y.expansionPrompt.text));let E=g;typeof g==`object`&&g&&(E=g.data?g.data:g.text?g.text:JSON.stringify(g));let D={task:u,subtaskCount:_,nextSubtaskId:x,additionalContext:i,complexityReasoningContext:v,gatheredContext:E||``,useResearch:r,expansionPrompt:T||void 0,hasCodebaseAnalysis:C,projectRoot:m||``},O=`default`;T?(O=`complexity-report`,h.info(`Using expansion prompt from complexity report for task ${u.id}.`)):r?(O=`research`,h.info(`Using research variant for task ${u.id}.`)):h.info(`Using standard prompt generation for task ${u.id}.`);let{systemPrompt:k,userPrompt:A}=S.loadPrompt(`expand-task`,D,O);h.debug(`Selected variant: ${O}`),h.debug(`Prompt params passed: ${JSON.stringify(D,null,2)}`),h.debug(`System prompt (first 500 chars): ${k.substring(0,500)}...`),h.debug(`User prompt (first 500 chars): ${A.substring(0,500)}...`);let te=[],j=null;p===`text`&&(j=Vc(`Generating ${_||`appropriate number of`} subtasks...\n`));let M=null;try{M=await a({prompt:A,systemPrompt:k,role:r?`research`:`main`,session:c,projectRoot:m,schema:ga[`expand-task`],objectName:`subtasks`,commandName:`expand-task`,outputType:p});let e=M?.mainResult;if(!e||!Array.isArray(e.subtasks))throw Error(`AI response did not include a valid subtasks array.`);te=e.subtasks.map(e=>({...e,dependencies:e.dependencies??[],status:e.status??`pending`,testStrategy:e.testStrategy??null})),h.info(`Received ${te.length} subtasks from AI.`)}catch(e){throw j&&$(j),e}finally{j&&$(j)}return Array.isArray(u.subtasks)||(u.subtasks=[]),u.subtasks.push(...te),o.tasks[l]=u,I(e,o,m,d),p===`text`&&M&&M.telemetryData&&nl(M.telemetryData,`cli`),{task:u,telemetryData:M?.telemetryData,tagInfo:M?.tagInfo}}catch(e){throw p!==`text`&&h.error(`Error expanding task ${t}: ${e.message}`,`error`),e}}async function Va(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||Ce();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=>!z()&&L(`info`,e),warn:e=>!z()&&L(`warn`,e),error:e=>!z()&&L(`error`,e),debug:e=>!z()&&be(s)&&L(`debug`,e)}),h=null,g=0,_=0,v=0,y=0,b=[];!f&&o===`text`&&(h=Vc(`Analyzing tasks for expansion...`));try{m.info(`Reading tasks from ${e}`);let s=F(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(y=c.length,m.info(`Found ${y} tasks eligible for expansion.`),h&&$(h,`Analysis complete.`),y===0)return m.info(`No tasks eligible for expansion.`),{success:!0,expandedCount:0,failedCount:0,skippedCount:0,tasksToExpand:0,telemetryData:b,message:`No tasks eligible for expansion.`};for(let l of c){let c=null;!f&&o===`text`&&(c=Vc(`Expanding task ${l.id}...`));try{let o=await Ba(e,l.id,t,n,r,{...a,projectRoot:p,tag:s.tag||u,complexityReportPath:d},i);if(o?.skipped){v++,c&&$(c,`Task ${l.id} skipped (no expansion recommended).`),m.info(`Skipped task ${l.id}: complexity report recommends no expansion.`);continue}g++,o&&o.telemetryData&&b.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, ${v} skipped, ${_} failed.`);let l=ae(b,`expand-all-tasks`);if(o===`text`){let e=`${B.text.bold(`Expansion Summary:`)}\n\n${V.cyan(`-`)} Attempted: ${V.bold(y)}\n${V.green(`-`)} Expanded: ${V.bold(g)}\n${B.muted(`-`)} Skipped: ${V.bold(v)}\n${V.red(`-`)} Failed: ${V.bold(_)}`;console.log(K(e,{padding:1,margin:{top:1},borderColor:_>0?`red`:`green`,borderStyle:`round`}))}return o===`text`&&l&&nl(l,`cli`),{success:!0,expandedCount:g,failedCount:_,skippedCount:v,tasksToExpand:y,telemetryData:l}}catch(e){throw h&&$(h,`Error.`,!1),m.error(`Error during expand all operation: ${e.message}`),!f&&be(s)&&console.error(e),e}}function Ha(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&&Ha(e,t,n))return!0}if(t.subtasks){for(let r of t.subtasks)if(Ha(e,r,n))return!0}return!1}async function Ua(e,t,n=null,r=!1,i=`text`,a={}){let{projectRoot:o,tag:s}=a;try{let a;try{let e=await(await x({projectPath:o||process.cwd()})).tasks.list({tag:s});a={tasks:e.tasks},L(`debug`,`Loaded ${e.tasks.length} tasks via tm-core`)}catch(t){L(`warn`,`TmCore failed, falling back to legacy readJSON: ${t.message}`),a=F(e,o,s)}if(!a||!a.tasks)throw Error(`No valid tasks found in ${e}`);let c=Te(n);c&&c.complexityAnalysis&&a.tasks.forEach(e=>E(e,c));let l;if(t&&t.toLowerCase()!==`all`){let e=t.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0);l=a.tasks.filter(t=>t.status&&e.includes(t.status.toLowerCase()))}else l=a.tasks;let u=a.tasks.length,d=a.tasks.filter(e=>e.status===`done`||e.status===`completed`).length,f=u>0?d/u*100:0,p=d,m=a.tasks.filter(e=>e.status===`in-progress`).length,h=a.tasks.filter(e=>e.status===`pending`).length,g=a.tasks.filter(e=>e.status===`blocked`).length,_=a.tasks.filter(e=>e.status===`deferred`).length,v=a.tasks.filter(e=>e.status===`cancelled`).length,y=a.tasks.filter(e=>e.status===`review`).length,b=0,S=0,C=0,w=0,T=0,ee=0,D=0,O=0;a.tasks.forEach(e=>{e.subtasks&&e.subtasks.length>0&&(b+=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,ee+=e.subtasks.filter(e=>e.status===`deferred`).length,D+=e.subtasks.filter(e=>e.status===`cancelled`).length,O+=e.subtasks.filter(e=>e.status===`review`).length)});let k=b>0?S/b*100:0,A=new Set(a.tasks.filter(e=>e.status===`done`||e.status===`completed`).map(e=>e.id)),te=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&(!e.dependencies||e.dependencies.length===0)).length,j=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>A.has(e))).length,M=a.tasks.filter(e=>e.status!==`done`&&e.status!==`completed`&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>A.has(e))).length,ne=te+j,re={};a.tasks.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{re[e]=(re[e]||0)+1})});let ie=null,ae=0;for(let[e,t]of Object.entries(re))t>ae&&(ae=t,ie=parseInt(e));let oe=ie===null?null:a.tasks.find(e=>e.id===ie),se=a.tasks.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0)/a.tasks.length,N=_r(a.tasks,c);if(i===`json`)return{tasks:l.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:u,completed:p,inProgress:m,pending:h,blocked:g,deferred:_,cancelled:v,review:y,completionPercentage:f,subtasks:{total:b,completed:S,inProgress:C,pending:w,blocked:T,deferred:ee,cancelled:D,completionPercentage:k}}};if(i===`markdown-readme`)return Ga(a,l,{totalTasks:u,completedTasks:d,completionPercentage:f,doneCount:p,inProgressCount:m,pendingCount:h,blockedCount:g,deferredCount:_,cancelledCount:v,totalSubtasks:b,completedSubtasks:S,subtaskCompletionPercentage:k,inProgressSubtasks:C,pendingSubtasks:w,blockedSubtasks:T,deferredSubtasks:ee,cancelledSubtasks:D,reviewSubtasks:O,tasksWithNoDeps:te,tasksReadyToWork:ne,tasksWithUnsatisfiedDeps:M,mostDependedOnTask:oe,mostDependedOnTaskId:ie,maxDependents:ae,avgDependenciesPerTask:se,complexityReport:c,withSubtasks:r,nextItem:N});if(i===`compact`)return Ya(l,r);let P={"in-progress":u>0?m/u*100:0,pending:u>0?h/u*100:0,blocked:u>0?g/u*100:0,deferred:u>0?_/u*100:0,cancelled:u>0?v/u*100:0,review:u>0?y/u*100:0},ce={"in-progress":b>0?C/b*100:0,pending:b>0?w/b*100:0,blocked:b>0?T/b*100:0,deferred:b>0?ee/b*100:0,cancelled:b>0?D/b*100:0,review:b>0?O/b*100:0},le=Gc(f,30,P),ue=Gc(k,30,ce),de;try{de=process.stdout.columns}catch{L(`debug`,`Could not determine terminal width, using default`)}de||=80,de=Math.max(de,80);let fe=V.bold(`Project Dashboard`)+`
1036
+ Tasks Progress: ${V.greenBright(le)} ${f.toFixed(0)}%\n${V.green(`█`)} Done: ${V.green(p)} ${V.cyan(`▓`)} In Progress: ${V.cyan(m)} ${V.yellow(`░`)} Pending: ${V.yellow(h)} ${V.red(`!`)} Blocked: ${V.red(g)} ${Q.muted(`─`)} Deferred: ${Q.muted(_)} ${Q.muted(`─`)} Cancelled: ${Q.muted(v)}\n\nSubtasks Progress: ${V.cyan(ue)} ${k.toFixed(0)}%\n${V.green(`█`)} Completed: ${V.green(S)}/${b} ${V.cyan(`▓`)} In Progress: ${V.cyan(C)} ${V.yellow(`░`)} Pending: ${V.yellow(w)} ${V.red(`!`)} Blocked: ${V.red(T)} ${Q.muted(`─`)} Deferred: ${Q.muted(ee)} ${Q.muted(`─`)} Cancelled: ${Q.muted(D)}\n\n`+V.cyan.bold(`Priority Breakdown:`)+`
1037
+ ${V.red(`•`)} ${V.reset(`High priority:`)} ${a.tasks.filter(e=>e.priority===`high`).length}\n${V.yellow(`•`)} ${V.reset(`Medium priority:`)} ${a.tasks.filter(e=>e.priority===`medium`).length}\n${V.green(`•`)} ${V.reset(`Low priority:`)} ${a.tasks.filter(e=>e.priority===`low`).length}`,pe=V.bold(`Dependency Status & Next Task`)+`
1038
+ `+V.cyan.bold(`Dependency Metrics:`)+`
1039
+ ${V.green(`•`)} ${V.reset(`Tasks with no dependencies:`)} ${te}\n${V.green(`•`)} ${V.reset(`Tasks ready to work on:`)} ${ne}\n${V.yellow(`•`)} ${V.reset(`Tasks blocked by dependencies:`)} ${M}\n${V.magenta(`•`)} ${V.reset(`Most depended-on task:`)} ${oe?V.cyan(`#${ie} (${ae} dependents)`):Q.muted(`None`)}\n${V.cyan(`•`)} ${V.reset(`Avg dependencies per task:`)} ${se.toFixed(1)}\n\n`+V.cyan.bold(`Next Task:`)+`
1040
+ ID: ${V.cyan(N?N.id:`N/A`)} - ${N?V.bold(R(N.title,40)):V.yellow(`No task available`)}
1041
+ Priority: ${N?V.reset(N.priority||`medium`):``} Dependencies: ${N?qc(N.dependencies,a.tasks,!0,c):``}
1042
+ Complexity: ${N&&N.complexityScore?Yc(N.complexityScore):Q.muted(`N/A`)}`;if(de>=104){let e=Math.floor(de/2),t=e-4,n=K(fe,{padding:1,borderColor:Fc,borderStyle:`round`,width:t,dimBorder:!1}),r=K(pe,{padding:1,borderColor:`magenta`,borderStyle:`round`,width:t,dimBorder:!1}),i=n.split(`
1049
1043
  `),a=r.split(`
1050
1044
  `),o=Math.max(i.length,a.length),s=[];for(let t=0;t<o;t++){let n=t<i.length?i[t]:``,r=t<a.length?a[t]:``,o=n.trimEnd().padEnd(e,` `);s.push(o+r)}console.log(s.join(`
1051
- `))}else{let e=q(fe,{padding:1,borderColor:wc,borderStyle:`round`,margin:{top:0,bottom:1}}),t=q(pe,{padding:1,borderColor:`magenta`,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}if(l.length===0){console.log(q(t?H.yellow(`No tasks with status '${t}' found`):H.yellow(`No tasks found`),{padding:1,borderColor:`yellow`,borderStyle:`round`}));return}let me=r?10:7,he=100-me-15-12-20-10,ge=de-10,I=Math.floor(me/100*ge),_e=Math.floor(15/100*ge),ve=Math.floor(12/100*ge),ye=Math.floor(20/100*ge),R=Math.floor(10/100*ge),be=Math.floor(he/100*ge),xe=new Y({head:[H.cyan.bold(`ID`),H.cyan.bold(`Title`),H.cyan.bold(`Status`),H.cyan.bold(`Priority`),H.cyan.bold(`Dependencies`),H.cyan.bold(`Complexity`)],colWidths:[I,be,_e,ve,ye,R],style:{head:[],border:[],compact:!1},wordWrap:!0,wrapOnWordBoundary:!0});l.forEach(e=>{let t=`None`;t=e.dependencies&&e.dependencies.length>0?Ic(e.dependencies,a.tasks,!0,c):Q.muted(`None`);let n=e.title.replace(/\n/g,` `),i={high:H.red,medium:H.yellow,low:Q.muted}[e.priority||`medium`]||H.reset,o=Fc(e.status,!0);xe.push([e.id.toString(),z(n,be-3),o,i(z(e.priority||`medium`,ve-2)),t,e.complexityScore?Rc(e.complexityScore):Q.muted(`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?H.green.bold(`${e.id}.${t}`):i?Q.active.bold(`${e.id}.${t}`):H.red.bold(`${e.id}.${t}`)}}let n=a.tasks.find(e=>e.id===t);if(n){E(n,c);let e=n.status===`done`||n.status===`completed`,r=n.status===`in-progress`;return e?H.green.bold(`${t}`):r?Q.active.bold(`${t}`):H.red.bold(`${t}`)}return H.cyan(t.toString())}).join(`, `)||Q.muted(`None`)),xe.push([`${e.id}.${t.id}`,H.dim(`└─ ${z(t.title,be-5)}`),Fc(t.status,!0),H.dim(`-`),n,t.complexityScore?Q.muted(`${t.complexityScore}`):Q.muted(`N/A`)])})});try{console.log(xe.toString())}catch(e){L(`error`,`Error rendering table: ${e.message}`),console.log(H.yellow(`
1052
- Falling back to simple task list due to terminal width constraints:`)),l.forEach(e=>{console.log(`${H.cyan(e.id)}: ${H.reset(e.title)} - ${Fc(e.status)}`)})}t&&(console.log(H.yellow(`\nFiltered by status: ${t}`)),console.log(H.yellow(`Showing ${l.length} of ${u} tasks`)));let Se={high:H.red.bold,medium:H.yellow,low:Q.muted};if(N){let e=``,t=a.tasks.find(e=>String(e.id)===String(N.id));t&&t.subtasks&&t.subtasks.length>0&&(e=`\n\n${H.bold(`Subtasks:`)}\n`,e+=t.subtasks.map(e=>{E(e,c);let n=e.status||`pending`,r={done:H.green,completed:H.green,pending:H.yellow,"in-progress":H.cyan,deferred:Q.muted,blocked:H.red,cancelled:Q.muted}[n.toLowerCase()]||H.reset;return`${H.cyan(`${t.id}.${e.id}`)} [${r(n)}] ${e.title}`}).join(`
1053
- `));let n=Lt(N.id,N.status,!!t?.subtasks?.length).slice(0,2).map(e=>`${H.cyan(`Next step:`)} ${H.yellow(e.command)} ${Q.muted(e.description)}`).join(`
1054
- `);console.log(q(Q.heading(`Next task: #${N.id} - ${N.title}`)+`
1045
+ `))}else{let e=K(fe,{padding:1,borderColor:Fc,borderStyle:`round`,margin:{top:0,bottom:1}}),t=K(pe,{padding:1,borderColor:`magenta`,borderStyle:`round`,margin:{top:0,bottom:1}});console.log(e),console.log(t)}if(l.length===0){console.log(K(t?V.yellow(`No tasks with status '${t}' found`):V.yellow(`No tasks found`),{padding:1,borderColor:`yellow`,borderStyle:`round`}));return}let me=r?10:7,he=100-me-15-12-20-10,ge=de-10,I=Math.floor(me/100*ge),_e=Math.floor(15/100*ge),ve=Math.floor(12/100*ge),ye=Math.floor(20/100*ge),be=Math.floor(10/100*ge),xe=Math.floor(he/100*ge),Se=new J({head:[V.cyan.bold(`ID`),V.cyan.bold(`Title`),V.cyan.bold(`Status`),V.cyan.bold(`Priority`),V.cyan.bold(`Dependencies`),V.cyan.bold(`Complexity`)],colWidths:[I,xe,_e,ve,ye,be],style:{head:[],border:[],compact:!1},wordWrap:!0,wrapOnWordBoundary:!0});l.forEach(e=>{let t=`None`;t=e.dependencies&&e.dependencies.length>0?qc(e.dependencies,a.tasks,!0,c):Q.muted(`None`);let n=e.title.replace(/\n/g,` `),i={high:V.red,medium:V.yellow,low:Q.muted}[e.priority||`medium`]||V.reset,o=Kc(e.status,!0);Se.push([e.id.toString(),R(n,xe-3),o,i(R(e.priority||`medium`,ve-2)),t,e.complexityScore?Yc(e.complexityScore):Q.muted(`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?V.green.bold(`${e.id}.${t}`):i?Q.active.bold(`${e.id}.${t}`):V.red.bold(`${e.id}.${t}`)}}let n=a.tasks.find(e=>e.id===t);if(n){E(n,c);let e=n.status===`done`||n.status===`completed`,r=n.status===`in-progress`;return e?V.green.bold(`${t}`):r?Q.active.bold(`${t}`):V.red.bold(`${t}`)}return V.cyan(t.toString())}).join(`, `)||Q.muted(`None`)),Se.push([`${e.id}.${t.id}`,V.dim(`└─ ${R(t.title,xe-5)}`),Kc(t.status,!0),V.dim(`-`),n,t.complexityScore?Q.muted(`${t.complexityScore}`):Q.muted(`N/A`)])})});try{console.log(Se.toString())}catch(e){L(`error`,`Error rendering table: ${e.message}`),console.log(V.yellow(`
1046
+ Falling back to simple task list due to terminal width constraints:`)),l.forEach(e=>{console.log(`${V.cyan(e.id)}: ${V.reset(e.title)} - ${Kc(e.status)}`)})}t&&(console.log(V.yellow(`\nFiltered by status: ${t}`)),console.log(V.yellow(`Showing ${l.length} of ${u} tasks`)));let Ce={high:V.red.bold,medium:V.yellow,low:Q.muted};if(N){let e=``,t=a.tasks.find(e=>String(e.id)===String(N.id));t&&t.subtasks&&t.subtasks.length>0&&(e=`\n\n${V.bold(`Subtasks:`)}\n`,e+=t.subtasks.map(e=>{E(e,c);let n=e.status||`pending`,r={done:V.green,completed:V.green,pending:V.yellow,"in-progress":V.cyan,deferred:Q.muted,blocked:V.red,cancelled:Q.muted}[n.toLowerCase()]||V.reset;return`${V.cyan(`${t.id}.${e.id}`)} [${r(n)}] ${e.title}`}).join(`
1047
+ `));let n=Xt(N.id,N.status,!!t?.subtasks?.length).slice(0,2).map(e=>`${V.cyan(`Next step:`)} ${V.yellow(e.command)} ${Q.muted(e.description)}`).join(`
1048
+ `);console.log(K(Q.heading(`Next task: #${N.id} - ${N.title}`)+`
1055
1049
 
1056
- ${H.reset(`Priority:`)} ${Se[N.priority||`medium`](N.priority||`medium`)} ${H.reset(`Status:`)} ${Fc(N.status,!0)}\n${H.reset(`Dependencies:`)} ${N.dependencies&&N.dependencies.length>0?Ic(N.dependencies,a.tasks,!0,c):Q.muted(`None`)}\n\n${H.reset(`Description:`)} ${Na(N,a.tasks)}`+e+`
1050
+ ${V.reset(`Priority:`)} ${Ce[N.priority||`medium`](N.priority||`medium`)} ${V.reset(`Status:`)} ${Kc(N.status,!0)}\n${V.reset(`Dependencies:`)} ${N.dependencies&&N.dependencies.length>0?qc(N.dependencies,a.tasks,!0,c):Q.muted(`None`)}\n\n${V.reset(`Description:`)} ${Wa(N,a.tasks)}`+e+`
1057
1051
 
1058
- ${n}\n${H.cyan(`View details:`)} ${H.yellow(`taskgraph show ${N.id}`)}`,{padding:{left:2,right:2,top:1,bottom:1},borderColor:wc,borderStyle:`round`,margin:{top:1,bottom:1},title:`Next task`,titleAlignment:`center`,width:de-4,fullscreen:!1}))}else console.log(q(Q.heading(`No eligible next task found`)+`
1052
+ ${n}\n${V.cyan(`View details:`)} ${V.yellow(`taskgraph show ${N.id}`)}`,{padding:{left:2,right:2,top:1,bottom:1},borderColor:Fc,borderStyle:`round`,margin:{top:1,bottom:1},title:`Next task`,titleAlignment:`center`,width:de-4,fullscreen:!1}))}else console.log(K(Q.heading(`No eligible next task found`)+`
1059
1053
 
1060
- All pending tasks have dependencies that are not yet completed, or all tasks are done.`,{padding:1,borderColor:wc,borderStyle:`round`,margin:{top:1,bottom:1},title:`Next task`,titleAlignment:`center`,width:de-4}));console.log(q(H.bold(`Suggested Next Steps:`)+`
1054
+ All pending tasks have dependencies that are not yet completed, or all tasks are done.`,{padding:1,borderColor:Fc,borderStyle:`round`,margin:{top:1,bottom:1},title:`Next task`,titleAlignment:`center`,width:de-4}));console.log(K(V.bold(`Suggested Next Steps:`)+`
1061
1055
 
1062
- ${H.cyan(`1.`)} Run ${H.yellow(`taskgraph next`)} to see what to work on next\n${H.cyan(`2.`)} Run ${H.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks\n${H.cyan(`3.`)} Run ${H.yellow(`taskgraph set-status --id=<id> --status=done`)} to mark a task as complete`,{padding:1,...ke,borderStyle:`round`,margin:{top:1}}))}catch(e){if(L(`error`,`Error listing tasks: ${e.message}`),i===`json`)throw{code:`TASK_LIST_ERROR`,message:e.message,details:e.stack};console.error(H.red(`Error: ${e.message}`)),process.exit(1)}}function Na(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.`}return t.find(t=>String(t.id)===String(e.id))?.description||`No description available.`}function Pa(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:ee,withSubtasks:D,nextItem:O}=n,k=``,A=(e,t=20)=>{let n=Math.round(e/100*t),r=t-n;return`█`.repeat(n)+`░`.repeat(r)},te=A(a,20),j=A(m,20);k+=`| Project Dashboard | |
1056
+ ${V.cyan(`1.`)} Run ${V.yellow(`taskgraph next`)} to see what to work on next\n${V.cyan(`2.`)} Run ${V.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks\n${V.cyan(`3.`)} Run ${V.yellow(`taskgraph set-status --id=<id> --status=done`)} to mark a task as complete`,{padding:1,...Ae,borderStyle:`round`,margin:{top:1}}))}catch(e){if(L(`error`,`Error listing tasks: ${e.message}`),i===`json`)throw{code:`TASK_LIST_ERROR`,message:e.message,details:e.stack};console.error(V.red(`Error: ${e.message}`)),process.exit(1)}}function Wa(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.`}return t.find(t=>String(t.id)===String(e.id))?.description||`No description available.`}function Ga(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:ee,withSubtasks:D,nextItem:O}=n,k=``,A=(e,t=20)=>{let n=Math.round(e/100*t),r=t-n;return`█`.repeat(n)+`░`.repeat(r)},te=A(a,20),j=A(m,20);k+=`| Project Dashboard | |
1063
1057
  `,k+=`| :- |:-|
1064
1058
  `,k+=`| Task Progress | ${te} ${Math.round(a)}% |\n`,k+=`| Done | ${o} |\n`,k+=`| In Progress | ${s} |\n`,k+=`| Pending | ${c} |\n`,k+=`| Deferred | ${u} |\n`,k+=`| Cancelled | ${d} |\n`,k+=`|-|-|
1065
1059
  `,k+=`| Subtask Progress | ${j} ${Math.round(m)}% |\n`,k+=`| Completed | ${p} |\n`,k+=`| In Progress | ${h} |\n`,k+=`| Pending | ${g} |\n`,k+=`
1066
1060
 
1067
1061
  `,k+=`| ID | Title | Status | Priority | Dependencies | Complexity |
1068
1062
  `,k+=`| :- | :- | :- | :- | :- | :- |
1069
- `;let M=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`}},ne=(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=M(t.status),i=t.priority||`medium`,a=ne(t.dependencies,e.tasks),o=t.complexityScore?`● ${t.complexityScore}`:`N/A`;k+=`| ${t.id} | ${n} | ${r} | ${i} | ${a} | ${o} |\n`,D&&t.subtasks&&t.subtasks.length>0&&t.subtasks.forEach(n=>{let r=`${n.title}`,i=M(n.status),a=ne(n.dependencies,e.tasks),o=n.complexityScore?n.complexityScore.toString():`N/A`;k+=`| ${t.id}.${n.id} | ${r} | ${i} | - | ${a} | ${o} |\n`})}),k}function Fa(e){if(!e||e.length===0)return``;if(e.length>5){let t=e.slice(0,5).join(`,`),n=e.length-5;return` → ${H.cyan(t)}${Q.muted(`... (+`+n+` more)`)}`}return` → ${H.cyan(e.join(`,`))}`}function Ia(e,t=50){let n=e.status||`pending`,r=e.priority||`medium`,i=z(e.title||`Untitled`,t),a=Fc(n,!0),o={high:H.red,medium:H.yellow,low:Q.muted}[r]||H.reset,s=Fa(e.dependencies);return`${H.cyan(e.id)} ${a} ${H.reset(i)} ${o(`(`+r+`)`)}${s}`}function La(e,t,n=47){let r=e.status||`pending`,i=z(e.title||`Untitled`,n),a=Fc(r,!0),o=Fa(e.dependencies);return` ${H.cyan(t+`.`+e.id)} ${a} ${H.dim(i)}${o}`}function Ra(e,t){if(e.length===0){console.log(`No tasks found`);return}let n=[];e.forEach(e=>{n.push(Ia(e)),t&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(t=>{n.push(La(t,e.id))})}),console.log(n.join(`
1070
- `))}function za(e,t,n={}){return pe(e,t,{...n,direction:`forward`,logger:{warn:console.warn}})}var Ba=class extends Error{constructor(e,t,n={}){super(t),this.name=`MoveTaskError`,this.code=e,this.data=n}};const Va={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 Ha(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 Ua(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 Ba(Va.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 Ua(e,s[n],c[n],!1,i);t.push(r)}return{message:`Successfully moved ${s.length} tasks/subtasks`,moves:t}}let l=F(e,a,o);if(l&&l._rawTaggedData&&(l=l._rawTaggedData),!l||!l[o]||!Array.isArray(l[o].tasks))throw new Ba(Va.INVALID_TASKS_FILE,`Invalid tasks file or tag "${o}" not found at ${e}`);let u=l[o].tasks;L(`info`,`Moving task/subtask ${t} to ${n} (tag: ${o})`);let d=t.includes(`.`),f=n.includes(`.`),p;return p=d&&f?Wa(u,t,n):d&&!f?Ga(u,t,n):!d&&f?Ka(u,t,n):qa(u,t,n),l[o].tasks=u,I(e,l,i.projectRoot,o),p}function Wa(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 Ba(Va.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!c)throw new Ba(Va.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 Ba(Va.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 Ja(u,s,l,c,o);return{message:`Moved subtask ${t} to ${n}`,movedItem:u}}function Ga(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 Ba(Va.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!o.subtasks)throw new Ba(Va.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 Ba(Va.SUBTASK_NOT_FOUND,`Source subtask ${t} not found`);let c=o.subtasks[s];if(e.find(e=>e.id===a))throw new Ba(Va.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 Ka(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 Ba(Va.TASK_NOT_FOUND,`Source task with ID ${r} not found`);if(!s)throw new Ba(Va.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 qa(e,t,n){let r=parseInt(t,10),i=parseInt(n,10),a=e.findIndex(e=>e.id===r);if(a===-1)throw new Ba(Va.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 Ba(Va.TASK_ALREADY_EXISTS,`Task with ID ${i} already exists. Use a different destination ID.`);return Ya(e,a,o,i)}function Ja(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 Ya(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),L(`info`,`Moved task ${n.id} to new ID ${r}`),{message:`Moved task ${n.id} to new ID ${r}`,movedItem:a}}function Xa(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 Za(e,t,n,r,i){let{projectRoot:a}=i,o=F(e,a,n);if(o&&o._rawTaggedData&&(o=o._rawTaggedData),!o||!o[n]||!Array.isArray(o[n].tasks))throw new Ba(Va.INVALID_SOURCE_TAG,`Source tag "${n}" not found or invalid`);o[r]||(o[r]={tasks:[]},L(`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=>{dl(e,n,r)}),{rawData:o,sourceTasks:c}}async function Qa(e){let{rawData:t,sourceTasks:n}=e;return{rawData:t,sourceTasks:n,allTasks:Xa(t)}}async function $a(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=za(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=Ha(e);return Number.isFinite(t)&&n.has(t)}),a=[.../* @__PURE__ */ new Set([...r,...i])];return L(`info`,`Moving ${a.length} tasks (including dependencies): ${a.join(`, `)}`),{tasksToMove:a,dependencyResolution:{type:`with-dependencies`,dependentTasks:i}}}let l=ul(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=Ha(e);return Number.isFinite(t)&&n.some(e=>e.id===t)?!1:(Number.isFinite(t)&&r.some(e=>e.id===t),!0)})}),L(`warn`,`Removed ${l.length} cross-tag dependencies`),{tasksToMove:r,dependencyResolution:{type:`ignored-dependencies`,conflicts:l}};throw new Ba(Va.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 eo(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 Ba(Va.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 Ba(Va.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=ro(o,t,n);r[n].tasks.push(c),s.push({id:i,fromTag:t,toTag:n}),L(`info`,`Moved task ${i} from "${t}" to "${n}"`)}return{rawData:r,movedTasks:s}}async function to(e,t,n,r,i,a){let{projectRoot:o}=n,{rawData:s,movedTasks:c}=e;I(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 "taskgraph validate-dependencies" to check for dependency issues.`,`Run "taskgraph fix-dependencies" to automatically repair dangling dependencies.`]),l}async function no(e,t,n,r,i={},a={}){let{rawData:o,sourceTasks:s,allTasks:c}=await Qa(await Za(e,t,n,r,a)),{tasksToMove:l,dependencyResolution:u}=await $a(s,c,i,t,n,r);return await to(await eo(l,n,r,o,a,e),e,a,n,r,u)}function ro(e,t,n){return e.tag=n,e.metadata||={},e.metadata.moveHistory||(e.metadata.moveHistory=[]),e.metadata.moveHistory.push({fromTag:t,toTag:n,timestamp:(/* @__PURE__ */ new Date()).toISOString()}),e}var io=class e extends Error{constructor(t,n){super(t),this.name=`StreamingError`,this.code=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}};const ao={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 oo=class e{static async withTimeout(e,t,n=`Operation`){let r,i=new Promise((e,i)=>{r=setTimeout(()=>{i(new io(`${n} timed out after ${t/1e3} seconds`,ao.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 io&&e.code===ao.STREAM_PROCESSING_FAILED&&e.message.includes(`timed out`)}},so=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 co=G.object({id:G.number(),title:G.string().min(1),description:G.string().min(1),details:G.string(),testStrategy:G.string(),priority:G.enum(Wi),dependencies:G.array(G.number()),status:G.string()}),lo=G.object({tasks:G.array(co),metadata:G.union([G.object({projectName:G.string(),totalTasks:G.number(),sourceFile:G.string(),generatedAt:G.string()}),G.null()]).default(null)});var uo=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||so.seconds(180).milliseconds,this.targetTag=this.tag||ne(this.projectRoot)||`master`,this.isMCP=!!this.mcpLog,this.outputFormat=this.isMCP&&!this.reportProgress?`json`:`text`,this.useStreaming=!1}hasCodebaseAnalysis(){return ee(this.research,this.projectRoot,this.session)}},fo=class{constructor(e,t){this.isMCP=!!e,this.outputFormat=this.isMCP&&!t?`json`:`text`,this.logFn=e||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)}}report(e,t=`info`){this.logFn&&typeof this.logFn[t]==`function`?this.logFn[t](e):!B()&&this.outputFormat===`text`&&L(t,e)}};function po(e){return`${Math.floor(e/60)}m ${Math.floor(e%60).toString().padStart(2,`0`)}s`}const mo={BAR_WIDTH:40,TABLE_COL_WIDTHS:[28,50],DEFAULT_MODEL:`Default`,DEFAULT_TEMPERATURE:.7},ho={HIGH:`high`,MEDIUM:`medium`,LOW:`low`},go={[ho.HIGH]:H.red,[ho.MEDIUM]:H.yellow,[ho.LOW]:V.muted},_o={main:{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0},borderColor:P,borderStyle:`round`},summary:{padding:{top:1,right:1,bottom:1,left:1},borderColor:P,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 vo({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+=` | ${H.cyan.bold(`🔬 Research Mode`)}`),H.bold(`🤖 Parsing PRD and ${s} Tasks`)+`
1071
- `+H.dim(c)+`
1063
+ `;let M=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`}},ne=(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=M(t.status),i=t.priority||`medium`,a=ne(t.dependencies,e.tasks),o=t.complexityScore?`● ${t.complexityScore}`:`N/A`;k+=`| ${t.id} | ${n} | ${r} | ${i} | ${a} | ${o} |\n`,D&&t.subtasks&&t.subtasks.length>0&&t.subtasks.forEach(n=>{let r=`${n.title}`,i=M(n.status),a=ne(n.dependencies,e.tasks),o=n.complexityScore?n.complexityScore.toString():`N/A`;k+=`| ${t.id}.${n.id} | ${r} | ${i} | - | ${a} | ${o} |\n`})}),k}function Ka(e){if(!e||e.length===0)return``;if(e.length>5){let t=e.slice(0,5).join(`,`),n=e.length-5;return` → ${V.cyan(t)}${Q.muted(`... (+`+n+` more)`)}`}return` → ${V.cyan(e.join(`,`))}`}function qa(e,t=50){let n=e.status||`pending`,r=e.priority||`medium`,i=R(e.title||`Untitled`,t),a=Kc(n,!0),o={high:V.red,medium:V.yellow,low:Q.muted}[r]||V.reset,s=Ka(e.dependencies);return`${V.cyan(e.id)} ${a} ${V.reset(i)} ${o(`(`+r+`)`)}${s}`}function Ja(e,t,n=47){let r=e.status||`pending`,i=R(e.title||`Untitled`,n),a=Kc(r,!0),o=Ka(e.dependencies);return` ${V.cyan(t+`.`+e.id)} ${a} ${V.dim(i)}${o}`}function Ya(e,t){if(e.length===0){console.log(`No tasks found`);return}let n=[];e.forEach(e=>{n.push(qa(e)),t&&e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(t=>{n.push(Ja(t,e.id))})}),console.log(n.join(`
1064
+ `))}function Xa(e,t,n={}){return pe(e,t,{...n,direction:`forward`,logger:{warn:console.warn}})}var Za=class extends Error{constructor(e,t,n={}){super(t),this.name=`MoveTaskError`,this.code=e,this.data=n}};const Qa={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 $a(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 eo(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 Za(Qa.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 eo(e,s[n],c[n],!1,i);t.push(r)}return{message:`Successfully moved ${s.length} tasks/subtasks`,moves:t}}let l=F(e,a,o);if(l&&l._rawTaggedData&&(l=l._rawTaggedData),!l||!l[o]||!Array.isArray(l[o].tasks))throw new Za(Qa.INVALID_TASKS_FILE,`Invalid tasks file or tag "${o}" not found at ${e}`);let u=l[o].tasks;L(`info`,`Moving task/subtask ${t} to ${n} (tag: ${o})`);let d=t.includes(`.`),f=n.includes(`.`),p;return p=d&&f?to(u,t,n):d&&!f?no(u,t,n):!d&&f?ro(u,t,n):io(u,t,n),l[o].tasks=u,I(e,l,i.projectRoot,o),p}function to(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 Za(Qa.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!c)throw new Za(Qa.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 Za(Qa.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 ao(u,s,l,c,o);return{message:`Moved subtask ${t} to ${n}`,movedItem:u}}function no(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 Za(Qa.PARENT_TASK_NOT_FOUND,`Source parent task with ID ${r} not found`);if(!o.subtasks)throw new Za(Qa.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 Za(Qa.SUBTASK_NOT_FOUND,`Source subtask ${t} not found`);let c=o.subtasks[s];if(e.find(e=>e.id===a))throw new Za(Qa.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 ro(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 Za(Qa.TASK_NOT_FOUND,`Source task with ID ${r} not found`);if(!s)throw new Za(Qa.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 io(e,t,n){let r=parseInt(t,10),i=parseInt(n,10),a=e.findIndex(e=>e.id===r);if(a===-1)throw new Za(Qa.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 Za(Qa.TASK_ALREADY_EXISTS,`Task with ID ${i} already exists. Use a different destination ID.`);return oo(e,a,o,i)}function ao(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),L(`info`,`Moved task ${n.id} to new ID ${r}`),{message:`Moved task ${n.id} to new ID ${r}`,movedItem:a}}function so(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 co(e,t,n,r,i){let{projectRoot:a}=i,o=F(e,a,n);if(o&&o._rawTaggedData&&(o=o._rawTaggedData),!o||!o[n]||!Array.isArray(o[n].tasks))throw new Za(Qa.INVALID_SOURCE_TAG,`Source tag "${n}" not found or invalid`);o[r]||(o[r]={tasks:[]},L(`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=>{Tl(e,n,r)}),{rawData:o,sourceTasks:c}}async function lo(e){let{rawData:t,sourceTasks:n}=e;return{rawData:t,sourceTasks:n,allTasks:so(t)}}async function uo(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=Xa(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=$a(e);return Number.isFinite(t)&&n.has(t)}),a=[.../* @__PURE__ */ new Set([...r,...i])];return L(`info`,`Moving ${a.length} tasks (including dependencies): ${a.join(`, `)}`),{tasksToMove:a,dependencyResolution:{type:`with-dependencies`,dependentTasks:i}}}let l=wl(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=$a(e);return Number.isFinite(t)&&n.some(e=>e.id===t)?!1:(Number.isFinite(t)&&r.some(e=>e.id===t),!0)})}),L(`warn`,`Removed ${l.length} cross-tag dependencies`),{tasksToMove:r,dependencyResolution:{type:`ignored-dependencies`,conflicts:l}};throw new Za(Qa.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 fo(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 Za(Qa.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 Za(Qa.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}),L(`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;I(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 "taskgraph validate-dependencies" to check for dependency issues.`,`Run "taskgraph fix-dependencies" to automatically repair dangling dependencies.`]),l}async function mo(e,t,n,r,i={},a={}){let{rawData:o,sourceTasks:s,allTasks:c}=await lo(await co(e,t,n,r,a)),{tasksToMove:l,dependencyResolution:u}=await uo(s,c,i,t,n,r);return await po(await fo(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:(/* @__PURE__ */ new Date()).toISOString()}),e}var go=class e extends Error{constructor(t,n){super(t),this.name=`StreamingError`,this.code=n,Error.captureStackTrace&&Error.captureStackTrace(this,e)}};const _o={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 vo=class e{static async withTimeout(e,t,n=`Operation`){let r,i=new Promise((e,i)=>{r=setTimeout(()=>{i(new go(`${n} timed out after ${t/1e3} seconds`,_o.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 go&&e.code===_o.STREAM_PROCESSING_FAILED&&e.message.includes(`timed out`)}},yo=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 bo=W.object({id:W.number(),title:W.string().min(1),description:W.string().min(1),details:W.string(),testStrategy:W.string(),priority:W.enum(ta),dependencies:W.array(W.number()),status:W.string()}),xo=W.object({tasks:W.array(bo),metadata:W.union([W.object({projectName:W.string(),totalTasks:W.number(),sourceFile:W.string(),generatedAt:W.string()}),W.null()]).default(null)});var So=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||yo.seconds(180).milliseconds,this.targetTag=this.tag||ne(this.projectRoot)||`master`,this.isMCP=!!this.mcpLog,this.outputFormat=this.isMCP&&!this.reportProgress?`json`:`text`,this.useStreaming=!1}hasCodebaseAnalysis(){return ee(this.research,this.projectRoot,this.session)}},Co=class{constructor(e,t){this.isMCP=!!e,this.outputFormat=this.isMCP&&!t?`json`:`text`,this.logFn=e||{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)}}report(e,t=`info`){this.logFn&&typeof this.logFn[t]==`function`?this.logFn[t](e):!z()&&this.outputFormat===`text`&&L(t,e)}};function wo(e){return`${Math.floor(e/60)}m ${Math.floor(e%60).toString().padStart(2,`0`)}s`}const To={BAR_WIDTH:40,TABLE_COL_WIDTHS:[28,50],DEFAULT_MODEL:`Default`,DEFAULT_TEMPERATURE:.7},Eo={HIGH:`high`,MEDIUM:`medium`,LOW:`low`},Do={[Eo.HIGH]:V.red,[Eo.MEDIUM]:V.yellow,[Eo.LOW]:B.muted},Oo={main:{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:0},borderColor:P,borderStyle:`round`},summary:{padding:{top:1,right:1,bottom:1,left:1},borderColor:P,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 ko({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+=` | ${V.cyan.bold(`🔬 Research Mode`)}`),V.bold(`🤖 Parsing PRD and ${s} Tasks`)+`
1065
+ `+V.dim(c)+`
1072
1066
 
1073
- `+V.brand(`Input: ${e}`)+`
1074
- `+V.brand(`Output: ${t}`)+`
1075
- `+V.brand(`Tasks to ${a?`Append`:`Generate`}: ${n}`)}function yo(e){console.log(q(e,_o.main))}function bo(e,t){console.log(H.yellow.bold(`📝 Append mode`)+` - Adding to ${e} existing tasks (next ID: ${t})`)}function xo(e){let t=H.red.bold(`⚠️ Force flag enabled`);return e?`${t} - Will overwrite if conflicts occur`:`${t} - Overwriting existing tasks`}function So({prdFilePath:e,outputPath:t,numTasks:n,model:r=mo.DEFAULT_MODEL,temperature:i=mo.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`);yo(vo({prdFilePath:e,outputPath:t,numTasks:n,model:r,temperature:i,append:a,research:o})),(a||s)&&(a&&bo(c.length,l),s&&console.log(xo(a)),console.log())}function Co(e,t){let n={};return Object.values(ho).forEach(r=>{let i=e[r]||0;n[r]={count:i,percentage:t>0?Math.round(i/t*100):0}}),n}function wo(e,t){let n=mo.BAR_WIDTH,r={};if(t===0)return Object.values(ho).forEach(e=>{r[e]=0}),r;let i={};Object.values(ho).forEach(r=>{i[r]=e[r].count/t*n}),Object.values(ho).forEach(e=>{r[e]=Math.floor(i[e])}),Object.values(ho).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(ho).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 To(e){let t=``;t+=go[ho.HIGH](`█`.repeat(e[ho.HIGH])),t+=go[ho.MEDIUM](`█`.repeat(e[ho.MEDIUM])),t+=go[ho.LOW](`█`.repeat(e[ho.LOW]));let n=Object.values(e).reduce((e,t)=>e+t,0);return n<mo.BAR_WIDTH&&(t+=V.muted(`░`.repeat(mo.BAR_WIDTH-n))),t}function Eo(e){let t=[];return Object.entries(ho).forEach(([n,r])=>{let i=e[r],a=go[r],o=n.charAt(0)+n.slice(1).toLowerCase();t.push(`${a.bold(i.count)} ${a(o)} (${i.percentage}%)`)}),[H.cyan(`Priority distribution:`),t.join(` · `)]}function Do(e){let{totalTasks:t,taskPriorities:n={},prdFilePath:r,outputPath:i,elapsedTime:a,usedFallback:o=!1,actionVerb:s=`generated`}=e,c=po(a),l=new Y({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:mo.TABLE_COL_WIDTHS});if(l.push([H.cyan(`Total tasks ${s}:`),H.bold(t)],[H.cyan(`Processing time:`),H.bold(c)]),n&&Object.keys(n).length>0){let e=Co(n,t),r=Eo(e);l.push(r);let i=To(wo(e,t));l.push([H.cyan(`Distribution:`),i])}l.push([H.cyan(`PRD source:`),H.italic(r)],[H.cyan(`Tasks file:`),H.italic(i)]),o&&l.push([H.yellow(`Fallback parsing:`),H.yellow(`✓ Used fallback parsing`)]);let u=[H.bold.underline(`PRD Parsing Complete - Tasks ${s.charAt(0).toUpperCase()+s.slice(1)}`),``,l.toString()].join(`
1076
- `);console.log(q(u,_o.summary)),o&&Oo(),ko()}function Oo(){let e=H.yellow.bold(`⚠️ Fallback Parsing Used`)+`
1067
+ `+B.brand(`Input: ${e}`)+`
1068
+ `+B.brand(`Output: ${t}`)+`
1069
+ `+B.brand(`Tasks to ${a?`Append`:`Generate`}: ${n}`)}function Ao(e){console.log(K(e,Oo.main))}function jo(e,t){console.log(V.yellow.bold(`📝 Append mode`)+` - Adding to ${e} existing tasks (next ID: ${t})`)}function Mo(e){let t=V.red.bold(`⚠️ Force flag enabled`);return e?`${t} - Will overwrite if conflicts occur`:`${t} - Overwriting existing tasks`}function No({prdFilePath:e,outputPath:t,numTasks:n,model:r=To.DEFAULT_MODEL,temperature:i=To.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`);Ao(ko({prdFilePath:e,outputPath:t,numTasks:n,model:r,temperature:i,append:a,research:o})),(a||s)&&(a&&jo(c.length,l),s&&console.log(Mo(a)),console.log())}function Po(e,t){let n={};return Object.values(Eo).forEach(r=>{let i=e[r]||0;n[r]={count:i,percentage:t>0?Math.round(i/t*100):0}}),n}function Fo(e,t){let n=To.BAR_WIDTH,r={};if(t===0)return Object.values(Eo).forEach(e=>{r[e]=0}),r;let i={};Object.values(Eo).forEach(r=>{i[r]=e[r].count/t*n}),Object.values(Eo).forEach(e=>{r[e]=Math.floor(i[e])}),Object.values(Eo).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(Eo).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 Io(e){let t=``;t+=Do[Eo.HIGH](`█`.repeat(e[Eo.HIGH])),t+=Do[Eo.MEDIUM](`█`.repeat(e[Eo.MEDIUM])),t+=Do[Eo.LOW](`█`.repeat(e[Eo.LOW]));let n=Object.values(e).reduce((e,t)=>e+t,0);return n<To.BAR_WIDTH&&(t+=B.muted(`░`.repeat(To.BAR_WIDTH-n))),t}function Lo(e){let t=[];return Object.entries(Eo).forEach(([n,r])=>{let i=e[r],a=Do[r],o=n.charAt(0)+n.slice(1).toLowerCase();t.push(`${a.bold(i.count)} ${a(o)} (${i.percentage}%)`)}),[V.cyan(`Priority distribution:`),t.join(` · `)]}function Ro(e){let{totalTasks:t,taskPriorities:n={},prdFilePath:r,outputPath:i,elapsedTime:a,usedFallback:o=!1,actionVerb:s=`generated`}=e,c=wo(a),l=new J({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:To.TABLE_COL_WIDTHS});if(l.push([V.cyan(`Total tasks ${s}:`),V.bold(t)],[V.cyan(`Processing time:`),V.bold(c)]),n&&Object.keys(n).length>0){let e=Po(n,t),r=Lo(e);l.push(r);let i=Io(Fo(e,t));l.push([V.cyan(`Distribution:`),i])}l.push([V.cyan(`PRD source:`),V.italic(r)],[V.cyan(`Tasks file:`),V.italic(i)]),o&&l.push([V.yellow(`Fallback parsing:`),V.yellow(`✓ Used fallback parsing`)]);let u=[V.bold.underline(`PRD Parsing Complete - Tasks ${s.charAt(0).toUpperCase()+s.slice(1)}`),``,l.toString()].join(`
1070
+ `);console.log(K(u,Oo.summary)),o&&zo(),Bo()}function zo(){let e=V.yellow.bold(`⚠️ Fallback Parsing Used`)+`
1077
1071
 
1078
- `+V.text(`The system used fallback parsing to complete task generation.`)+`
1079
- `+V.text(`This typically happens when streaming JSON parsing is incomplete.`)+`
1080
- `+V.text(`Your tasks were successfully generated, but consider:`)+`
1081
- `+V.text(`• Reviewing task completeness`)+`
1082
- `+V.text(`• Checking for any missing details`)+`
1072
+ `+B.text(`The system used fallback parsing to complete task generation.`)+`
1073
+ `+B.text(`This typically happens when streaming JSON parsing is incomplete.`)+`
1074
+ `+B.text(`Your tasks were successfully generated, but consider:`)+`
1075
+ `+B.text(`• Reviewing task completeness`)+`
1076
+ `+B.text(`• Checking for any missing details`)+`
1083
1077
 
1084
- `+V.text(`This is normal and usually doesn't indicate any issues.`);console.log(q(e,_o.warning))}function ko(){let e=V.text.bold(`Next Steps:`)+`
1078
+ `+B.text(`This is normal and usually doesn't indicate any issues.`);console.log(K(e,Oo.warning))}function Bo(){let e=B.text.bold(`Next Steps:`)+`
1085
1079
 
1086
- ${H.cyan(`1.`)} Run ${H.yellow(`taskgraph list`)} to view all tasks\n${H.cyan(`2.`)} Run ${H.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks\n${H.cyan(`3.`)} Run ${H.yellow(`taskgraph analyze-complexity`)} to analyze task complexity`;console.log(q(e,_o.nextSteps))}function Ao(e){if(typeof e!=`string`)return null;let t=e.indexOf(`{`);if(t<0)return null;let n=0,r=!1,i=!1;for(let a=t;a<e.length;a++){let o=e[a];if(r)i?i=!1:o===`\\`?i=!0:o===`"`&&(r=!1);else if(o===`"`)r=!0;else if(o===`{`)n++;else if(o===`}`&&(n--,n===0))return e.slice(t,a+1)}return null}function jo(e){let t=Ao(e);if(!t)return null;try{let e=lo.safeParse(JSON.parse(t));return e.success?e.data:null}catch{return null}}function Mo(e){return Math.ceil(e.length/4)}function No(e){let t=K.readFileSync(e,`utf8`);if(!t)throw Error(`Input file ${e} is empty or could not be read.`);return t}function Po(e,t){let n=[],r=1;if(!K.existsSync(e))return{existingTasks:n,nextId:r};try{let i=K.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 Fo({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.`,`debug`);else if(n)a.report(`Append mode enabled. Found ${e.length} existing tasks in tag '${t}'.`,`info`);else{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(H.red(n)),process.exit(1)}a.report(`Force flag enabled. Overwriting existing tasks in tag '${t}'.`,`debug`)}}function Io(e,t,n,r){Lo(e,t);let i=t,a=/* @__PURE__ */ 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&&(k(n,t)||o.some(e=>e.id===t)))}),o}function Lo(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 Ro(e,t,n,r){let i=W.dirname(e);K.existsSync(i)||K.mkdirSync(i,{recursive:!0});let a={};if(K.existsSync(e))try{let t=K.readFileSync(e,`utf8`);a=JSON.parse(t)}catch{a={}}a[n]={tasks:t,metadata:{created:a[n]?.metadata?.created||(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:`Tasks for ${n} context`}},O(a[n],{description:`Tasks for ${n} context`}),K.writeFileSync(e,JSON.stringify(a,null,2)),r.report(`Successfully saved ${t.length} tasks to ${e}`,`debug`)}async function zo(e,t,n){let r=_a(),i=ue(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 Bo({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 Vo({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`})();Do({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 oo.withSoftTimeout(o.mainResult.usage,1e3,void 0),Gc(o.telemetryData,`cli`))}function Ho({processedTasks:e,research:t,finalTasks:n,tasksPath:r,aiServiceResponse:i}){let a=W.relative(process.cwd(),r)||r,o=n.length>e.length?` · ${n.length} tasks in total`:``,s=t?` · research-backed`:``;console.log(V.muted(`Saved to ${a}${o}${s}`));let c=(e,t)=>`${H.yellow(e.padEnd(28))}${V.muted(t)}`;console.log(q(V.text.bold(`Next steps`)+`
1080
+ ${V.cyan(`1.`)} Run ${V.yellow(`taskgraph list`)} to view all tasks\n${V.cyan(`2.`)} Run ${V.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks\n${V.cyan(`3.`)} Run ${V.yellow(`taskgraph analyze-complexity`)} to analyze task complexity`;console.log(K(e,Oo.nextSteps))}function Vo(e){if(typeof e!=`string`)return null;let t=e.indexOf(`{`);if(t<0)return null;let n=0,r=!1,i=!1;for(let a=t;a<e.length;a++){let o=e[a];if(r)i?i=!1:o===`\\`?i=!0:o===`"`&&(r=!1);else if(o===`"`)r=!0;else if(o===`{`)n++;else if(o===`}`&&(n--,n===0))return e.slice(t,a+1)}return null}function Ho(e){let t=Vo(e);if(!t)return null;try{let e=xo.safeParse(JSON.parse(t));return e.success?e.data:null}catch{return null}}function Uo(e){return Math.ceil(e.length/4)}function Wo(e){let t=G.readFileSync(e,`utf8`);if(!t)throw Error(`Input file ${e} is empty or could not be read.`);return t}function Go(e,t){let n=[],r=1;if(!G.existsSync(e))return{existingTasks:n,nextId:r};try{let i=G.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 Ko({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.`,`debug`);else if(n)a.report(`Append mode enabled. Found ${e.length} existing tasks in tag '${t}'.`,`info`);else{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(V.red(n)),process.exit(1)}a.report(`Force flag enabled. Overwriting existing tasks in tag '${t}'.`,`debug`)}}function qo(e,t,n,r){Jo(e,t);let i=t,a=/* @__PURE__ */ 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&&(k(n,t)||o.some(e=>e.id===t)))}),o}function Jo(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 Yo(e,t,n,r){let i=U.dirname(e);G.existsSync(i)||G.mkdirSync(i,{recursive:!0});let a={};if(G.existsSync(e))try{let t=G.readFileSync(e,`utf8`);a=JSON.parse(t)}catch{a={}}a[n]={tasks:t,metadata:{created:a[n]?.metadata?.created||(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:`Tasks for ${n} context`}},O(a[n],{description:`Tasks for ${n} context`}),G.writeFileSync(e,JSON.stringify(a,null,2)),r.report(`Successfully saved ${t.length} tasks to ${e}`,`debug`)}async function Xo(e,t,n){let r=Oa(),i=ue(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 Zo({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 Qo({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`})();Ro({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 vo.withSoftTimeout(o.mainResult.usage,1e3,void 0),nl(o.telemetryData,`cli`))}function $o({processedTasks:e,research:t,finalTasks:n,tasksPath:r,aiServiceResponse:i}){let a=U.relative(process.cwd(),r)||r,o=n.length>e.length?` · ${n.length} tasks in total`:``,s=t?` · research-backed`:``;console.log(B.muted(`Saved to ${a}${o}${s}`));let c=(e,t)=>`${V.yellow(e.padEnd(28))}${B.muted(t)}`;console.log(K(B.text.bold(`Next steps`)+`
1087
1081
 
1088
1082
  `+[c(`taskgraph next`,`the task to start with`),c(`taskgraph graph`,`how the tasks depend on each other`),c(`taskgraph expand --id=<id>`,`split a task into subtasks`)].join(`
1089
- `),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&Gc(i.telemetryData,`cli`)}async function Uo(e,t,n,r=1){let i=new fo(e.mcpLog,e.reportProgress),a=Mo(t.systemPrompt+t.userPrompt),o=e.outputFormat===`text`&&!e.isMCP&&!e.reportProgress;if(i.report(`Calling AI service to generate tasks from PRD${e.research?` with research-backed analysis`:``}...`,`debug`),o){let o=null;try{return o=jc({prdName:W.basename(e.prdPath||`PRD`),numTasks:n,startId:r}),{...await Wo(e,t,o),estimatedInputTokens:a}}catch(t){if(Qe.isInstance(t)&&!qo(e))throw o?.fail(`Couldn't generate tasks`),t;o?.stop(),i.report(`Streaming task generation failed (${t.message}); retrying in one request`,`debug`),o?.printedCount&&console.log(`${H.yellow(`⚠`)} Live output stopped. Asking Claude again in one request; the final tasks may differ from the ones above.`)}}return{...await Ko(e,t,o),estimatedInputTokens:a}}async function Wo(e,n,r){let i=await t({...Jo(e,n)}),a=i?.mainResult,o=a?.partialObjectStream;if(!o)throw Error(`AI service did not return a stream`);for await(let e of o)r?.update(e);let s;try{s=await a.object}catch(e){if(s=jo(e?.text),!s)throw e}if(!s||!Array.isArray(s.tasks))throw Error(`AI service returned unexpected data structure.`);return r?.succeed(s),i.telemetryData=await Go(a,i,e),{parsedTasks:s.tasks,aiServiceResponse:i}}async function Go(e,t,n){let r=t.telemetryData;if(!r?.userId)return r;try{let a=await e.usage;return await i({userId:r.userId,commandName:`parse-prd`,providerName:t.providerName,modelId:t.modelId,inputTokens:a?.inputTokens??a?.promptTokens??0,outputTokens:a?.outputTokens??a?.completionTokens??0,cachedInputTokens:a?.inputTokenDetails?.cacheReadTokens??0,outputType:n.isMCP?`mcp`:`cli`})||r}catch{return r}}async function Ko(e,t,n){let r=n?Ac(`Parsing PRD and generating tasks…`):null;try{let n=await a(Jo(e,t)),i=Yo(n?.mainResult);if(!i)throw Error(`AI service returned unexpected data structure after validation.`);return r&&Mc(r,`${i.tasks.length} tasks generated`),{parsedTasks:i.tasks,aiServiceResponse:n}}catch(e){throw r&&Nc(r,`Couldn't generate tasks`),e}}function qo(e){let t=e.projectRoot,n=e.research?Ee(t):xe(t);return[xe(t),Te(t),Ee(t)].filter(Boolean).some(e=>e!==n)}function Jo(e,t){return{role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:lo,objectName:`tasks_data`,systemPrompt:t.systemPrompt,prompt:t.userPrompt,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}}function Yo(e){if(e&&typeof e==`object`){if(Array.isArray(e.tasks))return e;if(Array.isArray(e.object?.tasks))return e.object}return null}const[Xo,Zo,Qo]=Wi,$o=/* @__PURE__ */ new Map;var es=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]||V.muted}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:`🟢`}},ns=new es(`priority`,[Xo,Zo,Qo],{[Xo]:H.red,[Zo]:H.yellow,[Qo]:V.muted});function rs(e,t){let n=ts.cli.filled,r=ts.cli.empty,i=``;for(let a=0;a<3;a++)i+=a<e?t(n):V.text(r);return i}function is(e,t){return 3-t.indexOf(e)}function as(e,t){if($o.has(e))return $o.get(e);let n=t();return $o.set(e,n),n}function os(){return as(`mcp-priority-all`,()=>({[Xo]:ts.mcp.high,[Zo]:ts.mcp.medium,[Qo]:ts.mcp.low}))}function ss(){return as(`cli-priority-all`,()=>{let e={};return ns.levels.forEach(t=>{let n=is(t,ns.levels),r=ns.getColor(t);e[t]=rs(n,r)}),e})}function cs(){return as(`statusbar-priority-all`,()=>{let e={};return ns.levels.forEach((t,n)=>{let r=n===0?ts.statusBar.high:n===1?ts.statusBar.medium:ts.statusBar.low,i=ns.getColor(t);e[t]=i(r)}),e})}function ls(){return{[Xo]:ns.colors[Xo],[Zo]:ns.colors[Zo],[Qo]:ns.colors[Qo]}}function us(e=!1){return e?os():ss()}function ds(e,t=!1){let n=us(t);return n[e]||n[Zo]}new es(`complexity`,[`high`,`medium`,`low`],{high:H.red,medium:H.yellow,low:H.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const fs={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},ps={shades_classic:qe.Presets.shades_classic,shades_grey:qe.Presets.shades_grey,rect:qe.Presets.rect,legacy:qe.Presets.legacy},ms=new class{constructor(e={},t=ps.shades_classic){this.defaultOptions={...fs,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new qe.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new qe.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function hs(e={}){return ms.createMultiBar(e)}var gs=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=hs(),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(){}},_s=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 vs(e,t,n){new _s(e).createHeader(t,n)}function ys(e,t,n){new _s(e).createRow(t,n)}function bs(e,t){new _s(e).createBorder(t)}ss();const xs=cs();ls();const Ss={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 Cs=class{constructor(e=Ss.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}},ws=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():Ss.DEFAULT_PRIORITY;return Ss.VALID_PRIORITIES.includes(t)?t:Ss.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Ts=class{static formatTitle(e,t){return e?e.length>Ss.MAX_TITLE_LENGTH?e.substring(0,Ss.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return ds(e,!1).padEnd(Ss.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(Ss.TASK_ID_PAD_START,` `).padEnd(Ss.TASK_ID_PAD_END,` `)}},Es=class extends gs{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new ws,this.debouncer=new Cs,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${xs.high} {high} ${xs.medium} {medium} ${xs.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,vs(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=Ts.formatTitle(t,e),i=Ts.formatPriority(n),a=Ts.formatTaskId(e);ys(this.multibar,` ${a} | ${i} | {title}`,{title:r}),bs(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 Ds(e={}){return new Es(e)}async function Os(e,t,n){let r=ks(e,t,n);await js(e,n,r.estimatedInputTokens);let i=await Ms(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await Ns(e,n),s=await Ps(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(As(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-D-zQeZm3.js`),{getUserId:n}=await import(`./config-manager-Cf_jF2P3.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 Ws(s,i,r.estimatedInputTokens,a)}function ks(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new fo(e.mcpLog,e.reportProgress),estimatedInputTokens:Mo(r+i),defaultPriority:ue(e.projectRoot)||`medium`}}function As(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function js(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 Ms(e,n,r){let{systemPrompt:i,userPrompt:a}=n;return await oo.withTimeout(t({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:lo,systemPrompt:i,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),r,`Streaming operation`)}async function Ns(e,t){let n=us(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Ds({numUnits:t,unitName:`task`,append:e.append});let n=e.research?Ee():xe(),i=ge(e.research?`research`:`main`);So({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 Ps(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:lo},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 Fs(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 zs(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await Us(d,c)}}async function Fs(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=Mo(JSON.stringify(r))),await Is(r,t,n)}async function Is(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await Ls(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 Ls(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await Bo({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 Rs(a+1,r,i)}}async function Rs(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 zs(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 Bs(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function Bs(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?Vs(e,a,o):await Hs(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function Vs(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 Hs(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await Bo({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 Us(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 a({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||Mo(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||Mo(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function Ws(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 Gs(e,t,n){let r=new fo(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let i=Po(e.tasksPath,e.targetTag),a=e.append?i.existingTasks:[],o=e.append?i.nextId:1;Fo({existingTasks:i.existingTasks,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let s=await t(e,await zo(e,No(e.prdPath),o),e.numTasks,o),c=ue(e.projectRoot)||`medium`,l=Io(s.parsedTasks,o,a,c),u=e.append?[...a,...l]:l;return Ro(e.tasksPath,u,e.targetTag,r),await Ks(e,s,l,u,o,n),{success:!0,tasksPath:e.tasksPath,telemetryData:s.aiServiceResponse?.telemetryData,tagInfo:s.aiServiceResponse?.tagInfo}}catch(t){throw e.isMCP?r.report(`Error parsing PRD: ${t.message}`,`error`):R(e.projectRoot)&&console.error(t),t}}async function Ks(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 Vo({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||Ho({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function qs(e,t,n,r={}){return Gs(new uo(e,t,n,r),Os,!0)}async function Js(e,t,n,r={}){return Gs(new uo(e,t,n,r),Uo,!1)}async function Ys(e,t,n,r={}){let i=new uo(e,t,n,r);if(i.useStreaming)try{return await qs(e,t,n,r)}catch(a){if(a instanceof io||a.code===ao.NOT_ASYNC_ITERABLE||a.code===ao.STREAM_PROCESSING_FAILED||a.code===ao.STREAM_NOT_ITERABLE||oo.isTimeoutError(a)){let o=new fo(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(H.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 Js(e,t,n,r)}throw a}return await Js(e,t,n,r)}async function Xs(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{L(`info`,`Removing subtask ${t}...`);let r=F(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){L(`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),L(`info`,`Created new task ${e} from subtask ${t}`)}else L(`info`,`Subtask ${t} deleted`);return I(e,r,a,o),p}catch(e){throw L(`error`,`Error removing subtask: ${e.message}`),e}}function Zs(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)}async function Qs(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=F(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(Zs(s,e))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,L(`warn`,n)}else{let t=`Task with ID ${e} in tag '${i}' not found or already removed.`;a.errors.push(t),a.success=!1}if(a.removedTasks.length>0){let t=new Set(o.map(e=>typeof e==`string`&&e.includes(`.`)?e:parseInt(e,10)));n[i].tasks=s;for(let e in 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))})});I(e,n,r,i);for(let t of c){let n=W.join(W.dirname(e),`task_${t.toString().padStart(3,`0`)}.txt`);if(Pe.existsSync(n))try{Pe.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,L(`warn`,t)}}}else a.errors.length===0&&a.messages.push(`No tasks found matching the provided IDs.`);let l=a.messages.join(`
1083
+ `),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&nl(i.telemetryData,`cli`)}async function es(e,t,n,r=1){let i=new Co(e.mcpLog,e.reportProgress),a=Uo(t.systemPrompt+t.userPrompt),o=e.outputFormat===`text`&&!e.isMCP&&!e.reportProgress;if(i.report(`Calling AI service to generate tasks from PRD${e.research?` with research-backed analysis`:``}...`,`debug`),o){let o=null;try{return o=Hc({prdName:U.basename(e.prdPath||`PRD`),numTasks:n,startId:r}),{...await ts(e,t,o),estimatedInputTokens:a}}catch(t){if($e.isInstance(t)&&!is(e))throw o?.fail(`Couldn't generate tasks`),t;o?.stop(),i.report(`Streaming task generation failed (${t.message}); retrying in one request`,`debug`),o?.printedCount&&console.log(`${V.yellow(`⚠`)} Live output stopped. Asking Claude again in one request; the final tasks may differ from the ones above.`)}}return{...await rs(e,t,o),estimatedInputTokens:a}}async function ts(e,n,r){let i=await t({...as(e,n)}),a=i?.mainResult,o=a?.partialObjectStream;if(!o)throw Error(`AI service did not return a stream`);for await(let e of o)r?.update(e);let s;try{s=await a.object}catch(e){if(s=Ho(e?.text),!s)throw e}if(!s||!Array.isArray(s.tasks))throw Error(`AI service returned unexpected data structure.`);return r?.succeed(s),i.telemetryData=await ns(a,i,e),{parsedTasks:s.tasks,aiServiceResponse:i}}async function ns(e,t,n){let r=t.telemetryData;if(!r?.userId)return r;try{let a=await e.usage;return await i({userId:r.userId,commandName:`parse-prd`,providerName:t.providerName,modelId:t.modelId,inputTokens:a?.inputTokens??a?.promptTokens??0,outputTokens:a?.outputTokens??a?.completionTokens??0,cachedInputTokens:a?.inputTokenDetails?.cacheReadTokens??0,outputType:n.isMCP?`mcp`:`cli`})||r}catch{return r}}async function rs(e,t,n){let r=n?Vc(`Parsing PRD and generating tasks…`):null;try{let n=await a(as(e,t)),i=os(n?.mainResult);if(!i)throw Error(`AI service returned unexpected data structure after validation.`);return r&&Uc(r,`${i.tasks.length} tasks generated`),{parsedTasks:i.tasks,aiServiceResponse:n}}catch(e){throw r&&Wc(r,`Couldn't generate tasks`),e}}function is(e){let t=e.projectRoot,n=e.research?De(t):Se(t);return[Se(t),Ee(t),De(t)].filter(Boolean).some(e=>e!==n)}function as(e,t){return{role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:xo,objectName:`tasks_data`,systemPrompt:t.systemPrompt,prompt:t.userPrompt,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}}function os(e){if(e&&typeof e==`object`){if(Array.isArray(e.tasks))return e;if(Array.isArray(e.object?.tasks))return e.object}return null}const[ss,cs,ls]=ta,us=/* @__PURE__ */ new Map;var ds=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.muted}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 fs={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},ps=new ds(`priority`,[ss,cs,ls],{[ss]:V.red,[cs]:V.yellow,[ls]:B.muted});function ms(e,t){let n=fs.cli.filled,r=fs.cli.empty,i=``;for(let a=0;a<3;a++)i+=a<e?t(n):B.text(r);return i}function hs(e,t){return 3-t.indexOf(e)}function gs(e,t){if(us.has(e))return us.get(e);let n=t();return us.set(e,n),n}function _s(){return gs(`mcp-priority-all`,()=>({[ss]:fs.mcp.high,[cs]:fs.mcp.medium,[ls]:fs.mcp.low}))}function vs(){return gs(`cli-priority-all`,()=>{let e={};return ps.levels.forEach(t=>{let n=hs(t,ps.levels),r=ps.getColor(t);e[t]=ms(n,r)}),e})}function ys(){return gs(`statusbar-priority-all`,()=>{let e={};return ps.levels.forEach((t,n)=>{let r=n===0?fs.statusBar.high:n===1?fs.statusBar.medium:fs.statusBar.low,i=ps.getColor(t);e[t]=i(r)}),e})}function bs(){return{[ss]:ps.colors[ss],[cs]:ps.colors[cs],[ls]:ps.colors[ls]}}function xs(e=!1){return e?_s():vs()}function Ss(e,t=!1){let n=xs(t);return n[e]||n[cs]}new ds(`complexity`,[`high`,`medium`,`low`],{high:V.red,medium:V.yellow,low:V.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const Cs={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},ws={shades_classic:Je.Presets.shades_classic,shades_grey:Je.Presets.shades_grey,rect:Je.Presets.rect,legacy:Je.Presets.legacy},Ts=new class{constructor(e={},t=ws.shades_classic){this.defaultOptions={...Cs,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new Je.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new Je.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function Es(e={}){return Ts.createMultiBar(e)}var Ds=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=Es(),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(){}},Os=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 ks(e,t,n){new Os(e).createHeader(t,n)}function As(e,t,n){new Os(e).createRow(t,n)}function js(e,t){new Os(e).createBorder(t)}vs();const Ms=ys();bs();const Ns={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 Ps=class{constructor(e=Ns.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}},Fs=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():Ns.DEFAULT_PRIORITY;return Ns.VALID_PRIORITIES.includes(t)?t:Ns.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Is=class{static formatTitle(e,t){return e?e.length>Ns.MAX_TITLE_LENGTH?e.substring(0,Ns.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return Ss(e,!1).padEnd(Ns.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(Ns.TASK_ID_PAD_START,` `).padEnd(Ns.TASK_ID_PAD_END,` `)}},Ls=class extends Ds{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new Fs,this.debouncer=new Ps,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${Ms.high} {high} ${Ms.medium} {medium} ${Ms.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,ks(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=Is.formatTitle(t,e),i=Is.formatPriority(n),a=Is.formatTaskId(e);As(this.multibar,` ${a} | ${i} | {title}`,{title:r}),js(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 Rs(e={}){return new Ls(e)}async function zs(e,t,n){let r=Bs(e,t,n);await Hs(e,n,r.estimatedInputTokens);let i=await Us(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await Ws(e,n),s=await Gs(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(Vs(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-BuoDs5zU.js`),{getUserId:n}=await import(`./config-manager-CkwCWw53.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 tc(s,i,r.estimatedInputTokens,a)}function Bs(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new Co(e.mcpLog,e.reportProgress),estimatedInputTokens:Uo(r+i),defaultPriority:ue(e.projectRoot)||`medium`}}function Vs(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function Hs(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 Us(e,n,r){let{systemPrompt:i,userPrompt:a}=n;return await vo.withTimeout(t({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:xo,systemPrompt:i,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),r,`Streaming operation`)}async function Ws(e,t){let n=xs(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Rs({numUnits:t,unitName:`task`,append:e.append});let n=e.research?De():Se(),i=ge(e.research?`research`:`main`);No({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 Gs(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:xo},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 Ks(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 Xs(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await ec(d,c)}}async function Ks(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=Uo(JSON.stringify(r))),await qs(r,t,n)}async function qs(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await Js(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 Js(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await Zo({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 Ys(a+1,r,i)}}async function Ys(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 Xs(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 Zs(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function Zs(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?Qs(e,a,o):await $s(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function Qs(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 $s(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await Zo({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 ec(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 a({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||Uo(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||Uo(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function tc(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 nc(e,t,n){let r=new Co(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let i=Go(e.tasksPath,e.targetTag),a=e.append?i.existingTasks:[],o=e.append?i.nextId:1;Ko({existingTasks:i.existingTasks,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let s=await t(e,await Xo(e,Wo(e.prdPath),o),e.numTasks,o),c=ue(e.projectRoot)||`medium`,l=qo(s.parsedTasks,o,a,c),u=e.append?[...a,...l]:l;return Yo(e.tasksPath,u,e.targetTag,r),await rc(e,s,l,u,o,n),{success:!0,tasksPath:e.tasksPath,telemetryData:s.aiServiceResponse?.telemetryData,tagInfo:s.aiServiceResponse?.tagInfo}}catch(t){throw e.isMCP?r.report(`Error parsing PRD: ${t.message}`,`error`):be(e.projectRoot)&&console.error(t),t}}async function rc(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 Qo({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||$o({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function ic(e,t,n,r={}){return nc(new So(e,t,n,r),zs,!0)}async function ac(e,t,n,r={}){return nc(new So(e,t,n,r),es,!1)}async function oc(e,t,n,r={}){let i=new So(e,t,n,r);if(i.useStreaming)try{return await ic(e,t,n,r)}catch(a){if(a instanceof go||a.code===_o.NOT_ASYNC_ITERABLE||a.code===_o.STREAM_PROCESSING_FAILED||a.code===_o.STREAM_NOT_ITERABLE||vo.isTimeoutError(a)){let o=new Co(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(V.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 ac(e,t,n,r)}throw a}return await ac(e,t,n,r)}async function sc(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{L(`info`,`Removing subtask ${t}...`);let r=F(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){L(`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),L(`info`,`Created new task ${e} from subtask ${t}`)}else L(`info`,`Subtask ${t} deleted`);return I(e,r,a,o),p}catch(e){throw L(`debug`,`Error removing subtask: ${e.message}`),e}}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)}async function lc(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=F(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(cc(s,e))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,L(`warn`,n)}else{let t=`Task with ID ${e} in tag '${i}' not found or already removed.`;a.errors.push(t),a.success=!1}if(a.removedTasks.length>0){let t=new Set(o.map(e=>typeof e==`string`&&e.includes(`.`)?e:parseInt(e,10)));n[i].tasks=s;for(let e in 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))})});I(e,n,r,i);for(let t of c){let n=U.join(U.dirname(e),`task_${t.toString().padStart(3,`0`)}.txt`);if(Fe.existsSync(n))try{Fe.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,L(`warn`,t)}}}else a.errors.length===0&&a.messages.push(`No tasks found matching the provided IDs.`);let l=a.messages.join(`
1090
1084
  `),u=a.errors.join(`
1091
- `);return{success:a.success,message:l||`No tasks were removed.`,error:u||null,removedTasks:a.removedTasks}}catch(e){return L(`error`,`Error removing tasks: ${e.message}`),{success:!1,message:``,error:`Operation failed: ${e.message}`,removedTasks:[]}}}Be.use(Ve({code:e=>e.split(`
1092
- `).map(e=>` `+H.cyan(e)).join(`
1093
- `),blockquote:V.muted.italic,html:V.muted,heading:V.text.bold,hr:V.muted,listitem:V.text,paragraph:V.text,strong:V.text.bold,em:V.text.italic,codespan:H.cyan,del:H.dim.strikethrough,link:V.brand,href:V.brand.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:100})),Be.setOptions({breaks:!0,gfm:!0});async function $s(t,r={},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}=r,{session:h,mcpLog:g,commandName:_=`research`,outputType:v=`cli`}=i,y=!!g,b=f||Se();if(!b)throw Error(`Could not determine project root directory`);let x=y?g:{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)};a===`text`&&console.log(q(H.cyan.bold(`🔍 AI Research Query`),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));try{let f=new ya(b,p),g=[...s],S=[];try{let e=W.join(b,`.taskgraph`,`tasks`,`tasks.json`),n=await F(e,b,p);if(n&&n.tasks&&n.tasks.length>0){let e=new Ta(oe(n.tasks),`research`),r=e.findRelevantTasks(t,{maxResults:8,includeRecent:!0,includeCategoryMatches:!0});S=e.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(V.muted(`Provided tasks: `)+H.cyan(e.join(`, `))),i.length>0){let e=i.map(e=>parseInt(e)).sort((e,t)=>e-t).map(e=>e.toString());console.log(V.muted(`+ Auto-discovered related tasks: `)+H.cyan(e.join(`, `)))}}else console.log(V.muted(`Auto-discovered relevant tasks: `)+H.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=_a(),ee={query:t,gatheredContext:w||``,detailLevel:d,projectInfo:{root:b,taskCount:g.length,fileCount:c.length}},{systemPrompt:D,userPrompt:O}=await E.loadPrompt(`research`,ee),k=f.countTokens(D),A=f.countTokens(O),te=k+A;a===`text`&&ec(T,k,A),a!==`text`&&x.info(`Calling AI service with research role, context size: ${T.total} tokens (${w.length} characters)`);let j,M=``;try{if(a===`text`){console.log(H.cyan(`
1085
+ `);return{success:a.success,message:l||`No tasks were removed.`,error:u||null,removedTasks:a.removedTasks}}catch(e){return L(`error`,`Error removing tasks: ${e.message}`),{success:!1,message:``,error:`Operation failed: ${e.message}`,removedTasks:[]}}}Ve.use(He({code:e=>e.split(`
1086
+ `).map(e=>` `+V.cyan(e)).join(`
1087
+ `),blockquote:B.muted.italic,html:B.muted,heading:B.text.bold,hr:B.muted,listitem:B.text,paragraph:B.text,strong:B.text.bold,em:B.text.italic,codespan:V.cyan,del:V.dim.strikethrough,link:B.brand,href:B.brand.underline,showSectionPrefix:!1,unescape:!0,emoji:!1,tab:4,width:100})),Ve.setOptions({breaks:!0,gfm:!0});async function uc(t,r={},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}=r,{session:h,mcpLog:g,commandName:_=`research`,outputType:v=`cli`}=i,y=!!g,b=f||Ce();if(!b)throw Error(`Could not determine project root directory`);let x=y?g:{info:(...e)=>L(`info`,...e),warn:(...e)=>L(`warn`,...e),error:(...e)=>L(`error`,...e),debug:(...e)=>L(`debug`,...e),success:(...e)=>L(`success`,...e)};a===`text`&&console.log(K(V.cyan.bold(`🔍 AI Research Query`),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));try{let f=new Aa(b,p),g=[...s],S=[];try{let e=U.join(b,`.taskgraph`,`tasks`,`tasks.json`),n=await F(e,b,p);if(n&&n.tasks&&n.tasks.length>0){let e=new Ia(oe(n.tasks),`research`),r=e.findRelevantTasks(t,{maxResults:8,includeRecent:!0,includeCategoryMatches:!0});S=e.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.muted(`Provided tasks: `)+V.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.muted(`+ Auto-discovered related tasks: `)+V.cyan(e.join(`, `)))}}else console.log(B.muted(`Auto-discovered relevant tasks: `)+V.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=Oa(),ee={query:t,gatheredContext:w||``,detailLevel:d,projectInfo:{root:b,taskCount:g.length,fileCount:c.length}},{systemPrompt:D,userPrompt:O}=await E.loadPrompt(`research`,ee),k=f.countTokens(D),A=f.countTokens(O),te=k+A;a===`text`&&dc(T,k,A),a!==`text`&&x.info(`Calling AI service with research role, context size: ${T.total} tokens (${w.length} characters)`);let j,M=``;try{if(a===`text`){console.log(V.cyan(`
1094
1088
  🔍 Researching with AI...
1095
- `)),j=await e({role:`research`,session:h,projectRoot:b,systemPrompt:D,prompt:O,commandName:_,outputType:v,experimental_transform:$e({delayInMs:15,chunking:`word`})});for await(let e of j.mainResult.textStream){M+=e;let t=``;for(let n=0;n<e.length;n++)e.slice(n).startsWith(`<think>`)?n+=6:e.slice(n).startsWith(`</think>`)?n+=7:t+=e[n];t&&process.stdout.write(V.muted(t))}if(console.log(`
1096
- `),j.mainResult.usage){let e=await j.mainResult.usage,t=e.promptTokens||e.inputTokens||0,n=e.completionTokens||e.outputTokens||0,r=e.totalTokens||t+n;j.telemetryData={...j.telemetryData,inputTokens:t,outputTokens:n,totalTokens:r}}let n=process.stdout.columns||80,r=Math.min(n-4,120),i=q(H.green.bold(`Research Results`)+`
1097
-
1098
- `+V.muted(`Query: `)+V.text(t)+`
1099
- `+V.muted(`Detail Level: `)+H.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=M.replace(/<think>[\s\S]*?<\/think>/g,``).trim(),o=await Be.parse(a),s=q(o.trim(),{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`white`,width:r});console.log(s)}else j=await n({role:`research`,session:h,projectRoot:b,systemPrompt:D,prompt:O,commandName:_,outputType:v}),M=j.mainResult}catch(e){throw e}let ne=j.telemetryData,re=j.tagInfo,ie={interactiveSaveOccurred:!1};if(a===`text`&&(ne&&Gc(ne,`cli`),o&&!y&&(ie=await tc(r,i,a,b,x,t,M))),m&&y){let e=await rc([{question:t,answer:M,type:`initial`,timestamp:(/* @__PURE__ */ new Date()).toISOString()}],b,i,x);return{query:t,result:M,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:k,userPromptTokens:A,totalInputTokens:te,detailLevel:d,telemetryData:ne,tagInfo:re,savedFilePath:e,interactiveSaveOccurred:!1}}return x.success(`Research query completed successfully`),{query:t,result:M,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:k,userPromptTokens:A,totalInputTokens:te,detailLevel:d,telemetryData:ne,tagInfo:re,interactiveSaveOccurred:ie?.interactiveSaveOccurred||!1}}catch(e){throw x.error(`Research query failed: ${e.message}`),a===`text`&&console.error(H.red(`\n❌ Research failed: ${e.message}`)),e}}function ec(e,t,n){let r=[];if(e.customContext&&r.push(H.cyan(`Custom: `)+H.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` ${V.muted(e.id)} ${V.text(t)} ${H.yellow(e.tokens.toLocaleString())} tokens`}).join(`
1100
- `);r.push(H.cyan(`Tasks: `)+H.yellow(t.toLocaleString())+V.muted(` (${e.tasks.length} items)`)+`
1101
- `+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` ${V.muted(t)} ${H.yellow(e.tokens.toLocaleString())} tokens ${V.muted(`(${e.sizeKB}KB)`)}`}).join(`
1102
- `);r.push(H.cyan(`Files: `)+H.yellow(t.toLocaleString())+V.muted(` (${e.files.length} files)`)+`
1103
- `+n)}e.projectTree&&r.push(H.cyan(`Project Tree: `)+H.yellow(e.projectTree.tokens.toLocaleString())+V.muted(` (${e.projectTree.fileCount} files, ${e.projectTree.dirCount} dirs)`));let i=t+n,a=[` ${V.muted(`System:`)} ${H.yellow(t.toLocaleString())} tokens`,` ${V.muted(`User:`)} ${H.yellow(n.toLocaleString())} tokens`].join(`
1104
- `);if(r.push(H.cyan(`Prompts: `)+H.yellow(i.toLocaleString())+V.muted(` (generated)`)+`
1089
+ `)),j=await e({role:`research`,session:h,projectRoot:b,systemPrompt:D,prompt:O,commandName:_,outputType:v,experimental_transform:et({delayInMs:15,chunking:`word`})});for await(let e of j.mainResult.textStream){M+=e;let t=``;for(let n=0;n<e.length;n++)e.slice(n).startsWith(`<think>`)?n+=6:e.slice(n).startsWith(`</think>`)?n+=7:t+=e[n];t&&process.stdout.write(B.muted(t))}if(console.log(`
1090
+ `),j.mainResult.usage){let e=await j.mainResult.usage,t=e.promptTokens||e.inputTokens||0,n=e.completionTokens||e.outputTokens||0,r=e.totalTokens||t+n;j.telemetryData={...j.telemetryData,inputTokens:t,outputTokens:n,totalTokens:r}}let n=process.stdout.columns||80,r=Math.min(n-4,120),i=K(V.green.bold(`Research Results`)+`
1091
+
1092
+ `+B.muted(`Query: `)+B.text(t)+`
1093
+ `+B.muted(`Detail Level: `)+V.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=M.replace(/<think>[\s\S]*?<\/think>/g,``).trim(),o=await Ve.parse(a),s=K(o.trim(),{padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`white`,width:r});console.log(s)}else j=await n({role:`research`,session:h,projectRoot:b,systemPrompt:D,prompt:O,commandName:_,outputType:v}),M=j.mainResult}catch(e){throw e}let ne=j.telemetryData,re=j.tagInfo,ie={interactiveSaveOccurred:!1};if(a===`text`&&(ne&&nl(ne,`cli`),o&&!y&&(ie=await fc(r,i,a,b,x,t,M))),m&&y){let e=await mc([{question:t,answer:M,type:`initial`,timestamp:(/* @__PURE__ */ new Date()).toISOString()}],b,i,x);return{query:t,result:M,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:k,userPromptTokens:A,totalInputTokens:te,detailLevel:d,telemetryData:ne,tagInfo:re,savedFilePath:e,interactiveSaveOccurred:!1}}return x.success(`Research query completed successfully`),{query:t,result:M,contextSize:w.length,contextTokens:T.total,tokenBreakdown:T,systemPromptTokens:k,userPromptTokens:A,totalInputTokens:te,detailLevel:d,telemetryData:ne,tagInfo:re,interactiveSaveOccurred:ie?.interactiveSaveOccurred||!1}}catch(e){throw x.error(`Research query failed: ${e.message}`),a===`text`&&console.error(V.red(`\n❌ Research failed: ${e.message}`)),e}}function dc(e,t,n){let r=[];if(e.customContext&&r.push(V.cyan(`Custom: `)+V.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.muted(e.id)} ${B.text(t)} ${V.yellow(e.tokens.toLocaleString())} tokens`}).join(`
1094
+ `);r.push(V.cyan(`Tasks: `)+V.yellow(t.toLocaleString())+B.muted(` (${e.tasks.length} items)`)+`
1095
+ `+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.muted(t)} ${V.yellow(e.tokens.toLocaleString())} tokens ${B.muted(`(${e.sizeKB}KB)`)}`}).join(`
1096
+ `);r.push(V.cyan(`Files: `)+V.yellow(t.toLocaleString())+B.muted(` (${e.files.length} files)`)+`
1097
+ `+n)}e.projectTree&&r.push(V.cyan(`Project Tree: `)+V.yellow(e.projectTree.tokens.toLocaleString())+B.muted(` (${e.projectTree.fileCount} files, ${e.projectTree.dirCount} dirs)`));let i=t+n,a=[` ${B.muted(`System:`)} ${V.yellow(t.toLocaleString())} tokens`,` ${B.muted(`User:`)} ${V.yellow(n.toLocaleString())} tokens`].join(`
1098
+ `);if(r.push(V.cyan(`Prompts: `)+V.yellow(i.toLocaleString())+B.muted(` (generated)`)+`
1105
1099
  `+a),r.length>0){let e=r.join(`
1106
1100
 
1107
- `),t=q(e,{title:V.brand.bold(`Context Analysis`),titleAlignment:`left`,padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:P});console.log(t)}}async function tc(e,t,n,r,i,a,o){let s=!1;try{let{readJSON:c}=await import(`./utils-9HKKyDq7.js`);(await import(`./update-task-by-id-BomuFTXv.js`)).default;let{updateSubtaskById:l}=await import(`./update-subtask-by-id-Dncsj7jm.js`),u=[{question:a,answer:o,type:`initial`,timestamp:(/* @__PURE__ */ new Date()).toISOString()}];for(;;){let{action:a}=await Je.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 rc(u,r,t,i);else if(a===`save`)await nc(u,r,t,i)&&(s=!0);else if(a===`followup`){let{followUpQuery:r}=await Je.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(`
1108
- `+V.muted(`─`.repeat(60))+`
1109
- `);let i=oc(u),a={...e,taskIds:[],customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},o=await $s(r.trim(),a,t,n,!1);u.push({question:r.trim(),answer:o.result,type:`followup`,timestamp:(/* @__PURE__ */ new Date()).toISOString()})}}}catch(e){i.debug(`Follow-up questions not available: ${e.message}`)}return{interactiveSaveOccurred:s}}async function nc(e,t,n,r){try{let{readJSON:r}=await import(`./utils-9HKKyDq7.js`),i=(await import(`./update-task-by-id-BomuFTXv.js`)).default,{updateSubtaskById:a}=await import(`./update-subtask-by-id-Dncsj7jm.js`),{taskId:o}=await Je.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=ac(e),l=s.includes(`.`),u=W.join(t,`.taskgraph`,`tasks`,`tasks.json`);if(!K.existsSync(u)){console.log(H.red(`❌ Tasks file not found. Please run taskgraph init first.`));return}let d=r(u,t,n.tag);if(!d||!d.tasks){console.log(H.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(H.red(`❌ Parent task ${e} not found.`));return}if(!r.subtasks||!r.subtasks.find(e=>e.id===t)){console.log(H.red(`❌ Subtask ${s} not found.`));return}console.log(V.brand(`💾 Saving research conversation to subtask...`)),await a(u,s,c,!1,n,`text`),console.log(H.green(`✅ Research conversation saved to subtask ${s}`))}else{let e=parseInt(s,10);if(!d.tasks.find(t=>t.id===e)){console.log(H.red(`❌ Task ${s} not found.`));return}console.log(V.brand(`💾 Saving research conversation to task...`)),await i(u,e,c,!1,n,`text`,!0),console.log(H.green(`✅ Research conversation saved to task ${s}`))}return!0}catch(e){return console.log(H.red(`❌ Error saving conversation: ${e.message}`)),r.error(`Error saving conversation: ${e.message}`),!1}}async function rc(e,t,n,r){try{let n=W.join(t,`.taskgraph`,`docs`,`research`);K.existsSync(n)||K.mkdirSync(n,{recursive:!0});let i=e[0]?.question||`research-query`,a=`${(/* @__PURE__ */ 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=W.join(n,a),s=ic(e,i);K.writeFileSync(o,s,`utf8`);let c=W.relative(t,o);return console.log(H.green(`✅ Research saved to: ${H.cyan(c)}`)),r.success(`Research conversation saved to ${c}`),o}catch(e){throw console.log(H.red(`❌ Error saving research file: ${e.message}`)),r.error(`Error saving research file: ${e.message}`),e}}function ic(e,t){let n=(/* @__PURE__ */ new Date()).toISOString(),r=`---
1101
+ `),t=K(e,{title:B.brand.bold(`Context Analysis`),titleAlignment:`left`,padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:P});console.log(t)}}async function fc(e,t,n,r,i,a,o){let s=!1;try{let{readJSON:c}=await import(`./utils-CvXyXTNj.js`);(await import(`./update-task-by-id-C1xnfWPp.js`)).default;let{updateSubtaskById:l}=await import(`./update-subtask-by-id-Dlk8IQru.js`),u=[{question:a,answer:o,type:`initial`,timestamp:(/* @__PURE__ */ new Date()).toISOString()}];for(;;){let{action:a}=await Ye.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 mc(u,r,t,i);else if(a===`save`)await pc(u,r,t,i)&&(s=!0);else if(a===`followup`){let{followUpQuery:r}=await Ye.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(`
1102
+ `+B.muted(`─`.repeat(60))+`
1103
+ `);let i=_c(u),a={...e,taskIds:[],customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},o=await uc(r.trim(),a,t,n,!1);u.push({question:r.trim(),answer:o.result,type:`followup`,timestamp:(/* @__PURE__ */ new Date()).toISOString()})}}}catch(e){i.debug(`Follow-up questions not available: ${e.message}`)}return{interactiveSaveOccurred:s}}async function pc(e,t,n,r){try{let{readJSON:r}=await import(`./utils-CvXyXTNj.js`),i=(await import(`./update-task-by-id-C1xnfWPp.js`)).default,{updateSubtaskById:a}=await import(`./update-subtask-by-id-Dlk8IQru.js`),{taskId:o}=await Ye.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=gc(e),l=s.includes(`.`),u=U.join(t,`.taskgraph`,`tasks`,`tasks.json`);if(!G.existsSync(u)){console.log(V.red(`❌ Tasks file not found. Please run taskgraph init first.`));return}let d=r(u,t,n.tag);if(!d||!d.tasks){console.log(V.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(V.red(`❌ Parent task ${e} not found.`));return}if(!r.subtasks||!r.subtasks.find(e=>e.id===t)){console.log(V.red(`❌ Subtask ${s} not found.`));return}console.log(B.brand(`💾 Saving research conversation to subtask...`)),await a(u,s,c,!1,n,`text`),console.log(V.green(`✅ Research conversation saved to subtask ${s}`))}else{let e=parseInt(s,10);if(!d.tasks.find(t=>t.id===e)){console.log(V.red(`❌ Task ${s} not found.`));return}console.log(B.brand(`💾 Saving research conversation to task...`)),await i(u,e,c,!1,n,`text`,!0),console.log(V.green(`✅ Research conversation saved to task ${s}`))}return!0}catch(e){return console.log(V.red(`❌ Error saving conversation: ${e.message}`)),r.error(`Error saving conversation: ${e.message}`),!1}}async function mc(e,t,n,r){try{let n=U.join(t,`.taskgraph`,`docs`,`research`);G.existsSync(n)||G.mkdirSync(n,{recursive:!0});let i=e[0]?.question||`research-query`,a=`${(/* @__PURE__ */ 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=U.join(n,a),s=hc(e,i);G.writeFileSync(o,s,`utf8`);let c=U.relative(t,o);return console.log(V.green(`✅ Research saved to: ${V.cyan(c)}`)),r.success(`Research conversation saved to ${c}`),o}catch(e){throw console.log(V.red(`❌ Error saving research file: ${e.message}`)),r.error(`Error saving research file: ${e.message}`),e}}function hc(e,t){let n=(/* @__PURE__ */ new Date()).toISOString(),r=`---
1110
1104
  title: Research Session
1111
1105
  query: "${t}"
1112
1106
  date: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}
@@ -1119,10 +1113,10 @@ exchanges: ${e.length}
1119
1113
 
1120
1114
  `;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+=`---
1121
1115
 
1122
- `)}),r+=`\n---\n\n*Generated by TaskGraph Research Command* \n*Timestamp: ${n}*\n`,r}function ac(e){(/* @__PURE__ */ new Date()).toISOString();let t=`## Research Session - ${(/* @__PURE__ */ new Date()).toLocaleDateString()} ${(/* @__PURE__ */ 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+=`---
1116
+ `)}),r+=`\n---\n\n*Generated by TaskGraph Research Command* \n*Timestamp: ${n}*\n`,r}function gc(e){(/* @__PURE__ */ new Date()).toISOString();let t=`## Research Session - ${(/* @__PURE__ */ new Date()).toLocaleDateString()} ${(/* @__PURE__ */ 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+=`---
1123
1117
 
1124
- `)}),t}function oc(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(`
1125
- `)}const sc=[`light`,`regular`,`heavy`],cc=[`done`,`in-progress`,`review`,`cancelled`,`deferred`,`blocked`],lc=[`pending`];function uc(e){return sc.includes(e)}async function dc(e,t,n){let{projectRoot:r,tag:i,session:a}=n;try{let n={tasks:[e],metadata:{analyzedAt:(/* @__PURE__ */ new Date()).toISOString()}},o=te(null,{projectRoot:r,tag:i},null);if(!o)return L(`warn`,`No complexity report found - cannot re-analyze complexity`),null;await Ea({file:t,output:o,id:e.id.toString(),projectRoot:r,tag:i,_filteredTasksData:n,_originalTaskCount:1},{session:a});let s=we(o);if(s){let t=se(s,e.id);if(t)return L(`info`,`Re-analyzed task ${e.id} complexity: ${t.complexityScore}/10`),t.complexityScore}return L(`warn`,`Could not find updated complexity analysis for task ${e.id}`),null}catch(e){return L(`error`,`Failed to re-analyze task complexity: ${e.message}`),null}}function fc(e,t){let{projectRoot:n,tag:r}=t;try{let t=te(null,{projectRoot:n,tag:r},null);if(!t)return null;let i=we(t);if(!i)return null;let a=se(i,e);return a?a.complexityScore:null}catch(e){return L(`debug`,`Could not read current complexity score: ${e.message}`),null}}async function pc(e,t,n,r,i=`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=>cc.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(i===`light`){let e=Math.max(5,p+Math.ceil(m*1.1));f=Math.ceil(e*(.8+.4*h))}else if(i===`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(i===`light`){let t=Math.max(3,p+Math.ceil(m*.8));f=Math.ceil(t*e)}else if(i===`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))}}L(`debug`,`Complexity-aware subtask calculation${g}: ${m} pending -> target ${f} total`),L(`debug`,`Complexity-aware calculation${g}: ${m} pending -> ${f} total subtasks (${i} ${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:
1118
+ `)}),t}function _c(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(`
1119
+ `)}const vc=[`light`,`regular`,`heavy`],yc=[`done`,`in-progress`,`review`,`cancelled`,`deferred`,`blocked`],bc=[`pending`];function xc(e){return vc.includes(e)}async function Sc(e,t,n){let{projectRoot:r,tag:i,session:a}=n;try{let n={tasks:[e],metadata:{analyzedAt:(/* @__PURE__ */ new Date()).toISOString()}},o=te(null,{projectRoot:r,tag:i},null);if(!o)return L(`warn`,`No complexity report found - cannot re-analyze complexity`),null;await La({file:t,output:o,id:e.id.toString(),projectRoot:r,tag:i,_filteredTasksData:n,_originalTaskCount:1},{session:a});let s=Te(o);if(s){let t=se(s,e.id);if(t)return L(`info`,`Re-analyzed task ${e.id} complexity: ${t.complexityScore}/10`),t.complexityScore}return L(`warn`,`Could not find updated complexity analysis for task ${e.id}`),null}catch(e){return L(`error`,`Failed to re-analyze task complexity: ${e.message}`),null}}function Cc(e,t){let{projectRoot:n,tag:r}=t;try{let t=te(null,{projectRoot:n,tag:r},null);if(!t)return null;let i=Te(t);if(!i)return null;let a=se(i,e);return a?a.complexityScore:null}catch(e){return L(`debug`,`Could not read current complexity score: ${e.message}`),null}}async function wc(e,t,n,r,i=`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=>yc.includes(e.status)),d=e.subtasks.filter(e=>bc.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(i===`light`){let e=Math.max(5,p+Math.ceil(m*1.1));f=Math.ceil(e*(.8+.4*h))}else if(i===`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(i===`light`){let t=Math.max(3,p+Math.ceil(m*.8));f=Math.ceil(t*e)}else if(i===`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))}}L(`debug`,`Complexity-aware subtask calculation${g}: ${m} pending -> target ${f} total`),L(`debug`,`Complexity-aware calculation${g}: ${m} pending -> ${f} total subtasks (${i} ${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:
1126
1120
 
1127
1121
  **Task Title**: ${e.title}
1128
1122
  **Task Description**: ${e.description}
@@ -1169,7 +1163,7 @@ IMPORTANT:
1169
1163
  - The 'id' field must be a NUMBER, not a string!
1170
1164
  - Dependencies must be strings, not numbers!
1171
1165
 
1172
- Ensure the JSON is valid and properly formatted.`,s=G.object({subtasks:G.array(G.object({id:G.int().positive(),title:G.string().min(5),description:G.string().min(10),dependencies:G.array(G.string()),details:G.string().min(20),status:G.string(),testStrategy:G.string()}))}),c=(await a({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||[];mc(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=/* @__PURE__ */ 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 L(`warn`,`Failed to regenerate subtasks for task ${e.id}: ${t.message}`),{updatedTask:e,regenerated:!1,preserved:u.length,generated:0,error:t.message}}}function mc(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 hc(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.
1166
+ Ensure the JSON is valid and properly formatted.`,s=W.object({subtasks:W.array(W.object({id:W.int().positive(),title:W.string().min(5),description:W.string().min(10),dependencies:W.array(W.string()),details:W.string().min(20),status:W.string(),testStrategy:W.string()}))}),c=(await a({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||[];Tc(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=/* @__PURE__ */ 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 L(`warn`,`Failed to regenerate subtasks for task ${e.id}: ${t.message}`),{updatedTask:e,regenerated:!1,preserved:u.length,generated:0,error:t.message}}}function Tc(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 Ec(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.
1173
1167
 
1174
1168
  CURRENT TASK:
1175
1169
  Title: ${e.title}
@@ -1198,95 +1192,92 @@ Return a JSON object with the updated task containing these fields:
1198
1192
  - testStrategy: Updated test strategy
1199
1193
  - priority: Task priority ('low', 'medium', or 'high')
1200
1194
 
1201
- Ensure the JSON is valid and properly formatted.`,o}async function gc(e,t,n,r,i){let o=hc(e,t,n,r),s=G.object({title:G.string().min(1).describe(`Updated task title reflecting scope adjustment`),description:G.string().min(1).describe(`Updated task description with adjusted scope`),details:G.string().min(1).describe(`Updated implementation details with adjusted complexity`),testStrategy:G.string().min(1).describe(`Updated testing approach for the adjusted scope`),priority:G.enum([`low`,`medium`,`high`]).describe(`Task priority level`)}),c=await a({role:i.research?`research`:`main`,session:i.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:i.commandName||`scope-${t}`,outputType:i.outputType||`cli`}),l=c.mainResult,u={...l,priority:l.priority||e.priority||`medium`};return{updatedTask:{...e,...u},telemetryData:c.telemetryData}}async function _c(e,t,n=`regular`,r=null,i={},a=`text`){if(!uc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${sc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=F(e,o,s),l=c?.tasks||[];for(let e of t)if(!Zs(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=k(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&L(`info`,`Scoping up task ${f}: ${t.title}`);let p=fc(f,i);p&&a===`text`&&L(`info`,`Original complexity: ${p}/10`);let m=await gc(t,`up`,n,r,i),h=await pc(m.updatedTask,e,i,`up`,n,p);a===`text`&&h.regenerated&&L(`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{I(e,c,o,s);let t=await dc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;L(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&L(`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 I(e,c,o,s),a===`text`&&L(`info`,`Successfully scoped up ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function vc(e,t,n=`regular`,r=null,i={},a=`text`){if(!uc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${sc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=F(e,o,s),l=c?.tasks||[];for(let e of t)if(!Zs(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=k(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&L(`info`,`Scoping down task ${f}: ${t.title}`);let p=fc(f,i);p&&a===`text`&&L(`info`,`Original complexity: ${p}/10`);let m=await gc(t,`down`,n,r,i),h=await pc(m.updatedTask,e,i,`down`,n,p);a===`text`&&h.regenerated&&L(`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{I(e,c,o,s);let t=await dc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;L(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&L(`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 I(e,c,o,s),a===`text`&&L(`info`,`Successfully scoped down ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function yc(e,t,n,r,i=!0){if(!Vi(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,L(`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(H.yellow(`All subtasks of parent task ${e} are now marked as done.`)),console.log(H.yellow(`Consider updating the parent task status with: taskgraph 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,L(`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&&(L(`info`,`Also marking ${e.length} subtasks as '${n}'`),e.forEach(e=>{e.status=n}))}}}async function bc(e,t,n,r={}){let{projectRoot:i,tag:a}=r;try{if(!Vi(n))throw Error(`Error: Invalid status value: ${n}. Use one of: ${Bi.join(`, `)}`);let o=!!r?.mcpLog;o||console.log(q(V.text.bold(`Updating Task Status to: ${n}`),{padding:1,borderColor:P,borderStyle:`round`})),L(`info`,`Reading tasks from ${e}...`);let s=F(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 yc(e,t,n,c,!o),u.push({id:t,oldStatus:r,newStatus:n})}if(s[a].tasks=c.tasks,O(s[a],{description:`Tasks for ${a} context`}),I(e,s,i,a),L(`info`,`Validating dependencies after status update...`),rl(c.tasks),!o)for(let e of u){let{id:t,oldStatus:n,newStatus:r}=e;console.log(q(V.text.bold(`Successfully updated task ${t} status:`)+`
1202
- From: ${H.yellow(n)}\nTo: ${H.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(L(`error`,`Error setting task status: ${e.message}`),!r?.mcpLog)console.error(H.red(`Error: ${e.message}`)),R(r?.session)&&console.error(e),process.exit(1);else throw e}}async function xc(e,t,r,i=!1,a={},o=a.mcpLog?`json`:`text`){let{session:s,mcpLog:c,projectRoot:l,tag:u,metadata:d}=a,f=c||L,p=!!c,m=(e,...t)=>{p?typeof f[e]==`function`?f[e](...t):f.info(...t):B()||f(e,...t)},h=null;try{if(m(`info`,`Updating subtask ${t} with prompt: "${r}"`),!t||typeof t!=`string`)throw Error(`Subtask ID cannot be empty.`);if((!r||typeof r!=`string`||r.trim()===``)&&!d)throw Error(`Prompt cannot be empty unless metadata is provided. Please provide context for the subtask update or metadata to merge.`);let a=l||Se();if(!a)throw Error(`Could not determine project root directory`);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(!K.existsSync(e))throw Error(`Tasks file not found at path: ${e}`);let c=F(e,a,u);if(!c||!c.tasks)throw Error(`No valid tasks found in ${e}. The file may be corrupted or have an invalid format.`);let[f,g]=t.split(`.`),_=parseInt(f,10),v=parseInt(g,10);if(Number.isNaN(_)||_<=0||Number.isNaN(v)||v<=0)throw Error(`Invalid subtask ID format: ${t}. Both parent ID and subtask ID must be positive integers.`);let y=c.tasks.find(e=>e.id===_);if(!y)throw Error(`Parent task with ID ${_} not found. Please verify the task ID and try again.`);if(!y.subtasks||!Array.isArray(y.subtasks))throw Error(`Parent task ${_} has no subtasks.`);let b=y.subtasks.findIndex(e=>e.id===v);if(b===-1)throw Error(`Subtask with ID ${t} not found. Please verify the subtask ID and try again.`);let x=y.subtasks[b];if(d&&(!r||r.trim()===``))return m(`info`,`Metadata-only update for subtask ${t}`),x.metadata={...x.metadata||{},...d},y.subtasks[b]=x,I(e,c,a,u),m(`success`,`Successfully updated metadata for subtask ${t}`),{updatedSubtask:x,telemetryData:null,tagInfo:{tag:u}};let S=``;try{let e=new ya(a,u),n=new Ta(oe(c.tasks),`update-subtask`),i=`${y.title} ${x.title} ${r}`,o=n.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=n.getTaskIds(o),l=[.../* @__PURE__ */ new Set([t.toString(),...s])];l.length>0&&(S=(await e.gather({tasks:l,format:`research`})).context||``)}catch(e){m(`warn`,`Could not gather context: ${e.message}`)}if(o===`text`){let e=new Y({head:[H.cyan.bold(`ID`),H.cyan.bold(`Title`),H.cyan.bold(`Status`)],colWidths:[10,55,10],style:{border:le}});e.push([t,z(x.title,52),Fc(x.status)]),console.log(q(V.text.bold(`Updating Subtask #${t}`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),h=Ac(i?`Updating subtask with research...`:`Updating subtask...`)}let C=``,w=``,T=null;try{let e={id:y.id,title:y.title},t=b>0?{id:`${y.id}.${y.subtasks[b-1].id}`,title:y.subtasks[b-1].title,status:y.subtasks[b-1].status}:void 0,c=b<y.subtasks.length-1?{id:`${y.id}.${y.subtasks[b+1].id}`,title:y.subtasks[b+1].title,status:y.subtasks[b+1].status}:void 0,l=_a(),u={parentTask:e,prevSubtask:t,nextSubtask:c,currentDetails:x.details||`(No existing details)`,updatePrompt:r,useResearch:i,gatheredContext:S||``,hasCodebaseAnalysis:ee(i,a,s),projectRoot:a},d=i?`research`:`default`,{systemPrompt:f,userPrompt:g}=await l.loadPrompt(`update-subtask`,u,d),_=i?`research`:`main`;m(`info`,`Using AI text service with role: ${_}`),T=await n({prompt:g,systemPrompt:f,role:_,session:s,projectRoot:a,maxRetries:2,commandName:`update-subtask`,outputType:p?`mcp`:`cli`}),T&&T.mainResult&&typeof T.mainResult==`string`?C=T.mainResult:(C=``,m(`warn`,`AI service response did not contain expected text string.`)),o===`text`&&h&&($(h),h=null)}catch(e){throw m(`error`,`AI service call failed: ${e.message}`),o===`text`&&h&&($(h),h=null),e}if(C&&C.trim()){let e=(/* @__PURE__ */ new Date()).toISOString(),t=`<info added on ${e}>\n${C.trim()}\n</info added on ${e}>`;w=t,x.details=(x.details?x.details+`
1203
- `:``)+t}else m(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),w=`No new details were added by the AI.`;let E=y.subtasks[b];return d&&(E.metadata={...E.metadata||{},...d}),o===`text`&&R(s)&&console.log(`>>> DEBUG: Subtask details AFTER AI update:`,E.details),E.description&&r.length<100&&(o===`text`&&R(s)&&console.log(`>>> DEBUG: Subtask description BEFORE append:`,E.description),E.description+=` [Updated: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}]`,o===`text`&&R(s)&&console.log(`>>> DEBUG: Subtask description AFTER append:`,E.description)),o===`text`&&R(s)&&console.log(`>>> DEBUG: About to call writeJSON with updated data...`),I(e,c,a,u),o===`text`&&R(s)&&console.log(`>>> DEBUG: writeJSON call completed.`),m(`success`,`Successfully updated subtask ${t}`),o===`text`&&(h&&=($(h),null),console.log(q(H.green(`Successfully updated subtask #${t}`)+`
1195
+ Ensure the JSON is valid and properly formatted.`,o}async function Dc(e,t,n,r,i){let o=Ec(e,t,n,r),s=W.object({title:W.string().min(1).describe(`Updated task title reflecting scope adjustment`),description:W.string().min(1).describe(`Updated task description with adjusted scope`),details:W.string().min(1).describe(`Updated implementation details with adjusted complexity`),testStrategy:W.string().min(1).describe(`Updated testing approach for the adjusted scope`),priority:W.enum([`low`,`medium`,`high`]).describe(`Task priority level`)}),c=await a({role:i.research?`research`:`main`,session:i.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:i.commandName||`scope-${t}`,outputType:i.outputType||`cli`}),l=c.mainResult,u={...l,priority:l.priority||e.priority||`medium`};return{updatedTask:{...e,...u},telemetryData:c.telemetryData}}async function Oc(e,t,n=`regular`,r=null,i={},a=`text`){if(!xc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${vc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=F(e,o,s),l=c?.tasks||[];for(let e of t)if(!cc(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=k(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&L(`info`,`Scoping up task ${f}: ${t.title}`);let p=Cc(f,i);p&&a===`text`&&L(`info`,`Original complexity: ${p}/10`);let m=await Dc(t,`up`,n,r,i),h=await wc(m.updatedTask,e,i,`up`,n,p);a===`text`&&h.regenerated&&L(`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{I(e,c,o,s);let t=await Sc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;L(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&L(`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 I(e,c,o,s),a===`text`&&L(`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(!xc(n))throw Error(`Invalid strength level: ${n}. Must be one of: ${vc.join(`, `)}`);let{projectRoot:o=`.`,tag:s=`master`}=i,c=F(e,o,s),l=c?.tasks||[];for(let e of t)if(!cc(l,e))throw Error(`Task with ID ${e} not found`);let u=[],d=null;for(let f of t){let t=k(l,f).task;if(!t)throw Error(`Task with ID ${f} not found`);a===`text`&&L(`info`,`Scoping down task ${f}: ${t.title}`);let p=Cc(f,i);p&&a===`text`&&L(`info`,`Original complexity: ${p}/10`);let m=await Dc(t,`down`,n,r,i),h=await wc(m.updatedTask,e,i,`down`,n,p);a===`text`&&h.regenerated&&L(`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{I(e,c,o,s);let t=await Sc(h.updatedTask,e,i);if(t&&a===`text`){let e=t-p;L(`info`,`New complexity: ${p}/10 ${e>0?`↗️`:e<0?`↘️`:`➡️`} ${t}/10 (${e>0?`+`:``}${e})`)}}catch(e){a===`text`&&L(`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 I(e,c,o,s),a===`text`&&L(`info`,`Successfully scoped down ${u.length} task(s)`),{updatedTasks:u,telemetryData:d}}async function Ac(e,t,n,r,i=!0){if(!Qi(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,L(`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(V.yellow(`All subtasks of parent task ${e} are now marked as done.`)),console.log(V.yellow(`Consider updating the parent task status with: taskgraph 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,L(`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&&(L(`info`,`Also marking ${e.length} subtasks as '${n}'`),e.forEach(e=>{e.status=n}))}}}async function jc(e,t,n,r={}){let{projectRoot:i,tag:a}=r;try{if(!Qi(n))throw Error(`Error: Invalid status value: ${n}. Use one of: ${Zi.join(`, `)}`);let o=!!r?.mcpLog;o||console.log(K(B.text.bold(`Updating Task Status to: ${n}`),{padding:1,borderColor:P,borderStyle:`round`})),L(`info`,`Reading tasks from ${e}...`);let s=F(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 Ac(e,t,n,c,!o),u.push({id:t,oldStatus:r,newStatus:n})}if(s[a].tasks=c.tasks,O(s[a],{description:`Tasks for ${a} context`}),I(e,s,i,a),L(`info`,`Validating dependencies after status update...`),_l(c.tasks),!o)for(let e of u){let{id:t,oldStatus:n,newStatus:r}=e;console.log(K(B.text.bold(`Successfully updated task ${t} status:`)+`
1196
+ From: ${V.yellow(n)}\nTo: ${V.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(L(`error`,`Error setting task status: ${e.message}`),!r?.mcpLog)console.error(V.red(`Error: ${e.message}`)),be(r?.session)&&console.error(e),process.exit(1);else throw e}}async function Mc(e,t,r,i=!1,a={},o=a.mcpLog?`json`:`text`){let{session:s,mcpLog:c,projectRoot:l,tag:u,metadata:d}=a,f=c||L,p=!!c,m=(e,...t)=>{p?typeof f[e]==`function`?f[e](...t):f.info(...t):z()||f(e,...t)},h=null;try{if(m(`info`,`Updating subtask ${t} with prompt: "${r}"`),!t||typeof t!=`string`)throw Error(`Subtask ID cannot be empty.`);if((!r||typeof r!=`string`||r.trim()===``)&&!d)throw Error(`Prompt cannot be empty unless metadata is provided. Please provide context for the subtask update or metadata to merge.`);let a=l||Ce();if(!a)throw Error(`Could not determine project root directory`);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(!G.existsSync(e))throw Error(`Tasks file not found at path: ${e}`);let c=F(e,a,u);if(!c||!c.tasks)throw Error(`No valid tasks found in ${e}. The file may be corrupted or have an invalid format.`);let[f,g]=t.split(`.`),_=parseInt(f,10),v=parseInt(g,10);if(Number.isNaN(_)||_<=0||Number.isNaN(v)||v<=0)throw Error(`Invalid subtask ID format: ${t}. Both parent ID and subtask ID must be positive integers.`);let y=c.tasks.find(e=>e.id===_);if(!y)throw Error(`Task ${_} not found`);if(!y.subtasks||!Array.isArray(y.subtasks))throw Error(`Parent task ${_} has no subtasks.`);let b=y.subtasks.findIndex(e=>e.id===v);if(b===-1)throw Error(`Subtask ${t} not found`);let x=y.subtasks[b];if(d&&(!r||r.trim()===``))return m(`info`,`Metadata-only update for subtask ${t}`),x.metadata={...x.metadata||{},...d},y.subtasks[b]=x,I(e,c,a,u),m(`success`,`Successfully updated metadata for subtask ${t}`),{updatedSubtask:x,telemetryData:null,tagInfo:{tag:u}};let S=``;try{let e=new Aa(a,u),n=new Ia(oe(c.tasks),`update-subtask`),i=`${y.title} ${x.title} ${r}`,o=n.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=n.getTaskIds(o),l=[.../* @__PURE__ */ new Set([t.toString(),...s])];l.length>0&&(S=(await e.gather({tasks:l,format:`research`})).context||``)}catch(e){m(`warn`,`Could not gather context: ${e.message}`)}if(o===`text`){let e=new J({head:[V.cyan.bold(`ID`),V.cyan.bold(`Title`),V.cyan.bold(`Status`)],colWidths:[10,55,10],style:{border:le}});e.push([t,R(x.title,52),Kc(x.status)]),console.log(K(B.text.bold(`Updating Subtask #${t}`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),h=Vc(i?`Updating subtask with research...`:`Updating subtask...`)}let C=``,w=``,T=null;try{let e={id:y.id,title:y.title},t=b>0?{id:`${y.id}.${y.subtasks[b-1].id}`,title:y.subtasks[b-1].title,status:y.subtasks[b-1].status}:void 0,c=b<y.subtasks.length-1?{id:`${y.id}.${y.subtasks[b+1].id}`,title:y.subtasks[b+1].title,status:y.subtasks[b+1].status}:void 0,l=Oa(),u={parentTask:e,prevSubtask:t,nextSubtask:c,currentDetails:x.details||`(No existing details)`,updatePrompt:r,useResearch:i,gatheredContext:S||``,hasCodebaseAnalysis:ee(i,a,s),projectRoot:a},d=i?`research`:`default`,{systemPrompt:f,userPrompt:g}=await l.loadPrompt(`update-subtask`,u,d),_=i?`research`:`main`;m(`info`,`Using AI text service with role: ${_}`),T=await n({prompt:g,systemPrompt:f,role:_,session:s,projectRoot:a,maxRetries:2,commandName:`update-subtask`,outputType:p?`mcp`:`cli`}),T&&T.mainResult&&typeof T.mainResult==`string`?C=T.mainResult:(C=``,m(`warn`,`AI service response did not contain expected text string.`)),o===`text`&&h&&($(h),h=null)}catch(e){throw o===`text`&&h&&($(h),h=null),e}if(C&&C.trim()){let e=(/* @__PURE__ */ new Date()).toISOString(),t=`<info added on ${e}>\n${C.trim()}\n</info added on ${e}>`;w=t,x.details=(x.details?x.details+`
1197
+ `:``)+t}else m(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),w=`No new details were added by the AI.`;let E=y.subtasks[b];return d&&(E.metadata={...E.metadata||{},...d}),o===`text`&&be(s)&&console.log(`>>> DEBUG: Subtask details AFTER AI update:`,E.details),E.description&&r.length<100&&(o===`text`&&be(s)&&console.log(`>>> DEBUG: Subtask description BEFORE append:`,E.description),E.description+=` [Updated: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}]`,o===`text`&&be(s)&&console.log(`>>> DEBUG: Subtask description AFTER append:`,E.description)),o===`text`&&be(s)&&console.log(`>>> DEBUG: About to call writeJSON with updated data...`),I(e,c,a,u),o===`text`&&be(s)&&console.log(`>>> DEBUG: writeJSON call completed.`),m(`success`,`Successfully updated subtask ${t}`),o===`text`&&(h&&=($(h),null),console.log(K(V.green(`Successfully updated subtask #${t}`)+`
1204
1198
 
1205
- `+V.text.bold(`Title:`)+` `+E.title+`
1199
+ `+B.text.bold(`Title:`)+` `+E.title+`
1206
1200
 
1207
- `+V.text.bold(`Newly Added Snippet:`)+`
1208
- `+V.text(w),{padding:1,borderColor:`green`,borderStyle:`round`}))),o===`text`&&T.telemetryData&&Gc(T.telemetryData,`cli`),{updatedSubtask:E,telemetryData:T.telemetryData,tagInfo:T.tagInfo}}catch(e){if(o===`text`&&h&&($(h),h=null),m(`error`,`Error updating subtask: ${e.message}`),o===`text`)console.error(H.red(`Error: ${e.message}`)),e.message?.includes(`overloaded`)?(console.log(H.yellow(`
1209
- AI model overloaded, and fallback failed or was unavailable:`)),console.log(` 1. Try again in a few minutes.`),console.log(` 2. Check that Claude Code is installed and signed in: claude --version`)):e.message?.includes(`not found`)?(console.log(H.yellow(`
1210
- To fix this issue:`)),console.log(` 1. Run taskgraph 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(H.yellow(`
1211
- 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.`)),R(s)&&console.error(e);else throw e;return null}}async function Sc(e,t,r,i=!1,o={},s=`text`,c=!1){let{session:l,mcpLog:u,projectRoot:d,tag:f,metadata:p}=o,{report:m,isMCP:h}=Oa(u,l);try{if(m(`info`,`Updating single task ${t} with prompt: "${r}"`),t==null||String(t).trim()===``)throw Error(`Task ID cannot be empty.`);if((!r||typeof r!=`string`||r.trim()===``)&&!p)throw Error(`Prompt cannot be empty unless metadata is provided for update.`);let o=d||Se();if(!o)throw Error(`Could not determine project root directory`);if(!K.existsSync(e))throw Error(`Tasks file not found: ${e}`);let u=F(e,o,f);if(!u||!u.tasks)throw Error(`No valid tasks found in ${e}.`);let g=String(t).trim();if(!/^\d+$/.test(g))throw Error(`taskId must be a positive integer. Use update-subtask-by-id for IDs like "1.2".`);let _=Number(g),v=u.tasks.findIndex(e=>e.id===_);if(v===-1)throw m(`error`,`Task with ID ${_} not found`),Error(`Task with ID ${_} not found.`);let y=u.tasks[v];if(y.status===`done`||y.status===`completed`)return m(`warn`,`Task ${t} is already marked as done and cannot be updated`),s===`text`&&console.log(q(H.yellow(`Task ${t} is already marked as ${y.status} and cannot be updated.`)+`
1201
+ `+B.text.bold(`Newly Added Snippet:`)+`
1202
+ `+B.text(w),{padding:1,borderColor:`green`,borderStyle:`round`}))),o===`text`&&T.telemetryData&&nl(T.telemetryData,`cli`),{updatedSubtask:E,telemetryData:T.telemetryData,tagInfo:T.tagInfo}}catch(e){throw o===`text`&&h&&($(h),h=null),o!==`text`&&m(`error`,`Error updating subtask: ${e.message}`),e}}async function Nc(e,t,r,i=!1,o={},s=`text`,c=!1){let{session:l,mcpLog:u,projectRoot:d,tag:f,metadata:p}=o,{report:m,isMCP:h}=za(u,l);try{if(m(`info`,`Updating single task ${t} with prompt: "${r}"`),t==null||String(t).trim()===``)throw Error(`Task ID cannot be empty.`);if((!r||typeof r!=`string`||r.trim()===``)&&!p)throw Error(`Prompt cannot be empty unless metadata is provided for update.`);let o=d||Ce();if(!o)throw Error(`Could not determine project root directory`);if(!G.existsSync(e))throw Error(`Tasks file not found: ${e}`);let u=F(e,o,f);if(!u||!u.tasks)throw Error(`No valid tasks found in ${e}.`);let g=String(t).trim();if(!/^\d+$/.test(g))throw Error(`taskId must be a positive integer. Use update-subtask-by-id for IDs like "1.2".`);let _=Number(g),v=u.tasks.findIndex(e=>e.id===_);if(v===-1)throw Error(`Task ${_} not found`);let y=u.tasks[v];if(y.status===`done`||y.status===`completed`)return m(`warn`,`Task ${t} is already marked as done and cannot be updated`),s===`text`&&console.log(K(V.yellow(`Task ${t} is already marked as ${y.status} and cannot be updated.`)+`
1212
1203
 
1213
- `+V.text(`Completed tasks are locked to maintain consistency. To modify a completed task, you must first:`)+`
1214
- `+V.text(`1. Change its status to "pending" or "in-progress"`)+`
1215
- `+V.text(`2. Then run the update-task command`),{padding:1,borderColor:`yellow`,borderStyle:`round`})),null;if(p&&(!r||r.trim()===``))return m(`info`,`Metadata-only update for task ${t}`),y.metadata={...y.metadata||{},...p},u.tasks[v]=y,I(e,u,o,f),m(`success`,`Successfully updated metadata for task ${t}`),{updatedTask:y,telemetryData:null,tagInfo:{tag:f}};let b=``;try{let e=new ya(o,f),n=new Ta(oe(u.tasks),`update-task`),i=`${y.title} ${y.description} ${r}`,a=n.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=n.getTaskIds(a),c=[.../* @__PURE__ */ new Set([t.toString(),...s])];c.length>0&&(b=(await e.gather({tasks:c,format:`research`})).context||``)}catch(e){m(`warn`,`Could not gather context: ${e.message}`)}if(s===`text`){let e=new Y({head:[H.cyan.bold(`ID`),H.cyan.bold(`Title`),H.cyan.bold(`Status`)],colWidths:[5,60,10],style:{border:le}});e.push([y.id,z(y.title,57),Fc(y.status)]),console.log(q(V.text.bold(`Updating Task #${t}`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(q(H.cyan.bold(`How Completed Subtasks Are Handled:`)+`
1204
+ `+B.text(`Completed tasks are locked to maintain consistency. To modify a completed task, you must first:`)+`
1205
+ `+B.text(`1. Change its status to "pending" or "in-progress"`)+`
1206
+ `+B.text(`2. Then run the update-task command`),{padding:1,borderColor:`yellow`,borderStyle:`round`})),null;if(p&&(!r||r.trim()===``))return m(`info`,`Metadata-only update for task ${t}`),y.metadata={...y.metadata||{},...p},u.tasks[v]=y,I(e,u,o,f),m(`success`,`Successfully updated metadata for task ${t}`),{updatedTask:y,telemetryData:null,tagInfo:{tag:f}};let b=``;try{let e=new Aa(o,f),n=new Ia(oe(u.tasks),`update-task`),i=`${y.title} ${y.description} ${r}`,a=n.findRelevantTasks(i,{maxResults:5,includeSelf:!0}),s=n.getTaskIds(a),c=[.../* @__PURE__ */ new Set([t.toString(),...s])];c.length>0&&(b=(await e.gather({tasks:c,format:`research`})).context||``)}catch(e){m(`warn`,`Could not gather context: ${e.message}`)}if(s===`text`){let e=new J({head:[V.cyan.bold(`ID`),V.cyan.bold(`Title`),V.cyan.bold(`Status`)],colWidths:[5,60,10],style:{border:le}});e.push([y.id,R(y.title,57),Kc(y.status)]),console.log(K(B.text.bold(`Updating Task #${t}`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(K(V.cyan.bold(`How Completed Subtasks Are Handled:`)+`
1216
1207
 
1217
- `+V.text(`• Subtasks marked as "done" or "completed" will be preserved
1218
- `)+V.text(`• New subtasks will build upon what has already been completed
1219
- `)+V.text(`• If completed work needs revision, a new subtask will be created instead of modifying done items
1220
- `)+V.text(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}))}let x=_a(),S={task:y,taskJson:JSON.stringify(y,null,2),updatePrompt:r,appendMode:c,useResearch:i,currentDetails:y.details||`(No existing details)`,gatheredContext:b||``,hasCodebaseAnalysis:ee(i,o,l),projectRoot:o},C=c?`append`:i?`research`:`default`;m(`info`,`Loading prompt template with variant: ${C}, appendMode: ${c}, useResearch: ${i}`);let w,T;try{let e=x.loadPrompt(`update-task`,S,C);m(`info`,`Prompt result type: ${typeof e}, keys: ${e?Object.keys(e).join(`, `):`null`}`),w=e.systemPrompt,T=e.userPrompt,m(`info`,`Loaded prompts - systemPrompt length: ${w?.length}, userPrompt length: ${T?.length}`)}catch(e){throw m(`error`,`Failed to load prompt template: ${e.message}`),Error(`Failed to load prompt template: ${e.message}`)}if(!w||!T)throw Error(`Failed to load prompts: systemPrompt=${!!w}, userPrompt=${!!T}`);let E=null,D=null;!h&&s===`text`&&(E=Ac(i?`Updating task with research...
1208
+ `+B.text(`• Subtasks marked as "done" or "completed" will be preserved
1209
+ `)+B.text(`• New subtasks will build upon what has already been completed
1210
+ `)+B.text(`• If completed work needs revision, a new subtask will be created instead of modifying done items
1211
+ `)+B.text(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}))}let x=Oa(),S={task:y,taskJson:JSON.stringify(y,null,2),updatePrompt:r,appendMode:c,useResearch:i,currentDetails:y.details||`(No existing details)`,gatheredContext:b||``,hasCodebaseAnalysis:ee(i,o,l),projectRoot:o},C=c?`append`:i?`research`:`default`;m(`info`,`Loading prompt template with variant: ${C}, appendMode: ${c}, useResearch: ${i}`);let w,T;try{let e=x.loadPrompt(`update-task`,S,C);m(`info`,`Prompt result type: ${typeof e}, keys: ${e?Object.keys(e).join(`, `):`null`}`),w=e.systemPrompt,T=e.userPrompt,m(`info`,`Loaded prompts - systemPrompt length: ${w?.length}, userPrompt length: ${T?.length}`)}catch(e){throw m(`error`,`Failed to load prompt template: ${e.message}`),Error(`Failed to load prompt template: ${e.message}`)}if(!w||!T)throw Error(`Failed to load prompts: systemPrompt=${!!w}, userPrompt=${!!T}`);let E=null,D=null;!h&&s===`text`&&(E=Vc(i?`Updating task with research...
1221
1212
  `:`Updating task...
1222
- `));try{let d=i?`research`:`main`;if(D=c?await n({role:d,session:l,projectRoot:o,systemPrompt:w,prompt:T,commandName:`update-task`,outputType:h?`mcp`:`cli`}):await a({role:d,session:l,projectRoot:o,systemPrompt:w,prompt:T,schema:aa[`update-task-by-id`],objectName:`task`,commandName:`update-task`,outputType:h?`mcp`:`cli`}),E&&$(E,`AI update complete.`),c){let n=D.mainResult,i=``;if(n&&n.trim()){let e=(/* @__PURE__ */ new Date()).toISOString(),t=`<info added on ${e}>\n${n.trim()}\n</info added on ${e}>`;i=t,y.details=(y.details?y.details+`
1223
- `:``)+t}else m(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),i=`No new details were added by the AI.`;return r.length<100&&y.description&&(y.description+=` [Updated: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}]`),p&&(y.metadata={...y.metadata||{},...p}),u.tasks[v]=y,I(e,u,o,f),m(`success`,`Successfully appended to task ${t}`),s===`text`&&console.log(q(H.green(`Successfully appended to task #${t}`)+`
1224
-
1225
- `+V.text.bold(`Title:`)+` `+y.title+`
1226
-
1227
- `+V.text.bold(`Newly Added Content:`)+`
1228
- `+V.text(i),{padding:1,borderColor:`green`,borderStyle:`round`})),s===`text`&&D.telemetryData&&Gc(D.telemetryData,`cli`),{updatedTask:y,telemetryData:D.telemetryData,tagInfo:D.tagInfo}}let g=D.mainResult?.task;if(!g||typeof g!=`object`)throw Error(`Received invalid task object from AI.`);let _={...g,dependencies:g.dependencies??[],priority:g.priority??null,details:g.details??null,testStrategy:g.testStrategy??null};if(!_.title||!_.description)throw Error(`Updated task missing required fields.`);if(_.id!==t&&(m(`warn`,`AI changed task ID. Restoring original ID ${t}.`),_.id=t),_.status!==y.status&&!r.toLowerCase().includes(`status`)&&(m(`warn`,`AI changed task status. Restoring original status '${y.status}'.`),_.status=y.status),_.subtasks&&Array.isArray(_.subtasks)){let e=1;_.subtasks=_.subtasks.map(t=>{let n=y.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}),m(`info`,`Fixed ${_.subtasks.length} subtask IDs to be sequential numeric IDs.`)}if(y.subtasks?.length>0){if(!_.subtasks)m(`warn`,`Subtasks removed by AI. Restoring original subtasks.`),_.subtasks=y.subtasks;else{y.subtasks.filter(e=>e.status===`done`||e.status===`completed`).forEach(e=>{let t=_.subtasks.find(t=>t.id===e.id);(!t||JSON.stringify(t)!==JSON.stringify(e))&&(m(`warn`,`Completed subtask ${e.id} was modified or removed. Restoring.`),_.subtasks=_.subtasks.filter(t=>t.id!==e.id),_.subtasks.push(e))});let e=/* @__PURE__ */ new Set;_.subtasks=_.subtasks.filter(t=>e.has(t.id)?(m(`warn`,`Duplicate subtask ID ${t.id} removed.`),!1):(e.add(t.id),!0))}}return(y.metadata||p)&&(_.metadata={...y.metadata||{},...p||{}}),u.tasks[v]=_,I(e,u,o,f),m(`success`,`Successfully updated task ${t}`),s===`text`&&D.telemetryData&&Gc(D.telemetryData,`cli`),{updatedTask:_,telemetryData:D.telemetryData,tagInfo:D.tagInfo}}catch(e){throw E&&$(E),m(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&m(`error`,`Please ensure API keys are configured correctly.`),e}}catch(e){throw m(`error`,`Error updating task: ${e.message}`),s===`text`&&(console.error(H.red(`Error: ${e.message}`)),R(l)&&console.error(e),process.exit(1)),e}}async function Cc(e,t,n,r=!1,i={},o=`text`){let{session:s,mcpLog:c,projectRoot:l,tag:u}=i,d=c||L,f=!!c;f?d.info(`updateTasks called with context: session=${!!s}`):d(`info`,`updateTasks called`);try{f?d.info(`Updating tasks from ID ${t}`):d(`info`,`Updating tasks from ID ${t} with prompt: "${n}"`);let i=l||Se();if(!i)throw Error(`Could not determine project root directory`);let c=F(e,i,u);if(!c||!c.tasks)throw Error(`No valid tasks found in ${e}`);let p=c.tasks.filter(e=>e.id>=t&&e.status!==`done`);if(p.length===0){f?d.info(`No tasks to update (ID >= ${t} and not 'done').`):d(`info`,`No tasks to update (ID >= ${t} and not 'done').`),o===`text`&&console.log();return}let m=``;try{let e=new ya(i,u),t=new Ta(oe(c.tasks),`update`),r=t.findRelevantTasks(n,{maxResults:5,includeSelf:!0}),a=t.getTaskIds(r),o=p.map(e=>e.id.toString()),s=[.../* @__PURE__ */ new Set([...o,...a])];s.length>0&&(m=(await e.gather({tasks:s,format:`research`})).context||``)}catch(e){d(`warn`,`Could not gather additional context: ${e.message}`)}if(o===`text`){let e=new Y({head:[H.cyan.bold(`ID`),H.cyan.bold(`Title`),H.cyan.bold(`Status`)],colWidths:[5,70,20],style:{border:le}});p.forEach(t=>{e.push([t.id,z(t.title,57),Fc(t.status)])}),console.log(q(V.text.bold(`Updating ${p.length} tasks`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(q(H.cyan.bold(`How Completed Subtasks Are Handled:`)+`
1229
-
1230
- `+V.text(`• Subtasks marked as "done" or "completed" will be preserved
1231
- `)+V.text(`• New subtasks will build upon what has already been completed
1232
- `)+V.text(`• If completed work needs revision, a new subtask will be created instead of modifying done items
1233
- `)+V.text(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}))}let{systemPrompt:h,userPrompt:g}=await _a().loadPrompt(`update-tasks`,{tasks:p,updatePrompt:n,useResearch:r,projectContext:m,hasCodebaseAnalysis:ee(r,i,s),projectRoot:i}),_=null,v=null;!f&&o===`text`&&(_=Ac(`Updating tasks with AI...
1234
- `));try{v=await a({role:r?`research`:`main`,session:s,projectRoot:i,systemPrompt:h,prompt:g,schema:aa[`update-tasks`],objectName:`tasks`,commandName:`update-tasks`,outputType:f?`mcp`:`cli`}),_&&$(_,`AI update complete.`);let t=v.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.`);f?d.info(`Received ${t.length} updated tasks from AI.`):d(`info`,`Received ${t.length} updated tasks from AI.`);let n=new Map(t.map(e=>[e.id,e])),l=0;return c.tasks.forEach((e,t)=>{if(n.has(e.id)){let r=n.get(e.id);c.tasks[t]={...e,...r,subtasks:r.subtasks===void 0?e.subtasks:r.subtasks},l++}}),f?d.info(`Applied updates to ${l} tasks in the dataset.`):d(`info`,`Applied updates to ${l} tasks in the dataset.`),I(e,c,i,u),f?d.info(`Successfully updated ${l} tasks in ${e}`):d(`success`,`Successfully updated ${l} tasks in ${e}`),o===`text`&&v.telemetryData&&Gc(v.telemetryData,`cli`),{success:!0,updatedTasks:t,telemetryData:v.telemetryData,tagInfo:v.tagInfo}}catch(e){throw _&&$(_),f?d.error(`Error during AI service call: ${e.message}`):d(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&(f?d.error(`Please ensure API keys are configured correctly in .env or mcp.json.`):d(`error`,`Please ensure API keys are configured correctly in .env or mcp.json.`)),e}finally{_&&$(_)}}catch(e){if(f?d.error(`Error updating tasks: ${e.message}`):d(`error`,`Error updating tasks: ${e.message}`),o===`text`)console.error(H.red(`Error: ${e.message}`)),R(s)&&console.error(e),process.exit(1);else throw e}}const{theme:Q,BORDER_COLOR:wc,TABLE_BORDER:Tc}=Pn,Ec=Re(he);function Dc(e){!B()&&e&&e._migrationHappened&&console.log(q(H.bold(`FYI: `)+Q.muted(`TaskGraph now supports separate task lists per tag. `)+H.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 Oc(e,t={}){if(B())return;let{skipIfMaster:n=!1,dim:r=!1}=t;if(n&&e===`master`)return;let i=r?Q.muted(`[tag] ${e}`):H.dim(`[tag] `)+H.cyan(e);console.log(i)}function kc(){B()||ut({version:Hi(),projectName:me(null)})}function Ac(e){return B()?null:sn(e).start()}function jc(e){return B()?null:new fn(e).start()}function $(e){e&&typeof e.stop==`function`&&e.stop()}function Mc(e,t=null){e&&typeof e.succeed==`function`&&(t?e.succeed(t):e.succeed())}function Nc(e,t=null){e&&typeof e.fail==`function`&&(t?e.fail(t):e.fail())}function Pc(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?H.red:e<50||e<75?H.yellow:H.green;let l=c(`█`.repeat(i)),u=Q.muted(`─`.repeat(o)),d=``;if(n&&s>0){let e={pending:e=>H.yellow(`░`.repeat(e)),"in-progress":e=>Q.active(`▓`.repeat(e)),blocked:e=>H.red(`!`.repeat(e)),review:e=>H.magenta(`▒`.repeat(e))},t=Object.entries(n).filter(([e])=>![`deferred`,`cancelled`,`done`,`completed`].includes(e)).reduce((e,[t,n])=>e+n,0);if(t<=0)d=Q.muted(`░`.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]||(e=>Q.muted(`░`.repeat(e)));d+=c(o),r+=o}r<s&&(d+=Q.muted(`░`.repeat(s-r)))}}else d=Q.muted(`░`.repeat(s));let f=e===100?H.green:r===100?Q.muted:c;return`${l}${u}${d} ${f(`${r.toFixed(0)}%`)}`}function Fc(e,t=!1){if(!e)return Q.muted(`? unknown`);let n={done:{color:H.green,icon:`✓`,tableIcon:`✓`},completed:{color:H.green,icon:`✓`,tableIcon:`✓`},pending:{color:H.yellow,icon:`○`,tableIcon:`⏱`},"in-progress":{color:Q.active,icon:`▶`,tableIcon:`▶`},deferred:{color:Q.muted,icon:`x`,tableIcon:`⏱`},blocked:{color:H.red,icon:`!`,tableIcon:`✗`},review:{color:H.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:Q.muted,icon:`x`,tableIcon:`x`}}[e.toLowerCase()]||{color:H.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 Ic(e,t,n=!1,r=null){return!e||!Array.isArray(e)||e.length===0?n?Q.muted(`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=k(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?H.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?H.green.bold(i):c?H.yellow.bold(i):H.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?H.red(`${i} (Not found)`):`${i} (Not found)`;let l=c.subtasks.find(e=>e.id===s);if(!l)return n?H.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?H.green.bold(i):f?Q.active.bold(i):H.red.bold(i):i}let a=k(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?H.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?H.green.bold(i):c?H.yellow.bold(i):H.red.bold(i):i}).join(`, `)}function Lc(){let e=process.stdout.columns||100;console.log(q(H.bold(`TaskGraph CLI`),{padding:1,borderColor:wc,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 TaskGraph 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)`},{name:`completion --install`,args:``,desc:`Set up Tab completion for your shell`}]},{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 (${Bi.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:`graph`,args:`[--id=<id>]`,desc:`Show tasks as a dependency tree, with the next task marked`},{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(q(H[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=Math.max(25,Math.floor(e*.2)),r=Math.max(40,Math.floor(e*.35)),i=Math.max(45,Math.floor(e*.45)-10),a=new Y({colWidths:[n,r,i],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)=>{a.push([`${H.yellow.bold(e.name)}${H.reset(``)}`,`${H.reset(e.args)}${H.reset(``)}`,`${H.dim(e.desc)}${H.reset(``)}`])}),console.log(a.toString()),console.log(``)}),console.log(q(H.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=Math.max(30,Math.floor(t*.25)),r=Math.max(50,Math.floor(t*.45)),i=Math.max(30,Math.floor(t*.3)-10),a=new Y({colWidths:[n,r,i],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});a.push([`${H.yellow(D)}${H.reset(``)}`,`${H.reset(`AI model configuration file (project root)`)}${H.reset(``)}`,`${H.dim(`Managed by models cmd`)}${H.reset(``)}`],[`${H.yellow(`Claude Code`)}${H.reset(``)}`,`${H.reset(`Install and sign in to Claude Code (no API keys needed)`)}${H.reset(``)}`,`${H.dim(`Required on PATH`)}${H.reset(``)}`]),console.log(a.toString()),console.log(``),console.log(q(H.bold(`Quick Start:`)+`
1235
-
1236
- `+H.cyan(`1. Create Project: `)+H.reset(`taskgraph init`)+`
1237
- `+H.cyan(`2. Setup Models: `)+H.reset(`taskgraph models --setup`)+`
1238
- `+H.cyan(`3. Parse PRD: `)+H.reset(`taskgraph parse-prd --input=<prd-file>`)+`
1239
- `+H.cyan(`4. List Tasks: `)+H.reset(`taskgraph list`)+`
1240
- `+H.cyan(`5. Find Next Task: `)+H.reset(`taskgraph next`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1},width:Math.min(t-10,100)}))}function Rc(e){return e<=3?H.green(`● ${e}`):e<=6?H.yellow(`● ${e}`):H.red(`● ${e}`)}async function zc(e){if(!K.existsSync(e)){console.log(q(H.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=Fe.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(H.cyan(`Generate complexity report? (y/n): `),e)});if(t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`){console.log(H.cyan(`Generating complexity report...`));let t=M;return K.existsSync(t)?(await Ea({output:e,research:!1,file:t}),zc(e)):(console.error(`✗ No tasks.json file found. Please run "taskgraph init" or create a tasks.json file.`),null)}console.log(H.yellow(`Report generation cancelled.`));return}let t;try{t=JSON.parse(K.readFileSync(e,`utf8`))}catch(e){L(`error`,`Error reading complexity report: ${e.message}`);return}console.log(q(H.bold(`Task Complexity Analysis Report`),{padding:1,borderColor:wc,borderStyle:`round`,margin:{top:1,bottom:1}}));let n=new Y({style:{head:[],border:[],"padding-top":0,"padding-bottom":0,compact:!0},chars:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``},colWidths:[20,50]});n.push([H.cyan.bold(`Generated:`),new Date(t.meta.generatedAt).toLocaleString()],[H.cyan.bold(`Tasks Analyzed:`),t.meta.tasksAnalyzed],[H.cyan.bold(`Threshold Score:`),t.meta.thresholdScore],[H.cyan.bold(`Project:`),t.meta.projectName],[H.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 s=Math.round(o[0]/r.length*100),c=Math.round(o[1]/r.length*100),l=Math.round(o[2]/r.length*100);console.log(q(H.bold(`Complexity Distribution
1241
-
1242
- `)+`${H.green.bold(`Low (1-4):`)} ${o[0]} tasks (${s}%)\n${H.yellow.bold(`Medium (5-7):`)} ${o[1]} tasks (${c}%)\n${H.red.bold(`High (8-10):`)} ${o[2]} tasks (${l}%)`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));let u=process.stdout.columns||100,d=Math.floor(u*.25),f=u-12-d-8-8-10,p=new Y({head:[H.yellow.bold(`ID`),H.yellow.bold(`Title`),H.yellow.bold(`Score`),H.yellow.bold(`Subtasks`),H.yellow.bold(`Expansion Command`)],colWidths:[12,d,8,8,f],style:{head:[],border:[]},wordWrap:!0,wrapOnWordBoundary:!0});if(i.forEach(e=>{let t=`taskgraph expand --id=${e.taskId} --num=${e.recommendedSubtasks}${e.expansionPrompt?` --prompt="${e.expansionPrompt}"`:``}`;p.push([e.taskId,z(e.taskTitle,d-3),Rc(e.complexityScore),e.recommendedSubtasks,H.cyan(t)])}),console.log(p.toString()),a.length>0){console.log(q(H.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 Y({head:[H.green.bold(`ID`),H.green.bold(`Title`),H.green.bold(`Score`),H.green.bold(`Reasoning`)],colWidths:[5,40,8,50],style:{head:[],border:[]}});a.forEach(t=>{e.push([t.taskId,z(t.taskTitle,37),Rc(t.complexityScore),z(t.reasoning,47)])}),console.log(e.toString())}console.log(q(H.bold(`Suggested Actions:`)+`
1243
-
1244
- ${H.cyan(`1.`)} Expand all complex tasks: ${H.yellow(`taskgraph expand --all`)}\n${H.cyan(`2.`)} Expand a specific task: ${H.yellow(`taskgraph expand --id=<id>`)}\n${H.cyan(`3.`)} Regenerate with research: ${H.yellow(`taskgraph analyze-complexity --research`)}`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))}async function Bc(e){console.log(q(H.yellow(`It looks like you've already generated tasks for this project.
1245
- `)+H.yellow(`Executing this command will overwrite any existing tasks.`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=Fe.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(H.cyan(`Are you sure you wish to continue? (y/N): `),e)});return t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`}const Vc=(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=Q.muted(`☆☆☆`);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]?H.yellow(`★★★`):e>=r[n]?H.yellow(`★★`)+Q.muted(`☆`):H.yellow(`★`)+Q.muted(`☆☆`)}return`${n} ${a}`},Hc=e=>{if(!e)return`N/A`;if(e.input===0&&e.output===0)return H.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 Uc(e,t=[]){console.log(H.cyan.bold(`
1246
- Active Model Configuration:`));let n=e.activeModels,r=new Y({head:[`Role`,`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>H.cyan.bold(e)),colWidths:[10,14,30,18,20],style:{head:[`cyan`,`bold`],border:Tc}});r.push([H.reset(`Main`),n.main.provider,n.main.modelId,Vc(n.main.sweScore,t),Hc(n.main.cost)]),r.push([H.reset(`Research`),n.research.provider,n.research.modelId,Vc(n.research.sweScore,t),Hc(n.research.cost)]),n.fallback&&n.fallback.provider&&n.fallback.modelId?r.push([H.reset(`Fallback`),n.fallback.provider,n.fallback.modelId,Vc(n.fallback.sweScore,t),Hc(n.fallback.cost)]):r.push([H.reset(`Fallback`),Q.muted(`-`),Q.muted(`(Not Set)`),Q.muted(`-`),Q.muted(`-`)]),console.log(r.toString())}function Wc(e){if(!e||e.length===0){console.log(Q.muted(`
1247
- (No other models available or all are configured)`));return}console.log(H.cyan.bold(`
1248
- Other Available Models:`));let t=new Y({head:[`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>H.cyan.bold(e)),colWidths:[15,40,18,25],style:{head:[`cyan`,`bold`],border:Tc}});e.forEach(n=>{t.push([n.provider,n.modelId,Vc(n.sweScore,e),Hc(n.cost)])}),console.log(t.toString()),console.log(q(H.bold(`Next Steps:`)+`
1249
- `+H.cyan(`1. Set main model: ${H.yellow(`taskgraph models --set-main <model_id>`)}`)+`
1250
- `+H.cyan(`2. Set research model: ${H.yellow(`taskgraph models --set-research <model_id>`)}`)+`
1251
- `+H.cyan(`3. Set fallback model: ${H.yellow(`taskgraph models --set-fallback <model_id>`)}`)+`
1252
- `+H.cyan(`4. Run interactive setup: ${H.yellow(`taskgraph models --setup`)}`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}function Gc(e,t=`cli`){if(t!==`cli`&&t!==`text`||!e||B())return;let n=wn(e);n&&console.log(`\n${Q.muted(n)}`)}function Kc(e,t,n){if(B()||!e)return;let{highRelevance:r,mediumRelevance:i,recentTasks:a,allRelevantTasks:o}=e,s=H.bold(`Context Analysis`)+`
1253
-
1254
- `;s+=Q.muted(`Query: `)+H.reset(`"${t}"`)+`
1255
- `,s+=Q.muted(`Context size: `)+H.cyan(`${n.toLocaleString()} characters`)+`
1256
- `,s+=Q.muted(`Tasks found: `)+H.yellow(`${o.length} relevant tasks`)+`
1257
-
1258
- `,r.length>0&&(s+=H.green.bold(`High relevance matches:`)+`
1259
- `,r.slice(0,3).forEach(e=>{s+=H.green(` • Task ${e.id}: ${z(e.title,50)}`)+`
1260
- `}),r.length>3&&(s+=H.green(` • ... and ${r.length-3} more high relevance tasks`)+`
1213
+ `));try{let d=i?`research`:`main`;if(D=c?await n({role:d,session:l,projectRoot:o,systemPrompt:w,prompt:T,commandName:`update-task`,outputType:h?`mcp`:`cli`}):await a({role:d,session:l,projectRoot:o,systemPrompt:w,prompt:T,schema:ga[`update-task-by-id`],objectName:`task`,commandName:`update-task`,outputType:h?`mcp`:`cli`}),E&&$(E,`AI update complete.`),c){let n=D.mainResult,i=``;if(n&&n.trim()){let e=(/* @__PURE__ */ new Date()).toISOString(),t=`<info added on ${e}>\n${n.trim()}\n</info added on ${e}>`;i=t,y.details=(y.details?y.details+`
1214
+ `:``)+t}else m(`warn`,`AI response was empty or whitespace after trimming. Original details remain unchanged.`),i=`No new details were added by the AI.`;return r.length<100&&y.description&&(y.description+=` [Updated: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}]`),p&&(y.metadata={...y.metadata||{},...p}),u.tasks[v]=y,I(e,u,o,f),m(`success`,`Successfully appended to task ${t}`),s===`text`&&console.log(K(V.green(`Successfully appended to task #${t}`)+`
1215
+
1216
+ `+B.text.bold(`Title:`)+` `+y.title+`
1217
+
1218
+ `+B.text.bold(`Newly Added Content:`)+`
1219
+ `+B.text(i),{padding:1,borderColor:`green`,borderStyle:`round`})),s===`text`&&D.telemetryData&&nl(D.telemetryData,`cli`),{updatedTask:y,telemetryData:D.telemetryData,tagInfo:D.tagInfo}}let g=D.mainResult?.task;if(!g||typeof g!=`object`)throw Error(`Received invalid task object from AI.`);let _={...g,dependencies:g.dependencies??[],priority:g.priority??null,details:g.details??null,testStrategy:g.testStrategy??null};if(!_.title||!_.description)throw Error(`Updated task missing required fields.`);if(_.id!==t&&(m(`warn`,`AI changed task ID. Restoring original ID ${t}.`),_.id=t),_.status!==y.status&&!r.toLowerCase().includes(`status`)&&(m(`warn`,`AI changed task status. Restoring original status '${y.status}'.`),_.status=y.status),_.subtasks&&Array.isArray(_.subtasks)){let e=1;_.subtasks=_.subtasks.map(t=>{let n=y.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}),m(`info`,`Fixed ${_.subtasks.length} subtask IDs to be sequential numeric IDs.`)}if(y.subtasks?.length>0){if(!_.subtasks)m(`warn`,`Subtasks removed by AI. Restoring original subtasks.`),_.subtasks=y.subtasks;else{y.subtasks.filter(e=>e.status===`done`||e.status===`completed`).forEach(e=>{let t=_.subtasks.find(t=>t.id===e.id);(!t||JSON.stringify(t)!==JSON.stringify(e))&&(m(`warn`,`Completed subtask ${e.id} was modified or removed. Restoring.`),_.subtasks=_.subtasks.filter(t=>t.id!==e.id),_.subtasks.push(e))});let e=/* @__PURE__ */ new Set;_.subtasks=_.subtasks.filter(t=>e.has(t.id)?(m(`warn`,`Duplicate subtask ID ${t.id} removed.`),!1):(e.add(t.id),!0))}}return(y.metadata||p)&&(_.metadata={...y.metadata||{},...p||{}}),u.tasks[v]=_,I(e,u,o,f),m(`success`,`Successfully updated task ${t}`),s===`text`&&D.telemetryData&&nl(D.telemetryData,`cli`),{updatedTask:_,telemetryData:D.telemetryData,tagInfo:D.tagInfo}}catch(e){throw E&&$(E),e}}catch(e){throw s!==`text`&&m(`error`,`Error updating task: ${e.message}`),e}}async function Pc(e,t,n,r=!1,i={},o=`text`){let{session:s,mcpLog:c,projectRoot:l,tag:u}=i,d=c||L,f=!!c;f?d.info(`updateTasks called with context: session=${!!s}`):d(`info`,`updateTasks called`);try{f?d.info(`Updating tasks from ID ${t}`):d(`info`,`Updating tasks from ID ${t} with prompt: "${n}"`);let i=l||Ce();if(!i)throw Error(`Could not determine project root directory`);let c=F(e,i,u);if(!c||!c.tasks)throw Error(`No valid tasks found in ${e}`);let p=c.tasks.filter(e=>e.id>=t&&e.status!==`done`);if(p.length===0){f?d.info(`No tasks to update (ID >= ${t} and not 'done').`):d(`info`,`No tasks to update (ID >= ${t} and not 'done').`),o===`text`&&console.log();return}let m=``;try{let e=new Aa(i,u),t=new Ia(oe(c.tasks),`update`),r=t.findRelevantTasks(n,{maxResults:5,includeSelf:!0}),a=t.getTaskIds(r),o=p.map(e=>e.id.toString()),s=[.../* @__PURE__ */ new Set([...o,...a])];s.length>0&&(m=(await e.gather({tasks:s,format:`research`})).context||``)}catch(e){d(`warn`,`Could not gather additional context: ${e.message}`)}if(o===`text`){let e=new J({head:[V.cyan.bold(`ID`),V.cyan.bold(`Title`),V.cyan.bold(`Status`)],colWidths:[5,70,20],style:{border:le}});p.forEach(t=>{e.push([t.id,R(t.title,57),Kc(t.status)])}),console.log(K(B.text.bold(`Updating ${p.length} tasks`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:0}})),console.log(e.toString()),console.log(K(V.cyan.bold(`How Completed Subtasks Are Handled:`)+`
1220
+
1221
+ `+B.text(`• Subtasks marked as "done" or "completed" will be preserved
1222
+ `)+B.text(`• New subtasks will build upon what has already been completed
1223
+ `)+B.text(`• If completed work needs revision, a new subtask will be created instead of modifying done items
1224
+ `)+B.text(`• This approach maintains a clear record of completed work and new requirements`),{padding:1,borderColor:P,borderStyle:`round`,margin:{top:1,bottom:1}}))}let{systemPrompt:h,userPrompt:g}=await Oa().loadPrompt(`update-tasks`,{tasks:p,updatePrompt:n,useResearch:r,projectContext:m,hasCodebaseAnalysis:ee(r,i,s),projectRoot:i}),_=null,v=null;!f&&o===`text`&&(_=Vc(`Updating tasks with AI...
1225
+ `));try{v=await a({role:r?`research`:`main`,session:s,projectRoot:i,systemPrompt:h,prompt:g,schema:ga[`update-tasks`],objectName:`tasks`,commandName:`update-tasks`,outputType:f?`mcp`:`cli`}),_&&$(_,`AI update complete.`);let t=v.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.`);f?d.info(`Received ${t.length} updated tasks from AI.`):d(`info`,`Received ${t.length} updated tasks from AI.`);let n=new Map(t.map(e=>[e.id,e])),l=0;return c.tasks.forEach((e,t)=>{if(n.has(e.id)){let r=n.get(e.id);c.tasks[t]={...e,...r,subtasks:r.subtasks===void 0?e.subtasks:r.subtasks},l++}}),f?d.info(`Applied updates to ${l} tasks in the dataset.`):d(`info`,`Applied updates to ${l} tasks in the dataset.`),I(e,c,i,u),f?d.info(`Successfully updated ${l} tasks in ${e}`):d(`success`,`Successfully updated ${l} tasks in ${e}`),o===`text`&&v.telemetryData&&nl(v.telemetryData,`cli`),{success:!0,updatedTasks:t,telemetryData:v.telemetryData,tagInfo:v.tagInfo}}catch(e){throw _&&$(_),f?d.error(`Error during AI service call: ${e.message}`):d(`error`,`Error during AI service call: ${e.message}`),e.message.includes(`API key`)&&(f?d.error(`Please ensure API keys are configured correctly in .env or mcp.json.`):d(`error`,`Please ensure API keys are configured correctly in .env or mcp.json.`)),e}finally{_&&$(_)}}catch(e){if(f?d.error(`Error updating tasks: ${e.message}`):d(`error`,`Error updating tasks: ${e.message}`),o===`text`)console.error(V.red(`Error: ${e.message}`)),be(s)&&console.error(e),process.exit(1);else throw e}}const{theme:Q,BORDER_COLOR:Fc,TABLE_BORDER:Ic}=qn,Lc=ze(he);function Rc(e){!z()&&e&&e._migrationHappened&&console.log(K(V.bold(`FYI: `)+Q.muted(`TaskGraph now supports separate task lists per tag. `)+V.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 zc(e,t={}){if(z())return;let{skipIfMaster:n=!1,dim:r=!1}=t;if(n&&e===`master`)return;let i=r?Q.muted(`[tag] ${e}`):V.dim(`[tag] `)+V.cyan(e);console.log(i)}function Bc(){z()||Ct({version:$i(),projectName:me(null)})}function Vc(e){return z()?null:bn(e).start()}function Hc(e){return z()?null:new Tn(e).start()}function $(e){e&&typeof e.stop==`function`&&e.stop()}function Uc(e,t=null){e&&typeof e.succeed==`function`&&(t?e.succeed(t):e.succeed())}function Wc(e,t=null){e&&typeof e.fail==`function`&&(t?e.fail(t):e.fail())}function Gc(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?V.red:e<50||e<75?V.yellow:V.green;let l=c(`█`.repeat(i)),u=Q.muted(`─`.repeat(o)),d=``;if(n&&s>0){let e={pending:e=>V.yellow(`░`.repeat(e)),"in-progress":e=>Q.active(`▓`.repeat(e)),blocked:e=>V.red(`!`.repeat(e)),review:e=>V.magenta(`▒`.repeat(e))},t=Object.entries(n).filter(([e])=>![`deferred`,`cancelled`,`done`,`completed`].includes(e)).reduce((e,[t,n])=>e+n,0);if(t<=0)d=Q.muted(`░`.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]||(e=>Q.muted(`░`.repeat(e)));d+=c(o),r+=o}r<s&&(d+=Q.muted(`░`.repeat(s-r)))}}else d=Q.muted(`░`.repeat(s));let f=e===100?V.green:r===100?Q.muted:c;return`${l}${u}${d} ${f(`${r.toFixed(0)}%`)}`}function Kc(e,t=!1){if(!e)return Q.muted(`? unknown`);let n={done:{color:V.green,icon:`✓`,tableIcon:`✓`},completed:{color:V.green,icon:`✓`,tableIcon:`✓`},pending:{color:V.yellow,icon:`○`,tableIcon:`⏱`},"in-progress":{color:Q.active,icon:`▶`,tableIcon:`▶`},deferred:{color:Q.muted,icon:`x`,tableIcon:`⏱`},blocked:{color:V.red,icon:`!`,tableIcon:`✗`},review:{color:V.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:Q.muted,icon:`x`,tableIcon:`x`}}[e.toLowerCase()]||{color:V.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 qc(e,t,n=!1,r=null){return!e||!Array.isArray(e)||e.length===0?n?Q.muted(`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=k(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?V.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?V.green.bold(i):c?V.yellow.bold(i):V.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?V.red(`${i} (Not found)`):`${i} (Not found)`;let l=c.subtasks.find(e=>e.id===s);if(!l)return n?V.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?V.green.bold(i):f?Q.active.bold(i):V.red.bold(i):i}let a=k(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!a)return n?V.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?V.green.bold(i):c?V.yellow.bold(i):V.red.bold(i):i}).join(`, `)}function Jc(){let e=process.stdout.columns||100;console.log(K(V.bold(`TaskGraph CLI`),{padding:1,borderColor:Fc,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 TaskGraph 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)`},{name:`completion --install`,args:``,desc:`Set up Tab completion for your shell`}]},{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 (${Zi.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:`graph`,args:`[--id=<id>]`,desc:`Show tasks as a dependency tree, with the next task marked`},{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(K(V[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=Math.max(25,Math.floor(e*.2)),r=Math.max(40,Math.floor(e*.35)),i=Math.max(45,Math.floor(e*.45)-10),a=new J({colWidths:[n,r,i],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)=>{a.push([`${V.yellow.bold(e.name)}${V.reset(``)}`,`${V.reset(e.args)}${V.reset(``)}`,`${V.dim(e.desc)}${V.reset(``)}`])}),console.log(a.toString()),console.log(``)}),console.log(K(V.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=Math.max(30,Math.floor(t*.25)),r=Math.max(50,Math.floor(t*.45)),i=Math.max(30,Math.floor(t*.3)-10),a=new J({colWidths:[n,r,i],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});a.push([`${V.yellow(D)}${V.reset(``)}`,`${V.reset(`AI model configuration file (project root)`)}${V.reset(``)}`,`${V.dim(`Managed by models cmd`)}${V.reset(``)}`],[`${V.yellow(`Claude Code`)}${V.reset(``)}`,`${V.reset(`Install and sign in to Claude Code (no API keys needed)`)}${V.reset(``)}`,`${V.dim(`Required on PATH`)}${V.reset(``)}`]),console.log(a.toString()),console.log(``),console.log(K(V.bold(`Quick Start:`)+`
1226
+
1227
+ `+V.cyan(`1. Create Project: `)+V.reset(`taskgraph init`)+`
1228
+ `+V.cyan(`2. Setup Models: `)+V.reset(`taskgraph models --setup`)+`
1229
+ `+V.cyan(`3. Parse PRD: `)+V.reset(`taskgraph parse-prd --input=<prd-file>`)+`
1230
+ `+V.cyan(`4. List Tasks: `)+V.reset(`taskgraph list`)+`
1231
+ `+V.cyan(`5. Find Next Task: `)+V.reset(`taskgraph next`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1},width:Math.min(t-10,100)}))}function Yc(e){return e<=3?V.green(`● ${e}`):e<=6?V.yellow(`● ${e}`):V.red(`● ${e}`)}async function Xc(e){if(!G.existsSync(e)){console.log(K(V.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=Ie.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(V.cyan(`Generate complexity report? (y/n): `),e)});if(t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`){console.log(V.cyan(`Generating complexity report...`));let t=M;return G.existsSync(t)?(await La({output:e,research:!1,file:t}),Xc(e)):(console.error(`✗ No tasks.json file found. Please run "taskgraph init" or create a tasks.json file.`),null)}console.log(V.yellow(`Report generation cancelled.`));return}let t;try{t=JSON.parse(G.readFileSync(e,`utf8`))}catch(e){L(`error`,`Error reading complexity report: ${e.message}`);return}console.log(K(V.bold(`Task Complexity Analysis Report`),{padding:1,borderColor:Fc,borderStyle:`round`,margin:{top:1,bottom:1}}));let n=new J({style:{head:[],border:[],"padding-top":0,"padding-bottom":0,compact:!0},chars:{mid:``,"left-mid":``,"mid-mid":``,"right-mid":``},colWidths:[20,50]});n.push([V.cyan.bold(`Generated:`),new Date(t.meta.generatedAt).toLocaleString()],[V.cyan.bold(`Tasks Analyzed:`),t.meta.tasksAnalyzed],[V.cyan.bold(`Threshold Score:`),t.meta.thresholdScore],[V.cyan.bold(`Project:`),t.meta.projectName],[V.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 s=Math.round(o[0]/r.length*100),c=Math.round(o[1]/r.length*100),l=Math.round(o[2]/r.length*100);console.log(K(V.bold(`Complexity Distribution
1232
+
1233
+ `)+`${V.green.bold(`Low (1-4):`)} ${o[0]} tasks (${s}%)\n${V.yellow.bold(`Medium (5-7):`)} ${o[1]} tasks (${c}%)\n${V.red.bold(`High (8-10):`)} ${o[2]} tasks (${l}%)`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1,bottom:1}}));let u=process.stdout.columns||100,d=Math.floor(u*.25),f=u-12-d-8-8-10,p=new J({head:[V.yellow.bold(`ID`),V.yellow.bold(`Title`),V.yellow.bold(`Score`),V.yellow.bold(`Subtasks`),V.yellow.bold(`Expansion Command`)],colWidths:[12,d,8,8,f],style:{head:[],border:[]},wordWrap:!0,wrapOnWordBoundary:!0});if(i.forEach(e=>{let t=`taskgraph expand --id=${e.taskId} --num=${e.recommendedSubtasks}${e.expansionPrompt?` --prompt="${e.expansionPrompt}"`:``}`;p.push([e.taskId,R(e.taskTitle,d-3),Yc(e.complexityScore),e.recommendedSubtasks,V.cyan(t)])}),console.log(p.toString()),a.length>0){console.log(K(V.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 J({head:[V.green.bold(`ID`),V.green.bold(`Title`),V.green.bold(`Score`),V.green.bold(`Reasoning`)],colWidths:[5,40,8,50],style:{head:[],border:[]}});a.forEach(t=>{e.push([t.taskId,R(t.taskTitle,37),Yc(t.complexityScore),R(t.reasoning,47)])}),console.log(e.toString())}console.log(K(V.bold(`Suggested Actions:`)+`
1234
+
1235
+ ${V.cyan(`1.`)} Expand all complex tasks: ${V.yellow(`taskgraph expand --all`)}\n${V.cyan(`2.`)} Expand a specific task: ${V.yellow(`taskgraph expand --id=<id>`)}\n${V.cyan(`3.`)} Regenerate with research: ${V.yellow(`taskgraph analyze-complexity --research`)}`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}}))}async function Zc(e){console.log(K(V.yellow(`It looks like you've already generated tasks for this project.
1236
+ `)+V.yellow(`Executing this command will overwrite any existing tasks.`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=Ie.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(V.cyan(`Are you sure you wish to continue? (y/N): `),e)});return t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`}const Qc=(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=Q.muted(`☆☆☆`);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]?V.yellow(`★★★`):e>=r[n]?V.yellow(`★★`)+Q.muted(`☆`):V.yellow(`★`)+Q.muted(`☆☆`)}return`${n} ${a}`},$c=e=>{if(!e)return`N/A`;if(e.input===0&&e.output===0)return V.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(V.cyan.bold(`
1237
+ Active Model Configuration:`));let n=e.activeModels,r=new J({head:[`Role`,`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>V.cyan.bold(e)),colWidths:[10,14,30,18,20],style:{head:[`cyan`,`bold`],border:Ic}});r.push([V.reset(`Main`),n.main.provider,n.main.modelId,Qc(n.main.sweScore,t),$c(n.main.cost)]),r.push([V.reset(`Research`),n.research.provider,n.research.modelId,Qc(n.research.sweScore,t),$c(n.research.cost)]),n.fallback&&n.fallback.provider&&n.fallback.modelId?r.push([V.reset(`Fallback`),n.fallback.provider,n.fallback.modelId,Qc(n.fallback.sweScore,t),$c(n.fallback.cost)]):r.push([V.reset(`Fallback`),Q.muted(`-`),Q.muted(`(Not Set)`),Q.muted(`-`),Q.muted(`-`)]),console.log(r.toString())}function tl(e){if(!e||e.length===0){console.log(Q.muted(`
1238
+ (No other models available or all are configured)`));return}console.log(V.cyan.bold(`
1239
+ Other Available Models:`));let t=new J({head:[`Provider`,`Model ID`,`SWE Score`,`Cost ($/1M tkns)`].map(e=>V.cyan.bold(e)),colWidths:[15,40,18,25],style:{head:[`cyan`,`bold`],border:Ic}});e.forEach(n=>{t.push([n.provider,n.modelId,Qc(n.sweScore,e),$c(n.cost)])}),console.log(t.toString()),console.log(K(V.bold(`Next Steps:`)+`
1240
+ `+V.cyan(`1. Set main model: ${V.yellow(`taskgraph models --set-main <model_id>`)}`)+`
1241
+ `+V.cyan(`2. Set research model: ${V.yellow(`taskgraph models --set-research <model_id>`)}`)+`
1242
+ `+V.cyan(`3. Set fallback model: ${V.yellow(`taskgraph models --set-fallback <model_id>`)}`)+`
1243
+ `+V.cyan(`4. Run interactive setup: ${V.yellow(`taskgraph models --setup`)}`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}))}function nl(e,t=`cli`){if(t!==`cli`&&t!==`text`||!e||z())return;let n=Ln(e);n&&console.log(`\n${Q.muted(n)}`)}function rl(e,t,n){if(z()||!e)return;let{highRelevance:r,mediumRelevance:i,recentTasks:a,allRelevantTasks:o}=e,s=V.bold(`Context Analysis`)+`
1244
+
1245
+ `;s+=Q.muted(`Query: `)+V.reset(`"${t}"`)+`
1246
+ `,s+=Q.muted(`Context size: `)+V.cyan(`${n.toLocaleString()} characters`)+`
1247
+ `,s+=Q.muted(`Tasks found: `)+V.yellow(`${o.length} relevant tasks`)+`
1248
+
1249
+ `,r.length>0&&(s+=V.green.bold(`High relevance matches:`)+`
1250
+ `,r.slice(0,3).forEach(e=>{s+=V.green(` • Task ${e.id}: ${R(e.title,50)}`)+`
1251
+ `}),r.length>3&&(s+=V.green(` • ... and ${r.length-3} more high relevance tasks`)+`
1261
1252
  `),s+=`
1262
- `),i.length>0&&(s+=H.yellow.bold(`Medium relevance matches:`)+`
1263
- `,i.slice(0,3).forEach(e=>{s+=H.yellow(` • Task ${e.id}: ${z(e.title,50)}`)+`
1264
- `}),i.length>3&&(s+=H.yellow(` • ... and ${i.length-3} more medium relevance tasks`)+`
1253
+ `),i.length>0&&(s+=V.yellow.bold(`Medium relevance matches:`)+`
1254
+ `,i.slice(0,3).forEach(e=>{s+=V.yellow(` • Task ${e.id}: ${R(e.title,50)}`)+`
1255
+ `}),i.length>3&&(s+=V.yellow(` • ... and ${i.length-3} more medium relevance tasks`)+`
1265
1256
  `),s+=`
1266
- `);let c=a.filter(e=>!r.some(t=>t.id===e.id)&&!i.some(t=>t.id===e.id));c.length>0&&(s+=H.cyan.bold(`Recent tasks (for context):`)+`
1267
- `,c.slice(0,2).forEach(e=>{s+=H.cyan(` • Task ${e.id}: ${z(e.title,50)}`)+`
1268
- `}),c.length>2&&(s+=H.cyan(` • ... and ${c.length-2} more recent tasks`)+`
1269
- `)),console.log(q(s,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0},borderStyle:`round`,borderColor:wc,title:H.cyan(`Context gathering`),titleAlignment:`center`}))}function qc(e,t,n,r){console.log(H.red(`\n✗ Cannot move tasks from "${t}" to "${n}"`)),console.log(H.yellow(`
1270
- Cross-tag dependency conflicts detected:`)),e.length>0&&e.forEach(e=>{console.log(` • ${e.message}`)}),console.log(H.cyan(`
1271
- Resolution options:`)),console.log(` 1. Move with dependencies: taskgraph move --from=${r} --from-tag=${t} --to-tag=${n} --with-dependencies`),console.log(` 2. Break dependencies: taskgraph move --from=${r} --from-tag=${t} --to-tag=${n} --ignore-dependencies`),console.log(` 3. Validate and fix dependencies: taskgraph validate-dependencies && taskgraph fix-dependencies`),e.length>0&&console.log(` 4. Move dependencies first: taskgraph move --from=${e.map(e=>e.dependencyId).join(`,`)} --from-tag=${e[0].dependencyTag} --to-tag=${n}`)}function Jc(e){return e===null?`null`:e===void 0?`undefined`:e===``?`(empty)`:N(e)||`unknown`}function Yc(e,t,n){let r=Jc(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(H.yellow(`\n⚠ Warning: Unexpected taskId format "${i}". Using as-is for command suggestions.`)),a=i)}console.log(H.red(`\n✗ Cannot move subtask ${r} directly between tags`)),console.log(H.yellow(`
1272
- 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(H.cyan(`
1273
- Resolution options:`)),console.log(` 1. Promote subtask to full task: taskgraph remove-subtask --id=${r} --convert`),console.log(` 2. Then move the promoted task: taskgraph move --from=${a} --from-tag=${t} --to-tag=${n}`),console.log(` 3. Or move the parent task with all subtasks: taskgraph move --from=${a} --from-tag=${t} --to-tag=${n} --with-dependencies`)}function Xc(e,t,n){console.log(H.red(`
1274
- ✗ Invalid tag combination`)),console.log(H.yellow(`
1275
- Error details:`)),console.log(` • Source tag: "${e}"`),console.log(` • Target tag: "${t}"`),console.log(` • Reason: ${n}`),console.log(H.cyan(`
1276
- Resolution options:`)),console.log(` 1. Use different tags for cross-tag moves`),console.log(` 2. Use within-tag move: taskgraph move --from=<id> --to=<id> --tag=${e}`),console.log(` 3. Check available tags: taskgraph tags`)}function Zc(e=`general`){let t={"before-move":[`Tip: Run "taskgraph validate-dependencies" to check for dependency issues before moving tasks`,`Tip: Use "taskgraph fix-dependencies" to automatically resolve common dependency problems`,`Tip: Consider using --with-dependencies flag to move dependent tasks together`],"after-error":[`Quick fix: Run "taskgraph validate-dependencies" to identify specific issues`,`Quick fix: Use "taskgraph fix-dependencies" to automatically resolve problems`,`Quick fix: Check "taskgraph show <id>" to see task dependencies before moving`],general:[`Tip: Use "taskgraph validate-dependencies" to check for dependency issues`,`Tip: Use "taskgraph fix-dependencies" to automatically resolve problems`,`Tip: Use "taskgraph show <id>" to view task dependencies`,`Tip: Use --with-dependencies flag to move dependent tasks together`]},n=t[e]||t.general;console.log(H.cyan(`
1277
- Helpful hints:`)),new Set(n).forEach(e=>{console.log(` ${e}`)})}var Qc=class extends Error{constructor(e,t,n={}){super(t),this.name=`DependencyError`,this.code=e,this.data=n}};const $c={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 el(e,t,n,r={}){L(`info`,`Adding dependency ${n} to task ${t}...`);let i=F(e,r.projectRoot,r.tag);(!i||!i.tasks)&&(L(`error`,`No valid tasks found in tasks.json`),process.exit(1));let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=N(n);fe(i.tasks,o)||(L(`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||(L(`error`,`Parent task ${e} not found.`),process.exit(1)),n.subtasks||(L(`error`,`Parent task ${e} has no subtasks.`),process.exit(1)),s=n.subtasks.find(e=>e.id===t),s||(L(`error`,`Subtask ${a} not found.`),process.exit(1))}else s=i.tasks.find(e=>e.id===a),s||(L(`error`,`Task ${a} not found.`),process.exit(1));if(s.dependencies||(s.dependencies=[]),s.dependencies.some(e=>String(e)===String(o))){L(`warn`,`Dependency ${o} already exists in task ${a}.`);return}String(a)===String(o)&&(L(`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,L(`debug`,`Adding dependency between subtasks: ${a} depends on ${o}`),L(`debug`,`Parent IDs: ${e} and ${t}, Self-dependency check: ${c}`)}c&&(L(`error`,`Subtask ${a} cannot depend on itself.`),process.exit(1));let l=[a];nl(i.tasks,o,l)?(L(`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}return typeof e==`number`?-1:1}),I(e,i,r.projectRoot,r.tag),L(`success`,`Added dependency ${o} to task ${a}`),B()||console.log(q(H.green(`Successfully added dependency:
1257
+ `);let c=a.filter(e=>!r.some(t=>t.id===e.id)&&!i.some(t=>t.id===e.id));c.length>0&&(s+=V.cyan.bold(`Recent tasks (for context):`)+`
1258
+ `,c.slice(0,2).forEach(e=>{s+=V.cyan(` • Task ${e.id}: ${R(e.title,50)}`)+`
1259
+ `}),c.length>2&&(s+=V.cyan(` • ... and ${c.length-2} more recent tasks`)+`
1260
+ `)),console.log(K(s,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0},borderStyle:`round`,borderColor:Fc,title:V.cyan(`Context gathering`),titleAlignment:`center`}))}function il(e,t,n,r){console.log(V.red(`\n✗ Cannot move tasks from "${t}" to "${n}"`)),console.log(V.yellow(`
1261
+ Cross-tag dependency conflicts detected:`)),e.length>0&&e.forEach(e=>{console.log(` • ${e.message}`)}),console.log(V.cyan(`
1262
+ Resolution options:`)),console.log(` 1. Move with dependencies: taskgraph move --from=${r} --from-tag=${t} --to-tag=${n} --with-dependencies`),console.log(` 2. Break dependencies: taskgraph move --from=${r} --from-tag=${t} --to-tag=${n} --ignore-dependencies`),console.log(` 3. Validate and fix dependencies: taskgraph validate-dependencies && taskgraph fix-dependencies`),e.length>0&&console.log(` 4. Move dependencies first: taskgraph move --from=${e.map(e=>e.dependencyId).join(`,`)} --from-tag=${e[0].dependencyTag} --to-tag=${n}`)}function al(e){return e===null?`null`:e===void 0?`undefined`:e===``?`(empty)`:N(e)||`unknown`}function ol(e,t,n){let r=al(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(V.yellow(`\n⚠ Warning: Unexpected taskId format "${i}". Using as-is for command suggestions.`)),a=i)}console.log(V.red(`\n✗ Cannot move subtask ${r} directly between tags`)),console.log(V.yellow(`
1263
+ 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(V.cyan(`
1264
+ Resolution options:`)),console.log(` 1. Promote subtask to full task: taskgraph remove-subtask --id=${r} --convert`),console.log(` 2. Then move the promoted task: taskgraph move --from=${a} --from-tag=${t} --to-tag=${n}`),console.log(` 3. Or move the parent task with all subtasks: taskgraph move --from=${a} --from-tag=${t} --to-tag=${n} --with-dependencies`)}function sl(e,t,n){console.log(V.red(`
1265
+ ✗ Invalid tag combination`)),console.log(V.yellow(`
1266
+ Error details:`)),console.log(` • Source tag: "${e}"`),console.log(` • Target tag: "${t}"`),console.log(` • Reason: ${n}`),console.log(V.cyan(`
1267
+ Resolution options:`)),console.log(` 1. Use different tags for cross-tag moves`),console.log(` 2. Use within-tag move: taskgraph move --from=<id> --to=<id> --tag=${e}`),console.log(` 3. Check available tags: taskgraph tags`)}function cl(e=`general`){let t={"before-move":[`Tip: Run "taskgraph validate-dependencies" to check for dependency issues before moving tasks`,`Tip: Use "taskgraph fix-dependencies" to automatically resolve common dependency problems`,`Tip: Consider using --with-dependencies flag to move dependent tasks together`],"after-error":[`Quick fix: Run "taskgraph validate-dependencies" to identify specific issues`,`Quick fix: Use "taskgraph fix-dependencies" to automatically resolve problems`,`Quick fix: Check "taskgraph show <id>" to see task dependencies before moving`],general:[`Tip: Use "taskgraph validate-dependencies" to check for dependency issues`,`Tip: Use "taskgraph fix-dependencies" to automatically resolve problems`,`Tip: Use "taskgraph show <id>" to view task dependencies`,`Tip: Use --with-dependencies flag to move dependent tasks together`]},n=t[e]||t.general;console.log(V.cyan(`
1268
+ Helpful hints:`)),new Set(n).forEach(e=>{console.log(` ${e}`)})}const ll="Run `taskgraph list` to see task IDs",ul="Create some with `taskgraph parse-prd <file>`";function dl(e,t){z()?L(`error`,e):ht(e,t),process.exit(1)}var fl=class extends Error{constructor(e,t,n={}){super(t),this.name=`DependencyError`,this.code=e,this.data=n}};const pl={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 ml(e,t,n,r={}){L(`info`,`Adding dependency ${n} to task ${t}...`);let i=F(e,r.projectRoot,r.tag);(!i||!i.tasks)&&dl(`No tasks yet`,ul);let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=N(n);fe(i.tasks,o)||dl(`Task ${o} not found`,ll);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||dl(`Task ${e} not found`,ll),n.subtasks||dl(`Task ${e} has no subtasks`,`Add some with \`taskgraph expand --id=${e}\``),s=n.subtasks.find(e=>e.id===t),s||dl(`Subtask ${a} not found`,ll)}else s=i.tasks.find(e=>e.id===a),s||dl(`Task ${a} not found`,ll);if(s.dependencies||(s.dependencies=[]),s.dependencies.some(e=>String(e)===String(o))){L(`warn`,`Dependency ${o} already exists in task ${a}.`);return}String(a)===String(o)&&dl(`Task ${a} can't depend on itself`);let c=!1;if(typeof a==`string`&&typeof o==`string`&&a.includes(`.`)&&o.includes(`.`)){let[e]=a.split(`.`),[t]=o.split(`.`);c=a===o,L(`debug`,`Adding dependency between subtasks: ${a} depends on ${o}`),L(`debug`,`Parent IDs: ${e} and ${t}, Self-dependency check: ${c}`)}c&&dl(`Subtask ${a} can't depend on itself`);let l=[a];gl(i.tasks,o,l)?dl(`That would make a loop: task ${o} already depends on task ${a}`,"Run `taskgraph graph` to see how they connect"):(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}return typeof e==`number`?-1:1}),I(e,i,r.projectRoot,r.tag),L(`success`,`Added dependency ${o} to task ${a}`),z()||console.log(K(V.green(`Successfully added dependency:
1278
1269
 
1279
- `)+`Task ${H.bold(a)} now depends on ${H.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),L(`info`,`Task files regenerated with updated dependencies.`))}async function tl(e,t,n,r={}){L(`info`,`Removing dependency ${n} from task ${t}...`);let i=F(e,r.projectRoot,r.tag);(!i||!i.tasks)&&(L(`error`,`No valid tasks found.`),process.exit(1));let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=N(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||(L(`error`,`Parent task ${e} not found.`),process.exit(1)),n.subtasks||(L(`error`,`Parent task ${e} has no subtasks.`),process.exit(1)),s=n.subtasks.find(e=>e.id===t),c=!0,s||(L(`error`,`Subtask ${a} not found.`),process.exit(1))}else s=i.tasks.find(e=>e.id===a),s||(L(`error`,`Task ${a} not found.`),process.exit(1));if(!s.dependencies||s.dependencies.length===0){L(`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});u===-1?L(`info`,`Task ${a} does not depend on ${o}, no changes made.`):(s.dependencies.splice(u,1),I(e,i,r.projectRoot,r.tag),L(`success`,`Removed dependency: Task ${a} no longer depends on ${o}`),B()||console.log(q(H.green(`Successfully removed dependency:
1270
+ `)+`Task ${V.bold(a)} now depends on ${V.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})),L(`info`,`Task files regenerated with updated dependencies.`))}async function hl(e,t,n,r={}){L(`info`,`Removing dependency ${n} from task ${t}...`);let i=F(e,r.projectRoot,r.tag);(!i||!i.tasks)&&dl(`No tasks yet`,ul);let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=N(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||dl(`Task ${e} not found`,ll),n.subtasks||dl(`Task ${e} has no subtasks`,`Add some with \`taskgraph expand --id=${e}\``),s=n.subtasks.find(e=>e.id===t),c=!0,s||dl(`Subtask ${a} not found`,ll)}else s=i.tasks.find(e=>e.id===a),s||dl(`Task ${a} not found`,ll);if(!s.dependencies||s.dependencies.length===0){L(`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});u===-1?L(`info`,`Task ${a} does not depend on ${o}, no changes made.`):(s.dependencies.splice(u,1),I(e,i,r.projectRoot,r.tag),L(`success`,`Removed dependency: Task ${a} no longer depends on ${o}`),z()||console.log(K(V.green(`Successfully removed dependency:
1280
1271
 
1281
- `)+`Task ${H.bold(a)} no longer depends on ${H.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 rl(e){let t=[];return e.forEach(n=>{n.dependencies&&(n.dependencies.forEach(r=>{String(r)===String(n.id)?t.push({type:`self`,taskId:n.id,message:`Task ${n.id} depends on itself`}):fe(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=>{String(n)===String(i)||typeof n==`number`&&n===r.id?t.push({type:`self`,taskId:i,message:`Subtask ${i} depends on itself`}):fe(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 il(e,t={}){let{context:n={}}=t;L(`info`,`Checking for invalid dependencies in task files...`);let r=F(e,n.projectRoot,n.tag);(!r||!r.tasks)&&(L(`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)}),L(`info`,`Analyzing dependencies for ${i} tasks and ${a} subtasks...`);try{let e=rl(r.tasks);e.valid?(L(`success`,`No invalid dependencies found - all dependencies are valid`),B()||console.log(q(H.green(`All Dependencies Are Valid
1272
+ `)+`Task ${V.bold(a)} no longer depends on ${V.bold(o)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1}})))}function gl(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}`),gl(e,n,o)})}function _l(e){let t=[];return e.forEach(n=>{n.dependencies&&(n.dependencies.forEach(r=>{String(r)===String(n.id)?t.push({type:`self`,taskId:n.id,message:`Task ${n.id} depends on itself`}):fe(e,r)||t.push({type:`missing`,taskId:n.id,dependencyId:r,message:`Task ${n.id} depends on non-existent task ${r}`})}),gl(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=>{String(n)===String(i)||typeof n==`number`&&n===r.id?t.push({type:`self`,taskId:i,message:`Subtask ${i} depends on itself`}):fe(e,n)||t.push({type:`missing`,taskId:i,dependencyId:n,message:`Subtask ${i} depends on non-existent task/subtask ${n}`})}),gl(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;L(`info`,`Checking for invalid dependencies in task files...`);let r=F(e,n.projectRoot,n.tag);(!r||!r.tasks)&&(L(`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)}),L(`info`,`Analyzing dependencies for ${i} tasks and ${a} subtasks...`);try{let e=_l(r.tasks);e.valid?(L(`success`,`No invalid dependencies found - all dependencies are valid`),z()||console.log(K(V.green(`All Dependencies Are Valid
1282
1273
 
1283
- `)+`${H.cyan(`Tasks checked:`)} ${i}\n${H.cyan(`Subtasks checked:`)} ${a}\n${H.cyan(`Total dependencies verified:`)} ${al(r.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(L(`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})`),L(`error`,t)}),B()||console.log(q(H.red(`Dependency Validation FAILED
1274
+ `)+`${V.cyan(`Tasks checked:`)} ${i}\n${V.cyan(`Subtasks checked:`)} ${a}\n${V.cyan(`Total dependencies verified:`)} ${yl(r.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(L(`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})`),L(`error`,t)}),z()||console.log(K(V.red(`Dependency Validation FAILED
1284
1275
 
1285
- `)+`${H.cyan(`Tasks checked:`)} ${i}\n${H.cyan(`Subtasks checked:`)} ${a}\n${H.red(`Issues found:`)} ${e.issues.length}`,{padding:1,borderColor:`red`,borderStyle:`round`,margin:{top:1,bottom:1}})))}catch(e){L(`error`,`Error validating dependencies:`,e),process.exit(1)}}function al(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 ol(e,t={}){let{context:n={}}=t;L(`info`,`Checking for and fixing invalid dependencies in tasks.json...`);try{let t=F(e,n.projectRoot,n.tag);(!t||!t.tasks)&&(L(`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=/* @__PURE__ */ new Set,n=e.dependencies.length;e.dependencies=e.dependencies.filter(n=>{let r=String(n);return t.has(r)?(L(`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=/* @__PURE__ */ 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)?(L(`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=/* @__PURE__ */ 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:(L(`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:(L(`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)&&(t.dependencies=t.dependencies.filter(t=>(typeof t==`number`&&t<100?`${e.id}.${t}`:String(t))!==r||(L(`info`,`Removing self-dependency from subtask ${r}`),i.selfDependenciesRemoved++,!1))),t.dependencies=t.dependencies.filter(t=>{if(typeof t==`string`&&t.includes(`.`))return o.has(t)?!0:(L(`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:(L(`info`,`Removing invalid subtask dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}return a.has(n)?!0:(L(`info`,`Removing invalid task dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}),t.dependencies.length<n&&i.subtasksFixed++}})}),L(`info`,`Checking for circular dependencies...`);let s=/* @__PURE__ */ 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=A(e,s,/* @__PURE__ */ new Set,/* @__PURE__ */ 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)?(L(`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)?L(`info`,`No changes needed to fix dependencies`):(I(e,t,n.projectRoot,n.tag),L(`success`,`Fixed dependency issues in tasks.json`),L(`info`,`Regenerating task files to reflect dependency changes...`));let c=i.nonExistentDependenciesRemoved+i.selfDependenciesRemoved+i.duplicateDependenciesRemoved+i.circularDependenciesFixed;B()||(c>0?(L(`success`,`Fixed ${c} dependency issues in total!`),console.log(q(H.green(`Dependency Fixes Summary:
1276
+ `)+`${V.cyan(`Tasks checked:`)} ${i}\n${V.cyan(`Subtasks checked:`)} ${a}\n${V.red(`Issues found:`)} ${e.issues.length}`,{padding:1,borderColor:`red`,borderStyle:`round`,margin:{top:1,bottom:1}})))}catch(e){L(`error`,`Error validating dependencies:`,e),process.exit(1)}}function yl(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 bl(e,t={}){let{context:n={}}=t;L(`info`,`Checking for and fixing invalid dependencies in tasks.json...`);try{let t=F(e,n.projectRoot,n.tag);(!t||!t.tasks)&&(L(`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=/* @__PURE__ */ new Set,n=e.dependencies.length;e.dependencies=e.dependencies.filter(n=>{let r=String(n);return t.has(r)?(L(`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=/* @__PURE__ */ 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)?(L(`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=/* @__PURE__ */ 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:(L(`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:(L(`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)&&(t.dependencies=t.dependencies.filter(t=>(typeof t==`number`&&t<100?`${e.id}.${t}`:String(t))!==r||(L(`info`,`Removing self-dependency from subtask ${r}`),i.selfDependenciesRemoved++,!1))),t.dependencies=t.dependencies.filter(t=>{if(typeof t==`string`&&t.includes(`.`))return o.has(t)?!0:(L(`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:(L(`info`,`Removing invalid subtask dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}return a.has(n)?!0:(L(`info`,`Removing invalid task dependency from subtask ${r}: ${n}`),i.nonExistentDependenciesRemoved++,!1)}),t.dependencies.length<n&&i.subtasksFixed++}})}),L(`info`,`Checking for circular dependencies...`);let s=/* @__PURE__ */ 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=A(e,s,/* @__PURE__ */ new Set,/* @__PURE__ */ 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)?(L(`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)?L(`info`,`No changes needed to fix dependencies`):(I(e,t,n.projectRoot,n.tag),L(`success`,`Fixed dependency issues in tasks.json`),L(`info`,`Regenerating task files to reflect dependency changes...`));let c=i.nonExistentDependenciesRemoved+i.selfDependenciesRemoved+i.duplicateDependenciesRemoved+i.circularDependenciesFixed;z()||(c>0?(L(`success`,`Fixed ${c} dependency issues in total!`),console.log(K(V.green(`Dependency Fixes Summary:
1286
1277
 
1287
- `)+`${H.cyan(`Invalid dependencies removed:`)} ${i.nonExistentDependenciesRemoved}\n${H.cyan(`Self-dependencies removed:`)} ${i.selfDependenciesRemoved}\n${H.cyan(`Duplicate dependencies removed:`)} ${i.duplicateDependenciesRemoved}\n${H.cyan(`Circular dependencies fixed:`)} ${i.circularDependenciesFixed}\n\n${H.cyan(`Tasks fixed:`)} ${i.tasksFixed}\n${H.cyan(`Subtasks fixed:`)} ${i.subtasksFixed}\n`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(L(`success`,`No dependency issues found - all dependencies are valid`),console.log(q(H.green(`All Dependencies Are Valid
1278
+ `)+`${V.cyan(`Invalid dependencies removed:`)} ${i.nonExistentDependenciesRemoved}\n${V.cyan(`Self-dependencies removed:`)} ${i.selfDependenciesRemoved}\n${V.cyan(`Duplicate dependencies removed:`)} ${i.duplicateDependenciesRemoved}\n${V.cyan(`Circular dependencies fixed:`)} ${i.circularDependenciesFixed}\n\n${V.cyan(`Tasks fixed:`)} ${i.tasksFixed}\n${V.cyan(`Subtasks fixed:`)} ${i.subtasksFixed}\n`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))):(L(`success`,`No dependency issues found - all dependencies are valid`),console.log(K(V.green(`All Dependencies Are Valid
1288
1279
 
1289
- `)+`${H.cyan(`Tasks checked:`)} ${t.tasks.length}\n${H.cyan(`Total dependencies verified:`)} ${al(t.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))))}catch(e){L(`error`,`Error in fix-dependencies command:`,e),process.exit(1)}}function sl(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 cl(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=sl(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=sl(e,r,n,!1)}}return i}function ll(e,t,n){let r=[];return!Array.isArray(e.dependencies)||e.dependencies.length===0||e.dependencies.filter(e=>e!=null).forEach(i=>{let a=cl(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 ul(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=ll(e,n,r);i.push(...t)}),i}function dl(e,t,n){if(!e||typeof e!=`string`)throw new Qc($c.INVALID_TASK_ID,`Task ID must be a valid string`);if(!t||typeof t!=`string`)throw new Qc($c.INVALID_SOURCE_TAG,`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw new Qc($c.INVALID_TARGET_TAG,`Target tag must be a valid string`);if(e.includes(`.`))throw new Qc($c.CANNOT_MOVE_SUBTASK,`Cannot move subtask ${e} directly between tags.
1280
+ `)+`${V.cyan(`Tasks checked:`)} ${t.tasks.length}\n${V.cyan(`Total dependencies verified:`)} ${yl(t.tasks)}`,{padding:1,borderColor:`green`,borderStyle:`round`,margin:{top:1,bottom:1}}))))}catch(e){L(`error`,`Error in fix-dependencies command:`,e),process.exit(1)}}function xl(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 Sl(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=xl(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=xl(e,r,n,!1)}}return i}function Cl(e,t,n){let r=[];return!Array.isArray(e.dependencies)||e.dependencies.length===0||e.dependencies.filter(e=>e!=null).forEach(i=>{let a=Sl(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 wl(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=Cl(e,n,r);i.push(...t)}),i}function Tl(e,t,n){if(!e||typeof e!=`string`)throw new fl(pl.INVALID_TASK_ID,`Task ID must be a valid string`);if(!t||typeof t!=`string`)throw new fl(pl.INVALID_SOURCE_TAG,`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw new fl(pl.INVALID_TARGET_TAG,`Target tag must be a valid string`);if(e.includes(`.`))throw new fl(pl.CANNOT_MOVE_SUBTASK,`Cannot move subtask ${e} directly between tags.
1290
1281
 
1291
1282
  First promote it to a full task using:
1292
- taskgraph remove-subtask --id=${e} --convert`,{taskId:e,sourceTag:t,targetTag:n})}export{cr as $,Qs as A,Da as B,xc as C,_c as D,vc as E,no as F,zi as G,xa as H,Ma as I,Ai as J,ki as K,ja as L,Xs as M,Ys as N,uc as O,Ua as P,gr as Q,Aa as R,Sc as S,yc as T,Ui as U,Ea as V,Hi as W,pr as X,wi as Y,sr as Z,Dc as _,Ec as a,or as at,$ as b,Wc as c,Jn as ct,Oc as d,Z as dt,fr as et,Zc as f,dt as ft,Yc as g,Uc as h,il as i,dr as it,Zs as j,$s as k,zc as l,Kn as lt,Xc as m,ol as n,ur as nt,Bc as o,ar as ot,Lc as p,Oi as q,tl as r,hr as rt,kc as s,ir as st,el as t,mr as tt,qc as u,qn as ut,Fc as v,bc as w,Cc as x,Ac as y,ka as z};
1283
+ taskgraph remove-subtask --id=${e} --convert`,{taskId:e,sourceTag:t,targetTag:n})}export{yr as $,lc as A,Ra as B,Mc as C,Oc as D,kc as E,mo as F,Xi as G,Ma as H,Ua as I,Vi as J,Bi as K,Ha as L,sc as M,oc as N,xc as O,eo as P,Dr as Q,Va as R,Nc as S,Ac as T,ea as U,La as V,$i as W,wr as X,Fi as Y,vr as Z,Rc as _,Lc as a,_r as at,$ as b,tl as c,ar as ct,zc as d,wt as dt,Cr as et,cl as f,Y as ft,ol as g,el as h,vl as i,Sr as it,cc as j,uc as k,Xc as l,rr as lt,sl as m,ht as mt,bl as n,xr as nt,Zc as o,gr as ot,Jc as p,mt as pt,zi as q,hl as r,Er as rt,Bc as s,hr as st,ml as t,Tr as tt,il as u,ir as ut,Kc as v,jc as w,Pc as x,Vc as y,Ba as z};