taskgraph-ai 0.49.1 → 0.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +14 -27
  2. package/dist/ai-services-unified-DbjBfAvG.js +3 -0
  3. package/dist/ai-services-unified-TeIK2DoX.js +1 -0
  4. package/dist/{commands-CceFmRJA.js → commands-2aOf3ERj.js} +86 -86
  5. package/dist/config-manager-C8-BTReQ.js +1 -0
  6. package/dist/config-manager-Da0wEujO.js +1 -0
  7. package/dist/dependency-manager-DIbDdrUV.js +964 -0
  8. package/dist/git-utils-BFUgMf2g.js +1 -0
  9. package/dist/{git-utils-DllbRE35.js → git-utils-CrYiSKu0.js} +1 -1
  10. package/dist/{init-wtXaFE45.js → init-CNSqtmPC.js} +19 -19
  11. package/dist/mcp-server.js +5 -5
  12. package/dist/research-CUiuqEKk.js +1 -0
  13. package/dist/response-language-CGnha79j.js +1 -0
  14. package/dist/{response-language-BHhde6n_.js → response-language-Cc70IGmg.js} +1 -1
  15. package/dist/src-lvp18X-h.js +203 -0
  16. package/dist/tag-management-B5XoFcUP.js +1 -0
  17. package/dist/task-manager-BKqm9QPb.js +1 -0
  18. package/dist/taskgraph.js +1 -1
  19. package/dist/update-subtask-by-id-Ct9TTTgG.js +1 -0
  20. package/dist/update-task-by-id-BvdEKXsG.js +1 -0
  21. package/dist/utils-D1-Eo-6k.js +1 -0
  22. package/package.json +2 -4
  23. package/dist/ai-services-unified--6CT6QUI.js +0 -1
  24. package/dist/ai-services-unified-D8PahWkz.js +0 -3
  25. package/dist/config-manager-CvDCaURh.js +0 -1
  26. package/dist/config-manager-DD5sEcpv.js +0 -270
  27. package/dist/dependency-manager-B7SaMC6u.js +0 -966
  28. package/dist/git-utils-PBP1PRVP.js +0 -1
  29. package/dist/research-BRpAIbWg.js +0 -1
  30. package/dist/response-language-Dz-rFnaJ.js +0 -1
  31. package/dist/sentry-DNoFrfjb.js +0 -1
  32. package/dist/tag-management-BEKnBGXA.js +0 -1
  33. package/dist/task-manager-BQkOlw_W.js +0 -1
  34. package/dist/update-subtask-by-id-BOFRADbR.js +0 -1
  35. package/dist/update-task-by-id-DTHqRii_.js +0 -1
  36. package/dist/utils-DYpucGVy.js +0 -1
