@hhsw2015/task-master-ai 0.43.31 → 0.43.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,126 @@
1
1
  # task-master-ai
2
2
 
3
+ ## 0.43.32
4
+
5
+ ### Patch Changes
6
+
7
+ - [`5e1006f`](https://github.com/eyaltoledano/claude-task-master/commit/5e1006f1012c18b9276d87981eb1d17e11d75259) Thanks [@wowdd1](https://github.com/wowdd1)! - Fix cloud status writeback failures when Taskmaster uses non-native statuses like `blocked`, `review`, `deferred`, or `cancelled`.
8
+ - Map extended Taskmaster statuses to API-compatible values instead of throwing.
9
+ - Preserve original Taskmaster status in task metadata and restore it on read, so CLI still shows the intended status.
10
+ - Prevent `Failed to update task status via API` during longrun/auto execution flows.
11
+
12
+ - [`04ff2a1`](https://github.com/eyaltoledano/claude-task-master/commit/04ff2a1c193484128ff80158274da5f816c4879f) Thanks [@wowdd1](https://github.com/wowdd1)! - Fix CLI version reporting to always use Task Master's runtime package version.
13
+
14
+ `task-master --version` no longer depends on `TM_PUBLIC_VERSION` build-time injection, preventing stale version output after publishing and global installs.
15
+
16
+ - [`22cd9a3`](https://github.com/eyaltoledano/claude-task-master/commit/22cd9a39c1cc6f72e037b02804c32b1b7621f7c5) Thanks [@wowdd1](https://github.com/wowdd1)! - Add explicit Codex CLI support for `gpt-5.3-codex` with `xhigh` reasoning effort in provider validation logic and supported model metadata.
17
+
18
+ This prevents unnecessary fallback from `xhigh` to `high` when using GPT-5.3 Codex through Task Master's Codex provider path.
19
+
20
+ - [`336bdbb`](https://github.com/eyaltoledano/claude-task-master/commit/336bdbb06383a8d56eeb16410b1d77d0e91746a7) Thanks [@wowdd1](https://github.com/wowdd1)! - Make Codex CLI the default local executor for generated Task Master configs.
21
+
22
+ Default configs now use non-interactive Codex execution (`approvalMode: never`, `fullAuto: true`, `sandboxMode: danger-full-access`, `skipGitRepoCheck: true`) with `reasoningEffort: xhigh`, and default response language is set to `Chinese`.
23
+
24
+ Also fixes `task-master lang --response ...` failing with `successMessage is not defined`.
25
+
26
+ - [`43b57a7`](https://github.com/eyaltoledano/claude-task-master/commit/43b57a7fcd658a7587f66e2c82406c387ac85c99) Thanks [@wowdd1](https://github.com/wowdd1)! - Automatically inject project-level Taskmaster quick triggers into `AGENTS.md` during `task-master codex init`.
27
+ - Adds built-in shortcuts for Chinese commands:
28
+ - `拆分任务`: write PRD and run `task-master parse-prd`
29
+ - `开始实现`: run `task-master codex run` in foreground (uses active tag, not hardcoded `master`)
30
+ - Keeps longrun behavior unchanged while removing the need to repeat long prompt instructions each time.
31
+
32
+ - [`8156b97`](https://github.com/eyaltoledano/claude-task-master/commit/8156b97e912919c5521c59015f49452f167e56de) Thanks [@wowdd1](https://github.com/wowdd1)! - Codex CLI execution now prefers the system `codex` binary by default when available in `PATH`.
33
+
34
+ If no global `codex` executable is found, Task Master falls back to the provider's existing bundled resolution behavior.
35
+
36
+ Explicit `codexPath` configuration is still respected and will override the default selection.
37
+
38
+ - [`f95bf7e`](https://github.com/eyaltoledano/claude-task-master/commit/f95bf7e003846dcf71708c7ea7390036b9bb14c3) Thanks [@wowdd1](https://github.com/wowdd1)! - Add a Codex execution preflight check that runs before `start` and `loop` when using the Codex executor.
39
+
40
+ If the project is not trusted in `~/.codex/config.toml` or Codex approval policy is not set to unattended mode (`never`), Task Master now refuses execution and shows exact remediation guidance instead of hanging on interactive approvals.
41
+
42
+ - [`43b57a7`](https://github.com/eyaltoledano/claude-task-master/commit/43b57a7fcd658a7587f66e2c82406c387ac85c99) Thanks [@wowdd1](https://github.com/wowdd1)! - Make `task-master codex run` show full task execution flow in terminal by default.
43
+ - Keep real-time executor output (`stdout`/`stderr`) enabled by default.
44
+ - Add `--no-show-executor-output` to explicitly disable live streaming when needed.
45
+ - Improve run visibility with extra `[info]`/`[warn]` lifecycle messages during longrun execution.
46
+
47
+ - [`aa1d44b`](https://github.com/eyaltoledano/claude-task-master/commit/aa1d44bdfde116ecf1a38c34b356adf017a48473) Thanks [@wowdd1](https://github.com/wowdd1)! - Improve Codex longrun skill initialization by downloading and wiring upstream Taskmaster skill assets.
48
+ - Sync upstream skill asset files into `.codex/skills/taskmaster-longrun/assets/`:
49
+ - `SPEC_TEMPLATE.md`
50
+ - `PROGRESS_TEMPLATE.md`
51
+ - `todo_template.csv`
52
+ - Make `codex init` prefer these asset templates when creating runtime `SPEC.md` and `PROGRESS.md`.
53
+
54
+ - [`2119779`](https://github.com/eyaltoledano/claude-task-master/commit/21197799623c29f8b35542e289985bd0732b2283) Thanks [@wowdd1](https://github.com/wowdd1)! - Improve Codex longrun stability with runner-controlled execution outcomes and timeout controls.
55
+ - Add machine-readable `TM_RESULT` parsing so runner can reliably decide task success/failure and write Taskmaster status.
56
+ - Add per-task timeout controls:
57
+ - `--exec-idle-timeout-ms` (default enabled)
58
+ - `--exec-hard-timeout-ms` (optional hard cap)
59
+ - `--exec-hard-timeout-ms 0` to disable hard timeout
60
+ - Keep backward compatibility for `--exec-timeout-ms` as an alias of hard timeout.
61
+
62
+ - [`ebc0ef8`](https://github.com/eyaltoledano/claude-task-master/commit/ebc0ef8677aebe8eac61fa28396bea993d6426fb) Thanks [@wowdd1](https://github.com/wowdd1)! - Harden structured output schema normalization for Codex/OpenAI strict JSON schema validation.
63
+
64
+ Task Master now enforces that object schemas list every declared property in `required`, in addition to ensuring `additionalProperties: false`.
65
+
66
+ This fixes `parse-prd` failures with `codex-cli` + `gpt-5.3-codex` where providers rejected schemas with errors like:
67
+ - Missing `additionalProperties: false`
68
+ - `required` missing keys such as `metadata`
69
+
70
+ - [`0eb921d`](https://github.com/eyaltoledano/claude-task-master/commit/0eb921deaef0c8c70e512002cf34e14bd2c6ad88) Thanks [@wowdd1](https://github.com/wowdd1)! - Fix `task-master expand` routing so local CLI providers (including `codex-cli`) do not delegate subtask expansion to Hamster.
71
+
72
+ When a local CLI provider is active, expansion now stays on the local execution path.
73
+
74
+ - [`7604d11`](https://github.com/eyaltoledano/claude-task-master/commit/7604d110c225589219016fc5c4c90a80ac3934c9) Thanks [@wowdd1](https://github.com/wowdd1)! - Fix MCP `expand_task` in multi-tag projects so an explicit `tag` no longer falls back to the current active tag during task expansion.
75
+
76
+ - [`8decae7`](https://github.com/eyaltoledano/claude-task-master/commit/8decae70c9ca34bb5f648d913da2b6a2cafc406c) Thanks [@wowdd1](https://github.com/wowdd1)! - Exported task descriptions now follow your configured response language. Chinese mode outputs Chinese section headings and fallback text, while English mode keeps the existing English wording.
77
+
78
+ When creating a Hamster brief from local tasks, Task Master now forwards the preferred language for generated brief metadata and automatically retries without that field if the backend enforces a strict schema.
79
+
80
+ - [`8decae7`](https://github.com/eyaltoledano/claude-task-master/commit/8decae70c9ca34bb5f648d913da2b6a2cafc406c) Thanks [@wowdd1](https://github.com/wowdd1)! - Added first-class non-interactive export mode for automation/LLM use.
81
+ - `tm export` now supports `--yes` / `--non-interactive` to skip interactive prompts.
82
+ - Added `--invite-emails` for non-interactive collaborator invites.
83
+ - Added `--all-unexported` to export all local unexported tags without manual selection.
84
+ - When already connected to a brief, non-interactive export no longer blocks on confirmation.
85
+ - Auth/org guard now supports non-interactive behavior and fails fast with actionable errors instead of waiting for prompts.
86
+
87
+ - [`fd57b07`](https://github.com/eyaltoledano/claude-task-master/commit/fd57b07b5243cd4e3cb9bab24ed2d5318488d259) Thanks [@wowdd1](https://github.com/wowdd1)! - Add MCP support for choosing PRD parsing destination via `parse_prd.destination`.
88
+
89
+ You can now explicitly route PRD parsing to local `tasks.json` (`local`) or Hamster cloud brief generation (`hamster`) in non-interactive MCP flows.
90
+
91
+ - [`ebc3f11`](https://github.com/eyaltoledano/claude-task-master/commit/ebc3f11bf3122582517b418d87cbb2c32867c4dd) Thanks [@wowdd1](https://github.com/wowdd1)! - Ensure published npm packages are built at publish time by running `build` in `prepack`.
92
+
93
+ This prevents stale `dist` artifacts and keeps CLI-reported version output aligned with the published package version.
94
+
95
+ - [`ebc3f11`](https://github.com/eyaltoledano/claude-task-master/commit/ebc3f11bf3122582517b418d87cbb2c32867c4dd) Thanks [@wowdd1](https://github.com/wowdd1)! - Make CLI version resolution runtime-safe by reading package metadata from the installed Task Master package instead of relying on build-baked constants.
96
+
97
+ This keeps `task-master --version` aligned with the installed package version even when stale build artifacts are present.
98
+
99
+ - [`a9fa47a`](https://github.com/eyaltoledano/claude-task-master/commit/a9fa47a0c88b43ff6797aa536deb298d0bf65f77) Thanks [@wowdd1](https://github.com/wowdd1)! - Fix legacy `storage.type = "local"` compatibility so CLI commands no longer fail with `Unknown storage type: local`.
100
+ - Normalize legacy `local` storage type to `file` in runtime config resolution.
101
+ - Add defensive normalization in storage factory creation/validation paths.
102
+ - Add regression tests to prevent initialization failures in older project configs.
103
+
104
+ - [`7702148`](https://github.com/eyaltoledano/claude-task-master/commit/7702148014f97db3921c8df3768e9b0be7f4f8ee) Thanks [@wowdd1](https://github.com/wowdd1)! - Fix Hamster authentication bootstrap by adding built-in Supabase fallback defaults for the official hosted environment.
105
+
106
+ This prevents `tm auth login` from failing with missing Supabase env errors in self-built or custom-published packages when Supabase variables are not explicitly provided.
107
+
108
+ - [`7399e98`](https://github.com/eyaltoledano/claude-task-master/commit/7399e98cc0e8f583b7b7e3a5175183395d6d9c78) Thanks [@wowdd1](https://github.com/wowdd1)! - Fixed `sync push` for large task sets by batching task import requests to Hamster.
109
+ - Automatically splits bulk sync payloads into batches of up to 100 tasks
110
+ - Prevents API validation failures for projects with more than 100 tasks/subtasks
111
+ - Preserves existing sync behavior while improving reliability for larger plans
112
+
113
+ - [`e084b1a`](https://github.com/eyaltoledano/claude-task-master/commit/e084b1ac110714710d9eb6936ef961b0dc858a1c) Thanks [@wowdd1](https://github.com/wowdd1)! - Added a native `sync push` command to push local tasks into an existing Hamster brief (without creating a new brief).
114
+ - New command: `task-master sync push`
115
+ - Supports explicit brief targeting via `--brief <brief-id-or-url>`
116
+ - Supports local tag selection via `--tag <tag>`
117
+ - Supports non-interactive automation via `--yes` / `--non-interactive`
118
+ - Fails fast in non-interactive mode when no brief context is available
119
+
120
+ - [`ff6a908`](https://github.com/eyaltoledano/claude-task-master/commit/ff6a9089b9821ab5cc40c6795e3c12692909888d) Thanks [@wowdd1](https://github.com/wowdd1)! - Add `tm sync push --mode replace` to support overwrite-style sync into an existing Hamster brief.
121
+
122
+ When `--mode replace` is used, Task Master now clears existing tasks in the target brief before importing local tasks, preventing duplicate historical entries from repeated sync runs.
123
+
3
124
  ## 0.43.0
4
125
 
5
126
  ### Minor Changes
@@ -0,0 +1 @@
1
+ import{a as e,i as t,n,r,t as i}from"./ai-services-unified-C_wzEmAq.js";import"./config-manager-DZYVJT7n.js";import"./git-utils-DllbRE35.js";import"./sentry-C9gSa7DA.js";export{i as generateObjectService,n as generateTextService,r as logAiUsage,t as streamObjectService,e as streamTextService};
@@ -1,4 +1,4 @@
1
- import{C as e,E as t,Et as n,F as r,H as i,I as a,J as o,L as s,M as c,N as l,O as u,P as d,a as f,f as p,ht as m,j as h,l as g,m as _,o as ee,s as te,ut as v,v as y,w as b,x,y as S,yt as C}from"./config-manager-Bj2cZEwZ.js";import{n as w,t as T}from"./sentry-ClkRpQLz.js";import{createRequire as E}from"node:module";import D,{promises as O}from"fs";import k,{join as A}from"path";import{homedir as j}from"os";import{execSync as M,spawn as N}from"child_process";import*as P from"ai";import{jsonrepair as F}from"jsonrepair";import{EnvHttpProxyAgent as I}from"undici";import{createAnthropic as ne}from"@ai-sdk/anthropic";import{createPerplexity as re}from"@ai-sdk/perplexity";import{createGoogleGenerativeAI as ie}from"@ai-sdk/google";import{createOpenAI as ae}from"@ai-sdk/openai";import{createXai as oe}from"@ai-sdk/xai";import{createGroq as se}from"@ai-sdk/groq";import{createOpenRouter as ce}from"@openrouter/ai-sdk-provider";import{createOllama as le}from"ollama-ai-provider-v2";import{createAmazonBedrock as ue}from"@ai-sdk/amazon-bedrock";import{fromNodeProviderChain as de}from"@aws-sdk/credential-providers";import{createAzure as fe}from"@ai-sdk/azure";import{createVertex as pe}from"@ai-sdk/google-vertex";import{createClaudeCode as me}from"ai-sdk-provider-claude-code";import{createGeminiProvider as he}from"ai-sdk-provider-gemini-cli";import{APICallError as L,LoadAPIKeyError as ge,NoSuchModelError as R}from"@ai-sdk/provider";import{generateId as z}from"@ai-sdk/provider-utils";import{parse as _e}from"jsonc-parser";import{createCodexCli as ve}from"ai-sdk-provider-codex-cli";import{createOpenAICompatible as ye}from"@ai-sdk/openai-compatible";var be=Object.defineProperty,xe=e=>{let t={};for(var n in e)be(t,n,{get:e[n],enumerable:!0});return t},B=E(import.meta.url);let V=null;var H=class e{constructor(){this._providers=new Map,this._initialized=!1}static getInstance(){return V||=new e,V}initialize(){return this._initialized||=!0,this}registerProvider(e,t,n={}){if(!e||typeof e!=`string`)throw Error(`Provider name must be a non-empty string`);if(!t)throw Error(`Provider instance is required`);if(typeof t.generateText!=`function`||typeof t.streamText!=`function`||typeof t.generateObject!=`function`)throw Error(`Provider must implement BaseAIProvider interface`);return this._providers.set(e,{instance:t,options:n,registeredAt:new Date}),this}hasProvider(e){return this._providers.has(e)}getProvider(e){let t=this._providers.get(e);return t?t.instance:null}getAllProviders(){return new Map(this._providers)}unregisterProvider(e){return this._providers.has(e)?(this._providers.delete(e),!0):!1}reset(){this._providers.clear(),this._initialized=!1}};H.getInstance().initialize();var U=H;const{JSONParseError:Se,NoObjectGeneratedError:Ce,generateObject:we,generateText:Te,streamObject:Ee,streamText:De,zodSchema:Oe}=P,W=P.jsonSchema,ke=new Set([`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`]),Ae=[`additionalProperties`,`contains`,`if`,`then`,`else`,`not`,`propertyNames`],je=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],Me=[`definitions`,`$defs`,`dependentSchemas`,`patternProperties`,`properties`],Ne=e=>e?Array.isArray(e)?e.includes(`integer`):e===`integer`:!1,G=e=>{if(!e||typeof e!=`object`)return e;if(Array.isArray(e))return e.map(G);let t={...e};if(Ne(t.type))for(let e of ke)e in t&&delete t[e];for(let e of Ae)t[e]&&(t[e]=G(t[e]));for(let e of je)Array.isArray(t[e])&&(t[e]=t[e].map(G));for(let e of Me)if(t[e]&&typeof t[e]==`object`){let n={};for(let[r,i]of Object.entries(t[e]))n[r]=G(i);t[e]=n}return t.items&&=G(t.items),t},K=e=>{if(!e||typeof e!=`object`)return e;if(Array.isArray(e))return e.map(K);let t={};for(let[n,r]of Object.entries(e))t[n]=K(r);let n=t.type===`object`,r=t.properties&&typeof t.properties==`object`&&!Array.isArray(t.properties),i=Object.prototype.hasOwnProperty.call(t,`additionalProperties`),a=r?Object.keys(t.properties):[],o=Array.isArray(t.required),s=o?new Set(t.required):new Set,c=o&&a.every(e=>s.has(e))&&t.required.length===a.length;return n&&r&&!i&&(t.additionalProperties=!1),n&&r&&!c&&(t.required=a),t},q=e=>{let t=Oe(e);if(!t||typeof t!=`object`||!t.jsonSchema)return t;let n=K(G(t.jsonSchema));return typeof W==`function`?W(n,{validate:t.validate}):{...t,jsonSchema:n}};var J=class e{constructor(){if(this.constructor===e)throw Error(`BaseAIProvider cannot be instantiated directly`);this.name=this.constructor.name,this._proxyAgent=null,this.needsExplicitJsonSchema=!1,this.supportsTemperature=!0}validateAuth(e){if(!e.apiKey)throw Error(`${this.name} API key is required`)}createProxyFetch(){this._projectRoot||=v();let e=this._projectRoot;if(i(null,e))return this._proxyAgent||=new I,(e,t={})=>fetch(e,{...t,dispatcher:this._proxyAgent})}validateParams(e){if(this.validateAuth(e),!e.modelId)throw Error(`${this.name} Model ID is required`);this.validateOptionalParams(e)}validateOptionalParams(e){if(e.temperature!==void 0&&(e.temperature<0||e.temperature>1))throw Error(`Temperature must be between 0 and 1`);if(e.maxTokens!==void 0){let t=Number(e.maxTokens);if(!Number.isFinite(t)||t<=0)throw Error(`maxTokens must be a finite number greater than 0`)}}validateMessages(e){if(!e||!Array.isArray(e)||e.length===0)throw Error(`Invalid or empty messages array provided`);for(let t of e)if(!t.role||!t.content)throw Error(`Invalid message format. Each message must have role and content`)}handleError(e,t){let n=t.message||`Unknown error occurred`;throw C(`error`,`${this.name} ${e} failed: ${n}`,{error:t}),Error(`${this.name} API error during ${e}: ${n}`)}getClient(e){throw Error(`getClient must be implemented by provider`)}isRequiredApiKey(){return!0}getRequiredApiKeyName(){throw Error(`getRequiredApiKeyName must be implemented by provider`)}prepareTokenParam(e,t){return t===void 0?{}:{maxOutputTokens:Math.floor(Number(t))}}async generateText(e){try{this.validateParams(e),this.validateMessages(e.messages),C(`debug`,`Generating ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.generateText`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=await Te({model:t(e.modelId),messages:e.messages,...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r}});C(`debug`,`${this.name} generateText completed successfully for model: ${e.modelId}`);let a=i.usage?.inputTokens??i.usage?.promptTokens??0,o=i.usage?.outputTokens??i.usage?.completionTokens??0,s=i.usage?.totalTokens??a+o;return{text:i.text,usage:{inputTokens:a,outputTokens:o,totalTokens:s}}}catch(e){this.handleError(`text generation`,e)}}async streamText(e){try{this.validateParams(e),this.validateMessages(e.messages),C(`debug`,`Streaming ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.streamText`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=await De({model:t(e.modelId),messages:e.messages,...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r},...e.experimental_transform&&{experimental_transform:e.experimental_transform}});return C(`debug`,`${this.name} streamText initiated successfully for model: ${e.modelId}`),i}catch(e){this.handleError(`text streaming`,e)}}async streamObject(e){try{if(this.validateParams(e),this.validateMessages(e.messages),!e.schema)throw Error(`Schema is required for object streaming`);C(`debug`,`Streaming ${this.name} object with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.streamObject`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=q(e.schema),a=await Ee({model:t(e.modelId),messages:e.messages,schema:i,mode:e.mode||`auto`,maxOutputTokens:e.maxTokens,...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r}});return C(`debug`,`${this.name} streamObject initiated successfully for model: ${e.modelId}`),a}catch(e){this.handleError(`object streaming`,e)}}async generateObject(e){try{if(this.validateParams(e),this.validateMessages(e.messages),!e.schema)throw Error(`Schema is required for object generation`);if(!e.objectName)throw Error(`Object name is required for object generation`);C(`debug`,`Generating ${this.name} object ('${e.objectName}') with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.generateObject.${e.objectName}`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=q(e.schema),a=await we({model:t(e.modelId),messages:e.messages,schema:i,mode:this.needsExplicitJsonSchema?`json`:`auto`,schemaName:e.objectName,schemaDescription:`Generate a valid JSON object for ${e.objectName}`,maxTokens:e.maxTokens,...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r}});C(`debug`,`${this.name} generateObject completed successfully for model: ${e.modelId}`);let o=a.usage?.inputTokens??a.usage?.promptTokens??0,s=a.usage?.outputTokens??a.usage?.completionTokens??0,c=a.usage?.totalTokens??o+s;return{object:a.object,usage:{inputTokens:o,outputTokens:s,totalTokens:c}}}catch(e){if(Ce.isInstance(e)&&e.cause instanceof Se&&e.cause.text){C(`warn`,`${this.name} generated malformed JSON, attempting to repair...`);try{let t=F(e.cause.text),n=JSON.parse(t);return C(`info`,`Successfully repaired ${this.name} JSON output`),{object:n,usage:{inputTokens:e.usage?.promptTokens||e.usage?.inputTokens||0,outputTokens:e.usage?.completionTokens||e.usage?.outputTokens||0,totalTokens:e.usage?.totalTokens||0}}}catch(e){C(`error`,`Failed to repair ${this.name} JSON: ${e.message}`)}}this.handleError(`object generation`,e)}}},Pe=class extends J{constructor(){super(),this.name=`Anthropic`}getRequiredApiKeyName(){return`ANTHROPIC_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return ne({apiKey:t,...n&&{baseURL:n},headers:{"anthropic-beta":`output-128k-2025-02-19`},...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}},Fe=class extends J{constructor(){super(),this.name=`Perplexity`}getRequiredApiKeyName(){return`PERPLEXITY_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return re({apiKey:t,baseURL:n||`https://api.perplexity.ai`,...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}async generateObject(e){return super.generateObject({...e,mode:`json`})}},Ie=class extends J{constructor(){super(),this.name=`Google`}getRequiredApiKeyName(){return`GOOGLE_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return ie({apiKey:t,...n&&{baseURL:n},...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}},Le=class extends J{constructor(){super(),this.name=`OpenAI`}getRequiredApiKeyName(){return`OPENAI_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return ae({apiKey:t,...n&&{baseURL:n},...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}},Re=class extends J{constructor(){super(),this.name=`xAI`}getRequiredApiKeyName(){return`XAI_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e;return oe({apiKey:t,baseURL:n||`https://api.x.ai/v1`})}catch(e){this.handleError(`client initialization`,e)}}},ze=class extends J{constructor(){super(),this.name=`Groq`}getRequiredApiKeyName(){return`GROQ_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e;return se({apiKey:t,...n&&{baseURL:n}})}catch(e){this.handleError(`client initialization`,e)}}},Be=class extends J{constructor(){super(),this.name=`OpenRouter`}getRequiredApiKeyName(){return`OPENROUTER_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e;return ce({apiKey:t,...n&&{baseURL:n}})}catch(e){this.handleError(`client initialization`,e)}}},Ve=class extends J{constructor(){super(),this.name=`Ollama`}validateAuth(e){}getClient(e){try{let{baseURL:t}=e;return le({...t&&{baseURL:t}})}catch(e){this.handleError(`client initialization`,e)}}isRequiredApiKey(){return!1}getRequiredApiKeyName(){return`OLLAMA_API_KEY`}},He=class extends J{constructor(){super(),this.name=`Bedrock`}isRequiredApiKey(){return!1}getRequiredApiKeyName(){return`AWS_ACCESS_KEY_ID`}validateAuth(e){}getClient(e){try{let e=de(),t=this.createProxyFetch();return ue({credentialProvider:e,...t&&{fetch:t}})}catch(e){this.handleError(`client initialization`,e)}}},Ue=class extends J{constructor(){super(),this.name=`Azure OpenAI`}getRequiredApiKeyName(){return`AZURE_OPENAI_API_KEY`}validateAuth(e){if(!e.apiKey)throw Error(`Azure API key is required`);if(!e.baseURL)throw Error(`Azure endpoint URL is required. Set it in .taskmasterconfig global.azureBaseURL or models.[role].baseURL`)}normalizeBaseURL(e){if(!e)return e;try{let t=new URL(e),n=t.pathname.replace(/\/+$/,``);return n.endsWith(`/openai`)||(n=`${n}/openai`),t.pathname=n,t.toString()}catch{let t=e.replace(/\/+$/,``);return t.endsWith(`/openai`)?t:`${t}/openai`}}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.normalizeBaseURL(n),i=this.createProxyFetch();return fe({apiKey:t,baseURL:r,...i&&{fetch:i}})}catch(e){this.handleError(`client initialization`,e)}}},Y=class extends Error{constructor(e){super(e),this.name=`VertexAuthError`,this.code=`vertex_auth_error`}},X=class extends Error{constructor(e){super(e),this.name=`VertexConfigError`,this.code=`vertex_config_error`}},We=class extends Error{constructor(e,t){super(e),this.name=`VertexApiError`,this.code=`vertex_api_error`,this.statusCode=t}},Ge=class extends J{constructor(){super(),this.name=`Google Vertex AI`}getRequiredApiKeyName(){return`GOOGLE_API_KEY`}isRequiredApiKey(){return!1}isAuthenticationRequired(){return!0}isValidCredential(e){return e?typeof e==`string`?e.trim().length>0:typeof e==`object`:!1}validateAuth(e){let{apiKey:t,projectId:n,location:r,credentials:i}=e,a=this.isValidCredential(t),o=this.isValidCredential(i);if(!a&&!o)throw new Y(`Vertex AI requires authentication. Provide one of the following:
1
+ import{C as e,E as t,Et as n,F as r,H as i,I as a,J as o,L as s,M as c,N as l,O as u,P as d,a as f,f as p,ht as m,j as h,l as g,m as _,o as ee,s as te,ut as v,v as y,w as b,x,y as S,yt as C}from"./config-manager-DZYVJT7n.js";import{n as w,t as T}from"./sentry-C9gSa7DA.js";import{createRequire as E}from"node:module";import D,{promises as O}from"fs";import k,{join as A}from"path";import{homedir as j}from"os";import{execSync as M,spawn as N}from"child_process";import*as P from"ai";import{jsonrepair as F}from"jsonrepair";import{EnvHttpProxyAgent as I}from"undici";import{createAnthropic as ne}from"@ai-sdk/anthropic";import{createPerplexity as re}from"@ai-sdk/perplexity";import{createGoogleGenerativeAI as ie}from"@ai-sdk/google";import{createOpenAI as ae}from"@ai-sdk/openai";import{createXai as oe}from"@ai-sdk/xai";import{createGroq as se}from"@ai-sdk/groq";import{createOpenRouter as ce}from"@openrouter/ai-sdk-provider";import{createOllama as le}from"ollama-ai-provider-v2";import{createAmazonBedrock as ue}from"@ai-sdk/amazon-bedrock";import{fromNodeProviderChain as de}from"@aws-sdk/credential-providers";import{createAzure as fe}from"@ai-sdk/azure";import{createVertex as pe}from"@ai-sdk/google-vertex";import{createClaudeCode as me}from"ai-sdk-provider-claude-code";import{createGeminiProvider as he}from"ai-sdk-provider-gemini-cli";import{APICallError as L,LoadAPIKeyError as ge,NoSuchModelError as R}from"@ai-sdk/provider";import{generateId as z}from"@ai-sdk/provider-utils";import{parse as _e}from"jsonc-parser";import{createCodexCli as ve}from"ai-sdk-provider-codex-cli";import{createOpenAICompatible as ye}from"@ai-sdk/openai-compatible";var be=Object.defineProperty,xe=e=>{let t={};for(var n in e)be(t,n,{get:e[n],enumerable:!0});return t},B=E(import.meta.url);let V=null;var H=class e{constructor(){this._providers=new Map,this._initialized=!1}static getInstance(){return V||=new e,V}initialize(){return this._initialized||=!0,this}registerProvider(e,t,n={}){if(!e||typeof e!=`string`)throw Error(`Provider name must be a non-empty string`);if(!t)throw Error(`Provider instance is required`);if(typeof t.generateText!=`function`||typeof t.streamText!=`function`||typeof t.generateObject!=`function`)throw Error(`Provider must implement BaseAIProvider interface`);return this._providers.set(e,{instance:t,options:n,registeredAt:new Date}),this}hasProvider(e){return this._providers.has(e)}getProvider(e){let t=this._providers.get(e);return t?t.instance:null}getAllProviders(){return new Map(this._providers)}unregisterProvider(e){return this._providers.has(e)?(this._providers.delete(e),!0):!1}reset(){this._providers.clear(),this._initialized=!1}};H.getInstance().initialize();var U=H;const{JSONParseError:Se,NoObjectGeneratedError:Ce,generateObject:we,generateText:Te,streamObject:Ee,streamText:De,zodSchema:Oe}=P,W=P.jsonSchema,ke=new Set([`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`]),Ae=[`additionalProperties`,`contains`,`if`,`then`,`else`,`not`,`propertyNames`],je=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],Me=[`definitions`,`$defs`,`dependentSchemas`,`patternProperties`,`properties`],Ne=e=>e?Array.isArray(e)?e.includes(`integer`):e===`integer`:!1,G=e=>{if(!e||typeof e!=`object`)return e;if(Array.isArray(e))return e.map(G);let t={...e};if(Ne(t.type))for(let e of ke)e in t&&delete t[e];for(let e of Ae)t[e]&&(t[e]=G(t[e]));for(let e of je)Array.isArray(t[e])&&(t[e]=t[e].map(G));for(let e of Me)if(t[e]&&typeof t[e]==`object`){let n={};for(let[r,i]of Object.entries(t[e]))n[r]=G(i);t[e]=n}return t.items&&=G(t.items),t},K=e=>{if(!e||typeof e!=`object`)return e;if(Array.isArray(e))return e.map(K);let t={};for(let[n,r]of Object.entries(e))t[n]=K(r);let n=t.type===`object`,r=t.properties&&typeof t.properties==`object`&&!Array.isArray(t.properties),i=Object.prototype.hasOwnProperty.call(t,`additionalProperties`),a=r?Object.keys(t.properties):[],o=Array.isArray(t.required),s=o?new Set(t.required):new Set,c=o&&a.every(e=>s.has(e))&&t.required.length===a.length;return n&&r&&!i&&(t.additionalProperties=!1),n&&r&&!c&&(t.required=a),t},q=e=>{let t=Oe(e);if(!t||typeof t!=`object`||!t.jsonSchema)return t;let n=K(G(t.jsonSchema));return typeof W==`function`?W(n,{validate:t.validate}):{...t,jsonSchema:n}};var J=class e{constructor(){if(this.constructor===e)throw Error(`BaseAIProvider cannot be instantiated directly`);this.name=this.constructor.name,this._proxyAgent=null,this.needsExplicitJsonSchema=!1,this.supportsTemperature=!0}validateAuth(e){if(!e.apiKey)throw Error(`${this.name} API key is required`)}createProxyFetch(){this._projectRoot||=v();let e=this._projectRoot;if(i(null,e))return this._proxyAgent||=new I,(e,t={})=>fetch(e,{...t,dispatcher:this._proxyAgent})}validateParams(e){if(this.validateAuth(e),!e.modelId)throw Error(`${this.name} Model ID is required`);this.validateOptionalParams(e)}validateOptionalParams(e){if(e.temperature!==void 0&&(e.temperature<0||e.temperature>1))throw Error(`Temperature must be between 0 and 1`);if(e.maxTokens!==void 0){let t=Number(e.maxTokens);if(!Number.isFinite(t)||t<=0)throw Error(`maxTokens must be a finite number greater than 0`)}}validateMessages(e){if(!e||!Array.isArray(e)||e.length===0)throw Error(`Invalid or empty messages array provided`);for(let t of e)if(!t.role||!t.content)throw Error(`Invalid message format. Each message must have role and content`)}handleError(e,t){let n=t.message||`Unknown error occurred`;throw C(`error`,`${this.name} ${e} failed: ${n}`,{error:t}),Error(`${this.name} API error during ${e}: ${n}`)}getClient(e){throw Error(`getClient must be implemented by provider`)}isRequiredApiKey(){return!0}getRequiredApiKeyName(){throw Error(`getRequiredApiKeyName must be implemented by provider`)}prepareTokenParam(e,t){return t===void 0?{}:{maxOutputTokens:Math.floor(Number(t))}}async generateText(e){try{this.validateParams(e),this.validateMessages(e.messages),C(`debug`,`Generating ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.generateText`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=await Te({model:t(e.modelId),messages:e.messages,...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r}});C(`debug`,`${this.name} generateText completed successfully for model: ${e.modelId}`);let a=i.usage?.inputTokens??i.usage?.promptTokens??0,o=i.usage?.outputTokens??i.usage?.completionTokens??0,s=i.usage?.totalTokens??a+o;return{text:i.text,usage:{inputTokens:a,outputTokens:o,totalTokens:s}}}catch(e){this.handleError(`text generation`,e)}}async streamText(e){try{this.validateParams(e),this.validateMessages(e.messages),C(`debug`,`Streaming ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.streamText`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=await De({model:t(e.modelId),messages:e.messages,...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r},...e.experimental_transform&&{experimental_transform:e.experimental_transform}});return C(`debug`,`${this.name} streamText initiated successfully for model: ${e.modelId}`),i}catch(e){this.handleError(`text streaming`,e)}}async streamObject(e){try{if(this.validateParams(e),this.validateMessages(e.messages),!e.schema)throw Error(`Schema is required for object streaming`);C(`debug`,`Streaming ${this.name} object with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.streamObject`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=q(e.schema),a=await Ee({model:t(e.modelId),messages:e.messages,schema:i,mode:e.mode||`auto`,maxOutputTokens:e.maxTokens,...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r}});return C(`debug`,`${this.name} streamObject initiated successfully for model: ${e.modelId}`),a}catch(e){this.handleError(`object streaming`,e)}}async generateObject(e){try{if(this.validateParams(e),this.validateMessages(e.messages),!e.schema)throw Error(`Schema is required for object generation`);if(!e.objectName)throw Error(`Object name is required for object generation`);C(`debug`,`Generating ${this.name} object ('${e.objectName}') with model: ${e.modelId}`);let t=await this.getClient(e),n=e.commandName||`unknown`,r=T(`${this.name}.${e.modelId}.${n}.generateObject.${e.objectName}`,{command:n,outputType:e.outputType,tag:e.tag,projectHash:w(e.projectRoot),userId:e.userId,briefId:e.briefId}),i=q(e.schema),a=await we({model:t(e.modelId),messages:e.messages,schema:i,mode:this.needsExplicitJsonSchema?`json`:`auto`,schemaName:e.objectName,schemaDescription:`Generate a valid JSON object for ${e.objectName}`,maxTokens:e.maxTokens,...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...r&&{experimental_telemetry:r}});C(`debug`,`${this.name} generateObject completed successfully for model: ${e.modelId}`);let o=a.usage?.inputTokens??a.usage?.promptTokens??0,s=a.usage?.outputTokens??a.usage?.completionTokens??0,c=a.usage?.totalTokens??o+s;return{object:a.object,usage:{inputTokens:o,outputTokens:s,totalTokens:c}}}catch(e){if(Ce.isInstance(e)&&e.cause instanceof Se&&e.cause.text){C(`warn`,`${this.name} generated malformed JSON, attempting to repair...`);try{let t=F(e.cause.text),n=JSON.parse(t);return C(`info`,`Successfully repaired ${this.name} JSON output`),{object:n,usage:{inputTokens:e.usage?.promptTokens||e.usage?.inputTokens||0,outputTokens:e.usage?.completionTokens||e.usage?.outputTokens||0,totalTokens:e.usage?.totalTokens||0}}}catch(e){C(`error`,`Failed to repair ${this.name} JSON: ${e.message}`)}}this.handleError(`object generation`,e)}}},Pe=class extends J{constructor(){super(),this.name=`Anthropic`}getRequiredApiKeyName(){return`ANTHROPIC_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return ne({apiKey:t,...n&&{baseURL:n},headers:{"anthropic-beta":`output-128k-2025-02-19`},...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}},Fe=class extends J{constructor(){super(),this.name=`Perplexity`}getRequiredApiKeyName(){return`PERPLEXITY_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return re({apiKey:t,baseURL:n||`https://api.perplexity.ai`,...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}async generateObject(e){return super.generateObject({...e,mode:`json`})}},Ie=class extends J{constructor(){super(),this.name=`Google`}getRequiredApiKeyName(){return`GOOGLE_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return ie({apiKey:t,...n&&{baseURL:n},...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}},Le=class extends J{constructor(){super(),this.name=`OpenAI`}getRequiredApiKeyName(){return`OPENAI_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.createProxyFetch();return ae({apiKey:t,...n&&{baseURL:n},...r&&{fetch:r}})}catch(e){this.handleError(`client initialization`,e)}}},Re=class extends J{constructor(){super(),this.name=`xAI`}getRequiredApiKeyName(){return`XAI_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e;return oe({apiKey:t,baseURL:n||`https://api.x.ai/v1`})}catch(e){this.handleError(`client initialization`,e)}}},ze=class extends J{constructor(){super(),this.name=`Groq`}getRequiredApiKeyName(){return`GROQ_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e;return se({apiKey:t,...n&&{baseURL:n}})}catch(e){this.handleError(`client initialization`,e)}}},Be=class extends J{constructor(){super(),this.name=`OpenRouter`}getRequiredApiKeyName(){return`OPENROUTER_API_KEY`}getClient(e){try{let{apiKey:t,baseURL:n}=e;return ce({apiKey:t,...n&&{baseURL:n}})}catch(e){this.handleError(`client initialization`,e)}}},Ve=class extends J{constructor(){super(),this.name=`Ollama`}validateAuth(e){}getClient(e){try{let{baseURL:t}=e;return le({...t&&{baseURL:t}})}catch(e){this.handleError(`client initialization`,e)}}isRequiredApiKey(){return!1}getRequiredApiKeyName(){return`OLLAMA_API_KEY`}},He=class extends J{constructor(){super(),this.name=`Bedrock`}isRequiredApiKey(){return!1}getRequiredApiKeyName(){return`AWS_ACCESS_KEY_ID`}validateAuth(e){}getClient(e){try{let e=de(),t=this.createProxyFetch();return ue({credentialProvider:e,...t&&{fetch:t}})}catch(e){this.handleError(`client initialization`,e)}}},Ue=class extends J{constructor(){super(),this.name=`Azure OpenAI`}getRequiredApiKeyName(){return`AZURE_OPENAI_API_KEY`}validateAuth(e){if(!e.apiKey)throw Error(`Azure API key is required`);if(!e.baseURL)throw Error(`Azure endpoint URL is required. Set it in .taskmasterconfig global.azureBaseURL or models.[role].baseURL`)}normalizeBaseURL(e){if(!e)return e;try{let t=new URL(e),n=t.pathname.replace(/\/+$/,``);return n.endsWith(`/openai`)||(n=`${n}/openai`),t.pathname=n,t.toString()}catch{let t=e.replace(/\/+$/,``);return t.endsWith(`/openai`)?t:`${t}/openai`}}getClient(e){try{let{apiKey:t,baseURL:n}=e,r=this.normalizeBaseURL(n),i=this.createProxyFetch();return fe({apiKey:t,baseURL:r,...i&&{fetch:i}})}catch(e){this.handleError(`client initialization`,e)}}},Y=class extends Error{constructor(e){super(e),this.name=`VertexAuthError`,this.code=`vertex_auth_error`}},X=class extends Error{constructor(e){super(e),this.name=`VertexConfigError`,this.code=`vertex_config_error`}},We=class extends Error{constructor(e,t){super(e),this.name=`VertexApiError`,this.code=`vertex_api_error`,this.statusCode=t}},Ge=class extends J{constructor(){super(),this.name=`Google Vertex AI`}getRequiredApiKeyName(){return`GOOGLE_API_KEY`}isRequiredApiKey(){return!1}isAuthenticationRequired(){return!0}isValidCredential(e){return e?typeof e==`string`?e.trim().length>0:typeof e==`object`:!1}validateAuth(e){let{apiKey:t,projectId:n,location:r,credentials:i}=e,a=this.isValidCredential(t),o=this.isValidCredential(i);if(!a&&!o)throw new Y(`Vertex AI requires authentication. Provide one of the following:
2
2
  • GOOGLE_API_KEY environment variable (typical for API-based auth), OR
3
3
  • GOOGLE_APPLICATION_CREDENTIALS pointing to a service account JSON file (recommended for production)`);if(!n||typeof n==`string`&&n.trim().length===0)throw new X(`Google Cloud project ID is required for Vertex AI. Set VERTEX_PROJECT_ID environment variable.`);if(!r||typeof r==`string`&&r.trim().length===0)throw new X(`Google Cloud location is required for Vertex AI. Set VERTEX_LOCATION environment variable (e.g., "us-central1").`)}getClient(e){try{let{apiKey:t,projectId:n,location:r,credentials:i,baseURL:a}=e,o=this.createProxyFetch(),s={};return t?s.googleAuthOptions={...i,apiKey:t}:i&&(s.googleAuthOptions=i),pe({...s,project:n,location:r,...a&&{baseURL:a},...o&&{fetch:o}})}catch(e){this.handleError(`client initialization`,e)}}handleError(e,t){if(C(`error`,`Vertex AI ${e} error:`,t),t.name===`VertexAuthError`||t.name===`VertexConfigError`||t.name===`VertexApiError`)throw t;if(t.response){let e=t.response.status,n=t.response.data?.error?.message||t.message;throw e===401||e===403?new Y(`Authentication failed: ${n}`):e===400?new X(`Invalid request: ${n}`):new We(`API error (${e}): ${n}`,e)}throw Error(`Vertex AI ${e} failed: ${t.message}`)}};let Ke=!1;var qe=class extends J{constructor(){super(),this.name=`Claude Code`,this.supportedModels=d(`claude-code`),this.supportedModels.length===0&&C(`warn`,`No supported models found for claude-code provider. Check supported-models.json configuration.`),this.needsExplicitJsonSchema=!0,this.supportsTemperature=!1}getRequiredApiKeyName(){return`CLAUDE_CODE_API_KEY`}isRequiredApiKey(){return!1}validateAuth(e){if(process.env.NODE_ENV!==`test`&&!Ke&&!process.env.CLAUDE_CODE_OAUTH_TOKEN)try{M(`claude --version`,{stdio:`pipe`,timeout:1e3})}catch{C(`warn`,`Claude Code CLI not detected. Install it with: npm install -g @anthropic-ai/claude-code`)}finally{Ke=!0}}getClient(e={}){try{let t=g(e.commandName)||{},n=process.env.ANTHROPIC_API_KEY,r=process.env.CLAUDE_CODE_API_KEY;try{return r?process.env.ANTHROPIC_API_KEY=r:n&&delete process.env.ANTHROPIC_API_KEY,me({defaultSettings:{systemPrompt:{type:`preset`,preset:`claude_code`},settingSources:[`user`,`project`,`local`],...t}})}finally{n?process.env.ANTHROPIC_API_KEY=n:delete process.env.ANTHROPIC_API_KEY}}catch(e){let t=String(e?.message||``);if(e?.code===`ENOENT`||/claude/i.test(t)){let t=Error(`Claude Code CLI not available. Please install Claude Code CLI first. Original error: ${e.message}`);t.cause=e,this.handleError(`Claude Code CLI initialization`,t)}else this.handleError(`client initialization`,e)}}getSupportedModels(){return this.supportedModels}isModelSupported(e){return e?this.supportedModels.includes(String(e).toLowerCase()):!1}},Je=class extends J{constructor(){super(),this.name=`Gemini CLI`,this.supportsTemperature=!1}validateAuth(e){}async getClient(e){try{let t={};return t=e.apiKey&&e.apiKey!==`gemini-cli-no-key-required`?{authType:`api-key`,apiKey:e.apiKey}:{authType:`oauth-personal`},e.baseURL&&(t.baseURL=e.baseURL),he(t)}catch(e){this.handleError(`client initialization`,e)}}getRequiredApiKeyName(){return`GEMINI_API_KEY`}isRequiredApiKey(){return!1}};function Z({message:e,code:t,exitCode:n,stderr:r,stdout:i,promptExcerpt:a,isRetryable:o=!1}){return new L({message:e,isRetryable:o,url:`grok-cli://command`,requestBodyValues:a?{prompt:a}:void 0,data:{code:t,exitCode:n,stderr:r,stdout:i,promptExcerpt:a}})}function Ye({message:e}){return new ge({message:e||`Authentication failed. Please ensure Grok CLI is properly configured with API key.`})}function Xe({message:e,promptExcerpt:t,timeoutMs:n}){return new L({message:e,isRetryable:!0,url:`grok-cli://command`,requestBodyValues:t?{prompt:t}:void 0,data:{code:`TIMEOUT`,promptExcerpt:t,timeoutMs:n}})}function Ze({message:e}){return new L({message:e||`Grok CLI is not installed or not found in PATH. Please install with: npm install -g @vibe-kit/grok-cli`,isRetryable:!1,url:`grok-cli://installation`,requestBodyValues:void 0})}function Qe(e){let t=e.trim(),n=/```(?:json)?\s*([\s\S]*?)\s*```/i.exec(t);n&&(t=n[1]);let r=/^\s*(?:const|let|var)\s+\w+\s*=\s*([\s\S]*)/i.exec(t);r&&(t=r[1],t.trim().endsWith(`;`)&&(t=t.trim().slice(0,-1)));let i=t.indexOf(`{`),a=t.indexOf(`[`);if(i===-1&&a===-1)return e;let o=a===-1?i:i===-1?a:Math.min(i,a);t=t.slice(o);let s=e=>{let t=[];try{let n=_e(e,t,{allowTrailingComma:!0});if(t.length===0)return JSON.stringify(n,null,2)}catch{}},c=s(t);if(c!==void 0)return c;let l=t[0],u=l===`{`?`}`:`]`,d=[],f=0,p=!1,m=!1;for(let e=0;e<t.length;e++){let n=t[e];if(m){m=!1;continue}if(n===`\\`){m=!0;continue}if(n===`"`&&!p){p=!0;continue}if(n===`"`&&p){p=!1;continue}p||(n===l?f++:n===u&&(f--,f===0&&d.push(e+1)))}for(let e=d.length-1;e>=0;e--){let n=s(t.slice(0,d[e]));if(n!==void 0)return n}let h=Math.max(0,t.length-1e3);for(let e=t.length-1;e>h;e--){let n=s(t.slice(0,e));if(n!==void 0)return n}return e}function $e(e){return e.map(e=>{let t=``;return typeof e.content==`string`?t=e.content:Array.isArray(e.content)?t=e.content.filter(e=>e.type===`text`).map(e=>e.text||``).join(`
4
4
  `):e.content&&typeof e.content==`object`&&(t=e.content.text||JSON.stringify(e.content)),{role:e.role,content:t.trim()}})}function et(e){try{let t=e.trim().split(`
@@ -1,4 +1,4 @@
1
- import"./ai-services-unified-DtYBHWxu.js";import{B as e,Bt as t,D as n,Ht as r,Kt as i,Lt as a,Nt as o,On as s,Q as c,Rt as l,Tt as u,U as d,Ut as f,Vt as p,dt as m,h,hn as g,ln as ee,m as _,mn as te,p as v,t as y,ut as ne,yt as b,z as x}from"./config-manager-Bj2cZEwZ.js";import"./git-utils-DllbRE35.js";import"./sentry-ClkRpQLz.js";import{$ as S,C,D as w,F as T,I as E,J as re,L as ie,M as ae,N as oe,O as se,P as ce,Q as le,S as ue,St as de,X as D,Y as fe,Z as pe,_ as me,_t as he,a as ge,at as O,b as _e,bt as ve,c as ye,ct as be,d as k,dt as xe,et as A,f as Se,g as Ce,h as we,ht as Te,i as Ee,it as De,j as Oe,k as j,l as ke,m as Ae,n as je,nt as Me,o as Ne,ot as Pe,p as M,r as Fe,rt as Ie,s as Le,st as Re,t as ze,tt as Be,u as Ve,ut as He,v as N,vt as Ue,w as We,wt as Ge,xt as Ke,y as qe,yt as Je}from"./dependency-manager-DVN8Tt-x.js";import{t as Ye}from"./response-language-DgK4p10V.js";import{_ as Xe,a as Ze,c as Qe,d as $e,f as et,g as tt,h as nt,i as rt,l as P,m as it,n as at,o as F,p as ot,r as st,s as I,t as L,u as R,v as z}from"./profiles-C4AS-UkT.js";import B from"chalk";import V from"fs";import H from"path";import U from"boxen";import{Command as ct}from"commander";import W from"inquirer";const G={AUTHENTICATION:`authentication`,VALIDATION:`validation`,NETWORK:`network`,API:`api`,FILE_SYSTEM:`file_system`,TASK:`task`,PERMISSION:`permission`,TIMEOUT:`timeout`,GENERIC:`generic`},lt=[/\b[A-Za-z0-9_-]{20,}\b/g,/sk-[A-Za-z0-9]{32,}/g,/api[_-]?key[:\s=]+[^\s]+/gi,/bearer\s+[^\s]+/gi,/token[:\s=]+[^\s]+/gi,/\/Users\/[^/]+/g,/C:\\Users\\[^\\]+/g,/\/home\/[^/]+/g,/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,/https?:\/\/[^:]+:[^@]+@/g];function K(e){if(!e||typeof e!=`string`)return e;let t=e;for(let e of lt)t=t.replace(e,`***REDACTED***`);return t}function ut(e){if(!e)return G.GENERIC;let t=(e.message||``).toLowerCase(),n=(e.code||``).toLowerCase();return t.includes(`auth`)||t.includes(`unauthorized`)||t.includes(`forbidden`)||t.includes(`api key`)||t.includes(`token`)||n.includes(`auth`)?G.AUTHENTICATION:t.includes(`invalid`)||t.includes(`validation`)||t.includes(`required`)||t.includes(`must be`)||n.includes(`validation`)?G.VALIDATION:t.includes(`network`)||t.includes(`connection`)||t.includes(`econnrefused`)||t.includes(`enotfound`)||n.includes(`network`)||n.includes(`econnrefused`)||n.includes(`enotfound`)?G.NETWORK:t.includes(`timeout`)||t.includes(`timed out`)||n.includes(`timeout`)?G.TIMEOUT:t.includes(`api`)||t.includes(`rate limit`)||t.includes(`quota`)||n.includes(`api`)?G.API:t.includes(`enoent`)||t.includes(`eacces`)||t.includes(`file`)||t.includes(`directory`)||n.includes(`enoent`)||n.includes(`eacces`)?G.FILE_SYSTEM:t.includes(`permission`)||t.includes(`access denied`)||n.includes(`eperm`)?G.PERMISSION:t.includes(`task`)||t.includes(`subtask`)?G.TASK:G.GENERIC}function dt(e,t,n){let r=[],i=(t.message||``).toLowerCase();switch(e){case G.AUTHENTICATION:i.includes(`api key`)?(r.push(`Check that your API key is correctly set in the .env file`),r.push(`Verify the API key has not expired or been revoked`)):i.includes(`token`)?(r.push(`Your authentication token may have expired`),r.push(`Try running: tm auth refresh`)):(r.push(`Verify your credentials are correctly configured`),r.push(`Check the authentication status with: tm auth status`));break;case G.VALIDATION:i.includes(`brief id`)?(r.push(`Brief IDs are case-insensitive (e.g., "ham32" = "HAM-32")`),r.push(`Check the brief ID format: usually LETTERS-NUMBERS`)):i.includes(`task id`)||i.includes(`invalid id`)?(r.push(`Task IDs should be numbers (e.g., 1, 2, 3)`),r.push(`Subtask IDs use dot notation (e.g., 1.1, 2.3)`)):(r.push(`Check that all required parameters are provided`),r.push(`Verify parameter values match expected formats`));break;case G.NETWORK:i.includes(`econnrefused`)?(r.push(`Could not connect to the server`),r.push(`Check your internet connection`),r.push(`Verify the API endpoint URL is correct`)):i.includes(`enotfound`)?(r.push(`Could not resolve the server hostname`),r.push(`Check your internet connection`)):(r.push(`Check your network connection`),r.push(`Verify firewall settings are not blocking the request`));break;case G.TIMEOUT:r.push(`The operation took too long to complete`),r.push(`Try again with a simpler request`),r.push(`Check your network speed and stability`);break;case G.API:i.includes(`rate limit`)?(r.push(`You have exceeded the API rate limit`),r.push(`Wait a few minutes before trying again`)):i.includes(`quota`)?(r.push(`You have reached your API quota`),r.push(`Check your account usage and limits`)):(r.push(`The API returned an error`),r.push(`Try again in a few moments`));break;case G.FILE_SYSTEM:i.includes(`enoent`)?(r.push(`The specified file or directory does not exist`),r.push(`Check the file path and ensure it is correct`),n.includes(`tasks.json`)&&r.push(`Initialize the project with: tm init`)):i.includes(`eacces`)?(r.push(`Permission denied to access the file`),r.push(`Check file permissions or run with appropriate privileges`)):r.push(`Check that the file or directory exists and is accessible`);break;case G.PERMISSION:r.push(`You do not have permission to perform this operation`),r.push(`Check file/directory permissions`),r.push(`You may need elevated privileges (sudo)`);break;case G.TASK:i.includes(`not found`)?(r.push(`The specified task does not exist`),r.push(`Use: tm list to see all available tasks`)):i.includes(`dependency`)||i.includes(`circular`)?(r.push(`Task dependencies form a circular reference`),r.push(`Use: tm validate-dependencies to identify issues`)):(r.push(`Check that the task ID is correct`),r.push(`Use: tm show <id> to view task details`));break;default:r.push(`Check the error message for specific details`),n&&r.push(`Operation failed while: ${n}`)}return r.slice(0,2)}function ft(e,t={}){let{context:n=``,debug:r=!1,command:i=``}=t;typeof e==`string`&&(e=Error(e)),(!e||typeof e!=`object`)&&(e=Error(`An unknown error occurred`));let a=K(e.message||`Unknown error`),o=ut(e),s=dt(o,e,n);return{type:o,message:a,context:n||`Unknown operation`,hints:s,command:i||null,code:e.code||null,stack:r?K(e.stack):null}}function q(e,t={}){let n=ft(e,t),r=B.red.bold(`✗ Error
1
+ import"./ai-services-unified-C_wzEmAq.js";import{B as e,Bt as t,D as n,Ht as r,Kt as i,Lt as a,Nt as o,On as s,Q as c,Rt as l,Tt as u,U as d,Ut as f,Vt as p,dt as m,h,hn as g,ln as ee,m as _,mn as te,p as v,t as y,ut as ne,yt as b,z as x}from"./config-manager-DZYVJT7n.js";import"./git-utils-DllbRE35.js";import"./sentry-C9gSa7DA.js";import{$ as S,C,D as w,F as T,I as E,J as re,L as ie,M as ae,N as oe,O as se,P as ce,Q as le,S as ue,St as de,X as D,Y as fe,Z as pe,_ as me,_t as he,a as ge,at as O,b as _e,bt as ve,c as ye,ct as be,d as k,dt as xe,et as A,f as Se,g as Ce,h as we,ht as Te,i as Ee,it as De,j as Oe,k as j,l as ke,m as Ae,n as je,nt as Me,o as Ne,ot as Pe,p as M,r as Fe,rt as Ie,s as Le,st as Re,t as ze,tt as Be,u as Ve,ut as He,v as N,vt as Ue,w as We,wt as Ge,xt as Ke,y as qe,yt as Je}from"./dependency-manager-DvEjtS1v.js";import{t as Ye}from"./response-language-C-QKf5DA.js";import{_ as Xe,a as Ze,c as Qe,d as $e,f as et,g as tt,h as nt,i as rt,l as P,m as it,n as at,o as F,p as ot,r as st,s as I,t as L,u as R,v as z}from"./profiles-7X56Fodc.js";import B from"chalk";import V from"fs";import H from"path";import U from"boxen";import{Command as ct}from"commander";import W from"inquirer";const G={AUTHENTICATION:`authentication`,VALIDATION:`validation`,NETWORK:`network`,API:`api`,FILE_SYSTEM:`file_system`,TASK:`task`,PERMISSION:`permission`,TIMEOUT:`timeout`,GENERIC:`generic`},lt=[/\b[A-Za-z0-9_-]{20,}\b/g,/sk-[A-Za-z0-9]{32,}/g,/api[_-]?key[:\s=]+[^\s]+/gi,/bearer\s+[^\s]+/gi,/token[:\s=]+[^\s]+/gi,/\/Users\/[^/]+/g,/C:\\Users\\[^\\]+/g,/\/home\/[^/]+/g,/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,/https?:\/\/[^:]+:[^@]+@/g];function K(e){if(!e||typeof e!=`string`)return e;let t=e;for(let e of lt)t=t.replace(e,`***REDACTED***`);return t}function ut(e){if(!e)return G.GENERIC;let t=(e.message||``).toLowerCase(),n=(e.code||``).toLowerCase();return t.includes(`auth`)||t.includes(`unauthorized`)||t.includes(`forbidden`)||t.includes(`api key`)||t.includes(`token`)||n.includes(`auth`)?G.AUTHENTICATION:t.includes(`invalid`)||t.includes(`validation`)||t.includes(`required`)||t.includes(`must be`)||n.includes(`validation`)?G.VALIDATION:t.includes(`network`)||t.includes(`connection`)||t.includes(`econnrefused`)||t.includes(`enotfound`)||n.includes(`network`)||n.includes(`econnrefused`)||n.includes(`enotfound`)?G.NETWORK:t.includes(`timeout`)||t.includes(`timed out`)||n.includes(`timeout`)?G.TIMEOUT:t.includes(`api`)||t.includes(`rate limit`)||t.includes(`quota`)||n.includes(`api`)?G.API:t.includes(`enoent`)||t.includes(`eacces`)||t.includes(`file`)||t.includes(`directory`)||n.includes(`enoent`)||n.includes(`eacces`)?G.FILE_SYSTEM:t.includes(`permission`)||t.includes(`access denied`)||n.includes(`eperm`)?G.PERMISSION:t.includes(`task`)||t.includes(`subtask`)?G.TASK:G.GENERIC}function dt(e,t,n){let r=[],i=(t.message||``).toLowerCase();switch(e){case G.AUTHENTICATION:i.includes(`api key`)?(r.push(`Check that your API key is correctly set in the .env file`),r.push(`Verify the API key has not expired or been revoked`)):i.includes(`token`)?(r.push(`Your authentication token may have expired`),r.push(`Try running: tm auth refresh`)):(r.push(`Verify your credentials are correctly configured`),r.push(`Check the authentication status with: tm auth status`));break;case G.VALIDATION:i.includes(`brief id`)?(r.push(`Brief IDs are case-insensitive (e.g., "ham32" = "HAM-32")`),r.push(`Check the brief ID format: usually LETTERS-NUMBERS`)):i.includes(`task id`)||i.includes(`invalid id`)?(r.push(`Task IDs should be numbers (e.g., 1, 2, 3)`),r.push(`Subtask IDs use dot notation (e.g., 1.1, 2.3)`)):(r.push(`Check that all required parameters are provided`),r.push(`Verify parameter values match expected formats`));break;case G.NETWORK:i.includes(`econnrefused`)?(r.push(`Could not connect to the server`),r.push(`Check your internet connection`),r.push(`Verify the API endpoint URL is correct`)):i.includes(`enotfound`)?(r.push(`Could not resolve the server hostname`),r.push(`Check your internet connection`)):(r.push(`Check your network connection`),r.push(`Verify firewall settings are not blocking the request`));break;case G.TIMEOUT:r.push(`The operation took too long to complete`),r.push(`Try again with a simpler request`),r.push(`Check your network speed and stability`);break;case G.API:i.includes(`rate limit`)?(r.push(`You have exceeded the API rate limit`),r.push(`Wait a few minutes before trying again`)):i.includes(`quota`)?(r.push(`You have reached your API quota`),r.push(`Check your account usage and limits`)):(r.push(`The API returned an error`),r.push(`Try again in a few moments`));break;case G.FILE_SYSTEM:i.includes(`enoent`)?(r.push(`The specified file or directory does not exist`),r.push(`Check the file path and ensure it is correct`),n.includes(`tasks.json`)&&r.push(`Initialize the project with: tm init`)):i.includes(`eacces`)?(r.push(`Permission denied to access the file`),r.push(`Check file permissions or run with appropriate privileges`)):r.push(`Check that the file or directory exists and is accessible`);break;case G.PERMISSION:r.push(`You do not have permission to perform this operation`),r.push(`Check file/directory permissions`),r.push(`You may need elevated privileges (sudo)`);break;case G.TASK:i.includes(`not found`)?(r.push(`The specified task does not exist`),r.push(`Use: tm list to see all available tasks`)):i.includes(`dependency`)||i.includes(`circular`)?(r.push(`Task dependencies form a circular reference`),r.push(`Use: tm validate-dependencies to identify issues`)):(r.push(`Check that the task ID is correct`),r.push(`Use: tm show <id> to view task details`));break;default:r.push(`Check the error message for specific details`),n&&r.push(`Operation failed while: ${n}`)}return r.slice(0,2)}function ft(e,t={}){let{context:n=``,debug:r=!1,command:i=``}=t;typeof e==`string`&&(e=Error(e)),(!e||typeof e!=`object`)&&(e=Error(`An unknown error occurred`));let a=K(e.message||`Unknown error`),o=ut(e),s=dt(o,e,n);return{type:o,message:a,context:n||`Unknown operation`,hints:s,command:i||null,code:e.code||null,stack:r?K(e.stack):null}}function q(e,t={}){let n=ft(e,t),r=B.red.bold(`✗ Error
2
2
 
3
3
  `);r+=B.white(n.message)+`
4
4
 
@@ -106,7 +106,7 @@ Subtask update was not completed. Review the messages above for details.`))}catc
106
106
  To fix this issue:`)),console.log(` 1. Run task-master list --with-subtasks to see all available subtask IDs`),console.log(` 2. Use a valid subtask ID with the --id parameter in format "parentId.subtaskId"`)):e.message.includes(`API key`)&&console.log(B.yellow(`
107
107
  This error is related to API keys. Check your environment variables.`)),_()&&console.error(e),process.exit(1)}}),t.command(`scope-up`).description(`Increase task complexity with AI assistance`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-i, --id <ids>`,`Comma-separated task/subtask IDs to scope up (required)`).option(`-s, --strength <level>`,`Complexity increase strength: light, regular, heavy`,`regular`).option(`-p, --prompt <text>`,`Custom instructions for targeted scope adjustments`).option(`-r, --research`,`Use research AI for more informed adjustments`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async e=>{try{let t=J({tasksPath:e.file||!0,tag:e.tag}),n=t.getTasksPath(),r=t.getCurrentTag();await k(r),e.id||(console.error(B.red(`Error: --id parameter is required`)),console.log(B.yellow(`Usage example: task-master scope-up --id=1,2,3 --strength=regular`)),process.exit(1));let i=e.id.split(`,`).map(e=>{let t=parseInt(e.trim(),10);return(Number.isNaN(t)||t<=0)&&(console.error(B.red(`Error: Invalid task ID: ${e.trim()}`)),process.exit(1)),t});j(e.strength)||(console.error(B.red(`Error: Invalid strength level: ${e.strength}. Must be one of: light, regular, heavy`)),process.exit(1)),V.existsSync(n)||(console.error(B.red(`Error: Tasks file not found at path: ${n}`)),process.exit(1)),console.log(B.blue(`Scoping up ${i.length} task(s): ${i.join(`, `)}`)),console.log(B.blue(`Strength level: ${e.strength}`)),e.prompt&&console.log(B.blue(`Custom instructions: ${e.prompt}`));let a={projectRoot:t.getProjectRoot(),tag:r,commandName:`scope-up`,outputType:`cli`,research:e.research||!1},o=await se(n,i,e.strength,e.prompt||null,a,`text`);console.log(B.green(`✅ Successfully scoped up ${o.updatedTasks.length} task(s)`))}catch(e){console.error(B.red(`Error: ${e.message}`)),e.message.includes(`not found`)&&(console.log(B.yellow(`
108
108
  To fix this issue:`)),console.log(` 1. Run task-master list to see all available task IDs`),console.log(` 2. Use valid task IDs with the --id parameter`)),_()&&console.error(e),process.exit(1)}}),t.command(`scope-down`).description(`Decrease task complexity with AI assistance`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-i, --id <ids>`,`Comma-separated task/subtask IDs to scope down (required)`).option(`-s, --strength <level>`,`Complexity decrease strength: light, regular, heavy`,`regular`).option(`-p, --prompt <text>`,`Custom instructions for targeted scope adjustments`).option(`-r, --research`,`Use research AI for more informed adjustments`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async e=>{try{let t=J({tasksPath:e.file||!0,tag:e.tag}),n=t.getTasksPath(),r=t.getCurrentTag();await k(r),e.id||(console.error(B.red(`Error: --id parameter is required`)),console.log(B.yellow(`Usage example: task-master scope-down --id=1,2,3 --strength=regular`)),process.exit(1));let i=e.id.split(`,`).map(e=>{let t=parseInt(e.trim(),10);return(Number.isNaN(t)||t<=0)&&(console.error(B.red(`Error: Invalid task ID: ${e.trim()}`)),process.exit(1)),t});j(e.strength)||(console.error(B.red(`Error: Invalid strength level: ${e.strength}. Must be one of: light, regular, heavy`)),process.exit(1)),V.existsSync(n)||(console.error(B.red(`Error: Tasks file not found at path: ${n}`)),process.exit(1)),console.log(B.blue(`Scoping down ${i.length} task(s): ${i.join(`, `)}`)),console.log(B.blue(`Strength level: ${e.strength}`)),e.prompt&&console.log(B.blue(`Custom instructions: ${e.prompt}`));let a={projectRoot:t.getProjectRoot(),tag:r,commandName:`scope-down`,outputType:`cli`,research:e.research||!1},o=await w(n,i,e.strength,e.prompt||null,a,`text`);console.log(B.green(`✅ Successfully scoped down ${o.updatedTasks.length} task(s)`))}catch(e){console.error(B.red(`Error: ${e.message}`)),e.message.includes(`not found`)&&(console.log(B.yellow(`
109
- To fix this issue:`)),console.log(` 1. Run task-master list to see all available task IDs`),console.log(` 2. Use valid task IDs with the --id parameter`)),_()&&console.error(e),process.exit(1)}}),Pe(t),t.command(`expand`).description(`Expand a task into subtasks using AI`).option(`-i, --id <id>`,`ID of the task to expand`).option(`-a, --all`,`Expand all pending tasks based on complexity analysis`).option(`-n, --num <number>`,`Number of subtasks to generate (uses complexity analysis by default if available)`).option(`-r, --research`,`Enable research-backed generation (e.g., using Perplexity)`,!1).option(`-p, --prompt <text>`,`Additional context for subtask generation`).option(`-f, --force`,`Force expansion even if subtasks exist`,!1).option(`--file <file>`,`Path to the tasks file (relative to project root)`,i).option(`-cr, --complexity-report <file>`,`Path to the complexity report file (use this to specify the complexity report, not --file)`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async e=>{let n={tasksPath:e.file||!0,tag:e.tag};e.complexityReport&&(n.complexityReportPath=e.complexityReport);let r=J(n),i=r.getCurrentTag();if(await k(i),e.all){console.log(B.blue(`Expanding all pending tasks...`));try{await re(r.getTasksPath(),e.num,e.research,e.prompt,e.force,{projectRoot:r.getProjectRoot(),tag:i,complexityReportPath:r.getComplexityReportPath()})}catch(e){console.error(B.red(`Error expanding all tasks: ${e.message}`)),process.exit(1)}}else if(e.id){e.id||(console.error(B.red(`Error: Task ID is required unless using --all.`)),process.exit(1)),console.log(B.blue(`Expanding task ${e.id}...`));try{await fe(r.getTasksPath(),e.id,e.num,e.research,e.prompt,{projectRoot:r.getProjectRoot(),tag:i,complexityReportPath:r.getComplexityReportPath()},e.force)}catch(t){console.error(B.red(`Error expanding task ${e.id}: ${t.message}`)),process.exit(1)}}else console.error(B.red(`Error: You must specify either a task ID (--id) or --all.`)),t.help()}),t.command(`analyze-complexity`).description(`Analyze tasks and generate expansion recommendations${B.reset(``)}`).option(`-o, --output <file>`,`Output file path for the report`).option(`-m, --model <model>`,`LLM model to use for analysis (defaults to configured model)`).option(`-t, --threshold <number>`,`Minimum complexity score to recommend expansion (1-10)`,`5`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-r, --research`,`Use configured research model for research-backed complexity analysis`).option(`-i, --id <ids>`,`Comma-separated list of specific task IDs to analyze (e.g., "1,3,5")`).option(`--from <id>`,`Starting task ID in a range to analyze`).option(`--to <id>`,`Ending task ID in a range to analyze`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async e=>{let t={tasksPath:e.file||!0,tag:e.tag};e.output&&(t.complexityReportPath=e.output);let n=J(t);e.model,parseFloat(e.threshold);let r=e.research||!1,i=n.getCurrentTag();await k(i);let a=n.getComplexityReportPath();if(console.log(B.blue(`Analyzing task complexity from: ${n.getTasksPath()}`)),console.log(B.blue(`Output report will be saved to: ${a}`)),e.id)console.log(B.blue(`Analyzing specific task IDs: ${e.id}`));else if(e.from||e.to){let t=e.from?e.from:`first`,n=e.to?e.to:`last`;console.log(B.blue(`Analyzing tasks in range: ${t} to ${n}`))}r&&console.log(B.blue(`Using Perplexity AI for research-backed complexity analysis`)),await pe({...e,output:a,tag:i,projectRoot:n.getProjectRoot(),file:n.getTasksPath()})}),t.command(`research`).description(`Perform AI-powered research queries with project context`).argument(`[prompt]`,`Research prompt to investigate`).option(`--file <file>`,`Path to the tasks file`).option(`-i, --id <ids>`,`Comma-separated task/subtask IDs to include as context (e.g., "15,16.2")`).option(`-f, --files <paths>`,`Comma-separated file paths to include as context`).option(`-c, --context <text>`,`Additional custom context to include in the research prompt`).option(`-t, --tree`,`Include project file tree structure in the research context`).option(`-s, --save <file>`,`Save research results to the specified task/subtask(s)`).option(`-d, --detail <level>`,`Output detail level: low, medium, high`,`medium`).option(`--save-to <id>`,`Automatically save research results to specified task/subtask ID (e.g., "15" or "15.2")`).option(`--save-file`,`Save research results to .taskmaster/docs/research/ directory`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async(e,t)=>{let n=J({tasksPath:t.file||!0,tag:t.tag});(!e||typeof e!=`string`||e.trim().length===0)&&(console.error(B.red(`Error: Research prompt is required and cannot be empty`)),p(),process.exit(1));let r=[`low`,`medium`,`high`];t.detail&&!r.includes(t.detail.toLowerCase())&&(console.error(B.red(`Error: Detail level must be one of: ${r.join(`, `)}`)),process.exit(1));let i=[];if(t.id)try{i=t.id.split(`,`).map(e=>{let t=e.trim();if(!/^\d+(\.\d+)?$/.test(t))throw Error(`Invalid task ID format: "${t}". Expected format: "15" or "15.2"`);return t})}catch(e){console.error(B.red(`Error parsing task IDs: ${e.message}`)),process.exit(1)}let a=[];if(t.files)try{a=t.files.split(`,`).map(e=>{let t=e.trim();if(t.length===0)throw Error(`Empty file path provided`);return t})}catch(e){console.error(B.red(`Error parsing file paths: ${e.message}`)),process.exit(1)}if(t.saveTo){let e=t.saveTo.trim();e.length===0&&(console.error(B.red(`Error: Save-to ID cannot be empty`)),process.exit(1)),/^\d+(\.\d+)?$/.test(e)||(console.error(B.red(`Error: Save-to ID must be in format "15" for task or "15.2" for subtask`)),process.exit(1))}if(t.save){let e=t.save.trim();e.length===0&&(console.error(B.red(`Error: Save target cannot be empty`)),process.exit(1)),(e.includes(`..`)||e.startsWith(`/`))&&(console.error(B.red(`Error: Save path must be relative and cannot contain ".."`)),process.exit(1))}let o=n.getCurrentTag();if(await k(o),i.length>0)try{let e=u(n.getTasksPath(),n.getProjectRoot(),o);(!e||!e.tasks)&&(console.error(B.red(`Error: No valid tasks found in ${n.getTasksPath()} for tag '${o}'`)),process.exit(1))}catch(e){console.error(B.red(`Error reading tasks file: ${e.message}`)),process.exit(1)}if(a.length>0)for(let e of a){let t=H.isAbsolute(e)?e:H.join(n.getProjectRoot(),e);V.existsSync(t)||(console.error(B.red(`Error: File not found: ${e}`)),process.exit(1))}let s={prompt:e.trim(),taskIds:i,filePaths:a,customContext:t.context?t.context.trim():null,includeProjectTree:!!t.tree,saveTarget:t.save?t.save.trim():null,saveToId:t.saveTo?t.saveTo.trim():null,allowFollowUp:!0,detailLevel:t.detail?t.detail.toLowerCase():`medium`,tasksPath:n.getTasksPath(),projectRoot:n.getProjectRoot()};console.log(B.blue(`Researching: "${s.prompt}"`)),s.taskIds.length>0&&console.log(B.gray(`Task context: ${s.taskIds.join(`, `)}`)),s.filePaths.length>0&&console.log(B.gray(`File context: ${s.filePaths.join(`, `)}`)),s.customContext&&console.log(B.gray(`Custom context: ${s.customContext.substring(0,50)}${s.customContext.length>50?`...`:``}`)),s.includeProjectTree&&console.log(B.gray(`Including project file tree`)),console.log(B.gray(`Detail level: ${s.detailLevel}`));try{let{performResearch:e}=await import(`./research-UCqjqHBo.js`),n={taskIds:s.taskIds,filePaths:s.filePaths,customContext:s.customContext||``,includeProjectTree:s.includeProjectTree,detailLevel:s.detailLevel,projectRoot:s.projectRoot,saveToFile:!!t.saveFile,tag:o},r=await e(s.prompt,n,{commandName:`research`,outputType:`cli`,tag:o},`text`,s.allowFollowUp);if(s.saveToId&&!r.interactiveSaveOccurred)try{let e=s.saveToId.includes(`.`),t=`## Research Query: ${s.prompt}
109
+ To fix this issue:`)),console.log(` 1. Run task-master list to see all available task IDs`),console.log(` 2. Use valid task IDs with the --id parameter`)),_()&&console.error(e),process.exit(1)}}),Pe(t),t.command(`expand`).description(`Expand a task into subtasks using AI`).option(`-i, --id <id>`,`ID of the task to expand`).option(`-a, --all`,`Expand all pending tasks based on complexity analysis`).option(`-n, --num <number>`,`Number of subtasks to generate (uses complexity analysis by default if available)`).option(`-r, --research`,`Enable research-backed generation (e.g., using Perplexity)`,!1).option(`-p, --prompt <text>`,`Additional context for subtask generation`).option(`-f, --force`,`Force expansion even if subtasks exist`,!1).option(`--file <file>`,`Path to the tasks file (relative to project root)`,i).option(`-cr, --complexity-report <file>`,`Path to the complexity report file (use this to specify the complexity report, not --file)`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async e=>{let n={tasksPath:e.file||!0,tag:e.tag};e.complexityReport&&(n.complexityReportPath=e.complexityReport);let r=J(n),i=r.getCurrentTag();if(await k(i),e.all){console.log(B.blue(`Expanding all pending tasks...`));try{await re(r.getTasksPath(),e.num,e.research,e.prompt,e.force,{projectRoot:r.getProjectRoot(),tag:i,complexityReportPath:r.getComplexityReportPath()})}catch(e){console.error(B.red(`Error expanding all tasks: ${e.message}`)),process.exit(1)}}else if(e.id){e.id||(console.error(B.red(`Error: Task ID is required unless using --all.`)),process.exit(1)),console.log(B.blue(`Expanding task ${e.id}...`));try{await fe(r.getTasksPath(),e.id,e.num,e.research,e.prompt,{projectRoot:r.getProjectRoot(),tag:i,complexityReportPath:r.getComplexityReportPath()},e.force)}catch(t){console.error(B.red(`Error expanding task ${e.id}: ${t.message}`)),process.exit(1)}}else console.error(B.red(`Error: You must specify either a task ID (--id) or --all.`)),t.help()}),t.command(`analyze-complexity`).description(`Analyze tasks and generate expansion recommendations${B.reset(``)}`).option(`-o, --output <file>`,`Output file path for the report`).option(`-m, --model <model>`,`LLM model to use for analysis (defaults to configured model)`).option(`-t, --threshold <number>`,`Minimum complexity score to recommend expansion (1-10)`,`5`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-r, --research`,`Use configured research model for research-backed complexity analysis`).option(`-i, --id <ids>`,`Comma-separated list of specific task IDs to analyze (e.g., "1,3,5")`).option(`--from <id>`,`Starting task ID in a range to analyze`).option(`--to <id>`,`Ending task ID in a range to analyze`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async e=>{let t={tasksPath:e.file||!0,tag:e.tag};e.output&&(t.complexityReportPath=e.output);let n=J(t);e.model,parseFloat(e.threshold);let r=e.research||!1,i=n.getCurrentTag();await k(i);let a=n.getComplexityReportPath();if(console.log(B.blue(`Analyzing task complexity from: ${n.getTasksPath()}`)),console.log(B.blue(`Output report will be saved to: ${a}`)),e.id)console.log(B.blue(`Analyzing specific task IDs: ${e.id}`));else if(e.from||e.to){let t=e.from?e.from:`first`,n=e.to?e.to:`last`;console.log(B.blue(`Analyzing tasks in range: ${t} to ${n}`))}r&&console.log(B.blue(`Using Perplexity AI for research-backed complexity analysis`)),await pe({...e,output:a,tag:i,projectRoot:n.getProjectRoot(),file:n.getTasksPath()})}),t.command(`research`).description(`Perform AI-powered research queries with project context`).argument(`[prompt]`,`Research prompt to investigate`).option(`--file <file>`,`Path to the tasks file`).option(`-i, --id <ids>`,`Comma-separated task/subtask IDs to include as context (e.g., "15,16.2")`).option(`-f, --files <paths>`,`Comma-separated file paths to include as context`).option(`-c, --context <text>`,`Additional custom context to include in the research prompt`).option(`-t, --tree`,`Include project file tree structure in the research context`).option(`-s, --save <file>`,`Save research results to the specified task/subtask(s)`).option(`-d, --detail <level>`,`Output detail level: low, medium, high`,`medium`).option(`--save-to <id>`,`Automatically save research results to specified task/subtask ID (e.g., "15" or "15.2")`).option(`--save-file`,`Save research results to .taskmaster/docs/research/ directory`).option(`--tag <tag>`,`Specify tag context for task operations`).action(async(e,t)=>{let n=J({tasksPath:t.file||!0,tag:t.tag});(!e||typeof e!=`string`||e.trim().length===0)&&(console.error(B.red(`Error: Research prompt is required and cannot be empty`)),p(),process.exit(1));let r=[`low`,`medium`,`high`];t.detail&&!r.includes(t.detail.toLowerCase())&&(console.error(B.red(`Error: Detail level must be one of: ${r.join(`, `)}`)),process.exit(1));let i=[];if(t.id)try{i=t.id.split(`,`).map(e=>{let t=e.trim();if(!/^\d+(\.\d+)?$/.test(t))throw Error(`Invalid task ID format: "${t}". Expected format: "15" or "15.2"`);return t})}catch(e){console.error(B.red(`Error parsing task IDs: ${e.message}`)),process.exit(1)}let a=[];if(t.files)try{a=t.files.split(`,`).map(e=>{let t=e.trim();if(t.length===0)throw Error(`Empty file path provided`);return t})}catch(e){console.error(B.red(`Error parsing file paths: ${e.message}`)),process.exit(1)}if(t.saveTo){let e=t.saveTo.trim();e.length===0&&(console.error(B.red(`Error: Save-to ID cannot be empty`)),process.exit(1)),/^\d+(\.\d+)?$/.test(e)||(console.error(B.red(`Error: Save-to ID must be in format "15" for task or "15.2" for subtask`)),process.exit(1))}if(t.save){let e=t.save.trim();e.length===0&&(console.error(B.red(`Error: Save target cannot be empty`)),process.exit(1)),(e.includes(`..`)||e.startsWith(`/`))&&(console.error(B.red(`Error: Save path must be relative and cannot contain ".."`)),process.exit(1))}let o=n.getCurrentTag();if(await k(o),i.length>0)try{let e=u(n.getTasksPath(),n.getProjectRoot(),o);(!e||!e.tasks)&&(console.error(B.red(`Error: No valid tasks found in ${n.getTasksPath()} for tag '${o}'`)),process.exit(1))}catch(e){console.error(B.red(`Error reading tasks file: ${e.message}`)),process.exit(1)}if(a.length>0)for(let e of a){let t=H.isAbsolute(e)?e:H.join(n.getProjectRoot(),e);V.existsSync(t)||(console.error(B.red(`Error: File not found: ${e}`)),process.exit(1))}let s={prompt:e.trim(),taskIds:i,filePaths:a,customContext:t.context?t.context.trim():null,includeProjectTree:!!t.tree,saveTarget:t.save?t.save.trim():null,saveToId:t.saveTo?t.saveTo.trim():null,allowFollowUp:!0,detailLevel:t.detail?t.detail.toLowerCase():`medium`,tasksPath:n.getTasksPath(),projectRoot:n.getProjectRoot()};console.log(B.blue(`Researching: "${s.prompt}"`)),s.taskIds.length>0&&console.log(B.gray(`Task context: ${s.taskIds.join(`, `)}`)),s.filePaths.length>0&&console.log(B.gray(`File context: ${s.filePaths.join(`, `)}`)),s.customContext&&console.log(B.gray(`Custom context: ${s.customContext.substring(0,50)}${s.customContext.length>50?`...`:``}`)),s.includeProjectTree&&console.log(B.gray(`Including project file tree`)),console.log(B.gray(`Detail level: ${s.detailLevel}`));try{let{performResearch:e}=await import(`./research-DlLk0rWJ.js`),n={taskIds:s.taskIds,filePaths:s.filePaths,customContext:s.customContext||``,includeProjectTree:s.includeProjectTree,detailLevel:s.detailLevel,projectRoot:s.projectRoot,saveToFile:!!t.saveFile,tag:o},r=await e(s.prompt,n,{commandName:`research`,outputType:`cli`,tag:o},`text`,s.allowFollowUp);if(s.saveToId&&!r.interactiveSaveOccurred)try{let e=s.saveToId.includes(`.`),t=`## Research Query: ${s.prompt}
110
110
 
111
111
  **Detail Level:** ${r.detailLevel}
112
112
  **Context Size:** ${r.contextSize} characters
@@ -114,7 +114,7 @@ To fix this issue:`)),console.log(` 1. Run task-master list to see all availabl
114
114
 
115
115
  ### Results
116
116
 
117
- ${r.result}`;if(e){let{updateSubtaskById:e}=await import(`./update-subtask-by-id-B3lz3TnC.js`);await e(s.tasksPath,s.saveToId,t,!1,{commandName:`research-save`,outputType:`cli`,projectRoot:s.projectRoot,tag:o},`text`),console.log(B.green(`✅ Research saved to subtask ${s.saveToId}`))}else{let e=(await import(`./update-task-by-id-YhPa_LeH.js`)).default,n=parseInt(s.saveToId,10);await e(s.tasksPath,n,t,!1,{commandName:`research-save`,outputType:`cli`,projectRoot:s.projectRoot,tag:o},`text`,!0),console.log(B.green(`✅ Research saved to task ${s.saveToId}`))}}catch(e){console.log(B.red(`❌ Error saving to task/subtask: ${e.message}`))}if(s.saveTarget){let e=`# Research Query: ${s.prompt}
117
+ ${r.result}`;if(e){let{updateSubtaskById:e}=await import(`./update-subtask-by-id-DKVRZTLI.js`);await e(s.tasksPath,s.saveToId,t,!1,{commandName:`research-save`,outputType:`cli`,projectRoot:s.projectRoot,tag:o},`text`),console.log(B.green(`✅ Research saved to subtask ${s.saveToId}`))}else{let e=(await import(`./update-task-by-id-aVi1O1ZL.js`)).default,n=parseInt(s.saveToId,10);await e(s.tasksPath,n,t,!1,{commandName:`research-save`,outputType:`cli`,projectRoot:s.projectRoot,tag:o},`text`,!0),console.log(B.green(`✅ Research saved to task ${s.saveToId}`))}}catch(e){console.log(B.red(`❌ Error saving to task/subtask: ${e.message}`))}if(s.saveTarget){let e=`# Research Query: ${s.prompt}
118
118
 
119
119
  **Detail Level:** ${r.detailLevel}
120
120
  **Context Size:** ${r.contextSize} characters
@@ -309,7 +309,7 @@ Or specify profiles directly:
309
309
  `));for(let e of t)console.log(` • ${e.displayName} ${B.gray(`(${e.markerPath})`)}`);console.log(``),e=t.map(e=>e.profileName)}else e=await I(i);if(!e||e.length===0){console.log(B.yellow(`No profiles selected. Exiting.`));return}console.log(B.blue(`Installing ${e.length} selected profile(s)...`));let{allSuccessfulProfiles:t,totalSuccess:n,totalFailed:a}=L(await F(e,i,r.mode));console.log(B.green(`\n✓ Successfully installed ${t.length} profile(s)`)),n>0&&console.log(B.gray(` ${n} files processed, ${a} failed`));return}(!t||t.length===0)&&(console.error(`Please specify at least one rule profile (e.g., windsurf, roo).`),process.exit(1));let a=t.flatMap(e=>e.split(`,`).map(e=>e.trim())).filter(Boolean);if(e===P.REMOVE){let e=!0;if(r.force||(e=Qe(i,a)?await gt(a,Ze(i)):await ht(a)),!e){console.log(B.yellow(`Aborted: No rules were removed.`));return}}let o=[],s=[];for(let t of a){if(!nt(t)){console.warn(`Rule profile for "${t}" not found. Valid profiles: ${z.join(`, `)}. Skipping.`);continue}let a=it(t);if(e===P.ADD){console.log(B.blue(`Adding rules for profile: ${t}...`));let e=ot(i,a,{mode:await n(r.mode)});console.log(B.blue(`Completed adding rules for profile: ${t}`)),s.push({profileName:t,success:e.success,failed:e.failed}),console.log(B.green(rt(t,e)))}else if(e===P.REMOVE){console.log(B.blue(`Removing rules for profile: ${t}...`));let e=tt(i,a);o.push(e),console.log(B.green(st(t,e)))}else console.error(`Unknown action. Use "${P.ADD}" or "${P.REMOVE}".`),process.exit(1)}if(e===P.ADD&&s.length>0){let{allSuccessfulProfiles:e,totalSuccess:t,totalFailed:n}=L(s);e.length>0&&(console.log(B.green(`\nSuccessfully processed profiles: ${e.join(`, `)}`)),t>0?console.log(B.green(`Total: ${t} files processed, ${n} failed.`)):console.log(B.green(`Total: ${e.length} profile(s) set up successfully.`)))}if(e===P.REMOVE&&o.length>0){let{successfulRemovals:e,skippedRemovals:t,failedRemovals:n,removalsWithNotices:r}=at(o);e.length>0&&console.log(B.green(`\nSuccessfully removed profiles for: ${e.join(`, `)}`)),t.length>0&&console.log(B.yellow(`Skipped (default or protected): ${t.join(`, `)}`)),n.length>0&&(console.log(B.red(`
310
310
  Errors occurred:`)),n.forEach(e=>{console.log(B.red(` ${e.profileName}: ${e.error}`))})),r.length>0&&(console.log(B.cyan(`
311
311
  Notices:`)),r.forEach(e=>{console.log(B.cyan(` ${e.profileName}: ${e.notice}`))}));let i=o.length,a=e.length,s=t.length,c=n.length;console.log(B.blue(`\nTotal: ${i} profile(s) processed - ${a} removed, ${s} skipped, ${c} failed.`))}}),t.command(`migrate`).description(`Migrate existing project to use the new .taskmaster directory structure`).option(`-f, --force`,`Force migration even if .taskmaster directory already exists`).option(`--backup`,`Create backup of old files before migration (default: false)`,!1).option(`--cleanup`,`Remove old files after successful migration (default: true)`,!0).option(`-y, --yes`,`Skip confirmation prompts`).option(`--dry-run`,`Show what would be migrated without actually moving files`).action(async e=>{try{await ie(e)}catch(e){console.error(B.red(`Error during migration:`),e.message),process.exit(1)}}),t.command(`sync-readme`).description(`Sync the current task list to README.md in the project root`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`--with-subtasks`,`Include subtasks in the README output`).option(`-s, --status <status>`,`Show only tasks matching this status (e.g., pending, done)`).option(`-t, --tag <tag>`,`Tag to use for the task list (default: master)`).action(async e=>{let t=J({tasksPath:e.file||!0,tag:e.tag}),n=e.withSubtasks||!1,r=e.status||null,i=t.getCurrentTag();console.log(B.blue(`📝 Syncing tasks to README.md${n?` (with subtasks)`:``}${r?` (status: ${r})`:``}...`)),await syncTasksToReadme(t.getProjectRoot(),{withSubtasks:n,status:r,tasksPath:t.getTasksPath(),tag:i})||(console.error(B.red(`❌ Failed to sync tasks to README.md`)),process.exit(1))}),t.command(`add-tag`).description(`[DEPRECATED] Create a new tag context for organizing tasks (use "tm tags add" instead)`).argument(`[tagName]`,`Name of the new tag to create (optional when using --from-branch)`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`--copy-from-current`,`Copy tasks from the current tag to the new tag`).option(`--copy-from <tag>`,`Copy tasks from the specified tag to the new tag`).option(`--from-branch`,`Create tag name from current git branch (ignores tagName argument)`).option(`-d, --description <text>`,`Optional description for the tag`).action(async(e,t)=>{console.warn(B.yellow(`⚠ Warning: "tm add-tag" is deprecated. Use "tm tags add" instead.`)),console.log(B.gray(` This command will be removed in a future version.
312
- `));try{let n=J({tasksPath:t.file||!0}),r=n.getTasksPath();V.existsSync(r)||(console.error(B.red(`Error: Tasks file not found at path: ${r}`)),console.log(B.yellow(`Hint: Run task-master init or task-master parse-prd to create tasks.json first`)),process.exit(1)),!e&&!t.fromBranch&&(console.error(B.red(`Error: Either tagName argument or --from-branch option is required.`)),console.log(B.yellow(`Usage examples:`)),console.log(B.cyan(` task-master add-tag my-tag`)),console.log(B.cyan(` task-master add-tag --from-branch`)),process.exit(1));let i={projectRoot:n.getProjectRoot(),commandName:`add-tag`,outputType:`cli`};if(t.fromBranch){let{createTagFromBranch:e}=await import(`./tag-management-BvgwEfuM.js`),r=await import(`./git-utils-PBP1PRVP.js`);await r.isGitRepository(i.projectRoot)||(console.error(B.red(`Error: Not in a git repository. Cannot use --from-branch option.`)),process.exit(1));let a=await r.getCurrentBranch(i.projectRoot);a||(console.error(B.red(`Error: Could not determine current git branch.`)),process.exit(1));let o={copyFromCurrent:t.copyFromCurrent||!1,copyFromTag:t.copyFrom,description:t.description||`Tag created from git branch "${a}"`};await e(n.getTasksPath(),a,o,i,`text`)}else{let r={copyFromCurrent:t.copyFromCurrent||!1,copyFromTag:t.copyFrom,description:t.description};await be(n.getTasksPath(),e,r,i,`text`)}if(t.autoSwitch){let{useTag:r}=await import(`./tag-management-BvgwEfuM.js`),a=t.fromBranch?(await import(`./git-utils-PBP1PRVP.js`)).sanitizeBranchNameForTag(await(await import(`./git-utils-PBP1PRVP.js`)).getCurrentBranch(projectRoot)):e;await r(n.getTasksPath(),a,{},i,`text`)}}catch(e){console.error(B.red(`Error creating tag: ${e.message}`)),l(),process.exit(1)}}).on(`error`,function(e){console.error(B.red(`Error: ${e.message}`)),l(),process.exit(1)}),t.command(`delete-tag`).description(`[DEPRECATED] Delete an existing tag and all its tasks (use "tm tags remove" instead)`).argument(`<tagName>`,`Name of the tag to delete`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-y, --yes`,`Skip confirmation prompts`).action(async(e,t)=>{console.warn(B.yellow(`⚠ Warning: "tm delete-tag" is deprecated. Use "tm tags remove" instead.`)),console.log(B.gray(` This command will be removed in a future version.
312
+ `));try{let n=J({tasksPath:t.file||!0}),r=n.getTasksPath();V.existsSync(r)||(console.error(B.red(`Error: Tasks file not found at path: ${r}`)),console.log(B.yellow(`Hint: Run task-master init or task-master parse-prd to create tasks.json first`)),process.exit(1)),!e&&!t.fromBranch&&(console.error(B.red(`Error: Either tagName argument or --from-branch option is required.`)),console.log(B.yellow(`Usage examples:`)),console.log(B.cyan(` task-master add-tag my-tag`)),console.log(B.cyan(` task-master add-tag --from-branch`)),process.exit(1));let i={projectRoot:n.getProjectRoot(),commandName:`add-tag`,outputType:`cli`};if(t.fromBranch){let{createTagFromBranch:e}=await import(`./tag-management-BnPSKzYA.js`),r=await import(`./git-utils-PBP1PRVP.js`);await r.isGitRepository(i.projectRoot)||(console.error(B.red(`Error: Not in a git repository. Cannot use --from-branch option.`)),process.exit(1));let a=await r.getCurrentBranch(i.projectRoot);a||(console.error(B.red(`Error: Could not determine current git branch.`)),process.exit(1));let o={copyFromCurrent:t.copyFromCurrent||!1,copyFromTag:t.copyFrom,description:t.description||`Tag created from git branch "${a}"`};await e(n.getTasksPath(),a,o,i,`text`)}else{let r={copyFromCurrent:t.copyFromCurrent||!1,copyFromTag:t.copyFrom,description:t.description};await be(n.getTasksPath(),e,r,i,`text`)}if(t.autoSwitch){let{useTag:r}=await import(`./tag-management-BnPSKzYA.js`),a=t.fromBranch?(await import(`./git-utils-PBP1PRVP.js`)).sanitizeBranchNameForTag(await(await import(`./git-utils-PBP1PRVP.js`)).getCurrentBranch(projectRoot)):e;await r(n.getTasksPath(),a,{},i,`text`)}}catch(e){console.error(B.red(`Error creating tag: ${e.message}`)),l(),process.exit(1)}}).on(`error`,function(e){console.error(B.red(`Error: ${e.message}`)),l(),process.exit(1)}),t.command(`delete-tag`).description(`[DEPRECATED] Delete an existing tag and all its tasks (use "tm tags remove" instead)`).argument(`<tagName>`,`Name of the tag to delete`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-y, --yes`,`Skip confirmation prompts`).action(async(e,t)=>{console.warn(B.yellow(`⚠ Warning: "tm delete-tag" is deprecated. Use "tm tags remove" instead.`)),console.log(B.gray(` This command will be removed in a future version.
313
313
  `));try{let n=J({tasksPath:t.file||!0}),r=n.getTasksPath();V.existsSync(r)||(console.error(B.red(`Error: Tasks file not found at path: ${r}`)),process.exit(1));let i={yes:t.yes||!1},a={projectRoot:n.getProjectRoot(),commandName:`delete-tag`,outputType:`cli`};await He(n.getTasksPath(),e,i,a,`text`)}catch(e){console.error(B.red(`Error deleting tag: ${e.message}`)),d(),process.exit(1)}}).on(`error`,function(e){console.error(B.red(`Error: ${e.message}`)),d(),process.exit(1)}),t.command(`use-tag`).description(`[DEPRECATED] Switch to a different tag context (use "tm tags use" instead)`).argument(`<tagName>`,`Name of the tag to switch to`).option(`-f, --file <file>`,`Path to the tasks file`,i).action(async(e,t)=>{console.warn(B.yellow(`⚠ Warning: "tm use-tag" is deprecated. Use "tm tags use" instead.`)),console.log(B.gray(` This command will be removed in a future version.
314
314
  `));try{let n=J({tasksPath:t.file||!0}),r=n.getTasksPath();V.existsSync(r)||(console.error(B.red(`Error: Tasks file not found at path: ${r}`)),process.exit(1));let i={projectRoot:n.getProjectRoot(),commandName:`use-tag`,outputType:`cli`};await Te(n.getTasksPath(),e,{},i,`text`)}catch(e){console.error(B.red(`Error switching tag: ${e.message}`)),f(),process.exit(1)}}).on(`error`,function(e){console.error(B.red(`Error: ${e.message}`)),f(),process.exit(1)}),t.command(`rename-tag`).description(`[DEPRECATED] Rename an existing tag (use "tm tags rename" instead)`).argument(`<oldName>`,`Current name of the tag`).argument(`<newName>`,`New name for the tag`).option(`-f, --file <file>`,`Path to the tasks file`,i).action(async(e,t,n)=>{console.warn(B.yellow(`⚠ Warning: "tm rename-tag" is deprecated. Use "tm tags rename" instead.`)),console.log(B.gray(` This command will be removed in a future version.
315
315
  `));try{let r=J({tasksPath:n.file||!0}),i=r.getTasksPath();V.existsSync(i)||(console.error(B.red(`Error: Tasks file not found at path: ${i}`)),process.exit(1));let a={projectRoot:r.getProjectRoot(),commandName:`rename-tag`,outputType:`cli`};await xe(r.getTasksPath(),e,t,{},a,`text`)}catch(e){console.error(B.red(`Error renaming tag: ${e.message}`)),process.exit(1)}}).on(`error`,function(e){console.error(B.red(`Error: ${e.message}`)),process.exit(1)}),t.command(`copy-tag`).description(`[DEPRECATED] Copy an existing tag to create a new tag with the same tasks (use "tm tags copy" instead)`).argument(`<sourceName>`,`Name of the source tag to copy from`).argument(`<targetName>`,`Name of the new tag to create`).option(`-f, --file <file>`,`Path to the tasks file`,i).option(`-d, --description <text>`,`Optional description for the new tag`).action(async(e,t,n)=>{console.warn(B.yellow(`⚠ Warning: "tm copy-tag" is deprecated. Use "tm tags copy" instead.`)),console.log(B.gray(` This command will be removed in a future version.
@@ -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-Bj2cZEwZ.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 getCodebaseAnalysisMode,O as getCodexCliSettings,k as getCodexCliSettingsForCommand,z as getConfig,I as getDebugFlag,j as getDefaultNumTasks,A as getDefaultPriority,C as getDefaultSubtasks,G as getFallbackModelId,Y as getFallbackProvider,T as getGrokCliSettings,q as getGrokCliSettingsForCommand,v as getLogLevel,n as getMainModelId,K as getMainProvider,y as getMcpApiKeyStatus,a as getOllamaBaseURL,i as getOperatingMode,h as getParametersForRole,P as getProjectName,e as getProxyEnabled,N as getResearchModelId,p as getResearchProvider,m as getResponseLanguage,g as getSupportedModelsForProvider,o as getUserId,l as getVertexLocation,f as getVertexProjectId,_ as hasCodebaseAnalysis,X as isApiKeySet,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-DZYVJT7n.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 getCodebaseAnalysisMode,O as getCodexCliSettings,k as getCodexCliSettingsForCommand,z as getConfig,I as getDebugFlag,j as getDefaultNumTasks,A as getDefaultPriority,C as getDefaultSubtasks,G as getFallbackModelId,Y as getFallbackProvider,T as getGrokCliSettings,q as getGrokCliSettingsForCommand,v as getLogLevel,n as getMainModelId,K as getMainProvider,y as getMcpApiKeyStatus,a as getOllamaBaseURL,i as getOperatingMode,h as getParametersForRole,P as getProjectName,e as getProxyEnabled,N as getResearchModelId,p as getResearchProvider,m as getResponseLanguage,g as getSupportedModelsForProvider,o as getUserId,l as getVertexLocation,f as getVertexProjectId,_ as hasCodebaseAnalysis,X as isApiKeySet,t as isConfigFilePresent,x as isConfigWarningSuppressed,c as isProxyEnabled,b as setSuppressConfigWarnings,S as validateClaudeCodeSettings,s as validateCodexCliSettings,d as validateProvider,B as writeConfig};