@hhsw2015/task-master-ai 0.43.9 → 0.43.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- 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-Dn_JApjY.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};
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-CynteFcs.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};
@@ -1,5 +1,5 @@
1
1
  import{t as e}from"./git-utils-DllbRE35.js";import t,{join as n,resolve as r}from"node:path";import i from"chalk";import{createClient as a,isAuthError as o}from"@supabase/supabase-js";import s from"fs";import c,{join as l}from"path";import u from"fs/promises";import{Writer as d}from"steno";import f from"crypto";import p from"os";import m,{appendFile as h,mkdir as ee,readFile as te}from"node:fs/promises";import ne from"fs-extra";import{simpleGit as re}from"simple-git";import ie,{constants as ae,existsSync as g,readFileSync as oe,readdirSync as se,realpathSync as ce}from"node:fs";import le from"proper-lockfile";import{spawn as ue,spawnSync as de}from"node:child_process";import fe from"node:os";import{z as _}from"zod";import{exec as pe,execSync as me}from"child_process";import{promisify as he}from"util";import"node:crypto";import{format as ge,formatDistanceToNow as _e}from"date-fns";import{fileURLToPath as ve}from"url";import ye from"dotenv";const be=600*1e3,xe=3,Se=[`add-dependency`,`remove-dependency`,`validate-dependencies`,`fix-dependencies`,`clear-subtasks`,`models`,`generate`];function Ce(e){return Se.includes(e)}function we(e){let{hasValidSession:t,briefName:n,storageType:r,commandName:i}=e;return!Ce(i)||!t||r!==`api`?{isBlocked:!1,commandName:i}:{isBlocked:!0,briefName:n||`remote brief`,commandName:i}}const v={FILE_NOT_FOUND:`FILE_NOT_FOUND`,FILE_READ_ERROR:`FILE_READ_ERROR`,FILE_WRITE_ERROR:`FILE_WRITE_ERROR`,PARSE_ERROR:`PARSE_ERROR`,JSON_PARSE_ERROR:`JSON_PARSE_ERROR`,YAML_PARSE_ERROR:`YAML_PARSE_ERROR`,VALIDATION_ERROR:`VALIDATION_ERROR`,SCHEMA_VALIDATION_ERROR:`SCHEMA_VALIDATION_ERROR`,TYPE_VALIDATION_ERROR:`TYPE_VALIDATION_ERROR`,API_ERROR:`API_ERROR`,NETWORK_ERROR:`NETWORK_ERROR`,AUTHENTICATION_ERROR:`AUTHENTICATION_ERROR`,AUTHORIZATION_ERROR:`AUTHORIZATION_ERROR`,TASK_NOT_FOUND:`TASK_NOT_FOUND`,TASK_DEPENDENCY_ERROR:`TASK_DEPENDENCY_ERROR`,TASK_STATUS_ERROR:`TASK_STATUS_ERROR`,STORAGE_ERROR:`STORAGE_ERROR`,DATABASE_ERROR:`DATABASE_ERROR`,CONFIG_ERROR:`CONFIG_ERROR`,MISSING_CONFIGURATION:`MISSING_CONFIGURATION`,INVALID_CONFIGURATION:`INVALID_CONFIGURATION`,PROVIDER_ERROR:`PROVIDER_ERROR`,PROVIDER_NOT_FOUND:`PROVIDER_NOT_FOUND`,PROVIDER_INITIALIZATION_ERROR:`PROVIDER_INITIALIZATION_ERROR`,INTERNAL_ERROR:`INTERNAL_ERROR`,INVALID_INPUT:`INVALID_INPUT`,NOT_IMPLEMENTED:`NOT_IMPLEMENTED`,UNKNOWN_ERROR:`UNKNOWN_ERROR`,NOT_FOUND:`NOT_FOUND`,NO_BRIEF_SELECTED:`NO_BRIEF_SELECTED`};var y=class e extends Error{code;context;cause;timestamp;constructor(t,n=v.UNKNOWN_ERROR,r={},i){super(t),this.name=`TaskMasterError`,this.code=n,this.cause=i,this.timestamp=new Date,this.context={timestamp:this.timestamp,...r},Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e),i?.stack&&(this.stack=`${this.stack}\nCaused by: ${i.stack}`)}getUserMessage(){return this.context.userMessage||this.message}getSanitizedDetails(){let{details:e,resource:t,operation:n}=this.context;return{code:this.code,message:this.getUserMessage(),...t&&{resource:t},...n&&{operation:n},...e&&typeof e==`object`&&!this.containsSensitiveInfo(e)&&{details:e}}}containsSensitiveInfo(e){if(typeof e!=`object`||!e)return!1;let t=[`password`,`token`,`key`,`secret`,`auth`,`credential`],n=JSON.stringify(e).toLowerCase();return t.some(e=>n.includes(e))}toJSON(){let t={name:this.name,message:this.message,code:this.code,context:this.context,stack:this.stack};return this.cause&&(this.cause instanceof e?t.cause=this.cause.toJSON():t.cause={name:this.cause.name,message:this.cause.message,code:v.UNKNOWN_ERROR,context:{},stack:this.cause.stack}),t}toString(){let e=`${this.name}[${this.code}]: ${this.message}`;return this.context.operation&&(e+=` (operation: ${this.context.operation})`),this.context.resource&&(e+=` (resource: ${this.context.resource})`),this.cause&&(e+=`\nCaused by: ${this.cause.toString()}`),e}is(e){return this.code===e}hasCode(t){return this.is(t)?!0:this.cause instanceof e?this.cause.hasCode(t):!1}withContext(t){return new e(this.message,this.code,{...this.context,...t},this.cause)}wrap(t,n=v.INTERNAL_ERROR,r={}){return new e(t,n,r,this)}};let b=function(e){return e[e.SILENT=0]=`SILENT`,e[e.ERROR=1]=`ERROR`,e[e.WARN=2]=`WARN`,e[e.INFO=3]=`INFO`,e[e.DEBUG=4]=`DEBUG`,e}({});var Te=class e{config;static DEFAULT_CONFIG={level:b.SILENT,silent:!1,prefix:``,timestamp:!1,colors:!0,mcpMode:!1,logCallback:void 0};constructor(t={}){let n={};if((process.env.MCP_MODE===`true`||process.env.TASK_MASTER_MCP===`true`)&&(n.mcpMode=!0),(process.env.TASK_MASTER_SILENT===`true`||process.env.TM_SILENT===`true`)&&(n.silent=!0),process.env.TASK_MASTER_LOG_LEVEL||process.env.TM_LOG_LEVEL){let e=(process.env.TASK_MASTER_LOG_LEVEL||process.env.TM_LOG_LEVEL||``).toUpperCase();e in b&&(n.level=b[e])}(process.env.NO_COLOR===`true`||process.env.TASK_MASTER_NO_COLOR===`true`)&&(n.colors=!1),this.config={...e.DEFAULT_CONFIG,...t,...n},this.config.mcpMode&&!this.config.logCallback&&(this.config.silent=!0)}shouldLog(e){return this.config.logCallback?e<=this.config.level:this.config.silent||this.config.mcpMode?!1:e<=this.config.level}formatMessage(e,t,...n){let r=``;if(this.config.timestamp){let e=new Date().toISOString();r+=this.config.colors?i.gray(`[${e}] `):`[${e}] `}if(this.config.prefix&&(r+=this.config.colors?i.cyan(`[${this.config.prefix}] `):`[${this.config.prefix}] `),this.config.colors)switch(e){case b.ERROR:t=i.red(t);break;case b.WARN:t=i.yellow(t);break;case b.INFO:break;case b.DEBUG:t=i.gray(t);break}return r+=t,n.length>0&&(r+=` `+n.map(e=>typeof e==`object`?JSON.stringify(e,null,2):String(e)).join(` `)),r}isLogObject(e){return typeof e==`object`&&!!e&&`info`in e&&`warn`in e&&`error`in e&&`debug`in e}output(e,t,n,...r){let i=this.formatMessage(e,n,...r);if(this.config.logCallback){if(this.isLogObject(this.config.logCallback)){let e=t.toLowerCase();e in this.config.logCallback&&this.config.logCallback[e](i)}else this.config.logCallback(t.toLowerCase(),i);return}switch(e){case b.ERROR:console.error(i);break;case b.WARN:console.warn(i);break;default:console.log(i);break}}error(e,...t){this.shouldLog(b.ERROR)&&this.output(b.ERROR,`ERROR`,e,...t)}warn(e,...t){this.shouldLog(b.WARN)&&this.output(b.WARN,`WARN`,e,...t)}info(e,...t){this.shouldLog(b.INFO)&&this.output(b.INFO,`INFO`,e,...t)}debug(e,...t){this.shouldLog(b.DEBUG)&&this.output(b.DEBUG,`DEBUG`,e,...t)}log(e,...t){if(this.config.logCallback){let n=t.length>0?[e,...t].join(` `):e;this.isLogObject(this.config.logCallback)?this.config.logCallback.info(n):this.config.logCallback(`log`,n);return}this.config.silent||this.config.mcpMode||(t.length>0?console.log(e,...t):console.log(e))}setConfig(e){this.config={...this.config,...e},this.config.mcpMode&&!this.config.logCallback&&(this.config.silent=!0)}getConfig(){return{...this.config}}child(t,n){let r=this.config.prefix?`${this.config.prefix}:${t}`:t;return new e({...this.config,...n,prefix:r})}};let Ee=null;const De=new Map;function Oe(e){return new Te(e)}function x(e,t){return e?(De.has(e)||De.set(e,Oe({prefix:e,...t})),De.get(e)):(Ee||=Oe(t),Ee)}const ke=c.join(process.env.HOME||process.env.USERPROFILE||`~`,`.taskmaster`,`session.json`);var Ae=class{storage=new Map;persistPath;logger=x(`SupabaseSessionStorage`);writer;initPromise;constructor(e=ke){this.persistPath=e,this.writer=new d(e),this.initPromise=this.load()}async load(){try{let e=c.dirname(this.persistPath);if(await u.mkdir(e,{recursive:!0,mode:448}),s.existsSync(this.persistPath)){let e=JSON.parse(await u.readFile(this.persistPath,`utf8`));Object.entries(e).forEach(([e,t])=>this.storage.set(e,t)),this.logger.debug(`Loaded session from disk`,{keys:Array.from(this.storage.keys())})}}catch(e){this.logger.error(`Failed to load session:`,e)}}async persist(){try{let e=Object.fromEntries(this.storage),t=JSON.stringify(e,null,2);await this.writer.write(t+`
2
- `),this.logger.debug(`Persisted session to disk (steno)`)}catch(e){this.logger.error(`Failed to persist session:`,e)}}async getItem(e){await this.initPromise;let t=this.storage.get(e)??null;return this.logger.debug(`getItem called`,{key:e,hasValue:!!t}),t}async setItem(e,t){await this.initPromise,this.logger.debug(`setItem called`,{key:e}),this.storage.set(e,t),await this.persist()}async removeItem(e){await this.initPromise,this.logger.debug(`removeItem called`,{key:e}),this.storage.delete(e),await this.persist()}async clear(){await this.initPromise,this.logger.debug(`clear called`),this.storage.clear(),await this.persist()}},S=class extends Error{mfaChallenge;constructor(e,t,n,r){super(e),this.code=t,this.cause=n,this.name=`AuthenticationError`,this.mfaChallenge=r,n&&n instanceof Error&&(this.stack=`${this.stack}\nCaused by: ${n.stack}`)}};function C(e){return o(e)}const je={refresh_token_not_found:`Your session has expired. Please log in again with: task-master login`,refresh_token_already_used:`Your session has expired (token was already used). Please log in again with: task-master login`,invalid_refresh_token:`Your session has expired (invalid token). Please log in again with: task-master login`,session_expired:`Your session has expired. Please log in again with: task-master login`,user_not_found:`User account not found. Please log in again with: task-master login`,invalid_credentials:`Invalid credentials. Please log in again with: task-master login`},Me=[`refresh_token_not_found`,`refresh_token_already_used`];function w(e){return C(e)?Me.includes(e.code||``):!1}function Ne(e,t){let n=e.code,r=n&&je[n]||`${t}: ${e.message}`,i=`REFRESH_FAILED`;return n===`refresh_token_not_found`||n===`refresh_token_already_used`||n===`invalid_refresh_token`||n===`session_expired`||n===`user_not_found`?i=`NOT_AUTHENTICATED`:n===`invalid_credentials`&&(i=`INVALID_CREDENTIALS`),new S(r,i,e)}function Pe(){let{publicKey:e,privateKey:t}=f.generateKeyPairSync(`rsa`,{modulusLength:2048,publicKeyEncoding:{type:`spki`,format:`pem`},privateKeyEncoding:{type:`pkcs8`,format:`pem`}});return{publicKey:e,privateKey:t}}function Fe(e,t){try{let n=Buffer.from(e.encrypted_key,`base64`),r=Buffer.from(e.encrypted_data,`base64`),i=Buffer.from(e.iv,`base64`),a=Buffer.from(e.auth_tag,`base64`),o=f.privateDecrypt({key:t,padding:f.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:`sha256`},n),s=f.createDecipheriv(`aes-256-gcm`,o,i);s.setAuthTag(a);let c=Buffer.concat([s.update(r),s.final()]);return JSON.parse(c.toString(`utf8`))}catch(e){throw new S(`Token decryption failed: ${e instanceof Error?e.message:`Unknown error`}`,`DECRYPTION_FAILED`,e)}}var Ie=class e{static instance=null;client=null;sessionStorage;logger=x(`SupabaseAuthClient`);constructor(){this.sessionStorage=new Ae}static getInstance(){return e.instance||=new e,e.instance}static resetInstance(){e.instance&&(e.instance.client=null),e.instance=null}getClient(){if(!this.client){let e=process.env.TM_SUPABASE_URL||process.env.TM_PUBLIC_SUPABASE_URL||`https://tryhamster.com`,t=process.env.TM_SUPABASE_ANON_KEY||process.env.TM_PUBLIC_SUPABASE_ANON_KEY||`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im5zdHhhdGRwbnNmYWxja3hhd3R6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg3MzU3NTYsImV4cCI6MjA2NDMxMTc1Nn0.GF897_2zXRxl4pkeQ89-7xF4TkJfJuYPWKhv1bTbv9k`;if(!e||!t)throw new S(`Supabase configuration missing. Please set TM_SUPABASE_URL and TM_SUPABASE_ANON_KEY (runtime) or TM_PUBLIC_SUPABASE_URL and TM_PUBLIC_SUPABASE_ANON_KEY (build-time) environment variables.`,`CONFIG_MISSING`);this.client=a(e,t,{auth:{storage:this.sessionStorage,autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!1}})}return this.client}async initialize(){let e=this.getClient();try{let{data:{session:t},error:n}=await e.auth.getSession();return n?(w(n)||this.logger.warn(`Failed to restore session:`,n),null):(t&&this.logger.info(`Session restored successfully`),t)}catch(e){return w(e)?this.logger.debug(`Session not available (expected during MFA flow)`):C(e)?this.logger.warn(`Session expired or invalid`):this.logger.error(`Error initializing session:`,e),null}}async signInWithPKCE(){let e=this.getClient();try{let{data:t,error:n}=await e.auth.signInWithOAuth({provider:`github`,options:{redirectTo:process.env.TM_AUTH_CALLBACK_URL||`http://localhost:3421/auth/callback`,scopes:`email`}});if(n)throw new S(`Failed to initiate PKCE flow: ${n.message}`,`PKCE_INIT_FAILED`);if(!t?.url)throw new S(`No authorization URL returned`,`INVALID_RESPONSE`);return{url:t.url,codeVerifier:``}}catch(e){throw e instanceof S?e:new S(`Failed to start PKCE flow: ${e.message}`,`PKCE_FAILED`)}}async exchangeCodeForSession(e){let t=this.getClient();try{let{data:n,error:r}=await t.auth.exchangeCodeForSession(e);if(r)throw new S(`Failed to exchange code: ${r.message}`,`CODE_EXCHANGE_FAILED`);if(!n?.session)throw new S(`No session returned from code exchange`,`INVALID_RESPONSE`);return this.logger.info(`Successfully exchanged code for session`),n.session}catch(e){throw e instanceof S?e:new S(`Code exchange failed: ${e.message}`,`CODE_EXCHANGE_FAILED`)}}async getSession(){let e=this.getClient();try{let{data:{session:t},error:n}=await e.auth.getSession();return n?(w(n)||this.logger.warn(`Failed to get session:`,n),null):t}catch(e){return w(e)?this.logger.debug(`Session not available (expected during MFA flow)`):C(e)?this.logger.warn(`Session expired or invalid`):this.logger.error(`Error getting session:`,e),null}}async refreshSession(){let e=this.getClient();try{this.logger.info(`Refreshing session...`);let{data:{session:t},error:n}=await e.auth.refreshSession();if(n)throw this.logger.error(`Failed to refresh session:`,n),Ne(n,`Failed to refresh session`);return t&&this.logger.info(`Successfully refreshed session`),t}catch(e){throw e instanceof S?e:C(e)?Ne(e,`Session refresh failed`):new S(`Failed to refresh session: ${e.message}`,`REFRESH_FAILED`)}}async getUser(){let e=this.getClient();try{let{data:{user:t},error:n}=await e.auth.getUser();return n?(this.logger.warn(`Failed to get user:`,n),null):t}catch(e){return this.logger.error(`Error getting user:`,e),null}}async signOut(){let e=this.getClient();try{let{error:t}=await e.auth.signOut({scope:`local`});t&&this.logger.warn(`Failed to sign out:`,t),this.sessionStorage.clear()}catch(e){this.logger.error(`Error during sign out:`,e)}}async setSession(e){let t=this.getClient();try{let{error:n}=await t.auth.setSession({access_token:e.access_token,refresh_token:e.refresh_token});if(n)throw new S(`Failed to set session: ${n.message}`,`SESSION_SET_FAILED`);this.logger.info(`Session set successfully`)}catch(e){throw e instanceof S?e:new S(`Failed to set session: ${e.message}`,`SESSION_SET_FAILED`)}}async handleRecoverableError(e,t,n){return!t&&w(e)?(this.logger.debug(`MFA-expected error during token verification, clearing stale session and retrying`),await this.sessionStorage.clear(),n()):null}async verifyOneTimeCode(e,t=!1){let n=this.getClient(),r=()=>this.verifyOneTimeCode(e,!0);try{this.logger.info(`Verifying authentication token...`);let{data:i,error:a}=await n.auth.verifyOtp({token_hash:e,type:`magiclink`});if(a){let e=await this.handleRecoverableError(a,t,r);if(e)return e;throw this.logger.error(`Failed to verify token:`,a),Ne(a,`Failed to verify token`)}if(!i?.session)throw new S(`No session returned from token verification`,`INVALID_RESPONSE`);return this.logger.info(`Successfully verified authentication token`),i.session}catch(e){if(e instanceof S)throw e;if(C(e)){let n=await this.handleRecoverableError(e,t,r);if(n)return n;throw Ne(e,`Token verification failed`)}throw new S(`Token verification failed: ${e.message}`,`CODE_AUTH_FAILED`)}}async checkMFARequired(){let e=this.getClient();try{let{data:{session:t},error:n}=await e.auth.getSession();if(n||!t)return this.logger.warn(`No session available to check MFA`),{required:!1};let{data:r,error:i}=await e.auth.mfa.getAuthenticatorAssuranceLevel();if(i)return this.logger.warn(`Failed to get AAL:`,i),{required:!1};if(r?.currentLevel===`aal2`)return this.logger.info(`Session already at AAL2, MFA not required`),{required:!1};let{data:a,error:o}=await e.auth.mfa.listFactors();if(o)return this.logger.warn(`Failed to list MFA factors:`,o),{required:!1};let s=a?.totp?.filter(e=>e.status===`verified`);if(!s||s.length===0)return this.logger.info(`No verified MFA factors found`),{required:!1};let c=s[0];return this.logger.info(`MFA verification required`,{factorId:c.id,factorType:c.factor_type}),{required:!0,factorId:c.id,factorType:c.factor_type}}catch(e){return this.logger.error(`Error checking MFA requirement:`,e),{required:!1}}}async verifyMFA(e,t){let n=this.getClient();try{this.logger.info(`Verifying MFA code...`);let{data:r,error:i}=await n.auth.mfa.challenge({factorId:e});if(i||!r)throw new S(`Failed to create MFA challenge: ${i?.message||`Unknown error`}`,`MFA_VERIFICATION_FAILED`);let{data:a,error:o}=await n.auth.mfa.verify({factorId:e,challengeId:r.id,code:t});if(o)throw this.logger.error(`MFA verification failed:`,o),new S(`Invalid MFA code: ${o.message}`,`INVALID_MFA_CODE`);if(!a)throw new S(`No data returned from MFA verification`,`INVALID_RESPONSE`);let{data:{session:s},error:c}=await n.auth.refreshSession();if(c||!s)throw new S(`Failed to refresh session after MFA: ${c?.message||`No session returned`}`,`REFRESH_FAILED`);return this.logger.info(`Successfully verified MFA, session upgraded to AAL2`),s}catch(e){throw e instanceof S?e:new S(`MFA verification failed: ${e.message}`,`MFA_VERIFICATION_FAILED`)}}};const Le=c.join(process.env.HOME||process.env.USERPROFILE||`~`,`.taskmaster`,`context.json`);var Re=class e{static instance=null;logger=x(`ContextStore`);contextPath;constructor(e=Le){this.contextPath=e}static getInstance(t){return e.instance||=new e(t),e.instance}static resetInstance(){e.instance=null}getContext(){try{if(!s.existsSync(this.contextPath))return null;let e=JSON.parse(s.readFileSync(this.contextPath,`utf8`));return this.logger.debug(`Loaded context from disk`),e}catch(e){return this.logger.error(`Failed to read context:`,e),null}}saveContext(e){try{let t={...this.getContext()||{},...e,lastUpdated:new Date().toISOString()},n=c.dirname(this.contextPath);s.existsSync(n)||s.mkdirSync(n,{recursive:!0,mode:448});let r=`${this.contextPath}.tmp`;s.writeFileSync(r,JSON.stringify(t,null,2),{mode:384}),s.renameSync(r,this.contextPath),this.logger.debug(`Saved context to disk`)}catch(e){throw new S(`Failed to save context: ${e.message}`,`SAVE_FAILED`,e)}}updateUserContext(e){let t=this.getContext(),n={...t?.selectedContext||{},...e,updatedAt:new Date().toISOString()};this.saveContext({...t,selectedContext:n})}getUserContext(){return this.getContext()?.selectedContext||null}clearUserContext(){let e=this.getContext();if(e){let{selectedContext:t,...n}=e;this.saveContext(n)}}clearContext(){try{s.existsSync(this.contextPath)&&(s.unlinkSync(this.contextPath),this.logger.debug(`Cleared context from disk`))}catch(e){throw new S(`Failed to clear context: ${e.message}`,`CLEAR_FAILED`,e)}}hasContext(){return this.getContext()!==null}getContextPath(){return this.contextPath}},ze=`@hhsw2015/task-master-ai`,Be=`0.43.8`;const Ve=[`anthropic`,`openai`,`google`,`zai`,`zai-coding`,`perplexity`,`xai`,`groq`,`mistral`,`azure`,`openrouter`,`bedrock`,`ollama`],T={AZURE:`azure`,VERTEX:`vertex`,BEDROCK:`bedrock`,OPENROUTER:`openrouter`,OLLAMA:`ollama`,LMSTUDIO:`lmstudio`,OPENAI_COMPATIBLE:`openai-compatible`,CLAUDE_CODE:`claude-code`,MCP:`mcp`,GEMINI_CLI:`gemini-cli`,GROK_CLI:`grok-cli`,CODEX_CLI:`codex-cli`},He=Object.values(T),Ue=[...new Set([...Ve,...He])],We=`.taskmaster/tasks/tasks.json`,Ge=[`.taskmaster`,`.taskmaster/config.json`,We,`.taskmasterconfig`],Ke=`.git,.svn,.hg,.fossil,.github,.gitlab,.circleci,.travis.yml,.jenkins,.buildkite,.vscode,.idea,.project,.devcontainer,package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lockb,bun.lock,deno.lock,deno.json,deno.jsonc,package.json,lerna.json,nx.json,turbo.json,rush.json,pnpm-workspace.yaml,Cargo.toml,Cargo.lock,go.mod,go.sum,go.work,pyproject.toml,setup.py,setup.cfg,poetry.lock,Pipfile,Pipfile.lock,uv.lock,Gemfile,Gemfile.lock,composer.json,composer.lock,build.gradle,build.gradle.kts,settings.gradle,settings.gradle.kts,pom.xml,build.sbt,project.clj,deps.edn,mix.exs,rebar.config,pubspec.yaml,Package.swift,CMakeLists.txt,Makefile,meson.build,BUILD.bazel,WORKSPACE,flake.nix,shell.nix,default.nix,Dockerfile,docker-compose.yml,docker-compose.yaml,Containerfile,kubernetes.yml,kubernetes.yaml,helm/Chart.yaml`.split(`,`),qe=[`tasks/tasks.json`,`tasks.json`,...Ke,`requirements.txt`];[...Ge,...qe];const Je=Be||`unknown`,Ye=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`],Xe=[`done`,`completed`,`cancelled`];function Ze(e){return Xe.includes(e)}const Qe=[`text`,`json`,`compact`],$e={done:`✓`,completed:`✓`,"in-progress":`►`,blocked:`⭕`,pending:`○`,deferred:`⏸`,cancelled:`✗`,review:`👁`};function et(){return process.env.TM_BASE_DOMAIN||process.env.TM_PUBLIC_BASE_DOMAIN||`https://tryhamster.com`}function tt(){return{baseUrl:et(),configDir:c.join(p.homedir(),`.taskmaster`),configFile:c.join(p.homedir(),`.taskmaster`,`auth.json`)}}function nt(e){return{...tt(),...e}}new Proxy({},{get(e,t){return tt()[t]}});var rt=class{logger=x(`OAuthService`);contextStore;supabaseClient;configOverrides;authorizationUrl=null;keyPair=null;get baseUrl(){return nt(this.configOverrides).baseUrl}constructor(e,t,n={}){this.contextStore=e,this.supabaseClient=t,this.configOverrides=n}async authenticate(e={}){let{openBrowser:t,timeout:n=3e5,onAuthUrl:r,onWaitingForAuth:i,onSuccess:a,onError:o}=e;try{return await this.authenticateWithBackendPKCE({openBrowser:t,timeout:n,onAuthUrl:r,onWaitingForAuth:i,onSuccess:a})}catch(e){let t=e instanceof S?e:new S(`OAuth authentication failed: ${e.message}`,`OAUTH_FAILED`,e);throw o&&t.code!==`MFA_REQUIRED`&&o(t),t}}async authenticateWithBackendPKCE(e){let{openBrowser:t,timeout:n=3e5,onAuthUrl:r,onWaitingForAuth:i,onSuccess:a}=e;this.keyPair=Pe(),this.logger.debug(`Generated RSA keypair for E2E encryption`);let o=await this.startBackendFlow();if(!o.success||!o.flow_id)throw new S(o.message||`Failed to start authentication flow`,`START_FLOW_FAILED`);let{flow_id:s,verification_url:c,poll_interval:l=2}=o;if(this.authorizationUrl=c||null,r&&c&&r(c),t&&c)try{await t(c),this.logger.debug(`Browser opened successfully with URL:`,c)}catch(e){this.logger.warn(`Failed to open browser automatically:`,e)}i&&i();let u=await this.pollForCompletion(s,l*1e3,n);u.refreshToken||this.logger.warn(`No refresh token received from server - session refresh will not work`);let d={access_token:u.token,refresh_token:u.refreshToken??``,expires_in:u.expiresAt?Math.floor((new Date(u.expiresAt).getTime()-Date.now())/1e3):3600,token_type:`bearer`,user:{id:u.userId,email:u.email,app_metadata:{},user_metadata:{},aud:`authenticated`,created_at:``}};return await this.supabaseClient.setSession(d),this.contextStore.saveContext({userId:u.userId,email:u.email}),await this.checkAndThrowIfMFARequired(),a&&a(u),u}async startBackendFlow(){let e=`${this.baseUrl}/api/auth/cli/start`;if(!this.keyPair)throw new S(`Keypair not generated before starting flow`,`INTERNAL_ERROR`);try{let t=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,"User-Agent":`TaskMasterCLI/${this.getCliVersion()}`},body:JSON.stringify({name:`Task Master CLI`,version:this.getCliVersion(),device:p.hostname(),user:p.userInfo().username,platform:p.platform(),public_key:this.keyPair.publicKey})});if(!t.ok)throw new S((await t.json().catch(()=>({}))).message||`HTTP ${t.status}`,`START_FLOW_FAILED`);return await t.json()}catch(e){throw e instanceof S?e:(this.logger.warn(`Failed to reach backend for PKCE flow:`,e),new S(`Unable to reach authentication server`,`BACKEND_UNREACHABLE`,e))}}async pollForCompletion(e,t,n){let r=`${this.baseUrl}/api/auth/cli/status?flow_id=${e}`,i=Date.now();if(!this.keyPair)throw new S(`Keypair not available for decryption`,`INTERNAL_ERROR`);for(;Date.now()-i<n;){try{let e=await fetch(r,{method:`GET`,headers:{"User-Agent":`TaskMasterCLI/${this.getCliVersion()}`}});if(!e.ok){let t=await e.json().catch(()=>({}));throw e.status===404?new S(`Authentication flow expired or not found`,`FLOW_NOT_FOUND`):new S(t.message||`HTTP ${e.status}`,`POLL_FAILED`)}let t=await e.json();if(!t.success)throw new S(t.message||`Failed to check status`,`POLL_FAILED`);switch(t.status){case`complete`:{if(!t.encrypted_tokens)throw new S(`Server returned no encrypted tokens`,`MISSING_TOKENS`);let e=Fe(t.encrypted_tokens,this.keyPair.privateKey);return this.logger.debug(`Successfully decrypted authentication tokens`),{token:e.access_token,refreshToken:e.refresh_token,userId:e.user_id,email:e.email,expiresAt:e.expires_in?new Date(Date.now()+e.expires_in*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString()}}case`failed`:throw new S(t.error_description||t.error||`Authentication failed`,`OAUTH_FAILED`);case`expired`:throw new S(`Authentication flow expired`,`AUTH_TIMEOUT`);case`pending`:case`authenticating`:this.logger.debug(`Flow status: ${t.status}, continuing to poll`);break;default:this.logger.warn(`Unknown flow status: ${t.status}`)}}catch(e){if(e instanceof S)throw e;this.logger.debug(`Poll request failed, will retry:`,e)}await new Promise(e=>setTimeout(e,t))}throw new S(`Authentication timeout`,`AUTH_TIMEOUT`)}getCliVersion(){return Je}getAuthorizationUrl(){return this.authorizationUrl}async checkAndThrowIfMFARequired(){let e=await this.supabaseClient.checkMFARequired();if(e.required)throw!e.factorId||!e.factorType?(this.logger.error(`MFA required but factor information is incomplete`,{mfaCheck:e}),new S(`MFA is required but the server returned incomplete factor configuration. Please contact support or try re-enrolling MFA.`,`MFA_REQUIRED_INCOMPLETE`)):(this.logger.info(`MFA verification required after OAuth login`,{factorId:e.factorId,factorType:e.factorType}),new S(`MFA verification required. Please provide your authentication code.`,`MFA_REQUIRED`,void 0,{factorId:e.factorId,factorType:e.factorType}))}},it=class{logger=x(`OrganizationService`);constructor(e){this.supabaseClient=e}async getOrganizations(){try{let{data:e,error:t}=await this.supabaseClient.from(`user_accounts`).select(`
2
+ `),this.logger.debug(`Persisted session to disk (steno)`)}catch(e){this.logger.error(`Failed to persist session:`,e)}}async getItem(e){await this.initPromise;let t=this.storage.get(e)??null;return this.logger.debug(`getItem called`,{key:e,hasValue:!!t}),t}async setItem(e,t){await this.initPromise,this.logger.debug(`setItem called`,{key:e}),this.storage.set(e,t),await this.persist()}async removeItem(e){await this.initPromise,this.logger.debug(`removeItem called`,{key:e}),this.storage.delete(e),await this.persist()}async clear(){await this.initPromise,this.logger.debug(`clear called`),this.storage.clear(),await this.persist()}},S=class extends Error{mfaChallenge;constructor(e,t,n,r){super(e),this.code=t,this.cause=n,this.name=`AuthenticationError`,this.mfaChallenge=r,n&&n instanceof Error&&(this.stack=`${this.stack}\nCaused by: ${n.stack}`)}};function C(e){return o(e)}const je={refresh_token_not_found:`Your session has expired. Please log in again with: task-master login`,refresh_token_already_used:`Your session has expired (token was already used). Please log in again with: task-master login`,invalid_refresh_token:`Your session has expired (invalid token). Please log in again with: task-master login`,session_expired:`Your session has expired. Please log in again with: task-master login`,user_not_found:`User account not found. Please log in again with: task-master login`,invalid_credentials:`Invalid credentials. Please log in again with: task-master login`},Me=[`refresh_token_not_found`,`refresh_token_already_used`];function w(e){return C(e)?Me.includes(e.code||``):!1}function Ne(e,t){let n=e.code,r=n&&je[n]||`${t}: ${e.message}`,i=`REFRESH_FAILED`;return n===`refresh_token_not_found`||n===`refresh_token_already_used`||n===`invalid_refresh_token`||n===`session_expired`||n===`user_not_found`?i=`NOT_AUTHENTICATED`:n===`invalid_credentials`&&(i=`INVALID_CREDENTIALS`),new S(r,i,e)}function Pe(){let{publicKey:e,privateKey:t}=f.generateKeyPairSync(`rsa`,{modulusLength:2048,publicKeyEncoding:{type:`spki`,format:`pem`},privateKeyEncoding:{type:`pkcs8`,format:`pem`}});return{publicKey:e,privateKey:t}}function Fe(e,t){try{let n=Buffer.from(e.encrypted_key,`base64`),r=Buffer.from(e.encrypted_data,`base64`),i=Buffer.from(e.iv,`base64`),a=Buffer.from(e.auth_tag,`base64`),o=f.privateDecrypt({key:t,padding:f.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:`sha256`},n),s=f.createDecipheriv(`aes-256-gcm`,o,i);s.setAuthTag(a);let c=Buffer.concat([s.update(r),s.final()]);return JSON.parse(c.toString(`utf8`))}catch(e){throw new S(`Token decryption failed: ${e instanceof Error?e.message:`Unknown error`}`,`DECRYPTION_FAILED`,e)}}var Ie=class e{static instance=null;client=null;sessionStorage;logger=x(`SupabaseAuthClient`);constructor(){this.sessionStorage=new Ae}static getInstance(){return e.instance||=new e,e.instance}static resetInstance(){e.instance&&(e.instance.client=null),e.instance=null}getClient(){if(!this.client){let e=process.env.TM_SUPABASE_URL||process.env.TM_PUBLIC_SUPABASE_URL||`https://tryhamster.com`,t=process.env.TM_SUPABASE_ANON_KEY||process.env.TM_PUBLIC_SUPABASE_ANON_KEY||`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im5zdHhhdGRwbnNmYWxja3hhd3R6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDg3MzU3NTYsImV4cCI6MjA2NDMxMTc1Nn0.GF897_2zXRxl4pkeQ89-7xF4TkJfJuYPWKhv1bTbv9k`;if(!e||!t)throw new S(`Supabase configuration missing. Please set TM_SUPABASE_URL and TM_SUPABASE_ANON_KEY (runtime) or TM_PUBLIC_SUPABASE_URL and TM_PUBLIC_SUPABASE_ANON_KEY (build-time) environment variables.`,`CONFIG_MISSING`);this.client=a(e,t,{auth:{storage:this.sessionStorage,autoRefreshToken:!0,persistSession:!0,detectSessionInUrl:!1}})}return this.client}async initialize(){let e=this.getClient();try{let{data:{session:t},error:n}=await e.auth.getSession();return n?(w(n)||this.logger.warn(`Failed to restore session:`,n),null):(t&&this.logger.info(`Session restored successfully`),t)}catch(e){return w(e)?this.logger.debug(`Session not available (expected during MFA flow)`):C(e)?this.logger.warn(`Session expired or invalid`):this.logger.error(`Error initializing session:`,e),null}}async signInWithPKCE(){let e=this.getClient();try{let{data:t,error:n}=await e.auth.signInWithOAuth({provider:`github`,options:{redirectTo:process.env.TM_AUTH_CALLBACK_URL||`http://localhost:3421/auth/callback`,scopes:`email`}});if(n)throw new S(`Failed to initiate PKCE flow: ${n.message}`,`PKCE_INIT_FAILED`);if(!t?.url)throw new S(`No authorization URL returned`,`INVALID_RESPONSE`);return{url:t.url,codeVerifier:``}}catch(e){throw e instanceof S?e:new S(`Failed to start PKCE flow: ${e.message}`,`PKCE_FAILED`)}}async exchangeCodeForSession(e){let t=this.getClient();try{let{data:n,error:r}=await t.auth.exchangeCodeForSession(e);if(r)throw new S(`Failed to exchange code: ${r.message}`,`CODE_EXCHANGE_FAILED`);if(!n?.session)throw new S(`No session returned from code exchange`,`INVALID_RESPONSE`);return this.logger.info(`Successfully exchanged code for session`),n.session}catch(e){throw e instanceof S?e:new S(`Code exchange failed: ${e.message}`,`CODE_EXCHANGE_FAILED`)}}async getSession(){let e=this.getClient();try{let{data:{session:t},error:n}=await e.auth.getSession();return n?(w(n)||this.logger.warn(`Failed to get session:`,n),null):t}catch(e){return w(e)?this.logger.debug(`Session not available (expected during MFA flow)`):C(e)?this.logger.warn(`Session expired or invalid`):this.logger.error(`Error getting session:`,e),null}}async refreshSession(){let e=this.getClient();try{this.logger.info(`Refreshing session...`);let{data:{session:t},error:n}=await e.auth.refreshSession();if(n)throw this.logger.error(`Failed to refresh session:`,n),Ne(n,`Failed to refresh session`);return t&&this.logger.info(`Successfully refreshed session`),t}catch(e){throw e instanceof S?e:C(e)?Ne(e,`Session refresh failed`):new S(`Failed to refresh session: ${e.message}`,`REFRESH_FAILED`)}}async getUser(){let e=this.getClient();try{let{data:{user:t},error:n}=await e.auth.getUser();return n?(this.logger.warn(`Failed to get user:`,n),null):t}catch(e){return this.logger.error(`Error getting user:`,e),null}}async signOut(){let e=this.getClient();try{let{error:t}=await e.auth.signOut({scope:`local`});t&&this.logger.warn(`Failed to sign out:`,t),this.sessionStorage.clear()}catch(e){this.logger.error(`Error during sign out:`,e)}}async setSession(e){let t=this.getClient();try{let{error:n}=await t.auth.setSession({access_token:e.access_token,refresh_token:e.refresh_token});if(n)throw new S(`Failed to set session: ${n.message}`,`SESSION_SET_FAILED`);this.logger.info(`Session set successfully`)}catch(e){throw e instanceof S?e:new S(`Failed to set session: ${e.message}`,`SESSION_SET_FAILED`)}}async handleRecoverableError(e,t,n){return!t&&w(e)?(this.logger.debug(`MFA-expected error during token verification, clearing stale session and retrying`),await this.sessionStorage.clear(),n()):null}async verifyOneTimeCode(e,t=!1){let n=this.getClient(),r=()=>this.verifyOneTimeCode(e,!0);try{this.logger.info(`Verifying authentication token...`);let{data:i,error:a}=await n.auth.verifyOtp({token_hash:e,type:`magiclink`});if(a){let e=await this.handleRecoverableError(a,t,r);if(e)return e;throw this.logger.error(`Failed to verify token:`,a),Ne(a,`Failed to verify token`)}if(!i?.session)throw new S(`No session returned from token verification`,`INVALID_RESPONSE`);return this.logger.info(`Successfully verified authentication token`),i.session}catch(e){if(e instanceof S)throw e;if(C(e)){let n=await this.handleRecoverableError(e,t,r);if(n)return n;throw Ne(e,`Token verification failed`)}throw new S(`Token verification failed: ${e.message}`,`CODE_AUTH_FAILED`)}}async checkMFARequired(){let e=this.getClient();try{let{data:{session:t},error:n}=await e.auth.getSession();if(n||!t)return this.logger.warn(`No session available to check MFA`),{required:!1};let{data:r,error:i}=await e.auth.mfa.getAuthenticatorAssuranceLevel();if(i)return this.logger.warn(`Failed to get AAL:`,i),{required:!1};if(r?.currentLevel===`aal2`)return this.logger.info(`Session already at AAL2, MFA not required`),{required:!1};let{data:a,error:o}=await e.auth.mfa.listFactors();if(o)return this.logger.warn(`Failed to list MFA factors:`,o),{required:!1};let s=a?.totp?.filter(e=>e.status===`verified`);if(!s||s.length===0)return this.logger.info(`No verified MFA factors found`),{required:!1};let c=s[0];return this.logger.info(`MFA verification required`,{factorId:c.id,factorType:c.factor_type}),{required:!0,factorId:c.id,factorType:c.factor_type}}catch(e){return this.logger.error(`Error checking MFA requirement:`,e),{required:!1}}}async verifyMFA(e,t){let n=this.getClient();try{this.logger.info(`Verifying MFA code...`);let{data:r,error:i}=await n.auth.mfa.challenge({factorId:e});if(i||!r)throw new S(`Failed to create MFA challenge: ${i?.message||`Unknown error`}`,`MFA_VERIFICATION_FAILED`);let{data:a,error:o}=await n.auth.mfa.verify({factorId:e,challengeId:r.id,code:t});if(o)throw this.logger.error(`MFA verification failed:`,o),new S(`Invalid MFA code: ${o.message}`,`INVALID_MFA_CODE`);if(!a)throw new S(`No data returned from MFA verification`,`INVALID_RESPONSE`);let{data:{session:s},error:c}=await n.auth.refreshSession();if(c||!s)throw new S(`Failed to refresh session after MFA: ${c?.message||`No session returned`}`,`REFRESH_FAILED`);return this.logger.info(`Successfully verified MFA, session upgraded to AAL2`),s}catch(e){throw e instanceof S?e:new S(`MFA verification failed: ${e.message}`,`MFA_VERIFICATION_FAILED`)}}};const Le=c.join(process.env.HOME||process.env.USERPROFILE||`~`,`.taskmaster`,`context.json`);var Re=class e{static instance=null;logger=x(`ContextStore`);contextPath;constructor(e=Le){this.contextPath=e}static getInstance(t){return e.instance||=new e(t),e.instance}static resetInstance(){e.instance=null}getContext(){try{if(!s.existsSync(this.contextPath))return null;let e=JSON.parse(s.readFileSync(this.contextPath,`utf8`));return this.logger.debug(`Loaded context from disk`),e}catch(e){return this.logger.error(`Failed to read context:`,e),null}}saveContext(e){try{let t={...this.getContext()||{},...e,lastUpdated:new Date().toISOString()},n=c.dirname(this.contextPath);s.existsSync(n)||s.mkdirSync(n,{recursive:!0,mode:448});let r=`${this.contextPath}.tmp`;s.writeFileSync(r,JSON.stringify(t,null,2),{mode:384}),s.renameSync(r,this.contextPath),this.logger.debug(`Saved context to disk`)}catch(e){throw new S(`Failed to save context: ${e.message}`,`SAVE_FAILED`,e)}}updateUserContext(e){let t=this.getContext(),n={...t?.selectedContext||{},...e,updatedAt:new Date().toISOString()};this.saveContext({...t,selectedContext:n})}getUserContext(){return this.getContext()?.selectedContext||null}clearUserContext(){let e=this.getContext();if(e){let{selectedContext:t,...n}=e;this.saveContext(n)}}clearContext(){try{s.existsSync(this.contextPath)&&(s.unlinkSync(this.contextPath),this.logger.debug(`Cleared context from disk`))}catch(e){throw new S(`Failed to clear context: ${e.message}`,`CLEAR_FAILED`,e)}}hasContext(){return this.getContext()!==null}getContextPath(){return this.contextPath}},ze=`@hhsw2015/task-master-ai`,Be=`0.43.9`;const Ve=[`anthropic`,`openai`,`google`,`zai`,`zai-coding`,`perplexity`,`xai`,`groq`,`mistral`,`azure`,`openrouter`,`bedrock`,`ollama`],T={AZURE:`azure`,VERTEX:`vertex`,BEDROCK:`bedrock`,OPENROUTER:`openrouter`,OLLAMA:`ollama`,LMSTUDIO:`lmstudio`,OPENAI_COMPATIBLE:`openai-compatible`,CLAUDE_CODE:`claude-code`,MCP:`mcp`,GEMINI_CLI:`gemini-cli`,GROK_CLI:`grok-cli`,CODEX_CLI:`codex-cli`},He=Object.values(T),Ue=[...new Set([...Ve,...He])],We=`.taskmaster/tasks/tasks.json`,Ge=[`.taskmaster`,`.taskmaster/config.json`,We,`.taskmasterconfig`],Ke=`.git,.svn,.hg,.fossil,.github,.gitlab,.circleci,.travis.yml,.jenkins,.buildkite,.vscode,.idea,.project,.devcontainer,package-lock.json,yarn.lock,pnpm-lock.yaml,bun.lockb,bun.lock,deno.lock,deno.json,deno.jsonc,package.json,lerna.json,nx.json,turbo.json,rush.json,pnpm-workspace.yaml,Cargo.toml,Cargo.lock,go.mod,go.sum,go.work,pyproject.toml,setup.py,setup.cfg,poetry.lock,Pipfile,Pipfile.lock,uv.lock,Gemfile,Gemfile.lock,composer.json,composer.lock,build.gradle,build.gradle.kts,settings.gradle,settings.gradle.kts,pom.xml,build.sbt,project.clj,deps.edn,mix.exs,rebar.config,pubspec.yaml,Package.swift,CMakeLists.txt,Makefile,meson.build,BUILD.bazel,WORKSPACE,flake.nix,shell.nix,default.nix,Dockerfile,docker-compose.yml,docker-compose.yaml,Containerfile,kubernetes.yml,kubernetes.yaml,helm/Chart.yaml`.split(`,`),qe=[`tasks/tasks.json`,`tasks.json`,...Ke,`requirements.txt`];[...Ge,...qe];const Je=Be||`unknown`,Ye=[`pending`,`in-progress`,`done`,`deferred`,`cancelled`,`blocked`,`review`],Xe=[`done`,`completed`,`cancelled`];function Ze(e){return Xe.includes(e)}const Qe=[`text`,`json`,`compact`],$e={done:`✓`,completed:`✓`,"in-progress":`►`,blocked:`⭕`,pending:`○`,deferred:`⏸`,cancelled:`✗`,review:`👁`};function et(){return process.env.TM_BASE_DOMAIN||process.env.TM_PUBLIC_BASE_DOMAIN||`https://tryhamster.com`}function tt(){return{baseUrl:et(),configDir:c.join(p.homedir(),`.taskmaster`),configFile:c.join(p.homedir(),`.taskmaster`,`auth.json`)}}function nt(e){return{...tt(),...e}}new Proxy({},{get(e,t){return tt()[t]}});var rt=class{logger=x(`OAuthService`);contextStore;supabaseClient;configOverrides;authorizationUrl=null;keyPair=null;get baseUrl(){return nt(this.configOverrides).baseUrl}constructor(e,t,n={}){this.contextStore=e,this.supabaseClient=t,this.configOverrides=n}async authenticate(e={}){let{openBrowser:t,timeout:n=3e5,onAuthUrl:r,onWaitingForAuth:i,onSuccess:a,onError:o}=e;try{return await this.authenticateWithBackendPKCE({openBrowser:t,timeout:n,onAuthUrl:r,onWaitingForAuth:i,onSuccess:a})}catch(e){let t=e instanceof S?e:new S(`OAuth authentication failed: ${e.message}`,`OAUTH_FAILED`,e);throw o&&t.code!==`MFA_REQUIRED`&&o(t),t}}async authenticateWithBackendPKCE(e){let{openBrowser:t,timeout:n=3e5,onAuthUrl:r,onWaitingForAuth:i,onSuccess:a}=e;this.keyPair=Pe(),this.logger.debug(`Generated RSA keypair for E2E encryption`);let o=await this.startBackendFlow();if(!o.success||!o.flow_id)throw new S(o.message||`Failed to start authentication flow`,`START_FLOW_FAILED`);let{flow_id:s,verification_url:c,poll_interval:l=2}=o;if(this.authorizationUrl=c||null,r&&c&&r(c),t&&c)try{await t(c),this.logger.debug(`Browser opened successfully with URL:`,c)}catch(e){this.logger.warn(`Failed to open browser automatically:`,e)}i&&i();let u=await this.pollForCompletion(s,l*1e3,n);u.refreshToken||this.logger.warn(`No refresh token received from server - session refresh will not work`);let d={access_token:u.token,refresh_token:u.refreshToken??``,expires_in:u.expiresAt?Math.floor((new Date(u.expiresAt).getTime()-Date.now())/1e3):3600,token_type:`bearer`,user:{id:u.userId,email:u.email,app_metadata:{},user_metadata:{},aud:`authenticated`,created_at:``}};return await this.supabaseClient.setSession(d),this.contextStore.saveContext({userId:u.userId,email:u.email}),await this.checkAndThrowIfMFARequired(),a&&a(u),u}async startBackendFlow(){let e=`${this.baseUrl}/api/auth/cli/start`;if(!this.keyPair)throw new S(`Keypair not generated before starting flow`,`INTERNAL_ERROR`);try{let t=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,"User-Agent":`TaskMasterCLI/${this.getCliVersion()}`},body:JSON.stringify({name:`Task Master CLI`,version:this.getCliVersion(),device:p.hostname(),user:p.userInfo().username,platform:p.platform(),public_key:this.keyPair.publicKey})});if(!t.ok)throw new S((await t.json().catch(()=>({}))).message||`HTTP ${t.status}`,`START_FLOW_FAILED`);return await t.json()}catch(e){throw e instanceof S?e:(this.logger.warn(`Failed to reach backend for PKCE flow:`,e),new S(`Unable to reach authentication server`,`BACKEND_UNREACHABLE`,e))}}async pollForCompletion(e,t,n){let r=`${this.baseUrl}/api/auth/cli/status?flow_id=${e}`,i=Date.now();if(!this.keyPair)throw new S(`Keypair not available for decryption`,`INTERNAL_ERROR`);for(;Date.now()-i<n;){try{let e=await fetch(r,{method:`GET`,headers:{"User-Agent":`TaskMasterCLI/${this.getCliVersion()}`}});if(!e.ok){let t=await e.json().catch(()=>({}));throw e.status===404?new S(`Authentication flow expired or not found`,`FLOW_NOT_FOUND`):new S(t.message||`HTTP ${e.status}`,`POLL_FAILED`)}let t=await e.json();if(!t.success)throw new S(t.message||`Failed to check status`,`POLL_FAILED`);switch(t.status){case`complete`:{if(!t.encrypted_tokens)throw new S(`Server returned no encrypted tokens`,`MISSING_TOKENS`);let e=Fe(t.encrypted_tokens,this.keyPair.privateKey);return this.logger.debug(`Successfully decrypted authentication tokens`),{token:e.access_token,refreshToken:e.refresh_token,userId:e.user_id,email:e.email,expiresAt:e.expires_in?new Date(Date.now()+e.expires_in*1e3).toISOString():void 0,tokenType:`standard`,savedAt:new Date().toISOString()}}case`failed`:throw new S(t.error_description||t.error||`Authentication failed`,`OAUTH_FAILED`);case`expired`:throw new S(`Authentication flow expired`,`AUTH_TIMEOUT`);case`pending`:case`authenticating`:this.logger.debug(`Flow status: ${t.status}, continuing to poll`);break;default:this.logger.warn(`Unknown flow status: ${t.status}`)}}catch(e){if(e instanceof S)throw e;this.logger.debug(`Poll request failed, will retry:`,e)}await new Promise(e=>setTimeout(e,t))}throw new S(`Authentication timeout`,`AUTH_TIMEOUT`)}getCliVersion(){return Je}getAuthorizationUrl(){return this.authorizationUrl}async checkAndThrowIfMFARequired(){let e=await this.supabaseClient.checkMFARequired();if(e.required)throw!e.factorId||!e.factorType?(this.logger.error(`MFA required but factor information is incomplete`,{mfaCheck:e}),new S(`MFA is required but the server returned incomplete factor configuration. Please contact support or try re-enrolling MFA.`,`MFA_REQUIRED_INCOMPLETE`)):(this.logger.info(`MFA verification required after OAuth login`,{factorId:e.factorId,factorType:e.factorType}),new S(`MFA verification required. Please provide your authentication code.`,`MFA_REQUIRED`,void 0,{factorId:e.factorId,factorType:e.factorType}))}},it=class{logger=x(`OrganizationService`);constructor(e){this.supabaseClient=e}async getOrganizations(){try{let{data:e,error:t}=await this.supabaseClient.from(`user_accounts`).select(`
3
3
  id,
