taskgraph-ai 0.52.23 → 0.54.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +38 -34
  2. package/dist/ai-services-unified-BPPVDTpt.js +3 -0
  3. package/dist/ai-services-unified-Dskm2lPO.js +1 -0
  4. package/dist/assets/AGENTS.md +12 -13
  5. package/dist/commands-DJc5m0Gi.js +126 -0
  6. package/dist/config-manager-CKwBfpAp.js +1 -0
  7. package/dist/config-manager-Db2R8Tgw.js +1 -0
  8. package/dist/git-utils-CRR3iPaC.js +1 -0
  9. package/dist/{git-utils--i2q96hv.js → git-utils-NnZtE3nY.js} +1 -1
  10. package/dist/init-CK_i6ZcN.js +24 -0
  11. package/dist/mcp-server.js +2 -2
  12. package/dist/research-BKsPc_oX.js +1 -0
  13. package/dist/research-C8rAJdp0.js +585 -0
  14. package/dist/{response-language-ip84ug-k.js → response-language-C8euRV2w.js} +1 -1
  15. package/dist/response-language-DiIdcmnK.js +1 -0
  16. package/dist/rolldown-runtime-BxhE39jg.js +1 -0
  17. package/dist/src-CK3olqVP.js +468 -0
  18. package/dist/src-DRpuDe-k.js +207 -0
  19. package/dist/tag-management-BL0w3Tk3.js +1 -0
  20. package/dist/task-manager-B_UFNQnE.js +1 -0
  21. package/dist/task-manager-BipYRXFW.js +167 -0
  22. package/dist/taskgraph.js +1 -1
  23. package/package.json +3 -8
  24. package/dist/ai-services-unified-CigO4oTy.js +0 -1
  25. package/dist/ai-services-unified-kmQRPU0g.js +0 -3
  26. package/dist/assets/claude/TM_COMMANDS_GUIDE.md +0 -147
  27. package/dist/assets/scripts_README.md +0 -443
  28. package/dist/commands-dFNugMWF.js +0 -116
  29. package/dist/config-manager-C5Ih13nA.js +0 -1
  30. package/dist/config-manager-DhVH8AQp.js +0 -1
  31. package/dist/dependency-manager-CCREovZA.js +0 -758
  32. package/dist/git-utils-BezpEZd4.js +0 -1
  33. package/dist/init-p_pWjmVE.js +0 -3139
  34. package/dist/research-blv_5JOT.js +0 -1
  35. package/dist/response-language-D9UxmXBp.js +0 -1
  36. package/dist/src-TZm8h0X-.js +0 -207
  37. package/dist/src-yE1DeXKG.js +0 -468
  38. package/dist/tag-management-Br2FX-YC.js +0 -1
  39. package/dist/task-manager-DWPIhAB7.js +0 -1
  40. package/index.js +0 -157
