@zibby/core 0.1.43 → 0.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/agents/base.js +1 -1
- package/dist/index.js +84 -84
- package/dist/package.json +2 -2
- package/dist/register-built-in-strategies.js +103 -0
- package/dist/strategies/assistant-strategy.js +1 -1
- package/dist/strategies/claude-strategy.js +1 -1
- package/dist/strategies/codex-strategy.js +1 -1
- package/dist/strategies/cursor-strategy.js +2 -2
- package/dist/strategies/gemini-strategy.js +1 -1
- package/dist/strategies/index.js +7 -7
- package/dist/utils/mcp-config-writer.js +1 -1
- package/dist/utils/run-capacity-coordinator.js +1 -1
- package/dist/utils/run-index-post-cli.js +2 -2
- package/dist/utils/run-registry.js +1 -1
- package/dist/utils/timeline.js +1 -1
- package/package.json +2 -2
- package/templates/browser-test-automation/run-index.mjs +1 -1
- package/templates/register-nodes.js +1 -1
package/dist/strategies/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as gt,DEFAULT_OUTPUT_BASE as ht,SESSION_INFO_FILE as yt,STUDIO_STOP_REQUEST_FILE as St,getAllSkills as _t,getSkill as Le}from"@zibby/workflow";import{spawn as wt,execSync as Y}from"node:child_process";import{writeFileSync as De,readFileSync as Ue,mkdirSync as Be,existsSync as te,accessSync as Je,constants as je,unlinkSync as Et}from"node:fs";import{join as J,resolve as bt}from"node:path";import{homedir as oe}from"node:os";import ee from"chalk";var j={debug:0,info:1,warn:2,error:3,silent:4},we=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return j.debug;if(process.env.ZIBBY_VERBOSE==="true")return j.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in j?j[e]:j.info}_shouldLog(e){return j[e]>=this._level}_formatMessage(e,t,r={}){let o=new Date().toISOString(),s=`${this._getPrefix(e)} ${t}`;return Object.keys(r).length>0&&(s+=ee.dim(` ${JSON.stringify(r)}`)),s}_getPrefix(e){return{debug:ee.gray("[DEBUG]"),info:ee.cyan("[INFO]"),warn:ee.yellow("[WARN]"),error:ee.red("\u274C [ERROR]")}[e]||""}debug(e,t){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,t))}info(e,t){this._shouldLog("info")&&console.log(this._formatMessage("info",e,t))}warn(e,t){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,t))}error(e,t){this._shouldLog("error")&&console.error(this._formatMessage("error",e,t))}setLevel(e){e in j&&(this._level=j[e])}getLevel(){return Object.keys(j).find(e=>j[e]===this._level)}},a=new we;var U={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 Ee={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"},be={auto:"o4-mini","o4-mini":"o4-mini",o3:"o3","o3-mini":"o3-mini","codex-mini":"codex-mini-latest","gpt-4o":"gpt-4o","gpt-4o-mini":"gpt-4o-mini","gpt-5.2-codex":"gpt-5.2-codex","gpt-5.2":"gpt-5.2","gpt-5.3":"gpt-5.3","gpt-5.4":"gpt-5.4"},Ce={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},se={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var H=class i{constructor(){this.buffer="",this.extractedResult=null,this.rawText="",this.zodSchema=null,this.lastOutputLength=0,this.onToolCall=null,this._lastToolEmit=null}processChunk(e){if(!e)return null;this.buffer+=e;let t=this.buffer.split(`
|
|
1
|
+
import{AgentStrategy as gt,DEFAULT_OUTPUT_BASE as ht,SESSION_INFO_FILE as yt,STUDIO_STOP_REQUEST_FILE as St,getAllSkills as _t,getSkill as Le}from"@zibby/agent-workflow";import{spawn as wt,execSync as Y}from"node:child_process";import{writeFileSync as De,readFileSync as Ue,mkdirSync as Be,existsSync as te,accessSync as Je,constants as je,unlinkSync as Et}from"node:fs";import{join as J,resolve as bt}from"node:path";import{homedir as oe}from"node:os";import ee from"chalk";var j={debug:0,info:1,warn:2,error:3,silent:4},we=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return j.debug;if(process.env.ZIBBY_VERBOSE==="true")return j.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in j?j[e]:j.info}_shouldLog(e){return j[e]>=this._level}_formatMessage(e,t,r={}){let o=new Date().toISOString(),s=`${this._getPrefix(e)} ${t}`;return Object.keys(r).length>0&&(s+=ee.dim(` ${JSON.stringify(r)}`)),s}_getPrefix(e){return{debug:ee.gray("[DEBUG]"),info:ee.cyan("[INFO]"),warn:ee.yellow("[WARN]"),error:ee.red("\u274C [ERROR]")}[e]||""}debug(e,t){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,t))}info(e,t){this._shouldLog("info")&&console.log(this._formatMessage("info",e,t))}warn(e,t){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,t))}error(e,t){this._shouldLog("error")&&console.error(this._formatMessage("error",e,t))}setLevel(e){e in j&&(this._level=j[e])}getLevel(){return Object.keys(j).find(e=>j[e]===this._level)}},a=new we;var U={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 Ee={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"},be={auto:"o4-mini","o4-mini":"o4-mini",o3:"o3","o3-mini":"o3-mini","codex-mini":"codex-mini-latest","gpt-4o":"gpt-4o","gpt-4o-mini":"gpt-4o-mini","gpt-5.2-codex":"gpt-5.2-codex","gpt-5.2":"gpt-5.2","gpt-5.3":"gpt-5.3","gpt-5.4":"gpt-5.4"},Ce={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},se={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var H=class i{constructor(){this.buffer="",this.extractedResult=null,this.rawText="",this.zodSchema=null,this.lastOutputLength=0,this.onToolCall=null,this._lastToolEmit=null}processChunk(e){if(!e)return null;this.buffer+=e;let t=this.buffer.split(`
|
|
2
2
|
`);this.buffer=t.pop()||"";let r="";for(let o of t)if(o.trim())try{let n=JSON.parse(o);this._emitToolCalls(n);let s=this.extractText(n);if(s){if(this.rawText&&s.startsWith(this.rawText)){let l=s.substring(this.rawText.length);this.rawText=s,r+=l}else(!this.rawText.includes(s)||s.length<20)&&(this.rawText+=s,r+=s);this.tryExtractResult(this.rawText)}else this.isValidResult(n)&&(this.rawText+=`${o}
|
|
3
3
|
`,r+=`${o}
|
|
4
4
|
`,this.extractedResult=n)}catch{if(o.includes('"text"')||o.includes('"content"')){let s=o.match(/"text"\s*:\s*"([^"]*)/),l=o.match(/"content"\s*:\s*"([^"]*)/),c=s?s[1]:l?l[1]:null;c&&!this.rawText.includes(c)&&(r+=c,this.rawText+=c)}}return r||null}flush(){if(!this.buffer.trim())return null;let e="";try{let t=JSON.parse(this.buffer);this._emitToolCalls(t);let r=this.extractText(t);r&&(this.rawText+=r,e+=r,this.tryExtractResult(r))}catch{this.rawText+=this.buffer,e+=this.buffer,this.tryExtractResult(this.buffer)}return this.buffer="",e||null}_emitToolCalls(e){if(!this.onToolCall)return;let t=(s,l)=>{if(!s)return;let c=`${s}:${JSON.stringify(l??{})}`;this._lastToolEmit!==c&&(this._lastToolEmit=c,this.onToolCall(s,l??void 0))},r=s=>{if(s!=null){if(typeof s=="object"&&!Array.isArray(s))return s;if(typeof s=="string")try{return JSON.parse(s)}catch{return}}};if(e.type==="tool_use"||e.type==="tool_call"){if(e.name){t(e.name,r(e.input??e.arguments));return}let s=e.tool_call;if(s&&typeof s=="object"&&!Array.isArray(s)){let l=Object.keys(s);if(l.length===1){let c=l[0],f=s[c],p=f&&typeof f=="object"?f.args??f.input??f:void 0;t(c,r(p))}return}return}if(Array.isArray(e.tool_calls)){for(let s of e.tool_calls)t(s.name,r(s.input??s.arguments));return}let o=e.message??e;if(Array.isArray(o?.tool_calls)){for(let s of o.tool_calls)t(s.name,r(s.input??s.arguments));return}let n=o?.content??e.content;if(Array.isArray(n))for(let s of n)(s.type==="tool_use"||s.type==="tool_call")&&s.name&&t(s.name,r(s.input??s.arguments))}extractText(e){if(e.type==="assistant"&&e.message?.content){let t=e.message.content;if(Array.isArray(t))return t.filter(r=>r.type==="text"&&r.text).map(r=>r.text).join("")}return e.type==="thinking"&&e.text||e.text?e.text:e.content&&typeof e.content=="string"?e.content:e.delta?e.delta:null}tryExtractResult(e){if(!e||typeof e!="string")return;let t=[],r=/```json\s*\n?([\s\S]*?)\n?```/g,o;for(;(o=r.exec(e))!==null;){let h=o[1].trim();try{JSON.parse(h),t.push({text:h,source:"markdown"})}catch{}}let n=0,s=0;for(;n<e.length&&(n=e.indexOf("{",n),n!==-1);){let h=0,d=n;for(let y=n;y<e.length;y++)if(e[y]==="{")h++;else if(e[y]==="}"&&(h--,h===0)){d=y,t.push({text:e.substring(n,d+1),source:"brace"}),s++;break}n=d+1}let l=this.extractedResult,c=l?JSON.stringify(l).length:0,f=0,p=-1;for(let h=0;h<t.length;h++){let d=t[h];try{let y=d.text.replace(/,(\s*[}\]])/g,"$1"),b=JSON.parse(y);this.isValidResult(b)&&(f++,c=JSON.stringify(b).length,l=b,p=h)}catch{}}l&&(this.extractedResult=l)}isValidResult(e){if(!e||typeof e!="object"||Array.isArray(e)||e.session_id||e.timestamp_ms||e.type||e.call_id||e.tool_call||e.result&&typeof e.result=="object"&&(e.result.success&&typeof e.result.success=="object"||e.result.error&&typeof e.result.error=="object")||e.args&&typeof e.args=="object")return!1;if(this.zodSchema)try{return this.zodSchema.parse(e),!0}catch{return!1}return!0}getResult(){return this.extractedResult}getRawText(){return this.rawText}static extractResult(e,t=null){let r=new i;r.zodSchema=t,r.processChunk(e),r.flush();let o=r.getResult();return!o&&process.env.LOG_LEVEL==="debug"&&console.error("[StreamingParser] No result extracted from",e?.length||0,"chars"),o}};import{zodToJsonSchema as Ve}from"zod-to-json-schema";var ie=class{static generateFileOutputInstructions(e,t){let r;typeof e?.parse=="function"?r=Ve(e,{target:"openApi3"}):r=e;let o=this._buildExample(r);return`
|
|
@@ -39,7 +39,7 @@ ${l}
|
|
|
39
39
|
|
|
40
40
|
Extract all relevant information and format it according to the schema. If any required fields are missing, do your best to infer them from the content.`,f={model:U.OPENAI_POSTPROCESSING,messages:[{role:"user",content:c}],response_format:{type:"json_schema",json_schema:{name:"extract",schema:n,strict:!0}}};a.info(`\u{1F4E4} Sending to OpenAI proxy: model=${U.OPENAI_POSTPROCESSING}, schema keys=${Object.keys(n.properties||{}).join(", ")}`),a.debug(` Schema size: ${JSON.stringify(n).length} chars`),a.debug(` Prompt size: ${c.length} chars`);try{let p={"Content-Type":"application/json"};process.env.OPENAI_PROXY_TOKEN?(p["x-proxy-token"]=t,p["x-execution-id"]=process.env.EXECUTION_ID||""):(p.Authorization=`Bearer ${t}`,p["x-api-key"]=process.env.ZIBBY_API_KEY||"",p["x-execution-id"]=process.env.EXECUTION_ID||"");let d=(await Qe.post(r,f,{headers:p,timeout:se.OPENAI_REQUEST})).data?.choices?.[0]?.message?.content;if(!d)throw new Error("OpenAI proxy returned empty response");let y=JSON.parse(d);return a.info("\u2705 Successfully formatted with OpenAI proxy"),{structured:y,raw:i}}catch(p){if(p.response){let h=p.response.status,d=p.response.data;throw a.error(`\u274C OpenAI proxy request failed: ${h}`),a.error(` Status: ${h}`),a.error(` Response: ${JSON.stringify(d,null,2)}`),h===401||h===403?new Error(`Authentication failed for OpenAI proxy.
|
|
41
41
|
Run \`zibby login\` or set ZIBBY_USER_TOKEN environment variable.
|
|
42
|
-
Response: ${JSON.stringify(d)}`,{cause:p}):new Error(`Failed to format Cursor output: ${d?.error?.message||"Unknown error"}`,{cause:p})}throw a.error(`\u274C OpenAI proxy request failed: ${p.message}`),new Error(`Failed to format output: ${p.message}`,{cause:p})}}import{timeline as K,Timeline as Oo,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as Ao}from"@zibby/workflow";import{copyFileSync as lt,existsSync as Oe,lstatSync as at,mkdirSync as Pe,rmSync as ct,symlinkSync as ut,unlinkSync as ft}from"node:fs";import{join as G}from"node:path";import{homedir as pt}from"node:os";import{randomBytes as dt}from"node:crypto";var mt=["cli-config.json","config.json","auth.json","argv.json"];function Ne(i){return!(!i||typeof i!="string"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="1"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="true")}function Re(i){let e=G(i||process.cwd(),".zibby","tmp");Pe(e,{recursive:!0});let t=`${process.pid}-${Date.now()}-${dt(4).toString("hex")}`,r=G(e,`cursor-agent-home-${t}`),o=G(r,".cursor");Pe(o,{recursive:!0});let n=pt(),s=G(n,".cursor");if(Oe(s))for(let l of mt){let c=G(s,l);if(Oe(c))try{lt(c,G(o,l))}catch{}}if(process.platform==="darwin"){let l=G(n,"Library");if(Oe(l))try{ut(l,G(r,"Library"))}catch{}}return r}function Me(i){if(!(!i||typeof i!="string"))try{let e=G(i,"Library");try{at(e).isSymbolicLink()&&ft(e)}catch{}ct(i,{recursive:!0,force:!0})}catch{}}var le=class extends gt{constructor(){super("cursor","Cursor (CLI)",100)}canHandle(e){let t=[J(oe(),".local","bin","cursor-agent"),J(oe(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"];for(let r of t)try{if(r.startsWith("/")){Je(r,je.X_OK);let o=Y(`"${r}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(o&&o.length>0)return a.debug(`[Cursor] Found agent at: ${r} (version: ${o.trim().slice(0,50)})`),!0}else{let o=Y(`which ${r}`,{encoding:"utf-8",timeout:2e3,stdio:"pipe"}).trim();if(!o)continue;let n=Y(`${r} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(n&&n.length>0)return a.debug(`[Cursor] Found '${r}' in PATH at ${o} (version: ${n.trim().slice(0,50)})`),!0}}catch{continue}return a.warn("[Cursor] \u274C Cursor Agent CLI not found or not working. Run: agent --version"),!1}async invoke(e,t={}){let{workspace:r=process.cwd(),print:o=!1,schema:n=null,skills:s=null,sessionPath:l=null,nodeName:c=null,timeout:f=se.CURSOR_AGENT_DEFAULT,config:p={}}=t,h=p?.agent?.strictMode||!1,d=t.model??p?.agent?.cursor?.model??U.CURSOR;a.debug(`[Cursor] Invoking (model: ${d}, timeout: ${f/1e3}s, skills: ${JSON.stringify(s)})`);let b=(this._setupMcpConfig(l,r,p,s,c)||{}).isolatedMcpHome??null,C=[J(oe(),".local","bin","cursor-agent"),J(oe(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"],g=null;for(let u of C)try{if(u.startsWith("/"))Je(u,je.X_OK),Y(`"${u}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});else{if(!Y(`which ${u}`,{encoding:"utf-8",timeout:2e3}).trim())throw new Error("not in PATH");Y(`${u} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"})}g=u,a.debug(`[Agent] Using binary: ${u}`);break}catch(S){a.debug(`[Agent] Binary '${u}' check failed: ${S.message}`);continue}if(!g)throw new Error(`Cursor Agent CLI not found or not working.
|
|
42
|
+
Response: ${JSON.stringify(d)}`,{cause:p}):new Error(`Failed to format Cursor output: ${d?.error?.message||"Unknown error"}`,{cause:p})}throw a.error(`\u274C OpenAI proxy request failed: ${p.message}`),new Error(`Failed to format output: ${p.message}`,{cause:p})}}import{timeline as K,Timeline as Oo,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as Ao}from"@zibby/agent-workflow";import{copyFileSync as lt,existsSync as Oe,lstatSync as at,mkdirSync as Pe,rmSync as ct,symlinkSync as ut,unlinkSync as ft}from"node:fs";import{join as G}from"node:path";import{homedir as pt}from"node:os";import{randomBytes as dt}from"node:crypto";var mt=["cli-config.json","config.json","auth.json","argv.json"];function Ne(i){return!(!i||typeof i!="string"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="1"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="true")}function Re(i){let e=G(i||process.cwd(),".zibby","tmp");Pe(e,{recursive:!0});let t=`${process.pid}-${Date.now()}-${dt(4).toString("hex")}`,r=G(e,`cursor-agent-home-${t}`),o=G(r,".cursor");Pe(o,{recursive:!0});let n=pt(),s=G(n,".cursor");if(Oe(s))for(let l of mt){let c=G(s,l);if(Oe(c))try{lt(c,G(o,l))}catch{}}if(process.platform==="darwin"){let l=G(n,"Library");if(Oe(l))try{ut(l,G(r,"Library"))}catch{}}return r}function Me(i){if(!(!i||typeof i!="string"))try{let e=G(i,"Library");try{at(e).isSymbolicLink()&&ft(e)}catch{}ct(i,{recursive:!0,force:!0})}catch{}}var le=class extends gt{constructor(){super("cursor","Cursor (CLI)",100)}canHandle(e){let t=[J(oe(),".local","bin","cursor-agent"),J(oe(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"];for(let r of t)try{if(r.startsWith("/")){Je(r,je.X_OK);let o=Y(`"${r}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(o&&o.length>0)return a.debug(`[Cursor] Found agent at: ${r} (version: ${o.trim().slice(0,50)})`),!0}else{let o=Y(`which ${r}`,{encoding:"utf-8",timeout:2e3,stdio:"pipe"}).trim();if(!o)continue;let n=Y(`${r} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(n&&n.length>0)return a.debug(`[Cursor] Found '${r}' in PATH at ${o} (version: ${n.trim().slice(0,50)})`),!0}}catch{continue}return a.warn("[Cursor] \u274C Cursor Agent CLI not found or not working. Run: agent --version"),!1}async invoke(e,t={}){let{workspace:r=process.cwd(),print:o=!1,schema:n=null,skills:s=null,sessionPath:l=null,nodeName:c=null,timeout:f=se.CURSOR_AGENT_DEFAULT,config:p={}}=t,h=p?.agent?.strictMode||!1,d=t.model??p?.agent?.cursor?.model??U.CURSOR;a.debug(`[Cursor] Invoking (model: ${d}, timeout: ${f/1e3}s, skills: ${JSON.stringify(s)})`);let b=(this._setupMcpConfig(l,r,p,s,c)||{}).isolatedMcpHome??null,C=[J(oe(),".local","bin","cursor-agent"),J(oe(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"],g=null;for(let u of C)try{if(u.startsWith("/"))Je(u,je.X_OK),Y(`"${u}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});else{if(!Y(`which ${u}`,{encoding:"utf-8",timeout:2e3}).trim())throw new Error("not in PATH");Y(`${u} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"})}g=u,a.debug(`[Agent] Using binary: ${u}`);break}catch(S){a.debug(`[Agent] Binary '${u}' check failed: ${S.message}`);continue}if(!g)throw new Error(`Cursor Agent CLI not found or not working.
|
|
43
43
|
|
|
44
44
|
Checked paths:
|
|
45
45
|
${C.map(u=>` - ${u}`).join(`
|
|
@@ -75,13 +75,13 @@ Stderr: ${d.slice(-1e3)}`:""}${h.trim()?`
|
|
|
75
75
|
Stdout (last 500 chars): ${h.slice(-500)}`:""}`));return}let L=v.getResult(),x=L?JSON.stringify(L,null,2):v.getRawText()||h||"";c({stdout:h||d||"",parsedText:x})}),_.on("error",u=>{R(),clearTimeout(I),clearInterval(m),$&&clearInterval($),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 Ot,getSkill as At}from"@zibby/workflow";import{query as xt}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Tt}from"zod-to-json-schema";var ae=class extends Ot{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY;return t||a.debug("ClaudeAgentStrategy: ANTHROPIC_API_KEY not set"),t}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,images:s=[],skills:l=null,sessionPath:c=null,nodeName:f=null,timeout:p,config:h={}}=t,d=r;(!d||d==="auto")&&(a.debug(`Model is '${d||"undefined"}', using default: ${U.CLAUDE}`),d=U.CLAUDE);let y=Ee[d]||d;Ee[d]&&d!==y&&a.debug(`Mapped model: ${d} \u2192 ${y}`),a.debug(`Invoking Claude Agent SDK with model: ${y}, skills: ${JSON.stringify(l)}`);let b=process.env.ANTHROPIC_API_KEY,C=b?` | key: ***${b.slice(-4)}`:" | key: not set";console.log(`
|
|
78
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Ot,getSkill as At}from"@zibby/agent-workflow";import{query as xt}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as Tt}from"zod-to-json-schema";var ae=class extends Ot{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY;return t||a.debug("ClaudeAgentStrategy: ANTHROPIC_API_KEY not set"),t}async invoke(e,t={}){let{model:r,workspace:o=process.cwd(),schema:n=null,images:s=[],skills:l=null,sessionPath:c=null,nodeName:f=null,timeout:p,config:h={}}=t,d=r;(!d||d==="auto")&&(a.debug(`Model is '${d||"undefined"}', using default: ${U.CLAUDE}`),d=U.CLAUDE);let y=Ee[d]||d;Ee[d]&&d!==y&&a.debug(`Mapped model: ${d} \u2192 ${y}`),a.debug(`Invoking Claude Agent SDK with model: ${y}, skills: ${JSON.stringify(l)}`);let b=process.env.ANTHROPIC_API_KEY,C=b?` | key: ***${b.slice(-4)}`:" | key: not set";console.log(`
|
|
79
79
|
\u25C6 Model: ${y}${C}
|
|
80
80
|
`);let g=(await import("chalk")).default;console.log(`
|
|
81
|
-
${g.bold("Prompt sent to LLM:")}`),console.log(g.dim("\u2500".repeat(60))),console.log(g.dim(e)),console.log(g.dim("\u2500".repeat(60)));let{allowedTools:T,mcpServers:w}=this._resolveSkills(l,{sessionPath:c,workspace:o,nodeName:f});try{let E={cwd:o,allowedTools:T,permissionMode:"bypassPermissions",model:y,...Object.keys(w).length>0&&{mcpServers:w}};if(n){let I=typeof n.parse=="function"?Tt(n,{target:"openApi3"}):n;E.outputFormat={type:"json_schema",schema:I},a.debug("Structured output enforced via SDK outputFormat")}a.debug(`Agent SDK options: ${JSON.stringify({cwd:E.cwd,toolCount:T.length,permissionMode:E.permissionMode,model:E.model,hasOutputFormat:!!E.outputFormat})}`);let k="",R=0,N=[];a.debug("Starting Claude Agent SDK query stream");let _;try{_=xt({prompt:e,options:E})}catch(m){throw a.error(`Failed to initialize Claude Agent SDK: ${m.message}`),m}let $=null,O=0,P=3;try{for await(let m of _){if(N.push(m),m.type==="error"||m.error){let v=m.error?.message||m.error||m.message||"Unknown API error";throw new Error(typeof v=="string"?v:JSON.stringify(v))}let I=JSON.stringify(m.message?.content||m.text||"").slice(0,200);if(I===$){if(O++,O>=P){let v=(m.message?.content?.[0]?.text||m.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${O}x repeated): ${v}`)}}else $=I,O=1;if(m.type==="assistant"||m.constructor?.name==="AssistantMessage"){let v=m.message?.content||m.content||[];for(let u of v)if(u.type==="thinking"&&u.thinking)console.log(`${u.thinking.substring(0,200)}${u.thinking.length>200?"...":""}`);else if(u.type==="text"&&u.text)k+=u.text,u.text.length<500?console.log(`${u.text}`):console.log(`${u.text.substring(0,200)}... (${u.text.length} chars)`);else if(u.type==="tool_use"){R++,u.name.includes("memory")?K.stepMemory(`Tool: ${u.name}`):K.stepTool(`Tool: ${u.name}`);let A=JSON.stringify(u.input).substring(0,100);console.log(` Input: ${A}${JSON.stringify(u.input).length>100?"...":""}`)}}else if(!(m.type==="user"&&m.tool_use_result)){if(m.type==="result"||m.constructor?.name==="ResultMessage"){let v=m.result||m.text||m.content||k;if(n){if(m.structured_output){a.debug("Using SDK native structured_output");let S=typeof n.parse=="function"?n.parse(m.structured_output):m.structured_output;return{raw:v,structured:S}}if(v){let u=this._extractJson(v,n);if(u)return{raw:v,structured:u}}a.warn(`Could not extract structured output \u2014 returning raw text (${(v||"").length} chars)`)}return v||""}}}if(a.warn(`Agent SDK ended without result. Collected ${N.length} messages`),k.length>0)return a.debug("Returning accumulated text from messages"),k;throw new Error("Claude Agent SDK query ended without result")}catch(m){throw a.error(`Error during query stream: ${m.message}`),m}}catch(E){throw a.error("Claude Agent SDK call failed",{error:E.message}),E}}_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 s=At(n);if(!s){a.warn(`Unknown skill "${n}" \u2014 skipping`);continue}if(s.allowedTools&&r.push(...s.allowedTools),typeof s.resolve=="function"){let l=s.resolve(t);l&&(o[s.serverName]=l,a.debug(`MCP: ${s.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 s=JSON.parse(n);if(typeof s!="object"||s===null)continue;return typeof t.parse=="function"?t.parse(s):s}catch{}return null}};import{AgentStrategy as $t,getSkill as It}from"@zibby/workflow";import{execSync as vt}from"node:child_process";import{zodToJsonSchema as Ct}from"zod-to-json-schema";var ce=class extends $t{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY))return a.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return vt("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:s=null,sessionPath:l=null,nodeName:c=null,timeout:f,config:p={}}=t,{Codex:h}=await import("@openai/codex-sdk"),d=r;(!d||d==="auto")&&(a.debug(`Model is '${d||"undefined"}', using default: ${U.CODEX}`),d=U.CODEX);let y=be[d]||d;be[d]&&d!==y&&a.debug(`Mapped model: ${d} \u2192 ${y}`),a.debug(`Invoking Codex SDK with model: ${y}, skills: ${JSON.stringify(s)}`);let b=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;b&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=b);let C=b?` | key: ***${b.slice(-4)}`:" | key: not set";console.log(`
|
|
81
|
+
${g.bold("Prompt sent to LLM:")}`),console.log(g.dim("\u2500".repeat(60))),console.log(g.dim(e)),console.log(g.dim("\u2500".repeat(60)));let{allowedTools:T,mcpServers:w}=this._resolveSkills(l,{sessionPath:c,workspace:o,nodeName:f});try{let E={cwd:o,allowedTools:T,permissionMode:"bypassPermissions",model:y,...Object.keys(w).length>0&&{mcpServers:w}};if(n){let I=typeof n.parse=="function"?Tt(n,{target:"openApi3"}):n;E.outputFormat={type:"json_schema",schema:I},a.debug("Structured output enforced via SDK outputFormat")}a.debug(`Agent SDK options: ${JSON.stringify({cwd:E.cwd,toolCount:T.length,permissionMode:E.permissionMode,model:E.model,hasOutputFormat:!!E.outputFormat})}`);let k="",R=0,N=[];a.debug("Starting Claude Agent SDK query stream");let _;try{_=xt({prompt:e,options:E})}catch(m){throw a.error(`Failed to initialize Claude Agent SDK: ${m.message}`),m}let $=null,O=0,P=3;try{for await(let m of _){if(N.push(m),m.type==="error"||m.error){let v=m.error?.message||m.error||m.message||"Unknown API error";throw new Error(typeof v=="string"?v:JSON.stringify(v))}let I=JSON.stringify(m.message?.content||m.text||"").slice(0,200);if(I===$){if(O++,O>=P){let v=(m.message?.content?.[0]?.text||m.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${O}x repeated): ${v}`)}}else $=I,O=1;if(m.type==="assistant"||m.constructor?.name==="AssistantMessage"){let v=m.message?.content||m.content||[];for(let u of v)if(u.type==="thinking"&&u.thinking)console.log(`${u.thinking.substring(0,200)}${u.thinking.length>200?"...":""}`);else if(u.type==="text"&&u.text)k+=u.text,u.text.length<500?console.log(`${u.text}`):console.log(`${u.text.substring(0,200)}... (${u.text.length} chars)`);else if(u.type==="tool_use"){R++,u.name.includes("memory")?K.stepMemory(`Tool: ${u.name}`):K.stepTool(`Tool: ${u.name}`);let A=JSON.stringify(u.input).substring(0,100);console.log(` Input: ${A}${JSON.stringify(u.input).length>100?"...":""}`)}}else if(!(m.type==="user"&&m.tool_use_result)){if(m.type==="result"||m.constructor?.name==="ResultMessage"){let v=m.result||m.text||m.content||k;if(n){if(m.structured_output){a.debug("Using SDK native structured_output");let S=typeof n.parse=="function"?n.parse(m.structured_output):m.structured_output;return{raw:v,structured:S}}if(v){let u=this._extractJson(v,n);if(u)return{raw:v,structured:u}}a.warn(`Could not extract structured output \u2014 returning raw text (${(v||"").length} chars)`)}return v||""}}}if(a.warn(`Agent SDK ended without result. Collected ${N.length} messages`),k.length>0)return a.debug("Returning accumulated text from messages"),k;throw new Error("Claude Agent SDK query ended without result")}catch(m){throw a.error(`Error during query stream: ${m.message}`),m}}catch(E){throw a.error("Claude Agent SDK call failed",{error:E.message}),E}}_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 s=At(n);if(!s){a.warn(`Unknown skill "${n}" \u2014 skipping`);continue}if(s.allowedTools&&r.push(...s.allowedTools),typeof s.resolve=="function"){let l=s.resolve(t);l&&(o[s.serverName]=l,a.debug(`MCP: ${s.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 s=JSON.parse(n);if(typeof s!="object"||s===null)continue;return typeof t.parse=="function"?t.parse(s):s}catch{}return null}};import{AgentStrategy as $t,getSkill as It}from"@zibby/agent-workflow";import{execSync as vt}from"node:child_process";import{zodToJsonSchema as Ct}from"zod-to-json-schema";var ce=class extends $t{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY))return a.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return vt("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:s=null,sessionPath:l=null,nodeName:c=null,timeout:f,config:p={}}=t,{Codex:h}=await import("@openai/codex-sdk"),d=r;(!d||d==="auto")&&(a.debug(`Model is '${d||"undefined"}', using default: ${U.CODEX}`),d=U.CODEX);let y=be[d]||d;be[d]&&d!==y&&a.debug(`Mapped model: ${d} \u2192 ${y}`),a.debug(`Invoking Codex SDK with model: ${y}, skills: ${JSON.stringify(s)}`);let b=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;b&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=b);let C=b?` | key: ***${b.slice(-4)}`:" | key: not set";console.log(`
|
|
82
82
|
\u25C6 Model: ${y}${C}
|
|
83
83
|
`);let g=(await import("chalk")).default;console.log(`
|
|
84
|
-
${g.bold("Prompt sent to LLM:")}`),console.log(g.dim("\u2500".repeat(60))),console.log(g.dim(e)),console.log(g.dim("\u2500".repeat(60)));let T=this._resolveSkillsToMcp(s,{sessionPath:l,workspace:o,nodeName:c}),w={};Object.keys(T).length>0&&(w.mcp_servers=T,a.debug(`[Codex] MCP servers: ${Object.keys(T).join(", ")}`));let k=new h({...Object.keys(w).length>0&&{config:w}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),R=n&&typeof n.parse=="function",N={};if(n)try{let _=R?Ct(n,{target:"openAi"}):n;N.outputSchema=_,a.debug("Structured output via SDK outputSchema")}catch(_){a.warn(`[Codex] Schema conversion failed, will extract from text: ${_.message}`)}try{let{events:_}=await k.runStreamed(e,N),$=0,O="";for await(let P of _){let m=P.type;if(m==="item.completed"){let I=P.item,v=I?.type;if(v==="mcp_tool_call"){$++;let u=`${I.server}/${I.tool}`;if(K.stepTool(`Tool: ${u}`),I.arguments){let S=JSON.stringify(I.arguments),A=S.length>100?`${S.substring(0,100)}...`:S;console.log(` Input: ${A}`)}}else if(v==="tool_call"||v==="function_call"||v==="command_execution"){$++;let u=I.name||I.tool||I.command||"unknown";K.stepTool(`Tool: ${u}`)}else v==="agent_message"&&(O=I.text||"",O.length<500?console.log(O):console.log(`${O.substring(0,200)}... (${O.length} chars)`))}else m==="turn.completed"?a.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):a.debug(`[Codex] Event: ${m} ${JSON.stringify(P).slice(0,300)}`)}if(a.debug(`[Codex] Last agent message (${O.length} chars): ${O.slice(0,500)}`),n){if(!O)throw new Error("Codex agent returned no response");let P=JSON.parse(O),m=R?n.parse(P):P;return a.debug("\u2705 [Codex] Structured output validated"),{raw:O,structured:m}}return O||""}catch(_){let $=_.message||String(_);throw a.error(`\u274C [Codex] SDK call failed: ${$}`),$.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")),_}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let o of e){let n=It(o);if(!n){a.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof n.resolve!="function")continue;let s=n.resolve(t);if(!s)continue;let l=n.serverName||o,c={command:s.command};s.args?.length&&(c.args=s.args),s.env&&Object.keys(s.env).length>0&&(c.env=s.env),r[l]=c,a.debug(`[Codex] MCP: ${l} \u2192 ${s.command} ${(s.args||[]).join(" ")}`)}return r}};import{AgentStrategy as kt,getSkill as Pt}from"@zibby/workflow";import{execSync as Nt,spawn as Rt}from"node:child_process";import{zodToJsonSchema as Mt}from"zod-to-json-schema";import{existsSync as Ke,mkdirSync as Ge,readFileSync as Fe,rmSync as Lt,writeFileSync as Ye}from"node:fs";import{join as z}from"node:path";function Dt(i){if(!i)return null;let e=String(i),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,s=!1,l=-1;for(let c=r;c<e.length;c++){let f=e[c];if(n){s?s=!1:f==="\\"?s=!0:f==='"'&&(n=!1);continue}if(f==='"'){n=!0;continue}if(f==="{"){o===0&&(l=c),o+=1;continue}if(f==="}"){if(o===0)continue;if(o-=1,o===0&&l>=0){let p=e.slice(l,c+1);try{return JSON.parse(p)}catch{l=-1}}}}return null}function Ut(i){let e=String(i||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return Dt(e)}}function Bt(i){try{let e=JSON.parse(i);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 i}var ue=class extends kt{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY))return a.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return Nt("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:s=null,sessionPath:l=null,nodeName:c=null,timeout:f=600*1e3}=t,p=r;(!p||p==="auto")&&(p=U.GEMINI);let h=Ce[p]||p,d=String(process.env.GEMINI_API_KEY||"").trim(),y=String(process.env.GOOGLE_API_KEY||"").trim(),b=this._resolveSkillsToMcp(s,{sessionPath:l,workspace:o,nodeName:c}),C=Object.keys(b).length>0,g=new X(e),T=n&&typeof n.parse=="function",w=null;if(n){let x;try{let M=T?Mt(n,{target:"openAi"}):n;x=JSON.stringify(M,null,2)}catch{x="{}"}if(C){g.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
84
|
+
${g.bold("Prompt sent to LLM:")}`),console.log(g.dim("\u2500".repeat(60))),console.log(g.dim(e)),console.log(g.dim("\u2500".repeat(60)));let T=this._resolveSkillsToMcp(s,{sessionPath:l,workspace:o,nodeName:c}),w={};Object.keys(T).length>0&&(w.mcp_servers=T,a.debug(`[Codex] MCP servers: ${Object.keys(T).join(", ")}`));let k=new h({...Object.keys(w).length>0&&{config:w}}).startThread({workingDirectory:o,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),R=n&&typeof n.parse=="function",N={};if(n)try{let _=R?Ct(n,{target:"openAi"}):n;N.outputSchema=_,a.debug("Structured output via SDK outputSchema")}catch(_){a.warn(`[Codex] Schema conversion failed, will extract from text: ${_.message}`)}try{let{events:_}=await k.runStreamed(e,N),$=0,O="";for await(let P of _){let m=P.type;if(m==="item.completed"){let I=P.item,v=I?.type;if(v==="mcp_tool_call"){$++;let u=`${I.server}/${I.tool}`;if(K.stepTool(`Tool: ${u}`),I.arguments){let S=JSON.stringify(I.arguments),A=S.length>100?`${S.substring(0,100)}...`:S;console.log(` Input: ${A}`)}}else if(v==="tool_call"||v==="function_call"||v==="command_execution"){$++;let u=I.name||I.tool||I.command||"unknown";K.stepTool(`Tool: ${u}`)}else v==="agent_message"&&(O=I.text||"",O.length<500?console.log(O):console.log(`${O.substring(0,200)}... (${O.length} chars)`))}else m==="turn.completed"?a.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(P.usage||{})}`):a.debug(`[Codex] Event: ${m} ${JSON.stringify(P).slice(0,300)}`)}if(a.debug(`[Codex] Last agent message (${O.length} chars): ${O.slice(0,500)}`),n){if(!O)throw new Error("Codex agent returned no response");let P=JSON.parse(O),m=R?n.parse(P):P;return a.debug("\u2705 [Codex] Structured output validated"),{raw:O,structured:m}}return O||""}catch(_){let $=_.message||String(_);throw a.error(`\u274C [Codex] SDK call failed: ${$}`),$.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")),_}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let o of e){let n=It(o);if(!n){a.warn(`[Codex] Unknown skill "${o}" \u2014 skipping`);continue}if(typeof n.resolve!="function")continue;let s=n.resolve(t);if(!s)continue;let l=n.serverName||o,c={command:s.command};s.args?.length&&(c.args=s.args),s.env&&Object.keys(s.env).length>0&&(c.env=s.env),r[l]=c,a.debug(`[Codex] MCP: ${l} \u2192 ${s.command} ${(s.args||[]).join(" ")}`)}return r}};import{AgentStrategy as kt,getSkill as Pt}from"@zibby/agent-workflow";import{execSync as Nt,spawn as Rt}from"node:child_process";import{zodToJsonSchema as Mt}from"zod-to-json-schema";import{existsSync as Ke,mkdirSync as Ge,readFileSync as Fe,rmSync as Lt,writeFileSync as Ye}from"node:fs";import{join as z}from"node:path";function Dt(i){if(!i)return null;let e=String(i),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,s=!1,l=-1;for(let c=r;c<e.length;c++){let f=e[c];if(n){s?s=!1:f==="\\"?s=!0:f==='"'&&(n=!1);continue}if(f==='"'){n=!0;continue}if(f==="{"){o===0&&(l=c),o+=1;continue}if(f==="}"){if(o===0)continue;if(o-=1,o===0&&l>=0){let p=e.slice(l,c+1);try{return JSON.parse(p)}catch{l=-1}}}}return null}function Ut(i){let e=String(i||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return Dt(e)}}function Bt(i){try{let e=JSON.parse(i);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 i}var ue=class extends kt{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY))return a.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return Nt("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:s=null,sessionPath:l=null,nodeName:c=null,timeout:f=600*1e3}=t,p=r;(!p||p==="auto")&&(p=U.GEMINI);let h=Ce[p]||p,d=String(process.env.GEMINI_API_KEY||"").trim(),y=String(process.env.GOOGLE_API_KEY||"").trim(),b=this._resolveSkillsToMcp(s,{sessionPath:l,workspace:o,nodeName:c}),C=Object.keys(b).length>0,g=new X(e),T=n&&typeof n.parse=="function",w=null;if(n){let x;try{let M=T?Mt(n,{target:"openAi"}):n;x=JSON.stringify(M,null,2)}catch{x="{}"}if(C){g.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
85
85
|
${x}`,"schema_instruction","append");let M=`zibby-result-${Date.now()}.json`,D=z(o,".zibby","tmp");w=z(D,M),Ge(D,{recursive:!0}),g.addStructuredOutput(n,w)}else g.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
86
86
|
${x}`,"json_instruction","append")}let E=g.build(),k=g.getUserPrompt(),R=g.getStats(),N=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),_=N?` | key: ***${N.slice(-4)}`:" | key: not set";console.log(`
|
|
87
87
|
\u25C6 Model: ${h||"auto"}${_}
|
|
@@ -90,7 +90,7 @@ ${$.bold("Prompt sent to LLM:")}`),console.log($.dim("\u2500".repeat(60))),conso
|
|
|
90
90
|
${S}`):a.info(`[Gemini] Raw text preview (first 1000 chars):
|
|
91
91
|
${S.slice(0,1e3)}`),A=Ut(S)),!A)throw u||(a.error("[Gemini] Failed to extract valid JSON from output"),a.error("\u{1F4A1} Tip: Set strictMode=true in .zibby.config.js for OpenAI proxy fallback"),new Error("Gemini did not return valid JSON for structured output. Enable strictMode for proxy fallback."));let L=T?n.parse(A):A;return{raw:S,structured:L}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let o of e){let n=Pt(o);if(!n||typeof n.resolve!="function")continue;let s=n.resolve(t);if(!s)continue;let l=n.cursorKey||n.serverName||o,c={command:s.command};s.args?.length&&(c.args=s.args),s.env&&Object.keys(s.env).length>0&&(c.env=s.env),s.cwd&&(c.cwd=s.cwd),r[l]=c}return r}_createGeminiConfigDir(e,t){let r=`${Date.now()}-${Math.random().toString(16).slice(2,10)}`,o=z(e||process.cwd(),".zibby","tmp",`gemini-home-${r}`),n=z(o,".gemini");Ge(n,{recursive:!0});let s=z(n,"settings.json"),l={},c=z(process.env.HOME||"",".gemini","settings.json");if(Ke(c))try{l=JSON.parse(Fe(c,"utf-8"))}catch{l={}}let f={...l,mcpServers:{...l.mcpServers&&typeof l.mcpServers=="object"?l.mcpServers:{},...t||{}}};Ye(s,`${JSON.stringify(f,null,2)}
|
|
92
92
|
`,"utf-8");let p=z(e||process.cwd(),".zibby","tmp","gemini-settings-debug.json");try{Ye(p,`${JSON.stringify(f,null,2)}
|
|
93
|
-
`,"utf-8")}catch{}return a.debug(`[Gemini] Created isolated config with ${Object.keys(f.mcpServers||{}).length} MCP servers`),a.debug(`[Gemini] MCP servers: ${JSON.stringify(Object.keys(f.mcpServers||{}),null,2)}`),o}};import{AgentStrategy as Vt,getSkill as he}from"@zibby/workflow";var re=class{formatTools(e){throw new Error("formatTools() must be implemented")}hasToolCalls(e){throw new Error("hasToolCalls() must be implemented")}parseToolCalls(e){throw new Error("parseToolCalls() must be implemented")}getTextContent(e){throw new Error("getTextContent() must be implemented")}buildAssistantMessage(e){throw new Error("buildAssistantMessage() must be implemented")}buildToolResultMessage(e,t){throw new Error("buildToolResultMessage() must be implemented")}injectToolsIntoBody(e,t){throw new Error("injectToolsIntoBody() must be implemented")}};var q=class extends re{formatTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters||t.input_schema||{type:"object",properties:{}}}}))}hasToolCalls(e){let t=e.choices?.[0]?.message;return!!(t?.tool_calls&&t.tool_calls.length>0)}parseToolCalls(e){return(e.choices?.[0]?.message?.tool_calls||[]).map(r=>({id:r.id,name:r.function.name,args:JSON.parse(r.function.arguments||"{}")}))}getTextContent(e){return e.choices?.[0]?.message?.content||""}buildAssistantMessage(e){return e.choices?.[0]?.message}buildToolResultMessage(e,t){return{role:"tool",tool_call_id:e,content:typeof t=="string"?t:JSON.stringify(t)}}injectToolsIntoBody(e,t){return t.length>0&&(e.tools=t),e}};var ne=class{async fetchCompletion(e,t,r={}){throw new Error("fetchCompletion() must be implemented")}async fetchStreamingCompletion(e,t,r={}){throw new Error("fetchStreamingCompletion() must be implemented")}};function fe(i){return Buffer.byteLength(JSON.stringify(i),"utf8")}function pe(i,e){let t=String(i||"");if(t.length<=e)return t;let r=Math.max(0,e-28);return`${t.slice(0,r)}
|
|
93
|
+
`,"utf-8")}catch{}return a.debug(`[Gemini] Created isolated config with ${Object.keys(f.mcpServers||{}).length} MCP servers`),a.debug(`[Gemini] MCP servers: ${JSON.stringify(Object.keys(f.mcpServers||{}),null,2)}`),o}};import{AgentStrategy as Vt,getSkill as he}from"@zibby/agent-workflow";var re=class{formatTools(e){throw new Error("formatTools() must be implemented")}hasToolCalls(e){throw new Error("hasToolCalls() must be implemented")}parseToolCalls(e){throw new Error("parseToolCalls() must be implemented")}getTextContent(e){throw new Error("getTextContent() must be implemented")}buildAssistantMessage(e){throw new Error("buildAssistantMessage() must be implemented")}buildToolResultMessage(e,t){throw new Error("buildToolResultMessage() must be implemented")}injectToolsIntoBody(e,t){throw new Error("injectToolsIntoBody() must be implemented")}};var q=class extends re{formatTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters||t.input_schema||{type:"object",properties:{}}}}))}hasToolCalls(e){let t=e.choices?.[0]?.message;return!!(t?.tool_calls&&t.tool_calls.length>0)}parseToolCalls(e){return(e.choices?.[0]?.message?.tool_calls||[]).map(r=>({id:r.id,name:r.function.name,args:JSON.parse(r.function.arguments||"{}")}))}getTextContent(e){return e.choices?.[0]?.message?.content||""}buildAssistantMessage(e){return e.choices?.[0]?.message}buildToolResultMessage(e,t){return{role:"tool",tool_call_id:e,content:typeof t=="string"?t:JSON.stringify(t)}}injectToolsIntoBody(e,t){return t.length>0&&(e.tools=t),e}};var ne=class{async fetchCompletion(e,t,r={}){throw new Error("fetchCompletion() must be implemented")}async fetchStreamingCompletion(e,t,r={}){throw new Error("fetchStreamingCompletion() must be implemented")}};function fe(i){return Buffer.byteLength(JSON.stringify(i),"utf8")}function pe(i,e){let t=String(i||"");if(t.length<=e)return t;let r=Math.max(0,e-28);return`${t.slice(0,r)}
|
|
94
94
|
|
|
95
95
|
[truncated for size budget]`}function Ae(i,e=0){if(!i||typeof i!="object"||e>8)return i;if(Array.isArray(i))return i.map(r=>Ae(r,e+1));let t={};for(let[r,o]of Object.entries(i))r==="description"||r==="title"||r==="examples"||r==="default"||(t[r]=Ae(o,e+1));return t}function Jt(i=[]){return i.map(e=>({...e,function:{...e.function,description:pe(e.function?.description||"",180),parameters:Ae(e.function?.parameters||{type:"object",properties:{}})}}))}function ze(i){let e=new Set;for(let o of i)if(o.role==="assistant"&&Array.isArray(o.tool_calls))for(let n of o.tool_calls)e.add(n.id);let t=i.filter(o=>o.role==="tool"?e.has(o.tool_call_id):!0),r=new Set;for(let o of t)o.role==="tool"&&r.add(o.tool_call_id);return t.map(o=>{if(o.role!=="assistant"||!Array.isArray(o.tool_calls)||o.tool_calls.every(c=>r.has(c.id)))return o;let{tool_calls:s,...l}=o;return{...l,content:l.content||""}})}function xe(i,e={}){let t=e.maxBytes||49e3,r=e.systemMaxChars||12e3,o={...i,messages:Array.isArray(i.messages)?[...i.messages]:[],tools:Array.isArray(i.tools)?Jt(i.tools):i.tools};o.messages.length>0&&o.messages[0]?.role==="system"&&(o.messages[0]={...o.messages[0],content:pe(o.messages[0].content,r)});let n=!1;for(;fe(o)>t&&o.messages.length>2;)o.messages.splice(1,1),n=!0;if(n&&(o.messages=ze(o.messages)),fe(o)>t&&o.messages.length>0&&(o.messages[0]={...o.messages[0],content:pe(o.messages[0].content,6e3)},n=!0),fe(o)>t){let s=o.messages.find(c=>c.role==="system")||o.messages[0],l=o.messages.slice(-2);o.messages=ze([s,...l].filter(Boolean).map((c,f)=>({...c,content:pe(c.content,f===0?4e3:8e3)}))),n=!0}return{body:o,meta:{bytes:fe(o),trimmed:n,maxBytes:t,messageCount:o.messages.length}}}var He=i=>Buffer.byteLength(JSON.stringify(i),"utf8"),W=class extends ne{async fetchCompletion(e,t,r={}){let o=He(e),{body:n,meta:s}=xe(e,r.payloadCompaction);r.onBudget?.({streaming:!1,beforeBytes:o,meta:s});let l=this.#e(r),c=`${t.baseUrl}${r.chatCompletionsPath||"/v1/chat/completions"}`,f=await fetch(c,{method:"POST",headers:t.headers,body:JSON.stringify(n),signal:l});if(!f.ok){let p=await f.text();throw f.status===401||f.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Proxy error ${f.status}: ${p}`)}return f.json()}async fetchStreamingCompletion(e,t,r={}){let o={...e,stream:!0},n=He(o),{body:s,meta:l}=xe(o,r.payloadCompaction);r.onBudget?.({streaming:!0,beforeBytes:n,meta:l});let c=this.#e(r),f=`${t.baseUrl}${r.chatCompletionsPath||"/v1/chat/completions"}`,p=await fetch(f,{method:"POST",headers:t.headers,body:JSON.stringify(s),signal:c});if(!p.ok){let g=await p.text();throw p.status===401||p.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Proxy error ${p.status}: ${g}`)}let h=p.body.getReader(),d=new TextDecoder,y="",b="",C=new Map;for(;;){let{done:g,value:T}=await h.read();if(g)break;y+=d.decode(T,{stream:!0});let w=y.split(`
|
|
96
96
|
`);y=w.pop();for(let E of w){if(!E.startsWith("data: "))continue;let k=E.slice(6).trim();if(k==="[DONE]")continue;let R;try{R=JSON.parse(k)}catch{continue}let N=R.choices?.[0]?.delta;if(N&&(N.content&&(b+=N.content,r.onToken&&r.onToken(N.content)),N.tool_calls))for(let _ of N.tool_calls){let $=_.index??0;C.has($)||C.set($,{id:"",name:"",args:""});let O=C.get($);_.id&&(O.id=_.id),_.function?.name&&(O.name=_.function.name),_.function?.arguments!=null&&(O.args+=_.function.arguments)}}}if(C.size>0){let g=[...C.entries()].sort(([T],[w])=>T-w).map(([,T])=>({id:T.id,type:"function",function:{name:T.name,arguments:T.args}}));return{choices:[{message:{role:"assistant",content:b||null,tool_calls:g}}]}}return{choices:[{message:{role:"assistant",content:b}}]}}#e(e={}){let t=[e.signal,e.timeout?AbortSignal.timeout(e.timeout):null].filter(Boolean);return t.length>1?AbortSignal.any(t):t[0]||void 0}};import{Client as jt}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as Kt}from"@modelcontextprotocol/sdk/client/stdio.js";var de=class{#e=new Map;async ensureServer(e,t){if(this.#e.has(e))return this.#e.get(e);let{command:r,args:o=[],env:n={}}=t;a.debug(`[MCP] Starting ${e}: ${r} ${o.join(" ")}`);let s=new Kt({command:r,args:o,env:{...process.env,...n}}),l=new jt({name:`zibby-chat-${e}`,version:"1.0.0"},{capabilities:{}});await l.connect(s);let c={client:l,transport:s,serverConfig:t};return this.#e.set(e,c),c}async callTool(e,t,r={}){let o=this.#e.get(e);if(!o)throw new Error(`MCP server "${e}" not running`);a.debug(`[MCP] ${e}.${t}(${JSON.stringify(r).slice(0,200)})`);let n=await o.client.callTool({name:t,arguments:r});return{text:n.content?.filter(l=>l.type==="text").map(l=>l.text).join(`
|
|
@@ -100,7 +100,7 @@ ${S.slice(0,1e3)}`),A=Ut(S)),!A)throw u||(a.error("[Gemini] Failed to extract va
|
|
|
100
100
|
\u{1F4D6} get_skill_context("${f}") \u2192 ${y.length} chars (fragment: ${h.length} chars)`),console.log(` tools: [${d.join(", ")}]`),console.log(` fragment preview: ${h.slice(0,200).replace(/\n/g,"\\n")}\u2026
|
|
101
101
|
`)),y}let l=n?.get(e.name)||null;if(!l)return`Unknown tool: ${e.name}`;let c=he(l.skillId);if(!c)return`Skill "${l.skillId}" not found for tool "${e.name}"`;if(l.mode==="handler")try{return c.handleToolCall(e.name,e.args,t)}catch(f){return`Error in ${e.name}: ${f.message}`}if(l.mode==="mcp")try{if(!this.#o.isRunning(c.serverName)){let p=c.resolve(o);if(!p)return`Skill "${l.skillId}" is not available (cannot start server)`;await this.#o.ensureServer(c.serverName,p)}let f=await this.#o.callTool(c.serverName,e.name,e.args);return f.text||(f.isError?"Tool call failed":"Done")}catch(f){return`MCP error (${c.serverName}): ${f.message}`}return`Skill "${l.skillId}" owns tool "${e.name}" but has no execution mode`}async#a(e,t,r){return this.#t.fetchStreamingCompletion(e,t,{...r,onBudget:({beforeBytes:o,meta:n})=>{V()&&console.log(`payload bytes (stream) before=${o} after=${n.bytes} trimmed=${n.trimmed} messages=${n.messageCount}`)}})}async#s(e,t,r){return this.#t.fetchCompletion(e,t,{...r,onBudget:({beforeBytes:o,meta:n})=>{V()&&console.log(`payload bytes before=${o} after=${n.bytes} trimmed=${n.trimmed} messages=${n.messageCount}`)}})}async#c(e,t,r,o){let{zodToJsonSchema:n}=await import("zod-to-json-schema"),s=typeof o.schema?.parse=="function",l=s?n(o.schema):o.schema;delete l.$schema,Q(l);let c={model:e,messages:t,stream:!1,response_format:{type:"json_schema",json_schema:{name:"extract",schema:l,strict:!0}}},f=await this.#s(c,r,o),p=this.#e.getTextContent(f),h=JSON.parse(p),d=s?o.schema.parse(h):h;return{raw:p,structured:d}}#u(e={}){let t=e?.config?.agent?.assistant?.payloadCompaction||{};return{maxBytes:Number(t.maxBytes||e.maxPayloadBytes||qe.maxBytes),systemMaxChars:Number(t.systemMaxChars||qe.systemMaxChars)}}#f(e={}){let t=e?.config?.agent?.assistant?.toolPolicy||{};return{allowTools:ye(t.allowTools||e.allowTools),denyTools:ye(t.denyTools||e.denyTools),denyPrefixes:oo(t.denyPrefixes||e.denyToolPrefixes),includeSkills:ye(t.includeSkills||e.includeSkills),excludeSkills:ye(t.excludeSkills||e.excludeSkills),disableSkillContextTool:!!(t.disableSkillContextTool||e.disableSkillContextTool)}}#p(e,t){let r=t?.includeSkills||new Set,o=t?.excludeSkills||new Set;return r.size===0&&o.size===0?e:e.filter(n=>!(r.size>0&&!r.has(n)||o.has(n)))}#r(e,t){let r=String(e||"").trim();if(!r)return!1;let o=t?.allowTools;if(o&&o.size>0&&!o.has(r))return!1;let n=t?.denyTools;return!(n&&n.has(r)||(t?.denyPrefixes||[]).some(l=>r.startsWith(l)))}#d(e){let t=new Map,r=[];for(let o of e){let n=he(o);if(!n?.tools?.length)continue;let s=typeof n.handleToolCall=="function"?"handler":n.serverName&&typeof n.resolve=="function"?"mcp":null;if(s)for(let l of n.tools){let c=String(l?.name||"").trim();if(c){if(t.has(c)){r.push({tool:c,winner:t.get(c).skillId,skipped:o});continue}t.set(c,{skillId:o,mode:s})}}}if(r.length>0&&V()){let o=r.slice(0,5).map(n=>`${n.tool}:${n.winner}>${n.skipped}`).join(", ");console.log(`tool registry collisions: ${o}${r.length>5?" ...":""}`)}return t}async#m(e,t,r,o){console.log(`
|
|
102
102
|
\u25C6 Model: ${t} | proxy: ${r} | token: ${o||"none"}
|
|
103
|
-
`);let n=(await import("chalk")).default;console.log(n.bold("Prompt sent to LLM:")),console.log(n.dim("\u2500".repeat(60)));let s=!1;for(let l of e)if(l.role==="system")console.log(n.dim(`[System] ${l.content||""}`));else{s||(console.log(n.dim("\u2500\u2500\u2500 chat history \u2500\u2500\u2500")),s=!0);let c=l.role==="user"?"Human":"AI",f=l.content?.length>200?`${l.content.slice(0,200)}...`:l.content||"";console.log(n.dim(`[${c}] ${f}`))}console.log(n.dim("\u2500".repeat(60)))}};import{AgentStrategy as Vr}from"@zibby/workflow";var We=[new Se,new le,new ae,new ce,new ue];function ro(i={}){let{state:e={},preferredAgent:t=null}=i,r=t||e.agentType||process.env.AGENT_TYPE;if(!r)throw new Error("No agent specified. Set agent.claude, agent.cursor, agent.codex, or agent.gemini in .zibby.config.js");a.debug(`Agent selection: requested=${r}`);let o=We.find(n=>n.getName()===r);if(!o)throw new Error(`Unknown agent '${r}'. Available: ${We.map(n=>n.getName()).join(", ")}`);if(a.debug(`Checking if ${r} can handle this environment...`),!o.canHandle(i)){let s={assistant:"Run `zibby login` to authenticate",claude:"Set ANTHROPIC_API_KEY in .env",cursor:"Install cursor-agent CLI or set CURSOR_API_KEY",codex:"Install codex CLI (npm i -g @openai/codex) and set OPENAI_API_KEY in .env",gemini:"Install gemini CLI (npm i -g @google/gemini-cli) and set GEMINI_API_KEY in .env"}[r]||"Check your environment configuration";throw new Error(`Agent '${r}' is not available. ${s}`)}return a.debug(`Using agent: ${o.getName()}`),o}async function Zr(i,e={},t={}){try{await import("@zibby/skills")}catch{}let r=ro(e),o=e.state?.config||t.config||{},n=o.models||{},s=t.nodeName&&n[t.nodeName]||null,l=n.default||null,c=r.name,f=o.agent?.[c]?.model||null,p=s||l||f||t.model||null,h={...t,model:p,workspace:e.state?.workspace||t.workspace,schema:t.schema||e.schema,images:t.images||e.images||[],skills:t.skills||e.skills||[],config:o},d=h.skills||[],y=i;if(d.length>0&&!t.skipPromptFragments){let{getSkill:C}=await import("@zibby/workflow"),g=d.map(T=>{let w=C(T)?.promptFragment;return typeof w=="function"?w():w}).filter(Boolean);g.length>0&&(y+=`
|
|
103
|
+
`);let n=(await import("chalk")).default;console.log(n.bold("Prompt sent to LLM:")),console.log(n.dim("\u2500".repeat(60)));let s=!1;for(let l of e)if(l.role==="system")console.log(n.dim(`[System] ${l.content||""}`));else{s||(console.log(n.dim("\u2500\u2500\u2500 chat history \u2500\u2500\u2500")),s=!0);let c=l.role==="user"?"Human":"AI",f=l.content?.length>200?`${l.content.slice(0,200)}...`:l.content||"";console.log(n.dim(`[${c}] ${f}`))}console.log(n.dim("\u2500".repeat(60)))}};import{AgentStrategy as Vr}from"@zibby/agent-workflow";var We=[new Se,new le,new ae,new ce,new ue];function ro(i={}){let{state:e={},preferredAgent:t=null}=i,r=t||e.agentType||process.env.AGENT_TYPE;if(!r)throw new Error("No agent specified. Set agent.claude, agent.cursor, agent.codex, or agent.gemini in .zibby.config.js");a.debug(`Agent selection: requested=${r}`);let o=We.find(n=>n.getName()===r);if(!o)throw new Error(`Unknown agent '${r}'. Available: ${We.map(n=>n.getName()).join(", ")}`);if(a.debug(`Checking if ${r} can handle this environment...`),!o.canHandle(i)){let s={assistant:"Run `zibby login` to authenticate",claude:"Set ANTHROPIC_API_KEY in .env",cursor:"Install cursor-agent CLI or set CURSOR_API_KEY",codex:"Install codex CLI (npm i -g @openai/codex) and set OPENAI_API_KEY in .env",gemini:"Install gemini CLI (npm i -g @google/gemini-cli) and set GEMINI_API_KEY in .env"}[r]||"Check your environment configuration";throw new Error(`Agent '${r}' is not available. ${s}`)}return a.debug(`Using agent: ${o.getName()}`),o}async function Zr(i,e={},t={}){try{await import("@zibby/skills")}catch{}let r=ro(e),o=e.state?.config||t.config||{},n=o.models||{},s=t.nodeName&&n[t.nodeName]||null,l=n.default||null,c=r.name,f=o.agent?.[c]?.model||null,p=s||l||f||t.model||null,h={...t,model:p,workspace:e.state?.workspace||t.workspace,schema:t.schema||e.schema,images:t.images||e.images||[],skills:t.skills||e.skills||[],config:o},d=h.skills||[],y=i;if(d.length>0&&!t.skipPromptFragments){let{getSkill:C}=await import("@zibby/agent-workflow"),g=d.map(T=>{let w=C(T)?.promptFragment;return typeof w=="function"?w():w}).filter(Boolean);g.length>0&&(y+=`
|
|
104
104
|
|
|
105
105
|
${g.join(`
|
|
106
106
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{readFileSync as C,writeFileSync as y,existsSync as a,mkdirSync as S}from"node:fs";import{join as m}from"node:path";import{homedir as d}from"node:os";import{getSkill as v}from"@zibby/workflow";var f=m(d(),".cursor","mcp.json");function k(o){let r=new Set;if(!o||typeof o!="object")return r;for(let e of Object.keys(o)){let s=o[e];if(Array.isArray(s.tools))for(let t of s.tools)r.add(t)}return r}function w(o){let r=k(o);if(r.size===0)return console.log("[MCP Config] No tools requested \u2014 skipping MCP config write"),!1;let e={mcpServers:{}};try{a(f)&&(e=JSON.parse(C(f,"utf-8")),e.mcpServers||(e.mcpServers={}))}catch(i){console.warn(`[MCP Config] Could not read existing config, starting fresh: ${i.message}`),e={mcpServers:{}}}let s=0;for(let i of r){let n=v(i);if(!n){console.log(`[MCP Config] Unknown skill "${i}" \u2014 skipping`);continue}if(e.mcpServers[n.serverName]){console.log(`[MCP Config] Server "${n.serverName}" already configured \u2014 skipping`);continue}let g={},p=!1;for(let c of n.envKeys||[]){let u=process.env[c];if(!u){console.warn(`[MCP Config] Missing env var ${c} for skill "${i}" \u2014 skipping server`),p=!0;break}g[c]=u}if(p)continue;let l=(n.args||[]).map(c=>c);if(n.command==="node"&&l.length>0&&!a(l[0])){console.warn(`[MCP Config] Binary not found at ${l[0]} for "${i}" \u2014 skipping server`);continue}e.mcpServers[n.serverName]={command:n.command,args:l,env:g,description:n.description},s++,console.log(`[MCP Config] Added "${n.serverName}" server`)}if(s===0)return console.log("[MCP Config] No new MCP servers to add"),!1;let t=m(d(),".cursor");return a(t)||S(t,{recursive:!0}),y(f,JSON.stringify(e,null,2),"utf-8"),console.log(`[MCP Config] Wrote ${f} with ${Object.keys(e.mcpServers).length} server(s)`),!0}function A(o){if(!Array.isArray(o)||o.length===0)return"";let r=[];for(let e of o){let s=v(e);if(!s)continue;let t=(s.tools||[]).map(i=>`- ${i.name}: ${i.description}`).join(`
|
|
1
|
+
import{readFileSync as C,writeFileSync as y,existsSync as a,mkdirSync as S}from"node:fs";import{join as m}from"node:path";import{homedir as d}from"node:os";import{getSkill as v}from"@zibby/agent-workflow";var f=m(d(),".cursor","mcp.json");function k(o){let r=new Set;if(!o||typeof o!="object")return r;for(let e of Object.keys(o)){let s=o[e];if(Array.isArray(s.tools))for(let t of s.tools)r.add(t)}return r}function w(o){let r=k(o);if(r.size===0)return console.log("[MCP Config] No tools requested \u2014 skipping MCP config write"),!1;let e={mcpServers:{}};try{a(f)&&(e=JSON.parse(C(f,"utf-8")),e.mcpServers||(e.mcpServers={}))}catch(i){console.warn(`[MCP Config] Could not read existing config, starting fresh: ${i.message}`),e={mcpServers:{}}}let s=0;for(let i of r){let n=v(i);if(!n){console.log(`[MCP Config] Unknown skill "${i}" \u2014 skipping`);continue}if(e.mcpServers[n.serverName]){console.log(`[MCP Config] Server "${n.serverName}" already configured \u2014 skipping`);continue}let g={},p=!1;for(let c of n.envKeys||[]){let u=process.env[c];if(!u){console.warn(`[MCP Config] Missing env var ${c} for skill "${i}" \u2014 skipping server`),p=!0;break}g[c]=u}if(p)continue;let l=(n.args||[]).map(c=>c);if(n.command==="node"&&l.length>0&&!a(l[0])){console.warn(`[MCP Config] Binary not found at ${l[0]} for "${i}" \u2014 skipping server`);continue}e.mcpServers[n.serverName]={command:n.command,args:l,env:g,description:n.description},s++,console.log(`[MCP Config] Added "${n.serverName}" server`)}if(s===0)return console.log("[MCP Config] No new MCP servers to add"),!1;let t=m(d(),".cursor");return a(t)||S(t,{recursive:!0}),y(f,JSON.stringify(e,null,2),"utf-8"),console.log(`[MCP Config] Wrote ${f} with ${Object.keys(e.mcpServers).length} server(s)`),!0}function A(o){if(!Array.isArray(o)||o.length===0)return"";let r=[];for(let e of o){let s=v(e);if(!s)continue;let t=(s.tools||[]).map(i=>`- ${i.name}: ${i.description}`).join(`
|
|
2
2
|
`);r.push(`### ${s.description}
|
|
3
3
|
${t}`)}return r.length===0?"":`
|
|
4
4
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{existsSync as G,mkdirSync as C,readFileSync as tt,rmSync as et,statSync as nt,writeFileSync as rt}from"node:fs";import{join as y}from"node:path";import{randomUUID as it}from"node:crypto";import{DEFAULT_OUTPUT_BASE as ot,SESSIONS_DIR as ut}from"@zibby/workflow";function T(t){if(!t||typeof t!="object")return 8;let e=t.parallel;if(!e||typeof e!="object")return 8;let r=e.maxConcurrentRuns??e.maxConcurrent,n=Number(r);if(!Number.isFinite(n))return 8;let i=Math.floor(n);return i<1?8:Math.min(64,i)}function g(t){if(!t||typeof t!="object")return!1;let e=t.parallel;return!(!e||typeof e!="object"||e.waitWhenAtCapacity===!1)}import{existsSync as _,mkdirSync as X,readFileSync as Q,readdirSync as v,statSync as U,writeFileSync as W}from"node:fs";import{join as w}from"node:path";function m(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return null;try{return process.kill(e,0),!0}catch(r){let n=r&&typeof r=="object"?r.code:"";return n==="ESRCH"?!1:n==="EPERM"?!0:null}}function k(t,e={}){if(!t||!_(t))return{patched:0};let r=e.studioNoPidMaxAgeMs!=null&&Number.isFinite(e.studioNoPidMaxAgeMs)?Math.max(0,e.studioNoPidMaxAgeMs):120*1e3,n=Date.now(),i=0,o;try{o=v(t)}catch{return{patched:0}}for(let s of o){let u=w(t,s),a;try{a=U(u)}catch{continue}if(!a.isDirectory())continue;let c=x(u);if(!c||c.status!=="running")continue;let l=Number(c.updatedAt)||0,S=m(c.pid),f=!1,p="";S===!1?(f=!0,p="process-exited"):S===null&&c.runSource==="studio"&&r>0&&l>0&&n-l>r&&(f=!0,p="studio-stale-no-pid"),f&&(B(u,{status:"interrupted",activeNode:null,activeStageIndex:null,exitReason:p}),i+=1)}return{patched:i}}var $="zibby-run-state.json";function F(t){return w(t,$)}function x(t){if(!t||typeof t!="string")return null;let e=F(t);if(!_(e))return null;try{let r=Q(e,"utf8"),n=JSON.parse(r);return n&&typeof n=="object"?n:null}catch{return null}}function B(t,e){if(!t||typeof t!="string")return;try{X(t,{recursive:!0})}catch{return}let n={...x(t)||{v:1},...e,v:1,updatedAt:Date.now()};try{W(F(t),`${JSON.stringify(n)}
|
|
1
|
+
import{existsSync as G,mkdirSync as C,readFileSync as tt,rmSync as et,statSync as nt,writeFileSync as rt}from"node:fs";import{join as y}from"node:path";import{randomUUID as it}from"node:crypto";import{DEFAULT_OUTPUT_BASE as ot,SESSIONS_DIR as ut}from"@zibby/agent-workflow";function T(t){if(!t||typeof t!="object")return 8;let e=t.parallel;if(!e||typeof e!="object")return 8;let r=e.maxConcurrentRuns??e.maxConcurrent,n=Number(r);if(!Number.isFinite(n))return 8;let i=Math.floor(n);return i<1?8:Math.min(64,i)}function g(t){if(!t||typeof t!="object")return!1;let e=t.parallel;return!(!e||typeof e!="object"||e.waitWhenAtCapacity===!1)}import{existsSync as _,mkdirSync as X,readFileSync as Q,readdirSync as v,statSync as U,writeFileSync as W}from"node:fs";import{join as w}from"node:path";function m(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return null;try{return process.kill(e,0),!0}catch(r){let n=r&&typeof r=="object"?r.code:"";return n==="ESRCH"?!1:n==="EPERM"?!0:null}}function k(t,e={}){if(!t||!_(t))return{patched:0};let r=e.studioNoPidMaxAgeMs!=null&&Number.isFinite(e.studioNoPidMaxAgeMs)?Math.max(0,e.studioNoPidMaxAgeMs):120*1e3,n=Date.now(),i=0,o;try{o=v(t)}catch{return{patched:0}}for(let s of o){let u=w(t,s),a;try{a=U(u)}catch{continue}if(!a.isDirectory())continue;let c=x(u);if(!c||c.status!=="running")continue;let l=Number(c.updatedAt)||0,S=m(c.pid),f=!1,p="";S===!1?(f=!0,p="process-exited"):S===null&&c.runSource==="studio"&&r>0&&l>0&&n-l>r&&(f=!0,p="studio-stale-no-pid"),f&&(B(u,{status:"interrupted",activeNode:null,activeStageIndex:null,exitReason:p}),i+=1)}return{patched:i}}var $="zibby-run-state.json";function F(t){return w(t,$)}function x(t){if(!t||typeof t!="string")return null;let e=F(t);if(!_(e))return null;try{let r=Q(e,"utf8"),n=JSON.parse(r);return n&&typeof n=="object"?n:null}catch{return null}}function B(t,e){if(!t||typeof t!="string")return;try{X(t,{recursive:!0})}catch{return}let n={...x(t)||{v:1},...e,v:1,updatedAt:Date.now()};try{W(F(t),`${JSON.stringify(n)}
|
|
2
2
|
`,"utf8")}catch(i){console.warn(`[zibby run-state] ${i.message}`)}}function I(t,e={}){if(!t||!_(t))return[];e.reconcile!==!1&&k(t,e.reconcile||{});let r=e.maxStaleMs!=null&&Number.isFinite(e.maxStaleMs)&&e.maxStaleMs>0?e.maxStaleMs:1800*1e3,n=typeof e.now=="number"?e.now:Date.now(),i;try{i=v(t)}catch{return[]}let o=[];for(let s of i){let u=w(t,s),a;try{a=U(u)}catch{continue}if(!a.isDirectory())continue;let c=x(u);if(!c||c.status!=="running")continue;let l=Number(c.updatedAt)||0;r>0&&l>0&&n-l>r||o.push({sessionId:s,sessionPathAbs:u,...c})}return o}import{existsSync as A,mkdirSync as H,readFileSync as q,renameSync as Y,unlinkSync as J,writeFileSync as z}from"node:fs";import{join as K}from"node:path";var Z="run-capacity-wait.json",d=1,V=10800*1e3;function O(t){return K(t,Z)}function N(){return{v:d,entries:[]}}function b(t){if(!t||!A(t))return N();let e=O(t);if(!A(e))return N();try{let r=q(e,"utf8"),n=JSON.parse(r);if(!n||typeof n!="object")return N();let i=Array.isArray(n.entries)?n.entries:[];return{v:d,entries:i}}catch{return N()}}function L(t,e=Date.now()){let r=t&&Array.isArray(t.entries)?t.entries:[],n=[];for(let i of r){if(!i||typeof i!="object")continue;let o=Number(i.pid),s=Number(i.updatedAt)||Number(i.enqueuedAt)||0,u=Number.isFinite(o)&&o>0?m(o):null;u!==!1&&(u===null&&s>0&&e-s>V||n.push(i))}return{v:d,entries:n}}function P(t,e){let r=O(t);H(t,{recursive:!0});let n={v:d,entries:Array.isArray(e.entries)?e.entries:[]},i=`${r}.${process.pid}.${Date.now()}.tmp`;z(i,`${JSON.stringify(n)}
|
|
3
3
|
`,"utf8");try{A(r)&&J(r)}catch{}Y(i,r)}function j(t,e){let r=L(b(t)),n=e?.id!=null?String(e.id):"";if(!n)return;let i=r.entries.filter(s=>s&&String(s.id)!==n),o=Date.now();i.push({...e,id:n,pid:Number.isFinite(Number(e.pid))?Number(e.pid):process.pid,enqueuedAt:Number(e.enqueuedAt)||o,updatedAt:o}),P(t,{v:d,entries:i})}function E(t,e){let r=e!=null?String(e):"";if(!r||!t)return;let n=L(b(t)),i=n.entries.filter(o=>o&&String(o.id)!==r);i.length!==n.entries.length&&P(t,{v:d,entries:i})}var ct=".zibby-run-capacity-guard",st=12e4;function at(t,e){let r=e?.paths?.output||ot,n=y(t,r),i=y(n,ut);return{outputAbs:n,sessionsRootAbs:i}}function R(t){try{et(t,{recursive:!0,force:!0})}catch{}}function lt(t){try{let e=tt(y(t,"owner.pid"),"utf8"),r=Number(String(e).trim());return Number.isFinite(r)&&r>0?r:null}catch{return null}}function ft(t){if(!G(t))return!0;let e=lt(t);if(e!=null){let r=m(e);if(r===!0)return!1;if(r===!1)return R(t),!0}try{let r=nt(t);if(Date.now()-r.mtimeMs>st)return R(t),!0}catch{return R(t),!0}return!1}async function pt(t,e){C(t,{recursive:!0});let r=y(t,ct);for(;;)try{C(r,{recursive:!1}),rt(y(r,"owner.pid"),String(process.pid),"utf8");try{return await e()}finally{R(r)}}catch(n){if((n&&typeof n=="object"?n.code:"")!=="EEXIST")throw n;if(ft(r))continue;await new Promise(o=>setTimeout(o,35+Math.random()*45))}}async function gt(t){let{cwd:e,config:r,meta:n={},log:i,pollMs:o=1500}=t;if(process.env.ZIBBY_WAIT_FOR_RUN_CAPACITY==="0"||process.env.ZIBBY_WAIT_FOR_RUN_CAPACITY==="false")return{waited:!1,jobId:""};if(!g(r))return{waited:!1,jobId:""};let s=T(r),{outputAbs:u,sessionsRootAbs:a}=at(e,r);C(u,{recursive:!0});let c=it(),l=n.studioTestCaseId!=null&&String(n.studioTestCaseId).trim()!==""?String(n.studioTestCaseId).trim():null,S={id:c,pid:process.pid,cwd:String(e),enqueuedAt:Date.now(),updatedAt:Date.now(),source:n.source!=null?String(n.source):"cli",specHint:n.specHint!=null&&String(n.specHint).trim()!==""?String(n.specHint).trim().slice(0,240):"",studioTestCaseId:l},f=!1,p=0,D=()=>{try{E(u,c)}catch{}};try{for(;;){let h=!1;if(await pt(u,async()=>{if(C(u,{recursive:!0}),p=I(a,{reconcile:{}}).length,p<s){E(u,c),h=!0;return}j(u,{...S,updatedAt:Date.now()})}),h)return{waited:f,jobId:c};f||(typeof i=="function"&&i(`Waiting for run capacity (${p}/${s} active)\u2026`),f=!0),await new Promise(M=>setTimeout(M,o))}}finally{D()}}export{at as resolveRunCapacityPaths,gt as waitUntilRunCapacity};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{existsSync as h,readdirSync as F,statSync as Q}from"fs";import{join as a,relative as B,sep as x,resolve as m}from"path";import{appendFileSync as z,readFileSync as H,existsSync as _,mkdirSync as $}from"node:fs";import{join as w}from"node:path";import{DEFAULT_OUTPUT_BASE as E}from"@zibby/workflow";var b="run-index.jsonl";function A(e,t=E){let n=w(e,t);return w(n,b)}function R(e){if(!e||!e.sessionId)return;let t=e.cwd||process.cwd(),n=e.outputBase||E,s=w(t,n);_(s)||$(s,{recursive:!0});let r=w(s,b),i=`${JSON.stringify(e)}
|
|
1
|
+
import{existsSync as h,readdirSync as F,statSync as Q}from"fs";import{join as a,relative as B,sep as x,resolve as m}from"path";import{appendFileSync as z,readFileSync as H,existsSync as _,mkdirSync as $}from"node:fs";import{join as w}from"node:path";import{DEFAULT_OUTPUT_BASE as E}from"@zibby/agent-workflow";var b="run-index.jsonl";function A(e,t=E){let n=w(e,t);return w(n,b)}function R(e){if(!e||!e.sessionId)return;let t=e.cwd||process.cwd(),n=e.outputBase||E,s=w(t,n);_(s)||$(s,{recursive:!0});let r=w(s,b),i=`${JSON.stringify(e)}
|
|
2
2
|
`;z(r,i,"utf8")}function D(e){if(!e||!_(e))return[];let t;try{t=H(e,"utf8")}catch{return[]}let n=[];for(let s of t.split(`
|
|
3
3
|
`)){let r=s.trim();if(r)try{n.push(JSON.parse(r))}catch{}}return n}import{existsSync as J,mkdirSync as K,readFileSync as W,readdirSync as pe,statSync as fe,writeFileSync as G}from"node:fs";import{join as V}from"node:path";var X="zibby-run-state.json";function M(e){return V(e,X)}function P(e){if(!e||typeof e!="string")return null;let t=M(e);if(!J(t))return null;try{let n=W(t,"utf8"),s=JSON.parse(n);return s&&typeof s=="object"?s:null}catch{return null}}function v(e,t){if(!e||typeof e!="string")return;try{K(e,{recursive:!0})}catch{return}let s={...P(e)||{v:1},...t,v:1,updatedAt:Date.now()};try{G(M(e),`${JSON.stringify(s)}
|
|
4
|
-
`,"utf8")}catch(r){console.warn(`[zibby run-state] ${r.message}`)}}function q(e){return e?.recordKind==="progress"}function O(e){let t=Number(e)||0;return t<=0?0:t<1e12?t*1e3:t}function C(e,t={}){let n=t.maxProgressAgeMs!=null&&Number.isFinite(t.maxProgressAgeMs)?Math.max(0,t.maxProgressAgeMs):21e5,s=typeof t.now=="number"?t.now:Date.now(),{summary:r,progress:i}=e||{};if(!i)return!1;let o=O(i.ts);if(n>0&&o>0&&s-o>n)return!1;if(!r)return o>0;let p=O(r.ts);return o>p}function k(e){let t=new Map;for(let n of e||[]){if(!n?.sessionId)continue;let s=t.get(n.sessionId);s||(s={summary:null,progress:null});let r=Number(n.ts)||0;q(n)?(!s.progress||r>=(Number(s.progress.ts)||0))&&(s.progress=n):(!s.summary||r>=(Number(s.summary.ts)||0))&&(s.summary=n),t.set(n.sessionId,s)}return t}import{DEFAULT_OUTPUT_BASE as I,SESSIONS_DIR as N}from"@zibby/workflow";var y=Object.freeze(["preflight","execute_live","generate_script"]);function T(e){let t=process.env.ZIBBY_STUDIO_TEST_CASE_ID;return t!=null&&String(t).trim()!==""?String(t).trim():e!=null?String(e):""}var ee=[a("generate_script","generated-test.spec.js"),a("generate_script","generated-test.spec.ts"),a("generate_script","playwright.spec.ts"),a("generate_script","test.spec.ts")];function te(e){let t=[a(e,"execute_live","videos"),a(e,"execute_live"),e];for(let n of t){if(!h(n))continue;let s;try{s=F(n)}catch{continue}let r=s.find(i=>i.endsWith(".webm"));if(r)return a(n,r)}return null}function ne(e){let t=[a(e,"execute_live","events.json"),a(e,"events.json")];for(let n of t)if(h(n))return n;return null}function se(e){for(let t of ee){let n=a(e,t);if(h(n))return n}return null}function re(e){return!e||!h(e)?{videoPathAbs:null,eventsPathAbs:null,scriptPathAbs:null}:{videoPathAbs:te(e),eventsPathAbs:ne(e),scriptPathAbs:se(e)}}function U(e){let t=e.cwd||process.cwd(),n=e.outputBase||I,i=((e.result||{}).state||{}).sessionPath;if(!i||typeof i!="string")return null;let o=i.split(/[/\\]/).filter(Boolean).pop();if(!o)return null;let{videoPathAbs:p,eventsPathAbs:f,scriptPathAbs:l}=re(i),d=u=>{if(!u)return null;try{return B(t,u).split(x).join("/")}catch{return null}},c=null;if(e.specPath)try{let u=m(t,e.specPath);c=B(t,u).split(x).join("/")}catch{c=String(e.specPath).split(x).join("/")}return{v:1,recordKind:"summary",ts:Date.now(),sessionId:o,status:e.status??(e.success?"completed":"failed"),cwd:t,outputBase:n,sessionPathAbs:i,sessionDirRel:d(i),videoPathAbs:p||null,eventsPathAbs:f||null,scriptPathAbs:l||null,videoRel:d(p),eventsRel:d(f),scriptRel:d(l),specRel:c,source:process.env.ZIBBY_RUN_SOURCE||"cli",studioTestCaseId:T(o)||null,errorMessage:e.errorMessage||null}}function j({cwd:e,config:t,result:n,success:s,specPath:r,errorMessage:i}){try{let o=U({cwd:e||process.cwd(),result:n,success:s,outputBase:t?.paths?.output||I,specPath:r,errorMessage:i});o&&(R(o),o.sessionPathAbs&&v(o.sessionPathAbs,{sessionId:o.sessionId,studioTestCaseId:o.studioTestCaseId||o.sessionId,status:o.status,activeNode:null,activeStageIndex:null,errorMessage:o.errorMessage||null,runSource:o.source||"cli",cwd:o.cwd,outputBase:o.outputBase,sessionPathAbs:o.sessionPathAbs}))}catch(o){console.warn(`[zibby browser-test run-index] ${o.message}`)}}function oe({sessionPath:e,sessionId:t,cwd:n,outputBase:s=I}={}){let r=n||process.cwd(),i=s||I,o=t!=null&&String(t).trim()!==""?String(t).trim():null,p=process.env.ZIBBY_RUN_SOURCE==="studio",f=process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim();if(p&&f)return m(f);let l=e&&String(e).trim();if(l)return m(l);let d=process.env.ZIBBY_SESSIONS_ROOT&&String(process.env.ZIBBY_SESSIONS_ROOT).trim();return d&&o?m(a(d,o)):process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim()?m(String(process.env.ZIBBY_SESSION_PATH).trim()):m(a(r,i,N,o||"invalid"))}function ie(e){try{let t=e?.currentNode;if(!t||!y.includes(t))return;let n=e.sessionPath,s=e.sessionId||n&&String(n).split(/[/\\]/).filter(Boolean).pop()||null;if(!s)return;let r=e.cwd||process.cwd(),i=e.outputBase||I,o=y.indexOf(t),p=e?.specPath!=null?String(e.specPath).trim():"",f=e?.taskDescription!=null?String(e.taskDescription):"",l=null;if(p)try{let c=m(r,p);l=B(r,c).split(x).join("/")}catch{l=p.split(x).join("/")}let d=oe({sessionPath:n,sessionId:s,cwd:r,outputBase:i});R({v:1,recordKind:"progress",ts:Date.now(),sessionId:s,cwd:r,outputBase:i,sessionPathAbs:d,activeNode:t,activeStageIndex:o,specRel:l,taskDescription:f||null,studioTestCaseId:T(s)||null,source:process.env.ZIBBY_RUN_SOURCE||"cli"}),v(d,{sessionId:s,studioTestCaseId:T(s)||s,status:"running",activeNode:t,activeStageIndex:o,sessionPathAbs:d,cwd:r,outputBase:i,specPath:l||null,task:f||null,taskDescription:f||null,runSource:process.env.ZIBBY_RUN_SOURCE||"cli",pid:typeof process.pid=="number"?process.pid:null})}catch(t){console.warn(`[zibby browser-test run-index progress] ${t.message}`)}}function Y({cwd:e,config:t}={}){let n=e||process.cwd(),s=t?.paths?.output||I;return r=>{ie({cwd:r?.cwd||n,outputBase:r?.outputBase||s,sessionPath:r?.sessionPath,sessionId:r?.sessionId,currentNode:r?.currentNode,specPath:r?.specPath,taskDescription:r?.taskDescription})}}function Z(e={}){try{let t=e.cwd||process.cwd(),n=e.config?.paths?.output||e.outputBase||I,s=A(t,n),r=D(s),i=k(r),o=new Set,p=e.errorMessage||"Run stopped (SIGINT/SIGTERM) before a normal summary was written.",f=(c,u)=>{if(!c||!u||o.has(c))return;o.add(c);let S=U({cwd:t,outputBase:n,result:{state:{sessionPath:u}},success:!1,specPath:null,status:"interrupted",errorMessage:p});S&&(R(S),v(u,{sessionId:c,studioTestCaseId:S.studioTestCaseId||c,status:"interrupted",activeNode:null,activeStageIndex:null,errorMessage:S.errorMessage||null,runSource:S.source||"cli",cwd:t,outputBase:n,sessionPathAbs:u}))};for(let[c,u]of i){if(!C(u))continue;let S=u.progress;if(!S)continue;let g=String(c),L=S.sessionPathAbs&&String(S.sessionPathAbs)||a(t,n,N,g);f(g,L)}let l=a(t,n,N);if(!h(l))return;let d;try{d=F(l)}catch{return}for(let c of d){let u=a(l,c),S;try{S=Q(u)}catch{continue}if(!S.isDirectory())continue;let g=P(u);!g||g.status!=="running"||f(String(c),u)}}catch(t){console.warn(`[zibby browser-test run-index interrupt] ${t.message}`)}}function Te(e){j(e)}function _e(e){Z(e)}function Ee(e){return Y(e)}export{Ee as createCliRunIndexPipelineProgressAppender,_e as postCliInterruptedRunIndex,Te as postCliRunIndex};
|
|
4
|
+
`,"utf8")}catch(r){console.warn(`[zibby run-state] ${r.message}`)}}function q(e){return e?.recordKind==="progress"}function O(e){let t=Number(e)||0;return t<=0?0:t<1e12?t*1e3:t}function C(e,t={}){let n=t.maxProgressAgeMs!=null&&Number.isFinite(t.maxProgressAgeMs)?Math.max(0,t.maxProgressAgeMs):21e5,s=typeof t.now=="number"?t.now:Date.now(),{summary:r,progress:i}=e||{};if(!i)return!1;let o=O(i.ts);if(n>0&&o>0&&s-o>n)return!1;if(!r)return o>0;let p=O(r.ts);return o>p}function k(e){let t=new Map;for(let n of e||[]){if(!n?.sessionId)continue;let s=t.get(n.sessionId);s||(s={summary:null,progress:null});let r=Number(n.ts)||0;q(n)?(!s.progress||r>=(Number(s.progress.ts)||0))&&(s.progress=n):(!s.summary||r>=(Number(s.summary.ts)||0))&&(s.summary=n),t.set(n.sessionId,s)}return t}import{DEFAULT_OUTPUT_BASE as I,SESSIONS_DIR as N}from"@zibby/agent-workflow";var y=Object.freeze(["preflight","execute_live","generate_script"]);function T(e){let t=process.env.ZIBBY_STUDIO_TEST_CASE_ID;return t!=null&&String(t).trim()!==""?String(t).trim():e!=null?String(e):""}var ee=[a("generate_script","generated-test.spec.js"),a("generate_script","generated-test.spec.ts"),a("generate_script","playwright.spec.ts"),a("generate_script","test.spec.ts")];function te(e){let t=[a(e,"execute_live","videos"),a(e,"execute_live"),e];for(let n of t){if(!h(n))continue;let s;try{s=F(n)}catch{continue}let r=s.find(i=>i.endsWith(".webm"));if(r)return a(n,r)}return null}function ne(e){let t=[a(e,"execute_live","events.json"),a(e,"events.json")];for(let n of t)if(h(n))return n;return null}function se(e){for(let t of ee){let n=a(e,t);if(h(n))return n}return null}function re(e){return!e||!h(e)?{videoPathAbs:null,eventsPathAbs:null,scriptPathAbs:null}:{videoPathAbs:te(e),eventsPathAbs:ne(e),scriptPathAbs:se(e)}}function U(e){let t=e.cwd||process.cwd(),n=e.outputBase||I,i=((e.result||{}).state||{}).sessionPath;if(!i||typeof i!="string")return null;let o=i.split(/[/\\]/).filter(Boolean).pop();if(!o)return null;let{videoPathAbs:p,eventsPathAbs:f,scriptPathAbs:l}=re(i),d=u=>{if(!u)return null;try{return B(t,u).split(x).join("/")}catch{return null}},c=null;if(e.specPath)try{let u=m(t,e.specPath);c=B(t,u).split(x).join("/")}catch{c=String(e.specPath).split(x).join("/")}return{v:1,recordKind:"summary",ts:Date.now(),sessionId:o,status:e.status??(e.success?"completed":"failed"),cwd:t,outputBase:n,sessionPathAbs:i,sessionDirRel:d(i),videoPathAbs:p||null,eventsPathAbs:f||null,scriptPathAbs:l||null,videoRel:d(p),eventsRel:d(f),scriptRel:d(l),specRel:c,source:process.env.ZIBBY_RUN_SOURCE||"cli",studioTestCaseId:T(o)||null,errorMessage:e.errorMessage||null}}function j({cwd:e,config:t,result:n,success:s,specPath:r,errorMessage:i}){try{let o=U({cwd:e||process.cwd(),result:n,success:s,outputBase:t?.paths?.output||I,specPath:r,errorMessage:i});o&&(R(o),o.sessionPathAbs&&v(o.sessionPathAbs,{sessionId:o.sessionId,studioTestCaseId:o.studioTestCaseId||o.sessionId,status:o.status,activeNode:null,activeStageIndex:null,errorMessage:o.errorMessage||null,runSource:o.source||"cli",cwd:o.cwd,outputBase:o.outputBase,sessionPathAbs:o.sessionPathAbs}))}catch(o){console.warn(`[zibby browser-test run-index] ${o.message}`)}}function oe({sessionPath:e,sessionId:t,cwd:n,outputBase:s=I}={}){let r=n||process.cwd(),i=s||I,o=t!=null&&String(t).trim()!==""?String(t).trim():null,p=process.env.ZIBBY_RUN_SOURCE==="studio",f=process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim();if(p&&f)return m(f);let l=e&&String(e).trim();if(l)return m(l);let d=process.env.ZIBBY_SESSIONS_ROOT&&String(process.env.ZIBBY_SESSIONS_ROOT).trim();return d&&o?m(a(d,o)):process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim()?m(String(process.env.ZIBBY_SESSION_PATH).trim()):m(a(r,i,N,o||"invalid"))}function ie(e){try{let t=e?.currentNode;if(!t||!y.includes(t))return;let n=e.sessionPath,s=e.sessionId||n&&String(n).split(/[/\\]/).filter(Boolean).pop()||null;if(!s)return;let r=e.cwd||process.cwd(),i=e.outputBase||I,o=y.indexOf(t),p=e?.specPath!=null?String(e.specPath).trim():"",f=e?.taskDescription!=null?String(e.taskDescription):"",l=null;if(p)try{let c=m(r,p);l=B(r,c).split(x).join("/")}catch{l=p.split(x).join("/")}let d=oe({sessionPath:n,sessionId:s,cwd:r,outputBase:i});R({v:1,recordKind:"progress",ts:Date.now(),sessionId:s,cwd:r,outputBase:i,sessionPathAbs:d,activeNode:t,activeStageIndex:o,specRel:l,taskDescription:f||null,studioTestCaseId:T(s)||null,source:process.env.ZIBBY_RUN_SOURCE||"cli"}),v(d,{sessionId:s,studioTestCaseId:T(s)||s,status:"running",activeNode:t,activeStageIndex:o,sessionPathAbs:d,cwd:r,outputBase:i,specPath:l||null,task:f||null,taskDescription:f||null,runSource:process.env.ZIBBY_RUN_SOURCE||"cli",pid:typeof process.pid=="number"?process.pid:null})}catch(t){console.warn(`[zibby browser-test run-index progress] ${t.message}`)}}function Y({cwd:e,config:t}={}){let n=e||process.cwd(),s=t?.paths?.output||I;return r=>{ie({cwd:r?.cwd||n,outputBase:r?.outputBase||s,sessionPath:r?.sessionPath,sessionId:r?.sessionId,currentNode:r?.currentNode,specPath:r?.specPath,taskDescription:r?.taskDescription})}}function Z(e={}){try{let t=e.cwd||process.cwd(),n=e.config?.paths?.output||e.outputBase||I,s=A(t,n),r=D(s),i=k(r),o=new Set,p=e.errorMessage||"Run stopped (SIGINT/SIGTERM) before a normal summary was written.",f=(c,u)=>{if(!c||!u||o.has(c))return;o.add(c);let S=U({cwd:t,outputBase:n,result:{state:{sessionPath:u}},success:!1,specPath:null,status:"interrupted",errorMessage:p});S&&(R(S),v(u,{sessionId:c,studioTestCaseId:S.studioTestCaseId||c,status:"interrupted",activeNode:null,activeStageIndex:null,errorMessage:S.errorMessage||null,runSource:S.source||"cli",cwd:t,outputBase:n,sessionPathAbs:u}))};for(let[c,u]of i){if(!C(u))continue;let S=u.progress;if(!S)continue;let g=String(c),L=S.sessionPathAbs&&String(S.sessionPathAbs)||a(t,n,N,g);f(g,L)}let l=a(t,n,N);if(!h(l))return;let d;try{d=F(l)}catch{return}for(let c of d){let u=a(l,c),S;try{S=Q(u)}catch{continue}if(!S.isDirectory())continue;let g=P(u);!g||g.status!=="running"||f(String(c),u)}}catch(t){console.warn(`[zibby browser-test run-index interrupt] ${t.message}`)}}function Te(e){j(e)}function _e(e){Z(e)}function Ee(e){return Y(e)}export{Ee as createCliRunIndexPipelineProgressAppender,_e as postCliInterruptedRunIndex,Te as postCliRunIndex};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{appendFileSync as f,readFileSync as d,existsSync as i,mkdirSync as a}from"node:fs";import{join as r}from"node:path";import{DEFAULT_OUTPUT_BASE as c}from"@zibby/workflow";var u="run-index.jsonl";function I(n,o=c){let t=r(n,o);return r(t,u)}function y(n){if(!n||!n.sessionId)return;let o=n.cwd||process.cwd(),t=n.outputBase||c,e=r(o,t);i(e)||a(e,{recursive:!0});let s=r(e,u),p=`${JSON.stringify(n)}
|
|
1
|
+
import{appendFileSync as f,readFileSync as d,existsSync as i,mkdirSync as a}from"node:fs";import{join as r}from"node:path";import{DEFAULT_OUTPUT_BASE as c}from"@zibby/agent-workflow";var u="run-index.jsonl";function I(n,o=c){let t=r(n,o);return r(t,u)}function y(n){if(!n||!n.sessionId)return;let o=n.cwd||process.cwd(),t=n.outputBase||c,e=r(o,t);i(e)||a(e,{recursive:!0});let s=r(e,u),p=`${JSON.stringify(n)}
|
|
2
2
|
`;f(s,p,"utf8")}function R(n){if(!n||!i(n))return[];let o;try{o=d(n,"utf8")}catch{return[]}let t=[];for(let e of o.split(`
|
|
3
3
|
`)){let s=e.trim();if(s)try{t.push(JSON.parse(s))}catch{}}return t}function S(n){let o=new Map;for(let t of n){if(!t?.sessionId)continue;let e=o.get(t.sessionId),s=Number(t.ts)||0;(!e||s>=(Number(e.ts)||0))&&o.set(t.sessionId,t)}return o}export{u as RUN_INDEX_FILENAME,y as appendRunIndexRecord,S as latestRunRecordsBySession,R as readRunIndexRecordsFromFile,I as resolveRunIndexPath};
|
package/dist/utils/timeline.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{timeline as i,Timeline as _,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as m}from"@zibby/workflow";export{_ as Timeline,m as WORKFLOW_GRAPH_LOG_MARKER_PREFIX,i as timeline};
|
|
1
|
+
import{timeline as i,Timeline as _,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as m}from"@zibby/agent-workflow";export{_ as Timeline,m as WORKFLOW_GRAPH_LOG_MARKER_PREFIX,i as timeline};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
4
4
|
"description": "Core test automation engine with multi-agent and multi-MCP support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"node": ">=18.0.0"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@zibby/workflow": "^0.1.
|
|
72
|
+
"@zibby/agent-workflow": "^0.1.2",
|
|
73
73
|
"@anthropic-ai/claude-agent-sdk": "^0.2.104",
|
|
74
74
|
"@anthropic-ai/sdk": "^0.88.0",
|
|
75
75
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '../../src/utils/run-registry.js';
|
|
13
13
|
import { mergeSessionRunState, readSessionRunState } from '../../src/utils/run-state-session.js';
|
|
14
14
|
import { partitionRunIndexBySession, runIndexSessionEntryIsLive } from '../../src/utils/run-index-merge.js';
|
|
15
|
-
import { DEFAULT_OUTPUT_BASE, SESSIONS_DIR } from '@zibby/workflow';
|
|
15
|
+
import { DEFAULT_OUTPUT_BASE, SESSIONS_DIR } from '@zibby/agent-workflow';
|
|
16
16
|
import { BROWSER_TEST_PIPELINE_NODE_IDS } from './pipeline-ids.js';
|
|
17
17
|
|
|
18
18
|
export { BROWSER_TEST_PIPELINE_NODE_IDS };
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Usage: import '@zibby/core/templates/register-nodes.js';
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { registerNode } from '@zibby/workflow';
|
|
10
|
+
import { registerNode } from '@zibby/agent-workflow';
|
|
11
11
|
import { setupNode } from './code-analysis/nodes/setup-node.js';
|
|
12
12
|
import { analyzeTicketNode } from './code-analysis/nodes/analyze-ticket-node.js';
|
|
13
13
|
import { generateCodeNode, implementCodeNode } from './code-analysis/nodes/generate-code-node.js';
|