@zibby/core 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -75,7 +75,7 @@ Stderr: ${p.slice(-1e3)}`:""}${m.trim()?`
|
|
|
75
75
|
Stdout (last 500 chars): ${m.slice(-500)}`:""}`));return}let _=O.getResult(),B=_?JSON.stringify(_,null,2):O.getRawText()||m||"";a({stdout:m||p||"",parsedText:B})}),v.on("error",y=>{if(I(),clearTimeout(U),clearInterval(N),E&&clearInterval(E),$&&clearTimeout($),l&&!l.aborted)try{l.removeEventListener("abort",D)}catch{}u(new Error(`Cursor Agent spawn error: ${y.message}
|
|
76
76
|
Binary: ${e}
|
|
77
77
|
This usually means the binary is not in PATH. Try:
|
|
78
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Ln,getSkill as Dn}from"@zibby/agent-workflow";import{query as Un}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Bn}from"zod-to-json-schema";import{writeFileSync as mt,mkdirSync as gt,existsSync as sr,readFileSync as or}from"fs";import{homedir as ir}from"os";import{join as ge}from"path";var re=class extends Ln{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,r=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,n=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,s=t||r||n;return s||f.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),s}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,images:i=[],skills:c=null,sessionPath:l=null,nodeName:a=null,timeout:u,config:d={},signal:m=null}=t,p=r;(!p||p==="auto")&&(f.debug(`Model is '${p||"undefined"}', using default: ${j.CLAUDE}`),p=j.CLAUDE);let g=pt[p]||p;pt[p]&&p!==g&&f.debug(`Mapped model: ${p} \u2192 ${g}`);let S=[z("ANTHROPIC_API_KEY"),z("CLAUDE_CODE_OAUTH_TOKEN"),z("ANTHROPIC_AUTH_TOKEN")];try{f.debug(`Invoking Claude Agent SDK with model: ${g}, skills: ${JSON.stringify(c)}`);let h=process.env.CLAUDE_CODE_OAUTH_TOKEN,b=process.env.ANTHROPIC_API_KEY,x=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?Gn(process.env.CLAUDE_CODE_CREDENTIALS_JSON):h&&jn(h,process.env.__ZIBBY_CLAUDE_PLAN);let T=process.env.__ZIBBY_CLAUDE_PLAN,w=T?T.charAt(0).toUpperCase()+T.slice(1):null,A;h?A=w?`Claude ${w} plan \xB7 ***${h.slice(-4)}`:`Subscription \xB7 ***${h.slice(-4)}`:b?A=`API key \xB7 ***${b.slice(-4)}`:x?A=`Bearer \xB7 ***${x.slice(-4)}`:A="NONE \u2014 request will fail";let I=(await import("chalk")).default;console.log(""),console.log(` ${I.cyan("\u25C6")} ${I.bold(g)}`),console.log(` ${I.dim("Auth: ")}${A}`),console.log(` ${I.dim("Workdir: ")}${n}`),console.log(""),console.log(I.bold("Prompt sent to LLM:")),console.log(I.dim("\u2500".repeat(60))),console.log(I.dim(e)),console.log(I.dim("\u2500".repeat(60)));let{allowedTools:C,mcpServers:v}=this._resolveSkills(c,{sessionPath:l,workspace:n,nodeName:a});try{let $={cwd:n,allowedTools:C,permissionMode:"bypassPermissions",model:g,...Object.keys(v).length>0&&{mcpServers:v}};if(s){let k=typeof s.parse=="function"?Bn(s,{target:"openApi3"}):s;$.outputFormat={type:"json_schema",schema:k},f.debug("Structured output enforced via SDK outputFormat")}f.debug(`Agent SDK options: ${JSON.stringify({cwd:$.cwd,toolCount:C.length,permissionMode:$.permissionMode,model:$.model,hasOutputFormat:!!$.outputFormat})}`);let D="",E=0,R=[];f.debug("Starting Claude Agent SDK query stream");let M;try{M=Un({prompt:e,options:$})}catch(y){throw f.error(`Failed to initialize Claude Agent SDK: ${y.message}`),y}let N=null,U=0,O=3;if(m?.aborted){let y=new Error("Aborted via signal");throw y.name="AbortError",y}try{for await(let y of M){if(m?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}if(R.push(y),y.type==="error"||y.error){let P=y.error?.message||y.error||y.message||"Unknown API error";throw new Error(typeof P=="string"?P:JSON.stringify(P))}let k=JSON.stringify(y.message?.content||y.text||"").slice(0,200);if(k===N){if(U++,U>=O){let P=(y.message?.content?.[0]?.text||y.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${U}x repeated): ${P}`)}}else N=k,U=1;if(y.type==="assistant"||y.constructor?.name==="AssistantMessage"){let P=y.message?.content||y.content||[];for(let _ of P)if(_.type==="thinking"&&_.thinking)console.log(`${_.thinking.substring(0,200)}${_.thinking.length>200?"...":""}`);else if(_.type==="text"&&_.text)D+=_.text,_.text.length<500?console.log(`${_.text}`):console.log(`${_.text.substring(0,200)}... (${_.text.length} chars)`);else if(_.type==="tool_use"){E++,_.name.includes("memory")?Z.stepMemory(`Tool: ${_.name}`):Z.stepTool(`Tool: ${_.name}`);let L=JSON.stringify(_.input).substring(0,100);console.log(` Input: ${L}${JSON.stringify(_.input).length>100?"...":""}`)}}else if(!(y.type==="user"&&y.tool_use_result)){if(y.type==="result"||y.constructor?.name==="ResultMessage"){let P=y.result||y.text||y.content||D;try{Fn({message:y,sessionPath:l,nodeName:a,model:p,toolCallCount:E})}catch(_){f.debug(`usage.json write failed: ${_.message}`)}if(s){if(y.structured_output){f.debug("Using SDK native structured_output");let B=typeof s.parse=="function"?s.parse(y.structured_output):y.structured_output;return{raw:P,structured:B}}if(P){let _=this._extractJson(P,s);if(_)return{raw:P,structured:_}}f.warn(`Could not extract structured output \u2014 returning raw text (${(P||"").length} chars)`)}return P||""}}}if(f.warn(`Agent SDK ended without result. Collected ${R.length} messages`),D.length>0)return f.debug("Returning accumulated text from messages"),D;throw new Error("Claude Agent SDK query ended without result")}catch(y){throw f.error(`Error during query stream: ${y.message}`),y}}catch($){throw f.error("Claude Agent SDK call failed",{error:$.message}),$}}finally{for(let h of S)h.dispose()}}_resolveSkills(e,t){if(e===null)return f.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return f.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],n={};for(let s of e){let i=Dn(s);if(!i){f.warn(`Unknown skill "${s}" \u2014 skipping`);continue}if(i.allowedTools&&r.push(...i.allowedTools),typeof i.resolve=="function"){let c=i.resolve(t);c&&(n[i.serverName]=c,f.debug(`MCP: ${i.serverName} \u2192 ${c.command} ${c.args[0]}`))}}return{allowedTools:r,mcpServers:n}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,s=e.indexOf("===JSON_END===");return e.substring(n,s).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),s=e.lastIndexOf("}");if(n!==-1&&s>n)return e.substring(n,s+1)}];for(let n of r)try{let s=n();if(!s)continue;let i=JSON.parse(s);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function Fn({message:o,sessionPath:e,nodeName:t,model:r,toolCallCount:n}){if(!e||!t)return;let s=o?.usage||o?.message?.usage||{},i=Re(s.input_tokens,s.inputTokens),c=Re(s.output_tokens,s.outputTokens),l=Re(s.cache_read_input_tokens,s.cacheReadInputTokens),a=Re(s.cache_creation_input_tokens,s.cacheCreationInputTokens),u=Re(o?.duration_ms,o?.durationMs),d={model:r||null,input_tokens:i,output_tokens:c,cache_read_tokens:l,cache_creation_tokens:a,tool_call_count:typeof n=="number"?n:null,duration_ms:u,captured_at:new Date().toISOString()},m=ge(e,t);try{gt(m,{recursive:!0})}catch{}mt(ge(m,"usage.json"),JSON.stringify(d,null,2),"utf-8")}function Re(...o){for(let e of o){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function jn(o,e){let t=ge(ir(),".claude"),r=ge(t,".credentials.json"),n={claudeAiOauth:{accessToken:o,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(sr(r)&&JSON.parse(or(r,"utf-8"))?.claudeAiOauth?.accessToken===o)return;gt(t,{recursive:!0}),mt(r,JSON.stringify(n,null,2),"utf-8"),f.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(s){f.warn(`Could not write ${r}: ${s.message} \u2014 Claude SDK may fail to authenticate.`)}}function Gn(o){let e=ge(ir(),".claude"),t=ge(e,".credentials.json"),r;try{r=JSON.parse(o)}catch(n){f.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${n.message}`);return}if(!r?.claudeAiOauth?.accessToken){f.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(sr(t)){let n=JSON.parse(or(t,"utf-8"));if(n?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&n?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}gt(e,{recursive:!0}),mt(t,JSON.stringify(r,null,2),"utf-8"),f.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(n){f.warn(`Could not write ${t}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}import{AgentStrategy as zn,getSkill as Jn}from"@zibby/agent-workflow";import{execSync as Kn}from"node:child_process";import{zodToJsonSchema as Yn}from"zod-to-json-schema";var ne=class extends zn{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return f.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Kn("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return f.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a,config:u={},signal:d=null}=t,m=[z("OPENAI_API_KEY"),z("CODEX_API_KEY")];try{let{Codex:p}=await import("@openai/codex-sdk"),g=r;(!g||g==="auto")&&(f.debug(`Model is '${g||"undefined"}', using default: ${j.CODEX}`),g=j.CODEX);let S=ft[g]||g;ft[g]&&g!==S&&f.debug(`Mapped model: ${g} \u2192 ${S}`),f.debug(`Invoking Codex SDK with model: ${S}, skills: ${JSON.stringify(i)}`);let h=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;h&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=h);let b=h?` | key: ***${h.slice(-4)}`:" | key: not set";console.log(`
|
|
78
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Ln,getSkill as Dn}from"@zibby/agent-workflow";import{query as Un}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Bn}from"zod-to-json-schema";import{writeFileSync as mt,mkdirSync as gt,existsSync as sr,readFileSync as or}from"fs";import{homedir as ir}from"os";import{join as ge}from"path";var re=class extends Ln{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,r=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,n=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,s=t||r||n;return s||f.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),s}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,images:i=[],skills:c=null,sessionPath:l=null,nodeName:a=null,timeout:u,config:d={},signal:m=null}=t,p=r;(!p||p==="auto")&&(f.debug(`Model is '${p||"undefined"}', using default: ${j.CLAUDE}`),p=j.CLAUDE);let g=pt[p]||p;pt[p]&&p!==g&&f.debug(`Mapped model: ${p} \u2192 ${g}`);let S=[z("ANTHROPIC_API_KEY"),z("CLAUDE_CODE_OAUTH_TOKEN"),z("ANTHROPIC_AUTH_TOKEN")];try{f.debug(`Invoking Claude Agent SDK with model: ${g}, skills: ${JSON.stringify(c)}`);let h=process.env.CLAUDE_CODE_OAUTH_TOKEN,b=process.env.ANTHROPIC_API_KEY,x=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?Gn(process.env.CLAUDE_CODE_CREDENTIALS_JSON):h&&jn(h,process.env.__ZIBBY_CLAUDE_PLAN);let T=process.env.__ZIBBY_CLAUDE_PLAN,w=T?T.charAt(0).toUpperCase()+T.slice(1):null,A;h?A=w?`Claude ${w} plan \xB7 ***${h.slice(-4)}`:`Subscription \xB7 ***${h.slice(-4)}`:b?A=`API key \xB7 ***${b.slice(-4)}`:x?A=`Bearer \xB7 ***${x.slice(-4)}`:A="NONE \u2014 request will fail";let I=(await import("chalk")).default;console.log(""),console.log(` ${I.cyan("\u25C6")} ${I.bold(g)}`),console.log(` ${I.dim("Auth: ")}${A}`),console.log(` ${I.dim("Workdir: ")}${n}`),console.log(""),console.log(I.bold("Prompt sent to LLM:")),console.log(I.dim("\u2500".repeat(60))),console.log(I.dim(e)),console.log(I.dim("\u2500".repeat(60)));let{allowedTools:C,mcpServers:v}=this._resolveSkills(c,{sessionPath:l,workspace:n,nodeName:a});try{let $={cwd:n,allowedTools:C,permissionMode:process.env.ANTHROPIC_API_KEY?"bypassPermissions":"default",model:g,...Object.keys(v).length>0&&{mcpServers:v}};if(s){let k=typeof s.parse=="function"?Bn(s,{target:"openApi3"}):s;$.outputFormat={type:"json_schema",schema:k},f.debug("Structured output enforced via SDK outputFormat")}f.debug(`Agent SDK options: ${JSON.stringify({cwd:$.cwd,toolCount:C.length,permissionMode:$.permissionMode,model:$.model,hasOutputFormat:!!$.outputFormat})}`);let D="",E=0,R=[];f.debug("Starting Claude Agent SDK query stream");let M;try{M=Un({prompt:e,options:$})}catch(y){throw f.error(`Failed to initialize Claude Agent SDK: ${y.message}`),y}let N=null,U=0,O=3;if(m?.aborted){let y=new Error("Aborted via signal");throw y.name="AbortError",y}try{for await(let y of M){if(m?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}if(R.push(y),y.type==="error"||y.error){let P=y.error?.message||y.error||y.message||"Unknown API error";throw new Error(typeof P=="string"?P:JSON.stringify(P))}let k=JSON.stringify(y.message?.content||y.text||"").slice(0,200);if(k===N){if(U++,U>=O){let P=(y.message?.content?.[0]?.text||y.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${U}x repeated): ${P}`)}}else N=k,U=1;if(y.type==="assistant"||y.constructor?.name==="AssistantMessage"){let P=y.message?.content||y.content||[];for(let _ of P)if(_.type==="thinking"&&_.thinking)console.log(`${_.thinking.substring(0,200)}${_.thinking.length>200?"...":""}`);else if(_.type==="text"&&_.text)D+=_.text,_.text.length<500?console.log(`${_.text}`):console.log(`${_.text.substring(0,200)}... (${_.text.length} chars)`);else if(_.type==="tool_use"){E++,_.name.includes("memory")?Z.stepMemory(`Tool: ${_.name}`):Z.stepTool(`Tool: ${_.name}`);let L=JSON.stringify(_.input).substring(0,100);console.log(` Input: ${L}${JSON.stringify(_.input).length>100?"...":""}`)}}else if(!(y.type==="user"&&y.tool_use_result)){if(y.type==="result"||y.constructor?.name==="ResultMessage"){let P=y.result||y.text||y.content||D;try{Fn({message:y,sessionPath:l,nodeName:a,model:p,toolCallCount:E})}catch(_){f.debug(`usage.json write failed: ${_.message}`)}if(s){if(y.structured_output){f.debug("Using SDK native structured_output");let B=typeof s.parse=="function"?s.parse(y.structured_output):y.structured_output;return{raw:P,structured:B}}if(P){let _=this._extractJson(P,s);if(_)return{raw:P,structured:_}}f.warn(`Could not extract structured output \u2014 returning raw text (${(P||"").length} chars)`)}return P||""}}}if(f.warn(`Agent SDK ended without result. Collected ${R.length} messages`),D.length>0)return f.debug("Returning accumulated text from messages"),D;throw new Error("Claude Agent SDK query ended without result")}catch(y){throw f.error(`Error during query stream: ${y.message}`),y}}catch($){throw f.error("Claude Agent SDK call failed",{error:$.message}),$}}finally{for(let h of S)h.dispose()}}_resolveSkills(e,t){if(e===null)return f.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return f.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],n={};for(let s of e){let i=Dn(s);if(!i){f.warn(`Unknown skill "${s}" \u2014 skipping`);continue}if(i.allowedTools&&r.push(...i.allowedTools),typeof i.resolve=="function"){let c=i.resolve(t);c&&(n[i.serverName]=c,f.debug(`MCP: ${i.serverName} \u2192 ${c.command} ${c.args[0]}`))}}return{allowedTools:r,mcpServers:n}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,s=e.indexOf("===JSON_END===");return e.substring(n,s).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),s=e.lastIndexOf("}");if(n!==-1&&s>n)return e.substring(n,s+1)}];for(let n of r)try{let s=n();if(!s)continue;let i=JSON.parse(s);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function Fn({message:o,sessionPath:e,nodeName:t,model:r,toolCallCount:n}){if(!e||!t)return;let s=o?.usage||o?.message?.usage||{},i=Re(s.input_tokens,s.inputTokens),c=Re(s.output_tokens,s.outputTokens),l=Re(s.cache_read_input_tokens,s.cacheReadInputTokens),a=Re(s.cache_creation_input_tokens,s.cacheCreationInputTokens),u=Re(o?.duration_ms,o?.durationMs),d={model:r||null,input_tokens:i,output_tokens:c,cache_read_tokens:l,cache_creation_tokens:a,tool_call_count:typeof n=="number"?n:null,duration_ms:u,captured_at:new Date().toISOString()},m=ge(e,t);try{gt(m,{recursive:!0})}catch{}mt(ge(m,"usage.json"),JSON.stringify(d,null,2),"utf-8")}function Re(...o){for(let e of o){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function jn(o,e){let t=ge(ir(),".claude"),r=ge(t,".credentials.json"),n={claudeAiOauth:{accessToken:o,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(sr(r)&&JSON.parse(or(r,"utf-8"))?.claudeAiOauth?.accessToken===o)return;gt(t,{recursive:!0}),mt(r,JSON.stringify(n,null,2),"utf-8"),f.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(s){f.warn(`Could not write ${r}: ${s.message} \u2014 Claude SDK may fail to authenticate.`)}}function Gn(o){let e=ge(ir(),".claude"),t=ge(e,".credentials.json"),r;try{r=JSON.parse(o)}catch(n){f.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${n.message}`);return}if(!r?.claudeAiOauth?.accessToken){f.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(sr(t)){let n=JSON.parse(or(t,"utf-8"));if(n?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&n?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}gt(e,{recursive:!0}),mt(t,JSON.stringify(r,null,2),"utf-8"),f.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(n){f.warn(`Could not write ${t}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}import{AgentStrategy as zn,getSkill as Jn}from"@zibby/agent-workflow";import{execSync as Kn}from"node:child_process";import{zodToJsonSchema as Yn}from"zod-to-json-schema";var ne=class extends zn{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return f.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Kn("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return f.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a,config:u={},signal:d=null}=t,m=[z("OPENAI_API_KEY"),z("CODEX_API_KEY")];try{let{Codex:p}=await import("@openai/codex-sdk"),g=r;(!g||g==="auto")&&(f.debug(`Model is '${g||"undefined"}', using default: ${j.CODEX}`),g=j.CODEX);let S=ft[g]||g;ft[g]&&g!==S&&f.debug(`Mapped model: ${g} \u2192 ${S}`),f.debug(`Invoking Codex SDK with model: ${S}, skills: ${JSON.stringify(i)}`);let h=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;h&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=h);let b=h?` | key: ***${h.slice(-4)}`:" | key: not set";console.log(`
|
|
79
79
|
\u25C6 Model: ${S}${b}
|
|
80
80
|
`);let x=(await import("chalk")).default;console.log(`
|
|
81
81
|
${x.bold("Prompt sent to LLM:")}`),console.log(x.dim("\u2500".repeat(60))),console.log(x.dim(e)),console.log(x.dim("\u2500".repeat(60)));let T=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),w={};Object.keys(T).length>0&&(w.mcp_servers=T,f.debug(`[Codex] MCP servers: ${Object.keys(T).join(", ")}`));let I=new p({...Object.keys(w).length>0&&{config:w}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),C=s&&typeof s.parse=="function",v={};if(s)try{let $=C?Yn(s,{target:"openAi"}):s;v.outputSchema=$,f.debug("Structured output via SDK outputSchema")}catch($){f.warn(`[Codex] Schema conversion failed, will extract from text: ${$.message}`)}if(d?.aborted){let $=new Error("Aborted via signal");throw $.name="AbortError",$}try{let{events:$}=await I.runStreamed(e,v),D=0,E="";for await(let R of $){if(d?.aborted){let N=new Error("Aborted via signal");throw N.name="AbortError",N}let M=R.type;if(M==="item.completed"){let N=R.item,U=N?.type;if(U==="mcp_tool_call"){D++;let O=`${N.server}/${N.tool}`;if(Z.stepTool(`Tool: ${O}`),N.arguments){let y=JSON.stringify(N.arguments),k=y.length>100?`${y.substring(0,100)}...`:y;console.log(` Input: ${k}`)}}else if(U==="tool_call"||U==="function_call"||U==="command_execution"){D++;let O=N.name||N.tool||N.command||"unknown";Z.stepTool(`Tool: ${O}`)}else U==="agent_message"&&(E=N.text||"",E.length<500?console.log(E):console.log(`${E.substring(0,200)}... (${E.length} chars)`))}else M==="turn.completed"?f.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(R.usage||{})}`):f.debug(`[Codex] Event: ${M} ${JSON.stringify(R).slice(0,300)}`)}if(f.debug(`[Codex] Last agent message (${E.length} chars): ${E.slice(0,500)}`),s){if(!E)throw new Error("Codex agent returned no response");let R=JSON.parse(E),M=C?s.parse(R):R;return f.debug("\u2705 [Codex] Structured output validated"),{raw:E,structured:M}}return E||""}catch($){let D=$.message||String($);throw f.error(`\u274C [Codex] SDK call failed: ${D}`),D.includes("exited with code")&&(f.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),f.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),$}}finally{for(let p of m)p.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let s=Jn(n);if(!s){f.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof s.resolve!="function")continue;let i=s.resolve(t);if(!i)continue;let c=s.serverName||n,l={command:i.command};i.args?.length&&(l.args=i.args),i.env&&Object.keys(i.env).length>0&&(l.env=i.env),r[c]=l,f.debug(`[Codex] MCP: ${c} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return r}};import{AgentStrategy as Hn,getSkill as Zn}from"@zibby/agent-workflow";import{execSync as Wn,spawn as Xn}from"node:child_process";import{zodToJsonSchema as qn}from"zod-to-json-schema";import{existsSync as ar,mkdirSync as cr,readFileSync as lr,rmSync as Vn,writeFileSync as ur}from"node:fs";import{join as se}from"node:path";function Qn(o){if(!o)return null;let e=String(o),t=e.match(/```(?:json)?\s*([\s\S]*?)```/i);if(t?.[1])try{return JSON.parse(t[1].trim())}catch{}let r=e.indexOf("{");if(r<0)return null;let n=0,s=!1,i=!1,c=-1;for(let l=r;l<e.length;l++){let a=e[l];if(s){i?i=!1:a==="\\"?i=!0:a==='"'&&(s=!1);continue}if(a==='"'){s=!0;continue}if(a==="{"){n===0&&(c=l),n+=1;continue}if(a==="}"){if(n===0)continue;if(n-=1,n===0&&c>=0){let u=e.slice(c,l+1);try{return JSON.parse(u)}catch{c=-1}}}}return null}function es(o){let e=String(o||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return Qn(e)}}function ts(o){try{let e=JSON.parse(o);if(typeof e=="string")return e;if(typeof e?.response=="string")return e.response;if(typeof e?.text=="string")return e.text;if(typeof e?.output=="string")return e.output;if(Array.isArray(e?.candidates)&&e.candidates.length>0){let t=e.candidates[0];if(typeof t?.content=="string")return t.content;if(Array.isArray(t?.content?.parts)){let r=t.content.parts.map(n=>typeof n?.text=="string"?n.text:"").join("");if(r.trim())return r}}}catch{}return o}var oe=class extends Hn{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GEMINI_API_KEY_POOL||process.env.GOOGLE_API_KEY||process.env.GOOGLE_API_KEY_POOL))return f.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return Wn("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return f.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a=600*1e3,signal:u=null}=t,d=[z("GEMINI_API_KEY"),z("GOOGLE_API_KEY")];try{let m=r;(!m||m==="auto")&&(m=j.GEMINI);let p=Yt[m]||m,g=String(process.env.GEMINI_API_KEY||"").trim(),S=String(process.env.GOOGLE_API_KEY||"").trim(),h=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),b=Object.keys(h).length>0,x=new de(e),T=s&&typeof s.parse=="function",w=null;if(s){let _;try{let B=T?qn(s,{target:"openAi"}):s;_=JSON.stringify(B,null,2)}catch{_="{}"}if(b){x.addSystemInstruction(`Write valid JSON that matches this schema:
|
package/dist/package.json
CHANGED
|
@@ -75,7 +75,7 @@ Stderr: ${h.slice(-1e3)}`:""}${m.trim()?`
|
|
|
75
75
|
Stdout (last 500 chars): ${m.slice(-500)}`:""}`));return}let d=w.getResult(),D=d?JSON.stringify(d,null,2):w.getRawText()||m||"";p({stdout:m||h||"",parsedText:D})}),O.on("error",u=>{if(C(),clearTimeout(B),clearInterval(I),b&&clearInterval(b),A&&clearTimeout(A),c&&!c.aborted)try{c.removeEventListener("abort",M)}catch{}f(new Error(`Cursor Agent spawn error: ${u.message}
|
|
76
76
|
Binary: ${e}
|
|
77
77
|
This usually means the binary is not in PATH. Try:
|
|
78
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Bt,getSkill as Kt}from"@zibby/agent-workflow";import{query as Jt}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Gt}from"zod-to-json-schema";import{writeFileSync as Re,mkdirSync as Me,existsSync as tt,readFileSync as ot}from"fs";import{homedir as rt}from"os";import{join as ee}from"path";var ye=class extends Bt{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,r=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,o=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,s=t||r||o;return s||a.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),s}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:s=null,images:i=[],skills:l=null,sessionPath:c=null,nodeName:p=null,timeout:f,config:_={},signal:m=null}=t,h=r;(!h||h==="auto")&&(a.debug(`Model is '${h||"undefined"}', using default: ${K.CLAUDE}`),h=K.CLAUDE);let S=ke[h]||h;ke[h]&&h!==S&&a.debug(`Mapped model: ${h} \u2192 ${S}`);let L=[G("ANTHROPIC_API_KEY"),G("CLAUDE_CODE_OAUTH_TOKEN"),G("ANTHROPIC_AUTH_TOKEN")];try{a.debug(`Invoking Claude Agent SDK with model: ${S}, skills: ${JSON.stringify(l)}`);let y=process.env.CLAUDE_CODE_OAUTH_TOKEN,x=process.env.ANTHROPIC_API_KEY,$=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?Yt(process.env.CLAUDE_CODE_CREDENTIALS_JSON):y&&Ft(y,process.env.__ZIBBY_CLAUDE_PLAN);let v=process.env.__ZIBBY_CLAUDE_PLAN,g=v?v.charAt(0).toUpperCase()+v.slice(1):null,R;y?R=g?`Claude ${g} plan \xB7 ***${y.slice(-4)}`:`Subscription \xB7 ***${y.slice(-4)}`:x?R=`API key \xB7 ***${x.slice(-4)}`:$?R=`Bearer \xB7 ***${$.slice(-4)}`:R="NONE \u2014 request will fail";let C=(await import("chalk")).default;console.log(""),console.log(` ${C.cyan("\u25C6")} ${C.bold(S)}`),console.log(` ${C.dim("Auth: ")}${R}`),console.log(` ${C.dim("Workdir: ")}${o}`),console.log(""),console.log(C.bold("Prompt sent to LLM:")),console.log(C.dim("\u2500".repeat(60))),console.log(C.dim(e)),console.log(C.dim("\u2500".repeat(60)));let{allowedTools:k,mcpServers:O}=this._resolveSkills(l,{sessionPath:c,workspace:o,nodeName:p});try{let A={cwd:o,allowedTools:k,permissionMode:"bypassPermissions",model:S,...Object.keys(O).length>0&&{mcpServers:O}};if(s){let T=typeof s.parse=="function"?Gt(s,{target:"openApi3"}):s;A.outputFormat={type:"json_schema",schema:T},a.debug("Structured output enforced via SDK outputFormat")}a.debug(`Agent SDK options: ${JSON.stringify({cwd:A.cwd,toolCount:k.length,permissionMode:A.permissionMode,model:A.model,hasOutputFormat:!!A.outputFormat})}`);let M="",b=0,P=[];a.debug("Starting Claude Agent SDK query stream");let U;try{U=Jt({prompt:e,options:A})}catch(u){throw a.error(`Failed to initialize Claude Agent SDK: ${u.message}`),u}let I=null,B=0,w=3;if(m?.aborted){let u=new Error("Aborted via signal");throw u.name="AbortError",u}try{for await(let u of U){if(m?.aborted){let E=new Error("Aborted via signal");throw E.name="AbortError",E}if(P.push(u),u.type==="error"||u.error){let E=u.error?.message||u.error||u.message||"Unknown API error";throw new Error(typeof E=="string"?E:JSON.stringify(E))}let T=JSON.stringify(u.message?.content||u.text||"").slice(0,200);if(T===I){if(B++,B>=w){let E=(u.message?.content?.[0]?.text||u.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${B}x repeated): ${E}`)}}else I=T,B=1;if(u.type==="assistant"||u.constructor?.name==="AssistantMessage"){let E=u.message?.content||u.content||[];for(let d of E)if(d.type==="thinking"&&d.thinking)console.log(`${d.thinking.substring(0,200)}${d.thinking.length>200?"...":""}`);else if(d.type==="text"&&d.text)M+=d.text,d.text.length<500?console.log(`${d.text}`):console.log(`${d.text.substring(0,200)}... (${d.text.length} chars)`);else if(d.type==="tool_use"){b++,d.name.includes("memory")?Y.stepMemory(`Tool: ${d.name}`):Y.stepTool(`Tool: ${d.name}`);let N=JSON.stringify(d.input).substring(0,100);console.log(` Input: ${N}${JSON.stringify(d.input).length>100?"...":""}`)}}else if(!(u.type==="user"&&u.tool_use_result)){if(u.type==="result"||u.constructor?.name==="ResultMessage"){let E=u.result||u.text||u.content||M;try{jt({message:u,sessionPath:c,nodeName:p,model:h,toolCallCount:b})}catch(d){a.debug(`usage.json write failed: ${d.message}`)}if(s){if(u.structured_output){a.debug("Using SDK native structured_output");let D=typeof s.parse=="function"?s.parse(u.structured_output):u.structured_output;return{raw:E,structured:D}}if(E){let d=this._extractJson(E,s);if(d)return{raw:E,structured:d}}a.warn(`Could not extract structured output \u2014 returning raw text (${(E||"").length} chars)`)}return E||""}}}if(a.warn(`Agent SDK ended without result. Collected ${P.length} messages`),M.length>0)return a.debug("Returning accumulated text from messages"),M;throw new Error("Claude Agent SDK query ended without result")}catch(u){throw a.error(`Error during query stream: ${u.message}`),u}}catch(A){throw a.error("Claude Agent SDK call failed",{error:A.message}),A}}finally{for(let y of L)y.dispose()}}_resolveSkills(e,t){if(e===null)return a.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return a.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],o={};for(let s of e){let i=Kt(s);if(!i){a.warn(`Unknown skill "${s}" \u2014 skipping`);continue}if(i.allowedTools&&r.push(...i.allowedTools),typeof i.resolve=="function"){let l=i.resolve(t);l&&(o[i.serverName]=l,a.debug(`MCP: ${i.serverName} \u2192 ${l.command} ${l.args[0]}`))}}return{allowedTools:r,mcpServers:o}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,s=e.indexOf("===JSON_END===");return e.substring(o,s).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let o=e.indexOf("{"),s=e.lastIndexOf("}");if(o!==-1&&s>o)return e.substring(o,s+1)}];for(let o of r)try{let s=o();if(!s)continue;let i=JSON.parse(s);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function jt({message:n,sessionPath:e,nodeName:t,model:r,toolCallCount:o}){if(!e||!t)return;let s=n?.usage||n?.message?.usage||{},i=ce(s.input_tokens,s.inputTokens),l=ce(s.output_tokens,s.outputTokens),c=ce(s.cache_read_input_tokens,s.cacheReadInputTokens),p=ce(s.cache_creation_input_tokens,s.cacheCreationInputTokens),f=ce(n?.duration_ms,n?.durationMs),_={model:r||null,input_tokens:i,output_tokens:l,cache_read_tokens:c,cache_creation_tokens:p,tool_call_count:typeof o=="number"?o:null,duration_ms:f,captured_at:new Date().toISOString()},m=ee(e,t);try{Me(m,{recursive:!0})}catch{}Re(ee(m,"usage.json"),JSON.stringify(_,null,2),"utf-8")}function ce(...n){for(let e of n){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function Ft(n,e){let t=ee(rt(),".claude"),r=ee(t,".credentials.json"),o={claudeAiOauth:{accessToken:n,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(tt(r)&&JSON.parse(ot(r,"utf-8"))?.claudeAiOauth?.accessToken===n)return;Me(t,{recursive:!0}),Re(r,JSON.stringify(o,null,2),"utf-8"),a.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(s){a.warn(`Could not write ${r}: ${s.message} \u2014 Claude SDK may fail to authenticate.`)}}function Yt(n){let e=ee(rt(),".claude"),t=ee(e,".credentials.json"),r;try{r=JSON.parse(n)}catch(o){a.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!r?.claudeAiOauth?.accessToken){a.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(tt(t)){let o=JSON.parse(ot(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}Me(e,{recursive:!0}),Re(t,JSON.stringify(r,null,2),"utf-8"),a.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){a.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}import{AgentStrategy as zt,getSkill as Ht}from"@zibby/agent-workflow";import{execSync as Xt}from"node:child_process";import{zodToJsonSchema as Zt}from"zod-to-json-schema";var _e=class extends zt{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return a.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Xt("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return a.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:s=null,skills:i=null,sessionPath:l=null,nodeName:c=null,timeout:p,config:f={},signal:_=null}=t,m=[G("OPENAI_API_KEY"),G("CODEX_API_KEY")];try{let{Codex:h}=await import("@openai/codex-sdk"),S=r;(!S||S==="auto")&&(a.debug(`Model is '${S||"undefined"}', using default: ${K.CODEX}`),S=K.CODEX);let L=Pe[S]||S;Pe[S]&&S!==L&&a.debug(`Mapped model: ${S} \u2192 ${L}`),a.debug(`Invoking Codex SDK with model: ${L}, skills: ${JSON.stringify(i)}`);let y=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;y&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=y);let x=y?` | key: ***${y.slice(-4)}`:" | key: not set";console.log(`
|
|
78
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Bt,getSkill as Kt}from"@zibby/agent-workflow";import{query as Jt}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Gt}from"zod-to-json-schema";import{writeFileSync as Re,mkdirSync as Me,existsSync as tt,readFileSync as ot}from"fs";import{homedir as rt}from"os";import{join as ee}from"path";var ye=class extends Bt{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,r=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,o=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,s=t||r||o;return s||a.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),s}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:s=null,images:i=[],skills:l=null,sessionPath:c=null,nodeName:p=null,timeout:f,config:_={},signal:m=null}=t,h=r;(!h||h==="auto")&&(a.debug(`Model is '${h||"undefined"}', using default: ${K.CLAUDE}`),h=K.CLAUDE);let S=ke[h]||h;ke[h]&&h!==S&&a.debug(`Mapped model: ${h} \u2192 ${S}`);let L=[G("ANTHROPIC_API_KEY"),G("CLAUDE_CODE_OAUTH_TOKEN"),G("ANTHROPIC_AUTH_TOKEN")];try{a.debug(`Invoking Claude Agent SDK with model: ${S}, skills: ${JSON.stringify(l)}`);let y=process.env.CLAUDE_CODE_OAUTH_TOKEN,x=process.env.ANTHROPIC_API_KEY,$=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?Yt(process.env.CLAUDE_CODE_CREDENTIALS_JSON):y&&Ft(y,process.env.__ZIBBY_CLAUDE_PLAN);let v=process.env.__ZIBBY_CLAUDE_PLAN,g=v?v.charAt(0).toUpperCase()+v.slice(1):null,R;y?R=g?`Claude ${g} plan \xB7 ***${y.slice(-4)}`:`Subscription \xB7 ***${y.slice(-4)}`:x?R=`API key \xB7 ***${x.slice(-4)}`:$?R=`Bearer \xB7 ***${$.slice(-4)}`:R="NONE \u2014 request will fail";let C=(await import("chalk")).default;console.log(""),console.log(` ${C.cyan("\u25C6")} ${C.bold(S)}`),console.log(` ${C.dim("Auth: ")}${R}`),console.log(` ${C.dim("Workdir: ")}${o}`),console.log(""),console.log(C.bold("Prompt sent to LLM:")),console.log(C.dim("\u2500".repeat(60))),console.log(C.dim(e)),console.log(C.dim("\u2500".repeat(60)));let{allowedTools:k,mcpServers:O}=this._resolveSkills(l,{sessionPath:c,workspace:o,nodeName:p});try{let A={cwd:o,allowedTools:k,permissionMode:process.env.ANTHROPIC_API_KEY?"bypassPermissions":"default",model:S,...Object.keys(O).length>0&&{mcpServers:O}};if(s){let T=typeof s.parse=="function"?Gt(s,{target:"openApi3"}):s;A.outputFormat={type:"json_schema",schema:T},a.debug("Structured output enforced via SDK outputFormat")}a.debug(`Agent SDK options: ${JSON.stringify({cwd:A.cwd,toolCount:k.length,permissionMode:A.permissionMode,model:A.model,hasOutputFormat:!!A.outputFormat})}`);let M="",b=0,P=[];a.debug("Starting Claude Agent SDK query stream");let U;try{U=Jt({prompt:e,options:A})}catch(u){throw a.error(`Failed to initialize Claude Agent SDK: ${u.message}`),u}let I=null,B=0,w=3;if(m?.aborted){let u=new Error("Aborted via signal");throw u.name="AbortError",u}try{for await(let u of U){if(m?.aborted){let E=new Error("Aborted via signal");throw E.name="AbortError",E}if(P.push(u),u.type==="error"||u.error){let E=u.error?.message||u.error||u.message||"Unknown API error";throw new Error(typeof E=="string"?E:JSON.stringify(E))}let T=JSON.stringify(u.message?.content||u.text||"").slice(0,200);if(T===I){if(B++,B>=w){let E=(u.message?.content?.[0]?.text||u.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${B}x repeated): ${E}`)}}else I=T,B=1;if(u.type==="assistant"||u.constructor?.name==="AssistantMessage"){let E=u.message?.content||u.content||[];for(let d of E)if(d.type==="thinking"&&d.thinking)console.log(`${d.thinking.substring(0,200)}${d.thinking.length>200?"...":""}`);else if(d.type==="text"&&d.text)M+=d.text,d.text.length<500?console.log(`${d.text}`):console.log(`${d.text.substring(0,200)}... (${d.text.length} chars)`);else if(d.type==="tool_use"){b++,d.name.includes("memory")?Y.stepMemory(`Tool: ${d.name}`):Y.stepTool(`Tool: ${d.name}`);let N=JSON.stringify(d.input).substring(0,100);console.log(` Input: ${N}${JSON.stringify(d.input).length>100?"...":""}`)}}else if(!(u.type==="user"&&u.tool_use_result)){if(u.type==="result"||u.constructor?.name==="ResultMessage"){let E=u.result||u.text||u.content||M;try{jt({message:u,sessionPath:c,nodeName:p,model:h,toolCallCount:b})}catch(d){a.debug(`usage.json write failed: ${d.message}`)}if(s){if(u.structured_output){a.debug("Using SDK native structured_output");let D=typeof s.parse=="function"?s.parse(u.structured_output):u.structured_output;return{raw:E,structured:D}}if(E){let d=this._extractJson(E,s);if(d)return{raw:E,structured:d}}a.warn(`Could not extract structured output \u2014 returning raw text (${(E||"").length} chars)`)}return E||""}}}if(a.warn(`Agent SDK ended without result. Collected ${P.length} messages`),M.length>0)return a.debug("Returning accumulated text from messages"),M;throw new Error("Claude Agent SDK query ended without result")}catch(u){throw a.error(`Error during query stream: ${u.message}`),u}}catch(A){throw a.error("Claude Agent SDK call failed",{error:A.message}),A}}finally{for(let y of L)y.dispose()}}_resolveSkills(e,t){if(e===null)return a.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return a.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],o={};for(let s of e){let i=Kt(s);if(!i){a.warn(`Unknown skill "${s}" \u2014 skipping`);continue}if(i.allowedTools&&r.push(...i.allowedTools),typeof i.resolve=="function"){let l=i.resolve(t);l&&(o[i.serverName]=l,a.debug(`MCP: ${i.serverName} \u2192 ${l.command} ${l.args[0]}`))}}return{allowedTools:r,mcpServers:o}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,s=e.indexOf("===JSON_END===");return e.substring(o,s).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let o=e.indexOf("{"),s=e.lastIndexOf("}");if(o!==-1&&s>o)return e.substring(o,s+1)}];for(let o of r)try{let s=o();if(!s)continue;let i=JSON.parse(s);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function jt({message:n,sessionPath:e,nodeName:t,model:r,toolCallCount:o}){if(!e||!t)return;let s=n?.usage||n?.message?.usage||{},i=ce(s.input_tokens,s.inputTokens),l=ce(s.output_tokens,s.outputTokens),c=ce(s.cache_read_input_tokens,s.cacheReadInputTokens),p=ce(s.cache_creation_input_tokens,s.cacheCreationInputTokens),f=ce(n?.duration_ms,n?.durationMs),_={model:r||null,input_tokens:i,output_tokens:l,cache_read_tokens:c,cache_creation_tokens:p,tool_call_count:typeof o=="number"?o:null,duration_ms:f,captured_at:new Date().toISOString()},m=ee(e,t);try{Me(m,{recursive:!0})}catch{}Re(ee(m,"usage.json"),JSON.stringify(_,null,2),"utf-8")}function ce(...n){for(let e of n){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function Ft(n,e){let t=ee(rt(),".claude"),r=ee(t,".credentials.json"),o={claudeAiOauth:{accessToken:n,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(tt(r)&&JSON.parse(ot(r,"utf-8"))?.claudeAiOauth?.accessToken===n)return;Me(t,{recursive:!0}),Re(r,JSON.stringify(o,null,2),"utf-8"),a.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(s){a.warn(`Could not write ${r}: ${s.message} \u2014 Claude SDK may fail to authenticate.`)}}function Yt(n){let e=ee(rt(),".claude"),t=ee(e,".credentials.json"),r;try{r=JSON.parse(n)}catch(o){a.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!r?.claudeAiOauth?.accessToken){a.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(tt(t)){let o=JSON.parse(ot(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}Me(e,{recursive:!0}),Re(t,JSON.stringify(r,null,2),"utf-8"),a.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){a.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}import{AgentStrategy as zt,getSkill as Ht}from"@zibby/agent-workflow";import{execSync as Xt}from"node:child_process";import{zodToJsonSchema as Zt}from"zod-to-json-schema";var _e=class extends zt{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return a.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Xt("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return a.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:s=null,skills:i=null,sessionPath:l=null,nodeName:c=null,timeout:p,config:f={},signal:_=null}=t,m=[G("OPENAI_API_KEY"),G("CODEX_API_KEY")];try{let{Codex:h}=await import("@openai/codex-sdk"),S=r;(!S||S==="auto")&&(a.debug(`Model is '${S||"undefined"}', using default: ${K.CODEX}`),S=K.CODEX);let L=Pe[S]||S;Pe[S]&&S!==L&&a.debug(`Mapped model: ${S} \u2192 ${L}`),a.debug(`Invoking Codex SDK with model: ${L}, skills: ${JSON.stringify(i)}`);let y=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;y&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=y);let x=y?` | key: ***${y.slice(-4)}`:" | key: not set";console.log(`
|
|
79
79
|
\u25C6 Model: ${L}${x}
|
|
80
80
|
`);let $=(await import("chalk")).default;console.log(`
|
|
81
81
|
${$.bold("Prompt sent to LLM:")}`),console.log($.dim("\u2500".repeat(60))),console.log($.dim(e)),console.log($.dim("\u2500".repeat(60)));let v=this._resolveSkillsToMcp(i,{sessionPath:l,workspace:o,nodeName:c}),g={};Object.keys(v).length>0&&(g.mcp_servers=v,a.debug(`[Codex] MCP servers: ${Object.keys(v).join(", ")}`));let C=new h({...Object.keys(g).length>0&&{config:g}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),k=s&&typeof s.parse=="function",O={};if(s)try{let A=k?Zt(s,{target:"openAi"}):s;O.outputSchema=A,a.debug("Structured output via SDK outputSchema")}catch(A){a.warn(`[Codex] Schema conversion failed, will extract from text: ${A.message}`)}if(_?.aborted){let A=new Error("Aborted via signal");throw A.name="AbortError",A}try{let{events:A}=await C.runStreamed(e,O),M=0,b="";for await(let P of A){if(_?.aborted){let I=new Error("Aborted via signal");throw I.name="AbortError",I}let U=P.type;if(U==="item.completed"){let I=P.item,B=I?.type;if(B==="mcp_tool_call"){M++;let w=`${I.server}/${I.tool}`;if(Y.stepTool(`Tool: ${w}`),I.arguments){let u=JSON.stringify(I.arguments),T=u.length>100?`${u.substring(0,100)}...`:u;console.log(` Input: ${T}`)}}else if(B==="tool_call"||B==="function_call"||B==="command_execution"){M++;let w=I.name||I.tool||I.command||"unknown";Y.stepTool(`Tool: ${w}`)}else B==="agent_message"&&(b=I.text||"",b.length<500?console.log(b):console.log(`${b.substring(0,200)}... (${b.length} chars)`))}else U==="turn.completed"?a.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):a.debug(`[Codex] Event: ${U} ${JSON.stringify(P).slice(0,300)}`)}if(a.debug(`[Codex] Last agent message (${b.length} chars): ${b.slice(0,500)}`),s){if(!b)throw new Error("Codex agent returned no response");let P=JSON.parse(b),U=k?s.parse(P):P;return a.debug("\u2705 [Codex] Structured output validated"),{raw:b,structured:U}}return b||""}catch(A){let M=A.message||String(A);throw a.error(`\u274C [Codex] SDK call failed: ${M}`),M.includes("exited with code")&&(a.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),a.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),A}}finally{for(let h of m)h.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let o of e){let s=Ht(o);if(!s){a.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof s.resolve!="function")continue;let i=s.resolve(t);if(!i)continue;let l=s.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),i.env&&Object.keys(i.env).length>0&&(c.env=i.env),r[l]=c,a.debug(`[Codex] MCP: ${l} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return r}};import{AgentStrategy as Wt,getSkill as qt}from"@zibby/agent-workflow";import{execSync as Vt,spawn as Qt}from"node:child_process";import{zodToJsonSchema as eo}from"zod-to-json-schema";import{existsSync as st,mkdirSync as nt,readFileSync as it,rmSync as to,writeFileSync as lt}from"node:fs";import{join as W}from"node:path";function oo(n){if(!n)return null;let e=String(n),t=e.match(/```(?:json)?\s*([\s\S]*?)```/i);if(t?.[1])try{return JSON.parse(t[1].trim())}catch{}let r=e.indexOf("{");if(r<0)return null;let o=0,s=!1,i=!1,l=-1;for(let c=r;c<e.length;c++){let p=e[c];if(s){i?i=!1:p==="\\"?i=!0:p==='"'&&(s=!1);continue}if(p==='"'){s=!0;continue}if(p==="{"){o===0&&(l=c),o+=1;continue}if(p==="}"){if(o===0)continue;if(o-=1,o===0&&l>=0){let f=e.slice(l,c+1);try{return JSON.parse(f)}catch{l=-1}}}}return null}function ro(n){let e=String(n||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return oo(e)}}function so(n){try{let e=JSON.parse(n);if(typeof e=="string")return e;if(typeof e?.response=="string")return e.response;if(typeof e?.text=="string")return e.text;if(typeof e?.output=="string")return e.output;if(Array.isArray(e?.candidates)&&e.candidates.length>0){let t=e.candidates[0];if(typeof t?.content=="string")return t.content;if(Array.isArray(t?.content?.parts)){let r=t.content.parts.map(o=>typeof o?.text=="string"?o.text:"").join("");if(r.trim())return r}}}catch{}return n}var Se=class extends Wt{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GEMINI_API_KEY_POOL||process.env.GOOGLE_API_KEY||process.env.GOOGLE_API_KEY_POOL))return a.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return Vt("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return a.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:s=null,skills:i=null,sessionPath:l=null,nodeName:c=null,timeout:p=600*1e3,signal:f=null}=t,_=[G("GEMINI_API_KEY"),G("GOOGLE_API_KEY")];try{let m=r;(!m||m==="auto")&&(m=K.GEMINI);let h=je[m]||m,S=String(process.env.GEMINI_API_KEY||"").trim(),L=String(process.env.GOOGLE_API_KEY||"").trim(),y=this._resolveSkillsToMcp(i,{sessionPath:l,workspace:o,nodeName:c}),x=Object.keys(y).length>0,$=new V(e),v=s&&typeof s.parse=="function",g=null;if(s){let d;try{let D=v?eo(s,{target:"openAi"}):s;d=JSON.stringify(D,null,2)}catch{d="{}"}if(x){$.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AgentStrategy as te,getSkill as oe}from"@zibby/agent-workflow";import{query as ne}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as re}from"zod-to-json-schema";import{writeFileSync as x,mkdirSync as P,existsSync as q,readFileSync as X}from"fs";import{homedir as z}from"os";import{join as h}from"path";import S from"chalk";var g={debug:0,info:1,warn:2,error:3,silent:4},v=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return g.debug;if(process.env.ZIBBY_VERBOSE==="true")return g.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in g?g[e]:g.info}_shouldLog(e){return g[e]>=this._level}_formatMessage(e,o,s={}){let n=new Date().toISOString(),u=`${this._getPrefix(e)} ${o}`;return Object.keys(s).length>0&&(u+=S.dim(` ${JSON.stringify(s)}`)),u}_getPrefix(e){return{debug:S.gray("[DEBUG]"),info:S.cyan("[INFO]"),warn:S.yellow("[WARN]"),error:S.red("\u274C [ERROR]")}[e]||""}debug(e,o){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,o))}info(e,o){this._shouldLog("info")&&console.log(this._formatMessage("info",e,o))}warn(e,o){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,o))}error(e,o){this._shouldLog("error")&&console.error(this._formatMessage("error",e,o))}setLevel(e){e in g&&(this._level=g[e])}getLevel(){return Object.keys(g).find(e=>g[e]===this._level)}},i=new v;import{timeline as I,Timeline as pe,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as ge}from"@zibby/agent-workflow";var $={ASSISTANT:"gpt-5.4-nano-2026-03-17",CLAUDE:"claude-sonnet-4-6",CURSOR:"auto",CODEX:"o4-mini",GEMINI:"gemini-2.5-pro",OPENAI_POSTPROCESSING:"gpt-4o-mini"};var b={auto:"claude-sonnet-4-6","sonnet-4.6":"claude-sonnet-4-6","sonnet-4-6":"claude-sonnet-4-6","opus-4.6":"claude-opus-4-6","opus-4-6":"claude-opus-4-6","sonnet-4.5":"claude-sonnet-4-5-20250929","sonnet-4-5":"claude-sonnet-4-5-20250929","opus-4.5":"claude-opus-4-20250514","opus-4-5":"claude-opus-4-20250514","claude-sonnet-4-6":"claude-sonnet-4-6","claude-opus-4-6":"claude-opus-4-6","claude-sonnet-4-5-20250929":"claude-sonnet-4-5-20250929","claude-opus-4-20250514":"claude-opus-4-20250514"};var fe={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};function D(c){let e=`${c}_POOL`,o=process.env[e];if(!o||typeof o!="string")return{picked:null,count:0,dispose:()=>{}};let s=o.split(/[,\n]+/).map(u=>u.trim()).filter(Boolean);if(s.length===0)return{picked:null,count:0,dispose:()=>{}};let n=s[Math.floor(Math.random()*s.length)],t=process.env[c];return process.env[c]=n,i.debug(`[auth-pool] ${c}: picked 1 of ${s.length} from pool (***${n.slice(-4)})`),{picked:n,count:s.length,dispose(){t===void 0?delete process.env[c]:process.env[c]=t}}}var W=class extends te{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let o=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,s=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,n=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,t=o||s||n;return t||i.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),t}async invoke(e,o={}){let{model:s,workspace:n=process.cwd(),schema:t=null,images:u=[],skills:d=null,sessionPath:C=null,nodeName:y=null,timeout:R,config:M={},signal:O=null}=o,p=s;(!p||p==="auto")&&(i.debug(`Model is '${p||"undefined"}', using default: ${$.CLAUDE}`),p=$.CLAUDE);let A=b[p]||p;b[p]&&p!==A&&i.debug(`Mapped model: ${p} \u2192 ${A}`);let Q=[D("ANTHROPIC_API_KEY"),D("CLAUDE_CODE_OAUTH_TOKEN"),D("ANTHROPIC_AUTH_TOKEN")];try{i.debug(`Invoking Claude Agent SDK with model: ${A}, skills: ${JSON.stringify(d)}`);let _=process.env.CLAUDE_CODE_OAUTH_TOKEN,U=process.env.ANTHROPIC_API_KEY,K=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?le(process.env.CLAUDE_CODE_CREDENTIALS_JSON):_&&ie(_,process.env.__ZIBBY_CLAUDE_PLAN);let k=process.env.__ZIBBY_CLAUDE_PLAN,J=k?k.charAt(0).toUpperCase()+k.slice(1):null,E;_?E=J?`Claude ${J} plan \xB7 ***${_.slice(-4)}`:`Subscription \xB7 ***${_.slice(-4)}`:U?E=`API key \xB7 ***${U.slice(-4)}`:K?E=`Bearer \xB7 ***${K.slice(-4)}`:E="NONE \u2014 request will fail";let m=(await import("chalk")).default;console.log(""),console.log(` ${m.cyan("\u25C6")} ${m.bold(A)}`),console.log(` ${m.dim("Auth: ")}${E}`),console.log(` ${m.dim("Workdir: ")}${n}`),console.log(""),console.log(m.bold("Prompt sent to LLM:")),console.log(m.dim("\u2500".repeat(60))),console.log(m.dim(e)),console.log(m.dim("\u2500".repeat(60)));let{allowedTools:H,mcpServers:F}=this._resolveSkills(d,{sessionPath:C,workspace:n,nodeName:y});try{let f={cwd:n,allowedTools:H,permissionMode:"bypassPermissions",model:A,...Object.keys(F).length>0&&{mcpServers:F}};if(t){let w=typeof t.parse=="function"?re(t,{target:"openApi3"}):t;f.outputFormat={type:"json_schema",schema:w},i.debug("Structured output enforced via SDK outputFormat")}i.debug(`Agent SDK options: ${JSON.stringify({cwd:f.cwd,toolCount:H.length,permissionMode:f.permissionMode,model:f.model,hasOutputFormat:!!f.outputFormat})}`);let N="",B=0,G=[];i.debug("Starting Claude Agent SDK query stream");let j;try{j=ne({prompt:e,options:f})}catch(r){throw i.error(`Failed to initialize Claude Agent SDK: ${r.message}`),r}let Y=null,L=0,V=3;if(O?.aborted){let r=new Error("Aborted via signal");throw r.name="AbortError",r}try{for await(let r of j){if(O?.aborted){let a=new Error("Aborted via signal");throw a.name="AbortError",a}if(G.push(r),r.type==="error"||r.error){let a=r.error?.message||r.error||r.message||"Unknown API error";throw new Error(typeof a=="string"?a:JSON.stringify(a))}let w=JSON.stringify(r.message?.content||r.text||"").slice(0,200);if(w===Y){if(L++,L>=V){let a=(r.message?.content?.[0]?.text||r.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${L}x repeated): ${a}`)}}else Y=w,L=1;if(r.type==="assistant"||r.constructor?.name==="AssistantMessage"){let a=r.message?.content||r.content||[];for(let l of a)if(l.type==="thinking"&&l.thinking)console.log(`${l.thinking.substring(0,200)}${l.thinking.length>200?"...":""}`);else if(l.type==="text"&&l.text)N+=l.text,l.text.length<500?console.log(`${l.text}`):console.log(`${l.text.substring(0,200)}... (${l.text.length} chars)`);else if(l.type==="tool_use"){B++,l.name.includes("memory")?I.stepMemory(`Tool: ${l.name}`):I.stepTool(`Tool: ${l.name}`);let ee=JSON.stringify(l.input).substring(0,100);console.log(` Input: ${ee}${JSON.stringify(l.input).length>100?"...":""}`)}}else if(!(r.type==="user"&&r.tool_use_result)){if(r.type==="result"||r.constructor?.name==="ResultMessage"){let a=r.result||r.text||r.content||N;try{se({message:r,sessionPath:C,nodeName:y,model:p,toolCallCount:B})}catch(l){i.debug(`usage.json write failed: ${l.message}`)}if(t){if(r.structured_output){i.debug("Using SDK native structured_output");let Z=typeof t.parse=="function"?t.parse(r.structured_output):r.structured_output;return{raw:a,structured:Z}}if(a){let l=this._extractJson(a,t);if(l)return{raw:a,structured:l}}i.warn(`Could not extract structured output \u2014 returning raw text (${(a||"").length} chars)`)}return a||""}}}if(i.warn(`Agent SDK ended without result. Collected ${G.length} messages`),N.length>0)return i.debug("Returning accumulated text from messages"),N;throw new Error("Claude Agent SDK query ended without result")}catch(r){throw i.error(`Error during query stream: ${r.message}`),r}}catch(f){throw i.error("Claude Agent SDK call failed",{error:f.message}),f}}finally{for(let _ of Q)_.dispose()}}_resolveSkills(e,o){if(e===null)return i.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return i.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let s=[],n={};for(let t of e){let u=oe(t);if(!u){i.warn(`Unknown skill "${t}" \u2014 skipping`);continue}if(u.allowedTools&&s.push(...u.allowedTools),typeof u.resolve=="function"){let d=u.resolve(o);d&&(n[u.serverName]=d,i.debug(`MCP: ${u.serverName} \u2192 ${d.command} ${d.args[0]}`))}}return{allowedTools:s,mcpServers:n}}_extractJson(e,o){let s=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,t=e.indexOf("===JSON_END===");return e.substring(n,t).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),t=e.lastIndexOf("}");if(n!==-1&&t>n)return e.substring(n,t+1)}];for(let n of s)try{let t=n();if(!t)continue;let u=JSON.parse(t);if(typeof u!="object"||u===null)continue;return typeof o.parse=="function"?o.parse(u):u}catch{}return null}};function se({message:c,sessionPath:e,nodeName:o,model:s,toolCallCount:n}){if(!e||!o)return;let t=c?.usage||c?.message?.usage||{},u=T(t.input_tokens,t.inputTokens),d=T(t.output_tokens,t.outputTokens),C=T(t.cache_read_input_tokens,t.cacheReadInputTokens),y=T(t.cache_creation_input_tokens,t.cacheCreationInputTokens),R=T(c?.duration_ms,c?.durationMs),M={model:s||null,input_tokens:u,output_tokens:d,cache_read_tokens:C,cache_creation_tokens:y,tool_call_count:typeof n=="number"?n:null,duration_ms:R,captured_at:new Date().toISOString()},O=h(e,o);try{P(O,{recursive:!0})}catch{}x(h(O,"usage.json"),JSON.stringify(M,null,2),"utf-8")}function T(...c){for(let e of c){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function ie(c,e){let o=h(z(),".claude"),s=h(o,".credentials.json"),n={claudeAiOauth:{accessToken:c,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(q(s)&&JSON.parse(X(s,"utf-8"))?.claudeAiOauth?.accessToken===c)return;P(o,{recursive:!0}),x(s,JSON.stringify(n,null,2),"utf-8"),i.debug(`Wrote Claude Code OAuth credentials to ${s}`)}catch(t){i.warn(`Could not write ${s}: ${t.message} \u2014 Claude SDK may fail to authenticate.`)}}function le(c){let e=h(z(),".claude"),o=h(e,".credentials.json"),s;try{s=JSON.parse(c)}catch(n){i.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${n.message}`);return}if(!s?.claudeAiOauth?.accessToken){i.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(q(o)){let n=JSON.parse(X(o,"utf-8"));if(n?.claudeAiOauth?.accessToken===s.claudeAiOauth.accessToken&&n?.claudeAiOauth?.expiresAt===s.claudeAiOauth.expiresAt)return}P(e,{recursive:!0}),x(o,JSON.stringify(s,null,2),"utf-8"),i.debug(`Wrote full Claude Code credentials blob to ${o}`)}catch(n){i.warn(`Could not write ${o}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}export{W as ClaudeAgentStrategy};
|
|
1
|
+
import{AgentStrategy as te,getSkill as oe}from"@zibby/agent-workflow";import{query as ne}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as re}from"zod-to-json-schema";import{writeFileSync as P,mkdirSync as x,existsSync as q,readFileSync as X}from"fs";import{homedir as z}from"os";import{join as O}from"path";import S from"chalk";var g={debug:0,info:1,warn:2,error:3,silent:4},k=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return g.debug;if(process.env.ZIBBY_VERBOSE==="true")return g.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in g?g[e]:g.info}_shouldLog(e){return g[e]>=this._level}_formatMessage(e,o,s={}){let n=new Date().toISOString(),u=`${this._getPrefix(e)} ${o}`;return Object.keys(s).length>0&&(u+=S.dim(` ${JSON.stringify(s)}`)),u}_getPrefix(e){return{debug:S.gray("[DEBUG]"),info:S.cyan("[INFO]"),warn:S.yellow("[WARN]"),error:S.red("\u274C [ERROR]")}[e]||""}debug(e,o){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,o))}info(e,o){this._shouldLog("info")&&console.log(this._formatMessage("info",e,o))}warn(e,o){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,o))}error(e,o){this._shouldLog("error")&&console.error(this._formatMessage("error",e,o))}setLevel(e){e in g&&(this._level=g[e])}getLevel(){return Object.keys(g).find(e=>g[e]===this._level)}},i=new k;import{timeline as I,Timeline as pe,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as ge}from"@zibby/agent-workflow";var $={ASSISTANT:"gpt-5.4-nano-2026-03-17",CLAUDE:"claude-sonnet-4-6",CURSOR:"auto",CODEX:"o4-mini",GEMINI:"gemini-2.5-pro",OPENAI_POSTPROCESSING:"gpt-4o-mini"};var b={auto:"claude-sonnet-4-6","sonnet-4.6":"claude-sonnet-4-6","sonnet-4-6":"claude-sonnet-4-6","opus-4.6":"claude-opus-4-6","opus-4-6":"claude-opus-4-6","sonnet-4.5":"claude-sonnet-4-5-20250929","sonnet-4-5":"claude-sonnet-4-5-20250929","opus-4.5":"claude-opus-4-20250514","opus-4-5":"claude-opus-4-20250514","claude-sonnet-4-6":"claude-sonnet-4-6","claude-opus-4-6":"claude-opus-4-6","claude-sonnet-4-5-20250929":"claude-sonnet-4-5-20250929","claude-opus-4-20250514":"claude-opus-4-20250514"};var fe={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};function D(c){let e=`${c}_POOL`,o=process.env[e];if(!o||typeof o!="string")return{picked:null,count:0,dispose:()=>{}};let s=o.split(/[,\n]+/).map(u=>u.trim()).filter(Boolean);if(s.length===0)return{picked:null,count:0,dispose:()=>{}};let n=s[Math.floor(Math.random()*s.length)],t=process.env[c];return process.env[c]=n,i.debug(`[auth-pool] ${c}: picked 1 of ${s.length} from pool (***${n.slice(-4)})`),{picked:n,count:s.length,dispose(){t===void 0?delete process.env[c]:process.env[c]=t}}}var W=class extends te{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let o=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,s=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,n=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,t=o||s||n;return t||i.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),t}async invoke(e,o={}){let{model:s,workspace:n=process.cwd(),schema:t=null,images:u=[],skills:d=null,sessionPath:C=null,nodeName:y=null,timeout:R,config:M={},signal:h=null}=o,p=s;(!p||p==="auto")&&(i.debug(`Model is '${p||"undefined"}', using default: ${$.CLAUDE}`),p=$.CLAUDE);let A=b[p]||p;b[p]&&p!==A&&i.debug(`Mapped model: ${p} \u2192 ${A}`);let Q=[D("ANTHROPIC_API_KEY"),D("CLAUDE_CODE_OAUTH_TOKEN"),D("ANTHROPIC_AUTH_TOKEN")];try{i.debug(`Invoking Claude Agent SDK with model: ${A}, skills: ${JSON.stringify(d)}`);let _=process.env.CLAUDE_CODE_OAUTH_TOKEN,U=process.env.ANTHROPIC_API_KEY,K=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?le(process.env.CLAUDE_CODE_CREDENTIALS_JSON):_&&ie(_,process.env.__ZIBBY_CLAUDE_PLAN);let v=process.env.__ZIBBY_CLAUDE_PLAN,J=v?v.charAt(0).toUpperCase()+v.slice(1):null,E;_?E=J?`Claude ${J} plan \xB7 ***${_.slice(-4)}`:`Subscription \xB7 ***${_.slice(-4)}`:U?E=`API key \xB7 ***${U.slice(-4)}`:K?E=`Bearer \xB7 ***${K.slice(-4)}`:E="NONE \u2014 request will fail";let m=(await import("chalk")).default;console.log(""),console.log(` ${m.cyan("\u25C6")} ${m.bold(A)}`),console.log(` ${m.dim("Auth: ")}${E}`),console.log(` ${m.dim("Workdir: ")}${n}`),console.log(""),console.log(m.bold("Prompt sent to LLM:")),console.log(m.dim("\u2500".repeat(60))),console.log(m.dim(e)),console.log(m.dim("\u2500".repeat(60)));let{allowedTools:H,mcpServers:F}=this._resolveSkills(d,{sessionPath:C,workspace:n,nodeName:y});try{let f={cwd:n,allowedTools:H,permissionMode:process.env.ANTHROPIC_API_KEY?"bypassPermissions":"default",model:A,...Object.keys(F).length>0&&{mcpServers:F}};if(t){let w=typeof t.parse=="function"?re(t,{target:"openApi3"}):t;f.outputFormat={type:"json_schema",schema:w},i.debug("Structured output enforced via SDK outputFormat")}i.debug(`Agent SDK options: ${JSON.stringify({cwd:f.cwd,toolCount:H.length,permissionMode:f.permissionMode,model:f.model,hasOutputFormat:!!f.outputFormat})}`);let N="",B=0,G=[];i.debug("Starting Claude Agent SDK query stream");let j;try{j=ne({prompt:e,options:f})}catch(r){throw i.error(`Failed to initialize Claude Agent SDK: ${r.message}`),r}let Y=null,L=0,V=3;if(h?.aborted){let r=new Error("Aborted via signal");throw r.name="AbortError",r}try{for await(let r of j){if(h?.aborted){let a=new Error("Aborted via signal");throw a.name="AbortError",a}if(G.push(r),r.type==="error"||r.error){let a=r.error?.message||r.error||r.message||"Unknown API error";throw new Error(typeof a=="string"?a:JSON.stringify(a))}let w=JSON.stringify(r.message?.content||r.text||"").slice(0,200);if(w===Y){if(L++,L>=V){let a=(r.message?.content?.[0]?.text||r.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${L}x repeated): ${a}`)}}else Y=w,L=1;if(r.type==="assistant"||r.constructor?.name==="AssistantMessage"){let a=r.message?.content||r.content||[];for(let l of a)if(l.type==="thinking"&&l.thinking)console.log(`${l.thinking.substring(0,200)}${l.thinking.length>200?"...":""}`);else if(l.type==="text"&&l.text)N+=l.text,l.text.length<500?console.log(`${l.text}`):console.log(`${l.text.substring(0,200)}... (${l.text.length} chars)`);else if(l.type==="tool_use"){B++,l.name.includes("memory")?I.stepMemory(`Tool: ${l.name}`):I.stepTool(`Tool: ${l.name}`);let ee=JSON.stringify(l.input).substring(0,100);console.log(` Input: ${ee}${JSON.stringify(l.input).length>100?"...":""}`)}}else if(!(r.type==="user"&&r.tool_use_result)){if(r.type==="result"||r.constructor?.name==="ResultMessage"){let a=r.result||r.text||r.content||N;try{se({message:r,sessionPath:C,nodeName:y,model:p,toolCallCount:B})}catch(l){i.debug(`usage.json write failed: ${l.message}`)}if(t){if(r.structured_output){i.debug("Using SDK native structured_output");let Z=typeof t.parse=="function"?t.parse(r.structured_output):r.structured_output;return{raw:a,structured:Z}}if(a){let l=this._extractJson(a,t);if(l)return{raw:a,structured:l}}i.warn(`Could not extract structured output \u2014 returning raw text (${(a||"").length} chars)`)}return a||""}}}if(i.warn(`Agent SDK ended without result. Collected ${G.length} messages`),N.length>0)return i.debug("Returning accumulated text from messages"),N;throw new Error("Claude Agent SDK query ended without result")}catch(r){throw i.error(`Error during query stream: ${r.message}`),r}}catch(f){throw i.error("Claude Agent SDK call failed",{error:f.message}),f}}finally{for(let _ of Q)_.dispose()}}_resolveSkills(e,o){if(e===null)return i.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return i.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let s=[],n={};for(let t of e){let u=oe(t);if(!u){i.warn(`Unknown skill "${t}" \u2014 skipping`);continue}if(u.allowedTools&&s.push(...u.allowedTools),typeof u.resolve=="function"){let d=u.resolve(o);d&&(n[u.serverName]=d,i.debug(`MCP: ${u.serverName} \u2192 ${d.command} ${d.args[0]}`))}}return{allowedTools:s,mcpServers:n}}_extractJson(e,o){let s=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,t=e.indexOf("===JSON_END===");return e.substring(n,t).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),t=e.lastIndexOf("}");if(n!==-1&&t>n)return e.substring(n,t+1)}];for(let n of s)try{let t=n();if(!t)continue;let u=JSON.parse(t);if(typeof u!="object"||u===null)continue;return typeof o.parse=="function"?o.parse(u):u}catch{}return null}};function se({message:c,sessionPath:e,nodeName:o,model:s,toolCallCount:n}){if(!e||!o)return;let t=c?.usage||c?.message?.usage||{},u=T(t.input_tokens,t.inputTokens),d=T(t.output_tokens,t.outputTokens),C=T(t.cache_read_input_tokens,t.cacheReadInputTokens),y=T(t.cache_creation_input_tokens,t.cacheCreationInputTokens),R=T(c?.duration_ms,c?.durationMs),M={model:s||null,input_tokens:u,output_tokens:d,cache_read_tokens:C,cache_creation_tokens:y,tool_call_count:typeof n=="number"?n:null,duration_ms:R,captured_at:new Date().toISOString()},h=O(e,o);try{x(h,{recursive:!0})}catch{}P(O(h,"usage.json"),JSON.stringify(M,null,2),"utf-8")}function T(...c){for(let e of c){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function ie(c,e){let o=O(z(),".claude"),s=O(o,".credentials.json"),n={claudeAiOauth:{accessToken:c,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(q(s)&&JSON.parse(X(s,"utf-8"))?.claudeAiOauth?.accessToken===c)return;x(o,{recursive:!0}),P(s,JSON.stringify(n,null,2),"utf-8"),i.debug(`Wrote Claude Code OAuth credentials to ${s}`)}catch(t){i.warn(`Could not write ${s}: ${t.message} \u2014 Claude SDK may fail to authenticate.`)}}function le(c){let e=O(z(),".claude"),o=O(e,".credentials.json"),s;try{s=JSON.parse(c)}catch(n){i.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${n.message}`);return}if(!s?.claudeAiOauth?.accessToken){i.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(q(o)){let n=JSON.parse(X(o,"utf-8"));if(n?.claudeAiOauth?.accessToken===s.claudeAiOauth.accessToken&&n?.claudeAiOauth?.expiresAt===s.claudeAiOauth.expiresAt)return}x(e,{recursive:!0}),P(o,JSON.stringify(s,null,2),"utf-8"),i.debug(`Wrote full Claude Code credentials blob to ${o}`)}catch(n){i.warn(`Could not write ${o}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}export{W as ClaudeAgentStrategy};
|
package/dist/strategies/index.js
CHANGED
|
@@ -75,7 +75,7 @@ Stderr: ${g.slice(-1e3)}`:""}${m.trim()?`
|
|
|
75
75
|
Stdout (last 500 chars): ${m.slice(-500)}`:""}`));return}let d=w.getResult(),D=d?JSON.stringify(d,null,2):w.getRawText()||m||"";p({stdout:m||g||"",parsedText:D})}),E.on("error",u=>{if(C(),clearTimeout(K),clearInterval(v),b&&clearInterval(b),A&&clearTimeout(A),c&&!c.aborted)try{c.removeEventListener("abort",L)}catch{}f(new Error(`Cursor Agent spawn error: ${u.message}
|
|
76
76
|
Binary: ${e}
|
|
77
77
|
This usually means the binary is not in PATH. Try:
|
|
78
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Ut,getSkill as Kt}from"@zibby/agent-workflow";import{query as Bt}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Jt}from"zod-to-json-schema";import{writeFileSync as Ne,mkdirSync as Re,existsSync as et,readFileSync as tt}from"fs";import{homedir as ot}from"os";import{join as ee}from"path";var he=class extends Ut{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,r=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,o=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,n=t||r||o;return n||a.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),n}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,images:i=[],skills:l=null,sessionPath:c=null,nodeName:p=null,timeout:f,config:_={},signal:m=null}=t,g=r;(!g||g==="auto")&&(a.debug(`Model is '${g||"undefined"}', using default: ${B.CLAUDE}`),g=B.CLAUDE);let S=Ce[g]||g;Ce[g]&&g!==S&&a.debug(`Mapped model: ${g} \u2192 ${S}`);let N=[G("ANTHROPIC_API_KEY"),G("CLAUDE_CODE_OAUTH_TOKEN"),G("ANTHROPIC_AUTH_TOKEN")];try{a.debug(`Invoking Claude Agent SDK with model: ${S}, skills: ${JSON.stringify(l)}`);let h=process.env.CLAUDE_CODE_OAUTH_TOKEN,x=process.env.ANTHROPIC_API_KEY,T=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?Ft(process.env.CLAUDE_CODE_CREDENTIALS_JSON):h&&jt(h,process.env.__ZIBBY_CLAUDE_PLAN);let $=process.env.__ZIBBY_CLAUDE_PLAN,y=$?$.charAt(0).toUpperCase()+$.slice(1):null,M;h?M=y?`Claude ${y} plan \xB7 ***${h.slice(-4)}`:`Subscription \xB7 ***${h.slice(-4)}`:x?M=`API key \xB7 ***${x.slice(-4)}`:T?M=`Bearer \xB7 ***${T.slice(-4)}`:M="NONE \u2014 request will fail";let C=(await import("chalk")).default;console.log(""),console.log(` ${C.cyan("\u25C6")} ${C.bold(S)}`),console.log(` ${C.dim("Auth: ")}${M}`),console.log(` ${C.dim("Workdir: ")}${o}`),console.log(""),console.log(C.bold("Prompt sent to LLM:")),console.log(C.dim("\u2500".repeat(60))),console.log(C.dim(e)),console.log(C.dim("\u2500".repeat(60)));let{allowedTools:k,mcpServers:E}=this._resolveSkills(l,{sessionPath:c,workspace:o,nodeName:p});try{let A={cwd:o,allowedTools:k,permissionMode:"bypassPermissions",model:S,...Object.keys(E).length>0&&{mcpServers:E}};if(n){let I=typeof n.parse=="function"?Jt(n,{target:"openApi3"}):n;A.outputFormat={type:"json_schema",schema:I},a.debug("Structured output enforced via SDK outputFormat")}a.debug(`Agent SDK options: ${JSON.stringify({cwd:A.cwd,toolCount:k.length,permissionMode:A.permissionMode,model:A.model,hasOutputFormat:!!A.outputFormat})}`);let L="",b=0,P=[];a.debug("Starting Claude Agent SDK query stream");let U;try{U=Bt({prompt:e,options:A})}catch(u){throw a.error(`Failed to initialize Claude Agent SDK: ${u.message}`),u}let v=null,K=0,w=3;if(m?.aborted){let u=new Error("Aborted via signal");throw u.name="AbortError",u}try{for await(let u of U){if(m?.aborted){let O=new Error("Aborted via signal");throw O.name="AbortError",O}if(P.push(u),u.type==="error"||u.error){let O=u.error?.message||u.error||u.message||"Unknown API error";throw new Error(typeof O=="string"?O:JSON.stringify(O))}let I=JSON.stringify(u.message?.content||u.text||"").slice(0,200);if(I===v){if(K++,K>=w){let O=(u.message?.content?.[0]?.text||u.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${K}x repeated): ${O}`)}}else v=I,K=1;if(u.type==="assistant"||u.constructor?.name==="AssistantMessage"){let O=u.message?.content||u.content||[];for(let d of O)if(d.type==="thinking"&&d.thinking)console.log(`${d.thinking.substring(0,200)}${d.thinking.length>200?"...":""}`);else if(d.type==="text"&&d.text)L+=d.text,d.text.length<500?console.log(`${d.text}`):console.log(`${d.text.substring(0,200)}... (${d.text.length} chars)`);else if(d.type==="tool_use"){b++,d.name.includes("memory")?Y.stepMemory(`Tool: ${d.name}`):Y.stepTool(`Tool: ${d.name}`);let R=JSON.stringify(d.input).substring(0,100);console.log(` Input: ${R}${JSON.stringify(d.input).length>100?"...":""}`)}}else if(!(u.type==="user"&&u.tool_use_result)){if(u.type==="result"||u.constructor?.name==="ResultMessage"){let O=u.result||u.text||u.content||L;try{Gt({message:u,sessionPath:c,nodeName:p,model:g,toolCallCount:b})}catch(d){a.debug(`usage.json write failed: ${d.message}`)}if(n){if(u.structured_output){a.debug("Using SDK native structured_output");let D=typeof n.parse=="function"?n.parse(u.structured_output):u.structured_output;return{raw:O,structured:D}}if(O){let d=this._extractJson(O,n);if(d)return{raw:O,structured:d}}a.warn(`Could not extract structured output \u2014 returning raw text (${(O||"").length} chars)`)}return O||""}}}if(a.warn(`Agent SDK ended without result. Collected ${P.length} messages`),L.length>0)return a.debug("Returning accumulated text from messages"),L;throw new Error("Claude Agent SDK query ended without result")}catch(u){throw a.error(`Error during query stream: ${u.message}`),u}}catch(A){throw a.error("Claude Agent SDK call failed",{error:A.message}),A}}finally{for(let h of N)h.dispose()}}_resolveSkills(e,t){if(e===null)return a.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return a.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],o={};for(let n of e){let i=Kt(n);if(!i){a.warn(`Unknown skill "${n}" \u2014 skipping`);continue}if(i.allowedTools&&r.push(...i.allowedTools),typeof i.resolve=="function"){let l=i.resolve(t);l&&(o[i.serverName]=l,a.debug(`MCP: ${i.serverName} \u2192 ${l.command} ${l.args[0]}`))}}return{allowedTools:r,mcpServers:o}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,n=e.indexOf("===JSON_END===");return e.substring(o,n).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let o=e.indexOf("{"),n=e.lastIndexOf("}");if(o!==-1&&n>o)return e.substring(o,n+1)}];for(let o of r)try{let n=o();if(!n)continue;let i=JSON.parse(n);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function Gt({message:s,sessionPath:e,nodeName:t,model:r,toolCallCount:o}){if(!e||!t)return;let n=s?.usage||s?.message?.usage||{},i=ce(n.input_tokens,n.inputTokens),l=ce(n.output_tokens,n.outputTokens),c=ce(n.cache_read_input_tokens,n.cacheReadInputTokens),p=ce(n.cache_creation_input_tokens,n.cacheCreationInputTokens),f=ce(s?.duration_ms,s?.durationMs),_={model:r||null,input_tokens:i,output_tokens:l,cache_read_tokens:c,cache_creation_tokens:p,tool_call_count:typeof o=="number"?o:null,duration_ms:f,captured_at:new Date().toISOString()},m=ee(e,t);try{Re(m,{recursive:!0})}catch{}Ne(ee(m,"usage.json"),JSON.stringify(_,null,2),"utf-8")}function ce(...s){for(let e of s){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function jt(s,e){let t=ee(ot(),".claude"),r=ee(t,".credentials.json"),o={claudeAiOauth:{accessToken:s,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(et(r)&&JSON.parse(tt(r,"utf-8"))?.claudeAiOauth?.accessToken===s)return;Re(t,{recursive:!0}),Ne(r,JSON.stringify(o,null,2),"utf-8"),a.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(n){a.warn(`Could not write ${r}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}function Ft(s){let e=ee(ot(),".claude"),t=ee(e,".credentials.json"),r;try{r=JSON.parse(s)}catch(o){a.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!r?.claudeAiOauth?.accessToken){a.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(et(t)){let o=JSON.parse(tt(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}Re(e,{recursive:!0}),Ne(t,JSON.stringify(r,null,2),"utf-8"),a.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){a.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}import{AgentStrategy as Yt,getSkill as zt}from"@zibby/agent-workflow";import{execSync as Ht}from"node:child_process";import{zodToJsonSchema as Xt}from"zod-to-json-schema";var ye=class extends Yt{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return a.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Ht("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return a.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,skills:i=null,sessionPath:l=null,nodeName:c=null,timeout:p,config:f={},signal:_=null}=t,m=[G("OPENAI_API_KEY"),G("CODEX_API_KEY")];try{let{Codex:g}=await import("@openai/codex-sdk"),S=r;(!S||S==="auto")&&(a.debug(`Model is '${S||"undefined"}', using default: ${B.CODEX}`),S=B.CODEX);let N=ke[S]||S;ke[S]&&S!==N&&a.debug(`Mapped model: ${S} \u2192 ${N}`),a.debug(`Invoking Codex SDK with model: ${N}, skills: ${JSON.stringify(i)}`);let h=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;h&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=h);let x=h?` | key: ***${h.slice(-4)}`:" | key: not set";console.log(`
|
|
78
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Ut,getSkill as Kt}from"@zibby/agent-workflow";import{query as Bt}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Jt}from"zod-to-json-schema";import{writeFileSync as Ne,mkdirSync as Re,existsSync as et,readFileSync as tt}from"fs";import{homedir as ot}from"os";import{join as ee}from"path";var he=class extends Ut{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY||!!process.env.ANTHROPIC_API_KEY_POOL,r=!!process.env.CLAUDE_CODE_OAUTH_TOKEN||!!process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL,o=!!process.env.ANTHROPIC_AUTH_TOKEN||!!process.env.ANTHROPIC_AUTH_TOKEN_POOL,n=t||r||o;return n||a.debug("ClaudeAgentStrategy: no credentials. Set one of ANTHROPIC_API_KEY / CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN (or a *_POOL variant for multi-token rotation)."),n}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,images:i=[],skills:l=null,sessionPath:c=null,nodeName:p=null,timeout:f,config:_={},signal:m=null}=t,g=r;(!g||g==="auto")&&(a.debug(`Model is '${g||"undefined"}', using default: ${B.CLAUDE}`),g=B.CLAUDE);let S=Ce[g]||g;Ce[g]&&g!==S&&a.debug(`Mapped model: ${g} \u2192 ${S}`);let N=[G("ANTHROPIC_API_KEY"),G("CLAUDE_CODE_OAUTH_TOKEN"),G("ANTHROPIC_AUTH_TOKEN")];try{a.debug(`Invoking Claude Agent SDK with model: ${S}, skills: ${JSON.stringify(l)}`);let h=process.env.CLAUDE_CODE_OAUTH_TOKEN,x=process.env.ANTHROPIC_API_KEY,T=process.env.ANTHROPIC_AUTH_TOKEN;process.env.CLAUDE_CODE_CREDENTIALS_JSON?Ft(process.env.CLAUDE_CODE_CREDENTIALS_JSON):h&&jt(h,process.env.__ZIBBY_CLAUDE_PLAN);let $=process.env.__ZIBBY_CLAUDE_PLAN,y=$?$.charAt(0).toUpperCase()+$.slice(1):null,M;h?M=y?`Claude ${y} plan \xB7 ***${h.slice(-4)}`:`Subscription \xB7 ***${h.slice(-4)}`:x?M=`API key \xB7 ***${x.slice(-4)}`:T?M=`Bearer \xB7 ***${T.slice(-4)}`:M="NONE \u2014 request will fail";let C=(await import("chalk")).default;console.log(""),console.log(` ${C.cyan("\u25C6")} ${C.bold(S)}`),console.log(` ${C.dim("Auth: ")}${M}`),console.log(` ${C.dim("Workdir: ")}${o}`),console.log(""),console.log(C.bold("Prompt sent to LLM:")),console.log(C.dim("\u2500".repeat(60))),console.log(C.dim(e)),console.log(C.dim("\u2500".repeat(60)));let{allowedTools:k,mcpServers:E}=this._resolveSkills(l,{sessionPath:c,workspace:o,nodeName:p});try{let A={cwd:o,allowedTools:k,permissionMode:process.env.ANTHROPIC_API_KEY?"bypassPermissions":"default",model:S,...Object.keys(E).length>0&&{mcpServers:E}};if(n){let I=typeof n.parse=="function"?Jt(n,{target:"openApi3"}):n;A.outputFormat={type:"json_schema",schema:I},a.debug("Structured output enforced via SDK outputFormat")}a.debug(`Agent SDK options: ${JSON.stringify({cwd:A.cwd,toolCount:k.length,permissionMode:A.permissionMode,model:A.model,hasOutputFormat:!!A.outputFormat})}`);let L="",b=0,P=[];a.debug("Starting Claude Agent SDK query stream");let U;try{U=Bt({prompt:e,options:A})}catch(u){throw a.error(`Failed to initialize Claude Agent SDK: ${u.message}`),u}let v=null,K=0,w=3;if(m?.aborted){let u=new Error("Aborted via signal");throw u.name="AbortError",u}try{for await(let u of U){if(m?.aborted){let O=new Error("Aborted via signal");throw O.name="AbortError",O}if(P.push(u),u.type==="error"||u.error){let O=u.error?.message||u.error||u.message||"Unknown API error";throw new Error(typeof O=="string"?O:JSON.stringify(O))}let I=JSON.stringify(u.message?.content||u.text||"").slice(0,200);if(I===v){if(K++,K>=w){let O=(u.message?.content?.[0]?.text||u.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${K}x repeated): ${O}`)}}else v=I,K=1;if(u.type==="assistant"||u.constructor?.name==="AssistantMessage"){let O=u.message?.content||u.content||[];for(let d of O)if(d.type==="thinking"&&d.thinking)console.log(`${d.thinking.substring(0,200)}${d.thinking.length>200?"...":""}`);else if(d.type==="text"&&d.text)L+=d.text,d.text.length<500?console.log(`${d.text}`):console.log(`${d.text.substring(0,200)}... (${d.text.length} chars)`);else if(d.type==="tool_use"){b++,d.name.includes("memory")?Y.stepMemory(`Tool: ${d.name}`):Y.stepTool(`Tool: ${d.name}`);let R=JSON.stringify(d.input).substring(0,100);console.log(` Input: ${R}${JSON.stringify(d.input).length>100?"...":""}`)}}else if(!(u.type==="user"&&u.tool_use_result)){if(u.type==="result"||u.constructor?.name==="ResultMessage"){let O=u.result||u.text||u.content||L;try{Gt({message:u,sessionPath:c,nodeName:p,model:g,toolCallCount:b})}catch(d){a.debug(`usage.json write failed: ${d.message}`)}if(n){if(u.structured_output){a.debug("Using SDK native structured_output");let D=typeof n.parse=="function"?n.parse(u.structured_output):u.structured_output;return{raw:O,structured:D}}if(O){let d=this._extractJson(O,n);if(d)return{raw:O,structured:d}}a.warn(`Could not extract structured output \u2014 returning raw text (${(O||"").length} chars)`)}return O||""}}}if(a.warn(`Agent SDK ended without result. Collected ${P.length} messages`),L.length>0)return a.debug("Returning accumulated text from messages"),L;throw new Error("Claude Agent SDK query ended without result")}catch(u){throw a.error(`Error during query stream: ${u.message}`),u}}catch(A){throw a.error("Claude Agent SDK call failed",{error:A.message}),A}}finally{for(let h of N)h.dispose()}}_resolveSkills(e,t){if(e===null)return a.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return a.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],o={};for(let n of e){let i=Kt(n);if(!i){a.warn(`Unknown skill "${n}" \u2014 skipping`);continue}if(i.allowedTools&&r.push(...i.allowedTools),typeof i.resolve=="function"){let l=i.resolve(t);l&&(o[i.serverName]=l,a.debug(`MCP: ${i.serverName} \u2192 ${l.command} ${l.args[0]}`))}}return{allowedTools:r,mcpServers:o}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,n=e.indexOf("===JSON_END===");return e.substring(o,n).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let o=e.indexOf("{"),n=e.lastIndexOf("}");if(o!==-1&&n>o)return e.substring(o,n+1)}];for(let o of r)try{let n=o();if(!n)continue;let i=JSON.parse(n);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function Gt({message:s,sessionPath:e,nodeName:t,model:r,toolCallCount:o}){if(!e||!t)return;let n=s?.usage||s?.message?.usage||{},i=ce(n.input_tokens,n.inputTokens),l=ce(n.output_tokens,n.outputTokens),c=ce(n.cache_read_input_tokens,n.cacheReadInputTokens),p=ce(n.cache_creation_input_tokens,n.cacheCreationInputTokens),f=ce(s?.duration_ms,s?.durationMs),_={model:r||null,input_tokens:i,output_tokens:l,cache_read_tokens:c,cache_creation_tokens:p,tool_call_count:typeof o=="number"?o:null,duration_ms:f,captured_at:new Date().toISOString()},m=ee(e,t);try{Re(m,{recursive:!0})}catch{}Ne(ee(m,"usage.json"),JSON.stringify(_,null,2),"utf-8")}function ce(...s){for(let e of s){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""&&!isNaN(Number(e)))return Number(e)}return null}function jt(s,e){let t=ee(ot(),".claude"),r=ee(t,".credentials.json"),o={claudeAiOauth:{accessToken:s,...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(et(r)&&JSON.parse(tt(r,"utf-8"))?.claudeAiOauth?.accessToken===s)return;Re(t,{recursive:!0}),Ne(r,JSON.stringify(o,null,2),"utf-8"),a.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(n){a.warn(`Could not write ${r}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}function Ft(s){let e=ee(ot(),".claude"),t=ee(e,".credentials.json"),r;try{r=JSON.parse(s)}catch(o){a.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!r?.claudeAiOauth?.accessToken){a.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(et(t)){let o=JSON.parse(tt(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}Re(e,{recursive:!0}),Ne(t,JSON.stringify(r,null,2),"utf-8"),a.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){a.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}import{AgentStrategy as Yt,getSkill as zt}from"@zibby/agent-workflow";import{execSync as Ht}from"node:child_process";import{zodToJsonSchema as Xt}from"zod-to-json-schema";var ye=class extends Yt{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.OPENAI_API_KEY_POOL||process.env.CODEX_API_KEY||process.env.CODEX_API_KEY_POOL))return a.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Ht("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return a.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,skills:i=null,sessionPath:l=null,nodeName:c=null,timeout:p,config:f={},signal:_=null}=t,m=[G("OPENAI_API_KEY"),G("CODEX_API_KEY")];try{let{Codex:g}=await import("@openai/codex-sdk"),S=r;(!S||S==="auto")&&(a.debug(`Model is '${S||"undefined"}', using default: ${B.CODEX}`),S=B.CODEX);let N=ke[S]||S;ke[S]&&S!==N&&a.debug(`Mapped model: ${S} \u2192 ${N}`),a.debug(`Invoking Codex SDK with model: ${N}, skills: ${JSON.stringify(i)}`);let h=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;h&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=h);let x=h?` | key: ***${h.slice(-4)}`:" | key: not set";console.log(`
|
|
79
79
|
\u25C6 Model: ${N}${x}
|
|
80
80
|
`);let T=(await import("chalk")).default;console.log(`
|
|
81
81
|
${T.bold("Prompt sent to LLM:")}`),console.log(T.dim("\u2500".repeat(60))),console.log(T.dim(e)),console.log(T.dim("\u2500".repeat(60)));let $=this._resolveSkillsToMcp(i,{sessionPath:l,workspace:o,nodeName:c}),y={};Object.keys($).length>0&&(y.mcp_servers=$,a.debug(`[Codex] MCP servers: ${Object.keys($).join(", ")}`));let C=new g({...Object.keys(y).length>0&&{config:y}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),k=n&&typeof n.parse=="function",E={};if(n)try{let A=k?Xt(n,{target:"openAi"}):n;E.outputSchema=A,a.debug("Structured output via SDK outputSchema")}catch(A){a.warn(`[Codex] Schema conversion failed, will extract from text: ${A.message}`)}if(_?.aborted){let A=new Error("Aborted via signal");throw A.name="AbortError",A}try{let{events:A}=await C.runStreamed(e,E),L=0,b="";for await(let P of A){if(_?.aborted){let v=new Error("Aborted via signal");throw v.name="AbortError",v}let U=P.type;if(U==="item.completed"){let v=P.item,K=v?.type;if(K==="mcp_tool_call"){L++;let w=`${v.server}/${v.tool}`;if(Y.stepTool(`Tool: ${w}`),v.arguments){let u=JSON.stringify(v.arguments),I=u.length>100?`${u.substring(0,100)}...`:u;console.log(` Input: ${I}`)}}else if(K==="tool_call"||K==="function_call"||K==="command_execution"){L++;let w=v.name||v.tool||v.command||"unknown";Y.stepTool(`Tool: ${w}`)}else K==="agent_message"&&(b=v.text||"",b.length<500?console.log(b):console.log(`${b.substring(0,200)}... (${b.length} chars)`))}else U==="turn.completed"?a.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):a.debug(`[Codex] Event: ${U} ${JSON.stringify(P).slice(0,300)}`)}if(a.debug(`[Codex] Last agent message (${b.length} chars): ${b.slice(0,500)}`),n){if(!b)throw new Error("Codex agent returned no response");let P=JSON.parse(b),U=k?n.parse(P):P;return a.debug("\u2705 [Codex] Structured output validated"),{raw:b,structured:U}}return b||""}catch(A){let L=A.message||String(A);throw a.error(`\u274C [Codex] SDK call failed: ${L}`),L.includes("exited with code")&&(a.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),a.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),A}}finally{for(let g of m)g.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let o of e){let n=zt(o);if(!n){a.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof n.resolve!="function")continue;let i=n.resolve(t);if(!i)continue;let l=n.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),i.env&&Object.keys(i.env).length>0&&(c.env=i.env),r[l]=c,a.debug(`[Codex] MCP: ${l} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return r}};import{AgentStrategy as Zt,getSkill as Wt}from"@zibby/agent-workflow";import{execSync as qt,spawn as Vt}from"node:child_process";import{zodToJsonSchema as Qt}from"zod-to-json-schema";import{existsSync as rt,mkdirSync as nt,readFileSync as st,rmSync as eo,writeFileSync as it}from"node:fs";import{join as W}from"node:path";function to(s){if(!s)return null;let e=String(s),t=e.match(/```(?:json)?\s*([\s\S]*?)```/i);if(t?.[1])try{return JSON.parse(t[1].trim())}catch{}let r=e.indexOf("{");if(r<0)return null;let o=0,n=!1,i=!1,l=-1;for(let c=r;c<e.length;c++){let p=e[c];if(n){i?i=!1:p==="\\"?i=!0:p==='"'&&(n=!1);continue}if(p==='"'){n=!0;continue}if(p==="{"){o===0&&(l=c),o+=1;continue}if(p==="}"){if(o===0)continue;if(o-=1,o===0&&l>=0){let f=e.slice(l,c+1);try{return JSON.parse(f)}catch{l=-1}}}}return null}function oo(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return to(e)}}function ro(s){try{let e=JSON.parse(s);if(typeof e=="string")return e;if(typeof e?.response=="string")return e.response;if(typeof e?.text=="string")return e.text;if(typeof e?.output=="string")return e.output;if(Array.isArray(e?.candidates)&&e.candidates.length>0){let t=e.candidates[0];if(typeof t?.content=="string")return t.content;if(Array.isArray(t?.content?.parts)){let r=t.content.parts.map(o=>typeof o?.text=="string"?o.text:"").join("");if(r.trim())return r}}}catch{}return s}var _e=class extends Zt{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GEMINI_API_KEY_POOL||process.env.GOOGLE_API_KEY||process.env.GOOGLE_API_KEY_POOL))return a.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return qt("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return a.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,skills:i=null,sessionPath:l=null,nodeName:c=null,timeout:p=600*1e3,signal:f=null}=t,_=[G("GEMINI_API_KEY"),G("GOOGLE_API_KEY")];try{let m=r;(!m||m==="auto")&&(m=B.GEMINI);let g=Ge[m]||m,S=String(process.env.GEMINI_API_KEY||"").trim(),N=String(process.env.GOOGLE_API_KEY||"").trim(),h=this._resolveSkillsToMcp(i,{sessionPath:l,workspace:o,nodeName:c}),x=Object.keys(h).length>0,T=new V(e),$=n&&typeof n.parse=="function",y=null;if(n){let d;try{let D=$?Qt(n,{target:"openAi"}):n;d=JSON.stringify(D,null,2)}catch{d="{}"}if(x){T.addSystemInstruction(`Write valid JSON that matches this schema:
|