taskgraph-ai 0.54.13 → 0.54.14
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.
- package/dist/ai-services-unified-COsdujxy.js +1 -0
- package/dist/{ai-services-unified-CKKHbOMd.js → ai-services-unified-CvcPXr89.js} +1 -1
- package/dist/{commands-D1h9ghuW.js → commands-C59cmYBr.js} +4 -4
- package/dist/config-manager-Cs19NriM.js +1 -0
- package/dist/{config-manager-DIET_FiX.js → config-manager-CtE1yo1I.js} +1 -1
- package/dist/{init-CrPu9Yzo.js → init-DXIlIKlc.js} +2 -2
- package/dist/mcp-server.js +2 -2
- package/dist/{research-BKnv5Fvo.js → research-CEiR5MKk.js} +1 -1
- package/dist/{research-D_nwZW-q.js → research-DcB3PdqA.js} +1 -1
- package/dist/{response-language-CnU32t1k.js → response-language-BdYSHT6o.js} +1 -1
- package/dist/response-language-Cve83SLc.js +1 -0
- package/dist/{src-Cs4ilbQ-.js → src-DvvdBXWU.js} +1 -1
- package/dist/{src-V29fsb6x.js → src-Dz_uZuYA.js} +1 -1
- package/dist/tag-management-BH0vY7RP.js +1 -0
- package/dist/{task-manager-Dzqb02tY.js → task-manager-C-lF7v2M.js} +2 -2
- package/dist/{task-manager-BlaCtMcL.js → task-manager-rfPalXaq.js} +1 -1
- package/dist/taskgraph.js +1 -1
- package/package.json +1 -1
- package/dist/ai-services-unified-BpwsoWsI.js +0 -1
- package/dist/config-manager-HsHpBhNF.js +0 -1
- package/dist/response-language-BfqpW3Bx.js +0 -1
- package/dist/tag-management-DfrkCVTV.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export{t as appendResearchToTask,n as performResearch}from"./research-
|
|
1
|
+
export{t as appendResearchToTask,n as performResearch}from"./research-DcB3PdqA.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{O as e}from"./src-
|
|
1
|
+
import{O as e}from"./src-DvvdBXWU.js";import{$ as t,G as n,J as r,K as i,Q as a,Y as o,dt as s,g as c,it as l,lt as u}from"./config-manager-CtE1yo1I.js";import{A as d,C as f,F as p,H as m,L as h,M as g,N as _,R as v,V as y,W as b,j as ee,w as x,z as S}from"./src-Dz_uZuYA.js";import{n as te}from"./ai-services-unified-CvcPXr89.js";import C from"chalk";import w from"path";import T from"fs";import E from"boxen";import D from"inquirer";import O from"readline";import k from"fuse.js";import A from"ajv";import j from"ajv-formats";import M from"gpt-tokens";const{theme:N,BORDER_COLOR:P}=x;function F(){return e||`unknown`}function I(){a()||b({version:F(),projectName:c(null)})}function L(e){!a()&&e&&e._migrationHappened&&console.log(E(C.bold(`FYI: `)+N.muted(`TaskGraph now supports separate task lists per tag. `)+C.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 R(e,t={}){if(a())return;let{skipIfMaster:n=!1,dim:r=!1}=t;if(n&&e===`master`)return;let i=r?N.muted(`[tag] ${e}`):C.dim(`[tag] `)+C.cyan(e);console.log(i)}function z(e){return a()?null:m(e).start()}function B(e){return a()?null:new y(e).start()}function V(e){e&&typeof e.stop==`function`&&e.stop()}function H(e,t=null){e&&typeof e.succeed==`function`&&(t?e.succeed(t):e.succeed())}function U(e,t=null){e&&typeof e.fail==`function`&&(t?e.fail(t):e.fail())}function W(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?C.red:e<50||e<75?C.yellow:C.green;let l=c(`█`.repeat(i)),u=N.muted(`─`.repeat(o)),d=``;if(n&&s>0){let e={pending:e=>C.yellow(`░`.repeat(e)),"in-progress":e=>N.active(`▓`.repeat(e)),blocked:e=>C.red(`!`.repeat(e)),review:e=>C.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=N.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=>N.muted(`░`.repeat(e)));d+=c(o),r+=o}r<s&&(d+=N.muted(`░`.repeat(s-r)))}}else d=N.muted(`░`.repeat(s));let f=e===100?C.green:r===100?N.muted:c;return`${l}${u}${d} ${f(`${r.toFixed(0)}%`)}`}function G(e,t=!1){if(!e)return N.muted(`? unknown`);let n={done:{color:C.green,icon:`✓`,tableIcon:`✓`},completed:{color:C.green,icon:`✓`,tableIcon:`✓`},pending:{color:C.yellow,icon:`○`,tableIcon:`⏱`},"in-progress":{color:N.active,icon:`▶`,tableIcon:`▶`},deferred:{color:N.muted,icon:`x`,tableIcon:`⏱`},blocked:{color:C.red,icon:`!`,tableIcon:`✗`},review:{color:C.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:N.muted,icon:`x`,tableIcon:`x`}}[e.toLowerCase()]||{color:C.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 K(e,t,n=!1,r=null){return!e||!Array.isArray(e)||e.length===0?n?N.muted(`None`):`None`:e.map(e=>{let a=e.toString();if(a.includes(`.`)){let o=a.split(`.`);if(o.length!==2||!o[0]||!o[1]){let o=i(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!o)return n?C.red(`${a} (Not found)`):`${a} (Not found)`;let s=o.status||`pending`,c=s.toLowerCase()===`done`||s.toLowerCase()===`completed`,l=s.toLowerCase()===`in-progress`;return n?c?C.green.bold(a):l?C.yellow.bold(a):C.red.bold(a):a}let[s,c]=o.map(e=>parseInt(e,10)),l=t.find(e=>e.id===s);if(!l||!l.subtasks)return n?C.red(`${a} (Not found)`):`${a} (Not found)`;let u=l.subtasks.find(e=>e.id===c);if(!u)return n?C.red(`${a} (Not found)`):`${a} (Not found)`;let d=u.status||`pending`,f=d.toLowerCase()===`done`||d.toLowerCase()===`completed`,p=d.toLowerCase()===`in-progress`;return n?f?C.green.bold(a):p?N.active.bold(a):C.red.bold(a):a}let o=i(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!o)return n?C.red(`${a} (Not found)`):`${a} (Not found)`;let s=o.status||`pending`,c=s.toLowerCase()===`done`||s.toLowerCase()===`completed`,l=s.toLowerCase()===`in-progress`;return n?c?C.green.bold(a):l?C.yellow.bold(a):C.red.bold(a):a}).join(`, `)}function q(e){return e<=3?C.green(`● ${e}`):e<=6?C.yellow(`● ${e}`):C.red(`● ${e}`)}function J(){console.log(p())}async function Y(e){T.existsSync(e)||(f(`No complexity report for this tag yet`,"Run `taskgraph analyze-complexity` to create one"),process.exit(1));let t;try{t=JSON.parse(T.readFileSync(e,`utf8`))}catch(e){f(`Couldn't read the complexity report: ${e.message}`,"Run `taskgraph analyze-complexity` to create it again"),process.exit(1)}console.log(S(t))}async function X(e){console.log(E(C.yellow(`It looks like you've already generated tasks for this project.
|
|
2
2
|
`)+C.yellow(`Executing this command will overwrite any existing tasks.`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=O.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(C.cyan(`Are you sure you wish to continue? (y/N): `),e)});return t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`}function Z(e,t,n){if(a()||!e)return;let{highRelevance:r,mediumRelevance:i,recentTasks:o,allRelevantTasks:s}=e,c=C.bold(`Context Analysis`)+`
|
|
3
3
|
|
|
4
4
|
`;c+=N.muted(`Query: `)+C.reset(`"${t}"`)+`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as e,P as t,T as n,a as r,j as i}from"./config-manager-
|
|
1
|
+
import{$ as e,P as t,T as n,a as r,j as i}from"./config-manager-CtE1yo1I.js";function a(a,o={}){let{mcpLog:s,projectRoot:c}=o,l=(e,...t)=>{s&&typeof s[e]==`function`&&s[e](...t)},u=t(null,{projectRoot:c}),d=n(c);if(e(`debug`,`Checking for config file using findConfigPath, found: ${u}`),e(`debug`,`Checking config file using isConfigFilePresent(), exists: ${d}`),!d)return{success:!1,error:{code:`CONFIG_MISSING`,message:`The configuration file is missing. Run "taskgraph init" to create it.`}};if(typeof a!=`string`||a.trim()===``)return{success:!1,error:{code:`INVALID_RESPONSE_LANGUAGE`,message:`Invalid response language: ${a}. Must be a non-empty string.`}};try{let e=r(c);return e.global.responseLanguage=a,i(e,c)?{success:!0,data:{responseLanguage:a,message:`Response language set to ${a}`}}:{success:!1,error:{code:`WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}}}catch(e){return l(`error`,`Error setting response language: ${e.message}`),{success:!1,error:{code:`SET_RESPONSE_LANGUAGE_ERROR`,message:e.message}}}}export{a as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{t as default}from"./response-language-BdYSHT6o.js";
|
|
@@ -182,7 +182,7 @@ Find code smells and clean them up. ONE cleanup per session.
|
|
|
182
182
|
`,`utf-8`)}isPreset(e){return L(e)}async resolvePrompt(e){if(this.isPreset(e))return I[e];let t=await s(e,`utf-8`);if(!t.trim())throw Error(`Custom prompt file '${e}' is empty`);return t}buildContextHeader(e,t){let n=e.tag?` (tag: ${e.tag})`:``;return`@${e.progressFile} @CLAUDE.md
|
|
183
183
|
|
|
184
184
|
Loop iteration ${t} of ${e.iterations}${n}`}async buildPrompt(e,t){let n=await this.resolvePrompt(e.prompt);return`${this.buildContextHeader(e,t)}\n\n${n}`}parseCompletion(e,t){let n=e.match(/<loop-complete>([^<]*)<\/loop-complete>/i);if(n)return{status:`complete`,message:n[1].trim()};let r=e.match(/<loop-blocked>([^<]*)<\/loop-blocked>/i);return r?{status:`blocked`,message:r[1].trim()}:t===0?{status:`success`}:{status:`error`,message:`Exit code ${t}`}}async executeIteration(e,t,n,r=!1,i=!1,a){let o=Date.now(),s=n?`docker`:`claude`;if(i)return this.executeVerboseIteration(e,t,s,n,r,o,a);let c=this.buildCommandArgs(e,n,!1),l=ie(s,c,{cwd:this.projectRoot,encoding:`utf-8`,maxBuffer:52428800,stdio:[`inherit`,`pipe`,`pipe`]});if(l.error){let e=this.formatCommandError(l.error,s,n);return this.reportError(a,e),this.createErrorIteration(t,o,e)}let u=(l.stdout||``)+(l.stderr||``);if(u&&a?.onOutput?.(u),l.status===null){let e=`Command terminated abnormally (no exit code)`;return this.reportError(a,e),this.createErrorIteration(t,o,e)}let{status:d,message:f}=this.parseCompletion(u,l.status);return{iteration:t,status:d,duration:Date.now()-o,message:f,...r&&{output:u}}}executeVerboseIteration(e,t,n,r,i,a,o){let s=this.buildCommandArgs(e,r,!0);return new Promise(e=>{let c=!1,l=t=>{c||(c=!0,e(t))},u=re(n,s,{cwd:this.projectRoot,stdio:[`inherit`,`pipe`,`pipe`]}),d=!1,f=``,p=``,m=e=>{if(e.startsWith(`{`))try{let t=JSON.parse(e);if(!this.isValidStreamEvent(t))return;this.handleStreamEvent(t,o),t.type===`result`&&(f=typeof t.result==`string`?t.result:``)}catch(t){if(e.trim().startsWith(`{`)){let n=`Failed to parse JSON event: ${t instanceof Error?t.message:`Unknown error`}. Line: ${e.substring(0,100)}...`;this.reportError(o,n,`warning`)}}};u.stdout?(u.stdout.on(`data`,e=>{try{let t=this.processBufferedLines(p,e.toString(`utf-8`));p=t.remaining;for(let e of t.complete)m(e)}catch(e){this.reportError(o,`Failed to process stdout data: ${e instanceof Error?e.message:`Unknown error`}`,`warning`)}}),u.stdout.on(`end`,()=>{d=!0,p&&=(m(p),``)}),u.stderr?.on(`data`,e=>{let n=e.toString(`utf-8`);o?.onStderr?.(t,n)}),u.on(`error`,e=>{let i=this.formatCommandError(e,n,r);if(this.reportError(o,i),u.stdout?.removeAllListeners(),u.stderr?.removeAllListeners(),!u.killed)try{u.kill(`SIGTERM`)}catch{}l(this.createErrorIteration(t,a,i))}),u.on(`close`,e=>{if(!d&&p&&m(p),e===null){let e=`Command terminated abnormally (no exit code)`;this.reportError(o,e),l(this.createErrorIteration(t,a,e));return}let{status:n,message:r}=this.parseCompletion(f,e);l({iteration:t,status:n,duration:Date.now()-a,message:r,...i&&{output:f}})})):l(this.createErrorIteration(t,a,`Failed to capture stdout from child process`))})}isValidStreamEvent(e){if(!e||typeof e!=`object`)return!1;let t=e;if(!(`type`in t)||typeof t.type!=`string`)return!1;if(`message`in t&&t.message!==void 0){if(typeof t.message!=`object`||t.message===null)return!1;let e=t.message;if(`content`in e&&!Array.isArray(e.content))return!1}return!0}buildCommandArgs(e,t,n){if(t)return[`sandbox`,`run`,`claude`,`-p`,e];let r=[`-p`,e,`--dangerously-skip-permissions`];return n&&r.push(`--output-format`,`stream-json`,`--verbose`),r}formatCommandError(e,t,n){return e.code===`ENOENT`?n?`Docker is not installed. Install Docker Desktop to use --sandbox mode.`:`Claude CLI is not installed. Install with: npm install -g @anthropic-ai/claude-code`:e.code===`EACCES`?`Permission denied executing '${t}'`:`Failed to execute '${t}': ${e.message}`}createErrorIteration(e,t,n){return{iteration:e,status:`error`,duration:Date.now()-t,message:n}}handleStreamEvent(e,t){if(e.type===`assistant`&&e.message?.content)for(let n of e.message.content)n.type===`text`&&n.text?t?.onText?.(n.text):n.type===`tool_use`&&n.name&&t?.onToolUse?.(n.name)}processBufferedLines(e,t){let n=(e+t).split(`
|
|
185
|
-
`);return{complete:n.slice(0,-1),remaining:n[n.length-1]}}},pt=class{logger=x(`LoopDomain`);loopService=null;projectRoot;constructor(e){this.projectRoot=e.getProjectRoot()}checkSandboxAuth(){return new ft({projectRoot:this.projectRoot}).checkSandboxAuth()}runInteractiveAuth(){return new ft({projectRoot:this.projectRoot}).runInteractiveAuth()}isTrusted(){return ut(this.projectRoot)}trust(){dt(this.projectRoot)}async run(e){if(!e.sandbox&&!e.trusted&&!this.isTrusted())throw Error(`loop runs Claude with permission prompts off in this project. Approve it first, or pass --trust (or use --sandbox).`);if(this.loopService?.isRunning)try{this.loopService.stop()}catch(e){this.logger.warn(`Failed to stop previous loop service:`,e)}let t=this.buildConfig(e);return this.loopService=new ft({projectRoot:this.projectRoot}),this.loopService.run(t)}stop(){this.loopService&&=(this.loopService.stop(),null)}getIsRunning(){return this.loopService?.isRunning??!1}isPreset(e){return L(e)}async resolvePrompt(e,t){if(L(e))return st(e);if(!t)throw Error(`Custom prompt file requires readFile callback: ${e}`);return t(e)}getAvailablePresets(){return[...ot]}resolveIterations(e){let{userIterations:t,preset:n,pendingTaskCount:r}=e;return t===void 0?n==="default"&&r!==void 0&&r>0?r:10:t}buildConfig(e){return{iterations:e.iterations??10,prompt:e.prompt??`default`,progressFile:e.progressFile??t.join(this.projectRoot,`.taskgraph`,`progress.txt`),sleepSeconds:e.sleepSeconds??5,tag:e.tag,sandbox:e.sandbox??!1,includeOutput:e.includeOutput??!1,verbose:e.verbose??!1,callbacks:e.callbacks}}},mt=class{detectFormat(e){return!e||typeof e!=`object`?`standard`:Object.keys(e).some(e=>e!==`tasks`&&e!==`metadata`)?`legacy`:`standard`}extractTasks(e,t){return e?this.detectFormat(e)===`legacy`?this.extractTasksFromLegacy(e,t):this.extractTasksFromStandard(e):[]}extractTasksFromLegacy(e,t){if(t in e)return e[t]?.tasks||[];let n=Object.keys(e).filter(e=>e!==`tasks`&&e!==`metadata`);return t===`master`&&n.length>0&&e[n[0]]?.tasks||[]}extractTasksFromStandard(e){return e?.tasks||[]}extractMetadata(e,t){return e?this.detectFormat(e)===`legacy`?this.extractMetadataFromLegacy(e,t):this.extractMetadataFromStandard(e):null}extractMetadataFromLegacy(e,t){if(t in e){let n=e[t];return!n?.metadata&&n?.tasks?this.generateMetadataFromTasks(n.tasks,t):n?.metadata||null}let n=Object.keys(e).filter(e=>e!==`tasks`&&e!==`metadata`);if(t===`master`&&n.length>0){let t=n[0],r=e[t];return!r?.metadata&&r?.tasks?this.generateMetadataFromTasks(r.tasks,t):r?.metadata||null}return null}extractMetadataFromStandard(e){return e?.metadata||null}extractTags(e){return e?this.detectFormat(e)===`legacy`?Object.keys(e).filter(e=>e!==`tasks`&&e!==`metadata`):[`master`]:[]}convertToSaveFormat(e,t,n,r){let i=r||`master`,a=this.normalizeTasks(e);return n&&this.detectFormat(n)===`legacy`?this.convertToLegacyFormat(a,t,i):this.convertToStandardFormat(a,t,r)}convertToLegacyFormat(e,t,n){return{[n]:{tasks:e,metadata:{...t,tags:[n]}}}}convertToStandardFormat(e,t,n){return{tasks:e,metadata:{...t,tags:n?[n]:[]}}}normalizeTasks(e){return e.map(e=>({...e,id:String(e.id),dependencies:e.dependencies?.map(e=>String(e))||[],subtasks:e.subtasks?.map(t=>({...t,id:Number(t.id),parentId:String(t.parentId??e.id)}))||[]}))}generateMetadataFromTasks(e,t){return{version:`1.0.0`,lastModified:(/* @__PURE__ */ new Date()).toISOString(),taskCount:e.length,completedCount:e.filter(e=>e.status===`done`).length,tags:[t]}}};function ht(e){return typeof e==`number`&&Number.isInteger(e)&&e>=1}function gt(e){let t=e?.schemaVersion;return ht(t)?t:1}function z(e,t){let n=ht(t?.schemaVersion)?t.schemaVersion:0;return{...e,schemaVersion:Math.max(1,n)}}const _t=/* @__PURE__ */ new Set;function vt(e,t,n){let r=e?.schemaVersion,i=r!==void 0&&!ht(r);if(!i&>(e)<=1)return;let a=`${n}::${t}`;if(_t.has(a))return;_t.add(a);let o=i?`an unrecognized schemaVersion (${JSON.stringify(r)})`:`schema version ${r}, newer than the 1 this version understands`;process.stderr.write(`Warning: tag "${t}" in ${n} has ${o}. Loading it anyway; consider upgrading taskgraph.\n`)}function yt(e,n){let r=t.relative(process.cwd(),e),i=r&&!r.startsWith(`..`)&&!t.isAbsolute(r)?r:e,a=/\(line (\d+) column (\d+)\)/.exec(n.message),o=a?` (line ${a[1]}, column ${a[2]})`:``;return new C(`Invalid JSON in file ${e}: ${n.message}`,S.JSON_PARSE_ERROR,{resource:e,userMessage:`${i} isn't valid JSON${o}`},n)}const bt={stale:1e4,retries:{retries:5,factor:2,minTimeout:100,maxTimeout:1e3},realpath:!1};var xt=class{writers=/* @__PURE__ */ new Map;getWriter(e){let t=this.writers.get(e);return t||(t=new ce(e),this.writers.set(e,t)),t}async readJson(e){try{let t=await i.readFile(e,`utf-8`);return JSON.parse(t)}catch(t){throw t.code===`ENOENT`?t:t instanceof SyntaxError?yt(e,t):Error(`Failed to read file ${e}: ${t.message}`)}}async acquireLock(e){let t=`${e}.lock`;try{let e=await i.lstat(t);if(!e.isDirectory()&&Date.now()-e.mtimeMs>bt.stale){let e=`${t}.stale.${process.pid}.${Date.now()}`;await i.rename(t,e).catch(()=>void 0),await i.rm(e,{force:!0})}}catch(e){if(e.code!==`ENOENT`)throw e}return se.lock(e,bt)}async writeJson(e,t){await this.ensureFileExists(e);let n=null;try{n=await this.acquireLock(e);let r=JSON.stringify(t,null,2);await this.getWriter(e).write(r)}finally{if(n)try{await n()}catch(t){(process.env.DEBUG||process.env.TASKGRAPH_DEBUG===`true`)&&console.warn(`[WARN] Lock release warning for ${e}: ${t.message}`)}}}async modifyJson(e,t){await this.ensureFileExists(e);let n=null;try{n=await this.acquireLock(e);let r;try{let t=await i.readFile(e,`utf-8`);r=JSON.parse(t)}catch(t){if(t.code===`ENOENT`)r={};else if(t instanceof SyntaxError){let n=await i.readFile(e,`utf-8`).catch(()=>``);if(n.trim()===``||n.trim()===`{}`)r={};else throw Error(`Corrupted JSON in ${e}: ${t.message}. File contains: ${n.substring(0,100)}...`)}else throw Error(`Failed to read ${e} for modification: ${t.message}`)}let a=await t(r),o=JSON.stringify(a,null,2);await this.getWriter(e).write(o)}finally{if(n)try{await n()}catch(t){(process.env.DEBUG||process.env.TASKGRAPH_DEBUG===`true`)&&console.warn(`[WARN] Lock release warning for ${e}: ${t.message}`)}}}async ensureFileExists(e){let n=t.dirname(e);await i.mkdir(n,{recursive:!0});try{await i.writeFile(e,`{}`,{flag:`wx`})}catch(e){if(e.code!==`EEXIST`)throw e}}async exists(e){try{return await i.access(e,l.F_OK),!0}catch{return!1}}async getStats(e){return i.stat(e)}async readDir(e){return i.readdir(e)}async ensureDir(e){try{await i.mkdir(e,{recursive:!0})}catch(t){throw Error(`Failed to create directory ${e}: ${t.message}`)}}async deleteFile(e){try{await i.unlink(e)}catch(t){if(t.code!==`ENOENT`)throw Error(`Failed to delete file ${e}: ${t.message}`)}}async moveFile(e,t){try{await i.rename(e,t)}catch(n){throw Error(`Failed to move file from ${e} to ${t}: ${n.message}`)}}async copyFile(e,t){try{await i.copyFile(e,t)}catch(n){throw Error(`Failed to copy file from ${e} to ${t}: ${n.message}`)}}async cleanup(){this.writers.clear()}},St=class{basePath;tasksDir;tasksFilePath;constructor(e){this.basePath=t.join(e,`.taskgraph`),this.tasksDir=t.join(this.basePath,`tasks`),this.tasksFilePath=t.join(this.tasksDir,`tasks.json`)}getBasePath(){return this.basePath}getTasksDir(){return this.tasksDir}getTasksPath(){return this.tasksFilePath}};function Ct(e){return typeof e==`number`&&e<=99}function B(e,t){return Ct(t)?`${e}.${t}`:String(t)}const V=x(`ComplexityReportManager`);var wt=class{projectRoot;reportCache=/* @__PURE__ */ new Map;constructor(e){this.projectRoot=e}getReportPath(e){let t=m.join(this.projectRoot,`.taskgraph`,`reports`),n=e&&e!==`master`?`_${e}`:``;return m.join(t,`task-complexity-report${n}.json`)}async loadReport(e){let t=e||`master`,n=t;if(this.reportCache.has(n))return this.reportCache.get(n);let r=this.getReportPath(e);try{await i.access(r);let e=await i.readFile(r,`utf-8`),a=JSON.parse(e);return!a.meta||!Array.isArray(a.complexityAnalysis)?(V.warn(`Invalid complexity report structure at ${r}, ignoring`),null):(this.reportCache.set(n,a),V.debug(`Loaded complexity report for tag '${t}' with ${a.complexityAnalysis.length} analyses`),a)}catch(e){return e.code===`ENOENT`?(V.debug(`No complexity report found for tag '${t}'`),null):(V.warn(`Failed to load complexity report for tag '${t}': ${e.message}`),null)}}async getComplexityForTask(e,t){let n=await this.loadReport(t);if(!n)return null;let r=n.complexityAnalysis.find(t=>String(t.taskId)===String(e));return r?{complexityScore:r.complexityScore,recommendedSubtasks:r.recommendedSubtasks,expansionPrompt:r.expansionPrompt,complexityReasoning:r.complexityReasoning}:null}async getComplexityForTasks(e,t){let n=/* @__PURE__ */ new Map,r=await this.loadReport(t);if(!r)return n;let i=/* @__PURE__ */ new Map;return r.complexityAnalysis.forEach(e=>{i.set(String(e.taskId),e)}),e.forEach(e=>{let t=i.get(String(e));t&&n.set(String(e),{complexityScore:t.complexityScore,recommendedSubtasks:t.recommendedSubtasks,expansionPrompt:t.expansionPrompt,complexityReasoning:t.complexityReasoning})}),n}clearCache(e){e?this.reportCache.delete(e):this.reportCache.clear()}async hasReport(e){let t=this.getReportPath(e);try{return await i.access(t),!0}catch{return!1}}};function Tt(e,t){return{version:`1.0.0`,lastModified:(/* @__PURE__ */ new Date()).toISOString(),taskCount:e.length,completedCount:e.filter(e=>e.status===`done`).length,tags:[t]}}function Et(e,t,n,r,i){let a=Dt(r);return e.detectFormat(t)===`legacy`||Object.keys(t).some(e=>e!==`tasks`&&e!==`metadata`)?(t[n]={tasks:a,metadata:z(i,t[n]?.metadata)},t):n===`master`?{tasks:a,metadata:z(i,t.metadata)}:{master:{tasks:t.tasks||[],metadata:z(t.metadata||i,t.metadata)},[n]:{tasks:a,metadata:z(i)}}}function Dt(e){return e.map(e=>({...e,id:String(e.id),dependencies:e.dependencies?.map(e=>String(e))||[],subtasks:e.subtasks?.map(t=>({...t,id:Number(t.id),parentId:String(t.parentId??e.id)}))||[]}))}var Ot=class{pathResolver;fileOps;formatHandler;reader;constructor(e,t,n,r){this.pathResolver=e,this.fileOps=t,this.formatHandler=n,this.reader=r}async createTag(e,t){let n=this.pathResolver.getTasksPath();try{await this.fileOps.modifyJson(n,n=>{if(this.formatHandler.detectFormat(n)===`legacy`){if(e in n)throw new C(`Tag ${e} already exists`,S.VALIDATION_ERROR);let r=[];return t?.copyFrom&&t.copyFrom in n&&n[t.copyFrom].tasks&&(r=JSON.parse(JSON.stringify(n[t.copyFrom].tasks))),n[e]={tasks:r,metadata:z({created:(/* @__PURE__ */ new Date()).toISOString(),updatedAt:(/* @__PURE__ */ new Date()).toISOString(),description:t?.description||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,tags:[e]})},n}{let r=n.tasks||[],i=n.metadata||{},a=[];return(t?.copyFrom===`master`||!t?.copyFrom)&&(a=JSON.parse(JSON.stringify(r))),{master:{tasks:r,metadata:z({...i,tags:[`master`]},i)},[e]:{tasks:a,metadata:z({created:(/* @__PURE__ */ new Date()).toISOString(),updatedAt:(/* @__PURE__ */ new Date()).toISOString(),description:t?.description||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,tags:[e]})}}}})}catch(e){throw e.code===`ENOENT`?Error(`Tasks file not found - initialize project first`):e}}async deleteTag(e){let t=this.pathResolver.getTasksPath();try{let n=!1;await this.fileOps.modifyJson(t,t=>{if(this.formatHandler.detectFormat(t)!==`legacy`&&e===`master`)return n=!0,t;if(this.formatHandler.detectFormat(t)===`legacy`){if(e in t)return delete t[e],t;throw Error(`Tag ${e} not found`)}throw Error(`Tag ${e} not found in standard format`)}),n&&await this.fileOps.deleteFile(t)}catch(t){throw t.code===`ENOENT`?Error(`Tag ${e} not found - file doesn't exist`):t}}async renameTag(e,t){let n=this.pathResolver.getTasksPath();try{await this.fileOps.modifyJson(n,n=>{if(this.formatHandler.detectFormat(n)===`legacy`){if(e in n)return n[t]=n[e],delete n[e],n[t].metadata&&(n[t].metadata.tags=[t]),n;throw Error(`Tag ${e} not found`)}if(e===`master`){let e=n.tasks||[],r=n.metadata||{};return{[t]:{tasks:e,metadata:z({...r,tags:[t]},r)}}}throw Error(`Tag ${e} not found in standard format`)})}catch(t){throw t.code===`ENOENT`?Error(`Tag ${e} not found - file doesn't exist`):t}}async getTagsWithStats(){let e=await this.reader.getAllTags(),t=await this.getActiveTagFromState(),n=await Promise.all(e.map(async e=>{try{let n=await this.reader.loadTasks(e),r={},i=0,a={totalSubtasks:0,subtasksByStatus:{}};n.forEach(e=>{let t=e.status||`pending`;r[t]=(r[t]||0)+1,t===`done`&&i++,e.subtasks&&e.subtasks.length>0&&(a.totalSubtasks+=e.subtasks.length,e.subtasks.forEach(e=>{let t=e.status||`pending`;a.subtasksByStatus[t]=(a.subtasksByStatus[t]||0)+1}))});let o=await this.reader.loadMetadata(e);return{name:e,isCurrent:e===t,taskCount:n.length,completedTasks:i,statusBreakdown:r,subtaskCounts:a.totalSubtasks>0?a:void 0,created:o?.created,description:o?.description}}catch{return{name:e,isCurrent:e===t,taskCount:0,completedTasks:0,statusBreakdown:{}}}}));return{tags:n,currentTag:t,totalTags:n.length}}async getActiveTagFromState(){try{let e=t.join(this.pathResolver.getBasePath(),`state.json`);return(await this.fileOps.readJson(e))?.currentTag||`master`}catch{return`master`}}};function H(e,t=e){return new C(e,S.TASK_NOT_FOUND,{userMessage:t})}var kt=class{formatHandler;fileOps;pathResolver;complexityManager;tagOps;constructor(e){this.formatHandler=new mt,this.fileOps=new xt,this.pathResolver=new St(e),this.complexityManager=new wt(e),this.tagOps=new Ot(this.pathResolver,this.fileOps,this.formatHandler,this)}async initialize(){await this.fileOps.ensureDir(this.pathResolver.getTasksDir())}async close(){await this.fileOps.cleanup()}async getStats(){let e=this.pathResolver.getTasksPath();try{let t=await this.fileOps.getStats(e),n=await this.fileOps.readJson(e),r=this.formatHandler.extractTags(n),i=0,a=r.map(e=>{let r=this.formatHandler.extractTasks(n,e).length;return i+=r,{tag:e,taskCount:r,lastModified:t.mtime.toISOString()}});return{totalTasks:i,totalTags:r.length,lastModified:t.mtime.toISOString(),storageSize:0,tagStats:a}}catch(e){if(e.code===`ENOENT`)return{totalTasks:0,totalTags:0,lastModified:(/* @__PURE__ */ new Date()).toISOString(),storageSize:0,tagStats:[]};throw Error(`Failed to get storage stats: ${e.message}`)}}async loadTasks(e,t){let n=this.pathResolver.getTasksPath(),r=e||`master`;try{let e=await this.fileOps.readJson(n),i=this.formatHandler.extractTasks(e,r);return vt(this.formatHandler.extractMetadata(e,r),r,n),t&&(t.status&&(i=i.filter(e=>e.status===t.status)),t.excludeSubtasks&&(i=i.map(e=>({...e,subtasks:[]})))),await this.enrichTasksWithComplexity(i,r)}catch(e){if(e.code===`ENOENT`)return[];throw e instanceof C?e:Error(`Failed to load tasks: ${e.message}`)}}async loadTask(e,t){let n=await this.loadTasks(t);if(e.includes(`.`)){let[t,r]=e.split(`.`),i=n.find(e=>String(e.id)===t);if(!i||!i.subtasks)return null;let a=i.subtasks.find(e=>String(e.id)===r);if(!a)return null;let o=a.dependencies?.map(e=>B(i.id,e))??[];return{...a,id:e,title:a.title||`Subtask ${r}`,description:a.description||``,status:a.status||`pending`,priority:a.priority||i.priority||`medium`,dependencies:o,details:a.details||``,testStrategy:a.testStrategy||``,subtasks:[],tags:i.tags||[],assignee:a.assignee||i.assignee,complexity:a.complexity||i.complexity,createdAt:a.createdAt||i.createdAt,updatedAt:a.updatedAt||i.updatedAt,parentTask:{id:i.id,title:i.title,status:i.status},isSubtask:!0}}return n.find(t=>String(t.id)===String(e))||null}async saveTasks(e,t){let n=this.pathResolver.getTasksPath(),r=t||`master`;await this.fileOps.ensureDir(this.pathResolver.getTasksDir());let i=Tt(e,r);await this.fileOps.modifyJson(n,t=>Et(this.formatHandler,t,r,e,i))}async mutateTasks(e,t){let n=this.pathResolver.getTasksPath(),r=e||`master`,i;return await this.fileOps.ensureDir(this.pathResolver.getTasksDir()),await this.fileOps.modifyJson(n,e=>{let n=t(this.formatHandler.extractTasks(e,r));return i=n.result,n.tasks===null?e:Et(this.formatHandler,e,r,n.tasks,Tt(n.tasks,r))}),i}async exists(e){let t=this.pathResolver.getTasksPath();return this.fileOps.exists(t)}async getAllTags(){try{let e=this.pathResolver.getTasksPath(),t=await this.fileOps.readJson(e);return this.formatHandler.extractTags(t)}catch(e){if(e.code===`ENOENT`)return[];throw Error(`Failed to get tags: ${e.message}`)}}async loadMetadata(e){let t=this.pathResolver.getTasksPath(),n=e||`master`;try{let e=await this.fileOps.readJson(t);return this.formatHandler.extractMetadata(e,n)}catch(e){if(e.code===`ENOENT`)return null;throw Error(`Failed to load metadata: ${e.message}`)}}async saveMetadata(e,t){let n=await this.loadTasks(t);await this.saveTasks(n,t)}async appendTasks(e,t){await this.mutateTasks(t,t=>({tasks:[...t,...e],result:void 0}))}async updateTask(e,t,n){await this.mutateTasks(n,n=>{let r=n.findIndex(t=>String(t.id)===String(e));if(r===-1)throw H(`Task ${e} not found`);let i=n[r],a=t.subtasks;t.subtasks&&i.subtasks&&(a=t.subtasks.map(e=>{let t=i.subtasks?.find(t=>String(t.id)===String(e.id)||e.title&&t.title===e.title);return t?.metadata||e.metadata?{...e,metadata:{...t?.metadata||{},...e.metadata||{}}}:e}));let o=[...n];return o[r]={...i,...t,...a&&{subtasks:a},id:String(e)},{tasks:o,result:void 0}})}async updateTaskStatus(e,t,n){return this.mutateTasks(n,n=>{if(e.includes(`.`))return this.updateSubtaskStatusInFile(n,e,t);let r=n.findIndex(t=>String(t.id)===String(e));if(r===-1)throw H(`Task ${e} not found`);let i=n[r].status,a={success:!0,oldStatus:i,newStatus:t,taskId:String(e)};if(i===t)return{tasks:null,result:a};let o=[...n];return o[r]={...n[r],status:t,updatedAt:(/* @__PURE__ */ new Date()).toISOString()},{tasks:o,result:a}})}updateSubtaskStatusInFile(e,t,n){let r=t.split(`.`);if(r.length!==2)throw Error(`Invalid subtask ID format: ${t}. Expected format: parentId.subtaskId`);let[i,a]=r,o=a.trim();if(!/^\d+$/.test(o))throw Error(`Invalid subtask ID: ${o}. Subtask ID must be a positive integer.`);let s=Number(o),c=e.findIndex(e=>String(e.id)===String(i));if(c===-1)throw H(`Parent task ${i} not found`,`Task ${i} not found`);let l={...e[c],subtasks:[...e[c].subtasks??[]]},u=l.subtasks.findIndex(e=>e.id===s||String(e.id)===o);if(u===-1)throw H(`Subtask ${t} not found in parent task ${i}`,`Subtask ${t} not found`);let d=l.subtasks[u].status||`pending`,f={success:!0,oldStatus:d,newStatus:n,taskId:t};if(d===n)return{tasks:null,result:f};let p=(/* @__PURE__ */ new Date()).toISOString();l.subtasks[u]={...l.subtasks[u],status:n,updatedAt:p};let m=l.subtasks,h=l.status;if(m.length>0){let e=e=>e.status||`pending`,t=t=>{let n=e(t);return n===`done`||n===`completed`},n=m.every(t),r=m.some(t=>e(t)===`in-progress`),i=m.some(t),a=m.every(t=>e(t)===`pending`);n?h=`done`:r||i?h=`in-progress`:a&&(h=`pending`)}let g=[...e];return g[c]={...l,...h===l.status?{}:{status:h},updatedAt:p},{tasks:g,result:f}}async deleteTask(e,t){await this.mutateTasks(t,t=>{let n=t.filter(t=>String(t.id)!==String(e));if(n.length===t.length)throw H(`Task ${e} not found`);return{tasks:n,result:void 0}})}async createTag(e,t){return this.tagOps.createTag(e,t)}async deleteTag(e){return this.tagOps.deleteTag(e)}async renameTag(e,t){return this.tagOps.renameTag(e,t)}async copyTag(e,t){let n=await this.loadTasks(e);if(n.length===0)throw Error(`Source tag ${e} not found or has no tasks`);await this.saveTasks(n,t)}async getTagsWithStats(){return this.tagOps.getTagsWithStats()}async watch(e,t){let n=this.pathResolver.getTasksPath(),r=t?.debounceMs??100;if(!await this.fileOps.exists(n))throw new C(`Tasks file not found. Initialize the project first.`,S.NOT_FOUND,{path:n});let i,a=!1,o=c.watch(n,(t,n)=>{a||n&&t===`change`&&(i&&clearTimeout(i),i=setTimeout(()=>{a||e({type:`change`,timestamp:/* @__PURE__ */ new Date})},r))});return o.on(`error`,t=>{a||e({type:`error`,timestamp:/* @__PURE__ */ new Date,error:t})}),{unsubscribe:()=>{a=!0,i&&clearTimeout(i),o.close()}}}async enrichTasksWithComplexity(e,t){let n=e.map(e=>e.id),r=await this.complexityManager.getComplexityForTasks(n,t);return r.size===0?e:e.map(e=>{let t=r.get(String(e.id));return t?{...e,complexity:t.complexityScore,recommendedSubtasks:t.recommendedSubtasks,expansionPrompt:t.expansionPrompt,complexityReasoning:t.complexityReasoning}:e})}},At=class{static async createFromStorageConfig(e,t){return new kt(e.basePath||t)}},jt=`taskgraph-ai`,Mt=`0.54.13`;const Nt={CLAUDE_CODE:`claude-code`},Pt=Object.values(Nt);[...Pt];const Ft=`.taskgraph/tasks/tasks.json`,It=[`.taskgraph`,`.taskgraph/config.json`,Ft],Lt=/* @__PURE__ */ `.git,.svn,.hg,.fossil,.github,.gitlab,.circleci,.travis.yml,.jenkins,.buildkite,.vscode,.idea,.project,.devcontainer,package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lockb,bun.lock,deno.lock,deno.json,deno.jsonc,package.json,lerna.json,nx.json,turbo.json,rush.json,pnpm-workspace.yaml,Cargo.toml,Cargo.lock,go.mod,go.sum,go.work,pyproject.toml,setup.py,setup.cfg,poetry.lock,Pipfile,Pipfile.lock,uv.lock,Gemfile,Gemfile.lock,composer.json,composer.lock,build.gradle,build.gradle.kts,settings.gradle,settings.gradle.kts,pom.xml,build.sbt,project.clj,deps.edn,mix.exs,rebar.config,pubspec.yaml,Package.swift,CMakeLists.txt,Makefile,meson.build,BUILD.bazel,WORKSPACE,flake.nix,shell.nix,default.nix,Dockerfile,docker-compose.yml,docker-compose.yaml,Containerfile,kubernetes.yml,kubernetes.yaml,helm/Chart.yaml`.split(`,`),Rt=[`tasks.json`,...Lt,`requirements.txt`];[...It,...Rt];const zt=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`],Bt=[`done`,`completed`,`cancelled`];function U(e){return Bt.includes(e)}const Vt=[`text`,`json`,`compact`],Ht={done:`✓`,completed:`✓`,"in-progress":`►`,blocked:`⭕`,pending:`○`,deferred:`⏸`,cancelled:`✗`,review:`👁`},W=(e,t)=>e.localeCompare(t,void 0,{numeric:!0});function G(e){let t=[];for(let n of e){let e=String(n.id);t.push({id:e,title:n.title,status:n.status,priority:n.priority,deps:(n.dependencies??[]).map(String)});for(let r of n.subtasks??[])t.push({id:`${e}.${r.id}`,title:r.title,status:r.status??`pending`,priority:r.priority??n.priority,deps:(r.dependencies??[]).map(t=>B(e,t))})}let n=/* @__PURE__ */ new Map;for(let e of t)n.set(e.id,{id:e.id,title:e.title,status:e.status,priority:e.priority,dependencies:[],missing:[],selfDependency:!1,dependents:[]});for(let e of t){let t=n.get(e.id);for(let r of new Set(e.deps)){if(r===e.id){t.selfDependency=!0;continue}let i=n.get(r);i?(t.dependencies.push(r),i.dependents.push(e.id)):t.missing.push(r)}}return{nodes:n}}const K=e=>!U(e.status);function Ut(e,t=G(e)){let{nodes:n}=t,r=/* @__PURE__ */ new Map,i=[];for(let e of n.values())K(e)?i.push(e.id):r.set(e.id,0);let a=qt(i,e=>n.get(e).dependents,e=>K(n.get(e))),o=/* @__PURE__ */ new Map;a.forEach((e,t)=>{for(let n of e)o.set(n,t)});let s=Math.ceil(a.length/32),c=[];return a.forEach((e,t)=>{let i=new Uint32Array(s);for(let r of e)for(let e of n.get(r).dependents){let n=o.get(e);if(n===void 0||n===t)continue;i[n>>5]|=1<<(n&31);let r=c[n];for(let e=0;e<s;e++)i[e]|=r[e]}let l=e.length-1;for(let e=0;e<t;e++)i[e>>5]&1<<(e&31)&&(l+=a[e].length);c.push(i);for(let t of e)r.set(t,l)}),r}function Wt(e,t,n=G(e)){let{nodes:r}=n,i=[];for(let[t,a]of Ut(e,n)){let e=r.get(t);a>0&&K(e)&&i.push({id:t,title:e.title,status:e.status,blocks:a})}return i.sort((e,t)=>t.blocks-e.blocks||W(e.id,t.id)),t===void 0?i:i.slice(0,Math.max(0,t))}function Gt(e){let{nodes:t}=G(e);return qt([...t.keys()],e=>t.get(e).dependencies).filter(e=>e.length>1).map(e=>e.sort(W)).sort((e,t)=>W(e[0],t[0]))}function Kt(e,t=G(e)){let{nodes:n}=t,r=[...n.values()].filter(K).map(e=>e.id),i=e=>K(n.get(e)),a=new Set(qt(r,e=>n.get(e).dependencies,i).filter(e=>e.length>1).flat()),o=[...a];for(let e=0;e<o.length;e++)for(let t of n.get(o[e]).dependents)i(t)&&!a.has(t)&&(a.add(t),o.push(t));let s=r.filter(e=>!a.has(e)),c=e=>n.get(e).dependencies.filter(e=>i(e)&&!a.has(e)),l=/* @__PURE__ */ new Map;for(let e of s)l.set(e,c(e).length);let u=s.filter(e=>l.get(e)===0);for(let e=0;e<u.length;e++)for(let t of n.get(u[e]).dependents){if(!l.has(t))continue;let e=l.get(t)-1;l.set(t,e),e===0&&u.push(t)}let d=/* @__PURE__ */ new Map,f=null;for(let e of u){let t=1,n=null;for(let r of c(e)){let e=d.get(r).length+1;(e>t||e===t&&n!==null&&W(r,n)<0)&&(t=e,n=r)}d.set(e,{length:t,via:n});let r=f===null?null:d.get(f);(r===null||t>r.length||t===r.length&&W(e,f)<0)&&(f=e)}let p=[];for(let e=f;e!==null;e=d.get(e)?.via??null)p.unshift(e);return p}function qt(e,t,n=()=>!0){let r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Set,o=[],s=[],c=0;for(let l of e){if(r.has(l))continue;let e=[],u=s=>{r.set(s,c),i.set(s,c),c++,o.push(s),a.add(s),e.push({id:s,edges:t(s).filter(n),at:0})};for(u(l);e.length;){let t=e[e.length-1];if(t.at<t.edges.length){let e=t.edges[t.at++];r.has(e)?a.has(e)&&i.set(t.id,Math.min(i.get(t.id),r.get(e))):u(e);continue}if(e.pop(),i.get(t.id)===r.get(t.id)){let e=[],n;do n=o.pop(),a.delete(n),e.push(n);while(n!==t.id);s.push(e)}let n=e[e.length-1];n&&i.set(n.id,Math.min(i.get(n.id),i.get(t.id)))}}return s}const Jt=[`deferred`,`blocked`];function Yt(e,t){let{nodes:n}=G(e),r=n.get(String(t));if(!r)throw Error(`Task ${t} not found`);let i=Gt(e),a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set,s=/* @__PURE__ */ new Map,c=e=>{let t=e.kind===`cycle`?`cycle:${e.cycle}`:e.id,n=a.get(t);if(!n)a.set(t,e);else{for(let t of e.listedBy??[])n.listedBy?.includes(t)||n.listedBy?.push(t);for(let t of e.edges??[])n.edges?.some(e=>e.from===t.from&&e.to===t.to)||n.edges?.push(t)}},l=(e,t)=>{let n=i.find(e=>e.includes(t.id))??[t.id];return c({id:t.id,title:t.title,status:t.status,kind:`cycle`,cycle:n,edges:[{from:e.id,to:t.id}]}),{id:t.id,title:t.title,status:t.status,kind:`cycle`,blockers:[]}},u=e=>{let t=[];return e.selfDependency&&t.push(l(e,e)),{node:e,deps:e.dependencies.map(e=>n.get(e)).filter(e=>!U(e.status)).sort((e,t)=>W(e.id,t.id)),at:0,out:t}};if(U(r.status))return{id:r.id,title:r.title,status:r.status,blocked:!1,blockers:[],rootCauses:[]};let d=/* @__PURE__ */ new Set([r.id]),f=[u(r)],p=[];for(;f.length;){let e=f[f.length-1];if(e.at<e.deps.length){let t=e.deps[e.at++];d.has(t.id)?e.out.push(l(e.node,t)):o.has(t.id)?e.out.push({id:t.id,title:t.title,status:t.status,kind:s.get(t.id),blockers:[],repeated:!0}):(o.add(t.id),d.add(t.id),f.push(u(t)));continue}for(let t of[...e.node.missing].sort(W))c({id:t,kind:`missing`,listedBy:[e.node.id]}),e.out.push({id:t,kind:`missing`,blockers:[]});f.pop();let t=f[f.length-1];if(!t){p=e.out;break}let n=e.node;d.delete(n.id);let r=e.out.length?void 0:Jt.includes(n.status)?`stalled`:`ready`;s.set(n.id,r),r&&c({id:n.id,title:n.title,status:n.status,kind:r}),t.out.push({id:n.id,title:n.title,status:n.status,kind:r,blockers:e.out})}return{id:r.id,title:r.title,status:r.status,blocked:p.length>0,blockers:p,rootCauses:[...a.values()]}}function Xt(e,t={}){let n={bottlenecks:Wt(e,t.limit??5),criticalPath:Kt(e),cycles:Gt(e)};return t.id!==void 0&&(n.explanation=Yt(e,String(t.id))),n}const q=`dependencySources`;function J(e,t){return t===void 0?String(e):B(t,e)}function Y(e){let t=e?.[q];return!t||typeof t!=`object`||Array.isArray(t)?{}:{...t}}function Zt(e,t,n){let r=J(t,n);return(e.dependencies??[]).some(e=>J(e,n)===r)}const Qt=Zt;function X(e,t){let{[q]:n,...r}=e??{};return Object.keys(t).length>0&&(r[q]=t),Object.keys(r).length>0?r:void 0}function $t(e){if(!e)return;let{[q]:t,...n}=e;return Object.keys(n).length>0?n:void 0}function en(e,t){t?e.metadata=t:delete e.metadata}function tn(e,t,n){return Qt(e,t,n)&&Y(e.metadata)[J(t,n)]===`inferred`?`inferred`:`explicit`}function nn(e,t,n){let r=Y(t?.metadata),i={};for(let a of e.dependencies??[]){let e=J(a,n);(!(t&&Qt(t,a,n))||r[e]===`inferred`)&&(i[e]=`inferred`)}return X(t?.metadata??e.metadata,i)}function rn(e,t,n,r){let i=Y(e),a=J(t,r);return n===`inferred`?i[a]=`inferred`:delete i[a],X(e,i)}function an(e,t){let n={};for(let[r,i]of Object.entries(Y(e.metadata)))Qt(e,r,t)&&(n[r]=i);return X(e.metadata,n)}function on(e,t,n,r){let i=Y(e),a=i[J(t,r)];return delete i[J(t,r)],delete i[J(n,r)],a===`inferred`&&(i[J(n,r)]=`inferred`),X(e,i)}function sn(e,t,n,r=e=>e){let i=Y(e.metadata),a={};for(let o of e.dependencies??[])i[J(o,t)]===`inferred`&&(a[J(r(o),n)]=`inferred`);return X(e.metadata,a)}function cn(e,t={}){let n=new Map(e.map(e=>[String(e.id),e])),r=e=>(e.dependencies??[]).map(String).filter(t=>t!==String(e.id)),i=e=>r(e).filter(e=>n.has(e)),a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set,s=e=>{let t=a.get(e);if(t!==void 0)return t;if(o.has(e))return 1/0;o.add(e);let r=i(n.get(e)),c=r.length?Math.max(...r.map(s))+1:0;return o.delete(e),a.set(e,c),c},c=/* @__PURE__ */ new Map;for(let t of e){let e=String(t.id),n=i(t).filter(e=>Number.isFinite(s(e))).sort((e,t)=>s(e)-s(t)||W(e,t));c.set(e,n.length?n[n.length-1]:null)}let l=/* @__PURE__ */ new Map;for(let[e,t]of c)t&&l.set(t,[...l.get(t)??[],e]);let u=/* @__PURE__ */ new Set,d=e=>{u.add(e);let t=n.get(e),a=c.get(e);return{id:e,title:t.title,status:t.status,priority:t.priority,alsoNeeds:i(t).filter(e=>e!==a).sort(W),missing:r(t).filter(e=>!n.has(e)),inferred:i(t).filter(e=>tn(t,e)===`inferred`).sort(W),children:(l.get(e)??[]).filter(e=>!u.has(e)).sort(W).map(d)}},f=e=>Number.isFinite(s(String(e.id)))&&!c.get(String(e.id)),p=G(e),m={bottlenecks:Wt(e,5,p),criticalPath:Kt(e,p)},h;if(t.rootId!==void 0){let e=String(t.rootId);if(!n.has(e))throw Error(`Task ${e} not found`);let r=d(e);return r.inferred=r.inferred.filter(t=>t!==c.get(e)),h=[r],{roots:h,cyclic:[],total:ln(h),...m}}h=e.filter(f).map(e=>String(e.id)).sort(W).map(d);let g=e.map(e=>String(e.id)).filter(e=>!u.has(e)).sort(W).map(e=>({...d(e),children:[]}));return{roots:h,cyclic:g,total:e.length,...m}}function ln(e){return e.reduce((e,t)=>e+1+ln(t.children),0)}const un=e=>e===`done`||e===`completed`||e===`cancelled`;function dn(e){let t=e.filter(e=>[`pending`,`in-progress`,`done`,`completed`,`cancelled`].includes(e.status||`pending`)),n=Ut(e),r=e=>n.get(String(e.id))??0,i={critical:4,high:3,medium:2,low:1},a=/* @__PURE__ */ new Set;t.forEach(e=>{un(e.status)&&a.add(String(e.id)),Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{un(t.status)&&a.add(`${e.id}.${t.id}`)})});let o=[];if(t.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 r=t.dependencies?.map(t=>B(e.id,t))??[];(r.length===0||r.every(e=>a.has(String(e))))&&o.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,status:t.status||`pending`,priority:t.priority||e.priority||`medium`,dependencies:r,parentId:String(e.id),description:t.description,details:t.details,testStrategy:t.testStrategy,subtasks:[]})})}),o.length>0)return o.sort((e,t)=>{let n=i[e.priority]??2,a=i[t.priority]??2;if(a!==n)return a-n;if(r(e)!==r(t))return r(t)-r(e);if(e.dependencies.length!==t.dependencies.length)return e.dependencies.length-t.dependencies.length;let[o,s]=String(e.id).split(`.`).map(Number),[c,l]=String(t.id).split(`.`).map(Number);return o===c?s-l:o-c}),o[0];let s=t.filter(e=>{let t=(e.status||`pending`).toLowerCase();return t!==`pending`&&t!==`in-progress`?!1:(e.dependencies??[]).every(e=>a.has(String(e)))});return s.length===0?null:s.sort((e,t)=>{let n=i[e.priority]??2,a=i[t.priority]??2;if(a!==n)return a-n;if(r(e)!==r(t))return r(t)-r(e);let o=(e.dependencies??[]).length,s=(t.dependencies??[]).length;return o===s?Number(e.id)-Number(t.id):o-s})[0]}var fn=class e{id;title;description;status;priority;dependencies;details;testStrategy;subtasks;createdAt;updatedAt;effort;actualEffort;tags;assignee;complexity;recommendedSubtasks;expansionPrompt;complexityReasoning;metadata;constructor(e){this.validate(e),this.id=String(e.id),this.title=e.title,this.description=e.description,this.status=e.status,this.priority=e.priority,this.dependencies=(e.dependencies||[]).map(e=>String(e)),this.details=e.details,this.testStrategy=e.testStrategy,this.subtasks=(e.subtasks||[]).map(e=>({...e,id:String(e.id),parentId:String(e.parentId)})),this.createdAt=e.createdAt,this.updatedAt=e.updatedAt,this.effort=e.effort,this.actualEffort=e.actualEffort,this.tags=e.tags,this.assignee=e.assignee,this.complexity=e.complexity,this.recommendedSubtasks=e.recommendedSubtasks,this.expansionPrompt=e.expansionPrompt,this.complexityReasoning=e.complexityReasoning,this.metadata=e.metadata}validate(e){if(e.id===void 0||e.id===null||typeof e.id!=`string`&&typeof e.id!=`number`)throw new C(`Task ID is required and must be a string or number`,S.VALIDATION_ERROR);if(!e.title||e.title.trim().length===0)throw new C(`Task title is required`,S.VALIDATION_ERROR);if(!e.description||e.description.trim().length===0)throw new C(`Task description is required`,S.VALIDATION_ERROR);if(!this.isValidStatus(e.status))throw new C(`Invalid task status: ${e.status}`,S.VALIDATION_ERROR);if(!this.isValidPriority(e.priority))throw new C(`Invalid task priority: ${e.priority}`,S.VALIDATION_ERROR)}isValidStatus(e){return[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`].includes(e)}isValidPriority(e){return[`low`,`medium`,`high`,`critical`].includes(e)}canComplete(){return this.status===`done`||this.status===`cancelled`||this.status===`blocked`?!1:this.subtasks.every(e=>e.status===`done`||e.status===`cancelled`)}markAsComplete(){if(!this.canComplete())throw new C(`Task cannot be marked as complete`,S.TASK_STATUS_ERROR,{taskId:this.id,currentStatus:this.status,hasIncompleteSubtasks:this.subtasks.some(e=>e.status!==`done`&&e.status!==`cancelled`)});this.status=`done`,this.updatedAt=(/* @__PURE__ */ new Date()).toISOString()}hasDependencies(){return this.dependencies.length>0}hasSubtasks(){return this.subtasks.length>0}addSubtask(e){let t=this.subtasks.length+1;this.subtasks.push({...e,id:t,parentId:this.id}),this.updatedAt=(/* @__PURE__ */ new Date()).toISOString()}updateStatus(e){if(!this.isValidStatus(e))throw new C(`Invalid status: ${e}`,S.VALIDATION_ERROR);if(this.status===`done`&&e===`pending`)throw new C(`Cannot move completed task back to pending`,S.TASK_STATUS_ERROR);this.status=e,this.updatedAt=(/* @__PURE__ */ new Date()).toISOString()}toJSON(){return{id:this.id,title:this.title,description:this.description,status:this.status,priority:this.priority,dependencies:this.dependencies,details:this.details,testStrategy:this.testStrategy,subtasks:this.subtasks,createdAt:this.createdAt,updatedAt:this.updatedAt,effort:this.effort,actualEffort:this.actualEffort,tags:this.tags,assignee:this.assignee,complexity:this.complexity,recommendedSubtasks:this.recommendedSubtasks,expansionPrompt:this.expansionPrompt,complexityReasoning:this.complexityReasoning,metadata:this.metadata}}static fromObject(t){return new e(t)}static fromArray(t){return t.map(t=>new e(t))}},pn=class{configManager;storage;initialized=!1;logger=x(`TaskService`);constructor(e){this.configManager=e,this.storage=null}async initialize(){if(this.initialized)return;let e=this.configManager.getStorageConfig(),t=this.configManager.getProjectRoot();this.storage=await At.createFromStorageConfig(e,t),await this.storage.initialize(),this.initialized=!0}async getTaskList(e={}){let t=this.configManager.getActiveTag(),n=e.tag||t;try{let t=e.filter?.status&&!e.filter.priority&&!e.filter.tags&&!e.filter.assignee&&!e.filter.search&&e.filter.hasSubtasks===void 0,r={};if(t){let t=Array.isArray(e.filter.status)?e.filter.status:[e.filter.status];t.length===1&&(r.status=t[0])}e.includeSubtasks===!1&&(r.excludeSubtasks=!0);let i=await this.storage.loadTasks(n,r),a={};e.includeSubtasks===!1&&(a.excludeSubtasks=!0);let o=r.status===void 0?i:await this.storage.loadTasks(n,a),s=fn.fromArray(i),c=s;return(e.filter&&!t||e.filter?.status&&Array.isArray(e.filter.status)&&e.filter.status.length>1)&&(c=this.applyFilters(s,e.filter)),{tasks:c.map(e=>e.toJSON()),total:o.length,filtered:c.length,tag:n}}catch(t){throw t instanceof C?t:(this.logger.error(`Failed to get task list`,t),new C(`Failed to get task list`,S.INTERNAL_ERROR,{operation:`getTaskList`,tag:n,hasFilter:!!e.filter},t))}}async getTask(e,t){let n=t||this.getActiveTag();try{return await this.storage.loadTask(String(e),n)}catch(t){throw t instanceof C?t:new C(`Failed to get task ${e}`,S.STORAGE_ERROR,{operation:`getTask`,resource:`task`,taskId:String(e),tag:n},t)}}async getTasksByStatus(e,t){let n=Array.isArray(e)?e:[e];return(await this.getTaskList({tag:t,filter:{status:n}})).tasks}async getTaskStats(e){let t=await this.getTaskList({tag:e,includeSubtasks:!0}),n={total:t.total,byStatus:{},withSubtasks:0,blocked:0};return[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`].forEach(e=>{n.byStatus[e]=0}),t.tasks.forEach(e=>{n.byStatus[e.status]++,e.subtasks&&e.subtasks.length>0&&n.withSubtasks++,e.status===`blocked`&&n.blocked++}),n}async getNextTask(e){return dn((await this.getTaskList({tag:e})).tasks)}applyFilters(e,t){return e.filter(e=>{if(t.status&&!(Array.isArray(t.status)?t.status:[t.status]).includes(e.status)||t.priority&&!(Array.isArray(t.priority)?t.priority:[t.priority]).includes(e.priority)||t.tags&&t.tags.length>0&&(!e.tags||!t.tags.some(t=>e.tags?.includes(t)))||t.assignee&&e.assignee!==t.assignee)return!1;if(t.search){let n=t.search.toLowerCase(),r=e.title.toLowerCase().includes(n),i=e.description.toLowerCase().includes(n),a=e.details.toLowerCase().includes(n);if(!r&&!i&&!a)return!1}return t.hasSubtasks===void 0||e.subtasks.length>0===t.hasSubtasks})}getStorage(){return this.storage}getActiveTag(){return this.configManager.getActiveTag()}async setActiveTag(e){await this.configManager.setActiveTag(e)}async updateTask(e,t,n){if(!this.storage)throw new C(`Storage not initialized`,S.STORAGE_ERROR);this.initialized||await this.initialize();let r=n||this.getActiveTag(),i=String(e);try{await this.storage.updateTask(i,t,r)}catch(t){throw t instanceof C?t:new C(`Failed to update task ${e}`,S.STORAGE_ERROR,{operation:`updateTask`,resource:`task`,taskId:i,tag:r},t)}}async updateTaskStatus(e,t,n){if(!this.storage)throw new C(`Storage not initialized`,S.STORAGE_ERROR);let r=n||this.getActiveTag(),i=String(e);try{return await this.storage.updateTaskStatus(i,t,r)}catch(e){throw e instanceof C?e:new C(`Failed to update task status for ${i}`,S.STORAGE_ERROR,{operation:`updateTaskStatus`,resource:`task`,taskId:i,newStatus:t,tag:r},e)}}async getTagsWithStats(){if(!this.storage)throw new C(`Storage not initialized`,S.STORAGE_ERROR);this.initialized||await this.initialize();try{return await this.storage.getTagsWithStats()}catch(e){throw e instanceof C?e:new C(`Failed to get tags with stats`,S.STORAGE_ERROR,{operation:`getTagsWithStats`,resource:`tags`},e)}}async close(){this.storage&&await this.storage.close(),this.initialized=!1}},mn=class{taskService;constructor(e){this.taskService=e}async startTask(e,t={}){try{let{parentId:n,subtaskId:r}=this.parseTaskId(e);if(!t.force){let t=await this.checkInProgressConflicts(e);if(!t.canProceed)return{task:null,found:!1,started:!1,error:`Conflicting tasks in progress: ${t.conflictingTasks.map(e=>`#${e.id}: ${e.title}`).join(`, `)}`}}let i=await this.taskService.getTask(n);if(!i)return{task:null,found:!1,started:!1,error:`Task ${n} not found`};let a;if(r&&i.subtasks&&(a=i.subtasks.find(e=>String(e.id)===r)),t.updateStatus&&!t.dryRun)try{await this.taskService.updateTaskStatus(n,`in-progress`)}catch(e){console.warn(`Could not update task status: ${e instanceof Error?e.message:String(e)}`)}let o=!1,s=`Task ready to execute`,c;return t.dryRun?(o=!0,s=`Dry run - task would be executed`,c=await this.prepareExecutionCommand(i,a)):(c=await this.prepareExecutionCommand(i,a),o=!!c,s=c?`Command prepared: ${c.executable} ${c.args.join(` `)}`:`Failed to prepare execution command`),{task:i,found:!0,started:o,subtaskId:r,subtask:a,executionOutput:s,command:c||void 0}}catch(e){return{task:null,found:!1,started:!1,error:e instanceof Error?e.message:String(e)}}}async checkInProgressConflicts(e){let t=(await this.taskService.getTaskList()).tasks.filter(e=>e.status===`in-progress`);if(t.find(t=>t.id===e))return{canProceed:!0,conflictingTasks:[]};let n=e.includes(`.`);if(n){let n=e.split(`.`)[0];if(t.find(e=>e.id===n))return{canProceed:!0,conflictingTasks:[]}}let r=t.filter(t=>{if(t.id===e)return!1;if(n){let n=e.split(`.`)[0];if(t.id===n)return!1}if(t.id.toString().includes(`.`)){let r=t.id.toString().split(`.`)[0];if(n&&r===e.split(`.`)[0])return!1}return!0});return r.length>0?{canProceed:!1,conflictingTasks:r,reason:`Other tasks are already in progress`}:{canProceed:!0,conflictingTasks:[]}}async getNextAvailableTask(){return(await this.taskService.getNextTask())?.id||null}parseTaskId(e){if(e.includes(`.`)){let[t,n]=e.split(`.`);return{parentId:t,subtaskId:n}}return{parentId:e}}async canStartTask(e,t=!1){return t?!0:(await this.checkInProgressConflicts(e)).canProceed}async prepareExecutionCommand(e,t){try{return{executable:`claude`,args:[this.formatTaskPrompt(e,t)],cwd:process.cwd()}}catch(e){return console.warn(`Failed to prepare execution command: ${e instanceof Error?e.message:String(e)}`),null}}formatTaskPrompt(e,t){let n=t||e,r=t?`Subtask`:`Task`,i=`${r} #${t?`${e.id}.${t.id}`:e.id}: ${n.title}\n\n`;return n.description&&(i+=`Description:\n${n.description}\n\n`),n.details&&(i+=`Implementation Details:\n${n.details}\n\n`),n.testStrategy&&(i+=`Test Strategy:\n${n.testStrategy}\n\n`),e.dependencies&&e.dependencies.length>0&&(i+=`Dependencies: ${e.dependencies.join(`, `)}\n\n`),i+=`Please help me implement this ${r.toLowerCase()}.`,i}async getTaskWithSubtask(e){let{parentId:t,subtaskId:n}=this.parseTaskId(e),r=await this.taskService.getTask(t);return r?n&&r.subtasks?{task:r,subtask:r.subtasks.find(e=>String(e.id)===n),subtaskId:n}:{task:r}:{task:null}}};const Z=x(`TaskLoader`);function hn(e,t){let n=B(e,t),r=`${e}.`;return n.startsWith(r)?n.slice(r.length):null}var gn=class{taskService;constructor(e){if(!e)throw Error(`taskService is required for TaskLoaderService`);this.taskService=e}async loadAndValidateTask(e){Z.info(`Loading task ${e}...`);let t=await this.loadTask(e);if(!t)return{success:!1,errorType:`task_not_found`,errorMessage:`Task with ID "${e}" not found`,suggestion:`Use "taskgraph list" to see available tasks or verify the task ID is correct.`};let n=this.validateTaskStatus(t);if(!n.success)return n;let r=this.validateSubtasksExist(t);if(!r.success)return r;let i=this.validateSubtaskStructure(t);if(!i.success)return i;let a=this.validateDependencies(t);return a.success?(Z.info(`Task ${e} validated successfully`),{success:!0,task:t}):a}async loadTask(e){try{return await this.taskService.getTask(e)}catch(t){return Z.error(`Failed to load task ${e}:`,t),null}}validateTaskStatus(e){return U(e.status)?{success:!1,errorType:`task_completed`,errorMessage:`Task "${e.title}" is already ${e.status}`,suggestion:`Autopilot can only execute tasks that are pending or in-progress. Use a different task.`}:{success:!0}}validateSubtasksExist(e){return!e.subtasks||e.subtasks.length===0?{success:!1,errorType:`no_subtasks`,errorMessage:`Task "${e.title}" has no subtasks`,suggestion:this.buildExpansionSuggestion(e)}:{success:!0}}buildExpansionSuggestion(e){let t=[`Autopilot requires tasks to be broken down into subtasks for execution.`];return t.push(`
|
|
185
|
+
`);return{complete:n.slice(0,-1),remaining:n[n.length-1]}}},pt=class{logger=x(`LoopDomain`);loopService=null;projectRoot;constructor(e){this.projectRoot=e.getProjectRoot()}checkSandboxAuth(){return new ft({projectRoot:this.projectRoot}).checkSandboxAuth()}runInteractiveAuth(){return new ft({projectRoot:this.projectRoot}).runInteractiveAuth()}isTrusted(){return ut(this.projectRoot)}trust(){dt(this.projectRoot)}async run(e){if(!e.sandbox&&!e.trusted&&!this.isTrusted())throw Error(`loop runs Claude with permission prompts off in this project. Approve it first, or pass --trust (or use --sandbox).`);if(this.loopService?.isRunning)try{this.loopService.stop()}catch(e){this.logger.warn(`Failed to stop previous loop service:`,e)}let t=this.buildConfig(e);return this.loopService=new ft({projectRoot:this.projectRoot}),this.loopService.run(t)}stop(){this.loopService&&=(this.loopService.stop(),null)}getIsRunning(){return this.loopService?.isRunning??!1}isPreset(e){return L(e)}async resolvePrompt(e,t){if(L(e))return st(e);if(!t)throw Error(`Custom prompt file requires readFile callback: ${e}`);return t(e)}getAvailablePresets(){return[...ot]}resolveIterations(e){let{userIterations:t,preset:n,pendingTaskCount:r}=e;return t===void 0?n==="default"&&r!==void 0&&r>0?r:10:t}buildConfig(e){return{iterations:e.iterations??10,prompt:e.prompt??`default`,progressFile:e.progressFile??t.join(this.projectRoot,`.taskgraph`,`progress.txt`),sleepSeconds:e.sleepSeconds??5,tag:e.tag,sandbox:e.sandbox??!1,includeOutput:e.includeOutput??!1,verbose:e.verbose??!1,callbacks:e.callbacks}}},mt=class{detectFormat(e){return!e||typeof e!=`object`?`standard`:Object.keys(e).some(e=>e!==`tasks`&&e!==`metadata`)?`legacy`:`standard`}extractTasks(e,t){return e?this.detectFormat(e)===`legacy`?this.extractTasksFromLegacy(e,t):this.extractTasksFromStandard(e):[]}extractTasksFromLegacy(e,t){if(t in e)return e[t]?.tasks||[];let n=Object.keys(e).filter(e=>e!==`tasks`&&e!==`metadata`);return t===`master`&&n.length>0&&e[n[0]]?.tasks||[]}extractTasksFromStandard(e){return e?.tasks||[]}extractMetadata(e,t){return e?this.detectFormat(e)===`legacy`?this.extractMetadataFromLegacy(e,t):this.extractMetadataFromStandard(e):null}extractMetadataFromLegacy(e,t){if(t in e){let n=e[t];return!n?.metadata&&n?.tasks?this.generateMetadataFromTasks(n.tasks,t):n?.metadata||null}let n=Object.keys(e).filter(e=>e!==`tasks`&&e!==`metadata`);if(t===`master`&&n.length>0){let t=n[0],r=e[t];return!r?.metadata&&r?.tasks?this.generateMetadataFromTasks(r.tasks,t):r?.metadata||null}return null}extractMetadataFromStandard(e){return e?.metadata||null}extractTags(e){return e?this.detectFormat(e)===`legacy`?Object.keys(e).filter(e=>e!==`tasks`&&e!==`metadata`):[`master`]:[]}convertToSaveFormat(e,t,n,r){let i=r||`master`,a=this.normalizeTasks(e);return n&&this.detectFormat(n)===`legacy`?this.convertToLegacyFormat(a,t,i):this.convertToStandardFormat(a,t,r)}convertToLegacyFormat(e,t,n){return{[n]:{tasks:e,metadata:{...t,tags:[n]}}}}convertToStandardFormat(e,t,n){return{tasks:e,metadata:{...t,tags:n?[n]:[]}}}normalizeTasks(e){return e.map(e=>({...e,id:String(e.id),dependencies:e.dependencies?.map(e=>String(e))||[],subtasks:e.subtasks?.map(t=>({...t,id:Number(t.id),parentId:String(t.parentId??e.id)}))||[]}))}generateMetadataFromTasks(e,t){return{version:`1.0.0`,lastModified:(/* @__PURE__ */ new Date()).toISOString(),taskCount:e.length,completedCount:e.filter(e=>e.status===`done`).length,tags:[t]}}};function ht(e){return typeof e==`number`&&Number.isInteger(e)&&e>=1}function gt(e){let t=e?.schemaVersion;return ht(t)?t:1}function z(e,t){let n=ht(t?.schemaVersion)?t.schemaVersion:0;return{...e,schemaVersion:Math.max(1,n)}}const _t=/* @__PURE__ */ new Set;function vt(e,t,n){let r=e?.schemaVersion,i=r!==void 0&&!ht(r);if(!i&>(e)<=1)return;let a=`${n}::${t}`;if(_t.has(a))return;_t.add(a);let o=i?`an unrecognized schemaVersion (${JSON.stringify(r)})`:`schema version ${r}, newer than the 1 this version understands`;process.stderr.write(`Warning: tag "${t}" in ${n} has ${o}. Loading it anyway; consider upgrading taskgraph.\n`)}function yt(e,n){let r=t.relative(process.cwd(),e),i=r&&!r.startsWith(`..`)&&!t.isAbsolute(r)?r:e,a=/\(line (\d+) column (\d+)\)/.exec(n.message),o=a?` (line ${a[1]}, column ${a[2]})`:``;return new C(`Invalid JSON in file ${e}: ${n.message}`,S.JSON_PARSE_ERROR,{resource:e,userMessage:`${i} isn't valid JSON${o}`},n)}const bt={stale:1e4,retries:{retries:5,factor:2,minTimeout:100,maxTimeout:1e3},realpath:!1};var xt=class{writers=/* @__PURE__ */ new Map;getWriter(e){let t=this.writers.get(e);return t||(t=new ce(e),this.writers.set(e,t)),t}async readJson(e){try{let t=await i.readFile(e,`utf-8`);return JSON.parse(t)}catch(t){throw t.code===`ENOENT`?t:t instanceof SyntaxError?yt(e,t):Error(`Failed to read file ${e}: ${t.message}`)}}async acquireLock(e){let t=`${e}.lock`;try{let e=await i.lstat(t);if(!e.isDirectory()&&Date.now()-e.mtimeMs>bt.stale){let e=`${t}.stale.${process.pid}.${Date.now()}`;await i.rename(t,e).catch(()=>void 0),await i.rm(e,{force:!0})}}catch(e){if(e.code!==`ENOENT`)throw e}return se.lock(e,bt)}async writeJson(e,t){await this.ensureFileExists(e);let n=null;try{n=await this.acquireLock(e);let r=JSON.stringify(t,null,2);await this.getWriter(e).write(r)}finally{if(n)try{await n()}catch(t){(process.env.DEBUG||process.env.TASKGRAPH_DEBUG===`true`)&&console.warn(`[WARN] Lock release warning for ${e}: ${t.message}`)}}}async modifyJson(e,t){await this.ensureFileExists(e);let n=null;try{n=await this.acquireLock(e);let r;try{let t=await i.readFile(e,`utf-8`);r=JSON.parse(t)}catch(t){if(t.code===`ENOENT`)r={};else if(t instanceof SyntaxError){let n=await i.readFile(e,`utf-8`).catch(()=>``);if(n.trim()===``||n.trim()===`{}`)r={};else throw Error(`Corrupted JSON in ${e}: ${t.message}. File contains: ${n.substring(0,100)}...`)}else throw Error(`Failed to read ${e} for modification: ${t.message}`)}let a=await t(r),o=JSON.stringify(a,null,2);await this.getWriter(e).write(o)}finally{if(n)try{await n()}catch(t){(process.env.DEBUG||process.env.TASKGRAPH_DEBUG===`true`)&&console.warn(`[WARN] Lock release warning for ${e}: ${t.message}`)}}}async ensureFileExists(e){let n=t.dirname(e);await i.mkdir(n,{recursive:!0});try{await i.writeFile(e,`{}`,{flag:`wx`})}catch(e){if(e.code!==`EEXIST`)throw e}}async exists(e){try{return await i.access(e,l.F_OK),!0}catch{return!1}}async getStats(e){return i.stat(e)}async readDir(e){return i.readdir(e)}async ensureDir(e){try{await i.mkdir(e,{recursive:!0})}catch(t){throw Error(`Failed to create directory ${e}: ${t.message}`)}}async deleteFile(e){try{await i.unlink(e)}catch(t){if(t.code!==`ENOENT`)throw Error(`Failed to delete file ${e}: ${t.message}`)}}async moveFile(e,t){try{await i.rename(e,t)}catch(n){throw Error(`Failed to move file from ${e} to ${t}: ${n.message}`)}}async copyFile(e,t){try{await i.copyFile(e,t)}catch(n){throw Error(`Failed to copy file from ${e} to ${t}: ${n.message}`)}}async cleanup(){this.writers.clear()}},St=class{basePath;tasksDir;tasksFilePath;constructor(e){this.basePath=t.join(e,`.taskgraph`),this.tasksDir=t.join(this.basePath,`tasks`),this.tasksFilePath=t.join(this.tasksDir,`tasks.json`)}getBasePath(){return this.basePath}getTasksDir(){return this.tasksDir}getTasksPath(){return this.tasksFilePath}};function Ct(e){return typeof e==`number`&&e<=99}function B(e,t){return Ct(t)?`${e}.${t}`:String(t)}const V=x(`ComplexityReportManager`);var wt=class{projectRoot;reportCache=/* @__PURE__ */ new Map;constructor(e){this.projectRoot=e}getReportPath(e){let t=m.join(this.projectRoot,`.taskgraph`,`reports`),n=e&&e!==`master`?`_${e}`:``;return m.join(t,`task-complexity-report${n}.json`)}async loadReport(e){let t=e||`master`,n=t;if(this.reportCache.has(n))return this.reportCache.get(n);let r=this.getReportPath(e);try{await i.access(r);let e=await i.readFile(r,`utf-8`),a=JSON.parse(e);return!a.meta||!Array.isArray(a.complexityAnalysis)?(V.warn(`Invalid complexity report structure at ${r}, ignoring`),null):(this.reportCache.set(n,a),V.debug(`Loaded complexity report for tag '${t}' with ${a.complexityAnalysis.length} analyses`),a)}catch(e){return e.code===`ENOENT`?(V.debug(`No complexity report found for tag '${t}'`),null):(V.warn(`Failed to load complexity report for tag '${t}': ${e.message}`),null)}}async getComplexityForTask(e,t){let n=await this.loadReport(t);if(!n)return null;let r=n.complexityAnalysis.find(t=>String(t.taskId)===String(e));return r?{complexityScore:r.complexityScore,recommendedSubtasks:r.recommendedSubtasks,expansionPrompt:r.expansionPrompt,complexityReasoning:r.complexityReasoning}:null}async getComplexityForTasks(e,t){let n=/* @__PURE__ */ new Map,r=await this.loadReport(t);if(!r)return n;let i=/* @__PURE__ */ new Map;return r.complexityAnalysis.forEach(e=>{i.set(String(e.taskId),e)}),e.forEach(e=>{let t=i.get(String(e));t&&n.set(String(e),{complexityScore:t.complexityScore,recommendedSubtasks:t.recommendedSubtasks,expansionPrompt:t.expansionPrompt,complexityReasoning:t.complexityReasoning})}),n}clearCache(e){e?this.reportCache.delete(e):this.reportCache.clear()}async hasReport(e){let t=this.getReportPath(e);try{return await i.access(t),!0}catch{return!1}}};function Tt(e,t){return{version:`1.0.0`,lastModified:(/* @__PURE__ */ new Date()).toISOString(),taskCount:e.length,completedCount:e.filter(e=>e.status===`done`).length,tags:[t]}}function Et(e,t,n,r,i){let a=Dt(r);return e.detectFormat(t)===`legacy`||Object.keys(t).some(e=>e!==`tasks`&&e!==`metadata`)?(t[n]={tasks:a,metadata:z(i,t[n]?.metadata)},t):n===`master`?{tasks:a,metadata:z(i,t.metadata)}:{master:{tasks:t.tasks||[],metadata:z(t.metadata||i,t.metadata)},[n]:{tasks:a,metadata:z(i)}}}function Dt(e){return e.map(e=>({...e,id:String(e.id),dependencies:e.dependencies?.map(e=>String(e))||[],subtasks:e.subtasks?.map(t=>({...t,id:Number(t.id),parentId:String(t.parentId??e.id)}))||[]}))}var Ot=class{pathResolver;fileOps;formatHandler;reader;constructor(e,t,n,r){this.pathResolver=e,this.fileOps=t,this.formatHandler=n,this.reader=r}async createTag(e,t){let n=this.pathResolver.getTasksPath();try{await this.fileOps.modifyJson(n,n=>{if(this.formatHandler.detectFormat(n)===`legacy`){if(e in n)throw new C(`Tag ${e} already exists`,S.VALIDATION_ERROR);let r=[];return t?.copyFrom&&t.copyFrom in n&&n[t.copyFrom].tasks&&(r=JSON.parse(JSON.stringify(n[t.copyFrom].tasks))),n[e]={tasks:r,metadata:z({created:(/* @__PURE__ */ new Date()).toISOString(),updatedAt:(/* @__PURE__ */ new Date()).toISOString(),description:t?.description||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,tags:[e]})},n}{let r=n.tasks||[],i=n.metadata||{},a=[];return(t?.copyFrom===`master`||!t?.copyFrom)&&(a=JSON.parse(JSON.stringify(r))),{master:{tasks:r,metadata:z({...i,tags:[`master`]},i)},[e]:{tasks:a,metadata:z({created:(/* @__PURE__ */ new Date()).toISOString(),updatedAt:(/* @__PURE__ */ new Date()).toISOString(),description:t?.description||`Tag created on ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,tags:[e]})}}}})}catch(e){throw e.code===`ENOENT`?Error(`Tasks file not found - initialize project first`):e}}async deleteTag(e){let t=this.pathResolver.getTasksPath();try{let n=!1;await this.fileOps.modifyJson(t,t=>{if(this.formatHandler.detectFormat(t)!==`legacy`&&e===`master`)return n=!0,t;if(this.formatHandler.detectFormat(t)===`legacy`){if(e in t)return delete t[e],t;throw Error(`Tag ${e} not found`)}throw Error(`Tag ${e} not found in standard format`)}),n&&await this.fileOps.deleteFile(t)}catch(t){throw t.code===`ENOENT`?Error(`Tag ${e} not found - file doesn't exist`):t}}async renameTag(e,t){let n=this.pathResolver.getTasksPath();try{await this.fileOps.modifyJson(n,n=>{if(this.formatHandler.detectFormat(n)===`legacy`){if(e in n)return n[t]=n[e],delete n[e],n[t].metadata&&(n[t].metadata.tags=[t]),n;throw Error(`Tag ${e} not found`)}if(e===`master`){let e=n.tasks||[],r=n.metadata||{};return{[t]:{tasks:e,metadata:z({...r,tags:[t]},r)}}}throw Error(`Tag ${e} not found in standard format`)})}catch(t){throw t.code===`ENOENT`?Error(`Tag ${e} not found - file doesn't exist`):t}}async getTagsWithStats(){let e=await this.reader.getAllTags(),t=await this.getActiveTagFromState(),n=await Promise.all(e.map(async e=>{try{let n=await this.reader.loadTasks(e),r={},i=0,a={totalSubtasks:0,subtasksByStatus:{}};n.forEach(e=>{let t=e.status||`pending`;r[t]=(r[t]||0)+1,t===`done`&&i++,e.subtasks&&e.subtasks.length>0&&(a.totalSubtasks+=e.subtasks.length,e.subtasks.forEach(e=>{let t=e.status||`pending`;a.subtasksByStatus[t]=(a.subtasksByStatus[t]||0)+1}))});let o=await this.reader.loadMetadata(e);return{name:e,isCurrent:e===t,taskCount:n.length,completedTasks:i,statusBreakdown:r,subtaskCounts:a.totalSubtasks>0?a:void 0,created:o?.created,description:o?.description}}catch{return{name:e,isCurrent:e===t,taskCount:0,completedTasks:0,statusBreakdown:{}}}}));return{tags:n,currentTag:t,totalTags:n.length}}async getActiveTagFromState(){try{let e=t.join(this.pathResolver.getBasePath(),`state.json`);return(await this.fileOps.readJson(e))?.currentTag||`master`}catch{return`master`}}};function H(e,t=e){return new C(e,S.TASK_NOT_FOUND,{userMessage:t})}var kt=class{formatHandler;fileOps;pathResolver;complexityManager;tagOps;constructor(e){this.formatHandler=new mt,this.fileOps=new xt,this.pathResolver=new St(e),this.complexityManager=new wt(e),this.tagOps=new Ot(this.pathResolver,this.fileOps,this.formatHandler,this)}async initialize(){await this.fileOps.ensureDir(this.pathResolver.getTasksDir())}async close(){await this.fileOps.cleanup()}async getStats(){let e=this.pathResolver.getTasksPath();try{let t=await this.fileOps.getStats(e),n=await this.fileOps.readJson(e),r=this.formatHandler.extractTags(n),i=0,a=r.map(e=>{let r=this.formatHandler.extractTasks(n,e).length;return i+=r,{tag:e,taskCount:r,lastModified:t.mtime.toISOString()}});return{totalTasks:i,totalTags:r.length,lastModified:t.mtime.toISOString(),storageSize:0,tagStats:a}}catch(e){if(e.code===`ENOENT`)return{totalTasks:0,totalTags:0,lastModified:(/* @__PURE__ */ new Date()).toISOString(),storageSize:0,tagStats:[]};throw Error(`Failed to get storage stats: ${e.message}`)}}async loadTasks(e,t){let n=this.pathResolver.getTasksPath(),r=e||`master`;try{let e=await this.fileOps.readJson(n),i=this.formatHandler.extractTasks(e,r);return vt(this.formatHandler.extractMetadata(e,r),r,n),t&&(t.status&&(i=i.filter(e=>e.status===t.status)),t.excludeSubtasks&&(i=i.map(e=>({...e,subtasks:[]})))),await this.enrichTasksWithComplexity(i,r)}catch(e){if(e.code===`ENOENT`)return[];throw e instanceof C?e:Error(`Failed to load tasks: ${e.message}`)}}async loadTask(e,t){let n=await this.loadTasks(t);if(e.includes(`.`)){let[t,r]=e.split(`.`),i=n.find(e=>String(e.id)===t);if(!i||!i.subtasks)return null;let a=i.subtasks.find(e=>String(e.id)===r);if(!a)return null;let o=a.dependencies?.map(e=>B(i.id,e))??[];return{...a,id:e,title:a.title||`Subtask ${r}`,description:a.description||``,status:a.status||`pending`,priority:a.priority||i.priority||`medium`,dependencies:o,details:a.details||``,testStrategy:a.testStrategy||``,subtasks:[],tags:i.tags||[],assignee:a.assignee||i.assignee,complexity:a.complexity||i.complexity,createdAt:a.createdAt||i.createdAt,updatedAt:a.updatedAt||i.updatedAt,parentTask:{id:i.id,title:i.title,status:i.status},isSubtask:!0}}return n.find(t=>String(t.id)===String(e))||null}async saveTasks(e,t){let n=this.pathResolver.getTasksPath(),r=t||`master`;await this.fileOps.ensureDir(this.pathResolver.getTasksDir());let i=Tt(e,r);await this.fileOps.modifyJson(n,t=>Et(this.formatHandler,t,r,e,i))}async mutateTasks(e,t){let n=this.pathResolver.getTasksPath(),r=e||`master`,i;return await this.fileOps.ensureDir(this.pathResolver.getTasksDir()),await this.fileOps.modifyJson(n,e=>{let n=t(this.formatHandler.extractTasks(e,r));return i=n.result,n.tasks===null?e:Et(this.formatHandler,e,r,n.tasks,Tt(n.tasks,r))}),i}async exists(e){let t=this.pathResolver.getTasksPath();return this.fileOps.exists(t)}async getAllTags(){try{let e=this.pathResolver.getTasksPath(),t=await this.fileOps.readJson(e);return this.formatHandler.extractTags(t)}catch(e){if(e.code===`ENOENT`)return[];throw Error(`Failed to get tags: ${e.message}`)}}async loadMetadata(e){let t=this.pathResolver.getTasksPath(),n=e||`master`;try{let e=await this.fileOps.readJson(t);return this.formatHandler.extractMetadata(e,n)}catch(e){if(e.code===`ENOENT`)return null;throw Error(`Failed to load metadata: ${e.message}`)}}async saveMetadata(e,t){let n=await this.loadTasks(t);await this.saveTasks(n,t)}async appendTasks(e,t){await this.mutateTasks(t,t=>({tasks:[...t,...e],result:void 0}))}async updateTask(e,t,n){await this.mutateTasks(n,n=>{let r=n.findIndex(t=>String(t.id)===String(e));if(r===-1)throw H(`Task ${e} not found`);let i=n[r],a=t.subtasks;t.subtasks&&i.subtasks&&(a=t.subtasks.map(e=>{let t=i.subtasks?.find(t=>String(t.id)===String(e.id)||e.title&&t.title===e.title);return t?.metadata||e.metadata?{...e,metadata:{...t?.metadata||{},...e.metadata||{}}}:e}));let o=[...n];return o[r]={...i,...t,...a&&{subtasks:a},id:String(e)},{tasks:o,result:void 0}})}async updateTaskStatus(e,t,n){return this.mutateTasks(n,n=>{if(e.includes(`.`))return this.updateSubtaskStatusInFile(n,e,t);let r=n.findIndex(t=>String(t.id)===String(e));if(r===-1)throw H(`Task ${e} not found`);let i=n[r].status,a={success:!0,oldStatus:i,newStatus:t,taskId:String(e)};if(i===t)return{tasks:null,result:a};let o=[...n];return o[r]={...n[r],status:t,updatedAt:(/* @__PURE__ */ new Date()).toISOString()},{tasks:o,result:a}})}updateSubtaskStatusInFile(e,t,n){let r=t.split(`.`);if(r.length!==2)throw Error(`Invalid subtask ID format: ${t}. Expected format: parentId.subtaskId`);let[i,a]=r,o=a.trim();if(!/^\d+$/.test(o))throw Error(`Invalid subtask ID: ${o}. Subtask ID must be a positive integer.`);let s=Number(o),c=e.findIndex(e=>String(e.id)===String(i));if(c===-1)throw H(`Parent task ${i} not found`,`Task ${i} not found`);let l={...e[c],subtasks:[...e[c].subtasks??[]]},u=l.subtasks.findIndex(e=>e.id===s||String(e.id)===o);if(u===-1)throw H(`Subtask ${t} not found in parent task ${i}`,`Subtask ${t} not found`);let d=l.subtasks[u].status||`pending`,f={success:!0,oldStatus:d,newStatus:n,taskId:t};if(d===n)return{tasks:null,result:f};let p=(/* @__PURE__ */ new Date()).toISOString();l.subtasks[u]={...l.subtasks[u],status:n,updatedAt:p};let m=l.subtasks,h=l.status;if(m.length>0){let e=e=>e.status||`pending`,t=t=>{let n=e(t);return n===`done`||n===`completed`},n=m.every(t),r=m.some(t=>e(t)===`in-progress`),i=m.some(t),a=m.every(t=>e(t)===`pending`);n?h=`done`:r||i?h=`in-progress`:a&&(h=`pending`)}let g=[...e];return g[c]={...l,...h===l.status?{}:{status:h},updatedAt:p},{tasks:g,result:f}}async deleteTask(e,t){await this.mutateTasks(t,t=>{let n=t.filter(t=>String(t.id)!==String(e));if(n.length===t.length)throw H(`Task ${e} not found`);return{tasks:n,result:void 0}})}async createTag(e,t){return this.tagOps.createTag(e,t)}async deleteTag(e){return this.tagOps.deleteTag(e)}async renameTag(e,t){return this.tagOps.renameTag(e,t)}async copyTag(e,t){let n=await this.loadTasks(e);if(n.length===0)throw Error(`Source tag ${e} not found or has no tasks`);await this.saveTasks(n,t)}async getTagsWithStats(){return this.tagOps.getTagsWithStats()}async watch(e,t){let n=this.pathResolver.getTasksPath(),r=t?.debounceMs??100;if(!await this.fileOps.exists(n))throw new C(`Tasks file not found. Initialize the project first.`,S.NOT_FOUND,{path:n});let i,a=!1,o=c.watch(n,(t,n)=>{a||n&&t===`change`&&(i&&clearTimeout(i),i=setTimeout(()=>{a||e({type:`change`,timestamp:/* @__PURE__ */ new Date})},r))});return o.on(`error`,t=>{a||e({type:`error`,timestamp:/* @__PURE__ */ new Date,error:t})}),{unsubscribe:()=>{a=!0,i&&clearTimeout(i),o.close()}}}async enrichTasksWithComplexity(e,t){let n=e.map(e=>e.id),r=await this.complexityManager.getComplexityForTasks(n,t);return r.size===0?e:e.map(e=>{let t=r.get(String(e.id));return t?{...e,complexity:t.complexityScore,recommendedSubtasks:t.recommendedSubtasks,expansionPrompt:t.expansionPrompt,complexityReasoning:t.complexityReasoning}:e})}},At=class{static async createFromStorageConfig(e,t){return new kt(e.basePath||t)}},jt=`taskgraph-ai`,Mt=`0.54.14`;const Nt={CLAUDE_CODE:`claude-code`},Pt=Object.values(Nt);[...Pt];const Ft=`.taskgraph/tasks/tasks.json`,It=[`.taskgraph`,`.taskgraph/config.json`,Ft],Lt=/* @__PURE__ */ `.git,.svn,.hg,.fossil,.github,.gitlab,.circleci,.travis.yml,.jenkins,.buildkite,.vscode,.idea,.project,.devcontainer,package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lockb,bun.lock,deno.lock,deno.json,deno.jsonc,package.json,lerna.json,nx.json,turbo.json,rush.json,pnpm-workspace.yaml,Cargo.toml,Cargo.lock,go.mod,go.sum,go.work,pyproject.toml,setup.py,setup.cfg,poetry.lock,Pipfile,Pipfile.lock,uv.lock,Gemfile,Gemfile.lock,composer.json,composer.lock,build.gradle,build.gradle.kts,settings.gradle,settings.gradle.kts,pom.xml,build.sbt,project.clj,deps.edn,mix.exs,rebar.config,pubspec.yaml,Package.swift,CMakeLists.txt,Makefile,meson.build,BUILD.bazel,WORKSPACE,flake.nix,shell.nix,default.nix,Dockerfile,docker-compose.yml,docker-compose.yaml,Containerfile,kubernetes.yml,kubernetes.yaml,helm/Chart.yaml`.split(`,`),Rt=[`tasks.json`,...Lt,`requirements.txt`];[...It,...Rt];const zt=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`],Bt=[`done`,`completed`,`cancelled`];function U(e){return Bt.includes(e)}const Vt=[`text`,`json`,`compact`],Ht={done:`✓`,completed:`✓`,"in-progress":`►`,blocked:`⭕`,pending:`○`,deferred:`⏸`,cancelled:`✗`,review:`👁`},W=(e,t)=>e.localeCompare(t,void 0,{numeric:!0});function G(e){let t=[];for(let n of e){let e=String(n.id);t.push({id:e,title:n.title,status:n.status,priority:n.priority,deps:(n.dependencies??[]).map(String)});for(let r of n.subtasks??[])t.push({id:`${e}.${r.id}`,title:r.title,status:r.status??`pending`,priority:r.priority??n.priority,deps:(r.dependencies??[]).map(t=>B(e,t))})}let n=/* @__PURE__ */ new Map;for(let e of t)n.set(e.id,{id:e.id,title:e.title,status:e.status,priority:e.priority,dependencies:[],missing:[],selfDependency:!1,dependents:[]});for(let e of t){let t=n.get(e.id);for(let r of new Set(e.deps)){if(r===e.id){t.selfDependency=!0;continue}let i=n.get(r);i?(t.dependencies.push(r),i.dependents.push(e.id)):t.missing.push(r)}}return{nodes:n}}const K=e=>!U(e.status);function Ut(e,t=G(e)){let{nodes:n}=t,r=/* @__PURE__ */ new Map,i=[];for(let e of n.values())K(e)?i.push(e.id):r.set(e.id,0);let a=qt(i,e=>n.get(e).dependents,e=>K(n.get(e))),o=/* @__PURE__ */ new Map;a.forEach((e,t)=>{for(let n of e)o.set(n,t)});let s=Math.ceil(a.length/32),c=[];return a.forEach((e,t)=>{let i=new Uint32Array(s);for(let r of e)for(let e of n.get(r).dependents){let n=o.get(e);if(n===void 0||n===t)continue;i[n>>5]|=1<<(n&31);let r=c[n];for(let e=0;e<s;e++)i[e]|=r[e]}let l=e.length-1;for(let e=0;e<t;e++)i[e>>5]&1<<(e&31)&&(l+=a[e].length);c.push(i);for(let t of e)r.set(t,l)}),r}function Wt(e,t,n=G(e)){let{nodes:r}=n,i=[];for(let[t,a]of Ut(e,n)){let e=r.get(t);a>0&&K(e)&&i.push({id:t,title:e.title,status:e.status,blocks:a})}return i.sort((e,t)=>t.blocks-e.blocks||W(e.id,t.id)),t===void 0?i:i.slice(0,Math.max(0,t))}function Gt(e){let{nodes:t}=G(e);return qt([...t.keys()],e=>t.get(e).dependencies).filter(e=>e.length>1).map(e=>e.sort(W)).sort((e,t)=>W(e[0],t[0]))}function Kt(e,t=G(e)){let{nodes:n}=t,r=[...n.values()].filter(K).map(e=>e.id),i=e=>K(n.get(e)),a=new Set(qt(r,e=>n.get(e).dependencies,i).filter(e=>e.length>1).flat()),o=[...a];for(let e=0;e<o.length;e++)for(let t of n.get(o[e]).dependents)i(t)&&!a.has(t)&&(a.add(t),o.push(t));let s=r.filter(e=>!a.has(e)),c=e=>n.get(e).dependencies.filter(e=>i(e)&&!a.has(e)),l=/* @__PURE__ */ new Map;for(let e of s)l.set(e,c(e).length);let u=s.filter(e=>l.get(e)===0);for(let e=0;e<u.length;e++)for(let t of n.get(u[e]).dependents){if(!l.has(t))continue;let e=l.get(t)-1;l.set(t,e),e===0&&u.push(t)}let d=/* @__PURE__ */ new Map,f=null;for(let e of u){let t=1,n=null;for(let r of c(e)){let e=d.get(r).length+1;(e>t||e===t&&n!==null&&W(r,n)<0)&&(t=e,n=r)}d.set(e,{length:t,via:n});let r=f===null?null:d.get(f);(r===null||t>r.length||t===r.length&&W(e,f)<0)&&(f=e)}let p=[];for(let e=f;e!==null;e=d.get(e)?.via??null)p.unshift(e);return p}function qt(e,t,n=()=>!0){let r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Set,o=[],s=[],c=0;for(let l of e){if(r.has(l))continue;let e=[],u=s=>{r.set(s,c),i.set(s,c),c++,o.push(s),a.add(s),e.push({id:s,edges:t(s).filter(n),at:0})};for(u(l);e.length;){let t=e[e.length-1];if(t.at<t.edges.length){let e=t.edges[t.at++];r.has(e)?a.has(e)&&i.set(t.id,Math.min(i.get(t.id),r.get(e))):u(e);continue}if(e.pop(),i.get(t.id)===r.get(t.id)){let e=[],n;do n=o.pop(),a.delete(n),e.push(n);while(n!==t.id);s.push(e)}let n=e[e.length-1];n&&i.set(n.id,Math.min(i.get(n.id),i.get(t.id)))}}return s}const Jt=[`deferred`,`blocked`];function Yt(e,t){let{nodes:n}=G(e),r=n.get(String(t));if(!r)throw Error(`Task ${t} not found`);let i=Gt(e),a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set,s=/* @__PURE__ */ new Map,c=e=>{let t=e.kind===`cycle`?`cycle:${e.cycle}`:e.id,n=a.get(t);if(!n)a.set(t,e);else{for(let t of e.listedBy??[])n.listedBy?.includes(t)||n.listedBy?.push(t);for(let t of e.edges??[])n.edges?.some(e=>e.from===t.from&&e.to===t.to)||n.edges?.push(t)}},l=(e,t)=>{let n=i.find(e=>e.includes(t.id))??[t.id];return c({id:t.id,title:t.title,status:t.status,kind:`cycle`,cycle:n,edges:[{from:e.id,to:t.id}]}),{id:t.id,title:t.title,status:t.status,kind:`cycle`,blockers:[]}},u=e=>{let t=[];return e.selfDependency&&t.push(l(e,e)),{node:e,deps:e.dependencies.map(e=>n.get(e)).filter(e=>!U(e.status)).sort((e,t)=>W(e.id,t.id)),at:0,out:t}};if(U(r.status))return{id:r.id,title:r.title,status:r.status,blocked:!1,blockers:[],rootCauses:[]};let d=/* @__PURE__ */ new Set([r.id]),f=[u(r)],p=[];for(;f.length;){let e=f[f.length-1];if(e.at<e.deps.length){let t=e.deps[e.at++];d.has(t.id)?e.out.push(l(e.node,t)):o.has(t.id)?e.out.push({id:t.id,title:t.title,status:t.status,kind:s.get(t.id),blockers:[],repeated:!0}):(o.add(t.id),d.add(t.id),f.push(u(t)));continue}for(let t of[...e.node.missing].sort(W))c({id:t,kind:`missing`,listedBy:[e.node.id]}),e.out.push({id:t,kind:`missing`,blockers:[]});f.pop();let t=f[f.length-1];if(!t){p=e.out;break}let n=e.node;d.delete(n.id);let r=e.out.length?void 0:Jt.includes(n.status)?`stalled`:`ready`;s.set(n.id,r),r&&c({id:n.id,title:n.title,status:n.status,kind:r}),t.out.push({id:n.id,title:n.title,status:n.status,kind:r,blockers:e.out})}return{id:r.id,title:r.title,status:r.status,blocked:p.length>0,blockers:p,rootCauses:[...a.values()]}}function Xt(e,t={}){let n={bottlenecks:Wt(e,t.limit??5),criticalPath:Kt(e),cycles:Gt(e)};return t.id!==void 0&&(n.explanation=Yt(e,String(t.id))),n}const q=`dependencySources`;function J(e,t){return t===void 0?String(e):B(t,e)}function Y(e){let t=e?.[q];return!t||typeof t!=`object`||Array.isArray(t)?{}:{...t}}function Zt(e,t,n){let r=J(t,n);return(e.dependencies??[]).some(e=>J(e,n)===r)}const Qt=Zt;function X(e,t){let{[q]:n,...r}=e??{};return Object.keys(t).length>0&&(r[q]=t),Object.keys(r).length>0?r:void 0}function $t(e){if(!e)return;let{[q]:t,...n}=e;return Object.keys(n).length>0?n:void 0}function en(e,t){t?e.metadata=t:delete e.metadata}function tn(e,t,n){return Qt(e,t,n)&&Y(e.metadata)[J(t,n)]===`inferred`?`inferred`:`explicit`}function nn(e,t,n){let r=Y(t?.metadata),i={};for(let a of e.dependencies??[]){let e=J(a,n);(!(t&&Qt(t,a,n))||r[e]===`inferred`)&&(i[e]=`inferred`)}return X(t?.metadata??e.metadata,i)}function rn(e,t,n,r){let i=Y(e),a=J(t,r);return n===`inferred`?i[a]=`inferred`:delete i[a],X(e,i)}function an(e,t){let n={};for(let[r,i]of Object.entries(Y(e.metadata)))Qt(e,r,t)&&(n[r]=i);return X(e.metadata,n)}function on(e,t,n,r){let i=Y(e),a=i[J(t,r)];return delete i[J(t,r)],delete i[J(n,r)],a===`inferred`&&(i[J(n,r)]=`inferred`),X(e,i)}function sn(e,t,n,r=e=>e){let i=Y(e.metadata),a={};for(let o of e.dependencies??[])i[J(o,t)]===`inferred`&&(a[J(r(o),n)]=`inferred`);return X(e.metadata,a)}function cn(e,t={}){let n=new Map(e.map(e=>[String(e.id),e])),r=e=>(e.dependencies??[]).map(String).filter(t=>t!==String(e.id)),i=e=>r(e).filter(e=>n.has(e)),a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Set,s=e=>{let t=a.get(e);if(t!==void 0)return t;if(o.has(e))return 1/0;o.add(e);let r=i(n.get(e)),c=r.length?Math.max(...r.map(s))+1:0;return o.delete(e),a.set(e,c),c},c=/* @__PURE__ */ new Map;for(let t of e){let e=String(t.id),n=i(t).filter(e=>Number.isFinite(s(e))).sort((e,t)=>s(e)-s(t)||W(e,t));c.set(e,n.length?n[n.length-1]:null)}let l=/* @__PURE__ */ new Map;for(let[e,t]of c)t&&l.set(t,[...l.get(t)??[],e]);let u=/* @__PURE__ */ new Set,d=e=>{u.add(e);let t=n.get(e),a=c.get(e);return{id:e,title:t.title,status:t.status,priority:t.priority,alsoNeeds:i(t).filter(e=>e!==a).sort(W),missing:r(t).filter(e=>!n.has(e)),inferred:i(t).filter(e=>tn(t,e)===`inferred`).sort(W),children:(l.get(e)??[]).filter(e=>!u.has(e)).sort(W).map(d)}},f=e=>Number.isFinite(s(String(e.id)))&&!c.get(String(e.id)),p=G(e),m={bottlenecks:Wt(e,5,p),criticalPath:Kt(e,p)},h;if(t.rootId!==void 0){let e=String(t.rootId);if(!n.has(e))throw Error(`Task ${e} not found`);let r=d(e);return r.inferred=r.inferred.filter(t=>t!==c.get(e)),h=[r],{roots:h,cyclic:[],total:ln(h),...m}}h=e.filter(f).map(e=>String(e.id)).sort(W).map(d);let g=e.map(e=>String(e.id)).filter(e=>!u.has(e)).sort(W).map(e=>({...d(e),children:[]}));return{roots:h,cyclic:g,total:e.length,...m}}function ln(e){return e.reduce((e,t)=>e+1+ln(t.children),0)}const un=e=>e===`done`||e===`completed`||e===`cancelled`;function dn(e){let t=e.filter(e=>[`pending`,`in-progress`,`done`,`completed`,`cancelled`].includes(e.status||`pending`)),n=Ut(e),r=e=>n.get(String(e.id))??0,i={critical:4,high:3,medium:2,low:1},a=/* @__PURE__ */ new Set;t.forEach(e=>{un(e.status)&&a.add(String(e.id)),Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{un(t.status)&&a.add(`${e.id}.${t.id}`)})});let o=[];if(t.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 r=t.dependencies?.map(t=>B(e.id,t))??[];(r.length===0||r.every(e=>a.has(String(e))))&&o.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,status:t.status||`pending`,priority:t.priority||e.priority||`medium`,dependencies:r,parentId:String(e.id),description:t.description,details:t.details,testStrategy:t.testStrategy,subtasks:[]})})}),o.length>0)return o.sort((e,t)=>{let n=i[e.priority]??2,a=i[t.priority]??2;if(a!==n)return a-n;if(r(e)!==r(t))return r(t)-r(e);if(e.dependencies.length!==t.dependencies.length)return e.dependencies.length-t.dependencies.length;let[o,s]=String(e.id).split(`.`).map(Number),[c,l]=String(t.id).split(`.`).map(Number);return o===c?s-l:o-c}),o[0];let s=t.filter(e=>{let t=(e.status||`pending`).toLowerCase();return t!==`pending`&&t!==`in-progress`?!1:(e.dependencies??[]).every(e=>a.has(String(e)))});return s.length===0?null:s.sort((e,t)=>{let n=i[e.priority]??2,a=i[t.priority]??2;if(a!==n)return a-n;if(r(e)!==r(t))return r(t)-r(e);let o=(e.dependencies??[]).length,s=(t.dependencies??[]).length;return o===s?Number(e.id)-Number(t.id):o-s})[0]}var fn=class e{id;title;description;status;priority;dependencies;details;testStrategy;subtasks;createdAt;updatedAt;effort;actualEffort;tags;assignee;complexity;recommendedSubtasks;expansionPrompt;complexityReasoning;metadata;constructor(e){this.validate(e),this.id=String(e.id),this.title=e.title,this.description=e.description,this.status=e.status,this.priority=e.priority,this.dependencies=(e.dependencies||[]).map(e=>String(e)),this.details=e.details,this.testStrategy=e.testStrategy,this.subtasks=(e.subtasks||[]).map(e=>({...e,id:String(e.id),parentId:String(e.parentId)})),this.createdAt=e.createdAt,this.updatedAt=e.updatedAt,this.effort=e.effort,this.actualEffort=e.actualEffort,this.tags=e.tags,this.assignee=e.assignee,this.complexity=e.complexity,this.recommendedSubtasks=e.recommendedSubtasks,this.expansionPrompt=e.expansionPrompt,this.complexityReasoning=e.complexityReasoning,this.metadata=e.metadata}validate(e){if(e.id===void 0||e.id===null||typeof e.id!=`string`&&typeof e.id!=`number`)throw new C(`Task ID is required and must be a string or number`,S.VALIDATION_ERROR);if(!e.title||e.title.trim().length===0)throw new C(`Task title is required`,S.VALIDATION_ERROR);if(!e.description||e.description.trim().length===0)throw new C(`Task description is required`,S.VALIDATION_ERROR);if(!this.isValidStatus(e.status))throw new C(`Invalid task status: ${e.status}`,S.VALIDATION_ERROR);if(!this.isValidPriority(e.priority))throw new C(`Invalid task priority: ${e.priority}`,S.VALIDATION_ERROR)}isValidStatus(e){return[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`].includes(e)}isValidPriority(e){return[`low`,`medium`,`high`,`critical`].includes(e)}canComplete(){return this.status===`done`||this.status===`cancelled`||this.status===`blocked`?!1:this.subtasks.every(e=>e.status===`done`||e.status===`cancelled`)}markAsComplete(){if(!this.canComplete())throw new C(`Task cannot be marked as complete`,S.TASK_STATUS_ERROR,{taskId:this.id,currentStatus:this.status,hasIncompleteSubtasks:this.subtasks.some(e=>e.status!==`done`&&e.status!==`cancelled`)});this.status=`done`,this.updatedAt=(/* @__PURE__ */ new Date()).toISOString()}hasDependencies(){return this.dependencies.length>0}hasSubtasks(){return this.subtasks.length>0}addSubtask(e){let t=this.subtasks.length+1;this.subtasks.push({...e,id:t,parentId:this.id}),this.updatedAt=(/* @__PURE__ */ new Date()).toISOString()}updateStatus(e){if(!this.isValidStatus(e))throw new C(`Invalid status: ${e}`,S.VALIDATION_ERROR);if(this.status===`done`&&e===`pending`)throw new C(`Cannot move completed task back to pending`,S.TASK_STATUS_ERROR);this.status=e,this.updatedAt=(/* @__PURE__ */ new Date()).toISOString()}toJSON(){return{id:this.id,title:this.title,description:this.description,status:this.status,priority:this.priority,dependencies:this.dependencies,details:this.details,testStrategy:this.testStrategy,subtasks:this.subtasks,createdAt:this.createdAt,updatedAt:this.updatedAt,effort:this.effort,actualEffort:this.actualEffort,tags:this.tags,assignee:this.assignee,complexity:this.complexity,recommendedSubtasks:this.recommendedSubtasks,expansionPrompt:this.expansionPrompt,complexityReasoning:this.complexityReasoning,metadata:this.metadata}}static fromObject(t){return new e(t)}static fromArray(t){return t.map(t=>new e(t))}},pn=class{configManager;storage;initialized=!1;logger=x(`TaskService`);constructor(e){this.configManager=e,this.storage=null}async initialize(){if(this.initialized)return;let e=this.configManager.getStorageConfig(),t=this.configManager.getProjectRoot();this.storage=await At.createFromStorageConfig(e,t),await this.storage.initialize(),this.initialized=!0}async getTaskList(e={}){let t=this.configManager.getActiveTag(),n=e.tag||t;try{let t=e.filter?.status&&!e.filter.priority&&!e.filter.tags&&!e.filter.assignee&&!e.filter.search&&e.filter.hasSubtasks===void 0,r={};if(t){let t=Array.isArray(e.filter.status)?e.filter.status:[e.filter.status];t.length===1&&(r.status=t[0])}e.includeSubtasks===!1&&(r.excludeSubtasks=!0);let i=await this.storage.loadTasks(n,r),a={};e.includeSubtasks===!1&&(a.excludeSubtasks=!0);let o=r.status===void 0?i:await this.storage.loadTasks(n,a),s=fn.fromArray(i),c=s;return(e.filter&&!t||e.filter?.status&&Array.isArray(e.filter.status)&&e.filter.status.length>1)&&(c=this.applyFilters(s,e.filter)),{tasks:c.map(e=>e.toJSON()),total:o.length,filtered:c.length,tag:n}}catch(t){throw t instanceof C?t:(this.logger.error(`Failed to get task list`,t),new C(`Failed to get task list`,S.INTERNAL_ERROR,{operation:`getTaskList`,tag:n,hasFilter:!!e.filter},t))}}async getTask(e,t){let n=t||this.getActiveTag();try{return await this.storage.loadTask(String(e),n)}catch(t){throw t instanceof C?t:new C(`Failed to get task ${e}`,S.STORAGE_ERROR,{operation:`getTask`,resource:`task`,taskId:String(e),tag:n},t)}}async getTasksByStatus(e,t){let n=Array.isArray(e)?e:[e];return(await this.getTaskList({tag:t,filter:{status:n}})).tasks}async getTaskStats(e){let t=await this.getTaskList({tag:e,includeSubtasks:!0}),n={total:t.total,byStatus:{},withSubtasks:0,blocked:0};return[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`].forEach(e=>{n.byStatus[e]=0}),t.tasks.forEach(e=>{n.byStatus[e.status]++,e.subtasks&&e.subtasks.length>0&&n.withSubtasks++,e.status===`blocked`&&n.blocked++}),n}async getNextTask(e){return dn((await this.getTaskList({tag:e})).tasks)}applyFilters(e,t){return e.filter(e=>{if(t.status&&!(Array.isArray(t.status)?t.status:[t.status]).includes(e.status)||t.priority&&!(Array.isArray(t.priority)?t.priority:[t.priority]).includes(e.priority)||t.tags&&t.tags.length>0&&(!e.tags||!t.tags.some(t=>e.tags?.includes(t)))||t.assignee&&e.assignee!==t.assignee)return!1;if(t.search){let n=t.search.toLowerCase(),r=e.title.toLowerCase().includes(n),i=e.description.toLowerCase().includes(n),a=e.details.toLowerCase().includes(n);if(!r&&!i&&!a)return!1}return t.hasSubtasks===void 0||e.subtasks.length>0===t.hasSubtasks})}getStorage(){return this.storage}getActiveTag(){return this.configManager.getActiveTag()}async setActiveTag(e){await this.configManager.setActiveTag(e)}async updateTask(e,t,n){if(!this.storage)throw new C(`Storage not initialized`,S.STORAGE_ERROR);this.initialized||await this.initialize();let r=n||this.getActiveTag(),i=String(e);try{await this.storage.updateTask(i,t,r)}catch(t){throw t instanceof C?t:new C(`Failed to update task ${e}`,S.STORAGE_ERROR,{operation:`updateTask`,resource:`task`,taskId:i,tag:r},t)}}async updateTaskStatus(e,t,n){if(!this.storage)throw new C(`Storage not initialized`,S.STORAGE_ERROR);let r=n||this.getActiveTag(),i=String(e);try{return await this.storage.updateTaskStatus(i,t,r)}catch(e){throw e instanceof C?e:new C(`Failed to update task status for ${i}`,S.STORAGE_ERROR,{operation:`updateTaskStatus`,resource:`task`,taskId:i,newStatus:t,tag:r},e)}}async getTagsWithStats(){if(!this.storage)throw new C(`Storage not initialized`,S.STORAGE_ERROR);this.initialized||await this.initialize();try{return await this.storage.getTagsWithStats()}catch(e){throw e instanceof C?e:new C(`Failed to get tags with stats`,S.STORAGE_ERROR,{operation:`getTagsWithStats`,resource:`tags`},e)}}async close(){this.storage&&await this.storage.close(),this.initialized=!1}},mn=class{taskService;constructor(e){this.taskService=e}async startTask(e,t={}){try{let{parentId:n,subtaskId:r}=this.parseTaskId(e);if(!t.force){let t=await this.checkInProgressConflicts(e);if(!t.canProceed)return{task:null,found:!1,started:!1,error:`Conflicting tasks in progress: ${t.conflictingTasks.map(e=>`#${e.id}: ${e.title}`).join(`, `)}`}}let i=await this.taskService.getTask(n);if(!i)return{task:null,found:!1,started:!1,error:`Task ${n} not found`};let a;if(r&&i.subtasks&&(a=i.subtasks.find(e=>String(e.id)===r)),t.updateStatus&&!t.dryRun)try{await this.taskService.updateTaskStatus(n,`in-progress`)}catch(e){console.warn(`Could not update task status: ${e instanceof Error?e.message:String(e)}`)}let o=!1,s=`Task ready to execute`,c;return t.dryRun?(o=!0,s=`Dry run - task would be executed`,c=await this.prepareExecutionCommand(i,a)):(c=await this.prepareExecutionCommand(i,a),o=!!c,s=c?`Command prepared: ${c.executable} ${c.args.join(` `)}`:`Failed to prepare execution command`),{task:i,found:!0,started:o,subtaskId:r,subtask:a,executionOutput:s,command:c||void 0}}catch(e){return{task:null,found:!1,started:!1,error:e instanceof Error?e.message:String(e)}}}async checkInProgressConflicts(e){let t=(await this.taskService.getTaskList()).tasks.filter(e=>e.status===`in-progress`);if(t.find(t=>t.id===e))return{canProceed:!0,conflictingTasks:[]};let n=e.includes(`.`);if(n){let n=e.split(`.`)[0];if(t.find(e=>e.id===n))return{canProceed:!0,conflictingTasks:[]}}let r=t.filter(t=>{if(t.id===e)return!1;if(n){let n=e.split(`.`)[0];if(t.id===n)return!1}if(t.id.toString().includes(`.`)){let r=t.id.toString().split(`.`)[0];if(n&&r===e.split(`.`)[0])return!1}return!0});return r.length>0?{canProceed:!1,conflictingTasks:r,reason:`Other tasks are already in progress`}:{canProceed:!0,conflictingTasks:[]}}async getNextAvailableTask(){return(await this.taskService.getNextTask())?.id||null}parseTaskId(e){if(e.includes(`.`)){let[t,n]=e.split(`.`);return{parentId:t,subtaskId:n}}return{parentId:e}}async canStartTask(e,t=!1){return t?!0:(await this.checkInProgressConflicts(e)).canProceed}async prepareExecutionCommand(e,t){try{return{executable:`claude`,args:[this.formatTaskPrompt(e,t)],cwd:process.cwd()}}catch(e){return console.warn(`Failed to prepare execution command: ${e instanceof Error?e.message:String(e)}`),null}}formatTaskPrompt(e,t){let n=t||e,r=t?`Subtask`:`Task`,i=`${r} #${t?`${e.id}.${t.id}`:e.id}: ${n.title}\n\n`;return n.description&&(i+=`Description:\n${n.description}\n\n`),n.details&&(i+=`Implementation Details:\n${n.details}\n\n`),n.testStrategy&&(i+=`Test Strategy:\n${n.testStrategy}\n\n`),e.dependencies&&e.dependencies.length>0&&(i+=`Dependencies: ${e.dependencies.join(`, `)}\n\n`),i+=`Please help me implement this ${r.toLowerCase()}.`,i}async getTaskWithSubtask(e){let{parentId:t,subtaskId:n}=this.parseTaskId(e),r=await this.taskService.getTask(t);return r?n&&r.subtasks?{task:r,subtask:r.subtasks.find(e=>String(e.id)===n),subtaskId:n}:{task:r}:{task:null}}};const Z=x(`TaskLoader`);function hn(e,t){let n=B(e,t),r=`${e}.`;return n.startsWith(r)?n.slice(r.length):null}var gn=class{taskService;constructor(e){if(!e)throw Error(`taskService is required for TaskLoaderService`);this.taskService=e}async loadAndValidateTask(e){Z.info(`Loading task ${e}...`);let t=await this.loadTask(e);if(!t)return{success:!1,errorType:`task_not_found`,errorMessage:`Task with ID "${e}" not found`,suggestion:`Use "taskgraph list" to see available tasks or verify the task ID is correct.`};let n=this.validateTaskStatus(t);if(!n.success)return n;let r=this.validateSubtasksExist(t);if(!r.success)return r;let i=this.validateSubtaskStructure(t);if(!i.success)return i;let a=this.validateDependencies(t);return a.success?(Z.info(`Task ${e} validated successfully`),{success:!0,task:t}):a}async loadTask(e){try{return await this.taskService.getTask(e)}catch(t){return Z.error(`Failed to load task ${e}:`,t),null}}validateTaskStatus(e){return U(e.status)?{success:!1,errorType:`task_completed`,errorMessage:`Task "${e.title}" is already ${e.status}`,suggestion:`Autopilot can only execute tasks that are pending or in-progress. Use a different task.`}:{success:!0}}validateSubtasksExist(e){return!e.subtasks||e.subtasks.length===0?{success:!1,errorType:`no_subtasks`,errorMessage:`Task "${e.title}" has no subtasks`,suggestion:this.buildExpansionSuggestion(e)}:{success:!0}}buildExpansionSuggestion(e){let t=[`Autopilot requires tasks to be broken down into subtasks for execution.`];return t.push(`
|
|
186
186
|
Expand this task using:`),t.push(` taskgraph expand --id=${e.id}`),e.complexity||e.recommendedSubtasks?(t.push(`
|
|
187
187
|
This task has complexity analysis available. Consider reviewing it first:`),t.push(` taskgraph show ${e.id}`)):(t.push(`
|
|
188
188
|
Or analyze task complexity first to determine optimal subtask count:`),t.push(` taskgraph analyze-complexity --from=${e.id}`)),t.join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime-BxhE39jg.js";import{C as t,I as n,L as r,M as i,R as a,S as o,T as s,a as c,c as l,d as u,f as d,i as f,n as p,o as m,r as h,s as g,t as ee,w as _,x as te,z as ne}from"./src-
|
|
1
|
+
import{t as e}from"./rolldown-runtime-BxhE39jg.js";import{C as t,I as n,L as r,M as i,R as a,S as o,T as s,a as c,c as l,d as u,f as d,i as f,n as p,o as m,r as h,s as g,t as ee,w as _,x as te,z as ne}from"./src-DvvdBXWU.js";import{$ as v,B as re,P as ie,T as ae,X as y,Z as oe,_t as b,a as se,d as ce,dt as le,ft as ue,gt as de,ht as fe,it as x,j as pe,m as me,mt as he,n as ge,p as _e,pt as S,tt as ve,u as ye,v as be,y as xe}from"./config-manager-CtE1yo1I.js";import C from"chalk";import w,{resolve as Se}from"node:path";import T from"node:fs";import{stripVTControlCharacters as Ce}from"node:util";import we from"path";import{spawn as Te}from"child_process";import Ee from"node:os";import E from"fs";import{Argument as De,Command as D}from"commander";import Oe from"figlet";import ke from"gradient-string";import Ae from"terminal-link";import O from"boxen";import{Marked as je,marked as Me}from"marked";import{markedTerminal as Ne}from"marked-terminal";import Pe from"turndown";import Fe from"cli-table3";import Ie from"ora";import k from"process";import A from"inquirer";const Le={done:{color:C.green,icon:`✓`,tableIcon:`✓`},pending:{color:C.yellow,icon:`○`,tableIcon:`○`},"in-progress":{color:b.active,icon:`▶`,tableIcon:`▶`},deferred:{color:b.muted,icon:`–`,tableIcon:`–`},review:{color:C.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:b.muted,icon:`x`,tableIcon:`x`},blocked:{color:C.red,icon:`!`,tableIcon:`!`},completed:{color:C.green,icon:`✓`,tableIcon:`✓`}};function j(e){let t=Le[e];return t?t.color(t.icon):C.red(`X`)}function M(e,t=!1){let n=Le[e]||{color:C.red,icon:`X`,tableIcon:`X`},r=t?n.tableIcon:n.icon;return n.color(`${r} ${e}`)}function N(e=.9,t=40){let n=process.stdout.columns||80;return Math.max(Math.floor(n*e),t)}function P(){let e=process.stdout.columns;return e?Math.floor(e*.95):100}function Re(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 F(e,t){return e.length<=t?e:e.substring(0,t-3)+`...`}function ze(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`${C.green(`█`).repeat(i)+b.muted(`░`).repeat(a)} ${C.cyan(`${r}%`)} (${e}/${t})`}const Be=e=>e.replace(/\x1b\[[0-9;]*m/g,``).length,Ve=e=>b.brand(e),He=e=>e.length<2?e.join(``):`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`,Ue=(e,t)=>t?`${e} (${t})`:e;function We(e){return e.status===`done`||e.status===`completed`?[`Already done.`]:e.status===`cancelled`?[`Cancelled.`]:e.status===`pending`?[`Not blocked. Start it with: ${Ve(`taskgraph set-status --id=${e.id} --status=in-progress`)}`]:[`Not blocked by any dependencies (status: ${e.status}).`]}function Ge(e,t={}){let n=t.width??100,r=[],i=e=>{if(e.repeated)return`shown above`;let t={ready:`ready to start`,stalled:`${e.status}, needs a decision`,missing:`missing`,cycle:`loops back`};return e.kind?t[e.kind]:``},a=(e,t)=>{let r=`${t}${e.kind===`missing`?C.yellow(`⚠`):j(e.status)} ${b.brand(e.id)} `,a=i(e)?b.muted(` ← ${i(e)}`):``;return r+F(e.kind===`missing`?`no such task`:e.title??``,Math.max(12,n-Be(r)-Be(a)))+a},o=(e,t,n)=>{r.push(a(e,t+b.muted(n?`└─ `:`├─ `)));let i=t+b.muted(n?` `:`│ `);e.blockers.forEach((t,n)=>o(t,i,n===e.blockers.length-1))};if(r.push(`${j(e.status)} ${b.brand(e.id)} ${F(e.title,Math.max(12,n-e.id.length-4))}`),!e.blocked)return r.push(...We(e)),r;r.push(`Blocked by:`),e.blockers.forEach((t,n)=>o(t,``,n===e.blockers.length-1));let s=Ke(e.rootCauses);return s.length&&r.push(``,`To unblock:`,...s.map(e=>` ${e}`)),r}function Ke(e){let t=[],n=e.filter(e=>e.kind===`ready`);n.length&&t.push(`Do ${He(n.map(e=>Ue(e.id,e.title)))}: nothing else stands in ${n.length>1?`their`:`its`} way.`);for(let n of e)if(n.kind===`stalled`)t.push(`${n.id} is ${n.status}. Reopen it with: ${Ve(`taskgraph set-status --id=${n.id} --status=pending`)}`);else if(n.kind===`missing`){let e=(n.listedBy??[]).map(e=>Ve(`taskgraph remove-dependency --id=${e} --depends-on=${n.id}`));t.push(`${n.id} is not a task. Remove it with: ${He(e)}`)}else if(n.kind===`cycle`){let e=(n.edges??[]).map(e=>Ve(`taskgraph remove-dependency --id=${e.from} --depends-on=${e.to}`)),r=n.cycle??[n.id];t.push(r.length===1?`${n.id} depends on itself. Remove it with: ${He(e)}`:`${r.join(`, `)} depend on each other. Break the loop with: ${He(e)}`)}return t}function I(e,t,n){return(n?.color?C[n.color]:C.cyan)(Ae(e,t,{fallback:(e,t)=>n?.textOnlyFallback?e:`${e} (${t})`}))}function qe(e,t){return I(e,e,t)}function Je(e,t){return I(e,t,{color:`cyan`})}function Ye(){return Ae.isSupported}const Xe=ke(ue);function Ze(){return process.env.TM_HIDE_BANNER===`true`}function Qe(){return process.stdout.columns||80}function $e(e={}){if(Ze())return;let{version:t}=e;try{let e=Oe.textSync(`TaskGraph`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Xe(e))}catch{console.log(Xe(`=== TaskGraph ===`))}let n=`x.com/stephennmiller_`,r=I(n,`https://x.com/stephennmiller_`,{textOnlyFallback:!0}),i=C.dim(`by `)+C.cyan(r),a=t?t.replace(/^v/,``):``,o=`https://github.com/stephennmiller/taskgraph-ai/releases/tag/taskgraph-ai%40${a}`,s=t?I(`v${a}`,o,{color:`dim`,textOnlyFallback:!0}):``;if(s){let e=`by ${n}`.length,t=a.length+1,r=Qe()-e-t-1;r>=2?console.log(i+` `.repeat(r)+s):(console.log(i),console.log(s))}else console.log(i);console.log(``)}function et(){if(Ze())return;try{let e=Oe.textSync(`TaskGraph`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Xe(e))}catch{console.log(Xe(`=== TaskGraph ===`))}let e=I(`x.com/stephennmiller_`,`https://x.com/stephennmiller_`,{textOnlyFallback:!0});console.log(C.dim(`by `)+C.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:C.yellow.bold,s=a===`info`?S:`yellow`,c=[o(t),...n.map(e=>b.text(e))];r&&r.label&&r.action&&c.push(C.cyan(r.label)+`
|
|
2
2
|
`+b.brand.underline(r.action)),i&&c.push(b.muted(i));let l=c.join(`
|
|
3
3
|
|
|
4
4
|
`);return O(l,{padding:1,borderColor:s,borderStyle:`round`,margin:{top:1,bottom:1}})}const L={done:C.green(`█`),cancelled:b.muted(`─`),deferred:b.muted(`─`),inProgress:b.active(`▓`),review:C.magenta(`▒`),pending:C.yellow(`░`),blocked:C.red(`!`)};function nt(e,t=30,n){if(!n){let n=Math.round(e/100*t),r=t-n;return L.done.repeat(n)+b.muted(`░`).repeat(r)}let r=``,i=0,a=[[n.done,L.done],[n.cancelled,L.cancelled],[n.deferred,L.deferred],[n[`in-progress`],L.inProgress],[n.review,L.review],[n.pending,L.pending],[n.blocked,L.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+=L.pending.repeat(t-i)),r}function rt(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=>_(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function it(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=>_(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function at(e){let t=new Set(e.filter(e=>_(e.status)).map(e=>e.id)),n=e.filter(e=>!_(e.status)&&(!e.dependencies||e.dependencies.length===0)).length,r=e.filter(e=>!_(e.status)&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>t.has(e))).length,i=e.filter(e=>!_(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 ot(e){let t={critical:0,high:0,medium:0,low:0};return e.forEach(e=>{let n=e.priority||`medium`;t[n]++}),t}function st(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 ct(e,t=!1,n=!1){let r=[];t?r.push(`${L.done} Completed: ${C.green(`${e.completedCount}/${e.total}`)}`):r.push(`${L.done} Done: ${C.green(e.done)}`),r.push(`${L.cancelled} Cancelled: ${b.muted(e.cancelled)}`),r.push(`${L.deferred} Deferred: ${b.muted(e.deferred)}`);let i=e=>n?e.slice(0,2).join(` `)+(e.length>2?`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{c as createTagFromBranch,m as useTag}from"./src-Dz_uZuYA.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as e,_ as t,b as n,d as r,g as i,h as a,k as o,m as s,p as c,v as l,y as u}from"./src-Cs4ilbQ-.js";import{$ as d,B as f,C as p,G as m,J as h,K as g,N as _,Q as v,V as y,W as b,X as x,Y as S,_t as C,c as w,ct as T,dt as E,et as D,g as O,gt as k,h as A,ht as j,it as M,l as N,lt as P,nt as ee,o as F,p as I,pt as L,q as te,rt as ne,st as re,tt as ie,u as ae,v as oe,z as se}from"./config-manager-DIET_FiX.js";import{B as R,C as ce,U as le,h as ue}from"./src-V29fsb6x.js";import{A as z,C as B,S as de,_ as fe,a as pe,b as V,d as H,f as me,g as he,i as ge,k as _e,r as ve,u as ye,v as be,w as xe,x as U,y as Se}from"./research-D_nwZW-q.js";import{i as Ce,n as we,r as Te,t as W}from"./ai-services-unified-CKKHbOMd.js";import"./response-language-CnU32t1k.js";import G from"chalk";import Ee from"path";import{z as K}from"zod";import q,*as De from"fs";import J from"boxen";import Oe from"cli-table3";import"fuse.js";import{APICallError as ke}from"ai";import"@streamparser/json";import Ae from"cli-progress";function je(n,r,i){let o=t=>r===void 0?String(t):e(r,t),s=i===void 0?void 0:String(i),c=[...new Set((n.dependencies??[]).map(o))].filter(e=>e!==s),l=t(n,r,s,o);return{dependencies:c,metadata:a({dependencies:c,metadata:l},s)}}function Me(e,t){return je(e,void 0,t)}function Ne(t,n,r){let i=(e,t,r,i)=>{e.dependencies?.some(e=>t(e)===n)&&(e.dependencies=e.dependencies.map(e=>t(e)===n?r:e),c(e,l(e.metadata,n,String(r),i)))};for(let n of t){i(n,String,r);for(let t of n.subtasks??[])i(t,t=>e(n.id,t),String(r),n.id)}}const Pe="Run `taskgraph list` to see task IDs",Fe="Create some with `taskgraph parse-prd <file>`";function Ie(e,t,n,r){c(e,u(e.metadata,t,n,r))}function Le(e){for(let t of e||[]){t.metadata&&c(t,a(t));for(let e of t.subtasks||[])e.metadata&&c(e,a(e,t.id))}}var Re=class extends Error{constructor(e,t,n={},r){super(t,r),this.name=`DependencyError`,this.code=e,this.data=n}};const Y={NO_TASKS:`NO_TASKS`,TASK_NOT_FOUND:`TASK_NOT_FOUND`,NO_SUBTASKS:`NO_SUBTASKS`,SELF_DEPENDENCY:`SELF_DEPENDENCY`,CIRCULAR_DEPENDENCY:`CIRCULAR_DEPENDENCY`,FIX_FAILED:`FIX_FAILED`,CANNOT_MOVE_SUBTASK:`CANNOT_MOVE_SUBTASK`,INVALID_TASK_ID:`INVALID_TASK_ID`,INVALID_SOURCE_TAG:`INVALID_SOURCE_TAG`,INVALID_TARGET_TAG:`INVALID_TARGET_TAG`};function X(e,t,n,r){return new Re(e,t,{hint:n},r&&{cause:r})}async function ze(e,t,n,r={}){d(`debug`,`Adding dependency ${n} to task ${t}...`);let i=M(e,r.projectRoot,r.tag);if(!i||!i.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=S(n);if(!re(i.tasks,o))throw X(Y.TASK_NOT_FOUND,`Task ${o} not found`,Pe);let c=null,l;if(typeof a==`string`&&a.includes(`.`)){let[e,t]=a.split(`.`).map(e=>parseInt(e,10)),n=i.tasks.find(t=>t.id===e);if(!n)throw X(Y.TASK_NOT_FOUND,`Task ${e} not found`,Pe);if(!n.subtasks)throw X(Y.NO_SUBTASKS,`Task ${e} has no subtasks`,`Add some with \`taskgraph expand --id=${e}\``);if(c=n.subtasks.find(e=>e.id===t),l=e,!c)throw X(Y.TASK_NOT_FOUND,`Subtask ${a} not found`,Pe)}else if(c=i.tasks.find(e=>e.id===a),!c)throw X(Y.TASK_NOT_FOUND,`Task ${a} not found`,Pe);if(c.dependencies||(c.dependencies=[]),s(c,o,l)){let t=JSON.stringify(c.metadata);if(Ie(c,o,`explicit`,l),JSON.stringify(c.metadata)!==t){E(e,i,r.projectRoot,r.tag),d(`success`,`Task ${a} now lists task ${o} as an explicit dependency`);return}d(`info`,`Task ${a} already depends on task ${o}; nothing changed`);return}if(String(a)===String(o))throw X(Y.SELF_DEPENDENCY,`Task ${a} can't depend on itself`);let u=!1;if(typeof a==`string`&&typeof o==`string`&&a.includes(`.`)&&o.includes(`.`)){let[e]=a.split(`.`),[t]=o.split(`.`);u=a===o,d(`debug`,`Adding dependency between subtasks: ${a} depends on ${o}`),d(`debug`,`Parent IDs: ${e} and ${t}, Self-dependency check: ${u}`)}if(u)throw X(Y.SELF_DEPENDENCY,`Subtask ${a} can't depend on itself`);let f=[a];if(!Ve(i.tasks,o,f))c.dependencies.push(o),Ie(c,o,`explicit`,l),c.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}),E(e,i,r.projectRoot,r.tag),d(`success`,`Task ${a} now depends on task ${o}`),d(`debug`,`Task files regenerated with updated dependencies.`);else throw X(Y.CIRCULAR_DEPENDENCY,`That would make a loop: task ${o} already depends on task ${a}`,"Run `taskgraph graph` to see how they connect")}async function Be(t,n,r,i={}){d(`debug`,`Removing dependency ${r} from task ${n}...`);let a=M(t,i.projectRoot,i.tag);if(!a||!a.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);let o=typeof n==`string`&&n.includes(`.`)?n:parseInt(n,10),s=S(r),c=null,l=!1;if(typeof o==`string`&&o.includes(`.`)){let[e,t]=o.split(`.`).map(e=>parseInt(e,10)),n=a.tasks.find(t=>t.id===e);if(!n)throw X(Y.TASK_NOT_FOUND,`Task ${e} not found`,Pe);if(!n.subtasks)throw X(Y.NO_SUBTASKS,`Task ${e} has no subtasks`,`Add some with \`taskgraph expand --id=${e}\``);if(c=n.subtasks.find(e=>e.id===t),l=!0,!c)throw X(Y.TASK_NOT_FOUND,`Subtask ${o} not found`,Pe)}else if(c=a.tasks.find(e=>e.id===o),!c)throw X(Y.TASK_NOT_FOUND,`Task ${o} not found`,Pe);if(!c.dependencies||c.dependencies.length===0){d(`info`,`Task ${o} has no dependencies; nothing changed`);return}let u=String(s),f=c.dependencies.findIndex(t=>(l?e(o.split(`.`)[0],t):String(t))===u);if(f===-1){d(`info`,`Task ${o} doesn't depend on task ${s}; nothing changed`);return}let[p]=c.dependencies.splice(f,1);Ie(c,p,`explicit`,l?o.split(`.`)[0]:void 0),E(t,a,i.projectRoot,i.tag),d(`success`,`Task ${o} no longer depends on task ${s}`)}function Ve(t,n,r=[]){let i=String(n);if(r.some(e=>String(e)===i))return!0;let a=null,o=null;if(i.includes(`.`)){let[e,n]=i.split(`.`).map(Number),r=t.find(t=>t.id===e);o=e,r&&r.subtasks&&(a=r.subtasks.find(e=>e.id===n))}else{let e=parseInt(i,10);a=t.find(t=>t.id===e||String(t.id)===i)}if(!a||!a.dependencies||a.dependencies.length===0)return!1;let s=[...r,i];return a.dependencies.some(n=>Ve(t,o===null?String(n):e(o,n),s))}function He(t,{subtasksOnly:n=!1}={}){let r=/* @__PURE__ */ new Map,i=(e,t)=>{let i=t.filter(t=>t!==e&&(!n||t.includes(`.`)));r.set(e,i)};for(let r of t){let t=String(r.id);n||i(t,(r.dependencies||[]).map(String));for(let n of r.subtasks||[])i(`${t}.${n.id}`,(n.dependencies||[]).map(n=>e(t,n)))}return r}function Ue(e){let t=/* @__PURE__ */ new Map,n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Set,i=[],a=/* @__PURE__ */ new Set,o=0,s=a=>(t.set(a,o),n.set(a,o),o++,i.push(a),r.add(a),{id:a,edges:e.get(a),next:0});for(let o of e.keys()){if(t.has(o))continue;let c=[s(o)];for(;c.length>0;){let o=c[c.length-1];if(o.next<o.edges.length){let i=o.edges[o.next++];if(i===o.id&&a.add(i),!e.has(i))continue;t.has(i)?r.has(i)&&n.set(o.id,Math.min(n.get(o.id),t.get(i))):c.push(s(i));continue}if(c.pop(),n.get(o.id)===t.get(o.id)){let e=[],t;do t=i.pop(),r.delete(t),e.push(t);while(t!==o.id);if(e.length>1)for(let t of e)a.add(t)}let l=c[c.length-1];l&&n.set(l.id,Math.min(n.get(l.id),n.get(o.id)))}}return a}function We(e){let t=/* @__PURE__ */ new Map;for(let n of e)t.has(n.id)||t.set(n.id,n.subtasks?new Set(n.subtasks.map(e=>e.id)):null);return e=>{if(!e)return!1;if(typeof e==`string`&&e.includes(`.`)){let[n,r]=e.split(`.`).map(e=>parseInt(e,10));return Number.isNaN(n)||Number.isNaN(r)?!1:t.get(n)?.has(r)??!1}let n=parseInt(e,10);return!Number.isNaN(n)&&t.has(n)}}function Ge(t){let n=[],r=Ue(He(t)),i=Ue(He(t,{subtasksOnly:!0})),a=We(t);return t.forEach(t=>{t.dependencies&&(t.dependencies.forEach(e=>{String(e)===String(t.id)?n.push({type:`self`,taskId:t.id,message:`Task ${t.id} depends on itself`}):a(e)||n.push({type:`missing`,taskId:t.id,dependencyId:e,message:`Task ${t.id} depends on non-existent task ${e}`})}),r.has(String(t.id))&&n.push({type:`circular`,taskId:t.id,fixable:!1,message:`Task ${t.id} is part of a circular dependency chain`}),t.subtasks&&t.subtasks.length>0&&t.subtasks.forEach(s=>{if(!s.dependencies)return;let c=`${t.id}.${s.id}`;s.dependencies.forEach(r=>{if(String(r)===String(c)||o(r)&&r===s.id){n.push({type:`self`,taskId:c,message:`Subtask ${c} depends on itself`});return}let i=o(r)?e(t.id,r):r;a(i)||n.push({type:`missing`,taskId:c,dependencyId:i,message:`Subtask ${c} depends on non-existent task/subtask ${r}`})}),r.has(c)&&n.push({type:`circular`,taskId:c,fixable:i.has(c),message:`Subtask ${c} is part of a circular dependency chain`})}))}),{valid:n.length===0,issues:n}}async function Ke(e,t={}){let{context:n={}}=t;d(`debug`,`Checking for invalid dependencies in task files...`);let r=M(e,n.projectRoot,n.tag);if(!r||!r.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);let i=qe(r.tasks);d(`debug`,`Analyzing dependencies for ${i.taskCount} tasks and ${i.subtaskCount} subtasks...`);let{valid:a,issues:o}=Ge(r.tasks);return{valid:a,issues:o,...i}}function qe(e){let t=e.reduce((e,t)=>e+(Array.isArray(t.subtasks)?t.subtasks.length:0),0);return{taskCount:e.length,subtaskCount:t,dependencyCount:Je(e)}}function Je(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 Ye(t,n={}){let{context:r={}}=n;d(`debug`,`Checking for and fixing invalid dependencies in tasks.json...`);let i=M(t,r.projectRoot,r.tag);if(!i||!i.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);try{let n=[],a=JSON.parse(JSON.stringify(i)),s={nonExistentDependenciesRemoved:0,selfDependenciesRemoved:0,duplicateDependenciesRemoved:0,circularDependenciesFixed:0,tasksFixed:0,subtasksFixed:0};i.tasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let e=/* @__PURE__ */ new Set,r=t.dependencies.length;t.dependencies=t.dependencies.filter(r=>{let i=String(r);return e.has(i)?(n.push({type:`duplicate`,taskId:t.id,dependencyId:r}),s.duplicateDependenciesRemoved++,!1):(e.add(i),!0)}),t.dependencies.length<r&&s.tasksFixed++}t.subtasks&&Array.isArray(t.subtasks)&&t.subtasks.forEach(r=>{if(r.dependencies&&Array.isArray(r.dependencies)){let i=/* @__PURE__ */ new Set,a=r.dependencies.length;r.dependencies=r.dependencies.filter(a=>{let o=e(t.id,a);return i.has(o)?(n.push({type:`duplicate`,taskId:`${t.id}.${r.id}`,dependencyId:o}),s.duplicateDependenciesRemoved++,!1):(i.add(o),!0)}),r.dependencies.length<a&&s.subtasksFixed++}})});let c=new Set(i.tasks.map(e=>e.id)),l=/* @__PURE__ */ new Set;i.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{l.add(`${e.id}.${t.id}`)})}),i.tasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let e=t.dependencies.length;t.dependencies=t.dependencies.filter(e=>{if(String(e)===String(t.id))return n.push({type:`self`,taskId:t.id}),s.selfDependenciesRemoved++,!1;if(typeof e==`string`&&e.includes(`.`))return l.has(e)?!0:(n.push({type:`missing`,taskId:t.id,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1);{let r=typeof e==`string`?parseInt(e,10):e;return c.has(r)?!0:(n.push({type:`missing`,taskId:t.id,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1)}}),t.dependencies.length<e&&s.tasksFixed++}t.subtasks&&Array.isArray(t.subtasks)&&t.subtasks.forEach(r=>{if(r.dependencies&&Array.isArray(r.dependencies)){let i=r.dependencies.length,a=`${t.id}.${r.id}`;r.dependencies.some(e=>typeof e==`string`&&e.includes(`.`)?e===a:o(e)?e===r.id:!1)&&(r.dependencies=r.dependencies.filter(r=>e(t.id,r)!==a||(n.push({type:`self`,taskId:a}),s.selfDependenciesRemoved++,!1))),r.dependencies=r.dependencies.filter(e=>{if(typeof e==`string`&&e.includes(`.`))return l.has(e)?!0:(n.push({type:`missing`,taskId:a,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1);let r=typeof e==`number`?e:parseInt(e,10);if(o(e)){let e=`${t.id}.${r}`;return l.has(e)?!0:(n.push({type:`missing`,taskId:a,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1)}return c.has(r)?!0:(n.push({type:`missing`,taskId:a,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1)}),r.dependencies.length<i&&s.subtasksFixed++}})}),d(`debug`,`Checking for circular dependencies...`);let u=/* @__PURE__ */ new Map;i.tasks.forEach(t=>{t.subtasks&&Array.isArray(t.subtasks)&&t.subtasks.forEach(n=>{let r=`${t.id}.${n.id}`;if(n.dependencies&&Array.isArray(n.dependencies)){let i=n.dependencies.map(n=>typeof n==`string`&&n.includes(`.`)?n:e(t.id,n));u.set(r,i)}else u.set(r,[])})});let f=(e,t,n=/* @__PURE__ */ new Set)=>e===t||!n.has(e)&&(n.add(e),(u.get(e)||[]).some(e=>f(e,t,n)));for(let[t,r]of u.entries()){let[a,o]=t.split(`.`).map(Number),c=i.tasks.find(e=>e.id===a)?.subtasks?.find(e=>e.id===o);if(c?.dependencies)for(let i of[...r]){if(!f(i,t))continue;let o=c.dependencies.length;c.dependencies=c.dependencies.filter(t=>e(a,t)!==i),r.splice(r.indexOf(i),1),c.dependencies.length<o&&(n.push({type:`circular`,taskId:t,dependencyId:i}),s.circularDependenciesFixed++,s.subtasksFixed++)}}Le(i.tasks);let p=JSON.stringify(i)!==JSON.stringify(a);return p?(E(t,i,r.projectRoot,r.tag),d(`debug`,`Fixed ${n.length} dependency problems`,s)):d(`debug`,`No changes needed to fix dependencies`),{fixes:n,remaining:Ge(i.tasks).issues,changed:p,...qe(i.tasks)}}catch(e){throw X(Y.FIX_FAILED,`Couldn't fix dependencies: ${e.message}`,void 0,e)}}function Xe(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 Ze(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=Xe(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=Xe(e,r,n,!1)}}return i}function Qe(e,t,n){let r=[];return!Array.isArray(e.dependencies)||e.dependencies.length===0||e.dependencies.filter(e=>e!=null).forEach(i=>{let a=Ze(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 $e(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=Qe(e,n,r);i.push(...t)}),i}function et(e,t,n){if(!e||typeof e!=`string`)throw new Re(Y.INVALID_TASK_ID,`Task ID must be a valid string`);if(!t||typeof t!=`string`)throw new Re(Y.INVALID_SOURCE_TAG,`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw new Re(Y.INVALID_TARGET_TAG,`Target tag must be a valid string`);if(e.includes(`.`))throw new Re(Y.CANNOT_MOVE_SUBTASK,`Cannot move subtask ${e} directly between tags.
|
|
1
|
+
import{A as e,_ as t,b as n,d as r,g as i,h as a,k as o,m as s,p as c,v as l,y as u}from"./src-DvvdBXWU.js";import{$ as d,B as f,C as p,G as m,J as h,K as g,N as _,Q as v,V as y,W as b,X as x,Y as S,_t as C,c as w,ct as T,dt as E,et as D,g as O,gt as k,h as A,ht as j,it as M,l as N,lt as P,nt as ee,o as F,p as I,pt as L,q as te,rt as ne,st as re,tt as ie,u as ae,v as oe,z as se}from"./config-manager-CtE1yo1I.js";import{B as R,C as ce,U as le,h as ue}from"./src-Dz_uZuYA.js";import{A as z,C as B,S as de,_ as fe,a as pe,b as V,d as H,f as me,g as he,i as ge,k as _e,r as ve,u as ye,v as be,w as xe,x as U,y as Se}from"./research-DcB3PdqA.js";import{i as Ce,n as we,r as Te,t as W}from"./ai-services-unified-CvcPXr89.js";import"./response-language-BdYSHT6o.js";import G from"chalk";import Ee from"path";import{z as K}from"zod";import q,*as De from"fs";import J from"boxen";import Oe from"cli-table3";import"fuse.js";import{APICallError as ke}from"ai";import"@streamparser/json";import Ae from"cli-progress";function je(n,r,i){let o=t=>r===void 0?String(t):e(r,t),s=i===void 0?void 0:String(i),c=[...new Set((n.dependencies??[]).map(o))].filter(e=>e!==s),l=t(n,r,s,o);return{dependencies:c,metadata:a({dependencies:c,metadata:l},s)}}function Me(e,t){return je(e,void 0,t)}function Ne(t,n,r){let i=(e,t,r,i)=>{e.dependencies?.some(e=>t(e)===n)&&(e.dependencies=e.dependencies.map(e=>t(e)===n?r:e),c(e,l(e.metadata,n,String(r),i)))};for(let n of t){i(n,String,r);for(let t of n.subtasks??[])i(t,t=>e(n.id,t),String(r),n.id)}}const Pe="Run `taskgraph list` to see task IDs",Fe="Create some with `taskgraph parse-prd <file>`";function Ie(e,t,n,r){c(e,u(e.metadata,t,n,r))}function Le(e){for(let t of e||[]){t.metadata&&c(t,a(t));for(let e of t.subtasks||[])e.metadata&&c(e,a(e,t.id))}}var Re=class extends Error{constructor(e,t,n={},r){super(t,r),this.name=`DependencyError`,this.code=e,this.data=n}};const Y={NO_TASKS:`NO_TASKS`,TASK_NOT_FOUND:`TASK_NOT_FOUND`,NO_SUBTASKS:`NO_SUBTASKS`,SELF_DEPENDENCY:`SELF_DEPENDENCY`,CIRCULAR_DEPENDENCY:`CIRCULAR_DEPENDENCY`,FIX_FAILED:`FIX_FAILED`,CANNOT_MOVE_SUBTASK:`CANNOT_MOVE_SUBTASK`,INVALID_TASK_ID:`INVALID_TASK_ID`,INVALID_SOURCE_TAG:`INVALID_SOURCE_TAG`,INVALID_TARGET_TAG:`INVALID_TARGET_TAG`};function X(e,t,n,r){return new Re(e,t,{hint:n},r&&{cause:r})}async function ze(e,t,n,r={}){d(`debug`,`Adding dependency ${n} to task ${t}...`);let i=M(e,r.projectRoot,r.tag);if(!i||!i.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);let a=typeof t==`string`&&t.includes(`.`)?t:parseInt(t,10),o=S(n);if(!re(i.tasks,o))throw X(Y.TASK_NOT_FOUND,`Task ${o} not found`,Pe);let c=null,l;if(typeof a==`string`&&a.includes(`.`)){let[e,t]=a.split(`.`).map(e=>parseInt(e,10)),n=i.tasks.find(t=>t.id===e);if(!n)throw X(Y.TASK_NOT_FOUND,`Task ${e} not found`,Pe);if(!n.subtasks)throw X(Y.NO_SUBTASKS,`Task ${e} has no subtasks`,`Add some with \`taskgraph expand --id=${e}\``);if(c=n.subtasks.find(e=>e.id===t),l=e,!c)throw X(Y.TASK_NOT_FOUND,`Subtask ${a} not found`,Pe)}else if(c=i.tasks.find(e=>e.id===a),!c)throw X(Y.TASK_NOT_FOUND,`Task ${a} not found`,Pe);if(c.dependencies||(c.dependencies=[]),s(c,o,l)){let t=JSON.stringify(c.metadata);if(Ie(c,o,`explicit`,l),JSON.stringify(c.metadata)!==t){E(e,i,r.projectRoot,r.tag),d(`success`,`Task ${a} now lists task ${o} as an explicit dependency`);return}d(`info`,`Task ${a} already depends on task ${o}; nothing changed`);return}if(String(a)===String(o))throw X(Y.SELF_DEPENDENCY,`Task ${a} can't depend on itself`);let u=!1;if(typeof a==`string`&&typeof o==`string`&&a.includes(`.`)&&o.includes(`.`)){let[e]=a.split(`.`),[t]=o.split(`.`);u=a===o,d(`debug`,`Adding dependency between subtasks: ${a} depends on ${o}`),d(`debug`,`Parent IDs: ${e} and ${t}, Self-dependency check: ${u}`)}if(u)throw X(Y.SELF_DEPENDENCY,`Subtask ${a} can't depend on itself`);let f=[a];if(!Ve(i.tasks,o,f))c.dependencies.push(o),Ie(c,o,`explicit`,l),c.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}),E(e,i,r.projectRoot,r.tag),d(`success`,`Task ${a} now depends on task ${o}`),d(`debug`,`Task files regenerated with updated dependencies.`);else throw X(Y.CIRCULAR_DEPENDENCY,`That would make a loop: task ${o} already depends on task ${a}`,"Run `taskgraph graph` to see how they connect")}async function Be(t,n,r,i={}){d(`debug`,`Removing dependency ${r} from task ${n}...`);let a=M(t,i.projectRoot,i.tag);if(!a||!a.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);let o=typeof n==`string`&&n.includes(`.`)?n:parseInt(n,10),s=S(r),c=null,l=!1;if(typeof o==`string`&&o.includes(`.`)){let[e,t]=o.split(`.`).map(e=>parseInt(e,10)),n=a.tasks.find(t=>t.id===e);if(!n)throw X(Y.TASK_NOT_FOUND,`Task ${e} not found`,Pe);if(!n.subtasks)throw X(Y.NO_SUBTASKS,`Task ${e} has no subtasks`,`Add some with \`taskgraph expand --id=${e}\``);if(c=n.subtasks.find(e=>e.id===t),l=!0,!c)throw X(Y.TASK_NOT_FOUND,`Subtask ${o} not found`,Pe)}else if(c=a.tasks.find(e=>e.id===o),!c)throw X(Y.TASK_NOT_FOUND,`Task ${o} not found`,Pe);if(!c.dependencies||c.dependencies.length===0){d(`info`,`Task ${o} has no dependencies; nothing changed`);return}let u=String(s),f=c.dependencies.findIndex(t=>(l?e(o.split(`.`)[0],t):String(t))===u);if(f===-1){d(`info`,`Task ${o} doesn't depend on task ${s}; nothing changed`);return}let[p]=c.dependencies.splice(f,1);Ie(c,p,`explicit`,l?o.split(`.`)[0]:void 0),E(t,a,i.projectRoot,i.tag),d(`success`,`Task ${o} no longer depends on task ${s}`)}function Ve(t,n,r=[]){let i=String(n);if(r.some(e=>String(e)===i))return!0;let a=null,o=null;if(i.includes(`.`)){let[e,n]=i.split(`.`).map(Number),r=t.find(t=>t.id===e);o=e,r&&r.subtasks&&(a=r.subtasks.find(e=>e.id===n))}else{let e=parseInt(i,10);a=t.find(t=>t.id===e||String(t.id)===i)}if(!a||!a.dependencies||a.dependencies.length===0)return!1;let s=[...r,i];return a.dependencies.some(n=>Ve(t,o===null?String(n):e(o,n),s))}function He(t,{subtasksOnly:n=!1}={}){let r=/* @__PURE__ */ new Map,i=(e,t)=>{let i=t.filter(t=>t!==e&&(!n||t.includes(`.`)));r.set(e,i)};for(let r of t){let t=String(r.id);n||i(t,(r.dependencies||[]).map(String));for(let n of r.subtasks||[])i(`${t}.${n.id}`,(n.dependencies||[]).map(n=>e(t,n)))}return r}function Ue(e){let t=/* @__PURE__ */ new Map,n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Set,i=[],a=/* @__PURE__ */ new Set,o=0,s=a=>(t.set(a,o),n.set(a,o),o++,i.push(a),r.add(a),{id:a,edges:e.get(a),next:0});for(let o of e.keys()){if(t.has(o))continue;let c=[s(o)];for(;c.length>0;){let o=c[c.length-1];if(o.next<o.edges.length){let i=o.edges[o.next++];if(i===o.id&&a.add(i),!e.has(i))continue;t.has(i)?r.has(i)&&n.set(o.id,Math.min(n.get(o.id),t.get(i))):c.push(s(i));continue}if(c.pop(),n.get(o.id)===t.get(o.id)){let e=[],t;do t=i.pop(),r.delete(t),e.push(t);while(t!==o.id);if(e.length>1)for(let t of e)a.add(t)}let l=c[c.length-1];l&&n.set(l.id,Math.min(n.get(l.id),n.get(o.id)))}}return a}function We(e){let t=/* @__PURE__ */ new Map;for(let n of e)t.has(n.id)||t.set(n.id,n.subtasks?new Set(n.subtasks.map(e=>e.id)):null);return e=>{if(!e)return!1;if(typeof e==`string`&&e.includes(`.`)){let[n,r]=e.split(`.`).map(e=>parseInt(e,10));return Number.isNaN(n)||Number.isNaN(r)?!1:t.get(n)?.has(r)??!1}let n=parseInt(e,10);return!Number.isNaN(n)&&t.has(n)}}function Ge(t){let n=[],r=Ue(He(t)),i=Ue(He(t,{subtasksOnly:!0})),a=We(t);return t.forEach(t=>{t.dependencies&&(t.dependencies.forEach(e=>{String(e)===String(t.id)?n.push({type:`self`,taskId:t.id,message:`Task ${t.id} depends on itself`}):a(e)||n.push({type:`missing`,taskId:t.id,dependencyId:e,message:`Task ${t.id} depends on non-existent task ${e}`})}),r.has(String(t.id))&&n.push({type:`circular`,taskId:t.id,fixable:!1,message:`Task ${t.id} is part of a circular dependency chain`}),t.subtasks&&t.subtasks.length>0&&t.subtasks.forEach(s=>{if(!s.dependencies)return;let c=`${t.id}.${s.id}`;s.dependencies.forEach(r=>{if(String(r)===String(c)||o(r)&&r===s.id){n.push({type:`self`,taskId:c,message:`Subtask ${c} depends on itself`});return}let i=o(r)?e(t.id,r):r;a(i)||n.push({type:`missing`,taskId:c,dependencyId:i,message:`Subtask ${c} depends on non-existent task/subtask ${r}`})}),r.has(c)&&n.push({type:`circular`,taskId:c,fixable:i.has(c),message:`Subtask ${c} is part of a circular dependency chain`})}))}),{valid:n.length===0,issues:n}}async function Ke(e,t={}){let{context:n={}}=t;d(`debug`,`Checking for invalid dependencies in task files...`);let r=M(e,n.projectRoot,n.tag);if(!r||!r.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);let i=qe(r.tasks);d(`debug`,`Analyzing dependencies for ${i.taskCount} tasks and ${i.subtaskCount} subtasks...`);let{valid:a,issues:o}=Ge(r.tasks);return{valid:a,issues:o,...i}}function qe(e){let t=e.reduce((e,t)=>e+(Array.isArray(t.subtasks)?t.subtasks.length:0),0);return{taskCount:e.length,subtaskCount:t,dependencyCount:Je(e)}}function Je(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 Ye(t,n={}){let{context:r={}}=n;d(`debug`,`Checking for and fixing invalid dependencies in tasks.json...`);let i=M(t,r.projectRoot,r.tag);if(!i||!i.tasks)throw X(Y.NO_TASKS,`No tasks yet`,Fe);try{let n=[],a=JSON.parse(JSON.stringify(i)),s={nonExistentDependenciesRemoved:0,selfDependenciesRemoved:0,duplicateDependenciesRemoved:0,circularDependenciesFixed:0,tasksFixed:0,subtasksFixed:0};i.tasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let e=/* @__PURE__ */ new Set,r=t.dependencies.length;t.dependencies=t.dependencies.filter(r=>{let i=String(r);return e.has(i)?(n.push({type:`duplicate`,taskId:t.id,dependencyId:r}),s.duplicateDependenciesRemoved++,!1):(e.add(i),!0)}),t.dependencies.length<r&&s.tasksFixed++}t.subtasks&&Array.isArray(t.subtasks)&&t.subtasks.forEach(r=>{if(r.dependencies&&Array.isArray(r.dependencies)){let i=/* @__PURE__ */ new Set,a=r.dependencies.length;r.dependencies=r.dependencies.filter(a=>{let o=e(t.id,a);return i.has(o)?(n.push({type:`duplicate`,taskId:`${t.id}.${r.id}`,dependencyId:o}),s.duplicateDependenciesRemoved++,!1):(i.add(o),!0)}),r.dependencies.length<a&&s.subtasksFixed++}})});let c=new Set(i.tasks.map(e=>e.id)),l=/* @__PURE__ */ new Set;i.tasks.forEach(e=>{e.subtasks&&Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{l.add(`${e.id}.${t.id}`)})}),i.tasks.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)){let e=t.dependencies.length;t.dependencies=t.dependencies.filter(e=>{if(String(e)===String(t.id))return n.push({type:`self`,taskId:t.id}),s.selfDependenciesRemoved++,!1;if(typeof e==`string`&&e.includes(`.`))return l.has(e)?!0:(n.push({type:`missing`,taskId:t.id,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1);{let r=typeof e==`string`?parseInt(e,10):e;return c.has(r)?!0:(n.push({type:`missing`,taskId:t.id,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1)}}),t.dependencies.length<e&&s.tasksFixed++}t.subtasks&&Array.isArray(t.subtasks)&&t.subtasks.forEach(r=>{if(r.dependencies&&Array.isArray(r.dependencies)){let i=r.dependencies.length,a=`${t.id}.${r.id}`;r.dependencies.some(e=>typeof e==`string`&&e.includes(`.`)?e===a:o(e)?e===r.id:!1)&&(r.dependencies=r.dependencies.filter(r=>e(t.id,r)!==a||(n.push({type:`self`,taskId:a}),s.selfDependenciesRemoved++,!1))),r.dependencies=r.dependencies.filter(e=>{if(typeof e==`string`&&e.includes(`.`))return l.has(e)?!0:(n.push({type:`missing`,taskId:a,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1);let r=typeof e==`number`?e:parseInt(e,10);if(o(e)){let e=`${t.id}.${r}`;return l.has(e)?!0:(n.push({type:`missing`,taskId:a,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1)}return c.has(r)?!0:(n.push({type:`missing`,taskId:a,dependencyId:e}),s.nonExistentDependenciesRemoved++,!1)}),r.dependencies.length<i&&s.subtasksFixed++}})}),d(`debug`,`Checking for circular dependencies...`);let u=/* @__PURE__ */ new Map;i.tasks.forEach(t=>{t.subtasks&&Array.isArray(t.subtasks)&&t.subtasks.forEach(n=>{let r=`${t.id}.${n.id}`;if(n.dependencies&&Array.isArray(n.dependencies)){let i=n.dependencies.map(n=>typeof n==`string`&&n.includes(`.`)?n:e(t.id,n));u.set(r,i)}else u.set(r,[])})});let f=(e,t,n=/* @__PURE__ */ new Set)=>e===t||!n.has(e)&&(n.add(e),(u.get(e)||[]).some(e=>f(e,t,n)));for(let[t,r]of u.entries()){let[a,o]=t.split(`.`).map(Number),c=i.tasks.find(e=>e.id===a)?.subtasks?.find(e=>e.id===o);if(c?.dependencies)for(let i of[...r]){if(!f(i,t))continue;let o=c.dependencies.length;c.dependencies=c.dependencies.filter(t=>e(a,t)!==i),r.splice(r.indexOf(i),1),c.dependencies.length<o&&(n.push({type:`circular`,taskId:t,dependencyId:i}),s.circularDependenciesFixed++,s.subtasksFixed++)}}Le(i.tasks);let p=JSON.stringify(i)!==JSON.stringify(a);return p?(E(t,i,r.projectRoot,r.tag),d(`debug`,`Fixed ${n.length} dependency problems`,s)):d(`debug`,`No changes needed to fix dependencies`),{fixes:n,remaining:Ge(i.tasks).issues,changed:p,...qe(i.tasks)}}catch(e){throw X(Y.FIX_FAILED,`Couldn't fix dependencies: ${e.message}`,void 0,e)}}function Xe(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 Ze(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=Xe(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=Xe(e,r,n,!1)}}return i}function Qe(e,t,n){let r=[];return!Array.isArray(e.dependencies)||e.dependencies.length===0||e.dependencies.filter(e=>e!=null).forEach(i=>{let a=Ze(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 $e(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=Qe(e,n,r);i.push(...t)}),i}function et(e,t,n){if(!e||typeof e!=`string`)throw new Re(Y.INVALID_TASK_ID,`Task ID must be a valid string`);if(!t||typeof t!=`string`)throw new Re(Y.INVALID_SOURCE_TAG,`Source tag must be a valid string`);if(!n||typeof n!=`string`)throw new Re(Y.INVALID_TARGET_TAG,`Target tag must be a valid string`);if(e.includes(`.`))throw new Re(Y.CANNOT_MOVE_SUBTASK,`Cannot move subtask ${e} directly between tags.
|
|
2
2
|
|
|
3
3
|
First promote it to a full task using:
|
|
4
4
|
taskgraph remove-subtask --id=${e} --convert`,{taskId:e,sourceTag:t,targetTag:n})}async function tt(e,t,n=null,r=null,i=!1,a={}){let{projectRoot:o,tag:s}=a;try{d(`debug`,`Adding subtask to parent task ${t}...`);let i=M(e,o,s);if(!i||!i.tasks)throw Error(`Invalid or missing tasks file at ${e}`);let a=parseInt(t,10),l=i.tasks.find(e=>e.id===a);if(!l)throw Error(`Parent task with ID ${a} not found`);l.subtasks||=[];let u;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(kt(i.tasks,l,e))throw Error(`Cannot create circular dependency: task ${a} is already a subtask or dependent of task ${e}`);let o=(l.subtasks.length>0?Math.max(...l.subtasks.map(e=>e.id)):0)+1,{dependencies:s,metadata:f}=Me(r,a);u={...r,id:o,parentTaskId:a,dependencies:s},c(u,f),l.subtasks.push(u),i.tasks.splice(t,1),Ne(i.tasks,String(e),`${a}.${o}`),d(`debug`,`Converted task ${e} to subtask ${a}.${o}`)}else if(r){let e=(l.subtasks.length>0?Math.max(...l.subtasks.map(e=>e.id)):0)+1;u={id:e,title:r.title,description:r.description||``,details:r.details||``,status:r.status||`pending`,dependencies:r.dependencies||[],parentTaskId:a},l.subtasks.push(u),d(`debug`,`Created new subtask ${a}.${e}`)}else throw Error(`Either existingTaskId or newSubtaskData must be provided`);return E(e,i,o,s),u}catch(e){throw d(`debug`,`Error adding subtask: ${e.message}`),e}}const nt=[`high`,`medium`,`low`],rt=`medium`;function it(e){return nt.includes(e?.toLowerCase())}function at(e){if(!e)return null;let t=e.toLowerCase();return it(t)?t:null}const ot=K.object({title:K.string().describe(`Clear, concise title for the task`),description:K.string().describe(`A one or two sentence description of the task`),details:K.string().describe(`In-depth implementation details, considerations, and guidance`),testStrategy:K.string().describe(`Detailed approach for verifying task completion`),dependencies:K.array(K.number()).nullable().describe(`Array of task IDs that this task depends on (must be completed before this task can start)`)}).strict(),st=K.object({taskId:K.number().int().positive(),taskTitle:K.string(),complexityScore:K.number().min(1).max(10),recommendedSubtasks:K.number().int().nonnegative(),expansionPrompt:K.string(),reasoning:K.string()}).strict(),ct=K.object({complexityAnalysis:K.array(st)}).strict(),lt=K.enum([`pending`,`in-progress`,`blocked`,`done`,`cancelled`,`deferred`]),ut=K.object({id:K.number().int().positive(),title:K.string().min(1).max(200),description:K.string().min(1),status:lt,dependencies:K.array(K.union([K.number().int().positive(),K.string()])),priority:K.enum([`low`,`medium`,`high`,`critical`]).nullable(),details:K.string().nullable(),testStrategy:K.string().nullable()}).strict(),dt=K.object({id:K.number().int().positive(),title:K.string().min(5).max(200),description:K.string().min(10),dependencies:K.array(K.number().int().positive()),details:K.string().min(20),status:K.enum([`pending`,`done`,`completed`]),testStrategy:K.string().nullable()}).strict(),ft=K.object({subtasks:K.array(dt)}).strict(),pt=K.object({id:K.number().int().positive(),title:K.string().min(1),description:K.string().min(1),details:K.string().nullable(),testStrategy:K.string().nullable(),priority:K.enum([`high`,`medium`,`low`]).nullable(),dependencies:K.array(K.number().int().positive()).nullable(),status:K.string().nullable()}).strict(),mt=K.object({tasks:K.array(pt)}).strict(),ht=K.object({subtask:dt}).strict(),gt=ut.extend({subtasks:K.array(dt).nullable()}).strict(),_t={"update-tasks":K.object({tasks:K.array(gt)}).strict(),"expand-task":ft,"analyze-complexity":ct,"update-subtask-by-id":ht,"update-task-by-id":K.object({task:gt}),"add-task":ot,"parse-prd":mt};async function vt(e,t,n,r={}){let i;return await ie(e,a=>{let o=a??{};!o[t]&&r.createWith&&Object.keys(o).length===0&&(o[t]=r.createWith);let s=o[t];if(!s||!Array.isArray(s.tasks))throw Error(`Tag "${t}" no longer exists in ${e}`);return i=n(s),o}),i}function yt(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 bt(e,t,n=[],r=null,a={},o=`text`,s=null,l=!1){let{session:u,mcpLog:f,projectRoot:m,commandName:h,outputType:g,tag:_}=a,v=!!f,y=v?f:{info:(...e)=>d(`info`,...e),warn:(...e)=>d(`warn`,...e),error:(...e)=>d(`error`,...e),debug:(...e)=>d(`debug`,...e),success:(...e)=>d(`success`,...e)},x=r||w(m)||`medium`;if(r){let e=at(r);e?x=e:(o===`text`&&d(`warn`,`Invalid priority "${r}". Using default priority "${rt}".`),x=rt)}y.debug(`Adding new task with prompt: "${t}", Priority: ${x}, Dependencies: ${n.join(`, `)||`None`}, Research: ${l}, ProjectRoot: ${m}`),_&&y.debug(`Using tag context: ${_}`);let S=null,T=null,E=(e,t=`info`)=>{f?f[t](e):o===`text`&&d(t,e)};function O(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=O(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=M(e,m,_);r&&r._rawTaggedData&&(r=r._rawTaggedData),r||=(E(`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&&(E(`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`}}},b(r.master,{description:`Tasks for master context`}),ee(e),D(e),E(`Successfully migrated to tagged format.`,`success`));let a=_;if(!r[a])throw E(`Tag "${a}" does not exist. Please create it first using the 'add-tag' command.`,`error`),Error(`Tag "${a}" not found.`);r[a].tasks||(r[a].tasks=[]),r[a].metadata||(r[a].metadata={created:(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:``});let d=yt(r),f=r[a].tasks,y=(f.length>0?Math.max(...f.map(e=>e.id)):0)+1,w=n.filter(e=>{let t=parseInt(e,10);return Number.isNaN(t)||!d.some(e=>e.id===t)});w.length>0&&(E(`The following dependencies do not exist or are invalid: ${w.join(`, `)}`,`warn`),E(`Removing invalid dependencies...`,`info`),n=n.filter(e=>!w.includes(e)));let k=n.map(e=>parseInt(e,10)),A=[],j=/* @__PURE__ */ new Set,N=/* @__PURE__ */ new Map;for(let e of k){let t=O(d,e,/* @__PURE__ */ new Set,N);t&&A.push(t)}for(let[e,t]of N.entries())j.add(e);let F;if(s){if(E(`Using manually provided task data`,`info`),F=s,E(`DEBUG: Taking MANUAL task data path.`,`debug`),!F.title||typeof F.title!=`string`||!F.description||typeof F.description!=`string`)throw Error(`Manual task data must include at least a title and description.`)}else{E(`DEBUG: Taking AI task generation path.`,`debug`),E(`Generating task data with AI with prompt:\n${t}`,`debug`);let e=await new ge(m,_).gather({semanticQuery:t,dependencyTasks:k,format:`research`}),n=e.context,r=e.analysisData;o===`text`&&r&&me(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:a,userPrompt:c}=await pe().loadPrompt(`add-task`,{prompt:t,newTaskId:y,existingTasks:d,gatheredContext:n,contextFromArgs:i,useResearch:l,priority:x,dependencies:k,hasCodebaseAnalysis:p(l,m,u),projectRoot:m});o===`text`&&(S=U(`Writing the new task${l?` with research`:``}…`));try{let e=l?`research`:`main`;if(E(`DEBUG: Calling generateObjectService...`,`debug`),T=await W({role:e,session:u,projectRoot:m,schema:_t[`add-task`],objectName:`newTaskData`,systemPrompt:a,prompt:c,commandName:h||`add-task`,outputType:g||(v?`mcp`:`cli`)}),E(`DEBUG: generateObjectService returned successfully.`,`debug`),!T||!T.mainResult)throw Error(`AI service did not return the expected object structure.`);if(T.mainResult.title&&T.mainResult.description)F=T.mainResult;else if(T.mainResult.object&&T.mainResult.object.title&&T.mainResult.object.description)F=T.mainResult.object;else throw Error(`AI service did not return a valid task object.`);E(`Successfully generated task data from AI.`,`debug`),S&&=(B(S),null)}catch(e){throw S&&=(V(S,`AI generation failed`),null),E(`DEBUG: generateObjectService caught error: ${e.message}`,`debug`),E(`Error generating task with AI: ${e.message}`,`error`),e}finally{E(`DEBUG: generateObjectService finally block reached.`,`debug`),S&&B(S)}}let I={id:y,title:F.title,description:F.description,details:F.details||``,testStrategy:F.testStrategy||``,status:`pending`,dependencies:F.dependencies?.length?F.dependencies:k,priority:x,subtasks:[]};if(F.dependencies?.length&&(F.dependencies.every(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&d.some(e=>e.id===t)})||(E(`AI suggested invalid dependencies. Filtering them out...`,`warn`),I.dependencies=F.dependencies.filter(e=>{let t=parseInt(e,10);return!Number.isNaN(t)&&d.some(e=>e.id===t)}))),c(I,i(I,{dependencies:k})),E(`DEBUG: Writing tasks.json...`,`debug`),await vt(e,a,e=>{e.tasks.some(e=>e.id===I.id)&&(I.id=Math.max(...e.tasks.map(e=>e.id))+1),e.tasks.push(I),b(e,{description:`Tasks for ${a} context`})},{createWith:r[a]}),y=I.id,E(`DEBUG: tasks.json written.`,`debug`),o===`text`){let e=e=>{switch(e?.toLowerCase()){case`high`:return`red`;case`low`:return`dim`;default:return`yellow`}},t=I.dependencies.filter(e=>!k.includes(e)),n=k.filter(e=>!I.dependencies.includes(e)),r={};I.dependencies.forEach(e=>{let t=d.find(t=>t.id===e);t&&(r[e]=P(t.title,30))});let i=``;I.dependencies.length>0?(i=C.text(`Dependencies:`)+`
|
|
@@ -69,7 +69,7 @@ ${G.cyan(`1.`)} Run ${G.yellow(`taskgraph next`)} to see what to work on next\n$
|
|
|
69
69
|
${G.cyan(`1.`)} Run ${G.yellow(`taskgraph list`)} to view all tasks\n${G.cyan(`2.`)} Run ${G.yellow(`taskgraph expand --id=<id>`)} to break down a task into subtasks\n${G.cyan(`3.`)} Run ${G.yellow(`taskgraph analyze-complexity`)} to analyze task complexity`;console.log(J(e,mn.nextSteps))}function Dn(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 On(e){let t=Dn(e);if(!t)return null;try{let e=cn.safeParse(JSON.parse(t));return e.success?e.data:null}catch{return null}}function kn(e){return Math.ceil(e.length/4)}function An(e){let t=q.readFileSync(e,`utf8`);if(!t)throw Error(`Input file ${e} is empty or could not be read.`);return t}function jn(e,t){let n=[],r=1,i=Mn(e);return i[t]?.tasks&&Array.isArray(i[t].tasks)&&(n=i[t].tasks,n.length>0&&(r=Math.max(...n.map(e=>e.id||0))+1)),{existingTasks:n,nextId:r}}function Mn(e){if(!q.existsSync(e))return{};let t=q.readFileSync(e,`utf8`);if(t.trim()===``)return{};try{return JSON.parse(t)}catch(t){throw Error(`${e} is not valid JSON (${t.message}). Fix or remove the file, then run this again`)}}function Nn({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(G.red(n)),process.exit(1)}a.report(`Force flag enabled. Overwriting existing tasks in tag '${t}'.`,`debug`)}}function Pn(e,t,n,r){Fn(e,t);let a=t,o=/* @__PURE__ */ new Map,s=e.map(e=>{let t=a++;return o.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 s.forEach(e=>{e.dependencies=e.dependencies.map(e=>o.get(e)).filter(t=>t!=null&&t<e.id&&(g(n,t)||s.some(e=>e.id===t))),c(e,i(e))}),s}function Fn(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 In(e,t,n,r){let i=Ee.dirname(e);q.existsSync(i)||q.mkdirSync(i,{recursive:!0});let a=Mn(e);a[n]={tasks:t,metadata:{...a[n]?.metadata,created:a[n]?.metadata?.created||(/* @__PURE__ */ new Date()).toISOString(),updated:(/* @__PURE__ */ new Date()).toISOString(),description:`Tasks for ${n} context`}},b(a[n],{description:`Tasks for ${n} context`}),q.writeFileSync(e,JSON.stringify(a,null,2)),r.report(`Successfully saved ${t.length} tasks to ${e}`,`debug`)}async function Ln(e,t,n){let r=pe(),i=w(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 Rn({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 zn({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`})();wn({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 an.withSoftTimeout(o.mainResult.usage,1e3,void 0),H(o.telemetryData,`cli`))}function Bn({processedTasks:e,research:t,finalTasks:n,tasksPath:r,aiServiceResponse:i}){let a=Ee.relative(process.cwd(),r)||r,o=n.length>e.length?` · ${n.length} tasks in total`:``,s=t?` · research-backed`:``;console.log(C.muted(`Saved to ${a}${o}${s}`));let c=(e,t)=>`${G.yellow(e.padEnd(28))}${C.muted(t)}`;console.log(J(C.text.bold(`Next steps`)+`
|
|
70
70
|
|
|
71
71
|
`+[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(`
|
|
72
|
-
`),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&H(i.telemetryData,`cli`)}async function Vn(e,t,n,r=1){let i=new un(e.mcpLog,e.reportProgress),a=kn(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=de({prdName:Ee.basename(e.prdPath||`PRD`),numTasks:n,startId:r}),{...await Hn(e,t,o),estimatedInputTokens:a}}catch(t){if(ke.isInstance(t)&&!Gn(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(`${G.yellow(`⚠`)} Live output stopped. Asking Claude again in one request; the final tasks may differ from the ones above.`)}}return{...await Wn(e,t,o),estimatedInputTokens:a}}async function Hn(e,t,n){let r=await Ce({...Kn(e,t)}),i=r?.mainResult,a=i?.partialObjectStream;if(!a)throw Error(`AI service did not return a stream`);for await(let e of a)n?.update(e);let o;try{o=await i.object}catch(e){if(o=On(e?.text),!o)throw e}if(!o||!Array.isArray(o.tasks))throw Error(`AI service returned unexpected data structure.`);return n?.succeed(o),r.telemetryData=await Un(i,r,e),{parsedTasks:o.tasks,aiServiceResponse:r}}async function Un(e,t,n){let r=t.telemetryData;if(!r?.userId)return r;try{let i=await e.usage;return await Te({userId:r.userId,commandName:`parse-prd`,providerName:t.providerName,modelId:t.modelId,inputTokens:i?.inputTokens??i?.promptTokens??0,outputTokens:i?.outputTokens??i?.completionTokens??0,cachedInputTokens:i?.inputTokenDetails?.cacheReadTokens??0,outputType:n.isMCP?`mcp`:`cli`})||r}catch{return r}}async function Wn(e,t,n){let r=n?U(`Parsing PRD and generating tasks…`):null;try{let n=await W(Kn(e,t)),i=qn(n?.mainResult);if(!i)throw Error(`AI service returned unexpected data structure after validation.`);return r&&xe(r,`${i.tasks.length} tasks generated`),{parsedTasks:i.tasks,aiServiceResponse:n}}catch(e){throw r&&V(r,`Couldn't generate tasks`),e}}function Gn(e){let t=e.projectRoot,n=e.research?oe(t):I(t);return[I(t),ae(t),oe(t)].filter(Boolean).some(e=>e!==n)}function Kn(e,t){return{role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:cn,objectName:`tasks_data`,systemPrompt:t.systemPrompt,prompt:t.userPrompt,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}}function qn(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[Jn,Yn,Xn]=nt,Zn=/* @__PURE__ */ new Map;var Qn=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]||C.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 $n={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},er=new Qn(`priority`,[Jn,Yn,Xn],{[Jn]:G.red,[Yn]:G.yellow,[Xn]:C.muted});function tr(e,t){let n=$n.cli.filled,r=$n.cli.empty,i=``;for(let a=0;a<3;a++)i+=a<e?t(n):C.text(r);return i}function nr(e,t){return 3-t.indexOf(e)}function rr(e,t){if(Zn.has(e))return Zn.get(e);let n=t();return Zn.set(e,n),n}function ir(){return rr(`mcp-priority-all`,()=>({[Jn]:$n.mcp.high,[Yn]:$n.mcp.medium,[Xn]:$n.mcp.low}))}function ar(){return rr(`cli-priority-all`,()=>{let e={};return er.levels.forEach(t=>{let n=nr(t,er.levels),r=er.getColor(t);e[t]=tr(n,r)}),e})}function or(){return rr(`statusbar-priority-all`,()=>{let e={};return er.levels.forEach((t,n)=>{let r=n===0?$n.statusBar.high:n===1?$n.statusBar.medium:$n.statusBar.low,i=er.getColor(t);e[t]=i(r)}),e})}function sr(){return{[Jn]:er.colors[Jn],[Yn]:er.colors[Yn],[Xn]:er.colors[Xn]}}function cr(e=!1){return e?ir():ar()}function lr(e,t=!1){let n=cr(t);return n[e]||n[Yn]}new Qn(`complexity`,[`high`,`medium`,`low`],{high:G.red,medium:G.yellow,low:G.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const ur={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},dr={shades_classic:Ae.Presets.shades_classic,shades_grey:Ae.Presets.shades_grey,rect:Ae.Presets.rect,legacy:Ae.Presets.legacy},fr=new class{constructor(e={},t=dr.shades_classic){this.defaultOptions={...ur,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new Ae.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new Ae.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function pr(e={}){return fr.createMultiBar(e)}var mr=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=pr(),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(){}},hr=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 gr(e,t,n){new hr(e).createHeader(t,n)}function _r(e,t,n){new hr(e).createRow(t,n)}function vr(e,t){new hr(e).createBorder(t)}ar();const yr=or();sr();const br={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 xr=class{constructor(e=br.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}},Sr=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():br.DEFAULT_PRIORITY;return br.VALID_PRIORITIES.includes(t)?t:br.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Cr=class{static formatTitle(e,t){return e?e.length>br.MAX_TITLE_LENGTH?e.substring(0,br.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return lr(e,!1).padEnd(br.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(br.TASK_ID_PAD_START,` `).padEnd(br.TASK_ID_PAD_END,` `)}},wr=class extends mr{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new Sr,this.debouncer=new xr,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${yr.high} {high} ${yr.medium} {medium} ${yr.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,gr(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=Cr.formatTitle(t,e),i=Cr.formatPriority(n),a=Cr.formatTaskId(e);_r(this.multibar,` ${a} | ${i} | {title}`,{title:r}),vr(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 Tr(e={}){return new wr(e)}async function Er(e,t,n){let r=Dr(e,t,n);await kr(e,n,r.estimatedInputTokens);let i=await Ar(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await jr(e,n),s=await Mr(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(Or(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-BpwsoWsI.js`),{getUserId:n}=await import(`./config-manager-HsHpBhNF.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 Hr(s,i,r.estimatedInputTokens,a)}function Dr(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new un(e.mcpLog,e.reportProgress),estimatedInputTokens:kn(r+i),defaultPriority:w(e.projectRoot)||`medium`}}function Or(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function kr(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 Ar(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return await an.withTimeout(Ce({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:cn,systemPrompt:r,prompt:i,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),n,`Streaming operation`)}async function jr(e,t){let n=cr(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Tr({numUnits:t,unitName:`task`,append:e.append});let n=e.research?oe():I(),i=A(e.research?`research`:`main`);yn({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 Mr(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:cn},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 Nr(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 Lr(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await Vr(d,c)}}async function Nr(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=kn(JSON.stringify(r))),await Pr(r,t,n)}async function Pr(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await Fr(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 Fr(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await Rn({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 Ir(a+1,r,i)}}async function Ir(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 Lr(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 Rr(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function Rr(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?zr(e,a,o):await Br(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function zr(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 Br(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await Rn({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 Vr(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 W({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||kn(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||kn(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function Hr(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 Ur(e,t,n){let r=new un(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let i=jn(e.tasksPath,e.targetTag),a=e.append?i.existingTasks:[],o=e.append?i.nextId:1;Nn({existingTasks:i.existingTasks,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let s=await t(e,await Ln(e,An(e.prdPath),o),e.numTasks,o),c=w(e.projectRoot)||`medium`,l=Pn(s.parsedTasks,o,a,c),u=e.append?[...a,...l]:l;return In(e.tasksPath,u,e.targetTag,r),await Wr(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`):F(e.projectRoot)&&console.error(t),t}}async function Wr(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 zn({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||Bn({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function Gr(e,t,n,r={}){return Ur(new ln(e,t,n,r),Er,!0)}async function Kr(e,t,n,r={}){return Ur(new ln(e,t,n,r),Vn,!1)}async function qr(e,t,n,r={}){let i=new ln(e,t,n,r);if(i.useStreaming)try{return await Gr(e,t,n,r)}catch(a){if(a instanceof nn||a.code===rn.NOT_ASYNC_ITERABLE||a.code===rn.STREAM_PROCESSING_FAILED||a.code===rn.STREAM_NOT_ITERABLE||an.isTimeoutError(a)){let o=new un(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(G.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 Kr(e,t,n,r)}throw a}return await Kr(e,t,n,r)}async function Jr(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{d(`debug`,`Removing subtask ${t}...`);let r=M(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(`.`),l=parseInt(i,10),u=parseInt(s,10),f=r.tasks.find(e=>e.id===l);if(!f)throw Error(`Parent task with ID ${l} not found`);if(!f.subtasks||f.subtasks.length===0)throw Error(`Parent task ${l} has no subtasks`);let p=f.subtasks.findIndex(e=>e.id===u);if(p===-1)throw Error(`Subtask ${t} not found`);let m={...f.subtasks[p]};f.subtasks.splice(p,1),f.subtasks.length===0&&(f.subtasks=void 0);let h=null;if(n){d(`debug`,`Converting subtask ${t} to a standalone task...`);let e=Math.max(...r.tasks.map(e=>e.id))+1,n=je(m,l,void 0);h={id:e,title:m.title,description:m.description||``,details:m.details||``,status:m.status||`pending`,dependencies:n.dependencies,priority:f.priority||`medium`},c(h,n.metadata),h.dependencies.includes(String(l))||h.dependencies.push(String(l)),Ne(r.tasks,`${l}.${u}`,e),r.tasks.push(h),d(`info`,`Created new task ${e} from subtask ${t}`)}else d(`debug`,`Subtask ${t} deleted`);return E(e,r,a,o),h}catch(e){throw d(`debug`,`Error removing subtask: ${e.message}`),e}}function Yr(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 Xr(t,n,r={}){let{projectRoot:i,tag:o}=r,s={success:!0,messages:[],errors:[],removedTasks:[]},l=n.split(`,`).map(e=>e.trim()).filter(Boolean);if(l.length===0)return s.success=!1,s.errors.push(`No valid task IDs provided.`),s;try{let n=M(t,i,o);if(!n)throw Error(`Could not read tasks file at ${t}`);let r=n._rawTaggedData||n;if(!r[o]||!r[o].tasks)throw Error(`Tag '${o}' not found or has no tasks.`);let u=[];if(await vt(t,o,t=>{let n=t.tasks;for(let e of l)if(Yr(n,e))try{if(typeof e==`string`&&e.includes(`.`)){let[t,r]=e.split(`.`).map(e=>parseInt(e,10)),i=n.find(e=>e.id===t);if(!i||!i.subtasks)throw Error(`Parent task ${t} or its subtasks not found for subtask ${e}`);let a=i.subtasks.findIndex(e=>e.id===r);if(a===-1)throw Error(`Subtask ${r} not found in parent task ${t}`);let c={...i.subtasks[a],parentTaskId:t};s.removedTasks.push(c),i.subtasks.splice(a,1),s.messages.push(`Successfully removed subtask ${e} from tag '${o}'`)}else{let t=parseInt(e,10),r=n.findIndex(e=>e.id===t);if(r===-1)throw Error(`Task with ID ${e} not found in tag '${o}'`);let i=n[r];s.removedTasks.push(i),u.push(t),n.splice(r,1),s.messages.push(`Successfully removed task ${e} from tag '${o}'`)}}catch(t){let n=`Error processing ID ${e}: ${t.message}`;s.errors.push(n),s.success=!1,d(`warn`,n)}else{let t=`Task with ID ${e} in tag '${o}' not found or already removed.`;s.errors.push(t),s.success=!1}if(s.removedTasks.length>0){let t=new Set(l.map(e=>typeof e==`string`&&e.includes(`.`)?e:String(parseInt(e,10))));n.forEach(n=>{n.dependencies&&(n.dependencies=n.dependencies.filter(e=>!t.has(String(e))),c(n,a(n))),n.subtasks&&n.subtasks.forEach(r=>{r.dependencies&&(r.dependencies=r.dependencies.filter(r=>!t.has(e(n.id,r))),c(r,a(r,n.id)))})})}}),s.removedTasks.length>0)for(let e of u){let n=Ee.join(Ee.dirname(t),`task_${e.toString().padStart(3,`0`)}.txt`);if(De.existsSync(n))try{De.unlinkSync(n),s.messages.push(`Deleted task file: ${n}`)}catch(e){let t=`Failed to delete task file ${n}: ${e.message}`;s.errors.push(t),s.success=!1,d(`warn`,t)}}else s.errors.length===0&&s.messages.push(`No tasks found matching the provided IDs.`);let f=s.messages.join(`
|
|
72
|
+
`),{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&H(i.telemetryData,`cli`)}async function Vn(e,t,n,r=1){let i=new un(e.mcpLog,e.reportProgress),a=kn(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=de({prdName:Ee.basename(e.prdPath||`PRD`),numTasks:n,startId:r}),{...await Hn(e,t,o),estimatedInputTokens:a}}catch(t){if(ke.isInstance(t)&&!Gn(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(`${G.yellow(`⚠`)} Live output stopped. Asking Claude again in one request; the final tasks may differ from the ones above.`)}}return{...await Wn(e,t,o),estimatedInputTokens:a}}async function Hn(e,t,n){let r=await Ce({...Kn(e,t)}),i=r?.mainResult,a=i?.partialObjectStream;if(!a)throw Error(`AI service did not return a stream`);for await(let e of a)n?.update(e);let o;try{o=await i.object}catch(e){if(o=On(e?.text),!o)throw e}if(!o||!Array.isArray(o.tasks))throw Error(`AI service returned unexpected data structure.`);return n?.succeed(o),r.telemetryData=await Un(i,r,e),{parsedTasks:o.tasks,aiServiceResponse:r}}async function Un(e,t,n){let r=t.telemetryData;if(!r?.userId)return r;try{let i=await e.usage;return await Te({userId:r.userId,commandName:`parse-prd`,providerName:t.providerName,modelId:t.modelId,inputTokens:i?.inputTokens??i?.promptTokens??0,outputTokens:i?.outputTokens??i?.completionTokens??0,cachedInputTokens:i?.inputTokenDetails?.cacheReadTokens??0,outputType:n.isMCP?`mcp`:`cli`})||r}catch{return r}}async function Wn(e,t,n){let r=n?U(`Parsing PRD and generating tasks…`):null;try{let n=await W(Kn(e,t)),i=qn(n?.mainResult);if(!i)throw Error(`AI service returned unexpected data structure after validation.`);return r&&xe(r,`${i.tasks.length} tasks generated`),{parsedTasks:i.tasks,aiServiceResponse:n}}catch(e){throw r&&V(r,`Couldn't generate tasks`),e}}function Gn(e){let t=e.projectRoot,n=e.research?oe(t):I(t);return[I(t),ae(t),oe(t)].filter(Boolean).some(e=>e!==n)}function Kn(e,t){return{role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:cn,objectName:`tasks_data`,systemPrompt:t.systemPrompt,prompt:t.userPrompt,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}}function qn(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[Jn,Yn,Xn]=nt,Zn=/* @__PURE__ */ new Map;var Qn=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]||C.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 $n={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},er=new Qn(`priority`,[Jn,Yn,Xn],{[Jn]:G.red,[Yn]:G.yellow,[Xn]:C.muted});function tr(e,t){let n=$n.cli.filled,r=$n.cli.empty,i=``;for(let a=0;a<3;a++)i+=a<e?t(n):C.text(r);return i}function nr(e,t){return 3-t.indexOf(e)}function rr(e,t){if(Zn.has(e))return Zn.get(e);let n=t();return Zn.set(e,n),n}function ir(){return rr(`mcp-priority-all`,()=>({[Jn]:$n.mcp.high,[Yn]:$n.mcp.medium,[Xn]:$n.mcp.low}))}function ar(){return rr(`cli-priority-all`,()=>{let e={};return er.levels.forEach(t=>{let n=nr(t,er.levels),r=er.getColor(t);e[t]=tr(n,r)}),e})}function or(){return rr(`statusbar-priority-all`,()=>{let e={};return er.levels.forEach((t,n)=>{let r=n===0?$n.statusBar.high:n===1?$n.statusBar.medium:$n.statusBar.low,i=er.getColor(t);e[t]=i(r)}),e})}function sr(){return{[Jn]:er.colors[Jn],[Yn]:er.colors[Yn],[Xn]:er.colors[Xn]}}function cr(e=!1){return e?ir():ar()}function lr(e,t=!1){let n=cr(t);return n[e]||n[Yn]}new Qn(`complexity`,[`high`,`medium`,`low`],{high:G.red,medium:G.yellow,low:G.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const ur={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},dr={shades_classic:Ae.Presets.shades_classic,shades_grey:Ae.Presets.shades_grey,rect:Ae.Presets.rect,legacy:Ae.Presets.legacy},fr=new class{constructor(e={},t=dr.shades_classic){this.defaultOptions={...ur,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new Ae.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new Ae.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function pr(e={}){return fr.createMultiBar(e)}var mr=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=pr(),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(){}},hr=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 gr(e,t,n){new hr(e).createHeader(t,n)}function _r(e,t,n){new hr(e).createRow(t,n)}function vr(e,t){new hr(e).createBorder(t)}ar();const yr=or();sr();const br={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 xr=class{constructor(e=br.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}},Sr=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():br.DEFAULT_PRIORITY;return br.VALID_PRIORITIES.includes(t)?t:br.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Cr=class{static formatTitle(e,t){return e?e.length>br.MAX_TITLE_LENGTH?e.substring(0,br.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return lr(e,!1).padEnd(br.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(br.TASK_ID_PAD_START,` `).padEnd(br.TASK_ID_PAD_END,` `)}},wr=class extends mr{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new Sr,this.debouncer=new xr,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${yr.high} {high} ${yr.medium} {medium} ${yr.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,gr(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=Cr.formatTitle(t,e),i=Cr.formatPriority(n),a=Cr.formatTaskId(e);_r(this.multibar,` ${a} | ${i} | {title}`,{title:r}),vr(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 Tr(e={}){return new wr(e)}async function Er(e,t,n){let r=Dr(e,t,n);await kr(e,n,r.estimatedInputTokens);let i=await Ar(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await jr(e,n),s=await Mr(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(Or(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-COsdujxy.js`),{getUserId:n}=await import(`./config-manager-Cs19NriM.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 Hr(s,i,r.estimatedInputTokens,a)}function Dr(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new un(e.mcpLog,e.reportProgress),estimatedInputTokens:kn(r+i),defaultPriority:w(e.projectRoot)||`medium`}}function Or(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function kr(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 Ar(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return await an.withTimeout(Ce({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:cn,systemPrompt:r,prompt:i,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),n,`Streaming operation`)}async function jr(e,t){let n=cr(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Tr({numUnits:t,unitName:`task`,append:e.append});let n=e.research?oe():I(),i=A(e.research?`research`:`main`);yn({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 Mr(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:cn},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 Nr(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 Lr(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await Vr(d,c)}}async function Nr(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=kn(JSON.stringify(r))),await Pr(r,t,n)}async function Pr(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await Fr(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 Fr(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await Rn({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 Ir(a+1,r,i)}}async function Ir(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 Lr(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 Rr(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function Rr(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?zr(e,a,o):await Br(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function zr(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 Br(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await Rn({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 Vr(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 W({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||kn(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||kn(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function Hr(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 Ur(e,t,n){let r=new un(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let i=jn(e.tasksPath,e.targetTag),a=e.append?i.existingTasks:[],o=e.append?i.nextId:1;Nn({existingTasks:i.existingTasks,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let s=await t(e,await Ln(e,An(e.prdPath),o),e.numTasks,o),c=w(e.projectRoot)||`medium`,l=Pn(s.parsedTasks,o,a,c),u=e.append?[...a,...l]:l;return In(e.tasksPath,u,e.targetTag,r),await Wr(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`):F(e.projectRoot)&&console.error(t),t}}async function Wr(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 zn({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||Bn({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function Gr(e,t,n,r={}){return Ur(new ln(e,t,n,r),Er,!0)}async function Kr(e,t,n,r={}){return Ur(new ln(e,t,n,r),Vn,!1)}async function qr(e,t,n,r={}){let i=new ln(e,t,n,r);if(i.useStreaming)try{return await Gr(e,t,n,r)}catch(a){if(a instanceof nn||a.code===rn.NOT_ASYNC_ITERABLE||a.code===rn.STREAM_PROCESSING_FAILED||a.code===rn.STREAM_NOT_ITERABLE||an.isTimeoutError(a)){let o=new un(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(G.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 Kr(e,t,n,r)}throw a}return await Kr(e,t,n,r)}async function Jr(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{d(`debug`,`Removing subtask ${t}...`);let r=M(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(`.`),l=parseInt(i,10),u=parseInt(s,10),f=r.tasks.find(e=>e.id===l);if(!f)throw Error(`Parent task with ID ${l} not found`);if(!f.subtasks||f.subtasks.length===0)throw Error(`Parent task ${l} has no subtasks`);let p=f.subtasks.findIndex(e=>e.id===u);if(p===-1)throw Error(`Subtask ${t} not found`);let m={...f.subtasks[p]};f.subtasks.splice(p,1),f.subtasks.length===0&&(f.subtasks=void 0);let h=null;if(n){d(`debug`,`Converting subtask ${t} to a standalone task...`);let e=Math.max(...r.tasks.map(e=>e.id))+1,n=je(m,l,void 0);h={id:e,title:m.title,description:m.description||``,details:m.details||``,status:m.status||`pending`,dependencies:n.dependencies,priority:f.priority||`medium`},c(h,n.metadata),h.dependencies.includes(String(l))||h.dependencies.push(String(l)),Ne(r.tasks,`${l}.${u}`,e),r.tasks.push(h),d(`info`,`Created new task ${e} from subtask ${t}`)}else d(`debug`,`Subtask ${t} deleted`);return E(e,r,a,o),h}catch(e){throw d(`debug`,`Error removing subtask: ${e.message}`),e}}function Yr(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 Xr(t,n,r={}){let{projectRoot:i,tag:o}=r,s={success:!0,messages:[],errors:[],removedTasks:[]},l=n.split(`,`).map(e=>e.trim()).filter(Boolean);if(l.length===0)return s.success=!1,s.errors.push(`No valid task IDs provided.`),s;try{let n=M(t,i,o);if(!n)throw Error(`Could not read tasks file at ${t}`);let r=n._rawTaggedData||n;if(!r[o]||!r[o].tasks)throw Error(`Tag '${o}' not found or has no tasks.`);let u=[];if(await vt(t,o,t=>{let n=t.tasks;for(let e of l)if(Yr(n,e))try{if(typeof e==`string`&&e.includes(`.`)){let[t,r]=e.split(`.`).map(e=>parseInt(e,10)),i=n.find(e=>e.id===t);if(!i||!i.subtasks)throw Error(`Parent task ${t} or its subtasks not found for subtask ${e}`);let a=i.subtasks.findIndex(e=>e.id===r);if(a===-1)throw Error(`Subtask ${r} not found in parent task ${t}`);let c={...i.subtasks[a],parentTaskId:t};s.removedTasks.push(c),i.subtasks.splice(a,1),s.messages.push(`Successfully removed subtask ${e} from tag '${o}'`)}else{let t=parseInt(e,10),r=n.findIndex(e=>e.id===t);if(r===-1)throw Error(`Task with ID ${e} not found in tag '${o}'`);let i=n[r];s.removedTasks.push(i),u.push(t),n.splice(r,1),s.messages.push(`Successfully removed task ${e} from tag '${o}'`)}}catch(t){let n=`Error processing ID ${e}: ${t.message}`;s.errors.push(n),s.success=!1,d(`warn`,n)}else{let t=`Task with ID ${e} in tag '${o}' not found or already removed.`;s.errors.push(t),s.success=!1}if(s.removedTasks.length>0){let t=new Set(l.map(e=>typeof e==`string`&&e.includes(`.`)?e:String(parseInt(e,10))));n.forEach(n=>{n.dependencies&&(n.dependencies=n.dependencies.filter(e=>!t.has(String(e))),c(n,a(n))),n.subtasks&&n.subtasks.forEach(r=>{r.dependencies&&(r.dependencies=r.dependencies.filter(r=>!t.has(e(n.id,r))),c(r,a(r,n.id)))})})}}),s.removedTasks.length>0)for(let e of u){let n=Ee.join(Ee.dirname(t),`task_${e.toString().padStart(3,`0`)}.txt`);if(De.existsSync(n))try{De.unlinkSync(n),s.messages.push(`Deleted task file: ${n}`)}catch(e){let t=`Failed to delete task file ${n}: ${e.message}`;s.errors.push(t),s.success=!1,d(`warn`,t)}}else s.errors.length===0&&s.messages.push(`No tasks found matching the provided IDs.`);let f=s.messages.join(`
|
|
73
73
|
`),p=s.errors.join(`
|
|
74
74
|
`);return{success:s.success,message:f||`No tasks were removed.`,error:p||null,removedTasks:s.removedTasks}}catch(e){return d(`error`,`Error removing tasks: ${e.message}`),{success:!1,message:``,error:`Operation failed: ${e.message}`,removedTasks:[]}}}const Zr=[`light`,`regular`,`heavy`],Qr=[`done`,`in-progress`,`review`,`cancelled`,`deferred`,`blocked`],$r=[`pending`];function ei(e){return Zr.includes(e)}async function ti(e,t,n){let{projectRoot:r,tag:i,session:a}=n;try{let n={tasks:[e],metadata:{analyzedAt:(/* @__PURE__ */ new Date()).toISOString()}},o=_(null,{projectRoot:r,tag:i},null);if(!o)return d(`warn`,`No complexity report found - cannot re-analyze complexity`),null;await St({file:t,output:o,id:e.id.toString(),projectRoot:r,tag:i,_filteredTasksData:n,_originalTaskCount:1},{session:a});let s=ne(o);if(s){let t=te(s,e.id);if(t)return d(`info`,`Re-analyzed task ${e.id} complexity: ${t.complexityScore}/10`),t.complexityScore}return d(`warn`,`Could not find updated complexity analysis for task ${e.id}`),null}catch(e){return d(`error`,`Failed to re-analyze task complexity: ${e.message}`),null}}function ni(e,t){let{projectRoot:n,tag:r}=t;try{let t=_(null,{projectRoot:n,tag:r},null);if(!t)return null;let i=ne(t);if(!i)return null;let a=te(i,e);return a?a.complexityScore:null}catch(e){return d(`debug`,`Could not read current complexity score: ${e.message}`),null}}async function ri(e,t,n,r,a=`regular`,o=null){let{projectRoot:s,tag:l,session:u}=n;if(!e.subtasks||!Array.isArray(e.subtasks)||e.subtasks.length===0)return{updatedTask:e,regenerated:!1,preserved:0,generated:0};let f=e.subtasks.filter(e=>Qr.includes(e.status)),p=e.subtasks.filter(e=>$r.includes(e.status));if(p.length===0)return{updatedTask:e,regenerated:!1,preserved:f.length,generated:0};let m,h=f.length,g=p.length,_=o?Math.max(.5,o/10):1,v=o?` (original complexity: ${o}/10)`:``;if(r===`up`){if(a===`light`){let e=Math.max(5,h+Math.ceil(g*1.1));m=Math.ceil(e*(.8+.4*_))}else if(a===`regular`){let e=Math.max(6,h+Math.ceil(g*1.3));m=Math.ceil(e*(.8+.4*_))}else{let e=Math.max(8,h+Math.ceil(g*1.6));m=Math.ceil(e*(.8+.6*_))}}else{let e=o>=8?.7:o>=6?.85:1;if(a===`light`){let t=Math.max(3,h+Math.ceil(g*.8));m=Math.ceil(t*e)}else if(a===`regular`){let t=Math.max(3,h+Math.ceil(g*.5));m=Math.ceil(t*e)}else{let e=o>=9?.3:o>=7?.5:.7,t=Math.max(2,h+Math.ceil(g*.25));m=Math.max(1,Math.ceil(t*e))}}d(`debug`,`Complexity-aware subtask calculation${v}: ${g} pending -> target ${m} total`),d(`debug`,`Complexity-aware calculation${v}: ${g} pending -> ${m} total subtasks (${a} ${r})`);let y=Math.max(1,m-h);try{let t=`Based on this updated task, generate ${y} NEW subtasks that reflect the ${r===`up`?`increased`:`decreased`} complexity level:
|
|
75
75
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,a as t,b as n,c as r,d as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as _,y as v}from"./task-manager-
|
|
1
|
+
import{_ as e,a as t,b as n,c as r,d as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as _,y as v}from"./task-manager-C-lF7v2M.js";import{K as y,rt as b}from"./config-manager-CtE1yo1I.js";import{h as x}from"./src-Dz_uZuYA.js";import{n as S}from"./research-DcB3PdqA.js";import{t as C}from"./response-language-BdYSHT6o.js";export{n as addSubtask,v as addTask,_ as analyzeTaskComplexity,e as clearSubtasks,o as expandAllTasks,a as expandTask,x as findNextTask,y as findTaskById,l as isTaskDependentOn,f as listTasks,i as moveTask,g as parsePRD,S as performResearch,b as readComplexityReport,c as removeSubtask,m as removeTask,s as scopeDownTask,t as scopeUpTask,C as setResponseLanguage,r as taskExists,p as updateSubtaskById,u as updateTaskById,h as updateTasks,d as validateStrength};
|
package/dist/taskgraph.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{c as e}from"./src-
|
|
2
|
+
import{c as e}from"./src-DvvdBXWU.js";import t from"chalk";import{join as n}from"node:path";import r from"dotenv";function i(e,n=t){e.NO_COLOR&&e.FORCE_COLOR===void 0&&(e.FORCE_COLOR=`0`,n.level=0)}i(process.env);const a=process.cwd(),o=e();r.config({path:n(o,`.env`),quiet:!0}),process.env.TASKGRAPH_ORIGINAL_CWD=a,process.env.DEBUG===`1`&&console.error(`DEBUG - dev.js received args:`,process.argv.slice(2));const{runCLI:s}=await import(`./commands-C59cmYBr.js`);s(process.argv);export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taskgraph-ai",
|
|
3
|
-
"version": "0.54.
|
|
3
|
+
"version": "0.54.14",
|
|
4
4
|
"description": "Task management for AI-driven development, built for Claude Code: plan from a PRD, then work tasks one at a time with slash commands, a CLI or an MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|