4
4
  name,
5
5
  slug
@@ -1,4 +1,4 @@
1
- import{a as e,i as t,l as n,n as r,t as i}from"./ai-services-unified-D_pA4zzB.js";import{$ as a,A as o,At as s,B as c,Bt as l,C as u,Ct as d,D as f,Dn as p,En as m,Jt as h,Kt as g,L as _,Lt as v,Mt as y,O as b,On as x,Ot as S,R as C,Rt as w,S as T,Tn as E,Tt as D,X as O,Xt as k,Y as A,Yt as j,Z as M,Zt as N,_ as P,_n as ee,a as te,an as ne,bt as re,cn as ie,ct as ae,dn as F,dt as oe,en as se,et as ce,f as le,fn as ue,ft as de,g as fe,gn as pe,gt as me,h as he,hn as ge,ht as _e,i as ve,it as ye,j as be,jn as xe,kn as Se,kt as Ce,ln as I,lt as we,mn as Te,mt as Ee,n as De,nn as Oe,o as ke,on as Ae,p as je,pn as Me,pt as Ne,q as Pe,rt as Fe,sn as Ie,tt as Le,un as Re,ut as ze,v as Be,vn as Ve,vt as L,w as He,wt as Ue,xn as R,yn as We,yt as z}from"./config-manager-Dn_JApjY.js";import Ge,{resolve as Ke}from"node:path";import B from"chalk";import*as qe from"fs";import V from"fs";import H from"path";import Je from"os";import Ye from"node:fs/promises";import Xe from"node:fs";import Ze from"node:os";import{z as U}from"zod";import{spawn as Qe}from"child_process";import{fileURLToPath as $e}from"url";import{FastMCP as et}from"fastmcp";import{smoothStream as tt}from"ai";import W from"boxen";import nt from"readline";import{Command as G}from"commander";import rt from"figlet";import it from"gradient-string";import at from"terminal-link";import{marked as ot}from"marked";import{markedTerminal as st}from"marked-terminal";import ct from"turndown";import K from"cli-table3";import q from"inquirer";import J from"ora";import lt from"open";import ut,{Separator as dt}from"@inquirer/search";import ft from"process";import pt from"https";import mt from"cli-progress";import ht from"http";import gt from"fuse.js";import _t from"ajv";import vt from"ajv-formats";import yt from"gpt-tokens";import{LRUCache as bt}from"lru-cache";import"@streamparser/json";function xt(e,t,n){return(n?.color?B[n.color]:B.cyan)(at(e,t,{fallback:(e,t)=>`${e} (${t})`}))}function St(e,t){return xt(e,e,t)}const Ct=it([`#00b4d8`,`#0077b6`,`#03045e`]);function wt(){return process.env.TM_HIDE_BANNER===`true`}function Tt(){return process.stdout.columns||80}function Et(e={}){if(wt())return;let{version:t}=e;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Ct(e))}catch{console.log(Ct(`=== Task Master ===`))}let n=xt(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`),r=B.dim(`by `)+B.cyan(n),i=t?t.replace(/^v/,``):``,a=`https://github.com/eyaltoledano/claude-task-master/releases/tag/task-master-ai%40${i}`,o=t?xt(`v${i}`,a,{color:`gray`}):``;if(o){let e=i.length+1,t=Tt(),n=Math.max(2,t-22-e-2);console.log(r+` `.repeat(n)+o)}else console.log(r);let s=xt(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(s)),console.log(``)}function Dt(){if(wt())return;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Ct(e))}catch{console.log(Ct(`=== Task Master ===`))}let e=xt(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`);console.log(B.dim(`by `)+B.cyan(e));let t=xt(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(t)),console.log(``)}function Ot(e){let{header:t,body:n,callToAction:r,footer:i,level:a=`warn`}=e,o=a===`info`?B.blue.bold:B.yellow.bold,s=a===`info`?`blue`:`yellow`,c=[o(t),...n.map(e=>B.white(e))];return r&&r.label&&r.action&&c.push(B.cyan(r.label)+`
1
+ import{a as e,i as t,l as n,n as r,t as i}from"./ai-services-unified-DZEwiMzn.js";import{$ as a,A as o,At as s,B as c,Bt as l,C as u,Ct as d,D as f,Dn as p,En as m,Jt as h,Kt as g,L as _,Lt as v,Mt as y,O as b,On as x,Ot as S,R as C,Rt as w,S as T,Tn as E,Tt as D,X as O,Xt as k,Y as A,Yt as j,Z as M,Zt as N,_ as P,_n as ee,a as te,an as ne,bt as re,cn as ie,ct as ae,dn as F,dt as oe,en as se,et as ce,f as le,fn as ue,ft as de,g as fe,gn as pe,gt as me,h as he,hn as ge,ht as _e,i as ve,it as ye,j as be,jn as xe,kn as Se,kt as Ce,ln as I,lt as we,mn as Te,mt as Ee,n as De,nn as Oe,o as ke,on as Ae,p as je,pn as Me,pt as Ne,q as Pe,rt as Fe,sn as Ie,tt as Le,un as Re,ut as ze,v as Be,vn as Ve,vt as L,w as He,wt as Ue,xn as R,yn as We,yt as z}from"./config-manager-CynteFcs.js";import Ge,{resolve as Ke}from"node:path";import B from"chalk";import*as qe from"fs";import V from"fs";import H from"path";import Je from"os";import Ye from"node:fs/promises";import Xe from"node:fs";import Ze from"node:os";import{z as U}from"zod";import{spawn as Qe}from"child_process";import{fileURLToPath as $e}from"url";import{FastMCP as et}from"fastmcp";import{smoothStream as tt}from"ai";import W from"boxen";import nt from"readline";import{Command as G}from"commander";import rt from"figlet";import it from"gradient-string";import at from"terminal-link";import{marked as ot}from"marked";import{markedTerminal as st}from"marked-terminal";import ct from"turndown";import K from"cli-table3";import q from"inquirer";import J from"ora";import lt from"open";import ut,{Separator as dt}from"@inquirer/search";import ft from"process";import pt from"https";import mt from"cli-progress";import ht from"http";import gt from"fuse.js";import _t from"ajv";import vt from"ajv-formats";import yt from"gpt-tokens";import{LRUCache as bt}from"lru-cache";import"@streamparser/json";function xt(e,t,n){return(n?.color?B[n.color]:B.cyan)(at(e,t,{fallback:(e,t)=>`${e} (${t})`}))}function St(e,t){return xt(e,e,t)}const Ct=it([`#00b4d8`,`#0077b6`,`#03045e`]);function wt(){return process.env.TM_HIDE_BANNER===`true`}function Tt(){return process.stdout.columns||80}function Et(e={}){if(wt())return;let{version:t}=e;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Ct(e))}catch{console.log(Ct(`=== Task Master ===`))}let n=xt(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`),r=B.dim(`by `)+B.cyan(n),i=t?t.replace(/^v/,``):``,a=`https://github.com/eyaltoledano/claude-task-master/releases/tag/task-master-ai%40${i}`,o=t?xt(`v${i}`,a,{color:`gray`}):``;if(o){let e=i.length+1,t=Tt(),n=Math.max(2,t-22-e-2);console.log(r+` `.repeat(n)+o)}else console.log(r);let s=xt(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(s)),console.log(``)}function Dt(){if(wt())return;try{let e=rt.textSync(`Task Master`,{font:`Standard`,horizontalLayout:`default`,verticalLayout:`default`});console.log(Ct(e))}catch{console.log(Ct(`=== Task Master ===`))}let e=xt(`x.com/eyaltoledano`,`https://x.com/eyaltoledano`);console.log(B.dim(`by `)+B.cyan(e));let t=xt(`tryhamster.com`,`https://tryhamster.com`);console.log(B.dim(`Taskmaster for teams: `)+B.magenta(t)),console.log(``)}function Ot(e){let{header:t,body:n,callToAction:r,footer:i,level:a=`warn`}=e,o=a===`info`?B.blue.bold:B.yellow.bold,s=a===`info`?`blue`:`yellow`,c=[o(t),...n.map(e=>B.white(e))];return r&&r.label&&r.action&&c.push(B.cyan(r.label)+`
2
2
  `+B.blue.underline(r.action)),i&&c.push(B.gray(i)),W(c.join(`
3
3
 
4
4
  `),{padding:1,borderColor:s,borderStyle:`round`,margin:{top:1,bottom:1}})}function kt(e,t=30,n){if(!n){let n=Math.round(e/100*t),r=t-n;return B.green(`█`).repeat(n)+B.gray(`░`).repeat(r)}let r=``,i=0;if(n.done&&n.done>0){let e=Math.round(n.done/100*t);e>0&&(r+=B.green(`█`).repeat(e),i+=e)}if(n.cancelled&&i<t){let e=Math.round(n.cancelled/100*t),a=Math.min(e,t-i);a>0&&(r+=B.gray(`█`).repeat(a),i+=a)}if(n.deferred&&i<t){let e=Math.round(n.deferred/100*t),a=Math.min(e,t-i);a>0&&(r+=B.gray(`█`).repeat(a),i+=a)}if(n[`in-progress`]&&i<t){let e=Math.round(n[`in-progress`]/100*t),a=Math.min(e,t-i);a>0&&(r+=B.blue(`█`).repeat(a),i+=a)}if(n.review&&i<t){let e=Math.round(n.review/100*t),a=Math.min(e,t-i);a>0&&(r+=B.magenta(`░`).repeat(a),i+=a)}if(n.pending&&i<t){let e=Math.round(n.pending/100*t),a=Math.min(e,t-i);a>0&&(r+=B.yellow(`░`).repeat(a),i+=a)}if(n.blocked&&i<t){let e=Math.round(n.blocked/100*t),a=Math.min(e,t-i);a>0&&(r+=B.red(`░`).repeat(a),i+=a)}return i<t&&(r+=B.yellow(`░`).repeat(t-i)),r}function At(e){let t={total:e.length,done:0,inProgress:0,pending:0,blocked:0,deferred:0,cancelled:0,review:0,completionPercentage:0,completedCount:0};return e.forEach(e=>{switch(e.status){case`done`:t.done++;break;case`in-progress`:t.inProgress++;break;case`pending`:t.pending++;break;case`blocked`:t.blocked++;break;case`deferred`:t.deferred++;break;case`cancelled`:t.cancelled++;break;case`review`:t.review=(t.review||0)+1;break}}),t.completedCount=e.filter(e=>We(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function jt(e){let t={total:0,done:0,inProgress:0,pending:0,blocked:0,deferred:0,cancelled:0,review:0,completionPercentage:0,completedCount:0},n=[];return e.forEach(e=>{e.subtasks&&e.subtasks.length>0&&e.subtasks.forEach(e=>{switch(t.total++,n.push(e),e.status){case`done`:t.done++;break;case`in-progress`:t.inProgress++;break;case`pending`:t.pending++;break;case`blocked`:t.blocked++;break;case`deferred`:t.deferred++;break;case`cancelled`:t.cancelled++;break;case`review`:t.review=(t.review||0)+1;break}})}),t.completedCount=n.filter(e=>We(e.status)).length,t.completionPercentage=t.total>0?Math.round(t.completedCount/t.total*100):0,t}function Mt(e){let t=new Set(e.filter(e=>We(e.status)).map(e=>e.id)),n=e.filter(e=>!We(e.status)&&(!e.dependencies||e.dependencies.length===0)).length,r=e.filter(e=>!We(e.status)&&e.dependencies&&e.dependencies.length>0&&e.dependencies.every(e=>t.has(e))).length,i=e.filter(e=>!We(e.status)&&e.dependencies&&e.dependencies.length>0&&!e.dependencies.every(e=>t.has(e))).length,a={};e.forEach(e=>{e.dependencies&&e.dependencies.length>0&&e.dependencies.forEach(e=>{let t=String(e);a[t]=(a[t]||0)+1})});let o,s=0;for(let[e,t]of Object.entries(a))t>s&&(s=t,o=parseInt(e));let c=e.reduce((e,t)=>e+(t.dependencies?t.dependencies.length:0),0),l=e.length>0?c/e.length:0;return{tasksWithNoDeps:n,tasksReadyToWork:n+r,tasksBlockedByDeps:i,mostDependedOnTaskId:o,mostDependedOnCount:s,avgDependenciesPerTask:l}}function Nt(e){let t={critical:0,high:0,medium:0,low:0};return e.forEach(e=>{let n=e.priority||`medium`;t[n]++}),t}function Pt(e){return e.total===0?{}:{done:e.done/e.total*100,"in-progress":e.inProgress/e.total*100,pending:e.pending/e.total*100,blocked:e.blocked/e.total*100,deferred:e.deferred/e.total*100,cancelled:e.cancelled/e.total*100,review:(e.review||0)/e.total*100}}function Ft(e,t=!1){let n=[];t?n.push(`Completed: ${B.green(`${e.completedCount}/${e.total}`)}`):n.push(`Done: ${B.green(e.done)}`),n.push(`Cancelled: ${B.gray(e.cancelled)}`),n.push(`Deferred: ${B.gray(e.deferred)}`);let r=n.join(` `);n.length=0,n.push(`In Progress: ${B.blue(e.inProgress)}`),n.push(`Review: ${B.magenta(e.review||0)}`),n.push(`Pending: ${B.yellow(e.pending)}`),n.push(`Blocked: ${B.red(e.blocked)}`);let i=n.join(` `);return r+`
@@ -867,7 +867,7 @@ ${B.cyan(`1.`)} Run ${B.yellow(`task-master next`)} to see what to work on next\
867
867
  ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks\n${B.cyan(`3.`)} Run ${B.yellow(`task-master analyze-complexity`)} to analyze task complexity`;console.log(W(e,Yo.nextSteps))}function cs(e){return Math.ceil(e.length/4)}function ls(e){let t=V.readFileSync(e,`utf8`);if(!t)throw Error(`Input file ${e} is empty or could not be read.`);return t}function us(e,t){let n=[],r=1;if(!V.existsSync(e))return{existingTasks:n,nextId:r};try{let i=V.readFileSync(e,`utf8`),a=JSON.parse(i);a[t]?.tasks&&Array.isArray(a[t].tasks)&&(n=a[t].tasks,n.length>0&&(r=Math.max(...n.map(e=>e.id||0))+1))}catch{return{existingTasks:[],nextId:1}}return{existingTasks:n,nextId:r}}function ds({existingTasks:e,targetTag:t,append:n,force:r,isMCP:i,logger:a}){if(!(e.length>0)){a.report(`Tag '${t}' is empty or doesn't exist. Creating/updating tag with new tasks.`,`info`);return}if(n){a.report(`Append mode enabled. Found ${e.length} existing tasks in tag '${t}'.`,`info`);return}if(!r){let n=`Tag '${t}' already contains ${e.length} tasks. Use --force to overwrite or --append to add to existing tasks.`;if(a.report(n,`error`),i)throw Error(n);console.error(B.red(n)),process.exit(1)}a.report(`Force flag enabled. Overwriting existing tasks in tag '${t}'.`,`debug`)}function fs(e,t,n,r){ps(e,t);let i=t,a=new Map,o=e.map(e=>{let t=i++;return a.set(e.id,t),{...e,id:t,status:e.status||`pending`,priority:e.priority||r,dependencies:Array.isArray(e.dependencies)?e.dependencies:[],subtasks:e.subtasks||[],title:e.title||``,description:e.description||``,details:e.details||``,testStrategy:e.testStrategy||``}});return o.forEach(e=>{e.dependencies=e.dependencies.map(e=>a.get(e)).filter(t=>t!=null&&t<e.id&&(oe(n,t)||o.some(e=>e.id===t)))}),o}function ps(e,t=1){if(!Array.isArray(e)||e.length===0)return;let n=e.map(e=>e.id);if(n.some(e=>!Number.isInteger(e)||e<1))throw Error(`PRD tasks must use sequential positive integer IDs starting at 1.`);let r=new Set(n);if(r.size!==n.length)throw Error(`PRD task IDs must be unique and sequential starting at 1.`);let i=[...r].sort((e,t)=>e-t),a=i[0];if(a!==1&&a!==t)throw Error(`PRD task IDs must start at 1 or ${t} and be sequential.`);for(let e=0;e<i.length;e+=1)if(i[e]!==a+e)throw Error(`PRD task IDs must be a contiguous sequence starting at ${a}.`)}function ms(e,t,n,r){let i=H.dirname(e);V.existsSync(i)||V.mkdirSync(i,{recursive:!0});let a={};if(V.existsSync(e))try{let t=V.readFileSync(e,`utf8`);a=JSON.parse(t)}catch{a={}}a[n]={tasks:t,metadata:{created:a[n]?.metadata?.created||new Date().toISOString(),updated:new Date().toISOString(),description:`Tasks for ${n} context`}},ae(a[n],{description:`Tasks for ${n} context`}),V.writeFileSync(e,JSON.stringify(a,null,2)),r.report(`Successfully saved ${t.length} tasks to ${e}`,`debug`)}async function hs(e,t,n){let r=Da(),i=he(e.projectRoot)||`medium`;return r.loadPrompt(`parse-prd`,{research:e.research,numTasks:e.numTasks,nextId:n,prdContent:t,prdPath:e.prdPath,defaultTaskPriority:i,hasCodebaseAnalysis:e.hasCodebaseAnalysis(),projectRoot:e.projectRoot||``})}async function gs({task:e,currentCount:t,totalTasks:n,estimatedTokens:r,progressTracker:i,reportProgress:a,priorityMap:o,defaultPriority:s,estimatedInputTokens:c}){let l=e.priority||s,u=o[l]||o.medium;if(i&&(i.addTaskLine(t,e.title,l),r&&i.updateTokens(c,r)),a)try{let i=r?Math.floor(r/n):0;await a({progress:t,total:n,message:`${u} Task ${t}/${n} - ${e.title} | ~Output: ${i} tokens`})}catch{}}async function _s({processedTasks:e,nextId:t,summary:n,prdPath:r,tasksPath:i,usedFallback:a,aiServiceResponse:o}){let s=(()=>{if(!Array.isArray(e)||e.length===0)return`task_${String(t).padStart(3,`0`)}.txt`;let n=e[0].id,r=e[e.length-1].id;return e.length===1?`task_${String(n).padStart(3,`0`)}.txt`:`task_${String(n).padStart(3,`0`)}.txt -> task_${String(r).padStart(3,`0`)}.txt`})();as({totalTasks:e.length,taskPriorities:n.taskPriorities,prdFilePath:r,outputPath:i,elapsedTime:n.elapsedTime,usedFallback:a,taskFilesGenerated:s,actionVerb:n.actionVerb}),o?.telemetryData&&(o.mainResult?.usage&&await Bo.withSoftTimeout(o.mainResult.usage,1e3,void 0),Sl(o.telemetryData,`cli`))}function vs({processedTasks:e,research:t,finalTasks:n,tasksPath:r,aiServiceResponse:i}){console.log(W(B.green(`Successfully generated ${e.length} new tasks${t?` with research-backed analysis`:``}. Total tasks in ${r}: ${n.length}`),{padding:1,borderColor:`green`,borderStyle:`round`})),console.log(W(B.white.bold(`Next Steps:`)+`
868
868
 
869
869
  ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(`2.`)} Run ${B.yellow(`task-master expand --id=<id>`)} to break down a task into subtasks`,{padding:1,borderColor:`cyan`,borderStyle:`round`,margin:{top:1}})),i?.telemetryData&&Sl(i.telemetryData,`cli`)}async function ys(e,t){let n=new Go(e.mcpLog,e.reportProgress),{systemPrompt:r,userPrompt:a}=t,o=cs(r+a),s=null;e.outputFormat===`text`&&!e.isMCP&&(s=J(`Parsing PRD and generating tasks...