@@ -0,0 +1 @@
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"./git-utils-CrYiSKu0.js";export{a as checkAndAutoSwitchGitTagSync,n as getCurrentBranch,i as insideGitWorkTree,t as isGitRepository,e as isValidBranchForTag,r as sanitizeBranchNameForTag};
@@ -1 +1 @@
1
- import e from"fs";import t from"path";import{exec as n,execSync as r}from"child_process";import{promisify as i}from"util";const a=i(n);async function o(e){if(!e)throw Error(`projectRoot is required for isGitRepository`);try{return await a(`git rev-parse --git-dir`,{cwd:e}),!0}catch{return!1}}async function s(e){if(!e)throw Error(`projectRoot is required for getCurrentBranch`);try{let{stdout:t}=await a(`git rev-parse --abbrev-ref HEAD`,{cwd:e});return t.trim()}catch{return null}}function c(e){return!e||typeof e!=`string`?`unknown-branch`:e.replace(/[^a-zA-Z0-9_-]/g,`-`).replace(/^-+|-+$/g,``).replace(/-+/g,`-`).toLowerCase().substring(0,50)}function l(e){if(!e||typeof e!=`string`||[`main`,`master`,`develop`,`dev`,`HEAD`].includes(e.toLowerCase()))return!1;let t=c(e);return t.length>0&&t!==`unknown-branch`}function u(e,t){}function d(){try{return r(`git rev-parse --is-inside-work-tree`,{stdio:`ignore`,cwd:process.cwd()}),!0}catch{return!1}}export{l as a,o as i,s as n,c as o,d as r,u as t};
1
+ import e from"path";import{exec as t,execSync as n}from"child_process";import{promisify as r}from"util";import i from"fs";const a=r(t);async function o(e){if(!e)throw Error(`projectRoot is required for isGitRepository`);try{return await a(`git rev-parse --git-dir`,{cwd:e}),!0}catch{return!1}}async function s(e){if(!e)throw Error(`projectRoot is required for getCurrentBranch`);try{let{stdout:t}=await a(`git rev-parse --abbrev-ref HEAD`,{cwd:e});return t.trim()}catch{return null}}function c(e){return!e||typeof e!=`string`?`unknown-branch`:e.replace(/[^a-zA-Z0-9_-]/g,`-`).replace(/^-+|-+$/g,``).replace(/-+/g,`-`).toLowerCase().substring(0,50)}function l(e){if(!e||typeof e!=`string`||[`main`,`master`,`develop`,`dev`,`HEAD`].includes(e.toLowerCase()))return!1;let t=c(e);return t.length>0&&t!==`unknown-branch`}function u(e,t){}function d(){try{return n(`git rev-parse --is-inside-work-tree`,{stdio:`ignore`,cwd:process.cwd()}),!0}catch{return!1}}export{l as a,o as i,s as n,c as o,d as r,u as t};
@@ -1,12 +1,12 @@
1
- import{o as e}from"./ai-services-unified-D8PahWkz.js";import{At as t,Ct as n,Dt as r,Et as i,It as a,Mt as o,N as s,Nt as c,Pt as l,Tt as u,it as d,jt as f,kt as p,rt as m}from"./config-manager-DD5sEcpv.js";import{r as h}from"./git-utils-DllbRE35.js";import{a as ee,dt as g}from"./dependency-manager-B7SaMC6u.js";import _ from"chalk";import*as v from"node:path";import y from"fs";import b from"path";import{randomUUID as x}from"crypto";import S from"os";import*as C from"node:fs";import{execSync as w}from"child_process";import{fileURLToPath as te}from"url";import T from"boxen";import E from"readline";import ne from"figlet";import re from"gradient-string";import ie from"ora";const D=[`claude`];function ae(e){return e.filter(e=>!oe(e))}function oe(e){return D.includes(e)}const O=`# Task files`,k=`tasks.json`,A=`tasks/`;function j(e){return e.trim().replace(/^#/,``).trim()}function M(e){let t=j(e);return t===k||t===A}function se(e,t){return e.map(e=>{if(M(e)){let n=j(e),r=e.match(/\s*$/)[0];return t?`# ${n}${r}`:`${n}${r}`}return e})}function ce(e){let t=[],n=!1;for(let r of e){if(r.trim()===O){n=!0;continue}M(r)||n&&!r.trim()||(n&&r.trim()&&!M(r)&&(n=!1),n||t.push(r))}return t}function le(e,t){return e.filter(e=>{let n=e.trim();return!n||M(e)||n===O?!1:!t.has(n)})}function ue(e){let t=[O];return e?t.push(`# ${k}`,`# ${A} `):t.push(k,`${A} `),t}function N(e){if(e.some(e=>e.trim())){let t=e[e.length-1];t&&t.trim()&&e.push(``)}}function de(e,t,n){if(!e||typeof e!=`string`)throw Error(`targetPath must be a non-empty string`);if(!e.endsWith(`.gitignore`))throw Error(`targetPath must end with .gitignore`);if(!t||typeof t!=`string`)throw Error(`content must be a non-empty string`);if(typeof n!=`boolean`)throw Error(`storeTasksInGit must be a boolean`)}function fe(e,t,n){try{y.writeFileSync(e,t.join(`
1
+ import{o as e}from"./ai-services-unified-DbjBfAvG.js";import{At as t,Ct as n,Dt as r,Mt as i,Ot as a,Pt as o,Tt as s,j as c,jt as l,kt as u,nt as d,tt as f,wt as ee,xt as p}from"./config-manager-Da0wEujO.js";import{r as m}from"./git-utils-CrYiSKu0.js";import{a as h,dt as g}from"./dependency-manager-DIbDdrUV.js";import _ from"chalk";import*as v from"node:path";import y from"path";import*as b from"node:fs";import{execSync as x}from"child_process";import S from"fs";import{fileURLToPath as C}from"url";import w from"boxen";import T from"readline";import te from"figlet";import ne from"gradient-string";import re from"ora";import ie from"os";import{randomUUID as ae}from"crypto";const E=[`claude`];function oe(e){return e.filter(e=>!se(e))}function se(e){return E.includes(e)}const D=`# Task files`,O=`tasks.json`,k=`tasks/`;function A(e){return e.trim().replace(/^#/,``).trim()}function j(e){let t=A(e);return t===O||t===k}function ce(e,t){return e.map(e=>{if(j(e)){let n=A(e),r=e.match(/\s*$/)[0];return t?`# ${n}${r}`:`${n}${r}`}return e})}function le(e){let t=[],n=!1;for(let r of e){if(r.trim()===D){n=!0;continue}j(r)||n&&!r.trim()||(n&&r.trim()&&!j(r)&&(n=!1),n||t.push(r))}return t}function ue(e,t){return e.filter(e=>{let n=e.trim();return!n||j(e)||n===D?!1:!t.has(n)})}function de(e){let t=[D];return e?t.push(`# ${O}`,`# ${k} `):t.push(O,`${k} `),t}function M(e){if(e.some(e=>e.trim())){let t=e[e.length-1];t&&t.trim()&&e.push(``)}}function fe(e,t,n){if(!e||typeof e!=`string`)throw Error(`targetPath must be a non-empty string`);if(!e.endsWith(`.gitignore`))throw Error(`targetPath must end with .gitignore`);if(!t||typeof t!=`string`)throw Error(`content must be a non-empty string`);if(typeof n!=`boolean`)throw Error(`storeTasksInGit must be a boolean`)}function pe(e,t,n){try{S.writeFileSync(e,t.join(`
2
2
  `)+`
3
- `),typeof n==`function`&&n(`success`,`Created ${e} with full template`)}catch(t){throw typeof n==`function`&&n(`error`,`Failed to create ${e}: ${t.message}`),t}}function pe(e,t,n,r){try{let i=ce(y.readFileSync(e,`utf8`).split(`
4
- `)),a=le(t,new Set(i.map(e=>e.trim()).filter(e=>e))),o=[...i];a.length>0&&(N(o),o.push(...a)),N(o),o.push(...ue(n)),y.writeFileSync(e,o.join(`
3
+ `),typeof n==`function`&&n(`success`,`Created ${e} with full template`)}catch(t){throw typeof n==`function`&&n(`error`,`Failed to create ${e}: ${t.message}`),t}}function me(e,t,n,r){try{let i=le(S.readFileSync(e,`utf8`).split(`
4
+ `)),a=ue(t,new Set(i.map(e=>e.trim()).filter(e=>e))),o=[...i];a.length>0&&(M(o),o.push(...a)),M(o),o.push(...de(n)),S.writeFileSync(e,o.join(`
5
5
  `)+`
6
- `),typeof r==`function`&&r(`debug`,`Updated ${e} according to user preference${a.length>0?` and merged new content`:``}`)}catch(t){throw typeof r==`function`&&r(`error`,`Failed to merge content with ${e}: ${t.message}`),t}}function me(e,t,n=!0,r=null){de(e,t,n);let i=se(t.split(`
7
- `),n);y.existsSync(e)?pe(e,i,n,r):fe(e,i,r)}const he=te(import.meta.url),P=b.dirname(he);function F(){let e=[b.join(P,`assets`),b.join(P,`..`,`assets`),b.join(P,`..`,`..`,`public`,`assets`),b.join(process.cwd(),`assets`),b.join(process.cwd(),`node_modules`,`taskgraph-ai`,`dist`,`assets`),b.join(process.cwd(),`node_modules`,`taskgraph-ai`,`assets`)];for(let t of e)if(y.existsSync(t)){let e=b.join(t,`AGENTS.md`);if(y.existsSync(e))return t}throw Error(`Assets directory not found. This is likely a packaging issue.`)}function I(e){let t=F();return b.join(t,e)}function ge(e){try{let t=I(e);return y.existsSync(t)}catch{return!1}}function L(e,t=`utf8`){let n=I(e);return y.readFileSync(n,t)}const R=`taskgraph-ai`;function _e(e){return Array.isArray(e?.args)&&e.args.some(e=>typeof e==`string`&&e.includes(R))}function z(e){let t=JSON.stringify(e,null,` `);return t=t.replace(/(\[\n\t+)([^[\]]+?)(\n\t+\])/g,(e,t,n,r)=>!n.includes(`{`)&&!n.includes(`[`)?`[${n.replace(/\n\t+/g,` `).replace(/\s+/g,` `).trim()}]`:e),t}function ve(e,t){if(!t){d(`debug`,`[MCP Config] No mcpConfigPath provided, skipping MCP configuration setup`);return}let n=b.join(e,t),r=b.dirname(n);d(`info`,`Setting up MCP configuration at ${n}...`);let i={[R]:{command:`npx`,args:[`-y`,R],env:{TASKGRAPH_TOOLS:`core`}}};if(y.existsSync(r)||y.mkdirSync(r,{recursive:!0}),y.existsSync(n)){d(`info`,`MCP configuration file already exists, checking for existing taskgraph-ai...`);try{let e=JSON.parse(y.readFileSync(n,`utf8`));if(e.mcpServers||={},Object.values(e.mcpServers).some(_e)){d(`info`,`Found existing taskgraph-ai MCP configuration in mcp.json, leaving untouched`);return}e.mcpServers[R]?d(`info`,`taskgraph-ai server already configured in mcp.json`):(e.mcpServers[R]=i[R],d(`info`,`Added taskgraph-ai server to existing MCP configuration`)),y.writeFileSync(n,z(e)+`
8
- `),d(`success`,`Updated MCP configuration file`)}catch(e){d(`error`,`Failed to update MCP configuration: ${e.message}`);let t=`${n}.backup-${Date.now()}`;y.existsSync(n)&&(y.copyFileSync(n,t),d(`info`,`Created backup of existing mcp.json at ${t}`));let r={mcpServers:i};y.writeFileSync(n,z(r)+`
9
- `),d(`warn`,`Created new MCP configuration file (backup of original file was created if it existed)`)}}else{let e={mcpServers:i};y.writeFileSync(n,z(e)+`
6
+ `),typeof r==`function`&&r(`debug`,`Updated ${e} according to user preference${a.length>0?` and merged new content`:``}`)}catch(t){throw typeof r==`function`&&r(`error`,`Failed to merge content with ${e}: ${t.message}`),t}}function he(e,t,n=!0,r=null){fe(e,t,n);let i=ce(t.split(`
7
+ `),n);S.existsSync(e)?me(e,i,n,r):pe(e,i,r)}const ge=C(import.meta.url),N=y.dirname(ge);function P(){let e=[y.join(N,`assets`),y.join(N,`..`,`assets`),y.join(N,`..`,`..`,`public`,`assets`),y.join(process.cwd(),`assets`),y.join(process.cwd(),`node_modules`,`taskgraph-ai`,`dist`,`assets`),y.join(process.cwd(),`node_modules`,`taskgraph-ai`,`assets`)];for(let t of e)if(S.existsSync(t)){let e=y.join(t,`AGENTS.md`);if(S.existsSync(e))return t}throw Error(`Assets directory not found. This is likely a packaging issue.`)}function F(e){let t=P();return y.join(t,e)}function I(e){try{let t=F(e);return S.existsSync(t)}catch{return!1}}function L(e,t=`utf8`){let n=F(e);return S.readFileSync(n,t)}const R=`taskgraph-ai`;function _e(e){return Array.isArray(e?.args)&&e.args.some(e=>typeof e==`string`&&e.includes(R))}function z(e){let t=JSON.stringify(e,null,` `);return t=t.replace(/(\[\n\t+)([^[\]]+?)(\n\t+\])/g,(e,t,n,r)=>!n.includes(`{`)&&!n.includes(`[`)?`[${n.replace(/\n\t+/g,` `).replace(/\s+/g,` `).trim()}]`:e),t}function ve(e,t){if(!t){d(`debug`,`[MCP Config] No mcpConfigPath provided, skipping MCP configuration setup`);return}let n=y.join(e,t),r=y.dirname(n);d(`info`,`Setting up MCP configuration at ${n}...`);let i={[R]:{command:`npx`,args:[`-y`,R],env:{TASKGRAPH_TOOLS:`core`}}};if(S.existsSync(r)||S.mkdirSync(r,{recursive:!0}),S.existsSync(n)){d(`info`,`MCP configuration file already exists, checking for existing taskgraph-ai...`);try{let e=JSON.parse(S.readFileSync(n,`utf8`));if(e.mcpServers||={},Object.values(e.mcpServers).some(_e)){d(`info`,`Found existing taskgraph-ai MCP configuration in mcp.json, leaving untouched`);return}e.mcpServers[R]?d(`info`,`taskgraph-ai server already configured in mcp.json`):(e.mcpServers[R]=i[R],d(`info`,`Added taskgraph-ai server to existing MCP configuration`)),S.writeFileSync(n,z(e)+`
8
+ `),d(`success`,`Updated MCP configuration file`)}catch(e){d(`error`,`Failed to update MCP configuration: ${e.message}`);let t=`${n}.backup-${Date.now()}`;S.existsSync(n)&&(S.copyFileSync(n,t),d(`info`,`Created backup of existing mcp.json at ${t}`));let r={mcpServers:i};S.writeFileSync(n,z(r)+`
9
+ `),d(`warn`,`Created new MCP configuration file (backup of original file was created if it existed)`)}}else{let e={mcpServers:i};S.writeFileSync(n,z(e)+`
10
10
  `),d(`success`,`Created MCP configuration file at ${n}`)}d(`info`,`MCP server will use the installed taskgraph-ai package`)}function B(e){let{name:t,description:n,content:r,argumentHint:i,mode:a}=e;return{type:`static`,metadata:{name:t,description:n,...i&&{argumentHint:i},...a&&{mode:a}},content:r}}function V(e,t,n,r,i){if(!r.includes(`$ARGUMENTS`))throw Error(`Dynamic slash command "${e}" must contain $ARGUMENTS placeholder`);return{type:`dynamic`,metadata:{name:e,description:t,argumentHint:n,...i&&{mode:i}},content:r}}const ye=V(`parse-prd`,`Parse PRD`,`<prd-file>`,`Parse a PRD document to generate tasks.
11
11
 
12
12
  Arguments: $ARGUMENTS (PRD file path)
@@ -3439,22 +3439,22 @@ Works well with:
3439
3439
  - CI/CD pipelines
3440
3440
  - Project documentation
3441
3441
  - Team updates
3442
- - Client reports`)];function U(e,t){return t===`team`?e.filter(e=>e.metadata.mode===`team`||e.metadata.mode===`common`||!e.metadata.mode):e.filter(e=>e.metadata.mode===`solo`||e.metadata.mode===`common`||!e.metadata.mode)}U(H,`solo`),U(H,`team`),H.filter(e=>e.metadata.mode===`common`||!e.metadata.mode);var Ge=class{supportsNestedCommands=!0;get supportsCommands(){return this.commandsDir!==``}formatAll(e){return e.map(e=>this.format(e))}getFilename(e){return this.supportsNestedCommands?`${e}${this.extension}`:`tm-${e}${this.extension}`}transformArgumentPlaceholder(e){return e}postProcess(e){return e}getCommandsPath(e){return this.supportsNestedCommands?v.join(e,this.commandsDir,`tm`):v.join(e,this.commandsDir)}addSlashCommands(e,t,n){let r=this.getCommandsPath(e),i=[];if(!this.supportsCommands)return{success:!1,count:0,directory:r,files:[],error:`Profile "${this.name}" does not support slash commands`};try{n?.mode&&this.removeSlashCommands(e,t,!1);let a=n?.mode?U(t,n.mode):t;C.existsSync(r)||C.mkdirSync(r,{recursive:!0});let o=this.formatAll(a);for(let e of o){let t=v.join(r,e.filename);C.writeFileSync(t,e.content),i.push(e.filename)}return{success:!0,count:i.length,directory:r,files:i}}catch(e){return{success:!1,count:0,directory:r,files:[],error:e instanceof Error?e.message:String(e)}}}removeSlashCommands(e,t,n=!0){let r=this.getCommandsPath(e),i=[];if(!this.supportsCommands)return{success:!1,count:0,directory:r,files:[],error:`Profile "${this.name}" does not support slash commands`};if(!C.existsSync(r))return{success:!0,count:0,directory:r,files:[]};try{let e=new Set(t.map(e=>{let t=e.metadata.name.toLowerCase();return this.supportsNestedCommands?t:`tm-${t}`})),a=C.readdirSync(r);for(let t of a){let n=v.basename(t,v.extname(t)).toLowerCase();if(e.has(n)){let e=v.join(r,t);C.rmSync(e,{force:!0}),i.push(t)}}return n&&C.readdirSync(r).length===0&&C.rmSync(r,{recursive:!0,force:!0}),{success:!0,count:i.length,directory:r,files:i}}catch(e){return{success:!1,count:i.length,directory:r,files:i,error:e instanceof Error?e.message:String(e)}}}replaceSlashCommands(e,t,n){let r=this.removeSlashCommands(e,t);return r.success?this.addSlashCommands(e,t,{mode:n}):r}};const Ke={claude:new class extends Ge{name=`claude`;displayName=`Claude Code`;commandsDir=`.claude/commands`;extension=`.md`;format(e){let t=this.buildHeader(e),n=this.transformArgumentPlaceholder(e.content);return{filename:this.getFilename(e.metadata.name),content:`${t}${n}`}}buildHeader(e){let t=[e.metadata.description,``];return e.metadata.argumentHint&&(t.push(`Arguments: $ARGUMENTS`),t.push(``)),t.join(`
3443
- `)}}};function qe(e){return Ke[e.toLowerCase()]}function Je(){let e=S.homedir(),t=process.env.SHELL||``;if(t.includes(`zsh`))return b.join(e,`.zshrc`);if(t.includes(`bash`)){let t=b.join(e,`.bash_profile`);return process.platform===`darwin`?t:b.join(e,`.bashrc`)}if(t.includes(`fish`))return b.join(e,`.config`,`fish`,`config.fish`);if(process.platform===`win32`){if(process.env.PSModulePath){let t=process.env.PROFILE||b.join(e,`Documents`,`WindowsPowerShell`,`Microsoft.PowerShell_profile.ps1`),n=b.join(e,`Documents`,`PowerShell`,`Microsoft.PowerShell_profile.ps1`);return y.existsSync(n)?n:y.existsSync(t)?t:n}let t=b.join(e,`.bashrc`);if(y.existsSync(t))return t}let n=b.join(e,`.zshrc`);if(y.existsSync(n))return n;let r=b.join(e,`.bashrc`);return y.existsSync(r)?r:null}function W(e){return e.endsWith(`.ps1`)}function G(e){return e.includes(`config.fish`)}function Ye(e,t,n){if(!/^[A-Z_][A-Z0-9_]*$/i.test(e))return{success:!1,message:`Invalid environment variable name: ${e}. Must start with a letter or underscore and contain only alphanumeric characters and underscores.`};if(typeof t!=`string`||t.includes(`
3444
- `)||t.includes(`\r`))return{success:!1,message:`Invalid value: must be a single-line string without newlines`};let r=Je();if(!r)return{success:!1,message:`Could not determine shell type (zsh, bash, fish, or PowerShell)`};try{let i=b.dirname(r);if(y.existsSync(i)||y.mkdirSync(i,{recursive:!0}),!y.existsSync(r)){let e=process.platform===`darwin`&&r.endsWith(`.bash_profile`);if(W(r)||e)y.writeFileSync(r,``);else return{success:!1,shellConfigFile:r,message:`Shell config file ${r} not found`}}let a=y.readFileSync(r,`utf8`),o;if(o=W(r)?RegExp(`^\\s*\\$env:${e}\\s*=`,`m`).test(a):G(r)?RegExp(`^\\s*set\\s+-[gux]*x[gux]*\\s+${e}\\s+`,`m`).test(a):RegExp(`^\\s*export\\s+${e}\\s*=`,`m`).test(a),o)return{success:!0,shellConfigFile:r,message:`${e} already configured`,alreadyExists:!0};let s,c;W(r)?(s=`$env:${e} = "${t.replace(/["`$]/g,"`$&")}"`,c=`#`):G(r)?(s=`set -gx ${e} '${t.replace(/'/g,`'\\''`)}'`,c=`#`):(s=`export ${e}='${t.replace(/'/g,`'\\''`)}'`,c=`#`);let l=`\n${n?`${c} ${n}\n`:``}${s}\n`;return y.appendFileSync(r,l),{success:!0,shellConfigFile:r,message:`Added ${e} to ${r}`}}catch(e){return{success:!1,shellConfigFile:r,message:`Failed to modify shell config: ${e.message}`}}}function Xe(){return Ye(`ENABLE_EXPERIMENTAL_MCP_CLI`,`true`,`Claude Code deferred MCP loading (added by TaskGraph)`)}function Ze(e){let{name:t,displayName:n=t,profileDir:r=`.${t.toLowerCase()}`,rulesDir:i=`${r}/rules`,mcpConfig:a=!0,mcpConfigName:o=a?`mcp.json`:null,fileMap:s={},onAdd:c,onPostConvert:l}=e,u=o?b.join(r,o):null,f=null;try{let e=qe(t);e?.supportsCommands&&(f={profile:e,commands:H})}catch(e){d(`debug`,`[${n}] Slash command profile lookup failed: ${e.message}`)}return{profileName:t,displayName:n,profileDir:r,rulesDir:i,mcpConfig:a,mcpConfigName:o,mcpConfigPath:u,fileMap:s,slashCommands:f,...c&&{onAddRulesProfile:c},...l&&{onPostConvertRulesProfile:l}}}function Qe(e,t){d(`info`,`[Claude] Commands and agents are now available via the TaskGraph plugin`),d(`info`,`[Claude] Install with: /plugin marketplace add taskgraph`),d(`info`,`[Claude] Then: /plugin install taskgraph@taskgraph`);let n=b.join(t,`AGENTS.md`),r=b.join(e,`CLAUDE.md`),i=b.join(e,`.taskgraph`,`CLAUDE.md`),a=`@./.taskgraph/CLAUDE.md`,o=`\n## TaskGraph Instructions\n**Import TaskGraph's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n${a}`;if(y.existsSync(n))try{let t=b.join(e,`.taskgraph`);if(y.existsSync(t)||y.mkdirSync(t,{recursive:!0}),y.copyFileSync(n,i),d(`debug`,`[Claude] Created TaskGraph instructions at ${i}`),y.existsSync(r)){let e=y.readFileSync(r,`utf8`);if(e.includes(a))d(`info`,`[Claude] TaskGraph import already present in ${r}`);else{let t=e.trim()+`
3442
+ - Client reports`)];function U(e,t){return t===`team`?e.filter(e=>e.metadata.mode===`team`||e.metadata.mode===`common`||!e.metadata.mode):e.filter(e=>e.metadata.mode===`solo`||e.metadata.mode===`common`||!e.metadata.mode)}U(H,`solo`),U(H,`team`),H.filter(e=>e.metadata.mode===`common`||!e.metadata.mode);var Ge=class{supportsNestedCommands=!0;get supportsCommands(){return this.commandsDir!==``}formatAll(e){return e.map(e=>this.format(e))}getFilename(e){return this.supportsNestedCommands?`${e}${this.extension}`:`tm-${e}${this.extension}`}transformArgumentPlaceholder(e){return e}postProcess(e){return e}getCommandsPath(e){return this.supportsNestedCommands?v.join(e,this.commandsDir,`tm`):v.join(e,this.commandsDir)}addSlashCommands(e,t,n){let r=this.getCommandsPath(e),i=[];if(!this.supportsCommands)return{success:!1,count:0,directory:r,files:[],error:`Profile "${this.name}" does not support slash commands`};try{n?.mode&&this.removeSlashCommands(e,t,!1);let a=n?.mode?U(t,n.mode):t;b.existsSync(r)||b.mkdirSync(r,{recursive:!0});let o=this.formatAll(a);for(let e of o){let t=v.join(r,e.filename);b.writeFileSync(t,e.content),i.push(e.filename)}return{success:!0,count:i.length,directory:r,files:i}}catch(e){return{success:!1,count:0,directory:r,files:[],error:e instanceof Error?e.message:String(e)}}}removeSlashCommands(e,t,n=!0){let r=this.getCommandsPath(e),i=[];if(!this.supportsCommands)return{success:!1,count:0,directory:r,files:[],error:`Profile "${this.name}" does not support slash commands`};if(!b.existsSync(r))return{success:!0,count:0,directory:r,files:[]};try{let e=new Set(t.map(e=>{let t=e.metadata.name.toLowerCase();return this.supportsNestedCommands?t:`tm-${t}`})),a=b.readdirSync(r);for(let t of a){let n=v.basename(t,v.extname(t)).toLowerCase();if(e.has(n)){let e=v.join(r,t);b.rmSync(e,{force:!0}),i.push(t)}}return n&&b.readdirSync(r).length===0&&b.rmSync(r,{recursive:!0,force:!0}),{success:!0,count:i.length,directory:r,files:i}}catch(e){return{success:!1,count:i.length,directory:r,files:i,error:e instanceof Error?e.message:String(e)}}}replaceSlashCommands(e,t,n){let r=this.removeSlashCommands(e,t);return r.success?this.addSlashCommands(e,t,{mode:n}):r}};const Ke={claude:new class extends Ge{name=`claude`;displayName=`Claude Code`;commandsDir=`.claude/commands`;extension=`.md`;format(e){let t=this.buildHeader(e),n=this.transformArgumentPlaceholder(e.content);return{filename:this.getFilename(e.metadata.name),content:`${t}${n}`}}buildHeader(e){let t=[e.metadata.description,``];return e.metadata.argumentHint&&(t.push(`Arguments: $ARGUMENTS`),t.push(``)),t.join(`
3443
+ `)}}};function qe(e){return Ke[e.toLowerCase()]}function Je(){let e=ie.homedir(),t=process.env.SHELL||``;if(t.includes(`zsh`))return y.join(e,`.zshrc`);if(t.includes(`bash`)){let t=y.join(e,`.bash_profile`);return process.platform===`darwin`?t:y.join(e,`.bashrc`)}if(t.includes(`fish`))return y.join(e,`.config`,`fish`,`config.fish`);if(process.platform===`win32`){if(process.env.PSModulePath){let t=process.env.PROFILE||y.join(e,`Documents`,`WindowsPowerShell`,`Microsoft.PowerShell_profile.ps1`),n=y.join(e,`Documents`,`PowerShell`,`Microsoft.PowerShell_profile.ps1`);return S.existsSync(n)?n:S.existsSync(t)?t:n}let t=y.join(e,`.bashrc`);if(S.existsSync(t))return t}let n=y.join(e,`.zshrc`);if(S.existsSync(n))return n;let r=y.join(e,`.bashrc`);return S.existsSync(r)?r:null}function W(e){return e.endsWith(`.ps1`)}function G(e){return e.includes(`config.fish`)}function Ye(e,t,n){if(!/^[A-Z_][A-Z0-9_]*$/i.test(e))return{success:!1,message:`Invalid environment variable name: ${e}. Must start with a letter or underscore and contain only alphanumeric characters and underscores.`};if(typeof t!=`string`||t.includes(`
3444
+ `)||t.includes(`\r`))return{success:!1,message:`Invalid value: must be a single-line string without newlines`};let r=Je();if(!r)return{success:!1,message:`Could not determine shell type (zsh, bash, fish, or PowerShell)`};try{let i=y.dirname(r);if(S.existsSync(i)||S.mkdirSync(i,{recursive:!0}),!S.existsSync(r)){let e=process.platform===`darwin`&&r.endsWith(`.bash_profile`);if(W(r)||e)S.writeFileSync(r,``);else return{success:!1,shellConfigFile:r,message:`Shell config file ${r} not found`}}let a=S.readFileSync(r,`utf8`),o;if(o=W(r)?RegExp(`^\\s*\\$env:${e}\\s*=`,`m`).test(a):G(r)?RegExp(`^\\s*set\\s+-[gux]*x[gux]*\\s+${e}\\s+`,`m`).test(a):RegExp(`^\\s*export\\s+${e}\\s*=`,`m`).test(a),o)return{success:!0,shellConfigFile:r,message:`${e} already configured`,alreadyExists:!0};let s,c;W(r)?(s=`$env:${e} = "${t.replace(/["`$]/g,"`$&")}"`,c=`#`):G(r)?(s=`set -gx ${e} '${t.replace(/'/g,`'\\''`)}'`,c=`#`):(s=`export ${e}='${t.replace(/'/g,`'\\''`)}'`,c=`#`);let l=`\n${n?`${c} ${n}\n`:``}${s}\n`;return S.appendFileSync(r,l),{success:!0,shellConfigFile:r,message:`Added ${e} to ${r}`}}catch(e){return{success:!1,shellConfigFile:r,message:`Failed to modify shell config: ${e.message}`}}}function Xe(){return Ye(`ENABLE_EXPERIMENTAL_MCP_CLI`,`true`,`Claude Code deferred MCP loading (added by TaskGraph)`)}function Ze(e){let{name:t,displayName:n=t,profileDir:r=`.${t.toLowerCase()}`,rulesDir:i=`${r}/rules`,mcpConfig:a=!0,mcpConfigName:o=a?`mcp.json`:null,fileMap:s={},onAdd:c,onPostConvert:l}=e,u=o?y.join(r,o):null,f=null;try{let e=qe(t);e?.supportsCommands&&(f={profile:e,commands:H})}catch(e){d(`debug`,`[${n}] Slash command profile lookup failed: ${e.message}`)}return{profileName:t,displayName:n,profileDir:r,rulesDir:i,mcpConfig:a,mcpConfigName:o,mcpConfigPath:u,fileMap:s,slashCommands:f,...c&&{onAddRulesProfile:c},...l&&{onPostConvertRulesProfile:l}}}function Qe(e,t){d(`info`,`[Claude] Commands and agents are now available via the TaskGraph plugin`),d(`info`,`[Claude] Install with: /plugin marketplace add taskgraph`),d(`info`,`[Claude] Then: /plugin install taskgraph@taskgraph`);let n=y.join(t,`AGENTS.md`),r=y.join(e,`CLAUDE.md`),i=y.join(e,`.taskgraph`,`CLAUDE.md`),a=`@./.taskgraph/CLAUDE.md`,o=`\n## TaskGraph Instructions\n**Import TaskGraph's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n${a}`;if(S.existsSync(n))try{let t=y.join(e,`.taskgraph`);if(S.existsSync(t)||S.mkdirSync(t,{recursive:!0}),S.copyFileSync(n,i),d(`debug`,`[Claude] Created TaskGraph instructions at ${i}`),S.existsSync(r)){let e=S.readFileSync(r,`utf8`);if(e.includes(a))d(`info`,`[Claude] TaskGraph import already present in ${r}`);else{let t=e.trim()+`
3445
3445
  `+o+`
3446
- `;y.writeFileSync(r,t),d(`info`,`[Claude] Added TaskGraph import to existing ${r}`)}}else{let e=`# Claude Code Instructions\n${o}\n`;y.writeFileSync(r,e),d(`info`,`[Claude] Created ${r} with TaskGraph import`)}}catch(e){d(`error`,`[Claude] Failed to set up Claude instructions: ${e.message}`)}let s=Xe();s.success?s.alreadyExists?d(`debug`,`[Claude] Deferred MCP loading already configured`):(d(`info`,`[Claude] Enabled deferred MCP loading in ${s.shellConfigFile}`),d(`info`,`[Claude] Restart your terminal for changes to take effect`)):d(`debug`,`[Claude] Could not configure deferred loading: ${s.message}`)}function $e(e){let t={};if(e.mcpServers){t.mcpServers={};for(let[n,r]of Object.entries(e.mcpServers)){let e={};e.type=`stdio`,r.command&&(e.command=r.command),r.args&&(e.args=r.args),r.env&&(e.env=r.env),Object.keys(r).forEach(t=>{[`command`,`args`,`env`,`type`].includes(t)||(e[t]=r[t])}),t.mcpServers[n]=e}}return t}function et(e,t){let n=b.join(e,`.mcp.json`);if(y.existsSync(n))try{let e=$e(JSON.parse(y.readFileSync(n,`utf8`)));y.writeFileSync(n,JSON.stringify(e,null,` `)+`
3447
- `),d(`debug`,`[Claude] Transformed MCP configuration to Claude format at ${n}`)}catch(e){d(`error`,`[Claude] Failed to transform MCP configuration: ${e.message}`)}}const tt=Ze({name:`claude`,displayName:`Claude Code`,profileDir:`.`,rulesDir:`.`,mcpConfigName:`.mcp.json`,fileMap:{"AGENTS.md":`.taskgraph/CLAUDE.md`},onAdd:Qe,onPostConvert:et});var nt=e({claudeProfile:()=>tt});function rt(e){return D.includes(e)}function it(e){if(!rt(e))return null;let t=nt[`${e}Profile`];if(!t)throw Error(`Profile not found: static import missing for '${e}'. Valid profiles: ${D.join(`, `)}`);return t}function at(e,t,n){let r=b.join(e,t.rulesDir),i=n?.mode,a=0;if(typeof t.onAddRulesProfile==`function`)try{t.onAddRulesProfile(r,F()),d(`debug`,`[Rule Transformer] Called onAddRulesProfile for ${t.profileName}`)}catch(e){d(`error`,`[Rule Transformer] onAddRulesProfile failed for ${t.profileName}: ${e.message}`),a++}if(t.mcpConfig!==!1)try{ve(e,t.mcpConfigPath),d(`debug`,`[Rule Transformer] Setup MCP configuration for ${t.profileName}`)}catch(e){d(`error`,`[Rule Transformer] MCP setup failed for ${t.profileName}: ${e.message}`)}if(typeof t.onPostConvertRulesProfile==`function`)try{t.onPostConvertRulesProfile(r,F()),d(`debug`,`[Rule Transformer] Called onPostConvertRulesProfile for ${t.profileName}`)}catch(e){d(`error`,`[Rule Transformer] onPostConvertRulesProfile failed for ${t.profileName}: ${e.message}`)}if(t.slashCommands)try{let n=i?{mode:i}:void 0,r=t.slashCommands.profile.addSlashCommands(e,t.slashCommands.commands,n);r.success?d(`debug`,`[Rule Transformer] Created ${r.count} slash commands in ${r.directory}${i?` (mode: ${i})`:``}`):d(`error`,`[Rule Transformer] Failed to add slash commands for ${t.profileName}: ${r.error}`)}catch(e){d(`error`,`[Rule Transformer] Slash commands failed for ${t.profileName}: ${e.message}`)}return{success:1,failed:a}}function ot(){let e=(e,t)=>`${n.text(`${e}. `)}${_.yellow(t)}`,t=(e,t)=>`${n.text(e?` └─ `:` ├─ `)}${t}`,r=e=>`${_.dim(`CLI: `)}${_.cyan(e)}`,i=[e(1,`Choose your AI models (optional)`),t(!1,`${_.dim(`Models: Use `)}${_.cyan(`taskgraph models --setup`)}`),t(!0,_.dim("AI calls run through your signed-in Claude Code (run `claude` once to sign in)")),e(2,`Discuss your idea with AI and create a PRD`),t(!1,`${_.dim(`Simple projects: Use `)}${_.cyan(`example_prd.txt`)}${_.dim(` template`)}`),t(!0,`${_.dim(`Complex systems: Use `)}${_.cyan(`example_prd_rpg.txt`)}${_.dim(` template`)}`),e(3,`Parse your PRD to generate initial tasks`),t(!0,r(`taskgraph parse-prd .taskgraph/docs/prd.md`)),e(4,`Analyze task complexity`),t(!0,r(`taskgraph analyze-complexity --research`)),e(5,`Expand tasks into subtasks`),t(!0,r(`taskgraph expand --all --research`)),e(6,`Start working on tasks`),t(!0,r(`taskgraph next`)),`${n.text(`7. `)}${_.green.bold(`Ship it!`)}`],a=`${_.dim(`* Run `)}${_.cyan(`taskgraph --help`)}${_.dim(` to see all available commands`)}`;return`${_.cyan.bold(`Things you should do next:`)}\n\n${i.join(`
3448
- `)}\n\n${a}`}function st(e){try{let t=JSON.parse(y.readFileSync(e,`utf-8`));for(let e of[`main`,`research`,`fallback`])if(t.models&&t.models[e]){let n=t.models[e].provider,r=t.models[e].modelId;if(s[n]){let i=s[n].find(e=>e.id===r);i&&i.max_tokens&&(t.models[e].maxTokens=i.max_tokens)}}return y.writeFileSync(e,JSON.stringify(t,null,2)),!0}catch(e){return console.error(`Error updating config maxTokens:`,e.message),!1}}const K={debug:0,info:1,warn:2,error:3,success:4},q=process.env.TASKGRAPH_LOG_LEVEL?K[process.env.TASKGRAPH_LOG_LEVEL.toLowerCase()]:K.info;function ct(){m()||g()}function J(e,...t){let r={debug:n.muted(`•`),info:n.brand(`→`),warn:_.yellow(`!`),error:_.red(`✗`),success:_.green(`✓`)};if(K[e]>=q){let i=r[e]||``;m()||(e===`error`?console.error(i,_.red(...t)):e===`warn`?console.warn(i,_.yellow(...t)):e===`success`?console.log(i,_.green(...t)):e===`info`?console.log(i,n.brand(...t)):console.log(i,...t))}if(process.env.DEBUG===`true`){let n=`[${e.toUpperCase()}] ${t.join(` `)}\n`;y.appendFileSync(`init-debug.log`,n)}}function Y(e){y.existsSync(e)||(y.mkdirSync(e,{recursive:!0}),J(`info`,`Created directory: ${e}`))}function X(){let e=process.env.HOME||process.env.USERPROFILE,t;if(process.env.SHELL?.includes(`zsh`))t=b.join(e,`.zshrc`);else if(process.env.SHELL?.includes(`bash`))t=b.join(e,`.bashrc`);else return J(`debug`,`Could not determine shell type. Aliases not added.`),!1;try{if(!y.existsSync(t))return J(`debug`,`Shell config file ${t} not found.`),!1;let e=y.readFileSync(t,`utf8`),n=[{name:`tm`,line:`alias tm='taskgraph'`},{name:`taskgraph`,line:`alias taskgraph='taskgraph'`}].filter(t=>!e.includes(t.line));if(n.length===0)return J(`debug`,`All TaskGraph aliases already exist.`),!0;let r=n.map(e=>e.line).join(`
3446
+ `;S.writeFileSync(r,t),d(`info`,`[Claude] Added TaskGraph import to existing ${r}`)}}else{let e=`# Claude Code Instructions\n${o}\n`;S.writeFileSync(r,e),d(`info`,`[Claude] Created ${r} with TaskGraph import`)}}catch(e){d(`error`,`[Claude] Failed to set up Claude instructions: ${e.message}`)}let s=Xe();s.success?s.alreadyExists?d(`debug`,`[Claude] Deferred MCP loading already configured`):(d(`info`,`[Claude] Enabled deferred MCP loading in ${s.shellConfigFile}`),d(`info`,`[Claude] Restart your terminal for changes to take effect`)):d(`debug`,`[Claude] Could not configure deferred loading: ${s.message}`)}function $e(e){let t={};if(e.mcpServers){t.mcpServers={};for(let[n,r]of Object.entries(e.mcpServers)){let e={};e.type=`stdio`,r.command&&(e.command=r.command),r.args&&(e.args=r.args),r.env&&(e.env=r.env),Object.keys(r).forEach(t=>{[`command`,`args`,`env`,`type`].includes(t)||(e[t]=r[t])}),t.mcpServers[n]=e}}return t}function et(e,t){let n=y.join(e,`.mcp.json`);if(S.existsSync(n))try{let e=$e(JSON.parse(S.readFileSync(n,`utf8`)));S.writeFileSync(n,JSON.stringify(e,null,` `)+`
3447
+ `),d(`debug`,`[Claude] Transformed MCP configuration to Claude format at ${n}`)}catch(e){d(`error`,`[Claude] Failed to transform MCP configuration: ${e.message}`)}}const tt=Ze({name:`claude`,displayName:`Claude Code`,profileDir:`.`,rulesDir:`.`,mcpConfigName:`.mcp.json`,fileMap:{"AGENTS.md":`.taskgraph/CLAUDE.md`},onAdd:Qe,onPostConvert:et});var nt=e({claudeProfile:()=>tt});function rt(e){return E.includes(e)}function it(e){if(!rt(e))return null;let t=nt[`${e}Profile`];if(!t)throw Error(`Profile not found: static import missing for '${e}'. Valid profiles: ${E.join(`, `)}`);return t}function at(e,t,n){let r=y.join(e,t.rulesDir),i=n?.mode,a=0;if(typeof t.onAddRulesProfile==`function`)try{t.onAddRulesProfile(r,P()),d(`debug`,`[Rule Transformer] Called onAddRulesProfile for ${t.profileName}`)}catch(e){d(`error`,`[Rule Transformer] onAddRulesProfile failed for ${t.profileName}: ${e.message}`),a++}if(t.mcpConfig!==!1)try{ve(e,t.mcpConfigPath),d(`debug`,`[Rule Transformer] Setup MCP configuration for ${t.profileName}`)}catch(e){d(`error`,`[Rule Transformer] MCP setup failed for ${t.profileName}: ${e.message}`)}if(typeof t.onPostConvertRulesProfile==`function`)try{t.onPostConvertRulesProfile(r,P()),d(`debug`,`[Rule Transformer] Called onPostConvertRulesProfile for ${t.profileName}`)}catch(e){d(`error`,`[Rule Transformer] onPostConvertRulesProfile failed for ${t.profileName}: ${e.message}`)}if(t.slashCommands)try{let n=i?{mode:i}:void 0,r=t.slashCommands.profile.addSlashCommands(e,t.slashCommands.commands,n);r.success?d(`debug`,`[Rule Transformer] Created ${r.count} slash commands in ${r.directory}${i?` (mode: ${i})`:``}`):d(`error`,`[Rule Transformer] Failed to add slash commands for ${t.profileName}: ${r.error}`)}catch(e){d(`error`,`[Rule Transformer] Slash commands failed for ${t.profileName}: ${e.message}`)}return{success:1,failed:a}}function ot(){let e=(e,t)=>`${p.text(`${e}. `)}${_.yellow(t)}`,t=(e,t)=>`${p.text(e?` └─ `:` ├─ `)}${t}`,n=e=>`${_.dim(`CLI: `)}${_.cyan(e)}`,r=[e(1,`Choose your AI models (optional)`),t(!1,`${_.dim(`Models: Use `)}${_.cyan(`taskgraph models --setup`)}`),t(!0,_.dim("AI calls run through your signed-in Claude Code (run `claude` once to sign in)")),e(2,`Discuss your idea with AI and create a PRD`),t(!1,`${_.dim(`Simple projects: Use `)}${_.cyan(`example_prd.txt`)}${_.dim(` template`)}`),t(!0,`${_.dim(`Complex systems: Use `)}${_.cyan(`example_prd_rpg.txt`)}${_.dim(` template`)}`),e(3,`Parse your PRD to generate initial tasks`),t(!0,n(`taskgraph parse-prd .taskgraph/docs/prd.md`)),e(4,`Analyze task complexity`),t(!0,n(`taskgraph analyze-complexity --research`)),e(5,`Expand tasks into subtasks`),t(!0,n(`taskgraph expand --all --research`)),e(6,`Start working on tasks`),t(!0,n(`taskgraph next`)),`${p.text(`7. `)}${_.green.bold(`Ship it!`)}`],i=`${_.dim(`* Run `)}${_.cyan(`taskgraph --help`)}${_.dim(` to see all available commands`)}`;return`${_.cyan.bold(`Things you should do next:`)}\n\n${r.join(`
3448
+ `)}\n\n${i}`}function st(e){try{let t=JSON.parse(S.readFileSync(e,`utf-8`));for(let e of[`main`,`research`,`fallback`])if(t.models&&t.models[e]){let n=t.models[e].provider,r=t.models[e].modelId;if(c[n]){let i=c[n].find(e=>e.id===r);i&&i.max_tokens&&(t.models[e].maxTokens=i.max_tokens)}}return S.writeFileSync(e,JSON.stringify(t,null,2)),!0}catch(e){return console.error(`Error updating config maxTokens:`,e.message),!1}}const K={debug:0,info:1,warn:2,error:3,success:4},q=process.env.TASKGRAPH_LOG_LEVEL?K[process.env.TASKGRAPH_LOG_LEVEL.toLowerCase()]:K.info;function ct(){f()||g()}function J(e,...t){let n={debug:p.muted(`•`),info:p.brand(`→`),warn:_.yellow(`!`),error:_.red(`✗`),success:_.green(`✓`)};if(K[e]>=q){let r=n[e]||``;f()||(e===`error`?console.error(r,_.red(...t)):e===`warn`?console.warn(r,_.yellow(...t)):e===`success`?console.log(r,_.green(...t)):e===`info`?console.log(r,p.brand(...t)):console.log(r,...t))}if(process.env.DEBUG===`true`){let n=`[${e.toUpperCase()}] ${t.join(` `)}\n`;S.appendFileSync(`init-debug.log`,n)}}function Y(e){S.existsSync(e)||(S.mkdirSync(e,{recursive:!0}),J(`info`,`Created directory: ${e}`))}function X(){let e=process.env.HOME||process.env.USERPROFILE,t;if(process.env.SHELL?.includes(`zsh`))t=y.join(e,`.zshrc`);else if(process.env.SHELL?.includes(`bash`))t=y.join(e,`.bashrc`);else return J(`debug`,`Could not determine shell type. Aliases not added.`),!1;try{if(!S.existsSync(t))return J(`debug`,`Shell config file ${t} not found.`),!1;let e=S.readFileSync(t,`utf8`),n=[{name:`tm`,line:`alias tm='taskgraph'`},{name:`taskgraph`,line:`alias taskgraph='taskgraph'`}].filter(t=>!e.includes(t.line));if(n.length===0)return J(`debug`,`All TaskGraph aliases already exist.`),!0;let r=n.map(e=>e.line).join(`
3449
3449
  `),i=`
3450
3450
  # TaskGraph aliases added on ${new Date().toLocaleDateString()}
3451
3451
  ${r}
3452
- `;return y.appendFileSync(t,i),J(`debug`,`Added ${n.length} alias(es): ${n.map(e=>e.name).join(`, `)}`),!0}catch(e){return J(`debug`,`Failed to add aliases: ${e.message}`),!1}}function lt(e){let t=b.join(e,c);if(y.existsSync(t)){J(`debug`,`State file already exists, preserving current configuration`);return}let n={currentTag:`master`,lastSwitched:new Date().toISOString(),branchTagMapping:{},migrationNoticeShown:!1};try{y.writeFileSync(t,JSON.stringify(n,null,2)),J(`success`,`Created initial state file: ${t}`),J(`info`,`Default tag set to "master" for task organization`)}catch(e){J(`error`,`Failed to create state file: ${e.message}`)}}function Z(e,t,n={}){if(!ge(e)){J(`error`,`Source file not found: ${e}`);return}let r=L(e,`utf8`);if(Object.entries(n).forEach(([e,t])=>{let n=RegExp(`\\{\\{${e}\\}\\}`,`g`);r=r.replace(n,t)}),y.existsSync(t)){let e=b.basename(t);if(e===`.gitignore`){J(`info`,`${t} already exists, merging content...`);let e=y.readFileSync(t,`utf8`),n=new Set(e.split(`
3452
+ `;return S.appendFileSync(t,i),J(`debug`,`Added ${n.length} alias(es): ${n.map(e=>e.name).join(`, `)}`),!0}catch(e){return J(`debug`,`Failed to add aliases: ${e.message}`),!1}}function lt(e){let t=y.join(e,l);if(S.existsSync(t)){J(`debug`,`State file already exists, preserving current configuration`);return}let n={currentTag:`master`,lastSwitched:new Date().toISOString(),branchTagMapping:{},migrationNoticeShown:!1};try{S.writeFileSync(t,JSON.stringify(n,null,2)),J(`success`,`Created initial state file: ${t}`),J(`info`,`Default tag set to "master" for task organization`)}catch(e){J(`error`,`Failed to create state file: ${e.message}`)}}function Z(e,t,n={}){if(!I(e)){J(`error`,`Source file not found: ${e}`);return}let r=L(e,`utf8`);if(Object.entries(n).forEach(([e,t])=>{let n=RegExp(`\\{\\{${e}\\}\\}`,`g`);r=r.replace(n,t)}),S.existsSync(t)){let e=y.basename(t);if(e===`.gitignore`){J(`info`,`${t} already exists, merging content...`);let e=S.readFileSync(t,`utf8`),n=new Set(e.split(`
3453
3453
  `).map(e=>e.trim())),i=r.split(`
3454
3454
  `).filter(e=>!n.has(e.trim()));if(i.length>0){let n=`${e.trim()}\n\n# Added by TaskGraph\n${i.join(`
3455
- `)}`;y.writeFileSync(t,n),J(`success`,`Updated ${t} with additional entries`)}else J(`info`,`No new content to add to ${t}`);return}if(e===`README-taskgraph.md`){J(`info`,`${t} already exists`);let e=b.join(b.dirname(t),`README-taskgraph.md`);y.writeFileSync(e,r),J(`success`,`Created ${e} (preserved original README-taskgraph.md)`);return}J(`debug`,`${t} already exists, skipping.`);return}y.writeFileSync(t,r),J(`info`,`Created file: ${t}`)}async function ut(e={}){m()||ct(),e.git===!0?e.initGit=!0:e.git===!1&&(e.initGit=!1),e.gitTasks===!0?e.storeTasksInGit=!0:e.gitTasks===!1&&(e.storeTasksInGit=!1);let t=e.yes||e.name&&e.description,r;if(r=e.rulesExplicitlyProvided?e.rules:[],t){m()||console.log(`SKIPPING PROMPTS - Using defaults or provided values`),e.name,e.description,e.version,e.author;let t=e.dryRun||!1,n=e.initGit===void 0?!0:e.initGit,i=e.storeTasksInGit===void 0?!0:e.storeTasksInGit;if(t)return J(`info`,`DRY RUN MODE: No files will be modified`),J(`info`,`Would initialize TaskGraph project`),J(`info`,`Would create/update necessary project files`),J(`info`,`${n?`Would initialize Git repository`:`Would skip Git initialization`}`),J(`info`,`${i?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};await $(!0,n,i,t,{...e,preferredLanguage:`English`},r)}else{J(`debug`,`Required options not provided, proceeding with prompts.`);let t;try{J(`debug`,`Init started - taskgraph_id: ${dt()}`),t=E.createInterface({input:process.stdin,output:process.stdout});let i=!0,a=!0;i=e.initGit===void 0?(await Q(t,_.cyan(`Initialize a Git repository in project root? (Y/n): `),e=>{let t=e.trim().toLowerCase()!==`n`,n=t?_.green(`✓`):_.red(`✗`);return _.cyan(`Initialize a Git repository in project root?`)+` `+n+` `+_.dim(t?`Yes`:`No`)})).trim().toLowerCase()!==`n`:e.initGit,a=e.storeTasksInGit===void 0?(await Q(t,_.cyan(`Store tasks in Git (tasks.json and tasks/ directory)? (Y/n): `),e=>{let t=e.trim().toLowerCase()!==`n`,n=t?_.green(`✓`):_.red(`✗`);return _.cyan(`Store tasks in Git (tasks.json and tasks/ directory)?`)+` `+n+` `+_.dim(t?`Yes`:`No`)})).trim().toLowerCase()!==`n`:e.storeTasksInGit;let o=!1;e.rulesExplicitlyProvided?J(`info`,`Using rule profiles provided via command line: ${r.join(`, `)}`):o=(await Q(t,_.cyan(`Set up Claude Code integration (CLAUDE.md import)? (y/N): `),e=>{let t=e.trim().toLowerCase()===`y`,n=t?_.green(`✓`):_.red(`✗`);return _.cyan(`Set up Claude Code integration?`)+` `+n+` `+_.dim(t?`Yes`:`No`)})).trim().toLowerCase()===`y`;let s=(await Q(t,_.cyan(`Preferred response language (English): `))).trim()||`English`;console.log(`
3456
- `+_.bold(`TaskGraph Project Settings:`)),console.log(_.dim(`─`.repeat(50)));let c=o?_.green(`✓`):_.dim(`✗`);console.log(` `+_.dim(`Claude Code integration:`.padEnd(32)),c+` `+_.dim(o?`Yes`:`No`)),console.log(` `+_.dim(`Response language:`.padEnd(32)),n.text(s));let l=i?_.green(`✓`):_.dim(`✗`);console.log(` `+_.dim(`Initialize Git repository:`.padEnd(32)),l+` `+_.dim(i?`Yes`:`No`));let u=a?_.green(`✓`):_.dim(`✗`);if(console.log(` `+_.dim(`Store tasks in Git:`.padEnd(32)),u+` `+_.dim(a?`Yes`:`No`)),console.log(_.dim(`─`.repeat(50))),(await Q(t,_.yellow(`
3457
- Do you want to continue with these settings? (Y/n): `))).trim().toLowerCase()===`n`){t.close(),J(`info`,`Project initialization cancelled by user`),process.exit(0);return}let d=e.dryRun||!1;if(d)return J(`info`,`DRY RUN MODE: No files will be modified`),J(`info`,`Would initialize TaskGraph project`),J(`info`,`Would create/update necessary project files`),J(`info`,`${i?`Would initialize Git repository`:`Would skip Git initialization`}`),J(`info`,`${a?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};await $(!0,i,a,d,{...e,shouldSetupRules:o,preferredLanguage:s},o?D:r),t.close()}catch(e){t&&t.close(),J(`error`,`Error during initialization process: ${e.message}`),process.exit(1)}}}function Q(e,t,n){return new Promise(r=>{e.question(t,e=>{E.moveCursor(process.stdout,0,-1),E.cursorTo(process.stdout,0),E.clearLine(process.stdout,0),n&&process.stdout.write(n(e)+`
3458
- `),r(e)})})}function dt(){return x()}function ft(e){try{if(!y.existsSync(e)){J(`warn`,`Config file does not exist, skipping storage configuration`);return}let t=y.readFileSync(e,`utf8`),n=JSON.parse(t);n.storage||={},n.storage.type=`file`,n.storage.operatingMode=`solo`,J(`debug`,`Configured storage for local file storage`),y.writeFileSync(e,JSON.stringify(n,null,2)),J(`debug`,`Storage configuration updated in config.json`)}catch(e){J(`error`,`Failed to update storage configuration: ${e.message}`)}}async function $(e,n,s,c,d,g=D){let v=process.cwd();J(`debug`,`Initializing project in ${v}`),Y(b.join(v,t)),Y(b.join(v,l)),Y(b.join(v,f)),Y(b.join(v,o)),Y(b.join(v,a)),lt(v);let y={year:new Date().getFullYear()};function x(e){let t=it(e);t?at(v,t,{mode:`solo`}):J(`warn`,`Unknown rule profile: ${e}`)}Z(`env.example`,b.join(v,u),y),Z(`config.json`,b.join(v,p),{...y});let S=b.join(v,p);st(S)?J(`debug`,`Updated config with correct maxTokens values`):J(`debug`,`Could not update maxTokens in config`),ft(S);try{let e=L(`gitignore`,`utf8`);me(b.join(v,r),e,s,J)}catch(e){J(`error`,`Failed to create .gitignore: ${e.message}`)}Z(`example_prd.txt`,b.join(v,i)),Z(`example_prd_rpg.txt`,b.join(v,a,`example_prd_rpg.txt`));try{n===!1?J(`info`,`Git initialization skipped due to --no-git flag.`):n===!0?h()?J(`debug`,`Existing Git repository detected – skipping git init despite --git flag.`):(J(`info`,`Initializing Git repository due to --git flag...`),w(`git init`,{cwd:v,stdio:`ignore`}),J(`success`,`Git repository initialized`)):h()?J(`debug`,`Existing Git repository detected – skipping git init.`):(J(`info`,`No Git repository detected. Initializing one in project root...`),w(`git init`,{cwd:v,stdio:`ignore`}),J(`success`,`Git repository initialized`))}catch{J(`warn`,`Git not available, skipping repository initialization`)}if(g.length>0){J(`info`,`Setting up Claude Code integration...`);for(let e of g)x(e)}e&&X();let C={cwd:v,stdio:`inherit`};if(m()&&(C.stdio=`ignore`,J(`info`,`Running npm install silently...`)),d.preferredLanguage&&!c)try{let e=(await import(`./response-language-Dz-rFnaJ.js`)).default;e(d.preferredLanguage,{projectRoot:v,silent:!0}),J(`debug`,`Response language set to: ${d.preferredLanguage}`)}catch(e){J(`warn`,`Failed to set response language: ${e.message}`)}else m()&&!c?J(`debug`,`Skipping response language setup in silent (MCP) mode.`):c&&J(`debug`,`DRY RUN: Skipping response language setup.`);if(!m()&&!c&&!d?.yes){console.log(T(_.cyan(`Configuring AI Models...`),{padding:.5,margin:{top:1,bottom:.5},borderStyle:`round`,borderColor:`cyan`,width:60})),J(`info`,`Running interactive model setup. Please select your preferred AI models.`);try{w(`npx taskgraph models --setup`,{stdio:`inherit`,cwd:v}),J(`success`,`AI Models configured.`)}catch(e){J(`error`,`Failed to configure AI models:`,e.message),J(`warn`,`You may need to run "taskgraph models --setup" manually.`)}}else m()&&!c?(J(`info`,`Skipping interactive model setup in silent (MCP) mode.`),J(`warn`,`Please configure AI models using "taskgraph models --set-..." or the "models" MCP tool.`)):c?J(`info`,`DRY RUN: Skipping interactive model setup.`):d?.yes&&(J(`info`,`Skipping interactive model setup due to --yes flag.`),J(`info`,`Default AI models will be used. You can configure different models later using "taskgraph models --setup" or "taskgraph models --set-..." commands.`));if(e&&!c?(J(`debug`,`Adding shell aliases...`),X()&&J(`debug`,`Shell aliases added successfully`)):e&&c&&J(`debug`,`DRY RUN: Would add shell aliases (tm, taskgraph)`),m()||console.log(T(`${ee.multiline(ne.textSync(`Success!`,{font:`Standard`}))}\n${_.green(`Project initialized successfully!`)}`,{padding:1,margin:1,borderStyle:`double`,borderColor:`green`,width:60})),!m()){let e=ot();console.log(T(_.yellow.bold(`Workflow
3455
+ `)}`;S.writeFileSync(t,n),J(`success`,`Updated ${t} with additional entries`)}else J(`info`,`No new content to add to ${t}`);return}if(e===`README-taskgraph.md`){J(`info`,`${t} already exists`);let e=y.join(y.dirname(t),`README-taskgraph.md`);S.writeFileSync(e,r),J(`success`,`Created ${e} (preserved original README-taskgraph.md)`);return}J(`debug`,`${t} already exists, skipping.`);return}S.writeFileSync(t,r),J(`info`,`Created file: ${t}`)}async function ut(e={}){f()||ct(),e.git===!0?e.initGit=!0:e.git===!1&&(e.initGit=!1),e.gitTasks===!0?e.storeTasksInGit=!0:e.gitTasks===!1&&(e.storeTasksInGit=!1);let t=e.yes||e.name&&e.description,n;if(n=e.rulesExplicitlyProvided?e.rules:[],t){f()||console.log(`SKIPPING PROMPTS - Using defaults or provided values`),e.name,e.description,e.version,e.author;let t=e.dryRun||!1,r=e.initGit===void 0?!0:e.initGit,i=e.storeTasksInGit===void 0?!0:e.storeTasksInGit;if(t)return J(`info`,`DRY RUN MODE: No files will be modified`),J(`info`,`Would initialize TaskGraph project`),J(`info`,`Would create/update necessary project files`),J(`info`,`${r?`Would initialize Git repository`:`Would skip Git initialization`}`),J(`info`,`${i?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};await $(!0,r,i,t,{...e,preferredLanguage:`English`},n)}else{J(`debug`,`Required options not provided, proceeding with prompts.`);let t;try{J(`debug`,`Init started - taskgraph_id: ${dt()}`),t=T.createInterface({input:process.stdin,output:process.stdout});let r=!0,i=!0;r=e.initGit===void 0?(await Q(t,_.cyan(`Initialize a Git repository in project root? (Y/n): `),e=>{let t=e.trim().toLowerCase()!==`n`,n=t?_.green(`✓`):_.red(`✗`);return _.cyan(`Initialize a Git repository in project root?`)+` `+n+` `+_.dim(t?`Yes`:`No`)})).trim().toLowerCase()!==`n`:e.initGit,i=e.storeTasksInGit===void 0?(await Q(t,_.cyan(`Store tasks in Git (tasks.json and tasks/ directory)? (Y/n): `),e=>{let t=e.trim().toLowerCase()!==`n`,n=t?_.green(`✓`):_.red(`✗`);return _.cyan(`Store tasks in Git (tasks.json and tasks/ directory)?`)+` `+n+` `+_.dim(t?`Yes`:`No`)})).trim().toLowerCase()!==`n`:e.storeTasksInGit;let a=!1;e.rulesExplicitlyProvided?J(`info`,`Using rule profiles provided via command line: ${n.join(`, `)}`):a=(await Q(t,_.cyan(`Set up Claude Code integration (CLAUDE.md import)? (y/N): `),e=>{let t=e.trim().toLowerCase()===`y`,n=t?_.green(`✓`):_.red(`✗`);return _.cyan(`Set up Claude Code integration?`)+` `+n+` `+_.dim(t?`Yes`:`No`)})).trim().toLowerCase()===`y`;let o=(await Q(t,_.cyan(`Preferred response language (English): `))).trim()||`English`;console.log(`
3456
+ `+_.bold(`TaskGraph Project Settings:`)),console.log(_.dim(`─`.repeat(50)));let s=a?_.green(`✓`):_.dim(`✗`);console.log(` `+_.dim(`Claude Code integration:`.padEnd(32)),s+` `+_.dim(a?`Yes`:`No`)),console.log(` `+_.dim(`Response language:`.padEnd(32)),p.text(o));let c=r?_.green(`✓`):_.dim(`✗`);console.log(` `+_.dim(`Initialize Git repository:`.padEnd(32)),c+` `+_.dim(r?`Yes`:`No`));let l=i?_.green(`✓`):_.dim(`✗`);if(console.log(` `+_.dim(`Store tasks in Git:`.padEnd(32)),l+` `+_.dim(i?`Yes`:`No`)),console.log(_.dim(`─`.repeat(50))),(await Q(t,_.yellow(`
3457
+ Do you want to continue with these settings? (Y/n): `))).trim().toLowerCase()===`n`){t.close(),J(`info`,`Project initialization cancelled by user`),process.exit(0);return}let u=e.dryRun||!1;if(u)return J(`info`,`DRY RUN MODE: No files will be modified`),J(`info`,`Would initialize TaskGraph project`),J(`info`,`Would create/update necessary project files`),J(`info`,`${r?`Would initialize Git repository`:`Would skip Git initialization`}`),J(`info`,`${i?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};await $(!0,r,i,u,{...e,shouldSetupRules:a,preferredLanguage:o},a?E:n),t.close()}catch(e){t&&t.close(),J(`error`,`Error during initialization process: ${e.message}`),process.exit(1)}}}function Q(e,t,n){return new Promise(r=>{e.question(t,e=>{T.moveCursor(process.stdout,0,-1),T.cursorTo(process.stdout,0),T.clearLine(process.stdout,0),n&&process.stdout.write(n(e)+`
3458
+ `),r(e)})})}function dt(){return ae()}function ft(e){try{if(!S.existsSync(e)){J(`warn`,`Config file does not exist, skipping storage configuration`);return}let t=S.readFileSync(e,`utf8`),n=JSON.parse(t);n.storage||={},n.storage.type=`file`,n.storage.operatingMode=`solo`,J(`debug`,`Configured storage for local file storage`),S.writeFileSync(e,JSON.stringify(n,null,2)),J(`debug`,`Storage configuration updated in config.json`)}catch(e){J(`error`,`Failed to update storage configuration: ${e.message}`)}}async function $(e,c,l,d,p,g=E){let v=process.cwd();J(`debug`,`Initializing project in ${v}`),Y(y.join(v,a)),Y(y.join(v,i)),Y(y.join(v,u)),Y(y.join(v,t)),Y(y.join(v,o)),lt(v);let b={year:new Date().getFullYear()};function S(e){let t=it(e);t?at(v,t,{mode:`solo`}):J(`warn`,`Unknown rule profile: ${e}`)}Z(`env.example`,y.join(v,n),b),Z(`config.json`,y.join(v,r),{...b});let C=y.join(v,r);st(C)?J(`debug`,`Updated config with correct maxTokens values`):J(`debug`,`Could not update maxTokens in config`),ft(C);try{let e=L(`gitignore`,`utf8`);he(y.join(v,s),e,l,J)}catch(e){J(`error`,`Failed to create .gitignore: ${e.message}`)}Z(`example_prd.txt`,y.join(v,ee)),Z(`example_prd_rpg.txt`,y.join(v,o,`example_prd_rpg.txt`));try{c===!1?J(`info`,`Git initialization skipped due to --no-git flag.`):c===!0?m()?J(`debug`,`Existing Git repository detected – skipping git init despite --git flag.`):(J(`info`,`Initializing Git repository due to --git flag...`),x(`git init`,{cwd:v,stdio:`ignore`}),J(`success`,`Git repository initialized`)):m()?J(`debug`,`Existing Git repository detected – skipping git init.`):(J(`info`,`No Git repository detected. Initializing one in project root...`),x(`git init`,{cwd:v,stdio:`ignore`}),J(`success`,`Git repository initialized`))}catch{J(`warn`,`Git not available, skipping repository initialization`)}if(g.length>0){J(`info`,`Setting up Claude Code integration...`);for(let e of g)S(e)}e&&X();let T={cwd:v,stdio:`inherit`};if(f()&&(T.stdio=`ignore`,J(`info`,`Running npm install silently...`)),p.preferredLanguage&&!d)try{let e=(await import(`./response-language-CGnha79j.js`)).default;e(p.preferredLanguage,{projectRoot:v,silent:!0}),J(`debug`,`Response language set to: ${p.preferredLanguage}`)}catch(e){J(`warn`,`Failed to set response language: ${e.message}`)}else f()&&!d?J(`debug`,`Skipping response language setup in silent (MCP) mode.`):d&&J(`debug`,`DRY RUN: Skipping response language setup.`);if(!f()&&!d&&!p?.yes){console.log(w(_.cyan(`Configuring AI Models...`),{padding:.5,margin:{top:1,bottom:.5},borderStyle:`round`,borderColor:`cyan`,width:60})),J(`info`,`Running interactive model setup. Please select your preferred AI models.`);try{x(`npx taskgraph models --setup`,{stdio:`inherit`,cwd:v}),J(`success`,`AI Models configured.`)}catch(e){J(`error`,`Failed to configure AI models:`,e.message),J(`warn`,`You may need to run "taskgraph models --setup" manually.`)}}else f()&&!d?(J(`info`,`Skipping interactive model setup in silent (MCP) mode.`),J(`warn`,`Please configure AI models using "taskgraph models --set-..." or the "models" MCP tool.`)):d?J(`info`,`DRY RUN: Skipping interactive model setup.`):p?.yes&&(J(`info`,`Skipping interactive model setup due to --yes flag.`),J(`info`,`Default AI models will be used. You can configure different models later using "taskgraph models --setup" or "taskgraph models --set-..." commands.`));if(e&&!d?(J(`debug`,`Adding shell aliases...`),X()&&J(`debug`,`Shell aliases added successfully`)):e&&d&&J(`debug`,`DRY RUN: Would add shell aliases (tm, taskgraph)`),f()||console.log(w(`${h.multiline(te.textSync(`Success!`,{font:`Standard`}))}\n${_.green(`Project initialized successfully!`)}`,{padding:1,margin:1,borderStyle:`double`,borderColor:`green`,width:60})),!f()){let e=ot();console.log(w(_.yellow.bold(`Workflow
3459
3459
  `)+`
3460
- `+e,{padding:1,margin:{top:0,bottom:1,left:0,right:0},borderStyle:`round`,borderColor:`yellow`,width:60}))}}export{D as n,ae as r,ut as t};
3460
+ `+e,{padding:1,margin:{top:0,bottom:1,left:0,right:0},borderStyle:`round`,borderColor:`yellow`,width:60}))}}export{E as n,oe as r,ut as t};