@@ -0,0 +1,585 @@
1
+ import{O as e}from"./src-DRpuDe-k.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-CKwBfpAp.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-CK3olqVP.js";import{n as te}from"./ai-services-unified-BPPVDTpt.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
+ `)+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
+
4
+ `;c+=N.muted(`Query: `)+C.reset(`"${t}"`)+`
5
+ `,c+=N.muted(`Context size: `)+C.cyan(`${n.toLocaleString()} characters`)+`
6
+ `,c+=N.muted(`Tasks found: `)+C.yellow(`${s.length} relevant tasks`)+`
7
+
8
+ `,r.length>0&&(c+=C.green.bold(`High relevance matches:`)+`
9
+ `,r.slice(0,3).forEach(e=>{c+=C.green(` • Task ${e.id}: ${u(e.title,50)}`)+`
10
+ `}),r.length>3&&(c+=C.green(` • ... and ${r.length-3} more high relevance tasks`)+`
11
+ `),c+=`
12
+ `),i.length>0&&(c+=C.yellow.bold(`Medium relevance matches:`)+`
13
+ `,i.slice(0,3).forEach(e=>{c+=C.yellow(` • Task ${e.id}: ${u(e.title,50)}`)+`
14
+ `}),i.length>3&&(c+=C.yellow(` • ... and ${i.length-3} more medium relevance tasks`)+`
15
+ `),c+=`
16
+ `);let l=o.filter(e=>!r.some(t=>t.id===e.id)&&!i.some(t=>t.id===e.id));l.length>0&&(c+=C.cyan.bold(`Recent tasks (for context):`)+`
17
+ `,l.slice(0,2).forEach(e=>{c+=C.cyan(` • Task ${e.id}: ${u(e.title,50)}`)+`
18
+ `}),l.length>2&&(c+=C.cyan(` • ... and ${l.length-2} more recent tasks`)+`
19
+ `)),console.log(E(c,{padding:{top:1,bottom:1,left:2,right:2},margin:{top:1,bottom:0},borderStyle:`round`,borderColor:P,title:C.cyan(`Context gathering`),titleAlignment:`center`}))}function Q(e,t=`cli`){if(t!==`cli`&&t!==`text`||!e||a())return;let n=v(e);n&&console.log(`\n${N.muted(n)}`)}function ne(e,t){!a()&&t?.length&&console.log(`\n${h(e,t)}`)}function re(e,t,n,r){console.log(C.red(`\n✗ Cannot move tasks from "${t}" to "${n}"`)),console.log(C.yellow(`
20
+ Cross-tag dependency conflicts detected:`)),e.length>0&&e.forEach(e=>{console.log(` • ${e.message}`)}),console.log(C.cyan(`
21
+ Resolution options:`)),console.log(` 1. Move with dependencies: taskgraph move --from=${r} --from-tag=${t} --to-tag=${n} --with-dependencies`),console.log(` 2. Break dependencies: taskgraph move --from=${r} --from-tag=${t} --to-tag=${n} --ignore-dependencies`),console.log(` 3. Validate and fix dependencies: taskgraph validate-dependencies && taskgraph fix-dependencies`),e.length>0&&console.log(` 4. Move dependencies first: taskgraph move --from=${e.map(e=>e.dependencyId).join(`,`)} --from-tag=${e[0].dependencyTag} --to-tag=${n}`)}function ie(e){return e===null?`null`:e===void 0?`undefined`:e===``?`(empty)`:o(e)||`unknown`}function ae(e,t,n){let r=ie(e),i=e||`unknown`,a=i;if(i.includes(`.`)){let e=i.split(`.`);e.length===2&&e[0]&&e[1]?a=e[0]:(console.log(C.yellow(`\n⚠ Warning: Unexpected taskId format "${i}". Using as-is for command suggestions.`)),a=i)}console.log(C.red(`\n✗ Cannot move subtask ${r} directly between tags`)),console.log(C.yellow(`
22
+ Subtask movement restriction:`)),console.log(` • Subtasks cannot be moved directly between tags`),console.log(` • They must be promoted to full tasks first`),console.log(` • Source tag: "${t}"`),console.log(` • Target tag: "${n}"`),console.log(C.cyan(`
23
+ Resolution options:`)),console.log(` 1. Promote subtask to full task: taskgraph remove-subtask --id=${r} --convert`),console.log(` 2. Then move the promoted task: taskgraph move --from=${a} --from-tag=${t} --to-tag=${n}`),console.log(` 3. Or move the parent task with all subtasks: taskgraph move --from=${a} --from-tag=${t} --to-tag=${n} --with-dependencies`)}function oe(e,t,n){console.log(C.red(`
24
+ ✗ Invalid tag combination`)),console.log(C.yellow(`
25
+ Error details:`)),console.log(` • Source tag: "${e}"`),console.log(` • Target tag: "${t}"`),console.log(` • Reason: ${n}`),console.log(C.cyan(`
26
+ Resolution options:`)),console.log(` 1. Use different tags for cross-tag moves`),console.log(` 2. Use within-tag move: taskgraph move --from=<id> --to=<id> --tag=${e}`),console.log(` 3. Check available tags: taskgraph tags`)}function se(e=`general`){let t={"before-move":[`Tip: Run "taskgraph validate-dependencies" to check for dependency issues before moving tasks`,`Tip: Use "taskgraph fix-dependencies" to automatically resolve common dependency problems`,`Tip: Consider using --with-dependencies flag to move dependent tasks together`],"after-error":[`Quick fix: Run "taskgraph validate-dependencies" to identify specific issues`,`Quick fix: Use "taskgraph fix-dependencies" to automatically resolve problems`,`Quick fix: Check "taskgraph show <id>" to see task dependencies before moving`],general:[`Tip: Use "taskgraph validate-dependencies" to check for dependency issues`,`Tip: Use "taskgraph fix-dependencies" to automatically resolve problems`,`Tip: Use "taskgraph show <id>" to view task dependencies`,`Tip: Use --with-dependencies flag to move dependent tasks together`]},n=t[e]||t.general;console.log(C.cyan(`
27
+ Helpful hints:`)),new Set(n).forEach(e=>{console.log(` ${e}`)})}var ce={id:`add-task`,version:`1.0.0`,description:`Generate a new task based on description`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`task-creation`,`generation`]},parameters:{prompt:{type:`string`,required:!0,description:`User's task description`},newTaskId:{type:`number`,required:!0,description:`ID for the new task`},existingTasks:{type:`array`,description:`List of existing tasks for context`},gatheredContext:{type:`string`,description:`Context gathered from codebase analysis`},contextFromArgs:{type:`string`,description:`Additional context from manual args`},priority:{type:`string`,default:`medium`,enum:[`high`,`medium`,`low`],description:`Task priority`},dependencies:{type:`array`,description:`Task dependency IDs`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are a helpful assistant that creates well-structured tasks for a software development project. Generate a single new task based on the user's description, adhering strictly to the provided JSON schema.
28
+
29
+ IMPORTANT: Your response MUST be a JSON object with the following structure (no wrapper property, just these fields directly):
30
+ {
31
+ "title": "string",
32
+ "description": "string",
33
+ "details": "string",
34
+ "testStrategy": "string",
35
+ "dependencies": [array of numbers]
36
+ }
37
+
38
+ Do not include any other top-level properties. Do NOT wrap this in any additional object.
39
+
40
+ Pay special attention to dependencies between tasks, ensuring the new task correctly references any tasks it depends on.
41
+
42
+ When determining dependencies for a new task, follow these principles:
43
+ 1. Select dependencies based on logical requirements - what must be completed before this task can begin.
44
+ 2. Prioritize task dependencies that are semantically related to the functionality being built.
45
+ 3. Consider both direct dependencies (immediately prerequisite) and indirect dependencies.
46
+ 4. Avoid adding unnecessary dependencies - only include tasks that are genuinely prerequisite.
47
+ 5. Consider the current status of tasks - prefer completed tasks as dependencies when possible.
48
+ 6. Pay special attention to foundation tasks (1-5) but don't automatically include them without reason.
49
+ 7. Recent tasks (higher ID numbers) may be more relevant for newer functionality.
50
+
51
+ The dependencies array should contain task IDs (numbers) of prerequisite tasks.{{#if useResearch}}
52
+
53
+ Research current best practices and technologies relevant to this task.{{/if}}`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
54
+
55
+ You have access to powerful codebase analysis tools. Before generating the task:
56
+
57
+ 1. Use the Glob tool to explore the project structure (e.g., "**/*.js", "**/*.json", "**/README.md")
58
+ 2. Use the Grep tool to search for existing implementations, patterns, and technologies
59
+ 3. Use the Read tool to examine key files like package.json, main entry points, and relevant source files
60
+ 4. Analyze the current implementation to understand what already exists
61
+
62
+ Based on your analysis:
63
+ - Identify existing components/features that relate to this new task
64
+ - Understand the technology stack, frameworks, and patterns in use
65
+ - Generate implementation details that align with the project's current architecture
66
+ - Reference specific files, functions, or patterns from the codebase in your details
67
+
68
+ Project Root: {{projectRoot}}
69
+
70
+ {{/if}}You are generating the details for Task #{{newTaskId}}. Based on the user's request: "{{prompt}}", create a comprehensive new task for a software development project.
71
+
72
+ {{gatheredContext}}
73
+
74
+ {{#if useResearch}}Research current best practices, technologies, and implementation patterns relevant to this task. {{/if}}Based on the information about existing tasks provided above, include appropriate dependencies in the "dependencies" array. Only include task IDs that this new task directly depends on.
75
+
76
+ Return your answer as a single JSON object matching the schema precisely:
77
+
78
+ {
79
+ "title": "Task title goes here",
80
+ "description": "A concise one or two sentence description of what the task involves",
81
+ "details": "Detailed implementation steps, considerations, code examples, or technical approach",
82
+ "testStrategy": "Specific steps to verify correct implementation and functionality",
83
+ "dependencies": [1, 3] // Example: IDs of tasks that must be completed before this task
84
+ }
85
+
86
+ Make sure the details and test strategy are comprehensive and specific{{#if useResearch}}, incorporating current best practices from your research{{/if}}. DO NOT include the task ID in the title.
87
+ {{#if contextFromArgs}}{{contextFromArgs}}{{/if}}`}}},le={id:`analyze-complexity`,version:`1.0.0`,description:`Analyze task complexity and generate expansion recommendations`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`analysis`,`complexity`,`expansion`,`recommendations`]},parameters:{tasks:{type:`array`,required:!0,description:`Array of tasks to analyze`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},threshold:{type:`number`,default:5,min:1,max:10,description:`Complexity threshold for expansion recommendation`},useResearch:{type:`boolean`,default:!1,description:`Use research mode for deeper analysis`},hasCodebaseAnalysis:{type:`boolean`,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an expert software architect and project manager analyzing task complexity. Your analysis should consider implementation effort, technical challenges, dependencies, and testing requirements.
88
+
89
+ IMPORTANT: For each task, provide an analysis object with ALL of the following fields:
90
+ - taskId: The ID of the task being analyzed (positive integer)
91
+ - taskTitle: The title of the task
92
+ - complexityScore: A score from 1-10 indicating complexity
93
+ - recommendedSubtasks: Number of subtasks recommended (non-negative integer; 0 if no expansion needed)
94
+ - expansionPrompt: A prompt to guide subtask generation
95
+ - reasoning: Your reasoning for the complexity score
96
+
97
+ Your response MUST be a JSON object with a single "complexityAnalysis" property containing an array of these analysis objects. You may optionally include a "metadata" object, but no other top-level properties.`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
98
+
99
+ You have access to powerful codebase analysis tools. Before analyzing task complexity:
100
+
101
+ 1. Use the Glob tool to explore the project structure and understand the codebase size
102
+ 2. Use the Grep tool to search for existing implementations related to each task
103
+ 3. Use the Read tool to examine key files that would be affected by these tasks
104
+ 4. Understand the current implementation state, patterns used, and technical debt
105
+
106
+ Based on your codebase analysis:
107
+ - Assess complexity based on ACTUAL code that needs to be modified/created
108
+ - Consider existing abstractions and patterns that could simplify implementation
109
+ - Identify tasks that require refactoring vs. greenfield development
110
+ - Factor in dependencies between existing code and new features
111
+ - Provide more accurate subtask recommendations based on real code structure
112
+
113
+ Project Root: {{projectRoot}}
114
+
115
+ {{/if}}Analyze the following tasks to determine their complexity (1-10 scale) and recommend the number of subtasks for expansion. Provide a brief reasoning and an initial expansion prompt for each.{{#if useResearch}} Consider current best practices, common implementation patterns, and industry standards in your analysis.{{/if}}
116
+
117
+ Tasks:
118
+ {{{json tasks}}}
119
+ {{#if gatheredContext}}
120
+
121
+ # Project Context
122
+
123
+ {{gatheredContext}}
124
+ {{/if}}
125
+ `}}},ue={id:`expand-task`,version:`1.0.0`,description:`Break down a task into detailed subtasks`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`expansion`,`subtasks`,`breakdown`]},parameters:{subtaskCount:{type:`number`,required:!0,description:`Number of subtasks to generate`},task:{type:`object`,required:!0,description:`The task to expand`},nextSubtaskId:{type:`number`,required:!0,description:`Starting ID for new subtasks`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},expansionPrompt:{type:`string`,required:!1,description:`Expansion prompt from complexity report`},additionalContext:{type:`string`,required:!1,default:``,description:`Additional context for task expansion`},complexityReasoningContext:{type:`string`,required:!1,default:``,description:`Complexity analysis reasoning context`},gatheredContext:{type:`string`,required:!1,default:``,description:`Gathered project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{"complexity-report":{condition:`expansionPrompt`,system:`You are an AI assistant helping with task breakdown. Generate {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} subtasks based on the provided prompt and context.
126
+
127
+ IMPORTANT: Your response MUST be a JSON object with a "subtasks" property containing an array of subtask objects. Each subtask must include ALL of the following fields:
128
+ - id: MUST be sequential integers starting EXACTLY from {{nextSubtaskId}}. First subtask id={{nextSubtaskId}}, second id={{nextSubtaskId}}+1, etc. DO NOT use any other numbering pattern!
129
+ - title: A clear, actionable title (5-200 characters)
130
+ - description: A detailed description (minimum 10 characters)
131
+ - dependencies: An array of task IDs this subtask depends on (can be empty [])
132
+ - details: Implementation details (minimum 20 characters)
133
+ - status: Must be "pending" for new subtasks
134
+ - testStrategy: Testing approach (can be null)
135
+
136
+ You may optionally include a "metadata" object. Do not include any other top-level properties.`,user:`Break down the following task:
137
+
138
+ Parent Task:
139
+ ID: {{task.id}}
140
+ Title: {{task.title}}
141
+ Description: {{task.description}}
142
+ Current details: {{#if task.details}}{{task.details}}{{else}}None{{/if}}
143
+
144
+ {{expansionPrompt}}{{#if additionalContext}}
145
+
146
+ {{additionalContext}}{{/if}}{{#if complexityReasoningContext}}
147
+
148
+ {{complexityReasoningContext}}{{/if}}{{#if gatheredContext}}
149
+
150
+ # Project Context
151
+
152
+ {{gatheredContext}}{{/if}}
153
+
154
+ Generate {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} subtasks. CRITICAL: Use sequential IDs starting from {{nextSubtaskId}} (first={{nextSubtaskId}}, second={{nextSubtaskId}}+1, etc.).`},research:{condition:`useResearch === true && !expansionPrompt`,system:`You are an AI assistant with research capabilities analyzing and breaking down software development tasks.
155
+
156
+ IMPORTANT: Your response MUST be a JSON object with a "subtasks" property containing an array of subtask objects. Each subtask must include ALL of the following fields:
157
+ - id: MUST be sequential integers starting EXACTLY from {{nextSubtaskId}}. First subtask id={{nextSubtaskId}}, second id={{nextSubtaskId}}+1, etc. DO NOT use any other numbering pattern!
158
+ - title: A clear, actionable title (5-200 characters)
159
+ - description: A detailed description (minimum 10 characters)
160
+ - dependencies: An array of task IDs this subtask depends on (can be empty [])
161
+ - details: Implementation details (minimum 20 characters)
162
+ - status: Must be "pending" for new subtasks
163
+ - testStrategy: Testing approach (can be null)
164
+
165
+ You may optionally include a "metadata" object. Do not include any other top-level properties.`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
166
+
167
+ You have access to powerful codebase analysis tools. Before generating subtasks:
168
+
169
+ 1. Use the Glob tool to explore relevant files for this task (e.g., "**/*.js", "src/**/*.ts")
170
+ 2. Use the Grep tool to search for existing implementations related to this task
171
+ 3. Use the Read tool to examine files that would be affected by this task
172
+ 4. Understand the current implementation state and patterns used
173
+
174
+ Based on your analysis:
175
+ - Identify existing code that relates to this task
176
+ - Understand patterns and conventions to follow
177
+ - Generate subtasks that integrate smoothly with existing code
178
+ - Ensure subtasks are specific and actionable based on the actual codebase
179
+
180
+ Project Root: {{projectRoot}}
181
+
182
+ {{/if}}Analyze the following task and break it down into {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} specific subtasks. Each subtask should be actionable and well-defined.
183
+
184
+ Parent Task:
185
+ ID: {{task.id}}
186
+ Title: {{task.title}}
187
+ Description: {{task.description}}
188
+ Current details: {{#if task.details}}{{task.details}}{{else}}None{{/if}}{{#if additionalContext}}
189
+ Consider this context: {{additionalContext}}{{/if}}{{#if complexityReasoningContext}}
190
+ Complexity Analysis Reasoning: {{complexityReasoningContext}}{{/if}}{{#if gatheredContext}}
191
+
192
+ # Project Context
193
+
194
+ {{gatheredContext}}{{/if}}
195
+
196
+ CRITICAL: You MUST use sequential IDs starting from {{nextSubtaskId}}. The first subtask MUST have id={{nextSubtaskId}}, the second MUST have id={{nextSubtaskId}}+1, and so on. Do NOT use parent task ID in subtask numbering!`},default:{system:`You are an AI assistant helping with task breakdown for software development. Break down high-level tasks into specific, actionable subtasks that can be implemented sequentially.
197
+
198
+ IMPORTANT: Your response MUST be a JSON object with a "subtasks" property containing an array of subtask objects. Each subtask must include ALL of the following fields:
199
+ - id: MUST be sequential integers starting EXACTLY from {{nextSubtaskId}}. First subtask id={{nextSubtaskId}}, second id={{nextSubtaskId}}+1, etc. DO NOT use any other numbering pattern!
200
+ - title: A clear, actionable title (5-200 characters)
201
+ - description: A detailed description (minimum 10 characters)
202
+ - dependencies: An array of task IDs this subtask depends on (can be empty [])
203
+ - details: Implementation details (minimum 20 characters)
204
+ - status: Must be "pending" for new subtasks
205
+ - testStrategy: Testing approach (can be null)
206
+
207
+ You may optionally include a "metadata" object. Do not include any other top-level properties.`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
208
+
209
+ You have access to powerful codebase analysis tools. Before generating subtasks:
210
+
211
+ 1. Use the Glob tool to explore relevant files for this task (e.g., "**/*.js", "src/**/*.ts")
212
+ 2. Use the Grep tool to search for existing implementations related to this task
213
+ 3. Use the Read tool to examine files that would be affected by this task
214
+ 4. Understand the current implementation state and patterns used
215
+
216
+ Based on your analysis:
217
+ - Identify existing code that relates to this task
218
+ - Understand patterns and conventions to follow
219
+ - Generate subtasks that integrate smoothly with existing code
220
+ - Ensure subtasks are specific and actionable based on the actual codebase
221
+
222
+ Project Root: {{projectRoot}}
223
+
224
+ {{/if}}Break down this task into {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} specific subtasks:
225
+
226
+ Task ID: {{task.id}}
227
+ Title: {{task.title}}
228
+ Description: {{task.description}}
229
+ Current details: {{#if task.details}}{{task.details}}{{else}}None{{/if}}{{#if additionalContext}}
230
+ Additional context: {{additionalContext}}{{/if}}{{#if complexityReasoningContext}}
231
+ Complexity Analysis Reasoning: {{complexityReasoningContext}}{{/if}}{{#if gatheredContext}}
232
+
233
+ # Project Context
234
+
235
+ {{gatheredContext}}{{/if}}
236
+
237
+ CRITICAL: You MUST use sequential IDs starting from {{nextSubtaskId}}. The first subtask MUST have id={{nextSubtaskId}}, the second MUST have id={{nextSubtaskId}}+1, and so on. Do NOT use parent task ID in subtask numbering!`}}},de={id:`parse-prd`,version:`1.0.0`,description:`Parse a Product Requirements Document into structured tasks`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`prd`,`parsing`,`initialization`]},parameters:{numTasks:{type:`number`,required:!0,description:`Target number of tasks to generate`},nextId:{type:`number`,required:!0,description:`Starting ID for tasks`},research:{type:`boolean`,default:!1,description:`Enable research mode for latest best practices`},prdContent:{type:`string`,required:!0,description:`Content of the PRD file`},prdPath:{type:`string`,required:!0,description:`Path to the PRD file`},defaultTaskPriority:{type:`string`,required:!1,default:`medium`,enum:[`high`,`medium`,`low`],description:`Default priority for generated tasks`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant specialized in analyzing Product Requirements Documents (PRDs) and generating a structured, logically ordered, dependency-aware and sequenced list of development tasks in JSON format.{{#if research}}
238
+ Before breaking down the PRD into tasks, you will:
239
+ 1. Research and analyze the latest technologies, libraries, frameworks, and best practices that would be appropriate for this project
240
+ 2. Identify any potential technical challenges, security concerns, or scalability issues not explicitly mentioned in the PRD without discarding any explicit requirements or going overboard with complexity -- always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches
241
+ 3. Consider current industry standards and evolving trends relevant to this project (this step aims to solve LLM hallucinations and out of date information due to training data cutoff dates)
242
+ 4. Evaluate alternative implementation approaches and recommend the most efficient path
243
+ 5. Include specific library versions, helpful APIs, and concrete implementation guidance based on your research
244
+ 6. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches
245
+
246
+ Your task breakdown should incorporate this research, resulting in more detailed implementation guidance, more accurate dependency mapping, and more precise technology recommendations than would be possible from the PRD text alone, while maintaining all explicit requirements and best practices and all details and nuances of the PRD.{{/if}}
247
+
248
+ Analyze the provided PRD content and generate {{#if (gt numTasks 0)}}approximately {{numTasks}}{{else}}an appropriate number of{{/if}} top-level development tasks. If the complexity or the level of detail of the PRD is high, generate more tasks relative to the complexity of the PRD
249
+ Each task should represent a logical unit of work needed to implement the requirements and focus on the most direct and effective way to implement the requirements without unnecessary complexity or overengineering. Include pseudo-code, implementation details, and test strategy for each task. Find the most up to date information to implement each task.
250
+ Assign sequential IDs starting from {{nextId}}. Infer title, description, details, and test strategy for each task based *only* on the PRD content.
251
+ Set status to 'pending', dependencies to an empty array [], and priority to '{{defaultTaskPriority}}' initially for all tasks.
252
+ Generate a response containing a single key "tasks", where the value is an array of task objects adhering to the provided schema.
253
+
254
+ Each task should follow this JSON structure:
255
+ {
256
+ "id": number,
257
+ "title": string,
258
+ "description": string,
259
+ "status": "pending",
260
+ "dependencies": number[] (IDs of tasks this depends on),
261
+ "priority": "high" | "medium" | "low",
262
+ "details": string (implementation details),
263
+ "testStrategy": string (validation approach)
264
+ }
265
+
266
+ Guidelines:
267
+ 1. {{#if (gt numTasks 0)}}Unless complexity warrants otherwise{{else}}Depending on the complexity{{/if}}, create {{#if (gt numTasks 0)}}exactly {{numTasks}}{{else}}an appropriate number of{{/if}} tasks, numbered sequentially starting from {{nextId}}
268
+ 2. Each task should be atomic and focused on a single responsibility following the most up to date best practices and standards
269
+ 3. Order tasks logically - consider dependencies and implementation sequence
270
+ 4. Early tasks should focus on setup, core functionality first, then advanced features
271
+ 5. Include clear validation/testing approach for each task
272
+ 6. Set appropriate dependency IDs (a task can only depend on tasks with lower IDs, potentially including existing tasks with IDs less than {{nextId}} if applicable)
273
+ 7. Assign priority (high/medium/low) based on criticality and dependency order
274
+ 8. Include detailed implementation guidance in the "details" field{{#if research}}, with specific libraries and version recommendations based on your research{{/if}}
275
+ 9. If the PRD contains specific requirements for libraries, database schemas, frameworks, tech stacks, or any other implementation details, STRICTLY ADHERE to these requirements in your task breakdown and do not discard them under any circumstance
276
+ 10. Focus on filling in any gaps left by the PRD or areas that aren't fully specified, while preserving all explicit requirements
277
+ 11. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches{{#if research}}
278
+ 12. For each task, include specific, actionable guidance based on current industry standards and best practices discovered through research{{/if}}`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
279
+
280
+ You have access to powerful codebase analysis tools. Before generating tasks:
281
+
282
+ 1. Use the Glob tool to explore the project structure (e.g., "**/*.js", "**/*.json", "**/README.md")
283
+ 2. Use the Grep tool to search for existing implementations, patterns, and technologies
284
+ 3. Use the Read tool to examine key files like package.json, README.md, and main entry points
285
+ 4. Analyze the current state of implementation to understand what already exists
286
+
287
+ Based on your analysis:
288
+ - Identify what components/features are already implemented
289
+ - Understand the technology stack, frameworks, and patterns in use
290
+ - Generate tasks that build upon the existing codebase rather than duplicating work
291
+ - Ensure tasks align with the project's current architecture and conventions
292
+
293
+ Project Root: {{projectRoot}}
294
+
295
+ {{/if}}Here's the Product Requirements Document (PRD) to break down into {{#if (gt numTasks 0)}}approximately {{numTasks}}{{else}}an appropriate number of{{/if}} tasks, starting IDs from {{nextId}}:{{#if research}}
296
+
297
+ Remember to thoroughly research current best practices and technologies before task breakdown to provide specific, actionable implementation details.{{/if}}
298
+
299
+ {{prdContent}}
300
+
301
+ IMPORTANT: Your response must be a JSON object with a "tasks" property containing an array of task objects. You may optionally include a "metadata" object. Do not include any other properties.`}}},fe={id:`research`,version:`1.0.0`,description:`Perform AI-powered research with project context`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`research`,`context-aware`,`information-gathering`]},parameters:{query:{type:`string`,required:!0,description:`Research query`},gatheredContext:{type:`string`,default:``,description:`Gathered project context`},detailLevel:{type:`string`,enum:[`low`,`medium`,`high`],default:`medium`,description:`Level of detail for the response`},projectInfo:{type:`object`,description:`Project information`,properties:{root:{type:`string`,description:`Project root path`},taskCount:{type:`number`,description:`Number of related tasks`},fileCount:{type:`number`,description:`Number of related files`}}}},prompts:{default:{system:`You are an expert AI research assistant helping with a software development project. You have access to project context including tasks, files, and project structure.
302
+
303
+ Your role is to provide comprehensive, accurate, and actionable research responses based on the user's query and the provided project context.
304
+ {{#if (eq detailLevel "low")}}
305
+ **Response Style: Concise & Direct**
306
+ - Provide brief, focused answers (2-4 paragraphs maximum)
307
+ - Focus on the most essential information
308
+ - Use bullet points for key takeaways
309
+ - Avoid lengthy explanations unless critical
310
+ - Skip pleasantries, introductions, and conclusions
311
+ - No phrases like "Based on your project context" or "I'll provide guidance"
312
+ - No summary outros or alignment statements
313
+ - Get straight to the actionable information
314
+ - Use simple, direct language - users want info, not explanation{{/if}}{{#if (eq detailLevel "medium")}}
315
+ **Response Style: Balanced & Comprehensive**
316
+ - Provide thorough but well-structured responses (4-8 paragraphs)
317
+ - Include relevant examples and explanations
318
+ - Balance depth with readability
319
+ - Use headings and bullet points for organization{{/if}}{{#if (eq detailLevel "high")}}
320
+ **Response Style: Detailed & Exhaustive**
321
+ - Provide comprehensive, in-depth analysis (8+ paragraphs)
322
+ - Include multiple perspectives and approaches
323
+ - Provide detailed examples, code snippets, and step-by-step guidance
324
+ - Cover edge cases and potential pitfalls
325
+ - Use clear structure with headings, subheadings, and lists{{/if}}
326
+
327
+ **Guidelines:**
328
+ - Always consider the project context when formulating responses
329
+ - Reference specific tasks, files, or project elements when relevant
330
+ - Provide actionable insights that can be applied to the project
331
+ - If the query relates to existing project tasks, suggest how the research applies to those tasks
332
+ - Use markdown formatting for better readability
333
+ - Be precise and avoid speculation unless clearly marked as such
334
+ {{#if (eq detailLevel "low")}}
335
+ **For LOW detail level specifically:**
336
+ - Start immediately with the core information
337
+ - No introductory phrases or context acknowledgments
338
+ - No concluding summaries or project alignment statements
339
+ - Focus purely on facts, steps, and actionable items{{/if}}`,user:`# Research Query
340
+
341
+ {{query}}
342
+ {{#if gatheredContext}}
343
+
344
+ # Project Context
345
+
346
+ {{gatheredContext}}
347
+ {{/if}}
348
+
349
+ # Instructions
350
+
351
+ Please research and provide a {{detailLevel}}-detail response to the query above. Consider the project context provided and make your response as relevant and actionable as possible for this specific project.`}}},pe={id:`update-subtask`,version:`1.0.0`,description:`Append information to a subtask by generating only new content`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`subtask`,`append`,`logging`]},parameters:{parentTask:{type:`object`,required:!0,description:`The parent task context`},prevSubtask:{type:`object`,required:!1,description:`The previous subtask if any`},nextSubtask:{type:`object`,required:!1,description:`The next subtask if any`},currentDetails:{type:`string`,required:!0,default:`(No existing details)`,description:`Current subtask details`},updatePrompt:{type:`string`,required:!0,description:`User request for what to add`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update a subtask. You will be provided with the subtask's existing details, context about its parent and sibling tasks, and a user request string.{{#if useResearch}} You have access to current best practices and latest technical information to provide research-backed updates.{{/if}}
352
+
353
+ Your Goal: Based *only* on the user's request and all the provided context (including existing details if relevant to the request), GENERATE the new text content that should be added to the subtask's details.
354
+ Focus *only* on generating the substance of the update.
355
+
356
+ Output Requirements:
357
+ 1. Return *only* the newly generated text content as a plain string. Do NOT return a JSON object or any other structured data.
358
+ 2. Your string response should NOT include any of the subtask's original details, unless the user's request explicitly asks to rephrase, summarize, or directly modify existing text.
359
+ 3. Do NOT include any timestamps, XML-like tags, markdown, or any other special formatting in your string response.
360
+ 4. Ensure the generated text is concise yet complete for the update based on the user request. Avoid conversational fillers or explanations about what you are doing (e.g., do not start with "Okay, here's the update...").{{#if useResearch}}
361
+ 5. Include specific libraries, versions, and current best practices relevant to the subtask implementation.
362
+ 6. Provide research-backed technical recommendations and proven approaches.{{/if}}`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
363
+
364
+ You have access to powerful codebase analysis tools. Before generating the subtask update:
365
+
366
+ 1. Use the Glob tool to explore the project structure (e.g., "**/*.js", "**/*.json", "**/README.md")
367
+ 2. Use the Grep tool to search for existing implementations, patterns, and technologies
368
+ 3. Use the Read tool to examine relevant files and understand current implementation
369
+ 4. Analyze the current codebase to inform your subtask update
370
+
371
+ Based on your analysis:
372
+ - Include specific file references, code patterns, or implementation details
373
+ - Ensure suggestions align with the project's current architecture
374
+ - Reference existing components or patterns when relevant
375
+ - Make implementation notes specific to the codebase structure
376
+
377
+ Project Root: {{projectRoot}}
378
+
379
+ {{/if}}Task Context:
380
+
381
+ Parent Task: {{{json parentTask}}}
382
+ {{#if prevSubtask}}Previous Subtask: {{{json prevSubtask}}}
383
+ {{/if}}{{#if nextSubtask}}Next Subtask: {{{json nextSubtask}}}
384
+ {{/if}}Current Subtask Details (for context only):
385
+ {{currentDetails}}
386
+
387
+ User Request: "{{updatePrompt}}"
388
+
389
+ {{#if useResearch}}Research and incorporate current best practices, latest stable versions, and proven approaches into your update. {{/if}}Based on the User Request and all the Task Context (including current subtask details provided above), what is the new information or text that should be appended to this subtask's details? Return ONLY this new text as a plain string.{{#if useResearch}} Include specific technical recommendations based on current industry standards.{{/if}}
390
+ {{#if gatheredContext}}
391
+
392
+ # Additional Project Context
393
+
394
+ {{gatheredContext}}
395
+ {{/if}}`}}},me={id:`update-task`,version:`1.0.0`,description:`Update a single task with new information, supporting full updates and append mode`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`single-task`,`modification`,`append`]},parameters:{task:{type:`object`,required:!0,description:`The task to update`},taskJson:{type:`string`,required:!0,description:`JSON string representation of the task`},updatePrompt:{type:`string`,required:!0,description:`Description of changes to apply`},appendMode:{type:`boolean`,default:!1,description:`Whether to append to details or do full update`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},currentDetails:{type:`string`,default:`(No existing details)`,description:`Current task details for context`},gatheredContext:{type:`string`,default:``,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update a software development task based on new context.{{#if useResearch}} You have access to current best practices and latest technical information to provide research-backed updates.{{/if}}
396
+ You will be given a task and a prompt describing changes or new implementation details.
397
+ Your job is to update the task to reflect these changes, while preserving its basic structure.
398
+
399
+ Guidelines:
400
+ 1. VERY IMPORTANT: NEVER change the title of the task - keep it exactly as is
401
+ 2. Maintain the same ID, status, and dependencies unless specifically mentioned in the prompt{{#if useResearch}}
402
+ 3. Research and update the description, details, and test strategy with current best practices
403
+ 4. Include specific versions, libraries, and approaches that are current and well-tested{{/if}}{{#if (not useResearch)}}
404
+ 3. Update the description, details, and test strategy to reflect the new information
405
+ 4. Do not change anything unnecessarily - just adapt what needs to change based on the prompt{{/if}}
406
+ 5. Return the complete updated task
407
+ 6. VERY IMPORTANT: Preserve all subtasks marked as "done" or "completed" - do not modify their content
408
+ 7. For tasks with completed subtasks, build upon what has already been done rather than rewriting everything
409
+ 8. If an existing completed subtask needs to be changed/undone based on the new context, DO NOT modify it directly
410
+ 9. Instead, add a new subtask that clearly indicates what needs to be changed or replaced
411
+ 10. Use the existence of completed subtasks as an opportunity to make new subtasks more specific and targeted
412
+ 11. Ensure any new subtasks have unique IDs that don't conflict with existing ones
413
+ 12. CRITICAL: For subtask IDs, use ONLY numeric values (1, 2, 3, etc.) NOT strings ("1", "2", "3")
414
+ 13. CRITICAL: Subtask IDs should start from 1 and increment sequentially (1, 2, 3...) - do NOT use parent task ID as prefix{{#if useResearch}}
415
+ 14. Include links to documentation or resources where helpful
416
+ 15. Focus on practical, implementable solutions using current technologies{{/if}}
417
+
418
+ The changes described in the prompt should be thoughtfully applied to make the task more accurate and actionable.`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
419
+
420
+ You have access to powerful codebase analysis tools. Before updating the task:
421
+
422
+ 1. Use the Glob tool to explore the project structure (e.g., "**/*.js", "**/*.json", "**/README.md")
423
+ 2. Use the Grep tool to search for existing implementations, patterns, and technologies
424
+ 3. Use the Read tool to examine relevant files and understand current implementation
425
+ 4. Analyze how the task changes relate to the existing codebase
426
+
427
+ Based on your analysis:
428
+ - Update task details to reference specific files, functions, or patterns from the codebase
429
+ - Ensure implementation details align with the project's current architecture
430
+ - Include specific code examples or file references where appropriate
431
+ - Consider how changes impact existing components
432
+
433
+ Project Root: {{projectRoot}}
434
+
435
+ {{/if}}Here is the task to update{{#if useResearch}} with research-backed information{{/if}}:
436
+ {{{taskJson}}}
437
+
438
+ Please {{#if useResearch}}research and {{/if}}update this task based on the following {{#if useResearch}}context:
439
+ {{updatePrompt}}
440
+
441
+ Incorporate current best practices, latest stable versions, and proven approaches.{{/if}}{{#if (not useResearch)}}new context:
442
+ {{updatePrompt}}{{/if}}
443
+
444
+ IMPORTANT: {{#if useResearch}}Preserve any subtasks marked as "done" or "completed".{{/if}}{{#if (not useResearch)}}In the task JSON above, any subtasks with "status": "done" or "status": "completed" should be preserved exactly as is. Build your changes around these completed items.{{/if}}
445
+ {{#if gatheredContext}}
446
+
447
+ # Project Context
448
+
449
+ {{gatheredContext}}
450
+ {{/if}}
451
+
452
+ Return the complete updated task{{#if useResearch}} with research-backed improvements{{/if}}.
453
+
454
+ IMPORTANT: Your response must be a JSON object with a single property named "task" containing the updated task object.`},append:{condition:`appendMode === true`,system:`You are an AI assistant helping to append additional information to a software development task. You will be provided with the task's existing details, context, and a user request string.
455
+
456
+ Your Goal: Based *only* on the user's request and all the provided context (including existing details if relevant to the request), GENERATE the new text content that should be added to the task's details.
457
+ Focus *only* on generating the substance of the update.
458
+
459
+ Output Requirements:
460
+ 1. Return *only* the newly generated text content as a plain string. Do NOT return a JSON object or any other structured data.
461
+ 2. Your string response should NOT include any of the task's original details, unless the user's request explicitly asks to rephrase, summarize, or directly modify existing text.
462
+ 3. Do NOT include any timestamps, XML-like tags, markdown, or any other special formatting in your string response.
463
+ 4. Ensure the generated text is concise yet complete for the update based on the user request. Avoid conversational fillers or explanations about what you are doing (e.g., do not start with "Okay, here's the update...").`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
464
+
465
+ You have access to powerful codebase analysis tools. Before generating the task update:
466
+
467
+ 1. Use the Glob tool to explore the project structure (e.g., "**/*.js", "**/*.json", "**/README.md")
468
+ 2. Use the Grep tool to search for existing implementations, patterns, and technologies
469
+ 3. Use the Read tool to examine relevant files and understand current implementation
470
+ 4. Analyze the current codebase to inform your update
471
+
472
+ Based on your analysis:
473
+ - Include specific file references, code patterns, or implementation details
474
+ - Ensure suggestions align with the project's current architecture
475
+ - Reference existing components or patterns when relevant
476
+
477
+ Project Root: {{projectRoot}}
478
+
479
+ {{/if}}Task Context:
480
+
481
+ Task: {{{json task}}}
482
+ Current Task Details (for context only):
483
+ {{currentDetails}}
484
+
485
+ User Request: "{{updatePrompt}}"
486
+
487
+ Based on the User Request and all the Task Context (including current task details provided above), what is the new information or text that should be appended to this task's details? Return this new text as a plain string.
488
+ {{#if gatheredContext}}
489
+
490
+ # Additional Project Context
491
+
492
+ {{gatheredContext}}
493
+ {{/if}}`}}},he={id:`update-tasks`,version:`1.0.0`,description:`Update multiple tasks based on new context or changes`,metadata:{author:`system`,created:`2024-01-01T00:00:00Z`,updated:`2024-01-01T00:00:00Z`,tags:[`update`,`bulk`,`context-change`]},parameters:{tasks:{type:`array`,required:!0,description:`Array of tasks to update`},updatePrompt:{type:`string`,required:!0,description:`Description of changes to apply`},useResearch:{type:`boolean`,default:!1,description:`Use research mode`},projectContext:{type:`string`,description:`Additional project context`},hasCodebaseAnalysis:{type:`boolean`,required:!1,default:!1,description:`Whether codebase analysis is available`},projectRoot:{type:`string`,required:!1,default:``,description:`Project root path for context`}},prompts:{default:{system:`You are an AI assistant helping to update software development tasks based on new context.
494
+ You will be given a set of tasks and a prompt describing changes or new implementation details.
495
+ Your job is to update the tasks to reflect these changes, while preserving their basic structure.
496
+
497
+ Guidelines:
498
+ 1. Maintain the same IDs, statuses, and dependencies unless specifically mentioned in the prompt
499
+ 2. Update titles, descriptions, details, and test strategies to reflect the new information
500
+ 3. Do not change anything unnecessarily - just adapt what needs to change based on the prompt
501
+ 4. Return ALL the tasks in order, not just the modified ones
502
+ 5. VERY IMPORTANT: Preserve all subtasks marked as "done" or "completed" - do not modify their content
503
+ 6. For tasks with completed subtasks, build upon what has already been done rather than rewriting everything
504
+ 7. If an existing completed subtask needs to be changed/undone based on the new context, DO NOT modify it directly
505
+ 8. Instead, add a new subtask that clearly indicates what needs to be changed or replaced
506
+ 9. Use the existence of completed subtasks as an opportunity to make new subtasks more specific and targeted`,user:`{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required
507
+
508
+ You have access to powerful codebase analysis tools. Before updating tasks:
509
+
510
+ 1. Use the Glob tool to explore the project structure (e.g., "**/*.js", "**/*.json", "**/README.md")
511
+ 2. Use the Grep tool to search for existing implementations, patterns, and technologies
512
+ 3. Use the Read tool to examine relevant files and understand current implementation
513
+ 4. Analyze how the new changes relate to the existing codebase
514
+
515
+ Based on your analysis:
516
+ - Update task details to reference specific files, functions, or patterns from the codebase
517
+ - Ensure implementation details align with the project's current architecture
518
+ - Include specific code examples or file references where appropriate
519
+ - Consider how changes impact existing components
520
+
521
+ Project Root: {{projectRoot}}
522
+
523
+ {{/if}}Here are the tasks to update:
524
+ {{{json tasks}}}
525
+
526
+ Please update these tasks based on the following new context:
527
+ {{updatePrompt}}
528
+
529
+ IMPORTANT: In the tasks above, any subtasks with "status": "done" or "status": "completed" should be preserved exactly as is. Build your changes around these completed items.{{#if projectContext}}
530
+
531
+ # Project Context
532
+
533
+ {{projectContext}}{{/if}}
534
+
535
+ IMPORTANT: Your response must be a JSON object with a single property named "tasks" containing the updated array of tasks.`}}},ge={$schema:`http://json-schema.org/draft-07/schema#`,$id:`https://github.com/stephennmiller/taskgraph-ai/blob/main/src/prompts/schemas/prompt-template.schema.json`,version:`1.0.0`,title:`TaskGraph Prompt Template`,description:`Schema for TaskGraph prompt template files`,type:`object`,required:[`id`,`version`,`description`,`prompts`],properties:{id:{type:`string`,pattern:`^[a-z0-9-]+$`,description:`Unique identifier for the prompt template`},version:{type:`string`,pattern:`^\\d+\\.\\d+\\.\\d+$`,description:`Semantic version of the prompt template`},description:{type:`string`,minLength:1,description:`Brief description of what this prompt does`},metadata:{$ref:`#/definitions/metadata`},parameters:{type:`object`,additionalProperties:{$ref:`#/definitions/parameter`}},prompts:{type:`object`,properties:{default:{$ref:`#/definitions/promptVariant`}},additionalProperties:{$ref:`#/definitions/conditionalPromptVariant`}}},definitions:{parameter:{type:`object`,required:[`type`,`description`],properties:{type:{type:`string`,enum:[`string`,`number`,`boolean`,`array`,`object`]},description:{type:`string`,minLength:1},required:{type:`boolean`,default:!1},default:{description:`Default value for optional parameters`},enum:{type:`array`,description:`Valid values for string parameters`},pattern:{type:`string`,description:`Regular expression pattern for string validation`},minimum:{type:`number`,description:`Minimum value for number parameters`},maximum:{type:`number`,description:`Maximum value for number parameters`}}},promptVariant:{type:`object`,required:[`system`,`user`],properties:{system:{type:`string`,minLength:1},user:{type:`string`,minLength:1}}},conditionalPromptVariant:{allOf:[{$ref:`#/definitions/promptVariant`},{type:`object`,properties:{condition:{type:`string`,description:`JavaScript expression for variant selection`}}}]},metadata:{type:`object`,properties:{author:{type:`string`},created:{type:`string`,format:`date-time`},updated:{type:`string`,format:`date-time`},tags:{type:`array`,items:{type:`string`}},category:{type:`string`,enum:[`task`,`analysis`,`research`,`parsing`,`update`,`expansion`]}}}}},_e=class{constructor(){this.prompts=/* @__PURE__ */ new Map([[`analyze-complexity`,le],[`expand-task`,ue],[`add-task`,ce],[`research`,fe],[`parse-prd`,de],[`update-task`,me],[`update-tasks`,he],[`update-subtask`,pe]]),this.cache=/* @__PURE__ */ new Map,this.setupValidation()}setupValidation(){this.ajv=new A({allErrors:!0,strict:!1}),j(this.ajv);try{this.validatePrompt=this.ajv.compile(ge),t(`debug`,`✓ JSON schema validation enabled`)}catch(e){t(`warn`,`⚠ Schema validation disabled: ${e.message}`),this.validatePrompt=()=>!0}}loadPrompt(e,n={},r=null){try{let t=`${e}-${JSON.stringify(n)}-${r}`;if(this.cache.has(t))return this.cache.get(t);let i=this.loadTemplate(e);this.validatePrompt&&this.validatePrompt!==!0&&this.validateParameters(i,n);let a=r?{...i.prompts[r],name:r}:this.selectVariant(i,n),o={systemPrompt:this.renderTemplate(a.system,n),userPrompt:this.renderTemplate(a.user,n),metadata:{templateId:i.id,version:i.version,variant:a.name||`default`,parameters:n}};return this.cache.set(t,o),o}catch(n){throw t(`error`,`Failed to load prompt ${e}: ${n.message}`),n}}loadTemplate(e){let t=this.prompts.get(e);if(!t)throw Error(`Prompt template '${e}' not found`);if(this.validatePrompt&&this.validatePrompt!==!0){if(!this.validatePrompt(t)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}}else if(!t.id||!t.prompts||!t.prompts.default)throw Error(`Invalid template structure: missing required fields (id, prompts.default)`);return t}validateParameters(e,t){if(!e.parameters)return;let n=[];for(let[r,i]of Object.entries(e.parameters)){let e=t[r];i.required&&e===void 0?n.push(`Required parameter '${r}' missing`):e!==void 0&&(this.validateParameterType(e,i.type)||n.push(`Parameter '${r}' expected ${i.type}, got ${typeof e}`),i.enum&&!i.enum.includes(e)&&n.push(`Parameter '${r}' must be one of: ${i.enum.join(`, `)}`),i.pattern&&typeof e==`string`&&(new RegExp(i.pattern).test(e)||n.push(`Parameter '${r}' does not match required pattern: ${i.pattern}`)),typeof e==`number`&&(i.minimum!==void 0&&e<i.minimum&&n.push(`Parameter '${r}' must be >= ${i.minimum}`),i.maximum!==void 0&&e>i.maximum&&n.push(`Parameter '${r}' must be <= ${i.maximum}`)))}if(n.length>0)throw Error(`Parameter validation failed: ${n.join(`; `)}`)}validateParameterType(e,t){switch(t){case`string`:return typeof e==`string`;case`number`:return typeof e==`number`;case`boolean`:return typeof e==`boolean`;case`array`:return Array.isArray(e);case`object`:return typeof e==`object`&&!!e&&!Array.isArray(e);default:return!0}}selectVariant(e,t){for(let[n,r]of Object.entries(e.prompts))if(n!=="default"&&r.condition&&this.evaluateCondition(r.condition,t))return{...r,name:n};return{...e.prompts.default,name:`default`}}evaluateCondition(e,n){try{let t={...n};return Function(...Object.keys(t),`return ${e}`)(...Object.values(t))}catch{return t(`warn`,`Failed to evaluate condition: ${e}`),!1}}renderTemplate(e,t){let n=e;return n=n.replace(/\(eq\s+(\w+(?:\.\w+)*)\s+"([^"]+)"\)/g,(e,n,r)=>this.getNestedValue(t,n)===r?`true`:`false`),n=n.replace(/\(not\s+(\w+(?:\.\w+)*)\)/g,(e,n)=>this.getNestedValue(t,n)?`false`:`true`),n=n.replace(/\(gt\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>parseFloat(r)?`true`:`false`}),n=n.replace(/\(gte\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>=parseFloat(r)?`true`:`false`}),n=n.replace(/\{\{#if\s+([^}]+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g,(e,n,r,i=``)=>{let a;return a=n===`true`||n!==`false`&&this.getNestedValue(t,n),a?r:i}),n=n.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return Array.isArray(i)?i.map((e,n)=>{let a={...t,...e,"@index":n,"@first":n===0,"@last":n===i.length-1};return this.renderTemplate(r,a)}).join(``):``}),n=n.replace(/\{\{\{json\s+(\w+(?:\.\w+)*)\}\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:JSON.stringify(r,null,2)}),n=n.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:r}),n}getNestedValue(e,t){return t.split(`.`).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,e)}validateAllPrompts(){let e={total:0,errors:[],valid:[]};for(let[t,n]of this.prompts.entries()){e.total++;try{if(this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(n)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}e.valid.push(t)}catch(n){e.errors.push(`${t}: ${n.message}`)}}return e}listPrompts(){let e=[];for(let[n,r]of this.prompts.entries())try{e.push({id:r.id,description:r.description,version:r.version,parameters:r.parameters,tags:r.metadata?.tags||[]})}catch(e){t(`warn`,`Failed to process template ${n}: ${e.message}`)}return e}validateTemplate(e){try{let t;if(typeof e==`string`){if(t=this.prompts.get(e),!t)return{valid:!1,error:`Template '${e}' not found`}}else t=e;for(let e of[`id`,`version`,`description`,`prompts`])if(!t[e])return{valid:!1,error:`Missing required field: ${e}`};if(!t.prompts.default)return{valid:!1,error:`Missing default prompt variant`};for(let[e,n]of Object.entries(t.prompts))if(!n.system||!n.user)return{valid:!1,error:`Variant '${e}' missing system or user prompt`};return this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(t)?{valid:!1,error:`Schema validation failed: ${this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `)}`}:{valid:!0}}catch(e){return{valid:!1,error:e.message}}}};let ve=null;function ye(){return ve||=new _e,ve}const{encode:be}=M;var xe=class{constructor(e,t){this.projectRoot=e,this.tasksPath=w.join(e,`.taskgraph`,`tasks`,`tasks.json`),this.tag=t,this.allTasks=this._loadAllTasks()}_loadAllTasks(){try{return l(this.tasksPath,this.projectRoot,this.tag)?.tasks||[]}catch(e){return console.warn(`Warning: Could not load tasks for ContextGatherer: ${e.message}`),[]}}countTokens(e){if(!e||typeof e!=`string`)return 0;try{return be(e).length}catch{return Math.ceil(e.length/4)}}async gather(e={}){let{tasks:t=[],files:n=[],customContext:r=``,includeProjectTree:i=!1,format:a=`research`,includeTokenCounts:o=!1,semanticQuery:s,maxSemanticResults:c=10,dependencyTasks:l=[]}=e,u=[],d=new Set(t.map(String)),f=null,p=null;if(o&&(p={total:0,customContext:null,tasks:[],files:[],projectTree:null}),s&&this.allTasks.length>0){let e=this._performSemanticSearch(s,c);f=e.analysisData,e.tasks.forEach(e=>{d.add(String(e.id))})}if(l.length>0&&this._buildDependencyGraphs(l).allRelatedTaskIds.forEach(e=>d.add(String(e))),r&&r.trim()){let e=this._formatCustomContext(r,a);u.push(e),o&&(p.customContext={tokens:this.countTokens(e),characters:e.length},p.total+=p.customContext.tokens)}if(d.size>0){let e=await this._gatherTaskContext(Array.from(d),a,o);if(e.context&&(u.push(e.context),o&&e.breakdown)){p.tasks=e.breakdown;let t=e.breakdown.reduce((e,t)=>e+t.tokens,0);p.total+=t}}if(n.length>0){let e=await this._gatherFileContext(n,a,o);if(e.context&&(u.push(e.context),o&&e.breakdown)){p.files=e.breakdown;let t=e.breakdown.reduce((e,t)=>e+t.tokens,0);p.total+=t}}if(i){let e=await this._gatherProjectTreeContext(a,o);e.context&&(u.push(e.context),o&&e.breakdown&&(p.projectTree=e.breakdown,p.total+=e.breakdown.tokens))}let m={context:this._joinContextSections(u,a),analysisData:f,contextSections:u.length,finalTaskIds:Array.from(d)};return o&&(m.tokenBreakdown=p),m}_performSemanticSearch(e,t){let n=this.allTasks.map(e=>{let t=e.dependencies?.length>0?e.dependencies.map(e=>this.allTasks.find(t=>t.id===e)?.title).filter(Boolean).join(` `):``;return{...e,dependencyTitles:t}}),r=new k(n,{includeScore:!0,threshold:.4,keys:[{name:`title`,weight:1.5},{name:`description`,weight:2},{name:`details`,weight:3},{name:`dependencyTitles`,weight:.5}],shouldSort:!0,useExtendedSearch:!0,limit:50}),i=e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3),a=r.search(e),o=[];for(let e of i)if(e.length>5){let t=r.search(e);t.length>0&&o.push(...t)}let s=[...a];for(let e of o)s.some(t=>t.item.id===e.item.id)||s.push(e);let c=s.filter(e=>e.score<.25).map(e=>e.item),l=s.filter(e=>e.score>=.25&&e.score<.4).map(e=>e.item),u=[...this.allTasks].sort((e,t)=>t.id-e.id).slice(0,5),d=[...c];for(let e of l)d.some(t=>t.id===e.id)||d.push(e);for(let e of u)d.some(t=>t.id===e.id)||d.push(e);return{tasks:d.slice(0,t),analysisData:{highRelevance:c,mediumRelevance:l,recentTasks:u,allRelevantTasks:d}}}_buildDependencyContext(e){let{allRelatedTaskIds:t,graphs:n,depthMap:r}=this._buildDependencyGraphs(e);if(t.size===0)return``;let i=Array.from(t).map(e=>this.allTasks.find(t=>t.id===e)).filter(Boolean).sort((e,t)=>(r.get(e.id)||0)-(r.get(t.id)||0)),a=i.slice(0,8),o=`\nThis task relates to a dependency structure with ${i.length} related tasks in the chain.`,s=this.allTasks.filter(t=>e.includes(t.id));s.length>0&&(o+=`\n\nDirect dependencies:\n${s.map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
536
+ `)}`);let c=i.filter(t=>!e.includes(t.id));c.length>0&&(o+=`\n\nIndirect dependencies (dependencies of dependencies):\n${c.slice(0,5).map(e=>`- Task ${e.id}: ${e.title} - ${e.description}`).join(`
537
+ `)}`,c.length>5&&(o+=`\n- ... and ${c.length-5} more indirect dependencies`)),o+=`
538
+
539
+ Detailed information about dependencies:`;for(let t of a){let n=e.includes(t.id)?` [DIRECT DEPENDENCY]`:``;o+=`\n\n------ Task ${t.id}${n}: ${t.title} ------\n`,o+=`Description: ${t.description}\n`,t.dependencies?.length&&(o+=`Dependencies: ${t.dependencies.join(`, `)}\n`),t.details&&(o+=`Implementation Details: ${u(t.details,400)}\n`)}return n.length>0&&(o+=`
540
+
541
+ Dependency Chain Visualization:`,o+=n.map(e=>this._formatDependencyChain(e)).join(``)),o}_buildDependencyGraphs(e){let t=/* @__PURE__ */ new Set,n=/* @__PURE__ */ new Map,r=[];for(let i of e){let e=this._buildDependencyGraph(i,t,n);e&&r.push(e)}return{allRelatedTaskIds:t,graphs:r,depthMap:n}}_buildDependencyGraph(e,t,n,r=0){if(t.has(e)||r>5)return null;let i=this.allTasks.find(t=>t.id===e);if(!i)return null;t.add(e),(!n.has(e)||r<n.get(e))&&n.set(e,r);let a=i.dependencies?.map(e=>this._buildDependencyGraph(e,t,n,r+1)).filter(Boolean)||[];return{...i,dependencies:a}}_formatDependencyChain(e,t=``,n=!0,r=0){if(r>3)return``;let i=`${t}${n?`└── `:`├── `}Task ${e.id}: ${e.title}`;if(e.dependencies?.length){let a=t+(n?` `:`│ `);i+=e.dependencies.map((t,n)=>this._formatDependencyChain(t,a,n===e.dependencies.length-1,r+1)).join(``)}return`
542
+ `+i}_parseTaskIds(e){let t=[];for(let n of e)if(n.includes(`.`)){let[e,r]=n.split(`.`);t.push({type:`subtask`,parentId:parseInt(e,10),subtaskId:parseInt(r,10),fullId:n})}else t.push({type:`task`,taskId:parseInt(n,10),fullId:n});return t}async _gatherTaskContext(e,t,n=!1){try{if(!this.allTasks||this.allTasks.length===0)return{context:null,breakdown:[]};let r=this._parseTaskIds(e),a=[],o=[];for(let e of r){let r=null,s=null;if(e.type===`task`){let a=i(this.allTasks,e.taskId);a.task&&(r=this._formatTaskForContext(a.task,t),s={id:e.fullId,type:`task`,title:a.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}else if(e.type===`subtask`){let a=i(this.allTasks,e.parentId);if(a.task&&a.task.subtasks){let i=a.task.subtasks.find(t=>t.id===e.subtaskId);i&&(r=this._formatSubtaskForContext(i,a.task,t),s={id:e.fullId,type:`subtask`,title:i.title,parentTitle:a.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}}r&&s&&(a.push(r),n&&o.push(s))}return a.length===0?{context:null,breakdown:[]}:{context:this._formatTaskContextSection(a,t),breakdown:n?o:[]}}catch(e){return console.warn(`Warning: Could not gather task context: ${e.message}`),{context:null,breakdown:[]}}}_formatTaskForContext(e,t){let n=[];if(n.push(`**Task ${e.id}: ${e.title}**`),n.push(`Description: ${e.description}`),n.push(`Status: ${e.status||`pending`}`),n.push(`Priority: ${e.priority||`medium`}`),e.dependencies&&e.dependencies.length>0&&n.push(`Dependencies: ${e.dependencies.join(`, `)}`),e.details){let t=u(e.details,500);n.push(`Implementation Details: ${t}`)}if(e.testStrategy){let t=u(e.testStrategy,300);n.push(`Test Strategy: ${t}`)}return e.subtasks&&e.subtasks.length>0&&n.push(`Subtasks: ${e.subtasks.length} subtasks defined`),n.join(`
543
+ `)}_formatSubtaskForContext(e,t,n){let r=[];if(r.push(`**Subtask ${t.id}.${e.id}: ${e.title}**`),r.push(`Parent Task: ${t.title}`),r.push(`Description: ${e.description}`),r.push(`Status: ${e.status||`pending`}`),e.dependencies&&e.dependencies.length>0&&r.push(`Dependencies: ${e.dependencies.join(`, `)}`),e.details){let t=u(e.details,500);r.push(`Implementation Details: ${t}`)}return r.join(`
544
+ `)}async _gatherFileContext(e,t,n=!1){let r=[],i=[];for(let a of e)try{let e=w.isAbsolute(a)?a:w.join(this.projectRoot,a);if(!T.existsSync(e))continue;let o=T.statSync(e);if(!o.isFile()||o.size>51200)continue;let s=T.readFileSync(e,`utf-8`),c=w.relative(this.projectRoot,e),l={path:c,size:o.size,content:s,lastModified:o.mtime};if(r.push(l),n){let e=this._formatSingleFileForContext(l,t);i.push({path:c,sizeKB:Math.round(o.size/1024),tokens:this.countTokens(e),characters:e.length})}}catch(e){console.warn(`Warning: Could not read file ${a}: ${e.message}`)}return r.length===0?{context:null,breakdown:[]}:{context:this._formatFileContextSection(r,t),breakdown:n?i:[]}}async _gatherProjectTreeContext(e,t=!1){try{let n=this._generateFileTree(this.projectRoot,5),r=this._formatProjectTreeSection(n,e);return{context:r,breakdown:t?{tokens:this.countTokens(r),characters:r.length,fileCount:n.fileCount||0,dirCount:n.dirCount||0}:null}}catch(e){return console.warn(`Warning: Could not generate project tree: ${e.message}`),{context:null,breakdown:null}}}_formatSingleFileForContext(e,t){return`${`**File: ${e.path}** (${Math.round(e.size/1024)}KB)`}\n\n${`\`\`\`\n${e.content}\n\`\`\``}`}_generateFileTree(e,t,n=0){let r=[`.git`,`node_modules`,`.env`,`coverage`,`dist`,`build`],i=[`.DS_Store`,`.env`,`.env.local`,`.env.production`];if(n>=t)return null;try{let a=T.readdirSync(e),o={name:w.basename(e),type:`directory`,children:[],fileCount:0,dirCount:0};for(let s of a){if(r.includes(s)||i.includes(s))continue;let a=w.join(e,s),c=T.statSync(a);if(c.isDirectory()){if(o.dirCount++,n<t-1){let e=this._generateFileTree(a,t,n+1);e&&o.children.push(e)}}else o.fileCount++,o.children.push({name:s,type:`file`,size:c.size})}return o}catch{return null}}_formatCustomContext(e,t){switch(t){case`research`:return`## Additional Context\n\n${e}`;case`chat`:return`**Additional Context:**\n${e}`;case`system-prompt`:return`Additional context: ${e}`;default:return e}}_formatTaskContextSection(e,t){switch(t){case`research`:return`## Task Context\n\n${e.join(`
545
+
546
+ ---
547
+
548
+ `)}`;case`chat`:return`**Task Context:**\n\n${e.join(`
549
+
550
+ `)}`;case`system-prompt`:return`Task context: ${e.join(` | `)}`;default:return e.join(`
551
+
552
+ `)}}_formatFileContextSection(e,t){let n=e.map(e=>`${`**File: ${e.path}** (${Math.round(e.size/1024)}KB)`}\n\n${`\`\`\`\n${e.content}\n\`\`\``}`);switch(t){case`research`:return`## File Context\n\n${n.join(`
553
+
554
+ ---
555
+
556
+ `)}`;case`chat`:return`**File Context:**\n\n${n.join(`
557
+
558
+ `)}`;case`system-prompt`:return`File context: ${e.map(e=>`${e.path} (${e.content.substring(0,200)}...)`).join(` | `)}`;default:return n.join(`
559
+
560
+ `)}}_formatProjectTreeSection(e,t){let n=this._renderFileTree(e);switch(t){case`research`:return`## Project Structure\n\n\`\`\`\n${n}\n\`\`\``;case`chat`:return`**Project Structure:**\n\`\`\`\n${n}\n\`\`\``;case`system-prompt`:return`Project structure: ${n.replace(/\n/g,` | `)}`;default:return n}}_renderFileTree(e,t=``){let n=`${t}${e.name}/`;return(e.fileCount>0||e.dirCount>0)&&(n+=` (${e.fileCount} files, ${e.dirCount} dirs)`),n+=`
561
+ `,e.children&&e.children.forEach((r,i)=>{let a=t+(i===e.children.length-1?`└── `:`├── `);t+``,r.type===`directory`?n+=this._renderFileTree(r,a):n+=`${a}${r.name}\n`}),n}_joinContextSections(e,t){if(e.length===0)return``;switch(t){case`research`:return e.join(`
562
+
563
+ ---
564
+
565
+ `);case`chat`:return e.join(`
566
+
567
+ `);case`system-prompt`:return e.join(` `);default:return e.join(`
568
+
569
+ `)}}};const Se={research:{threshold:.5,limit:20,keys:[{name:`title`,weight:2},{name:`description`,weight:1},{name:`details`,weight:.5},{name:`dependencyTitles`,weight:.5}]},addTask:{threshold:.4,limit:15,keys:[{name:`title`,weight:2},{name:`description`,weight:1.5},{name:`details`,weight:.8},{name:`dependencyTitles`,weight:.5}]},default:{threshold:.4,limit:15,keys:[{name:`title`,weight:2},{name:`description`,weight:1.5},{name:`details`,weight:1},{name:`dependencyTitles`,weight:.5}]}},Ce=[{pattern:/(command|cli|flag)/i,label:`CLI commands`},{pattern:/(task|subtask|add)/i,label:`Task management`},{pattern:/(dependency|depend)/i,label:`Dependency handling`},{pattern:/(AI|model|prompt|research)/i,label:`AI integration`},{pattern:/(UI|display|show|interface)/i,label:`User interface`},{pattern:/(schedule|time|cron)/i,label:`Scheduling`},{pattern:/(config|setting|option)/i,label:`Configuration`},{pattern:/(test|testing|spec)/i,label:`Testing`},{pattern:/(auth|login|user)/i,label:`Authentication`},{pattern:/(database|db|data)/i,label:`Data management`},{pattern:/(api|endpoint|route)/i,label:`API development`},{pattern:/(deploy|build|release)/i,label:`Deployment`},{pattern:/(security|auth|login|user)/i,label:`Security`},{pattern:/.*/,label:`Other`}],$={high:.25,medium:.4,low:.6};var we=class{constructor(e,t=`default`){this.tasks=e,this.config=Se[t]||Se.default,this.searchableTasks=this._prepareSearchableTasks(e),this.fuse=new k(this.searchableTasks,{includeScore:!0,threshold:this.config.threshold,keys:this.config.keys,shouldSort:!0,useExtendedSearch:!0,limit:this.config.limit})}_prepareSearchableTasks(e){return e.map(t=>{let n=t.dependencies?.length>0?t.dependencies.map(t=>{let n=e.find(e=>e.id===t);return n?n.title:``}).filter(e=>e).join(` `):``;return{...t,dependencyTitles:n}})}_extractPromptWords(e){return e.toLowerCase().replace(/[^\w\s-]/g,` `).split(/\s+/).filter(e=>e.length>3)}findRelevantTasks(e,t={}){let{maxResults:n=8,includeRecent:r=!0,includeCategoryMatches:i=!0}=t,a=this._extractPromptWords(e),o=this.fuse.search(e),s=[];for(let e of a)if(e.length>5){let t=this.fuse.search(e);t.length>0&&s.push(...t)}let c=[...o];for(let e of s)c.some(t=>t.item.id===e.item.id)||c.push(e);let l=c.filter(e=>e.score<$.high).map(e=>({...e.item,score:e.score})),u=c.filter(e=>e.score>=$.high&&e.score<$.medium).map(e=>({...e.item,score:e.score})),d=c.filter(e=>e.score>=$.medium&&e.score<$.low).map(e=>({...e.item,score:e.score})),f=r?[...this.tasks].sort((e,t)=>t.id-e.id).slice(0,5):[],p=[],m=null;i&&(m=Ce.find(t=>t.pattern.test(e)),p=m?this.tasks.filter(e=>m.pattern.test(e.title)||m.pattern.test(e.description)||e.details&&m.pattern.test(e.details)).slice(0,3):[]);let h=[...l];for(let e of u)h.some(t=>t.id===e.id)||h.push(e);for(let e of d)h.some(t=>t.id===e.id)||h.push(e);for(let e of p)h.some(t=>t.id===e.id)||h.push(e);for(let e of f)h.some(t=>t.id===e.id)||h.push(e);let g=h.slice(0,n);return{results:g,breakdown:{highRelevance:l,mediumRelevance:u,lowRelevance:d,categoryTasks:p,recentTasks:f,promptCategory:m,promptWords:a},metadata:{totalSearched:this.tasks.length,fuzzyMatches:o.length,wordMatches:s.length,finalCount:g.length}}}getTaskIds(e){return e.results.map(e=>e.id.toString())}getTaskIdsWithSubtasks(e,t=!1){let n=[];for(let r of e.results)if(n.push(r.id.toString()),t&&r.subtasks&&r.subtasks.length>0)for(let e of r.subtasks)n.push(`${r.id}.${e.id}`);return n}formatSearchSummary(e,t={}){let{includeScores:n=!1,includeBreakdown:r=!1}=t,{results:i,breakdown:a,metadata:o}=e,s=`Found ${i.length} relevant tasks from ${o.totalSearched} total tasks`;if(r&&a){let e=[];a.highRelevance.length>0&&e.push(`${a.highRelevance.length} high relevance`),a.mediumRelevance.length>0&&e.push(`${a.mediumRelevance.length} medium relevance`),a.lowRelevance.length>0&&e.push(`${a.lowRelevance.length} low relevance`),a.categoryTasks.length>0&&e.push(`${a.categoryTasks.length} category matches`),e.length>0&&(s+=` (${e.join(`, `)})`),a.promptCategory&&(s+=`\nCategory detected: ${a.promptCategory.label}`)}return s}};function Te(e){return e.replace(/<think>[\s\S]*?<\/think>/g,``).trim()}async function Ee(e,i={},a={},o=`text`,s=!0){let{taskIds:c=[],filePaths:u=[],customContext:f=``,includeProjectTree:p=!1,detailLevel:m=`medium`,projectRoot:h,tag:g,saveToFile:_=!1}=i,{session:v,mcpLog:y,commandName:b=`research`,outputType:x=`cli`}=a,S=!!y,C=o===`text`,T=h||n();if(!T)throw Error(`Could not determine project root directory`);let E=S?y:{info:(...e)=>t(`debug`,...e),warn:(...e)=>t(`warn`,...e),error:(...e)=>t(`debug`,...e),debug:(...e)=>t(`debug`,...e),success:(...e)=>t(`debug`,...e)},D=new xe(T,g),O=c.map(String),k=[];try{let t=w.join(T,`.taskgraph`,`tasks`,`tasks.json`),n=await l(t,T,g);if(n&&n.tasks&&n.tasks.length>0){let t=new we(r(n.tasks),`research`),i=t.findRelevantTasks(e,{maxResults:8,includeRecent:!0,includeCategoryMatches:!0});k=t.getTaskIds(i).map(String).filter(e=>!O.includes(e))}}catch(e){E.debug(`Could not auto-discover tasks: ${e.message}`)}let A=[...O,...k],j=await D.gather({tasks:A,files:u,customContext:f,includeProjectTree:p,format:`research`,includeTokenCounts:!0}),M=j.context,N=j.tokenBreakdown,P=ye(),F={query:e,gatheredContext:M||``,detailLevel:m,projectInfo:{root:T,taskCount:A.length,fileCount:u.length}},{systemPrompt:I,userPrompt:L}=await P.loadPrompt(`research`,F),R=D.countTokens(I),B=D.countTokens(L),H=R+B;if(C){let e=ee({taskIds:O,relatedTaskIds:k,files:u,projectTree:p,customContext:!!f});e&&console.log(e)}E.info(`Calling AI service with research role, context size: ${N.total} tokens (${M.length} characters)`);let U=null,W=null;if(C){let e=Date.now();U=z(`Researching…`),U&&(W=setInterval(()=>{let t=Math.round((Date.now()-e)/1e3);U.text=`Researching… ${t}s`},1e3))}let G;try{G=await te({role:`research`,session:v,projectRoot:T,systemPrompt:I,prompt:L,commandName:b,outputType:x})}catch(e){throw E.error(`Research query failed: ${e.message}`),e}finally{W&&clearInterval(W),V(U)}let K=Te(G.mainResult||``),q=G.telemetryData,J=G.tagInfo,Y={interactiveSaveOccurred:!1},X;C&&(console.log(`\n${d(K)}`),q&&Q(q,`cli`));let Z=[{question:e,answer:K,type:`initial`,timestamp:(/* @__PURE__ */ new Date()).toISOString()}];return _&&(X=await Ae(Z,T,a,E,o)),C&&s&&!S&&process.stdin.isTTY&&process.stdout.isTTY&&(Y=await De(i,a,o,T,E,Z)),E.success(`Research query completed successfully`),{query:e,result:K,contextSize:M.length,contextTokens:N.total,tokenBreakdown:N,systemPromptTokens:R,userPromptTokens:B,totalInputTokens:H,detailLevel:m,telemetryData:q,tagInfo:J,...X?{savedFilePath:X}:{},interactiveSaveOccurred:Y?.interactiveSaveOccurred||!1}}async function De(e,t,n,r,i,a){let o=!1;try{for(;;){console.log();let{action:s}=await D.prompt([{type:`select`,name:`action`,message:`What next?`,choices:[{name:`Ask a follow-up`,value:`followup`},{name:`Save to a file`,value:`savefile`},{name:`Save to a task`,value:`save`},{name:`Done`,value:`quit`}]}]);if(s===`quit`)break;if(s===`savefile`)try{await Ae(a,r,t,i,n)}catch{}else if(s===`save`)await ke(a,r,t,i)&&(o=!0);else if(s===`followup`){let{followUpQuery:r}=await D.prompt([{type:`input`,name:`followUpQuery`,message:`Follow-up question:`,validate:e=>e&&e.trim().length>0?!0:`Type a question, or press Ctrl-C to stop`}]);console.log();let i=Ne(a),o={...e,taskIds:[],saveToFile:!1,customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},s=await Ee(r.trim(),o,t,n,!1);a.push({question:r.trim(),answer:s.result,type:`followup`,timestamp:(/* @__PURE__ */ new Date()).toISOString()})}}}catch(e){e?.name!==`ExitPromptError`&&console.log(C.red(`✗ ${e.message}`)),i.debug(`Follow-up ended: ${e.message}`)}return{interactiveSaveOccurred:o}}function Oe(e,t,n,r={}){let{projectRoot:i,tag:a}=r,o=String(t).trim();if(!/^\d+(\.\d+)?$/.test(o))throw Error(`"${o}" isn't a task ID like 15 or 15.2`);let c=l(e,i,a);if(!c||!Array.isArray(c.tasks))throw Error(`No tasks found`);let[u,d]=o.split(`.`).map(e=>Number.parseInt(e,10)),f=c.tasks.find(e=>Number(e.id)===u);if(!f)throw Error(`Task ${u} doesn't exist`);let p=f;if(d!==void 0&&(p=(f.subtasks||[]).find(e=>Number(e.id)===d),!p))throw Error(`Subtask ${o} doesn't exist`);let m=(/* @__PURE__ */ new Date()).toISOString(),h=`<info added on ${m}>\n${n.trim()}\n</info added on ${m}>`;return p.details=p.details?`${p.details}\n${h}`:h,s(e,c,i,a),{id:o,title:p.title}}async function ke(e,t,n,r){let{taskId:i}=await D.prompt([{type:`input`,name:`taskId`,message:`Task ID (15, or 15.2 for a subtask):`,validate:e=>/^\d+(\.\d+)?$/.test((e||``).trim())?!0:`Use 15 for a task or 15.2 for a subtask`}]),a={kind:`task`,id:i.trim()},o=w.join(t,`.taskgraph`,`tasks`,`tasks.json`);try{return Oe(o,a.id,Me(e),{projectRoot:t,tag:n.tag}),console.log(_(a)),!0}catch(e){return console.log(g(a,e.message)),r.debug(`Error saving conversation: ${e.message}`),!1}}async function Ae(e,t,n,r,i=`text`){try{let n=w.join(t,`.taskgraph`,`docs`,`research`);T.existsSync(n)||T.mkdirSync(n,{recursive:!0});let a=e[0]?.question||`research-query`,o=`${(/* @__PURE__ */ new Date()).toISOString().split(`T`)[0]}_${a.toLowerCase().replace(/[^a-z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50).replace(/^-+|-+$/g,``)}.md`,s=w.join(n,o),c=je(e,a);T.writeFileSync(s,c,`utf8`);let l=w.relative(t,s);return i===`text`&&console.log(_({kind:`file`,path:l})),r.success(`Research conversation saved to ${l}`),s}catch(e){throw i===`text`&&console.log(g({kind:`file`,path:``},e.message)),r.error(`Error saving research file: ${e.message}`),e}}function je(e,t){let n=(/* @__PURE__ */ new Date()).toISOString(),r=`---
570
+ title: Research Session
571
+ query: "${t}"
572
+ date: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}
573
+ time: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}
574
+ timestamp: ${n}
575
+ exchanges: ${e.length}
576
+ ---
577
+
578
+ # Research Session
579
+
580
+ `;return e.forEach((t,n)=>{t.type===`initial`?r+=`## Initial Query\n\n**Question:** ${t.question}\n\n**Response:**\n\n${t.answer}\n\n`:r+=`## Follow-up ${n}\n\n**Question:** ${t.question}\n\n**Response:**\n\n${t.answer}\n\n`,n<e.length-1&&(r+=`---
581
+
582
+ `)}),r+=`\n---\n\n*Generated by TaskGraph Research Command* \n*Timestamp: ${n}*\n`,r}function Me(e){(/* @__PURE__ */ new Date()).toISOString();let t=`## Research Session - ${(/* @__PURE__ */ new Date()).toLocaleDateString()} ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}\n\n`;return e.forEach((n,r)=>{n.type===`initial`?(t+=`**Initial Query:** ${n.question}\n\n`,t+=`**Response:** ${n.answer}\n\n`):(t+=`**Follow-up ${r}:** ${n.question}\n\n`,t+=`**Response:** ${n.answer}\n\n`),r<e.length-1&&(t+=`---
583
+
584
+ `)}),t}function Ne(e){if(e.length===0)return``;let t=[`--- Conversation History ---`];return e.forEach((e,n)=>{let r=e.type===`initial`?`Initial Question`:`Follow-up ${n}`,i=e.type===`initial`?`Initial Answer`:`Answer ${n}`;t.push(`\n${r}: ${e.question}`),t.push(`${i}: ${e.answer}`)}),t.join(`
585
+ `)}export{N as A,V as C,L as D,R as E,F as O,B as S,I as T,K as _,ye as a,U as b,oe as c,Q as d,Z as f,W as g,J as h,xe as i,P as k,ae as l,Y as m,Ee as n,re as o,X as p,we as r,se as s,Oe as t,ne as u,q as v,H as w,z as x,G as y};