870
- `).start());try{n.report(`Calling AI service to generate tasks from PRD${e.research?` with research-backed analysis`:``}...`,`info`);let t=await i({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Uo,objectName:`tasks_data`,systemPrompt:r,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),c=null;if(t?.mainResult&&(typeof t.mainResult==`object`&&t.mainResult!==null&&`tasks`in t.mainResult?c=t.mainResult:typeof t.mainResult.object==`object`&&t.mainResult.object!==null&&`tasks`in t.mainResult.object&&(c=t.mainResult.object)),!c||!Array.isArray(c.tasks))throw Error(`AI service returned unexpected data structure after validation.`);return s&&s.succeed(`Tasks generated successfully!`),{parsedTasks:c.tasks,aiServiceResponse:t,estimatedInputTokens:o}}catch(e){throw s&&s.fail(`Error parsing PRD: ${e.message}`),e}}const[bs,xs,Ss]=Qi,Cs=new Map;var ws=class{constructor(e,t,n,r=null){this.name=e,this.levels=t,this.colors=n,this.thresholds=r}getColor(e){return this.colors[e]||B.gray}getLevelFromScore(e){if(!this.thresholds)throw Error(`${this.name} does not support score-based levels`);return e>=7?this.levels[0]:e<=3?this.levels[2]:this.levels[1]}};const Ts={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},Es=new ws(`priority`,[bs,xs,Ss],{[bs]:B.hex(`#CC0000`),[xs]:B.hex(`#FF8800`),[Ss]:B.yellow});function Ds(e,t){let n=Ts.cli.filled,r=Ts.cli.empty,i=``;for(let a=0;a<3;a++)a<e?i+=t(n):i+=B.white(r);return i}function Os(e,t){return 3-t.indexOf(e)}function ks(e,t){if(Cs.has(e))return Cs.get(e);let n=t();return Cs.set(e,n),n}function As(){return ks(`mcp-priority-all`,()=>({[bs]:Ts.mcp.high,[xs]:Ts.mcp.medium,[Ss]:Ts.mcp.low}))}function js(){return ks(`cli-priority-all`,()=>{let e={};return Es.levels.forEach(t=>{e[t]=Ds(Os(t,Es.levels),Es.getColor(t))}),e})}function Ms(){return ks(`statusbar-priority-all`,()=>{let e={};return Es.levels.forEach((t,n)=>{let r=n===0?Ts.statusBar.high:n===1?Ts.statusBar.medium:Ts.statusBar.low;e[t]=Es.getColor(t)(r)}),e})}function Ns(){return{[bs]:Es.colors[bs],[xs]:Es.colors[xs],[Ss]:Es.colors[Ss]}}function Ps(e=!1){return e?As():js()}function Fs(e,t=!1){let n=Ps(t);return n[e]||n[xs]}new ws(`complexity`,[`high`,`medium`,`low`],{high:B.hex(`#CC0000`),medium:B.hex(`#FF8800`),low:B.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const Is={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},Ls={shades_classic:mt.Presets.shades_classic,shades_grey:mt.Presets.shades_grey,rect:mt.Presets.rect,legacy:mt.Presets.legacy},Rs=new class{constructor(e={},t=Ls.shades_classic){this.defaultOptions={...Is,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function zs(e={}){return Rs.createMultiBar(e)}var Bs=class{constructor(e={}){this.numUnits=e.numUnits||1,this.unitName=e.unitName||`unit`,this.startTime=null,this.completedUnits=0,this.tokensIn=0,this.tokensOut=0,this.isEstimate=!0,this.bestAvgTimePerUnit=null,this.lastEstimateTime=null,this.lastEstimateSeconds=0,this.multibar=null,this.timeTokensBar=null,this.progressBar=null,this._timerInterval=null,this.isStarted=!1,this.isFinished=!1,this._initializeCustomProperties(e)}_initializeCustomProperties(e){}get unitNamePlural(){return`${this.unitName}s`}start(){this.isStarted||this.isFinished||(this.isStarted=!0,this.startTime=Date.now(),this.multibar=zs(),this.timeTokensBar=this.multibar.create(1,0,{},{format:this._getTimeTokensBarFormat(),barsize:1,hideCursor:!0,clearOnComplete:!1}),this.progressBar=this.multibar.create(this.numUnits,0,{},{format:this._getProgressBarFormat(),barCompleteChar:`█`,barIncompleteChar:`░`}),this._updateTimeTokensBar(),this.progressBar.update(0,{[this.unitNamePlural]:`0/${this.numUnits}`}),this._timerInterval=setInterval(()=>this._updateTimeTokensBar(),1e3),this._setupCustomUI())}_setupCustomUI(){}_getTimeTokensBarFormat(){return`{clock} {elapsed} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`${this.unitName.charAt(0).toUpperCase()+this.unitName.slice(1)}s {${this.unitNamePlural}} |{bar}| {percentage}%`}updateTokens(e,t,n=!1){this.tokensIn=e||0,this.tokensOut=t||0,this.isEstimate=n,this._updateTimeTokensBar()}_updateTimeTokensBar(){if(!this.timeTokensBar||this.isFinished)return;let e=this._formatElapsedTime(),t=this._estimateRemainingTime(),n=this.isEstimate?`~ Tokens (I/O)`:`Tokens (I/O)`;this.timeTokensBar.update(1,{clock:`⏱️`,elapsed:e,in:this.tokensIn,out:this.tokensOut,remaining:t,tokensLabel:n,...this._getCustomTimeTokensPayload()})}_getCustomTimeTokensPayload(){return{}}_formatElapsedTime(){if(!this.startTime)return`0m 00s`;let e=Math.floor((Date.now()-this.startTime)/1e3);return`${Math.floor(e/60)}m ${(e%60).toString().padStart(2,`0`)}s`}_estimateRemainingTime(){let e=this._getProgressFraction();if(e>=1)return`~0s`;let t=Date.now(),n=(t-this.startTime)/1e3;if(e===0)return`~calculating...`;let r=n/e;(this.bestAvgTimePerUnit===null||r<this.bestAvgTimePerUnit)&&(this.bestAvgTimePerUnit=r);let i=this.numUnits*(1-e),a=Math.ceil(i*this.bestAvgTimePerUnit);if(this.lastEstimateTime){let e=Math.floor((t-this.lastEstimateTime)/1e3),n=Math.max(0,this.lastEstimateSeconds-e);if(n===0)return`~0s`;a=Math.min(a,n)}return this.lastEstimateTime=t,this.lastEstimateSeconds=a,`~${this._formatDuration(a)}`}_getProgressFraction(){return this.completedUnits/this.numUnits}_formatDuration(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return t<60?n>0?`${t}m ${n}s`:`${t}m`:`${Math.floor(t/60)}h ${t%60}m`}getElapsedTime(){return this.startTime?Date.now()-this.startTime:0}stop(){this.isFinished||(this.isFinished=!0,this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar&&(this._updateTimeTokensBar(),this.multibar.stop()),this.cleanup())}getSummary(){return{completedUnits:this.completedUnits,elapsedTime:this.getElapsedTime()}}cleanup(){if(this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar){try{this.multibar.stop()}catch{}this.multibar=null}this.timeTokensBar=null,this.progressBar=null,this.isStarted=!1,this.isFinished=!0,this._performCustomCleanup()}_performCustomCleanup(){}},Vs=class{constructor(e){if(!e)throw Error(`Multibar instance is required`);this.multibar=e}createBar(e,t={}){if(typeof e!=`string`)throw Error(`Format must be a string`);let n=this.multibar.create(1,1,{},{format:e,barsize:1,hideCursor:!0,clearOnComplete:!1});return n.update(1,t),n}createHeader(e,t){this.createBar(t),this.createBar(e),this.createBar(t)}createRow(e,t){if(!t||typeof t!=`object`)throw Error(`Payload must be an object`);return this.createBar(e,t)}createBorder(e){return this.createBar(e)}};function Hs(e,t,n){new Vs(e).createHeader(t,n)}function Us(e,t,n){new Vs(e).createRow(t,n)}function Ws(e,t){new Vs(e).createBorder(t)}js();const Gs=Ms();Ns();const Ks={DEBOUNCE_DELAY:100,MAX_TITLE_LENGTH:57,TRUNCATED_LENGTH:54,TASK_ID_PAD_START:3,TASK_ID_PAD_END:4,PRIORITY_PAD_END:3,VALID_PRIORITIES:[`high`,`medium`,`low`],DEFAULT_PRIORITY:`medium`};var qs=class{constructor(e=Ks.DEBOUNCE_DELAY){this.delay=e,this.pendingTimeout=null}debounce(e){this.clear(),this.pendingTimeout=setTimeout(()=>{e(),this.pendingTimeout=null},this.delay)}clear(){this.pendingTimeout&&=(clearTimeout(this.pendingTimeout),null)}hasPending(){return this.pendingTimeout!==null}},Js=class{constructor(){this.priorities={high:0,medium:0,low:0}}increment(e){let t=this.normalize(e);return this.priorities[t]++,t}normalize(e){let t=e?e.toLowerCase():Ks.DEFAULT_PRIORITY;return Ks.VALID_PRIORITIES.includes(t)?t:Ks.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Ys=class{static formatTitle(e,t){return e?e.length>Ks.MAX_TITLE_LENGTH?e.substring(0,Ks.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return Fs(e,!1).padEnd(Ks.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(Ks.TASK_ID_PAD_START,` `).padEnd(Ks.TASK_ID_PAD_END,` `)}},Xs=class extends Bs{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new Js,this.debouncer=new qs,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${Gs.high} {high} ${Gs.medium} {medium} ${Gs.low} {low} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`Tasks {tasks} |{bar}| {percentage}%`}_getCustomTimeTokensPayload(){return this.priorityManager.getCounts()}addTaskLine(e,t,n=`medium`){if(!this.multibar||this.isFinished)return;this._ensureHeaderShown();let r=this._updateTaskCounters(e,n);this._updateTimeTokensBar(),this.debouncer.debounce(()=>{this._updateProgressDisplay(e,t,r)})}_ensureHeaderShown(){this.headerShown||(this.headerShown=!0,Hs(this.multibar,` TASK | PRI | TITLE`,`------+-----+----------------------------------------------------------------`))}_updateTaskCounters(e,t){let n=this.priorityManager.increment(t);return this.completedUnits=e,n}_updateProgressDisplay(e,t,n){this.progressBar.update(this.completedUnits,{tasks:`${this.completedUnits}/${this.numUnits}`});let r=Ys.formatTitle(t,e),i=Ys.formatPriority(n),a=Ys.formatTaskId(e);Us(this.multibar,` ${a} | ${i} | {title}`,{title:r}),Ws(this.multibar,`------+-----+----------------------------------------------------------------`),this._updateTimeTokensBar()}finish(){this.debouncer.hasPending()&&(this.debouncer.clear(),this._updateTimeTokensBar()),this.cleanup(),super.finish()}_performCustomCleanup(){this.debouncer.clear()}getSummary(){return{...super.getSummary(),taskPriorities:this.priorityManager.getCounts(),actionVerb:this.append?`appended`:`generated`}}};function Zs(e={}){return new Xs(e)}async function Qs(e,t,n){let r=$s(e,t,n);await tc(e,n,r.estimatedInputTokens);let i=await nc(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await rc(e,n),s=await ic(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(ec(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-DYXlveV4.js`),{getUserId:n}=await import(`./config-manager-BiA1Lh9-.js`),a=n(e.projectRoot);if(a&&i.providerName&&i.modelId)try{let n=await t({userId:a,commandName:`parse-prd`,providerName:i.providerName,modelId:i.modelId,inputTokens:s.usage.promptTokens||0,outputTokens:s.usage.completionTokens||0,outputType:e.isMCP?`mcp`:`cli`});n&&(i.telemetryData=n)}catch(e){r.logger.report(`Failed to log telemetry: ${e.message}`,`debug`)}}return mc(s,i,r.estimatedInputTokens,a)}function $s(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new Go(e.mcpLog,e.reportProgress),estimatedInputTokens:cs(r+i),defaultPriority:he(e.projectRoot)||`medium`}}function ec(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function tc(e,t,n){e.reportProgress&&await e.reportProgress({progress:0,total:t,message:`Starting PRD analysis (Input: ${n} tokens)${e.research?` with research`:``}...`})}async function nc(e,n,r){let{systemPrompt:i,userPrompt:a}=n;return await Bo.withTimeout(t({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Uo,systemPrompt:i,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),r,`Streaming operation`)}async function rc(e,t){let n=Ps(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Zs({numUnits:t,unitName:`task`,append:e.append});let n=e.research?o():T(),i=f(e.research?`research`:`main`);es({prdFilePath:e.prdPath,outputPath:e.tasksPath,numTasks:t,append:e.append,research:e.research,force:e.force,existingTasks:[],nextId:1,model:n||`Default`,temperature:i?.temperature||.7}),r.start()}return{progressTracker:r,priorityMap:n}}async function ic(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:Uo},numTasks:r,progressTracker:i,priorityMap:a,defaultPriority:o,estimatedInputTokens:s,prompt:u,systemPrompt:l};try{let t={lastPartialObject:null,taskCount:0,estimatedOutputTokens:0,usage:null};if(await ac(e.partialObjectStream,t,d),e.usage)try{t.usage=await e.usage}catch(e){c.report(`Failed to get usage data: ${e.message}`,`debug`)}return lc(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await pc(d,c)}}async function ac(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=cs(JSON.stringify(r))),await oc(r,t,n)}async function oc(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await sc(e.tasks,t.taskCount,r,t.estimatedOutputTokens,n),t.taskCount=r):n.progressTracker&&t.estimatedOutputTokens>0&&n.progressTracker.updateTokens(n.estimatedInputTokens,t.estimatedOutputTokens,!0)}async function sc(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await gs({task:t,currentCount:a+1,totalTasks:i.numTasks,estimatedTokens:r,progressTracker:i.progressTracker,reportProgress:i.config.reportProgress,priorityMap:i.priorityMap,defaultPriority:i.defaultPriority,estimatedInputTokens:i.estimatedInputTokens}):await cc(a+1,r,i)}}async function cc(e,t,n){let{progressTracker:r,config:i,numTasks:a,defaultPriority:o,estimatedInputTokens:s}=n;r&&(r.addTaskLine(e,`Generating task ${e}...`,o),r.updateTokens(s,t,!0)),i.reportProgress&&!r&&await i.reportProgress({progress:e,total:a,message:`Generating task ${e}/${a}...`})}async function lc(e,t){let{lastPartialObject:n,estimatedOutputTokens:r,taskCount:i,usage:a}=e;if(!n?.tasks||!Array.isArray(n.tasks))throw Error(`No tasks generated from streamObject`);let o=a?.completionTokens||r,s=a?.promptTokens||t.estimatedInputTokens;return t.progressTracker&&await uc(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function uc(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?dc(e,a,o):await fc(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function dc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&t.addTaskLine(r+1,i.title,i.priority||n)}}async function fc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await gs({task:i,currentCount:r+1,totalTasks:n.numTasks,estimatedTokens:t,progressTracker:n.progressTracker,reportProgress:n.config.reportProgress,priorityMap:n.priorityMap,defaultPriority:n.defaultPriority,estimatedInputTokens:n.estimatedInputTokens})}}async function pc(e,t){if(t.report(`Using generateObject fallback for PRD parsing`,`info`),e.progressTracker)for(let t=0;t<e.numTasks;t++)e.progressTracker.addTaskLine(t+1,`Generating task ${t+1}...`,e.defaultPriority),e.progressTracker.updateTokens(e.estimatedInputTokens,0,!0);let n=await i({role:e.config.research?`research`:`main`,commandName:`parse-prd`,prompt:e.prompt,systemPrompt:e.systemPrompt,schema:e.config.schema,outputFormat:e.config.outputFormat||`text`,projectRoot:e.config.projectRoot,session:e.config.session}),r=n?.mainResult||n;if(r&&Array.isArray(r.tasks)&&(r.tasks=r.tasks.map(e=>({...e,dependencies:e.dependencies??[],priority:e.priority??null,details:e.details??null,testStrategy:e.testStrategy??null}))),r&&Array.isArray(r.tasks)){if(e.progressTracker){for(let t=0;t<r.tasks.length;t++){let n=r.tasks[t];n&&n.title&&e.progressTracker.addTaskLine(t+1,n.title,n.priority||e.defaultPriority)}let t=n.telemetryData?.outputTokens||cs(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||cs(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function mc(e,t,n,r){let i=null;if(r&&(i=r.getSummary(),r.cleanup()),e.usage&&t){let n=e.usage;t.usage||={promptTokens:n.promptTokens||0,completionTokens:n.completionTokens||0,totalTokens:n.totalTokens||0}}return{parsedTasks:e.parsedTasks,aiServiceResponse:t,estimatedInputTokens:e.actualInputTokens||n,estimatedOutputTokens:e.estimatedOutputTokens,usedFallback:e.usedFallback,progressTracker:r,summary:i}}async function hc(e,t,n){let r=new Go(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let{existingTasks:i,nextId:a}=us(e.tasksPath,e.targetTag);ds({existingTasks:i,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let o=await t(e,await hs(e,ls(e.prdPath),a),e.numTasks),s=he(e.projectRoot)||`medium`,c=fs(o.parsedTasks,a,i,s),l=e.append?[...i,...c]:c;return ms(e.tasksPath,l,e.targetTag,r),await gc(e,o,c,l,a,n),{success:!0,tasksPath:e.tasksPath,telemetryData:o.aiServiceResponse?.telemetryData,tagInfo:o.aiServiceResponse?.tagInfo}}catch(t){throw r.report(`Error parsing PRD: ${t.message}`,`error`),e.isMCP||(console.error(B.red(`Error: ${t.message}`)),je(e.projectRoot)&&console.error(t)),t}}async function gc(e,t,n,r,i,a){let{aiServiceResponse:o,estimatedInputTokens:s,estimatedOutputTokens:c}=t;if(e.reportProgress){let t=o?.telemetryData&&(o.telemetryData.inputTokens>0||o.telemetryData.outputTokens>0),n;if(t){let e=o.telemetryData.totalCost||0,t=o.telemetryData.currency||`USD`;n=`✅ Task Generation Completed | Tokens (I/O): ${o.telemetryData.inputTokens}/${o.telemetryData.outputTokens} | Cost: ${t===`USD`?`$`:t}${e.toFixed(4)}`}else n=`✅ Task Generation Completed | ~Tokens (I/O): ${s}/${a?c:`unknown`} | Cost: ~$0.00`;await e.reportProgress({progress:e.numTasks,total:e.numTasks,message:n})}e.outputFormat===`text`&&!e.isMCP&&(a&&t.summary?await _s({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||vs({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function _c(e,t,n,r={}){return hc(new Wo(e,t,n,r),Qs,!0)}async function vc(e,t,n,r={}){return hc(new Wo(e,t,n,r),ys,!1)}async function yc(e,t,n,r={}){let i=new Wo(e,t,n,r);if(i.useStreaming)try{return await _c(e,t,n,r)}catch(a){if(a instanceof Ro||a.code===zo.NOT_ASYNC_ITERABLE||a.code===zo.STREAM_PROCESSING_FAILED||a.code===zo.STREAM_NOT_ITERABLE||Bo.isTimeoutError(a)){let o=new Go(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(B.yellow(`⚠️ Streaming operation ${a.message.includes(`timed out`)?`timed out`:`failed`}. Falling back to non-streaming mode...`)):o.report(`Streaming failed (${a.message}), falling back to non-streaming mode...`,`warn`),await vc(e,t,n,r)}else throw a}else return await vc(e,t,n,r)}var bc=yc;async function xc(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{z(`info`,`Removing subtask ${t}...`);let r=D(e,a,o);if(!r||!r.tasks)throw Error(`Invalid or missing tasks file at ${e}`);if(!t.includes(`.`))throw Error(`Invalid subtask ID format: ${t}. Expected format: "parentId.subtaskId"`);let[i,s]=t.split(`.`),c=parseInt(i,10),l=parseInt(s,10),u=r.tasks.find(e=>e.id===c);if(!u)throw Error(`Parent task with ID ${c} not found`);if(!u.subtasks||u.subtasks.length===0)throw Error(`Parent task ${c} has no subtasks`);let d=u.subtasks.findIndex(e=>e.id===l);if(d===-1)throw Error(`Subtask ${t} not found`);let f={...u.subtasks[d]};u.subtasks.splice(d,1),u.subtasks.length===0&&(u.subtasks=void 0);let p=null;if(n){z(`info`,`Converting subtask ${t} to a standalone task...`);let e=Math.max(...r.tasks.map(e=>e.id))+1;p={id:e,title:f.title,description:f.description||``,details:f.details||``,status:f.status||`pending`,dependencies:f.dependencies||[],priority:u.priority||`medium`},p.dependencies.includes(c)||p.dependencies.push(c),r.tasks.push(p),z(`info`,`Created new task ${e} from subtask ${t}`)}else z(`info`,`Subtask ${t} deleted`);return y(e,r,a,o),p}catch(e){throw z(`error`,`Error removing subtask: ${e.message}`),e}}var Sc=xc;function Cc(e,t){if(typeof t==`string`&&t.includes(`.`)){let n=t.split(`.`);if(n.length!==2||!n[0]||!n[1]){let n=parseInt(t,10);return e.some(e=>e.id===n)}let[r,i]=n,a=parseInt(r,10),o=parseInt(i,10),s=e.find(e=>e.id===a);return s&&s.subtasks&&s.subtasks.some(e=>e.id===o)}let n=parseInt(t,10);return e.some(e=>e.id===n)}var wc=Cc;async function Tc(e,t,n={}){let{projectRoot:r,tag:i}=n,a={success:!0,messages:[],errors:[],removedTasks:[]},o=t.split(`,`).map(e=>e.trim()).filter(Boolean);if(o.length===0)return a.success=!1,a.errors.push(`No valid task IDs provided.`),a;try{let t=D(e,r,i);if(!t)throw Error(`Could not read tasks file at ${e}`);let n=t._rawTaggedData||t;if(!n[i]||!n[i].tasks)throw Error(`Tag '${i}' not found or has no tasks.`);let s=n[i].tasks,c=[];for(let e of o){if(!wc(s,e)){let t=`Task with ID ${e} in tag '${i}' not found or already removed.`;a.errors.push(t),a.success=!1;continue}try{if(typeof e==`string`&&e.includes(`.`)){let[t,n]=e.split(`.`).map(e=>parseInt(e,10)),r=s.find(e=>e.id===t);if(!r||!r.subtasks)throw Error(`Parent task ${t} or its subtasks not found for subtask ${e}`);let o=r.subtasks.findIndex(e=>e.id===n);if(o===-1)throw Error(`Subtask ${n} not found in parent task ${t}`);let c={...r.subtasks[o],parentTaskId:t};a.removedTasks.push(c),r.subtasks.splice(o,1),a.messages.push(`Successfully removed subtask ${e} from tag '${i}'`)}else{let t=parseInt(e,10),n=s.findIndex(e=>e.id===t);if(n===-1)throw Error(`Task with ID ${e} not found in tag '${i}'`);let r=s[n];a.removedTasks.push(r),c.push(t),s.splice(n,1),a.messages.push(`Successfully removed task ${e} from tag '${i}'`)}}catch(t){let n=`Error processing ID ${e}: ${t.message}`;a.errors.push(n),a.success=!1,z(`warn`,n)}}if(a.removedTasks.length>0){let t=new Set(o.map(e=>typeof e==`string`&&e.includes(`.`)?e:parseInt(e,10)));for(let e in n[i].tasks=s,n)Object.prototype.hasOwnProperty.call(n,e)&&n[e]&&n[e].tasks&&n[e].tasks.forEach(e=>{e.dependencies&&=e.dependencies.filter(e=>!t.has(e)),e.subtasks&&e.subtasks.forEach(n=>{n.dependencies&&=n.dependencies.filter(n=>!t.has(`${e.id}.${n}`)&&!t.has(n))})});y(e,n,r,i);for(let t of c){let n=H.join(H.dirname(e),`task_${t.toString().padStart(3,`0`)}.txt`);if(qe.existsSync(n))try{qe.unlinkSync(n),a.messages.push(`Deleted task file: ${n}`)}catch(e){let t=`Failed to delete task file ${n}: ${e.message}`;a.errors.push(t),a.success=!1,z(`warn`,t)}}}else a.errors.length===0&&a.messages.push(`No tasks found matching the provided IDs.`);let l=a.messages.join(`
870
+ `).start());try{n.report(`Calling AI service to generate tasks from PRD${e.research?` with research-backed analysis`:``}...`,`info`);let t=await i({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Uo,objectName:`tasks_data`,systemPrompt:r,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),c=null;if(t?.mainResult&&(typeof t.mainResult==`object`&&t.mainResult!==null&&`tasks`in t.mainResult?c=t.mainResult:typeof t.mainResult.object==`object`&&t.mainResult.object!==null&&`tasks`in t.mainResult.object&&(c=t.mainResult.object)),!c||!Array.isArray(c.tasks))throw Error(`AI service returned unexpected data structure after validation.`);return s&&s.succeed(`Tasks generated successfully!`),{parsedTasks:c.tasks,aiServiceResponse:t,estimatedInputTokens:o}}catch(e){throw s&&s.fail(`Error parsing PRD: ${e.message}`),e}}const[bs,xs,Ss]=Qi,Cs=new Map;var ws=class{constructor(e,t,n,r=null){this.name=e,this.levels=t,this.colors=n,this.thresholds=r}getColor(e){return this.colors[e]||B.gray}getLevelFromScore(e){if(!this.thresholds)throw Error(`${this.name} does not support score-based levels`);return e>=7?this.levels[0]:e<=3?this.levels[2]:this.levels[1]}};const Ts={cli:{filled:`●`,empty:`○`},statusBar:{high:`⋮`,medium:`:`,low:`.`},mcp:{high:`🔴`,medium:`🟠`,low:`🟢`}},Es=new ws(`priority`,[bs,xs,Ss],{[bs]:B.hex(`#CC0000`),[xs]:B.hex(`#FF8800`),[Ss]:B.yellow});function Ds(e,t){let n=Ts.cli.filled,r=Ts.cli.empty,i=``;for(let a=0;a<3;a++)a<e?i+=t(n):i+=B.white(r);return i}function Os(e,t){return 3-t.indexOf(e)}function ks(e,t){if(Cs.has(e))return Cs.get(e);let n=t();return Cs.set(e,n),n}function As(){return ks(`mcp-priority-all`,()=>({[bs]:Ts.mcp.high,[xs]:Ts.mcp.medium,[Ss]:Ts.mcp.low}))}function js(){return ks(`cli-priority-all`,()=>{let e={};return Es.levels.forEach(t=>{e[t]=Ds(Os(t,Es.levels),Es.getColor(t))}),e})}function Ms(){return ks(`statusbar-priority-all`,()=>{let e={};return Es.levels.forEach((t,n)=>{let r=n===0?Ts.statusBar.high:n===1?Ts.statusBar.medium:Ts.statusBar.low;e[t]=Es.getColor(t)(r)}),e})}function Ns(){return{[bs]:Es.colors[bs],[xs]:Es.colors[xs],[Ss]:Es.colors[Ss]}}function Ps(e=!1){return e?As():js()}function Fs(e,t=!1){let n=Ps(t);return n[e]||n[xs]}new ws(`complexity`,[`high`,`medium`,`low`],{high:B.hex(`#CC0000`),medium:B.hex(`#FF8800`),low:B.green},{high:e=>e>=7,medium:e=>e>=4&&e<=6,low:e=>e<=3});const Is={clearOnComplete:!1,stopOnComplete:!0,hideCursor:!0,barsize:40},Ls={shades_classic:mt.Presets.shades_classic,shades_grey:mt.Presets.shades_grey,rect:mt.Presets.rect,legacy:mt.Presets.legacy},Rs=new class{constructor(e={},t=Ls.shades_classic){this.defaultOptions={...Is,...e},this.defaultPreset=t}createSingleBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.SingleBar(n,r)}createMultiBar(e={},t=null){let n=this._mergeConfig(e),r=t||this.defaultPreset;return new mt.MultiBar(n,r)}_mergeConfig(e){return{...this.defaultOptions,...e}}setDefaultOptions(e){this.defaultOptions={...this.defaultOptions,...e}}setDefaultPreset(e){this.defaultPreset=e}};function zs(e={}){return Rs.createMultiBar(e)}var Bs=class{constructor(e={}){this.numUnits=e.numUnits||1,this.unitName=e.unitName||`unit`,this.startTime=null,this.completedUnits=0,this.tokensIn=0,this.tokensOut=0,this.isEstimate=!0,this.bestAvgTimePerUnit=null,this.lastEstimateTime=null,this.lastEstimateSeconds=0,this.multibar=null,this.timeTokensBar=null,this.progressBar=null,this._timerInterval=null,this.isStarted=!1,this.isFinished=!1,this._initializeCustomProperties(e)}_initializeCustomProperties(e){}get unitNamePlural(){return`${this.unitName}s`}start(){this.isStarted||this.isFinished||(this.isStarted=!0,this.startTime=Date.now(),this.multibar=zs(),this.timeTokensBar=this.multibar.create(1,0,{},{format:this._getTimeTokensBarFormat(),barsize:1,hideCursor:!0,clearOnComplete:!1}),this.progressBar=this.multibar.create(this.numUnits,0,{},{format:this._getProgressBarFormat(),barCompleteChar:`█`,barIncompleteChar:`░`}),this._updateTimeTokensBar(),this.progressBar.update(0,{[this.unitNamePlural]:`0/${this.numUnits}`}),this._timerInterval=setInterval(()=>this._updateTimeTokensBar(),1e3),this._setupCustomUI())}_setupCustomUI(){}_getTimeTokensBarFormat(){return`{clock} {elapsed} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`${this.unitName.charAt(0).toUpperCase()+this.unitName.slice(1)}s {${this.unitNamePlural}} |{bar}| {percentage}%`}updateTokens(e,t,n=!1){this.tokensIn=e||0,this.tokensOut=t||0,this.isEstimate=n,this._updateTimeTokensBar()}_updateTimeTokensBar(){if(!this.timeTokensBar||this.isFinished)return;let e=this._formatElapsedTime(),t=this._estimateRemainingTime(),n=this.isEstimate?`~ Tokens (I/O)`:`Tokens (I/O)`;this.timeTokensBar.update(1,{clock:`⏱️`,elapsed:e,in:this.tokensIn,out:this.tokensOut,remaining:t,tokensLabel:n,...this._getCustomTimeTokensPayload()})}_getCustomTimeTokensPayload(){return{}}_formatElapsedTime(){if(!this.startTime)return`0m 00s`;let e=Math.floor((Date.now()-this.startTime)/1e3);return`${Math.floor(e/60)}m ${(e%60).toString().padStart(2,`0`)}s`}_estimateRemainingTime(){let e=this._getProgressFraction();if(e>=1)return`~0s`;let t=Date.now(),n=(t-this.startTime)/1e3;if(e===0)return`~calculating...`;let r=n/e;(this.bestAvgTimePerUnit===null||r<this.bestAvgTimePerUnit)&&(this.bestAvgTimePerUnit=r);let i=this.numUnits*(1-e),a=Math.ceil(i*this.bestAvgTimePerUnit);if(this.lastEstimateTime){let e=Math.floor((t-this.lastEstimateTime)/1e3),n=Math.max(0,this.lastEstimateSeconds-e);if(n===0)return`~0s`;a=Math.min(a,n)}return this.lastEstimateTime=t,this.lastEstimateSeconds=a,`~${this._formatDuration(a)}`}_getProgressFraction(){return this.completedUnits/this.numUnits}_formatDuration(e){if(e<60)return`${e}s`;let t=Math.floor(e/60),n=e%60;return t<60?n>0?`${t}m ${n}s`:`${t}m`:`${Math.floor(t/60)}h ${t%60}m`}getElapsedTime(){return this.startTime?Date.now()-this.startTime:0}stop(){this.isFinished||(this.isFinished=!0,this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar&&(this._updateTimeTokensBar(),this.multibar.stop()),this.cleanup())}getSummary(){return{completedUnits:this.completedUnits,elapsedTime:this.getElapsedTime()}}cleanup(){if(this._timerInterval&&=(clearInterval(this._timerInterval),null),this.multibar){try{this.multibar.stop()}catch{}this.multibar=null}this.timeTokensBar=null,this.progressBar=null,this.isStarted=!1,this.isFinished=!0,this._performCustomCleanup()}_performCustomCleanup(){}},Vs=class{constructor(e){if(!e)throw Error(`Multibar instance is required`);this.multibar=e}createBar(e,t={}){if(typeof e!=`string`)throw Error(`Format must be a string`);let n=this.multibar.create(1,1,{},{format:e,barsize:1,hideCursor:!0,clearOnComplete:!1});return n.update(1,t),n}createHeader(e,t){this.createBar(t),this.createBar(e),this.createBar(t)}createRow(e,t){if(!t||typeof t!=`object`)throw Error(`Payload must be an object`);return this.createBar(e,t)}createBorder(e){return this.createBar(e)}};function Hs(e,t,n){new Vs(e).createHeader(t,n)}function Us(e,t,n){new Vs(e).createRow(t,n)}function Ws(e,t){new Vs(e).createBorder(t)}js();const Gs=Ms();Ns();const Ks={DEBOUNCE_DELAY:100,MAX_TITLE_LENGTH:57,TRUNCATED_LENGTH:54,TASK_ID_PAD_START:3,TASK_ID_PAD_END:4,PRIORITY_PAD_END:3,VALID_PRIORITIES:[`high`,`medium`,`low`],DEFAULT_PRIORITY:`medium`};var qs=class{constructor(e=Ks.DEBOUNCE_DELAY){this.delay=e,this.pendingTimeout=null}debounce(e){this.clear(),this.pendingTimeout=setTimeout(()=>{e(),this.pendingTimeout=null},this.delay)}clear(){this.pendingTimeout&&=(clearTimeout(this.pendingTimeout),null)}hasPending(){return this.pendingTimeout!==null}},Js=class{constructor(){this.priorities={high:0,medium:0,low:0}}increment(e){let t=this.normalize(e);return this.priorities[t]++,t}normalize(e){let t=e?e.toLowerCase():Ks.DEFAULT_PRIORITY;return Ks.VALID_PRIORITIES.includes(t)?t:Ks.DEFAULT_PRIORITY}getCounts(){return{...this.priorities}}},Ys=class{static formatTitle(e,t){return e?e.length>Ks.MAX_TITLE_LENGTH?e.substring(0,Ks.TRUNCATED_LENGTH)+`...`:e:`Task ${t}`}static formatPriority(e){return Fs(e,!1).padEnd(Ks.PRIORITY_PAD_END,` `)}static formatTaskId(e){return e.toString().padStart(Ks.TASK_ID_PAD_START,` `).padEnd(Ks.TASK_ID_PAD_END,` `)}},Xs=class extends Bs{_initializeCustomProperties(e){this.append=e.append,this.priorityManager=new Js,this.debouncer=new qs,this.headerShown=!1}_getTimeTokensBarFormat(){return`{clock} {elapsed} | ${Gs.high} {high} ${Gs.medium} {medium} ${Gs.low} {low} | Tokens (I/O): {in}/{out} | Est: {remaining}`}_getProgressBarFormat(){return`Tasks {tasks} |{bar}| {percentage}%`}_getCustomTimeTokensPayload(){return this.priorityManager.getCounts()}addTaskLine(e,t,n=`medium`){if(!this.multibar||this.isFinished)return;this._ensureHeaderShown();let r=this._updateTaskCounters(e,n);this._updateTimeTokensBar(),this.debouncer.debounce(()=>{this._updateProgressDisplay(e,t,r)})}_ensureHeaderShown(){this.headerShown||(this.headerShown=!0,Hs(this.multibar,` TASK | PRI | TITLE`,`------+-----+----------------------------------------------------------------`))}_updateTaskCounters(e,t){let n=this.priorityManager.increment(t);return this.completedUnits=e,n}_updateProgressDisplay(e,t,n){this.progressBar.update(this.completedUnits,{tasks:`${this.completedUnits}/${this.numUnits}`});let r=Ys.formatTitle(t,e),i=Ys.formatPriority(n),a=Ys.formatTaskId(e);Us(this.multibar,` ${a} | ${i} | {title}`,{title:r}),Ws(this.multibar,`------+-----+----------------------------------------------------------------`),this._updateTimeTokensBar()}finish(){this.debouncer.hasPending()&&(this.debouncer.clear(),this._updateTimeTokensBar()),this.cleanup(),super.finish()}_performCustomCleanup(){this.debouncer.clear()}getSummary(){return{...super.getSummary(),taskPriorities:this.priorityManager.getCounts(),actionVerb:this.append?`appended`:`generated`}}};function Zs(e={}){return new Xs(e)}async function Qs(e,t,n){let r=$s(e,t,n);await tc(e,n,r.estimatedInputTokens);let i=await nc(e,t,e.streamingTimeout),{progressTracker:a,priorityMap:o}=await rc(e,n),s=await ic(i.mainResult,e,t,n,a,o,r.defaultPriority,r.estimatedInputTokens,r.logger);if(ec(s),s.usage&&e.projectRoot){let{logAiUsage:t}=await import(`./ai-services-unified-DmRuRuIX.js`),{getUserId:n}=await import(`./config-manager-C0k5tmLo.js`),a=n(e.projectRoot);if(a&&i.providerName&&i.modelId)try{let n=await t({userId:a,commandName:`parse-prd`,providerName:i.providerName,modelId:i.modelId,inputTokens:s.usage.promptTokens||0,outputTokens:s.usage.completionTokens||0,outputType:e.isMCP?`mcp`:`cli`});n&&(i.telemetryData=n)}catch(e){r.logger.report(`Failed to log telemetry: ${e.message}`,`debug`)}}return mc(s,i,r.estimatedInputTokens,a)}function $s(e,t,n){let{systemPrompt:r,userPrompt:i}=t;return{logger:new Go(e.mcpLog,e.reportProgress),estimatedInputTokens:cs(r+i),defaultPriority:he(e.projectRoot)||`medium`}}function ec(e){if(e.parsedTasks.length===0)throw Error(`No tasks were generated from the PRD`)}async function tc(e,t,n){e.reportProgress&&await e.reportProgress({progress:0,total:t,message:`Starting PRD analysis (Input: ${n} tokens)${e.research?` with research`:``}...`})}async function nc(e,n,r){let{systemPrompt:i,userPrompt:a}=n;return await Bo.withTimeout(t({role:e.research?`research`:`main`,session:e.session,projectRoot:e.projectRoot,schema:Uo,systemPrompt:i,prompt:a,commandName:`parse-prd`,outputType:e.isMCP?`mcp`:`cli`}),r,`Streaming operation`)}async function rc(e,t){let n=Ps(e.isMCP),r=null;if(e.outputFormat===`text`&&!e.isMCP){r=Zs({numUnits:t,unitName:`task`,append:e.append});let n=e.research?o():T(),i=f(e.research?`research`:`main`);es({prdFilePath:e.prdPath,outputPath:e.tasksPath,numTasks:t,append:e.append,research:e.research,force:e.force,existingTasks:[],nextId:1,model:n||`Default`,temperature:i?.temperature||.7}),r.start()}return{progressTracker:r,priorityMap:n}}async function ic(e,t,n,r,i,a,o,s,c){let{systemPrompt:l,userPrompt:u}=n,d={config:{...t,schema:Uo},numTasks:r,progressTracker:i,priorityMap:a,defaultPriority:o,estimatedInputTokens:s,prompt:u,systemPrompt:l};try{let t={lastPartialObject:null,taskCount:0,estimatedOutputTokens:0,usage:null};if(await ac(e.partialObjectStream,t,d),e.usage)try{t.usage=await e.usage}catch(e){c.report(`Failed to get usage data: ${e.message}`,`debug`)}return lc(t,d)}catch(e){return c.report(`StreamObject processing failed: ${e.message}. Falling back to generateObject.`,`debug`),await pc(d,c)}}async function ac(e,t,n){for await(let r of e)t.lastPartialObject=r,r&&(t.estimatedOutputTokens=cs(JSON.stringify(r))),await oc(r,t,n)}async function oc(e,t,n){if(!e?.tasks||!Array.isArray(e.tasks))return;let r=e.tasks.length;r>t.taskCount?(await sc(e.tasks,t.taskCount,r,t.estimatedOutputTokens,n),t.taskCount=r):n.progressTracker&&t.estimatedOutputTokens>0&&n.progressTracker.updateTokens(n.estimatedInputTokens,t.estimatedOutputTokens,!0)}async function sc(e,t,n,r,i){for(let a=t;a<n;a++){let t=e[a]||{};t.title?await gs({task:t,currentCount:a+1,totalTasks:i.numTasks,estimatedTokens:r,progressTracker:i.progressTracker,reportProgress:i.config.reportProgress,priorityMap:i.priorityMap,defaultPriority:i.defaultPriority,estimatedInputTokens:i.estimatedInputTokens}):await cc(a+1,r,i)}}async function cc(e,t,n){let{progressTracker:r,config:i,numTasks:a,defaultPriority:o,estimatedInputTokens:s}=n;r&&(r.addTaskLine(e,`Generating task ${e}...`,o),r.updateTokens(s,t,!0)),i.reportProgress&&!r&&await i.reportProgress({progress:e,total:a,message:`Generating task ${e}/${a}...`})}async function lc(e,t){let{lastPartialObject:n,estimatedOutputTokens:r,taskCount:i,usage:a}=e;if(!n?.tasks||!Array.isArray(n.tasks))throw Error(`No tasks generated from streamObject`);let o=a?.completionTokens||r,s=a?.promptTokens||t.estimatedInputTokens;return t.progressTracker&&await uc(n.tasks,i,a?o:r,t,a?s:null),{parsedTasks:n.tasks,estimatedOutputTokens:o,actualInputTokens:s,usage:a,usedFallback:!1}}async function uc(e,t,n,r,i=null){let{progressTracker:a,defaultPriority:o,estimatedInputTokens:s}=r;t>0?dc(e,a,o):await fc(e,n,r),a.updateTokens(i||s,n,!1),a.stop()}function dc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&t.addTaskLine(r+1,i.title,i.priority||n)}}async function fc(e,t,n){for(let r=0;r<e.length;r++){let i=e[r];i?.title&&await gs({task:i,currentCount:r+1,totalTasks:n.numTasks,estimatedTokens:t,progressTracker:n.progressTracker,reportProgress:n.config.reportProgress,priorityMap:n.priorityMap,defaultPriority:n.defaultPriority,estimatedInputTokens:n.estimatedInputTokens})}}async function pc(e,t){if(t.report(`Using generateObject fallback for PRD parsing`,`info`),e.progressTracker)for(let t=0;t<e.numTasks;t++)e.progressTracker.addTaskLine(t+1,`Generating task ${t+1}...`,e.defaultPriority),e.progressTracker.updateTokens(e.estimatedInputTokens,0,!0);let n=await i({role:e.config.research?`research`:`main`,commandName:`parse-prd`,prompt:e.prompt,systemPrompt:e.systemPrompt,schema:e.config.schema,outputFormat:e.config.outputFormat||`text`,projectRoot:e.config.projectRoot,session:e.config.session}),r=n?.mainResult||n;if(r&&Array.isArray(r.tasks)&&(r.tasks=r.tasks.map(e=>({...e,dependencies:e.dependencies??[],priority:e.priority??null,details:e.details??null,testStrategy:e.testStrategy??null}))),r&&Array.isArray(r.tasks)){if(e.progressTracker){for(let t=0;t<r.tasks.length;t++){let n=r.tasks[t];n&&n.title&&e.progressTracker.addTaskLine(t+1,n.title,n.priority||e.defaultPriority)}let t=n.telemetryData?.outputTokens||cs(JSON.stringify(r)),i=n.telemetryData?.inputTokens||e.estimatedInputTokens;e.progressTracker.updateTokens(i,t,!1)}return{parsedTasks:r.tasks,estimatedOutputTokens:n.telemetryData?.outputTokens||cs(JSON.stringify(r)),actualInputTokens:n.telemetryData?.inputTokens,telemetryData:n.telemetryData,usedFallback:!0}}throw Error(`Failed to generate tasks using generateObject fallback`)}function mc(e,t,n,r){let i=null;if(r&&(i=r.getSummary(),r.cleanup()),e.usage&&t){let n=e.usage;t.usage||={promptTokens:n.promptTokens||0,completionTokens:n.completionTokens||0,totalTokens:n.totalTokens||0}}return{parsedTasks:e.parsedTasks,aiServiceResponse:t,estimatedInputTokens:e.actualInputTokens||n,estimatedOutputTokens:e.estimatedOutputTokens,usedFallback:e.usedFallback,progressTracker:r,summary:i}}async function hc(e,t,n){let r=new Go(e.mcpLog,e.reportProgress);r.report(`Parsing PRD file: ${e.prdPath}, Force: ${e.force}, Append: ${e.append}, Research: ${e.research}`,`debug`);try{let{existingTasks:i,nextId:a}=us(e.tasksPath,e.targetTag);ds({existingTasks:i,targetTag:e.targetTag,append:e.append,force:e.force,isMCP:e.isMCP,logger:r});let o=await t(e,await hs(e,ls(e.prdPath),a),e.numTasks),s=he(e.projectRoot)||`medium`,c=fs(o.parsedTasks,a,i,s),l=e.append?[...i,...c]:c;return ms(e.tasksPath,l,e.targetTag,r),await gc(e,o,c,l,a,n),{success:!0,tasksPath:e.tasksPath,telemetryData:o.aiServiceResponse?.telemetryData,tagInfo:o.aiServiceResponse?.tagInfo}}catch(t){throw r.report(`Error parsing PRD: ${t.message}`,`error`),e.isMCP||(console.error(B.red(`Error: ${t.message}`)),je(e.projectRoot)&&console.error(t)),t}}async function gc(e,t,n,r,i,a){let{aiServiceResponse:o,estimatedInputTokens:s,estimatedOutputTokens:c}=t;if(e.reportProgress){let t=o?.telemetryData&&(o.telemetryData.inputTokens>0||o.telemetryData.outputTokens>0),n;if(t){let e=o.telemetryData.totalCost||0,t=o.telemetryData.currency||`USD`;n=`✅ Task Generation Completed | Tokens (I/O): ${o.telemetryData.inputTokens}/${o.telemetryData.outputTokens} | Cost: ${t===`USD`?`$`:t}${e.toFixed(4)}`}else n=`✅ Task Generation Completed | ~Tokens (I/O): ${s}/${a?c:`unknown`} | Cost: ~$0.00`;await e.reportProgress({progress:e.numTasks,total:e.numTasks,message:n})}e.outputFormat===`text`&&!e.isMCP&&(a&&t.summary?await _s({processedTasks:n,nextId:i,summary:t.summary,prdPath:e.prdPath,tasksPath:e.tasksPath,usedFallback:t.usedFallback,aiServiceResponse:o}):a||vs({processedTasks:n,research:e.research,finalTasks:r,tasksPath:e.tasksPath,aiServiceResponse:o}))}async function _c(e,t,n,r={}){return hc(new Wo(e,t,n,r),Qs,!0)}async function vc(e,t,n,r={}){return hc(new Wo(e,t,n,r),ys,!1)}async function yc(e,t,n,r={}){let i=new Wo(e,t,n,r);if(i.useStreaming)try{return await _c(e,t,n,r)}catch(a){if(a instanceof Ro||a.code===zo.NOT_ASYNC_ITERABLE||a.code===zo.STREAM_PROCESSING_FAILED||a.code===zo.STREAM_NOT_ITERABLE||Bo.isTimeoutError(a)){let o=new Go(i.mcpLog,i.reportProgress);return i.outputFormat===`text`&&!i.isMCP?console.log(B.yellow(`⚠️ Streaming operation ${a.message.includes(`timed out`)?`timed out`:`failed`}. Falling back to non-streaming mode...`)):o.report(`Streaming failed (${a.message}), falling back to non-streaming mode...`,`warn`),await vc(e,t,n,r)}else throw a}else return await vc(e,t,n,r)}var bc=yc;async function xc(e,t,n=!1,r=!1,i={}){let{projectRoot:a,tag:o}=i;try{z(`info`,`Removing subtask ${t}...`);let r=D(e,a,o);if(!r||!r.tasks)throw Error(`Invalid or missing tasks file at ${e}`);if(!t.includes(`.`))throw Error(`Invalid subtask ID format: ${t}. Expected format: "parentId.subtaskId"`);let[i,s]=t.split(`.`),c=parseInt(i,10),l=parseInt(s,10),u=r.tasks.find(e=>e.id===c);if(!u)throw Error(`Parent task with ID ${c} not found`);if(!u.subtasks||u.subtasks.length===0)throw Error(`Parent task ${c} has no subtasks`);let d=u.subtasks.findIndex(e=>e.id===l);if(d===-1)throw Error(`Subtask ${t} not found`);let f={...u.subtasks[d]};u.subtasks.splice(d,1),u.subtasks.length===0&&(u.subtasks=void 0);let p=null;if(n){z(`info`,`Converting subtask ${t} to a standalone task...`);let e=Math.max(...r.tasks.map(e=>e.id))+1;p={id:e,title:f.title,description:f.description||``,details:f.details||``,status:f.status||`pending`,dependencies:f.dependencies||[],priority:u.priority||`medium`},p.dependencies.includes(c)||p.dependencies.push(c),r.tasks.push(p),z(`info`,`Created new task ${e} from subtask ${t}`)}else z(`info`,`Subtask ${t} deleted`);return y(e,r,a,o),p}catch(e){throw z(`error`,`Error removing subtask: ${e.message}`),e}}var Sc=xc;function Cc(e,t){if(typeof t==`string`&&t.includes(`.`)){let n=t.split(`.`);if(n.length!==2||!n[0]||!n[1]){let n=parseInt(t,10);return e.some(e=>e.id===n)}let[r,i]=n,a=parseInt(r,10),o=parseInt(i,10),s=e.find(e=>e.id===a);return s&&s.subtasks&&s.subtasks.some(e=>e.id===o)}let n=parseInt(t,10);return e.some(e=>e.id===n)}var wc=Cc;async function Tc(e,t,n={}){let{projectRoot:r,tag:i}=n,a={success:!0,messages:[],errors:[],removedTasks:[]},o=t.split(`,`).map(e=>e.trim()).filter(Boolean);if(o.length===0)return a.success=!1,a.errors.push(`No valid task IDs provided.`),a;try{let t=D(e,r,i);if(!t)throw Error(`Could not read tasks file at ${e}`);let n=t._rawTaggedData||t;if(!n[i]||!n[i].tasks)throw Error(`Tag '${i}' not found or has no tasks.`);let s=n[i].tasks,c=[];for(let e of o){if(!wc(s,e)){let t=`Task with ID ${e} in tag '${i}' not found or already removed.`;a.errors.push(t),a.success=!1;continue}try{if(typeof e==`string`&&e.includes(`.`)){let[t,n]=e.split(`.`).map(e=>parseInt(e,10)),r=s.find(e=>e.id===t);if(!r||!r.subtasks)throw Error(`Parent task ${t} or its subtasks not found for subtask ${e}`);let o=r.subtasks.findIndex(e=>e.id===n);if(o===-1)throw Error(`Subtask ${n} not found in parent task ${t}`);let c={...r.subtasks[o],parentTaskId:t};a.removedTasks.push(c),r.subtasks.splice(o,1),a.messages.push(`Successfully removed subtask ${e} from tag '${i}'`)}else{let t=parseInt(e,10),n=s.findIndex(e=>e.id===t);if(n===-1)throw Error(`Task with ID ${e} not found in tag '${i}'`);let r=s[n];a.removedTasks.push(r),c.push(t),s.splice(n,1),a.messages.push(`Successfully removed task ${e} from tag '${i}'`)}}catch(t){let n=`Error processing ID ${e}: ${t.message}`;a.errors.push(n),a.success=!1,z(`warn`,n)}}if(a.removedTasks.length>0){let t=new Set(o.map(e=>typeof e==`string`&&e.includes(`.`)?e:parseInt(e,10)));for(let e in n[i].tasks=s,n)Object.prototype.hasOwnProperty.call(n,e)&&n[e]&&n[e].tasks&&n[e].tasks.forEach(e=>{e.dependencies&&=e.dependencies.filter(e=>!t.has(e)),e.subtasks&&e.subtasks.forEach(n=>{n.dependencies&&=n.dependencies.filter(n=>!t.has(`${e.id}.${n}`)&&!t.has(n))})});y(e,n,r,i);for(let t of c){let n=H.join(H.dirname(e),`task_${t.toString().padStart(3,`0`)}.txt`);if(qe.existsSync(n))try{qe.unlinkSync(n),a.messages.push(`Deleted task file: ${n}`)}catch(e){let t=`Failed to delete task file ${n}: ${e.message}`;a.errors.push(t),a.success=!1,z(`warn`,t)}}}else a.errors.length===0&&a.messages.push(`No tasks found matching the provided IDs.`);let l=a.messages.join(`
871
871
  `),u=a.errors.join(`
