@zibby/core 0.5.18 → 0.5.20
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/backend-client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as _,readFileSync as E}from"node:fs";import{homedir as
|
|
1
|
+
import{existsSync as _,readFileSync as E}from"node:fs";import{homedir as T}from"node:os";import{join as y}from"node:path";var l=new Map,u={github:"GITHUB_TOKEN",gitlab:"GITLAB_TOKEN",sentry:"SENTRY_AUTH_TOKEN",slack:"SLACK_BOT_TOKEN"};function d(){let e=process.env.ZIBBY_SELF_HOST;return e!=null&&e!==""&&e!=="0"&&e.toLowerCase()!=="false"}function h(){if(process.env.PROJECT_API_TOKEN)return process.env.PROJECT_API_TOKEN;if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let e=y(T(),".zibby","config.json");return _(e)&&JSON.parse(E(e,"utf-8")).sessionToken||null}catch{return null}}function w(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://api-prod.zibby.app"}async function k(e){if(d()){let f=u[e];if(f&&process.env[f])return{token:process.env[f]}}let i=Date.now(),o=l.get(e);if(o&&o.expiresAt>i)return o.data;let r=h();if(!r)throw new Error("No session token. Run `zibby login` first.");let s=`${w()}/integrations/token/${e}`,n=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!n.ok){let f=await n.text().catch(()=>"");throw n.status===404?new Error(`${e} is not connected. Connect it at https://studio.zibby.dev/integrations`):n.status===401||n.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${e} token (${n.status}): ${f}`)}let t=await n.json();if(!t||typeof t!="object")throw new Error(`Invalid response from ${e} token endpoint: expected object, got ${typeof t}`);if(e==="jira"){if(!t.token||typeof t.token!="string")throw new Error(`Invalid jira token response: token is ${typeof t.token}, expected string`);if(!t.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(e==="github"&&(!t.token||typeof t.token!="string"))throw new Error(`Invalid github token response: token is ${typeof t.token}, expected string`);let c=((t.expiresInSec||3e3)-120)*1e3;return l.set(e,{data:t,expiresAt:i+c}),t}function O(e){e?l.delete(e):l.clear()}var a=null;function p(e){let i=process.env.WORKFLOW_ENABLED_INTEGRATIONS;if(typeof i!="string"||i.trim()==="")return e;let o=new Set(i.split(",").map(s=>s.trim()).filter(Boolean));if(o.size===0)return e;let r={};for(let[s,n]of Object.entries(e))o.has(s)&&(r[s]=n);return r}async function A(){let e=Date.now();if(a&&a.expiresAt>e)return a.data;if(d()){let o={};for(let[s,n]of Object.entries(u))o[s]=!!process.env[n];let r=p(o);return a={data:r,expiresAt:e+6e4},r}let i=h();if(!i)return{};try{let o=await fetch(`${w()}/integrations/status`,{method:"GET",headers:{Authorization:`Bearer ${i}`}});if(!o.ok)return{};let r=await o.json(),s={};if(r&&typeof r=="object")for(let[t,c]of Object.entries(r))c&&typeof c=="object"&&"connected"in c&&(s[t]=!!c.connected);let n=p(s);return a={data:n,expiresAt:e+6e4},n}catch{return{}}}function B(){a=null}export{B as clearConnectedCache,O as clearTokenCache,A as getConnectedIntegrations,k as resolveIntegrationToken};
|
package/dist/index.js
CHANGED
|
@@ -80,7 +80,7 @@ This usually means the binary is not in PATH. Try:
|
|
|
80
80
|
`),stringified:(()=>{try{return JSON.stringify(x,Object.getOwnPropertyNames(Object(x)))}catch{return String(x)}})()};throw p.error(`Error during query stream: ${x?.message||x}`,L),x}}catch($){throw p.error("Claude Agent SDK call failed",{message:$?.message,name:$?.name,code:$?.code,cause:$?.cause?.message||$?.cause}),$}}finally{for(let S of E)S.dispose()}}_resolveSkills(e,t){let r=["Read","Write","Edit","Bash","Grep","Glob"];if(e===null)return p.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return p.debug("Default IDE skills for code generation"),{allowedTools:[...r],mcpServers:{}};let n=[...r],o={},i=process.env.WORKFLOW_ENABLED_INTEGRATIONS,c=typeof i=="string"&&i.trim()!==""?new Set(i.split(",").map(a=>a.trim()).filter(Boolean)):null,l=a=>c!==null&&c.size>0&&Bn.includes(a)&&!c.has(a);for(let a of e){if(l(a)){p.debug(`Skill "${a}" disabled by enabledIntegrations allowlist \u2014 skipping`);continue}let u=Fn(a);if(!u){p.warn(`Unknown skill "${a}" \u2014 skipping`);continue}if(u.allowedTools&&n.push(...u.allowedTools),typeof u.resolve=="function"){let d=u.resolve(t);d&&(o[u.serverName]=d,p.debug(`MCP: ${u.serverName} \u2192 ${d.command} ${d.args[0]}`))}}return{allowedTools:n,mcpServers:o}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,o=e.indexOf("===JSON_END===");return e.substring(n,o).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("{"),o=e.lastIndexOf("}");if(n!==-1&&o>n)return e.substring(n,o+1)}];for(let n of r)try{let o=n();if(!o)continue;let i=JSON.parse(o);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function Kn({message:s,sessionPath:e,nodeName:t,model:r,toolCallCount:n}){if(!e||!t)return;let o=s?.usage||s?.message?.usage||{},i=De(o.input_tokens,o.inputTokens),c=De(o.output_tokens,o.outputTokens),l=De(o.cache_read_input_tokens,o.cacheReadInputTokens),a=De(o.cache_creation_input_tokens,o.cacheCreationInputTokens),u=De(s?.duration_ms,s?.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{mt(m,{recursive:!0})}catch{}dt(ge(m,"usage.json"),JSON.stringify(d,null,2),"utf-8")}function De(...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 Jn(s,e){let t=ge(ir(),".claude"),r=ge(t,".credentials.json"),n={claudeAiOauth:{accessToken:s,refreshToken:"",expiresAt:Date.now()+365*24*60*60*1e3,scopes:["user:inference","user:profile"],...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(or(r)&&JSON.parse(sr(r,"utf-8"))?.claudeAiOauth?.accessToken===s)return;mt(t,{recursive:!0}),dt(r,JSON.stringify(n,null,2),"utf-8"),p.debug(`Wrote Claude Code OAuth credentials to ${r}`)}catch(o){p.warn(`Could not write ${r}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}function zn(s){let e=ge(ir(),".claude"),t=ge(e,".credentials.json"),r;try{r=JSON.parse(s)}catch(n){p.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${n.message}`);return}if(!r?.claudeAiOauth?.accessToken){p.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(or(t)){let n=JSON.parse(sr(t,"utf-8"));if(n?.claudeAiOauth?.accessToken===r.claudeAiOauth.accessToken&&n?.claudeAiOauth?.expiresAt===r.claudeAiOauth.expiresAt)return}mt(e,{recursive:!0}),dt(t,JSON.stringify(r,null,2),"utf-8"),p.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(n){p.warn(`Could not write ${t}: ${n.message} \u2014 Claude SDK may fail to authenticate.`)}}Me();import{AgentStrategy as Yn,getSkill as Hn}from"@zibby/agent-workflow";import{execSync as Wn}from"node:child_process";var se=class extends Yn{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 p.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return Wn("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return p.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:o=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a,config:u={},signal:d=null}=t,m=[Y("OPENAI_API_KEY"),Y("CODEX_API_KEY")];try{let{Codex:f}=await import("@openai/codex-sdk"),g=r;(!g||g==="auto")&&(p.debug(`Model is '${g||"undefined"}', using default: ${J.CODEX}`),g=J.CODEX);let y=Xe[g]||g;Xe[g]&&g!==y&&p.debug(`Mapped model: ${g} \u2192 ${y}`),p.debug(`Invoking Codex SDK with model: ${y}, 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(`
|
|
81
81
|
\u25C6 Model: ${y}${b}
|
|
82
82
|
`);let w=(await import("chalk")).default;console.log(`
|
|
83
|
-
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let E=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),S={};Object.keys(E).length>0&&(S.mcp_servers=E,p.debug(`[Codex] MCP servers: ${Object.keys(E).join(", ")}`));let C=new f({...Object.keys(S).length>0&&{config:S}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),I=o&&typeof o.parse=="function",T={};if(o)try{let P=I?ne(o,{target:"openAi"}):o;T.outputSchema=P,p.debug("Structured output via SDK outputSchema")}catch(P){p.warn(`[Codex] Schema conversion failed, will extract from text: ${P.message}`)}if(d?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}try{let{events:P}=await C.runStreamed(e,T),D=0,v="";for await(let k of P){if(d?.aborted){let N=new Error("Aborted via signal");throw N.name="AbortError",N}let $=k.type;if($==="item.completed"){let N=k.item,B=N?.type;if(B==="mcp_tool_call"){D++;let R=`${N.server}/${N.tool}`;if(Z.stepTool(`Tool: ${R}`),N.arguments){let _=JSON.stringify(N.arguments),M=_.length>100?`${_.substring(0,100)}...`:_;console.log(` Input: ${M}`)}}else if(B==="tool_call"||B==="function_call"||B==="command_execution"){D++;let R=N.name||N.tool||N.command||"unknown";Z.stepTool(`Tool: ${R}`)}else B==="agent_message"&&(v=N.text||"",v.length<500?console.log(v):console.log(`${v.substring(0,200)}... (${v.length} chars)`))}else $==="turn.completed"?p.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(k.usage||{})}`):p.debug(`[Codex] Event: ${$} ${JSON.stringify(k).slice(0,300)}`)}if(p.debug(`[Codex] Last agent message (${v.length} chars): ${v.slice(0,500)}`),o){if(!v)throw new Error("Codex agent returned no response");let k=JSON.parse(v),$=I?o.parse(k):k;return p.debug("\u2705 [Codex] Structured output validated"),{raw:v,structured:$}}return v||""}catch(P){let D=P.message||String(P);throw p.error(`\u274C [Codex] SDK call failed: ${D}`),D.includes("exited with code")&&(p.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),p.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),P}}finally{for(let f of m)f.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let o=Hn(n);if(!o){p.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof o.resolve!="function")continue;let i=o.resolve(t);if(!i)continue;let c=o.serverName||n,l={command:i.command};i.args?.length&&(l.args=i.args),
|
|
83
|
+
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let E=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),S={};Object.keys(E).length>0&&(S.mcp_servers=E,p.debug(`[Codex] MCP servers: ${Object.keys(E).join(", ")}`));let C=new f({...Object.keys(S).length>0&&{config:S}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),I=o&&typeof o.parse=="function",T={};if(o)try{let P=I?ne(o,{target:"openAi"}):o;T.outputSchema=P,p.debug("Structured output via SDK outputSchema")}catch(P){p.warn(`[Codex] Schema conversion failed, will extract from text: ${P.message}`)}if(d?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}try{let{events:P}=await C.runStreamed(e,T),D=0,v="";for await(let k of P){if(d?.aborted){let N=new Error("Aborted via signal");throw N.name="AbortError",N}let $=k.type;if($==="item.completed"){let N=k.item,B=N?.type;if(B==="mcp_tool_call"){D++;let R=`${N.server}/${N.tool}`;if(Z.stepTool(`Tool: ${R}`),N.arguments){let _=JSON.stringify(N.arguments),M=_.length>100?`${_.substring(0,100)}...`:_;console.log(` Input: ${M}`)}}else if(B==="tool_call"||B==="function_call"||B==="command_execution"){D++;let R=N.name||N.tool||N.command||"unknown";Z.stepTool(`Tool: ${R}`)}else B==="agent_message"&&(v=N.text||"",v.length<500?console.log(v):console.log(`${v.substring(0,200)}... (${v.length} chars)`))}else $==="turn.completed"?p.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(k.usage||{})}`):p.debug(`[Codex] Event: ${$} ${JSON.stringify(k).slice(0,300)}`)}if(p.debug(`[Codex] Last agent message (${v.length} chars): ${v.slice(0,500)}`),o){if(!v)throw new Error("Codex agent returned no response");let k=JSON.parse(v),$=I?o.parse(k):k;return p.debug("\u2705 [Codex] Structured output validated"),{raw:v,structured:$}}return v||""}catch(P){let D=P.message||String(P);throw p.error(`\u274C [Codex] SDK call failed: ${D}`),D.includes("exited with code")&&(p.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),p.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),P}}finally{for(let f of m)f.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let o=Hn(n);if(!o){p.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof o.resolve!="function")continue;let i=o.resolve(t);if(!i)continue;let c=o.serverName||n,l={command:i.command};i.args?.length&&(l.args=i.args),l.env={...process.env,...i.env||{}},r[c]=l,p.debug(`[Codex] MCP: ${c} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return r}};Me();import{AgentStrategy as Vn,getSkill as Zn}from"@zibby/agent-workflow";import{execSync as Xn,spawn as qn}from"node:child_process";import{existsSync as ar,mkdirSync as lr,readFileSync as cr,rmSync as Qn,writeFileSync as ur}from"node:fs";import{join as ie}from"node:path";function eo(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 n=0,o=!1,i=!1,c=-1;for(let l=r;l<e.length;l++){let a=e[l];if(o){i?i=!1:a==="\\"?i=!0:a==='"'&&(o=!1);continue}if(a==='"'){o=!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 to(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return eo(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(n=>typeof n?.text=="string"?n.text:"").join("");if(r.trim())return r}}}catch{}return s}var ae=class extends Vn{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 p.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return Xn("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return p.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:o=null,skills:i=null,sessionPath:c=null,nodeName:l=null,timeout:a=600*1e3,signal:u=null}=t,d=[Y("GEMINI_API_KEY"),Y("GOOGLE_API_KEY")];try{let m=r;(!m||m==="auto")&&(m=J.GEMINI);let f=pt[m]||m,g=String(process.env.GEMINI_API_KEY||"").trim(),y=String(process.env.GOOGLE_API_KEY||"").trim(),h=this._resolveSkillsToMcp(i,{sessionPath:c,workspace:n,nodeName:l}),b=Object.keys(h).length>0,w=new de(e),E=o&&typeof o.parse=="function",S=null;if(o){let A;try{let x=E?ne(o,{target:"openAi"}):o;A=JSON.stringify(x,null,2)}catch{A="{}"}if(b){w.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
84
|
${A}`,"schema_instruction","append");let x=`zibby-result-${Date.now()}.json`,L=ie(n,".zibby","tmp");S=ie(L,x),lr(L,{recursive:!0}),w.addStructuredOutput(o,S)}else w.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
85
85
|
${A}`,"json_instruction","append")}let O=w.build(),C=w.getUserPrompt(),I=w.getStats(),T=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),P=T?` | key: ***${T.slice(-4)}`:" | key: not set";console.log(`
|
|
86
86
|
\u25C6 Model: ${f||"auto"}${P}
|
|
@@ -149,7 +149,7 @@ ${b.join(`
|
|
|
149
149
|
|
|
150
150
|
${y}
|
|
151
151
|
`),p.debug(`Prompt length: ${f.length} chars`),process.env.STAGE!=="prod"&&p.debug(`Full prompt:
|
|
152
|
-
${f}`),r.invoke(f,d)}import{SKILLS as Np}from"@zibby/agent-workflow";import{registerSkill as Lp,getSkill as Mp,hasSkill as Dp,getAllSkills as Up,listSkillIds as jp}from"@zibby/agent-workflow";var Fo={READ_FILE:"read_file",WRITE_FILE:"write_file",LIST_DIRECTORY:"list_directory",RUN_COMMAND:"run_command",OPEN_URL:"open_url",WAIT:"wait"},Bo={LIST_PROJECTS:"jira_list_projects",SEARCH:"jira_search",GET_ISSUE:"jira_get_issue",CREATE_ISSUE:"jira_create_issue",LIST_SPRINTS:"jira_list_sprints",GET_SPRINT_ISSUES:"jira_get_sprint_issues",GET_COMMENTS:"jira_get_comments",ADD_COMMENT:"jira_add_comment",EDIT_ISSUE:"jira_edit_issue",TRANSITION_ISSUE:"jira_transition_issue"},Go={GET_USER:"github_get_user",LIST_ORGS:"github_list_orgs",LIST_REPOS:"github_list_repos",CLONE:"github_clone",SEARCH_REPOS:"github_search_repos",SEARCH_ISSUES:"github_search_issues",SEARCH_CODE:"github_search_code",GET_PR:"github_get_pr",GET_PR_DIFF:"github_get_pr_diff",LIST_PR_FILES:"github_list_pr_files",LIST_PR_COMMENTS:"github_list_pr_comments",LIST_COMMITS:"github_list_commits",GET_COMMIT:"github_get_commit",GET_FILE:"github_get_file",CREATE_ISSUE:"github_create_issue"},Ko={LIST_CHANNELS:"slack_list_channels",POST_MESSAGE:"slack_post_message",REPLY_TO_THREAD:"slack_reply_to_thread",ADD_REACTION:"slack_add_reaction",GET_CHANNEL_HISTORY:"slack_get_channel_history",GET_THREAD_REPLIES:"slack_get_thread_replies",GET_USERS:"slack_get_users",GET_USER_PROFILE:"slack_get_user_profile"},Jo={GENERATE:"run_generate",TEST:"run_test",STATUS:"run_status",CANCEL:"run_cancel",WAIT:"run_wait",ARTIFACTS:"run_artifacts",LIST_SPECS:"list_specs"},zo={GET_TEST_HISTORY:"memory_get_test_history",GET_SELECTORS:"memory_get_selectors",GET_PAGE_MODEL:"memory_get_page_model",GET_NAVIGATION:"memory_get_navigation",SAVE_INSIGHT:"memory_save_insight"},Yo={STORE:"memory_store",RECALL:"memory_recall",BRIEF:"memory_brief",END_SESSION:"memory_end_session",TASK_LOG:"task_log",TASK_HISTORY:"task_history"},Ho={INSTALL:"install_skill",UNINSTALL:"uninstall_skill",LIST_AVAILABLE:"list_available_skills"},Jl={...Fo,...Bo,...Go,...Ko,...Jo,...zo,...Yo,...Ho};import{existsSync as Wo,readFileSync as Vo}from"node:fs";import{homedir as Zo}from"node:os";import{join as Xo}from"node:path";var it=new Map,qo={github:"GITHUB_TOKEN",gitlab:"GITLAB_TOKEN",slack:"SLACK_BOT_TOKEN"};function Qo(){let s=process.env.ZIBBY_SELF_HOST;return s!=null&&s!==""&&s!=="0"&&s.toLowerCase()!=="false"}function es(){if(process.env.PROJECT_API_TOKEN)return process.env.PROJECT_API_TOKEN;if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let s=Xo(Zo(),".zibby","config.json");return Wo(s)&&JSON.parse(Vo(s,"utf-8")).sessionToken||null}catch{return null}}function ts(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://api-prod.zibby.app"}async function rs(s){if(Qo()){let l=qo[s];if(l&&process.env[l])return{token:process.env[l]}}let e=Date.now(),t=it.get(s);if(t&&t.expiresAt>e)return t.data;let r=es();if(!r)throw new Error("No session token. Run `zibby login` first.");let n=`${ts()}/integrations/token/${s}`,o=await fetch(n,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!o.ok){let l=await o.text().catch(()=>"");throw o.status===404?new Error(`${s} is not connected. Connect it at https://studio.zibby.dev/integrations`):o.status===401||o.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${s} token (${o.status}): ${l}`)}let i=await o.json();if(!i||typeof i!="object")throw new Error(`Invalid response from ${s} token endpoint: expected object, got ${typeof i}`);if(s==="jira"){if(!i.token||typeof i.token!="string")throw new Error(`Invalid jira token response: token is ${typeof i.token}, expected string`);if(!i.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(s==="github"&&(!i.token||typeof i.token!="string"))throw new Error(`Invalid github token response: token is ${typeof i.token}, expected string`);let c=((i.expiresInSec||3e3)-120)*1e3;return it.set(s,{data:i,expiresAt:e+c}),i}function ns(s){s?it.delete(s):it.clear()}import{readdir as os,access as vr,copyFile as ss,constants as Tr}from"fs/promises";import{join as at,relative as is}from"node:path";async function as(s={}){let{testResultsDir:e="test-results",testsDir:t="tests",projectRoot:r=process.cwd(),verbose:n=!0}=s;n&&console.log(`\u{1F3A5} Organizing test videos...
|
|
152
|
+
${f}`),r.invoke(f,d)}import{SKILLS as Np}from"@zibby/agent-workflow";import{registerSkill as Lp,getSkill as Mp,hasSkill as Dp,getAllSkills as Up,listSkillIds as jp}from"@zibby/agent-workflow";var Fo={READ_FILE:"read_file",WRITE_FILE:"write_file",LIST_DIRECTORY:"list_directory",RUN_COMMAND:"run_command",OPEN_URL:"open_url",WAIT:"wait"},Bo={LIST_PROJECTS:"jira_list_projects",SEARCH:"jira_search",GET_ISSUE:"jira_get_issue",CREATE_ISSUE:"jira_create_issue",LIST_SPRINTS:"jira_list_sprints",GET_SPRINT_ISSUES:"jira_get_sprint_issues",GET_COMMENTS:"jira_get_comments",ADD_COMMENT:"jira_add_comment",EDIT_ISSUE:"jira_edit_issue",TRANSITION_ISSUE:"jira_transition_issue"},Go={GET_USER:"github_get_user",LIST_ORGS:"github_list_orgs",LIST_REPOS:"github_list_repos",CLONE:"github_clone",SEARCH_REPOS:"github_search_repos",SEARCH_ISSUES:"github_search_issues",SEARCH_CODE:"github_search_code",GET_PR:"github_get_pr",GET_PR_DIFF:"github_get_pr_diff",LIST_PR_FILES:"github_list_pr_files",LIST_PR_COMMENTS:"github_list_pr_comments",LIST_COMMITS:"github_list_commits",GET_COMMIT:"github_get_commit",GET_FILE:"github_get_file",CREATE_ISSUE:"github_create_issue"},Ko={LIST_CHANNELS:"slack_list_channels",POST_MESSAGE:"slack_post_message",REPLY_TO_THREAD:"slack_reply_to_thread",ADD_REACTION:"slack_add_reaction",GET_CHANNEL_HISTORY:"slack_get_channel_history",GET_THREAD_REPLIES:"slack_get_thread_replies",GET_USERS:"slack_get_users",GET_USER_PROFILE:"slack_get_user_profile"},Jo={GENERATE:"run_generate",TEST:"run_test",STATUS:"run_status",CANCEL:"run_cancel",WAIT:"run_wait",ARTIFACTS:"run_artifacts",LIST_SPECS:"list_specs"},zo={GET_TEST_HISTORY:"memory_get_test_history",GET_SELECTORS:"memory_get_selectors",GET_PAGE_MODEL:"memory_get_page_model",GET_NAVIGATION:"memory_get_navigation",SAVE_INSIGHT:"memory_save_insight"},Yo={STORE:"memory_store",RECALL:"memory_recall",BRIEF:"memory_brief",END_SESSION:"memory_end_session",TASK_LOG:"task_log",TASK_HISTORY:"task_history"},Ho={INSTALL:"install_skill",UNINSTALL:"uninstall_skill",LIST_AVAILABLE:"list_available_skills"},Jl={...Fo,...Bo,...Go,...Ko,...Jo,...zo,...Yo,...Ho};import{existsSync as Wo,readFileSync as Vo}from"node:fs";import{homedir as Zo}from"node:os";import{join as Xo}from"node:path";var it=new Map,qo={github:"GITHUB_TOKEN",gitlab:"GITLAB_TOKEN",sentry:"SENTRY_AUTH_TOKEN",slack:"SLACK_BOT_TOKEN"};function Qo(){let s=process.env.ZIBBY_SELF_HOST;return s!=null&&s!==""&&s!=="0"&&s.toLowerCase()!=="false"}function es(){if(process.env.PROJECT_API_TOKEN)return process.env.PROJECT_API_TOKEN;if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let s=Xo(Zo(),".zibby","config.json");return Wo(s)&&JSON.parse(Vo(s,"utf-8")).sessionToken||null}catch{return null}}function ts(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://api-prod.zibby.app"}async function rs(s){if(Qo()){let l=qo[s];if(l&&process.env[l])return{token:process.env[l]}}let e=Date.now(),t=it.get(s);if(t&&t.expiresAt>e)return t.data;let r=es();if(!r)throw new Error("No session token. Run `zibby login` first.");let n=`${ts()}/integrations/token/${s}`,o=await fetch(n,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!o.ok){let l=await o.text().catch(()=>"");throw o.status===404?new Error(`${s} is not connected. Connect it at https://studio.zibby.dev/integrations`):o.status===401||o.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${s} token (${o.status}): ${l}`)}let i=await o.json();if(!i||typeof i!="object")throw new Error(`Invalid response from ${s} token endpoint: expected object, got ${typeof i}`);if(s==="jira"){if(!i.token||typeof i.token!="string")throw new Error(`Invalid jira token response: token is ${typeof i.token}, expected string`);if(!i.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(s==="github"&&(!i.token||typeof i.token!="string"))throw new Error(`Invalid github token response: token is ${typeof i.token}, expected string`);let c=((i.expiresInSec||3e3)-120)*1e3;return it.set(s,{data:i,expiresAt:e+c}),i}function ns(s){s?it.delete(s):it.clear()}import{readdir as os,access as vr,copyFile as ss,constants as Tr}from"fs/promises";import{join as at,relative as is}from"node:path";async function as(s={}){let{testResultsDir:e="test-results",testsDir:t="tests",projectRoot:r=process.cwd(),verbose:n=!0}=s;n&&console.log(`\u{1F3A5} Organizing test videos...
|
|
153
153
|
`);let o=at(r,e),i=at(r,t);try{let c=await os(o),l=0;for(let a of c){if(a.startsWith("."))continue;let u=at(o,a,"video.webm");try{await vr(u,Tr.F_OK)}catch{continue}let d=a.replace(/-chromium$/,"").replace(/-firefox$/,"").replace(/-webkit$/,""),m=await ls(i,d);if(m){let f=m.replace(/\.spec\.(js|ts)$/,".spec.webm");await ss(u,f),n&&console.log(`\u2705 ${is(r,f)}`),l++}else n&&console.log(`\u26A0\uFE0F Could not find test file for: ${a}`)}return n&&(console.log(`
|
|
154
154
|
\u{1F3AC} Organized ${l} video(s)`),console.log(`\u{1F4C2} Videos are now next to their test files in ${t}/`)),{movedCount:l,success:!0}}catch(c){return n&&console.error("\u274C Error organizing videos:",c.message),{movedCount:0,success:!1,error:c.message}}}async function ls(s,e){let t=e.split("-");for(let r=t.length;r>0;r--){let o=t.slice(0,r).join("/");for(let i of["js","ts"]){let c=at(s,`${o}.spec.${i}`);try{return await vr(c,Tr.F_OK),c}catch{}}}return null}var Be=class{constructor(e,t={}){this.apiKey=e,this.baseUrl=t.baseUrl||process.env.ZIBBY_API_URL||"https://api-prod.zibby.app",this.enabled=!!e}isEnabled(){return this.enabled}};function Ar(){let s=process.env.ZIBBY_API_KEY;return new Be(s)}import{execSync as cs}from"node:child_process";import{existsSync as us,mkdirSync as ps}from"node:fs";import{join as fs}from"node:path";async function ds(s={}){let{baseDir:e="/workspace/repos",repos:t=null,depth:r=1,branch:n=null}=s,o=process.env.REPOS;if(!o)throw new Error("REPOS environment variable not set. Are you running in a Zibby workflow container?");let i;try{i=JSON.parse(o)}catch(a){throw new Error(`Failed to parse REPOS env var: ${a.message}`,{cause:a})}if(!Array.isArray(i)||i.length===0)throw new Error("No repositories configured for this project");let c=t?i.filter(a=>t.includes(a.name)):i;if(c.length===0)throw new Error(`No matching repositories found. Available: ${i.map(a=>a.name).join(", ")}`);us(e)||ps(e,{recursive:!0});let l={};return await Promise.all(c.map(async a=>{let u=a.provider||"github",d=u==="gitlab"?process.env.GITLAB_TOKEN:process.env.GITHUB_TOKEN;if(!d){console.error(`${u.toUpperCase()}_TOKEN not set, skipping ${a.name}`),l[a.name]=null;return}let m=a.name.replace(/\//g,"-"),f=fs(e,m),g=a.cloneUrl||a.url;if(!g){console.error(`Repository "${a.name}" has no clone URL`),l[a.name]=null;return}let y;u==="gitlab"?y=g.replace(/^https:\/\//,`https://oauth2:${d}@`):y=g.replace(/^https:\/\//,`https://x-access-token:${d}@`);let h=["clone"];r>0&&h.push("--depth",r.toString()),n&&h.push("--branch",n),h.push(y,f);let b=`git ${h.join(" ")}`;console.log(`Cloning ${a.name} (${u}) to ${f}...`);try{cs(b,{stdio:"pipe",env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),console.log(`Repository ${a.name} cloned successfully`),l[a.name]=f}catch(w){let E=w.message.replace(d,"***").replace(y,g);console.error(`Failed to clone ${a.name}: ${E}`),l[a.name]=null}})),l}var $r=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;function ms(s){return typeof s=="string"&&$r.test(s)}var Or=ms;function gs(s){if(!Or(s))throw TypeError("Invalid UUID");let e;return Uint8Array.of((e=parseInt(s.slice(0,8),16))>>>24,e>>>16&255,e>>>8&255,e&255,(e=parseInt(s.slice(9,13),16))>>>8,e&255,(e=parseInt(s.slice(14,18),16))>>>8,e&255,(e=parseInt(s.slice(19,23),16))>>>8,e&255,(e=parseInt(s.slice(24,36),16))/1099511627776&255,e/4294967296&255,e>>>24&255,e>>>16&255,e>>>8&255,e&255)}var At=gs;var K=[];for(let s=0;s<256;++s)K.push((s+256).toString(16).slice(1));function Ir(s,e=0){return(K[s[e+0]]+K[s[e+1]]+K[s[e+2]]+K[s[e+3]]+"-"+K[s[e+4]]+K[s[e+5]]+"-"+K[s[e+6]]+K[s[e+7]]+"-"+K[s[e+8]]+K[s[e+9]]+"-"+K[s[e+10]]+K[s[e+11]]+K[s[e+12]]+K[s[e+13]]+K[s[e+14]]+K[s[e+15]]).toLowerCase()}function hs(s){s=unescape(encodeURIComponent(s));let e=new Uint8Array(s.length);for(let t=0;t<s.length;++t)e[t]=s.charCodeAt(t);return e}var Cr="6ba7b810-9dad-11d1-80b4-00c04fd430c8",Pr="6ba7b811-9dad-11d1-80b4-00c04fd430c8";function $t(s,e,t,r,n,o){let i=typeof t=="string"?hs(t):t,c=typeof r=="string"?At(r):r;if(typeof r=="string"&&(r=At(r)),r?.length!==16)throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let l=new Uint8Array(16+i.length);if(l.set(c),l.set(i,c.length),l=e(l),l[6]=l[6]&15|s,l[8]=l[8]&63|128,n){if(o=o||0,o<0||o+16>n.length)throw new RangeError(`UUID byte range ${o}:${o+15} is out of buffer bounds`);for(let a=0;a<16;++a)n[o+a]=l[a];return n}return Ir(l)}import{createHash as ys}from"crypto";function bs(s){return Array.isArray(s)?s=Buffer.from(s):typeof s=="string"&&(s=Buffer.from(s,"utf8")),ys("sha1").update(s).digest()}var kr=bs;function Ot(s,e,t,r){return $t(80,kr,s,e,t,r)}Ot.DNS=Cr;Ot.URL=Pr;var It=Ot;var Nr="@zibby/core ZibbySessionStore/1",Ge=class{constructor({apiUrl:e,apiKey:t,workflowUuid:r,fetchImpl:n=globalThis.fetch}){if(!e)throw new Error("ZibbySessionStore: apiUrl is required");if(!t)throw new Error("ZibbySessionStore: apiKey is required");if(!r)throw new Error("ZibbySessionStore: workflowUuid is required");this._apiUrl=String(e).replace(/\/+$/,""),this._apiKey=t,this._workflowUuid=r,this._fetch=n}async append(e,t){if(!Array.isArray(t)||t.length===0)return;let r=`${this._apiUrl}/workflows/${encodeURIComponent(this._workflowUuid)}/sessions/${encodeURIComponent(e.sessionId)}/append`,n=await this._fetch(r,{method:"POST",headers:{Authorization:`Bearer ${this._apiKey}`,"Content-Type":"application/json","User-Agent":Nr},body:JSON.stringify({entries:t})});if(!n.ok)throw new Error(`ZibbySessionStore.append HTTP ${n.status}`)}async load(e){let t=`${this._apiUrl}/workflows/${encodeURIComponent(this._workflowUuid)}/sessions/${encodeURIComponent(e.sessionId)}`,r;try{r=await this._fetch(t,{method:"GET",headers:{Authorization:`Bearer ${this._apiKey}`,"User-Agent":Nr}})}catch{return null}if(r.status===404||!r.ok)return null;let n;try{n=await r.json()}catch{return null}let o=Array.isArray(n?.entries)?n.entries:null;return o&&o.length>0?o:null}};var Ss="6ba7b810-9dad-11d1-80b4-00c04fd430c8",Rr=new Set;function ws(){return(process.env.PROGRESS_API_URL||process.env.ZIBBY_API_BASE||"").replace(/\/executions\/?$/,"").replace(/\/+$/,"")}function Lr({namespace:s=Ss}={}){return{id:"session",description:"Persist agent conversation state across invocations (Claude-only in v1)",envKeys:[],tools:[],invokeAgentOptions(e,t){let r=e?.conversationId,n=e?.workflowUuid;if(!r||!n)return null;let o=t?.agentType;if(o&&o!=="claude")return Rr.has(o)||(console.warn(`[SKILLS.SESSION] agent type '${o}' does not support native sessions \u2014 node running stateless`),Rr.add(o)),null;let i=It(`${n}:${r}`,s),c=ws(),l=process.env.PROJECT_API_TOKEN||process.env.ZIBBY_USER_TOKEN,a=null;if(c&&l)try{a=new Ge({apiUrl:c,apiKey:l,workflowUuid:n})}catch(m){console.warn(`[SKILLS.SESSION] failed to build SessionStore: ${m.message}`),a=null}return e.resetConversation?{sessionId:i,resume:i,forkSession:!0,...a&&{sessionStore:a}}:e.hasPriorSession?{resume:i,...a&&{sessionStore:a}}:{sessionId:i,...a&&{sessionStore:a}}}}}import{spawn as Mr}from"node:child_process";import{readFileSync as _s,writeFileSync as xs,existsSync as lt}from"node:fs";import{homedir as Dr}from"node:os";import{join as _e}from"node:path";async function Es(){let s=_e(Dr(),".local/share/cursor-agent/versions");if(!lt(s))throw new Error(`cursor-agent not found at ${s}. Please install cursor-agent first.`);return console.log(`\u{1F527} Patching cursor-agent for CI/CD...
|
|
155
155
|
`),new Promise((e,t)=>{let r=_e(__dirname,"../../scripts/patch-cursor-mcp.py");if(!lt(r)){t(new Error("Patch script not found"));return}let n=Mr("python3",[r],{stdio:"inherit"});n.on("close",o=>{o===0?e({success:!0}):t(new Error(`Patch failed with code ${o}`))}),n.on("error",o=>{t(o)})})}function vs(){let s=_e(Dr(),".local/share/cursor-agent/versions");if(!lt(s))return{patched:!1,installed:!1};try{let e=nn("fs").readdirSync(s);if(e.length===0)return{patched:!1,installed:!1};let t=e.sort().reverse()[0],r=_e(s,t,"index.js");return lt(r)?{patched:_s(r,"utf-8").includes("AUTO-APPROVE MCP TOOLS FOR CI/CD"),installed:!0,path:r}:{patched:!1,installed:!1}}catch(e){return{patched:!1,installed:!1,error:e.message}}}async function Ts(s){return console.log(`\u{1F511} Getting MCP approval keys...
|
package/dist/package.json
CHANGED
|
@@ -80,7 +80,7 @@ This usually means the binary is not in PATH. Try:
|
|
|
80
80
|
`),stringified:(()=>{try{return JSON.stringify(p,Object.getOwnPropertyNames(Object(p)))}catch{return String(p)}})()};throw l.error(`Error during query stream: ${p?.message||p}`,$),p}}catch(k){throw l.error("Claude Agent SDK call failed",{message:k?.message,name:k?.name,code:k?.code,cause:k?.cause?.message||k?.cause}),k}}finally{for(let m of L)m.dispose()}}_resolveSkills(e,t){let n=["Read","Write","Edit","Bash","Grep","Glob"];if(e===null)return l.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return l.debug("Default IDE skills for code generation"),{allowedTools:[...n],mcpServers:{}};let o=[...n],r={},i=process.env.WORKFLOW_ENABLED_INTEGRATIONS,a=typeof i=="string"&&i.trim()!==""?new Set(i.split(",").map(d=>d.trim()).filter(Boolean)):null,c=d=>a!==null&&a.size>0&&Qt.includes(d)&&!a.has(d);for(let d of e){if(c(d)){l.debug(`Skill "${d}" disabled by enabledIntegrations allowlist \u2014 skipping`);continue}let u=qt(d);if(!u){l.warn(`Unknown skill "${d}" \u2014 skipping`);continue}if(u.allowedTools&&o.push(...u.allowedTools),typeof u.resolve=="function"){let h=u.resolve(t);h&&(r[u.serverName]=h,l.debug(`MCP: ${u.serverName} \u2192 ${h.command} ${h.args[0]}`))}}return{allowedTools:o,mcpServers:r}}_extractJson(e,t){let n=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,r=e.indexOf("===JSON_END===");return e.substring(o,r).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("{"),r=e.lastIndexOf("}");if(o!==-1&&r>o)return e.substring(o,r+1)}];for(let o of n)try{let r=o();if(!r)continue;let i=JSON.parse(r);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function to({message:s,sessionPath:e,nodeName:t,model:n,toolCallCount:o}){if(!e||!t)return;let r=s?.usage||s?.message?.usage||{},i=pe(r.input_tokens,r.inputTokens),a=pe(r.output_tokens,r.outputTokens),c=pe(r.cache_read_input_tokens,r.cacheReadInputTokens),d=pe(r.cache_creation_input_tokens,r.cacheCreationInputTokens),u=pe(s?.duration_ms,s?.durationMs),h={model:n||null,input_tokens:i,output_tokens:a,cache_read_tokens:c,cache_creation_tokens:d,tool_call_count:typeof o=="number"?o:null,duration_ms:u,captured_at:new Date().toISOString()},g=oe(e,t);try{Ke(g,{recursive:!0})}catch{}Ue(oe(g,"usage.json"),JSON.stringify(h,null,2),"utf-8")}function pe(...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 oo(s,e){let t=oe(ct(),".claude"),n=oe(t,".credentials.json"),o={claudeAiOauth:{accessToken:s,refreshToken:"",expiresAt:Date.now()+365*24*60*60*1e3,scopes:["user:inference","user:profile"],...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(lt(n)&&JSON.parse(at(n,"utf-8"))?.claudeAiOauth?.accessToken===s)return;Ke(t,{recursive:!0}),Ue(n,JSON.stringify(o,null,2),"utf-8"),l.debug(`Wrote Claude Code OAuth credentials to ${n}`)}catch(r){l.warn(`Could not write ${n}: ${r.message} \u2014 Claude SDK may fail to authenticate.`)}}function no(s){let e=oe(ct(),".claude"),t=oe(e,".credentials.json"),n;try{n=JSON.parse(s)}catch(o){l.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!n?.claudeAiOauth?.accessToken){l.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(lt(t)){let o=JSON.parse(at(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===n.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===n.claudeAiOauth.expiresAt)return}Ke(e,{recursive:!0}),Ue(t,JSON.stringify(n,null,2),"utf-8"),l.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){l.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}fe();import{AgentStrategy as ro,getSkill as so}from"@zibby/agent-workflow";import{execSync as io}from"node:child_process";var Ae=class extends ro{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 l.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return io("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d,config:u={},signal:h=null}=t,g=[F("OPENAI_API_KEY"),F("CODEX_API_KEY")];try{let{Codex:S}=await import("@openai/codex-sdk"),E=n;(!E||E==="auto")&&(l.debug(`Model is '${E||"undefined"}', using default: ${j.CODEX}`),E=j.CODEX);let U=Le[E]||E;Le[E]&&E!==U&&l.debug(`Mapped model: ${E} \u2192 ${U}`),l.debug(`Invoking Codex SDK with model: ${U}, skills: ${JSON.stringify(i)}`);let _=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;_&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=_);let b=_?` | key: ***${_.slice(-4)}`:" | key: not set";console.log(`
|
|
81
81
|
\u25C6 Model: ${U}${b}
|
|
82
82
|
`);let w=(await import("chalk")).default;console.log(`
|
|
83
|
-
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let L=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),m={};Object.keys(L).length>0&&(m.mcp_servers=L,l.debug(`[Codex] MCP servers: ${Object.keys(L).join(", ")}`));let B=new S({...Object.keys(m).length>0&&{config:m}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),M=r&&typeof r.parse=="function",O={};if(r)try{let T=M?Z(r,{target:"openAi"}):r;O.outputSchema=T,l.debug("Structured output via SDK outputSchema")}catch(T){l.warn(`[Codex] Schema conversion failed, will extract from text: ${T.message}`)}if(h?.aborted){let T=new Error("Aborted via signal");throw T.name="AbortError",T}try{let{events:T}=await B.runStreamed(e,O),N=0,A="";for await(let C of T){if(h?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}let k=C.type;if(k==="item.completed"){let P=C.item,G=P?.type;if(G==="mcp_tool_call"){N++;let v=`${P.server}/${P.tool}`;if(H.stepTool(`Tool: ${v}`),P.arguments){let f=JSON.stringify(P.arguments),R=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${R}`)}}else if(G==="tool_call"||G==="function_call"||G==="command_execution"){N++;let v=P.name||P.tool||P.command||"unknown";H.stepTool(`Tool: ${v}`)}else G==="agent_message"&&(A=P.text||"",A.length<500?console.log(A):console.log(`${A.substring(0,200)}... (${A.length} chars)`))}else k==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(C.usage||{})}`):l.debug(`[Codex] Event: ${k} ${JSON.stringify(C).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${A.length} chars): ${A.slice(0,500)}`),r){if(!A)throw new Error("Codex agent returned no response");let C=JSON.parse(A),k=M?r.parse(C):C;return l.debug("\u2705 [Codex] Structured output validated"),{raw:A,structured:k}}return A||""}catch(T){let N=T.message||String(T);throw l.error(`\u274C [Codex] SDK call failed: ${N}`),N.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),T}}finally{for(let S of g)S.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=so(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),
|
|
83
|
+
${w.bold("Prompt sent to LLM:")}`),console.log(w.dim("\u2500".repeat(60))),console.log(w.dim(e)),console.log(w.dim("\u2500".repeat(60)));let L=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),m={};Object.keys(L).length>0&&(m.mcp_servers=L,l.debug(`[Codex] MCP servers: ${Object.keys(L).join(", ")}`));let B=new S({...Object.keys(m).length>0&&{config:m}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),M=r&&typeof r.parse=="function",O={};if(r)try{let T=M?Z(r,{target:"openAi"}):r;O.outputSchema=T,l.debug("Structured output via SDK outputSchema")}catch(T){l.warn(`[Codex] Schema conversion failed, will extract from text: ${T.message}`)}if(h?.aborted){let T=new Error("Aborted via signal");throw T.name="AbortError",T}try{let{events:T}=await B.runStreamed(e,O),N=0,A="";for await(let C of T){if(h?.aborted){let P=new Error("Aborted via signal");throw P.name="AbortError",P}let k=C.type;if(k==="item.completed"){let P=C.item,G=P?.type;if(G==="mcp_tool_call"){N++;let v=`${P.server}/${P.tool}`;if(H.stepTool(`Tool: ${v}`),P.arguments){let f=JSON.stringify(P.arguments),R=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${R}`)}}else if(G==="tool_call"||G==="function_call"||G==="command_execution"){N++;let v=P.name||P.tool||P.command||"unknown";H.stepTool(`Tool: ${v}`)}else G==="agent_message"&&(A=P.text||"",A.length<500?console.log(A):console.log(`${A.substring(0,200)}... (${A.length} chars)`))}else k==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(C.usage||{})}`):l.debug(`[Codex] Event: ${k} ${JSON.stringify(C).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${A.length} chars): ${A.slice(0,500)}`),r){if(!A)throw new Error("Codex agent returned no response");let C=JSON.parse(A),k=M?r.parse(C):C;return l.debug("\u2705 [Codex] Structured output validated"),{raw:A,structured:k}}return A||""}catch(T){let N=T.message||String(T);throw l.error(`\u274C [Codex] SDK call failed: ${N}`),N.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),T}}finally{for(let S of g)S.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=so(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),c.env={...process.env,...i.env||{}},n[a]=c,l.debug(`[Codex] MCP: ${a} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return n}};fe();import{AgentStrategy as lo,getSkill as ao}from"@zibby/agent-workflow";import{execSync as co,spawn as uo}from"node:child_process";import{existsSync as ut,mkdirSync as dt,readFileSync as ft,rmSync as fo,writeFileSync as pt}from"node:fs";import{join as q}from"node:path";function po(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 n=e.indexOf("{");if(n<0)return null;let o=0,r=!1,i=!1,a=-1;for(let c=n;c<e.length;c++){let d=e[c];if(r){i?i=!1:d==="\\"?i=!0:d==='"'&&(r=!1);continue}if(d==='"'){r=!0;continue}if(d==="{"){o===0&&(a=c),o+=1;continue}if(d==="}"){if(o===0)continue;if(o-=1,o===0&&a>=0){let u=e.slice(a,c+1);try{return JSON.parse(u)}catch{a=-1}}}}return null}function mo(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return po(e)}}function go(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 n=t.content.parts.map(o=>typeof o?.text=="string"?o.text:"").join("");if(n.trim())return n}}}catch{}return s}var ve=class extends lo{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 l.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return co("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d=600*1e3,signal:u=null}=t,h=[F("GEMINI_API_KEY"),F("GOOGLE_API_KEY")];try{let g=n;(!g||g==="auto")&&(g=j.GEMINI);let S=ze[g]||g,E=String(process.env.GEMINI_API_KEY||"").trim(),U=String(process.env.GOOGLE_API_KEY||"").trim(),_=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),b=Object.keys(_).length>0,w=new ee(e),L=r&&typeof r.parse=="function",m=null;if(r){let y;try{let p=L?Z(r,{target:"openAi"}):r;y=JSON.stringify(p,null,2)}catch{y="{}"}if(b){w.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
84
|
${y}`,"schema_instruction","append");let p=`zibby-result-${Date.now()}.json`,$=q(o,".zibby","tmp");m=q($,p),dt($,{recursive:!0}),w.addStructuredOutput(r,m)}else w.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
85
85
|
${y}`,"json_instruction","append")}let K=w.build(),B=w.getUserPrompt(),M=w.getStats(),O=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),T=O?` | key: ***${O.slice(-4)}`:" | key: not set";console.log(`
|
|
86
86
|
\u25C6 Model: ${S||"auto"}${T}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as
|
|
1
|
+
import{AgentStrategy as B,getSkill as j}from"@zibby/agent-workflow";import{execSync as z}from"node:child_process";import{z as G}from"zod";import{zodToJsonSchema as F}from"zod-to-json-schema";function V(l,e={target:"openApi3"}){if(!l)return null;if(typeof G?.toJSONSchema=="function")try{return G.toJSONSchema(l)}catch{}try{return F(l,e)}catch{return null}}import y from"chalk";var u={debug:0,info:1,warn:2,error:3,silent:4},A=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return u.debug;if(process.env.ZIBBY_VERBOSE==="true")return u.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in u?u[e]:u.info}_shouldLog(e){return u[e]>=this._level}_formatMessage(e,o,s={}){let c=new Date().toISOString(),i=`${this._getPrefix(e)} ${o}`;return Object.keys(s).length>0&&(i+=y.dim(` ${JSON.stringify(s)}`)),i}_getPrefix(e){return{debug:y.gray("[DEBUG]"),info:y.cyan("[INFO]"),warn:y.yellow("[WARN]"),error:y.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 u&&(this._level=u[e])}getLevel(){return Object.keys(u).find(e=>u[e]===this._level)}},n=new A;import{timeline as L,Timeline as le,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as se}from"@zibby/agent-workflow";var J=[{alias:"auto",canonicalId:"claude-sonnet-4-6",vendor:"claude",label:"Claude \xB7 Sonnet 4.6",family:"claude-sonnet-4",pickerVisible:!0,isDefault:!0},{alias:"opus-4.8",canonicalId:"claude-opus-4-8",vendor:"claude",label:"Claude \xB7 Opus 4.8",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-8",canonicalId:"claude-opus-4-8",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.8"},{alias:"sonnet-4.8",canonicalId:"claude-sonnet-4-8",vendor:"claude",label:"Claude \xB7 Sonnet 4.8",family:"claude-sonnet-4",pickerVisible:!0},{alias:"sonnet-4-8",canonicalId:"claude-sonnet-4-8",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.8"},{alias:"opus-4.7",canonicalId:"claude-opus-4-7",vendor:"claude",label:"Claude \xB7 Opus 4.7",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-7",canonicalId:"claude-opus-4-7",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.7"},{alias:"sonnet-4.7",canonicalId:"claude-sonnet-4-7",vendor:"claude",label:"Claude \xB7 Sonnet 4.7",family:"claude-sonnet-4",pickerVisible:!0},{alias:"sonnet-4-7",canonicalId:"claude-sonnet-4-7",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.7"},{alias:"sonnet-4.6",canonicalId:"claude-sonnet-4-6",vendor:"claude",family:"claude-sonnet-4",aliasOf:"auto"},{alias:"sonnet-4-6",canonicalId:"claude-sonnet-4-6",vendor:"claude",family:"claude-sonnet-4",aliasOf:"auto"},{alias:"opus-4.6",canonicalId:"claude-opus-4-6",vendor:"claude",label:"Claude \xB7 Opus 4.6",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-6",canonicalId:"claude-opus-4-6",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.6"},{alias:"sonnet-4.5",canonicalId:"claude-sonnet-4-5-20250929",vendor:"claude",label:"Claude \xB7 Sonnet 4.5",family:"claude-sonnet-4",pickerVisible:!0},{alias:"sonnet-4-5",canonicalId:"claude-sonnet-4-5-20250929",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.5"},{alias:"opus-4.5",canonicalId:"claude-opus-4-5-20251101",vendor:"claude",label:"Claude \xB7 Opus 4.5",family:"claude-opus-4",pickerVisible:!0},{alias:"opus-4-5",canonicalId:"claude-opus-4-5-20251101",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.5"},{alias:"haiku-4.5",canonicalId:"claude-haiku-4-5-20251001",vendor:"claude",label:"Claude \xB7 Haiku 4.5",family:"claude-haiku-4"},{alias:"haiku-4-5",canonicalId:"claude-haiku-4-5-20251001",vendor:"claude",family:"claude-haiku-4",aliasOf:"haiku-4.5"},{alias:"claude-opus-4-8",canonicalId:"claude-opus-4-8",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.8"},{alias:"claude-sonnet-4-8",canonicalId:"claude-sonnet-4-8",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.8"},{alias:"claude-opus-4-7",canonicalId:"claude-opus-4-7",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.7"},{alias:"claude-sonnet-4-7",canonicalId:"claude-sonnet-4-7",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.7"},{alias:"claude-sonnet-4-6",canonicalId:"claude-sonnet-4-6",vendor:"claude",family:"claude-sonnet-4",aliasOf:"auto"},{alias:"claude-opus-4-6",canonicalId:"claude-opus-4-6",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.6"},{alias:"claude-sonnet-4-5-20250929",canonicalId:"claude-sonnet-4-5-20250929",vendor:"claude",family:"claude-sonnet-4",aliasOf:"sonnet-4.5"},{alias:"claude-opus-4-5-20251101",canonicalId:"claude-opus-4-5-20251101",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.5"},{alias:"claude-haiku-4-5-20251001",canonicalId:"claude-haiku-4-5-20251001",vendor:"claude",family:"claude-haiku-4",aliasOf:"haiku-4.5"},{alias:"claude-opus-4-20250514",canonicalId:"claude-opus-4-20250514",vendor:"claude",family:"claude-opus-4",aliasOf:"opus-4.5"},{alias:"auto",canonicalId:"o4-mini",vendor:"codex",label:"Codex \xB7 o4-mini",family:"o4-mini",isDefault:!0},{alias:"o4-mini",canonicalId:"o4-mini",vendor:"codex",label:"Codex \xB7 o4-mini",family:"o4-mini",pickerVisible:!0},{alias:"o3",canonicalId:"o3",vendor:"codex",family:"o3"},{alias:"o3-mini",canonicalId:"o3-mini",vendor:"codex",family:"o3-mini"},{alias:"codex-mini",canonicalId:"codex-mini-latest",vendor:"codex",family:"codex-mini"},{alias:"gpt-4o",canonicalId:"gpt-4o",vendor:"codex",label:"Codex \xB7 GPT-4o",family:"gpt-4o",pickerVisible:!0},{alias:"gpt-4o-mini",canonicalId:"gpt-4o-mini",vendor:"codex",label:"Codex \xB7 GPT-4o mini",family:"gpt-4o-mini",pickerVisible:!0},{alias:"gpt-5.2-codex",canonicalId:"gpt-5.2-codex",vendor:"codex",label:"Codex \xB7 GPT-5.2",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.2",canonicalId:"gpt-5.2",vendor:"codex",label:"Codex \xB7 GPT-5.2 base",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.3",canonicalId:"gpt-5.3",vendor:"codex",label:"Codex \xB7 GPT-5.3",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.3-codex",canonicalId:"gpt-5.3-codex",vendor:"codex",family:"gpt-5"},{alias:"gpt-5.4",canonicalId:"gpt-5.4",vendor:"codex",label:"Codex \xB7 GPT-5.4",family:"gpt-5",pickerVisible:!0},{alias:"gpt-5.5",canonicalId:"gpt-5.5",vendor:"codex",label:"Codex \xB7 GPT-5.5",family:"gpt-5",pickerVisible:!0},{alias:"auto",canonicalId:"gemini-3-pro",vendor:"gemini",label:"Gemini \xB7 3 Pro",family:"gemini-3",isDefault:!0},{alias:"gemini-3-pro",canonicalId:"gemini-3-pro",vendor:"gemini",label:"Gemini \xB7 3 Pro",family:"gemini-3",pickerVisible:!0},{alias:"gemini-3-flash",canonicalId:"gemini-3-flash",vendor:"gemini",label:"Gemini \xB7 3 Flash",family:"gemini-3",pickerVisible:!0},{alias:"gemini-2.5-pro",canonicalId:"gemini-2.5-pro",vendor:"gemini",label:"Gemini \xB7 2.5 Pro",family:"gemini-2.5",pickerVisible:!0},{alias:"gemini-2.5-flash",canonicalId:"gemini-2.5-flash",vendor:"gemini",label:"Gemini \xB7 2.5 Flash",family:"gemini-2.5",pickerVisible:!0}];function _(l){let e={};for(let o of J)o.vendor===l&&(e[o.alias]=o.canonicalId);return e}var w={ASSISTANT:"gpt-5.4-nano-2026-03-17",CLAUDE:"claude-sonnet-4-6",CURSOR:"auto",CODEX:"o4-mini",GEMINI:"gemini-3-pro",OPENAI_POSTPROCESSING:"gpt-4o-mini"};var ce=_("claude"),M=_("codex"),de=_("gemini"),ue={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};function $(l){let e=`${l}_POOL`,o=process.env[e];if(!o||typeof o!="string")return{picked:null,count:0,dispose:()=>{}};let s=o.split(/[,\n]+/).map(i=>i.trim()).filter(Boolean);if(s.length===0)return{picked:null,count:0,dispose:()=>{}};let c=s[Math.floor(Math.random()*s.length)],a=process.env[l];return process.env[l]=c,n.debug(`[auth-pool] ${l}: picked 1 of ${s.length} from pool (***${c.slice(-4)})`),{picked:c,count:s.length,dispose(){a===void 0?delete process.env[l]:process.env[l]=a}}}var R=class extends B{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 n.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return z("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return n.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,o={}){let{model:s,workspace:c=process.cwd(),schema:a=null,skills:i=null,sessionPath:O=null,nodeName:m=null,timeout:W,config:H={},signal:D=null}=o,K=[$("OPENAI_API_KEY"),$("CODEX_API_KEY")];try{let{Codex:E}=await import("@openai/codex-sdk"),p=s;(!p||p==="auto")&&(n.debug(`Model is '${p||"undefined"}', using default: ${w.CODEX}`),p=w.CODEX);let b=M[p]||p;M[p]&&p!==b&&n.debug(`Mapped model: ${p} \u2192 ${b}`),n.debug(`Invoking Codex SDK with model: ${b}, skills: ${JSON.stringify(i)}`);let x=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;x&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=x);let Y=x?` | key: ***${x.slice(-4)}`:" | key: not set";console.log(`
|
|
2
2
|
\u25C6 Model: ${b}${Y}
|
|
3
3
|
`);let h=(await import("chalk")).default;console.log(`
|
|
4
|
-
${h.bold("Prompt sent to LLM:")}`),console.log(h.dim("\u2500".repeat(60))),console.log(h.dim(e)),console.log(h.dim("\u2500".repeat(60)));let k=this._resolveSkillsToMcp(
|
|
4
|
+
${h.bold("Prompt sent to LLM:")}`),console.log(h.dim("\u2500".repeat(60))),console.log(h.dim(e)),console.log(h.dim("\u2500".repeat(60)));let k=this._resolveSkillsToMcp(i,{sessionPath:O,workspace:c,nodeName:m}),C={};Object.keys(k).length>0&&(C.mcp_servers=k,n.debug(`[Codex] MCP servers: ${Object.keys(k).join(", ")}`));let U=new E({...Object.keys(C).length>0&&{config:C}}).startThread({workingDirectory:c,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),T=a&&typeof a.parse=="function",N={};if(a)try{let t=T?V(a,{target:"openAi"}):a;N.outputSchema=t,n.debug("Structured output via SDK outputSchema")}catch(t){n.warn(`[Codex] Schema conversion failed, will extract from text: ${t.message}`)}if(D?.aborted){let t=new Error("Aborted via signal");throw t.name="AbortError",t}try{let{events:t}=await U.runStreamed(e,N),g=0,d="";for await(let f of t){if(D?.aborted){let r=new Error("Aborted via signal");throw r.name="AbortError",r}let v=f.type;if(v==="item.completed"){let r=f.item,I=r?.type;if(I==="mcp_tool_call"){g++;let S=`${r.server}/${r.tool}`;if(L.stepTool(`Tool: ${S}`),r.arguments){let P=JSON.stringify(r.arguments),X=P.length>100?`${P.substring(0,100)}...`:P;console.log(` Input: ${X}`)}}else if(I==="tool_call"||I==="function_call"||I==="command_execution"){g++;let S=r.name||r.tool||r.command||"unknown";L.stepTool(`Tool: ${S}`)}else I==="agent_message"&&(d=r.text||"",d.length<500?console.log(d):console.log(`${d.substring(0,200)}... (${d.length} chars)`))}else v==="turn.completed"?n.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(f.usage||{})}`):n.debug(`[Codex] Event: ${v} ${JSON.stringify(f).slice(0,300)}`)}if(n.debug(`[Codex] Last agent message (${d.length} chars): ${d.slice(0,500)}`),a){if(!d)throw new Error("Codex agent returned no response");let f=JSON.parse(d),v=T?a.parse(f):f;return n.debug("\u2705 [Codex] Structured output validated"),{raw:d,structured:v}}return d||""}catch(t){let g=t.message||String(t);throw n.error(`\u274C [Codex] SDK call failed: ${g}`),g.includes("exited with code")&&(n.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),n.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),t}}finally{for(let E of K)E.dispose()}}_resolveSkillsToMcp(e,o={}){if(!Array.isArray(e)||e.length===0)return{};let s={};for(let c of e){let a=j(c);if(!a){n.warn(`[Codex] Unknown skill "${c}" \u2014 skipping`);continue}if(typeof a.resolve!="function")continue;let i=a.resolve(o);if(!i)continue;let O=a.serverName||c,m={command:i.command};i.args?.length&&(m.args=i.args),m.env={...process.env,...i.env||{}},s[O]=m,n.debug(`[Codex] MCP: ${O} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return s}};export{R as CodexAgentStrategy};
|
package/dist/strategies/index.js
CHANGED
|
@@ -80,7 +80,7 @@ This usually means the binary is not in PATH. Try:
|
|
|
80
80
|
`),stringified:(()=>{try{return JSON.stringify(p,Object.getOwnPropertyNames(Object(p)))}catch{return String(p)}})()};throw l.error(`Error during query stream: ${p?.message||p}`,C),p}}catch(N){throw l.error("Claude Agent SDK call failed",{message:N?.message,name:N?.name,code:N?.code,cause:N?.cause?.message||N?.cause}),N}}finally{for(let g of w)g.dispose()}}_resolveSkills(e,t){let n=["Read","Write","Edit","Bash","Grep","Glob"];if(e===null)return l.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return l.debug("Default IDE skills for code generation"),{allowedTools:[...n],mcpServers:{}};let o=[...n],r={},i=process.env.WORKFLOW_ENABLED_INTEGRATIONS,a=typeof i=="string"&&i.trim()!==""?new Set(i.split(",").map(d=>d.trim()).filter(Boolean)):null,c=d=>a!==null&&a.size>0&&qt.includes(d)&&!a.has(d);for(let d of e){if(c(d)){l.debug(`Skill "${d}" disabled by enabledIntegrations allowlist \u2014 skipping`);continue}let u=Zt(d);if(!u){l.warn(`Unknown skill "${d}" \u2014 skipping`);continue}if(u.allowedTools&&o.push(...u.allowedTools),typeof u.resolve=="function"){let h=u.resolve(t);h&&(r[u.serverName]=h,l.debug(`MCP: ${u.serverName} \u2192 ${h.command} ${h.args[0]}`))}}return{allowedTools:o,mcpServers:r}}_extractJson(e,t){let n=[()=>{if(e.includes("===JSON_START===")){let o=e.indexOf("===JSON_START===")+16,r=e.indexOf("===JSON_END===");return e.substring(o,r).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("{"),r=e.lastIndexOf("}");if(o!==-1&&r>o)return e.substring(o,r+1)}];for(let o of n)try{let r=o();if(!r)continue;let i=JSON.parse(r);if(typeof i!="object"||i===null)continue;return typeof t.parse=="function"?t.parse(i):i}catch{}return null}};function eo({message:s,sessionPath:e,nodeName:t,model:n,toolCallCount:o}){if(!e||!t)return;let r=s?.usage||s?.message?.usage||{},i=pe(r.input_tokens,r.inputTokens),a=pe(r.output_tokens,r.outputTokens),c=pe(r.cache_read_input_tokens,r.cacheReadInputTokens),d=pe(r.cache_creation_input_tokens,r.cacheCreationInputTokens),u=pe(s?.duration_ms,s?.durationMs),h={model:n||null,input_tokens:i,output_tokens:a,cache_read_tokens:c,cache_creation_tokens:d,tool_call_count:typeof o=="number"?o:null,duration_ms:u,captured_at:new Date().toISOString()},m=oe(e,t);try{Ue(m,{recursive:!0})}catch{}De(oe(m,"usage.json"),JSON.stringify(h,null,2),"utf-8")}function pe(...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 to(s,e){let t=oe(at(),".claude"),n=oe(t,".credentials.json"),o={claudeAiOauth:{accessToken:s,refreshToken:"",expiresAt:Date.now()+365*24*60*60*1e3,scopes:["user:inference","user:profile"],...e?{subscriptionType:String(e).toLowerCase()}:{}}};try{if(it(n)&&JSON.parse(lt(n,"utf-8"))?.claudeAiOauth?.accessToken===s)return;Ue(t,{recursive:!0}),De(n,JSON.stringify(o,null,2),"utf-8"),l.debug(`Wrote Claude Code OAuth credentials to ${n}`)}catch(r){l.warn(`Could not write ${n}: ${r.message} \u2014 Claude SDK may fail to authenticate.`)}}function oo(s){let e=oe(at(),".claude"),t=oe(e,".credentials.json"),n;try{n=JSON.parse(s)}catch(o){l.warn(`CLAUDE_CODE_CREDENTIALS_JSON not valid JSON: ${o.message}`);return}if(!n?.claudeAiOauth?.accessToken){l.warn("CLAUDE_CODE_CREDENTIALS_JSON missing claudeAiOauth.accessToken \u2014 skipping write.");return}try{if(it(t)){let o=JSON.parse(lt(t,"utf-8"));if(o?.claudeAiOauth?.accessToken===n.claudeAiOauth.accessToken&&o?.claudeAiOauth?.expiresAt===n.claudeAiOauth.expiresAt)return}Ue(e,{recursive:!0}),De(t,JSON.stringify(n,null,2),"utf-8"),l.debug(`Wrote full Claude Code credentials blob to ${t}`)}catch(o){l.warn(`Could not write ${t}: ${o.message} \u2014 Claude SDK may fail to authenticate.`)}}fe();import{AgentStrategy as no,getSkill as ro}from"@zibby/agent-workflow";import{execSync as so}from"node:child_process";var Ee=class extends no{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 l.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return so("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d,config:u={},signal:h=null}=t,m=[F("OPENAI_API_KEY"),F("CODEX_API_KEY")];try{let{Codex:y}=await import("@openai/codex-sdk"),E=n;(!E||E==="auto")&&(l.debug(`Model is '${E||"undefined"}', using default: ${j.CODEX}`),E=j.CODEX);let D=Me[E]||E;Me[E]&&E!==D&&l.debug(`Mapped model: ${E} \u2192 ${D}`),l.debug(`Invoking Codex SDK with model: ${D}, skills: ${JSON.stringify(i)}`);let _=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;_&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=_);let O=_?` | key: ***${_.slice(-4)}`:" | key: not set";console.log(`
|
|
81
81
|
\u25C6 Model: ${D}${O}
|
|
82
82
|
`);let S=(await import("chalk")).default;console.log(`
|
|
83
|
-
${S.bold("Prompt sent to LLM:")}`),console.log(S.dim("\u2500".repeat(60))),console.log(S.dim(e)),console.log(S.dim("\u2500".repeat(60)));let w=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),g={};Object.keys(w).length>0&&(g.mcp_servers=w,l.debug(`[Codex] MCP servers: ${Object.keys(w).join(", ")}`));let B=new y({...Object.keys(g).length>0&&{config:g}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),k=r&&typeof r.parse=="function",A={};if(r)try{let I=k?Z(r,{target:"openAi"}):r;A.outputSchema=I,l.debug("Structured output via SDK outputSchema")}catch(I){l.warn(`[Codex] Schema conversion failed, will extract from text: ${I.message}`)}if(h?.aborted){let I=new Error("Aborted via signal");throw I.name="AbortError",I}try{let{events:I}=await B.runStreamed(e,A),M=0,T="";for await(let P of I){if(h?.aborted){let R=new Error("Aborted via signal");throw R.name="AbortError",R}let N=P.type;if(N==="item.completed"){let R=P.item,J=R?.type;if(J==="mcp_tool_call"){M++;let v=`${R.server}/${R.tool}`;if(H.stepTool(`Tool: ${v}`),R.arguments){let f=JSON.stringify(R.arguments),L=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${L}`)}}else if(J==="tool_call"||J==="function_call"||J==="command_execution"){M++;let v=R.name||R.tool||R.command||"unknown";H.stepTool(`Tool: ${v}`)}else J==="agent_message"&&(T=R.text||"",T.length<500?console.log(T):console.log(`${T.substring(0,200)}... (${T.length} chars)`))}else N==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):l.debug(`[Codex] Event: ${N} ${JSON.stringify(P).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${T.length} chars): ${T.slice(0,500)}`),r){if(!T)throw new Error("Codex agent returned no response");let P=JSON.parse(T),N=k?r.parse(P):P;return l.debug("\u2705 [Codex] Structured output validated"),{raw:T,structured:N}}return T||""}catch(I){let M=I.message||String(I);throw l.error(`\u274C [Codex] SDK call failed: ${M}`),M.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),I}}finally{for(let y of m)y.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=ro(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),
|
|
83
|
+
${S.bold("Prompt sent to LLM:")}`),console.log(S.dim("\u2500".repeat(60))),console.log(S.dim(e)),console.log(S.dim("\u2500".repeat(60)));let w=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),g={};Object.keys(w).length>0&&(g.mcp_servers=w,l.debug(`[Codex] MCP servers: ${Object.keys(w).join(", ")}`));let B=new y({...Object.keys(g).length>0&&{config:g}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),k=r&&typeof r.parse=="function",A={};if(r)try{let I=k?Z(r,{target:"openAi"}):r;A.outputSchema=I,l.debug("Structured output via SDK outputSchema")}catch(I){l.warn(`[Codex] Schema conversion failed, will extract from text: ${I.message}`)}if(h?.aborted){let I=new Error("Aborted via signal");throw I.name="AbortError",I}try{let{events:I}=await B.runStreamed(e,A),M=0,T="";for await(let P of I){if(h?.aborted){let R=new Error("Aborted via signal");throw R.name="AbortError",R}let N=P.type;if(N==="item.completed"){let R=P.item,J=R?.type;if(J==="mcp_tool_call"){M++;let v=`${R.server}/${R.tool}`;if(H.stepTool(`Tool: ${v}`),R.arguments){let f=JSON.stringify(R.arguments),L=f.length>100?`${f.substring(0,100)}...`:f;console.log(` Input: ${L}`)}}else if(J==="tool_call"||J==="function_call"||J==="command_execution"){M++;let v=R.name||R.tool||R.command||"unknown";H.stepTool(`Tool: ${v}`)}else J==="agent_message"&&(T=R.text||"",T.length<500?console.log(T):console.log(`${T.substring(0,200)}... (${T.length} chars)`))}else N==="turn.completed"?l.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):l.debug(`[Codex] Event: ${N} ${JSON.stringify(P).slice(0,300)}`)}if(l.debug(`[Codex] Last agent message (${T.length} chars): ${T.slice(0,500)}`),r){if(!T)throw new Error("Codex agent returned no response");let P=JSON.parse(T),N=k?r.parse(P):P;return l.debug("\u2705 [Codex] Structured output validated"),{raw:T,structured:N}}return T||""}catch(I){let M=I.message||String(I);throw l.error(`\u274C [Codex] SDK call failed: ${M}`),M.includes("exited with code")&&(l.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),l.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),I}}finally{for(let y of m)y.dispose()}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let n={};for(let o of e){let r=ro(o);if(!r){l.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof r.resolve!="function")continue;let i=r.resolve(t);if(!i)continue;let a=r.serverName||o,c={command:i.command};i.args?.length&&(c.args=i.args),c.env={...process.env,...i.env||{}},n[a]=c,l.debug(`[Codex] MCP: ${a} \u2192 ${i.command} ${(i.args||[]).join(" ")}`)}return n}};fe();import{AgentStrategy as io,getSkill as lo}from"@zibby/agent-workflow";import{execSync as ao,spawn as co}from"node:child_process";import{existsSync as ct,mkdirSync as ut,readFileSync as dt,rmSync as uo,writeFileSync as ft}from"node:fs";import{join as q}from"node:path";function fo(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 n=e.indexOf("{");if(n<0)return null;let o=0,r=!1,i=!1,a=-1;for(let c=n;c<e.length;c++){let d=e[c];if(r){i?i=!1:d==="\\"?i=!0:d==='"'&&(r=!1);continue}if(d==='"'){r=!0;continue}if(d==="{"){o===0&&(a=c),o+=1;continue}if(d==="}"){if(o===0)continue;if(o-=1,o===0&&a>=0){let u=e.slice(a,c+1);try{return JSON.parse(u)}catch{a=-1}}}}return null}function po(s){let e=String(s||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return fo(e)}}function mo(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 n=t.content.parts.map(o=>typeof o?.text=="string"?o.text:"").join("");if(n.trim())return n}}}catch{}return s}var Ae=class extends io{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 l.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return ao("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return l.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:n,workspace:o=process.cwd(),schema:r=null,skills:i=null,sessionPath:a=null,nodeName:c=null,timeout:d=600*1e3,signal:u=null}=t,h=[F("GEMINI_API_KEY"),F("GOOGLE_API_KEY")];try{let m=n;(!m||m==="auto")&&(m=j.GEMINI);let y=Ye[m]||m,E=String(process.env.GEMINI_API_KEY||"").trim(),D=String(process.env.GOOGLE_API_KEY||"").trim(),_=this._resolveSkillsToMcp(i,{sessionPath:a,workspace:o,nodeName:c}),O=Object.keys(_).length>0,S=new ee(e),w=r&&typeof r.parse=="function",g=null;if(r){let b;try{let p=w?Z(r,{target:"openAi"}):r;b=JSON.stringify(p,null,2)}catch{b="{}"}if(O){S.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
84
|
${b}`,"schema_instruction","append");let p=`zibby-result-${Date.now()}.json`,C=q(o,".zibby","tmp");g=q(C,p),ut(C,{recursive:!0}),S.addStructuredOutput(r,g)}else S.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
85
85
|
${b}`,"json_instruction","append")}let K=S.build(),B=S.getUserPrompt(),k=S.getStats(),A=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),I=A?` | key: ***${A.slice(-4)}`:" | key: not set";console.log(`
|
|
86
86
|
\u25C6 Model: ${y||"auto"}${I}
|