@hhsw2015/task-master-ai 0.43.23 → 0.43.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ai-services-unified-DtbZ97I9.js → ai-services-unified-BowF9Vy-.js} +1 -1
- package/dist/ai-services-unified-BrOxyGnK.js +1 -0
- package/dist/{commands-DQQiVMX6.js → commands-NfRQi5z9.js} +5 -5
- package/dist/{config-manager-CWpKNiYl.js → config-manager-DyVbAaPA.js} +1 -1
- package/dist/{config-manager-BuZz09-s.js → config-manager-sjIWkXoH.js} +3 -3
- package/dist/{dependency-manager-n41vxXSd.js → dependency-manager-DQ1KOp7k.js} +5 -5
- package/dist/mcp-server.js +3 -3
- package/dist/{profiles-Cboh56FD.js → profiles-DyfO-NpI.js} +82 -82
- package/dist/research-CRMEGWua.js +1 -0
- package/dist/response-language-B-J-_qEU.js +1 -0
- package/dist/{response-language-C7cKb2Ko.js → response-language-BecQLUIF.js} +1 -1
- package/dist/{sentry-BO485gI2.js → sentry-Be7jGuko.js} +1 -1
- package/dist/tag-management-DyNjp_pG.js +1 -0
- package/dist/{task-manager-DWiOU-Qz.js → task-manager-DAaLRrbY.js} +1 -1
- package/dist/task-master.js +1 -1
- package/dist/update-subtask-by-id-bImgwSPt.js +1 -0
- package/dist/update-task-by-id-DrnkDCmy.js +1 -0
- package/dist/{utils-C0PQr5j9.js → utils-5vnyX__r.js} +1 -1
- package/package.json +1 -1
- package/dist/ai-services-unified-DYnwtn3B.js +0 -1
- package/dist/research-BKRDZpbK.js +0 -1
- package/dist/response-language-Ck21x8Tz.js +0 -1
- package/dist/tag-management-D95A287N.js +0 -1
- package/dist/update-subtask-by-id-DXTuaE1V.js +0 -1
- package/dist/update-task-by-id-Dshn8T-y.js +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{c as e}from"./ai-services-unified-
|
|
1
|
+
import{c as e}from"./ai-services-unified-BowF9Vy-.js";import{Bt as t,D as n,Ft as r,Gt as i,Ht as a,It as o,J as s,Pt as c,Ut as l,Vt as u,Wt as d,hn as f,ln as p,qt as m,vt as h,yt as g}from"./config-manager-sjIWkXoH.js";import{r as _}from"./git-utils-DllbRE35.js";import{Ct as v,St as y,Tt as b,x}from"./dependency-manager-DQ1KOp7k.js";import*as S from"node:path";import C from"chalk";import w from"fs";import T from"path";import{randomUUID as E}from"crypto";import D from"os";import*as O from"node:fs";import*as k from"node:os";import{execSync as A}from"child_process";import{fileURLToPath as ee}from"url";import j from"boxen";import M from"readline";import te from"figlet";import ne from"gradient-string";import re from"inquirer";import ie from"ora";import ae from"open";const N=[`amp`,`claude`,`cline`,`codex`,`cursor`,`gemini`,`kiro`,`opencode`,`kilo`,`roo`,`trae`,`vscode`,`windsurf`,`zed`],oe=[`architect`,`ask`,`orchestrator`,`code`,`debug`,`test`],se=`# Task files`,ce=`tasks.json`,le=`tasks/`;function ue(e){return e.trim().replace(/^#/,``).trim()}function P(e){let t=ue(e);return t===ce||t===le}function de(e,t){return e.map(e=>{if(P(e)){let n=ue(e),r=e.match(/\s*$/)[0];return t?`# ${n}${r}`:`${n}${r}`}return e})}function fe(e){let t=[],n=!1;for(let r of e){if(r.trim()===se){n=!0;continue}P(r)||n&&!r.trim()||(n&&r.trim()&&!P(r)&&(n=!1),n||t.push(r))}return t}function pe(e,t){return e.filter(e=>{let n=e.trim();return!n||P(e)||n===se?!1:!t.has(n)})}function me(e){let t=[se];return e?t.push(`# ${ce}`,`# ${le} `):t.push(ce,`${le} `),t}function he(e){if(e.some(e=>e.trim())){let t=e[e.length-1];t&&t.trim()&&e.push(``)}}function ge(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 _e(e,t,n){try{w.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
|
|
4
|
-
`)),a=
|
|
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 ve(e,t,n,r){try{let i=fe(w.readFileSync(e,`utf8`).split(`
|
|
4
|
+
`)),a=pe(t,new Set(i.map(e=>e.trim()).filter(e=>e))),o=[...i];a.length>0&&(he(o),o.push(...a)),he(o),o.push(...me(n)),w.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
|
|
7
|
-
`),n);
|
|
8
|
-
`),
|
|
9
|
-
`),
|
|
10
|
-
`),
|
|
11
|
-
`),r.success=!0,r.removed=!0,r.deleted=!1,
|
|
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 ye(e,t,n=!0,r=null){ge(e,t,n);let i=de(t.split(`
|
|
7
|
+
`),n);w.existsSync(e)?ve(e,i,n,r):_e(e,i,r)}const be=ee(import.meta.url),F=T.dirname(be);function I(){let e=[T.join(F,`assets`),T.join(F,`..`,`assets`),T.join(F,`..`,`..`,`public`,`assets`),T.join(process.cwd(),`assets`),T.join(process.cwd(),`node_modules`,`task-master-ai`,`dist`,`assets`),T.join(process.cwd(),`node_modules`,`task-master-ai`,`assets`)];for(let t of e)if(w.existsSync(t)){let e=T.join(t,`rules`,`taskmaster.mdc`);if(w.existsSync(e))return t}throw Error(`Assets directory not found. This is likely a packaging issue.`)}function xe(e){let t=I();return T.join(t,e)}function Se(e){try{let t=xe(e);return w.existsSync(t)}catch{return!1}}function L(e,t=`utf8`){let n=xe(e);return w.readFileSync(n,t)}function R(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 Ce(e,t){if(!t){g(`debug`,`[MCP Config] No mcpConfigPath provided, skipping MCP configuration setup`);return}let n=T.join(e,t),r=T.dirname(n);g(`info`,`Setting up MCP configuration at ${n}...`);let i={"task-master-ai":{command:`npx`,args:[`-y`,`task-master-ai`],env:{TASK_MASTER_TOOLS:`core`,ANTHROPIC_API_KEY:`YOUR_ANTHROPIC_API_KEY_HERE`,PERPLEXITY_API_KEY:`YOUR_PERPLEXITY_API_KEY_HERE`,OPENAI_API_KEY:`YOUR_OPENAI_KEY_HERE`,GOOGLE_API_KEY:`YOUR_GOOGLE_KEY_HERE`,XAI_API_KEY:`YOUR_XAI_KEY_HERE`,OPENROUTER_API_KEY:`YOUR_OPENROUTER_KEY_HERE`,MISTRAL_API_KEY:`YOUR_MISTRAL_KEY_HERE`,AZURE_OPENAI_API_KEY:`YOUR_AZURE_KEY_HERE`,OLLAMA_API_KEY:`YOUR_OLLAMA_API_KEY_HERE`}}};if(w.existsSync(r)||w.mkdirSync(r,{recursive:!0}),w.existsSync(n)){g(`info`,`MCP configuration file already exists, checking for existing task-master-ai...`);try{let e=JSON.parse(w.readFileSync(n,`utf8`));if(e.mcpServers||={},Object.values(e.mcpServers).some(e=>e.args&&Array.isArray(e.args)&&e.args.some(e=>typeof e==`string`&&e.includes(`task-master-ai`)))){g(`info`,`Found existing task-master-ai MCP configuration in mcp.json, leaving untouched`);return}e.mcpServers[`task-master-ai`]?g(`info`,`task-master-ai server already configured in mcp.json`):(e.mcpServers[`task-master-ai`]=i[`task-master-ai`],g(`info`,`Added task-master-ai server to existing MCP configuration`)),w.writeFileSync(n,R(e)+`
|
|
8
|
+
`),g(`success`,`Updated MCP configuration file`)}catch(e){g(`error`,`Failed to update MCP configuration: ${e.message}`);let t=`${n}.backup-${Date.now()}`;w.existsSync(n)&&(w.copyFileSync(n,t),g(`info`,`Created backup of existing mcp.json at ${t}`));let r={mcpServers:i};w.writeFileSync(n,R(r)+`
|
|
9
|
+
`),g(`warn`,`Created new MCP configuration file (backup of original file was created if it existed)`)}}else{let e={mcpServers:i};w.writeFileSync(n,R(e)+`
|
|
10
|
+
`),g(`success`,`Created MCP configuration file at ${n}`)}g(`info`,`MCP server will use the installed task-master-ai package`)}function we(e,t){if(!t)return{success:!0,removed:!1,deleted:!1,error:null,hasOtherServers:!1};let n=T.join(e,t),r={success:!1,removed:!1,deleted:!1,error:null,hasOtherServers:!1};if(!w.existsSync(n))return r.success=!0,r.removed=!1,g(`debug`,`[MCP Config] MCP config file does not exist: ${n}`),r;try{let e=JSON.parse(w.readFileSync(n,`utf8`));if(!e.mcpServers)return r.success=!0,r.removed=!1,g(`debug`,`[MCP Config] No mcpServers section found in: ${n}`),r;if(!(e.mcpServers[`task-master-ai`]||Object.values(e.mcpServers).some(e=>e.args&&Array.isArray(e.args)&&e.args.some(e=>typeof e==`string`&&e.includes(`task-master-ai`)))))return r.success=!0,r.removed=!1,g(`debug`,`[MCP Config] Task Master not found in MCP config: ${n}`),r;delete e.mcpServers[`task-master-ai`],Object.keys(e.mcpServers).forEach(t=>{let n=e.mcpServers[t];n.args&&Array.isArray(n.args)&&n.args.some(e=>typeof e==`string`&&e.includes(`task-master-ai`))&&(delete e.mcpServers[t],g(`debug`,`[MCP Config] Removed server '${t}' containing task-master-ai`))});let t=Object.keys(e.mcpServers);r.hasOtherServers=t.length>0,r.hasOtherServers?(w.writeFileSync(n,R(e)+`
|
|
11
|
+
`),r.success=!0,r.removed=!0,r.deleted=!1,g(`info`,`[MCP Config] Removed Task Master from MCP config, preserving other servers: ${t.join(`, `)}`)):(w.rmSync(n,{force:!0}),r.success=!0,r.removed=!0,r.deleted=!0,g(`info`,`[MCP Config] Removed MCP config file (no other servers remaining): ${n}`))}catch(e){r.error=e.message,g(`error`,`[MCP Config] Failed to remove Task Master from MCP config: ${e.message}`)}return r}function z(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 B(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 Te=B(`parse-prd`,`Parse PRD`,`<prd-file>`,`Parse a PRD document to generate tasks.
|
|
12
12
|
|
|
13
13
|
Arguments: $ARGUMENTS (PRD file path)
|
|
14
14
|
|
|
@@ -56,7 +56,7 @@ After parsing:
|
|
|
56
56
|
1. Display task summary
|
|
57
57
|
2. Show dependency graph
|
|
58
58
|
3. Suggest task expansion for complex items
|
|
59
|
-
4. Recommend sprint planning`,`solo`),
|
|
59
|
+
4. Recommend sprint planning`,`solo`),Ee=B(`parse-prd-with-research`,`Parse PRD With Research`,`<prd-file>`,`Parse PRD with enhanced research mode for better task generation.
|
|
60
60
|
|
|
61
61
|
Arguments: $ARGUMENTS (PRD file path)
|
|
62
62
|
|
|
@@ -103,7 +103,7 @@ Research mode typically:
|
|
|
103
103
|
- New technology domains
|
|
104
104
|
- Complex requirements
|
|
105
105
|
- Regulatory compliance needed
|
|
106
|
-
- Best practices crucial`,`solo`),
|
|
106
|
+
- Best practices crucial`,`solo`),De=B(`analyze-complexity`,`Analyze Complexity`,`[options]`,`Analyze task complexity and generate expansion recommendations.
|
|
107
107
|
|
|
108
108
|
Arguments: $ARGUMENTS
|
|
109
109
|
|
|
@@ -223,7 +223,7 @@ After analysis:
|
|
|
223
223
|
/taskmaster:expand 5 # Expand specific task
|
|
224
224
|
/taskmaster:expand-all # Expand all recommended
|
|
225
225
|
/taskmaster:complexity-report # View detailed report
|
|
226
|
-
\`\`\``,`solo`),
|
|
226
|
+
\`\`\``,`solo`),Oe=B(`complexity-report`,`Complexity Report`,`[--file=<path>]`,`Display the task complexity analysis report.
|
|
227
227
|
|
|
228
228
|
Arguments: $ARGUMENTS
|
|
229
229
|
|
|
@@ -339,7 +339,7 @@ Use report for:
|
|
|
339
339
|
After viewing:
|
|
340
340
|
/taskmaster:expand 5
|
|
341
341
|
→ Expand high-complexity task
|
|
342
|
-
\`\`\``,`solo`),
|
|
342
|
+
\`\`\``,`solo`),ke=B(`expand-task`,`Expand Task`,`<task-id>`,`Break down a complex task into subtasks.
|
|
343
343
|
|
|
344
344
|
Arguments: $ARGUMENTS (task ID)
|
|
345
345
|
|
|
@@ -387,7 +387,7 @@ After expansion:
|
|
|
387
387
|
1. Show subtask hierarchy
|
|
388
388
|
2. Update time estimates
|
|
389
389
|
3. Suggest implementation order
|
|
390
|
-
4. Highlight critical path`,`solo`),
|
|
390
|
+
4. Highlight critical path`,`solo`),Ae=z({name:`expand-all-tasks`,description:`Expand All Tasks`,content:`Expand all pending tasks that need subtasks.
|
|
391
391
|
|
|
392
392
|
## Bulk Task Expansion
|
|
393
393
|
|
|
@@ -437,7 +437,7 @@ After bulk expansion:
|
|
|
437
437
|
- Summary of tasks expanded
|
|
438
438
|
- New subtask count
|
|
439
439
|
- Updated complexity metrics
|
|
440
|
-
- Suggested task order`,mode:`solo`}),
|
|
440
|
+
- Suggested task order`,mode:`solo`}),je=B(`add-task`,`Add Task`,`<description>`,`Add new tasks with intelligent parsing and context awareness.
|
|
441
441
|
|
|
442
442
|
Arguments: $ARGUMENTS
|
|
443
443
|
|
|
@@ -514,7 +514,7 @@ Intelligent defaults based on:
|
|
|
514
514
|
- Historical data
|
|
515
515
|
- Current sprint/phase
|
|
516
516
|
|
|
517
|
-
Result: High-quality tasks from minimal input.`,`solo`),
|
|
517
|
+
Result: High-quality tasks from minimal input.`,`solo`),Me=B(`add-subtask`,`Add Subtask`,`<parent-id> <title>`,`Add a subtask to a parent task.
|
|
518
518
|
|
|
519
519
|
Arguments: $ARGUMENTS
|
|
520
520
|
|
|
@@ -589,7 +589,7 @@ task-master add-subtask --parent=<id> --task-id=<existing-id>
|
|
|
589
589
|
- Show updated task hierarchy
|
|
590
590
|
- Suggest logical next subtasks
|
|
591
591
|
- Update complexity estimates
|
|
592
|
-
- Recommend subtask order`,`solo`),
|
|
592
|
+
- Recommend subtask order`,`solo`),Ne=B(`remove-task`,`Remove Task`,`<task-id>`,`Remove a task permanently from the project.
|
|
593
593
|
|
|
594
594
|
Arguments: $ARGUMENTS (task ID)
|
|
595
595
|
|
|
@@ -695,7 +695,7 @@ Remove anyway? (y/n)
|
|
|
695
695
|
- Impact preview
|
|
696
696
|
- Removal logging
|
|
697
697
|
- Suggest alternatives
|
|
698
|
-
- No cascade delete of dependents`,`solo`),
|
|
698
|
+
- No cascade delete of dependents`,`solo`),Pe=B(`remove-subtask`,`Remove Subtask`,`<subtask-id>`,`Remove a subtask from its parent task.
|
|
699
699
|
|
|
700
700
|
Arguments: $ARGUMENTS
|
|
701
701
|
|
|
@@ -778,7 +778,7 @@ Confirm deletion? (y/n)
|
|
|
778
778
|
- Update parent task status
|
|
779
779
|
- Recalculate estimates
|
|
780
780
|
- Show updated hierarchy
|
|
781
|
-
- Suggest next actions`,`solo`),
|
|
781
|
+
- Suggest next actions`,`solo`),Fe=B(`remove-subtasks`,`Remove Subtasks`,`<task-id>`,`Clear all subtasks from a specific task.
|
|
782
782
|
|
|
783
783
|
Arguments: $ARGUMENTS (task ID)
|
|
784
784
|
|
|
@@ -863,7 +863,7 @@ Suggest alternatives:
|
|
|
863
863
|
→ Cleared all subtasks from task #5
|
|
864
864
|
→ Updated parent task estimates
|
|
865
865
|
→ Suggestion: Consider re-expanding with better breakdown
|
|
866
|
-
\`\`\``,`solo`),
|
|
866
|
+
\`\`\``,`solo`),Ie=z({name:`remove-all-subtasks`,description:`Remove All Subtasks`,content:`Clear all subtasks from all tasks globally.
|
|
867
867
|
|
|
868
868
|
## Global Subtask Clearing
|
|
869
869
|
|
|
@@ -955,7 +955,7 @@ Next steps:
|
|
|
955
955
|
- Review updated task list
|
|
956
956
|
- Re-expand complex tasks as needed
|
|
957
957
|
- Check project timeline
|
|
958
|
-
\`\`\``,mode:`solo`}),
|
|
958
|
+
\`\`\``,mode:`solo`}),Le=B(`convert-task-to-subtask`,`Convert Task To Subtask`,`<parent-id> <task-id>`,`Convert an existing task into a subtask.
|
|
959
959
|
|
|
960
960
|
Arguments: $ARGUMENTS
|
|
961
961
|
|
|
@@ -1025,7 +1025,7 @@ After: #5.1 "Implement validation" (subtask of #5)
|
|
|
1025
1025
|
- Show new task hierarchy
|
|
1026
1026
|
- List updated dependencies
|
|
1027
1027
|
- Verify project integrity
|
|
1028
|
-
- Suggest related conversions`,`solo`),
|
|
1028
|
+
- Suggest related conversions`,`solo`),Re=B(`add-dependency`,`Add Dependency`,`<task-id> <depends-on-id>`,`Add a dependency between tasks.
|
|
1029
1029
|
|
|
1030
1030
|
Arguments: $ARGUMENTS
|
|
1031
1031
|
|
|
@@ -1079,7 +1079,7 @@ After adding dependency:
|
|
|
1079
1079
|
→ Task #5 now depends on Task #3
|
|
1080
1080
|
→ Task #5 is now blocked until #3 completes
|
|
1081
1081
|
→ Suggested: Also consider if #5 needs #4
|
|
1082
|
-
\`\`\``,`solo`),
|
|
1082
|
+
\`\`\``,`solo`),ze=B(`remove-dependency`,`Remove Dependency`,`<task-id> <depends-on-id>`,`Remove a dependency between tasks.
|
|
1083
1083
|
|
|
1084
1084
|
Arguments: $ARGUMENTS
|
|
1085
1085
|
|
|
@@ -1140,7 +1140,7 @@ After removing:
|
|
|
1140
1140
|
→ Removed: Task #5 no longer depends on #3
|
|
1141
1141
|
→ Task #5 is now UNBLOCKED and ready to start
|
|
1142
1142
|
→ Warning: Consider if #5 still needs #2 completed first
|
|
1143
|
-
\`\`\``,`solo`),
|
|
1143
|
+
\`\`\``,`solo`),Be=z({name:`fix-dependencies`,description:`Fix Dependencies`,content:`Automatically fix dependency issues found during validation.
|
|
1144
1144
|
|
|
1145
1145
|
## Automatic Dependency Repair
|
|
1146
1146
|
|
|
@@ -1220,7 +1220,7 @@ Run '/taskmaster:validate-dependencies' to verify fixes
|
|
|
1220
1220
|
- Preview mode available
|
|
1221
1221
|
- Rollback capability
|
|
1222
1222
|
- Change logging
|
|
1223
|
-
- No data loss`,mode:`solo`}),
|
|
1223
|
+
- No data loss`,mode:`solo`}),Ve=z({name:`validate-dependencies`,description:`Validate Dependencies`,content:`Validate all task dependencies for issues.
|
|
1224
1224
|
|
|
1225
1225
|
## Dependency Validation
|
|
1226
1226
|
|
|
@@ -1290,7 +1290,7 @@ For each issue found:
|
|
|
1290
1290
|
After validation:
|
|
1291
1291
|
- Run \`/taskmaster:fix-dependencies\` to auto-fix
|
|
1292
1292
|
- Manually adjust problematic dependencies
|
|
1293
|
-
- Rerun to verify fixes`,mode:`solo`}),
|
|
1293
|
+
- Rerun to verify fixes`,mode:`solo`}),He=z({name:`setup-models`,description:`Setup Models`,content:`Run interactive setup to configure AI models.
|
|
1294
1294
|
|
|
1295
1295
|
## Interactive Model Configuration
|
|
1296
1296
|
|
|
@@ -1340,7 +1340,7 @@ After configuration:
|
|
|
1340
1340
|
- Test each provider
|
|
1341
1341
|
- Show usage examples
|
|
1342
1342
|
- Suggest next steps
|
|
1343
|
-
- Verify parse-prd works`,mode:`solo`}),
|
|
1343
|
+
- Verify parse-prd works`,mode:`solo`}),Ue=z({name:`view-models`,description:`View Models`,content:`View current AI model configuration.
|
|
1344
1344
|
|
|
1345
1345
|
## Model Configuration Display
|
|
1346
1346
|
|
|
@@ -1390,7 +1390,7 @@ Available Models:
|
|
|
1390
1390
|
Based on configuration:
|
|
1391
1391
|
- If missing API keys → Suggest setup
|
|
1392
1392
|
- If no research model → Explain benefits
|
|
1393
|
-
- If all configured → Show usage tips`,mode:`solo`}),
|
|
1393
|
+
- If all configured → Show usage tips`,mode:`solo`}),We=z({name:`install-taskmaster`,description:`Install TaskMaster`,content:`Check if Task Master is installed and install it if needed.
|
|
1394
1394
|
|
|
1395
1395
|
This command helps you get Task Master set up globally on your system.
|
|
1396
1396
|
|
|
@@ -1506,7 +1506,7 @@ Try: /taskmaster:init your-prd.md
|
|
|
1506
1506
|
After installation:
|
|
1507
1507
|
1. Run \`/taskmaster:status\` to verify setup
|
|
1508
1508
|
2. Configure AI providers with \`/taskmaster:setup-models\`
|
|
1509
|
-
3. Start using Task Master commands!`,mode:`solo`}),
|
|
1509
|
+
3. Start using Task Master commands!`,mode:`solo`}),Ge=z({name:`quick-install-taskmaster`,description:`Quick Install TaskMaster`,content:`Quick install Task Master globally if not already installed.
|
|
1510
1510
|
|
|
1511
1511
|
Execute this streamlined installation:
|
|
1512
1512
|
|
|
@@ -1527,7 +1527,7 @@ If you see "command not found" after installation, you may need to:
|
|
|
1527
1527
|
|
|
1528
1528
|
Once installed, you can use all the Task Master commands!
|
|
1529
1529
|
|
|
1530
|
-
Quick test: Run \`/taskmaster:help\` to see all available commands.`,mode:`solo`}),
|
|
1530
|
+
Quick test: Run \`/taskmaster:help\` to see all available commands.`,mode:`solo`}),Ke=B(`to-review`,`To Review`,`<task-id>`,`Set a task's status to review.
|
|
1531
1531
|
|
|
1532
1532
|
Arguments: $ARGUMENTS (task ID)
|
|
1533
1533
|
|
|
@@ -1566,7 +1566,7 @@ When setting to review:
|
|
|
1566
1566
|
- Create review reminders
|
|
1567
1567
|
- Track review duration
|
|
1568
1568
|
- Suggest reviewers based on expertise
|
|
1569
|
-
- Prepare rollback plan if needed`,`solo`),
|
|
1569
|
+
- Prepare rollback plan if needed`,`solo`),qe=B(`to-deferred`,`To Deferred`,`<task-id>`,`Defer a task for later consideration.
|
|
1570
1570
|
|
|
1571
1571
|
Arguments: $ARGUMENTS (task ID)
|
|
1572
1572
|
|
|
@@ -1612,7 +1612,7 @@ When deferring:
|
|
|
1612
1612
|
- Monitor deferral duration
|
|
1613
1613
|
- Alert when criteria met
|
|
1614
1614
|
- Prevent scope creep
|
|
1615
|
-
- Regular review cycles`,`solo`),
|
|
1615
|
+
- Regular review cycles`,`solo`),Je=B(`to-cancelled`,`To Cancelled`,`<task-id>`,`Cancel a task permanently.
|
|
1616
1616
|
|
|
1617
1617
|
Arguments: $ARGUMENTS (task ID)
|
|
1618
1618
|
|
|
@@ -1666,7 +1666,7 @@ When cancelling:
|
|
|
1666
1666
|
- Keep for reference
|
|
1667
1667
|
- Tag with cancellation reason
|
|
1668
1668
|
- Link to replacement if any
|
|
1669
|
-
- Maintain audit trail`,`solo`),
|
|
1669
|
+
- Maintain audit trail`,`solo`),Ye=B(`init-project`,`Init Project`,`[prd-file]`,`Initialize a new Task Master project.
|
|
1670
1670
|
|
|
1671
1671
|
Arguments: $ARGUMENTS
|
|
1672
1672
|
|
|
@@ -1715,7 +1715,7 @@ If PRD file provided:
|
|
|
1715
1715
|
\`\`\`
|
|
1716
1716
|
/taskmaster:init my-prd.md
|
|
1717
1717
|
→ Automatically runs parse-prd after init
|
|
1718
|
-
\`\`\``,`solo`),
|
|
1718
|
+
\`\`\``,`solo`),Xe=B(`init-project-quick`,`Init Project Quick`,`[prd-file]`,`Quick initialization with auto-confirmation.
|
|
1719
1719
|
|
|
1720
1720
|
Arguments: $ARGUMENTS
|
|
1721
1721
|
|
|
@@ -1872,7 +1872,7 @@ Ready for:
|
|
|
1872
1872
|
- Easy task sharing
|
|
1873
1873
|
- AI tool compatibility
|
|
1874
1874
|
- Offline task access
|
|
1875
|
-
- Backup redundancy`,mode:`solo`});const V=[
|
|
1875
|
+
- Backup redundancy`,mode:`solo`});const V=[Te,Ee,De,Oe,ke,Ae,je,Me,Ne,Pe,Fe,Ie,Le,Re,ze,Be,Ve,He,Ue,We,Ge,Ke,qe,Je,Ye,Xe,z({name:`goham`,description:`Start Working with Hamster Brief`,argumentHint:`[brief-url]`,mode:`team`,content:`# Start Working with Hamster Brief
|
|
1876
1876
|
|
|
1877
1877
|
End-to-end workflow for working on tasks from a connected Hamster brief. All tasks from the brief are worked on in a single branch, with one PR created at the end.
|
|
1878
1878
|
|
|
@@ -3458,71 +3458,71 @@ Works well with:
|
|
|
3458
3458
|
- CI/CD pipelines
|
|
3459
3459
|
- Project documentation
|
|
3460
3460
|
- Team updates
|
|
3461
|
-
- Client reports`)];function H(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)}H(V,`solo`),H(V,`team`),V.filter(e=>e.metadata.mode===`common`||!e.metadata.mode);var U=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?
|
|
3462
|
-
`)}},
|
|
3463
|
-
`)}}
|
|
3461
|
+
- Client reports`)];function H(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)}H(V,`solo`),H(V,`team`),V.filter(e=>e.metadata.mode===`common`||!e.metadata.mode);var U=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?S.join(e,this.commandsDir,`tm`):S.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?H(t,n.mode):t;O.existsSync(r)||O.mkdirSync(r,{recursive:!0});let o=this.formatAll(a);for(let e of o){let t=S.join(r,e.filename);O.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(!O.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=O.readdirSync(r);for(let t of a){let n=S.basename(t,S.extname(t)).toLowerCase();if(e.has(n)){let e=S.join(r,t);O.rmSync(e,{force:!0}),i.push(t)}}return n&&O.readdirSync(r).length===0&&O.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}},Ze=class extends U{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(`
|
|
3462
|
+
`)}},Qe=class extends U{name=`codex`;displayName=`Codex`;commandsDir=`.codex/prompts`;extension=`.md`;supportsNestedCommands=!1;isHomeRelative=!0;homeDir;constructor(e){super(),this.homeDir=e?.homeDir??k.homedir()}getCommandsPath(e){return S.join(this.homeDir,this.commandsDir)}format(e){let t=this.buildFrontmatter(e);return{filename:this.getFilename(e.metadata.name),content:`${t}${e.content}`}}buildFrontmatter(e){let t=e=>e.replace(/"/g,`\\"`),n=[`---`,`description: "${t(e.metadata.description)}"`];return e.metadata.argumentHint&&n.push(`argument-hint: "${t(e.metadata.argumentHint)}"`),n.push(`---`,``),n.join(`
|
|
3463
|
+
`)}},$e=class extends U{name=`cursor`;displayName=`Cursor`;commandsDir=`.cursor/commands`;extension=`.md`;format(e){return{filename:this.getFilename(e.metadata.name),content:e.content}}},et=class extends U{name=`gemini`;displayName=`Gemini`;commandsDir=`.gemini/commands`;extension=`.toml`;format(e){let t=this.escapeForPython(e.metadata.description),n=this.escapeForTripleQuotedString(e.content.trim());return{filename:this.getFilename(e.metadata.name),content:`description="${t}"
|
|
3464
3464
|
prompt = """
|
|
3465
3465
|
${n}
|
|
3466
3466
|
"""
|
|
3467
|
-
`}}escapeForPython(e){return e.replace(/"/g,`\\"`)}escapeForTripleQuotedString(e){return e.replace(/"""/g,`""\\"`)}},
|
|
3468
|
-
`)}},
|
|
3469
|
-
`)}};const
|
|
3470
|
-
`)||t.includes(`\r`))return{success:!1,message:`Invalid value: must be a single-line string without newlines`};let r=
|
|
3467
|
+
`}}escapeForPython(e){return e.replace(/"/g,`\\"`)}escapeForTripleQuotedString(e){return e.replace(/"""/g,`""\\"`)}},tt=class extends U{name=`opencode`;displayName=`OpenCode`;commandsDir=`.opencode/command`;extension=`.md`;supportsNestedCommands=!1;format(e){let t=this.buildFrontmatter(e),n=this.transformArgumentPlaceholder(e.content);return{filename:this.getFilename(e.metadata.name),content:`${t}${n}`}}buildFrontmatter(e){return[`---`,`description: ${e.metadata.description}`,`---`,``].join(`
|
|
3468
|
+
`)}},nt=class extends U{name=`roo`;displayName=`Roo Code`;commandsDir=`.roo/commands`;extension=`.md`;supportsNestedCommands=!1;format(e){let t=this.buildFrontmatter(e),n=this.transformArgumentPlaceholder(e.content);return{filename:this.getFilename(e.metadata.name),content:`${t}${n}`}}buildFrontmatter(e){let t=[`---`,`description: ${e.metadata.description}`];return e.metadata.argumentHint&&t.push(`argument-hint: ${e.metadata.argumentHint}`),t.push(`---`,``,``),t.join(`
|
|
3469
|
+
`)}};const rt={claude:new Ze,codex:new Qe,cursor:new $e,gemini:new et,opencode:new tt,roo:new nt};function it(e){return rt[e.toLowerCase()]}function at(){let e=D.homedir(),t=process.env.SHELL||``;if(t.includes(`zsh`))return T.join(e,`.zshrc`);if(t.includes(`bash`)){let t=T.join(e,`.bash_profile`);return process.platform===`darwin`?t:T.join(e,`.bashrc`)}if(t.includes(`fish`))return T.join(e,`.config`,`fish`,`config.fish`);if(process.platform===`win32`){if(process.env.PSModulePath){let t=process.env.PROFILE||T.join(e,`Documents`,`WindowsPowerShell`,`Microsoft.PowerShell_profile.ps1`),n=T.join(e,`Documents`,`PowerShell`,`Microsoft.PowerShell_profile.ps1`);return w.existsSync(n)?n:w.existsSync(t)?t:n}let t=T.join(e,`.bashrc`);if(w.existsSync(t))return t}let n=T.join(e,`.zshrc`);if(w.existsSync(n))return n;let r=T.join(e,`.bashrc`);return w.existsSync(r)?r:null}function W(e){return e.endsWith(`.ps1`)}function ot(e){return e.includes(`config.fish`)}function st(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(`
|
|
3470
|
+
`)||t.includes(`\r`))return{success:!1,message:`Invalid value: must be a single-line string without newlines`};let r=at();if(!r)return{success:!1,message:`Could not determine shell type (zsh, bash, fish, or PowerShell)`};try{let i=T.dirname(r);if(w.existsSync(i)||w.mkdirSync(i,{recursive:!0}),!w.existsSync(r)){let e=process.platform===`darwin`&&r.endsWith(`.bash_profile`);if(W(r)||e)w.writeFileSync(r,``);else return{success:!1,shellConfigFile:r,message:`Shell config file ${r} not found`}}let a=w.readFileSync(r,`utf8`),o;if(o=W(r)?RegExp(`^\\s*\\$env:${e}\\s*=`,`m`).test(a):ot(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=`#`):ot(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 w.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 ct(){return st(`ENABLE_EXPERIMENTAL_MCP_CLI`,`true`,`Claude Code deferred MCP loading (added by Taskmaster)`)}const lt=[{profileName:`cursor`,markers:[{path:`.cursor`,type:`directory`}],displayName:`Cursor`},{profileName:`claude`,markers:[{path:`.claude`,type:`directory`}],displayName:`Claude Code`},{profileName:`windsurf`,markers:[{path:`.windsurf`,type:`directory`}],displayName:`Windsurf`},{profileName:`vscode`,markers:[{path:`.vscode`,type:`directory`}],displayName:`VS Code`},{profileName:`roo`,markers:[{path:`.roo`,type:`directory`}],displayName:`Roo Code`},{profileName:`cline`,markers:[{path:`.cline`,type:`directory`}],displayName:`Cline`},{profileName:`kiro`,markers:[{path:`.kiro`,type:`directory`}],displayName:`Kiro`},{profileName:`zed`,markers:[{path:`.zed`,type:`directory`}],displayName:`Zed`},{profileName:`kilo`,markers:[{path:`.kilo`,type:`directory`}],displayName:`Kilo Code`},{profileName:`trae`,markers:[{path:`.trae`,type:`directory`}],displayName:`Trae`},{profileName:`gemini`,markers:[{path:`.gemini`,type:`directory`},{path:`GEMINI.md`,type:`file`}],displayName:`Gemini`},{profileName:`opencode`,markers:[{path:`.opencode`,type:`directory`}],displayName:`OpenCode`},{profileName:`codex`,markers:[{path:`.codex`,type:`directory`}],displayName:`Codex`}];function ut(e){let{projectRoot:t}=e,n=[];for(let e of lt)for(let r of e.markers){let i=T.join(t,r.path);try{let t=w.statSync(i);if(r.type===`directory`?t.isDirectory():t.isFile()){n.push({profileName:e.profileName,markerPath:r.path,displayName:e.displayName,exists:!0});break}}catch{}}return n}function dt(e){return ut(e).map(e=>e.profileName)}const ft={solo:[`rules/taskmaster.mdc`,`rules/dev_workflow.mdc`,`rules/self_improve.mdc`,`rules/cursor_rules.mdc`,`rules/taskmaster_hooks_workflow.mdc`],team:[`rules/hamster.mdc`]};function pt(e,t){return t===`team`?Object.fromEntries(Object.entries(e).filter(([e])=>ft.team.includes(e))):Object.fromEntries(Object.entries(e).filter(([e])=>ft.solo.includes(e)))}function G(e){let{name:t,displayName:n=t,url:r,docsUrl:i,profileDir:a=`.${t.toLowerCase()}`,rulesDir:o=`${a}/rules`,mcpConfig:s=!0,mcpConfigName:c=s?`mcp.json`:null,fileExtension:l=`.mdc`,targetExtension:u=`.md`,toolMappings:d={},customReplacements:f=[],fileMap:p={},supportsRulesSubdirectories:m=!1,includeDefaultRules:h=!0,onAdd:_,onRemove:v,onPostConvert:y}=e,b=c?T.join(a,c):null,x=m?`taskmaster/`:``,S={"rules/cursor_rules.mdc":`${t.toLowerCase()}_rules${u}`,"rules/dev_workflow.mdc":`${x}dev_workflow${u}`,"rules/self_improve.mdc":`self_improve${u}`,"rules/taskmaster.mdc":`${x}taskmaster${u}`,"rules/hamster.mdc":`${x}hamster${u}`},C=h?{...S,...p}:p,w=[{from:/cursor\.so/gi,to:r},{from:/cursor\s*\.\s*so/gi,to:r},{from:/https?:\/\/cursor\.so/gi,to:`https://${r}`},{from:/https?:\/\/www\.cursor\.so/gi,to:`https://www.${r}`},{from:/\bedit_file\b/gi,to:d.edit_file||`edit_file`},{from:/\bsearch tool\b/gi,to:`${d.search||`search`} tool`},{from:/\bSearch Tool\b/g,to:`${d.search||`Search`} Tool`},{from:/\bcursor\b/gi,to:e=>e.charAt(0)===`C`?n:t.toLowerCase()},{from:/Cursor/g,to:n},{from:/CURSOR/g,to:n.toUpperCase()},...u===l?[]:[{from:RegExp(`\\${l}(?!\\])\\b`,`g`),to:u}],{from:/docs\.cursor\.com/gi,to:i},...f],E={search:`search`,read_file:`read_file`,edit_file:`edit_file`,create_file:`create_file`,run_command:`run_command`,terminal_command:`terminal_command`,use_mcp:`use_mcp`,switch_mode:`switch_mode`,...d},D={profileTerms:[{from:/cursor\.so/g,to:r},{from:/\[cursor\.so\]/g,to:`[${r}]`},{from:/href="https:\/\/cursor\.so/g,to:`href="https://${r}`},{from:/\(https:\/\/cursor\.so/g,to:`(https://${r}`},{from:/\bcursor\b/gi,to:e=>e===`Cursor`?n:t.toLowerCase()},{from:/Cursor/g,to:n}],fileExtensions:u===l?[]:[{from:RegExp(`\\${l}\\b`,`g`),to:u}],docUrls:[{from:RegExp(`https:\\/\\/docs\\.cursor\\.com\\/[^\\s)'"]+`,`g`),to:e=>e.replace(`docs.cursor.com`,i)},{from:RegExp(`https:\\/\\/${i}\\/`,`g`),to:`https://${i}/`}],toolNames:E,toolContexts:Object.entries(E).flatMap(([e,t])=>[{from:RegExp(`\\b${e} tool\\b`,`g`),to:`${t} tool`},{from:RegExp(`\\bthe ${e}\\b`,`g`),to:`the ${t}`},{from:RegExp(`\\bThe ${e}\\b`,`g`),to:`The ${t}`},{from:RegExp(`\\bCursor ${e}\\b`,`g`),to:`${n} ${t}`}]),toolGroups:[{from:/\bSearch tools\b/g,to:`Read Group tools`},{from:/\bEdit tools\b/g,to:`Edit Group tools`},{from:/\bRun tools\b/g,to:`Command Group tools`},{from:/\bMCP servers\b/g,to:`MCP Group tools`},{from:/\bSearch Group\b/g,to:`Read Group`},{from:/\bEdit Group\b/g,to:`Edit Group`},{from:/\bRun Group\b/g,to:`Command Group`}],fileReferences:{pathPattern:/\[(.+?)\]\(mdc:\.cursor\/rules\/(.+?)\.mdc\)/g,replacement:(e,n,r)=>{let i=T.basename(r,`.mdc`),a=C[`rules/${i}.mdc`]||`${i}${u}`,s=T.basename(a);return t.toLowerCase()===`cursor`?`[${s}](mdc:${o}/${a})`:`[${s}](${o}/${a})`}}};function O(e){return C[e]?C[e]:u===l?e:e.replace(RegExp(`\\${l}$`),u)}let k=null;try{let e=it(t);e?.supportsCommands&&(k={profile:e,commands:V})}catch(e){g(`debug`,`[${n}] Slash command profile lookup failed: ${e.message}`)}return{profileName:t,displayName:n,profileDir:a,rulesDir:o,mcpConfig:s,mcpConfigName:c,mcpConfigPath:b,supportsRulesSubdirectories:m,includeDefaultRules:h,fileMap:C,globalReplacements:w,conversionConfig:D,getTargetRuleFilename:O,targetExtension:u,slashCommands:k,..._&&{onAddRulesProfile:_},...v&&{onRemoveRulesProfile:v},...y&&{onPostConvertRulesProfile:y}}}const mt={STANDARD:{},ROO_STYLE:{edit_file:`apply_diff`,search:`search_files`,create_file:`write_to_file`,run_command:`execute_command`,terminal_command:`execute_command`,use_mcp:`use_mcp_tool`}};function ht(e){let t={};e.mcpServers&&(t[`amp.mcpServers`]=e.mcpServers);for(let[n,r]of Object.entries(e))n!==`mcpServers`&&(t[n]=r);return t}function gt(e,t){let n=T.join(t,`AGENTS.md`),r=T.join(e,`AGENT.md`),i=T.join(e,`.taskmaster`,`AGENT.md`),a=`@./.taskmaster/AGENT.md`,o=`\n## Task Master AI Instructions\n**Import Task Master's development workflow commands and guidelines, treat as if import is in the main AGENT.md file.**\n${a}`;if(w.existsSync(n))try{let t=T.join(e,`.taskmaster`);if(w.existsSync(t)||w.mkdirSync(t,{recursive:!0}),w.copyFileSync(n,i),g(`debug`,`[Amp] Created Task Master instructions at ${i}`),w.existsSync(r)){let e=w.readFileSync(r,`utf8`);if(e.includes(a))g(`info`,`[Amp] Task Master import already present in ${r}`);else{let t=e.trim()+`
|
|
3471
3471
|
`+o+`
|
|
3472
|
-
`;
|
|
3472
|
+
`;w.writeFileSync(r,t),g(`info`,`[Amp] Added Task Master import to existing ${r}`)}}else{let e=`# Amp Instructions\n${o}\n`;w.writeFileSync(r,e),g(`info`,`[Amp] Created ${r} with Task Master import`)}}catch(e){g(`error`,`[Amp] Failed to set up Amp instructions: ${e.message}`)}}function _t(e){let t=T.join(e,`AGENT.md`),n=T.join(e,`.taskmaster`,`AGENT.md`);try{if(w.existsSync(n)&&(w.rmSync(n,{force:!0}),g(`debug`,`[Amp] Removed ${n}`)),w.existsSync(t)){let e=w.readFileSync(t,`utf8`).split(`
|
|
3473
3473
|
`),n=[],r=0;for(let t=0;t<e.length;t++){if(r>0){r--;continue}if(e[t].includes(`## Task Master AI Instructions`)){r=2;continue}e[t].trim()!==`@./.taskmaster/AGENT.md`&&n.push(e[t])}let i=n.join(`
|
|
3474
3474
|
`).replace(/\n{3,}/g,`
|
|
3475
3475
|
|
|
3476
|
-
`).trim();i===`# Amp Instructions`||i===``?(
|
|
3477
|
-
`),
|
|
3478
|
-
`),
|
|
3479
|
-
`),
|
|
3476
|
+
`).trim();i===`# Amp Instructions`||i===``?(w.rmSync(t,{force:!0}),g(`debug`,`[Amp] Removed empty ${t}`)):(w.writeFileSync(t,i+`
|
|
3477
|
+
`),g(`debug`,`[Amp] Removed Task Master import from ${t}`))}}catch(e){g(`error`,`[Amp] Failed to remove Amp instructions: ${e.message}`)}let r=T.join(e,`.vscode`,`settings.json`);if(!w.existsSync(r)){g(`debug`,`[Amp] No .vscode/settings.json found to clean up`);return}try{let t=w.readFileSync(r,`utf8`),n=JSON.parse(t);if(n[`amp.mcpServers`]&&n[`amp.mcpServers`][`task-master-ai`])if(delete n[`amp.mcpServers`][`task-master-ai`],Object.keys(n[`amp.mcpServers`]).length===0&&(delete n[`amp.mcpServers`],g(`debug`,`[Amp] Removed empty amp.mcpServers section`)),Object.keys(n).length===0){w.rmSync(r,{force:!0}),g(`info`,`[Amp] Removed empty settings.json file`);let t=T.join(e,`.vscode`);w.existsSync(t)&&w.readdirSync(t).length===0&&(w.rmSync(t,{recursive:!0,force:!0}),g(`debug`,`[Amp] Removed empty .vscode directory`))}else w.writeFileSync(r,JSON.stringify(n,null,` `)+`
|
|
3478
|
+
`),g(`info`,`[Amp] Removed TaskMaster from settings.json, preserved other configurations`);else g(`debug`,`[Amp] TaskMaster not found in amp.mcpServers`)}catch(e){g(`error`,`[Amp] Failed to clean up settings.json: ${e.message}`)}}function vt(e,t){gt(e,t);let n=T.join(e,`.vscode`,`settings.json`);if(!w.existsSync(n)){g(`debug`,`[Amp] No .vscode/settings.json found to transform`);return}try{let e=w.readFileSync(n,`utf8`),t=JSON.parse(e);if(t[`amp.mcpServers`]){g(`info`,`[Amp] settings.json already in Amp format, skipping transformation`);return}let r=ht(t);w.writeFileSync(n,JSON.stringify(r,null,` `)+`
|
|
3479
|
+
`),g(`info`,`[Amp] Transformed settings.json to Amp format`),g(`debug`,`[Amp] Renamed mcpServers to amp.mcpServers`)}catch(e){g(`error`,`[Amp] Failed to transform settings.json: ${e.message}`)}}const yt=G({name:`amp`,displayName:`Amp`,url:`ampcode.com`,docsUrl:`ampcode.com/manual`,profileDir:`.vscode`,rulesDir:`.`,mcpConfig:!0,mcpConfigName:`settings.json`,includeDefaultRules:!1,fileMap:{"AGENTS.md":`.taskmaster/AGENT.md`},onAdd:gt,onRemove:_t,onPostConvert:vt});function bt(e,t){g(`info`,`[Claude] Commands and agents are now available via the Task Master plugin`),g(`info`,`[Claude] Install with: /plugin marketplace add taskmaster`),g(`info`,`[Claude] Then: /plugin install taskmaster@taskmaster`);let n=T.join(t,`AGENTS.md`),r=T.join(e,`CLAUDE.md`),i=T.join(e,`.taskmaster`,`CLAUDE.md`),a=`@./.taskmaster/CLAUDE.md`,o=`\n## Task Master AI Instructions\n**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**\n${a}`;if(w.existsSync(n))try{let t=T.join(e,`.taskmaster`);if(w.existsSync(t)||w.mkdirSync(t,{recursive:!0}),w.copyFileSync(n,i),g(`debug`,`[Claude] Created Task Master instructions at ${i}`),w.existsSync(r)){let e=w.readFileSync(r,`utf8`);if(e.includes(a))g(`info`,`[Claude] Task Master import already present in ${r}`);else{let t=e.trim()+`
|
|
3480
3480
|
`+o+`
|
|
3481
|
-
`;
|
|
3481
|
+
`;w.writeFileSync(r,t),g(`info`,`[Claude] Added Task Master import to existing ${r}`)}}else{let e=`# Claude Code Instructions\n${o}\n`;w.writeFileSync(r,e),g(`info`,`[Claude] Created ${r} with Task Master import`)}}catch(e){g(`error`,`[Claude] Failed to set up Claude instructions: ${e.message}`)}let s=ct();s.success?s.alreadyExists?g(`debug`,`[Claude] Deferred MCP loading already configured`):(g(`info`,`[Claude] Enabled deferred MCP loading in ${s.shellConfigFile}`),g(`info`,`[Claude] Restart your terminal for changes to take effect`)):g(`debug`,`[Claude] Could not configure deferred loading: ${s.message}`)}function xt(e){g(`info`,`[Claude] To remove Task Master commands/agents, uninstall the plugin with: /plugin uninstall taskmaster`);let t=T.join(e,`CLAUDE.md`),n=T.join(e,`.taskmaster`,`CLAUDE.md`);try{if(w.existsSync(n)&&(w.rmSync(n,{force:!0}),g(`debug`,`[Claude] Removed ${n}`)),w.existsSync(t)){let e=w.readFileSync(t,`utf8`).split(`
|
|
3482
3482
|
`),n=[],r=0;for(let t=0;t<e.length;t++){if(r>0){r--;continue}if(e[t].includes(`## Task Master AI Instructions`)){r=2;continue}e[t].trim()!==`@./.taskmaster/CLAUDE.md`&&n.push(e[t])}let i=n.join(`
|
|
3483
3483
|
`).replace(/\n{3,}/g,`
|
|
3484
3484
|
|
|
3485
|
-
`).trim();i===`# Claude Code Instructions`||i===``?(
|
|
3486
|
-
`),
|
|
3487
|
-
`),
|
|
3485
|
+
`).trim();i===`# Claude Code Instructions`||i===``?(w.rmSync(t,{force:!0}),g(`debug`,`[Claude] Removed empty ${t}`)):(w.writeFileSync(t,i+`
|
|
3486
|
+
`),g(`debug`,`[Claude] Removed Task Master import from ${t}`))}}catch(e){g(`error`,`[Claude] Failed to remove Claude instructions: ${e.message}`)}}function St(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 Ct(e,t){bt(e,t);let n=T.join(e,`.mcp.json`);if(w.existsSync(n))try{let e=St(JSON.parse(w.readFileSync(n,`utf8`)));w.writeFileSync(n,JSON.stringify(e,null,` `)+`
|
|
3487
|
+
`),g(`debug`,`[Claude] Transformed MCP configuration to Claude format at ${n}`)}catch(e){g(`error`,`[Claude] Failed to transform MCP configuration: ${e.message}`)}}const wt=G({name:`claude`,displayName:`Claude Code`,url:`claude.ai`,docsUrl:`docs.anthropic.com/en/docs/claude-code`,profileDir:`.`,rulesDir:`.`,mcpConfigName:`.mcp.json`,includeDefaultRules:!1,fileMap:{"AGENTS.md":`.taskmaster/CLAUDE.md`},onAdd:bt,onRemove:xt,onPostConvert:Ct}),Tt=G({name:`cline`,displayName:`Cline`,url:`cline.bot`,docsUrl:`docs.cline.bot`,profileDir:`.clinerules`,rulesDir:`.clinerules`,mcpConfig:!1}),Et=G({name:`codex`,displayName:`Codex`,url:`codex.ai`,docsUrl:`platform.openai.com/docs/codex`,profileDir:`.`,rulesDir:`.`,mcpConfig:!1,mcpConfigName:null,includeDefaultRules:!1,fileMap:{"AGENTS.md":`AGENTS.md`}}),Dt=G({name:`cursor`,displayName:`Cursor`,url:`cursor.so`,docsUrl:`docs.cursor.com`,targetExtension:`.mdc`,supportsRulesSubdirectories:!0}),Ot=G({name:`gemini`,displayName:`Gemini`,url:`codeassist.google`,docsUrl:`github.com/google-gemini/gemini-cli`,profileDir:`.gemini`,rulesDir:`.`,mcpConfigName:`settings.json`,includeDefaultRules:!1,fileMap:{"AGENT.md":`AGENTS.md`,"GEMINI.md":`GEMINI.md`}});function kt(e){let t=[{from:/\broo\b/gi,to:e=>e.charAt(0)===`R`?`Kilo`:`kilo`},{from:/Roo/g,to:`Kilo`},{from:/ROO/g,to:`KILO`},{from:/roocode\.com/gi,to:`kilocode.com`},{from:/docs\.roocode\.com/gi,to:`docs.kilocode.com`},{from:/https?:\/\/roocode\.com/gi,to:`https://kilocode.com`},{from:/https?:\/\/docs\.roocode\.com/gi,to:`https://docs.kilocode.com`},{from:/\.roo\//g,to:`.kilo/`},{from:/\.roomodes/g,to:`.kilocodemodes`},{from:/roo-rules/g,to:`kilo-rules`},{from:/rules-roo/g,to:`rules-kilo`}],n=e;for(let e of t)n=n.replace(e.from,e.to);return n}function At(e,t){let n=w.existsSync(e),r=n&&w.statSync(e);n&&r.isDirectory()?(w.existsSync(t)||w.mkdirSync(t,{recursive:!0}),w.readdirSync(e).forEach(n=>{At(T.join(e,n),T.join(t,n))})):w.copyFileSync(e,t)}function jt(e,t){let n=T.join(t,`roocode`);if(!w.existsSync(n)){g(`error`,`[Kilo] Source directory does not exist: ${n}`);return}At(n,e),g(`debug`,`[Kilo] Copied roocode directory to ${e}`);let r=T.join(n,`.roomodes`),i=T.join(e,`.kilocodemodes`);if(w.existsSync(r))try{let t=kt(w.readFileSync(r,`utf8`));w.writeFileSync(i,t),g(`debug`,`[Kilo] Created .kilocodemodes at ${i}`),w.unlinkSync(T.join(e,`.roomodes`))}catch(e){g(`error`,`[Kilo] Failed to transform .roomodes: ${e.message}`)}let a=T.join(n,`.roo`),o=T.join(e,`.kilo`);w.existsSync(T.join(e,`.roo`))&&w.rmSync(T.join(e,`.roo`),{recursive:!0,force:!0});for(let e of oe){let t=T.join(a,`rules-${e}`,`${e}-rules`),n=T.join(o,`rules-${e}`,`${e}-rules`);if(w.existsSync(t))try{let r=T.dirname(n);w.existsSync(r)||w.mkdirSync(r,{recursive:!0});let i=kt(w.readFileSync(t,`utf8`));w.writeFileSync(n,i),g(`debug`,`[Kilo] Transformed and copied ${e}-rules to ${n}`)}catch(e){g(`error`,`[Kilo] Failed to transform ${t} to ${n}: ${e.message}`)}}}function Mt(e){let t=T.join(e,`.kilocodemodes`);if(w.existsSync(t))try{w.rmSync(t,{force:!0}),g(`debug`,`[Kilo] Removed .kilocodemodes from ${t}`)}catch(e){g(`error`,`[Kilo] Failed to remove .kilocodemodes: ${e.message}`)}let n=T.join(e,`.kilo`);if(w.existsSync(n)&&(w.readdirSync(n).forEach(e=>{if(e.startsWith(`rules-`)){let t=T.join(n,e);try{w.rmSync(t,{recursive:!0,force:!0}),g(`debug`,`[Kilo] Removed ${e} directory from ${t}`)}catch(e){g(`error`,`[Kilo] Failed to remove ${t}: ${e.message}`)}}}),w.readdirSync(n).length===0))try{w.rmSync(n,{recursive:!0,force:!0}),g(`debug`,`[Kilo] Removed empty .kilo directory from ${n}`)}catch(e){g(`error`,`[Kilo] Failed to remove .kilo directory: ${e.message}`)}}function Nt(e,t){jt(e,t)}const Pt=G({name:`kilo`,displayName:`Kilo Code`,url:`kilocode.com`,docsUrl:`docs.kilocode.com`,profileDir:`.kilo`,rulesDir:`.kilo/rules`,toolMappings:mt.ROO_STYLE,fileMap:{"rules/cursor_rules.mdc":`kilo_rules.md`,"rules/dev_workflow.mdc":`dev_workflow.md`,"rules/self_improve.mdc":`self_improve.md`,"rules/taskmaster.mdc":`taskmaster.md`},onAdd:jt,onRemove:Mt,onPostConvert:Nt}),Ft=G({name:`kiro`,displayName:`Kiro`,url:`kiro.dev`,docsUrl:`kiro.dev/docs`,profileDir:`.kiro`,rulesDir:`.kiro/steering`,mcpConfig:!0,mcpConfigName:`settings/mcp.json`,includeDefaultRules:!0,targetExtension:`.md`,fileMap:{"rules/taskmaster_hooks_workflow.mdc":`taskmaster_hooks_workflow.md`},customReplacements:[{from:/\.cursor\/rules/g,to:`.kiro/steering`},{from:/\.cursor\/mcp\.json/g,to:`.kiro/settings/mcp.json`},{from:/\.kiro\/rules/g,to:`.kiro/steering`},{from:/\[(.+?)\]\(mdc:\.cursor\/rules\/(.+?)\.mdc\)/g,to:`[$1](.kiro/steering/$2.md)`},{from:/rules directory/g,to:`steering directory`},{from:/cursor rules/gi,to:`Kiro steering files`},{from:/^---\n(?:description:\s*[^\n]*\n)?(?:globs:\s*[^\n]*\n)?(?:alwaysApply:\s*true\n)?---/m,to:`---
|
|
3488
3488
|
inclusion: always
|
|
3489
|
-
---`}],onPostConvert:(e,t)=>{let n=
|
|
3490
|
-
`),
|
|
3491
|
-
`),
|
|
3492
|
-
`),
|
|
3493
|
-
`),
|
|
3494
|
-
`),
|
|
3495
|
-
`),
|
|
3496
|
-
`),h(`info`,`[Zed] Transformed settings.json to Zed format`),h(`debug`,`[Zed] Renamed mcpServers to context_servers`)}catch(e){h(`error`,`[Zed] Failed to transform settings.json: ${e.message}`)}}const tn=G({name:`zed`,displayName:`Zed`,url:`zed.dev`,docsUrl:`zed.dev/docs`,profileDir:`.zed`,rulesDir:`.`,mcpConfig:!0,mcpConfigName:`settings.json`,includeDefaultRules:!1,fileMap:{"AGENTS.md":`.rules`},onAdd:Qt,onRemove:$t,onPostConvert:en});var nn=e({ampProfile:()=>vt,claudeProfile:()=>Ct,clineProfile:()=>wt,codexProfile:()=>Tt,cursorProfile:()=>Et,geminiProfile:()=>Dt,kiloProfile:()=>Nt,kiroProfile:()=>Pt,opencodeProfile:()=>Rt,rooProfile:()=>Wt,traeProfile:()=>Gt,vscodeProfile:()=>Yt,windsurfProfile:()=>Xt,zedProfile:()=>tn});function K(e){return A.includes(e)}function q(e){if(!K(e))return null;let t=nn[`${e}Profile`];if(!t)throw Error(`Profile not found: static import missing for '${e}'. Valid profiles: ${A.join(`, `)}`);return t}function rn(e,t){let n=e;return t.profileTerms.forEach(e=>{n=(e.to,n.replace(e.from,e.to))}),t.fileExtensions.forEach(e=>{n=n.replace(e.from,e.to)}),n}function an(e,t){let n=e,r=t.toolNames,i=RegExp(`\\b(${Object.keys(r).join(`|`)})\\b`,`g`);return n=n.replace(i,(e,t)=>r[t]||t),t.toolContexts.forEach(e=>{n=n.replace(e.from,e.to)}),t.toolGroups.forEach(e=>{n=n.replace(e.from,e.to)}),n}function on(e,t){let n=e;return t.docUrls.forEach(e=>{n=(e.to,n.replace(e.from,e.to))}),n}function sn(e,t){let{pathPattern:n,replacement:r}=t.fileReferences;return e.replace(n,r)}function cn(e,t,n){let r=e;return r=sn(r,t),r=rn(r,t),r=an(r,t),r=on(r,t),n.forEach(e=>{r=(e.to,r.replace(e.from,e.to))}),r}function ln(e,t){let n=C.join(e,t.rulesDir);if(!S.existsSync(n))return;let r=Object.values(t.fileMap);for(let e of r){let t=C.join(n,e);if(S.existsSync(t))try{S.rmSync(t,{force:!0}),h(`debug`,`[Rule Transformer] Removed rule file: ${e}`)}catch(t){h(`warn`,`[Rule Transformer] Failed to remove rule file ${e}: ${t.message}`)}}}function J(e,t,n){let r=C.join(e,t.rulesDir),i=n?.mode,a=0,o=0;if(i&&(ln(e,t),h(`debug`,`[Rule Transformer] Cleaned up existing rules before adding ${i} mode rules`)),typeof t.onAddRulesProfile==`function`)try{let e=I();t.onAddRulesProfile(r,e),h(`debug`,`[Rule Transformer] Called onAddRulesProfile for ${t.profileName}`)}catch(e){h(`error`,`[Rule Transformer] onAddRulesProfile failed for ${t.profileName}: ${e.message}`),o++}let s=i?ft(t.fileMap,i):t.fileMap,c=Object.keys(s);if(c.length>0){S.existsSync(r)||S.mkdirSync(r,{recursive:!0});for(let e of c){let n=!e.startsWith(`rules/`);try{if(!xe(e)){h(`warn`,`[Rule Transformer] Source file not found: ${e}, skipping`);continue}let i=s[e],o=C.join(r,i),c=C.dirname(o);S.existsSync(c)||S.mkdirSync(c,{recursive:!0});let l=L(e,`utf8`);n||(l=cn(l,t.conversionConfig,t.globalReplacements)),S.writeFileSync(o,l,`utf8`),a++,h(`debug`,`[Rule Transformer] ${n?`Copied`:`Converted`} ${e} -> ${i} for ${t.profileName}`)}catch(r){o++,h(`error`,`[Rule Transformer] Failed to ${n?`copy`:`convert`} ${e} for ${t.profileName}: ${r.message}`)}}}if(t.mcpConfig!==!1)try{Se(e,t.mcpConfigPath),h(`debug`,`[Rule Transformer] Setup MCP configuration for ${t.profileName}`)}catch(e){h(`error`,`[Rule Transformer] MCP setup failed for ${t.profileName}: ${e.message}`)}if(typeof t.onPostConvertRulesProfile==`function`)try{let e=I();t.onPostConvertRulesProfile(r,e),h(`debug`,`[Rule Transformer] Called onPostConvertRulesProfile for ${t.profileName}`)}catch(e){h(`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?h(`debug`,`[Rule Transformer] Created ${r.count} slash commands in ${r.directory}${i?` (mode: ${i})`:``}`):h(`error`,`[Rule Transformer] Failed to add slash commands for ${t.profileName}: ${r.error}`)}catch(e){h(`error`,`[Rule Transformer] Slash commands failed for ${t.profileName}: ${e.message}`)}return{success:Math.max(a,1),failed:o}}function un(e,t){let n=C.join(e,t.rulesDir),r=C.join(e,t.profileDir),i={profileName:t.profileName,success:!1,skipped:!1,error:null,filesRemoved:[],mcpResult:null,profileDirRemoved:!1,notice:null};try{if(typeof t.onRemoveRulesProfile==`function`)try{t.onRemoveRulesProfile(n),h(`debug`,`[Rule Transformer] Called onRemoveRulesProfile for ${t.profileName}`)}catch(e){h(`error`,`[Rule Transformer] onRemoveRulesProfile failed for ${t.profileName}: ${e.message}`)}let a=Object.keys(t.fileMap);if(a.length>0){if(!S.existsSync(r))return i.success=!0,i.skipped=!0,h(`debug`,`[Rule Transformer] Profile directory does not exist: ${r}`),i;let o=!1;if(S.existsSync(n)){let r=a.map(e=>t.fileMap[e]),s=[];if(n===e||t.rulesDir===`.`){let e=S.readdirSync(n);for(let t of e){if(t===`node_modules`||t===`.git`||t===`dist`)continue;let e=C.join(n,t);try{let n=S.lstatSync(e);n.isFile()?s.push(t):n.isDirectory()&&!n.isSymbolicLink()&&S.readdirSync(e,{recursive:!0}).forEach(e=>{s.push(C.join(t,e.toString()))})}catch{}}}else s=S.readdirSync(n,{recursive:!0});let c=s.filter(e=>{let t=C.join(n,e);try{return S.statSync(t).isFile()}catch{return!1}}).map(e=>e.toString());for(let e of r){let t=C.join(n,e);if(S.existsSync(t))try{S.rmSync(t,{force:!0}),i.filesRemoved.push(e),h(`debug`,`[Rule Transformer] Removed Task Master file: ${e}`)}catch(t){h(`error`,`[Rule Transformer] Failed to remove ${e}: ${t.message}`)}}let l=c.filter(e=>!r.includes(e));o=l.length>0,l.length===0?(S.rmSync(n,{recursive:!0,force:!0}),h(`debug`,`[Rule Transformer] Removed empty rules directory: ${n}`)):o&&(i.notice=`Preserved ${l.length} existing rule files in ${t.rulesDir}`,h(`info`,`[Rule Transformer] ${i.notice}`))}}if(t.mcpConfig!==!1)try{i.mcpResult=Ce(e,t.mcpConfigPath),i.mcpResult.hasOtherServers&&(i.notice?i.notice+=`; preserved other MCP server configurations`:i.notice=`Preserved other MCP server configurations`),h(`debug`,`[Rule Transformer] Processed MCP configuration for ${t.profileName}`)}catch(e){h(`error`,`[Rule Transformer] MCP cleanup failed for ${t.profileName}: ${e.message}`)}if(t.slashCommands)try{let n=t.slashCommands.profile.removeSlashCommands(e,t.slashCommands.commands);n.success&&n.count>0?h(`debug`,`[Rule Transformer] Removed ${n.count} slash commands for ${t.profileName}`):n.success||h(`error`,`[Rule Transformer] Failed to remove slash commands for ${t.profileName}: ${n.error}`)}catch(e){h(`error`,`[Rule Transformer] Slash command cleanup failed for ${t.profileName}: ${e.message}`)}if(S.existsSync(r)){let e=S.readdirSync(r);if(e.length===0&&t.profileDir!==`.`)try{S.rmSync(r,{recursive:!0,force:!0}),i.profileDirRemoved=!0,h(`debug`,`[Rule Transformer] Removed empty profile directory: ${r}`)}catch(e){h(`error`,`[Rule Transformer] Failed to remove profile directory ${r}: ${e.message}`)}else if(e.length>0){let n=`Preserved ${e.length} existing files/folders in ${t.profileDir}`;i.notice?i.notice+=`; ${n.toLowerCase()}`:i.notice=n,h(`info`,`[Rule Transformer] ${n}`)}}i.success=!0,h(`debug`,`[Rule Transformer] Successfully removed ${t.profileName} Task Master files from ${e}`)}catch(e){i.error=e.message,h(`error`,`[Rule Transformer] Failed to remove ${t.profileName} rules: ${e.message}`)}return i}function dn(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(s[n]){let i=s[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 Y={debug:0,info:1,warn:2,error:3,success:4},fn=process.env.TASKMASTER_LOG_LEVEL?Y[process.env.TASKMASTER_LOG_LEVEL.toLowerCase()]:Y.info;function pn(){m()||y()}function X(e,...t){let n={debug:x.gray(`•`),info:x.blue(`→`),warn:x.yellow(`!`),error:x.red(`✗`),success:x.green(`✓`)};if(Y[e]>=fn){let r=n[e]||``;m()||(e===`error`?console.error(r,x.red(...t)):e===`warn`?console.warn(r,x.yellow(...t)):e===`success`?console.log(r,x.green(...t)):e===`info`?console.log(r,x.blue(...t)):console.log(r,...t))}if(process.env.DEBUG===`true`){let n=`[${e.toUpperCase()}] ${t.join(` `)}\n`;S.appendFileSync(`init-debug.log`,n)}}function Z(e){S.existsSync(e)||(S.mkdirSync(e,{recursive:!0}),X(`info`,`Created directory: ${e}`))}function mn(){let e=process.env.HOME||process.env.USERPROFILE,t;if(process.env.SHELL?.includes(`zsh`))t=C.join(e,`.zshrc`);else if(process.env.SHELL?.includes(`bash`))t=C.join(e,`.bashrc`);else return X(`debug`,`Could not determine shell type. Aliases not added.`),!1;try{if(!S.existsSync(t))return X(`debug`,`Shell config file ${t} not found.`),!1;let e=S.readFileSync(t,`utf8`),n=[{name:`tm`,line:`alias tm='task-master'`},{name:`taskmaster`,line:`alias taskmaster='task-master'`},{name:`hamster`,line:`alias hamster='task-master'`},{name:`ham`,line:`alias ham='task-master'`}].filter(t=>!e.includes(t.line));if(n.length===0)return X(`debug`,`All Task Master aliases already exist.`),!0;let r=n.map(e=>e.line).join(`
|
|
3489
|
+
---`}],onPostConvert:(e,t)=>{let n=T.join(t,`kiro-hooks`),r=T.join(e,`.kiro`,`hooks`);if(w.existsSync(r)||w.mkdirSync(r,{recursive:!0}),w.existsSync(n)){let e=w.readdirSync(n).filter(e=>e.endsWith(`.kiro.hook`));e.forEach(e=>{let t=T.join(n,e),i=T.join(r,e);w.copyFileSync(t,i)}),e.length>0&&g(`info`,`[Kiro] Installed ${e.length} Taskmaster hooks in .kiro/hooks/`)}}});function It(e){let t={$schema:`https://opencode.ai/config.json`};if(e.mcpServers){t.mcp={};for(let[n,r]of Object.entries(e.mcpServers)){let e={type:`local`};r.command&&r.args?e.command=[r.command,...r.args]:r.command&&(e.command=[r.command]),e.enabled=!0,r.env&&(e.environment=r.env),t.mcp[n]=e}}return t}function Lt(e,t){let n=T.join(e,`opencode.json`);if(!w.existsSync(n)){g(`debug`,`[OpenCode] No opencode.json found to transform`);return}try{let e=w.readFileSync(n,`utf8`),t=JSON.parse(e);if(t.$schema){g(`info`,`[OpenCode] opencode.json already in OpenCode format, skipping transformation`);return}let r=It(t);w.writeFileSync(n,JSON.stringify(r,null,2)+`
|
|
3490
|
+
`),g(`info`,`[OpenCode] Transformed opencode.json to OpenCode format`),g(`debug`,`[OpenCode] Added schema, renamed mcpServers->mcp, combined command+args, added type/enabled, renamed env->environment`)}catch(e){g(`error`,`[OpenCode] Failed to transform opencode.json: ${e.message}`)}}function Rt(e){let t=T.join(e,`opencode.json`);if(!w.existsSync(t)){g(`debug`,`[OpenCode] No opencode.json found to clean up`);return}try{let e=w.readFileSync(t,`utf8`),n=JSON.parse(e);n.mcp&&n.mcp[`taskmaster-ai`]?(delete n.mcp[`taskmaster-ai`],Object.keys(n.mcp).length===0&&delete n.mcp,Object.keys(n).filter(e=>e!==`$schema`).length===0?(w.rmSync(t,{force:!0}),g(`info`,`[OpenCode] Removed empty opencode.json file`)):(w.writeFileSync(t,JSON.stringify(n,null,2)+`
|
|
3491
|
+
`),g(`info`,`[OpenCode] Removed TaskMaster from opencode.json, preserved other configurations`))):g(`debug`,`[OpenCode] TaskMaster not found in opencode.json`)}catch(e){g(`error`,`[OpenCode] Failed to clean up opencode.json: ${e.message}`)}}const zt=G({name:`opencode`,displayName:`OpenCode`,url:`opencode.ai`,docsUrl:`opencode.ai/docs/`,profileDir:`.`,rulesDir:`.`,mcpConfigName:`opencode.json`,includeDefaultRules:!1,fileMap:{"AGENTS.md":`AGENTS.md`},onPostConvert:Lt,onRemove:Rt});function Bt(e){if(!w.existsSync(e)){g(`warn`,`[Roo] MCP configuration file not found at ${e}`);return}try{let t=JSON.parse(w.readFileSync(e,`utf8`));if(t.mcpServers&&t.mcpServers[`task-master-ai`]){let n=t.mcpServers[`task-master-ai`];n.timeout=300,w.writeFileSync(e,R(t)+`
|
|
3492
|
+
`),g(`debug`,`[Roo] Enhanced MCP configuration with timeout at ${e}`)}else g(`warn`,`[Roo] task-master-ai server not found in MCP configuration`)}catch(e){g(`error`,`[Roo] Failed to enhance MCP configuration: ${e.message}`)}}function Vt(e,t){let n=T.join(t,`roocode`);if(!w.existsSync(n)){g(`error`,`[Roo] Source directory does not exist: ${n}`);return}Ht(n,e),g(`debug`,`[Roo] Copied roocode directory to ${e}`);let r=T.join(n,`.roo`),i=T.join(n,`.roomodes`),a=T.join(e,`.roomodes`);if(w.existsSync(i))try{w.copyFileSync(i,a),g(`debug`,`[Roo] Copied .roomodes to ${a}`)}catch(e){g(`error`,`[Roo] Failed to copy .roomodes: ${e.message}`)}for(let t of oe){let n=T.join(r,`rules-${t}`,`${t}-rules`),i=T.join(e,`.roo`,`rules-${t}`,`${t}-rules`);if(w.existsSync(n))try{let e=T.dirname(i);w.existsSync(e)||w.mkdirSync(e,{recursive:!0}),w.copyFileSync(n,i),g(`debug`,`[Roo] Copied ${t}-rules to ${i}`)}catch(e){g(`error`,`[Roo] Failed to copy ${n} to ${i}: ${e.message}`)}}}function Ht(e,t){let n=w.existsSync(e),r=n&&w.statSync(e);n&&r.isDirectory()?(w.existsSync(t)||w.mkdirSync(t,{recursive:!0}),w.readdirSync(e).forEach(n=>{Ht(T.join(e,n),T.join(t,n))})):w.copyFileSync(e,t)}function Ut(e){let t=T.join(e,`.roomodes`);if(w.existsSync(t))try{w.rmSync(t,{force:!0}),g(`debug`,`[Roo] Removed .roomodes from ${t}`)}catch(e){g(`error`,`[Roo] Failed to remove .roomodes: ${e.message}`)}let n=T.join(e,`.roo`);if(w.existsSync(n)){let e=T.join(n,`mcp.json`);try{w.rmSync(e,{force:!0}),g(`debug`,`[Roo] Removed MCP configuration from ${e}`)}catch(e){g(`error`,`[Roo] Failed to remove MCP configuration: ${e.message}`)}if(w.readdirSync(n).forEach(e=>{if(e.startsWith(`rules-`)){let t=T.join(n,e);try{w.rmSync(t,{recursive:!0,force:!0}),g(`debug`,`[Roo] Removed ${e} directory from ${t}`)}catch(e){g(`error`,`[Roo] Failed to remove ${t}: ${e.message}`)}}}),w.readdirSync(n).length===0)try{w.rmSync(n,{recursive:!0,force:!0}),g(`debug`,`[Roo] Removed empty .roo directory from ${n}`)}catch(e){g(`error`,`[Roo] Failed to remove .roo directory: ${e.message}`)}}}function Wt(e,t){let n=T.join(e,`.roo`,`mcp.json`);try{Bt(n)}catch(e){g(`error`,`[Roo] Failed to enhance MCP configuration: ${e.message}`)}}const Gt=G({name:`roo`,displayName:`Roo Code`,url:`roocode.com`,docsUrl:`docs.roocode.com`,toolMappings:mt.ROO_STYLE,mcpConfig:!0,onAdd:Vt,onRemove:Ut,onPostConvert:Wt}),Kt=G({name:`trae`,displayName:`Trae`,url:`trae.ai`,docsUrl:`docs.trae.ai`,mcpConfig:!1});function qt(e){let t={};if(e.mcpServers){t.servers={};for(let[n,r]of Object.entries(e.mcpServers)){let e={...r};if(e.env){let r={};e.command&&(r.command=e.command),e.args&&(r.args=e.args),e.env&&(r.env=e.env),r.type=`stdio`,Object.keys(e).forEach(t=>{[`command`,`args`,`env`,`type`].includes(t)||(r[t]=e[t])}),t.servers[n]=r}else e.type=`stdio`,t.servers[n]=e}}return t}function Jt(e,t){let n=T.join(e,`.vscode`,`mcp.json`);if(!w.existsSync(n)){g(`debug`,`[VS Code] No .vscode/mcp.json found to transform`);return}try{let e=w.readFileSync(n,`utf8`),t=JSON.parse(e);if(t.servers){g(`info`,`[VS Code] mcp.json already in VS Code format, skipping transformation`);return}let r=qt(t);w.writeFileSync(n,JSON.stringify(r,null,2)+`
|
|
3493
|
+
`),g(`info`,`[VS Code] Transformed mcp.json to VS Code format`),g(`debug`,`[VS Code] Renamed mcpServers->servers, added type: "stdio"`)}catch(e){g(`error`,`[VS Code] Failed to transform mcp.json: ${e.message}`)}}function Yt(e){let t=T.join(e,`.vscode`,`mcp.json`);if(!w.existsSync(t)){g(`debug`,`[VS Code] No .vscode/mcp.json found to clean up`);return}try{let e=w.readFileSync(t,`utf8`),n=JSON.parse(e);if(n.servers&&n.servers[`task-master-ai`])if(delete n.servers[`task-master-ai`],Object.keys(n.servers).length===0){w.rmSync(t,{force:!0}),g(`info`,`[VS Code] Removed empty mcp.json file`);let e=T.dirname(t);try{w.readdirSync(e).length===0&&(w.rmSync(e,{recursive:!0,force:!0}),g(`debug`,`[VS Code] Removed empty .vscode directory`))}catch{}}else w.writeFileSync(t,JSON.stringify(n,null,2)+`
|
|
3494
|
+
`),g(`info`,`[VS Code] Removed TaskMaster from mcp.json, preserved other configurations`);else g(`debug`,`[VS Code] TaskMaster not found in mcp.json`)}catch(e){g(`error`,`[VS Code] Failed to clean up mcp.json: ${e.message}`)}}const Xt=G({name:`vscode`,displayName:`VS Code`,url:`code.visualstudio.com`,docsUrl:`code.visualstudio.com/docs`,rulesDir:`.github/instructions`,profileDir:`.vscode`,mcpConfigName:`mcp.json`,targetExtension:`.instructions.md`,customReplacements:[{from:/\.cursor\/rules/g,to:`.github/instructions`},{from:/\.cursor\/mcp\.json/g,to:`.vscode/mcp.json`},{from:/\.vscode\/rules/g,to:`.github/instructions`},{from:/^globs:\s*(.+)$/gm,to:`applyTo: "$1"`},{from:/^alwaysApply:\s*(true|false)\s*\n?/gm,to:``},{from:/\[(.+?)\]\(mdc:\.cursor\/rules\/(.+?)\.mdc\)/g,to:`[$1](.github/instructions/$2.instructions.md)`},{from:/rules directory/g,to:`instructions directory`},{from:/cursor rules/gi,to:`VS Code instructions`}],onPostConvert:Jt,onRemove:Yt}),Zt=G({name:`windsurf`,displayName:`Windsurf`,url:`windsurf.com`,docsUrl:`docs.windsurf.com`});function Qt(e){let t={};e.mcpServers&&(t.context_servers=e.mcpServers);for(let[n,r]of Object.entries(e))n!==`mcpServers`&&(t[n]=r);return t}function $t(e,t){}function en(e){let t=T.join(e,`.rules`);try{w.existsSync(t)&&(w.rmSync(t,{force:!0}),g(`debug`,`[Zed] Removed ${t}`))}catch(e){g(`error`,`[Zed] Failed to remove Zed instructions: ${e.message}`)}let n=T.join(e,`.zed`,`settings.json`);if(!w.existsSync(n)){g(`debug`,`[Zed] No .zed/settings.json found to clean up`);return}try{let t=w.readFileSync(n,`utf8`),r=JSON.parse(t);if(r.context_servers&&r.context_servers[`task-master-ai`])if(delete r.context_servers[`task-master-ai`],Object.keys(r.context_servers).length===0&&(delete r.context_servers,g(`debug`,`[Zed] Removed empty context_servers section`)),Object.keys(r).length===0){w.rmSync(n,{force:!0}),g(`info`,`[Zed] Removed empty settings.json file`);let t=T.join(e,`.zed`);w.existsSync(t)&&w.readdirSync(t).length===0&&(w.rmSync(t,{recursive:!0,force:!0}),g(`debug`,`[Zed] Removed empty .zed directory`))}else w.writeFileSync(n,JSON.stringify(r,null,` `)+`
|
|
3495
|
+
`),g(`info`,`[Zed] Removed TaskMaster from settings.json, preserved other configurations`);else g(`debug`,`[Zed] TaskMaster not found in context_servers`)}catch(e){g(`error`,`[Zed] Failed to clean up settings.json: ${e.message}`)}}function tn(e,t){let n=T.join(e,`.zed`,`settings.json`);if(!w.existsSync(n)){g(`debug`,`[Zed] No .zed/settings.json found to transform`);return}try{let e=w.readFileSync(n,`utf8`),t=JSON.parse(e);if(t.context_servers){g(`info`,`[Zed] settings.json already in Zed format, skipping transformation`);return}let r=Qt(t);r.context_servers&&r.context_servers[`task-master-ai`]&&(r.context_servers[`task-master-ai`].source=`custom`),w.writeFileSync(n,JSON.stringify(r,null,` `)+`
|
|
3496
|
+
`),g(`info`,`[Zed] Transformed settings.json to Zed format`),g(`debug`,`[Zed] Renamed mcpServers to context_servers`)}catch(e){g(`error`,`[Zed] Failed to transform settings.json: ${e.message}`)}}const nn=G({name:`zed`,displayName:`Zed`,url:`zed.dev`,docsUrl:`zed.dev/docs`,profileDir:`.zed`,rulesDir:`.`,mcpConfig:!0,mcpConfigName:`settings.json`,includeDefaultRules:!1,fileMap:{"AGENTS.md":`.rules`},onAdd:$t,onRemove:en,onPostConvert:tn});var rn=e({ampProfile:()=>yt,claudeProfile:()=>wt,clineProfile:()=>Tt,codexProfile:()=>Et,cursorProfile:()=>Dt,geminiProfile:()=>Ot,kiloProfile:()=>Pt,kiroProfile:()=>Ft,opencodeProfile:()=>zt,rooProfile:()=>Gt,traeProfile:()=>Kt,vscodeProfile:()=>Xt,windsurfProfile:()=>Zt,zedProfile:()=>nn});function K(e){return N.includes(e)}function q(e){if(!K(e))return null;let t=rn[`${e}Profile`];if(!t)throw Error(`Profile not found: static import missing for '${e}'. Valid profiles: ${N.join(`, `)}`);return t}function an(e,t){let n=e;return t.profileTerms.forEach(e=>{n=(e.to,n.replace(e.from,e.to))}),t.fileExtensions.forEach(e=>{n=n.replace(e.from,e.to)}),n}function on(e,t){let n=e,r=t.toolNames,i=RegExp(`\\b(${Object.keys(r).join(`|`)})\\b`,`g`);return n=n.replace(i,(e,t)=>r[t]||t),t.toolContexts.forEach(e=>{n=n.replace(e.from,e.to)}),t.toolGroups.forEach(e=>{n=n.replace(e.from,e.to)}),n}function sn(e,t){let n=e;return t.docUrls.forEach(e=>{n=(e.to,n.replace(e.from,e.to))}),n}function cn(e,t){let{pathPattern:n,replacement:r}=t.fileReferences;return e.replace(n,r)}function ln(e,t,n){let r=e;return r=cn(r,t),r=an(r,t),r=on(r,t),r=sn(r,t),n.forEach(e=>{r=(e.to,r.replace(e.from,e.to))}),r}function un(e,t){let n=T.join(e,t.rulesDir);if(!w.existsSync(n))return;let r=Object.values(t.fileMap);for(let e of r){let t=T.join(n,e);if(w.existsSync(t))try{w.rmSync(t,{force:!0}),g(`debug`,`[Rule Transformer] Removed rule file: ${e}`)}catch(t){g(`warn`,`[Rule Transformer] Failed to remove rule file ${e}: ${t.message}`)}}}function J(e,t,n){let r=T.join(e,t.rulesDir),i=n?.mode,a=0,o=0;if(i&&(un(e,t),g(`debug`,`[Rule Transformer] Cleaned up existing rules before adding ${i} mode rules`)),typeof t.onAddRulesProfile==`function`)try{let e=I();t.onAddRulesProfile(r,e),g(`debug`,`[Rule Transformer] Called onAddRulesProfile for ${t.profileName}`)}catch(e){g(`error`,`[Rule Transformer] onAddRulesProfile failed for ${t.profileName}: ${e.message}`),o++}let s=i?pt(t.fileMap,i):t.fileMap,c=Object.keys(s);if(c.length>0){w.existsSync(r)||w.mkdirSync(r,{recursive:!0});for(let e of c){let n=!e.startsWith(`rules/`);try{if(!Se(e)){g(`warn`,`[Rule Transformer] Source file not found: ${e}, skipping`);continue}let i=s[e],o=T.join(r,i),c=T.dirname(o);w.existsSync(c)||w.mkdirSync(c,{recursive:!0});let l=L(e,`utf8`);n||(l=ln(l,t.conversionConfig,t.globalReplacements)),w.writeFileSync(o,l,`utf8`),a++,g(`debug`,`[Rule Transformer] ${n?`Copied`:`Converted`} ${e} -> ${i} for ${t.profileName}`)}catch(r){o++,g(`error`,`[Rule Transformer] Failed to ${n?`copy`:`convert`} ${e} for ${t.profileName}: ${r.message}`)}}}if(t.mcpConfig!==!1)try{Ce(e,t.mcpConfigPath),g(`debug`,`[Rule Transformer] Setup MCP configuration for ${t.profileName}`)}catch(e){g(`error`,`[Rule Transformer] MCP setup failed for ${t.profileName}: ${e.message}`)}if(typeof t.onPostConvertRulesProfile==`function`)try{let e=I();t.onPostConvertRulesProfile(r,e),g(`debug`,`[Rule Transformer] Called onPostConvertRulesProfile for ${t.profileName}`)}catch(e){g(`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?g(`debug`,`[Rule Transformer] Created ${r.count} slash commands in ${r.directory}${i?` (mode: ${i})`:``}`):g(`error`,`[Rule Transformer] Failed to add slash commands for ${t.profileName}: ${r.error}`)}catch(e){g(`error`,`[Rule Transformer] Slash commands failed for ${t.profileName}: ${e.message}`)}return{success:Math.max(a,1),failed:o}}function dn(e,t){let n=T.join(e,t.rulesDir),r=T.join(e,t.profileDir),i={profileName:t.profileName,success:!1,skipped:!1,error:null,filesRemoved:[],mcpResult:null,profileDirRemoved:!1,notice:null};try{if(typeof t.onRemoveRulesProfile==`function`)try{t.onRemoveRulesProfile(n),g(`debug`,`[Rule Transformer] Called onRemoveRulesProfile for ${t.profileName}`)}catch(e){g(`error`,`[Rule Transformer] onRemoveRulesProfile failed for ${t.profileName}: ${e.message}`)}let a=Object.keys(t.fileMap);if(a.length>0){if(!w.existsSync(r))return i.success=!0,i.skipped=!0,g(`debug`,`[Rule Transformer] Profile directory does not exist: ${r}`),i;let o=!1;if(w.existsSync(n)){let r=a.map(e=>t.fileMap[e]),s=[];if(n===e||t.rulesDir===`.`){let e=w.readdirSync(n);for(let t of e){if(t===`node_modules`||t===`.git`||t===`dist`)continue;let e=T.join(n,t);try{let n=w.lstatSync(e);n.isFile()?s.push(t):n.isDirectory()&&!n.isSymbolicLink()&&w.readdirSync(e,{recursive:!0}).forEach(e=>{s.push(T.join(t,e.toString()))})}catch{}}}else s=w.readdirSync(n,{recursive:!0});let c=s.filter(e=>{let t=T.join(n,e);try{return w.statSync(t).isFile()}catch{return!1}}).map(e=>e.toString());for(let e of r){let t=T.join(n,e);if(w.existsSync(t))try{w.rmSync(t,{force:!0}),i.filesRemoved.push(e),g(`debug`,`[Rule Transformer] Removed Task Master file: ${e}`)}catch(t){g(`error`,`[Rule Transformer] Failed to remove ${e}: ${t.message}`)}}let l=c.filter(e=>!r.includes(e));o=l.length>0,l.length===0?(w.rmSync(n,{recursive:!0,force:!0}),g(`debug`,`[Rule Transformer] Removed empty rules directory: ${n}`)):o&&(i.notice=`Preserved ${l.length} existing rule files in ${t.rulesDir}`,g(`info`,`[Rule Transformer] ${i.notice}`))}}if(t.mcpConfig!==!1)try{i.mcpResult=we(e,t.mcpConfigPath),i.mcpResult.hasOtherServers&&(i.notice?i.notice+=`; preserved other MCP server configurations`:i.notice=`Preserved other MCP server configurations`),g(`debug`,`[Rule Transformer] Processed MCP configuration for ${t.profileName}`)}catch(e){g(`error`,`[Rule Transformer] MCP cleanup failed for ${t.profileName}: ${e.message}`)}if(t.slashCommands)try{let n=t.slashCommands.profile.removeSlashCommands(e,t.slashCommands.commands);n.success&&n.count>0?g(`debug`,`[Rule Transformer] Removed ${n.count} slash commands for ${t.profileName}`):n.success||g(`error`,`[Rule Transformer] Failed to remove slash commands for ${t.profileName}: ${n.error}`)}catch(e){g(`error`,`[Rule Transformer] Slash command cleanup failed for ${t.profileName}: ${e.message}`)}if(w.existsSync(r)){let e=w.readdirSync(r);if(e.length===0&&t.profileDir!==`.`)try{w.rmSync(r,{recursive:!0,force:!0}),i.profileDirRemoved=!0,g(`debug`,`[Rule Transformer] Removed empty profile directory: ${r}`)}catch(e){g(`error`,`[Rule Transformer] Failed to remove profile directory ${r}: ${e.message}`)}else if(e.length>0){let n=`Preserved ${e.length} existing files/folders in ${t.profileDir}`;i.notice?i.notice+=`; ${n.toLowerCase()}`:i.notice=n,g(`info`,`[Rule Transformer] ${n}`)}}i.success=!0,g(`debug`,`[Rule Transformer] Successfully removed ${t.profileName} Task Master files from ${e}`)}catch(e){i.error=e.message,g(`error`,`[Rule Transformer] Failed to remove ${t.profileName} rules: ${e.message}`)}return i}function fn(e){try{let t=JSON.parse(w.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 w.writeFileSync(e,JSON.stringify(t,null,2)),!0}catch(e){return console.error(`Error updating config maxTokens:`,e.message),!1}}const Y={debug:0,info:1,warn:2,error:3,success:4},pn=process.env.TASKMASTER_LOG_LEVEL?Y[process.env.TASKMASTER_LOG_LEVEL.toLowerCase()]:Y.info;function mn(){h()||b()}function X(e,...t){let n={debug:C.gray(`•`),info:C.blue(`→`),warn:C.yellow(`!`),error:C.red(`✗`),success:C.green(`✓`)};if(Y[e]>=pn){let r=n[e]||``;h()||(e===`error`?console.error(r,C.red(...t)):e===`warn`?console.warn(r,C.yellow(...t)):e===`success`?console.log(r,C.green(...t)):e===`info`?console.log(r,C.blue(...t)):console.log(r,...t))}if(process.env.DEBUG===`true`){let n=`[${e.toUpperCase()}] ${t.join(` `)}\n`;w.appendFileSync(`init-debug.log`,n)}}function hn(e,t){return T.relative(e,t).split(T.sep).join(`/`)}function gn(e,t){return[`@${hn(e,t.skillAgentsPath)}`,`@${hn(e,t.skillPath)}`]}async function _n(e,t={},n=!1){if(!t.withCodex)return null;let r={agentsPath:T.join(e,`AGENTS.md`),skillPath:T.join(e,`.codex`,`skills`,`taskmaster-longrun`,`SKILL.md`),skillAgentsPath:T.join(e,`.codex`,`skills`,`taskmaster-longrun`,`AGENTS.md`)};if(n)return{enabled:!0,skipped:!0,reason:`dry-run`,paths:r,loadHints:gn(e,r)};let i;try{i=await p({projectPath:e});let t=await i.skillRun.initAssets({});return{enabled:!0,initialized:!0,paths:t.paths,created:t.created??[],updated:t.updated??[],skipped:t.skipped??[],loadHints:gn(e,t.paths)}}catch(t){return X(`warn`,`Codex asset initialization failed: ${t.message}`),X(`warn`,`You can retry with: task-master codex init`),{enabled:!0,initialized:!1,error:t.message,paths:r,loadHints:gn(e,r)}}finally{if(i)try{await i.close()}catch(e){X(`debug`,`Failed to close tm-core after codex init: ${e.message}`)}}}function vn(e){if(!e||h())return;let t=e.initialized?`Codex longrun assets ready (--with-codex).`:`Codex longrun assets were not fully initialized.`,n=e.initialized?C.green:C.yellow;console.log(n(t)),console.log(C.white(` Ask Codex to load: ${e.loadHints[0]} then ${e.loadHints[1]}`)),console.log(`TM_IMMEDIATE_ACTION: LOAD ${e.loadHints[0]}`),console.log(`TM_IMMEDIATE_ACTION: LOAD ${e.loadHints[1]}`),e.error&&console.log(C.yellow(` Detail: ${e.error}`))}function Z(e){w.existsSync(e)||(w.mkdirSync(e,{recursive:!0}),X(`info`,`Created directory: ${e}`))}function yn(){let e=process.env.HOME||process.env.USERPROFILE,t;if(process.env.SHELL?.includes(`zsh`))t=T.join(e,`.zshrc`);else if(process.env.SHELL?.includes(`bash`))t=T.join(e,`.bashrc`);else return X(`debug`,`Could not determine shell type. Aliases not added.`),!1;try{if(!w.existsSync(t))return X(`debug`,`Shell config file ${t} not found.`),!1;let e=w.readFileSync(t,`utf8`),n=[{name:`tm`,line:`alias tm='task-master'`},{name:`taskmaster`,line:`alias taskmaster='task-master'`},{name:`hamster`,line:`alias hamster='task-master'`},{name:`ham`,line:`alias ham='task-master'`}].filter(t=>!e.includes(t.line));if(n.length===0)return X(`debug`,`All Task Master aliases already exist.`),!0;let r=n.map(e=>e.line).join(`
|
|
3497
3497
|
`),i=`
|
|
3498
3498
|
# Task Master aliases added on ${new Date().toLocaleDateString()}
|
|
3499
3499
|
${r}
|
|
3500
|
-
`;return
|
|
3500
|
+
`;return w.appendFileSync(t,i),X(`debug`,`Added ${n.length} alias(es): ${n.map(e=>e.name).join(`, `)}`),!0}catch(e){return X(`debug`,`Failed to add aliases: ${e.message}`),!1}}function bn(e){let t=T.join(e,d);if(w.existsSync(t)){X(`debug`,`State file already exists, preserving current configuration`);return}let n={currentTag:`master`,lastSwitched:new Date().toISOString(),branchTagMapping:{},migrationNoticeShown:!1};try{w.writeFileSync(t,JSON.stringify(n,null,2)),X(`success`,`Created initial state file: ${t}`),X(`info`,`Default tag set to "master" for task organization`)}catch(e){X(`error`,`Failed to create state file: ${e.message}`)}}function Q(e,t,n={}){if(!Se(e)){X(`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)}),w.existsSync(t)){let e=T.basename(t);if(e===`.gitignore`){X(`info`,`${t} already exists, merging content...`);let e=w.readFileSync(t,`utf8`),n=new Set(e.split(`
|
|
3501
3501
|
`).map(e=>e.trim())),i=r.split(`
|
|
3502
3502
|
`).filter(e=>!n.has(e.trim()));if(i.length>0){let n=`${e.trim()}\n\n# Added by Taskmaster\n${i.join(`
|
|
3503
|
-
`)}`;
|
|
3503
|
+
`)}`;w.writeFileSync(t,n),X(`success`,`Updated ${t} with additional entries`)}else X(`info`,`No new content to add to ${t}`);return}if(e===`README-task-master.md`){X(`info`,`${t} already exists`);let e=T.join(T.dirname(t),`README-task-master.md`);w.writeFileSync(e,r),X(`success`,`Created ${e} (preserved original README-task-master.md)`);return}X(`debug`,`${t} already exists, skipping.`);return}w.writeFileSync(t,r),X(`info`,`Created file: ${t}`)}async function xn(e={}){h()||mn(),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){h()||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 X(`info`,`DRY RUN MODE: No files will be modified`),X(`info`,`Would initialize Task Master project`),X(`info`,`Would create/update necessary project files`),X(`info`,`${r?`Would initialize Git repository`:`Would skip Git initialization`}`),X(`info`,`${i?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};let a=e.storage||`local`;await Tn(!0,r,i,t,{...e,preferredLanguage:`Chinese`},n,a,null);let o=await _n(process.cwd(),e,t);return vn(o),o?{codex:o}:{}}else{X(`debug`,`Required options not provided, proceeding with prompts.`);let t;try{let r=Sn();X(`debug`,`Init started - taskmaster_id: ${r}`);let i=await wn();X(`debug`,`Storage selected: ${i} - taskmaster_id: ${r}`);let a=null;if(i===`cloud`)try{let e=f.getInstance(),t=await e.getAuthCredentials();t?(X(`success`,`Already authenticated with Hamster`),a=t):(X(`info`,`Starting authentication flow...`),console.log(C.blue(`
|
|
3504
3504
|
🔐 Authentication Required
|
|
3505
|
-
`)),console.log(
|
|
3506
|
-
`)),a=await
|
|
3507
|
-
`+
|
|
3508
|
-
Do you want to continue with these settings? (Y/n): `))).trim().toLowerCase()===`n`){t.close(),X(`info`,`Project initialization cancelled by user`),process.exit(0);return}let d=e.dryRun||!1;if(d)return X(`info`,`DRY RUN MODE: No files will be modified`),X(`info`,`Would initialize Task Master project`),X(`info`,`Would create/update necessary project files`),X(`info`,`${o?`Would initialize Git repository`:`Would skip Git initialization`}`),X(`info`,`${s?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};await
|
|
3509
|
-
`),r(e)})})}function
|
|
3510
|
-
`));let{storageType:e}=await
|
|
3511
|
-
`),choices:[{name:[
|
|
3512
|
-
`),value:`local`,short:`Solo (Taskmaster)`},{name:[
|
|
3513
|
-
`),value:`cloud`,short:`Together (Hamster)`}],default:`local`,pageSize:20}]);return e}catch(e){if(e.isTtyError||e.name===`ExitPromptError`)return X(`warn`,`Storage selection cancelled, defaulting to local storage`),`local`;throw e}}async function
|
|
3514
|
-
|
|
3515
|
-
`)+
|
|
3516
|
-
`)+
|
|
3517
|
-
`)+
|
|
3518
|
-
`)+
|
|
3519
|
-
`+
|
|
3520
|
-
`),
|
|
3521
|
-
`);console.log(
|
|
3505
|
+
`)),console.log(C.white(` Selecting cloud storage will open your browser for authentication.`)),console.log(C.gray(` This enables sync across devices with Hamster.
|
|
3506
|
+
`)),a=await v(e),X(`debug`,`Auth completed - taskmaster_id: ${r}`));let n=await y(e,{promptMessage:`Select an organization to continue:`});n.success||X(`warn`,n.message||`Organization selection required`)}catch(e){X(`error`,`Failed to authenticate: ${e.message}. Falling back to local storage.`),i=`local`}t=M.createInterface({input:process.stdin,output:process.stdout});let o=!0,s=!0;i===`local`?(o=e.initGit===void 0?(await $(t,C.cyan(`Initialize a Git repository in project root? (Y/n): `),e=>{let t=e.trim().toLowerCase()!==`n`,n=t?C.green(`✓`):C.red(`✗`);return C.cyan(`Initialize a Git repository in project root?`)+` `+n+` `+C.dim(t?`Yes`:`No`)})).trim().toLowerCase()!==`n`:e.initGit,s=e.storeTasksInGit===void 0?(await $(t,C.cyan(`Store tasks in Git (tasks.json and tasks/ directory)? (Y/n): `),e=>{let t=e.trim().toLowerCase()!==`n`,n=t?C.green(`✓`):C.red(`✗`);return C.cyan(`Store tasks in Git (tasks.json and tasks/ directory)?`)+` `+n+` `+C.dim(t?`Yes`:`No`)})).trim().toLowerCase()!==`n`:e.storeTasksInGit):(o=!0,s=!1);let c=!1;e.rulesExplicitlyProvided?X(`info`,`Using rule profiles provided via command line: ${n.join(`, `)}`):c=(await $(t,C.cyan(`Set up AI IDE rules for better integration? (Cursor, Windsurf, etc.) (y/N): `),e=>{let t=e.trim().toLowerCase()===`y`,n=t?C.green(`✓`):C.red(`✗`);return C.cyan(`Set up AI IDE rules for better integration?`)+` `+n+` `+C.dim(t?`Yes`:`No`)})).trim().toLowerCase()===`y`;let l=(await $(t,C.cyan(`Preferred response language (Chinese): `))).trim()||`Chinese`;console.log(`
|
|
3507
|
+
`+C.bold(`Taskmaster Project Settings:`)),console.log(C.dim(`─`.repeat(50))),console.log(` `+C.dim(`Storage:`.padEnd(32)),C.white(i===`cloud`?`Hamster Studio`:`Local File Storage`));let u=c?C.green(`✓`):C.dim(`✗`);if(console.log(` `+C.dim(`AI IDE rules:`.padEnd(32)),u+` `+C.dim(c?`Yes`:`No`)),console.log(` `+C.dim(`Response language:`.padEnd(32)),C.white(l)),i===`local`){let e=o?C.green(`✓`):C.dim(`✗`);console.log(` `+C.dim(`Initialize Git repository:`.padEnd(32)),e+` `+C.dim(o?`Yes`:`No`));let t=s?C.green(`✓`):C.dim(`✗`);console.log(` `+C.dim(`Store tasks in Git:`.padEnd(32)),t+` `+C.dim(s?`Yes`:`No`))}if(console.log(C.dim(`─`.repeat(50))),(await $(t,C.yellow(`
|
|
3508
|
+
Do you want to continue with these settings? (Y/n): `))).trim().toLowerCase()===`n`){t.close(),X(`info`,`Project initialization cancelled by user`),process.exit(0);return}let d=e.dryRun||!1;if(d)return X(`info`,`DRY RUN MODE: No files will be modified`),X(`info`,`Would initialize Task Master project`),X(`info`,`Would create/update necessary project files`),X(`info`,`${o?`Would initialize Git repository`:`Would skip Git initialization`}`),X(`info`,`${s?`Would store tasks in Git`:`Would exclude tasks from Git`}`),{dryRun:!0};await Tn(!0,o,s,d,{...e,shouldSetupRules:c,preferredLanguage:l},n,i,a);let p=await _n(process.cwd(),e,d);return vn(p),t.close(),p?{codex:p}:{}}catch(e){t&&t.close(),X(`error`,`Error during initialization process: ${e.message}`),process.exit(1)}}}function $(e,t,n){return new Promise(r=>{e.question(t,e=>{M.moveCursor(process.stdout,0,-1),M.cursorTo(process.stdout,0),M.clearLine(process.stdout,0),n&&process.stdout.write(n(e)+`
|
|
3509
|
+
`),r(e)})})}function Sn(){return E()}function Cn(e,t,n){try{if(!w.existsSync(e)){X(`warn`,`Config file does not exist, skipping storage configuration`);return}let n=w.readFileSync(e,`utf8`),r=JSON.parse(n);r.storage||={},t===`cloud`?(r.storage.type=`api`,r.storage.apiEndpoint=process.env.TM_BASE_DOMAIN||process.env.TM_PUBLIC_BASE_DOMAIN||`https://tryhamster.com/api`,r.storage.operatingMode=`team`,X(`debug`,`Connected to Hamster Studio`)):(r.storage.type=`file`,r.storage.operatingMode=`solo`,X(`debug`,`Configured storage for local file storage`)),w.writeFileSync(e,JSON.stringify(r,null,2)),X(`debug`,`Storage configuration updated in config.json`)}catch(e){X(`error`,`Failed to update storage configuration: ${e.message}`)}}async function wn(){if(h())return`local`;try{console.log(C.bold.cyan(`You need a plan before you execute.
|
|
3510
|
+
`));let{storageType:e}=await re.prompt([{type:`list`,name:`storageType`,message:C.white(`How do you want to build it?
|
|
3511
|
+
`),choices:[{name:[C.bold(`Solo (Taskmaster)`),``,C.white(` • Parse your own PRDs into structured task lists and build with any IDE or background agents`),C.white(` • Agents execute tasks with precision, no scope creep, no going off-track`),C.white(` • Tasks live in a local JSON file, everything stays in your repo`),C.white(` • Upgrade to Hamster to bring the Taskmaster experience to your team`),``].join(`
|
|
3512
|
+
`),value:`local`,short:`Solo (Taskmaster)`},{name:[C.bold(`Together (Hamster)`),``,C.white(` • Write a brief with your team. Hamster refines it into a plan.`),C.white(` • Your team drafts, refines, and aligns on the same page before executing`),C.white(` • One brief, one plan, one source of truth for execution`),C.white(` • Access tasks on Taskmaster and execute with any AI agent`),``].join(`
|
|
3513
|
+
`),value:`cloud`,short:`Together (Hamster)`}],default:`local`,pageSize:20}]);return e}catch(e){if(e.isTtyError||e.name===`ExitPromptError`)return X(`warn`,`Storage selection cancelled, defaulting to local storage`),`local`;throw e}}async function Tn(e,n,s,d,f,p=N,g=`local`,v=null){let y=process.cwd();X(`debug`,`Initializing project in ${y}`),Z(T.join(y,u)),Z(T.join(y,i)),Z(T.join(y,a)),Z(T.join(y,l)),Z(T.join(y,m)),bn(y);let b={year:new Date().getFullYear()},S=g===`cloud`?`team`:`solo`;function w(e){let t=q(e);t?J(y,t,{mode:S}):X(`warn`,`Unknown rule profile: ${e}`)}Q(`env.example`,T.join(y,c),b),Q(`config.json`,T.join(y,t),{...b});let E=T.join(y,t);fn(E)?X(`debug`,`Updated config with correct maxTokens values`):X(`debug`,`Could not update maxTokens in config`),Cn(E,g,v);try{let e=L(`gitignore`,`utf8`);ye(T.join(y,o),e,s,X)}catch(e){X(`error`,`Failed to create .gitignore: ${e.message}`)}Q(`example_prd.txt`,T.join(y,r)),Q(`example_prd_rpg.txt`,T.join(y,m,`example_prd_rpg.txt`));try{n===!1?X(`info`,`Git initialization skipped due to --no-git flag.`):n===!0?_()?X(`debug`,`Existing Git repository detected – skipping git init despite --git flag.`):(X(`info`,`Initializing Git repository due to --git flag...`),A(`git init`,{cwd:y,stdio:`ignore`}),X(`success`,`Git repository initialized`)):_()?X(`debug`,`Existing Git repository detected – skipping git init.`):(X(`info`,`No Git repository detected. Initializing one in project root...`),A(`git init`,{cwd:y,stdio:`ignore`}),X(`success`,`Git repository initialized`))}catch{X(`warn`,`Git not available, skipping repository initialization`)}if(f.rulesExplicitlyProvided||f.yes){X(`info`,`Generating profile rules from command-line flags...`);for(let e of p)w(e)}e&&yn();let D={cwd:y,stdio:`inherit`};if(h()&&(D.stdio=`ignore`,X(`info`,`Running npm install silently...`)),f.shouldSetupRules&&!h()&&!d&&!f?.yes&&!f.rulesExplicitlyProvided){console.log(j(C.cyan(`Configuring Rule Profiles...`),{padding:.5,margin:{top:1,bottom:.5},borderStyle:`round`,borderColor:`cyan`,width:60})),X(`info`,`Running interactive rules setup. Please select which rule profiles to include.`);try{A(`npx task-master rules --setup`,{stdio:`inherit`,cwd:y}),X(`success`,`Rule profiles configured.`)}catch(e){X(`error`,`Failed to configure rule profiles:`,e.message),X(`warn`,`You may need to run "task-master rules --setup" manually.`)}}else h()||d||f?.yes?f.rulesExplicitlyProvided?X(`debug`,`Skipping interactive rules setup because --rules flag was used.`):X(`debug`,`Skipping interactive rules setup in non-interactive mode.`):f.shouldSetupRules||X(`debug`,`Skipping rules setup - user declined.`);if(f.preferredLanguage&&!d)try{let e=(await import(`./response-language-B-J-_qEU.js`)).default;e(f.preferredLanguage,{projectRoot:y,silent:!0}),X(`debug`,`Response language set to: ${f.preferredLanguage}`)}catch(e){X(`warn`,`Failed to set response language: ${e.message}`)}else h()&&!d?X(`debug`,`Skipping response language setup in silent (MCP) mode.`):d&&X(`debug`,`DRY RUN: Skipping response language setup.`);if(!h()&&!d&&!f?.yes&&g===`local`){console.log(j(C.cyan(`Configuring AI Models...`),{padding:.5,margin:{top:1,bottom:.5},borderStyle:`round`,borderColor:`cyan`,width:60})),X(`info`,`Running interactive model setup. Please select your preferred AI models.`);try{A(`npx task-master models --setup`,{stdio:`inherit`,cwd:y}),X(`success`,`AI Models configured.`)}catch(e){X(`error`,`Failed to configure AI models:`,e.message),X(`warn`,`You may need to run "task-master models --setup" manually.`)}}else g===`cloud`&&!d?console.log(j(C.green.bold(`✓ AI Models Managed by Hamster - go ham!
|
|
3514
|
+
|
|
3515
|
+
`)+C.white(`Hamster handles all AI model configuration for you.
|
|
3516
|
+
`)+C.dim(`• Optimized model selection for your tasks
|
|
3517
|
+
`)+C.dim(`• No API keys required
|
|
3518
|
+
`)+C.dim(`• No extra costs`),{padding:1,margin:{top:1,bottom:.5},borderStyle:`round`,borderColor:`cyan`,width:60})):h()&&!d?(X(`info`,`Skipping interactive model setup in silent (MCP) mode.`),X(`warn`,`Please configure AI models using "task-master models --set-..." or the "models" MCP tool.`)):d?X(`info`,`DRY RUN: Skipping interactive model setup.`):f?.yes&&(X(`info`,`Skipping interactive model setup due to --yes flag.`),X(`info`,`Default AI models will be used. You can configure different models later using "task-master models --setup" or "task-master models --set-..." commands.`));if(e&&!d?(X(`debug`,`Adding shell aliases...`),yn()&&X(`debug`,`Shell aliases added successfully`)):e&&d&&X(`debug`,`DRY RUN: Would add shell aliases (tm, taskmaster)`),!h())if(g===`cloud`){let e=L(`hamster-art.txt`,`utf8`);console.log(`
|
|
3519
|
+
`+C.cyan(e)),console.log(``);let t=[C.green.bold(`✓ Connected to Hamster Studio`),``,C.white(`Your team's workspace is ready to go ham!
|
|
3520
|
+
`),C.dim(`Draft together. Align once. Build with agents.`),``,C.cyan(`How to orchestrate with Taskmaster:`),C.white(` • Create your first brief at: `)+C.underline.cyan(`https://tryhamster.com`),C.white(` • Connect your brief using `)+C.bold(`tm context <brief-url>`)+C.white(` to access tasks in Taskmaster`),C.white(` • Orchestrate and implement tasks using `)+C.bold(`tm next`)+C.white(` to kickoff any AI agent`),C.white(` • Run `)+C.bold(`tm help`)+C.white(` to explore other available commands`),C.white(` • Run `)+C.bold(`tm rules --setup`)+C.white(` to configure AI IDE rules for better integration`)].join(`
|
|
3521
|
+
`);console.log(j(t,{padding:1,margin:{top:1,bottom:0,left:0,right:0},borderStyle:`round`,borderColor:`cyan`,width:60}))}else console.log(j(`${x.multiline(te.textSync(`Success!`,{font:`Standard`}))}\n${C.green(`Project initialized successfully!`)}`,{padding:1,margin:1,borderStyle:`double`,borderColor:`green`,width:60}));if(!h()){let e;e=g===`cloud`?`${C.cyan.bold(`Here's how to execute your Hamster briefs with Taskmaster`)}\n\n${C.white(`1. `)}${C.yellow(`Create your first brief at`)} ${C.cyan.underline(`https://tryhamster.com`)}\n${C.white(` └─ `)}${C.dim(`Hamster will write your brief and generate the full task plan`)}\n${C.white(`2. `)}${C.yellow(`Add rules for your AI IDE(s)`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`tm rules --setup`)}${C.dim(` - Opens interactive setup`)}\n${C.white(`3. `)}${C.yellow(`Connect your brief to Taskmaster`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`tm context <brief-url> OR tm briefs`)}\n${C.white(`4. `)}${C.yellow(`View your tasks from the brief`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`tm list`)}${C.dim(` or `)}${C.cyan(`tm list all`)}${C.dim(` (with subtasks)`)}\n${C.white(`5. `)}${C.yellow(`Work on tasks with any AI coding assistant or background agent`)}\n${C.white(` ├─ `)}${C.dim(`CLI: `)}${C.cyan(`tm next`)}${C.dim(` - Find the next task to work on`)}\n${C.white(` ├─ `)}${C.dim(`CLI: `)}${C.cyan(`tm show <id>`)}${C.dim(` - View task details`)}\n${C.white(` ├─ `)}${C.dim(`CLI: `)}${C.cyan(`tm status <id> in-progress`)}${C.dim(` - Mark task started`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`tm status <id> done`)}${C.dim(` - Mark task complete`)}\n${C.white(`6. `)}${C.yellow(`Add notes or updates to tasks`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`tm update-task <id> <notes>`)}\n${C.white(`7. `)}${C.green.bold(`Ship it!`)}\n\n${C.dim(`* Run `)}${C.cyan(`tm help`)}${C.dim(` to see all available commands`)}`:`${C.cyan.bold(`Things you should do next:`)}\n\n${C.white(`1. `)}${C.yellow("Configure AI models and add API keys to `.env`")}\n${C.white(` ├─ `)}${C.dim(`Models: Use `)}${C.cyan(`task-master models`)}${C.dim(` commands`)}\n${C.white(` └─ `)}${C.dim(`Keys: Add provider API keys to .env (or .cursor/mcp.json)`)}\n${C.white(`2. `)}${C.yellow(`Discuss your idea with AI and create a PRD`)}\n${C.white(` ├─ `)}${C.dim(`Simple projects: Use `)}${C.cyan(`example_prd.txt`)}${C.dim(` template`)}\n${C.white(` └─ `)}${C.dim(`Complex systems: Use `)}${C.cyan(`example_prd_rpg.txt`)}${C.dim(` template`)}\n${C.white(`3. `)}${C.yellow(`Parse your PRD to generate initial tasks`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`task-master parse-prd .taskmaster/docs/prd.txt`)}\n${C.white(`4. `)}${C.yellow(`Analyze task complexity`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`task-master analyze-complexity --research`)}\n${C.white(`5. `)}${C.yellow(`Expand tasks into subtasks`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`task-master expand --all --research`)}\n${C.white(`6. `)}${C.yellow(`Start working on tasks`)}\n${C.white(` └─ `)}${C.dim(`CLI: `)}${C.cyan(`task-master next`)}\n${C.white(`7. `)}${C.green.bold(`Ship it!`)}\n\n${C.dim(`* Run `)}${C.cyan(`task-master --help`)}${C.dim(` to see all available commands`)}\n${C.dim(`* Run `)}${C.cyan(`tm rules --setup`)}${C.dim(` to configure AI IDE rules for better integration`)}`,console.log(j(C.yellow.bold(`Workflow
|
|
3522
3522
|
`)+`
|
|
3523
|
-
`+e,{padding:1,margin:{top:0,bottom:1,left:0,right:0},borderStyle:`round`,borderColor:`yellow`,width:60}))}}const
|
|
3524
|
-
`))}let n=
|
|
3525
|
-
`);console.log(
|
|
3523
|
+
`+e,{padding:1,margin:{top:0,bottom:1,left:0,right:0},borderStyle:`round`,borderColor:`yellow`,width:60}))}}const En={ADD:`add`,REMOVE:`remove`},Dn=`setup`;function On(e){return Object.values(En).includes(e)}function kn(e){try{return q(e).displayName||e}catch{return e}}function An(e){let t=[];for(let n of N)try{let r=q(n),i=T.join(e,r.profileDir);if(r.profileDir===`.`||w.existsSync(i)){let i=T.join(e,r.rulesDir);w.existsSync(i)&&Object.values(r.fileMap).some(e=>w.existsSync(T.join(i,e)))&&t.push(n)}}catch{}return t}function jn(e,t){let n=An(e);return n.length===0?!1:n.filter(e=>!t.includes(e)).length===0}async function Mn(e=process.cwd()){let t=dt({projectRoot:e});if(t.length>0){let e=t.map(e=>kn(e)).join(`, `);console.log(C.cyan(`\n🔍 Auto-detected IDEs: ${e}`)+C.gray(` (pre-selected below)
|
|
3524
|
+
`))}let n=N.map(e=>{let t=kn(e),n=q(e),r,i=Object.keys(n.fileMap).length>0,a=n.mcpConfig===!0;return n.includeDefaultRules?i&&a?r=e===`roo`?`Rule profile, MCP config, and agent modes`:`Rule profile and MCP config`:i&&(r=`Rule profile`):r=e===`claude`?`Integration guide with Task Master slash commands`:e===`codex`?`Comprehensive Task Master integration guide`:a?`Integration guide and MCP config`:`Integration guide`,{profileName:e,displayName:t,description:r}}).sort((e,t)=>e.displayName.localeCompare(t.displayName)),r=n.map(({displayName:e,description:t})=>`${C.white(`• `)}${C.yellow(e)}${C.white(` - ${t}`)}`).join(`
|
|
3525
|
+
`);console.log(j(`${C.white.bold(`Rule Profiles Setup`)}\n\n${C.white(`Rule profiles help enforce best practices and conventions for Task Master.
|
|
3526
3526
|
Each profile provides coding guidelines tailored for specific AI coding environments.
|
|
3527
3527
|
|
|
3528
|
-
`)}${
|
|
3528
|
+
`)}${C.cyan(`Available Profiles:`)}\n${r}`,{padding:1,borderColor:`blue`,borderStyle:`round`,margin:{top:1,bottom:1}}));let i=n.map(({profileName:e,displayName:n})=>({name:t.includes(e)?`${n} ${C.dim(`(detected)`)}`:n,value:e,checked:t.includes(e)})),a={type:`checkbox`,name:`ruleProfiles`,message:`Which rule profiles would you like to add to your project?`,choices:i,pageSize:i.length,loop:!1,validate:e=>e.length>0||`You must select at least one.`},{ruleProfiles:o}=await re.prompt([a]);return o}async function Nn(e,t,r){let i=[],a=await n(r);for(let n=0;n<e.length;n++){let r=e[n];if(console.log(C.blue(`Processing profile ${n+1}/${e.length}: ${r}...`)),!K(r)){console.warn(`Rule profile for "${r}" not found. Valid profiles: ${N.join(`, `)}. Skipping.`);continue}let o=J(t,q(r),{mode:a});i.push({profileName:r,success:o.success,failed:o.failed}),console.log(C.green(Pn(r,o)))}return i}function Pn(e,t){return q(e).includeDefaultRules?`Summary for ${e}: ${t.success} files processed, ${t.failed} failed.`:`Summary for ${e}: Integration guide installed.`}function Fn(e,t){if(t.skipped)return`Summary for ${e}: Skipped (default or protected files)`;if(t.error&&!t.success)return`Summary for ${e}: Failed to remove - ${t.error}`;if(q(e).includeDefaultRules){let n=`Summary for ${e}: Rule profile removed`;return t.notice?`${n} (${t.notice})`:n}else{let n=`Summary for ${e}: Integration guide removed`;return t.notice?`${n} (${t.notice})`:n}}function In(e){let t=[],n=0,r=0;return e.forEach(e=>{n+=e.success,r+=e.failed,(e.success>0||e.failed===0)&&t.push(e.profileName)}),{successfulProfiles:t,allSuccessfulProfiles:t,totalSuccess:n,totalFailed:r}}function Ln(e){let t=[],n=[],r=[],i=[];return e.forEach(e=>{e.success?t.push(e.profileName):e.skipped?n.push(e.profileName):e.error&&r.push(e),e.notice&&i.push(e)}),{successfulRemovals:t,skippedRemovals:n,failedRemovals:r,removalsWithNotices:i}}export{ut as _,An as a,jn as c,On as d,xn as f,dn as g,K as h,Pn as i,En as l,q as m,Ln as n,Nn as o,J as p,Fn as r,Mn as s,In as t,Dn as u,N as v};
|