872
872
  `);return{success:a.success,message:l||`No tasks were removed.`,error:u||null,removedTasks:a.removedTasks}}catch(e){return z(`error`,`Error removing tasks: ${e.message}`),{success:!1,message:``,error:`Operation failed: ${e.message}`,removedTasks:[]}}}var Ec=Tc;ot.use(st({code:e=>e.split(`
873
873
  `).map(e=>` `+B.cyan(e)).join(`
@@ -885,9 +885,9 @@ ${B.cyan(`1.`)} Run ${B.yellow(`task-master list`)} to view all tasks\n${B.cyan(
885
885
  `);if(r.push(B.cyan(`Prompts: `)+B.yellow(i.toLocaleString())+B.gray(` (generated)`)+`
886
886
  `+a),r.length>0){let e=W(r.join(`
887
887
 
888
- `),{title:B.blue.bold(`Context Analysis`),titleAlignment:`left`,padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`blue`});console.log(e)}}async function kc(e,t,n,r,i,a,o){let s=!1;try{let{readJSON:c}=await import(`./utils-CtCI5DEr.js`);(await import(`./update-task-by-id-mhULzJWi.js`)).default;let{updateSubtaskById:l}=await import(`./update-subtask-by-id-OR7LPqsO.js`),u=[{question:a,answer:o,type:`initial`,timestamp:new Date().toISOString()}];for(;;){let{action:a}=await q.prompt([{type:`list`,name:`action`,message:`What would you like to do next?`,choices:[{name:`Ask a follow-up question`,value:`followup`},{name:`Save to file`,value:`savefile`},{name:`Save to task/subtask`,value:`save`},{name:`Quit`,value:`quit`}],pageSize:4}]);if(a===`quit`)break;if(a===`savefile`){await jc(u,r,t,i);continue}if(a===`save`){await Ac(u,r,t,i)&&(s=!0);continue}if(a===`followup`){let{followUpQuery:r}=await q.prompt([{type:`input`,name:`followUpQuery`,message:`Enter your follow-up question:`,validate:e=>!e||e.trim().length===0?`Please enter a valid question.`:!0}]);if(!r||r.trim().length===0)continue;console.log(`
888
+ `),{title:B.blue.bold(`Context Analysis`),titleAlignment:`left`,padding:{top:1,bottom:1,left:2,right:2},margin:{top:0,bottom:1},borderStyle:`single`,borderColor:`blue`});console.log(e)}}async function kc(e,t,n,r,i,a,o){let s=!1;try{let{readJSON:c}=await import(`./utils-CAcuaoG3.js`);(await import(`./update-task-by-id-BHYw3Axm.js`)).default;let{updateSubtaskById:l}=await import(`./update-subtask-by-id-BWC9_KFA.js`),u=[{question:a,answer:o,type:`initial`,timestamp:new Date().toISOString()}];for(;;){let{action:a}=await q.prompt([{type:`list`,name:`action`,message:`What would you like to do next?`,choices:[{name:`Ask a follow-up question`,value:`followup`},{name:`Save to file`,value:`savefile`},{name:`Save to task/subtask`,value:`save`},{name:`Quit`,value:`quit`}],pageSize:4}]);if(a===`quit`)break;if(a===`savefile`){await jc(u,r,t,i);continue}if(a===`save`){await Ac(u,r,t,i)&&(s=!0);continue}if(a===`followup`){let{followUpQuery:r}=await q.prompt([{type:`input`,name:`followUpQuery`,message:`Enter your follow-up question:`,validate:e=>!e||e.trim().length===0?`Please enter a valid question.`:!0}]);if(!r||r.trim().length===0)continue;console.log(`
889
889
  `+B.gray(`─`.repeat(60))+`
890
- `);let i=Pc(u),a={...e,taskIds:[],customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},o=await Dc(r.trim(),a,t,n,!1);u.push({question:r.trim(),answer:o.result,type:`followup`,timestamp:new Date().toISOString()})}}}catch(e){i.debug(`Follow-up questions not available: ${e.message}`)}return{interactiveSaveOccurred:s}}async function Ac(e,t,n,r){try{let{readJSON:r}=await import(`./utils-CtCI5DEr.js`),i=(await import(`./update-task-by-id-mhULzJWi.js`)).default,{updateSubtaskById:a}=await import(`./update-subtask-by-id-OR7LPqsO.js`),{taskId:o}=await q.prompt([{type:`input`,name:`taskId`,message:`Enter task ID (e.g., "15" for task or "15.2" for subtask):`,validate:e=>{if(!e||e.trim().length===0)return`Please enter a task ID.`;let t=e.trim();return/^\d+(\.\d+)?$/.test(t)?!0:`Invalid format. Use "15" for task or "15.2" for subtask.`}}]),s=o.trim(),c=Nc(e),l=s.includes(`.`),u=H.join(t,`.taskmaster`,`tasks`,`tasks.json`);if(!V.existsSync(u)){console.log(B.red(`❌ Tasks file not found. Please run task-master init first.`));return}let d=r(u,t,n.tag);if(!d||!d.tasks){console.log(B.red(`❌ No valid tasks found.`));return}if(l){let[e,t]=s.split(`.`).map(e=>parseInt(e,10)),r=d.tasks.find(t=>t.id===e);if(!r){console.log(B.red(`❌ Parent task ${e} not found.`));return}if(!r.subtasks||!r.subtasks.find(e=>e.id===t)){console.log(B.red(`❌ Subtask ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to subtask...`)),await a(u,s,c,!1,n,`text`),console.log(B.green(`✅ Research conversation saved to subtask ${s}`))}else{let e=parseInt(s,10);if(!d.tasks.find(t=>t.id===e)){console.log(B.red(`❌ Task ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to task...`)),await i(u,e,c,!1,n,`text`,!0),console.log(B.green(`✅ Research conversation saved to task ${s}`))}return!0}catch(e){return console.log(B.red(`❌ Error saving conversation: ${e.message}`)),r.error(`Error saving conversation: ${e.message}`),!1}}async function jc(e,t,n,r){try{let n=H.join(t,`.taskmaster`,`docs`,`research`);V.existsSync(n)||V.mkdirSync(n,{recursive:!0});let i=e[0]?.question||`research-query`,a=`${new Date().toISOString().split(`T`)[0]}_${i.toLowerCase().replace(/[^a-z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50).replace(/^-+|-+$/g,``)}.md`,o=H.join(n,a),s=Mc(e,i);V.writeFileSync(o,s,`utf8`);let c=H.relative(t,o);return console.log(B.green(`✅ Research saved to: ${B.cyan(c)}`)),r.success(`Research conversation saved to ${c}`),o}catch(e){throw console.log(B.red(`❌ Error saving research file: ${e.message}`)),r.error(`Error saving research file: ${e.message}`),e}}function Mc(e,t){let n=new Date().toISOString(),r=`---
890
+ `);let i=Pc(u),a={...e,taskIds:[],customContext:i+(e.customContext?`\n\n--- Original Context ---\n${e.customContext}`:``)},o=await Dc(r.trim(),a,t,n,!1);u.push({question:r.trim(),answer:o.result,type:`followup`,timestamp:new Date().toISOString()})}}}catch(e){i.debug(`Follow-up questions not available: ${e.message}`)}return{interactiveSaveOccurred:s}}async function Ac(e,t,n,r){try{let{readJSON:r}=await import(`./utils-CAcuaoG3.js`),i=(await import(`./update-task-by-id-BHYw3Axm.js`)).default,{updateSubtaskById:a}=await import(`./update-subtask-by-id-BWC9_KFA.js`),{taskId:o}=await q.prompt([{type:`input`,name:`taskId`,message:`Enter task ID (e.g., "15" for task or "15.2" for subtask):`,validate:e=>{if(!e||e.trim().length===0)return`Please enter a task ID.`;let t=e.trim();return/^\d+(\.\d+)?$/.test(t)?!0:`Invalid format. Use "15" for task or "15.2" for subtask.`}}]),s=o.trim(),c=Nc(e),l=s.includes(`.`),u=H.join(t,`.taskmaster`,`tasks`,`tasks.json`);if(!V.existsSync(u)){console.log(B.red(`❌ Tasks file not found. Please run task-master init first.`));return}let d=r(u,t,n.tag);if(!d||!d.tasks){console.log(B.red(`❌ No valid tasks found.`));return}if(l){let[e,t]=s.split(`.`).map(e=>parseInt(e,10)),r=d.tasks.find(t=>t.id===e);if(!r){console.log(B.red(`❌ Parent task ${e} not found.`));return}if(!r.subtasks||!r.subtasks.find(e=>e.id===t)){console.log(B.red(`❌ Subtask ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to subtask...`)),await a(u,s,c,!1,n,`text`),console.log(B.green(`✅ Research conversation saved to subtask ${s}`))}else{let e=parseInt(s,10);if(!d.tasks.find(t=>t.id===e)){console.log(B.red(`❌ Task ${s} not found.`));return}console.log(B.blue(`💾 Saving research conversation to task...`)),await i(u,e,c,!1,n,`text`,!0),console.log(B.green(`✅ Research conversation saved to task ${s}`))}return!0}catch(e){return console.log(B.red(`❌ Error saving conversation: ${e.message}`)),r.error(`Error saving conversation: ${e.message}`),!1}}async function jc(e,t,n,r){try{let n=H.join(t,`.taskmaster`,`docs`,`research`);V.existsSync(n)||V.mkdirSync(n,{recursive:!0});let i=e[0]?.question||`research-query`,a=`${new Date().toISOString().split(`T`)[0]}_${i.toLowerCase().replace(/[^a-z0-9\s-]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50).replace(/^-+|-+$/g,``)}.md`,o=H.join(n,a),s=Mc(e,i);V.writeFileSync(o,s,`utf8`);let c=H.relative(t,o);return console.log(B.green(`✅ Research saved to: ${B.cyan(c)}`)),r.success(`Research conversation saved to ${c}`),o}catch(e){throw console.log(B.red(`❌ Error saving research file: ${e.message}`)),r.error(`Error saving research file: ${e.message}`),e}}function Mc(e,t){let n=new Date().toISOString(),r=`---
891
891
  title: Research Session
892
892
  query: "${t}"
893
893
  date: ${new Date().toLocaleDateString()}