taskgraph-ai 0.54.13 → 0.54.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- export{t as appendResearchToTask,n as performResearch}from"./research-D_nwZW-q.js";
1
+ export{t as appendResearchToTask,n as performResearch}from"./research-DbaGD34z.js";
@@ -1,30 +1,13 @@
1
- import{O as e}from"./src-Cs4ilbQ-.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-DIET_FiX.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-V29fsb6x.js";import{n as te}from"./ai-services-unified-CKKHbOMd.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.
1
+ import{O as e,t}from"./src-BQZsjzA5.js";import{$ as n,G as r,J as i,K as a,Q as o,Y as s,dt as c,g as l,it as u,lt as d}from"./config-manager-DTkRerDn.js";import{$ as f,B as p,C as m,G as h,H as g,K as _,Q as v,U as y,V as b,X as x,Y as S,q as C,w,z as ee}from"./src-CpPJ2WS1.js";import{n as te}from"./ai-services-unified-B45jIPar.js";import T from"chalk";import E from"path";import D from"fs";import O from"boxen";import k from"inquirer";import A from"readline";import j from"fuse.js";import M from"ajv";import N from"ajv-formats";import ne from"gpt-tokens";const{theme:P,BORDER_COLOR:F}=w;function I(){return e||`unknown`}function L(){o()||f({version:I(),projectName:l(null)})}function R(e){!o()&&e&&e._migrationHappened&&console.log(O(T.bold(`FYI: `)+P.muted(`TaskGraph now supports separate task lists per tag. `)+T.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 z(e,n={}){o()||t(e||`master`,n.projectRoot,n.tasksPath)&&console.log(v(e||`master`))}function B(e){return o()?null:x(e).start()}function V(e){return o()?null:new S(e).start()}function re(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?T.red:e<50||e<75?T.yellow:T.green;let l=c(`█`.repeat(i)),u=P.muted(`─`.repeat(o)),d=``;if(n&&s>0){let e={pending:e=>T.yellow(`░`.repeat(e)),"in-progress":e=>P.active(`▓`.repeat(e)),blocked:e=>T.red(`!`.repeat(e)),review:e=>T.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=P.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=>P.muted(`░`.repeat(e)));d+=c(o),r+=o}r<s&&(d+=P.muted(`░`.repeat(s-r)))}}else d=P.muted(`░`.repeat(s));let f=e===100?T.green:r===100?P.muted:c;return`${l}${u}${d} ${f(`${r.toFixed(0)}%`)}`}function G(e,t=!1){if(!e)return P.muted(`? unknown`);let n={done:{color:T.green,icon:`✓`,tableIcon:`✓`},completed:{color:T.green,icon:`✓`,tableIcon:`✓`},pending:{color:T.yellow,icon:`○`,tableIcon:`⏱`},"in-progress":{color:P.active,icon:`▶`,tableIcon:`▶`},deferred:{color:P.muted,icon:`x`,tableIcon:`⏱`},blocked:{color:T.red,icon:`!`,tableIcon:`✗`},review:{color:T.magenta,icon:`?`,tableIcon:`?`},cancelled:{color:P.muted,icon:`x`,tableIcon:`x`}}[e.toLowerCase()]||{color:T.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?P.muted(`None`):`None`:e.map(e=>{let i=e.toString();if(i.includes(`.`)){let o=i.split(`.`);if(o.length!==2||!o[0]||!o[1]){let o=a(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!o)return n?T.red(`${i} (Not found)`):`${i} (Not found)`;let s=o.status||`pending`,c=s.toLowerCase()===`done`||s.toLowerCase()===`completed`,l=s.toLowerCase()===`in-progress`;return n?c?T.green.bold(i):l?T.yellow.bold(i):T.red.bold(i):i}let[s,c]=o.map(e=>parseInt(e,10)),l=t.find(e=>e.id===s);if(!l||!l.subtasks)return n?T.red(`${i} (Not found)`):`${i} (Not found)`;let u=l.subtasks.find(e=>e.id===c);if(!u)return n?T.red(`${i} (Not found)`):`${i} (Not found)`;let d=u.status||`pending`,f=d.toLowerCase()===`done`||d.toLowerCase()===`completed`,p=d.toLowerCase()===`in-progress`;return n?f?T.green.bold(i):p?P.active.bold(i):T.red.bold(i):i}let o=a(t,typeof e==`string`?parseInt(e,10):e,r).task;if(!o)return n?T.red(`${i} (Not found)`):`${i} (Not found)`;let s=o.status||`pending`,c=s.toLowerCase()===`done`||s.toLowerCase()===`completed`,l=s.toLowerCase()===`in-progress`;return n?c?T.green.bold(i):l?T.yellow.bold(i):T.red.bold(i):i}).join(`, `)}function q(e){return e<=3?T.green(`● ${e}`):e<=6?T.yellow(`● ${e}`):T.red(`● ${e}`)}function J(){console.log(y())}async function Y(e){D.existsSync(e)||(m(`No complexity report for this tag yet`,"Run `taskgraph analyze-complexity` to create one"),process.exit(1));let t;try{t=JSON.parse(D.readFileSync(e,`utf8`))}catch(e){m(`Couldn't read the complexity report: ${e.message}`,"Run `taskgraph analyze-complexity` to create it again"),process.exit(1)}console.log(C(t))}async function ie(e){console.log(O(T.yellow(`It looks like you've already generated tasks for this project.
2
+ `)+T.yellow(`Executing this command will overwrite any existing tasks.`),{padding:1,borderColor:`yellow`,borderStyle:`round`,margin:{top:1}}));let t=A.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(e=>{t.question(T.cyan(`Are you sure you wish to continue? (y/N): `),e)});return t.close(),n.toLowerCase()===`y`||n.toLowerCase()===`yes`}function X(e,t=`cli`){if(t!==`cli`&&t!==`text`||!e||o())return;let n=_(e);n&&console.log(`\n${P.muted(n)}`)}function ae(e,t){!o()&&t?.length&&console.log(`\n${h(e,t)}`)}function oe(e,t,n,r){console.log(T.red(`\n✗ Cannot move tasks from "${t}" to "${n}"`)),console.log(T.yellow(`
3
+ Cross-tag dependency conflicts detected:`)),e.length>0&&e.forEach(e=>{console.log(` • ${e.message}`)}),console.log(T.cyan(`
4
+ 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 se(e){return e===null?`null`:e===void 0?`undefined`:e===``?`(empty)`:s(e)||`unknown`}function ce(e,t,n){let r=se(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(T.yellow(`\n⚠ Warning: Unexpected taskId format "${i}". Using as-is for command suggestions.`)),a=i)}console.log(T.red(`\n✗ Cannot move subtask ${r} directly between tags`)),console.log(T.yellow(`
5
+ 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(T.cyan(`
6
+ 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 le(e,t,n){console.log(T.red(`
7
+ ✗ Invalid tag combination`)),console.log(T.yellow(`
8
+ Error details:`)),console.log(` • Source tag: "${e}"`),console.log(` • Target tag: "${t}"`),console.log(` • Reason: ${n}`),console.log(T.cyan(`
9
+ 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 ue(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(T.cyan(`
10
+ Helpful hints:`)),new Set(n).forEach(e=>{console.log(` ${e}`)})}var de={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
11
 
29
12
  IMPORTANT: Your response MUST be a JSON object with the following structure (no wrapper property, just these fields directly):
30
13
  {
@@ -84,7 +67,7 @@ Project Root: {{projectRoot}}
84
67
  }
85
68
 
86
69
  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.
70
+ {{#if contextFromArgs}}{{contextFromArgs}}{{/if}}`}}},fe={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
71
 
89
72
  IMPORTANT: For each task, provide an analysis object with ALL of the following fields:
90
73
  - taskId: The ID of the task being analyzed (positive integer)
@@ -122,7 +105,7 @@ Tasks:
122
105
 
123
106
  {{gatheredContext}}
124
107
  {{/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.
108
+ `}}},pe={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
109
 
127
110
  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
111
  - 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!
@@ -234,7 +217,7 @@ Complexity Analysis Reasoning: {{complexityReasoningContext}}{{/if}}{{#if gather
234
217
 
235
218
  {{gatheredContext}}{{/if}}
236
219
 
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}}
220
+ 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!`}}},me={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
221
  Before breaking down the PRD into tasks, you will:
239
222
  1. Research and analyze the latest technologies, libraries, frameworks, and best practices that would be appropriate for this project
240
223
  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
@@ -298,7 +281,7 @@ Remember to thoroughly research current best practices and technologies before t
298
281
 
299
282
  {{prdContent}}
300
283
 
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.
284
+ 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.`}}},he={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
285
 
303
286
  Your role is to provide comprehensive, accurate, and actionable research responses based on the user's query and the provided project context.
304
287
  {{#if (eq detailLevel "low")}}
@@ -348,7 +331,7 @@ Your role is to provide comprehensive, accurate, and actionable research respons
348
331
 
349
332
  # Instructions
350
333
 
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}}
334
+ 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.`}}},ge={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
335
 
353
336
  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
337
  Focus *only* on generating the substance of the update.
@@ -392,7 +375,7 @@ User Request: "{{updatePrompt}}"
392
375
  # Additional Project Context
393
376
 
394
377
  {{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}}
378
+ {{/if}}`}}},_e={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
379
  You will be given a task and a prompt describing changes or new implementation details.
397
380
  Your job is to update the task to reflect these changes, while preserving its basic structure.
398
381
 
@@ -490,7 +473,7 @@ Based on the User Request and all the Task Context (including current task detai
490
473
  # Additional Project Context
491
474
 
492
475
  {{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.
476
+ {{/if}}`}}},ve={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
477
  You will be given a set of tasks and a prompt describing changes or new implementation details.
495
478
  Your job is to update the tasks to reflect these changes, while preserving their basic structure.
496
479
 
@@ -532,16 +515,16 @@ IMPORTANT: In the tasks above, any subtasks with "status": "done" or "status": "
532
515
 
533
516
  {{projectContext}}{{/if}}
534
517
 
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(`
518
+ IMPORTANT: Your response must be a JSON object with a single property named "tasks" containing the updated array of tasks.`}}},ye={$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`]}}}}},be=class{constructor(){this.prompts=/* @__PURE__ */ new Map([[`analyze-complexity`,fe],[`expand-task`,pe],[`add-task`,de],[`research`,he],[`parse-prd`,me],[`update-task`,_e],[`update-tasks`,ve],[`update-subtask`,ge]]),this.cache=/* @__PURE__ */ new Map,this.setupValidation()}setupValidation(){this.ajv=new M({allErrors:!0,strict:!1}),N(this.ajv);try{this.validatePrompt=this.ajv.compile(ye),n(`debug`,`✓ JSON schema validation enabled`)}catch(e){n(`warn`,`⚠ Schema validation disabled: ${e.message}`),this.validatePrompt=()=>!0}}loadPrompt(e,t={},r=null){try{let n=`${e}-${JSON.stringify(t)}-${r}`;if(this.cache.has(n))return this.cache.get(n);let i=this.loadTemplate(e);this.validatePrompt&&this.validatePrompt!==!0&&this.validateParameters(i,t);let a=r?{...i.prompts[r],name:r}:this.selectVariant(i,t),o={systemPrompt:this.renderTemplate(a.system,t),userPrompt:this.renderTemplate(a.user,t),metadata:{templateId:i.id,version:i.version,variant:a.name||`default`,parameters:t}};return this.cache.set(n,o),o}catch(t){throw n(`error`,`Failed to load prompt ${e}: ${t.message}`),t}}loadTemplate(e){let t=this.prompts.get(e);if(!t)throw Error(`Prompt template '${e}' not found`);if(this.validatePrompt&&this.validatePrompt!==!0){if(!this.validatePrompt(t)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}}else if(!t.id||!t.prompts||!t.prompts.default)throw Error(`Invalid template structure: missing required fields (id, prompts.default)`);return t}validateParameters(e,t){if(!e.parameters)return;let n=[];for(let[r,i]of Object.entries(e.parameters)){let e=t[r];i.required&&e===void 0?n.push(`Required parameter '${r}' missing`):e!==void 0&&(this.validateParameterType(e,i.type)||n.push(`Parameter '${r}' expected ${i.type}, got ${typeof e}`),i.enum&&!i.enum.includes(e)&&n.push(`Parameter '${r}' must be one of: ${i.enum.join(`, `)}`),i.pattern&&typeof e==`string`&&(new RegExp(i.pattern).test(e)||n.push(`Parameter '${r}' does not match required pattern: ${i.pattern}`)),typeof e==`number`&&(i.minimum!==void 0&&e<i.minimum&&n.push(`Parameter '${r}' must be >= ${i.minimum}`),i.maximum!==void 0&&e>i.maximum&&n.push(`Parameter '${r}' must be <= ${i.maximum}`)))}if(n.length>0)throw Error(`Parameter validation failed: ${n.join(`; `)}`)}validateParameterType(e,t){switch(t){case`string`:return typeof e==`string`;case`number`:return typeof e==`number`;case`boolean`:return typeof e==`boolean`;case`array`:return Array.isArray(e);case`object`:return typeof e==`object`&&!!e&&!Array.isArray(e);default:return!0}}selectVariant(e,t){for(let[n,r]of Object.entries(e.prompts))if(n!=="default"&&r.condition&&this.evaluateCondition(r.condition,t))return{...r,name:n};return{...e.prompts.default,name:`default`}}evaluateCondition(e,t){try{let n={...t};return Function(...Object.keys(n),`return ${e}`)(...Object.values(n))}catch{return n(`warn`,`Failed to evaluate condition: ${e}`),!1}}renderTemplate(e,t){let n=e;return n=n.replace(/\(eq\s+(\w+(?:\.\w+)*)\s+"([^"]+)"\)/g,(e,n,r)=>this.getNestedValue(t,n)===r?`true`:`false`),n=n.replace(/\(not\s+(\w+(?:\.\w+)*)\)/g,(e,n)=>this.getNestedValue(t,n)?`false`:`true`),n=n.replace(/\(gt\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>parseFloat(r)?`true`:`false`}),n=n.replace(/\(gte\s+(\w+(?:\.\w+)*)\s+(\d+(?:\.\d+)?)\)/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return typeof i==`number`&&i>=parseFloat(r)?`true`:`false`}),n=n.replace(/\{\{#if\s+([^}]+)\}\}([\s\S]*?)(?:\{\{else\}\}([\s\S]*?))?\{\{\/if\}\}/g,(e,n,r,i=``)=>{let a;return a=n===`true`||n!==`false`&&this.getNestedValue(t,n),a?r:i}),n=n.replace(/\{\{#each\s+(\w+(?:\.\w+)*)\}\}([\s\S]*?)\{\{\/each\}\}/g,(e,n,r)=>{let i=this.getNestedValue(t,n);return Array.isArray(i)?i.map((e,n)=>{let a={...t,...e,"@index":n,"@first":n===0,"@last":n===i.length-1};return this.renderTemplate(r,a)}).join(``):``}),n=n.replace(/\{\{\{json\s+(\w+(?:\.\w+)*)\}\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:JSON.stringify(r,null,2)}),n=n.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g,(e,n)=>{let r=this.getNestedValue(t,n);return r===void 0?``:r}),n}getNestedValue(e,t){return t.split(`.`).reduce((e,t)=>e&&e[t]!==void 0?e[t]:void 0,e)}validateAllPrompts(){let e={total:0,errors:[],valid:[]};for(let[t,n]of this.prompts.entries()){e.total++;try{if(this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(n)){let e=this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `);throw Error(`Schema validation failed: ${e}`)}e.valid.push(t)}catch(n){e.errors.push(`${t}: ${n.message}`)}}return e}listPrompts(){let e=[];for(let[t,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){n(`warn`,`Failed to process template ${t}: ${e.message}`)}return e}validateTemplate(e){try{let t;if(typeof e==`string`){if(t=this.prompts.get(e),!t)return{valid:!1,error:`Template '${e}' not found`}}else t=e;for(let e of[`id`,`version`,`description`,`prompts`])if(!t[e])return{valid:!1,error:`Missing required field: ${e}`};if(!t.prompts.default)return{valid:!1,error:`Missing default prompt variant`};for(let[e,n]of Object.entries(t.prompts))if(!n.system||!n.user)return{valid:!1,error:`Variant '${e}' missing system or user prompt`};return this.validatePrompt&&this.validatePrompt!==!0&&!this.validatePrompt(t)?{valid:!1,error:`Schema validation failed: ${this.validatePrompt.errors.map(e=>`${e.instancePath||`root`}: ${e.message}`).join(`, `)}`}:{valid:!0}}catch(e){return{valid:!1,error:e.message}}}};let Z=null;function xe(){return Z||=new be,Z}const{encode:Se}=ne;var Ce=class{constructor(e,t){this.projectRoot=e,this.tasksPath=E.join(e,`.taskgraph`,`tasks`,`tasks.json`),this.tag=t,this.allTasks=this._loadAllTasks()}_loadAllTasks(){try{return u(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 Se(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 j(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
519
  `)}`);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
520
  `)}`,c.length>5&&(o+=`\n- ... and ${c.length-5} more indirect dependencies`)),o+=`
538
521
 
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+=`
522
+ 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: ${d(t.details,400)}\n`)}return n.length>0&&(o+=`
540
523
 
541
524
  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(`
525
+ `+i}_parseTaskIds(e){let t=[];for(let n of e)if(n.includes(`.`)){let[e,r]=n.split(`.`);t.push({type:`subtask`,parentId:parseInt(e,10),subtaskId:parseInt(r,10),fullId:n})}else t.push({type:`task`,taskId:parseInt(n,10),fullId:n});return t}async _gatherTaskContext(e,t,n=!1){try{if(!this.allTasks||this.allTasks.length===0)return{context:null,breakdown:[]};let r=this._parseTaskIds(e),i=[],o=[];for(let e of r){let r=null,s=null;if(e.type===`task`){let i=a(this.allTasks,e.taskId);i.task&&(r=this._formatTaskForContext(i.task,t),s={id:e.fullId,type:`task`,title:i.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}else if(e.type===`subtask`){let i=a(this.allTasks,e.parentId);if(i.task&&i.task.subtasks){let a=i.task.subtasks.find(t=>t.id===e.subtaskId);a&&(r=this._formatSubtaskForContext(a,i.task,t),s={id:e.fullId,type:`subtask`,title:a.title,parentTitle:i.task.title,tokens:n?this.countTokens(r):0,characters:r.length})}}r&&s&&(i.push(r),n&&o.push(s))}return i.length===0?{context:null,breakdown:[]}:{context:this._formatTaskContextSection(i,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=d(e.details,500);n.push(`Implementation Details: ${t}`)}if(e.testStrategy){let t=d(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(`
526
+ `)}_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=d(e.details,500);r.push(`Implementation Details: ${t}`)}return r.join(`
527
+ `)}async _gatherFileContext(e,t,n=!1){let r=[],i=[];for(let a of e)try{let e=E.isAbsolute(a)?a:E.join(this.projectRoot,a);if(!D.existsSync(e))continue;let o=D.statSync(e);if(!o.isFile()||o.size>51200)continue;let s=D.readFileSync(e,`utf-8`),c=E.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=D.readdirSync(e),o={name:E.basename(e),type:`directory`,children:[],fileCount:0,dirCount:0};for(let s of a){if(r.includes(s)||i.includes(s))continue;let a=E.join(e,s),c=D.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
528
 
546
529
  ---
547
530
 
@@ -566,7 +549,7 @@ Dependency Chain Visualization:`,o+=n.map(e=>this._formatDependencyChain(e)).joi
566
549
 
567
550
  `);case`system-prompt`:return e.join(` `);default:return e.join(`
568
551
 
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=`---
552
+ `)}}};const we={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}]}},Te=[{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`}],Q={high:.25,medium:.4,low:.6};var Ee=class{constructor(e,t=`default`){this.tasks=e,this.config=we[t]||we.default,this.searchableTasks=this._prepareSearchableTasks(e),this.fuse=new j(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<Q.high).map(e=>({...e.item,score:e.score})),u=c.filter(e=>e.score>=Q.high&&e.score<Q.medium).map(e=>({...e.item,score:e.score})),d=c.filter(e=>e.score>=Q.medium&&e.score<Q.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=Te.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 De(e){return e.replace(/<think>[\s\S]*?<\/think>/g,``).trim()}async function Oe(e,t={},a={},o=`text`,s=!0){let{taskIds:c=[],filePaths:l=[],customContext:d=``,includeProjectTree:f=!1,detailLevel:m=`medium`,projectRoot:h,tag:g,saveToFile:_=!1}=t,{session:v,mcpLog:y,commandName:b=`research`,outputType:x=`cli`}=a,S=!!y,C=o===`text`,w=h||r();if(!w)throw Error(`Could not determine project root directory`);let T=S?y:{info:(...e)=>n(`debug`,...e),warn:(...e)=>n(`warn`,...e),error:(...e)=>n(`debug`,...e),debug:(...e)=>n(`debug`,...e),success:(...e)=>n(`debug`,...e)},D=new Ce(w,g),O=c.map(String),k=[];try{let t=E.join(w,`.taskgraph`,`tasks`,`tasks.json`),n=await u(t,w,g);if(n&&n.tasks&&n.tasks.length>0){let t=new Ee(i(n.tasks),`research`),r=t.findRelevantTasks(e,{maxResults:8,includeRecent:!0,includeCategoryMatches:!0});k=t.getTaskIds(r).map(String).filter(e=>!O.includes(e))}}catch(e){T.debug(`Could not auto-discover tasks: ${e.message}`)}let A=[...O,...k],j=await D.gather({tasks:A,files:l,customContext:d,includeProjectTree:f,format:`research`,includeTokenCounts:!0}),M=j.context,N=j.tokenBreakdown,ne=xe(),P={query:e,gatheredContext:M||``,detailLevel:m,projectInfo:{root:w,taskCount:A.length,fileCount:l.length}},{systemPrompt:F,userPrompt:I}=await ne.loadPrompt(`research`,P),L=D.countTokens(F),R=D.countTokens(I),z=L+R;if(C){let e=p({taskIds:O,relatedTaskIds:k,files:l,projectTree:f,customContext:!!d});e&&console.log(e)}T.info(`Calling AI service with research role, context size: ${N.total} tokens (${M.length} characters)`);let V=null,H=null;if(C){let e=Date.now();V=B(`Researching…`),V&&(H=setInterval(()=>{let t=Math.round((Date.now()-e)/1e3);V.text=`Researching… ${t}s`},1e3))}let U;try{U=await te({role:`research`,session:v,projectRoot:w,systemPrompt:F,prompt:I,commandName:b,outputType:x})}catch(e){throw T.error(`Research query failed: ${e.message}`),e}finally{H&&clearInterval(H),re(V)}let W=De(U.mainResult||``),G=U.telemetryData,K=U.tagInfo,q={interactiveSaveOccurred:!1},J;C&&(console.log(`\n${ee(W)}`),G&&X(G,`cli`));let Y=[{question:e,answer:W,type:`initial`,timestamp:(/* @__PURE__ */ new Date()).toISOString()}];return _&&(J=await $(Y,w,a,T,o)),C&&s&&!S&&process.stdin.isTTY&&process.stdout.isTTY&&(q=await ke(t,a,o,w,T,Y)),T.success(`Research query completed successfully`),{query:e,result:W,contextSize:M.length,contextTokens:N.total,tokenBreakdown:N,systemPromptTokens:L,userPromptTokens:R,totalInputTokens:z,detailLevel:m,telemetryData:G,tagInfo:K,...J?{savedFilePath:J}:{},interactiveSaveOccurred:q?.interactiveSaveOccurred||!1}}async function ke(e,t,n,r,i,a){let o=!1;try{for(;;){console.log();let{action:s}=await k.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 $(a,r,t,i,n)}catch{}else if(s===`save`)await je(a,r,t,i)&&(o=!0);else if(s===`followup`){let{followUpQuery:r}=await k.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=Pe(a),o={...e,taskIds:[],saveToFile:!1,customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},s=await Oe(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(T.red(`✗ ${e.message}`)),i.debug(`Follow-up ended: ${e.message}`)}return{interactiveSaveOccurred:o}}function Ae(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 s=u(e,i,a);if(!s||!Array.isArray(s.tasks))throw Error(`No tasks found`);let[l,d]=o.split(`.`).map(e=>Number.parseInt(e,10)),f=s.tasks.find(e=>Number(e.id)===l);if(!f)throw Error(`Task ${l} 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,c(e,s,i,a),{id:o,title:p.title}}async function je(e,t,n,r){let{taskId:i}=await k.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=E.join(t,`.taskgraph`,`tasks`,`tasks.json`);try{return Ae(o,a.id,Ne(e),{projectRoot:t,tag:n.tag}),console.log(g(a)),!0}catch(e){return console.log(b(a,e.message)),r.debug(`Error saving conversation: ${e.message}`),!1}}async function $(e,t,n,r,i=`text`){try{let n=E.join(t,`.taskgraph`,`docs`,`research`);D.existsSync(n)||D.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=E.join(n,o),c=Me(e,a);D.writeFileSync(s,c,`utf8`);let l=E.relative(t,s);return i===`text`&&console.log(g({kind:`file`,path:l})),r.success(`Research conversation saved to ${l}`),s}catch(e){throw i===`text`&&console.log(b({kind:`file`,path:``},e.message)),r.error(`Error saving research file: ${e.message}`),e}}function Me(e,t){let n=(/* @__PURE__ */ new Date()).toISOString(),r=`---
570
553
  title: Research Session
571
554
  query: "${t}"
572
555
  date: ${(/* @__PURE__ */ new Date()).toLocaleDateString()}
@@ -579,7 +562,7 @@ exchanges: ${e.length}
579
562
 
580
563
  `;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
564
 
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+=`---
565
+ `)}),r+=`\n---\n\n*Generated by TaskGraph Research Command* \n*Timestamp: ${n}*\n`,r}function Ne(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
566
 
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};
567
+ `)}),t}function Pe(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(`
568
+ `)}export{H as C,I as D,R as E,F as O,re as S,z as T,q as _,xe as a,B as b,le as c,X as d,ie as f,K as g,W as h,Ce as i,P as k,ce as l,J as m,Oe as n,oe as o,Y as p,Ee as r,ue as s,Ae as t,ae as u,G as v,L as w,V as x,U as y};
@@ -1 +1 @@
1
- import{$ as e,P as t,T as n,a as r,j as i}from"./config-manager-DIET_FiX.js";function a(a,o={}){let{mcpLog:s,projectRoot:c}=o,l=(e,...t)=>{s&&typeof s[e]==`function`&&s[e](...t)},u=t(null,{projectRoot:c}),d=n(c);if(e(`debug`,`Checking for config file using findConfigPath, found: ${u}`),e(`debug`,`Checking config file using isConfigFilePresent(), exists: ${d}`),!d)return{success:!1,error:{code:`CONFIG_MISSING`,message:`The configuration file is missing. Run "taskgraph init" to create it.`}};if(typeof a!=`string`||a.trim()===``)return{success:!1,error:{code:`INVALID_RESPONSE_LANGUAGE`,message:`Invalid response language: ${a}. Must be a non-empty string.`}};try{let e=r(c);return e.global.responseLanguage=a,i(e,c)?{success:!0,data:{responseLanguage:a,message:`Response language set to ${a}`}}:{success:!1,error:{code:`WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}}}catch(e){return l(`error`,`Error setting response language: ${e.message}`),{success:!1,error:{code:`SET_RESPONSE_LANGUAGE_ERROR`,message:e.message}}}}export{a as t};
1
+ import{$ as e,P as t,T as n,a as r,j as i}from"./config-manager-DTkRerDn.js";function a(a,o={}){let{mcpLog:s,projectRoot:c}=o,l=(e,...t)=>{s&&typeof s[e]==`function`&&s[e](...t)},u=t(null,{projectRoot:c}),d=n(c);if(e(`debug`,`Checking for config file using findConfigPath, found: ${u}`),e(`debug`,`Checking config file using isConfigFilePresent(), exists: ${d}`),!d)return{success:!1,error:{code:`CONFIG_MISSING`,message:`The configuration file is missing. Run "taskgraph init" to create it.`}};if(typeof a!=`string`||a.trim()===``)return{success:!1,error:{code:`INVALID_RESPONSE_LANGUAGE`,message:`Invalid response language: ${a}. Must be a non-empty string.`}};try{let e=r(c);return e.global.responseLanguage=a,i(e,c)?{success:!0,data:{responseLanguage:a,message:`Response language set to ${a}`}}:{success:!1,error:{code:`WRITE_ERROR`,message:`Error writing updated configuration to configuration file`}}}catch(e){return l(`error`,`Error setting response language: ${e.message}`),{success:!1,error:{code:`SET_RESPONSE_LANGUAGE_ERROR`,message:e.message}}}}export{a as t};
@@ -0,0 +1 @@
1
+ export{t as default}from"./response-language-CbtAaYK6.js";