taskgraph-ai 0.54.13 → 0.54.22
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/README.md +1 -1
- package/dist/{ai-services-unified-CKKHbOMd.js → ai-services-unified-B45jIPar.js} +1 -1
- package/dist/ai-services-unified-DUvxqUPT.js +1 -0
- package/dist/assets/AGENTS.md +9 -429
- package/dist/commands-CqI6qTC_.js +125 -0
- package/dist/config-manager-DP3N5npn.js +1 -0
- package/dist/config-manager-DTkRerDn.js +1 -0
- package/dist/init-DyCHcgGz.js +24 -0
- package/dist/mcp-server.js +3 -2
- package/dist/{research-BKnv5Fvo.js → research-8cDDG5MH.js} +1 -1
- package/dist/{research-D_nwZW-q.js → research-DbaGD34z.js} +26 -43
- package/dist/{response-language-CnU32t1k.js → response-language-CbtAaYK6.js} +1 -1
- package/dist/response-language-cUVFE-lr.js +1 -0
- package/dist/src-BQZsjzA5.js +207 -0
- package/dist/src-CpPJ2WS1.js +489 -0
- package/dist/tag-management-bTibzuNg.js +1 -0
- package/dist/task-manager-CHSNsnL1.js +129 -0
- package/dist/task-manager-CUvgnPJh.js +1 -0
- package/dist/taskgraph.js +1 -1
- package/package.json +1 -1
- package/dist/ai-services-unified-BpwsoWsI.js +0 -1
- package/dist/commands-D1h9ghuW.js +0 -126
- package/dist/config-manager-DIET_FiX.js +0 -1
- package/dist/config-manager-HsHpBhNF.js +0 -1
- package/dist/init-CrPu9Yzo.js +0 -24
- package/dist/response-language-BfqpW3Bx.js +0 -1
- package/dist/src-Cs4ilbQ-.js +0 -207
- package/dist/src-V29fsb6x.js +0 -468
- package/dist/tag-management-DfrkCVTV.js +0 -1
- package/dist/task-manager-BlaCtMcL.js +0 -1
- package/dist/task-manager-Dzqb02tY.js +0 -167
package/README.md
CHANGED
|
@@ -265,7 +265,7 @@ In Claude Code, say `Change the main model to opus`, or run `taskgraph models --
|
|
|
265
265
|
|
|
266
266
|
Projects created with Task Master, or with a TaskGraph release before 0.47, also need a few manual changes:
|
|
267
267
|
|
|
268
|
-
- **
|
|
268
|
+
- **Import `.taskmaster/`** with `taskgraph init --from-taskmaster --yes`. It copies every tag, the docs and reports, and the settings that still apply, and leaves `.taskmaster/` in place. See [Migrating from Task Master](apps/docs/migrating-from-taskmaster.mdx).
|
|
269
269
|
- **Rename environment variables:** `TASK_MASTER_*` and `TASKMASTER_*` are now `TASKGRAPH_*`. The old names are ignored.
|
|
270
270
|
- **Removed:** the `taskgraph migrate` command and `.taskmasterconfig`. Configuration lives in `.taskgraph/config.json`; run `taskgraph models --setup` to recreate it.
|
|
271
271
|
- **Claude Code only:** other providers and their flags are gone, models are `opus`, `sonnet` and `haiku`, and the only API key still read is the optional `CLAUDE_CODE_API_KEY`.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-BxhE39jg.js";import{
|
|
1
|
+
import{n as e}from"./rolldown-runtime-BxhE39jg.js";import{Y as t}from"./src-BQZsjzA5.js";import{$ as n,D as r,G as i,M as a,S as o,X as s,at as c,b as l,d as u,h as d,i as f,m as p,o as m,p as h,u as g,v as _,x as v,y}from"./config-manager-DTkRerDn.js";import b from"path";import{execSync as x}from"child_process";import S from"fs";import{createClaudeCode as C}from"ai-sdk-provider-claude-code";import*as w from"ai";import{jsonrepair as T}from"jsonrepair";import{EnvHttpProxyAgent as E}from"undici";const D=[`Read`,`Grep`,`Glob`];function O(e){let t=e,n=[];for(;;)try{return b.join(S.realpathSync(t),...n.reverse())}catch{let r=b.dirname(t);if(r===t)return e;n.push(b.basename(t)),t=r}}function k(e,t){if(typeof t!=`string`||t.startsWith(`~`))return!1;let n=O(b.resolve(e,t)),r=b.relative(e,n),i=r===`..`||r.startsWith(`..${b.sep}`);return r===``||!i&&!b.isAbsolute(r)}const A=/^(\.env(\..*)?|\.git|\.npmrc|id_(rsa|dsa|ecdsa|ed25519).*)$|\.pem$/i,ee=/^\.env\.(example|sample|template)$/i;function j(e){return e.split(/[\\/,]/).map(e=>e.replace(/[*?[\]{}]/g,``)).some(e=>A.test(e)&&!ee.test(e))}function M(e,t){let n=b.resolve(e,t);return[n,O(n)].some(t=>j(b.relative(e,t)))}function N(e){return e.split(/[\\/]/).includes(`..`)}function P(e){if(!b.posix.isAbsolute(e)&&!b.win32.isAbsolute(e))return null;if(!/[*?[{]/.test(e)){let t=e.replace(/[\\/]+$/,``)||e;return b.win32.isAbsolute(t)&&!b.posix.isAbsolute(t)?b.win32.dirname(t):b.posix.dirname(t)}let t=e.split(/[*?[{]/)[0],n=Math.max(t.lastIndexOf(`/`),t.lastIndexOf(`\\`));return t.slice(0,n+1)||t}function te(e,t,n={}){if(!D.includes(t))return null;let r=[n.file_path,n.path].filter(e=>e!=null);for(let n of r){if(!k(e,n))return`${t} is limited to the project directory (${e}); ${n} is outside it.`;if(M(e,n))return`${t} may not open secret files such as .env, .git or keys (${n}).`}if(typeof n.glob==`string`&&j(n.glob))return`${t} globs may not match secret files such as .env, .git or keys.`;let i=t===`Glob`?n.pattern:void 0;if(typeof i==`string`){let n=`${t} patterns may not leave the project directory (${e}).`;if(N(i)||i.startsWith(`~`))return n;if(j(i))return`${t} patterns may not match secret files such as .env, .git or keys.`;let r=P(i);if(r!==null&&!k(e,r))return n}return null}function ne(e){let t=O(b.resolve(e));return{matcher:D.join(`|`),hooks:[async e=>{let n=te(t,e?.tool_name,e?.tool_input);return n?{hookSpecificOutput:{hookEventName:`PreToolUse`,permissionDecision:`deny`,permissionDecisionReason:n}}:{}}]}}const{JSONParseError:re,NoObjectGeneratedError:ie,generateObject:ae,generateText:oe,streamObject:se,streamText:ce,zodSchema:le}=w,F=w.jsonSchema,I=/* @__PURE__ */ new Set([`minimum`,`maximum`,`exclusiveMinimum`,`exclusiveMaximum`]),L=[`additionalProperties`,`contains`,`if`,`then`,`else`,`not`,`propertyNames`],R=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],z=[`definitions`,`$defs`,`dependentSchemas`,`patternProperties`,`properties`],B=e=>e?Array.isArray(e)?e.includes(`integer`):e===`integer`:!1,V=e=>{if(!e||typeof e!=`object`)return e;if(Array.isArray(e))return e.map(V);let t={...e};if(B(t.type))for(let e of I)e in t&&delete t[e];for(let e of L)t[e]&&(t[e]=V(t[e]));for(let e of R)Array.isArray(t[e])&&(t[e]=t[e].map(V));for(let e of z)if(t[e]&&typeof t[e]==`object`){let n={};for(let[r,i]of Object.entries(t[e]))n[r]=V(i);t[e]=n}return t.items&&=V(t.items),t},H=e=>{let t=le(e);if(!t||typeof t!=`object`||!t.jsonSchema)return t;let n=V(t.jsonSchema);return typeof F==`function`?F(n,{validate:t.validate}):{...t,jsonSchema:n}};function U(){let e=Number(process.env.TASKGRAPH_AI_TIMEOUT_MS);return AbortSignal.timeout(Number.isFinite(e)&&e>0?e:6e5)}var W=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||=i();let e=this._projectRoot;if(r(null,e))return this._proxyAgent||=new E,(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 r=t.message||`Unknown error occurred`;throw n(`error`,`${this.name} ${e} failed: ${r}`,{error:t}),Error(`${this.name} API error during ${e}: ${r}`)}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))}}prepareMessages(e){let t=e.filter(e=>e.role===`system`);return t.length===0?{messages:e}:{instructions:t.map(e=>typeof e.content==`string`?e.content:e.content.map(e=>e.text??``).join(``)).join(`
|
|
2
2
|
|
|
3
3
|
`),messages:e.filter(e=>e.role!==`system`)}}async generateText(e){try{this.validateParams(e),this.validateMessages(e.messages),n(`debug`,`Generating ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),r=await oe({abortSignal:U(),model:t(e.modelId),...this.prepareMessages(e.messages),...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{}});n(`debug`,`${this.name} generateText completed successfully for model: ${e.modelId}`);let i=r.usage?.inputTokens??r.usage?.promptTokens??0,a=r.usage?.outputTokens??r.usage?.completionTokens??0,o=r.usage?.totalTokens??i+a,s=r.usage?.inputTokenDetails?.cacheReadTokens??r.usage?.cachedInputTokens??0;return{text:r.text,usage:{inputTokens:i,outputTokens:a,totalTokens:o,cachedInputTokens:s}}}catch(e){this.handleError(`text generation`,e)}}async streamText(e){try{this.validateParams(e),this.validateMessages(e.messages),n(`debug`,`Streaming ${this.name} text with model: ${e.modelId}`);let t=await this.getClient(e),r=await ce({model:t(e.modelId),...this.prepareMessages(e.messages),...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},...e.experimental_transform&&{experimental_transform:e.experimental_transform}});return n(`debug`,`${this.name} streamText initiated successfully for model: ${e.modelId}`),r}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`);n(`debug`,`Streaming ${this.name} object with model: ${e.modelId}`);let t=await this.getClient(e),r=H(e.schema),i=await se({model:t(e.modelId),...this.prepareMessages(e.messages),schema:r,mode:this.needsExplicitJsonSchema?`json`:`auto`,...e.objectName&&{schemaName:e.objectName,schemaDescription:`Generate a valid JSON object for ${e.objectName}`},...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{},onError:({error:e})=>n(`debug`,`${this.name} stream error: ${e?.message??e}`)});return n(`debug`,`${this.name} streamObject initiated successfully for model: ${e.modelId}`),i}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`);n(`debug`,`Generating ${this.name} object ('${e.objectName}') with model: ${e.modelId}`);let t=await this.getClient(e),r=H(e.schema),i=await ae({abortSignal:U(),model:t(e.modelId),...this.prepareMessages(e.messages),schema:r,mode:this.needsExplicitJsonSchema?`json`:`auto`,schemaName:e.objectName,schemaDescription:`Generate a valid JSON object for ${e.objectName}`,...this.prepareTokenParam(e.modelId,e.maxTokens),...this.supportsTemperature&&e.temperature!==void 0?{temperature:e.temperature}:{}});n(`debug`,`${this.name} generateObject 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,c=i.usage?.inputTokenDetails?.cacheReadTokens??i.usage?.cachedInputTokens??0;return{object:i.object,usage:{inputTokens:a,outputTokens:o,totalTokens:s,cachedInputTokens:c}}}catch(e){if(ie.isInstance(e)&&e.cause instanceof re&&e.cause.text){n(`warn`,`${this.name} generated malformed JSON, attempting to repair...`);try{let t=T(e.cause.text),r=JSON.parse(t);return n(`debug`,`Successfully repaired ${this.name} JSON output`),{object:r,usage:{inputTokens:e.usage?.promptTokens||e.usage?.inputTokens||0,outputTokens:e.usage?.completionTokens||e.usage?.outputTokens||0,totalTokens:e.usage?.totalTokens||0}}}catch(e){n(`error`,`Failed to repair ${this.name} JSON: ${e.message}`)}}this.handleError(`object generation`,e)}}};let G=!1;const ue=[`WebSearch`,`WebFetch`],de=[`Read`,`Grep`,`Glob`],fe=/^claude(\.exe|\.cmd)?$/i;function K(e,t){let n=b.relative(e,t);return n===``||n!==`..`&&!n.startsWith(`..${b.sep}`)&&!b.isAbsolute(n)}function pe(e,t){if(typeof e!=`string`||!b.isAbsolute(e)||!fe.test(b.basename(e)))return!1;let n;try{n=S.realpathSync(e)}catch{return!1}if(!t)return!0;let r=b.resolve(t),i=r;try{i=S.realpathSync(r)}catch{}return!K(r,b.resolve(e))&&!K(i,n)}function me(e,t){let r=e.pathToClaudeCodeExecutable;if(r===void 0||pe(r,t))return e;n(`warn`,`Ignoring pathToClaudeCodeExecutable "${r}": it must be an absolute path to a file named claude outside the project`);let{pathToClaudeCodeExecutable:i,...a}=e;return a}function he(e,t,n){let r=e===`research`,i=r?ue:n?de:[];return{tools:[...i],allowedTools:[...i],permissionMode:`dontAsk`,permissionPrompts:`none`,strictMcpConfig:!0,mcpServers:{},settingSources:[],...r?{maxTurns:t.maxTurns??8}:{cwd:n??void 0,additionalDirectories:void 0,hooks:n?{PreToolUse:[ne(n)]}:{}}}}var ge=class extends W{constructor(){super(),this.name=`Claude Code`,this.supportedModels=v(`claude-code`),this.supportedModels.length===0&&n(`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`&&!G&&!process.env.CLAUDE_CODE_OAUTH_TOKEN)try{x(`claude --version`,{stdio:`pipe`,timeout:1e3})}catch{n(`debug`,"No `claude` on PATH; using the Claude Code bundled with the Agent SDK")}finally{G=!0}}getClient(e={}){try{let r=e.projectRoot?b.resolve(e.projectRoot):null,i=me(f(e.commandName)||{},r),a=r?t(r):{...process.env},o=a.CLAUDE_CODE_API_KEY;return o?a.ANTHROPIC_API_KEY=o:delete a.ANTHROPIC_API_KEY,C({defaultSettings:{systemPrompt:{type:`preset`,preset:`claude_code`},env:a,logger:{debug:e=>n(`debug`,e),info:e=>n(`debug`,e),warn:e=>n(`debug`,e),error:e=>n(`error`,e)},...i,...he(e.role,i,r)}})}catch(e){let t=String(e?.message||``);if(e?.code===`ENOENT`||/claude/i.test(t)){let t=/* @__PURE__ */ 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}};let q=null;var J=class e{constructor(){this._providers=/* @__PURE__ */ new Map,this._initialized=!1}static getInstance(){return q||=new e,q}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:/* @__PURE__ */ 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}};J.getInstance().initialize(),globalThis.AI_SDK_LOG_WARNINGS===void 0&&(globalThis.AI_SDK_LOG_WARNINGS=({warnings:e,provider:t,model:r})=>{for(let i of e){let e=i.message||i.feature||i.setting||i.type;n(`debug`,`AI SDK warning (${t??`?`}/${r??`?`}): ${e}`)}});const Y={"claude-code":new ge};function X(e){if(Y[e])return Y[e];let t=J.getInstance();return t.hasProvider(e)?(n(`debug`,`Provider "${e}" found in dynamic registry`),t.getProvider(e)):null}function _e(e,t){let r={inputCost:0,outputCost:0,currency:`USD`,isUnknown:!1};if(!a||!a[e])return n(`warn`,`Provider "${e}" not found in MODEL_MAP. Cannot determine cost for model ${t}.`),{...r,isUnknown:!0};let i=a[e].find(e=>e.id===t);if(!i)return n(`debug`,`Model "${t}" not found under provider "${e}". Assuming unknown cost.`),{...r,isUnknown:!0};if(i.cost_per_1m_tokens===null)return n(`debug`,`Cost data is null for model "${t}" under provider "${e}". Pricing unknown.`),{...r,isUnknown:!0};if(i.cost_per_1m_tokens===void 0)return n(`debug`,`Cost data not found for model "${t}" under provider "${e}". Pricing unknown.`),{...r,isUnknown:!0};let o=i.cost_per_1m_tokens;return{inputCost:o.input||0,outputCost:o.output||0,currency:o.currency||`USD`,isUnknown:!1}}function ve(e,t,n,r){let i=(e||0)/1e6*n+(t||0)/1e6*r;return parseFloat(i.toFixed(6))}function ye(e){let t={currentTag:`master`,availableTags:[`master`]};try{return e?{currentTag:s(e)||`master`,availableTags:be(e)}:t}catch(e){return m()&&n(`debug`,`Error getting tag information: ${e.message}`),t}}function be(t){let r=[`master`];try{let n=e(`path`),i=e(`fs`),a=n.join(t,`.taskgraph`,`tasks`,`tasks.json`);if(!i.existsSync(a))return r;let o=JSON.parse(i.readFileSync(a,`utf8`));if(!o||typeof o!=`object`)return r;let s=Object.keys(o).filter(e=>xe(o[e]));return s.length>0?s:r}catch(e){return m()&&n(`debug`,`Could not read tasks file for available tags: ${e.message}`),r}}function xe(e){return e&&typeof e==`object`&&Array.isArray(e.tasks)}function Se(e){let t=e.message?.toLowerCase()||``;return e.name===`TimeoutError`||t.includes(`aborted`)?!1:t.includes(`rate limit`)||t.includes(`overloaded`)||t.includes(`service temporarily unavailable`)||t.includes(`timeout`)||t.includes(`network error`)||e.status===429||e.status>=500}function Z(e){try{if(e?.data?.error?.message)return e.data.error.message;if(e?.error?.message)return e.error.message;if(typeof e?.responseBody==`string`)try{let t=JSON.parse(e.responseBody);if(t?.error?.message)return t.error.message}catch{}return typeof e?.message==`string`&&e.message?e.message:typeof e==`string`?e:`An unknown AI service error occurred.`}catch{return`Failed to extract error message.`}}function Ce(e,t){return{main:{provider:p(t),modelId:h(t)},research:{provider:y(t),modelId:_(t)},fallback:{provider:u(t),modelId:g(t)}}[e]||null}function we(e,t,n=null){let r=X(e);if(!r)throw Error(`Unknown provider '${e}' for API key resolution.`);let i=r.getRequiredApiKeyName();if(i===null)return null;let a=c(i,t,n);if(!r.isRequiredApiKey())return a||null;if(!a)throw Error(`Required API key ${i} for provider '${e}' is not set in environment, session, or .env file.`);return a}async function Te(e,t,r,i,a,o){let s=0,c=t;for(;s<=2;)try{m()&&n(`info`,`Attempt ${s+1}/3 calling ${c} (Provider: ${i}, Model: ${a}, Role: ${o})`);let l=await e[t](r);return m()&&n(`info`,`${c} succeeded for role ${o} (Provider: ${i}) on attempt ${s+1}`),l}catch(e){if(n(`warn`,`Attempt ${s+1} failed for role ${o} (${c} / ${i}): ${e.message}`),Se(e)&&s<2){s++;let e=1e3*2**(s-1);n(`info`,`Something went wrong on the provider side. Retrying in ${e/1e3}s...`),await new Promise(t=>setTimeout(t,e))}else throw n(`error`,`Something went wrong on the provider side. Max retries reached for role ${o} (${c} / ${i}).`),e}throw Error(`Exhausted all retries for role ${o} (${c} / ${i})`)}async function Q(e,t){let{role:r,session:a,projectRoot:s,systemPrompt:c,prompt:u,schema:f,objectName:p,commandName:h,outputType:g,experimental_transform:_,...v}=t;m()&&n(`debug`,`${e}Service called`,{role:r,commandName:h,outputType:g,projectRoot:s});let y=s||i(),b=o(y),x;r===`main`?x=[`main`,`fallback`,`research`]:r===`research`?x=[`research`,`fallback`,`main`]:r===`fallback`?x=[`fallback`,`main`,`research`]:(n(`warn`,`Unknown initial role: ${r}. Defaulting to main -> fallback -> research sequence.`),x=[`main`,`fallback`,`research`]);let S=/* @__PURE__ */ new Set,C=null,w=`AI service call failed for all configured roles.`;for(let t of x){let r,i,o,s,m,x,T=null;try{n(`debug`,`New AI service call with role: ${t}`);let w=Ce(t,y);if(!w){n(`error`,`Unknown role encountered in _unifiedServiceRunner: ${t}`),C||=/* @__PURE__ */ Error(`Unknown AI role specified: ${t}`);continue}if(r=w.provider,i=w.modelId,!r||!i){n(`warn`,`Skipping role '${t}': Provider or Model ID not configured.`),C||=/* @__PURE__ */ Error(`Configuration missing for role '${t}'. Provider: ${r}, Model: ${i}`);continue}if(S.has(`${r}/${i}`)){n(`debug`,`Skipping role '${t}': ${r}/${i} already failed for this request.`);continue}if(m=X(r?.toLowerCase()),!m){n(`warn`,`Skipping role '${t}': Provider '${r}' not supported.`),C||=/* @__PURE__ */ Error(`Unsupported provider configured: ${r}`);continue}s=d(t,y),o=we(r?.toLowerCase(),a,y);let E=[],D=`${c} \n\n Always respond in ${l(y)}.`;if(E.push({role:`system`,content:D.trim()}),u)E.push({role:`user`,content:u});else throw Error(`User prompt content is missing.`);let O={apiKey:o,modelId:i,maxTokens:s.maxTokens,temperature:s.temperature,messages:E,...(e===`generateObject`||e===`streamObject`)&&{schema:f,objectName:p},role:t,projectRoot:y,...h&&{commandName:h},..._&&{experimental_transform:_},...v};if(x=await Te(m,e,O,r,i,t),b&&x&&x.usage)try{T=await $({userId:b,commandName:h,providerName:r,modelId:i,inputTokens:x.usage.inputTokens,outputTokens:x.usage.outputTokens,cachedInputTokens:x.usage.cachedInputTokens,outputType:g})}catch{}else b&&x&&!x.usage&&n(`warn`,`Cannot log telemetry for ${h} (${r}/${i}): AI result missing 'usage' data. (May be expected for streams)`);let k;e===`generateText`?k=x.text:e===`generateObject`?k=x.object:(e===`streamText`||e===`streamObject`||n(`error`,`Unknown serviceType in _unifiedServiceRunner: ${e}`),k=x);let A=ye(y);return{mainResult:k,telemetryData:T,tagInfo:A,providerName:r,modelId:i}}catch(a){let o=Z(a);if(n(`error`,`Service call failed for role ${t} (Provider: ${r||`unknown`}, Model: ${i||`unknown`}): ${o}`),C=a,w=o,r&&i&&S.add(`${r}/${i}`),e===`generateObject`){let e=o.toLowerCase();if(e.includes(`no endpoints found that support tool use`)||e.includes(`does not support tool_use`)||e.includes(`tool use is not supported`)||e.includes(`tools are not supported`)||e.includes(`function calling is not supported`)||e.includes(`tool use is not supported`)){let e=`Model '${i||`unknown`}' via provider '${r||`unknown`}' does not support the 'tool use' required by generateObjectService. Please configure a model that supports tool/function calling for the '${t}' role, or use generateTextService if structured output is not strictly required.`;throw n(`error`,`[Tool Support Error] ${e}`),Error(e)}}}}throw n(`error`,`All roles in the sequence [${x.join(`, `)}] failed.`),Error(w)}async function Ee(e){return Q(`generateText`,{outputType:`cli`,...e})}async function De(e){let t={outputType:`cli`,...e};if(!t.schema)throw Error(`streamObjectService requires a schema parameter`);return Q(`streamObject`,t)}async function Oe(e){return Q(`generateObject`,{objectName:`generated_object`,maxRetries:3,outputType:`cli`,...e})}async function $({userId:e,commandName:t,providerName:r,modelId:i,inputTokens:a,outputTokens:o,cachedInputTokens:s,outputType:c}){try{let c=(/* @__PURE__ */ new Date()).toISOString(),l=(a||0)+(o||0),{inputCost:u,outputCost:d,currency:f,isUnknown:p}=_e(r,i),h=ve(a,o,u,d),g={timestamp:c,userId:e,commandName:t,modelUsed:i,providerName:r,inputTokens:a||0,outputTokens:o||0,totalTokens:l,...s>0?{cachedInputTokens:s}:{},totalCost:h,currency:f,isUnknownCost:p};return m()&&n(`debug`,`AI Usage Telemetry:`,g),g}catch(e){return n(`error`,`Failed to log AI usage telemetry: ${e.message}`,{error:e}),null}}export{k as a,De as i,Ee as n,$ as r,Oe as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{r as logAiUsage}from"./ai-services-unified-B45jIPar.js";
|
package/dist/assets/AGENTS.md
CHANGED
|
@@ -1,433 +1,13 @@
|
|
|
1
|
-
# TaskGraph
|
|
1
|
+
# TaskGraph
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This project tracks work in TaskGraph. Run `taskgraph prime` for the task in progress, what's ready next, and the workflow rules; follow those rules. A Claude Code session with the TaskGraph plugin gets this at startup.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Daily commands
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
taskgraph
|
|
10
|
-
taskgraph
|
|
11
|
-
taskgraph
|
|
7
|
+
- `taskgraph next`: the next task to work on
|
|
8
|
+
- `taskgraph show <id>`: one task in detail (`3`, or a subtask like `3.2`)
|
|
9
|
+
- `taskgraph list`: all tasks, filtered by `--status` or `--tag`
|
|
10
|
+
- `taskgraph set-status --id=<id> --status=in-progress`: claim a task (`--status=done` when finished)
|
|
11
|
+
- `taskgraph add-task --prompt="<what>"`: add a task
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
taskgraph list # Show all tasks with status
|
|
15
|
-
taskgraph next # Get next available task to work on
|
|
16
|
-
taskgraph show <id> # View detailed task information (e.g., taskgraph show 1.2)
|
|
17
|
-
taskgraph set-status --id=<id> --status=done # Mark task complete
|
|
18
|
-
|
|
19
|
-
# Task Management
|
|
20
|
-
taskgraph add-task --prompt="description" --research # Add new task with AI assistance
|
|
21
|
-
taskgraph expand --id=<id> --research --force # Break task into subtasks
|
|
22
|
-
taskgraph update-task --id=<id> --prompt="changes" # Update specific task
|
|
23
|
-
taskgraph update --from=<id> --prompt="changes" # Update multiple tasks from ID onwards
|
|
24
|
-
taskgraph update-subtask --id=<id> --prompt="notes" # Add implementation notes to subtask
|
|
25
|
-
|
|
26
|
-
# Analysis & Planning
|
|
27
|
-
taskgraph analyze-complexity --research # Analyze task complexity
|
|
28
|
-
taskgraph complexity-report # View complexity analysis
|
|
29
|
-
taskgraph expand --all --research # Expand all eligible tasks
|
|
30
|
-
|
|
31
|
-
# Dependencies & Organization
|
|
32
|
-
taskgraph add-dependency --id=<id> --depends-on=<id> # Add task dependency
|
|
33
|
-
taskgraph move --from=<id> --to=<id> # Reorganize task hierarchy
|
|
34
|
-
taskgraph validate-dependencies # Check for dependency issues
|
|
35
|
-
taskgraph generate # Update task markdown files (usually auto-called)
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Key Files & Project Structure
|
|
39
|
-
|
|
40
|
-
### Core Files
|
|
41
|
-
|
|
42
|
-
- `.taskgraph/tasks/tasks.json` - Main task data file (auto-managed)
|
|
43
|
-
- `.taskgraph/config.json` - AI model configuration (use `taskgraph models` to modify)
|
|
44
|
-
- `.taskgraph/docs/prd.md` - Product Requirements Document for parsing (`.md` extension recommended for better editor support)
|
|
45
|
-
- `.taskgraph/tasks/*.txt` - Individual task files (auto-generated from tasks.json)
|
|
46
|
-
- `.env` - Optional environment variables (for example `CLAUDE_CODE_API_KEY`)
|
|
47
|
-
|
|
48
|
-
**PRD File Format:** While both `.txt` and `.md` extensions work, **`.md` is recommended** because:
|
|
49
|
-
- Markdown syntax highlighting in editors improves readability
|
|
50
|
-
- Proper rendering when previewing in VS Code, GitHub, or other tools
|
|
51
|
-
- Better collaboration through formatted documentation
|
|
52
|
-
|
|
53
|
-
### Claude Code Integration Files
|
|
54
|
-
|
|
55
|
-
- `CLAUDE.md` - Auto-loaded context for Claude Code (this file)
|
|
56
|
-
- `.claude/settings.json` - Claude Code tool allowlist and preferences
|
|
57
|
-
- `.claude/commands/` - Custom slash commands for repeated workflows
|
|
58
|
-
- `.mcp.json` - MCP server configuration (project-specific)
|
|
59
|
-
|
|
60
|
-
### Directory Structure
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
project/
|
|
64
|
-
├── .taskgraph/
|
|
65
|
-
│ ├── tasks/ # Task files directory
|
|
66
|
-
│ │ ├── tasks.json # Main task database
|
|
67
|
-
│ │ ├── task-1.md # Individual task files
|
|
68
|
-
│ │ └── task-2.md
|
|
69
|
-
│ ├── docs/ # Documentation directory
|
|
70
|
-
│ │ ├── prd.md # Product requirements (.md recommended)
|
|
71
|
-
│ ├── reports/ # Analysis reports directory
|
|
72
|
-
│ │ └── task-complexity-report.json
|
|
73
|
-
│ ├── templates/ # Template files
|
|
74
|
-
│ │ └── example_prd.md # Example PRD template (.md recommended)
|
|
75
|
-
│ └── config.json # AI models & settings
|
|
76
|
-
├── .claude/
|
|
77
|
-
│ ├── settings.json # Claude Code configuration
|
|
78
|
-
│ └── commands/ # Custom slash commands
|
|
79
|
-
├── .env # Optional env vars
|
|
80
|
-
├── .mcp.json # MCP configuration
|
|
81
|
-
└── CLAUDE.md # This file - auto-loaded by Claude Code
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Slash Commands & CLI (Preferred)
|
|
85
|
-
|
|
86
|
-
Use slash commands or the `taskgraph` CLI first. They need no MCP server and load no extra tool definitions into context. Only fall back to the MCP tools below when a command you need has no slash command or CLI equivalent.
|
|
87
|
-
|
|
88
|
-
With the TaskGraph plugin installed (`/plugin marketplace add stephennmiller/taskgraph-ai`, then `/plugin install taskgraph@taskgraph`), the slash commands live under `/taskgraph:` (type `/taskgraph` to list them). `taskgraph init` does not write slash commands:
|
|
89
|
-
|
|
90
|
-
| Task | Slash command | CLI |
|
|
91
|
-
|------|---------------|-----|
|
|
92
|
-
| Find next task | `/taskgraph:next-task` | `taskgraph next` |
|
|
93
|
-
| View a task | `/taskgraph:show-task <id>` | `taskgraph show <id>` |
|
|
94
|
-
| List tasks | `/taskgraph:list-tasks` | `taskgraph list` |
|
|
95
|
-
| Parse a PRD | `/taskgraph:parse-prd` | `taskgraph parse-prd <file>` |
|
|
96
|
-
| Add a task | `/taskgraph:add-task` | `taskgraph add-task --prompt="..."` |
|
|
97
|
-
| Break into subtasks | `/taskgraph:expand-task <id>` | `taskgraph expand --id=<id>` |
|
|
98
|
-
| Change status | `/taskgraph:set-status <id> <status>`, or the shortcuts `/taskgraph:to-in-progress <id>` and `/taskgraph:to-done <id>` | `taskgraph set-status --id=<id> --status=<status>` |
|
|
99
|
-
| Update a task | `/taskgraph:update-task <id>` | `taskgraph update-task --id=<id> --prompt="..."` |
|
|
100
|
-
| Check complexity | `/taskgraph:analyze-complexity` | `taskgraph analyze-complexity` |
|
|
101
|
-
|
|
102
|
-
## MCP Integration (Optional)
|
|
103
|
-
|
|
104
|
-
TaskGraph also provides an MCP server that Claude Code can connect to. It is optional; the slash commands and CLI above cover the same workflow. To use it, configure `.mcp.json`:
|
|
105
|
-
|
|
106
|
-
```json
|
|
107
|
-
{
|
|
108
|
-
"mcpServers": {
|
|
109
|
-
"taskgraph-ai": {
|
|
110
|
-
"command": "npx",
|
|
111
|
-
"args": ["-y", "taskgraph-ai"],
|
|
112
|
-
"env": {
|
|
113
|
-
"TASKGRAPH_TOOLS": "core"
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### MCP Tool Tiers
|
|
121
|
-
|
|
122
|
-
Default: `core` (7 tools). Set via `TASKGRAPH_TOOLS` env var.
|
|
123
|
-
|
|
124
|
-
| Tier | Count | Tools |
|
|
125
|
-
|------|-------|-------|
|
|
126
|
-
| `core` | 7 | `get_tasks`, `next_task`, `get_task`, `set_task_status`, `update_subtask`, `parse_prd`, `expand_task` |
|
|
127
|
-
| `standard` | 15 | core + `initialize_project`, `analyze_project_complexity`, `expand_all`, `add_subtask`, `remove_task`, `add_task`, `complexity_report`, `dependency_analysis` |
|
|
128
|
-
| `all` | 46 | standard + dependencies, tags, research, autopilot, scoping, models |
|
|
129
|
-
|
|
130
|
-
**Upgrade when tool unavailable:** Edit MCP config, change `TASKGRAPH_TOOLS` from `"core"` to `"standard"` or `"all"`, restart MCP.
|
|
131
|
-
|
|
132
|
-
### Essential MCP Tools
|
|
133
|
-
|
|
134
|
-
```javascript
|
|
135
|
-
// Project setup
|
|
136
|
-
initialize_project; // = taskgraph init
|
|
137
|
-
parse_prd; // = taskgraph parse-prd
|
|
138
|
-
|
|
139
|
-
// Daily workflow
|
|
140
|
-
get_tasks; // = taskgraph list
|
|
141
|
-
next_task; // = taskgraph next
|
|
142
|
-
get_task; // = taskgraph show <id>
|
|
143
|
-
set_task_status; // = taskgraph set-status
|
|
144
|
-
|
|
145
|
-
// Task management
|
|
146
|
-
add_task; // = taskgraph add-task
|
|
147
|
-
expand_task; // = taskgraph expand
|
|
148
|
-
update_task; // = taskgraph update-task
|
|
149
|
-
update_subtask; // = taskgraph update-subtask
|
|
150
|
-
update; // = taskgraph update
|
|
151
|
-
|
|
152
|
-
// Analysis
|
|
153
|
-
analyze_project_complexity; // = taskgraph analyze-complexity
|
|
154
|
-
complexity_report; // = taskgraph complexity-report
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Claude Code Workflow Integration
|
|
158
|
-
|
|
159
|
-
### Standard Development Workflow
|
|
160
|
-
|
|
161
|
-
#### 1. Project Initialization
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
# Initialize TaskGraph
|
|
165
|
-
taskgraph init
|
|
166
|
-
|
|
167
|
-
# Create or obtain PRD, then parse it (use .md extension for better editor support)
|
|
168
|
-
taskgraph parse-prd .taskgraph/docs/prd.md
|
|
169
|
-
|
|
170
|
-
# Analyze complexity and expand tasks
|
|
171
|
-
taskgraph analyze-complexity --research
|
|
172
|
-
taskgraph expand --all --research
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
If tasks already exist, another PRD can be parsed (with new information only!) using parse-prd with --append flag. This will add the generated tasks to the existing list of tasks..
|
|
176
|
-
|
|
177
|
-
#### 2. Daily Development Loop
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
# Start each session
|
|
181
|
-
taskgraph next # Find next available task
|
|
182
|
-
taskgraph show <id> # Review task details
|
|
183
|
-
|
|
184
|
-
# During implementation, check in code context into the tasks and subtasks
|
|
185
|
-
taskgraph update-subtask --id=<id> --prompt="implementation notes..."
|
|
186
|
-
|
|
187
|
-
# Complete tasks
|
|
188
|
-
taskgraph set-status --id=<id> --status=done
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
#### 3. Multi-Claude Workflows
|
|
192
|
-
|
|
193
|
-
For complex projects, use multiple Claude Code sessions:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# Terminal 1: Main implementation
|
|
197
|
-
cd project && claude
|
|
198
|
-
|
|
199
|
-
# Terminal 2: Testing and validation
|
|
200
|
-
cd project-test-worktree && claude
|
|
201
|
-
|
|
202
|
-
# Terminal 3: Documentation updates
|
|
203
|
-
cd project-docs-worktree && claude
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Custom Slash Commands
|
|
207
|
-
|
|
208
|
-
Create `.claude/commands/taskgraph-next.md`:
|
|
209
|
-
|
|
210
|
-
```markdown
|
|
211
|
-
Find the next available TaskGraph task and show its details.
|
|
212
|
-
|
|
213
|
-
Steps:
|
|
214
|
-
|
|
215
|
-
1. Run `taskgraph next` to get the next task
|
|
216
|
-
2. If a task is available, run `taskgraph show <id>` for full details
|
|
217
|
-
3. Provide a summary of what needs to be implemented
|
|
218
|
-
4. Suggest the first implementation step
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Create `.claude/commands/taskgraph-complete.md`:
|
|
222
|
-
|
|
223
|
-
```markdown
|
|
224
|
-
Complete a TaskGraph task: $ARGUMENTS
|
|
225
|
-
|
|
226
|
-
Steps:
|
|
227
|
-
|
|
228
|
-
1. Review the current task with `taskgraph show $ARGUMENTS`
|
|
229
|
-
2. Verify all implementation is complete
|
|
230
|
-
3. Run any tests related to this task
|
|
231
|
-
4. Mark as complete: `taskgraph set-status --id=$ARGUMENTS --status=done`
|
|
232
|
-
5. Show the next available task with `taskgraph next`
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
## Tool Allowlist Recommendations
|
|
236
|
-
|
|
237
|
-
Add to `.claude/settings.json`:
|
|
238
|
-
|
|
239
|
-
```json
|
|
240
|
-
{
|
|
241
|
-
"allowedTools": [
|
|
242
|
-
"Edit",
|
|
243
|
-
"Bash(taskgraph *)",
|
|
244
|
-
"Bash(git commit:*)",
|
|
245
|
-
"Bash(git add:*)",
|
|
246
|
-
"Bash(npm run *)",
|
|
247
|
-
"mcp__taskgraph_ai__*"
|
|
248
|
-
]
|
|
249
|
-
}
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Configuration & Setup
|
|
253
|
-
|
|
254
|
-
### Authentication
|
|
255
|
-
|
|
256
|
-
TaskGraph runs every AI call through your signed-in Claude Code, so no provider API keys are needed. Run `claude` once to sign in. Optionally set `CLAUDE_CODE_API_KEY` to bill calls to a specific Anthropic API key.
|
|
257
|
-
|
|
258
|
-
### Model Configuration
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
# Interactive setup (recommended)
|
|
262
|
-
taskgraph models --setup
|
|
263
|
-
|
|
264
|
-
# Set specific models
|
|
265
|
-
taskgraph models --set-main sonnet
|
|
266
|
-
taskgraph models --set-research opus
|
|
267
|
-
taskgraph models --set-fallback haiku
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
## Task Structure & IDs
|
|
271
|
-
|
|
272
|
-
### Task ID Format
|
|
273
|
-
|
|
274
|
-
- Main tasks: `1`, `2`, `3`, etc.
|
|
275
|
-
- Subtasks: `1.1`, `1.2`, `2.1`, etc.
|
|
276
|
-
- Sub-subtasks: `1.1.1`, `1.1.2`, etc.
|
|
277
|
-
|
|
278
|
-
### Task Status Values
|
|
279
|
-
|
|
280
|
-
- `pending` - Ready to work on
|
|
281
|
-
- `in-progress` - Currently being worked on
|
|
282
|
-
- `done` - Completed and verified
|
|
283
|
-
- `deferred` - Postponed
|
|
284
|
-
- `cancelled` - No longer needed
|
|
285
|
-
- `blocked` - Waiting on external factors
|
|
286
|
-
|
|
287
|
-
### Task Fields
|
|
288
|
-
|
|
289
|
-
```json
|
|
290
|
-
{
|
|
291
|
-
"id": "1.2",
|
|
292
|
-
"title": "Implement user authentication",
|
|
293
|
-
"description": "Set up JWT-based auth system",
|
|
294
|
-
"status": "pending",
|
|
295
|
-
"priority": "high",
|
|
296
|
-
"dependencies": ["1.1"],
|
|
297
|
-
"details": "Use bcrypt for hashing, JWT for tokens...",
|
|
298
|
-
"testStrategy": "Unit tests for auth functions, integration tests for login flow",
|
|
299
|
-
"subtasks": []
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
## Claude Code Best Practices with TaskGraph
|
|
304
|
-
|
|
305
|
-
### Context Management
|
|
306
|
-
|
|
307
|
-
- Use `/clear` between different tasks to maintain focus
|
|
308
|
-
- This CLAUDE.md file is automatically loaded for context
|
|
309
|
-
- Use `taskgraph show <id>` to pull specific task context when needed
|
|
310
|
-
|
|
311
|
-
### Iterative Implementation
|
|
312
|
-
|
|
313
|
-
1. `taskgraph show <subtask-id>` - Understand requirements
|
|
314
|
-
2. Explore codebase and plan implementation
|
|
315
|
-
3. `taskgraph update-subtask --id=<id> --prompt="detailed plan"` - Log plan
|
|
316
|
-
4. `taskgraph set-status --id=<id> --status=in-progress` - Start work
|
|
317
|
-
5. Implement code following logged plan
|
|
318
|
-
6. `taskgraph update-subtask --id=<id> --prompt="what worked/didn't work"` - Log progress
|
|
319
|
-
7. `taskgraph set-status --id=<id> --status=done` - Complete task
|
|
320
|
-
|
|
321
|
-
### Complex Workflows with Checklists
|
|
322
|
-
|
|
323
|
-
For large migrations or multi-step processes:
|
|
324
|
-
|
|
325
|
-
1. Create a markdown PRD file describing the new changes: `touch task-migration-checklist.md` (prds can be .txt or .md)
|
|
326
|
-
2. Use TaskGraph to parse the new prd with `taskgraph parse-prd --append` (also available in MCP)
|
|
327
|
-
3. Use TaskGraph to expand the newly generated tasks into subtasks. Consdier using `analyze-complexity` with the correct --to and --from IDs (the new ids) to identify the ideal subtask amounts for each task. Then expand them.
|
|
328
|
-
4. Work through items systematically, checking them off as completed
|
|
329
|
-
5. Use `taskgraph update-subtask` to log progress on each task/subtask and/or updating/researching them before/during implementation if getting stuck
|
|
330
|
-
|
|
331
|
-
### Git Integration
|
|
332
|
-
|
|
333
|
-
TaskGraph works well with `gh` CLI:
|
|
334
|
-
|
|
335
|
-
```bash
|
|
336
|
-
# Create PR for completed task
|
|
337
|
-
gh pr create --title "Complete task 1.2: User authentication" --body "Implements JWT auth system as specified in task 1.2"
|
|
338
|
-
|
|
339
|
-
# Reference task in commits
|
|
340
|
-
git commit -m "feat: implement JWT auth (task 1.2)"
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### Parallel Development with Git Worktrees
|
|
344
|
-
|
|
345
|
-
```bash
|
|
346
|
-
# Create worktrees for parallel task development
|
|
347
|
-
git worktree add ../project-auth feature/auth-system
|
|
348
|
-
git worktree add ../project-api feature/api-refactor
|
|
349
|
-
|
|
350
|
-
# Run Claude Code in each worktree
|
|
351
|
-
cd ../project-auth && claude # Terminal 1: Auth work
|
|
352
|
-
cd ../project-api && claude # Terminal 2: API work
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
## Troubleshooting
|
|
356
|
-
|
|
357
|
-
### AI Commands Failing
|
|
358
|
-
|
|
359
|
-
```bash
|
|
360
|
-
# Make sure Claude Code is installed and signed in
|
|
361
|
-
claude --version
|
|
362
|
-
|
|
363
|
-
# Verify model configuration
|
|
364
|
-
taskgraph models
|
|
365
|
-
|
|
366
|
-
# Test with different model
|
|
367
|
-
taskgraph models --set-fallback haiku
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
### MCP Connection Issues (only if you use MCP)
|
|
371
|
-
|
|
372
|
-
- Check `.mcp.json` configuration
|
|
373
|
-
- Verify Node.js installation
|
|
374
|
-
- Use `--mcp-debug` flag when starting Claude Code
|
|
375
|
-
- Slash commands and the CLI work without MCP; use them if the server will not connect
|
|
376
|
-
|
|
377
|
-
### Task File Sync Issues
|
|
378
|
-
|
|
379
|
-
```bash
|
|
380
|
-
# Regenerate task files from tasks.json
|
|
381
|
-
taskgraph generate
|
|
382
|
-
|
|
383
|
-
# Fix dependency issues
|
|
384
|
-
taskgraph fix-dependencies
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
DO NOT RE-INITIALIZE. That will not do anything beyond re-adding the same TaskGraph core files.
|
|
388
|
-
|
|
389
|
-
## Important Notes
|
|
390
|
-
|
|
391
|
-
### AI-Powered Operations
|
|
392
|
-
|
|
393
|
-
These commands make AI calls and may take up to a minute:
|
|
394
|
-
|
|
395
|
-
- `parse_prd` / `taskgraph parse-prd`
|
|
396
|
-
- `analyze_project_complexity` / `taskgraph analyze-complexity`
|
|
397
|
-
- `expand_task` / `taskgraph expand`
|
|
398
|
-
- `expand_all` / `taskgraph expand --all`
|
|
399
|
-
- `add_task` / `taskgraph add-task`
|
|
400
|
-
- `update` / `taskgraph update`
|
|
401
|
-
- `update_task` / `taskgraph update-task`
|
|
402
|
-
- `update_subtask` / `taskgraph update-subtask`
|
|
403
|
-
|
|
404
|
-
### File Management
|
|
405
|
-
|
|
406
|
-
- Never manually edit `tasks.json` - use commands instead
|
|
407
|
-
- Never manually edit `.taskgraph/config.json` - use `taskgraph models`
|
|
408
|
-
- Task markdown files in `tasks/` are auto-generated
|
|
409
|
-
- Run `taskgraph generate` after manual changes to tasks.json
|
|
410
|
-
|
|
411
|
-
### Claude Code Session Management
|
|
412
|
-
|
|
413
|
-
- Use `/clear` frequently to maintain focused context
|
|
414
|
-
- Create custom slash commands for repeated TaskGraph workflows
|
|
415
|
-
- Configure tool allowlist to streamline permissions
|
|
416
|
-
- Use headless mode for automation: `claude -p "taskgraph next"`
|
|
417
|
-
|
|
418
|
-
### Multi-Task Updates
|
|
419
|
-
|
|
420
|
-
- Use `update --from=<id>` to update multiple future tasks
|
|
421
|
-
- Use `update-task --id=<id>` for single task updates
|
|
422
|
-
- Use `update-subtask --id=<id>` for implementation logging
|
|
423
|
-
|
|
424
|
-
### Research Mode
|
|
425
|
-
|
|
426
|
-
- Add `--research` flag for research-based AI enhancement
|
|
427
|
-
- The research role has web search and fetch only; it cannot read or change your files
|
|
428
|
-
- Provides more informed task creation and updates
|
|
429
|
-
- Recommended for complex technical tasks
|
|
430
|
-
|
|
431
|
-
---
|
|
432
|
-
|
|
433
|
-
_This guide ensures Claude Code has immediate access to TaskGraph's essential functionality for agentic development workflows._
|
|
13
|
+
Statuses: pending, in-progress, review, done, deferred, cancelled, blocked. Subtask IDs have one dot (`3.2`). Change tasks through the commands, not by editing `.taskgraph/tasks/tasks.json`. `taskgraph --help` lists the rest.
|