taskgraph-ai 0.52.9 → 0.52.10

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.
@@ -182,7 +182,7 @@ Find code smells and clean them up. ONE cleanup per session.
182
182
  `,`utf-8`)}isPreset(e){return H(e)}async resolvePrompt(e){if(this.isPreset(e))return B[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=v(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=_(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]}}},$e=class{logger=C(`LoopDomain`);loopService=null;projectRoot;constructor(e){this.projectRoot=e.getProjectRoot()}checkSandboxAuth(){return new U({projectRoot:this.projectRoot}).checkSandboxAuth()}runInteractiveAuth(){return new U({projectRoot:this.projectRoot}).runInteractiveAuth()}async run(e){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 U({projectRoot:this.projectRoot}),this.loopService.run(t)}stop(){this.loopService&&=(this.loopService.stop(),null)}getIsRunning(){return this.loopService?.isRunning??!1}isPreset(e){return H(e)}async resolvePrompt(e,t){if(H(e))return Qe(e);if(!t)throw Error(`Custom prompt file requires readFile callback: ${e}`);return t(e)}getAvailablePresets(){return[...V]}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}}},et=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(e=>({...e,id:Number(e.id),parentId:String(e.parentId)}))||[]}))}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]}}};const W={stale:1e4,retries:{retries:5,factor:2,minTimeout:100,maxTimeout:1e3},realpath:!1};var tt=class{writers=/* @__PURE__ */ new Map;getWriter(e){let t=this.writers.get(e);return t||(t=new oe(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?Error(`Invalid JSON in file ${e}: ${t.message}`):Error(`Failed to read file ${e}: ${t.message}`)}}async writeJson(e,t){await this.ensureFileExists(e);let n=null;try{n=await ae.lock(e,W);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 ae.lock(e,W);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,ne.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()}},nt=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}};const G=C(`ComplexityReportManager`);var rt=class{projectRoot;reportCache=/* @__PURE__ */ new Map;constructor(e){this.projectRoot=e}getReportPath(e){let t=c.join(this.projectRoot,`.taskgraph`,`reports`),n=e&&e!==`master`?`_${e}`:``;return c.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)?(G.warn(`Invalid complexity report structure at ${r}, ignoring`),null):(this.reportCache.set(n,a),G.debug(`Loaded complexity report for tag '${t}' with ${a.complexityAnalysis.length} analyses`),a)}catch(e){return e.code===`ENOENT`?(G.debug(`No complexity report found for tag '${t}'`),null):(G.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}}},it=class{formatHandler;fileOps;pathResolver;complexityManager;constructor(e){this.formatHandler=new et,this.fileOps=new tt,this.pathResolver=new nt(e),this.complexityManager=new rt(e)}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 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 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=e=>{let t=String(e);return t.includes(`.`)?t:`${i.id}.${t}`},s=a.dependencies?.map(e=>o(e))??[];return{...a,id:e,title:a.title||`Subtask ${r}`,description:a.description||``,status:a.status||`pending`,priority:a.priority||i.priority||`medium`,dependencies:s,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={version:`1.0.0`,lastModified:(/* @__PURE__ */ new Date()).toISOString(),taskCount:e.length,completedCount:e.filter(e=>e.status===`done`).length,tags:[r]},a=this.normalizeTaskIds(e);await this.fileOps.modifyJson(n,e=>this.formatHandler.detectFormat(e)===`legacy`||Object.keys(e).some(e=>e!==`tasks`&&e!==`metadata`)?(e[r]={tasks:a,metadata:i},e):r===`master`?{tasks:a,metadata:i}:{master:{tasks:e.tasks||[],metadata:e.metadata||i},[r]:{tasks:a,metadata:i}})}normalizeTaskIds(e){return e.map(e=>({...e,id:String(e.id),dependencies:e.dependencies?.map(e=>String(e))||[],subtasks:e.subtasks?.map(e=>({...e,id:Number(e.id),parentId:String(e.parentId)}))||[]}))}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){let n=[...await this.loadTasks(t),...e];await this.saveTasks(n,t)}async updateTask(e,t,n){let r=await this.loadTasks(n),i=r.findIndex(t=>String(t.id)===String(e));if(i===-1)throw Error(`Task ${e} not found`);let a=r[i],o=t.subtasks;t.subtasks&&a.subtasks&&(o=t.subtasks.map(e=>{let t=a.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})),r[i]={...a,...t,...o&&{subtasks:o},id:String(e)},await this.saveTasks(r,n)}async updateTaskStatus(e,t,n){let r=await this.loadTasks(n);if(e.includes(`.`))return this.updateSubtaskStatusInFile(r,e,t,n);let i=r.findIndex(t=>String(t.id)===String(e));if(i===-1)throw Error(`Task ${e} not found`);let a=r[i].status;return a===t||(r[i]={...r[i],status:t,updatedAt:(/* @__PURE__ */ new Date()).toISOString()},await this.saveTasks(r,n)),{success:!0,oldStatus:a,newStatus:t,taskId:String(e)}}async updateSubtaskStatusInFile(e,t,n,r){let i=t.split(`.`);if(i.length!==2)throw Error(`Invalid subtask ID format: ${t}. Expected format: parentId.subtaskId`);let[a,o]=i,s=o.trim();if(!/^\d+$/.test(s))throw Error(`Invalid subtask ID: ${s}. Subtask ID must be a positive integer.`);let c=Number(s),l=e.findIndex(e=>String(e.id)===String(a));if(l===-1)throw Error(`Parent task ${a} not found`);let u=e[l],d=u.subtasks.findIndex(e=>e.id===c||String(e.id)===s);if(d===-1)throw Error(`Subtask ${t} not found in parent task ${a}`);let f=u.subtasks[d].status||`pending`;if(f===n)return{success:!0,oldStatus:f,newStatus:n,taskId:t};let p=(/* @__PURE__ */ new Date()).toISOString();u.subtasks[d]={...u.subtasks[d],status:n,updatedAt:p};let m=u.subtasks,h=u.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`)}return e[l]={...u,...h===u.status?{}:{status:h},updatedAt:p},await this.saveTasks(e,r),{success:!0,oldStatus:f,newStatus:n,taskId:t}}async deleteTask(e,t){let n=await this.loadTasks(t),r=n.filter(t=>String(t.id)!==String(e));if(r.length===n.length)throw Error(`Task ${e} not found`);await this.saveTasks(r,t)}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 T(`Tag ${e} already exists`,w.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:{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:{...i,tags:[`master`]}},[e]:{tasks:a,metadata:{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:{...r,tags:[t]}}}}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 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(){let e=await this.getAllTags(),t=await this.getActiveTagFromState(),n=await Promise.all(e.map(async e=>{try{let n=await this.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.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`}}async watch(e,t){let n=this.pathResolver.getTasksPath(),r=t?.debounceMs??100;if(!await this.fileOps.exists(n))throw new T(`Tasks file not found. Initialize the project first.`,w.NOT_FOUND,{path:n});let i,a=!1,o=te.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 it(e.basePath||t)}},ot=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 T(`Task ID is required and must be a string or number`,w.VALIDATION_ERROR);if(!e.title||e.title.trim().length===0)throw new T(`Task title is required`,w.VALIDATION_ERROR);if(!e.description||e.description.trim().length===0)throw new T(`Task description is required`,w.VALIDATION_ERROR);if(!this.isValidStatus(e.status))throw new T(`Invalid task status: ${e.status}`,w.VALIDATION_ERROR);if(!this.isValidPriority(e.priority))throw new T(`Invalid task priority: ${e.priority}`,w.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 T(`Task cannot be marked as complete`,w.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 T(`Invalid status: ${e}`,w.VALIDATION_ERROR);if(this.status===`done`&&e===`pending`)throw new T(`Cannot move completed task back to pending`,w.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))}},st=class{configManager;storage;initialized=!1;logger=C(`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=ot.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 T?t:(this.logger.error(`Failed to get task list`,t),new T(`Failed to get task list`,w.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 T?t:new T(`Failed to get task ${e}`,w.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){let t=(await this.getTaskList({tag:e,filter:{status:[`pending`,`in-progress`,`done`]}})).tasks,n={critical:4,high:3,medium:2,low:1},r=(e,t)=>typeof t==`string`&&t.includes(`.`)?t:`${e}.${t}`,i=/* @__PURE__ */ new Set;t.forEach(e=>{e.status===`done`&&i.add(String(e.id)),Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{t.status===`done`&&i.add(`${e.id}.${t.id}`)})});let a=[];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 o=t.dependencies?.map(t=>r(String(e.id),t))??[];(o.length===0||o.every(e=>i.has(String(e))))&&a.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,status:t.status||`pending`,priority:t.priority||e.priority||`medium`,dependencies:o,parentId:String(e.id),description:t.description,details:t.details,testStrategy:t.testStrategy,subtasks:[]})})}),a.length>0)return a.sort((e,t)=>{let r=n[e.priority]??2,i=n[t.priority]??2;if(i!==r)return i-r;if(e.dependencies.length!==t.dependencies.length)return e.dependencies.length-t.dependencies.length;let[a,o]=String(e.id).split(`.`).map(Number),[s,c]=String(t.id).split(`.`).map(Number);return a===s?o-c:a-s}),a[0];let o=t.filter(e=>{let t=(e.status||`pending`).toLowerCase();return t!==`pending`&&t!==`in-progress`?!1:(e.dependencies??[]).every(e=>i.has(String(e)))});return o.length===0?null:o.sort((e,t)=>{let r=n[e.priority]??2,i=n[t.priority]??2;if(i!==r)return i-r;let a=(e.dependencies??[]).length,o=(t.dependencies??[]).length;return a===o?Number(e.id)-Number(t.id):a-o})[0]}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 T(`Storage not initialized`,w.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 T?t:new T(`Failed to update task ${e}`,w.STORAGE_ERROR,{operation:`updateTask`,resource:`task`,taskId:i,tag:r},t)}}async updateTaskStatus(e,t,n){if(!this.storage)throw new T(`Storage not initialized`,w.STORAGE_ERROR);let r=n||this.getActiveTag(),i=String(e);try{return await this.storage.updateTaskStatus(i,t,r)}catch(e){throw e instanceof T?e:new T(`Failed to update task status for ${i}`,w.STORAGE_ERROR,{operation:`updateTaskStatus`,resource:`task`,taskId:i,newStatus:t,tag:r},e)}}async getTagsWithStats(){if(!this.storage)throw new T(`Storage not initialized`,w.STORAGE_ERROR);this.initialized||await this.initialize();try{return await this.storage.getTagsWithStats()}catch(e){throw e instanceof T?e:new T(`Failed to get tags with stats`,w.STORAGE_ERROR,{operation:`getTagsWithStats`,resource:`tags`},e)}}async close(){this.storage&&await this.storage.close(),this.initialized=!1}},ct=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}}},lt=`taskgraph-ai`,ut=`0.52.9`;const dt={CLAUDE_CODE:`claude-code`},ft=Object.values(dt);[...ft];const pt=`.taskgraph/tasks/tasks.json`,K=[`.taskgraph`,`.taskgraph/config.json`,pt],q=/* @__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(`,`),mt=[`tasks.json`,...q,`requirements.txt`];[...K,...mt];const J=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`],ht=[`done`,`completed`,`cancelled`];function Y(e){return ht.includes(e)}const gt=[`text`,`json`,`compact`],_t={done:`✓`,completed:`✓`,"in-progress":`►`,blocked:`⭕`,pending:`○`,deferred:`⏸`,cancelled:`✗`,review:`👁`},X=C(`TaskLoader`);var vt=class{taskService;constructor(e){if(!e)throw Error(`taskService is required for TaskLoaderService`);this.taskService=e}async loadAndValidateTask(e){X.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?(X.info(`Task ${e} validated successfully`),{success:!0,task:t}):a}async loadTask(e){try{return await this.taskService.getTask(e)}catch(t){return X.error(`Failed to load task ${e}:`,t),null}}validateTaskStatus(e){return Y(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]}}},$e=class{logger=C(`LoopDomain`);loopService=null;projectRoot;constructor(e){this.projectRoot=e.getProjectRoot()}checkSandboxAuth(){return new U({projectRoot:this.projectRoot}).checkSandboxAuth()}runInteractiveAuth(){return new U({projectRoot:this.projectRoot}).runInteractiveAuth()}async run(e){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 U({projectRoot:this.projectRoot}),this.loopService.run(t)}stop(){this.loopService&&=(this.loopService.stop(),null)}getIsRunning(){return this.loopService?.isRunning??!1}isPreset(e){return H(e)}async resolvePrompt(e,t){if(H(e))return Qe(e);if(!t)throw Error(`Custom prompt file requires readFile callback: ${e}`);return t(e)}getAvailablePresets(){return[...V]}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}}},et=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(e=>({...e,id:Number(e.id),parentId:String(e.parentId)}))||[]}))}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]}}};const W={stale:1e4,retries:{retries:5,factor:2,minTimeout:100,maxTimeout:1e3},realpath:!1};var tt=class{writers=/* @__PURE__ */ new Map;getWriter(e){let t=this.writers.get(e);return t||(t=new oe(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?Error(`Invalid JSON in file ${e}: ${t.message}`):Error(`Failed to read file ${e}: ${t.message}`)}}async writeJson(e,t){await this.ensureFileExists(e);let n=null;try{n=await ae.lock(e,W);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 ae.lock(e,W);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,ne.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()}},nt=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}};const G=C(`ComplexityReportManager`);var rt=class{projectRoot;reportCache=/* @__PURE__ */ new Map;constructor(e){this.projectRoot=e}getReportPath(e){let t=c.join(this.projectRoot,`.taskgraph`,`reports`),n=e&&e!==`master`?`_${e}`:``;return c.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)?(G.warn(`Invalid complexity report structure at ${r}, ignoring`),null):(this.reportCache.set(n,a),G.debug(`Loaded complexity report for tag '${t}' with ${a.complexityAnalysis.length} analyses`),a)}catch(e){return e.code===`ENOENT`?(G.debug(`No complexity report found for tag '${t}'`),null):(G.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}}},it=class{formatHandler;fileOps;pathResolver;complexityManager;constructor(e){this.formatHandler=new et,this.fileOps=new tt,this.pathResolver=new nt(e),this.complexityManager=new rt(e)}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 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 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=e=>{let t=String(e);return t.includes(`.`)?t:`${i.id}.${t}`},s=a.dependencies?.map(e=>o(e))??[];return{...a,id:e,title:a.title||`Subtask ${r}`,description:a.description||``,status:a.status||`pending`,priority:a.priority||i.priority||`medium`,dependencies:s,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={version:`1.0.0`,lastModified:(/* @__PURE__ */ new Date()).toISOString(),taskCount:e.length,completedCount:e.filter(e=>e.status===`done`).length,tags:[r]},a=this.normalizeTaskIds(e);await this.fileOps.modifyJson(n,e=>this.formatHandler.detectFormat(e)===`legacy`||Object.keys(e).some(e=>e!==`tasks`&&e!==`metadata`)?(e[r]={tasks:a,metadata:i},e):r===`master`?{tasks:a,metadata:i}:{master:{tasks:e.tasks||[],metadata:e.metadata||i},[r]:{tasks:a,metadata:i}})}normalizeTaskIds(e){return e.map(e=>({...e,id:String(e.id),dependencies:e.dependencies?.map(e=>String(e))||[],subtasks:e.subtasks?.map(e=>({...e,id:Number(e.id),parentId:String(e.parentId)}))||[]}))}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){let n=[...await this.loadTasks(t),...e];await this.saveTasks(n,t)}async updateTask(e,t,n){let r=await this.loadTasks(n),i=r.findIndex(t=>String(t.id)===String(e));if(i===-1)throw Error(`Task ${e} not found`);let a=r[i],o=t.subtasks;t.subtasks&&a.subtasks&&(o=t.subtasks.map(e=>{let t=a.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})),r[i]={...a,...t,...o&&{subtasks:o},id:String(e)},await this.saveTasks(r,n)}async updateTaskStatus(e,t,n){let r=await this.loadTasks(n);if(e.includes(`.`))return this.updateSubtaskStatusInFile(r,e,t,n);let i=r.findIndex(t=>String(t.id)===String(e));if(i===-1)throw Error(`Task ${e} not found`);let a=r[i].status;return a===t||(r[i]={...r[i],status:t,updatedAt:(/* @__PURE__ */ new Date()).toISOString()},await this.saveTasks(r,n)),{success:!0,oldStatus:a,newStatus:t,taskId:String(e)}}async updateSubtaskStatusInFile(e,t,n,r){let i=t.split(`.`);if(i.length!==2)throw Error(`Invalid subtask ID format: ${t}. Expected format: parentId.subtaskId`);let[a,o]=i,s=o.trim();if(!/^\d+$/.test(s))throw Error(`Invalid subtask ID: ${s}. Subtask ID must be a positive integer.`);let c=Number(s),l=e.findIndex(e=>String(e.id)===String(a));if(l===-1)throw Error(`Parent task ${a} not found`);let u=e[l],d=u.subtasks.findIndex(e=>e.id===c||String(e.id)===s);if(d===-1)throw Error(`Subtask ${t} not found in parent task ${a}`);let f=u.subtasks[d].status||`pending`;if(f===n)return{success:!0,oldStatus:f,newStatus:n,taskId:t};let p=(/* @__PURE__ */ new Date()).toISOString();u.subtasks[d]={...u.subtasks[d],status:n,updatedAt:p};let m=u.subtasks,h=u.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`)}return e[l]={...u,...h===u.status?{}:{status:h},updatedAt:p},await this.saveTasks(e,r),{success:!0,oldStatus:f,newStatus:n,taskId:t}}async deleteTask(e,t){let n=await this.loadTasks(t),r=n.filter(t=>String(t.id)!==String(e));if(r.length===n.length)throw Error(`Task ${e} not found`);await this.saveTasks(r,t)}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 T(`Tag ${e} already exists`,w.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:{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:{...i,tags:[`master`]}},[e]:{tasks:a,metadata:{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:{...r,tags:[t]}}}}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 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(){let e=await this.getAllTags(),t=await this.getActiveTagFromState(),n=await Promise.all(e.map(async e=>{try{let n=await this.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.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`}}async watch(e,t){let n=this.pathResolver.getTasksPath(),r=t?.debounceMs??100;if(!await this.fileOps.exists(n))throw new T(`Tasks file not found. Initialize the project first.`,w.NOT_FOUND,{path:n});let i,a=!1,o=te.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 it(e.basePath||t)}},ot=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 T(`Task ID is required and must be a string or number`,w.VALIDATION_ERROR);if(!e.title||e.title.trim().length===0)throw new T(`Task title is required`,w.VALIDATION_ERROR);if(!e.description||e.description.trim().length===0)throw new T(`Task description is required`,w.VALIDATION_ERROR);if(!this.isValidStatus(e.status))throw new T(`Invalid task status: ${e.status}`,w.VALIDATION_ERROR);if(!this.isValidPriority(e.priority))throw new T(`Invalid task priority: ${e.priority}`,w.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 T(`Task cannot be marked as complete`,w.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 T(`Invalid status: ${e}`,w.VALIDATION_ERROR);if(this.status===`done`&&e===`pending`)throw new T(`Cannot move completed task back to pending`,w.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))}},st=class{configManager;storage;initialized=!1;logger=C(`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=ot.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 T?t:(this.logger.error(`Failed to get task list`,t),new T(`Failed to get task list`,w.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 T?t:new T(`Failed to get task ${e}`,w.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){let t=(await this.getTaskList({tag:e,filter:{status:[`pending`,`in-progress`,`done`]}})).tasks,n={critical:4,high:3,medium:2,low:1},r=(e,t)=>typeof t==`string`&&t.includes(`.`)?t:`${e}.${t}`,i=/* @__PURE__ */ new Set;t.forEach(e=>{e.status===`done`&&i.add(String(e.id)),Array.isArray(e.subtasks)&&e.subtasks.forEach(t=>{t.status===`done`&&i.add(`${e.id}.${t.id}`)})});let a=[];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 o=t.dependencies?.map(t=>r(String(e.id),t))??[];(o.length===0||o.every(e=>i.has(String(e))))&&a.push({id:`${e.id}.${t.id}`,title:t.title||`Subtask ${t.id}`,status:t.status||`pending`,priority:t.priority||e.priority||`medium`,dependencies:o,parentId:String(e.id),description:t.description,details:t.details,testStrategy:t.testStrategy,subtasks:[]})})}),a.length>0)return a.sort((e,t)=>{let r=n[e.priority]??2,i=n[t.priority]??2;if(i!==r)return i-r;if(e.dependencies.length!==t.dependencies.length)return e.dependencies.length-t.dependencies.length;let[a,o]=String(e.id).split(`.`).map(Number),[s,c]=String(t.id).split(`.`).map(Number);return a===s?o-c:a-s}),a[0];let o=t.filter(e=>{let t=(e.status||`pending`).toLowerCase();return t!==`pending`&&t!==`in-progress`?!1:(e.dependencies??[]).every(e=>i.has(String(e)))});return o.length===0?null:o.sort((e,t)=>{let r=n[e.priority]??2,i=n[t.priority]??2;if(i!==r)return i-r;let a=(e.dependencies??[]).length,o=(t.dependencies??[]).length;return a===o?Number(e.id)-Number(t.id):a-o})[0]}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 T(`Storage not initialized`,w.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 T?t:new T(`Failed to update task ${e}`,w.STORAGE_ERROR,{operation:`updateTask`,resource:`task`,taskId:i,tag:r},t)}}async updateTaskStatus(e,t,n){if(!this.storage)throw new T(`Storage not initialized`,w.STORAGE_ERROR);let r=n||this.getActiveTag(),i=String(e);try{return await this.storage.updateTaskStatus(i,t,r)}catch(e){throw e instanceof T?e:new T(`Failed to update task status for ${i}`,w.STORAGE_ERROR,{operation:`updateTaskStatus`,resource:`task`,taskId:i,newStatus:t,tag:r},e)}}async getTagsWithStats(){if(!this.storage)throw new T(`Storage not initialized`,w.STORAGE_ERROR);this.initialized||await this.initialize();try{return await this.storage.getTagsWithStats()}catch(e){throw e instanceof T?e:new T(`Failed to get tags with stats`,w.STORAGE_ERROR,{operation:`getTagsWithStats`,resource:`tags`},e)}}async close(){this.storage&&await this.storage.close(),this.initialized=!1}},ct=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}}},lt=`taskgraph-ai`,ut=`0.52.10`;const dt={CLAUDE_CODE:`claude-code`},ft=Object.values(dt);[...ft];const pt=`.taskgraph/tasks/tasks.json`,K=[`.taskgraph`,`.taskgraph/config.json`,pt],q=/* @__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(`,`),mt=[`tasks.json`,...q,`requirements.txt`];[...K,...mt];const J=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`],ht=[`done`,`completed`,`cancelled`];function Y(e){return ht.includes(e)}const gt=[`text`,`json`,`compact`],_t={done:`✓`,completed:`✓`,"in-progress":`►`,blocked:`⭕`,pending:`○`,deferred:`⏸`,cancelled:`✗`,review:`👁`},X=C(`TaskLoader`);var vt=class{taskService;constructor(e){if(!e)throw Error(`taskService is required for TaskLoaderService`);this.taskService=e}async loadAndValidateTask(e){X.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?(X.info(`Task ${e} validated successfully`),{success:!0,task:t}):a}async loadTask(e){try{return await this.taskService.getTask(e)}catch(t){return X.error(`Failed to load task ${e}:`,t),null}}validateTaskStatus(e){return Y(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 +1 @@
1
- export{Q as createTagFromBranch,it as useTag}from"./dependency-manager-CgVcJkvK.js";
1
+ export{Q as createTagFromBranch,it as useTag}from"./dependency-manager-LkUwzM2z.js";
@@ -1 +1 @@
1
- import{J as e,st as t}from"./config-manager-BR7-QmoJ.js";import{A as n,B as r,C as i,D as a,E as o,H as s,I as c,L as l,M as u,N as d,O as f,P as p,R as m,S as h,T as g,U as _,V as v,at as y,j as b,k as x,w as S,x as C,z as w}from"./dependency-manager-CgVcJkvK.js";import{t as T}from"./response-language-D37M4YTj.js";export{_ as addSubtask,s as addTask,v as analyzeTaskComplexity,r as clearSubtasks,m as expandAllTasks,w as expandTask,y as findNextTask,e as findTaskById,l as isTaskDependentOn,c as listTasks,p as moveTask,d as parsePRD,x as performResearch,t as readComplexityReport,u as removeSubtask,n as removeTask,o as scopeDownTask,a as scopeUpTask,T as setResponseLanguage,S as setTaskStatus,b as taskExists,g as updateSingleTaskStatus,i as updateSubtaskById,h as updateTaskById,C as updateTasks,f as validateStrength};
1
+ import{J as e,st as t}from"./config-manager-BOVIL1tN.js";import{A as n,B as r,C as i,D as a,E as o,H as s,I as c,L as l,M as u,N as d,O as f,P as p,R as m,S as h,T as g,U as _,V as v,at as y,j as b,k as x,w as S,x as C,z as w}from"./dependency-manager-LkUwzM2z.js";import{t as T}from"./response-language-Jp4uf0oe.js";export{_ as addSubtask,s as addTask,v as analyzeTaskComplexity,r as clearSubtasks,m as expandAllTasks,w as expandTask,y as findNextTask,e as findTaskById,l as isTaskDependentOn,c as listTasks,p as moveTask,d as parsePRD,x as performResearch,t as readComplexityReport,u as removeSubtask,n as removeTask,o as scopeDownTask,a as scopeUpTask,T as setResponseLanguage,S as setTaskStatus,b as taskExists,g as updateSingleTaskStatus,i as updateSubtaskById,h as updateTaskById,C as updateTasks,f as validateStrength};
package/dist/taskgraph.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{c as e}from"./src-B0-DNEPs.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`)}),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-CH1-vxnG.js`);s(process.argv);export{};
2
+ import{c as e}from"./src-ZFNFV1Cv.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`)}),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-WPzx09Df.js`);s(process.argv);export{};
@@ -0,0 +1 @@
1
+ import"./dependency-manager-LkUwzM2z.js";export{};
@@ -0,0 +1 @@
1
+ export{S as default}from"./dependency-manager-LkUwzM2z.js";
@@ -0,0 +1 @@
1
+ export{ct as readJSON}from"./config-manager-BOVIL1tN.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskgraph-ai",
3
- "version": "0.52.9",
3
+ "version": "0.52.10",
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
  "main": "index.js",
6
6
  "type": "module",
@@ -1,3 +0,0 @@
1
- import{D as e,Q as t,S as n,b as r,d as i,h as a,i as o,j as s,lt as c,m as l,nt as u,o as d,p as f,q as p,u as m,v as h,x as g,y as _}from"./config-manager-BR7-QmoJ.js";import{createRequire as v}from"node:module";import{execSync as y}from"child_process";import{createClaudeCode as b}from"ai-sdk-provider-claude-code";import*as x from"ai";import{jsonrepair as S}from"jsonrepair";import{EnvHttpProxyAgent as C}from"undici";var w=Object.defineProperty,T=(e,t)=>{let n={};for(var r in e)w(n,r,{get:e[r],enumerable:!0});return t||w(n,Symbol.toStringTag,{value:`Module`}),n},E=/* @__PURE__ */ v(import.meta.url);const{JSONParseError:D,NoObjectGeneratedError:O,generateObject:k,generateText:A,streamObject:j,streamText:ee,zodSchema:te}=x,M=x.jsonSchema,N=/* @__PURE__ */ new Set([`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`]),P=[`additionalProperties`,`contains`,`if`,`then`,`else`,`not`,`propertyNames`],F=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],I=[`definitions`,`$defs`,`dependentSchemas`,`patternProperties`,`properties`],ne=e=>e?Array.isArray(e)?e.includes(`integer`):e===`integer`:!1,L=e=>{if(!e||typeof e!=`object`)return e;if(Array.isArray(e))return e.map(L);let t={...e};if(ne(t.type))for(let e of N)e in t&&delete t[e];for(let e of P)t[e]&&(t[e]=L(t[e]));for(let e of F)Array.isArray(t[e])&&(t[e]=t[e].map(L));for(let e of I)if(t[e]&&typeof t[e]==`object`){let n={};for(let[r,i]of Object.entries(t[e]))n[r]=L(i);t[e]=n}return t.items&&=L(t.items),t},R=e=>{let t=te(e);if(!t||typeof t!=`object`||!t.jsonSchema)return t;let n=L(t.jsonSchema);return typeof M==`function`?M(n,{validate:t.validate}):{...t,jsonSchema:n}};var z=class t{constructor(){if(this.constructor===t)throw Error(`BaseAIProvider cannot be instantiated directly`);this.name=this.constructor.name,this._proxyAgent=null,this.needsExplicitJsonSchema=!1,this.supportsTemperature=!0}validateAuth(e){if(!e.apiKey)throw Error(`${this.name} API key is required`)}createProxyFetch(){this._projectRoot||=p();let t=this._projectRoot;if(e(null,t))return this._proxyAgent||=new C,(e,t={})=>fetch(e,{...t,dispatcher:this._proxyAgent})}validateParams(e){if(this.validateAuth(e),!e.modelId)throw Error(`${this.name} Model ID is required`);this.validateOptionalParams(e)}validateOptionalParams(e){if(e.temperature!==void 0&&(e.temperature<0||e.temperature>1))throw Error(`Temperature must be between 0 and 1`);if(e.maxTokens!==void 0){let t=Number(e.maxTokens);if(!Number.isFinite(t)||t<=0)throw Error(`maxTokens must be a finite number greater than 0`)}}validateMessages(e){if(!e||!Array.isArray(e)||e.length===0)throw Error(`Invalid or empty messages array provided`);for(let t of e)if(!t.role||!t.content)throw Error(`Invalid message format. Each message must have role and content`)}handleError(e,t){let n=t.message||`Unknown error occurred`;throw u(`error`,`${this.name} ${e} failed: ${n}`,{error:t}),Error(`${this.name} API error during ${e}: ${n}`)}getClient(e){throw Error(`getClient must be implemented by provider`)}isRequiredApiKey(){return!0}getRequiredApiKeyName(){throw Error(`getRequiredApiKeyName must be implemented by provider`)}prepareTokenParam(e,t){return t===void 0?{}:{maxOutputTokens:Math.floor(Number(t))}}prepareMessages(e){let t=e.filter(e=>e.role===`system`);return t.length===0?{messages:e}:{instructions:t.map(e=>typeof e.content==`string`?e.content:e.content.map(e=>e.text??``).join(``)).join(`
2
-
3
- `),messages:e.filter(e=>e.role!==`system`)}}async generateText(e){try{this.validateParams(e),this.validateMessages(e.messages),u(`debug`,`Generating ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),n=await A({model:t(e.modelId),...this.prepareMessages(e.messages),...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{}});u(`debug`,`${this.name} generateText completed successfully for model: ${e.modelId}`);let r=n.usage?.inputTokens??n.usage?.promptTokens??0,i=n.usage?.outputTokens??n.usage?.completionTokens??0,a=n.usage?.totalTokens??r+i;return{text:n.text,usage:{inputTokens:r,outputTokens:i,totalTokens:a}}}catch(e){this.handleError(`text generation`,e)}}async streamText(e){try{this.validateParams(e),this.validateMessages(e.messages),u(`debug`,`Streaming ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),n=await ee({model:t(e.modelId),...this.prepareMessages(e.messages),...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...e.experimental_transform&&{experimental_transform:e.experimental_transform}});return u(`debug`,`${this.name} streamText initiated successfully for model: ${e.modelId}`),n}catch(e){this.handleError(`text streaming`,e)}}async streamObject(e){try{if(this.validateParams(e),this.validateMessages(e.messages),!e.schema)throw Error(`Schema is required for object streaming`);u(`debug`,`Streaming ${this.name} object with model: ${e.modelId}`);let t=await this.getClient(e),n=R(e.schema),r=await j({model:t(e.modelId),...this.prepareMessages(e.messages),schema:n,mode:this.needsExplicitJsonSchema?`json`:`auto`,...e.objectName&&{schemaName:e.objectName,schemaDescription:`Generate a valid JSON object for ${e.objectName}`},maxTokens:e.maxTokens,...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},onError:({error:e})=>u(`debug`,`${this.name} stream error: ${e?.message??e}`)});return u(`debug`,`${this.name} streamObject initiated successfully for model: ${e.modelId}`),r}catch(e){this.handleError(`object streaming`,e)}}async generateObject(e){try{if(this.validateParams(e),this.validateMessages(e.messages),!e.schema)throw Error(`Schema is required for object generation`);if(!e.objectName)throw Error(`Object name is required for object generation`);u(`debug`,`Generating ${this.name} object ('${e.objectName}') with model: ${e.modelId}`);let t=await this.getClient(e),n=R(e.schema),r=await k({model:t(e.modelId),...this.prepareMessages(e.messages),schema:n,mode:this.needsExplicitJsonSchema?`json`:`auto`,schemaName:e.objectName,schemaDescription:`Generate a valid JSON object for ${e.objectName}`,maxTokens:e.maxTokens,...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{}});u(`debug`,`${this.name} generateObject completed successfully for model: ${e.modelId}`);let i=r.usage?.inputTokens??r.usage?.promptTokens??0,a=r.usage?.outputTokens??r.usage?.completionTokens??0,o=r.usage?.totalTokens??i+a;return{object:r.object,usage:{inputTokens:i,outputTokens:a,totalTokens:o}}}catch(e){if(O.isInstance(e)&&e.cause instanceof D&&e.cause.text){u(`warn`,`${this.name} generated malformed JSON, attempting to repair...`);try{let t=S(e.cause.text),n=JSON.parse(t);return u(`info`,`Successfully repaired ${this.name} JSON output`),{object:n,usage:{inputTokens:e.usage?.promptTokens||e.usage?.inputTokens||0,outputTokens:e.usage?.completionTokens||e.usage?.outputTokens||0,totalTokens:e.usage?.totalTokens||0}}}catch(e){u(`error`,`Failed to repair ${this.name} JSON: ${e.message}`)}}this.handleError(`object generation`,e)}}};let B=!1;const V=[`WebSearch`,`WebFetch`],H=[`Read`,`Grep`,`Glob`];function U(e,t){let n=e===`research`,r=n?V:H;return{tools:[...r],allowedTools:[...r],permissionMode:`dontAsk`,permissionPrompts:`none`,strictMcpConfig:!0,mcpServers:{},...n&&{settingSources:[],maxTurns:t.maxTurns??8}}}var W=class extends z{constructor(){super(),this.name=`Claude Code`,this.supportedModels=g(`claude-code`),this.supportedModels.length===0&&u(`warn`,`No supported models found for claude-code provider. Check supported-models.json configuration.`),this.needsExplicitJsonSchema=!0,this.supportsTemperature=!1}getRequiredApiKeyName(){return`CLAUDE_CODE_API_KEY`}isRequiredApiKey(){return!1}validateAuth(e){if(process.env.NODE_ENV!==`test`&&!B&&!process.env.CLAUDE_CODE_OAUTH_TOKEN)try{y(`claude --version`,{stdio:`pipe`,timeout:1e3})}catch{u(`warn`,`Claude Code CLI not detected. Install it with: npm install -g @anthropic-ai/claude-code`)}finally{B=!0}}getClient(e={}){try{let t=o(e.commandName)||{},n={...process.env};return process.env.CLAUDE_CODE_API_KEY?n.ANTHROPIC_API_KEY=process.env.CLAUDE_CODE_API_KEY:delete n.ANTHROPIC_API_KEY,b({defaultSettings:{systemPrompt:{type:`preset`,preset:`claude_code`},settingSources:[`user`,`project`,`local`],env:n,logger:{debug:e=>u(`debug`,e),info:e=>u(`debug`,e),warn:e=>u(`debug`,e),error:e=>u(`error`,e)},...t,...U(e.role,t)}})}catch(e){let t=String(e?.message||``);if(e?.code===`ENOENT`||/claude/i.test(t)){let t=/* @__PURE__ */ Error(`Claude Code CLI not available. Please install Claude Code CLI first. Original error: ${e.message}`);t.cause=e,this.handleError(`Claude Code CLI initialization`,t)}else this.handleError(`client initialization`,e)}}getSupportedModels(){return this.supportedModels}isModelSupported(e){return e?this.supportedModels.includes(String(e).toLowerCase()):!1}};let G=null;var K=class e{constructor(){this._providers=/* @__PURE__ */ new Map,this._initialized=!1}static getInstance(){return G||=new e,G}initialize(){return this._initialized||=!0,this}registerProvider(e,t,n={}){if(!e||typeof e!=`string`)throw Error(`Provider name must be a non-empty string`);if(!t)throw Error(`Provider instance is required`);if(typeof t.generateText!=`function`||typeof t.streamText!=`function`||typeof t.generateObject!=`function`)throw Error(`Provider must implement BaseAIProvider interface`);return this._providers.set(e,{instance:t,options:n,registeredAt:/* @__PURE__ */ new Date}),this}hasProvider(e){return this._providers.has(e)}getProvider(e){let t=this._providers.get(e);return t?t.instance:null}getAllProviders(){return new Map(this._providers)}unregisterProvider(e){return this._providers.has(e)?(this._providers.delete(e),!0):!1}reset(){this._providers.clear(),this._initialized=!1}};K.getInstance().initialize(),globalThis.AI_SDK_LOG_WARNINGS===void 0&&(globalThis.AI_SDK_LOG_WARNINGS=({warnings:e,provider:t,model:n})=>{for(let r of e){let e=r.message||r.feature||r.setting||r.type;u(`debug`,`AI SDK warning (${t??`?`}/${n??`?`}): ${e}`)}});const q={"claude-code":new W};function J(e){if(q[e])return q[e];let t=K.getInstance();return t.hasProvider(e)?(u(`debug`,`Provider "${e}" found in dynamic registry`),t.getProvider(e)):null}function Y(e,t){let n={inputCost:0,outputCost:0,currency:`USD`,isUnknown:!1};if(!s||!s[e])return u(`warn`,`Provider "${e}" not found in MODEL_MAP. Cannot determine cost for model ${t}.`),{...n,isUnknown:!0};let r=s[e].find(e=>e.id===t);if(!r)return u(`debug`,`Model "${t}" not found under provider "${e}". Assuming unknown cost.`),{...n,isUnknown:!0};if(r.cost_per_1m_tokens===null)return u(`debug`,`Cost data is null for model "${t}" under provider "${e}". Pricing unknown.`),{...n,isUnknown:!0};if(r.cost_per_1m_tokens===void 0)return u(`debug`,`Cost data not found for model "${t}" under provider "${e}". Pricing unknown.`),{...n,isUnknown:!0};let i=r.cost_per_1m_tokens;return{inputCost:i.input||0,outputCost:i.output||0,currency:i.currency||`USD`,isUnknown:!1}}function X(e,t,n,r){let i=(e||0)/1e6*n+(t||0)/1e6*r;return parseFloat(i.toFixed(6))}function re(e){let n={currentTag:`master`,availableTags:[`master`]};try{return e?{currentTag:t(e)||`master`,availableTags:ie(e)}:n}catch(e){return d()&&u(`debug`,`Error getting tag information: ${e.message}`),n}}function ie(e){let t=[`master`];try{let n=E(`path`),r=E(`fs`),i=n.join(e,`.taskgraph`,`tasks`,`tasks.json`);if(!r.existsSync(i))return t;let a=JSON.parse(r.readFileSync(i,`utf8`));if(!a||typeof a!=`object`)return t;let o=Object.keys(a).filter(e=>ae(a[e]));return o.length>0?o:t}catch(e){return d()&&u(`debug`,`Could not read tasks file for available tags: ${e.message}`),t}}function ae(e){return e&&typeof e==`object`&&Array.isArray(e.tasks)}function oe(e){let t=e.message?.toLowerCase()||``;return t.includes(`rate limit`)||t.includes(`overloaded`)||t.includes(`service temporarily unavailable`)||t.includes(`timeout`)||t.includes(`network error`)||e.status===429||e.status>=500}function se(e){try{if(e?.data?.error?.message)return e.data.error.message;if(e?.error?.message)return e.error.message;if(typeof e?.responseBody==`string`)try{let t=JSON.parse(e.responseBody);if(t?.error?.message)return t.error.message}catch{}return typeof e?.message==`string`&&e.message?e.message:typeof e==`string`?e:`An unknown AI service error occurred.`}catch{return`Failed to extract error message.`}}function ce(e,t){return{main:{provider:l(t),modelId:f(t)},research:{provider:_(t),modelId:h(t)},fallback:{provider:i(t),modelId:m(t)}}[e]||null}function Z(e,t,n=null){let r=J(e);if(!r)throw Error(`Unknown provider '${e}' for API key resolution.`);let i=r.getRequiredApiKeyName();if(i===null)return null;let a=c(i,t,n);if(!r.isRequiredApiKey())return a||null;if(!a)throw Error(`Required API key ${i} for provider '${e}' is not set in environment, session, or .env file.`);return a}async function le(e,t,n,r,i,a){let o=0,s=t;for(;o<=2;)try{d()&&u(`info`,`Attempt ${o+1}/3 calling ${s} (Provider: ${r}, Model: ${i}, Role: ${a})`);let c=await e[t](n);return d()&&u(`info`,`${s} succeeded for role ${a} (Provider: ${r}) on attempt ${o+1}`),c}catch(e){if(u(`warn`,`Attempt ${o+1} failed for role ${a} (${s} / ${r}): ${e.message}`),oe(e)&&o<2){o++;let e=1e3*2**(o-1);u(`info`,`Something went wrong on the provider side. Retrying in ${e/1e3}s...`),await new Promise(t=>setTimeout(t,e))}else throw u(`error`,`Something went wrong on the provider side. Max retries reached for role ${a} (${s} / ${r}).`),e}throw Error(`Exhausted all retries for role ${a} (${s} / ${r})`)}async function Q(e,t){let{role:i,session:o,projectRoot:s,systemPrompt:c,prompt:l,schema:f,objectName:m,commandName:h,outputType:g,experimental_transform:_,...v}=t;d()&&u(`info`,`${e}Service called`,{role:i,commandName:h,outputType:g,projectRoot:s});let y=s||p(),b=n(y),x;i===`main`?x=[`main`,`fallback`,`research`]:i===`research`?x=[`research`,`fallback`,`main`]:i===`fallback`?x=[`fallback`,`main`,`research`]:(u(`warn`,`Unknown initial role: ${i}. Defaulting to main -> fallback -> research sequence.`),x=[`main`,`fallback`,`research`]);let S=/* @__PURE__ */ new Set,C=null,w=`AI service call failed for all configured roles.`;for(let t of x){let n,i,s,d,p,x,T=null;try{u(`debug`,`New AI service call with role: ${t}`);let w=ce(t,y);if(!w){u(`error`,`Unknown role encountered in _unifiedServiceRunner: ${t}`),C||=/* @__PURE__ */ Error(`Unknown AI role specified: ${t}`);continue}if(n=w.provider,i=w.modelId,!n||!i){u(`warn`,`Skipping role '${t}': Provider or Model ID not configured.`),C||=/* @__PURE__ */ Error(`Configuration missing for role '${t}'. Provider: ${n}, Model: ${i}`);continue}if(S.has(`${n}/${i}`)){u(`debug`,`Skipping role '${t}': ${n}/${i} already failed for this request.`);continue}if(p=J(n?.toLowerCase()),!p){u(`warn`,`Skipping role '${t}': Provider '${n}' not supported.`),C||=/* @__PURE__ */ Error(`Unsupported provider configured: ${n}`);continue}d=a(t,y),s=Z(n?.toLowerCase(),o,y);let E=[],D=`${c} \n\n Always respond in ${r(y)}.`;if(E.push({role:`system`,content:D.trim()}),l)E.push({role:`user`,content:l});else throw Error(`User prompt content is missing.`);let O={apiKey:s,modelId:i,maxTokens:d.maxTokens,temperature:d.temperature,messages:E,...(e===`generateObject`||e===`streamObject`)&&{schema:f,objectName:m},role:t,...h&&{commandName:h},..._&&{experimental_transform:_},...v};if(x=await le(p,e,O,n,i,t),b&&x&&x.usage)try{T=await $({userId:b,commandName:h,providerName:n,modelId:i,inputTokens:x.usage.inputTokens,outputTokens:x.usage.outputTokens,outputType:g})}catch{}else b&&x&&!x.usage&&u(`warn`,`Cannot log telemetry for ${h} (${n}/${i}): AI result missing 'usage' data. (May be expected for streams)`);let k;e===`generateText`?k=x.text:e===`generateObject`?k=x.object:(e===`streamText`||e===`streamObject`||u(`error`,`Unknown serviceType in _unifiedServiceRunner: ${e}`),k=x);let A=re(y);return{mainResult:k,telemetryData:T,tagInfo:A,providerName:n,modelId:i}}catch(r){let a=se(r);if(u(`error`,`Service call failed for role ${t} (Provider: ${n||`unknown`}, Model: ${i||`unknown`}): ${a}`),C=r,w=a,n&&i&&S.add(`${n}/${i}`),e===`generateObject`){let e=a.toLowerCase();if(e.includes(`no endpoints found that support tool use`)||e.includes(`does not support tool_use`)||e.includes(`tool use is not supported`)||e.includes(`tools are not supported`)||e.includes(`function calling is not supported`)||e.includes(`tool use is not supported`)){let e=`Model '${i||`unknown`}' via provider '${n||`unknown`}' does not support the 'tool use' required by generateObjectService. Please configure a model that supports tool/function calling for the '${t}' role, or use generateTextService if structured output is not strictly required.`;throw u(`error`,`[Tool Support Error] ${e}`),Error(e)}}}}throw u(`error`,`All roles in the sequence [${x.join(`, `)}] failed.`),Error(w)}async function ue(e){return Q(`generateText`,{outputType:`cli`,...e})}async function de(e){return Q(`streamText`,{outputType:`cli`,...e})}async function fe(e){let t={outputType:`cli`,...e};if(!t.schema)throw Error(`streamObjectService requires a schema parameter`);return Q(`streamObject`,t)}async function pe(e){return Q(`generateObject`,{objectName:`generated_object`,maxRetries:3,outputType:`cli`,...e})}async function $({userId:e,commandName:t,providerName:n,modelId:r,inputTokens:i,outputTokens:a,outputType:o}){try{let o=(/* @__PURE__ */ new Date()).toISOString(),s=(i||0)+(a||0),{inputCost:c,outputCost:l,currency:f,isUnknown:p}=Y(n,r),m=X(i,a,c,l),h={timestamp:o,userId:e,commandName:t,modelUsed:r,providerName:n,inputTokens:i||0,outputTokens:a||0,totalTokens:s,totalCost:m,currency:f,isUnknownCost:p};return d()&&u(`info`,`AI Usage Telemetry:`,h),h}catch(e){return u(`error`,`Failed to log AI usage telemetry: ${e.message}`,{error:e}),null}}export{de as a,fe as i,ue as n,T as o,$ as r,pe as t};
@@ -1 +0,0 @@
1
- export{r as logAiUsage}from"./ai-services-unified-BlUEKymz.js";
@@ -1 +0,0 @@
1
- import"./src-B0-DNEPs.js";export{S as getUserId}from"./config-manager-BR7-QmoJ.js";
@@ -1 +0,0 @@
1
- export{k as performResearch}from"./dependency-manager-CgVcJkvK.js";
@@ -1 +0,0 @@
1
- export{t as default}from"./response-language-D37M4YTj.js";
@@ -1 +0,0 @@
1
- import"./dependency-manager-CgVcJkvK.js";export{};
@@ -1 +0,0 @@
1
- export{S as default}from"./dependency-manager-CgVcJkvK.js";
@@ -1 +0,0 @@
1
- export{ct as readJSON}from"./config-manager-BR7-QmoJ.js";