@hhsw2015/task-master-ai 0.43.11 → 0.43.13
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-BPC7geqj.js +1 -0
- package/dist/{ai-services-unified-CEISDqFA.js → ai-services-unified-DRuFwL_e.js} +1 -1
- package/dist/assets/config.json +20 -10
- package/dist/{commands-KgO10GUj.js → commands-Dz0lboMw.js} +5 -5
- package/dist/{config-manager-3pTgfD7M.js → config-manager-ClruewMP.js} +2 -2
- package/dist/{config-manager-CgVZwH7E.js → config-manager-DbOMSXgZ.js} +1 -1
- package/dist/{dependency-manager-C-vZzEg8.js → dependency-manager-CvhwFgTc.js} +5 -5
- package/dist/mcp-server.js +2 -2
- package/dist/{profiles-Bcr6LYd4.js → profiles-7bbMp9Tz.js} +4 -4
- package/dist/research-Dk2DpbPy.js +1 -0
- package/dist/response-language-DOZ-CzdZ.js +1 -0
- package/dist/{response-language-CoZ1-GFh.js → response-language-DpiGaJZK.js} +1 -1
- package/dist/{sentry-BU9KKY_b.js → sentry-DP3nr70b.js} +1 -1
- package/dist/tag-management-CFQqYS7R.js +1 -0
- package/dist/{task-manager-usj-gUpk.js → task-manager-H0H_vNIg.js} +1 -1
- package/dist/task-master.js +1 -1
- package/dist/update-subtask-by-id-r9mGhUE1.js +1 -0
- package/dist/update-task-by-id-B9n9vQcI.js +1 -0
- package/dist/{utils-Dr4DuQDO.js → utils-CEHCzNvD.js} +1 -1
- package/package.json +1 -1
- package/dist/ai-services-unified-BpfeMi5b.js +0 -1
- package/dist/research-LCg5MHnP.js +0 -1
- package/dist/response-language-Cqon4F_J.js +0 -1
- package/dist/tag-management-DvcGPdM_.js +0 -1
- package/dist/update-subtask-by-id-B5uMpDq6.js +0 -1
- package/dist/update-task-by-id-D_HOOs3f.js +0 -1
|
@@ -41,7 +41,7 @@ import{t as e}from"./git-utils-DllbRE35.js";import t,{join as n,resolve as r}fro
|
|
|
41
41
|
title,
|
|
42
42
|
description
|
|
43
43
|
)
|
|
44
|
-
`).eq(`brief_id`,e).order(`position`,{ascending:!0}).order(`subtask_position`,{ascending:!0}).order(`created_at`,{ascending:!0});if(n)throw new b(`Failed to fetch tasks: ${n.message}`,y.API_ERROR,{operation:`getTasks`,briefId:e},n);return!t||t.length===0?(this.logger.debug(`No tasks found for brief ${e}`),[]):t.map(e=>({id:e.id,briefId:e.brief_id,documentId:e.document_id,position:e.position,subtaskPosition:e.subtask_position,status:e.status,createdAt:e.created_at,updatedAt:e.updated_at,document:e.document?{id:e.document.id,document_name:e.document.document_name,title:e.document.title,description:e.document.description}:void 0}))}catch(t){throw t instanceof b?t:new b(`Failed to fetch tasks`,y.API_ERROR,{operation:`getTasks`,briefId:e},t)}}},ut=class{logger=S(`SessionManager`);LEGACY_AUTH_FILE=c.join(p.homedir(),`.taskmaster`,`auth.json`);initializationPromise;constructor(e,t){this.supabaseClient=e,this.contextStore=t,this.initializationPromise=this.initialize()}async initialize(){try{await this.initializeSupabaseSession(),await this.migrateLegacyAuth()}catch(e){this.logger.debug(`Session initialization completed with warnings`,e)}}async waitForInitialization(){await this.initializationPromise}async initializeSupabaseSession(){try{await this.supabaseClient.initialize()}catch{this.logger.debug(`No existing session to restore`)}}async migrateLegacyAuth(){if(s.existsSync(this.LEGACY_AUTH_FILE))try{if(await this.supabaseClient.getSession()){s.unlinkSync(this.LEGACY_AUTH_FILE),this.logger.info(`Migrated to Supabase auth, removed legacy auth.json`);return}this.logger.warn(`Legacy auth.json found but no valid Supabase session.`),this.logger.warn(`Please run: task-master auth login`)}catch(e){this.logger.debug(`Error during legacy auth migration:`,e)}}async hasValidSession(){await this.waitForInitialization();try{return await this.supabaseClient.getSession()!=null}catch{return!1}}async getSession(){return await this.waitForInitialization(),this.supabaseClient.getSession()}getStoredContext(){return this.contextStore.getContext()}async getAccessToken(){return await this.waitForInitialization(),(await this.supabaseClient.getSession())?.access_token||null}async getAuthCredentials(){await this.waitForInitialization();let e=await this.supabaseClient.getSession();if(!e)return null;let t=e.user,n=this.contextStore.getUserContext();return{token:e.access_token,refreshToken:e.refresh_token,userId:t.id,email:t.email,expiresAt:e.expires_at?new Date(e.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString(),selectedContext:n||void 0}}async refreshToken(){await this.waitForInitialization();try{let e=await this.supabaseClient.refreshSession();if(!e)throw new C(`Failed to refresh session`,`REFRESH_FAILED`);this.contextStore.saveContext({userId:e.user.id,email:e.user.email});let t=this.contextStore.getContext();return{token:e.access_token,refreshToken:e.refresh_token,userId:e.user.id,email:e.user.email,expiresAt:e.expires_at?new Date(e.expires_at*1e3).toISOString():void 0,savedAt:new Date().toISOString(),selectedContext:t?.selectedContext}}catch(e){throw e instanceof C?e:new C(`Token refresh failed: ${e.message}`,`REFRESH_FAILED`)}}async authenticateWithCode(e){await this.waitForInitialization();try{this.logger.info(`Authenticating with one-time token...`);let t=await this.supabaseClient.verifyOneTimeCode(e);if(!t||!t.access_token)throw new C(`Failed to obtain access token from token`,`NO_TOKEN`);let n=await this.supabaseClient.getUser();if(!n)throw new C(`Failed to get user information`,`INVALID_RESPONSE`);let r=await this.supabaseClient.checkMFARequired();if(r.required&&r.factorId&&r.factorType)throw new C(`MFA verification required. Please provide your authentication code.`,`MFA_REQUIRED`,void 0,{factorId:r.factorId,factorType:r.factorType});this.contextStore.saveContext({userId:n.id,email:n.email});let i=this.contextStore.getUserContext(),a={token:t.access_token,refreshToken:t.refresh_token,userId:n.id,email:n.email,expiresAt:t.expires_at?new Date(t.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString(),selectedContext:i||void 0};return this.logger.info(`Successfully authenticated with token`),a}catch(e){throw e instanceof C?e:new C(`Token authentication failed: ${e.message}`,`CODE_AUTH_FAILED`)}}async verifyMFA(e,t){await this.waitForInitialization();try{this.logger.info(`Verifying MFA code...`);let n=await this.supabaseClient.verifyMFA(e,t);if(!n||!n.access_token)throw new C(`Failed to obtain access token after MFA verification`,`NO_TOKEN`);let r=await this.supabaseClient.getUser();if(!r)throw new C(`Failed to get user information`,`INVALID_RESPONSE`);this.contextStore.saveContext({userId:r.id,email:r.email});let i=this.contextStore.getUserContext(),a={token:n.access_token,refreshToken:n.refresh_token,userId:r.id,email:r.email,expiresAt:n.expires_at?new Date(n.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString(),selectedContext:i||void 0};return this.logger.info(`Successfully verified MFA and authenticated`),a}catch(e){throw e instanceof C?e:new C(`MFA verification failed: ${e.message}`,`MFA_VERIFICATION_FAILED`)}}async logout(){await this.waitForInitialization();try{await this.supabaseClient.signOut()}catch(e){this.logger.warn(`Failed to sign out from Supabase:`,e)}this.contextStore.clearContext();try{s.existsSync(this.LEGACY_AUTH_FILE)&&(s.unlinkSync(this.LEGACY_AUTH_FILE),this.logger.debug(`Cleared legacy auth.json`))}catch{this.logger.debug(`No legacy credentials to clear`)}}},D=class e{static instance=null;static staticLogger=S(`AuthManager`);contextStore;oauthService;sessionManager;supabaseClient;organizationService;constructor(e){this.contextStore=Re.getInstance(),this.supabaseClient=Ie.getInstance(),this.sessionManager=new ut(this.supabaseClient,this.contextStore),this.oauthService=new ct(this.contextStore,this.supabaseClient,e)}static getInstance(t){return e.instance?t&&e.staticLogger.warn(`getInstance called with config after initialization; config is ignored.`):e.instance=new e(t),e.instance}static resetInstance(){e.instance=null,Re.resetInstance(),Ie.resetInstance()}async getAccessToken(){return this.sessionManager.getAccessToken()}async getAuthCredentials(){return this.sessionManager.getAuthCredentials()}async authenticateWithOAuth(e={}){return this.oauthService.authenticate(e)}async authenticateWithCode(e){return this.sessionManager.authenticateWithCode(e)}async verifyMFA(e,t){return this.sessionManager.verifyMFA(e,t)}async verifyMFAWithRetry(e,t,n){let r=n?.maxAttempts??3,i=n?.onInvalidCode;if(!Number.isFinite(r)||!Number.isInteger(r)||r<1)throw TypeError(`Invalid maxAttempts value: ${r}. Must be a positive integer.`);for(let n=1;n<=r;n++)try{let r=await t(),i=await this.verifyMFA(e,r);return{success:!0,attemptsUsed:n,credentials:i}}catch(e){if(e instanceof C&&e.code===`INVALID_MFA_CODE`){let e=r-n;if(i&&i(n,e),n>=r)return{success:!1,attemptsUsed:n,errorCode:`INVALID_MFA_CODE`};continue}throw e}return{success:!1,attemptsUsed:r,errorCode:`MFA_VERIFICATION_FAILED`}}getAuthorizationUrl(){return this.oauthService.getAuthorizationUrl()}async refreshToken(){return this.sessionManager.refreshToken()}async logout(){return this.sessionManager.logout()}async hasValidSession(){return this.sessionManager.hasValidSession()}async getSession(){return this.sessionManager.getSession()}getStoredContext(){return this.sessionManager.getStoredContext()}getContext(){return this.contextStore.getUserContext()}async updateContext(e){if(!await this.hasValidSession())throw new C(`Not authenticated`,`NOT_AUTHENTICATED`);this.contextStore.updateUserContext(e)}async clearContext(){if(!await this.hasValidSession())throw new C(`Not authenticated`,`NOT_AUTHENTICATED`);this.contextStore.clearUserContext()}async getOrganizationService(){if(!this.organizationService){if(!await this.sessionManager.getSession())throw new C(`Not authenticated`,`NOT_AUTHENTICATED`);this.organizationService=new lt(this.supabaseClient.getClient())}return this.organizationService}async getOrganizations(){return(await this.getOrganizationService()).getOrganizations()}async getBriefs(e){return(await this.getOrganizationService()).getBriefs(e)}async getOrganization(e){return(await this.getOrganizationService()).getOrganization(e)}async getBrief(e){return(await this.getOrganizationService()).getBrief(e)}async getTasks(e){return(await this.getOrganizationService()).getTasks(e)}ensureBriefSelected(e){let t=this.getContext();if(!t?.briefId)throw new b(`No brief selected`,y.NO_BRIEF_SELECTED,{operation:e,userMessage:`No brief selected. Please select a brief first using: tm context brief <brief-id> or tm context brief <brief-url>`});return t}},O=class{authManager;constructor(){this.authManager=D.getInstance()}async hasValidSession(){return this.authManager.hasValidSession()}async getSession(){return this.authManager.getSession()}getStoredContext(){return this.authManager.getStoredContext()}async getCredentials(){return this.authManager.getAuthCredentials()}async getAccessToken(){return this.authManager.getAccessToken()}async authenticateWithOAuth(e){return this.authManager.authenticateWithOAuth(e)}async authenticateWithCode(e){return this.authManager.authenticateWithCode(e)}async verifyMFA(e,t){return this.authManager.verifyMFA(e,t)}async verifyMFAWithRetry(e,t,n){return this.authManager.verifyMFAWithRetry(e,t,n)}getAuthorizationUrl(){return this.authManager.getAuthorizationUrl()}async refreshToken(){return this.authManager.refreshToken()}async logout(){return this.authManager.logout()}getContext(){return this.authManager.getContext()}async updateContext(e){return this.authManager.updateContext(e)}async clearContext(){return this.authManager.clearContext()}async getOrganizations(){return this.authManager.getOrganizations()}async getOrganization(e){return this.authManager.getOrganization(e)}async getBriefs(e){return this.authManager.getBriefs(e)}async getBrief(e){return this.authManager.getBrief(e)}async getTasks(e){return this.authManager.getTasks(e)}getStorageDisplayInfo(e){if(e===`api`){let e=this.getContext();if(e?.briefId&&e?.briefName)return{storageType:`api`,briefInfo:{briefId:e.briefId,briefName:e.briefName,orgSlug:e.orgSlug,webAppUrl:this.getWebAppUrl()}}}return{storageType:`file`,filePath:t.join(`.taskmaster`,`tasks`,`tasks.json`)}}getBriefCreationUrl(){let e=this.getContext(),t=this.getWebAppUrl();return!t||!e?.orgSlug?null:`${t}/home/${e.orgSlug}/briefs/create`}async guardCommand(e,t){return we({hasValidSession:await this.hasValidSession(),briefName:this.getContext()?.briefName,storageType:t,commandName:e})}getApiBaseUrl(){let e=process.env.TM_BASE_DOMAIN||process.env.TM_PUBLIC_BASE_DOMAIN;if(e)return e.startsWith(`http://`)||e.startsWith(`https://`)?e:e.includes(`localhost`)||e.includes(`127.0.0.1`)?`http://${e}`:`https://${e}`}getWebAppUrl(){return this.getApiBaseUrl()}},dt=class{constructor(e){this.configManager=e}getConfig(){return this.configManager.getConfig()}getStorageConfig(){return this.configManager.getStorageConfig()}getModelConfig(){return this.configManager.getModelConfig()}getResponseLanguage(){return this.configManager.getResponseLanguage()}getProjectRoot(){return this.configManager.getProjectRoot()}isApiExplicitlyConfigured(){return this.configManager.isApiExplicitlyConfigured()}getActiveTag(){return this.configManager.getActiveTag()}async setActiveTag(e){return this.configManager.setActiveTag(e)}async updateConfig(e){return this.configManager.updateConfig(e)}async setResponseLanguage(e){return this.configManager.setResponseLanguage(e)}async saveConfig(){return this.configManager.saveConfig()}async reset(){return this.configManager.reset()}getConfigSources(){return this.configManager.getConfigSources()}};const k={MODELS:{MAIN:`claude-sonnet-4-20250514`,FALLBACK:`claude-3-7-sonnet-20250219`},TASKS:{DEFAULT_PRIORITY:`medium`,DEFAULT_COMPLEXITY:`moderate`,MAX_SUBTASKS:20,MAX_CONCURRENT:5,TASK_ID_PREFIX:`TASK-`},TAGS:{DEFAULT_TAG:`master`,MAX_TAGS_PER_TASK:10,NAMING_CONVENTION:`kebab-case`},WORKFLOW:{ENABLE_AUTOPILOT:!0,MAX_PHASE_ATTEMPTS:3,BRANCH_PATTERN:`task-{taskId}`,REQUIRE_CLEAN_WORKING_TREE:!0,AUTO_STAGE_CHANGES:!0,INCLUDE_CO_AUTHOR:!0,CO_AUTHOR_NAME:`TaskMaster AI`,CO_AUTHOR_EMAIL:`taskmaster@tryhamster.com`,MIN_TESTS:1,MAX_FAILURES_IN_GREEN:0,COMMIT_MESSAGE_TEMPLATE:`{type}({scope}): {description} (Task {taskId}.{subtaskIndex})`,ALLOWED_COMMIT_TYPES:[`feat`,`fix`,`refactor`,`test`,`docs`,`chore`],DEFAULT_COMMIT_TYPE:`feat`,OPERATION_TIMEOUT:6e4,ENABLE_ACTIVITY_LOGGING:!0,ACTIVITY_LOG_PATH:`.taskmaster/logs/workflow-activity.log`,ENABLE_STATE_BACKUP:!0,MAX_STATE_BACKUPS:5,ABORT_ON_MAX_ATTEMPTS:!1},STORAGE:{TYPE:`auto`,ENCODING:`utf8`,MAX_BACKUPS:5},RETRY:{ATTEMPTS:3,DELAY:1e3,MAX_DELAY:3e4,BACKOFF_MULTIPLIER:2,TIMEOUT:3e4},LOGGING:{LEVEL:`info`,MAX_FILE_SIZE:10,MAX_FILES:5},SECURITY:{MAX_REQUESTS_PER_MINUTE:60,MAX_PROMPT_LENGTH:1e5,ALLOWED_EXTENSIONS:[`.txt`,`.md`,`.json`]},VERSION:`1.0.0`};var ft=class{localConfigPath;globalConfigPath;logger=S(`ConfigLoader`);constructor(e){this.localConfigPath=t.join(e,`.taskmaster`,`config.json`),this.globalConfigPath=t.join(process.env.HOME||``,`.taskmaster`,`config.json`)}getDefaultConfig(){return{models:{main:k.MODELS.MAIN,fallback:k.MODELS.FALLBACK},workflow:{enableAutopilot:k.WORKFLOW.ENABLE_AUTOPILOT,maxPhaseAttempts:k.WORKFLOW.MAX_PHASE_ATTEMPTS,branchPattern:k.WORKFLOW.BRANCH_PATTERN,requireCleanWorkingTree:k.WORKFLOW.REQUIRE_CLEAN_WORKING_TREE,autoStageChanges:k.WORKFLOW.AUTO_STAGE_CHANGES,includeCoAuthor:k.WORKFLOW.INCLUDE_CO_AUTHOR,coAuthorName:k.WORKFLOW.CO_AUTHOR_NAME,coAuthorEmail:k.WORKFLOW.CO_AUTHOR_EMAIL,testThresholds:{minTests:k.WORKFLOW.MIN_TESTS,maxFailuresInGreen:k.WORKFLOW.MAX_FAILURES_IN_GREEN},commitMessageTemplate:k.WORKFLOW.COMMIT_MESSAGE_TEMPLATE,allowedCommitTypes:[...k.WORKFLOW.ALLOWED_COMMIT_TYPES],defaultCommitType:k.WORKFLOW.DEFAULT_COMMIT_TYPE,operationTimeout:k.WORKFLOW.OPERATION_TIMEOUT,enableActivityLogging:k.WORKFLOW.ENABLE_ACTIVITY_LOGGING,activityLogPath:k.WORKFLOW.ACTIVITY_LOG_PATH,enableStateBackup:k.WORKFLOW.ENABLE_STATE_BACKUP,maxStateBackups:k.WORKFLOW.MAX_STATE_BACKUPS,abortOnMaxAttempts:k.WORKFLOW.ABORT_ON_MAX_ATTEMPTS},storage:{type:k.STORAGE.TYPE,encoding:k.STORAGE.ENCODING,enableBackup:!1,maxBackups:k.STORAGE.MAX_BACKUPS,enableCompression:!1,atomicOperations:!0},version:k.VERSION}}async loadLocalConfig(){try{let e=await _.readFile(this.localConfigPath,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return this.logger.debug(`No local config.json found, using defaults`),null;throw new b(`Failed to load local configuration`,y.CONFIG_ERROR,{configPath:this.localConfigPath},e)}}async loadGlobalConfig(){return null}async hasLocalConfig(){try{return await _.access(this.localConfigPath),!0}catch{return!1}}async hasGlobalConfig(){try{return await _.access(this.globalConfigPath),!0}catch{return!1}}};const A={DEFAULTS:0,GLOBAL:1,LOCAL:2,ENVIRONMENT:3};var pt=class{configSources=[];addSource(e){this.configSources.push(e)}clearSources(){this.configSources=[]}merge(){let e=[...this.configSources].sort((e,t)=>e.precedence-t.precedence),t={};for(let n of e)t=this.deepMerge(t,n.config);return t}deepMerge(e,t){if(!t)return e;if(!e)return t;let n={...e};for(let e in t)t[e]===null||t[e]===void 0||(typeof t[e]==`object`&&!Array.isArray(t[e])?n[e]=this.deepMerge(n[e]||{},t[e]):n[e]=t[e]);return n}getSources(){return[...this.configSources].sort((e,t)=>t.precedence-e.precedence)}hasSource(e){return this.configSources.some(t=>t.name===e)}removeSource(e){let t=this.configSources.length;return this.configSources=this.configSources.filter(t=>t.name!==e),this.configSources.length<t}},mt=class{localConfigPath;backupDir;logger=S(`ConfigPersistence`);constructor(e){this.localConfigPath=t.join(e,`.taskmaster`,`config.json`),this.backupDir=t.join(e,`.taskmaster`,`backups`)}async saveConfig(e,n={}){let{createBackup:r=!1,atomic:i=!0}=n;try{r&&await this.configExists()&&await this.createBackup();let n=t.dirname(this.localConfigPath);await _.mkdir(n,{recursive:!0});let a=JSON.stringify(e,null,2);if(i){let e=`${this.localConfigPath}.tmp`;await _.writeFile(e,a,`utf-8`),await _.rename(e,this.localConfigPath)}else await _.writeFile(this.localConfigPath,a,`utf-8`)}catch(e){throw new b(`Failed to save configuration`,y.CONFIG_ERROR,{configPath:this.localConfigPath},e)}}async createBackup(){try{await _.mkdir(this.backupDir,{recursive:!0});let e=new Date().toISOString().replace(/[:.]/g,`-`),n=t.join(this.backupDir,`config-${e}.json`),r=await _.readFile(this.localConfigPath,`utf-8`);return await _.writeFile(n,r,`utf-8`),await this.cleanOldBackups(),n}catch(e){throw this.logger.warn(`Failed to create backup:`,e),e}}async cleanOldBackups(e=5){try{let n=(await _.readdir(this.backupDir)).filter(e=>e.startsWith(`config-`)&&e.endsWith(`.json`)).sort().reverse().slice(e);for(let e of n)await _.unlink(t.join(this.backupDir,e))}catch(e){this.logger.warn(`Failed to clean old backups:`,e)}}async configExists(){try{return await _.access(this.localConfigPath),!0}catch{return!1}}async deleteConfig(){try{await _.unlink(this.localConfigPath)}catch(e){if(e.code!==`ENOENT`)throw new b(`Failed to delete configuration`,y.CONFIG_ERROR,{configPath:this.localConfigPath},e)}}async getBackups(){try{return(await _.readdir(this.backupDir)).filter(e=>e.startsWith(`config-`)&&e.endsWith(`.json`)).sort().reverse()}catch{return[]}}async restoreFromBackup(e){let n=t.join(this.backupDir,e);try{let e=await _.readFile(n,`utf-8`);await _.writeFile(this.localConfigPath,e,`utf-8`)}catch(e){throw new b(`Failed to restore from backup`,y.CONFIG_ERROR,{backupPath:n},e)}}},ht=class e{logger=S(`EnvironmentConfigProvider`);static DEFAULT_MAPPINGS=[{env:`TASKMASTER_STORAGE_TYPE`,path:[`storage`,`type`],validate:e=>[`file`,`api`].includes(e)},{env:`TASKMASTER_API_ENDPOINT`,path:[`storage`,`apiEndpoint`]},{env:`TASKMASTER_API_TOKEN`,path:[`storage`,`apiAccessToken`]},{env:`TASKMASTER_MODEL_MAIN`,path:[`models`,`main`]},{env:`TASKMASTER_MODEL_RESEARCH`,path:[`models`,`research`]},{env:`TASKMASTER_MODEL_FALLBACK`,path:[`models`,`fallback`]},{env:`TASKMASTER_RESPONSE_LANGUAGE`,path:[`custom`,`responseLanguage`]}];static RUNTIME_STATE_MAPPINGS=[{env:`TASKMASTER_TAG`,path:[`activeTag`],isRuntimeState:!0}];mappings;constructor(t){this.mappings=t||[...e.DEFAULT_MAPPINGS,...e.RUNTIME_STATE_MAPPINGS]}loadConfig(){let e={};for(let t of this.mappings){if(t.isRuntimeState)continue;let n=process.env[t.env];if(n){if(t.validate&&!t.validate(n)){this.logger.warn(`Invalid value for ${t.env}: ${n}`);continue}this.setNestedProperty(e,t.path,n)}}return e}getRuntimeState(){let e={};for(let t of this.mappings){if(!t.isRuntimeState)continue;let n=process.env[t.env];if(n){let r=t.path[t.path.length-1];e[r]=n}}return e}setNestedProperty(e,t,n){let r=t[t.length-1],i=t.slice(0,-1),a=e;for(let e of i)a[e]||(a[e]={}),a=a[e];a[r]=n}hasEnvVar(e){return e in process.env&&process.env[e]!==void 0}getAllTaskmasterEnvVars(){let e={};for(let[t,n]of Object.entries(process.env))t.startsWith(`TASKMASTER_`)&&n!==void 0&&(e[t]=n);return e}addMapping(e){this.mappings.push(e)}getMappings(){return[...this.mappings]}},gt=class{stateFilePath;currentState;logger=S(`RuntimeStateManager`);constructor(e){this.stateFilePath=t.join(e,`.taskmaster`,`state.json`),this.currentState={currentTag:k.TAGS.DEFAULT_TAG}}async loadState(){try{let e=await _.readFile(this.stateFilePath,`utf-8`),t=JSON.parse(e),n={currentTag:t.currentTag||t.activeTag||k.TAGS.DEFAULT_TAG,lastUpdated:t.lastUpdated,metadata:t.metadata};return process.env.TASKMASTER_TAG&&(n.currentTag=process.env.TASKMASTER_TAG),this.currentState=n,n}catch(e){return e.code===`ENOENT`?(this.logger.debug(`No state.json found, using default state`),process.env.TASKMASTER_TAG&&(this.currentState.currentTag=process.env.TASKMASTER_TAG),this.currentState):(this.logger.warn(`Failed to load state file:`,e.message),this.currentState)}}async saveState(){let e=t.dirname(this.stateFilePath);try{await _.mkdir(e,{recursive:!0});let t={...this.currentState,lastUpdated:new Date().toISOString()};await _.writeFile(this.stateFilePath,JSON.stringify(t,null,2),`utf-8`)}catch(e){throw new b(`Failed to save runtime state`,y.CONFIG_ERROR,{statePath:this.stateFilePath},e)}}getCurrentTag(){return this.currentState.currentTag}async setCurrentTag(e){this.currentState.currentTag=e,await this.saveState()}getState(){return{...this.currentState}}async updateMetadata(e){this.currentState.metadata={...this.currentState.metadata,...e},await this.saveState()}async clearState(){try{await _.unlink(this.stateFilePath)}catch(e){if(e.code!==`ENOENT`)throw e}this.currentState={currentTag:k.TAGS.DEFAULT_TAG}}},_t=class e{projectRoot;config={};initialized=!1;loader;merger;stateManager;persistence;envProvider;static async create(t){let n=new e(t);return await n.initialize(),n}constructor(e){this.projectRoot=e,this.loader=new ft(e),this.merger=new pt,this.stateManager=new gt(e),this.persistence=new mt(e),this.envProvider=new ht}async initialize(){if(this.initialized)return;this.merger.clearSources(),this.merger.addSource({name:`defaults`,config:this.loader.getDefaultConfig(),precedence:A.DEFAULTS});let e=await this.loader.loadGlobalConfig();e&&this.merger.addSource({name:`global`,config:e,precedence:A.GLOBAL});let t=await this.loader.loadLocalConfig();t&&this.merger.addSource({name:`local`,config:t,precedence:A.LOCAL});let n=this.envProvider.loadConfig();Object.keys(n).length>0&&this.merger.addSource({name:`environment`,config:n,precedence:A.ENVIRONMENT}),this.config=this.merger.merge(),await this.stateManager.loadState(),this.initialized=!0}getConfig(){return this.config}getStorageConfig(){let e=this.config.storage,t=e?.type||`auto`,n=e?.basePath??this.projectRoot;return t===`api`||t===`auto`?{type:t,basePath:n,apiEndpoint:e?.apiEndpoint,apiAccessToken:e?.apiAccessToken,apiConfigured:!!(e?.apiEndpoint||e?.apiAccessToken)}:{type:t,basePath:n,apiConfigured:!1}}getModelConfig(){return this.config.models||{main:k.MODELS.MAIN,fallback:k.MODELS.FALLBACK}}getResponseLanguage(){return this.config.custom?.responseLanguage||`English`}getProjectRoot(){return this.projectRoot}isApiExplicitlyConfigured(){return this.getStorageConfig().type===`api`}getActiveTag(){return this.stateManager.getCurrentTag()}async setActiveTag(e){await this.stateManager.setCurrentTag(e)}async updateConfig(e){Object.assign(this.config,e),await this.persistence.saveConfig(this.config),this.initialized=!1,await this.initialize()}async setResponseLanguage(e){this.config.custom||(this.config.custom={}),this.config.custom.responseLanguage=e,await this.persistence.saveConfig(this.config)}async saveConfig(){await this.persistence.saveConfig(this.config,{createBackup:!0,atomic:!0})}async reset(){await this.persistence.deleteConfig(),await this.stateManager.clearState(),this.initialized=!1,this.config={},await this.initialize()}getConfigSources(){return this.merger.getSources()}},j=class{projectPath;git;constructor(e){if(!e)throw Error(`Project path is required`);if(!c.isAbsolute(e))throw Error(`Project path must be an absolute path`);this.projectPath=c.normalize(e),this.git=ce(this.projectPath)}async isGitRepository(){try{let e=c.join(this.projectPath,`.git`);if(await se.pathExists(e))return!0;try{return await this.git.revparse([`--git-dir`]),!0}catch{return!1}}catch{return!1}}async validateGitInstallation(){try{await this.git.version()}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Git is not installed or not accessible: ${t}`)}}async getGitVersion(){let e=await this.git.version();return{major:e.major,minor:e.minor,patch:typeof e.patch==`string`?parseInt(e.patch):e.patch||0,agent:e.agent}}async getRepositoryRoot(){try{let e=await this.git.revparse([`--show-toplevel`]);return c.normalize(e.trim())}catch{throw Error(`not a git repository: ${this.projectPath}`)}}async validateRepository(){if(!await this.isGitRepository())throw Error(`not a git repository: ${this.projectPath}`);try{await this.git.status()}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Repository validation failed: ${t}`)}}async ensureGitRepository(){if(!await this.isGitRepository())throw Error(`not a git repository: ${this.projectPath}\nPlease run this command from within a git repository, or initialize one with 'git init'.`)}async isWorkingTreeClean(){return(await this.git.status()).isClean()}async getStatus(){return await this.git.status()}async hasUncommittedChanges(){return!(await this.git.status()).isClean()}async hasStagedChanges(){return(await this.git.status()).staged.length>0}async hasUntrackedFiles(){return(await this.git.status()).not_added.length>0}async getStatusSummary(){let e=await this.git.status(),t=e.staged.length,n=e.modified.length,r=e.deleted.length,i=e.not_added.length,a=t+n+r+i;return{isClean:e.isClean(),staged:t,modified:n,deleted:r,untracked:i,totalChanges:a}}async ensureCleanWorkingTree(){if(!(await this.git.status()).isClean()){let e=await this.getStatusSummary();throw Error(`working tree is not clean: ${this.projectPath}\nStaged: ${e.staged}, Modified: ${e.modified}, Deleted: ${e.deleted}, Untracked: ${e.untracked}\nPlease commit or stash your changes before proceeding.`)}}async getCurrentBranch(){return(await this.git.status()).current||`HEAD`}async listBranches(){let e=await this.git.branchLocal();return Object.keys(e.branches)}async branchExists(e){return(await this.listBranches()).includes(e)}async createBranch(e,t={}){if(await this.branchExists(e))throw Error(`branch already exists: ${e}`);t.checkout&&await this.ensureCleanWorkingTree(),await this.git.branch([e]),t.checkout&&await this.git.checkout(e)}async checkoutBranch(e,t={}){if(!await this.branchExists(e))throw Error(`branch does not exist: ${e}`);t.force||await this.ensureCleanWorkingTree();let n=t.force?[`-f`,e]:[e];await this.git.checkout(n)}async createAndCheckoutBranch(e){if(await this.ensureCleanWorkingTree(),await this.branchExists(e))throw Error(`branch already exists: ${e}`);await this.git.checkoutLocalBranch(e)}async deleteBranch(e,t={}){if(!await this.branchExists(e))throw Error(`branch does not exist: ${e}`);if(await this.getCurrentBranch()===e)throw Error(`cannot delete current branch: ${e}`);let n=t.force?[`-D`,e]:[`-d`,e];await this.git.branch(n)}async stageFiles(e){await this.git.add(e)}async unstageFiles(e){await this.git.reset([`HEAD`,`--`,...e])}async createCommit(e,t={}){if(t.enforceNonDefaultBranch&&!t.force){let e=await this.getCurrentBranch();if([`main`,`master`,`develop`].includes(e))throw Error(`cannot commit to default branch: ${e}\nPlease create a feature branch or use force option.`)}if(!t.allowEmpty&&!await this.hasStagedChanges())throw Error(`no staged changes to commit`);let n=[`commit`];if(n.push(`-m`,e),t.metadata){n.push(`-m`,``);for(let[e,r]of Object.entries(t.metadata))n.push(`-m`,`[${e}:${r}]`)}n.push(`--no-gpg-sign`),t.allowEmpty&&n.push(`--allow-empty`),await this.git.raw(n)}async getCommitLog(e={}){let t={format:{hash:`%H`,date:`%ai`,message:`%B`,author_name:`%an`,author_email:`%ae`}};return e.maxCount&&(t.maxCount=e.maxCount),[...(await this.git.log(t)).all]}async getLastCommit(){return(await this.git.log({maxCount:1,format:{hash:`%H`,date:`%ai`,message:`%B`,author_name:`%an`,author_email:`%ae`}})).latest}async getDefaultBranch(){let e=await this.getCurrentBranch(),t=[`main`,`master`,`develop`];if(t.includes(e))return e;let n=await this.listBranches();for(let e of t)if(n.includes(e))return e;return`main`}async isDefaultBranch(e){return[`main`,`master`,`develop`].includes(e)}async isOnDefaultBranch(){let e=await this.getCurrentBranch();return await this.isDefaultBranch(e)}async ensureNotOnDefaultBranch(){if(await this.isOnDefaultBranch()){let e=await this.getCurrentBranch();throw Error(`currently on default branch: ${e}\nPlease create a feature branch before proceeding.`)}}async hasRemote(){return(await this.git.getRemotes()).length>0}async getRemotes(){return await this.git.getRemotes(!0)}};const vt=[[`**/*.test.*`,`test`],[`**/*.spec.*`,`test`],[`**/test/**`,`test`],[`**/tests/**`,`test`],[`**/__tests__/**`,`test`],[`**/package-lock.json`,`deps`],[`package-lock.json`,`deps`],[`**/pnpm-lock.yaml`,`deps`],[`pnpm-lock.yaml`,`deps`],[`**/yarn.lock`,`deps`],[`yarn.lock`,`deps`],[`**/package.json`,`config`],[`package.json`,`config`],[`**/tsconfig*.json`,`config`],[`tsconfig*.json`,`config`],[`**/.eslintrc*`,`config`],[`.eslintrc*`,`config`],[`**/vite.config.*`,`config`],[`vite.config.*`,`config`],[`**/vitest.config.*`,`config`],[`vitest.config.*`,`config`],[`packages/cli/**`,`cli`],[`packages/tm-core/**`,`core`],[`packages/mcp-server/**`,`mcp`],[`**/workflow/**`,`workflow`],[`**/git/**`,`git`],[`**/storage/**`,`storage`],[`**/auth/**`,`auth`],[`**/config/**`,`config`],[`**/*.md`,`docs`],[`**/docs/**`,`docs`],[`README*`,`docs`],[`CHANGELOG*`,`docs`]],yt={core:100,cli:90,mcp:85,workflow:80,git:75,storage:70,auth:65,config:60,test:50,docs:30,deps:20,repo:10};var bt=class{scopeMappings;scopePriorities;constructor(e,t){this.scopeMappings=[...vt],e&&(this.scopeMappings=[...Object.entries(e),...this.scopeMappings]),this.scopePriorities={...yt,...t}}detectScope(e){if(e.length===0)return`repo`;let t=new Map;for(let n of e){let e=this.getMatchingScope(n);e&&t.set(e,(t.get(e)||0)+1)}if(t.size===0)return`repo`;let n=`repo`,r=0;for(let[e,i]of t){let t=this.getScopePriority(e)*i;t>r&&(r=t,n=e)}return n}getAllMatchingScopes(e){let t=new Set;for(let n of e){let e=this.getMatchingScope(n);e&&t.add(e)}return Array.from(t)}getMatchingScope(e){let t=e.replace(/\\/g,`/`);for(let[e,n]of this.scopeMappings)if(this.matchesPattern(t,e))return n;return null}getScopePriority(e){return this.scopePriorities[e]||0}matchesPattern(e,t){let n=t.replace(/\*\*/g,`§GLOBSTAR§`);return n=n.replace(/[.+^${}()|[\]\\]/g,`\\$&`),n=n.replace(/\*/g,`[^/]*`),n=n.replace(/§GLOBSTAR§/g,`.*`),RegExp(`^${n}$`).test(e)}};const xt={commitMessage:`{{type}}{{#scope}}({{scope}}){{/scope}}{{#breaking}}!{{/breaking}}: {{description}}
|
|
44
|
+
`).eq(`brief_id`,e).order(`position`,{ascending:!0}).order(`subtask_position`,{ascending:!0}).order(`created_at`,{ascending:!0});if(n)throw new b(`Failed to fetch tasks: ${n.message}`,y.API_ERROR,{operation:`getTasks`,briefId:e},n);return!t||t.length===0?(this.logger.debug(`No tasks found for brief ${e}`),[]):t.map(e=>({id:e.id,briefId:e.brief_id,documentId:e.document_id,position:e.position,subtaskPosition:e.subtask_position,status:e.status,createdAt:e.created_at,updatedAt:e.updated_at,document:e.document?{id:e.document.id,document_name:e.document.document_name,title:e.document.title,description:e.document.description}:void 0}))}catch(t){throw t instanceof b?t:new b(`Failed to fetch tasks`,y.API_ERROR,{operation:`getTasks`,briefId:e},t)}}},ut=class{logger=S(`SessionManager`);LEGACY_AUTH_FILE=c.join(p.homedir(),`.taskmaster`,`auth.json`);initializationPromise;constructor(e,t){this.supabaseClient=e,this.contextStore=t,this.initializationPromise=this.initialize()}async initialize(){try{await this.initializeSupabaseSession(),await this.migrateLegacyAuth()}catch(e){this.logger.debug(`Session initialization completed with warnings`,e)}}async waitForInitialization(){await this.initializationPromise}async initializeSupabaseSession(){try{await this.supabaseClient.initialize()}catch{this.logger.debug(`No existing session to restore`)}}async migrateLegacyAuth(){if(s.existsSync(this.LEGACY_AUTH_FILE))try{if(await this.supabaseClient.getSession()){s.unlinkSync(this.LEGACY_AUTH_FILE),this.logger.info(`Migrated to Supabase auth, removed legacy auth.json`);return}this.logger.warn(`Legacy auth.json found but no valid Supabase session.`),this.logger.warn(`Please run: task-master auth login`)}catch(e){this.logger.debug(`Error during legacy auth migration:`,e)}}async hasValidSession(){await this.waitForInitialization();try{return await this.supabaseClient.getSession()!=null}catch{return!1}}async getSession(){return await this.waitForInitialization(),this.supabaseClient.getSession()}getStoredContext(){return this.contextStore.getContext()}async getAccessToken(){return await this.waitForInitialization(),(await this.supabaseClient.getSession())?.access_token||null}async getAuthCredentials(){await this.waitForInitialization();let e=await this.supabaseClient.getSession();if(!e)return null;let t=e.user,n=this.contextStore.getUserContext();return{token:e.access_token,refreshToken:e.refresh_token,userId:t.id,email:t.email,expiresAt:e.expires_at?new Date(e.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString(),selectedContext:n||void 0}}async refreshToken(){await this.waitForInitialization();try{let e=await this.supabaseClient.refreshSession();if(!e)throw new C(`Failed to refresh session`,`REFRESH_FAILED`);this.contextStore.saveContext({userId:e.user.id,email:e.user.email});let t=this.contextStore.getContext();return{token:e.access_token,refreshToken:e.refresh_token,userId:e.user.id,email:e.user.email,expiresAt:e.expires_at?new Date(e.expires_at*1e3).toISOString():void 0,savedAt:new Date().toISOString(),selectedContext:t?.selectedContext}}catch(e){throw e instanceof C?e:new C(`Token refresh failed: ${e.message}`,`REFRESH_FAILED`)}}async authenticateWithCode(e){await this.waitForInitialization();try{this.logger.info(`Authenticating with one-time token...`);let t=await this.supabaseClient.verifyOneTimeCode(e);if(!t||!t.access_token)throw new C(`Failed to obtain access token from token`,`NO_TOKEN`);let n=await this.supabaseClient.getUser();if(!n)throw new C(`Failed to get user information`,`INVALID_RESPONSE`);let r=await this.supabaseClient.checkMFARequired();if(r.required&&r.factorId&&r.factorType)throw new C(`MFA verification required. Please provide your authentication code.`,`MFA_REQUIRED`,void 0,{factorId:r.factorId,factorType:r.factorType});this.contextStore.saveContext({userId:n.id,email:n.email});let i=this.contextStore.getUserContext(),a={token:t.access_token,refreshToken:t.refresh_token,userId:n.id,email:n.email,expiresAt:t.expires_at?new Date(t.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString(),selectedContext:i||void 0};return this.logger.info(`Successfully authenticated with token`),a}catch(e){throw e instanceof C?e:new C(`Token authentication failed: ${e.message}`,`CODE_AUTH_FAILED`)}}async verifyMFA(e,t){await this.waitForInitialization();try{this.logger.info(`Verifying MFA code...`);let n=await this.supabaseClient.verifyMFA(e,t);if(!n||!n.access_token)throw new C(`Failed to obtain access token after MFA verification`,`NO_TOKEN`);let r=await this.supabaseClient.getUser();if(!r)throw new C(`Failed to get user information`,`INVALID_RESPONSE`);this.contextStore.saveContext({userId:r.id,email:r.email});let i=this.contextStore.getUserContext(),a={token:n.access_token,refreshToken:n.refresh_token,userId:r.id,email:r.email,expiresAt:n.expires_at?new Date(n.expires_at*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString(),selectedContext:i||void 0};return this.logger.info(`Successfully verified MFA and authenticated`),a}catch(e){throw e instanceof C?e:new C(`MFA verification failed: ${e.message}`,`MFA_VERIFICATION_FAILED`)}}async logout(){await this.waitForInitialization();try{await this.supabaseClient.signOut()}catch(e){this.logger.warn(`Failed to sign out from Supabase:`,e)}this.contextStore.clearContext();try{s.existsSync(this.LEGACY_AUTH_FILE)&&(s.unlinkSync(this.LEGACY_AUTH_FILE),this.logger.debug(`Cleared legacy auth.json`))}catch{this.logger.debug(`No legacy credentials to clear`)}}},D=class e{static instance=null;static staticLogger=S(`AuthManager`);contextStore;oauthService;sessionManager;supabaseClient;organizationService;constructor(e){this.contextStore=Re.getInstance(),this.supabaseClient=Ie.getInstance(),this.sessionManager=new ut(this.supabaseClient,this.contextStore),this.oauthService=new ct(this.contextStore,this.supabaseClient,e)}static getInstance(t){return e.instance?t&&e.staticLogger.warn(`getInstance called with config after initialization; config is ignored.`):e.instance=new e(t),e.instance}static resetInstance(){e.instance=null,Re.resetInstance(),Ie.resetInstance()}async getAccessToken(){return this.sessionManager.getAccessToken()}async getAuthCredentials(){return this.sessionManager.getAuthCredentials()}async authenticateWithOAuth(e={}){return this.oauthService.authenticate(e)}async authenticateWithCode(e){return this.sessionManager.authenticateWithCode(e)}async verifyMFA(e,t){return this.sessionManager.verifyMFA(e,t)}async verifyMFAWithRetry(e,t,n){let r=n?.maxAttempts??3,i=n?.onInvalidCode;if(!Number.isFinite(r)||!Number.isInteger(r)||r<1)throw TypeError(`Invalid maxAttempts value: ${r}. Must be a positive integer.`);for(let n=1;n<=r;n++)try{let r=await t(),i=await this.verifyMFA(e,r);return{success:!0,attemptsUsed:n,credentials:i}}catch(e){if(e instanceof C&&e.code===`INVALID_MFA_CODE`){let e=r-n;if(i&&i(n,e),n>=r)return{success:!1,attemptsUsed:n,errorCode:`INVALID_MFA_CODE`};continue}throw e}return{success:!1,attemptsUsed:r,errorCode:`MFA_VERIFICATION_FAILED`}}getAuthorizationUrl(){return this.oauthService.getAuthorizationUrl()}async refreshToken(){return this.sessionManager.refreshToken()}async logout(){return this.sessionManager.logout()}async hasValidSession(){return this.sessionManager.hasValidSession()}async getSession(){return this.sessionManager.getSession()}getStoredContext(){return this.sessionManager.getStoredContext()}getContext(){return this.contextStore.getUserContext()}async updateContext(e){if(!await this.hasValidSession())throw new C(`Not authenticated`,`NOT_AUTHENTICATED`);this.contextStore.updateUserContext(e)}async clearContext(){if(!await this.hasValidSession())throw new C(`Not authenticated`,`NOT_AUTHENTICATED`);this.contextStore.clearUserContext()}async getOrganizationService(){if(!this.organizationService){if(!await this.sessionManager.getSession())throw new C(`Not authenticated`,`NOT_AUTHENTICATED`);this.organizationService=new lt(this.supabaseClient.getClient())}return this.organizationService}async getOrganizations(){return(await this.getOrganizationService()).getOrganizations()}async getBriefs(e){return(await this.getOrganizationService()).getBriefs(e)}async getOrganization(e){return(await this.getOrganizationService()).getOrganization(e)}async getBrief(e){return(await this.getOrganizationService()).getBrief(e)}async getTasks(e){return(await this.getOrganizationService()).getTasks(e)}ensureBriefSelected(e){let t=this.getContext();if(!t?.briefId)throw new b(`No brief selected`,y.NO_BRIEF_SELECTED,{operation:e,userMessage:`No brief selected. Please select a brief first using: tm context brief <brief-id> or tm context brief <brief-url>`});return t}},O=class{authManager;constructor(){this.authManager=D.getInstance()}async hasValidSession(){return this.authManager.hasValidSession()}async getSession(){return this.authManager.getSession()}getStoredContext(){return this.authManager.getStoredContext()}async getCredentials(){return this.authManager.getAuthCredentials()}async getAccessToken(){return this.authManager.getAccessToken()}async authenticateWithOAuth(e){return this.authManager.authenticateWithOAuth(e)}async authenticateWithCode(e){return this.authManager.authenticateWithCode(e)}async verifyMFA(e,t){return this.authManager.verifyMFA(e,t)}async verifyMFAWithRetry(e,t,n){return this.authManager.verifyMFAWithRetry(e,t,n)}getAuthorizationUrl(){return this.authManager.getAuthorizationUrl()}async refreshToken(){return this.authManager.refreshToken()}async logout(){return this.authManager.logout()}getContext(){return this.authManager.getContext()}async updateContext(e){return this.authManager.updateContext(e)}async clearContext(){return this.authManager.clearContext()}async getOrganizations(){return this.authManager.getOrganizations()}async getOrganization(e){return this.authManager.getOrganization(e)}async getBriefs(e){return this.authManager.getBriefs(e)}async getBrief(e){return this.authManager.getBrief(e)}async getTasks(e){return this.authManager.getTasks(e)}getStorageDisplayInfo(e){if(e===`api`){let e=this.getContext();if(e?.briefId&&e?.briefName)return{storageType:`api`,briefInfo:{briefId:e.briefId,briefName:e.briefName,orgSlug:e.orgSlug,webAppUrl:this.getWebAppUrl()}}}return{storageType:`file`,filePath:t.join(`.taskmaster`,`tasks`,`tasks.json`)}}getBriefCreationUrl(){let e=this.getContext(),t=this.getWebAppUrl();return!t||!e?.orgSlug?null:`${t}/home/${e.orgSlug}/briefs/create`}async guardCommand(e,t){return we({hasValidSession:await this.hasValidSession(),briefName:this.getContext()?.briefName,storageType:t,commandName:e})}getApiBaseUrl(){let e=process.env.TM_BASE_DOMAIN||process.env.TM_PUBLIC_BASE_DOMAIN;if(e)return e.startsWith(`http://`)||e.startsWith(`https://`)?e:e.includes(`localhost`)||e.includes(`127.0.0.1`)?`http://${e}`:`https://${e}`}getWebAppUrl(){return this.getApiBaseUrl()}},dt=class{constructor(e){this.configManager=e}getConfig(){return this.configManager.getConfig()}getStorageConfig(){return this.configManager.getStorageConfig()}getModelConfig(){return this.configManager.getModelConfig()}getResponseLanguage(){return this.configManager.getResponseLanguage()}getProjectRoot(){return this.configManager.getProjectRoot()}isApiExplicitlyConfigured(){return this.configManager.isApiExplicitlyConfigured()}getActiveTag(){return this.configManager.getActiveTag()}async setActiveTag(e){return this.configManager.setActiveTag(e)}async updateConfig(e){return this.configManager.updateConfig(e)}async setResponseLanguage(e){return this.configManager.setResponseLanguage(e)}async saveConfig(){return this.configManager.saveConfig()}async reset(){return this.configManager.reset()}getConfigSources(){return this.configManager.getConfigSources()}};const k={MODELS:{MAIN:`claude-sonnet-4-20250514`,FALLBACK:`claude-3-7-sonnet-20250219`},TASKS:{DEFAULT_PRIORITY:`medium`,DEFAULT_COMPLEXITY:`moderate`,MAX_SUBTASKS:20,MAX_CONCURRENT:5,TASK_ID_PREFIX:`TASK-`},TAGS:{DEFAULT_TAG:`master`,MAX_TAGS_PER_TASK:10,NAMING_CONVENTION:`kebab-case`},WORKFLOW:{ENABLE_AUTOPILOT:!0,MAX_PHASE_ATTEMPTS:3,BRANCH_PATTERN:`task-{taskId}`,REQUIRE_CLEAN_WORKING_TREE:!0,AUTO_STAGE_CHANGES:!0,INCLUDE_CO_AUTHOR:!0,CO_AUTHOR_NAME:`TaskMaster AI`,CO_AUTHOR_EMAIL:`taskmaster@tryhamster.com`,MIN_TESTS:1,MAX_FAILURES_IN_GREEN:0,COMMIT_MESSAGE_TEMPLATE:`{type}({scope}): {description} (Task {taskId}.{subtaskIndex})`,ALLOWED_COMMIT_TYPES:[`feat`,`fix`,`refactor`,`test`,`docs`,`chore`],DEFAULT_COMMIT_TYPE:`feat`,OPERATION_TIMEOUT:6e4,ENABLE_ACTIVITY_LOGGING:!0,ACTIVITY_LOG_PATH:`.taskmaster/logs/workflow-activity.log`,ENABLE_STATE_BACKUP:!0,MAX_STATE_BACKUPS:5,ABORT_ON_MAX_ATTEMPTS:!1},STORAGE:{TYPE:`auto`,ENCODING:`utf8`,MAX_BACKUPS:5},RETRY:{ATTEMPTS:3,DELAY:1e3,MAX_DELAY:3e4,BACKOFF_MULTIPLIER:2,TIMEOUT:3e4},LOGGING:{LEVEL:`info`,MAX_FILE_SIZE:10,MAX_FILES:5},SECURITY:{MAX_REQUESTS_PER_MINUTE:60,MAX_PROMPT_LENGTH:1e5,ALLOWED_EXTENSIONS:[`.txt`,`.md`,`.json`]},VERSION:`1.0.0`};var ft=class{localConfigPath;globalConfigPath;logger=S(`ConfigLoader`);constructor(e){this.localConfigPath=t.join(e,`.taskmaster`,`config.json`),this.globalConfigPath=t.join(process.env.HOME||``,`.taskmaster`,`config.json`)}getDefaultConfig(){return{models:{main:k.MODELS.MAIN,fallback:k.MODELS.FALLBACK},workflow:{enableAutopilot:k.WORKFLOW.ENABLE_AUTOPILOT,maxPhaseAttempts:k.WORKFLOW.MAX_PHASE_ATTEMPTS,branchPattern:k.WORKFLOW.BRANCH_PATTERN,requireCleanWorkingTree:k.WORKFLOW.REQUIRE_CLEAN_WORKING_TREE,autoStageChanges:k.WORKFLOW.AUTO_STAGE_CHANGES,includeCoAuthor:k.WORKFLOW.INCLUDE_CO_AUTHOR,coAuthorName:k.WORKFLOW.CO_AUTHOR_NAME,coAuthorEmail:k.WORKFLOW.CO_AUTHOR_EMAIL,testThresholds:{minTests:k.WORKFLOW.MIN_TESTS,maxFailuresInGreen:k.WORKFLOW.MAX_FAILURES_IN_GREEN},commitMessageTemplate:k.WORKFLOW.COMMIT_MESSAGE_TEMPLATE,allowedCommitTypes:[...k.WORKFLOW.ALLOWED_COMMIT_TYPES],defaultCommitType:k.WORKFLOW.DEFAULT_COMMIT_TYPE,operationTimeout:k.WORKFLOW.OPERATION_TIMEOUT,enableActivityLogging:k.WORKFLOW.ENABLE_ACTIVITY_LOGGING,activityLogPath:k.WORKFLOW.ACTIVITY_LOG_PATH,enableStateBackup:k.WORKFLOW.ENABLE_STATE_BACKUP,maxStateBackups:k.WORKFLOW.MAX_STATE_BACKUPS,abortOnMaxAttempts:k.WORKFLOW.ABORT_ON_MAX_ATTEMPTS},storage:{type:k.STORAGE.TYPE,encoding:k.STORAGE.ENCODING,enableBackup:!1,maxBackups:k.STORAGE.MAX_BACKUPS,enableCompression:!1,atomicOperations:!0},version:k.VERSION}}async loadLocalConfig(){try{let e=await _.readFile(this.localConfigPath,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return this.logger.debug(`No local config.json found, using defaults`),null;throw new b(`Failed to load local configuration`,y.CONFIG_ERROR,{configPath:this.localConfigPath},e)}}async loadGlobalConfig(){return null}async hasLocalConfig(){try{return await _.access(this.localConfigPath),!0}catch{return!1}}async hasGlobalConfig(){try{return await _.access(this.globalConfigPath),!0}catch{return!1}}};const A={DEFAULTS:0,GLOBAL:1,LOCAL:2,ENVIRONMENT:3};var pt=class{configSources=[];addSource(e){this.configSources.push(e)}clearSources(){this.configSources=[]}merge(){let e=[...this.configSources].sort((e,t)=>e.precedence-t.precedence),t={};for(let n of e)t=this.deepMerge(t,n.config);return t}deepMerge(e,t){if(!t)return e;if(!e)return t;let n={...e};for(let e in t)t[e]===null||t[e]===void 0||(typeof t[e]==`object`&&!Array.isArray(t[e])?n[e]=this.deepMerge(n[e]||{},t[e]):n[e]=t[e]);return n}getSources(){return[...this.configSources].sort((e,t)=>t.precedence-e.precedence)}hasSource(e){return this.configSources.some(t=>t.name===e)}removeSource(e){let t=this.configSources.length;return this.configSources=this.configSources.filter(t=>t.name!==e),this.configSources.length<t}},mt=class{localConfigPath;backupDir;logger=S(`ConfigPersistence`);constructor(e){this.localConfigPath=t.join(e,`.taskmaster`,`config.json`),this.backupDir=t.join(e,`.taskmaster`,`backups`)}async saveConfig(e,n={}){let{createBackup:r=!1,atomic:i=!0}=n;try{r&&await this.configExists()&&await this.createBackup();let n=t.dirname(this.localConfigPath);await _.mkdir(n,{recursive:!0});let a=JSON.stringify(e,null,2);if(i){let e=`${this.localConfigPath}.tmp`;await _.writeFile(e,a,`utf-8`),await _.rename(e,this.localConfigPath)}else await _.writeFile(this.localConfigPath,a,`utf-8`)}catch(e){throw new b(`Failed to save configuration`,y.CONFIG_ERROR,{configPath:this.localConfigPath},e)}}async createBackup(){try{await _.mkdir(this.backupDir,{recursive:!0});let e=new Date().toISOString().replace(/[:.]/g,`-`),n=t.join(this.backupDir,`config-${e}.json`),r=await _.readFile(this.localConfigPath,`utf-8`);return await _.writeFile(n,r,`utf-8`),await this.cleanOldBackups(),n}catch(e){throw this.logger.warn(`Failed to create backup:`,e),e}}async cleanOldBackups(e=5){try{let n=(await _.readdir(this.backupDir)).filter(e=>e.startsWith(`config-`)&&e.endsWith(`.json`)).sort().reverse().slice(e);for(let e of n)await _.unlink(t.join(this.backupDir,e))}catch(e){this.logger.warn(`Failed to clean old backups:`,e)}}async configExists(){try{return await _.access(this.localConfigPath),!0}catch{return!1}}async deleteConfig(){try{await _.unlink(this.localConfigPath)}catch(e){if(e.code!==`ENOENT`)throw new b(`Failed to delete configuration`,y.CONFIG_ERROR,{configPath:this.localConfigPath},e)}}async getBackups(){try{return(await _.readdir(this.backupDir)).filter(e=>e.startsWith(`config-`)&&e.endsWith(`.json`)).sort().reverse()}catch{return[]}}async restoreFromBackup(e){let n=t.join(this.backupDir,e);try{let e=await _.readFile(n,`utf-8`);await _.writeFile(this.localConfigPath,e,`utf-8`)}catch(e){throw new b(`Failed to restore from backup`,y.CONFIG_ERROR,{backupPath:n},e)}}},ht=class e{logger=S(`EnvironmentConfigProvider`);static DEFAULT_MAPPINGS=[{env:`TASKMASTER_STORAGE_TYPE`,path:[`storage`,`type`],validate:e=>[`file`,`api`].includes(e)},{env:`TASKMASTER_API_ENDPOINT`,path:[`storage`,`apiEndpoint`]},{env:`TASKMASTER_API_TOKEN`,path:[`storage`,`apiAccessToken`]},{env:`TASKMASTER_MODEL_MAIN`,path:[`models`,`main`]},{env:`TASKMASTER_MODEL_RESEARCH`,path:[`models`,`research`]},{env:`TASKMASTER_MODEL_FALLBACK`,path:[`models`,`fallback`]},{env:`TASKMASTER_RESPONSE_LANGUAGE`,path:[`custom`,`responseLanguage`]}];static RUNTIME_STATE_MAPPINGS=[{env:`TASKMASTER_TAG`,path:[`activeTag`],isRuntimeState:!0}];mappings;constructor(t){this.mappings=t||[...e.DEFAULT_MAPPINGS,...e.RUNTIME_STATE_MAPPINGS]}loadConfig(){let e={};for(let t of this.mappings){if(t.isRuntimeState)continue;let n=process.env[t.env];if(n){if(t.validate&&!t.validate(n)){this.logger.warn(`Invalid value for ${t.env}: ${n}`);continue}this.setNestedProperty(e,t.path,n)}}return e}getRuntimeState(){let e={};for(let t of this.mappings){if(!t.isRuntimeState)continue;let n=process.env[t.env];if(n){let r=t.path[t.path.length-1];e[r]=n}}return e}setNestedProperty(e,t,n){let r=t[t.length-1],i=t.slice(0,-1),a=e;for(let e of i)a[e]||(a[e]={}),a=a[e];a[r]=n}hasEnvVar(e){return e in process.env&&process.env[e]!==void 0}getAllTaskmasterEnvVars(){let e={};for(let[t,n]of Object.entries(process.env))t.startsWith(`TASKMASTER_`)&&n!==void 0&&(e[t]=n);return e}addMapping(e){this.mappings.push(e)}getMappings(){return[...this.mappings]}},gt=class{stateFilePath;currentState;logger=S(`RuntimeStateManager`);constructor(e){this.stateFilePath=t.join(e,`.taskmaster`,`state.json`),this.currentState={currentTag:k.TAGS.DEFAULT_TAG}}async loadState(){try{let e=await _.readFile(this.stateFilePath,`utf-8`),t=JSON.parse(e),n={currentTag:t.currentTag||t.activeTag||k.TAGS.DEFAULT_TAG,lastUpdated:t.lastUpdated,metadata:t.metadata};return process.env.TASKMASTER_TAG&&(n.currentTag=process.env.TASKMASTER_TAG),this.currentState=n,n}catch(e){return e.code===`ENOENT`?(this.logger.debug(`No state.json found, using default state`),process.env.TASKMASTER_TAG&&(this.currentState.currentTag=process.env.TASKMASTER_TAG),this.currentState):(this.logger.warn(`Failed to load state file:`,e.message),this.currentState)}}async saveState(){let e=t.dirname(this.stateFilePath);try{await _.mkdir(e,{recursive:!0});let t={...this.currentState,lastUpdated:new Date().toISOString()};await _.writeFile(this.stateFilePath,JSON.stringify(t,null,2),`utf-8`)}catch(e){throw new b(`Failed to save runtime state`,y.CONFIG_ERROR,{statePath:this.stateFilePath},e)}}getCurrentTag(){return this.currentState.currentTag}async setCurrentTag(e){this.currentState.currentTag=e,await this.saveState()}getState(){return{...this.currentState}}async updateMetadata(e){this.currentState.metadata={...this.currentState.metadata,...e},await this.saveState()}async clearState(){try{await _.unlink(this.stateFilePath)}catch(e){if(e.code!==`ENOENT`)throw e}this.currentState={currentTag:k.TAGS.DEFAULT_TAG}}},_t=class e{projectRoot;config={};initialized=!1;loader;merger;stateManager;persistence;envProvider;static async create(t){let n=new e(t);return await n.initialize(),n}constructor(e){this.projectRoot=e,this.loader=new ft(e),this.merger=new pt,this.stateManager=new gt(e),this.persistence=new mt(e),this.envProvider=new ht}async initialize(){if(this.initialized)return;this.merger.clearSources(),this.merger.addSource({name:`defaults`,config:this.loader.getDefaultConfig(),precedence:A.DEFAULTS});let e=await this.loader.loadGlobalConfig();e&&this.merger.addSource({name:`global`,config:e,precedence:A.GLOBAL});let t=await this.loader.loadLocalConfig();t&&this.merger.addSource({name:`local`,config:t,precedence:A.LOCAL});let n=this.envProvider.loadConfig();Object.keys(n).length>0&&this.merger.addSource({name:`environment`,config:n,precedence:A.ENVIRONMENT}),this.config=this.merger.merge(),await this.stateManager.loadState(),this.initialized=!0}getConfig(){return this.config}getStorageConfig(){let e=this.config.storage,t=e?.type||`auto`,n=e?.basePath??this.projectRoot;return t===`api`||t===`auto`?{type:t,basePath:n,apiEndpoint:e?.apiEndpoint,apiAccessToken:e?.apiAccessToken,apiConfigured:!!(e?.apiEndpoint||e?.apiAccessToken)}:{type:t,basePath:n,apiConfigured:!1}}getModelConfig(){return this.config.models||{main:k.MODELS.MAIN,fallback:k.MODELS.FALLBACK}}getResponseLanguage(){return this.config.custom?.responseLanguage||`Chinese`}getProjectRoot(){return this.projectRoot}isApiExplicitlyConfigured(){return this.getStorageConfig().type===`api`}getActiveTag(){return this.stateManager.getCurrentTag()}async setActiveTag(e){await this.stateManager.setCurrentTag(e)}async updateConfig(e){Object.assign(this.config,e),await this.persistence.saveConfig(this.config),this.initialized=!1,await this.initialize()}async setResponseLanguage(e){this.config.custom||(this.config.custom={}),this.config.custom.responseLanguage=e,await this.persistence.saveConfig(this.config)}async saveConfig(){await this.persistence.saveConfig(this.config,{createBackup:!0,atomic:!0})}async reset(){await this.persistence.deleteConfig(),await this.stateManager.clearState(),this.initialized=!1,this.config={},await this.initialize()}getConfigSources(){return this.merger.getSources()}},j=class{projectPath;git;constructor(e){if(!e)throw Error(`Project path is required`);if(!c.isAbsolute(e))throw Error(`Project path must be an absolute path`);this.projectPath=c.normalize(e),this.git=ce(this.projectPath)}async isGitRepository(){try{let e=c.join(this.projectPath,`.git`);if(await se.pathExists(e))return!0;try{return await this.git.revparse([`--git-dir`]),!0}catch{return!1}}catch{return!1}}async validateGitInstallation(){try{await this.git.version()}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Git is not installed or not accessible: ${t}`)}}async getGitVersion(){let e=await this.git.version();return{major:e.major,minor:e.minor,patch:typeof e.patch==`string`?parseInt(e.patch):e.patch||0,agent:e.agent}}async getRepositoryRoot(){try{let e=await this.git.revparse([`--show-toplevel`]);return c.normalize(e.trim())}catch{throw Error(`not a git repository: ${this.projectPath}`)}}async validateRepository(){if(!await this.isGitRepository())throw Error(`not a git repository: ${this.projectPath}`);try{await this.git.status()}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Repository validation failed: ${t}`)}}async ensureGitRepository(){if(!await this.isGitRepository())throw Error(`not a git repository: ${this.projectPath}\nPlease run this command from within a git repository, or initialize one with 'git init'.`)}async isWorkingTreeClean(){return(await this.git.status()).isClean()}async getStatus(){return await this.git.status()}async hasUncommittedChanges(){return!(await this.git.status()).isClean()}async hasStagedChanges(){return(await this.git.status()).staged.length>0}async hasUntrackedFiles(){return(await this.git.status()).not_added.length>0}async getStatusSummary(){let e=await this.git.status(),t=e.staged.length,n=e.modified.length,r=e.deleted.length,i=e.not_added.length,a=t+n+r+i;return{isClean:e.isClean(),staged:t,modified:n,deleted:r,untracked:i,totalChanges:a}}async ensureCleanWorkingTree(){if(!(await this.git.status()).isClean()){let e=await this.getStatusSummary();throw Error(`working tree is not clean: ${this.projectPath}\nStaged: ${e.staged}, Modified: ${e.modified}, Deleted: ${e.deleted}, Untracked: ${e.untracked}\nPlease commit or stash your changes before proceeding.`)}}async getCurrentBranch(){return(await this.git.status()).current||`HEAD`}async listBranches(){let e=await this.git.branchLocal();return Object.keys(e.branches)}async branchExists(e){return(await this.listBranches()).includes(e)}async createBranch(e,t={}){if(await this.branchExists(e))throw Error(`branch already exists: ${e}`);t.checkout&&await this.ensureCleanWorkingTree(),await this.git.branch([e]),t.checkout&&await this.git.checkout(e)}async checkoutBranch(e,t={}){if(!await this.branchExists(e))throw Error(`branch does not exist: ${e}`);t.force||await this.ensureCleanWorkingTree();let n=t.force?[`-f`,e]:[e];await this.git.checkout(n)}async createAndCheckoutBranch(e){if(await this.ensureCleanWorkingTree(),await this.branchExists(e))throw Error(`branch already exists: ${e}`);await this.git.checkoutLocalBranch(e)}async deleteBranch(e,t={}){if(!await this.branchExists(e))throw Error(`branch does not exist: ${e}`);if(await this.getCurrentBranch()===e)throw Error(`cannot delete current branch: ${e}`);let n=t.force?[`-D`,e]:[`-d`,e];await this.git.branch(n)}async stageFiles(e){await this.git.add(e)}async unstageFiles(e){await this.git.reset([`HEAD`,`--`,...e])}async createCommit(e,t={}){if(t.enforceNonDefaultBranch&&!t.force){let e=await this.getCurrentBranch();if([`main`,`master`,`develop`].includes(e))throw Error(`cannot commit to default branch: ${e}\nPlease create a feature branch or use force option.`)}if(!t.allowEmpty&&!await this.hasStagedChanges())throw Error(`no staged changes to commit`);let n=[`commit`];if(n.push(`-m`,e),t.metadata){n.push(`-m`,``);for(let[e,r]of Object.entries(t.metadata))n.push(`-m`,`[${e}:${r}]`)}n.push(`--no-gpg-sign`),t.allowEmpty&&n.push(`--allow-empty`),await this.git.raw(n)}async getCommitLog(e={}){let t={format:{hash:`%H`,date:`%ai`,message:`%B`,author_name:`%an`,author_email:`%ae`}};return e.maxCount&&(t.maxCount=e.maxCount),[...(await this.git.log(t)).all]}async getLastCommit(){return(await this.git.log({maxCount:1,format:{hash:`%H`,date:`%ai`,message:`%B`,author_name:`%an`,author_email:`%ae`}})).latest}async getDefaultBranch(){let e=await this.getCurrentBranch(),t=[`main`,`master`,`develop`];if(t.includes(e))return e;let n=await this.listBranches();for(let e of t)if(n.includes(e))return e;return`main`}async isDefaultBranch(e){return[`main`,`master`,`develop`].includes(e)}async isOnDefaultBranch(){let e=await this.getCurrentBranch();return await this.isDefaultBranch(e)}async ensureNotOnDefaultBranch(){if(await this.isOnDefaultBranch()){let e=await this.getCurrentBranch();throw Error(`currently on default branch: ${e}\nPlease create a feature branch before proceeding.`)}}async hasRemote(){return(await this.git.getRemotes()).length>0}async getRemotes(){return await this.git.getRemotes(!0)}};const vt=[[`**/*.test.*`,`test`],[`**/*.spec.*`,`test`],[`**/test/**`,`test`],[`**/tests/**`,`test`],[`**/__tests__/**`,`test`],[`**/package-lock.json`,`deps`],[`package-lock.json`,`deps`],[`**/pnpm-lock.yaml`,`deps`],[`pnpm-lock.yaml`,`deps`],[`**/yarn.lock`,`deps`],[`yarn.lock`,`deps`],[`**/package.json`,`config`],[`package.json`,`config`],[`**/tsconfig*.json`,`config`],[`tsconfig*.json`,`config`],[`**/.eslintrc*`,`config`],[`.eslintrc*`,`config`],[`**/vite.config.*`,`config`],[`vite.config.*`,`config`],[`**/vitest.config.*`,`config`],[`vitest.config.*`,`config`],[`packages/cli/**`,`cli`],[`packages/tm-core/**`,`core`],[`packages/mcp-server/**`,`mcp`],[`**/workflow/**`,`workflow`],[`**/git/**`,`git`],[`**/storage/**`,`storage`],[`**/auth/**`,`auth`],[`**/config/**`,`config`],[`**/*.md`,`docs`],[`**/docs/**`,`docs`],[`README*`,`docs`],[`CHANGELOG*`,`docs`]],yt={core:100,cli:90,mcp:85,workflow:80,git:75,storage:70,auth:65,config:60,test:50,docs:30,deps:20,repo:10};var bt=class{scopeMappings;scopePriorities;constructor(e,t){this.scopeMappings=[...vt],e&&(this.scopeMappings=[...Object.entries(e),...this.scopeMappings]),this.scopePriorities={...yt,...t}}detectScope(e){if(e.length===0)return`repo`;let t=new Map;for(let n of e){let e=this.getMatchingScope(n);e&&t.set(e,(t.get(e)||0)+1)}if(t.size===0)return`repo`;let n=`repo`,r=0;for(let[e,i]of t){let t=this.getScopePriority(e)*i;t>r&&(r=t,n=e)}return n}getAllMatchingScopes(e){let t=new Set;for(let n of e){let e=this.getMatchingScope(n);e&&t.add(e)}return Array.from(t)}getMatchingScope(e){let t=e.replace(/\\/g,`/`);for(let[e,n]of this.scopeMappings)if(this.matchesPattern(t,e))return n;return null}getScopePriority(e){return this.scopePriorities[e]||0}matchesPattern(e,t){let n=t.replace(/\*\*/g,`§GLOBSTAR§`);return n=n.replace(/[.+^${}()|[\]\\]/g,`\\$&`),n=n.replace(/\*/g,`[^/]*`),n=n.replace(/§GLOBSTAR§/g,`.*`),RegExp(`^${n}$`).test(e)}};const xt={commitMessage:`{{type}}{{#scope}}({{scope}}){{/scope}}{{#breaking}}!{{/breaking}}: {{description}}
|
|
45
45
|
|
|
46
46
|
{{#body}}{{body}}
|
|
47
47
|
|
|
@@ -270,4 +270,4 @@ Or analyze task complexity first to determine optimal subtask count:`),t.push(`
|
|
|
270
270
|
`;return n+=`
|
|
271
271
|
`,e.description&&(n+=`${e.description}\n`),e.details&&(n+=`\n**Details:**\n\n${e.details}\n`),n}formatDependenciesWithStatus(e,t){return e.map(e=>{let n=t.find(t=>String(t.id)===String(e));return n?`${e}${this.getStatusSymbol(n.status)}`:String(e)}).join(`, `)}getStatusSymbol(e){switch(e){case`done`:return` ✓`;case`in-progress`:return` ⧖`;case`blocked`:return` ⛔`;case`cancelled`:return` ✗`;case`deferred`:return` ⏸`;default:return``}}},Tn=class{taskService;executionService;loaderService;preflightChecker;briefsDomain;tagService;taskFileGenerator;projectRoot;configManager;constructor(e,t){this.projectRoot=e.getProjectRoot(),this.configManager=e,this.taskService=new fn(e),this.executionService=new pn(this.taskService,this.projectRoot),this.loaderService=new mn(this.taskService),this.preflightChecker=new xn(this.projectRoot),this.briefsDomain=new $t}async initialize(){await this.taskService.initialize(),this.tagService=new Cn(this.taskService.getStorage()),this.taskFileGenerator=new wn(this.taskService.getStorage(),this.projectRoot,this.configManager)}async list(e){return this.taskService.getTaskList(e)}async get(e,t){let n=e.split(`.`),r=n[0],i=n[1],a=await this.taskService.getTask(r,t);if(!a)return{task:null,isSubtask:!1};if(i&&a.subtasks){let e=a.subtasks.find(e=>String(e.id)===i);return e?{task:e,isSubtask:!0}:{task:null,isSubtask:!0}}return{task:a,isSubtask:!1}}async getByStatus(e,t){return this.taskService.getTasksByStatus(e,t)}async getStats(e){return this.taskService.getTaskStats(e)}async getNext(e){return this.taskService.getNextTask(e)}async getCount(e,t){let n=await this.list({tag:t}),r=0;for(let t of n.tasks)if(t.status===e&&r++,t.subtasks&&t.subtasks.length>0)for(let n of t.subtasks)(n.status===e||e===`pending`&&!n.status)&&r++;return r}async update(e,t,n){return this.taskService.updateTask(e,t,n)}async updateWithPrompt(e,t,n,r){return this.taskService.updateTaskWithPrompt(e,t,n,r)}async expand(e,t,n){return this.taskService.expandTaskWithPrompt(e,t,n)}async updateStatus(e,t,n){return this.taskService.updateTaskStatus(e,t,n)}async setActiveTag(e){return this.taskService.setActiveTag(e)}async resolveBrief(e,t){return this.briefsDomain.resolveBrief(e,t)}async switchTag(e){this.taskService.getStorageType()===`file`?await this.setActiveTag(e):await this.briefsDomain.switchBrief(e)}async start(e,t){return this.executionService.startTask(e,t)}async checkInProgressConflicts(e){return this.executionService.checkInProgressConflicts(e)}async getNextAvailable(){return this.executionService.getNextAvailableTask()}async canStart(e,t){return this.executionService.canStartTask(e,t)}async loadAndValidate(e){return this.loaderService.loadAndValidateTask(e)}getExecutionOrder(e){return this.loaderService.getExecutionOrder(e)}async runPreflightChecks(){return this.preflightChecker.runAllChecks()}async detectTestCommand(){return this.preflightChecker.detectTestCommand()}async checkGitWorkingTree(){return this.preflightChecker.checkGitWorkingTree()}async validateRequiredTools(){return this.preflightChecker.validateRequiredTools()}async detectDefaultBranch(){return this.preflightChecker.detectDefaultBranch()}async createTag(e,t){return this.tagService.createTag(e,t)}async deleteTag(e,t){return this.tagService.deleteTag(e,t)}async renameTag(e,t){return this.tagService.renameTag(e,t)}async copyTag(e,t,n){return this.tagService.copyTag(e,t,n)}async getTagsWithStats(){return this.tagService.getTagsWithStats()}getStorageType(){return this.taskService.getStorageType()}async watch(e,t){return this.taskService.getStorage().watch(e,t)}async generateTaskFiles(e){return this.getStorageType()===`api`?{success:!1,count:0,directory:``,orphanedFilesRemoved:0,error:`Task file generation is only available for local file storage. API storage manages tasks in the cloud.`}:this.taskFileGenerator.generateTaskFiles(e)}async close(){await this.taskService.close()}},En=class{projectRoot;statePath;backupDir;sessionDir;maxBackups;logger=S(`WorkflowStateManager`);writer=null;writerInitPromise=null;constructor(e,n=5){this.projectRoot=t.resolve(e),this.maxBackups=n;let r=this.getProjectIdentifier(this.projectRoot),i=fe.homedir(),a=t.join(i,`.taskmaster`,r);this.sessionDir=t.join(a,`sessions`),this.statePath=t.join(this.sessionDir,`workflow-state.json`),this.backupDir=t.join(this.sessionDir,`backups`)}getProjectIdentifier(e){return`-`+t.resolve(e).replace(/^\//,``).replace(/[^a-zA-Z0-9]+/g,`-`).replace(/-+/g,`-`).replace(/-+$/,``)}async ensureWriter(){if(!this.writer){if(this.writerInitPromise){await this.writerInitPromise;return}this.writerInitPromise=(async()=>{await _.mkdir(this.sessionDir,{recursive:!0}),this.writer=new d(this.statePath)})(),await this.writerInitPromise,this.writerInitPromise=null}}async exists(){try{return await _.access(this.statePath),!0}catch{return!1}}async load(){try{let e=await _.readFile(this.statePath,`utf-8`);return JSON.parse(e)}catch(e){throw e.code===`ENOENT`?Error(`Workflow state file not found at ${this.statePath}`):Error(`Failed to load workflow state: ${e.message}`)}}async save(e){try{await this.ensureWriter();let t=JSON.stringify(e,null,2);try{JSON.parse(t)}catch{throw this.logger.error(`Generated invalid JSON:`,t),Error(`Failed to generate valid JSON from workflow state`)}await this.writer.write(t+`
|
|
272
272
|
`),this.logger.debug(`Saved workflow state (${t.length} bytes)`)}catch(e){throw Error(`Failed to save workflow state: ${e.message}`)}}async createBackup(){try{if(!await this.exists())return;let e=await this.load();await _.mkdir(this.backupDir,{recursive:!0});let n=new Date().toISOString().replace(/[:.]/g,`-`),r=t.join(this.backupDir,`workflow-state-${n}.json`),i={timestamp:new Date().toISOString(),state:e};await _.writeFile(r,JSON.stringify(i,null,2),`utf-8`),await this.pruneBackups()}catch(e){throw Error(`Failed to create backup: ${e.message}`)}}async delete(){try{await _.unlink(this.statePath)}catch(e){if(e.code!==`ENOENT`)throw Error(`Failed to delete workflow state: ${e.message}`)}}async listBackups(){try{return(await _.readdir(this.backupDir)).filter(e=>e.startsWith(`workflow-state-`)&&e.endsWith(`.json`)).sort().reverse()}catch(e){if(e.code===`ENOENT`)return[];throw Error(`Failed to list backups: ${e.message}`)}}async restoreBackup(e){try{let n=t.join(this.backupDir,e),r=await _.readFile(n,`utf-8`),i=JSON.parse(r);await this.save(i.state)}catch(e){throw Error(`Failed to restore backup: ${e.message}`)}}async pruneBackups(){try{let e=await this.listBackups();if(e.length>this.maxBackups){let n=e.slice(this.maxBackups);for(let e of n)await _.unlink(t.join(this.backupDir,e))}}catch(e){this.logger.warn(`Failed to prune backups: ${e.message}`)}}getStatePath(){return this.statePath}getBackupDir(){return this.backupDir}getSessionDir(){return this.sessionDir}getProjectRoot(){return this.projectRoot}getActivityLogPath(){return t.join(this.sessionDir,`activity.jsonl`)}},Dn=class{currentPhase;context;transitions;eventListeners;persistCallback;autoPersistEnabled=!1;phaseGuards;aborted=!1;testResultValidator;gitOperationHook;executeHook;constructor(e){this.currentPhase=`PREFLIGHT`,this.context={...e},this.transitions=this.defineTransitions(),this.eventListeners=new Map,this.phaseGuards=new Map}defineTransitions(){return[{from:`PREFLIGHT`,to:`BRANCH_SETUP`,event:`PREFLIGHT_COMPLETE`},{from:`BRANCH_SETUP`,to:`SUBTASK_LOOP`,event:`BRANCH_CREATED`},{from:`SUBTASK_LOOP`,to:`FINALIZE`,event:`ALL_SUBTASKS_COMPLETE`},{from:`FINALIZE`,to:`COMPLETE`,event:`FINALIZE_COMPLETE`}]}getCurrentPhase(){return this.currentPhase}getCurrentTDDPhase(){if(this.currentPhase===`SUBTASK_LOOP`)return this.context.currentTDDPhase||`RED`}getContext(){return{...this.context}}async transition(e){if(this.aborted&&e.type!==`ABORT`)throw Error(`Workflow has been aborted`);if(e.type===`ERROR`){this.handleError(e.error),await this.triggerAutoPersist();return}if(e.type===`ABORT`){this.aborted=!0,await this.triggerAutoPersist();return}if(e.type===`RETRY`){this.handleRetry(),await this.triggerAutoPersist();return}if(this.currentPhase===`SUBTASK_LOOP`){await this.handleTDDPhaseTransition(e),await this.triggerAutoPersist();return}let t=this.transitions.find(t=>t.from===this.currentPhase&&t.event===e.type);if(!t)throw Error(`Invalid transition: ${e.type} from ${this.currentPhase}`);this.executeTransition(t,e),await this.triggerAutoPersist()}async handleTDDPhaseTransition(e){let t=this.context.currentTDDPhase||`RED`;switch(e.type){case`RED_PHASE_COMPLETE`:if(t!==`RED`)throw Error(`Invalid transition: RED_PHASE_COMPLETE from non-RED phase`);if(!e.testResults)throw Error(`Test results required for RED phase transition`);if(this.context.lastTestResults=e.testResults,e.testResults.failed===0){this.emit(`tdd:red:completed`),this.emit(`tdd:feature-already-implemented`,{subtaskId:this.getCurrentSubtaskId(),testResults:e.testResults});let t=this.context.subtasks[this.context.currentSubtaskIndex];t&&(t.status=`completed`),this.emit(`subtask:completed`),this.context.currentSubtaskIndex++;let n=this.getProgress();this.emit(`progress:updated`,{completed:n.completed,total:n.total,percentage:n.percentage}),this.context.currentSubtaskIndex<this.context.subtasks.length?(this.context.currentTDDPhase=`RED`,this.emit(`tdd:red:started`),this.emit(`subtask:started`)):await this.transition({type:`ALL_SUBTASKS_COMPLETE`});break}this.emit(`tdd:red:completed`),this.context.currentTDDPhase=`GREEN`,this.emit(`tdd:green:started`);break;case`GREEN_PHASE_COMPLETE`:if(t!==`GREEN`)throw Error(`Invalid transition: GREEN_PHASE_COMPLETE from non-GREEN phase`);if(!e.testResults)throw Error(`Test results required for GREEN phase transition`);if(e.testResults.failed!==0)throw Error(`GREEN phase must have zero failures`);this.context.lastTestResults=e.testResults,this.emit(`tdd:green:completed`),this.context.currentTDDPhase=`COMMIT`,this.emit(`tdd:commit:started`);break;case`COMMIT_COMPLETE`:if(t!==`COMMIT`)throw Error(`Invalid transition: COMMIT_COMPLETE from non-COMMIT phase`);this.emit(`tdd:commit:completed`);let n=this.context.subtasks[this.context.currentSubtaskIndex];n&&(n.status=`completed`);break;case`SUBTASK_COMPLETE`:this.emit(`subtask:completed`),this.context.currentSubtaskIndex++;let r=this.getProgress();this.emit(`progress:updated`,{completed:r.completed,total:r.total,percentage:r.percentage}),this.context.currentSubtaskIndex<this.context.subtasks.length?(this.context.currentTDDPhase=`RED`,this.emit(`tdd:red:started`),this.emit(`subtask:started`)):await this.transition({type:`ALL_SUBTASKS_COMPLETE`});break;case`ALL_SUBTASKS_COMPLETE`:this.emit(`phase:exited`),this.currentPhase=`FINALIZE`,this.context.currentTDDPhase=void 0,this.emit(`phase:entered`);break;default:throw Error(`Invalid transition: ${e.type} in SUBTASK_LOOP`)}}executeTransition(e,t){if(e.guard&&!e.guard(this.context))throw Error(`Guard condition failed for transition to ${e.to}`);let n=this.phaseGuards.get(e.to);if(n&&!n(this.context))throw Error(`Guard condition failed`);this.emit(`phase:exited`),this.updateContext(t),this.currentPhase=e.to,this.emit(`phase:entered`),this.currentPhase===`SUBTASK_LOOP`&&(this.context.currentTDDPhase=`RED`,this.emit(`tdd:red:started`),this.emit(`subtask:started`))}updateContext(e){switch(e.type){case`BRANCH_CREATED`:this.context.branchName=e.branchName,this.emit(`git:branch:created`,{branchName:e.branchName}),this.gitOperationHook&&this.gitOperationHook(`branch:created`,{branchName:e.branchName});break;case`ERROR`:this.context.errors.push(e.error),this.emit(`error:occurred`,{error:e.error});break}}getState(){return{phase:this.currentPhase,context:{...this.context}}}restoreState(e){this.currentPhase=e.phase,this.context={...e.context},this.emit(`workflow:resumed`,{phase:this.currentPhase,progress:this.getProgress()})}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t)}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}emit(e,t){let n={type:e,timestamp:new Date,phase:this.currentPhase,tddPhase:this.context.currentTDDPhase,subtaskId:this.getCurrentSubtaskId(),data:{...t,adapters:{testValidator:!!this.testResultValidator,gitHook:!!this.gitOperationHook,executeHook:!!this.executeHook}}},r=this.eventListeners.get(e);r&&r.forEach(e=>e(n))}getCurrentSubtaskId(){return this.context.subtasks[this.context.currentSubtaskIndex]?.id}onStatePersist(e){this.persistCallback=e}enableAutoPersist(e){this.persistCallback=e,this.autoPersistEnabled=!0}disableAutoPersist(){this.autoPersistEnabled=!1}async persistState(){this.persistCallback&&await this.persistCallback(this.getState()),this.emit(`state:persisted`)}async triggerAutoPersist(){this.autoPersistEnabled&&this.persistCallback&&await this.persistCallback(this.getState())}addGuard(e,t){this.phaseGuards.set(e,t)}removeGuard(e){this.phaseGuards.delete(e)}getCurrentSubtask(){return this.context.subtasks[this.context.currentSubtaskIndex]}getProgress(){let e=this.context.subtasks.filter(e=>e.status===`completed`).length,t=this.context.subtasks.length;return{completed:e,total:t,current:this.context.currentSubtaskIndex+1,percentage:t>0?Math.round(e/t*100):0}}canProceed(){return this.currentPhase===`SUBTASK_LOOP`?this.getCurrentSubtask()?.status===`completed`:!1}incrementAttempts(){let e=this.getCurrentSubtask();e&&e.attempts++}hasExceededMaxAttempts(){let e=this.getCurrentSubtask();return!e||!e.maxAttempts?!1:e.attempts>e.maxAttempts}handleError(e){this.context.errors.push(e),this.emit(`error:occurred`,{error:e})}handleRetry(){this.currentPhase===`SUBTASK_LOOP`&&(this.context.currentTDDPhase=`RED`,this.emit(`tdd:red:started`))}retryCurrentSubtask(){this.currentPhase===`SUBTASK_LOOP`&&(this.context.currentTDDPhase=`RED`,this.emit(`tdd:red:started`))}handleMaxAttemptsExceeded(){let e=this.getCurrentSubtask();e&&(e.status=`failed`,this.emit(`subtask:failed`,{subtaskId:e.id,attempts:e.attempts,maxAttempts:e.maxAttempts}))}isAborted(){return this.aborted}canResumeFromState(e){return!(![`PREFLIGHT`,`BRANCH_SETUP`,`SUBTASK_LOOP`,`FINALIZE`,`COMPLETE`].includes(e.phase)||!e.context||typeof e.context!=`object`||!e.context.taskId||!Array.isArray(e.context.subtasks)||typeof e.context.currentSubtaskIndex!=`number`||!Array.isArray(e.context.errors))}setTestResultValidator(e){this.testResultValidator=e,this.emit(`adapter:configured`,{adapterType:`test-validator`})}hasTestResultValidator(){return!!this.testResultValidator}removeTestResultValidator(){this.testResultValidator=void 0}onGitOperation(e){this.gitOperationHook=e}onExecute(e){this.executeHook=e}executeCommand(e){this.executeHook&&this.executeHook(e,this.context)}};async function On(e,t){let n={...t,timestamp:new Date().toISOString()};await se.ensureDir(c.dirname(e));let r=JSON.stringify(n)+`
|
|
273
|
-
`;await se.appendFile(e,r,`utf-8`)}const kn=[`workflow:started`,`workflow:completed`,`workflow:error`,`workflow:resumed`,`phase:entered`,`phase:exited`,`tdd:feature-already-implemented`,`tdd:red:started`,`tdd:red:completed`,`tdd:green:started`,`tdd:green:completed`,`tdd:commit:started`,`tdd:commit:completed`,`subtask:started`,`subtask:completed`,`subtask:failed`,`test:run`,`test:passed`,`test:failed`,`git:branch:created`,`git:commit:created`,`error:occurred`,`state:persisted`,`progress:updated`,`adapter:configured`];var An=class{activityLogPath;orchestrator;logger=S(`WorkflowActivityLogger`);listenerMap=new Map;isActive=!1;constructor(e,t){this.orchestrator=e,this.activityLogPath=t}start(){if(this.isActive){this.logger.warn(`Activity logger is already active`);return}kn.forEach(e=>{let t=e=>this.logEvent(e);this.listenerMap.set(e,t),this.orchestrator.on(e,t)}),this.isActive=!0,this.logger.debug(`Activity logger started, logging to: ${this.activityLogPath}`)}stop(){this.isActive&&(this.listenerMap.forEach((e,t)=>{this.orchestrator.off(t,e)}),this.listenerMap.clear(),this.isActive=!1,this.logger.debug(`Activity logger stopped and listeners removed`))}async logEvent(e){if(this.isActive)try{let t=e.timestamp instanceof Date?e.timestamp.toISOString():new Date(e.timestamp).toISOString(),n={type:e.type,phase:e.phase,tddPhase:e.tddPhase,subtaskId:e.subtaskId,eventTimestamp:t,...e.data||{}};await On(this.activityLogPath,n)}catch(t){this.logger.error(`Failed to log activity event ${e.type}: ${t.message}`)}}getActivityLogPath(){return this.activityLogPath}isLogging(){return this.isActive}},jn=class{projectRoot;stateManager;taskStatusUpdater;tag;logger=S(`WorkflowService`);orchestrator;activityLogger;constructor(e){typeof e==`string`?this.projectRoot=e:(this.projectRoot=e.projectRoot,this.taskStatusUpdater=e.taskStatusUpdater,this.tag=e.tag),this.stateManager=new En(this.projectRoot)}async updateTaskStatus(e,t,n){if(this.taskStatusUpdater)try{await this.taskStatusUpdater.updateStatus(e,t,n??this.tag)}catch(t){let n=t instanceof Error?t.message:String(t);this.logger.warn(`Failed to update task ${e} status: ${n}`)}}async hasWorkflow(){return await this.stateManager.exists()}async startWorkflow(e){let{taskId:t,taskTitle:n,subtasks:r,maxAttempts:i=3,force:a,tag:o,orgSlug:s}=e;if(await this.hasWorkflow()&&!a)throw Error(`Workflow already exists. Use force=true to override or resume existing workflow.`);let c=new j(this.projectRoot);await c.ensureGitRepository(),await c.ensureCleanWorkingTree();let l=r.map(e=>({id:e.id,title:e.title,status:e.status===`done`?`completed`:`pending`,attempts:0,maxAttempts:e.maxAttempts||i})),u=l.findIndex(e=>e.status!==`completed`);if(u===-1)throw Error(`All subtasks for task ${t} are already completed. Nothing to do.`);this.orchestrator=new Dn({taskId:t,subtasks:l,currentSubtaskIndex:u,tag:o,errors:[],metadata:{startedAt:new Date().toISOString(),taskTitle:n,resumedFromSubtask:u>0?l[u].id:void 0}}),this.orchestrator.enableAutoPersist(async e=>{await this.stateManager.save(e)}),this.activityLogger=new An(this.orchestrator,this.stateManager.getActivityLogPath()),this.activityLogger.start(),await this.orchestrator.transition({type:`PREFLIGHT_COMPLETE`});let d=this.generateBranchName(t,n,o,s);return await c.getCurrentBranch()!==d&&await c.createAndCheckoutBranch(d),await this.orchestrator.transition({type:`BRANCH_CREATED`,branchName:d}),await this.updateTaskStatus(t,`in-progress`,o),this.getStatus()}async resumeWorkflow(){let e=await this.stateManager.load();if(this.orchestrator=new Dn(e.context),!this.orchestrator.canResumeFromState(e))throw Error(`Invalid workflow state. State may be corrupted. Consider starting a new workflow.`);return this.orchestrator.restoreState(e),this.orchestrator.enableAutoPersist(async e=>{await this.stateManager.save(e)}),this.activityLogger=new An(this.orchestrator,this.stateManager.getActivityLogPath()),this.activityLogger.start(),this.getStatus()}getStatus(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getContext(),t=this.orchestrator.getProgress(),n=this.orchestrator.getCurrentSubtask();return{taskId:e.taskId,phase:this.orchestrator.getCurrentPhase(),tddPhase:this.orchestrator.getCurrentTDDPhase(),branchName:e.branchName,currentSubtask:n?{id:n.id,title:n.title,attempts:n.attempts,maxAttempts:n.maxAttempts||3}:void 0,progress:t}}getContext(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);return this.orchestrator.getContext()}getNextAction(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getCurrentPhase(),t=this.orchestrator.getCurrentTDDPhase(),n=this.orchestrator.getCurrentSubtask();if(e===`COMPLETE`)return{action:`workflow_complete`,description:`All subtasks completed`,nextSteps:`All subtasks completed! Review the entire implementation and merge your branch when ready.`,phase:e};if(e===`FINALIZE`)return{action:`finalize_workflow`,description:`Finalize and complete the workflow`,nextSteps:`All subtasks are complete! Use autopilot_finalize to verify no uncommitted changes remain and mark the workflow as complete.`,phase:e};if(e!==`SUBTASK_LOOP`||!t||!n)return{action:`unknown`,description:`Workflow is not in active state`,nextSteps:`Use autopilot_status to check workflow state.`,phase:e};let r={phase:e,tddPhase:t,subtask:{id:n.id,title:n.title}};switch(t){case`RED`:return{...r,action:`generate_test`,description:`Generate failing test for current subtask`,nextSteps:`Write failing tests for subtask ${n.id}: "${n.title}". Create test file(s) that validate the expected behavior. Run tests and use autopilot_complete_phase with results. Note: If all tests pass (0 failures), the feature is already implemented and the subtask will be auto-completed.`};case`GREEN`:return{...r,action:`implement_code`,description:`Implement feature to make tests pass`,nextSteps:`Implement code to make tests pass for subtask ${n.id}: "${n.title}". Write the minimal code needed to pass all tests (GREEN phase), then use autopilot_complete_phase with test results.`};case`COMMIT`:return{...r,action:`commit_changes`,description:`Commit RED-GREEN cycle changes`,nextSteps:`Review and commit your changes for subtask ${n.id}: "${n.title}". Use autopilot_commit to create the commit and advance to the next subtask.`};default:return{...r,action:`unknown`,description:`Unknown TDD phase`,nextSteps:`Use autopilot_status to check workflow state.`}}}async completePhase(e){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let t=this.orchestrator.getCurrentTDDPhase();if(!t)throw Error(`Not in active TDD phase`);switch(t){case`RED`:await this.orchestrator.transition({type:`RED_PHASE_COMPLETE`,testResults:e});break;case`GREEN`:await this.orchestrator.transition({type:`GREEN_PHASE_COMPLETE`,testResults:e});break;case`COMMIT`:throw Error(`Cannot complete COMMIT phase with test results. Use commit() instead.`);default:throw Error(`Unknown TDD phase: ${t}`)}return this.getStatus()}async commit(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getCurrentTDDPhase();if(e!==`COMMIT`)throw Error(`Cannot commit in ${e} phase. Complete RED and GREEN phases first.`);let t=this.orchestrator.getCurrentSubtask()?.id;await this.orchestrator.transition({type:`COMMIT_COMPLETE`});let n=this.orchestrator.getProgress();if(n.current<n.total?await this.orchestrator.transition({type:`SUBTASK_COMPLETE`}):await this.orchestrator.transition({type:`ALL_SUBTASKS_COMPLETE`}),t){let e=this.orchestrator.getContext();await this.updateTaskStatus(t,`done`,e.tag)}return this.getStatus()}async finalizeWorkflow(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getCurrentPhase();if(e!==`FINALIZE`)throw Error(`Cannot finalize workflow in ${e} phase. Complete all subtasks first.`);let t=await new j(this.projectRoot).getStatusSummary();if(!t.isClean)throw Error(`Cannot finalize workflow: working tree has uncommitted changes.\nStaged: ${t.staged}, Modified: ${t.modified}, Deleted: ${t.deleted}, Untracked: ${t.untracked}\nPlease commit all changes before finalizing the workflow.`);let n=this.orchestrator.getContext(),r=n.taskId;await this.orchestrator.transition({type:`FINALIZE_COMPLETE`});let i=this.getStatus();return await this.updateTaskStatus(r,`done`,n.tag),await this.stateManager.delete(),this.orchestrator=void 0,i}async abortWorkflow(){this.orchestrator&&await this.orchestrator.transition({type:`ABORT`}),await this.stateManager.delete(),this.orchestrator=void 0}generateBranchName(e,t,n,r){let i=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).substring(0,50),a=e.replace(/\./g,`-`),o=r||n;return`${o?`tm/${o}`:`tm`}/task-${a}-${i}`}},Mn=class{workflowService=null;projectRoot;configManager;tasksDomain=null;constructor(e){this.configManager=e,this.projectRoot=e.getProjectRoot()}setTasksDomain(e){this.tasksDomain=e}getWorkflowService(){if(!this.workflowService){let e=this.configManager.getActiveTag(),t=this.tasksDomain?{updateStatus:async(e,t,n)=>{await this.tasksDomain.updateStatus(e,t,n)}}:void 0;this.workflowService=new jn({projectRoot:this.projectRoot,taskStatusUpdater:t,tag:e})}return this.workflowService}resetWorkflowService(){this.workflowService=null}async start(e){return this.resetWorkflowService(),this.getWorkflowService().startWorkflow(e)}async resume(){return this.resetWorkflowService(),this.getWorkflowService().resumeWorkflow()}getStatus(){return this.getWorkflowService().getStatus()}getContext(){return this.getWorkflowService().getContext()}getNextAction(){return this.getWorkflowService().getNextAction()}async completePhase(e){return this.getWorkflowService().completePhase(e)}async commit(){return this.getWorkflowService().commit()}async finalize(){let e=await this.getWorkflowService().finalizeWorkflow();return this.resetWorkflowService(),e}async abort(){await this.getWorkflowService().abortWorkflow(),this.resetWorkflowService()}async hasWorkflow(){return this.getWorkflowService().hasWorkflow()}},Nn=class e{_projectPath;_configManager;_logger;_tasks;_auth;_workflow;_git;_config;_integration;_loop;get tasks(){return this._tasks}get auth(){return this._auth}get workflow(){return this._workflow}get git(){return this._git}get config(){return this._config}get integration(){return this._integration}get loop(){return this._loop}get logger(){return this._logger}static async create(t){let n=new e(t);return await n.initialize(),n}_options;constructor(e){if(!e.projectPath)throw new b(`Project path is required`,y.MISSING_CONFIGURATION);if(!t.isAbsolute(e.projectPath))throw new b(`Project path must be an absolute path, received: "${e.projectPath}"`,y.INVALID_INPUT);this._projectPath=t.resolve(e.projectPath),this._options=e}async initialize(){try{this._logger=Oe(this._options.loggerConfig),this._configManager=await _t.create(this._projectPath),this._options.configuration&&await this._configManager.updateConfig(this._options.configuration),this._auth=new O,this._tasks=new Tn(this._configManager,this._auth),this._workflow=new Mn(this._configManager),this._git=new Tt(this._projectPath),this._config=new dt(this._configManager),this._integration=new Mt(this._configManager),this._loop=new Xt(this._configManager),await this._tasks.initialize(),this._workflow.setTasksDomain(this._tasks),this._logger.info(`TmCore initialized successfully`)}catch(e){throw this._logger&&this._logger.error(`Failed to initialize TmCore:`,e),new b(`Failed to initialize TmCore`,y.INTERNAL_ERROR,{operation:`initialize`},e)}}get projectPath(){return this._projectPath}async close(){this._tasks&&await this._tasks.close()}};async function Pn(e){return Nn.create(e)}function Fn(e,n){try{return m.existsSync(t.join(e,n))}catch{return!1}}function R(e,t){return t.some(t=>Fn(e,t))}function In(e=process.cwd()){let n=t.resolve(e),r=t.parse(n).root,i=0,a=null;if(R(n,Ue)||R(n,We))return n;let o=t.dirname(n);for(i=1;i<50;){let e=R(o,Ue),n=R(o,We);if(e&&(n||i===1))return o;if(n&&!e){a=o;break}if(o===r)break;let s=t.dirname(o);if(s===o)break;o=s,i++}for(n=a||t.resolve(e),i=0;i<50;){if(R(n,Ge))return n;if(n===r)break;let e=t.dirname(n);if(e===n)break;n=e,i++}return t.resolve(e)}function Ln(e){if(!e)return``;let n=String(e).split(t.sep),r=n.findIndex(e=>e===`.taskmaster`);return r===-1?String(e):n.slice(0,r).join(t.sep)||t.sep}function Rn(e){let t=e?r(process.cwd(),e):In();return{projectRoot:t,tasksPath:n(t,He)}}function zn(e){return _e(typeof e==`string`?new Date(e):e,{addSuffix:!0})}function Bn(e){return ge(e,`hh:mm:ss a`)}function Vn(e){if(!e)return e;let t=e.trim();if(/^\d+(\.\d+)?$/.test(t))return t;let n=t.match(/^([a-zA-Z]{3})-?(\d+)$/);return n?`${n[1].toUpperCase()}-${n[2]}`:t}const Hn=/^\d+$/,Un=/^\d+\.\d+$/,Wn=/^[a-zA-Z]{3}-?\d+$/;function Gn(e){if(!e)return!1;let t=e.trim();return!!(Hn.test(t)||Un.test(t)||Wn.test(t))}function Kn(e){if(!e)return!1;let t=e.trim();return!!(Hn.test(t)||Wn.test(t))}const qn=v.string().trim().refine(Gn,{message:`Invalid task ID format. Expected: numeric ("1", "1.2") or prefixed with hyphen ("HAM-1")`}),Jn=v.string().trim().refine(Gn,{message:`Invalid task ID format. Expected: numeric ("1") or prefixed with hyphen ("HAM-1")`}).refine(Kn,{message:`Subtask IDs are not allowed. Please provide a main task ID (e.g., "1", "HAM-1")`}),Yn=qn.transform(Vn),Xn=Jn.transform(Vn),Zn=qn,Qn=Jn,$n=/^(\d+(\.\d+)*|[A-Za-z]+-?\d+)$/;function er(e){return $n.test(e)}v.string().min(1,`Task ID cannot be empty`).refine(er,{message:`Invalid task ID format. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123')`});const tr=v.string().min(1,`Task ID(s) cannot be empty`).refine(e=>{let t=e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);return t.length>0&&t.every(er)},{message:`Invalid task ID format. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123'). Multiple IDs should be comma-separated.`});function nr(e){let t=e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);if(t.length===0)throw Error(`No valid task IDs provided`);let n=t.filter(e=>!er(e));if(n.length>0)throw Error(`Invalid task ID format: ${n.join(`, `)}. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123')`);return t.map(Vn)}const rr=S(`TaskFilters`),ir=[`pending`,`in-progress`,`review`];function ar(e){let t=new Map(e.map(e=>[String(e.id),[]])),n=[];for(let r of e)for(let e of r.dependencies??[]){let i=String(e),a=t.get(i);a?a.push(String(r.id)):n.push({taskId:String(r.id),depId:i})}return{blocksMap:t,invalidDependencies:n}}function or(e){let t=new Set(e.filter(e=>nt(e.status)).map(e=>String(e.id)));return e.filter(e=>(et.includes(e.status)||rr.warn(`Task ${e.id} has unexpected status "${e.status}". Valid statuses are: ${et.join(`, `)}`),ir.includes(e.status)?(e.dependencies??[]).every(e=>t.has(String(e))):!1))}function sr(e){return e.filter(e=>e.blocks.length>0)}const cr=[{type:`task_count`,threshold:10,message:`Your tasks are growing! Upgrade to Hamster Studio (Multiplayer) for coordinated team action, AI context sharing, and faster shipping.`,promptType:`upgrade_suggestion`,showOnce:!1,cooldownDays:7,priority:80},{type:`tags_used`,threshold:3,message:`Organize by tags? Hamster briefs let you group and collaborate on tagged tasks with your team.`,promptType:`educational_notice`,showOnce:!1,cooldownDays:14,priority:70},{type:`list_count`,threshold:5,message:`Managing multiple projects? Create Hamster briefs to organize work across your team.`,promptType:`educational_notice`,showOnce:!1,cooldownDays:14,priority:50},{type:`dependencies_complex`,threshold:5,message:`Your tasks have complex dependencies. Hamster visualizes these relationships and tracks blockers automatically.`,promptType:`educational_notice`,showOnce:!1,cooldownDays:14,priority:60},{type:`days_active`,threshold:7,message:`Ready to collaborate? Export your tasks to Hamster Studio and start shipping faster with your team.`,promptType:`upgrade_suggestion`,showOnce:!0,priority:90},{type:`export_attempt`,threshold:1,message:`Export to Hamster Studio to enable coordinated team action, AI context sharing, and alignment in hours.`,promptType:`critical_choice`,showOnce:!1,cooldownDays:1,priority:100},{type:`no_connection`,threshold:1,message:`Connect to Hamster Studio to sync your tasks across devices and collaborate with your team.`,promptType:`upgrade_suggestion`,showOnce:!1,cooldownDays:3,priority:75},{type:`parse_prd`,threshold:1,message:`Export your PRD to Hamster for dynamic task generation and team collaboration.`,promptType:`critical_choice`,showOnce:!1,cooldownDays:1,priority:95}],lr=`1.0.0`,ur=`upgradePrompts`;var dr=class{logger=S(`PromptStateManager`);runtimeStateManager;cachedState=null;constructor(e){this.runtimeStateManager=new gt(e)}async getState(){return this.cachedState||=await this.loadState(),this.cachedState}async loadState(){try{await this.runtimeStateManager.loadState();let e=this.runtimeStateManager.getState().metadata?.[ur];if(e&&typeof e==`object`)return this.validateAndMigrate(e)}catch(e){this.logger.warn(`Failed to load prompt state, using defaults:`,e)}return this.createDefaultState()}createDefaultState(){return{triggers:{},metrics:{totalTaskCount:0,tagCount:0,listCommandCount:0,tasksWithDependencies:0},lastUpdated:new Date().toISOString(),version:lr}}validateAndMigrate(e){return{triggers:e.triggers||{},metrics:{totalTaskCount:e.metrics?.totalTaskCount||0,tagCount:e.metrics?.tagCount||0,listCommandCount:e.metrics?.listCommandCount||0,tasksWithDependencies:e.metrics?.tasksWithDependencies||0,firstActivityAt:e.metrics?.firstActivityAt,lastActivityAt:e.metrics?.lastActivityAt},lastUpdated:e.lastUpdated||new Date().toISOString(),version:lr}}async saveState(){if(this.cachedState)try{this.cachedState.lastUpdated=new Date().toISOString(),await this.runtimeStateManager.updateMetadata({[ur]:this.cachedState})}catch(e){throw this.logger.error(`Failed to save prompt state:`,e),e}}async getTriggerState(e){return(await this.getState()).triggers[e]||null}async recordPromptShown(e){let t=await this.getState(),n=new Date().toISOString(),r=t.triggers[e];t.triggers[e]={firstShownAt:r?.firstShownAt||n,lastShownAt:n,showCount:(r?.showCount||0)+1,dismissed:r?.dismissed||!1},await this.saveState()}async recordPromptAction(e,t){let n=await this.getState(),r=new Date().toISOString(),i=n.triggers[e]||{showCount:1,dismissed:!1};n.triggers[e]={...i,action:t,actionAt:r,dismissed:t===`dismissed`},await this.saveState()}async updateMetrics(e){let t=await this.getState(),n=new Date().toISOString();t.metrics.firstActivityAt||(t.metrics.firstActivityAt=n),t.metrics.lastActivityAt=n,Object.assign(t.metrics,e),await this.saveState()}async incrementMetric(e,t=1){let n=await this.getState();n.metrics[e]=(n.metrics[e]||0)+t,n.metrics.firstActivityAt||(n.metrics.firstActivityAt=new Date().toISOString()),n.metrics.lastActivityAt=new Date().toISOString(),await this.saveState()}async getMetrics(){return(await this.getState()).metrics}async isWithinCooldown(e,t){let n=await this.getTriggerState(e);if(!n?.lastShownAt)return!1;let r=new Date(n.lastShownAt),i=t*24*60*60*1e3;return Date.now()-r.getTime()<i}async isDismissed(e){return(await this.getTriggerState(e))?.dismissed||!1}async getDaysActive(){let e=await this.getState();if(!e.metrics.firstActivityAt)return 0;let t=new Date(e.metrics.firstActivityAt),n=Date.now();return Math.floor((n-t.getTime())/(1440*60*1e3))}async reset(){this.cachedState=this.createDefaultState(),await this.saveState()}async resetTrigger(e){let t=await this.getState();delete t.triggers[e],await this.saveState()}},fr=class{stateManager;config;constructor(e,t){this.stateManager=e,this.config=t||{enabled:!0,triggers:cr,defaultCooldownDays:7,respectDismissed:!0}}async evaluate(e={}){if(!this.config.enabled)return{shouldShow:!1,reason:`Prompts are disabled`};let t=await this.stateManager.getMetrics(),n=await this.stateManager.getDaysActive(),r=[...this.config.triggers].sort((e,t)=>t.priority-e.priority);for(let i of r){let r=await this.evaluateTrigger(i,t,n,e);if(r.shouldShow)return r}return{shouldShow:!1,reason:`No trigger conditions met`}}async evaluateTriggerType(e,t={}){let n=this.config.triggers.find(t=>t.type===e);if(!n)return{shouldShow:!1,reason:`Unknown trigger type: ${e}`};let r=await this.stateManager.getMetrics(),i=await this.stateManager.getDaysActive();return this.evaluateTrigger(n,r,i,t)}async evaluateTrigger(e,t,n,r){if(this.config.respectDismissed&&await this.stateManager.isDismissed(e.type))return{shouldShow:!1,trigger:e,reason:`Prompt was dismissed by user`};let i=e.cooldownDays??this.config.defaultCooldownDays;if(await this.stateManager.isWithinCooldown(e.type,i))return{shouldShow:!1,trigger:e,reason:`Within cooldown period (${i} days)`};if(e.showOnce){let t=await this.stateManager.getTriggerState(e.type);if(t&&t.showCount>0)return{shouldShow:!1,trigger:e,reason:`Prompt already shown (showOnce=true)`}}let a=this.evaluateThreshold(e,t,n,r);return a.met?{shouldShow:!0,trigger:e,reason:a.reason}:{shouldShow:!1,trigger:e,reason:a.reason}}evaluateThreshold(e,t,n,r){switch(e.type){case`task_count`:let i=t.totalTaskCount>=e.threshold;return{met:i,reason:i?`Task count ${t.totalTaskCount} >= ${e.threshold}`:`Task count ${t.totalTaskCount} < ${e.threshold}`};case`tags_used`:let a=t.tagCount>=e.threshold;return{met:a,reason:a?`Tag count ${t.tagCount} >= ${e.threshold}`:`Tag count ${t.tagCount} < ${e.threshold}`};case`list_count`:let o=t.listCommandCount>=e.threshold;return{met:o,reason:o?`List count ${t.listCommandCount} >= ${e.threshold}`:`List count ${t.listCommandCount} < ${e.threshold}`};case`dependencies_complex`:let s=t.tasksWithDependencies>=e.threshold;return{met:s,reason:s?`Tasks with dependencies ${t.tasksWithDependencies} >= ${e.threshold}`:`Tasks with dependencies ${t.tasksWithDependencies} < ${e.threshold}`};case`days_active`:let c=n>=e.threshold;return{met:c,reason:c?`Days active ${n} >= ${e.threshold}`:`Days active ${n} < ${e.threshold}`};case`export_attempt`:let l=r.currentCommand===`export`;return{met:l,reason:l?`User is attempting export`:`Not an export command`};case`no_connection`:let u=!r.isAuthenticated||!r.hasBriefConnected;return{met:u,reason:u?`No Hamster connection detected`:`User is connected to Hamster`};case`parse_prd`:let d=r.currentCommand===`parse-prd`;return{met:d,reason:d?`User is parsing a PRD`:`Not a parse-prd command`};default:return{met:!1,reason:`Unknown trigger type: ${e.type}`}}}getTriggers(){return this.config.triggers}getTrigger(e){return this.config.triggers.find(t=>t.type===e)}isEnabled(){return this.config.enabled}},pr=class{logger=S(`PromptService`);stateManager;evaluator;constructor(e,t){this.stateManager=new dr(e),this.evaluator=new fr(this.stateManager,t)}async evaluatePrompts(e={}){try{return await this.evaluator.evaluate(e)}catch(e){return this.logger.error(`Error evaluating prompts:`,e),{shouldShow:!1,reason:`Evaluation error: ${e.message}`}}}async evaluateTrigger(e,t={}){try{return await this.evaluator.evaluateTriggerType(e,t)}catch(t){return this.logger.error(`Error evaluating trigger ${e}:`,t),{shouldShow:!1,reason:`Evaluation error: ${t.message}`}}}async recordPromptShown(e){try{await this.stateManager.recordPromptShown(e),this.logger.debug(`Recorded prompt shown: ${e}`)}catch(e){this.logger.error(`Error recording prompt shown:`,e)}}async recordAction(e,t){try{await this.stateManager.recordPromptAction(e,t),this.logger.debug(`Recorded prompt action: ${e} -> ${t}`)}catch(e){this.logger.error(`Error recording prompt action:`,e)}}async updateMetrics(e){try{await this.stateManager.updateMetrics(e)}catch(e){this.logger.error(`Error updating metrics:`,e)}}async incrementMetric(e,t=1){try{await this.stateManager.incrementMetric(e,t)}catch(t){this.logger.error(`Error incrementing metric ${e}:`,t)}}async getMetrics(){return this.stateManager.getMetrics()}async dismissPrompt(e){await this.recordAction(e,`dismissed`)}isEnabled(){return this.evaluator.isEnabled()}getPromptMessage(e){return this.evaluator.getTrigger(e)?.message||null}async reset(){await this.stateManager.reset()}async resetTrigger(e){await this.stateManager.resetTrigger(e)}async syncMetrics(e){let t={};e.taskCount!==void 0&&(t.totalTaskCount=e.taskCount),e.tagCount!==void 0&&(t.tagCount=e.tagCount),e.tasksWithDependencies!==void 0&&(t.tasksWithDependencies=e.tasksWithDependencies),Object.keys(t).length>0&&await this.updateMetrics(t)}static buildContext(e){return{currentCommand:e.command,isAuthenticated:e.isAuthenticated,hasBriefConnected:e.hasBriefConnected,custom:e.custom}}};const mr=[`add-task`,`analyze-complexity`,`expand-task`,`parse-prd`,`research`,`research-save`,`update-subtask`,`update-task`,`update-tasks`],hr=`.taskmaster`,gr=`.taskmaster/tasks`,_r=`.taskmaster/docs`,vr=`.taskmaster/reports`,yr=`.taskmaster/templates`,br=`.taskmaster/config.json`,xr=`.taskmaster/state.json`,z=`.taskmasterconfig`,Sr=`.taskmaster/reports/task-complexity-report.json`,Cr=`.taskmaster/docs/prd.txt`,wr=`.taskmaster/templates/example_prd.txt`,Tr=`.taskmaster/tasks/tasks.json`,Er=`tasks/tasks.json`,Dr=`.env.example`,Or=`.gitignore`;let kr=!1;const Ar={maxRetries:5,retryDelay:100,staleLockAge:1e4};function jr(e){if(typeof SharedArrayBuffer<`u`&&typeof Atomics<`u`&&typeof Atomics.wait==`function`)try{let t=new SharedArrayBuffer(4),n=new Int32Array(t);Atomics.wait(n,0,0,e);return}catch{}let t=Date.now()+e;for(;Date.now()<t;);}function Mr(e,t,n={}){let{createIfMissing:r=!1}=n,i=c.dirname(e);if(s.existsSync(i)||s.mkdirSync(i,{recursive:!0}),r)try{s.writeFileSync(e,`{}`,{flag:`wx`})}catch(e){if(e.code!==`EEXIST`)throw e}let a=`${e}.lock`,{maxRetries:o,retryDelay:l,staleLockAge:u}=Ar,d=!1;for(let e=0;e<o;e++)try{let e=JSON.stringify({pid:process.pid,timestamp:Date.now()});s.writeFileSync(a,e,{flag:`wx`}),d=!0;break}catch(t){if(t.code===`EEXIST`){try{let e=s.statSync(a);if(Date.now()-e.mtimeMs>u){let e=`${a}.stale.${process.pid}.${Date.now()}`;try{s.renameSync(a,e);try{s.unlinkSync(e)}catch{}continue}catch{}}}catch(e){if(e.code===`ENOENT`)continue;throw e}e<o-1&&jr(l*2**e)}else throw t}if(!d)throw Error(`Failed to acquire lock on ${e} after ${o} attempts`);try{return t()}finally{try{s.unlinkSync(a)}catch(t){U(`warn`,`Failed to release lock for ${e}: ${t.message}`)}}}function B(e,t=null,n=null){if(t?.env?.[e])return t.env[e];if(n){let t=c.join(n,`.env`);if(s.existsSync(t))try{let n=s.readFileSync(t,`utf-8`),r=ye.parse(n);if(r&&r[e])return r[e]}catch(e){U(`warn`,`Could not read or parse ${t}: ${e.message}`)}}if(process.env[e])return process.env[e]}function V(e=process.cwd(),t=[`package.json`,`pyproject.toml`,`.git`,z]){let n=c.resolve(e),r=c.parse(n).root;for(;n!==r;){if(t.some(e=>{let t=c.join(n,e);return s.existsSync(t)}))return n;n=c.dirname(n)}return t.some(e=>{let t=c.join(r,e);return s.existsSync(t)})?r:null}const H={debug:0,info:1,warn:2,error:3,success:1};function Nr(){kr=!0}function Pr(){kr=!1}function Fr(){return kr}function U(e,...t){if(Fr())return;let n=`info`;try{n=Ii()||`info`}catch{n=`info`}let r={debug:i.gray(`[DEBUG]`),info:i.blue(`[INFO]`),warn:i.yellow(`[WARN]`),error:i.red(`[ERROR]`),success:i.green(`[SUCCESS]`)},a=H.hasOwnProperty(e)?e:`info`;if(H[a]>=(H[n]??H.info)){let e=r[a]||``,n=t.map(e=>typeof e==`object`?JSON.stringify(e):e).join(` `);console.log(`${e} ${n}`)}}function Ir(e){if(!e||typeof e!=`object`)return!1;for(let t in e)if(e.hasOwnProperty(t)&&typeof e[t]==`object`&&Array.isArray(e[t].tasks))return!0;return!1}function W(e){Array.isArray(e)&&e.forEach(e=>{if(e.id!==void 0){let t=parseInt(e.id,10);!isNaN(t)&&t>0&&(e.id=t)}Array.isArray(e.subtasks)&&e.subtasks.forEach(e=>{if(e.id!==void 0)if(typeof e.id==`string`&&e.id.includes(`.`)){let t=e.id.split(`.`);e.id=parseInt(t[t.length-1],10)}else{let t=parseInt(e.id,10);!isNaN(t)&&t>0&&(e.id=t)}})})}function Lr(t,n=null,r=null){let i=!1;try{i=$()}catch{}if(i&&console.log(`readJSON called with: ${t}, projectRoot: ${n}, tag: ${r}`),!t)return null;let a;try{a=JSON.parse(s.readFileSync(t,`utf8`)),i&&console.log(`Successfully read JSON from ${t}`)}catch(e){return i&&console.log(`Failed to read JSON from ${t}: ${e.message}`),null}if(!t.includes(`tasks.json`)||!a)return i&&console.log(`File is not tasks.json or data is null, returning as-is`),a;if(Array.isArray(a.tasks)&&!a._rawTaggedData&&!Ir(a)){i&&console.log(`File is in legacy format, performing migration...`),W(a.tasks);let r={master:{tasks:a.tasks,metadata:a.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for master context`}}};try{if(Hr(t,r),i&&console.log(`Successfully migrated legacy format to tagged format`),Rr(t),n)try{e(n,t)}catch{}Vr(t)}catch(e){i&&console.log(`Error writing migrated data: ${e.message}`)}a=r}if(typeof a==`object`&&!a.tasks){for(let e in i&&console.log(`File is in tagged format, resolving tag...`),a)if(a.hasOwnProperty(e)&&typeof a[e]==`object`&&a[e].tasks)try{ii(a[e],{description:`Tasks for ${e} context`,skipUpdate:!0})}catch(t){i&&console.log(`Failed to ensure metadata for tag ${e}: ${t.message}`)}let o=JSON.parse(JSON.stringify(a));for(let e in o)o[e]&&Array.isArray(o[e].tasks)&&W(o[e].tasks);if(n)try{e(n,t)}catch{}try{let e=`master`;try{if(r)e=r;else if(n)e=ti({projectRoot:n});else{let n=V(c.dirname(t));n&&(e=ti({projectRoot:n}))}}catch(e){i&&console.log(`Tag resolution failed, using master: ${e.message}`)}i&&console.log(`Resolved tag: ${e}`);let s=a[e];if(s&&s.tasks){W(s.tasks);let t={...s,tag:e,_rawTaggedData:o};return i&&console.log(`Returning data for tag '${e}' with ${s.tasks.length} tasks`),t}else{let t=a.master;return t&&t.tasks?(W(t.tasks),i&&console.log(`Tag '${e}' not found, falling back to master with ${t.tasks.length} tasks`),{...t,tag:`master`,_rawTaggedData:o}):(i&&console.log(`No valid tag data found, returning empty structure`),{tasks:[],tag:`master`,_rawTaggedData:o})}}catch(e){i&&console.log(`Error during tag resolution: ${e.message}`);let t=a.master;return t&&t.tasks?(W(t.tasks),{...t,_rawTaggedData:o}):{tasks:[],_rawTaggedData:o}}}return i&&console.log(`File format not recognized, returning as-is`),a}function Rr(e){try{let t=V(c.dirname(e))||c.dirname(e),n=c.join(t,`.taskmaster`,`config.json`);s.existsSync(n)&&zr(n);let r=c.join(t,`.taskmaster`,`state.json`);s.existsSync(r)||Br(r),$()&&U(`debug`,`Complete tag migration performed for project: ${t}`)}catch(e){$()&&U(`warn`,`Error during complete tag migration: ${e.message}`)}}function zr(e){try{let t=s.readFileSync(e,`utf8`),n=JSON.parse(t);if(!n)return;let r=!1;n.global||={},n.global.defaultTag||(n.global.defaultTag=`master`,r=!0),r&&(s.writeFileSync(e,JSON.stringify(n,null,2),`utf8`),process.env.TASKMASTER_DEBUG===`true`&&console.log(`[DEBUG] Updated config.json with tagged task system settings`))}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error migrating config.json: ${e.message}`)}}function Br(e){try{let t={currentTag:`master`,lastSwitched:new Date().toISOString(),branchTagMapping:{},migrationNoticeShown:!1};s.writeFileSync(e,JSON.stringify(t,null,2),`utf8`),process.env.TASKMASTER_DEBUG===`true`&&console.log(`[DEBUG] Created initial state.json for tagged task system`)}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error creating state.json: ${e.message}`)}}function Vr(e){try{let t=c.dirname(c.dirname(e)),n=c.join(t,`.taskmaster`,`state.json`);s.existsSync(n)||Br(n);try{let e=s.readFileSync(n,`utf8`),t=JSON.parse(e)||{};t.migrationNoticeShown===void 0&&(t.migrationNoticeShown=!1,s.writeFileSync(n,JSON.stringify(t,null,2),`utf8`))}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error updating state for migration notice: ${e.message}`)}}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error marking migration for notice: ${e.message}`)}}function Hr(e,t,n=null,r=null){let i=process.env.TASKMASTER_DEBUG===`true`;try{Mr(e,()=>{let a=t;if(t&&!t._rawTaggedData&&n&&Array.isArray(t.tasks)&&!Ir(t)){let o=r||ei(n);i&&console.log(`writeJSON: Detected resolved tag data missing _rawTaggedData. Re-reading raw data to prevent data loss for tag '${o}'.`);let c={};try{c=JSON.parse(s.readFileSync(e,`utf8`))}catch(e){i&&console.log(`writeJSON: Could not read existing file, starting fresh: ${e.message}`)}a={...c,[o]:{metadata:{...c[o]?.metadata||{},...t.metadata||{}},tasks:t.tasks}}}else if(t&&t._rawTaggedData&&n){let o=r||ei(n),c;try{c=JSON.parse(s.readFileSync(e,`utf8`))}catch(e){c=t._rawTaggedData,i&&console.log(`writeJSON: Using _rawTaggedData as fallback: ${e.message}`)}let{_rawTaggedData:l,tag:u,...d}=t;a={...c,[o]:d},i&&console.log(`writeJSON: Merging resolved data back into tag '${o}'`)}let o=a;if(o&&typeof o==`object`){let{_rawTaggedData:e,tag:t,...n}=o;if(o=n,typeof o==`object`&&!Array.isArray(o)){let e={};for(let[t,n]of Object.entries(o))if(n&&typeof n==`object`&&Array.isArray(n.tasks)){let{created:r,description:i,...a}=n;a.metadata||={},r&&!a.metadata.created&&(a.metadata.created=r),i&&!a.metadata.description&&(a.metadata.description=i),e[t]=a}else e[t]=n;o=e}}let c=`${e}.tmp.${process.pid}`;try{s.writeFileSync(c,JSON.stringify(o,null,2),`utf8`),s.renameSync(c,e)}catch(e){try{s.existsSync(c)&&s.unlinkSync(c)}catch{}throw e}i&&console.log(`writeJSON: Successfully wrote to ${e}`)},{createIfMissing:!0})}catch(t){throw U(`error`,`Error writing JSON file ${e}:`,t.message),i&&U(`error`,`Full error details:`,t),t}}function Ur(e=null){let t=!1;try{t=$()}catch{t=!1}try{let n;if(e)n=e;else{let e=c.join(process.cwd(),Sr),t=c.join(process.cwd(),`scripts/task-complexity-report.json`);n=s.existsSync(e)?e:t}if(!s.existsSync(n))return t&&U(`debug`,`Complexity report not found at ${n}`),null;let r=Lr(n);return t&&U(`debug`,`Successfully read complexity report from ${n}`),r}catch(e){return t&&U(`error`,`Error reading complexity report: ${e.message}`),null}}function Wr(e,t){return!e||!e.complexityAnalysis||!Array.isArray(e.complexityAnalysis)?null:e.complexityAnalysis.find(e=>e.taskId===t)}function Gr(e,t){let n;n=e.isSubtask?e.parentTask.id:e.parentId?e.parentId:e.id;let r=Wr(t,n);r&&(e.complexityScore=r.complexityScore)}function Kr(e,t){if(!t||!e||!Array.isArray(e))return!1;if(typeof t==`string`&&t.includes(`.`)){let[n,r]=t.split(`.`).map(e=>parseInt(e,10)),i=e.find(e=>e.id===n);return!i||!i.subtasks?!1:i.subtasks.some(e=>e.id===r)}let n=parseInt(t,10);return e.some(e=>e.id===n)}function qr(e){return typeof e==`string`&&e.includes(`.`)?e:typeof e==`number`?e.toString():e}function Jr(e,t,n=null,r=null){if(!t||!e||!Array.isArray(e))return{task:null,originalSubtaskCount:null};if(typeof t==`string`&&t.includes(`.`)){let[r,i]=t.split(`.`).map(e=>parseInt(e,10)),a=e.find(e=>e.id===r);if(!a||!a.subtasks)return{task:null,originalSubtaskCount:null,originalSubtasks:null};let o=a.subtasks.find(e=>e.id===i);return o&&(o.parentTask={id:a.id,title:a.title,status:a.status},o.isSubtask=!0),o&&n&&Gr(o,n),{task:o||null,originalSubtaskCount:null,originalSubtasks:null}}let i=null,a=null,o=null,s=parseInt(t,10),c=e.find(e=>e.id===s)||null;if(!c)return{task:null,originalSubtaskCount:null,originalSubtasks:null};if(i=c,r&&c.subtasks&&Array.isArray(c.subtasks)){o=[...c.subtasks],a=c.subtasks.length;let e={...c};e.subtasks=c.subtasks.filter(e=>e.status&&e.status.toLowerCase()===r.toLowerCase()),i=e}return i&&n&&Gr(i,n),{task:i,originalSubtaskCount:a,originalSubtasks:o}}function Yr(e,t){return!e||e.length<=t?e:`${e.slice(0,t-3)}...`}function Xr(e){return Array.isArray(e)?e.length===0:typeof e==`object`&&e?Object.keys(e).length===0:!1}function Zr(e,t,n=new Set,r=new Set,i=[]){n.add(e),r.add(e),i.push(e);let a=[],o=t.get(e)||[];for(let e of o)if(n.has(e)){if(r.has(e)){let t=i.indexOf(e);i.slice(t),a.push(e)}}else{let o=Zr(e,t,n,r,[...i]);a.push(...o)}return r.delete(e),a}function Qr(e,t,n={}){let{maxDepth:r=50,includeSelf:i=!1,direction:a=`forward`,logger:o=null}=n,s=new Set,c=new Set;function l(e){if(typeof e==`string`){if(e.includes(`.`))return e;let t=parseInt(e,10);return isNaN(t)?e:t}return e}function u(e,n=0){if(n>=r){let t=`Maximum recursion depth (${r}) reached for task ${e}`;o&&typeof o.warn==`function`?o.warn(t):U!==void 0&&U.warn?U.warn(t):console.warn(t);return}if(c.has(e))return;c.add(e);let a=t.find(t=>t.id===e);!a||!Array.isArray(a.dependencies)||a.dependencies.forEach(t=>{let r=l(t);r==null||!i&&r===e||(s.add(r),u(r,n+1))})}function d(e,n=0){if(n>=r){let t=`Maximum recursion depth (${r}) reached for task ${e}`;o&&typeof o.warn==`function`?o.warn(t):U!==void 0&&U.warn?U.warn(t):console.warn(t);return}c.has(e)||(c.add(e),t.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)&&t.dependencies.some(t=>l(t)===e)){if(t.id==null||!i&&t.id===e)return;s.add(t.id),d(t.id,n+1)}}))}let f=a===`reverse`?d:u;return e.forEach(e=>{e&&e.id&&f(e.id)}),Array.from(s)}function $r(e,t){if(!e||e.length===0)return null;let n={timestamp:new Date().toISOString(),userId:e[0].userId,commandName:t,modelUsed:`Multiple`,providerName:`Multiple`,inputTokens:0,outputTokens:0,totalTokens:0,totalCost:0,currency:e[0].currency||`USD`},r=new Set,i=new Set,a=new Set;return e.forEach(e=>{n.inputTokens+=e.inputTokens||0,n.outputTokens+=e.outputTokens||0,n.totalCost+=e.totalCost||0,r.add(e.modelUsed),i.add(e.providerName),a.add(e.currency||`USD`)}),n.totalTokens=n.inputTokens+n.outputTokens,n.totalCost=parseFloat(n.totalCost.toFixed(6)),r.size===1&&(n.modelUsed=[...r][0]),i.size===1&&(n.providerName=[...i][0]),a.size>1?n.currency=`Multiple`:a.size===1&&(n.currency=[...a][0]),n}function ei(e){if(!e)throw Error(`projectRoot is required for getCurrentTag`);try{let t=c.join(e,`.taskmaster`,`state.json`);if(s.existsSync(t)){let e=s.readFileSync(t,`utf8`),n=JSON.parse(e);if(n&&n.currentTag)return n.currentTag}}catch{}try{let t=c.join(e,`.taskmaster`,`config.json`);if(s.existsSync(t)){let e=s.readFileSync(t,`utf8`),n=JSON.parse(e);if(n&&n.global&&n.global.defaultTag)return n.global.defaultTag}}catch{}return`master`}function ti(e={}){let{projectRoot:t,tag:n}=e;if(!t)throw Error(`projectRoot is required for resolveTag`);return n||ei(t)}function ni(e,t){return!e||!t?[]:e[t]&&e[t].tasks&&Array.isArray(e[t].tasks)?e[t].tasks:[]}function ri(e){let t=[];for(let n of e)if(t.push({...n,searchableId:n.id.toString(),isSubtask:!1}),n.subtasks&&n.subtasks.length>0)for(let e of n.subtasks)t.push({...e,searchableId:`${n.id}.${e.id}`,isSubtask:!0,parentId:n.id,parentTitle:n.title,title:`${e.title} (subtask of: ${n.title})`,description:`${e.description} [Parent: ${n.description}]`});return t}function ii(e,t={}){if(!e||typeof e!=`object`)throw Error(`tagObj must be a valid object`);let n=new Date().toISOString();return e.metadata?(e.metadata.created||(e.metadata.created=n),t.skipUpdate||(e.metadata.updated=n),t.description&&!e.metadata.description&&(e.metadata.description=t.description)):e.metadata={created:n,updated:n,...t.description?{description:t.description}:{}},e}function ai(){return{info:(e,...t)=>U(`info`,e,...t),warn:(e,...t)=>U(`warn`,e,...t),error:(e,...t)=>U(`error`,e,...t),debug:(e,...t)=>U(`debug`,e,...t),success:(e,...t)=>U(`success`,e,...t)}}function G(e=null){return e||ai()}function K(e){return Ln(e)}function q(e=process.cwd()){return In(e)}function oi(e=null,t=null,n=null){let r=G(n),i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i);if(e){let t=c.isAbsolute(e)?e:c.resolve(a,e);if(s.existsSync(t))return r.info?.(`Using explicit tasks path: ${t}`),t;r.warn?.(`Explicit tasks path not found: ${t}, trying fallbacks`)}let o=[c.join(a,Tr),c.join(a,Er)];for(let e of o)if(s.existsSync(e))return r.info?.(`Found tasks file at: ${e}`),e.includes(`tasks/tasks.json`)&&!e.includes(`.taskmaster`)?r.warn?.(`⚠️ DEPRECATION WARNING: Found tasks.json in legacy location '${e}'. Please migrate to the new .taskmaster directory structure. Run 'task-master migrate' to automatically migrate your project.`):e.endsWith(`tasks.json`)&&!e.includes(`.taskmaster`)&&!e.includes(`tasks/`)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found tasks.json in legacy root location '${e}'. Please migrate to the new .taskmaster directory structure. Run 'task-master migrate' to automatically migrate your project.`),e;return r.warn?.(`No tasks.json found in project: ${a}`),null}function si(e=null,t=null,n=null){let r=G(n);if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);if(s.existsSync(n))return r.info?.(`Using explicit PRD path: ${n}`),n;r.warn?.(`Explicit PRD path not found: ${n}, trying fallbacks`)}let i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i),o=[_r,`scripts/`,``],l=[`PRD.md`,`prd.md`,`PRD.txt`,`prd.txt`];for(let e of o)for(let t of l){let n=c.join(a,e,t);if(s.existsSync(n))return r.info?.(`Found PRD document at: ${n}`),(e===`scripts/`||e===``)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found PRD file in legacy location '${n}'. Please migrate to .taskmaster/docs/ directory. Run 'task-master migrate' to automatically migrate your project.`),n}return r.warn?.(`No PRD document found in project: ${a}`),null}function ci(e=null,t=null,n=null){let r=G(n);if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);if(s.existsSync(n))return r.info?.(`Using explicit complexity report path: ${n}`),n;r.warn?.(`Explicit complexity report path not found: ${n}, trying fallbacks`)}let i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i),o=[vr,`scripts/`,``],l=[`task-complexity-report`,`task-complexity`,`complexity-report`].map(e=>t?.tag&&t?.tag!==`master`?`${e}_${t.tag}.json`:`${e}.json`);for(let e of o)for(let t of l){let n=c.join(a,e,t);if(s.existsSync(n))return r.info?.(`Found complexity report at: ${n}`),(e===`scripts/`||e===``)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found complexity report in legacy location '${n}'. Please migrate to .taskmaster/reports/ directory. Run 'task-master migrate' to automatically migrate your project.`),n}return r.warn?.(`No complexity report found in project: ${a}`),null}function li(e=null,t=null,n=null){let r=G(n),i=t?.tag;if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);return r.info?.(`Using explicit complexity report output path: ${n}`),n}let a=K(t?.projectRoot||q()||process.cwd()),o=`task-complexity-report.json`;i&&i!==`master`&&(o=`task-complexity-report_${i}.json`);let l=c.join(a,`.taskmaster/reports`,o);r.info?.(`Using tag-aware complexity report output path: ${l}`);let u=c.dirname(l);return s.existsSync(u)||(r.info?.(`Creating reports directory: ${u}`),s.mkdirSync(u,{recursive:!0})),l}function ui(e=null,t=null,n=null){let r=G(n);if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);if(s.existsSync(n))return r.info?.(`Using explicit config path: ${n}`),n;r.warn?.(`Explicit config path not found: ${n}, trying fallbacks`)}let i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i),o=[c.join(a,br),c.join(a,z)];for(let e of o)if(s.existsSync(e))return e?.endsWith(z)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found configuration in legacy location '${e}'. Please migrate to .taskmaster/config.json. Run 'task-master migrate' to automatically migrate your project.`),e;if(!(hi()||t?.storageType===`api`)){let e=`config_warning_${a}`;global._tmConfigWarningsThisRun||(global._tmConfigWarningsThisRun=new Set),global._tmConfigWarningsThisRun.has(e)||(global._tmConfigWarningsThisRun.add(e),r.warn?.(`No configuration file found in project: ${a}`))}return null}var J={anthropic:[{id:`claude-sonnet-4-20250514`,swe_score:.727,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:64e3,supported:!0},{id:`claude-opus-4-20250514`,swe_score:.725,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`],max_tokens:32e3,supported:!0},{id:`claude-3-7-sonnet-20250219`,swe_score:.623,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:12e4,supported:!0},{id:`claude-3-5-sonnet-20241022`,swe_score:.49,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:8192,supported:!0},{id:`claude-sonnet-4-5`,name:`Claude Sonnet 4.5`,swe_score:.772,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:64e3,supported:!0},{id:`claude-haiku-4-5`,name:`Claude Haiku 4.5`,swe_score:.733,cost_per_1m_tokens:{input:1,output:5},allowed_roles:[`main`,`fallback`],max_tokens:2e5,supported:!0},{id:`claude-opus-4-1`,name:`Claude Opus 4.1`,swe_score:.745,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`],max_tokens:32e3,supported:!0},{id:`claude-opus-4-5`,name:`Claude Opus 4.5`,swe_score:.809,cost_per_1m_tokens:{input:5,output:25},allowed_roles:[`main`,`fallback`],max_tokens:32e3,supported:!0}],"claude-code":[{id:`opus`,swe_score:.725,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32e3,supported:!0},{id:`sonnet`,swe_score:.727,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:64e3,supported:!0},{id:`haiku`,swe_score:.45,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:2e5,supported:!0}],"codex-cli":[{id:`gpt-5.3-codex`,name:`GPT-5.3 Codex`,swe_score:.84,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.2-codex`,name:`GPT-5.2 Codex`,swe_score:.82,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.1-codex-max`,name:`GPT-5.1 Codex Max`,swe_score:.78,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.1-codex-mini`,name:`GPT-5.1 Codex Mini`,swe_score:.72,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`],supported:!0},{id:`gpt-5.2`,name:`GPT-5.2`,swe_score:.8,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0}],mcp:[{id:`mcp-sampling`,swe_score:null,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:1e5,supported:!0}],"gemini-cli":[{id:`gemini-3-flash-preview`,name:`Gemini 3 Flash`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:1048576,supported:!0},{id:`gemini-3-pro-preview`,swe_score:.762,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0},{id:`gemini-2.5-pro`,swe_score:.72,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0},{id:`gemini-2.5-flash`,swe_score:.71,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0}],"grok-cli":[{id:`grok-4-latest`,name:`Grok 4 Latest`,swe_score:.7,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-latest`,name:`Grok 3 Latest`,swe_score:.65,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-fast`,name:`Grok 3 Fast`,swe_score:.6,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-mini-fast`,name:`Grok 3 Mini Fast`,swe_score:.55,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0}],openai:[{id:`gpt-4o`,swe_score:.332,cost_per_1m_tokens:{input:2.5,output:10},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`o1`,swe_score:.489,cost_per_1m_tokens:{input:15,output:60},allowed_roles:[`main`],supported:!0},{id:`o3`,swe_score:.5,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`o3-mini`,swe_score:.493,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`],max_tokens:1e5,supported:!0},{id:`o4-mini`,swe_score:.45,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],supported:!0},{id:`o1-mini`,swe_score:.4,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`],supported:!0},{id:`o1-pro`,swe_score:0,cost_per_1m_tokens:{input:150,output:600},allowed_roles:[`main`],supported:!0},{id:`gpt-4-5-preview`,swe_score:.38,cost_per_1m_tokens:{input:75,output:150},allowed_roles:[`main`],supported:!0},{id:`gpt-4-1-mini`,swe_score:0,cost_per_1m_tokens:{input:.4,output:1.6},allowed_roles:[`main`],supported:!0},{id:`gpt-4-1-nano`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.4},allowed_roles:[`main`],supported:!0},{id:`gpt-4o-mini`,swe_score:.3,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`],supported:!0},{id:`gpt-4o-search-preview`,swe_score:.33,cost_per_1m_tokens:{input:2.5,output:10},allowed_roles:[`research`],supported:!0},{id:`gpt-4o-mini-search-preview`,swe_score:.3,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`research`],supported:!0},{id:`gpt-5`,swe_score:.749,cost_per_1m_tokens:{input:5,output:20},allowed_roles:[`main`,`fallback`],max_tokens:1e5,temperature:1,supported:!0},{id:`gpt-5.1`,swe_score:.76,cost_per_1m_tokens:{input:1.25,output:10},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`],supported:!0},{id:`gpt-5.1-codex-max`,swe_score:.78,cost_per_1m_tokens:{input:1.25,output:10},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.2`,swe_score:.8,cost_per_1m_tokens:{input:1.75,output:14},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.2-pro`,swe_score:.82,cost_per_1m_tokens:{input:21,output:168},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`medium`,`high`,`xhigh`],supported:!0}],google:[{id:`gemini-3-flash-preview`,name:`Gemini 3 Flash`,swe_score:0,cost_per_1m_tokens:{input:.5,output:3},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`gemini-3-pro-preview`,swe_score:.762,cost_per_1m_tokens:{input:2,output:12},allowed_roles:[`main`,`fallback`,`research`],max_tokens:1e6,supported:!0},{id:`gemini-2.5-pro-preview-05-06`,swe_score:.638,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.5-pro-preview-03-25`,swe_score:.638,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.5-flash-preview-04-17`,swe_score:.604,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.0-flash`,swe_score:.518,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.0-flash-lite`,swe_score:0,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0}],xai:[{id:`grok-3`,name:`Grok 3`,swe_score:null,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-fast`,name:`Grok 3 Fast`,swe_score:0,cost_per_1m_tokens:{input:5,output:25},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-4`,name:`Grok 4`,swe_score:null,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0}],groq:[{id:`moonshotai/kimi-k2-instruct`,swe_score:.66,cost_per_1m_tokens:{input:1,output:3},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`llama-3.3-70b-versatile`,swe_score:.55,cost_per_1m_tokens:{input:.59,output:.79},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`llama-3.1-8b-instant`,swe_score:.32,cost_per_1m_tokens:{input:.05,output:.08},allowed_roles:[`main`,`fallback`],max_tokens:131072,supported:!0},{id:`llama-4-scout`,swe_score:.45,cost_per_1m_tokens:{input:.11,output:.34},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`llama-4-maverick`,swe_score:.52,cost_per_1m_tokens:{input:.5,output:.77},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`mixtral-8x7b-32768`,swe_score:.35,cost_per_1m_tokens:{input:.24,output:.24},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!0},{id:`qwen-qwq-32b-preview`,swe_score:.4,cost_per_1m_tokens:{input:.18,output:.18},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`deepseek-r1-distill-llama-70b`,swe_score:.52,cost_per_1m_tokens:{input:.75,output:.99},allowed_roles:[`main`,`research`],max_tokens:8192,supported:!0},{id:`gemma2-9b-it`,swe_score:.3,cost_per_1m_tokens:{input:.2,output:.2},allowed_roles:[`main`,`fallback`],max_tokens:8192,supported:!0},{id:`whisper-large-v3`,swe_score:0,cost_per_1m_tokens:{input:.11,output:0},allowed_roles:[`main`],max_tokens:0,supported:!0}],perplexity:[{id:`sonar-pro`,swe_score:0,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`research`],max_tokens:8700,supported:!0},{id:`sonar`,swe_score:0,cost_per_1m_tokens:{input:1,output:1},allowed_roles:[`research`],max_tokens:8700,supported:!0},{id:`sonar-deep-research`,swe_score:.211,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`research`],max_tokens:8700,supported:!0},{id:`sonar-reasoning-pro`,swe_score:.211,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`research`,`fallback`],max_tokens:8700,supported:!0},{id:`sonar-reasoning`,swe_score:.211,cost_per_1m_tokens:{input:1,output:5},allowed_roles:[`main`,`research`,`fallback`],max_tokens:8700,supported:!0}],openrouter:[{id:`google/gemini-2.5-flash-preview-05-20`,swe_score:0,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`google/gemini-2.5-flash-preview-05-20:thinking`,swe_score:0,cost_per_1m_tokens:{input:.15,output:3.5},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`google/gemini-2.5-pro-exp-03-25`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`deepseek/deepseek-chat-v3-0324:free`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:163840,supported:!1,reason:`Free OpenRouter models are not supported due to severe rate limits, lack of tool use support, and other reliability issues that make them impractical for production use.`},{id:`deepseek/deepseek-chat-v3-0324`,swe_score:0,cost_per_1m_tokens:{input:.27,output:1.1},allowed_roles:[`main`],max_tokens:64e3,supported:!0},{id:`openai/gpt-4.1`,swe_score:0,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`openai/gpt-4.1-mini`,swe_score:0,cost_per_1m_tokens:{input:.4,output:1.6},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`openai/gpt-4.1-nano`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.4},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`openai/o3`,swe_score:0,cost_per_1m_tokens:{input:10,output:40},allowed_roles:[`main`,`fallback`],max_tokens:2e5,supported:!0},{id:`openai/codex-mini`,swe_score:0,cost_per_1m_tokens:{input:1.5,output:6},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/gpt-4o-mini`,swe_score:0,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/o4-mini`,swe_score:.45,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/o4-mini-high`,swe_score:0,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/o1-pro`,swe_score:0,cost_per_1m_tokens:{input:150,output:600},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`meta-llama/llama-3.3-70b-instruct`,swe_score:0,cost_per_1m_tokens:{input:120,output:600},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`meta-llama/llama-4-maverick`,swe_score:0,cost_per_1m_tokens:{input:.18,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`meta-llama/llama-4-scout`,swe_score:0,cost_per_1m_tokens:{input:.08,output:.3},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`qwen/qwen-max`,swe_score:0,cost_per_1m_tokens:{input:1.6,output:6.4},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!0},{id:`qwen/qwen-turbo`,swe_score:0,cost_per_1m_tokens:{input:.05,output:.2},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!0},{id:`qwen/qwen3-235b-a22b`,swe_score:0,cost_per_1m_tokens:{input:.14,output:2},allowed_roles:[`main`,`fallback`],max_tokens:24e3,supported:!0},{id:`mistralai/mistral-small-3.1-24b-instruct:free`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:96e3,supported:!1,reason:`Free OpenRouter models are not supported due to severe rate limits, lack of tool use support, and other reliability issues that make them impractical for production use.`},{id:`mistralai/mistral-small-3.1-24b-instruct`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.3},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`mistralai/devstral-small`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.3},allowed_roles:[`main`],max_tokens:11e4,supported:!0},{id:`mistralai/mistral-nemo`,swe_score:0,cost_per_1m_tokens:{input:.03,output:.07},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`thudm/glm-4-32b:free`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!1,reason:`Free OpenRouter models are not supported due to severe rate limits, lack of tool use support, and other reliability issues that make them impractical for production use.`}],zai:[{id:`glm-4.6`,swe_score:.68,cost_per_1m_tokens:{input:.6,output:2.2},allowed_roles:[`main`,`fallback`,`research`],max_tokens:204800,supported:!0},{id:`glm-4.5`,swe_score:.65,cost_per_1m_tokens:{input:.6,output:2.2},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`glm-4.5-air`,swe_score:.62,cost_per_1m_tokens:{input:.2,output:1.1},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0}],"zai-coding":[{id:`glm-4.6`,swe_score:.68,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:204800,supported:!0},{id:`glm-4.5`,swe_score:.65,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`glm-4.5-air`,swe_score:.62,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0}],ollama:[{id:`gpt-oss:latest`,swe_score:.607,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`gpt-oss:20b`,swe_score:.607,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`gpt-oss:120b`,swe_score:.624,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`devstral:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`qwen3:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`qwen3:14b`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`qwen3:32b`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`mistral-small3.1:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`llama3.3:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`phi4:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0}],azure:[{id:`gpt-4o`,swe_score:.332,cost_per_1m_tokens:{input:2.5,output:10},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`gpt-4o-mini`,swe_score:.3,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`gpt-4-1`,swe_score:0,cost_per_1m_tokens:{input:2,output:10},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`gpt-5`,name:`GPT-5`,swe_score:.749,cost_per_1m_tokens:{input:5,output:20},allowed_roles:[`main`,`fallback`],max_tokens:1e5,temperature:1,supported:!0,api_type:`responses`},{id:`o1`,name:`o1`,swe_score:.489,cost_per_1m_tokens:{input:15,output:60},allowed_roles:[`main`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`o3`,name:`o3`,swe_score:.5,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`o3-mini`,name:`o3-mini`,swe_score:.493,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`o4-mini`,name:`o4-mini`,swe_score:.45,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`gpt-5.1`,name:`GPT-5.1`,swe_score:.76,cost_per_1m_tokens:{input:1.25,output:10},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`],supported:!0,api_type:`responses`},{id:`gpt-5.2`,name:`GPT-5.2`,swe_score:.8,cost_per_1m_tokens:{input:1.75,output:14},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0,api_type:`responses`}],bedrock:[{id:`us.anthropic.claude-3-haiku-20240307-v1:0`,swe_score:.4,cost_per_1m_tokens:{input:.25,output:1.25},allowed_roles:[`main`,`fallback`],supported:!0},{id:`us.anthropic.claude-3-opus-20240229-v1:0`,swe_score:.725,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-3-5-sonnet-20240620-v1:0`,swe_score:.49,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-3-5-sonnet-20241022-v2:0`,swe_score:.49,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-3-7-sonnet-20250219-v1:0`,swe_score:.623,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0},{id:`us.anthropic.claude-3-5-haiku-20241022-v1:0`,swe_score:.4,cost_per_1m_tokens:{input:.8,output:4},allowed_roles:[`main`,`fallback`],supported:!0},{id:`us.anthropic.claude-opus-4-20250514-v1:0`,swe_score:.725,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-sonnet-4-20250514-v1:0`,swe_score:.727,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.deepseek.r1-v1:0`,swe_score:0,cost_per_1m_tokens:{input:1.35,output:5.4},allowed_roles:[`research`],max_tokens:65536,supported:!0}]};const di=ve(import.meta.url);c.dirname(di);const Y={models:{main:{provider:`anthropic`,modelId:`claude-sonnet-4-20250514`,maxTokens:64e3,temperature:.2},research:{provider:`perplexity`,modelId:`sonar`,maxTokens:8700,temperature:.1},fallback:{provider:`anthropic`,modelId:`claude-3-7-sonnet-20250219`,maxTokens:12e4,temperature:.2}},global:{logLevel:`info`,debug:!1,defaultNumTasks:10,defaultSubtasks:5,defaultPriority:`medium`,projectName:`Task Master`,ollamaBaseURL:`http://localhost:11434/api`,bedrockBaseURL:`https://bedrock.us-east-1.amazonaws.com`,responseLanguage:`English`,enableCodebaseAnalysis:!0,enableProxy:!1,anonymousTelemetry:!0},claudeCode:{},codexCli:{},grokCli:{timeout:12e4,workingDirectory:null,defaultModel:`grok-4-latest`}};let fi=null,pi=null;function mi(e){global._tmSuppressConfigWarnings=e}function hi(){return global._tmSuppressConfigWarnings===!0}var gi=class extends Error{constructor(e){super(e),this.name=`ConfigurationError`}};function _i(e=null,t={}){let n=Y,r=e,{storageType:a}=t;e&&`${e}`,r||(r=V(),r||=process.cwd(),`${r}`);let o=null,l={...n};if((s.existsSync(c.join(r,hr))||s.existsSync(c.join(r,z)))&&(o=ui(null,{projectRoot:r,storageType:a})),o){let e=o.endsWith(z);try{let t=s.readFileSync(o,`utf-8`),r=JSON.parse(t);l={models:{main:{...n.models.main,...r?.models?.main},research:{...n.models.research,...r?.models?.research},fallback:r?.models?.fallback?.provider&&r?.models?.fallback?.modelId?{...n.models.fallback,...r.models.fallback}:{...n.models.fallback}},global:{...n.global,...r?.global},claudeCode:{...n.claudeCode,...r?.claudeCode},codexCli:{...n.codexCli,...r?.codexCli},grokCli:{...n.grokCli,...r?.grokCli}},`${o}`,e&&console.warn(i.yellow(`⚠️ DEPRECATION WARNING: Found configuration in legacy location '${o}'. Please migrate to .taskmaster/config.json. Run 'task-master migrate' to automatically migrate your project.`)),vi(l.models.main.provider)||(console.warn(i.yellow(`Warning: Invalid main provider "${l.models.main.provider}" in ${o}. Falling back to default.`)),l.models.main={...n.models.main}),vi(l.models.research.provider)||(console.warn(i.yellow(`Warning: Invalid research provider "${l.models.research.provider}" in ${o}. Falling back to default.`)),l.models.research={...n.models.research}),l.models.fallback?.provider&&!vi(l.models.fallback.provider)&&(console.warn(i.yellow(`Warning: Invalid fallback provider "${l.models.fallback.provider}" in ${o}. Fallback model configuration will be ignored.`)),l.models.fallback.provider=void 0,l.models.fallback.modelId=void 0),l.claudeCode&&!Xr(l.claudeCode)&&(l.claudeCode=bi(l.claudeCode)),l.codexCli&&!Xr(l.codexCli)&&(l.codexCli=xi(l.codexCli))}catch(e){console.error(i.red(`Error reading or parsing ${o}: ${e.message}. Using default configuration.`)),l={...n},`${o}`}}else{if(!hi()&&a!==`api`)if(e)console.warn(i.yellow(`Warning: Configuration file not found at provided project root (${e}). Using default configuration. Run 'task-master models --setup' to configure.`));else{let e=s.existsSync(c.join(r,hr)),t=s.existsSync(c.join(r,z));(e||t)&&console.warn(i.yellow(`Warning: Configuration file not found at derived root (${r}). Using defaults.`))}l={...n},`${r}`}return l}function X(e=null,t=!1,n={}){if(!fi||t||e&&e!==pi){let r=_i(e,n);return(t||e)&&(fi=r,pi=e),r}return fi}function vi(e){return Be.includes(e)?!0:ze.includes(e)?!!(J&&J[e]):!1}function yi(e){return J[e]?J[e].filter(e=>e.supported!==!1).map(e=>e.id):[]}function bi(e){let t=v.object({pathToClaudeCodeExecutable:v.string().optional(),maxTurns:v.number().int().positive().optional(),customSystemPrompt:v.string().optional(),appendSystemPrompt:v.string().optional(),permissionMode:v.enum([`default`,`acceptEdits`,`plan`,`bypassPermissions`]).optional(),allowedTools:v.array(v.string()).optional(),disallowedTools:v.array(v.string()).optional(),mcpServers:v.record(v.string(),v.object({type:v.enum([`stdio`,`sse`]).optional(),command:v.string(),args:v.array(v.string()).optional(),env:v.record(v.string(),v.string()).optional(),url:v.url().optional(),headers:v.record(v.string(),v.string()).optional()})).optional()}),n=v.record(v.string(),t).refine(e=>Object.keys(e||{}).every(e=>mr.includes(e)),{message:`Invalid command name in commandSpecific`}),r=t.extend({commandSpecific:n.optional()}),a={};try{a=r.parse(e)}catch(e){console.warn(i.yellow(`Warning: Invalid Claude Code settings in config: ${e.message}. Falling back to default.`)),a={}}return a}function xi(e){let t=v.object({codexPath:v.string().optional(),cwd:v.string().optional(),approvalMode:v.enum([`untrusted`,`on-failure`,`on-request`,`never`]).optional(),sandboxMode:v.enum([`read-only`,`workspace-write`,`danger-full-access`]).optional(),fullAuto:v.boolean().optional(),dangerouslyBypassApprovalsAndSandbox:v.boolean().optional(),skipGitRepoCheck:v.boolean().optional(),color:v.enum([`always`,`never`,`auto`]).optional(),allowNpx:v.boolean().optional(),outputLastMessageFile:v.string().optional(),env:v.record(v.string(),v.string()).optional(),verbose:v.boolean().optional(),logger:v.union([v.object({}).passthrough(),v.literal(!1)]).optional(),reasoningEffort:v.enum([`none`,`minimal`,`low`,`medium`,`high`,`xhigh`]).optional()}),n=v.record(v.string(),t).refine(e=>Object.keys(e||{}).every(e=>mr.includes(e)),{message:`Invalid command name in commandSpecific`}),r=t.extend({commandSpecific:n.optional()});try{return r.parse(e)}catch(e){return console.warn(i.yellow(`Warning: Invalid Codex CLI settings in config: ${e.message}. Falling back to default.`)),{}}}function Si(e=null,t=!1){let n=X(e,t);return{...Y.claudeCode,...n?.claudeCode||{}}}function Ci(e=null,t=!1){let n=X(e,t);return{...Y.codexCli,...n?.codexCli||{}}}function wi(e,t=null,n=!1){let r=Ci(t,n),i=r?.commandSpecific||{};return{...r,...i[e]}}function Ti(e,t=null,n=!1){let r=Si(t,n),i=r?.commandSpecific||{};return{...r,...i[e]}}function Ei(e=null,t=!1){let n=X(e,t);return{...Y.grokCli,...n?.grokCli||{}}}function Di(e,t=null,n=!1){let r=Ei(t,n),i=r?.commandSpecific||{};return{...r,...i[e]}}function Z(e,t=null){return X(t)?.models?.[e]||(U(`warn`,`No model configuration found for role: ${e}. Returning default.`),Y.models[e]||{})}function Oi(e=null){return Z(`main`,e).provider}function ki(e=null){return Z(`main`,e).modelId}function Ai(e=null){return Z(`research`,e).provider}function ji(e=null,t=null){let n=B(`TASKMASTER_ENABLE_CODEBASE_ANALYSIS`,e,t);if(n!=null&&n!==``)return n.toLowerCase()===`true`||n===`1`;if(e?.env?.TASKMASTER_ENABLE_CODEBASE_ANALYSIS){let t=e.env.TASKMASTER_ENABLE_CODEBASE_ANALYSIS;return t.toLowerCase()===`true`||t===`1`}return Q(t).enableCodebaseAnalysis!==!1}function Mi(e=!1,t=null,n=null){if(!ji(n,t))return!1;let r=e?Ai(t):Oi(t);return r===E.CLAUDE_CODE||r===E.GEMINI_CLI||r===E.GROK_CLI||r===E.CODEX_CLI}function Ni(e=null){return Z(`research`,e).modelId}function Pi(e=null){return Z(`fallback`,e).provider}function Fi(e=null){return Z(`fallback`,e).modelId}function Q(e=null){let t=X(e);return{...Y.global,...t?.global||{}}}function Ii(e=null){return Q(e).logLevel.toLowerCase()}function $(e=null){return Q(e).debug===!0}function Li(e=null){let t=Q(e).defaultSubtasks,n=parseInt(t,10);return Number.isNaN(n)?Y.global.defaultSubtasks:n}function Ri(e=null){let t=Q(e).defaultNumTasks,n=parseInt(t,10);return Number.isNaN(n)?Y.global.defaultNumTasks:n}function zi(e=null){return Q(e).defaultPriority}function Bi(e=null){return Q(e).projectName}function Vi(e=null){return Q(e).ollamaBaseURL}function Hi(e=null){return Q(e).azureBaseURL}function Ui(e=null){return Q(e).bedrockBaseURL}function Wi(e=null){return Q(e).vertexProjectId}function Gi(e=null){return Q(e).vertexLocation}function Ki(e=null){return Q(e).responseLanguage}function qi(e=null){return Q(e).enableProxy===!0}function Ji(e=null){return Q(e).anonymousTelemetry!==!1}function Yi(e=null,t=null){let n=B(`TASKMASTER_ENABLE_PROXY`,e,t);if(n!=null&&n!==``)return n.toLowerCase()===`true`||n===`1`;if(e?.env?.TASKMASTER_ENABLE_PROXY){let t=e.env.TASKMASTER_ENABLE_PROXY;return t.toLowerCase()===`true`||t===`1`}return qi(t)}function Xi(e,t=null){let n=Z(e,t),r=n.maxTokens,i=n.temperature,a=n.modelId,o=n.provider,s=r,c=i;try{let e=J[o];if(e&&Array.isArray(e)){let t=e.find(e=>e.id===a);if(t&&typeof t.max_tokens==`number`&&t.max_tokens>0){let e=t.max_tokens;s=Math.min(r,e),U(`debug`,`Applying model-specific max_tokens (${e}) for ${a}. Effective limit: ${s}`)}else U(`debug`,`No valid model-specific max_tokens override found for ${a}. Using role default: ${r}`);t&&typeof t.temperature==`number`&&t.temperature>=0&&t.temperature<=1&&(c=t.temperature,U(`debug`,`Applying model-specific temperature (${t.temperature}) for ${a}`))}else o===E.OPENROUTER?(s=Math.min(r,32768),U(`debug`,`Custom OpenRouter model ${a} detected. Using conservative max_tokens: ${s}`)):U(`debug`,`No model definitions found for provider ${o} in MODEL_MAP. Using role default maxTokens: ${r}`)}catch(e){U(`warn`,`Error looking up model-specific parameters for ${a}: ${e.message}. Using role defaults.`),s=r,c=i}return{maxTokens:s,temperature:c}}function Zi(e,t=null,n=null){if([E.OLLAMA,E.BEDROCK,E.GEMINI_CLI,E.GROK_CLI,E.MCP,E.CODEX_CLI].includes(e?.toLowerCase())||e?.toLowerCase()===`claude-code`||e?.toLowerCase()===`codex-cli`)return!0;let r={openai:`OPENAI_API_KEY`,anthropic:`ANTHROPIC_API_KEY`,google:`GOOGLE_API_KEY`,perplexity:`PERPLEXITY_API_KEY`,mistral:`MISTRAL_API_KEY`,azure:`AZURE_OPENAI_API_KEY`,openrouter:`OPENROUTER_API_KEY`,xai:`XAI_API_KEY`,zai:`ZAI_API_KEY`,"zai-coding":`ZAI_API_KEY`,groq:`GROQ_API_KEY`,vertex:`GOOGLE_API_KEY`,"claude-code":`CLAUDE_CODE_API_KEY`,bedrock:`AWS_ACCESS_KEY_ID`},i=e?.toLowerCase();if(!i||!r[i])return U(`warn`,`Unknown provider name: ${e} in isApiKeySet check.`),!1;let a=r[i],o=B(a,t,n);return o&&o.trim()!==``&&!/YOUR_.*_API_KEY_HERE/.test(o)&&!o.includes(`KEY_HERE`)}function Qi(e,t=null){let n=t||V();if(!n)return console.warn(i.yellow(`Warning: Could not find project root to check mcp.json.`)),!1;let r=c.join(n,`.cursor`,`mcp.json`);if(!s.existsSync(r))return!1;try{let t=s.readFileSync(r,`utf-8`),n=JSON.parse(t),i=n?.mcpServers?.[`task-master-ai`]?.env||n?.mcpServers?.[`taskmaster-ai`]?.env;if(!i)return!1;let a=null;switch(e){case`anthropic`:a=i.ANTHROPIC_API_KEY;break;case`openai`:a=i.OPENAI_API_KEY;break;case`openrouter`:a=i.OPENROUTER_API_KEY;break;case`google`:a=i.GOOGLE_API_KEY;break;case`perplexity`:a=i.PERPLEXITY_API_KEY;break;case`xai`:a=i.XAI_API_KEY;break;case`zai`:case`zai-coding`:a=i.ZAI_API_KEY;break;case`groq`:a=i.GROQ_API_KEY;break;case`ollama`:return!0;case`claude-code`:return!0;case`codex-cli`:return!0;case`mistral`:a=i.MISTRAL_API_KEY;break;case`azure`:a=i.AZURE_OPENAI_API_KEY;break;case`vertex`:a=i.GOOGLE_API_KEY;break;case`bedrock`:a=i.AWS_ACCESS_KEY_ID;break;default:return!1}return!!a&&!/KEY_HERE$/.test(a)}catch(e){return console.error(i.red(`Error reading or parsing .cursor/mcp.json: ${e.message}`)),!1}}function $i(){let e=[];for(let[t,n]of Object.entries(J))n.length>0?n.filter(e=>!!e.supported).forEach(n=>{let r=n.id,i=n.swe_score,a=n.cost_per_1m_tokens,o=n.allowed_roles||[`main`,`fallback`],s=n.name;s||(s=r.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `),r===`claude-3.5-sonnet-20240620`&&(s=`Claude 3.5 Sonnet`),r===`claude-3-7-sonnet-20250219`&&(s=`Claude 3.7 Sonnet`),r===`gpt-4o`&&(s=`GPT-4o`),r===`gpt-4-turbo`&&(s=`GPT-4 Turbo`),r===`sonar-pro`&&(s=`Perplexity Sonar Pro`),r===`sonar-mini`&&(s=`Perplexity Sonar Mini`)),e.push({id:r,name:s,provider:t,swe_score:i,cost_per_1m_tokens:a,allowed_roles:o,max_tokens:n.max_tokens})}):e.push({id:`[${t}-any]`,name:`Any (${t})`,provider:t});return e}function ea(e,t=null){let n=t;if(t==null){let e=V();if(!e)return console.error(i.red(`Error: Could not determine project root. Configuration not saved.`)),!1;n=e}let r=c.join(n,`.taskmaster`),a=c.join(r,`config.json`);try{return s.existsSync(r)||s.mkdirSync(r,{recursive:!0}),s.writeFileSync(a,JSON.stringify(e,null,2)),fi=e,!0}catch(e){return console.error(i.red(`Error writing configuration to ${a}: ${e.message}`)),!1}}function ta(e=null){return ui(null,{projectRoot:e})!==null}function na(e=null){let t=X(e);return t.global||={},t.global.userId||(t.global.userId=`1234567890`,ea(t,e)||U(`warning`,`Failed to write updated configuration with new userId. Please let the developers know.`)),t.global.userId}function ra(){return Ve}function ia(e,t=null){let n=Z(e,t);if(n&&typeof n.baseURL==`string`)return n.baseURL;let r=n?.provider;if(r)return B(`${r.toUpperCase()}_BASE_URL`,null,t)}async function aa(e){if(e===`solo`||e===`team`)return e;try{mi(!0);let e=X(null,!1,{storageType:`api`});if(e?.storage?.operatingMode)return e.storage.operatingMode}catch{}finally{mi(!1)}try{if(await D.getInstance().getAuthCredentials())return`team`}catch{}return`solo`}E.OLLAMA,E.BEDROCK,E.GEMINI_CLI,E.GROK_CLI,E.MCP,E.CODEX_CLI;export{oi as $,tr as $t,Ni as A,Yr as At,ta as B,br as Bt,Oi as C,ze as Cn,Rr as Ct,Xi as D,be as Dn,ti as Dt,aa as E,C as En,B as Et,Gi as F,wr as Ft,xi as G,gr as Gt,Yi as H,_r as Ht,Wi as I,Or as It,J,pr as Jt,vi as K,Tr as Kt,Mi as L,z as Lt,Ki as M,Hr as Mt,yi as N,Sr as Nt,Bi as O,Se as On,Kr as Ot,na as P,Dr as Pt,q as Q,nr as Qt,Zi as R,Er as Rt,ki as S,Be as Sn,W as St,Vi as T,w as Tn,Lr as Tt,mi as U,vr as Ut,hi as V,hr as Vt,bi as W,xr as Wt,ui as X,sr as Xt,ci as Y,ar as Yt,si as Z,or as Zt,Fi as _,it as _n,Xr as _t,Hi as a,zn as an,Br as at,Di as b,Ve as bn,Vr as bt,Si as c,In as cn,ii as ct,wi as d,N as dn,Jr as dt,Xn as en,K as et,X as f,wt as fn,Wr as ft,Li as g,rt as gn,ni as gt,zi as h,D as hn,ei as ht,$i as i,Vn as in,$r as it,Ai as j,Mr as jt,qi as k,xe as kn,Qr as kt,Ti as l,Pn as ln,Zr as lt,Ri as m,O as mn,qr as mt,ra as n,Yn as nn,H as nt,ia as o,Bn as on,Pr as ot,$ as p,j as pn,ri as pt,ea as q,yr as qt,Ji as r,Zn as rn,Gr as rt,Ui as s,Rn as sn,Nr as st,gi as t,Qn as tn,li as tt,Ci as u,Nt as un,V as ut,Pi as v,et as vn,Fr as vt,Qi as w,je as wn,Ur as wt,Ii as x,E as xn,zr as xt,Ei as y,nt as yn,U as yt,ji as z,Cr as zt};
|
|
273
|
+
`;await se.appendFile(e,r,`utf-8`)}const kn=[`workflow:started`,`workflow:completed`,`workflow:error`,`workflow:resumed`,`phase:entered`,`phase:exited`,`tdd:feature-already-implemented`,`tdd:red:started`,`tdd:red:completed`,`tdd:green:started`,`tdd:green:completed`,`tdd:commit:started`,`tdd:commit:completed`,`subtask:started`,`subtask:completed`,`subtask:failed`,`test:run`,`test:passed`,`test:failed`,`git:branch:created`,`git:commit:created`,`error:occurred`,`state:persisted`,`progress:updated`,`adapter:configured`];var An=class{activityLogPath;orchestrator;logger=S(`WorkflowActivityLogger`);listenerMap=new Map;isActive=!1;constructor(e,t){this.orchestrator=e,this.activityLogPath=t}start(){if(this.isActive){this.logger.warn(`Activity logger is already active`);return}kn.forEach(e=>{let t=e=>this.logEvent(e);this.listenerMap.set(e,t),this.orchestrator.on(e,t)}),this.isActive=!0,this.logger.debug(`Activity logger started, logging to: ${this.activityLogPath}`)}stop(){this.isActive&&(this.listenerMap.forEach((e,t)=>{this.orchestrator.off(t,e)}),this.listenerMap.clear(),this.isActive=!1,this.logger.debug(`Activity logger stopped and listeners removed`))}async logEvent(e){if(this.isActive)try{let t=e.timestamp instanceof Date?e.timestamp.toISOString():new Date(e.timestamp).toISOString(),n={type:e.type,phase:e.phase,tddPhase:e.tddPhase,subtaskId:e.subtaskId,eventTimestamp:t,...e.data||{}};await On(this.activityLogPath,n)}catch(t){this.logger.error(`Failed to log activity event ${e.type}: ${t.message}`)}}getActivityLogPath(){return this.activityLogPath}isLogging(){return this.isActive}},jn=class{projectRoot;stateManager;taskStatusUpdater;tag;logger=S(`WorkflowService`);orchestrator;activityLogger;constructor(e){typeof e==`string`?this.projectRoot=e:(this.projectRoot=e.projectRoot,this.taskStatusUpdater=e.taskStatusUpdater,this.tag=e.tag),this.stateManager=new En(this.projectRoot)}async updateTaskStatus(e,t,n){if(this.taskStatusUpdater)try{await this.taskStatusUpdater.updateStatus(e,t,n??this.tag)}catch(t){let n=t instanceof Error?t.message:String(t);this.logger.warn(`Failed to update task ${e} status: ${n}`)}}async hasWorkflow(){return await this.stateManager.exists()}async startWorkflow(e){let{taskId:t,taskTitle:n,subtasks:r,maxAttempts:i=3,force:a,tag:o,orgSlug:s}=e;if(await this.hasWorkflow()&&!a)throw Error(`Workflow already exists. Use force=true to override or resume existing workflow.`);let c=new j(this.projectRoot);await c.ensureGitRepository(),await c.ensureCleanWorkingTree();let l=r.map(e=>({id:e.id,title:e.title,status:e.status===`done`?`completed`:`pending`,attempts:0,maxAttempts:e.maxAttempts||i})),u=l.findIndex(e=>e.status!==`completed`);if(u===-1)throw Error(`All subtasks for task ${t} are already completed. Nothing to do.`);this.orchestrator=new Dn({taskId:t,subtasks:l,currentSubtaskIndex:u,tag:o,errors:[],metadata:{startedAt:new Date().toISOString(),taskTitle:n,resumedFromSubtask:u>0?l[u].id:void 0}}),this.orchestrator.enableAutoPersist(async e=>{await this.stateManager.save(e)}),this.activityLogger=new An(this.orchestrator,this.stateManager.getActivityLogPath()),this.activityLogger.start(),await this.orchestrator.transition({type:`PREFLIGHT_COMPLETE`});let d=this.generateBranchName(t,n,o,s);return await c.getCurrentBranch()!==d&&await c.createAndCheckoutBranch(d),await this.orchestrator.transition({type:`BRANCH_CREATED`,branchName:d}),await this.updateTaskStatus(t,`in-progress`,o),this.getStatus()}async resumeWorkflow(){let e=await this.stateManager.load();if(this.orchestrator=new Dn(e.context),!this.orchestrator.canResumeFromState(e))throw Error(`Invalid workflow state. State may be corrupted. Consider starting a new workflow.`);return this.orchestrator.restoreState(e),this.orchestrator.enableAutoPersist(async e=>{await this.stateManager.save(e)}),this.activityLogger=new An(this.orchestrator,this.stateManager.getActivityLogPath()),this.activityLogger.start(),this.getStatus()}getStatus(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getContext(),t=this.orchestrator.getProgress(),n=this.orchestrator.getCurrentSubtask();return{taskId:e.taskId,phase:this.orchestrator.getCurrentPhase(),tddPhase:this.orchestrator.getCurrentTDDPhase(),branchName:e.branchName,currentSubtask:n?{id:n.id,title:n.title,attempts:n.attempts,maxAttempts:n.maxAttempts||3}:void 0,progress:t}}getContext(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);return this.orchestrator.getContext()}getNextAction(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getCurrentPhase(),t=this.orchestrator.getCurrentTDDPhase(),n=this.orchestrator.getCurrentSubtask();if(e===`COMPLETE`)return{action:`workflow_complete`,description:`All subtasks completed`,nextSteps:`All subtasks completed! Review the entire implementation and merge your branch when ready.`,phase:e};if(e===`FINALIZE`)return{action:`finalize_workflow`,description:`Finalize and complete the workflow`,nextSteps:`All subtasks are complete! Use autopilot_finalize to verify no uncommitted changes remain and mark the workflow as complete.`,phase:e};if(e!==`SUBTASK_LOOP`||!t||!n)return{action:`unknown`,description:`Workflow is not in active state`,nextSteps:`Use autopilot_status to check workflow state.`,phase:e};let r={phase:e,tddPhase:t,subtask:{id:n.id,title:n.title}};switch(t){case`RED`:return{...r,action:`generate_test`,description:`Generate failing test for current subtask`,nextSteps:`Write failing tests for subtask ${n.id}: "${n.title}". Create test file(s) that validate the expected behavior. Run tests and use autopilot_complete_phase with results. Note: If all tests pass (0 failures), the feature is already implemented and the subtask will be auto-completed.`};case`GREEN`:return{...r,action:`implement_code`,description:`Implement feature to make tests pass`,nextSteps:`Implement code to make tests pass for subtask ${n.id}: "${n.title}". Write the minimal code needed to pass all tests (GREEN phase), then use autopilot_complete_phase with test results.`};case`COMMIT`:return{...r,action:`commit_changes`,description:`Commit RED-GREEN cycle changes`,nextSteps:`Review and commit your changes for subtask ${n.id}: "${n.title}". Use autopilot_commit to create the commit and advance to the next subtask.`};default:return{...r,action:`unknown`,description:`Unknown TDD phase`,nextSteps:`Use autopilot_status to check workflow state.`}}}async completePhase(e){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let t=this.orchestrator.getCurrentTDDPhase();if(!t)throw Error(`Not in active TDD phase`);switch(t){case`RED`:await this.orchestrator.transition({type:`RED_PHASE_COMPLETE`,testResults:e});break;case`GREEN`:await this.orchestrator.transition({type:`GREEN_PHASE_COMPLETE`,testResults:e});break;case`COMMIT`:throw Error(`Cannot complete COMMIT phase with test results. Use commit() instead.`);default:throw Error(`Unknown TDD phase: ${t}`)}return this.getStatus()}async commit(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getCurrentTDDPhase();if(e!==`COMMIT`)throw Error(`Cannot commit in ${e} phase. Complete RED and GREEN phases first.`);let t=this.orchestrator.getCurrentSubtask()?.id;await this.orchestrator.transition({type:`COMMIT_COMPLETE`});let n=this.orchestrator.getProgress();if(n.current<n.total?await this.orchestrator.transition({type:`SUBTASK_COMPLETE`}):await this.orchestrator.transition({type:`ALL_SUBTASKS_COMPLETE`}),t){let e=this.orchestrator.getContext();await this.updateTaskStatus(t,`done`,e.tag)}return this.getStatus()}async finalizeWorkflow(){if(!this.orchestrator)throw Error(`No active workflow. Start or resume a workflow first.`);let e=this.orchestrator.getCurrentPhase();if(e!==`FINALIZE`)throw Error(`Cannot finalize workflow in ${e} phase. Complete all subtasks first.`);let t=await new j(this.projectRoot).getStatusSummary();if(!t.isClean)throw Error(`Cannot finalize workflow: working tree has uncommitted changes.\nStaged: ${t.staged}, Modified: ${t.modified}, Deleted: ${t.deleted}, Untracked: ${t.untracked}\nPlease commit all changes before finalizing the workflow.`);let n=this.orchestrator.getContext(),r=n.taskId;await this.orchestrator.transition({type:`FINALIZE_COMPLETE`});let i=this.getStatus();return await this.updateTaskStatus(r,`done`,n.tag),await this.stateManager.delete(),this.orchestrator=void 0,i}async abortWorkflow(){this.orchestrator&&await this.orchestrator.transition({type:`ABORT`}),await this.stateManager.delete(),this.orchestrator=void 0}generateBranchName(e,t,n,r){let i=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).substring(0,50),a=e.replace(/\./g,`-`),o=r||n;return`${o?`tm/${o}`:`tm`}/task-${a}-${i}`}},Mn=class{workflowService=null;projectRoot;configManager;tasksDomain=null;constructor(e){this.configManager=e,this.projectRoot=e.getProjectRoot()}setTasksDomain(e){this.tasksDomain=e}getWorkflowService(){if(!this.workflowService){let e=this.configManager.getActiveTag(),t=this.tasksDomain?{updateStatus:async(e,t,n)=>{await this.tasksDomain.updateStatus(e,t,n)}}:void 0;this.workflowService=new jn({projectRoot:this.projectRoot,taskStatusUpdater:t,tag:e})}return this.workflowService}resetWorkflowService(){this.workflowService=null}async start(e){return this.resetWorkflowService(),this.getWorkflowService().startWorkflow(e)}async resume(){return this.resetWorkflowService(),this.getWorkflowService().resumeWorkflow()}getStatus(){return this.getWorkflowService().getStatus()}getContext(){return this.getWorkflowService().getContext()}getNextAction(){return this.getWorkflowService().getNextAction()}async completePhase(e){return this.getWorkflowService().completePhase(e)}async commit(){return this.getWorkflowService().commit()}async finalize(){let e=await this.getWorkflowService().finalizeWorkflow();return this.resetWorkflowService(),e}async abort(){await this.getWorkflowService().abortWorkflow(),this.resetWorkflowService()}async hasWorkflow(){return this.getWorkflowService().hasWorkflow()}},Nn=class e{_projectPath;_configManager;_logger;_tasks;_auth;_workflow;_git;_config;_integration;_loop;get tasks(){return this._tasks}get auth(){return this._auth}get workflow(){return this._workflow}get git(){return this._git}get config(){return this._config}get integration(){return this._integration}get loop(){return this._loop}get logger(){return this._logger}static async create(t){let n=new e(t);return await n.initialize(),n}_options;constructor(e){if(!e.projectPath)throw new b(`Project path is required`,y.MISSING_CONFIGURATION);if(!t.isAbsolute(e.projectPath))throw new b(`Project path must be an absolute path, received: "${e.projectPath}"`,y.INVALID_INPUT);this._projectPath=t.resolve(e.projectPath),this._options=e}async initialize(){try{this._logger=Oe(this._options.loggerConfig),this._configManager=await _t.create(this._projectPath),this._options.configuration&&await this._configManager.updateConfig(this._options.configuration),this._auth=new O,this._tasks=new Tn(this._configManager,this._auth),this._workflow=new Mn(this._configManager),this._git=new Tt(this._projectPath),this._config=new dt(this._configManager),this._integration=new Mt(this._configManager),this._loop=new Xt(this._configManager),await this._tasks.initialize(),this._workflow.setTasksDomain(this._tasks),this._logger.info(`TmCore initialized successfully`)}catch(e){throw this._logger&&this._logger.error(`Failed to initialize TmCore:`,e),new b(`Failed to initialize TmCore`,y.INTERNAL_ERROR,{operation:`initialize`},e)}}get projectPath(){return this._projectPath}async close(){this._tasks&&await this._tasks.close()}};async function Pn(e){return Nn.create(e)}function Fn(e,n){try{return m.existsSync(t.join(e,n))}catch{return!1}}function R(e,t){return t.some(t=>Fn(e,t))}function In(e=process.cwd()){let n=t.resolve(e),r=t.parse(n).root,i=0,a=null;if(R(n,Ue)||R(n,We))return n;let o=t.dirname(n);for(i=1;i<50;){let e=R(o,Ue),n=R(o,We);if(e&&(n||i===1))return o;if(n&&!e){a=o;break}if(o===r)break;let s=t.dirname(o);if(s===o)break;o=s,i++}for(n=a||t.resolve(e),i=0;i<50;){if(R(n,Ge))return n;if(n===r)break;let e=t.dirname(n);if(e===n)break;n=e,i++}return t.resolve(e)}function Ln(e){if(!e)return``;let n=String(e).split(t.sep),r=n.findIndex(e=>e===`.taskmaster`);return r===-1?String(e):n.slice(0,r).join(t.sep)||t.sep}function Rn(e){let t=e?r(process.cwd(),e):In();return{projectRoot:t,tasksPath:n(t,He)}}function zn(e){return _e(typeof e==`string`?new Date(e):e,{addSuffix:!0})}function Bn(e){return ge(e,`hh:mm:ss a`)}function Vn(e){if(!e)return e;let t=e.trim();if(/^\d+(\.\d+)?$/.test(t))return t;let n=t.match(/^([a-zA-Z]{3})-?(\d+)$/);return n?`${n[1].toUpperCase()}-${n[2]}`:t}const Hn=/^\d+$/,Un=/^\d+\.\d+$/,Wn=/^[a-zA-Z]{3}-?\d+$/;function Gn(e){if(!e)return!1;let t=e.trim();return!!(Hn.test(t)||Un.test(t)||Wn.test(t))}function Kn(e){if(!e)return!1;let t=e.trim();return!!(Hn.test(t)||Wn.test(t))}const qn=v.string().trim().refine(Gn,{message:`Invalid task ID format. Expected: numeric ("1", "1.2") or prefixed with hyphen ("HAM-1")`}),Jn=v.string().trim().refine(Gn,{message:`Invalid task ID format. Expected: numeric ("1") or prefixed with hyphen ("HAM-1")`}).refine(Kn,{message:`Subtask IDs are not allowed. Please provide a main task ID (e.g., "1", "HAM-1")`}),Yn=qn.transform(Vn),Xn=Jn.transform(Vn),Zn=qn,Qn=Jn,$n=/^(\d+(\.\d+)*|[A-Za-z]+-?\d+)$/;function er(e){return $n.test(e)}v.string().min(1,`Task ID cannot be empty`).refine(er,{message:`Invalid task ID format. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123')`});const tr=v.string().min(1,`Task ID(s) cannot be empty`).refine(e=>{let t=e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);return t.length>0&&t.every(er)},{message:`Invalid task ID format. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123'). Multiple IDs should be comma-separated.`});function nr(e){let t=e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);if(t.length===0)throw Error(`No valid task IDs provided`);let n=t.filter(e=>!er(e));if(n.length>0)throw Error(`Invalid task ID format: ${n.join(`, `)}. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123')`);return t.map(Vn)}const rr=S(`TaskFilters`),ir=[`pending`,`in-progress`,`review`];function ar(e){let t=new Map(e.map(e=>[String(e.id),[]])),n=[];for(let r of e)for(let e of r.dependencies??[]){let i=String(e),a=t.get(i);a?a.push(String(r.id)):n.push({taskId:String(r.id),depId:i})}return{blocksMap:t,invalidDependencies:n}}function or(e){let t=new Set(e.filter(e=>nt(e.status)).map(e=>String(e.id)));return e.filter(e=>(et.includes(e.status)||rr.warn(`Task ${e.id} has unexpected status "${e.status}". Valid statuses are: ${et.join(`, `)}`),ir.includes(e.status)?(e.dependencies??[]).every(e=>t.has(String(e))):!1))}function sr(e){return e.filter(e=>e.blocks.length>0)}const cr=[{type:`task_count`,threshold:10,message:`Your tasks are growing! Upgrade to Hamster Studio (Multiplayer) for coordinated team action, AI context sharing, and faster shipping.`,promptType:`upgrade_suggestion`,showOnce:!1,cooldownDays:7,priority:80},{type:`tags_used`,threshold:3,message:`Organize by tags? Hamster briefs let you group and collaborate on tagged tasks with your team.`,promptType:`educational_notice`,showOnce:!1,cooldownDays:14,priority:70},{type:`list_count`,threshold:5,message:`Managing multiple projects? Create Hamster briefs to organize work across your team.`,promptType:`educational_notice`,showOnce:!1,cooldownDays:14,priority:50},{type:`dependencies_complex`,threshold:5,message:`Your tasks have complex dependencies. Hamster visualizes these relationships and tracks blockers automatically.`,promptType:`educational_notice`,showOnce:!1,cooldownDays:14,priority:60},{type:`days_active`,threshold:7,message:`Ready to collaborate? Export your tasks to Hamster Studio and start shipping faster with your team.`,promptType:`upgrade_suggestion`,showOnce:!0,priority:90},{type:`export_attempt`,threshold:1,message:`Export to Hamster Studio to enable coordinated team action, AI context sharing, and alignment in hours.`,promptType:`critical_choice`,showOnce:!1,cooldownDays:1,priority:100},{type:`no_connection`,threshold:1,message:`Connect to Hamster Studio to sync your tasks across devices and collaborate with your team.`,promptType:`upgrade_suggestion`,showOnce:!1,cooldownDays:3,priority:75},{type:`parse_prd`,threshold:1,message:`Export your PRD to Hamster for dynamic task generation and team collaboration.`,promptType:`critical_choice`,showOnce:!1,cooldownDays:1,priority:95}],lr=`1.0.0`,ur=`upgradePrompts`;var dr=class{logger=S(`PromptStateManager`);runtimeStateManager;cachedState=null;constructor(e){this.runtimeStateManager=new gt(e)}async getState(){return this.cachedState||=await this.loadState(),this.cachedState}async loadState(){try{await this.runtimeStateManager.loadState();let e=this.runtimeStateManager.getState().metadata?.[ur];if(e&&typeof e==`object`)return this.validateAndMigrate(e)}catch(e){this.logger.warn(`Failed to load prompt state, using defaults:`,e)}return this.createDefaultState()}createDefaultState(){return{triggers:{},metrics:{totalTaskCount:0,tagCount:0,listCommandCount:0,tasksWithDependencies:0},lastUpdated:new Date().toISOString(),version:lr}}validateAndMigrate(e){return{triggers:e.triggers||{},metrics:{totalTaskCount:e.metrics?.totalTaskCount||0,tagCount:e.metrics?.tagCount||0,listCommandCount:e.metrics?.listCommandCount||0,tasksWithDependencies:e.metrics?.tasksWithDependencies||0,firstActivityAt:e.metrics?.firstActivityAt,lastActivityAt:e.metrics?.lastActivityAt},lastUpdated:e.lastUpdated||new Date().toISOString(),version:lr}}async saveState(){if(this.cachedState)try{this.cachedState.lastUpdated=new Date().toISOString(),await this.runtimeStateManager.updateMetadata({[ur]:this.cachedState})}catch(e){throw this.logger.error(`Failed to save prompt state:`,e),e}}async getTriggerState(e){return(await this.getState()).triggers[e]||null}async recordPromptShown(e){let t=await this.getState(),n=new Date().toISOString(),r=t.triggers[e];t.triggers[e]={firstShownAt:r?.firstShownAt||n,lastShownAt:n,showCount:(r?.showCount||0)+1,dismissed:r?.dismissed||!1},await this.saveState()}async recordPromptAction(e,t){let n=await this.getState(),r=new Date().toISOString(),i=n.triggers[e]||{showCount:1,dismissed:!1};n.triggers[e]={...i,action:t,actionAt:r,dismissed:t===`dismissed`},await this.saveState()}async updateMetrics(e){let t=await this.getState(),n=new Date().toISOString();t.metrics.firstActivityAt||(t.metrics.firstActivityAt=n),t.metrics.lastActivityAt=n,Object.assign(t.metrics,e),await this.saveState()}async incrementMetric(e,t=1){let n=await this.getState();n.metrics[e]=(n.metrics[e]||0)+t,n.metrics.firstActivityAt||(n.metrics.firstActivityAt=new Date().toISOString()),n.metrics.lastActivityAt=new Date().toISOString(),await this.saveState()}async getMetrics(){return(await this.getState()).metrics}async isWithinCooldown(e,t){let n=await this.getTriggerState(e);if(!n?.lastShownAt)return!1;let r=new Date(n.lastShownAt),i=t*24*60*60*1e3;return Date.now()-r.getTime()<i}async isDismissed(e){return(await this.getTriggerState(e))?.dismissed||!1}async getDaysActive(){let e=await this.getState();if(!e.metrics.firstActivityAt)return 0;let t=new Date(e.metrics.firstActivityAt),n=Date.now();return Math.floor((n-t.getTime())/(1440*60*1e3))}async reset(){this.cachedState=this.createDefaultState(),await this.saveState()}async resetTrigger(e){let t=await this.getState();delete t.triggers[e],await this.saveState()}},fr=class{stateManager;config;constructor(e,t){this.stateManager=e,this.config=t||{enabled:!0,triggers:cr,defaultCooldownDays:7,respectDismissed:!0}}async evaluate(e={}){if(!this.config.enabled)return{shouldShow:!1,reason:`Prompts are disabled`};let t=await this.stateManager.getMetrics(),n=await this.stateManager.getDaysActive(),r=[...this.config.triggers].sort((e,t)=>t.priority-e.priority);for(let i of r){let r=await this.evaluateTrigger(i,t,n,e);if(r.shouldShow)return r}return{shouldShow:!1,reason:`No trigger conditions met`}}async evaluateTriggerType(e,t={}){let n=this.config.triggers.find(t=>t.type===e);if(!n)return{shouldShow:!1,reason:`Unknown trigger type: ${e}`};let r=await this.stateManager.getMetrics(),i=await this.stateManager.getDaysActive();return this.evaluateTrigger(n,r,i,t)}async evaluateTrigger(e,t,n,r){if(this.config.respectDismissed&&await this.stateManager.isDismissed(e.type))return{shouldShow:!1,trigger:e,reason:`Prompt was dismissed by user`};let i=e.cooldownDays??this.config.defaultCooldownDays;if(await this.stateManager.isWithinCooldown(e.type,i))return{shouldShow:!1,trigger:e,reason:`Within cooldown period (${i} days)`};if(e.showOnce){let t=await this.stateManager.getTriggerState(e.type);if(t&&t.showCount>0)return{shouldShow:!1,trigger:e,reason:`Prompt already shown (showOnce=true)`}}let a=this.evaluateThreshold(e,t,n,r);return a.met?{shouldShow:!0,trigger:e,reason:a.reason}:{shouldShow:!1,trigger:e,reason:a.reason}}evaluateThreshold(e,t,n,r){switch(e.type){case`task_count`:let i=t.totalTaskCount>=e.threshold;return{met:i,reason:i?`Task count ${t.totalTaskCount} >= ${e.threshold}`:`Task count ${t.totalTaskCount} < ${e.threshold}`};case`tags_used`:let a=t.tagCount>=e.threshold;return{met:a,reason:a?`Tag count ${t.tagCount} >= ${e.threshold}`:`Tag count ${t.tagCount} < ${e.threshold}`};case`list_count`:let o=t.listCommandCount>=e.threshold;return{met:o,reason:o?`List count ${t.listCommandCount} >= ${e.threshold}`:`List count ${t.listCommandCount} < ${e.threshold}`};case`dependencies_complex`:let s=t.tasksWithDependencies>=e.threshold;return{met:s,reason:s?`Tasks with dependencies ${t.tasksWithDependencies} >= ${e.threshold}`:`Tasks with dependencies ${t.tasksWithDependencies} < ${e.threshold}`};case`days_active`:let c=n>=e.threshold;return{met:c,reason:c?`Days active ${n} >= ${e.threshold}`:`Days active ${n} < ${e.threshold}`};case`export_attempt`:let l=r.currentCommand===`export`;return{met:l,reason:l?`User is attempting export`:`Not an export command`};case`no_connection`:let u=!r.isAuthenticated||!r.hasBriefConnected;return{met:u,reason:u?`No Hamster connection detected`:`User is connected to Hamster`};case`parse_prd`:let d=r.currentCommand===`parse-prd`;return{met:d,reason:d?`User is parsing a PRD`:`Not a parse-prd command`};default:return{met:!1,reason:`Unknown trigger type: ${e.type}`}}}getTriggers(){return this.config.triggers}getTrigger(e){return this.config.triggers.find(t=>t.type===e)}isEnabled(){return this.config.enabled}},pr=class{logger=S(`PromptService`);stateManager;evaluator;constructor(e,t){this.stateManager=new dr(e),this.evaluator=new fr(this.stateManager,t)}async evaluatePrompts(e={}){try{return await this.evaluator.evaluate(e)}catch(e){return this.logger.error(`Error evaluating prompts:`,e),{shouldShow:!1,reason:`Evaluation error: ${e.message}`}}}async evaluateTrigger(e,t={}){try{return await this.evaluator.evaluateTriggerType(e,t)}catch(t){return this.logger.error(`Error evaluating trigger ${e}:`,t),{shouldShow:!1,reason:`Evaluation error: ${t.message}`}}}async recordPromptShown(e){try{await this.stateManager.recordPromptShown(e),this.logger.debug(`Recorded prompt shown: ${e}`)}catch(e){this.logger.error(`Error recording prompt shown:`,e)}}async recordAction(e,t){try{await this.stateManager.recordPromptAction(e,t),this.logger.debug(`Recorded prompt action: ${e} -> ${t}`)}catch(e){this.logger.error(`Error recording prompt action:`,e)}}async updateMetrics(e){try{await this.stateManager.updateMetrics(e)}catch(e){this.logger.error(`Error updating metrics:`,e)}}async incrementMetric(e,t=1){try{await this.stateManager.incrementMetric(e,t)}catch(t){this.logger.error(`Error incrementing metric ${e}:`,t)}}async getMetrics(){return this.stateManager.getMetrics()}async dismissPrompt(e){await this.recordAction(e,`dismissed`)}isEnabled(){return this.evaluator.isEnabled()}getPromptMessage(e){return this.evaluator.getTrigger(e)?.message||null}async reset(){await this.stateManager.reset()}async resetTrigger(e){await this.stateManager.resetTrigger(e)}async syncMetrics(e){let t={};e.taskCount!==void 0&&(t.totalTaskCount=e.taskCount),e.tagCount!==void 0&&(t.tagCount=e.tagCount),e.tasksWithDependencies!==void 0&&(t.tasksWithDependencies=e.tasksWithDependencies),Object.keys(t).length>0&&await this.updateMetrics(t)}static buildContext(e){return{currentCommand:e.command,isAuthenticated:e.isAuthenticated,hasBriefConnected:e.hasBriefConnected,custom:e.custom}}};const mr=[`add-task`,`analyze-complexity`,`expand-task`,`parse-prd`,`research`,`research-save`,`update-subtask`,`update-task`,`update-tasks`],hr=`.taskmaster`,gr=`.taskmaster/tasks`,_r=`.taskmaster/docs`,vr=`.taskmaster/reports`,yr=`.taskmaster/templates`,br=`.taskmaster/config.json`,xr=`.taskmaster/state.json`,z=`.taskmasterconfig`,Sr=`.taskmaster/reports/task-complexity-report.json`,Cr=`.taskmaster/docs/prd.txt`,wr=`.taskmaster/templates/example_prd.txt`,Tr=`.taskmaster/tasks/tasks.json`,Er=`tasks/tasks.json`,Dr=`.env.example`,Or=`.gitignore`;let kr=!1;const Ar={maxRetries:5,retryDelay:100,staleLockAge:1e4};function jr(e){if(typeof SharedArrayBuffer<`u`&&typeof Atomics<`u`&&typeof Atomics.wait==`function`)try{let t=new SharedArrayBuffer(4),n=new Int32Array(t);Atomics.wait(n,0,0,e);return}catch{}let t=Date.now()+e;for(;Date.now()<t;);}function Mr(e,t,n={}){let{createIfMissing:r=!1}=n,i=c.dirname(e);if(s.existsSync(i)||s.mkdirSync(i,{recursive:!0}),r)try{s.writeFileSync(e,`{}`,{flag:`wx`})}catch(e){if(e.code!==`EEXIST`)throw e}let a=`${e}.lock`,{maxRetries:o,retryDelay:l,staleLockAge:u}=Ar,d=!1;for(let e=0;e<o;e++)try{let e=JSON.stringify({pid:process.pid,timestamp:Date.now()});s.writeFileSync(a,e,{flag:`wx`}),d=!0;break}catch(t){if(t.code===`EEXIST`){try{let e=s.statSync(a);if(Date.now()-e.mtimeMs>u){let e=`${a}.stale.${process.pid}.${Date.now()}`;try{s.renameSync(a,e);try{s.unlinkSync(e)}catch{}continue}catch{}}}catch(e){if(e.code===`ENOENT`)continue;throw e}e<o-1&&jr(l*2**e)}else throw t}if(!d)throw Error(`Failed to acquire lock on ${e} after ${o} attempts`);try{return t()}finally{try{s.unlinkSync(a)}catch(t){U(`warn`,`Failed to release lock for ${e}: ${t.message}`)}}}function B(e,t=null,n=null){if(t?.env?.[e])return t.env[e];if(n){let t=c.join(n,`.env`);if(s.existsSync(t))try{let n=s.readFileSync(t,`utf-8`),r=ye.parse(n);if(r&&r[e])return r[e]}catch(e){U(`warn`,`Could not read or parse ${t}: ${e.message}`)}}if(process.env[e])return process.env[e]}function V(e=process.cwd(),t=[`package.json`,`pyproject.toml`,`.git`,z]){let n=c.resolve(e),r=c.parse(n).root;for(;n!==r;){if(t.some(e=>{let t=c.join(n,e);return s.existsSync(t)}))return n;n=c.dirname(n)}return t.some(e=>{let t=c.join(r,e);return s.existsSync(t)})?r:null}const H={debug:0,info:1,warn:2,error:3,success:1};function Nr(){kr=!0}function Pr(){kr=!1}function Fr(){return kr}function U(e,...t){if(Fr())return;let n=`info`;try{n=Ii()||`info`}catch{n=`info`}let r={debug:i.gray(`[DEBUG]`),info:i.blue(`[INFO]`),warn:i.yellow(`[WARN]`),error:i.red(`[ERROR]`),success:i.green(`[SUCCESS]`)},a=H.hasOwnProperty(e)?e:`info`;if(H[a]>=(H[n]??H.info)){let e=r[a]||``,n=t.map(e=>typeof e==`object`?JSON.stringify(e):e).join(` `);console.log(`${e} ${n}`)}}function Ir(e){if(!e||typeof e!=`object`)return!1;for(let t in e)if(e.hasOwnProperty(t)&&typeof e[t]==`object`&&Array.isArray(e[t].tasks))return!0;return!1}function W(e){Array.isArray(e)&&e.forEach(e=>{if(e.id!==void 0){let t=parseInt(e.id,10);!isNaN(t)&&t>0&&(e.id=t)}Array.isArray(e.subtasks)&&e.subtasks.forEach(e=>{if(e.id!==void 0)if(typeof e.id==`string`&&e.id.includes(`.`)){let t=e.id.split(`.`);e.id=parseInt(t[t.length-1],10)}else{let t=parseInt(e.id,10);!isNaN(t)&&t>0&&(e.id=t)}})})}function Lr(t,n=null,r=null){let i=!1;try{i=$()}catch{}if(i&&console.log(`readJSON called with: ${t}, projectRoot: ${n}, tag: ${r}`),!t)return null;let a;try{a=JSON.parse(s.readFileSync(t,`utf8`)),i&&console.log(`Successfully read JSON from ${t}`)}catch(e){return i&&console.log(`Failed to read JSON from ${t}: ${e.message}`),null}if(!t.includes(`tasks.json`)||!a)return i&&console.log(`File is not tasks.json or data is null, returning as-is`),a;if(Array.isArray(a.tasks)&&!a._rawTaggedData&&!Ir(a)){i&&console.log(`File is in legacy format, performing migration...`),W(a.tasks);let r={master:{tasks:a.tasks,metadata:a.metadata||{created:new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for master context`}}};try{if(Hr(t,r),i&&console.log(`Successfully migrated legacy format to tagged format`),Rr(t),n)try{e(n,t)}catch{}Vr(t)}catch(e){i&&console.log(`Error writing migrated data: ${e.message}`)}a=r}if(typeof a==`object`&&!a.tasks){for(let e in i&&console.log(`File is in tagged format, resolving tag...`),a)if(a.hasOwnProperty(e)&&typeof a[e]==`object`&&a[e].tasks)try{ii(a[e],{description:`Tasks for ${e} context`,skipUpdate:!0})}catch(t){i&&console.log(`Failed to ensure metadata for tag ${e}: ${t.message}`)}let o=JSON.parse(JSON.stringify(a));for(let e in o)o[e]&&Array.isArray(o[e].tasks)&&W(o[e].tasks);if(n)try{e(n,t)}catch{}try{let e=`master`;try{if(r)e=r;else if(n)e=ti({projectRoot:n});else{let n=V(c.dirname(t));n&&(e=ti({projectRoot:n}))}}catch(e){i&&console.log(`Tag resolution failed, using master: ${e.message}`)}i&&console.log(`Resolved tag: ${e}`);let s=a[e];if(s&&s.tasks){W(s.tasks);let t={...s,tag:e,_rawTaggedData:o};return i&&console.log(`Returning data for tag '${e}' with ${s.tasks.length} tasks`),t}else{let t=a.master;return t&&t.tasks?(W(t.tasks),i&&console.log(`Tag '${e}' not found, falling back to master with ${t.tasks.length} tasks`),{...t,tag:`master`,_rawTaggedData:o}):(i&&console.log(`No valid tag data found, returning empty structure`),{tasks:[],tag:`master`,_rawTaggedData:o})}}catch(e){i&&console.log(`Error during tag resolution: ${e.message}`);let t=a.master;return t&&t.tasks?(W(t.tasks),{...t,_rawTaggedData:o}):{tasks:[],_rawTaggedData:o}}}return i&&console.log(`File format not recognized, returning as-is`),a}function Rr(e){try{let t=V(c.dirname(e))||c.dirname(e),n=c.join(t,`.taskmaster`,`config.json`);s.existsSync(n)&&zr(n);let r=c.join(t,`.taskmaster`,`state.json`);s.existsSync(r)||Br(r),$()&&U(`debug`,`Complete tag migration performed for project: ${t}`)}catch(e){$()&&U(`warn`,`Error during complete tag migration: ${e.message}`)}}function zr(e){try{let t=s.readFileSync(e,`utf8`),n=JSON.parse(t);if(!n)return;let r=!1;n.global||={},n.global.defaultTag||(n.global.defaultTag=`master`,r=!0),r&&(s.writeFileSync(e,JSON.stringify(n,null,2),`utf8`),process.env.TASKMASTER_DEBUG===`true`&&console.log(`[DEBUG] Updated config.json with tagged task system settings`))}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error migrating config.json: ${e.message}`)}}function Br(e){try{let t={currentTag:`master`,lastSwitched:new Date().toISOString(),branchTagMapping:{},migrationNoticeShown:!1};s.writeFileSync(e,JSON.stringify(t,null,2),`utf8`),process.env.TASKMASTER_DEBUG===`true`&&console.log(`[DEBUG] Created initial state.json for tagged task system`)}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error creating state.json: ${e.message}`)}}function Vr(e){try{let t=c.dirname(c.dirname(e)),n=c.join(t,`.taskmaster`,`state.json`);s.existsSync(n)||Br(n);try{let e=s.readFileSync(n,`utf8`),t=JSON.parse(e)||{};t.migrationNoticeShown===void 0&&(t.migrationNoticeShown=!1,s.writeFileSync(n,JSON.stringify(t,null,2),`utf8`))}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error updating state for migration notice: ${e.message}`)}}catch(e){process.env.TASKMASTER_DEBUG===`true`&&console.warn(`[WARN] Error marking migration for notice: ${e.message}`)}}function Hr(e,t,n=null,r=null){let i=process.env.TASKMASTER_DEBUG===`true`;try{Mr(e,()=>{let a=t;if(t&&!t._rawTaggedData&&n&&Array.isArray(t.tasks)&&!Ir(t)){let o=r||ei(n);i&&console.log(`writeJSON: Detected resolved tag data missing _rawTaggedData. Re-reading raw data to prevent data loss for tag '${o}'.`);let c={};try{c=JSON.parse(s.readFileSync(e,`utf8`))}catch(e){i&&console.log(`writeJSON: Could not read existing file, starting fresh: ${e.message}`)}a={...c,[o]:{metadata:{...c[o]?.metadata||{},...t.metadata||{}},tasks:t.tasks}}}else if(t&&t._rawTaggedData&&n){let o=r||ei(n),c;try{c=JSON.parse(s.readFileSync(e,`utf8`))}catch(e){c=t._rawTaggedData,i&&console.log(`writeJSON: Using _rawTaggedData as fallback: ${e.message}`)}let{_rawTaggedData:l,tag:u,...d}=t;a={...c,[o]:d},i&&console.log(`writeJSON: Merging resolved data back into tag '${o}'`)}let o=a;if(o&&typeof o==`object`){let{_rawTaggedData:e,tag:t,...n}=o;if(o=n,typeof o==`object`&&!Array.isArray(o)){let e={};for(let[t,n]of Object.entries(o))if(n&&typeof n==`object`&&Array.isArray(n.tasks)){let{created:r,description:i,...a}=n;a.metadata||={},r&&!a.metadata.created&&(a.metadata.created=r),i&&!a.metadata.description&&(a.metadata.description=i),e[t]=a}else e[t]=n;o=e}}let c=`${e}.tmp.${process.pid}`;try{s.writeFileSync(c,JSON.stringify(o,null,2),`utf8`),s.renameSync(c,e)}catch(e){try{s.existsSync(c)&&s.unlinkSync(c)}catch{}throw e}i&&console.log(`writeJSON: Successfully wrote to ${e}`)},{createIfMissing:!0})}catch(t){throw U(`error`,`Error writing JSON file ${e}:`,t.message),i&&U(`error`,`Full error details:`,t),t}}function Ur(e=null){let t=!1;try{t=$()}catch{t=!1}try{let n;if(e)n=e;else{let e=c.join(process.cwd(),Sr),t=c.join(process.cwd(),`scripts/task-complexity-report.json`);n=s.existsSync(e)?e:t}if(!s.existsSync(n))return t&&U(`debug`,`Complexity report not found at ${n}`),null;let r=Lr(n);return t&&U(`debug`,`Successfully read complexity report from ${n}`),r}catch(e){return t&&U(`error`,`Error reading complexity report: ${e.message}`),null}}function Wr(e,t){return!e||!e.complexityAnalysis||!Array.isArray(e.complexityAnalysis)?null:e.complexityAnalysis.find(e=>e.taskId===t)}function Gr(e,t){let n;n=e.isSubtask?e.parentTask.id:e.parentId?e.parentId:e.id;let r=Wr(t,n);r&&(e.complexityScore=r.complexityScore)}function Kr(e,t){if(!t||!e||!Array.isArray(e))return!1;if(typeof t==`string`&&t.includes(`.`)){let[n,r]=t.split(`.`).map(e=>parseInt(e,10)),i=e.find(e=>e.id===n);return!i||!i.subtasks?!1:i.subtasks.some(e=>e.id===r)}let n=parseInt(t,10);return e.some(e=>e.id===n)}function qr(e){return typeof e==`string`&&e.includes(`.`)?e:typeof e==`number`?e.toString():e}function Jr(e,t,n=null,r=null){if(!t||!e||!Array.isArray(e))return{task:null,originalSubtaskCount:null};if(typeof t==`string`&&t.includes(`.`)){let[r,i]=t.split(`.`).map(e=>parseInt(e,10)),a=e.find(e=>e.id===r);if(!a||!a.subtasks)return{task:null,originalSubtaskCount:null,originalSubtasks:null};let o=a.subtasks.find(e=>e.id===i);return o&&(o.parentTask={id:a.id,title:a.title,status:a.status},o.isSubtask=!0),o&&n&&Gr(o,n),{task:o||null,originalSubtaskCount:null,originalSubtasks:null}}let i=null,a=null,o=null,s=parseInt(t,10),c=e.find(e=>e.id===s)||null;if(!c)return{task:null,originalSubtaskCount:null,originalSubtasks:null};if(i=c,r&&c.subtasks&&Array.isArray(c.subtasks)){o=[...c.subtasks],a=c.subtasks.length;let e={...c};e.subtasks=c.subtasks.filter(e=>e.status&&e.status.toLowerCase()===r.toLowerCase()),i=e}return i&&n&&Gr(i,n),{task:i,originalSubtaskCount:a,originalSubtasks:o}}function Yr(e,t){return!e||e.length<=t?e:`${e.slice(0,t-3)}...`}function Xr(e){return Array.isArray(e)?e.length===0:typeof e==`object`&&e?Object.keys(e).length===0:!1}function Zr(e,t,n=new Set,r=new Set,i=[]){n.add(e),r.add(e),i.push(e);let a=[],o=t.get(e)||[];for(let e of o)if(n.has(e)){if(r.has(e)){let t=i.indexOf(e);i.slice(t),a.push(e)}}else{let o=Zr(e,t,n,r,[...i]);a.push(...o)}return r.delete(e),a}function Qr(e,t,n={}){let{maxDepth:r=50,includeSelf:i=!1,direction:a=`forward`,logger:o=null}=n,s=new Set,c=new Set;function l(e){if(typeof e==`string`){if(e.includes(`.`))return e;let t=parseInt(e,10);return isNaN(t)?e:t}return e}function u(e,n=0){if(n>=r){let t=`Maximum recursion depth (${r}) reached for task ${e}`;o&&typeof o.warn==`function`?o.warn(t):U!==void 0&&U.warn?U.warn(t):console.warn(t);return}if(c.has(e))return;c.add(e);let a=t.find(t=>t.id===e);!a||!Array.isArray(a.dependencies)||a.dependencies.forEach(t=>{let r=l(t);r==null||!i&&r===e||(s.add(r),u(r,n+1))})}function d(e,n=0){if(n>=r){let t=`Maximum recursion depth (${r}) reached for task ${e}`;o&&typeof o.warn==`function`?o.warn(t):U!==void 0&&U.warn?U.warn(t):console.warn(t);return}c.has(e)||(c.add(e),t.forEach(t=>{if(t.dependencies&&Array.isArray(t.dependencies)&&t.dependencies.some(t=>l(t)===e)){if(t.id==null||!i&&t.id===e)return;s.add(t.id),d(t.id,n+1)}}))}let f=a===`reverse`?d:u;return e.forEach(e=>{e&&e.id&&f(e.id)}),Array.from(s)}function $r(e,t){if(!e||e.length===0)return null;let n={timestamp:new Date().toISOString(),userId:e[0].userId,commandName:t,modelUsed:`Multiple`,providerName:`Multiple`,inputTokens:0,outputTokens:0,totalTokens:0,totalCost:0,currency:e[0].currency||`USD`},r=new Set,i=new Set,a=new Set;return e.forEach(e=>{n.inputTokens+=e.inputTokens||0,n.outputTokens+=e.outputTokens||0,n.totalCost+=e.totalCost||0,r.add(e.modelUsed),i.add(e.providerName),a.add(e.currency||`USD`)}),n.totalTokens=n.inputTokens+n.outputTokens,n.totalCost=parseFloat(n.totalCost.toFixed(6)),r.size===1&&(n.modelUsed=[...r][0]),i.size===1&&(n.providerName=[...i][0]),a.size>1?n.currency=`Multiple`:a.size===1&&(n.currency=[...a][0]),n}function ei(e){if(!e)throw Error(`projectRoot is required for getCurrentTag`);try{let t=c.join(e,`.taskmaster`,`state.json`);if(s.existsSync(t)){let e=s.readFileSync(t,`utf8`),n=JSON.parse(e);if(n&&n.currentTag)return n.currentTag}}catch{}try{let t=c.join(e,`.taskmaster`,`config.json`);if(s.existsSync(t)){let e=s.readFileSync(t,`utf8`),n=JSON.parse(e);if(n&&n.global&&n.global.defaultTag)return n.global.defaultTag}}catch{}return`master`}function ti(e={}){let{projectRoot:t,tag:n}=e;if(!t)throw Error(`projectRoot is required for resolveTag`);return n||ei(t)}function ni(e,t){return!e||!t?[]:e[t]&&e[t].tasks&&Array.isArray(e[t].tasks)?e[t].tasks:[]}function ri(e){let t=[];for(let n of e)if(t.push({...n,searchableId:n.id.toString(),isSubtask:!1}),n.subtasks&&n.subtasks.length>0)for(let e of n.subtasks)t.push({...e,searchableId:`${n.id}.${e.id}`,isSubtask:!0,parentId:n.id,parentTitle:n.title,title:`${e.title} (subtask of: ${n.title})`,description:`${e.description} [Parent: ${n.description}]`});return t}function ii(e,t={}){if(!e||typeof e!=`object`)throw Error(`tagObj must be a valid object`);let n=new Date().toISOString();return e.metadata?(e.metadata.created||(e.metadata.created=n),t.skipUpdate||(e.metadata.updated=n),t.description&&!e.metadata.description&&(e.metadata.description=t.description)):e.metadata={created:n,updated:n,...t.description?{description:t.description}:{}},e}function ai(){return{info:(e,...t)=>U(`info`,e,...t),warn:(e,...t)=>U(`warn`,e,...t),error:(e,...t)=>U(`error`,e,...t),debug:(e,...t)=>U(`debug`,e,...t),success:(e,...t)=>U(`success`,e,...t)}}function G(e=null){return e||ai()}function K(e){return Ln(e)}function q(e=process.cwd()){return In(e)}function oi(e=null,t=null,n=null){let r=G(n),i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i);if(e){let t=c.isAbsolute(e)?e:c.resolve(a,e);if(s.existsSync(t))return r.info?.(`Using explicit tasks path: ${t}`),t;r.warn?.(`Explicit tasks path not found: ${t}, trying fallbacks`)}let o=[c.join(a,Tr),c.join(a,Er)];for(let e of o)if(s.existsSync(e))return r.info?.(`Found tasks file at: ${e}`),e.includes(`tasks/tasks.json`)&&!e.includes(`.taskmaster`)?r.warn?.(`⚠️ DEPRECATION WARNING: Found tasks.json in legacy location '${e}'. Please migrate to the new .taskmaster directory structure. Run 'task-master migrate' to automatically migrate your project.`):e.endsWith(`tasks.json`)&&!e.includes(`.taskmaster`)&&!e.includes(`tasks/`)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found tasks.json in legacy root location '${e}'. Please migrate to the new .taskmaster directory structure. Run 'task-master migrate' to automatically migrate your project.`),e;return r.warn?.(`No tasks.json found in project: ${a}`),null}function si(e=null,t=null,n=null){let r=G(n);if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);if(s.existsSync(n))return r.info?.(`Using explicit PRD path: ${n}`),n;r.warn?.(`Explicit PRD path not found: ${n}, trying fallbacks`)}let i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i),o=[_r,`scripts/`,``],l=[`PRD.md`,`prd.md`,`PRD.txt`,`prd.txt`];for(let e of o)for(let t of l){let n=c.join(a,e,t);if(s.existsSync(n))return r.info?.(`Found PRD document at: ${n}`),(e===`scripts/`||e===``)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found PRD file in legacy location '${n}'. Please migrate to .taskmaster/docs/ directory. Run 'task-master migrate' to automatically migrate your project.`),n}return r.warn?.(`No PRD document found in project: ${a}`),null}function ci(e=null,t=null,n=null){let r=G(n);if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);if(s.existsSync(n))return r.info?.(`Using explicit complexity report path: ${n}`),n;r.warn?.(`Explicit complexity report path not found: ${n}, trying fallbacks`)}let i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i),o=[vr,`scripts/`,``],l=[`task-complexity-report`,`task-complexity`,`complexity-report`].map(e=>t?.tag&&t?.tag!==`master`?`${e}_${t.tag}.json`:`${e}.json`);for(let e of o)for(let t of l){let n=c.join(a,e,t);if(s.existsSync(n))return r.info?.(`Found complexity report at: ${n}`),(e===`scripts/`||e===``)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found complexity report in legacy location '${n}'. Please migrate to .taskmaster/reports/ directory. Run 'task-master migrate' to automatically migrate your project.`),n}return r.warn?.(`No complexity report found in project: ${a}`),null}function li(e=null,t=null,n=null){let r=G(n),i=t?.tag;if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);return r.info?.(`Using explicit complexity report output path: ${n}`),n}let a=K(t?.projectRoot||q()||process.cwd()),o=`task-complexity-report.json`;i&&i!==`master`&&(o=`task-complexity-report_${i}.json`);let l=c.join(a,`.taskmaster/reports`,o);r.info?.(`Using tag-aware complexity report output path: ${l}`);let u=c.dirname(l);return s.existsSync(u)||(r.info?.(`Creating reports directory: ${u}`),s.mkdirSync(u,{recursive:!0})),l}function ui(e=null,t=null,n=null){let r=G(n);if(e){let t=process.env.TASKMASTER_ORIGINAL_CWD||process.cwd(),n=c.isAbsolute(e)?e:c.resolve(t,e);if(s.existsSync(n))return r.info?.(`Using explicit config path: ${n}`),n;r.warn?.(`Explicit config path not found: ${n}, trying fallbacks`)}let i=t?.projectRoot||q();if(!i)return r.warn?.(`Could not determine project root directory`),null;let a=K(i),o=[c.join(a,br),c.join(a,z)];for(let e of o)if(s.existsSync(e))return e?.endsWith(z)&&r.warn?.(`⚠️ DEPRECATION WARNING: Found configuration in legacy location '${e}'. Please migrate to .taskmaster/config.json. Run 'task-master migrate' to automatically migrate your project.`),e;if(!(hi()||t?.storageType===`api`)){let e=`config_warning_${a}`;global._tmConfigWarningsThisRun||(global._tmConfigWarningsThisRun=new Set),global._tmConfigWarningsThisRun.has(e)||(global._tmConfigWarningsThisRun.add(e),r.warn?.(`No configuration file found in project: ${a}`))}return null}var J={anthropic:[{id:`claude-sonnet-4-20250514`,swe_score:.727,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:64e3,supported:!0},{id:`claude-opus-4-20250514`,swe_score:.725,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`],max_tokens:32e3,supported:!0},{id:`claude-3-7-sonnet-20250219`,swe_score:.623,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:12e4,supported:!0},{id:`claude-3-5-sonnet-20241022`,swe_score:.49,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:8192,supported:!0},{id:`claude-sonnet-4-5`,name:`Claude Sonnet 4.5`,swe_score:.772,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`],max_tokens:64e3,supported:!0},{id:`claude-haiku-4-5`,name:`Claude Haiku 4.5`,swe_score:.733,cost_per_1m_tokens:{input:1,output:5},allowed_roles:[`main`,`fallback`],max_tokens:2e5,supported:!0},{id:`claude-opus-4-1`,name:`Claude Opus 4.1`,swe_score:.745,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`],max_tokens:32e3,supported:!0},{id:`claude-opus-4-5`,name:`Claude Opus 4.5`,swe_score:.809,cost_per_1m_tokens:{input:5,output:25},allowed_roles:[`main`,`fallback`],max_tokens:32e3,supported:!0}],"claude-code":[{id:`opus`,swe_score:.725,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32e3,supported:!0},{id:`sonnet`,swe_score:.727,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:64e3,supported:!0},{id:`haiku`,swe_score:.45,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:2e5,supported:!0}],"codex-cli":[{id:`gpt-5.3-codex`,name:`GPT-5.3 Codex`,swe_score:.84,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.2-codex`,name:`GPT-5.2 Codex`,swe_score:.82,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.1-codex-max`,name:`GPT-5.1 Codex Max`,swe_score:.78,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.1-codex-mini`,name:`GPT-5.1 Codex Mini`,swe_score:.72,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`],supported:!0},{id:`gpt-5.2`,name:`GPT-5.2`,swe_score:.8,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0}],mcp:[{id:`mcp-sampling`,swe_score:null,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:1e5,supported:!0}],"gemini-cli":[{id:`gemini-3-flash-preview`,name:`Gemini 3 Flash`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:1048576,supported:!0},{id:`gemini-3-pro-preview`,swe_score:.762,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0},{id:`gemini-2.5-pro`,swe_score:.72,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0},{id:`gemini-2.5-flash`,swe_score:.71,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0}],"grok-cli":[{id:`grok-4-latest`,name:`Grok 4 Latest`,swe_score:.7,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-latest`,name:`Grok 3 Latest`,swe_score:.65,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-fast`,name:`Grok 3 Fast`,swe_score:.6,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-mini-fast`,name:`Grok 3 Mini Fast`,swe_score:.55,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0}],openai:[{id:`gpt-4o`,swe_score:.332,cost_per_1m_tokens:{input:2.5,output:10},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`o1`,swe_score:.489,cost_per_1m_tokens:{input:15,output:60},allowed_roles:[`main`],supported:!0},{id:`o3`,swe_score:.5,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`o3-mini`,swe_score:.493,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`],max_tokens:1e5,supported:!0},{id:`o4-mini`,swe_score:.45,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],supported:!0},{id:`o1-mini`,swe_score:.4,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`],supported:!0},{id:`o1-pro`,swe_score:0,cost_per_1m_tokens:{input:150,output:600},allowed_roles:[`main`],supported:!0},{id:`gpt-4-5-preview`,swe_score:.38,cost_per_1m_tokens:{input:75,output:150},allowed_roles:[`main`],supported:!0},{id:`gpt-4-1-mini`,swe_score:0,cost_per_1m_tokens:{input:.4,output:1.6},allowed_roles:[`main`],supported:!0},{id:`gpt-4-1-nano`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.4},allowed_roles:[`main`],supported:!0},{id:`gpt-4o-mini`,swe_score:.3,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`],supported:!0},{id:`gpt-4o-search-preview`,swe_score:.33,cost_per_1m_tokens:{input:2.5,output:10},allowed_roles:[`research`],supported:!0},{id:`gpt-4o-mini-search-preview`,swe_score:.3,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`research`],supported:!0},{id:`gpt-5`,swe_score:.749,cost_per_1m_tokens:{input:5,output:20},allowed_roles:[`main`,`fallback`],max_tokens:1e5,temperature:1,supported:!0},{id:`gpt-5.1`,swe_score:.76,cost_per_1m_tokens:{input:1.25,output:10},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`],supported:!0},{id:`gpt-5.1-codex-max`,swe_score:.78,cost_per_1m_tokens:{input:1.25,output:10},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.2`,swe_score:.8,cost_per_1m_tokens:{input:1.75,output:14},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0},{id:`gpt-5.2-pro`,swe_score:.82,cost_per_1m_tokens:{input:21,output:168},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`medium`,`high`,`xhigh`],supported:!0}],google:[{id:`gemini-3-flash-preview`,name:`Gemini 3 Flash`,swe_score:0,cost_per_1m_tokens:{input:.5,output:3},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`gemini-3-pro-preview`,swe_score:.762,cost_per_1m_tokens:{input:2,output:12},allowed_roles:[`main`,`fallback`,`research`],max_tokens:1e6,supported:!0},{id:`gemini-2.5-pro-preview-05-06`,swe_score:.638,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.5-pro-preview-03-25`,swe_score:.638,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.5-flash-preview-04-17`,swe_score:.604,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.0-flash`,swe_score:.518,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0},{id:`gemini-2.0-flash-lite`,swe_score:0,cost_per_1m_tokens:null,allowed_roles:[`main`,`fallback`],max_tokens:1048e3,supported:!0}],xai:[{id:`grok-3`,name:`Grok 3`,swe_score:null,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-3-fast`,name:`Grok 3 Fast`,swe_score:0,cost_per_1m_tokens:{input:5,output:25},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`grok-4`,name:`Grok 4`,swe_score:null,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0}],groq:[{id:`moonshotai/kimi-k2-instruct`,swe_score:.66,cost_per_1m_tokens:{input:1,output:3},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`llama-3.3-70b-versatile`,swe_score:.55,cost_per_1m_tokens:{input:.59,output:.79},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`llama-3.1-8b-instant`,swe_score:.32,cost_per_1m_tokens:{input:.05,output:.08},allowed_roles:[`main`,`fallback`],max_tokens:131072,supported:!0},{id:`llama-4-scout`,swe_score:.45,cost_per_1m_tokens:{input:.11,output:.34},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`llama-4-maverick`,swe_score:.52,cost_per_1m_tokens:{input:.5,output:.77},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`mixtral-8x7b-32768`,swe_score:.35,cost_per_1m_tokens:{input:.24,output:.24},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!0},{id:`qwen-qwq-32b-preview`,swe_score:.4,cost_per_1m_tokens:{input:.18,output:.18},allowed_roles:[`main`,`fallback`,`research`],max_tokens:32768,supported:!0},{id:`deepseek-r1-distill-llama-70b`,swe_score:.52,cost_per_1m_tokens:{input:.75,output:.99},allowed_roles:[`main`,`research`],max_tokens:8192,supported:!0},{id:`gemma2-9b-it`,swe_score:.3,cost_per_1m_tokens:{input:.2,output:.2},allowed_roles:[`main`,`fallback`],max_tokens:8192,supported:!0},{id:`whisper-large-v3`,swe_score:0,cost_per_1m_tokens:{input:.11,output:0},allowed_roles:[`main`],max_tokens:0,supported:!0}],perplexity:[{id:`sonar-pro`,swe_score:0,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`research`],max_tokens:8700,supported:!0},{id:`sonar`,swe_score:0,cost_per_1m_tokens:{input:1,output:1},allowed_roles:[`research`],max_tokens:8700,supported:!0},{id:`sonar-deep-research`,swe_score:.211,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`research`],max_tokens:8700,supported:!0},{id:`sonar-reasoning-pro`,swe_score:.211,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`research`,`fallback`],max_tokens:8700,supported:!0},{id:`sonar-reasoning`,swe_score:.211,cost_per_1m_tokens:{input:1,output:5},allowed_roles:[`main`,`research`,`fallback`],max_tokens:8700,supported:!0}],openrouter:[{id:`google/gemini-2.5-flash-preview-05-20`,swe_score:0,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`google/gemini-2.5-flash-preview-05-20:thinking`,swe_score:0,cost_per_1m_tokens:{input:.15,output:3.5},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`google/gemini-2.5-pro-exp-03-25`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`deepseek/deepseek-chat-v3-0324:free`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:163840,supported:!1,reason:`Free OpenRouter models are not supported due to severe rate limits, lack of tool use support, and other reliability issues that make them impractical for production use.`},{id:`deepseek/deepseek-chat-v3-0324`,swe_score:0,cost_per_1m_tokens:{input:.27,output:1.1},allowed_roles:[`main`],max_tokens:64e3,supported:!0},{id:`openai/gpt-4.1`,swe_score:0,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`openai/gpt-4.1-mini`,swe_score:0,cost_per_1m_tokens:{input:.4,output:1.6},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`openai/gpt-4.1-nano`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.4},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`openai/o3`,swe_score:0,cost_per_1m_tokens:{input:10,output:40},allowed_roles:[`main`,`fallback`],max_tokens:2e5,supported:!0},{id:`openai/codex-mini`,swe_score:0,cost_per_1m_tokens:{input:1.5,output:6},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/gpt-4o-mini`,swe_score:0,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/o4-mini`,swe_score:.45,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/o4-mini-high`,swe_score:0,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`openai/o1-pro`,swe_score:0,cost_per_1m_tokens:{input:150,output:600},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`meta-llama/llama-3.3-70b-instruct`,swe_score:0,cost_per_1m_tokens:{input:120,output:600},allowed_roles:[`main`,`fallback`],max_tokens:1048576,supported:!0},{id:`meta-llama/llama-4-maverick`,swe_score:0,cost_per_1m_tokens:{input:.18,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`meta-llama/llama-4-scout`,swe_score:0,cost_per_1m_tokens:{input:.08,output:.3},allowed_roles:[`main`,`fallback`],max_tokens:1e6,supported:!0},{id:`qwen/qwen-max`,swe_score:0,cost_per_1m_tokens:{input:1.6,output:6.4},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!0},{id:`qwen/qwen-turbo`,swe_score:0,cost_per_1m_tokens:{input:.05,output:.2},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!0},{id:`qwen/qwen3-235b-a22b`,swe_score:0,cost_per_1m_tokens:{input:.14,output:2},allowed_roles:[`main`,`fallback`],max_tokens:24e3,supported:!0},{id:`mistralai/mistral-small-3.1-24b-instruct:free`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:96e3,supported:!1,reason:`Free OpenRouter models are not supported due to severe rate limits, lack of tool use support, and other reliability issues that make them impractical for production use.`},{id:`mistralai/mistral-small-3.1-24b-instruct`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.3},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`mistralai/devstral-small`,swe_score:0,cost_per_1m_tokens:{input:.1,output:.3},allowed_roles:[`main`],max_tokens:11e4,supported:!0},{id:`mistralai/mistral-nemo`,swe_score:0,cost_per_1m_tokens:{input:.03,output:.07},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0},{id:`thudm/glm-4-32b:free`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:32768,supported:!1,reason:`Free OpenRouter models are not supported due to severe rate limits, lack of tool use support, and other reliability issues that make them impractical for production use.`}],zai:[{id:`glm-4.6`,swe_score:.68,cost_per_1m_tokens:{input:.6,output:2.2},allowed_roles:[`main`,`fallback`,`research`],max_tokens:204800,supported:!0},{id:`glm-4.5`,swe_score:.65,cost_per_1m_tokens:{input:.6,output:2.2},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`glm-4.5-air`,swe_score:.62,cost_per_1m_tokens:{input:.2,output:1.1},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0}],"zai-coding":[{id:`glm-4.6`,swe_score:.68,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:204800,supported:!0},{id:`glm-4.5`,swe_score:.65,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0},{id:`glm-4.5-air`,swe_score:.62,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`,`research`],max_tokens:131072,supported:!0}],ollama:[{id:`gpt-oss:latest`,swe_score:.607,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`gpt-oss:20b`,swe_score:.607,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`gpt-oss:120b`,swe_score:.624,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],max_tokens:128e3,supported:!0},{id:`devstral:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`qwen3:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`qwen3:14b`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`qwen3:32b`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`mistral-small3.1:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`llama3.3:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0},{id:`phi4:latest`,swe_score:0,cost_per_1m_tokens:{input:0,output:0},allowed_roles:[`main`,`fallback`],supported:!0}],azure:[{id:`gpt-4o`,swe_score:.332,cost_per_1m_tokens:{input:2.5,output:10},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`gpt-4o-mini`,swe_score:.3,cost_per_1m_tokens:{input:.15,output:.6},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`gpt-4-1`,swe_score:0,cost_per_1m_tokens:{input:2,output:10},allowed_roles:[`main`,`fallback`],max_tokens:16384,supported:!0},{id:`gpt-5`,name:`GPT-5`,swe_score:.749,cost_per_1m_tokens:{input:5,output:20},allowed_roles:[`main`,`fallback`],max_tokens:1e5,temperature:1,supported:!0,api_type:`responses`},{id:`o1`,name:`o1`,swe_score:.489,cost_per_1m_tokens:{input:15,output:60},allowed_roles:[`main`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`o3`,name:`o3`,swe_score:.5,cost_per_1m_tokens:{input:2,output:8},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`o3-mini`,name:`o3-mini`,swe_score:.493,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`o4-mini`,name:`o4-mini`,swe_score:.45,cost_per_1m_tokens:{input:1.1,output:4.4},allowed_roles:[`main`,`fallback`],max_tokens:1e5,supported:!0,api_type:`responses`},{id:`gpt-5.1`,name:`GPT-5.1`,swe_score:.76,cost_per_1m_tokens:{input:1.25,output:10},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`],supported:!0,api_type:`responses`},{id:`gpt-5.2`,name:`GPT-5.2`,swe_score:.8,cost_per_1m_tokens:{input:1.75,output:14},allowed_roles:[`main`,`fallback`],max_tokens:128e3,reasoning_efforts:[`none`,`low`,`medium`,`high`,`xhigh`],supported:!0,api_type:`responses`}],bedrock:[{id:`us.anthropic.claude-3-haiku-20240307-v1:0`,swe_score:.4,cost_per_1m_tokens:{input:.25,output:1.25},allowed_roles:[`main`,`fallback`],supported:!0},{id:`us.anthropic.claude-3-opus-20240229-v1:0`,swe_score:.725,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-3-5-sonnet-20240620-v1:0`,swe_score:.49,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-3-5-sonnet-20241022-v2:0`,swe_score:.49,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-3-7-sonnet-20250219-v1:0`,swe_score:.623,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],max_tokens:65536,supported:!0},{id:`us.anthropic.claude-3-5-haiku-20241022-v1:0`,swe_score:.4,cost_per_1m_tokens:{input:.8,output:4},allowed_roles:[`main`,`fallback`],supported:!0},{id:`us.anthropic.claude-opus-4-20250514-v1:0`,swe_score:.725,cost_per_1m_tokens:{input:15,output:75},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.anthropic.claude-sonnet-4-20250514-v1:0`,swe_score:.727,cost_per_1m_tokens:{input:3,output:15},allowed_roles:[`main`,`fallback`,`research`],supported:!0},{id:`us.deepseek.r1-v1:0`,swe_score:0,cost_per_1m_tokens:{input:1.35,output:5.4},allowed_roles:[`research`],max_tokens:65536,supported:!0}]};const di=ve(import.meta.url);c.dirname(di);const Y={models:{main:{provider:`codex-cli`,modelId:`gpt-5.3-codex`,maxTokens:32e3,temperature:.2},research:{provider:`codex-cli`,modelId:`gpt-5.3-codex`,maxTokens:32e3,temperature:.1},fallback:{provider:`codex-cli`,modelId:`gpt-5.3-codex`,maxTokens:32e3,temperature:.2}},global:{logLevel:`info`,debug:!1,defaultNumTasks:10,defaultSubtasks:5,defaultPriority:`medium`,projectName:`Task Master`,ollamaBaseURL:`http://localhost:11434/api`,bedrockBaseURL:`https://bedrock.us-east-1.amazonaws.com`,responseLanguage:`Chinese`,enableCodebaseAnalysis:!0,enableProxy:!1,anonymousTelemetry:!0},claudeCode:{},codexCli:{approvalMode:`never`,sandboxMode:`danger-full-access`,fullAuto:!0,skipGitRepoCheck:!0,reasoningEffort:`xhigh`},grokCli:{timeout:12e4,workingDirectory:null,defaultModel:`grok-4-latest`}};let fi=null,pi=null;function mi(e){global._tmSuppressConfigWarnings=e}function hi(){return global._tmSuppressConfigWarnings===!0}var gi=class extends Error{constructor(e){super(e),this.name=`ConfigurationError`}};function _i(e=null,t={}){let n=Y,r=e,{storageType:a}=t;e&&`${e}`,r||(r=V(),r||=process.cwd(),`${r}`);let o=null,l={...n};if((s.existsSync(c.join(r,hr))||s.existsSync(c.join(r,z)))&&(o=ui(null,{projectRoot:r,storageType:a})),o){let e=o.endsWith(z);try{let t=s.readFileSync(o,`utf-8`),r=JSON.parse(t);l={models:{main:{...n.models.main,...r?.models?.main},research:{...n.models.research,...r?.models?.research},fallback:r?.models?.fallback?.provider&&r?.models?.fallback?.modelId?{...n.models.fallback,...r.models.fallback}:{...n.models.fallback}},global:{...n.global,...r?.global},claudeCode:{...n.claudeCode,...r?.claudeCode},codexCli:{...n.codexCli,...r?.codexCli},grokCli:{...n.grokCli,...r?.grokCli}},`${o}`,e&&console.warn(i.yellow(`⚠️ DEPRECATION WARNING: Found configuration in legacy location '${o}'. Please migrate to .taskmaster/config.json. Run 'task-master migrate' to automatically migrate your project.`)),vi(l.models.main.provider)||(console.warn(i.yellow(`Warning: Invalid main provider "${l.models.main.provider}" in ${o}. Falling back to default.`)),l.models.main={...n.models.main}),vi(l.models.research.provider)||(console.warn(i.yellow(`Warning: Invalid research provider "${l.models.research.provider}" in ${o}. Falling back to default.`)),l.models.research={...n.models.research}),l.models.fallback?.provider&&!vi(l.models.fallback.provider)&&(console.warn(i.yellow(`Warning: Invalid fallback provider "${l.models.fallback.provider}" in ${o}. Fallback model configuration will be ignored.`)),l.models.fallback.provider=void 0,l.models.fallback.modelId=void 0),l.claudeCode&&!Xr(l.claudeCode)&&(l.claudeCode=bi(l.claudeCode)),l.codexCli&&!Xr(l.codexCli)&&(l.codexCli=xi(l.codexCli))}catch(e){console.error(i.red(`Error reading or parsing ${o}: ${e.message}. Using default configuration.`)),l={...n},`${o}`}}else{if(!hi()&&a!==`api`)if(e)console.warn(i.yellow(`Warning: Configuration file not found at provided project root (${e}). Using default configuration. Run 'task-master models --setup' to configure.`));else{let e=s.existsSync(c.join(r,hr)),t=s.existsSync(c.join(r,z));(e||t)&&console.warn(i.yellow(`Warning: Configuration file not found at derived root (${r}). Using defaults.`))}l={...n},`${r}`}return l}function X(e=null,t=!1,n={}){if(!fi||t||e&&e!==pi){let r=_i(e,n);return(t||e)&&(fi=r,pi=e),r}return fi}function vi(e){return Be.includes(e)?!0:ze.includes(e)?!!(J&&J[e]):!1}function yi(e){return J[e]?J[e].filter(e=>e.supported!==!1).map(e=>e.id):[]}function bi(e){let t=v.object({pathToClaudeCodeExecutable:v.string().optional(),maxTurns:v.number().int().positive().optional(),customSystemPrompt:v.string().optional(),appendSystemPrompt:v.string().optional(),permissionMode:v.enum([`default`,`acceptEdits`,`plan`,`bypassPermissions`]).optional(),allowedTools:v.array(v.string()).optional(),disallowedTools:v.array(v.string()).optional(),mcpServers:v.record(v.string(),v.object({type:v.enum([`stdio`,`sse`]).optional(),command:v.string(),args:v.array(v.string()).optional(),env:v.record(v.string(),v.string()).optional(),url:v.url().optional(),headers:v.record(v.string(),v.string()).optional()})).optional()}),n=v.record(v.string(),t).refine(e=>Object.keys(e||{}).every(e=>mr.includes(e)),{message:`Invalid command name in commandSpecific`}),r=t.extend({commandSpecific:n.optional()}),a={};try{a=r.parse(e)}catch(e){console.warn(i.yellow(`Warning: Invalid Claude Code settings in config: ${e.message}. Falling back to default.`)),a={}}return a}function xi(e){let t=v.object({codexPath:v.string().optional(),cwd:v.string().optional(),approvalMode:v.enum([`untrusted`,`on-failure`,`on-request`,`never`]).optional(),sandboxMode:v.enum([`read-only`,`workspace-write`,`danger-full-access`]).optional(),fullAuto:v.boolean().optional(),dangerouslyBypassApprovalsAndSandbox:v.boolean().optional(),skipGitRepoCheck:v.boolean().optional(),color:v.enum([`always`,`never`,`auto`]).optional(),allowNpx:v.boolean().optional(),outputLastMessageFile:v.string().optional(),env:v.record(v.string(),v.string()).optional(),verbose:v.boolean().optional(),logger:v.union([v.object({}).passthrough(),v.literal(!1)]).optional(),reasoningEffort:v.enum([`none`,`minimal`,`low`,`medium`,`high`,`xhigh`]).optional()}),n=v.record(v.string(),t).refine(e=>Object.keys(e||{}).every(e=>mr.includes(e)),{message:`Invalid command name in commandSpecific`}),r=t.extend({commandSpecific:n.optional()});try{return r.parse(e)}catch(e){return console.warn(i.yellow(`Warning: Invalid Codex CLI settings in config: ${e.message}. Falling back to default.`)),{}}}function Si(e=null,t=!1){let n=X(e,t);return{...Y.claudeCode,...n?.claudeCode||{}}}function Ci(e=null,t=!1){let n=X(e,t);return{...Y.codexCli,...n?.codexCli||{}}}function wi(e,t=null,n=!1){let r=Ci(t,n),i=r?.commandSpecific||{};return{...r,...i[e]}}function Ti(e,t=null,n=!1){let r=Si(t,n),i=r?.commandSpecific||{};return{...r,...i[e]}}function Ei(e=null,t=!1){let n=X(e,t);return{...Y.grokCli,...n?.grokCli||{}}}function Di(e,t=null,n=!1){let r=Ei(t,n),i=r?.commandSpecific||{};return{...r,...i[e]}}function Z(e,t=null){return X(t)?.models?.[e]||(U(`warn`,`No model configuration found for role: ${e}. Returning default.`),Y.models[e]||{})}function Oi(e=null){return Z(`main`,e).provider}function ki(e=null){return Z(`main`,e).modelId}function Ai(e=null){return Z(`research`,e).provider}function ji(e=null,t=null){let n=B(`TASKMASTER_ENABLE_CODEBASE_ANALYSIS`,e,t);if(n!=null&&n!==``)return n.toLowerCase()===`true`||n===`1`;if(e?.env?.TASKMASTER_ENABLE_CODEBASE_ANALYSIS){let t=e.env.TASKMASTER_ENABLE_CODEBASE_ANALYSIS;return t.toLowerCase()===`true`||t===`1`}return Q(t).enableCodebaseAnalysis!==!1}function Mi(e=!1,t=null,n=null){if(!ji(n,t))return!1;let r=e?Ai(t):Oi(t);return r===E.CLAUDE_CODE||r===E.GEMINI_CLI||r===E.GROK_CLI||r===E.CODEX_CLI}function Ni(e=null){return Z(`research`,e).modelId}function Pi(e=null){return Z(`fallback`,e).provider}function Fi(e=null){return Z(`fallback`,e).modelId}function Q(e=null){let t=X(e);return{...Y.global,...t?.global||{}}}function Ii(e=null){return Q(e).logLevel.toLowerCase()}function $(e=null){return Q(e).debug===!0}function Li(e=null){let t=Q(e).defaultSubtasks,n=parseInt(t,10);return Number.isNaN(n)?Y.global.defaultSubtasks:n}function Ri(e=null){let t=Q(e).defaultNumTasks,n=parseInt(t,10);return Number.isNaN(n)?Y.global.defaultNumTasks:n}function zi(e=null){return Q(e).defaultPriority}function Bi(e=null){return Q(e).projectName}function Vi(e=null){return Q(e).ollamaBaseURL}function Hi(e=null){return Q(e).azureBaseURL}function Ui(e=null){return Q(e).bedrockBaseURL}function Wi(e=null){return Q(e).vertexProjectId}function Gi(e=null){return Q(e).vertexLocation}function Ki(e=null){return Q(e).responseLanguage}function qi(e=null){return Q(e).enableProxy===!0}function Ji(e=null){return Q(e).anonymousTelemetry!==!1}function Yi(e=null,t=null){let n=B(`TASKMASTER_ENABLE_PROXY`,e,t);if(n!=null&&n!==``)return n.toLowerCase()===`true`||n===`1`;if(e?.env?.TASKMASTER_ENABLE_PROXY){let t=e.env.TASKMASTER_ENABLE_PROXY;return t.toLowerCase()===`true`||t===`1`}return qi(t)}function Xi(e,t=null){let n=Z(e,t),r=n.maxTokens,i=n.temperature,a=n.modelId,o=n.provider,s=r,c=i;try{let e=J[o];if(e&&Array.isArray(e)){let t=e.find(e=>e.id===a);if(t&&typeof t.max_tokens==`number`&&t.max_tokens>0){let e=t.max_tokens;s=Math.min(r,e),U(`debug`,`Applying model-specific max_tokens (${e}) for ${a}. Effective limit: ${s}`)}else U(`debug`,`No valid model-specific max_tokens override found for ${a}. Using role default: ${r}`);t&&typeof t.temperature==`number`&&t.temperature>=0&&t.temperature<=1&&(c=t.temperature,U(`debug`,`Applying model-specific temperature (${t.temperature}) for ${a}`))}else o===E.OPENROUTER?(s=Math.min(r,32768),U(`debug`,`Custom OpenRouter model ${a} detected. Using conservative max_tokens: ${s}`)):U(`debug`,`No model definitions found for provider ${o} in MODEL_MAP. Using role default maxTokens: ${r}`)}catch(e){U(`warn`,`Error looking up model-specific parameters for ${a}: ${e.message}. Using role defaults.`),s=r,c=i}return{maxTokens:s,temperature:c}}function Zi(e,t=null,n=null){if([E.OLLAMA,E.BEDROCK,E.GEMINI_CLI,E.GROK_CLI,E.MCP,E.CODEX_CLI].includes(e?.toLowerCase())||e?.toLowerCase()===`claude-code`||e?.toLowerCase()===`codex-cli`)return!0;let r={openai:`OPENAI_API_KEY`,anthropic:`ANTHROPIC_API_KEY`,google:`GOOGLE_API_KEY`,perplexity:`PERPLEXITY_API_KEY`,mistral:`MISTRAL_API_KEY`,azure:`AZURE_OPENAI_API_KEY`,openrouter:`OPENROUTER_API_KEY`,xai:`XAI_API_KEY`,zai:`ZAI_API_KEY`,"zai-coding":`ZAI_API_KEY`,groq:`GROQ_API_KEY`,vertex:`GOOGLE_API_KEY`,"claude-code":`CLAUDE_CODE_API_KEY`,bedrock:`AWS_ACCESS_KEY_ID`},i=e?.toLowerCase();if(!i||!r[i])return U(`warn`,`Unknown provider name: ${e} in isApiKeySet check.`),!1;let a=r[i],o=B(a,t,n);return o&&o.trim()!==``&&!/YOUR_.*_API_KEY_HERE/.test(o)&&!o.includes(`KEY_HERE`)}function Qi(e,t=null){let n=t||V();if(!n)return console.warn(i.yellow(`Warning: Could not find project root to check mcp.json.`)),!1;let r=c.join(n,`.cursor`,`mcp.json`);if(!s.existsSync(r))return!1;try{let t=s.readFileSync(r,`utf-8`),n=JSON.parse(t),i=n?.mcpServers?.[`task-master-ai`]?.env||n?.mcpServers?.[`taskmaster-ai`]?.env;if(!i)return!1;let a=null;switch(e){case`anthropic`:a=i.ANTHROPIC_API_KEY;break;case`openai`:a=i.OPENAI_API_KEY;break;case`openrouter`:a=i.OPENROUTER_API_KEY;break;case`google`:a=i.GOOGLE_API_KEY;break;case`perplexity`:a=i.PERPLEXITY_API_KEY;break;case`xai`:a=i.XAI_API_KEY;break;case`zai`:case`zai-coding`:a=i.ZAI_API_KEY;break;case`groq`:a=i.GROQ_API_KEY;break;case`ollama`:return!0;case`claude-code`:return!0;case`codex-cli`:return!0;case`mistral`:a=i.MISTRAL_API_KEY;break;case`azure`:a=i.AZURE_OPENAI_API_KEY;break;case`vertex`:a=i.GOOGLE_API_KEY;break;case`bedrock`:a=i.AWS_ACCESS_KEY_ID;break;default:return!1}return!!a&&!/KEY_HERE$/.test(a)}catch(e){return console.error(i.red(`Error reading or parsing .cursor/mcp.json: ${e.message}`)),!1}}function $i(){let e=[];for(let[t,n]of Object.entries(J))n.length>0?n.filter(e=>!!e.supported).forEach(n=>{let r=n.id,i=n.swe_score,a=n.cost_per_1m_tokens,o=n.allowed_roles||[`main`,`fallback`],s=n.name;s||(s=r.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `),r===`claude-3.5-sonnet-20240620`&&(s=`Claude 3.5 Sonnet`),r===`claude-3-7-sonnet-20250219`&&(s=`Claude 3.7 Sonnet`),r===`gpt-4o`&&(s=`GPT-4o`),r===`gpt-4-turbo`&&(s=`GPT-4 Turbo`),r===`sonar-pro`&&(s=`Perplexity Sonar Pro`),r===`sonar-mini`&&(s=`Perplexity Sonar Mini`)),e.push({id:r,name:s,provider:t,swe_score:i,cost_per_1m_tokens:a,allowed_roles:o,max_tokens:n.max_tokens})}):e.push({id:`[${t}-any]`,name:`Any (${t})`,provider:t});return e}function ea(e,t=null){let n=t;if(t==null){let e=V();if(!e)return console.error(i.red(`Error: Could not determine project root. Configuration not saved.`)),!1;n=e}let r=c.join(n,`.taskmaster`),a=c.join(r,`config.json`);try{return s.existsSync(r)||s.mkdirSync(r,{recursive:!0}),s.writeFileSync(a,JSON.stringify(e,null,2)),fi=e,!0}catch(e){return console.error(i.red(`Error writing configuration to ${a}: ${e.message}`)),!1}}function ta(e=null){return ui(null,{projectRoot:e})!==null}function na(e=null){let t=X(e);return t.global||={},t.global.userId||(t.global.userId=`1234567890`,ea(t,e)||U(`warning`,`Failed to write updated configuration with new userId. Please let the developers know.`)),t.global.userId}function ra(){return Ve}function ia(e,t=null){let n=Z(e,t);if(n&&typeof n.baseURL==`string`)return n.baseURL;let r=n?.provider;if(r)return B(`${r.toUpperCase()}_BASE_URL`,null,t)}async function aa(e){if(e===`solo`||e===`team`)return e;try{mi(!0);let e=X(null,!1,{storageType:`api`});if(e?.storage?.operatingMode)return e.storage.operatingMode}catch{}finally{mi(!1)}try{if(await D.getInstance().getAuthCredentials())return`team`}catch{}return`solo`}E.OLLAMA,E.BEDROCK,E.GEMINI_CLI,E.GROK_CLI,E.MCP,E.CODEX_CLI;export{oi as $,tr as $t,Ni as A,Yr as At,ta as B,br as Bt,Oi as C,ze as Cn,Rr as Ct,Xi as D,be as Dn,ti as Dt,aa as E,C as En,B as Et,Gi as F,wr as Ft,xi as G,gr as Gt,Yi as H,_r as Ht,Wi as I,Or as It,J,pr as Jt,vi as K,Tr as Kt,Mi as L,z as Lt,Ki as M,Hr as Mt,yi as N,Sr as Nt,Bi as O,Se as On,Kr as Ot,na as P,Dr as Pt,q as Q,nr as Qt,Zi as R,Er as Rt,ki as S,Be as Sn,W as St,Vi as T,w as Tn,Lr as Tt,mi as U,vr as Ut,hi as V,hr as Vt,bi as W,xr as Wt,ui as X,sr as Xt,ci as Y,ar as Yt,si as Z,or as Zt,Fi as _,it as _n,Xr as _t,Hi as a,zn as an,Br as at,Di as b,Ve as bn,Vr as bt,Si as c,In as cn,ii as ct,wi as d,N as dn,Jr as dt,Xn as en,K as et,X as f,wt as fn,Wr as ft,Li as g,rt as gn,ni as gt,zi as h,D as hn,ei as ht,$i as i,Vn as in,$r as it,Ai as j,Mr as jt,qi as k,xe as kn,Qr as kt,Ti as l,Pn as ln,Zr as lt,Ri as m,O as mn,qr as mt,ra as n,Yn as nn,H as nt,ia as o,Bn as on,Pr as ot,$ as p,j as pn,ri as pt,ea as q,yr as qt,Ji as r,Zn as rn,Gr as rt,Ui as s,Rn as sn,Nr as st,gi as t,Qn as tn,li as tt,Ci as u,Nt as un,V as ut,Pi as v,et as vn,Fr as vt,Qi as w,je as wn,Ur as wt,Ii as x,E as xn,zr as xt,Ei as y,nt as yn,U as yt,ji as z,Cr as zt};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as e,B as t,C as n,Cn as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,P as g,R as _,S as v,T as y,U as b,V as x,W as S,_ as C,a as w,b as T,bn as E,c as D,d as O,f as k,g as A,h as j,i as M,j as N,k as P,l as F,m as I,n as L,o as R,p as z,q as B,r as V,s as H,t as U,u as W,v as G,w as K,x as q,xn as J,y as Y,z as X}from"./config-manager-
|
|
1
|
+
import{A as e,B as t,C as n,Cn as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,P as g,R as _,S as v,T as y,U as b,V as x,W as S,_ as C,a as w,b as T,bn as E,c as D,d as O,f as k,g as A,h as j,i as M,j as N,k as P,l as F,m as I,n as L,o as R,p as z,q as B,r as V,s as H,t as U,u as W,v as G,w as K,x as q,xn as J,y as Y,z as X}from"./config-manager-ClruewMP.js";import"./git-utils-DllbRE35.js";export{E as ALL_PROVIDERS,J as CUSTOM_PROVIDERS,U as ConfigurationError,u as MODEL_MAP,r as VALIDATED_PROVIDERS,L as getAllProviders,V as getAnonymousTelemetryEnabled,M as getAvailableModels,w as getAzureBaseURL,R as getBaseUrlForRole,H as getBedrockBaseURL,D as getClaudeCodeSettings,F as getClaudeCodeSettingsForCommand,W as getCodexCliSettings,O as getCodexCliSettingsForCommand,k as getConfig,z as getDebugFlag,I as getDefaultNumTasks,j as getDefaultPriority,A as getDefaultSubtasks,C as getFallbackModelId,G as getFallbackProvider,Y as getGrokCliSettings,T as getGrokCliSettingsForCommand,q as getLogLevel,v as getMainModelId,n as getMainProvider,K as getMcpApiKeyStatus,y as getOllamaBaseURL,a as getOperatingMode,i as getParametersForRole,h as getProjectName,P as getProxyEnabled,e as getResearchModelId,N as getResearchProvider,p as getResponseLanguage,m as getSupportedModelsForProvider,g as getUserId,o as getVertexLocation,l as getVertexProjectId,f as hasCodebaseAnalysis,_ as isApiKeySet,X as isCodebaseAnalysisEnabled,t as isConfigFilePresent,x as isConfigWarningSuppressed,c as isProxyEnabled,b as setSuppressConfigWarnings,S as validateClaudeCodeSettings,s as validateCodexCliSettings,d as validateProvider,B as writeConfig};
|