@zibby/core 0.1.43 → 0.1.44
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 +11 -11
- package/dist/package.json +2 -2
- 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/README.md
CHANGED
|
@@ -108,7 +108,7 @@ const allIds = listSkillIds();
|
|
|
108
108
|
```
|
|
109
109
|
@zibby/core
|
|
110
110
|
├── src/
|
|
111
|
-
│ ├── strategies/ # Concrete agent strategies (extend AgentStrategy from @zibby/workflow)
|
|
111
|
+
│ ├── strategies/ # Concrete agent strategies (extend AgentStrategy from @zibby/agent-workflow)
|
|
112
112
|
│ │ ├── claude-strategy.js
|
|
113
113
|
│ │ ├── cursor-strategy.js
|
|
114
114
|
│ │ ├── codex-strategy.js
|
|
@@ -129,7 +129,7 @@ const allIds = listSkillIds();
|
|
|
129
129
|
│ └── index.js # Public API
|
|
130
130
|
│
|
|
131
131
|
│ # Workflow engine itself (WorkflowGraph, Node, registries, AgentStrategy
|
|
132
|
-
│ # base, timeline, etc.) lives in @zibby/workflow — core consumes it.
|
|
132
|
+
│ # base, timeline, etc.) lives in @zibby/agent-workflow — core consumes it.
|
|
133
133
|
├── templates/ # Built-in workflow templates
|
|
134
134
|
│ ├── browser-test-automation/
|
|
135
135
|
│ └── code-analysis/
|
package/dist/agents/base.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{spawn as G}from"node:child_process";import{mkdirSync as R,existsSync as D,writeFileSync as J}from"node:fs";import{join as C}from"node:path";import{ContextLoader as F,WorkflowGraph as z,Node as H,WorkflowState as U,DEFAULT_OUTPUT_BASE as k,SESSIONS_DIR as B,SESSION_INFO_FILE as V}from"@zibby/workflow";var S=class m{constructor(){this.buffer="",this.extractedResult=null,this.rawText="",this.zodSchema=null,this.lastOutputLength=0,this.onToolCall=null,this._lastToolEmit=null}processChunk(t){if(!t)return null;this.buffer+=t;let r=this.buffer.split(`
|
|
1
|
+
import{spawn as G}from"node:child_process";import{mkdirSync as R,existsSync as D,writeFileSync as J}from"node:fs";import{join as C}from"node:path";import{ContextLoader as F,WorkflowGraph as z,Node as H,WorkflowState as U,DEFAULT_OUTPUT_BASE as k,SESSIONS_DIR as B,SESSION_INFO_FILE as V}from"@zibby/agent-workflow";var S=class m{constructor(){this.buffer="",this.extractedResult=null,this.rawText="",this.zodSchema=null,this.lastOutputLength=0,this.onToolCall=null,this._lastToolEmit=null}processChunk(t){if(!t)return null;this.buffer+=t;let r=this.buffer.split(`
|
|
2
2
|
`);this.buffer=r.pop()||"";let s="";for(let o of r)if(o.trim())try{let a=JSON.parse(o);this._emitToolCalls(a);let e=this.extractText(a);if(e){if(this.rawText&&e.startsWith(this.rawText)){let n=e.substring(this.rawText.length);this.rawText=e,s+=n}else(!this.rawText.includes(e)||e.length<20)&&(this.rawText+=e,s+=e);this.tryExtractResult(this.rawText)}else this.isValidResult(a)&&(this.rawText+=`${o}
|
|
3
3
|
`,s+=`${o}
|
|
4
4
|
`,this.extractedResult=a)}catch{if(o.includes('"text"')||o.includes('"content"')){let e=o.match(/"text"\s*:\s*"([^"]*)/),n=o.match(/"content"\s*:\s*"([^"]*)/),i=e?e[1]:n?n[1]:null;i&&!this.rawText.includes(i)&&(s+=i,this.rawText+=i)}}return s||null}flush(){if(!this.buffer.trim())return null;let t="";try{let r=JSON.parse(this.buffer);this._emitToolCalls(r);let s=this.extractText(r);s&&(this.rawText+=s,t+=s,this.tryExtractResult(s))}catch{this.rawText+=this.buffer,t+=this.buffer,this.tryExtractResult(this.buffer)}return this.buffer="",t||null}_emitToolCalls(t){if(!this.onToolCall)return;let r=(e,n)=>{if(!e)return;let i=`${e}:${JSON.stringify(n??{})}`;this._lastToolEmit!==i&&(this._lastToolEmit=i,this.onToolCall(e,n??void 0))},s=e=>{if(e!=null){if(typeof e=="object"&&!Array.isArray(e))return e;if(typeof e=="string")try{return JSON.parse(e)}catch{return}}};if(t.type==="tool_use"||t.type==="tool_call"){if(t.name){r(t.name,s(t.input??t.arguments));return}let e=t.tool_call;if(e&&typeof e=="object"&&!Array.isArray(e)){let n=Object.keys(e);if(n.length===1){let i=n[0],l=e[i],d=l&&typeof l=="object"?l.args??l.input??l:void 0;r(i,s(d))}return}return}if(Array.isArray(t.tool_calls)){for(let e of t.tool_calls)r(e.name,s(e.input??e.arguments));return}let o=t.message??t;if(Array.isArray(o?.tool_calls)){for(let e of o.tool_calls)r(e.name,s(e.input??e.arguments));return}let a=o?.content??t.content;if(Array.isArray(a))for(let e of a)(e.type==="tool_use"||e.type==="tool_call")&&e.name&&r(e.name,s(e.input??e.arguments))}extractText(t){if(t.type==="assistant"&&t.message?.content){let r=t.message.content;if(Array.isArray(r))return r.filter(s=>s.type==="text"&&s.text).map(s=>s.text).join("")}return t.type==="thinking"&&t.text||t.text?t.text:t.content&&typeof t.content=="string"?t.content:t.delta?t.delta:null}tryExtractResult(t){if(!t||typeof t!="string")return;let r=[],s=/```json\s*\n?([\s\S]*?)\n?```/g,o;for(;(o=s.exec(t))!==null;){let u=o[1].trim();try{JSON.parse(u),r.push({text:u,source:"markdown"})}catch{}}let a=0,e=0;for(;a<t.length&&(a=t.indexOf("{",a),a!==-1);){let u=0,c=a;for(let f=a;f<t.length;f++)if(t[f]==="{")u++;else if(t[f]==="}"&&(u--,u===0)){c=f,r.push({text:t.substring(a,c+1),source:"brace"}),e++;break}a=c+1}let n=this.extractedResult,i=n?JSON.stringify(n).length:0,l=0,d=-1;for(let u=0;u<r.length;u++){let c=r[u];try{let f=c.text.replace(/,(\s*[}\]])/g,"$1"),p=JSON.parse(f);this.isValidResult(p)&&(l++,i=JSON.stringify(p).length,n=p,d=u)}catch{}}n&&(this.extractedResult=n)}isValidResult(t){if(!t||typeof t!="object"||Array.isArray(t)||t.session_id||t.timestamp_ms||t.type||t.call_id||t.tool_call||t.result&&typeof t.result=="object"&&(t.result.success&&typeof t.result.success=="object"||t.result.error&&typeof t.result.error=="object")||t.args&&typeof t.args=="object")return!1;if(this.zodSchema)try{return this.zodSchema.parse(t),!0}catch{return!1}return!0}getResult(){return this.extractedResult}getRawText(){return this.rawText}static extractResult(t,r=null){let s=new m;s.zodSchema=r,s.processChunk(t),s.flush();let o=s.getResult();return!o&&process.env.LOG_LEVEL==="debug"&&console.error("[StreamingParser] No result extracted from",t?.length||0,"chars"),o}};import{exec as P}from"node:child_process";import{promisify as N}from"node:util";import{existsSync as v}from"node:fs";import{join as b}from"node:path";import{homedir as A}from"node:os";var $=N(P);async function E(){try{return await $("cursor-agent --version"),"cursor-agent"}catch{let t=[b(A(),".local","bin","cursor-agent"),b(A(),".cursor","bin","cursor-agent"),b(A(),".cursor-agent","bin","cursor-agent")];for(let r of t)if(v(r))try{return await $(`"${r}" --version`),r}catch{}return null}}var O=class m{constructor(t={}){this.config=t,this.adapter=null,this.paths=t.paths||{specs:"test-specs",generated:"tests"},this.agentCommand=t.agentCommand||"cursor-agent",this.buildArgs=t.buildArgs||((r,s=!0)=>{let o=["-p",r,"--approve-mcps","--force"];return s&&(o.push("--output-format","stream-json"),o.push("--stream-partial-output")),o})}static extractJsonFromStream(t){return S.extractResult(t)}async initialize(t){this.adapter=t,t&&!t.isConnected()&&await t.connect()}buildGraph(){throw new Error("buildGraph() must be implemented by subclass")}async onComplete(t){}async run(t,r={}){let s=this.buildGraph(),o=typeof t=="object"&&!Array.isArray(t)?{input:t,...t,...r}:{input:t,...r};return await s.run(this,o)}async executeNode(t,r){let{prompt:s,outputSchema:o,model:a}=t,e=typeof s=="function"?s(r):s;console.log(`
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var zr=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});import{readFileSync as Dr,existsSync as Ur}from"node:fs";import{join as be,resolve as Br,isAbsolute as Go}from"node:path";import{DEFAULT_OUTPUT_BASE as zo,SESSIONS_DIR as Fr,RESULT_FILE as Jo,resolveWorkflowSession as Ko,clearInheritedSessionEnvForFreshRun as Yo,readStudioPinnedSessionPathFromEnv as Ho}from"@zibby/workflow";import{existsSync as xe,readdirSync as jt,statSync as en}from"fs";import{join as j,relative as st,sep as we,resolve as X}from"path";import{appendFileSync as Jr,readFileSync as Kr,existsSync as Rt,mkdirSync as Yr}from"node:fs";import{join as Be}from"node:path";import{DEFAULT_OUTPUT_BASE as Nt}from"@zibby/workflow";var kt="run-index.jsonl";function Mt(i,e=Nt){let t=Be(i,e);return Be(t,kt)}function Fe(i){if(!i||!i.sessionId)return;let e=i.cwd||process.cwd(),t=i.outputBase||Nt,r=Be(e,t);Rt(r)||Yr(r,{recursive:!0});let n=Be(r,kt),s=`${JSON.stringify(i)}
|
|
1
|
+
var zr=(i=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(i,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):i)(function(i){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+i+'" is not supported')});import{readFileSync as Dr,existsSync as Ur}from"node:fs";import{join as be,resolve as Br,isAbsolute as Go}from"node:path";import{DEFAULT_OUTPUT_BASE as zo,SESSIONS_DIR as Fr,RESULT_FILE as Jo,resolveWorkflowSession as Ko,clearInheritedSessionEnvForFreshRun as Yo,readStudioPinnedSessionPathFromEnv as Ho}from"@zibby/agent-workflow";import{existsSync as xe,readdirSync as jt,statSync as en}from"fs";import{join as j,relative as st,sep as we,resolve as X}from"path";import{appendFileSync as Jr,readFileSync as Kr,existsSync as Rt,mkdirSync as Yr}from"node:fs";import{join as Be}from"node:path";import{DEFAULT_OUTPUT_BASE as Nt}from"@zibby/agent-workflow";var kt="run-index.jsonl";function Mt(i,e=Nt){let t=Be(i,e);return Be(t,kt)}function Fe(i){if(!i||!i.sessionId)return;let e=i.cwd||process.cwd(),t=i.outputBase||Nt,r=Be(e,t);Rt(r)||Yr(r,{recursive:!0});let n=Be(r,kt),s=`${JSON.stringify(i)}
|
|
2
2
|
`;Jr(n,s,"utf8")}function Lt(i){if(!i||!Rt(i))return[];let e;try{e=Kr(i,"utf8")}catch{return[]}let t=[];for(let r of e.split(`
|
|
3
3
|
`)){let n=r.trim();if(n)try{t.push(JSON.parse(n))}catch{}}return t}import{existsSync as Hr,mkdirSync as Zr,readFileSync as Wr,readdirSync as si,statSync as oi,writeFileSync as Vr}from"node:fs";import{join as Xr}from"node:path";var qr="zibby-run-state.json";function Dt(i){return Xr(i,qr)}function rt(i){if(!i||typeof i!="string")return null;let e=Dt(i);if(!Hr(e))return null;try{let t=Wr(e,"utf8"),r=JSON.parse(t);return r&&typeof r=="object"?r:null}catch{return null}}function je(i,e){if(!i||typeof i!="string")return;try{Zr(i,{recursive:!0})}catch{return}let r={...rt(i)||{v:1},...e,v:1,updatedAt:Date.now()};try{Vr(Dt(i),`${JSON.stringify(r)}
|
|
4
|
-
`,"utf8")}catch(n){console.warn(`[zibby run-state] ${n.message}`)}}function Qr(i){return i?.recordKind==="progress"}function Ut(i){let e=Number(i)||0;return e<=0?0:e<1e12?e*1e3:e}function Bt(i,e={}){let t=e.maxProgressAgeMs!=null&&Number.isFinite(e.maxProgressAgeMs)?Math.max(0,e.maxProgressAgeMs):21e5,r=typeof e.now=="number"?e.now:Date.now(),{summary:n,progress:s}=i||{};if(!s)return!1;let o=Ut(s.ts);if(t>0&&o>0&&r-o>t)return!1;if(!n)return o>0;let c=Ut(n.ts);return o>c}function Ft(i){let e=new Map;for(let t of i||[]){if(!t?.sessionId)continue;let r=e.get(t.sessionId);r||(r={summary:null,progress:null});let n=Number(t.ts)||0;Qr(t)?(!r.progress||n>=(Number(r.progress.ts)||0))&&(r.progress=t):(!r.summary||n>=(Number(r.summary.ts)||0))&&(r.summary=t),e.set(t.sessionId,r)}return e}import{DEFAULT_OUTPUT_BASE as q,SESSIONS_DIR as ot}from"@zibby/workflow";var nt=Object.freeze(["preflight","execute_live","generate_script"]);function it(i){let e=process.env.ZIBBY_STUDIO_TEST_CASE_ID;return e!=null&&String(e).trim()!==""?String(e).trim():i!=null?String(i):""}var tn=[j("generate_script","generated-test.spec.js"),j("generate_script","generated-test.spec.ts"),j("generate_script","playwright.spec.ts"),j("generate_script","test.spec.ts")];function rn(i){let e=[j(i,"execute_live","videos"),j(i,"execute_live"),i];for(let t of e){if(!xe(t))continue;let r;try{r=jt(t)}catch{continue}let n=r.find(s=>s.endsWith(".webm"));if(n)return j(t,n)}return null}function nn(i){let e=[j(i,"execute_live","events.json"),j(i,"events.json")];for(let t of e)if(xe(t))return t;return null}function sn(i){for(let e of tn){let t=j(i,e);if(xe(t))return t}return null}function on(i){return!i||!xe(i)?{videoPathAbs:null,eventsPathAbs:null,scriptPathAbs:null}:{videoPathAbs:rn(i),eventsPathAbs:nn(i),scriptPathAbs:sn(i)}}function Gt(i){let e=i.cwd||process.cwd(),t=i.outputBase||q,s=((i.result||{}).state||{}).sessionPath;if(!s||typeof s!="string")return null;let o=s.split(/[/\\]/).filter(Boolean).pop();if(!o)return null;let{videoPathAbs:c,eventsPathAbs:l,scriptPathAbs:a}=on(s),u=d=>{if(!d)return null;try{return st(e,d).split(we).join("/")}catch{return null}},f=null;if(i.specPath)try{let d=X(e,i.specPath);f=st(e,d).split(we).join("/")}catch{f=String(i.specPath).split(we).join("/")}return{v:1,recordKind:"summary",ts:Date.now(),sessionId:o,status:i.status??(i.success?"completed":"failed"),cwd:e,outputBase:t,sessionPathAbs:s,sessionDirRel:u(s),videoPathAbs:c||null,eventsPathAbs:l||null,scriptPathAbs:a||null,videoRel:u(c),eventsRel:u(l),scriptRel:u(a),specRel:f,source:process.env.ZIBBY_RUN_SOURCE||"cli",studioTestCaseId:it(o)||null,errorMessage:i.errorMessage||null}}function zt({cwd:i,config:e,result:t,success:r,specPath:n,errorMessage:s}){try{let o=Gt({cwd:i||process.cwd(),result:t,success:r,outputBase:e?.paths?.output||q,specPath:n,errorMessage:s});o&&(Fe(o),o.sessionPathAbs&&je(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 an({sessionPath:i,sessionId:e,cwd:t,outputBase:r=q}={}){let n=t||process.cwd(),s=r||q,o=e!=null&&String(e).trim()!==""?String(e).trim():null,c=process.env.ZIBBY_RUN_SOURCE==="studio",l=process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim();if(c&&l)return X(l);let a=i&&String(i).trim();if(a)return X(a);let u=process.env.ZIBBY_SESSIONS_ROOT&&String(process.env.ZIBBY_SESSIONS_ROOT).trim();return u&&o?X(j(u,o)):process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim()?X(String(process.env.ZIBBY_SESSION_PATH).trim()):X(j(n,s,ot,o||"invalid"))}function cn(i){try{let e=i?.currentNode;if(!e||!nt.includes(e))return;let t=i.sessionPath,r=i.sessionId||t&&String(t).split(/[/\\]/).filter(Boolean).pop()||null;if(!r)return;let n=i.cwd||process.cwd(),s=i.outputBase||q,o=nt.indexOf(e),c=i?.specPath!=null?String(i.specPath).trim():"",l=i?.taskDescription!=null?String(i.taskDescription):"",a=null;if(c)try{let f=X(n,c);a=st(n,f).split(we).join("/")}catch{a=c.split(we).join("/")}let u=an({sessionPath:t,sessionId:r,cwd:n,outputBase:s});Fe({v:1,recordKind:"progress",ts:Date.now(),sessionId:r,cwd:n,outputBase:s,sessionPathAbs:u,activeNode:e,activeStageIndex:o,specRel:a,taskDescription:l||null,studioTestCaseId:it(r)||null,source:process.env.ZIBBY_RUN_SOURCE||"cli"}),je(u,{sessionId:r,studioTestCaseId:it(r)||r,status:"running",activeNode:e,activeStageIndex:o,sessionPathAbs:u,cwd:n,outputBase:s,specPath:a||null,task:l||null,taskDescription:l||null,runSource:process.env.ZIBBY_RUN_SOURCE||"cli",pid:typeof process.pid=="number"?process.pid:null})}catch(e){console.warn(`[zibby browser-test run-index progress] ${e.message}`)}}function Jt({cwd:i,config:e}={}){let t=i||process.cwd(),r=e?.paths?.output||q;return n=>{cn({cwd:n?.cwd||t,outputBase:n?.outputBase||r,sessionPath:n?.sessionPath,sessionId:n?.sessionId,currentNode:n?.currentNode,specPath:n?.specPath,taskDescription:n?.taskDescription})}}function Kt(i={}){try{let e=i.cwd||process.cwd(),t=i.config?.paths?.output||i.outputBase||q,r=Mt(e,t),n=Lt(r),s=Ft(n),o=new Set,c=i.errorMessage||"Run stopped (SIGINT/SIGTERM) before a normal summary was written.",l=(f,d)=>{if(!f||!d||o.has(f))return;o.add(f);let p=Gt({cwd:e,outputBase:t,result:{state:{sessionPath:d}},success:!1,specPath:null,status:"interrupted",errorMessage:c});p&&(Fe(p),je(d,{sessionId:f,studioTestCaseId:p.studioTestCaseId||f,status:"interrupted",activeNode:null,activeStageIndex:null,errorMessage:p.errorMessage||null,runSource:p.source||"cli",cwd:e,outputBase:t,sessionPathAbs:d}))};for(let[f,d]of s){if(!Bt(d))continue;let p=d.progress;if(!p)continue;let g=String(f),S=p.sessionPathAbs&&String(p.sessionPathAbs)||j(e,t,ot,g);l(g,S)}let a=j(e,t,ot);if(!xe(a))return;let u;try{u=jt(a)}catch{return}for(let f of u){let d=j(a,f),p;try{p=en(d)}catch{continue}if(!p.isDirectory())continue;let g=rt(d);!g||g.status!=="running"||l(String(f),d)}}catch(e){console.warn(`[zibby browser-test run-index interrupt] ${e.message}`)}}function Ge(i){zt(i)}function at(i){Kt(i)}function Yt(i){return Jt(i)}import{spawn as mn}from"node:child_process";import{mkdirSync as Zt,existsSync as gn,writeFileSync as hn}from"node:fs";import{join as pt}from"node:path";import{ContextLoader as yn,WorkflowGraph as Sn,Node as bn,WorkflowState as wn,DEFAULT_OUTPUT_BASE as Wt,SESSIONS_DIR as xn,SESSION_INFO_FILE as _n}from"@zibby/workflow";var K=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(`
|
|
4
|
+
`,"utf8")}catch(n){console.warn(`[zibby run-state] ${n.message}`)}}function Qr(i){return i?.recordKind==="progress"}function Ut(i){let e=Number(i)||0;return e<=0?0:e<1e12?e*1e3:e}function Bt(i,e={}){let t=e.maxProgressAgeMs!=null&&Number.isFinite(e.maxProgressAgeMs)?Math.max(0,e.maxProgressAgeMs):21e5,r=typeof e.now=="number"?e.now:Date.now(),{summary:n,progress:s}=i||{};if(!s)return!1;let o=Ut(s.ts);if(t>0&&o>0&&r-o>t)return!1;if(!n)return o>0;let c=Ut(n.ts);return o>c}function Ft(i){let e=new Map;for(let t of i||[]){if(!t?.sessionId)continue;let r=e.get(t.sessionId);r||(r={summary:null,progress:null});let n=Number(t.ts)||0;Qr(t)?(!r.progress||n>=(Number(r.progress.ts)||0))&&(r.progress=t):(!r.summary||n>=(Number(r.summary.ts)||0))&&(r.summary=t),e.set(t.sessionId,r)}return e}import{DEFAULT_OUTPUT_BASE as q,SESSIONS_DIR as ot}from"@zibby/agent-workflow";var nt=Object.freeze(["preflight","execute_live","generate_script"]);function it(i){let e=process.env.ZIBBY_STUDIO_TEST_CASE_ID;return e!=null&&String(e).trim()!==""?String(e).trim():i!=null?String(i):""}var tn=[j("generate_script","generated-test.spec.js"),j("generate_script","generated-test.spec.ts"),j("generate_script","playwright.spec.ts"),j("generate_script","test.spec.ts")];function rn(i){let e=[j(i,"execute_live","videos"),j(i,"execute_live"),i];for(let t of e){if(!xe(t))continue;let r;try{r=jt(t)}catch{continue}let n=r.find(s=>s.endsWith(".webm"));if(n)return j(t,n)}return null}function nn(i){let e=[j(i,"execute_live","events.json"),j(i,"events.json")];for(let t of e)if(xe(t))return t;return null}function sn(i){for(let e of tn){let t=j(i,e);if(xe(t))return t}return null}function on(i){return!i||!xe(i)?{videoPathAbs:null,eventsPathAbs:null,scriptPathAbs:null}:{videoPathAbs:rn(i),eventsPathAbs:nn(i),scriptPathAbs:sn(i)}}function Gt(i){let e=i.cwd||process.cwd(),t=i.outputBase||q,s=((i.result||{}).state||{}).sessionPath;if(!s||typeof s!="string")return null;let o=s.split(/[/\\]/).filter(Boolean).pop();if(!o)return null;let{videoPathAbs:c,eventsPathAbs:l,scriptPathAbs:a}=on(s),u=d=>{if(!d)return null;try{return st(e,d).split(we).join("/")}catch{return null}},f=null;if(i.specPath)try{let d=X(e,i.specPath);f=st(e,d).split(we).join("/")}catch{f=String(i.specPath).split(we).join("/")}return{v:1,recordKind:"summary",ts:Date.now(),sessionId:o,status:i.status??(i.success?"completed":"failed"),cwd:e,outputBase:t,sessionPathAbs:s,sessionDirRel:u(s),videoPathAbs:c||null,eventsPathAbs:l||null,scriptPathAbs:a||null,videoRel:u(c),eventsRel:u(l),scriptRel:u(a),specRel:f,source:process.env.ZIBBY_RUN_SOURCE||"cli",studioTestCaseId:it(o)||null,errorMessage:i.errorMessage||null}}function zt({cwd:i,config:e,result:t,success:r,specPath:n,errorMessage:s}){try{let o=Gt({cwd:i||process.cwd(),result:t,success:r,outputBase:e?.paths?.output||q,specPath:n,errorMessage:s});o&&(Fe(o),o.sessionPathAbs&&je(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 an({sessionPath:i,sessionId:e,cwd:t,outputBase:r=q}={}){let n=t||process.cwd(),s=r||q,o=e!=null&&String(e).trim()!==""?String(e).trim():null,c=process.env.ZIBBY_RUN_SOURCE==="studio",l=process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim();if(c&&l)return X(l);let a=i&&String(i).trim();if(a)return X(a);let u=process.env.ZIBBY_SESSIONS_ROOT&&String(process.env.ZIBBY_SESSIONS_ROOT).trim();return u&&o?X(j(u,o)):process.env.ZIBBY_SESSION_PATH&&String(process.env.ZIBBY_SESSION_PATH).trim()?X(String(process.env.ZIBBY_SESSION_PATH).trim()):X(j(n,s,ot,o||"invalid"))}function cn(i){try{let e=i?.currentNode;if(!e||!nt.includes(e))return;let t=i.sessionPath,r=i.sessionId||t&&String(t).split(/[/\\]/).filter(Boolean).pop()||null;if(!r)return;let n=i.cwd||process.cwd(),s=i.outputBase||q,o=nt.indexOf(e),c=i?.specPath!=null?String(i.specPath).trim():"",l=i?.taskDescription!=null?String(i.taskDescription):"",a=null;if(c)try{let f=X(n,c);a=st(n,f).split(we).join("/")}catch{a=c.split(we).join("/")}let u=an({sessionPath:t,sessionId:r,cwd:n,outputBase:s});Fe({v:1,recordKind:"progress",ts:Date.now(),sessionId:r,cwd:n,outputBase:s,sessionPathAbs:u,activeNode:e,activeStageIndex:o,specRel:a,taskDescription:l||null,studioTestCaseId:it(r)||null,source:process.env.ZIBBY_RUN_SOURCE||"cli"}),je(u,{sessionId:r,studioTestCaseId:it(r)||r,status:"running",activeNode:e,activeStageIndex:o,sessionPathAbs:u,cwd:n,outputBase:s,specPath:a||null,task:l||null,taskDescription:l||null,runSource:process.env.ZIBBY_RUN_SOURCE||"cli",pid:typeof process.pid=="number"?process.pid:null})}catch(e){console.warn(`[zibby browser-test run-index progress] ${e.message}`)}}function Jt({cwd:i,config:e}={}){let t=i||process.cwd(),r=e?.paths?.output||q;return n=>{cn({cwd:n?.cwd||t,outputBase:n?.outputBase||r,sessionPath:n?.sessionPath,sessionId:n?.sessionId,currentNode:n?.currentNode,specPath:n?.specPath,taskDescription:n?.taskDescription})}}function Kt(i={}){try{let e=i.cwd||process.cwd(),t=i.config?.paths?.output||i.outputBase||q,r=Mt(e,t),n=Lt(r),s=Ft(n),o=new Set,c=i.errorMessage||"Run stopped (SIGINT/SIGTERM) before a normal summary was written.",l=(f,d)=>{if(!f||!d||o.has(f))return;o.add(f);let p=Gt({cwd:e,outputBase:t,result:{state:{sessionPath:d}},success:!1,specPath:null,status:"interrupted",errorMessage:c});p&&(Fe(p),je(d,{sessionId:f,studioTestCaseId:p.studioTestCaseId||f,status:"interrupted",activeNode:null,activeStageIndex:null,errorMessage:p.errorMessage||null,runSource:p.source||"cli",cwd:e,outputBase:t,sessionPathAbs:d}))};for(let[f,d]of s){if(!Bt(d))continue;let p=d.progress;if(!p)continue;let g=String(f),S=p.sessionPathAbs&&String(p.sessionPathAbs)||j(e,t,ot,g);l(g,S)}let a=j(e,t,ot);if(!xe(a))return;let u;try{u=jt(a)}catch{return}for(let f of u){let d=j(a,f),p;try{p=en(d)}catch{continue}if(!p.isDirectory())continue;let g=rt(d);!g||g.status!=="running"||l(String(f),d)}}catch(e){console.warn(`[zibby browser-test run-index interrupt] ${e.message}`)}}function Ge(i){zt(i)}function at(i){Kt(i)}function Yt(i){return Jt(i)}import{spawn as mn}from"node:child_process";import{mkdirSync as Zt,existsSync as gn,writeFileSync as hn}from"node:fs";import{join as pt}from"node:path";import{ContextLoader as yn,WorkflowGraph as Sn,Node as bn,WorkflowState as wn,DEFAULT_OUTPUT_BASE as Wt,SESSIONS_DIR as xn,SESSION_INFO_FILE as _n}from"@zibby/agent-workflow";var K=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(`
|
|
5
5
|
`);this.buffer=t.pop()||"";let r="";for(let n of t)if(n.trim())try{let s=JSON.parse(n);this._emitToolCalls(s);let o=this.extractText(s);if(o){if(this.rawText&&o.startsWith(this.rawText)){let c=o.substring(this.rawText.length);this.rawText=o,r+=c}else(!this.rawText.includes(o)||o.length<20)&&(this.rawText+=o,r+=o);this.tryExtractResult(this.rawText)}else this.isValidResult(s)&&(this.rawText+=`${n}
|
|
6
6
|
`,r+=`${n}
|
|
7
7
|
`,this.extractedResult=s)}catch{if(n.includes('"text"')||n.includes('"content"')){let o=n.match(/"text"\s*:\s*"([^"]*)/),c=n.match(/"content"\s*:\s*"([^"]*)/),l=o?o[1]:c?c[1]:null;l&&!this.rawText.includes(l)&&(r+=l,this.rawText+=l)}}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=(o,c)=>{if(!o)return;let l=`${o}:${JSON.stringify(c??{})}`;this._lastToolEmit!==l&&(this._lastToolEmit=l,this.onToolCall(o,c??void 0))},r=o=>{if(o!=null){if(typeof o=="object"&&!Array.isArray(o))return o;if(typeof o=="string")try{return JSON.parse(o)}catch{return}}};if(e.type==="tool_use"||e.type==="tool_call"){if(e.name){t(e.name,r(e.input??e.arguments));return}let o=e.tool_call;if(o&&typeof o=="object"&&!Array.isArray(o)){let c=Object.keys(o);if(c.length===1){let l=c[0],a=o[l],u=a&&typeof a=="object"?a.args??a.input??a:void 0;t(l,r(u))}return}return}if(Array.isArray(e.tool_calls)){for(let o of e.tool_calls)t(o.name,r(o.input??o.arguments));return}let n=e.message??e;if(Array.isArray(n?.tool_calls)){for(let o of n.tool_calls)t(o.name,r(o.input??o.arguments));return}let s=n?.content??e.content;if(Array.isArray(s))for(let o of s)(o.type==="tool_use"||o.type==="tool_call")&&o.name&&t(o.name,r(o.input??o.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,n;for(;(n=r.exec(e))!==null;){let f=n[1].trim();try{JSON.parse(f),t.push({text:f,source:"markdown"})}catch{}}let s=0,o=0;for(;s<e.length&&(s=e.indexOf("{",s),s!==-1);){let f=0,d=s;for(let p=s;p<e.length;p++)if(e[p]==="{")f++;else if(e[p]==="}"&&(f--,f===0)){d=p,t.push({text:e.substring(s,d+1),source:"brace"}),o++;break}s=d+1}let c=this.extractedResult,l=c?JSON.stringify(c).length:0,a=0,u=-1;for(let f=0;f<t.length;f++){let d=t[f];try{let p=d.text.replace(/,(\s*[}\]])/g,"$1"),g=JSON.parse(p);this.isValidResult(g)&&(a++,l=JSON.stringify(g).length,c=g,u=f)}catch{}}c&&(this.extractedResult=c)}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 n=r.getResult();return!n&&process.env.LOG_LEVEL==="debug"&&console.error("[StreamingParser] No result extracted from",e?.length||0,"chars"),n}};import{exec as ln}from"node:child_process";import{promisify as un}from"node:util";import{existsSync as pn}from"node:fs";import{join as ct}from"node:path";import{homedir as lt}from"node:os";var Ht=un(ln);async function ut(){try{return await Ht("cursor-agent --version"),"cursor-agent"}catch{let e=[ct(lt(),".local","bin","cursor-agent"),ct(lt(),".cursor","bin","cursor-agent"),ct(lt(),".cursor-agent","bin","cursor-agent")];for(let t of e)if(pn(t))try{return await Ht(`"${t}" --version`),t}catch{}return null}}async function fn(){return await ut()!==null}function dn(){return`
|
|
@@ -37,7 +37,7 @@ ${JSON.stringify(l,null,2)}
|
|
|
37
37
|
${"=".repeat(80)}`),console.log(`\u{1F3AF} SINGLE NODE EXECUTION: ${e}`),console.log(`\u{1F4C1} Session: ${o.split("/").pop()}${r.sessionPath?" (reusing)":""}`),console.log(`${"=".repeat(80)}
|
|
38
38
|
`);let f=await yn.loadContext(r.specPath||"",s,r.contextConfig||{}),d=new wn({...r,sessionPath:o,sessionTimestamp:c,context:f}),g=await new bn(n).execute(this,d);return console.log(`
|
|
39
39
|
${"=".repeat(80)}`),console.log(`\u2705 Node ${e} completed`),console.log(`${"=".repeat(80)}
|
|
40
|
-
`),{success:!0,output:g.output,outputPath:r.outputPath,state:g}}calculateOutputPath(e){let{specs:t,generated:r}=this.paths;if(!e)return`${r}/generated-test.spec.js`;let n=e.replace(new RegExp(`^${t}/`),"").replace(/\.[^.]+$/,".spec.js");return`${r}/${n}`.replace(/\/+/g,"/")}};function En(i,e={}){let t=new oe(e);return t.buildGraph=function(){let r=new Sn;return i(r),r},e.onComplete&&(t.onComplete=e.onComplete),t}import{WorkflowGraph as Cu,resolveWorkflowSession as Ru,generateWorkflowSessionId as Nu,clearInheritedSessionEnvForFreshRun as ku,shouldTrustInheritedSessionEnv as Mu,readStudioPinnedSessionPathFromEnv as Lu,syncProcessEnvToSession as Du}from"@zibby/workflow";import{writeFileSync as Vt,existsSync as Tn,mkdirSync as vn}from"node:fs";import{join as ft}from"node:path";import _e from"chalk";var G={debug:0,info:1,warn:2,error:3,silent:4},ze=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return G.debug;if(process.env.ZIBBY_VERBOSE==="true")return G.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in G?G[e]:G.info}_shouldLog(e){return G[e]>=this._level}_formatMessage(e,t,r={}){let n=new Date().toISOString(),o=`${this._getPrefix(e)} ${t}`;return Object.keys(r).length>0&&(o+=_e.dim(` ${JSON.stringify(r)}`)),o}_getPrefix(e){return{debug:_e.gray("[DEBUG]"),info:_e.cyan("[INFO]"),warn:_e.yellow("[WARN]"),error:_e.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 G&&(this._level=G[e])}getLevel(){return Object.keys(G).find(e=>G[e]===this._level)}},m=new ze;var dt=class i{static saveTitle(e,t){let r=e.state.sessionPath;if(!r)return;let n=i._findInState(e.state,"title")||i._findInState(e.state,"result");if(!(!n||typeof n!="string"))try{let s=ft(r,"title.txt");Vt(s,n,"utf-8"),m.info(`Saved title to session: "${n}"`)}catch(s){console.warn("\u26A0\uFE0F Could not save title file:",s.message)}}static _findInState(e,t){for(let[,r]of Object.entries(e))if(r&&typeof r=="object"&&r[t]!==void 0)return r[t]}static async saveExecutionData(e){let t=e.state.sessionPath;if(t)for(let[r,n]of Object.entries(e.state)){if(!n||typeof n!="object")continue;let s=Array.isArray(n.actions)&&n.actions.length>0,o=typeof n.scriptPath=="string"&&n.scriptPath.trim().length>0;if(!(!s&&!o))try{let c=ft(t,r);Tn(c)||vn(c,{recursive:!0});let l=ft(c,"result.json");Vt(l,JSON.stringify(n,null,2),"utf-8"),m.info(`Saved execution data to ${r} folder`),await this.onNodeSaved(c,n)}catch(c){console.warn(`\u26A0\uFE0F Could not save execution data for ${r}:`,c.message)}}}static async onNodeSaved(e,t){}static logResult(e,t){let r=Object.entries(e.state).filter(([,o])=>o&&typeof o=="object"&&o.success!==void 0),n=r.length>0&&r.every(([,o])=>o.success),s=r.some(([,o])=>o.success===!1);if(n)m.info("Workflow completed successfully."),t&&m.info(`Output: ${t}`);else if(s){let o=r.filter(([,c])=>!c.success).map(([c])=>c);m.info(`Workflow completed with failures in: ${o.join(", ")}`),t&&m.info(`Output: ${t}`)}return n}static handle(e,t,r){return this.saveTitle(e,t),this.saveExecutionData(e),this.logResult(e,r)}};import{z as Fu}from"zod/v3";import{AgentStrategy as Kn,DEFAULT_OUTPUT_BASE as Yn,SESSION_INFO_FILE as Hn,STUDIO_STOP_REQUEST_FILE as Zn,getAllSkills as Wn,getSkill as nr}from"@zibby/workflow";import{spawn as Vn,execSync as Q}from"node:child_process";import{writeFileSync as sr,readFileSync as or,mkdirSync as ir,existsSync as Ee,accessSync as ar,constants as cr,unlinkSync as Xn}from"node:fs";import{join as z,resolve as qn}from"node:path";import{homedir as Te}from"node:os";var B={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"},$n={ASSISTANT:"assistant",CLAUDE:"claude",CURSOR:"cursor",CODEX:"codex",GEMINI:"gemini"},In={DEBUG:"debug",INFO:"info",WARN:"warn",ERROR:"error",SILENT:"silent"},mt={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"},gt={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"},Xt={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},Je={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};import{zodToJsonSchema as An}from"zod-to-json-schema";var Ke=class{static generateFileOutputInstructions(e,t){let r;typeof e?.parse=="function"?r=An(e,{target:"openApi3"}):r=e;let n=this._buildExample(r);return`
|
|
40
|
+
`),{success:!0,output:g.output,outputPath:r.outputPath,state:g}}calculateOutputPath(e){let{specs:t,generated:r}=this.paths;if(!e)return`${r}/generated-test.spec.js`;let n=e.replace(new RegExp(`^${t}/`),"").replace(/\.[^.]+$/,".spec.js");return`${r}/${n}`.replace(/\/+/g,"/")}};function En(i,e={}){let t=new oe(e);return t.buildGraph=function(){let r=new Sn;return i(r),r},e.onComplete&&(t.onComplete=e.onComplete),t}import{WorkflowGraph as Cu,resolveWorkflowSession as Ru,generateWorkflowSessionId as Nu,clearInheritedSessionEnvForFreshRun as ku,shouldTrustInheritedSessionEnv as Mu,readStudioPinnedSessionPathFromEnv as Lu,syncProcessEnvToSession as Du}from"@zibby/agent-workflow";import{writeFileSync as Vt,existsSync as Tn,mkdirSync as vn}from"node:fs";import{join as ft}from"node:path";import _e from"chalk";var G={debug:0,info:1,warn:2,error:3,silent:4},ze=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return G.debug;if(process.env.ZIBBY_VERBOSE==="true")return G.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in G?G[e]:G.info}_shouldLog(e){return G[e]>=this._level}_formatMessage(e,t,r={}){let n=new Date().toISOString(),o=`${this._getPrefix(e)} ${t}`;return Object.keys(r).length>0&&(o+=_e.dim(` ${JSON.stringify(r)}`)),o}_getPrefix(e){return{debug:_e.gray("[DEBUG]"),info:_e.cyan("[INFO]"),warn:_e.yellow("[WARN]"),error:_e.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 G&&(this._level=G[e])}getLevel(){return Object.keys(G).find(e=>G[e]===this._level)}},m=new ze;var dt=class i{static saveTitle(e,t){let r=e.state.sessionPath;if(!r)return;let n=i._findInState(e.state,"title")||i._findInState(e.state,"result");if(!(!n||typeof n!="string"))try{let s=ft(r,"title.txt");Vt(s,n,"utf-8"),m.info(`Saved title to session: "${n}"`)}catch(s){console.warn("\u26A0\uFE0F Could not save title file:",s.message)}}static _findInState(e,t){for(let[,r]of Object.entries(e))if(r&&typeof r=="object"&&r[t]!==void 0)return r[t]}static async saveExecutionData(e){let t=e.state.sessionPath;if(t)for(let[r,n]of Object.entries(e.state)){if(!n||typeof n!="object")continue;let s=Array.isArray(n.actions)&&n.actions.length>0,o=typeof n.scriptPath=="string"&&n.scriptPath.trim().length>0;if(!(!s&&!o))try{let c=ft(t,r);Tn(c)||vn(c,{recursive:!0});let l=ft(c,"result.json");Vt(l,JSON.stringify(n,null,2),"utf-8"),m.info(`Saved execution data to ${r} folder`),await this.onNodeSaved(c,n)}catch(c){console.warn(`\u26A0\uFE0F Could not save execution data for ${r}:`,c.message)}}}static async onNodeSaved(e,t){}static logResult(e,t){let r=Object.entries(e.state).filter(([,o])=>o&&typeof o=="object"&&o.success!==void 0),n=r.length>0&&r.every(([,o])=>o.success),s=r.some(([,o])=>o.success===!1);if(n)m.info("Workflow completed successfully."),t&&m.info(`Output: ${t}`);else if(s){let o=r.filter(([,c])=>!c.success).map(([c])=>c);m.info(`Workflow completed with failures in: ${o.join(", ")}`),t&&m.info(`Output: ${t}`)}return n}static handle(e,t,r){return this.saveTitle(e,t),this.saveExecutionData(e),this.logResult(e,r)}};import{z as Fu}from"zod/v3";import{AgentStrategy as Kn,DEFAULT_OUTPUT_BASE as Yn,SESSION_INFO_FILE as Hn,STUDIO_STOP_REQUEST_FILE as Zn,getAllSkills as Wn,getSkill as nr}from"@zibby/agent-workflow";import{spawn as Vn,execSync as Q}from"node:child_process";import{writeFileSync as sr,readFileSync as or,mkdirSync as ir,existsSync as Ee,accessSync as ar,constants as cr,unlinkSync as Xn}from"node:fs";import{join as z,resolve as qn}from"node:path";import{homedir as Te}from"node:os";var B={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"},$n={ASSISTANT:"assistant",CLAUDE:"claude",CURSOR:"cursor",CODEX:"codex",GEMINI:"gemini"},In={DEBUG:"debug",INFO:"info",WARN:"warn",ERROR:"error",SILENT:"silent"},mt={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"},gt={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"},Xt={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},Je={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};import{zodToJsonSchema as An}from"zod-to-json-schema";var Ke=class{static generateFileOutputInstructions(e,t){let r;typeof e?.parse=="function"?r=An(e,{target:"openApi3"}):r=e;let n=this._buildExample(r);return`
|
|
41
41
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
42
42
|
\u{1F6A8} MANDATORY: WRITE RESULT TO FILE \u{1F6A8}
|
|
43
43
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
@@ -75,7 +75,7 @@ ${c}
|
|
|
75
75
|
|
|
76
76
|
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.`,a={model:B.OPENAI_POSTPROCESSING,messages:[{role:"user",content:l}],response_format:{type:"json_schema",json_schema:{name:"extract",schema:s,strict:!0}}};m.info(`\u{1F4E4} Sending to OpenAI proxy: model=${B.OPENAI_POSTPROCESSING}, schema keys=${Object.keys(s.properties||{}).join(", ")}`),m.debug(` Schema size: ${JSON.stringify(s).length} chars`),m.debug(` Prompt size: ${l.length} chars`);try{let u={"Content-Type":"application/json"};process.env.OPENAI_PROXY_TOKEN?(u["x-proxy-token"]=t,u["x-execution-id"]=process.env.EXECUTION_ID||""):(u.Authorization=`Bearer ${t}`,u["x-api-key"]=process.env.ZIBBY_API_KEY||"",u["x-execution-id"]=process.env.EXECUTION_ID||"");let d=(await Pn.post(r,a,{headers:u,timeout:Je.OPENAI_REQUEST})).data?.choices?.[0]?.message?.content;if(!d)throw new Error("OpenAI proxy returned empty response");let p=JSON.parse(d);return m.info("\u2705 Successfully formatted with OpenAI proxy"),{structured:p,raw:i}}catch(u){if(u.response){let f=u.response.status,d=u.response.data;throw m.error(`\u274C OpenAI proxy request failed: ${f}`),m.error(` Status: ${f}`),m.error(` Response: ${JSON.stringify(d,null,2)}`),f===401||f===403?new Error(`Authentication failed for OpenAI proxy.
|
|
77
77
|
Run \`zibby login\` or set ZIBBY_USER_TOKEN environment variable.
|
|
78
|
-
Response: ${JSON.stringify(d)}`,{cause:u}):new Error(`Failed to format Cursor output: ${d?.error?.message||"Unknown error"}`,{cause:u})}throw m.error(`\u274C OpenAI proxy request failed: ${u.message}`),new Error(`Failed to format output: ${u.message}`,{cause:u})}}import{timeline as Y,Timeline as ta,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as ra}from"@zibby/workflow";import{copyFileSync as Dn,existsSync as ht,lstatSync as Un,mkdirSync as Qt,rmSync as Bn,symlinkSync as Fn,unlinkSync as jn}from"node:fs";import{join as H}from"node:path";import{homedir as Gn}from"node:os";import{randomBytes as zn}from"node:crypto";var Jn=["cli-config.json","config.json","auth.json","argv.json"];function er(i){return!(!i||typeof i!="string"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="1"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="true")}function tr(i){let e=H(i||process.cwd(),".zibby","tmp");Qt(e,{recursive:!0});let t=`${process.pid}-${Date.now()}-${zn(4).toString("hex")}`,r=H(e,`cursor-agent-home-${t}`),n=H(r,".cursor");Qt(n,{recursive:!0});let s=Gn(),o=H(s,".cursor");if(ht(o))for(let c of Jn){let l=H(o,c);if(ht(l))try{Dn(l,H(n,c))}catch{}}if(process.platform==="darwin"){let c=H(s,"Library");if(ht(c))try{Fn(c,H(r,"Library"))}catch{}}return r}function rr(i){if(!(!i||typeof i!="string"))try{let e=H(i,"Library");try{Un(e).isSymbolicLink()&&jn(e)}catch{}Bn(i,{recursive:!0,force:!0})}catch{}}var ve=class extends Kn{constructor(){super("cursor","Cursor (CLI)",100)}canHandle(e){let t=[z(Te(),".local","bin","cursor-agent"),z(Te(),".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("/")){ar(r,cr.X_OK);let n=Q(`"${r}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(n&&n.length>0)return m.debug(`[Cursor] Found agent at: ${r} (version: ${n.trim().slice(0,50)})`),!0}else{let n=Q(`which ${r}`,{encoding:"utf-8",timeout:2e3,stdio:"pipe"}).trim();if(!n)continue;let s=Q(`${r} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(s&&s.length>0)return m.debug(`[Cursor] Found '${r}' in PATH at ${n} (version: ${s.trim().slice(0,50)})`),!0}}catch{continue}return m.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:n=!1,schema:s=null,skills:o=null,sessionPath:c=null,nodeName:l=null,timeout:a=Je.CURSOR_AGENT_DEFAULT,config:u={}}=t,f=u?.agent?.strictMode||!1,d=t.model??u?.agent?.cursor?.model??B.CURSOR;m.debug(`[Cursor] Invoking (model: ${d}, timeout: ${a/1e3}s, skills: ${JSON.stringify(o)})`);let g=(this._setupMcpConfig(c,r,u,o,l)||{}).isolatedMcpHome??null,S=[z(Te(),".local","bin","cursor-agent"),z(Te(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"],h=null;for(let y of S)try{if(y.startsWith("/"))ar(y,cr.X_OK),Q(`"${y}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});else{if(!Q(`which ${y}`,{encoding:"utf-8",timeout:2e3}).trim())throw new Error("not in PATH");Q(`${y} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"})}h=y,m.debug(`[Agent] Using binary: ${y}`);break}catch(T){m.debug(`[Agent] Binary '${y}' check failed: ${T.message}`);continue}if(!h)throw new Error(`Cursor Agent CLI not found or not working.
|
|
78
|
+
Response: ${JSON.stringify(d)}`,{cause:u}):new Error(`Failed to format Cursor output: ${d?.error?.message||"Unknown error"}`,{cause:u})}throw m.error(`\u274C OpenAI proxy request failed: ${u.message}`),new Error(`Failed to format output: ${u.message}`,{cause:u})}}import{timeline as Y,Timeline as ta,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as ra}from"@zibby/agent-workflow";import{copyFileSync as Dn,existsSync as ht,lstatSync as Un,mkdirSync as Qt,rmSync as Bn,symlinkSync as Fn,unlinkSync as jn}from"node:fs";import{join as H}from"node:path";import{homedir as Gn}from"node:os";import{randomBytes as zn}from"node:crypto";var Jn=["cli-config.json","config.json","auth.json","argv.json"];function er(i){return!(!i||typeof i!="string"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="1"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="true")}function tr(i){let e=H(i||process.cwd(),".zibby","tmp");Qt(e,{recursive:!0});let t=`${process.pid}-${Date.now()}-${zn(4).toString("hex")}`,r=H(e,`cursor-agent-home-${t}`),n=H(r,".cursor");Qt(n,{recursive:!0});let s=Gn(),o=H(s,".cursor");if(ht(o))for(let c of Jn){let l=H(o,c);if(ht(l))try{Dn(l,H(n,c))}catch{}}if(process.platform==="darwin"){let c=H(s,"Library");if(ht(c))try{Fn(c,H(r,"Library"))}catch{}}return r}function rr(i){if(!(!i||typeof i!="string"))try{let e=H(i,"Library");try{Un(e).isSymbolicLink()&&jn(e)}catch{}Bn(i,{recursive:!0,force:!0})}catch{}}var ve=class extends Kn{constructor(){super("cursor","Cursor (CLI)",100)}canHandle(e){let t=[z(Te(),".local","bin","cursor-agent"),z(Te(),".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("/")){ar(r,cr.X_OK);let n=Q(`"${r}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(n&&n.length>0)return m.debug(`[Cursor] Found agent at: ${r} (version: ${n.trim().slice(0,50)})`),!0}else{let n=Q(`which ${r}`,{encoding:"utf-8",timeout:2e3,stdio:"pipe"}).trim();if(!n)continue;let s=Q(`${r} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(s&&s.length>0)return m.debug(`[Cursor] Found '${r}' in PATH at ${n} (version: ${s.trim().slice(0,50)})`),!0}}catch{continue}return m.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:n=!1,schema:s=null,skills:o=null,sessionPath:c=null,nodeName:l=null,timeout:a=Je.CURSOR_AGENT_DEFAULT,config:u={}}=t,f=u?.agent?.strictMode||!1,d=t.model??u?.agent?.cursor?.model??B.CURSOR;m.debug(`[Cursor] Invoking (model: ${d}, timeout: ${a/1e3}s, skills: ${JSON.stringify(o)})`);let g=(this._setupMcpConfig(c,r,u,o,l)||{}).isolatedMcpHome??null,S=[z(Te(),".local","bin","cursor-agent"),z(Te(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"],h=null;for(let y of S)try{if(y.startsWith("/"))ar(y,cr.X_OK),Q(`"${y}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});else{if(!Q(`which ${y}`,{encoding:"utf-8",timeout:2e3}).trim())throw new Error("not in PATH");Q(`${y} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"})}h=y,m.debug(`[Agent] Using binary: ${y}`);break}catch(T){m.debug(`[Agent] Binary '${y}' check failed: ${T.message}`);continue}if(!h)throw new Error(`Cursor Agent CLI not found or not working.
|
|
79
79
|
|
|
80
80
|
Checked paths:
|
|
81
81
|
${S.map(y=>` - ${y}`).join(`
|
|
@@ -111,13 +111,13 @@ Stderr: ${d.slice(-1e3)}`:""}${f.trim()?`
|
|
|
111
111
|
Stdout (last 500 chars): ${f.slice(-500)}`:""}`));return}let L=A.getResult(),N=L?JSON.stringify(L,null,2):A.getRawText()||f||"";l({stdout:f||d||"",parsedText:N})}),E.on("error",y=>{O(),clearTimeout(P),clearInterval(b),$&&clearInterval($),a(new Error(`Cursor Agent spawn error: ${y.message}
|
|
112
112
|
Binary: ${e}
|
|
113
113
|
This usually means the binary is not in PATH. Try:
|
|
114
|
-
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Qn,getSkill as es}from"@zibby/workflow";import{query as ts}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as rs}from"zod-to-json-schema";var $e=class extends Qn{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY;return t||m.debug("ClaudeAgentStrategy: ANTHROPIC_API_KEY not set"),t}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,images:o=[],skills:c=null,sessionPath:l=null,nodeName:a=null,timeout:u,config:f={}}=t,d=r;(!d||d==="auto")&&(m.debug(`Model is '${d||"undefined"}', using default: ${B.CLAUDE}`),d=B.CLAUDE);let p=mt[d]||d;mt[d]&&d!==p&&m.debug(`Mapped model: ${d} \u2192 ${p}`),m.debug(`Invoking Claude Agent SDK with model: ${p}, skills: ${JSON.stringify(c)}`);let g=process.env.ANTHROPIC_API_KEY,S=g?` | key: ***${g.slice(-4)}`:" | key: not set";console.log(`
|
|
114
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc`))})})}};import{AgentStrategy as Qn,getSkill as es}from"@zibby/agent-workflow";import{query as ts}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as rs}from"zod-to-json-schema";var $e=class extends Qn{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let t=!!process.env.ANTHROPIC_API_KEY;return t||m.debug("ClaudeAgentStrategy: ANTHROPIC_API_KEY not set"),t}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,images:o=[],skills:c=null,sessionPath:l=null,nodeName:a=null,timeout:u,config:f={}}=t,d=r;(!d||d==="auto")&&(m.debug(`Model is '${d||"undefined"}', using default: ${B.CLAUDE}`),d=B.CLAUDE);let p=mt[d]||d;mt[d]&&d!==p&&m.debug(`Mapped model: ${d} \u2192 ${p}`),m.debug(`Invoking Claude Agent SDK with model: ${p}, skills: ${JSON.stringify(c)}`);let g=process.env.ANTHROPIC_API_KEY,S=g?` | key: ***${g.slice(-4)}`:" | key: not set";console.log(`
|
|
115
115
|
\u25C6 Model: ${p}${S}
|
|
116
116
|
`);let h=(await import("chalk")).default;console.log(`
|
|
117
|
-
${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{allowedTools:w,mcpServers:x}=this._resolveSkills(c,{sessionPath:l,workspace:n,nodeName:a});try{let _={cwd:n,allowedTools:w,permissionMode:"bypassPermissions",model:p,...Object.keys(x).length>0&&{mcpServers:x}};if(s){let P=typeof s.parse=="function"?rs(s,{target:"openApi3"}):s;_.outputFormat={type:"json_schema",schema:P},m.debug("Structured output enforced via SDK outputFormat")}m.debug(`Agent SDK options: ${JSON.stringify({cwd:_.cwd,toolCount:w.length,permissionMode:_.permissionMode,model:_.model,hasOutputFormat:!!_.outputFormat})}`);let v="",O=0,C=[];m.debug("Starting Claude Agent SDK query stream");let E;try{E=ts({prompt:e,options:_})}catch(b){throw m.error(`Failed to initialize Claude Agent SDK: ${b.message}`),b}let $=null,I=0,k=3;try{for await(let b of E){if(C.push(b),b.type==="error"||b.error){let A=b.error?.message||b.error||b.message||"Unknown API error";throw new Error(typeof A=="string"?A:JSON.stringify(A))}let P=JSON.stringify(b.message?.content||b.text||"").slice(0,200);if(P===$){if(I++,I>=k){let A=(b.message?.content?.[0]?.text||b.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${I}x repeated): ${A}`)}}else $=P,I=1;if(b.type==="assistant"||b.constructor?.name==="AssistantMessage"){let A=b.message?.content||b.content||[];for(let y of A)if(y.type==="thinking"&&y.thinking)console.log(`${y.thinking.substring(0,200)}${y.thinking.length>200?"...":""}`);else if(y.type==="text"&&y.text)v+=y.text,y.text.length<500?console.log(`${y.text}`):console.log(`${y.text.substring(0,200)}... (${y.text.length} chars)`);else if(y.type==="tool_use"){O++,y.name.includes("memory")?Y.stepMemory(`Tool: ${y.name}`):Y.stepTool(`Tool: ${y.name}`);let R=JSON.stringify(y.input).substring(0,100);console.log(` Input: ${R}${JSON.stringify(y.input).length>100?"...":""}`)}}else if(!(b.type==="user"&&b.tool_use_result)){if(b.type==="result"||b.constructor?.name==="ResultMessage"){let A=b.result||b.text||b.content||v;if(s){if(b.structured_output){m.debug("Using SDK native structured_output");let T=typeof s.parse=="function"?s.parse(b.structured_output):b.structured_output;return{raw:A,structured:T}}if(A){let y=this._extractJson(A,s);if(y)return{raw:A,structured:y}}m.warn(`Could not extract structured output \u2014 returning raw text (${(A||"").length} chars)`)}return A||""}}}if(m.warn(`Agent SDK ended without result. Collected ${C.length} messages`),v.length>0)return m.debug("Returning accumulated text from messages"),v;throw new Error("Claude Agent SDK query ended without result")}catch(b){throw m.error(`Error during query stream: ${b.message}`),b}}catch(_){throw m.error("Claude Agent SDK call failed",{error:_.message}),_}}_resolveSkills(e,t){if(e===null)return m.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return m.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],n={};for(let s of e){let o=es(s);if(!o){m.warn(`Unknown skill "${s}" \u2014 skipping`);continue}if(o.allowedTools&&r.push(...o.allowedTools),typeof o.resolve=="function"){let c=o.resolve(t);c&&(n[o.serverName]=c,m.debug(`MCP: ${o.serverName} \u2192 ${c.command} ${c.args[0]}`))}}return{allowedTools:r,mcpServers:n}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,s=e.indexOf("===JSON_END===");return e.substring(n,s).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),s=e.lastIndexOf("}");if(n!==-1&&s>n)return e.substring(n,s+1)}];for(let n of r)try{let s=n();if(!s)continue;let o=JSON.parse(s);if(typeof o!="object"||o===null)continue;return typeof t.parse=="function"?t.parse(o):o}catch{}return null}};import{AgentStrategy as ns,getSkill as ss}from"@zibby/workflow";import{execSync as os}from"node:child_process";import{zodToJsonSchema as is}from"zod-to-json-schema";var Ie=class extends ns{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY))return m.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return os("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return m.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:o=null,sessionPath:c=null,nodeName:l=null,timeout:a,config:u={}}=t,{Codex:f}=await import("@openai/codex-sdk"),d=r;(!d||d==="auto")&&(m.debug(`Model is '${d||"undefined"}', using default: ${B.CODEX}`),d=B.CODEX);let p=gt[d]||d;gt[d]&&d!==p&&m.debug(`Mapped model: ${d} \u2192 ${p}`),m.debug(`Invoking Codex SDK with model: ${p}, skills: ${JSON.stringify(o)}`);let g=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;g&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=g);let S=g?` | key: ***${g.slice(-4)}`:" | key: not set";console.log(`
|
|
117
|
+
${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{allowedTools:w,mcpServers:x}=this._resolveSkills(c,{sessionPath:l,workspace:n,nodeName:a});try{let _={cwd:n,allowedTools:w,permissionMode:"bypassPermissions",model:p,...Object.keys(x).length>0&&{mcpServers:x}};if(s){let P=typeof s.parse=="function"?rs(s,{target:"openApi3"}):s;_.outputFormat={type:"json_schema",schema:P},m.debug("Structured output enforced via SDK outputFormat")}m.debug(`Agent SDK options: ${JSON.stringify({cwd:_.cwd,toolCount:w.length,permissionMode:_.permissionMode,model:_.model,hasOutputFormat:!!_.outputFormat})}`);let v="",O=0,C=[];m.debug("Starting Claude Agent SDK query stream");let E;try{E=ts({prompt:e,options:_})}catch(b){throw m.error(`Failed to initialize Claude Agent SDK: ${b.message}`),b}let $=null,I=0,k=3;try{for await(let b of E){if(C.push(b),b.type==="error"||b.error){let A=b.error?.message||b.error||b.message||"Unknown API error";throw new Error(typeof A=="string"?A:JSON.stringify(A))}let P=JSON.stringify(b.message?.content||b.text||"").slice(0,200);if(P===$){if(I++,I>=k){let A=(b.message?.content?.[0]?.text||b.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${I}x repeated): ${A}`)}}else $=P,I=1;if(b.type==="assistant"||b.constructor?.name==="AssistantMessage"){let A=b.message?.content||b.content||[];for(let y of A)if(y.type==="thinking"&&y.thinking)console.log(`${y.thinking.substring(0,200)}${y.thinking.length>200?"...":""}`);else if(y.type==="text"&&y.text)v+=y.text,y.text.length<500?console.log(`${y.text}`):console.log(`${y.text.substring(0,200)}... (${y.text.length} chars)`);else if(y.type==="tool_use"){O++,y.name.includes("memory")?Y.stepMemory(`Tool: ${y.name}`):Y.stepTool(`Tool: ${y.name}`);let R=JSON.stringify(y.input).substring(0,100);console.log(` Input: ${R}${JSON.stringify(y.input).length>100?"...":""}`)}}else if(!(b.type==="user"&&b.tool_use_result)){if(b.type==="result"||b.constructor?.name==="ResultMessage"){let A=b.result||b.text||b.content||v;if(s){if(b.structured_output){m.debug("Using SDK native structured_output");let T=typeof s.parse=="function"?s.parse(b.structured_output):b.structured_output;return{raw:A,structured:T}}if(A){let y=this._extractJson(A,s);if(y)return{raw:A,structured:y}}m.warn(`Could not extract structured output \u2014 returning raw text (${(A||"").length} chars)`)}return A||""}}}if(m.warn(`Agent SDK ended without result. Collected ${C.length} messages`),v.length>0)return m.debug("Returning accumulated text from messages"),v;throw new Error("Claude Agent SDK query ended without result")}catch(b){throw m.error(`Error during query stream: ${b.message}`),b}}catch(_){throw m.error("Claude Agent SDK call failed",{error:_.message}),_}}_resolveSkills(e,t){if(e===null)return m.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return m.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let r=[],n={};for(let s of e){let o=es(s);if(!o){m.warn(`Unknown skill "${s}" \u2014 skipping`);continue}if(o.allowedTools&&r.push(...o.allowedTools),typeof o.resolve=="function"){let c=o.resolve(t);c&&(n[o.serverName]=c,m.debug(`MCP: ${o.serverName} \u2192 ${c.command} ${c.args[0]}`))}}return{allowedTools:r,mcpServers:n}}_extractJson(e,t){let r=[()=>{if(e.includes("===JSON_START===")){let n=e.indexOf("===JSON_START===")+16,s=e.indexOf("===JSON_END===");return e.substring(n,s).trim()}},()=>e.match(/```json\s*\n([\s\S]*?)\n```/)?.[1]?.trim(),()=>{if(!e.startsWith("{"))return e.match(/```\s*\n([\s\S]*?)\n```/)?.[1]?.trim()},()=>e.trim(),()=>{let n=e.indexOf("{"),s=e.lastIndexOf("}");if(n!==-1&&s>n)return e.substring(n,s+1)}];for(let n of r)try{let s=n();if(!s)continue;let o=JSON.parse(s);if(typeof o!="object"||o===null)continue;return typeof t.parse=="function"?t.parse(o):o}catch{}return null}};import{AgentStrategy as ns,getSkill as ss}from"@zibby/agent-workflow";import{execSync as os}from"node:child_process";import{zodToJsonSchema as is}from"zod-to-json-schema";var Ie=class extends ns{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY))return m.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return os("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return m.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:o=null,sessionPath:c=null,nodeName:l=null,timeout:a,config:u={}}=t,{Codex:f}=await import("@openai/codex-sdk"),d=r;(!d||d==="auto")&&(m.debug(`Model is '${d||"undefined"}', using default: ${B.CODEX}`),d=B.CODEX);let p=gt[d]||d;gt[d]&&d!==p&&m.debug(`Mapped model: ${d} \u2192 ${p}`),m.debug(`Invoking Codex SDK with model: ${p}, skills: ${JSON.stringify(o)}`);let g=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;g&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=g);let S=g?` | key: ***${g.slice(-4)}`:" | key: not set";console.log(`
|
|
118
118
|
\u25C6 Model: ${p}${S}
|
|
119
119
|
`);let h=(await import("chalk")).default;console.log(`
|
|
120
|
-
${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 w=this._resolveSkillsToMcp(o,{sessionPath:c,workspace:n,nodeName:l}),x={};Object.keys(w).length>0&&(x.mcp_servers=w,m.debug(`[Codex] MCP servers: ${Object.keys(w).join(", ")}`));let v=new f({...Object.keys(x).length>0&&{config:x}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),O=s&&typeof s.parse=="function",C={};if(s)try{let E=O?is(s,{target:"openAi"}):s;C.outputSchema=E,m.debug("Structured output via SDK outputSchema")}catch(E){m.warn(`[Codex] Schema conversion failed, will extract from text: ${E.message}`)}try{let{events:E}=await v.runStreamed(e,C),$=0,I="";for await(let k of E){let b=k.type;if(b==="item.completed"){let P=k.item,A=P?.type;if(A==="mcp_tool_call"){$++;let y=`${P.server}/${P.tool}`;if(Y.stepTool(`Tool: ${y}`),P.arguments){let T=JSON.stringify(P.arguments),R=T.length>100?`${T.substring(0,100)}...`:T;console.log(` Input: ${R}`)}}else if(A==="tool_call"||A==="function_call"||A==="command_execution"){$++;let y=P.name||P.tool||P.command||"unknown";Y.stepTool(`Tool: ${y}`)}else A==="agent_message"&&(I=P.text||"",I.length<500?console.log(I):console.log(`${I.substring(0,200)}... (${I.length} chars)`))}else b==="turn.completed"?m.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(k.usage||{})}`):m.debug(`[Codex] Event: ${b} ${JSON.stringify(k).slice(0,300)}`)}if(m.debug(`[Codex] Last agent message (${I.length} chars): ${I.slice(0,500)}`),s){if(!I)throw new Error("Codex agent returned no response");let k=JSON.parse(I),b=O?s.parse(k):k;return m.debug("\u2705 [Codex] Structured output validated"),{raw:I,structured:b}}return I||""}catch(E){let $=E.message||String(E);throw m.error(`\u274C [Codex] SDK call failed: ${$}`),$.includes("exited with code")&&(m.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),m.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),E}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let s=ss(n);if(!s){m.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof s.resolve!="function")continue;let o=s.resolve(t);if(!o)continue;let c=s.serverName||n,l={command:o.command};o.args?.length&&(l.args=o.args),o.env&&Object.keys(o.env).length>0&&(l.env=o.env),r[c]=l,m.debug(`[Codex] MCP: ${c} \u2192 ${o.command} ${(o.args||[]).join(" ")}`)}return r}};import{AgentStrategy as as,getSkill as cs}from"@zibby/workflow";import{execSync as ls,spawn as us}from"node:child_process";import{zodToJsonSchema as ps}from"zod-to-json-schema";import{existsSync as lr,mkdirSync as ur,readFileSync as pr,rmSync as fs,writeFileSync as fr}from"node:fs";import{join as ee}from"node:path";function ds(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 n=0,s=!1,o=!1,c=-1;for(let l=r;l<e.length;l++){let a=e[l];if(s){o?o=!1:a==="\\"?o=!0:a==='"'&&(s=!1);continue}if(a==='"'){s=!0;continue}if(a==="{"){n===0&&(c=l),n+=1;continue}if(a==="}"){if(n===0)continue;if(n-=1,n===0&&c>=0){let u=e.slice(c,l+1);try{return JSON.parse(u)}catch{c=-1}}}}return null}function ms(i){let e=String(i||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return ds(e)}}function gs(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(n=>typeof n?.text=="string"?n.text:"").join("");if(r.trim())return r}}}catch{}return i}var Ae=class extends as{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY))return m.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return ls("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return m.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:o=null,sessionPath:c=null,nodeName:l=null,timeout:a=600*1e3}=t,u=r;(!u||u==="auto")&&(u=B.GEMINI);let f=Xt[u]||u,d=String(process.env.GEMINI_API_KEY||"").trim(),p=String(process.env.GOOGLE_API_KEY||"").trim(),g=this._resolveSkillsToMcp(o,{sessionPath:c,workspace:n,nodeName:l}),S=Object.keys(g).length>0,h=new ie(e),w=s&&typeof s.parse=="function",x=null;if(s){let N;try{let M=w?ps(s,{target:"openAi"}):s;N=JSON.stringify(M,null,2)}catch{N="{}"}if(S){h.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
120
|
+
${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 w=this._resolveSkillsToMcp(o,{sessionPath:c,workspace:n,nodeName:l}),x={};Object.keys(w).length>0&&(x.mcp_servers=w,m.debug(`[Codex] MCP servers: ${Object.keys(w).join(", ")}`));let v=new f({...Object.keys(x).length>0&&{config:x}}).startThread({workingDirectory:n,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),O=s&&typeof s.parse=="function",C={};if(s)try{let E=O?is(s,{target:"openAi"}):s;C.outputSchema=E,m.debug("Structured output via SDK outputSchema")}catch(E){m.warn(`[Codex] Schema conversion failed, will extract from text: ${E.message}`)}try{let{events:E}=await v.runStreamed(e,C),$=0,I="";for await(let k of E){let b=k.type;if(b==="item.completed"){let P=k.item,A=P?.type;if(A==="mcp_tool_call"){$++;let y=`${P.server}/${P.tool}`;if(Y.stepTool(`Tool: ${y}`),P.arguments){let T=JSON.stringify(P.arguments),R=T.length>100?`${T.substring(0,100)}...`:T;console.log(` Input: ${R}`)}}else if(A==="tool_call"||A==="function_call"||A==="command_execution"){$++;let y=P.name||P.tool||P.command||"unknown";Y.stepTool(`Tool: ${y}`)}else A==="agent_message"&&(I=P.text||"",I.length<500?console.log(I):console.log(`${I.substring(0,200)}... (${I.length} chars)`))}else b==="turn.completed"?m.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(k.usage||{})}`):m.debug(`[Codex] Event: ${b} ${JSON.stringify(k).slice(0,300)}`)}if(m.debug(`[Codex] Last agent message (${I.length} chars): ${I.slice(0,500)}`),s){if(!I)throw new Error("Codex agent returned no response");let k=JSON.parse(I),b=O?s.parse(k):k;return m.debug("\u2705 [Codex] Structured output validated"),{raw:I,structured:b}}return I||""}catch(E){let $=E.message||String(E);throw m.error(`\u274C [Codex] SDK call failed: ${$}`),$.includes("exited with code")&&(m.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),m.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),E}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let s=ss(n);if(!s){m.warn(`[Codex] Unknown skill "${n}" \u2014 skipping`);continue}if(typeof s.resolve!="function")continue;let o=s.resolve(t);if(!o)continue;let c=s.serverName||n,l={command:o.command};o.args?.length&&(l.args=o.args),o.env&&Object.keys(o.env).length>0&&(l.env=o.env),r[c]=l,m.debug(`[Codex] MCP: ${c} \u2192 ${o.command} ${(o.args||[]).join(" ")}`)}return r}};import{AgentStrategy as as,getSkill as cs}from"@zibby/agent-workflow";import{execSync as ls,spawn as us}from"node:child_process";import{zodToJsonSchema as ps}from"zod-to-json-schema";import{existsSync as lr,mkdirSync as ur,readFileSync as pr,rmSync as fs,writeFileSync as fr}from"node:fs";import{join as ee}from"node:path";function ds(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 n=0,s=!1,o=!1,c=-1;for(let l=r;l<e.length;l++){let a=e[l];if(s){o?o=!1:a==="\\"?o=!0:a==='"'&&(s=!1);continue}if(a==='"'){s=!0;continue}if(a==="{"){n===0&&(c=l),n+=1;continue}if(a==="}"){if(n===0)continue;if(n-=1,n===0&&c>=0){let u=e.slice(c,l+1);try{return JSON.parse(u)}catch{c=-1}}}}return null}function ms(i){let e=String(i||"").trim();if(!e)return null;try{return JSON.parse(e)}catch{return ds(e)}}function gs(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(n=>typeof n?.text=="string"?n.text:"").join("");if(r.trim())return r}}}catch{}return i}var Ae=class extends as{constructor(){super("gemini","Gemini (Google)",70)}canHandle(e){if(!!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY))return m.debug("GeminiAgentStrategy: GEMINI_API_KEY or GOOGLE_API_KEY not set"),!1;try{return ls("gemini --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return m.warn("[Gemini] gemini CLI not found. Install: npm install -g @google/gemini-cli"),!1}}async invoke(e,t={}){let{model:r,workspace:n=process.cwd(),schema:s=null,skills:o=null,sessionPath:c=null,nodeName:l=null,timeout:a=600*1e3}=t,u=r;(!u||u==="auto")&&(u=B.GEMINI);let f=Xt[u]||u,d=String(process.env.GEMINI_API_KEY||"").trim(),p=String(process.env.GOOGLE_API_KEY||"").trim(),g=this._resolveSkillsToMcp(o,{sessionPath:c,workspace:n,nodeName:l}),S=Object.keys(g).length>0,h=new ie(e),w=s&&typeof s.parse=="function",x=null;if(s){let N;try{let M=w?ps(s,{target:"openAi"}):s;N=JSON.stringify(M,null,2)}catch{N="{}"}if(S){h.addSystemInstruction(`Write valid JSON that matches this schema:
|
|
121
121
|
${N}`,"schema_instruction","append");let M=`zibby-result-${Date.now()}.json`,D=ee(n,".zibby","tmp");x=ee(D,M),ur(D,{recursive:!0}),h.addStructuredOutput(s,x)}else h.addSystemInstruction(`Return ONLY valid JSON (no markdown, no commentary) that matches this schema:
|
|
122
122
|
${N}`,"json_instruction","append")}let _=h.build(),v=h.getUserPrompt(),O=h.getStats(),C=String(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||"").trim(),E=C?` | key: ***${C.slice(-4)}`:" | key: not set";console.log(`
|
|
123
123
|
\u25C6 Model: ${f||"auto"}${E}
|
|
@@ -126,7 +126,7 @@ ${$.bold("Prompt sent to LLM:")}`),console.log($.dim("\u2500".repeat(60))),conso
|
|
|
126
126
|
${T}`):m.info(`[Gemini] Raw text preview (first 1000 chars):
|
|
127
127
|
${T.slice(0,1e3)}`),R=ms(T)),!R)throw y||(m.error("[Gemini] Failed to extract valid JSON from output"),m.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=w?s.parse(R):R;return{raw:T,structured:L}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let r={};for(let n of e){let s=cs(n);if(!s||typeof s.resolve!="function")continue;let o=s.resolve(t);if(!o)continue;let c=s.cursorKey||s.serverName||n,l={command:o.command};o.args?.length&&(l.args=o.args),o.env&&Object.keys(o.env).length>0&&(l.env=o.env),o.cwd&&(l.cwd=o.cwd),r[c]=l}return r}_createGeminiConfigDir(e,t){let r=`${Date.now()}-${Math.random().toString(16).slice(2,10)}`,n=ee(e||process.cwd(),".zibby","tmp",`gemini-home-${r}`),s=ee(n,".gemini");ur(s,{recursive:!0});let o=ee(s,"settings.json"),c={},l=ee(process.env.HOME||"",".gemini","settings.json");if(lr(l))try{c=JSON.parse(pr(l,"utf-8"))}catch{c={}}let a={...c,mcpServers:{...c.mcpServers&&typeof c.mcpServers=="object"?c.mcpServers:{},...t||{}}};fr(o,`${JSON.stringify(a,null,2)}
|
|
128
128
|
`,"utf-8");let u=ee(e||process.cwd(),".zibby","tmp","gemini-settings-debug.json");try{fr(u,`${JSON.stringify(a,null,2)}
|
|
129
|
-
`,"utf-8")}catch{}return m.debug(`[Gemini] Created isolated config with ${Object.keys(a.mcpServers||{}).length} MCP servers`),m.debug(`[Gemini] MCP servers: ${JSON.stringify(Object.keys(a.mcpServers||{}),null,2)}`),n}};import{AgentStrategy as As,getSkill as Ve}from"@zibby/workflow";var ce=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 te=class extends ce{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 Pe=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 Ye(i){return Buffer.byteLength(JSON.stringify(i),"utf8")}function He(i,e){let t=String(i||"");if(t.length<=e)return t;let r=Math.max(0,e-28);return`${t.slice(0,r)}
|
|
129
|
+
`,"utf-8")}catch{}return m.debug(`[Gemini] Created isolated config with ${Object.keys(a.mcpServers||{}).length} MCP servers`),m.debug(`[Gemini] MCP servers: ${JSON.stringify(Object.keys(a.mcpServers||{}),null,2)}`),n}};import{AgentStrategy as As,getSkill as Ve}from"@zibby/agent-workflow";var ce=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 te=class extends ce{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 Pe=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 Ye(i){return Buffer.byteLength(JSON.stringify(i),"utf8")}function He(i,e){let t=String(i||"");if(t.length<=e)return t;let r=Math.max(0,e-28);return`${t.slice(0,r)}
|
|
130
130
|
|
|
131
131
|
[truncated for size budget]`}function yt(i,e=0){if(!i||typeof i!="object"||e>8)return i;if(Array.isArray(i))return i.map(r=>yt(r,e+1));let t={};for(let[r,n]of Object.entries(i))r==="description"||r==="title"||r==="examples"||r==="default"||(t[r]=yt(n,e+1));return t}function hs(i=[]){return i.map(e=>({...e,function:{...e.function,description:He(e.function?.description||"",180),parameters:yt(e.function?.parameters||{type:"object",properties:{}})}}))}function dr(i){let e=new Set;for(let n of i)if(n.role==="assistant"&&Array.isArray(n.tool_calls))for(let s of n.tool_calls)e.add(s.id);let t=i.filter(n=>n.role==="tool"?e.has(n.tool_call_id):!0),r=new Set;for(let n of t)n.role==="tool"&&r.add(n.tool_call_id);return t.map(n=>{if(n.role!=="assistant"||!Array.isArray(n.tool_calls)||n.tool_calls.every(l=>r.has(l.id)))return n;let{tool_calls:o,...c}=n;return{...c,content:c.content||""}})}function St(i,e={}){let t=e.maxBytes||49e3,r=e.systemMaxChars||12e3,n={...i,messages:Array.isArray(i.messages)?[...i.messages]:[],tools:Array.isArray(i.tools)?hs(i.tools):i.tools};n.messages.length>0&&n.messages[0]?.role==="system"&&(n.messages[0]={...n.messages[0],content:He(n.messages[0].content,r)});let s=!1;for(;Ye(n)>t&&n.messages.length>2;)n.messages.splice(1,1),s=!0;if(s&&(n.messages=dr(n.messages)),Ye(n)>t&&n.messages.length>0&&(n.messages[0]={...n.messages[0],content:He(n.messages[0].content,6e3)},s=!0),Ye(n)>t){let o=n.messages.find(l=>l.role==="system")||n.messages[0],c=n.messages.slice(-2);n.messages=dr([o,...c].filter(Boolean).map((l,a)=>({...l,content:He(l.content,a===0?4e3:8e3)}))),s=!0}return{body:n,meta:{bytes:Ye(n),trimmed:s,maxBytes:t,messageCount:n.messages.length}}}var mr=i=>Buffer.byteLength(JSON.stringify(i),"utf8"),le=class extends Pe{async fetchCompletion(e,t,r={}){let n=mr(e),{body:s,meta:o}=St(e,r.payloadCompaction);r.onBudget?.({streaming:!1,beforeBytes:n,meta:o});let c=this.#e(r),l=`${t.baseUrl}${r.chatCompletionsPath||"/v1/chat/completions"}`,a=await fetch(l,{method:"POST",headers:t.headers,body:JSON.stringify(s),signal:c});if(!a.ok){let u=await a.text();throw a.status===401||a.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Proxy error ${a.status}: ${u}`)}return a.json()}async fetchStreamingCompletion(e,t,r={}){let n={...e,stream:!0},s=mr(n),{body:o,meta:c}=St(n,r.payloadCompaction);r.onBudget?.({streaming:!0,beforeBytes:s,meta:c});let l=this.#e(r),a=`${t.baseUrl}${r.chatCompletionsPath||"/v1/chat/completions"}`,u=await fetch(a,{method:"POST",headers:t.headers,body:JSON.stringify(o),signal:l});if(!u.ok){let h=await u.text();throw u.status===401||u.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Proxy error ${u.status}: ${h}`)}let f=u.body.getReader(),d=new TextDecoder,p="",g="",S=new Map;for(;;){let{done:h,value:w}=await f.read();if(h)break;p+=d.decode(w,{stream:!0});let x=p.split(`
|
|
132
132
|
`);p=x.pop();for(let _ of x){if(!_.startsWith("data: "))continue;let v=_.slice(6).trim();if(v==="[DONE]")continue;let O;try{O=JSON.parse(v)}catch{continue}let C=O.choices?.[0]?.delta;if(C&&(C.content&&(g+=C.content,r.onToken&&r.onToken(C.content)),C.tool_calls))for(let E of C.tool_calls){let $=E.index??0;S.has($)||S.set($,{id:"",name:"",args:""});let I=S.get($);E.id&&(I.id=E.id),E.function?.name&&(I.name=E.function.name),E.function?.arguments!=null&&(I.args+=E.function.arguments)}}}if(S.size>0){let h=[...S.entries()].sort(([w],[x])=>w-x).map(([,w])=>({id:w.id,type:"function",function:{name:w.name,arguments:w.args}}));return{choices:[{message:{role:"assistant",content:g||null,tool_calls:h}}]}}return{choices:[{message:{role:"assistant",content:g}}]}}#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 ys}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as Ss}from"@modelcontextprotocol/sdk/client/stdio.js";var Oe=class{#e=new Map;async ensureServer(e,t){if(this.#e.has(e))return this.#e.get(e);let{command:r,args:n=[],env:s={}}=t;m.debug(`[MCP] Starting ${e}: ${r} ${n.join(" ")}`);let o=new Ss({command:r,args:n,env:{...process.env,...s}}),c=new ys({name:`zibby-chat-${e}`,version:"1.0.0"},{capabilities:{}});await c.connect(o);let l={client:c,transport:o,serverConfig:t};return this.#e.set(e,l),l}async callTool(e,t,r={}){let n=this.#e.get(e);if(!n)throw new Error(`MCP server "${e}" not running`);m.debug(`[MCP] ${e}.${t}(${JSON.stringify(r).slice(0,200)})`);let s=await n.client.callTool({name:t,arguments:r});return{text:s.content?.filter(c=>c.type==="text").map(c=>c.text).join(`
|
|
@@ -136,7 +136,7 @@ ${T.slice(0,1e3)}`),R=ms(T)),!R)throw y||(m.error("[Gemini] Failed to extract va
|
|
|
136
136
|
\u{1F4D6} get_skill_context("${a}") \u2192 ${p.length} chars (fragment: ${f.length} chars)`),console.log(` tools: [${d.join(", ")}]`),console.log(` fragment preview: ${f.slice(0,200).replace(/\n/g,"\\n")}\u2026
|
|
137
137
|
`)),p}let c=s?.get(e.name)||null;if(!c)return`Unknown tool: ${e.name}`;let l=Ve(c.skillId);if(!l)return`Skill "${c.skillId}" not found for tool "${e.name}"`;if(c.mode==="handler")try{return l.handleToolCall(e.name,e.args,t)}catch(a){return`Error in ${e.name}: ${a.message}`}if(c.mode==="mcp")try{if(!this.#r.isRunning(l.serverName)){let u=l.resolve(n);if(!u)return`Skill "${c.skillId}" is not available (cannot start server)`;await this.#r.ensureServer(l.serverName,u)}let a=await this.#r.callTool(l.serverName,e.name,e.args);return a.text||(a.isError?"Tool call failed":"Done")}catch(a){return`MCP error (${l.serverName}): ${a.message}`}return`Skill "${c.skillId}" owns tool "${e.name}" but has no execution mode`}async#c(e,t,r){return this.#t.fetchStreamingCompletion(e,t,{...r,onBudget:({beforeBytes:n,meta:s})=>{ue()&&console.log(`payload bytes (stream) before=${n} after=${s.bytes} trimmed=${s.trimmed} messages=${s.messageCount}`)}})}async#o(e,t,r){return this.#t.fetchCompletion(e,t,{...r,onBudget:({beforeBytes:n,meta:s})=>{ue()&&console.log(`payload bytes before=${n} after=${s.bytes} trimmed=${s.trimmed} messages=${s.messageCount}`)}})}async#l(e,t,r,n){let{zodToJsonSchema:s}=await import("zod-to-json-schema"),o=typeof n.schema?.parse=="function",c=o?s(n.schema):n.schema;delete c.$schema,pe(c);let l={model:e,messages:t,stream:!1,response_format:{type:"json_schema",json_schema:{name:"extract",schema:c,strict:!0}}},a=await this.#o(l,r,n),u=this.#e.getTextContent(a),f=JSON.parse(u),d=o?n.schema.parse(f):f;return{raw:u,structured:d}}#u(e={}){let t=e?.config?.agent?.assistant?.payloadCompaction||{};return{maxBytes:Number(t.maxBytes||e.maxPayloadBytes||yr.maxBytes),systemMaxChars:Number(t.systemMaxChars||yr.systemMaxChars)}}#p(e={}){let t=e?.config?.agent?.assistant?.toolPolicy||{};return{allowTools:Xe(t.allowTools||e.allowTools),denyTools:Xe(t.denyTools||e.denyTools),denyPrefixes:Rs(t.denyPrefixes||e.denyToolPrefixes),includeSkills:Xe(t.includeSkills||e.includeSkills),excludeSkills:Xe(t.excludeSkills||e.excludeSkills),disableSkillContextTool:!!(t.disableSkillContextTool||e.disableSkillContextTool)}}#f(e,t){let r=t?.includeSkills||new Set,n=t?.excludeSkills||new Set;return r.size===0&&n.size===0?e:e.filter(s=>!(r.size>0&&!r.has(s)||n.has(s)))}#n(e,t){let r=String(e||"").trim();if(!r)return!1;let n=t?.allowTools;if(n&&n.size>0&&!n.has(r))return!1;let s=t?.denyTools;return!(s&&s.has(r)||(t?.denyPrefixes||[]).some(c=>r.startsWith(c)))}#d(e){let t=new Map,r=[];for(let n of e){let s=Ve(n);if(!s?.tools?.length)continue;let o=typeof s.handleToolCall=="function"?"handler":s.serverName&&typeof s.resolve=="function"?"mcp":null;if(o)for(let c of s.tools){let l=String(c?.name||"").trim();if(l){if(t.has(l)){r.push({tool:l,winner:t.get(l).skillId,skipped:n});continue}t.set(l,{skillId:n,mode:o})}}}if(r.length>0&&ue()){let n=r.slice(0,5).map(s=>`${s.tool}:${s.winner}>${s.skipped}`).join(", ");console.log(`tool registry collisions: ${n}${r.length>5?" ...":""}`)}return t}async#m(e,t,r,n){console.log(`
|
|
138
138
|
\u25C6 Model: ${t} | proxy: ${r} | token: ${n||"none"}
|
|
139
|
-
`);let s=(await import("chalk")).default;console.log(s.bold("Prompt sent to LLM:")),console.log(s.dim("\u2500".repeat(60)));let o=!1;for(let c of e)if(c.role==="system")console.log(s.dim(`[System] ${c.content||""}`));else{o||(console.log(s.dim("\u2500\u2500\u2500 chat history \u2500\u2500\u2500")),o=!0);let l=c.role==="user"?"Human":"AI",a=c.content?.length>200?`${c.content.slice(0,200)}...`:c.content||"";console.log(s.dim(`[${l}] ${a}`))}console.log(s.dim("\u2500".repeat(60)))}};import{AgentStrategy as ks}from"@zibby/workflow";var Sr=[new Ce,new ve,new $e,new Ie,new Ae];function br(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");m.debug(`Agent selection: requested=${r}`);let n=Sr.find(s=>s.getName()===r);if(!n)throw new Error(`Unknown agent '${r}'. Available: ${Sr.map(s=>s.getName()).join(", ")}`);if(m.debug(`Checking if ${r} can handle this environment...`),!n.canHandle(i)){let o={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. ${o}`)}return m.debug(`Using agent: ${n.getName()}`),n}async function Ns(i,e={},t={}){try{await import("@zibby/skills")}catch{}let r=br(e),n=e.state?.config||t.config||{},s=n.models||{},o=t.nodeName&&s[t.nodeName]||null,c=s.default||null,l=r.name,a=n.agent?.[l]?.model||null,u=o||c||a||t.model||null,f={...t,model:u,workspace:e.state?.workspace||t.workspace,schema:t.schema||e.schema,images:t.images||e.images||[],skills:t.skills||e.skills||[],config:n},d=f.skills||[],p=i;if(d.length>0&&!t.skipPromptFragments){let{getSkill:S}=await import("@zibby/workflow"),h=d.map(w=>{let x=S(w)?.promptFragment;return typeof x=="function"?x():x}).filter(Boolean);h.length>0&&(p+=`
|
|
139
|
+
`);let s=(await import("chalk")).default;console.log(s.bold("Prompt sent to LLM:")),console.log(s.dim("\u2500".repeat(60)));let o=!1;for(let c of e)if(c.role==="system")console.log(s.dim(`[System] ${c.content||""}`));else{o||(console.log(s.dim("\u2500\u2500\u2500 chat history \u2500\u2500\u2500")),o=!0);let l=c.role==="user"?"Human":"AI",a=c.content?.length>200?`${c.content.slice(0,200)}...`:c.content||"";console.log(s.dim(`[${l}] ${a}`))}console.log(s.dim("\u2500".repeat(60)))}};import{AgentStrategy as ks}from"@zibby/agent-workflow";var Sr=[new Ce,new ve,new $e,new Ie,new Ae];function br(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");m.debug(`Agent selection: requested=${r}`);let n=Sr.find(s=>s.getName()===r);if(!n)throw new Error(`Unknown agent '${r}'. Available: ${Sr.map(s=>s.getName()).join(", ")}`);if(m.debug(`Checking if ${r} can handle this environment...`),!n.canHandle(i)){let o={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. ${o}`)}return m.debug(`Using agent: ${n.getName()}`),n}async function Ns(i,e={},t={}){try{await import("@zibby/skills")}catch{}let r=br(e),n=e.state?.config||t.config||{},s=n.models||{},o=t.nodeName&&s[t.nodeName]||null,c=s.default||null,l=r.name,a=n.agent?.[l]?.model||null,u=o||c||a||t.model||null,f={...t,model:u,workspace:e.state?.workspace||t.workspace,schema:t.schema||e.schema,images:t.images||e.images||[],skills:t.skills||e.skills||[],config:n},d=f.skills||[],p=i;if(d.length>0&&!t.skipPromptFragments){let{getSkill:S}=await import("@zibby/agent-workflow"),h=d.map(w=>{let x=S(w)?.promptFragment;return typeof x=="function"?x():x}).filter(Boolean);h.length>0&&(p+=`
|
|
140
140
|
|
|
141
141
|
${h.join(`
|
|
142
142
|
|
|
@@ -148,13 +148,13 @@ ${h.join(`
|
|
|
148
148
|
|
|
149
149
|
${g}
|
|
150
150
|
`),m.debug(`Prompt length: ${p.length} chars`),process.env.STAGE!=="prod"&&m.debug(`Full prompt:
|
|
151
|
-
${p}`),r.invoke(p,f)}import{SKILLS as Ku}from"@zibby/workflow";import{registerSkill as Hu,getSkill as Zu,hasSkill as Wu,getAllSkills as Vu,listSkillIds as Xu}from"@zibby/workflow";var Ms={READ_FILE:"read_file",WRITE_FILE:"write_file",LIST_DIRECTORY:"list_directory",RUN_COMMAND:"run_command",OPEN_URL:"open_url",WAIT:"wait"},Ls={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"},Ds={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"},Us={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"},Bs={GENERATE:"run_generate",TEST:"run_test",STATUS:"run_status",CANCEL:"run_cancel",WAIT:"run_wait",ARTIFACTS:"run_artifacts",LIST_SPECS:"list_specs"},Fs={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"},js={STORE:"memory_store",RECALL:"memory_recall",BRIEF:"memory_brief",END_SESSION:"memory_end_session",TASK_LOG:"task_log",TASK_HISTORY:"task_history"},Gs={INSTALL:"install_skill",UNINSTALL:"uninstall_skill",LIST_AVAILABLE:"list_available_skills"},Pc={...Ms,...Ls,...Ds,...Us,...Bs,...Fs,...js,...Gs};import{existsSync as zs,readFileSync as Js}from"node:fs";import{homedir as Ks}from"node:os";import{join as Ys}from"node:path";var qe=new Map;function Hs(){if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let i=Ys(Ks(),".zibby","config.json");return zs(i)&&JSON.parse(Js(i,"utf-8")).sessionToken||null}catch{return null}}function Zs(){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://account-api-prod.zibby.app"}async function Ws(i){let e=Date.now(),t=qe.get(i);if(t&&t.expiresAt>e)return t.data;let r=Hs();if(!r)throw new Error("No session token. Run `zibby login` first.");let n=`${Zs()}/integrations/token/${i}`,s=await fetch(n,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!s.ok){let l=await s.text().catch(()=>"");throw s.status===404?new Error(`${i} is not connected. Connect it at https://studio.zibby.app/integrations`):s.status===401||s.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${i} token (${s.status}): ${l}`)}let o=await s.json();if(!o||typeof o!="object")throw new Error(`Invalid response from ${i} token endpoint: expected object, got ${typeof o}`);if(i==="jira"){if(!o.token||typeof o.token!="string")throw new Error(`Invalid jira token response: token is ${typeof o.token}, expected string`);if(!o.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(i==="github"&&(!o.token||typeof o.token!="string"))throw new Error(`Invalid github token response: token is ${typeof o.token}, expected string`);let c=((o.expiresInSec||3e3)-120)*1e3;return qe.set(i,{data:o,expiresAt:e+c}),o}function Vs(i){i?qe.delete(i):qe.clear()}import{readdir as Xs,access as wr,copyFile as qs,constants as xr}from"fs/promises";import{join as Qe,relative as Qs}from"node:path";async function eo(i={}){let{testResultsDir:e="test-results",testsDir:t="tests",projectRoot:r=process.cwd(),verbose:n=!0}=i;n&&console.log(`\u{1F3A5} Organizing test videos...
|
|
151
|
+
${p}`),r.invoke(p,f)}import{SKILLS as Ku}from"@zibby/agent-workflow";import{registerSkill as Hu,getSkill as Zu,hasSkill as Wu,getAllSkills as Vu,listSkillIds as Xu}from"@zibby/agent-workflow";var Ms={READ_FILE:"read_file",WRITE_FILE:"write_file",LIST_DIRECTORY:"list_directory",RUN_COMMAND:"run_command",OPEN_URL:"open_url",WAIT:"wait"},Ls={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"},Ds={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"},Us={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"},Bs={GENERATE:"run_generate",TEST:"run_test",STATUS:"run_status",CANCEL:"run_cancel",WAIT:"run_wait",ARTIFACTS:"run_artifacts",LIST_SPECS:"list_specs"},Fs={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"},js={STORE:"memory_store",RECALL:"memory_recall",BRIEF:"memory_brief",END_SESSION:"memory_end_session",TASK_LOG:"task_log",TASK_HISTORY:"task_history"},Gs={INSTALL:"install_skill",UNINSTALL:"uninstall_skill",LIST_AVAILABLE:"list_available_skills"},Pc={...Ms,...Ls,...Ds,...Us,...Bs,...Fs,...js,...Gs};import{existsSync as zs,readFileSync as Js}from"node:fs";import{homedir as Ks}from"node:os";import{join as Ys}from"node:path";var qe=new Map;function Hs(){if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let i=Ys(Ks(),".zibby","config.json");return zs(i)&&JSON.parse(Js(i,"utf-8")).sessionToken||null}catch{return null}}function Zs(){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://account-api-prod.zibby.app"}async function Ws(i){let e=Date.now(),t=qe.get(i);if(t&&t.expiresAt>e)return t.data;let r=Hs();if(!r)throw new Error("No session token. Run `zibby login` first.");let n=`${Zs()}/integrations/token/${i}`,s=await fetch(n,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!s.ok){let l=await s.text().catch(()=>"");throw s.status===404?new Error(`${i} is not connected. Connect it at https://studio.zibby.app/integrations`):s.status===401||s.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Failed to resolve ${i} token (${s.status}): ${l}`)}let o=await s.json();if(!o||typeof o!="object")throw new Error(`Invalid response from ${i} token endpoint: expected object, got ${typeof o}`);if(i==="jira"){if(!o.token||typeof o.token!="string")throw new Error(`Invalid jira token response: token is ${typeof o.token}, expected string`);if(!o.cloudId)throw new Error("Invalid jira token response: missing cloudId")}else if(i==="github"&&(!o.token||typeof o.token!="string"))throw new Error(`Invalid github token response: token is ${typeof o.token}, expected string`);let c=((o.expiresInSec||3e3)-120)*1e3;return qe.set(i,{data:o,expiresAt:e+c}),o}function Vs(i){i?qe.delete(i):qe.clear()}import{readdir as Xs,access as wr,copyFile as qs,constants as xr}from"fs/promises";import{join as Qe,relative as Qs}from"node:path";async function eo(i={}){let{testResultsDir:e="test-results",testsDir:t="tests",projectRoot:r=process.cwd(),verbose:n=!0}=i;n&&console.log(`\u{1F3A5} Organizing test videos...
|
|
152
152
|
`);let s=Qe(r,e),o=Qe(r,t);try{let c=await Xs(s),l=0;for(let a of c){if(a.startsWith("."))continue;let u=Qe(s,a,"video.webm");try{await wr(u,xr.F_OK)}catch{continue}let f=a.replace(/-chromium$/,"").replace(/-firefox$/,"").replace(/-webkit$/,""),d=await to(o,f);if(d){let p=d.replace(/\.spec\.(js|ts)$/,".spec.webm");await qs(u,p),n&&console.log(`\u2705 ${Qs(r,p)}`),l++}else n&&console.log(`\u26A0\uFE0F Could not find test file for: ${a}`)}return n&&(console.log(`
|
|
153
153
|
\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 to(i,e){let t=e.split("-");for(let r=t.length;r>0;r--){let s=t.slice(0,r).join("/");for(let o of["js","ts"]){let c=Qe(i,`${s}.spec.${o}`);try{return await wr(c,xr.F_OK),c}catch{}}}return null}var Re=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 _r(){let i=process.env.ZIBBY_API_KEY;return new Re(i)}import{execSync as ro}from"node:child_process";import{existsSync as no,mkdirSync as so}from"node:fs";import{join as oo}from"node:path";async function io(i={}){let{baseDir:e="/workspace/repos",repos:t=null,depth:r=1,branch:n=null}=i,s=process.env.REPOS;if(!s)throw new Error("REPOS environment variable not set. Are you running in a Zibby workflow container?");let o;try{o=JSON.parse(s)}catch(a){throw new Error(`Failed to parse REPOS env var: ${a.message}`,{cause:a})}if(!Array.isArray(o)||o.length===0)throw new Error("No repositories configured for this project");let c=t?o.filter(a=>t.includes(a.name)):o;if(c.length===0)throw new Error(`No matching repositories found. Available: ${o.map(a=>a.name).join(", ")}`);no(e)||so(e,{recursive:!0});let l={};return await Promise.all(c.map(async a=>{let u=a.provider||"github",f=u==="gitlab"?process.env.GITLAB_TOKEN:process.env.GITHUB_TOKEN;if(!f){console.error(`${u.toUpperCase()}_TOKEN not set, skipping ${a.name}`),l[a.name]=null;return}let d=a.name.replace(/\//g,"-"),p=oo(e,d),g=a.cloneUrl||a.url;if(!g){console.error(`Repository "${a.name}" has no clone URL`),l[a.name]=null;return}let S;u==="gitlab"?S=g.replace(/^https:\/\//,`https://oauth2:${f}@`):S=g.replace(/^https:\/\//,`https://x-access-token:${f}@`);let h=["clone"];r>0&&h.push("--depth",r.toString()),n&&h.push("--branch",n),h.push(S,p);let w=`git ${h.join(" ")}`;console.log(`Cloning ${a.name} (${u}) to ${p}...`);try{ro(w,{stdio:"pipe",env:{...process.env,GIT_TERMINAL_PROMPT:"0"}}),console.log(`Repository ${a.name} cloned successfully`),l[a.name]=p}catch(x){let _=x.message.replace(f,"***").replace(S,g);console.error(`Failed to clone ${a.name}: ${_}`),l[a.name]=null}})),l}import{spawn as Er}from"node:child_process";import{readFileSync as ao,writeFileSync as co,existsSync as et}from"node:fs";import{homedir as Tr}from"node:os";import{join as fe}from"node:path";async function lo(){let i=fe(Tr(),".local/share/cursor-agent/versions");if(!et(i))throw new Error(`cursor-agent not found at ${i}. Please install cursor-agent first.`);return console.log(`\u{1F527} Patching cursor-agent for CI/CD...
|
|
154
154
|
`),new Promise((e,t)=>{let r=fe(__dirname,"../../scripts/patch-cursor-mcp.py");if(!et(r)){t(new Error("Patch script not found"));return}let n=Er("python3",[r],{stdio:"inherit"});n.on("close",s=>{s===0?e({success:!0}):t(new Error(`Patch failed with code ${s}`))}),n.on("error",s=>{t(s)})})}function uo(){let i=fe(Tr(),".local/share/cursor-agent/versions");if(!et(i))return{patched:!1,installed:!1};try{let e=zr("fs").readdirSync(i);if(e.length===0)return{patched:!1,installed:!1};let t=e.sort().reverse()[0],r=fe(i,t,"index.js");return et(r)?{patched:ao(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 po(i){return console.log(`\u{1F511} Getting MCP approval keys...
|
|
155
155
|
`),new Promise((e,t)=>{let r=Er("cursor-agent",["mcp","list"],{cwd:i,stdio:"pipe"}),n="";r.stdout.on("data",s=>{n+=s.toString(),process.stdout.write(s)}),r.stderr.on("data",s=>{process.stderr.write(s)}),r.on("close",s=>{if(s===0){let o=fo(n);e({success:!0,keys:o,output:n})}else t(new Error(`Failed to get approval keys (exit code ${s})`))}),r.on("error",s=>{t(s)})})}function fo(i){let e={},t=/🔑 APPROVAL KEY:\s+(\S+)\s+=>\s+(\S+)/g,r;for(;(r=t.exec(i))!==null;)e[r[1]]=r[2];return e}function mo(i,e){let t=fe(i,".cursor/projects"),r=fe(t,"mcp-approvals.json");co(r,JSON.stringify(e,null,2)),console.log(`
|
|
156
156
|
\u2705 Saved approval keys to: ${r}
|
|
157
|
-
`)}import{DEFAULT_OUTPUT_BASE as ip,SESSIONS_DIR as ap,SESSION_INFO_FILE as cp,RESULT_FILE as lp,RAW_OUTPUT_FILE as up,EVENTS_FILE as pp,CI_ENV_VARS as fp}from"@zibby/workflow";var vr=`
|
|
157
|
+
`)}import{DEFAULT_OUTPUT_BASE as ip,SESSIONS_DIR as ap,SESSION_INFO_FILE as cp,RESULT_FILE as lp,RAW_OUTPUT_FILE as up,EVENTS_FILE as pp,CI_ENV_VARS as fp}from"@zibby/agent-workflow";var vr=`
|
|
158
158
|
const style = document.createElement('style');
|
|
159
159
|
style.textContent = \`
|
|
160
160
|
@keyframes zibby-ripple {
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.44",
|
|
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",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as he,getSkill as F}from"@zibby/workflow";import R from"chalk";var w={debug:0,info:1,warn:2,error:3,silent:4},Y=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return w.debug;if(process.env.ZIBBY_VERBOSE==="true")return w.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in w?w[e]:w.info}_shouldLog(e){return w[e]>=this._level}_formatMessage(e,t,s={}){let o=new Date().toISOString(),l=`${this._getPrefix(e)} ${t}`;return Object.keys(s).length>0&&(l+=R.dim(` ${JSON.stringify(s)}`)),l}_getPrefix(e){return{debug:R.gray("[DEBUG]"),info:R.cyan("[INFO]"),warn:R.yellow("[WARN]"),error:R.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 w&&(this._level=w[e])}getLevel(){return Object.keys(w).find(e=>w[e]===this._level)}},O=new Y;var K={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 we={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var L=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 $=class extends L{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(s=>({id:s.id,name:s.function.name,args:JSON.parse(s.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 M=class{async fetchCompletion(e,t,s={}){throw new Error("fetchCompletion() must be implemented")}async fetchStreamingCompletion(e,t,s={}){throw new Error("fetchStreamingCompletion() must be implemented")}};function N(n){return Buffer.byteLength(JSON.stringify(n),"utf8")}function U(n,e){let t=String(n||"");if(t.length<=e)return t;let s=Math.max(0,e-28);return`${t.slice(0,s)}
|
|
1
|
+
import{AgentStrategy as he,getSkill as F}from"@zibby/agent-workflow";import R from"chalk";var w={debug:0,info:1,warn:2,error:3,silent:4},Y=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return w.debug;if(process.env.ZIBBY_VERBOSE==="true")return w.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in w?w[e]:w.info}_shouldLog(e){return w[e]>=this._level}_formatMessage(e,t,s={}){let o=new Date().toISOString(),l=`${this._getPrefix(e)} ${t}`;return Object.keys(s).length>0&&(l+=R.dim(` ${JSON.stringify(s)}`)),l}_getPrefix(e){return{debug:R.gray("[DEBUG]"),info:R.cyan("[INFO]"),warn:R.yellow("[WARN]"),error:R.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 w&&(this._level=w[e])}getLevel(){return Object.keys(w).find(e=>w[e]===this._level)}},O=new Y;var K={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 we={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var L=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 $=class extends L{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(s=>({id:s.id,name:s.function.name,args:JSON.parse(s.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 M=class{async fetchCompletion(e,t,s={}){throw new Error("fetchCompletion() must be implemented")}async fetchStreamingCompletion(e,t,s={}){throw new Error("fetchStreamingCompletion() must be implemented")}};function N(n){return Buffer.byteLength(JSON.stringify(n),"utf8")}function U(n,e){let t=String(n||"");if(t.length<=e)return t;let s=Math.max(0,e-28);return`${t.slice(0,s)}
|
|
2
2
|
|
|
3
3
|
[truncated for size budget]`}function G(n,e=0){if(!n||typeof n!="object"||e>8)return n;if(Array.isArray(n))return n.map(s=>G(s,e+1));let t={};for(let[s,o]of Object.entries(n))s==="description"||s==="title"||s==="examples"||s==="default"||(t[s]=G(o,e+1));return t}function ne(n=[]){return n.map(e=>({...e,function:{...e.function,description:U(e.function?.description||"",180),parameters:G(e.function?.parameters||{type:"object",properties:{}})}}))}function q(n){let e=new Set;for(let o of n)if(o.role==="assistant"&&Array.isArray(o.tool_calls))for(let r of o.tool_calls)e.add(r.id);let t=n.filter(o=>o.role==="tool"?e.has(o.tool_call_id):!0),s=new Set;for(let o of t)o.role==="tool"&&s.add(o.tool_call_id);return t.map(o=>{if(o.role!=="assistant"||!Array.isArray(o.tool_calls)||o.tool_calls.every(a=>s.has(a.id)))return o;let{tool_calls:l,...i}=o;return{...i,content:i.content||""}})}function X(n,e={}){let t=e.maxBytes||49e3,s=e.systemMaxChars||12e3,o={...n,messages:Array.isArray(n.messages)?[...n.messages]:[],tools:Array.isArray(n.tools)?ne(n.tools):n.tools};o.messages.length>0&&o.messages[0]?.role==="system"&&(o.messages[0]={...o.messages[0],content:U(o.messages[0].content,s)});let r=!1;for(;N(o)>t&&o.messages.length>2;)o.messages.splice(1,1),r=!0;if(r&&(o.messages=q(o.messages)),N(o)>t&&o.messages.length>0&&(o.messages[0]={...o.messages[0],content:U(o.messages[0].content,6e3)},r=!0),N(o)>t){let l=o.messages.find(a=>a.role==="system")||o.messages[0],i=o.messages.slice(-2);o.messages=q([l,...i].filter(Boolean).map((a,c)=>({...a,content:U(a.content,c===0?4e3:8e3)}))),r=!0}return{body:o,meta:{bytes:N(o),trimmed:r,maxBytes:t,messageCount:o.messages.length}}}var W=n=>Buffer.byteLength(JSON.stringify(n),"utf8"),P=class extends M{async fetchCompletion(e,t,s={}){let o=W(e),{body:r,meta:l}=X(e,s.payloadCompaction);s.onBudget?.({streaming:!1,beforeBytes:o,meta:l});let i=this.#e(s),a=`${t.baseUrl}${s.chatCompletionsPath||"/v1/chat/completions"}`,c=await fetch(a,{method:"POST",headers:t.headers,body:JSON.stringify(r),signal:i});if(!c.ok){let u=await c.text();throw c.status===401||c.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Proxy error ${c.status}: ${u}`)}return c.json()}async fetchStreamingCompletion(e,t,s={}){let o={...e,stream:!0},r=W(o),{body:l,meta:i}=X(o,s.payloadCompaction);s.onBudget?.({streaming:!0,beforeBytes:r,meta:i});let a=this.#e(s),c=`${t.baseUrl}${s.chatCompletionsPath||"/v1/chat/completions"}`,u=await fetch(c,{method:"POST",headers:t.headers,body:JSON.stringify(l),signal:a});if(!u.ok){let d=await u.text();throw u.status===401||u.status===403?new Error("Session expired. Run `zibby login` to re-authenticate."):new Error(`Proxy error ${u.status}: ${d}`)}let p=u.body.getReader(),x=new TextDecoder,S="",A="",E=new Map;for(;;){let{done:d,value:g}=await p.read();if(d)break;S+=x.decode(g,{stream:!0});let h=S.split(`
|
|
4
4
|
`);S=h.pop();for(let f of h){if(!f.startsWith("data: "))continue;let m=f.slice(6).trim();if(m==="[DONE]")continue;let C;try{C=JSON.parse(m)}catch{continue}let T=C.choices?.[0]?.delta;if(T&&(T.content&&(A+=T.content,s.onToken&&s.onToken(T.content)),T.tool_calls))for(let y of T.tool_calls){let b=y.index??0;E.has(b)||E.set(b,{id:"",name:"",args:""});let k=E.get(b);y.id&&(k.id=y.id),y.function?.name&&(k.name=y.function.name),y.function?.arguments!=null&&(k.args+=y.function.arguments)}}}if(E.size>0){let d=[...E.entries()].sort(([g],[h])=>g-h).map(([,g])=>({id:g.id,type:"function",function:{name:g.name,arguments:g.args}}));return{choices:[{message:{role:"assistant",content:A||null,tool_calls:d}}]}}return{choices:[{message:{role:"assistant",content:A}}]}}#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 re}from"@modelcontextprotocol/sdk/client/index.js";import{StdioClientTransport as ie}from"@modelcontextprotocol/sdk/client/stdio.js";var D=class{#e=new Map;async ensureServer(e,t){if(this.#e.has(e))return this.#e.get(e);let{command:s,args:o=[],env:r={}}=t;O.debug(`[MCP] Starting ${e}: ${s} ${o.join(" ")}`);let l=new ie({command:s,args:o,env:{...process.env,...r}}),i=new re({name:`zibby-chat-${e}`,version:"1.0.0"},{capabilities:{}});await i.connect(l);let a={client:i,transport:l,serverConfig:t};return this.#e.set(e,a),a}async callTool(e,t,s={}){let o=this.#e.get(e);if(!o)throw new Error(`MCP server "${e}" not running`);O.debug(`[MCP] ${e}.${t}(${JSON.stringify(s).slice(0,200)})`);let r=await o.client.callTool({name:t,arguments:s});return{text:r.content?.filter(i=>i.type==="text").map(i=>i.text).join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as G,getSkill as K}from"@zibby/workflow";import{query as J}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as F}from"zod-to-json-schema";import f from"chalk";var c={debug:0,info:1,warn:2,error:3,silent:4},O=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return c.debug;if(process.env.ZIBBY_VERBOSE==="true")return c.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in c?c[e]:c.info}_shouldLog(e){return c[e]>=this._level}_formatMessage(e,s,a={}){let i=new Date().toISOString(),l=`${this._getPrefix(e)} ${s}`;return Object.keys(a).length>0&&(l+=f.dim(` ${JSON.stringify(a)}`)),l}_getPrefix(e){return{debug:f.gray("[DEBUG]"),info:f.cyan("[INFO]"),warn:f.yellow("[WARN]"),error:f.red("\u274C [ERROR]")}[e]||""}debug(e,s){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,s))}info(e,s){this._shouldLog("info")&&console.log(this._formatMessage("info",e,s))}warn(e,s){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,s))}error(e,s){this._shouldLog("error")&&console.error(this._formatMessage("error",e,s))}setLevel(e){e in c&&(this._level=c[e])}getLevel(){return Object.keys(c).find(e=>c[e]===this._level)}},r=new O;import{timeline as A,Timeline as H,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as X}from"@zibby/workflow";var y={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 w={auto:"claude-sonnet-4-6","sonnet-4.6":"claude-sonnet-4-6","sonnet-4-6":"claude-sonnet-4-6","opus-4.6":"claude-opus-4-6","opus-4-6":"claude-opus-4-6","sonnet-4.5":"claude-sonnet-4-5-20250929","sonnet-4-5":"claude-sonnet-4-5-20250929","opus-4.5":"claude-opus-4-20250514","opus-4-5":"claude-opus-4-20250514","claude-sonnet-4-6":"claude-sonnet-4-6","claude-opus-4-6":"claude-opus-4-6","claude-sonnet-4-5-20250929":"claude-sonnet-4-5-20250929","claude-opus-4-20250514":"claude-opus-4-20250514"};var V={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var $=class extends G{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let s=!!process.env.ANTHROPIC_API_KEY;return s||r.debug("ClaudeAgentStrategy: ANTHROPIC_API_KEY not set"),s}async invoke(e,s={}){let{model:a,workspace:i=process.cwd(),schema:n=null,images:l=[],skills:p=null,sessionPath:v=null,nodeName:R=null,timeout:B,config:Z={}}=s,g=a;(!g||g==="auto")&&(r.debug(`Model is '${g||"undefined"}', using default: ${y.CLAUDE}`),g=y.CLAUDE);let m=w[g]||g;w[g]&&g!==m&&r.debug(`Mapped model: ${g} \u2192 ${m}`),r.debug(`Invoking Claude Agent SDK with model: ${m}, skills: ${JSON.stringify(p)}`);let L=process.env.ANTHROPIC_API_KEY,C=L?` | key: ***${L.slice(-4)}`:" | key: not set";console.log(`
|
|
1
|
+
import{AgentStrategy as G,getSkill as K}from"@zibby/agent-workflow";import{query as J}from"@anthropic-ai/claude-agent-sdk";import{zodToJsonSchema as F}from"zod-to-json-schema";import f from"chalk";var c={debug:0,info:1,warn:2,error:3,silent:4},O=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return c.debug;if(process.env.ZIBBY_VERBOSE==="true")return c.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in c?c[e]:c.info}_shouldLog(e){return c[e]>=this._level}_formatMessage(e,s,a={}){let i=new Date().toISOString(),l=`${this._getPrefix(e)} ${s}`;return Object.keys(a).length>0&&(l+=f.dim(` ${JSON.stringify(a)}`)),l}_getPrefix(e){return{debug:f.gray("[DEBUG]"),info:f.cyan("[INFO]"),warn:f.yellow("[WARN]"),error:f.red("\u274C [ERROR]")}[e]||""}debug(e,s){this._shouldLog("debug")&&console.log(this._formatMessage("debug",e,s))}info(e,s){this._shouldLog("info")&&console.log(this._formatMessage("info",e,s))}warn(e,s){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",e,s))}error(e,s){this._shouldLog("error")&&console.error(this._formatMessage("error",e,s))}setLevel(e){e in c&&(this._level=c[e])}getLevel(){return Object.keys(c).find(e=>c[e]===this._level)}},r=new O;import{timeline as A,Timeline as H,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as X}from"@zibby/agent-workflow";var y={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 w={auto:"claude-sonnet-4-6","sonnet-4.6":"claude-sonnet-4-6","sonnet-4-6":"claude-sonnet-4-6","opus-4.6":"claude-opus-4-6","opus-4-6":"claude-opus-4-6","sonnet-4.5":"claude-sonnet-4-5-20250929","sonnet-4-5":"claude-sonnet-4-5-20250929","opus-4.5":"claude-opus-4-20250514","opus-4-5":"claude-opus-4-20250514","claude-sonnet-4-6":"claude-sonnet-4-6","claude-opus-4-6":"claude-opus-4-6","claude-sonnet-4-5-20250929":"claude-sonnet-4-5-20250929","claude-opus-4-20250514":"claude-opus-4-20250514"};var V={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var $=class extends G{constructor(){super("claude","Claude (Anthropic API)",50)}canHandle(e){let s=!!process.env.ANTHROPIC_API_KEY;return s||r.debug("ClaudeAgentStrategy: ANTHROPIC_API_KEY not set"),s}async invoke(e,s={}){let{model:a,workspace:i=process.cwd(),schema:n=null,images:l=[],skills:p=null,sessionPath:v=null,nodeName:R=null,timeout:B,config:Z={}}=s,g=a;(!g||g==="auto")&&(r.debug(`Model is '${g||"undefined"}', using default: ${y.CLAUDE}`),g=y.CLAUDE);let m=w[g]||g;w[g]&&g!==m&&r.debug(`Mapped model: ${g} \u2192 ${m}`),r.debug(`Invoking Claude Agent SDK with model: ${m}, skills: ${JSON.stringify(p)}`);let L=process.env.ANTHROPIC_API_KEY,C=L?` | key: ***${L.slice(-4)}`:" | key: not set";console.log(`
|
|
2
2
|
\u25C6 Model: ${m}${C}
|
|
3
3
|
`);let h=(await import("chalk")).default;console.log(`
|
|
4
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{allowedTools:M,mcpServers:T}=this._resolveSkills(p,{sessionPath:v,workspace:i,nodeName:R});try{let d={cwd:i,allowedTools:M,permissionMode:"bypassPermissions",model:m,...Object.keys(T).length>0&&{mcpServers:T}};if(n){let E=typeof n.parse=="function"?F(n,{target:"openApi3"}):n;d.outputFormat={type:"json_schema",schema:E},r.debug("Structured output enforced via SDK outputFormat")}r.debug(`Agent SDK options: ${JSON.stringify({cwd:d.cwd,toolCount:M.length,permissionMode:d.permissionMode,model:d.model,hasOutputFormat:!!d.outputFormat})}`);let _="",k=0,x=[];r.debug("Starting Claude Agent SDK query stream");let I;try{I=J({prompt:e,options:d})}catch(t){throw r.error(`Failed to initialize Claude Agent SDK: ${t.message}`),t}let N=null,S=0,P=3;try{for await(let t of I){if(x.push(t),t.type==="error"||t.error){let u=t.error?.message||t.error||t.message||"Unknown API error";throw new Error(typeof u=="string"?u:JSON.stringify(u))}let E=JSON.stringify(t.message?.content||t.text||"").slice(0,200);if(E===N){if(S++,S>=P){let u=(t.message?.content?.[0]?.text||t.text||"unknown").slice(0,100);throw new Error(`API stuck in loop (${S}x repeated): ${u}`)}}else N=E,S=1;if(t.type==="assistant"||t.constructor?.name==="AssistantMessage"){let u=t.message?.content||t.content||[];for(let o of u)if(o.type==="thinking"&&o.thinking)console.log(`${o.thinking.substring(0,200)}${o.thinking.length>200?"...":""}`);else if(o.type==="text"&&o.text)_+=o.text,o.text.length<500?console.log(`${o.text}`):console.log(`${o.text.substring(0,200)}... (${o.text.length} chars)`);else if(o.type==="tool_use"){k++,o.name.includes("memory")?A.stepMemory(`Tool: ${o.name}`):A.stepTool(`Tool: ${o.name}`);let U=JSON.stringify(o.input).substring(0,100);console.log(` Input: ${U}${JSON.stringify(o.input).length>100?"...":""}`)}}else if(!(t.type==="user"&&t.tool_use_result)){if(t.type==="result"||t.constructor?.name==="ResultMessage"){let u=t.result||t.text||t.content||_;if(n){if(t.structured_output){r.debug("Using SDK native structured_output");let D=typeof n.parse=="function"?n.parse(t.structured_output):t.structured_output;return{raw:u,structured:D}}if(u){let o=this._extractJson(u,n);if(o)return{raw:u,structured:o}}r.warn(`Could not extract structured output \u2014 returning raw text (${(u||"").length} chars)`)}return u||""}}}if(r.warn(`Agent SDK ended without result. Collected ${x.length} messages`),_.length>0)return r.debug("Returning accumulated text from messages"),_;throw new Error("Claude Agent SDK query ended without result")}catch(t){throw r.error(`Error during query stream: ${t.message}`),t}}catch(d){throw r.error("Claude Agent SDK call failed",{error:d.message}),d}}_resolveSkills(e,s){if(e===null)return r.debug("No skills \u2014 pure LLM mode"),{allowedTools:[],mcpServers:{}};if(!Array.isArray(e)||e.length===0)return r.debug("Default IDE skills for code generation"),{allowedTools:["Read","Write","Bash","Grep","Glob"],mcpServers:{}};let a=[],i={};for(let n of e){let l=K(n);if(!l){r.warn(`Unknown skill "${n}" \u2014 skipping`);continue}if(l.allowedTools&&a.push(...l.allowedTools),typeof l.resolve=="function"){let p=l.resolve(s);p&&(i[l.serverName]=p,r.debug(`MCP: ${l.serverName} \u2192 ${p.command} ${p.args[0]}`))}}return{allowedTools:a,mcpServers:i}}_extractJson(e,s){let a=[()=>{if(e.includes("===JSON_START===")){let i=e.indexOf("===JSON_START===")+16,n=e.indexOf("===JSON_END===");return e.substring(i,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 i=e.indexOf("{"),n=e.lastIndexOf("}");if(i!==-1&&n>i)return e.substring(i,n+1)}];for(let i of a)try{let n=i();if(!n)continue;let l=JSON.parse(n);if(typeof l!="object"||l===null)continue;return typeof s.parse=="function"?s.parse(l):l}catch{}return null}};export{$ as ClaudeAgentStrategy};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as K,getSkill as U}from"@zibby/workflow";import{execSync as G}from"node:child_process";import{zodToJsonSchema as X}from"zod-to-json-schema";import E from"chalk";var i={debug:0,info:1,warn:2,error:3,silent:4},L=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return i.debug;if(process.env.ZIBBY_VERBOSE==="true")return i.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in i?i[e]:i.info}_shouldLog(e){return i[e]>=this._level}_formatMessage(e,t,u={}){let d=new Date().toISOString(),n=`${this._getPrefix(e)} ${t}`;return Object.keys(u).length>0&&(n+=E.dim(` ${JSON.stringify(u)}`)),n}_getPrefix(e){return{debug:E.gray("[DEBUG]"),info:E.cyan("[INFO]"),warn:E.yellow("[WARN]"),error:E.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 i&&(this._level=i[e])}getLevel(){return Object.keys(i).find(e=>i[e]===this._level)}},o=new L;import{timeline as y,Timeline as Z,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as H}from"@zibby/workflow";var w={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 $={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"};var q={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var P=class extends K{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY))return o.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return G("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return o.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:u,workspace:d=process.cwd(),schema:s=null,skills:n=null,sessionPath:h=null,nodeName:p=null,timeout:Y,config:j={}}=t,{Codex:b}=await import("@openai/codex-sdk"),c=u;(!c||c==="auto")&&(o.debug(`Model is '${c||"undefined"}', using default: ${w.CODEX}`),c=w.CODEX);let x=$[c]||c;$[c]&&c!==x&&o.debug(`Mapped model: ${c} \u2192 ${x}`),o.debug(`Invoking Codex SDK with model: ${x}, skills: ${JSON.stringify(n)}`);let O=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;O&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=O);let k=O?` | key: ***${O.slice(-4)}`:" | key: not set";console.log(`
|
|
1
|
+
import{AgentStrategy as K,getSkill as U}from"@zibby/agent-workflow";import{execSync as G}from"node:child_process";import{zodToJsonSchema as X}from"zod-to-json-schema";import E from"chalk";var i={debug:0,info:1,warn:2,error:3,silent:4},L=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return i.debug;if(process.env.ZIBBY_VERBOSE==="true")return i.info;let e=process.env.LOG_LEVEL?.toLowerCase();return e&&e in i?i[e]:i.info}_shouldLog(e){return i[e]>=this._level}_formatMessage(e,t,u={}){let d=new Date().toISOString(),n=`${this._getPrefix(e)} ${t}`;return Object.keys(u).length>0&&(n+=E.dim(` ${JSON.stringify(u)}`)),n}_getPrefix(e){return{debug:E.gray("[DEBUG]"),info:E.cyan("[INFO]"),warn:E.yellow("[WARN]"),error:E.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 i&&(this._level=i[e])}getLevel(){return Object.keys(i).find(e=>i[e]===this._level)}},o=new L;import{timeline as y,Timeline as Z,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as H}from"@zibby/agent-workflow";var w={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 $={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"};var q={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var P=class extends K{constructor(){super("codex","Codex (OpenAI)",75)}canHandle(e){if(!!!(process.env.OPENAI_API_KEY||process.env.CODEX_API_KEY))return o.debug("CodexAgentStrategy: OPENAI_API_KEY or CODEX_API_KEY not set"),!1;try{return G("codex --version",{encoding:"utf-8",timeout:5e3,stdio:"pipe"}),!0}catch{return o.warn("[Codex] codex CLI not found. Install: npm install -g @openai/codex"),!1}}async invoke(e,t={}){let{model:u,workspace:d=process.cwd(),schema:s=null,skills:n=null,sessionPath:h=null,nodeName:p=null,timeout:Y,config:j={}}=t,{Codex:b}=await import("@openai/codex-sdk"),c=u;(!c||c==="auto")&&(o.debug(`Model is '${c||"undefined"}', using default: ${w.CODEX}`),c=w.CODEX);let x=$[c]||c;$[c]&&c!==x&&o.debug(`Mapped model: ${c} \u2192 ${x}`),o.debug(`Invoking Codex SDK with model: ${x}, skills: ${JSON.stringify(n)}`);let O=process.env.CODEX_API_KEY||process.env.OPENAI_API_KEY;O&&!process.env.CODEX_API_KEY&&(process.env.CODEX_API_KEY=O);let k=O?` | key: ***${O.slice(-4)}`:" | key: not set";console.log(`
|
|
2
2
|
\u25C6 Model: ${x}${k}
|
|
3
3
|
`);let v=(await import("chalk")).default;console.log(`
|
|
4
4
|
${v.bold("Prompt sent to LLM:")}`),console.log(v.dim("\u2500".repeat(60))),console.log(v.dim(e)),console.log(v.dim("\u2500".repeat(60)));let S=this._resolveSkillsToMcp(n,{sessionPath:h,workspace:d,nodeName:p}),C={};Object.keys(S).length>0&&(C.mcp_servers=S,o.debug(`[Codex] MCP servers: ${Object.keys(S).join(", ")}`));let T=new b({...Object.keys(C).length>0&&{config:C}}).startThread({workingDirectory:d,skipGitRepoCheck:!0,approvalPolicy:"never",sandboxMode:"danger-full-access",networkAccessEnabled:!0}),M=s&&typeof s.parse=="function",D={};if(s)try{let l=M?X(s,{target:"openAi"}):s;D.outputSchema=l,o.debug("Structured output via SDK outputSchema")}catch(l){o.warn(`[Codex] Schema conversion failed, will extract from text: ${l.message}`)}try{let{events:l}=await T.runStreamed(e,D),m=0,r="";for await(let g of l){let f=g.type;if(f==="item.completed"){let a=g.item,_=a?.type;if(_==="mcp_tool_call"){m++;let A=`${a.server}/${a.tool}`;if(y.stepTool(`Tool: ${A}`),a.arguments){let I=JSON.stringify(a.arguments),R=I.length>100?`${I.substring(0,100)}...`:I;console.log(` Input: ${R}`)}}else if(_==="tool_call"||_==="function_call"||_==="command_execution"){m++;let A=a.name||a.tool||a.command||"unknown";y.stepTool(`Tool: ${A}`)}else _==="agent_message"&&(r=a.text||"",r.length<500?console.log(r):console.log(`${r.substring(0,200)}... (${r.length} chars)`))}else f==="turn.completed"?o.debug(`[Codex] Turn completed. Usage: ${JSON.stringify(g.usage||{})}`):o.debug(`[Codex] Event: ${f} ${JSON.stringify(g).slice(0,300)}`)}if(o.debug(`[Codex] Last agent message (${r.length} chars): ${r.slice(0,500)}`),s){if(!r)throw new Error("Codex agent returned no response");let g=JSON.parse(r),f=M?s.parse(g):g;return o.debug("\u2705 [Codex] Structured output validated"),{raw:r,structured:f}}return r||""}catch(l){let m=l.message||String(l);throw o.error(`\u274C [Codex] SDK call failed: ${m}`),m.includes("exited with code")&&(o.error("\u{1F4A1} [Codex] Verify: codex --version && echo $OPENAI_API_KEY"),o.error("\u{1F4A1} [Codex] If codex is missing: npm install -g @openai/codex")),l}}_resolveSkillsToMcp(e,t={}){if(!Array.isArray(e)||e.length===0)return{};let u={};for(let d of e){let s=U(d);if(!s){o.warn(`[Codex] Unknown skill "${d}" \u2014 skipping`);continue}if(typeof s.resolve!="function")continue;let n=s.resolve(t);if(!n)continue;let h=s.serverName||d,p={command:n.command};n.args?.length&&(p.args=n.args),n.env&&Object.keys(n.env).length>0&&(p.env=n.env),u[h]=p,o.debug(`[Codex] MCP: ${h} \u2192 ${n.command} ${(n.args||[]).join(" ")}`)}return u}};export{P as CodexAgentStrategy};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as Rt,DEFAULT_OUTPUT_BASE as Pt,SESSION_INFO_FILE as Ct,STUDIO_STOP_REQUEST_FILE as Nt,getAllSkills as kt,getSkill as it}from"@zibby/workflow";import{spawn as Lt,execSync as M}from"node:child_process";import{writeFileSync as lt,readFileSync as at,mkdirSync as ut,existsSync as H,accessSync as ct,constants as pt,unlinkSync as Ut}from"node:fs";import{join as v,resolve as Mt}from"node:path";import{homedir as Y}from"node:os";import K from"chalk";var C={debug:0,info:1,warn:2,error:3,silent:4},q=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return C.debug;if(process.env.ZIBBY_VERBOSE==="true")return C.info;let t=process.env.LOG_LEVEL?.toLowerCase();return t&&t in C?C[t]:C.info}_shouldLog(t){return C[t]>=this._level}_formatMessage(t,e,r={}){let s=new Date().toISOString(),n=`${this._getPrefix(t)} ${e}`;return Object.keys(r).length>0&&(n+=K.dim(` ${JSON.stringify(r)}`)),n}_getPrefix(t){return{debug:K.gray("[DEBUG]"),info:K.cyan("[INFO]"),warn:K.yellow("[WARN]"),error:K.red("\u274C [ERROR]")}[t]||""}debug(t,e){this._shouldLog("debug")&&console.log(this._formatMessage("debug",t,e))}info(t,e){this._shouldLog("info")&&console.log(this._formatMessage("info",t,e))}warn(t,e){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",t,e))}error(t,e){this._shouldLog("error")&&console.error(this._formatMessage("error",t,e))}setLevel(t){t in C&&(this._level=C[t])}getLevel(){return Object.keys(C).find(t=>C[t]===this._level)}},o=new q;var G={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 W={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var Z=class l{constructor(){this.buffer="",this.extractedResult=null,this.rawText="",this.zodSchema=null,this.lastOutputLength=0,this.onToolCall=null,this._lastToolEmit=null}processChunk(t){if(!t)return null;this.buffer+=t;let e=this.buffer.split(`
|
|
1
|
+
import{AgentStrategy as Rt,DEFAULT_OUTPUT_BASE as Pt,SESSION_INFO_FILE as Ct,STUDIO_STOP_REQUEST_FILE as Nt,getAllSkills as kt,getSkill as it}from"@zibby/agent-workflow";import{spawn as Lt,execSync as M}from"node:child_process";import{writeFileSync as lt,readFileSync as at,mkdirSync as ut,existsSync as H,accessSync as ct,constants as pt,unlinkSync as Ut}from"node:fs";import{join as v,resolve as Mt}from"node:path";import{homedir as Y}from"node:os";import K from"chalk";var C={debug:0,info:1,warn:2,error:3,silent:4},q=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return C.debug;if(process.env.ZIBBY_VERBOSE==="true")return C.info;let t=process.env.LOG_LEVEL?.toLowerCase();return t&&t in C?C[t]:C.info}_shouldLog(t){return C[t]>=this._level}_formatMessage(t,e,r={}){let s=new Date().toISOString(),n=`${this._getPrefix(t)} ${e}`;return Object.keys(r).length>0&&(n+=K.dim(` ${JSON.stringify(r)}`)),n}_getPrefix(t){return{debug:K.gray("[DEBUG]"),info:K.cyan("[INFO]"),warn:K.yellow("[WARN]"),error:K.red("\u274C [ERROR]")}[t]||""}debug(t,e){this._shouldLog("debug")&&console.log(this._formatMessage("debug",t,e))}info(t,e){this._shouldLog("info")&&console.log(this._formatMessage("info",t,e))}warn(t,e){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",t,e))}error(t,e){this._shouldLog("error")&&console.error(this._formatMessage("error",t,e))}setLevel(t){t in C&&(this._level=C[t])}getLevel(){return Object.keys(C).find(t=>C[t]===this._level)}},o=new q;var G={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 W={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};var Z=class l{constructor(){this.buffer="",this.extractedResult=null,this.rawText="",this.zodSchema=null,this.lastOutputLength=0,this.onToolCall=null,this._lastToolEmit=null}processChunk(t){if(!t)return null;this.buffer+=t;let e=this.buffer.split(`
|
|
2
2
|
`);this.buffer=e.pop()||"";let r="";for(let s of e)if(s.trim())try{let a=JSON.parse(s);this._emitToolCalls(a);let n=this.extractText(a);if(n){if(this.rawText&&n.startsWith(this.rawText)){let u=n.substring(this.rawText.length);this.rawText=n,r+=u}else(!this.rawText.includes(n)||n.length<20)&&(this.rawText+=n,r+=n);this.tryExtractResult(this.rawText)}else this.isValidResult(a)&&(this.rawText+=`${s}
|
|
3
3
|
`,r+=`${s}
|
|
4
4
|
`,this.extractedResult=a)}catch{if(s.includes('"text"')||s.includes('"content"')){let n=s.match(/"text"\s*:\s*"([^"]*)/),u=s.match(/"content"\s*:\s*"([^"]*)/),p=n?n[1]:u?u[1]:null;p&&!this.rawText.includes(p)&&(r+=p,this.rawText+=p)}}return r||null}flush(){if(!this.buffer.trim())return null;let t="";try{let e=JSON.parse(this.buffer);this._emitToolCalls(e);let r=this.extractText(e);r&&(this.rawText+=r,t+=r,this.tryExtractResult(r))}catch{this.rawText+=this.buffer,t+=this.buffer,this.tryExtractResult(this.buffer)}return this.buffer="",t||null}_emitToolCalls(t){if(!this.onToolCall)return;let e=(n,u)=>{if(!n)return;let p=`${n}:${JSON.stringify(u??{})}`;this._lastToolEmit!==p&&(this._lastToolEmit=p,this.onToolCall(n,u??void 0))},r=n=>{if(n!=null){if(typeof n=="object"&&!Array.isArray(n))return n;if(typeof n=="string")try{return JSON.parse(n)}catch{return}}};if(t.type==="tool_use"||t.type==="tool_call"){if(t.name){e(t.name,r(t.input??t.arguments));return}let n=t.tool_call;if(n&&typeof n=="object"&&!Array.isArray(n)){let u=Object.keys(n);if(u.length===1){let p=u[0],g=n[p],c=g&&typeof g=="object"?g.args??g.input??g:void 0;e(p,r(c))}return}return}if(Array.isArray(t.tool_calls)){for(let n of t.tool_calls)e(n.name,r(n.input??n.arguments));return}let s=t.message??t;if(Array.isArray(s?.tool_calls)){for(let n of s.tool_calls)e(n.name,r(n.input??n.arguments));return}let a=s?.content??t.content;if(Array.isArray(a))for(let n of a)(n.type==="tool_use"||n.type==="tool_call")&&n.name&&e(n.name,r(n.input??n.arguments))}extractText(t){if(t.type==="assistant"&&t.message?.content){let e=t.message.content;if(Array.isArray(e))return e.filter(r=>r.type==="text"&&r.text).map(r=>r.text).join("")}return t.type==="thinking"&&t.text||t.text?t.text:t.content&&typeof t.content=="string"?t.content:t.delta?t.delta:null}tryExtractResult(t){if(!t||typeof t!="string")return;let e=[],r=/```json\s*\n?([\s\S]*?)\n?```/g,s;for(;(s=r.exec(t))!==null;){let f=s[1].trim();try{JSON.parse(f),e.push({text:f,source:"markdown"})}catch{}}let a=0,n=0;for(;a<t.length&&(a=t.indexOf("{",a),a!==-1);){let f=0,m=a;for(let E=a;E<t.length;E++)if(t[E]==="{")f++;else if(t[E]==="}"&&(f--,f===0)){m=E,e.push({text:t.substring(a,m+1),source:"brace"}),n++;break}a=m+1}let u=this.extractedResult,p=u?JSON.stringify(u).length:0,g=0,c=-1;for(let f=0;f<e.length;f++){let m=e[f];try{let E=m.text.replace(/,(\s*[}\]])/g,"$1"),A=JSON.parse(E);this.isValidResult(A)&&(g++,p=JSON.stringify(A).length,u=A,c=f)}catch{}}u&&(this.extractedResult=u)}isValidResult(t){if(!t||typeof t!="object"||Array.isArray(t)||t.session_id||t.timestamp_ms||t.type||t.call_id||t.tool_call||t.result&&typeof t.result=="object"&&(t.result.success&&typeof t.result.success=="object"||t.result.error&&typeof t.result.error=="object")||t.args&&typeof t.args=="object")return!1;if(this.zodSchema)try{return this.zodSchema.parse(t),!0}catch{return!1}return!0}getResult(){return this.extractedResult}getRawText(){return this.rawText}static extractResult(t,e=null){let r=new l;r.zodSchema=e,r.processChunk(t),r.flush();let s=r.getResult();return!s&&process.env.LOG_LEVEL==="debug"&&console.error("[StreamingParser] No result extracted from",t?.length||0,"chars"),s}};import{zodToJsonSchema as dt}from"zod-to-json-schema";var X=class{static generateFileOutputInstructions(t,e){let r;typeof t?.parse=="function"?r=dt(t,{target:"openApi3"}):r=t;let s=this._buildExample(r);return`
|
|
@@ -39,7 +39,7 @@ ${u}
|
|
|
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.`,g={model:G.OPENAI_POSTPROCESSING,messages:[{role:"user",content:p}],response_format:{type:"json_schema",json_schema:{name:"extract",schema:a,strict:!0}}};o.info(`\u{1F4E4} Sending to OpenAI proxy: model=${G.OPENAI_POSTPROCESSING}, schema keys=${Object.keys(a.properties||{}).join(", ")}`),o.debug(` Schema size: ${JSON.stringify(a).length} chars`),o.debug(` Prompt size: ${p.length} chars`);try{let c={"Content-Type":"application/json"};process.env.OPENAI_PROXY_TOKEN?(c["x-proxy-token"]=e,c["x-execution-id"]=process.env.EXECUTION_ID||""):(c.Authorization=`Bearer ${e}`,c["x-api-key"]=process.env.ZIBBY_API_KEY||"",c["x-execution-id"]=process.env.EXECUTION_ID||"");let m=(await gt.post(r,g,{headers:c,timeout:W.OPENAI_REQUEST})).data?.choices?.[0]?.message?.content;if(!m)throw new Error("OpenAI proxy returned empty response");let E=JSON.parse(m);return o.info("\u2705 Successfully formatted with OpenAI proxy"),{structured:E,raw:l}}catch(c){if(c.response){let f=c.response.status,m=c.response.data;throw o.error(`\u274C OpenAI proxy request failed: ${f}`),o.error(` Status: ${f}`),o.error(` Response: ${JSON.stringify(m,null,2)}`),f===401||f===403?new Error(`Authentication failed for OpenAI proxy.
|
|
41
41
|
Run \`zibby login\` or set ZIBBY_USER_TOKEN environment variable.
|
|
42
|
-
Response: ${JSON.stringify(m)}`,{cause:c}):new Error(`Failed to format Cursor output: ${m?.error?.message||"Unknown error"}`,{cause:c})}throw o.error(`\u274C OpenAI proxy request failed: ${c.message}`),new Error(`Failed to format output: ${c.message}`,{cause:c})}}import{timeline as Q,Timeline as re,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as ne}from"@zibby/workflow";import{copyFileSync as bt,existsSync as tt,lstatSync as At,mkdirSync as rt,rmSync as xt,symlinkSync as It,unlinkSync as Tt}from"node:fs";import{join as k}from"node:path";import{homedir as wt}from"node:os";import{randomBytes as $t}from"node:crypto";var vt=["cli-config.json","config.json","auth.json","argv.json"];function nt(l){return!(!l||typeof l!="string"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="1"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="true")}function st(l){let t=k(l||process.cwd(),".zibby","tmp");rt(t,{recursive:!0});let e=`${process.pid}-${Date.now()}-${$t(4).toString("hex")}`,r=k(t,`cursor-agent-home-${e}`),s=k(r,".cursor");rt(s,{recursive:!0});let a=wt(),n=k(a,".cursor");if(tt(n))for(let u of vt){let p=k(n,u);if(tt(p))try{bt(p,k(s,u))}catch{}}if(process.platform==="darwin"){let u=k(a,"Library");if(tt(u))try{It(u,k(r,"Library"))}catch{}}return r}function ot(l){if(!(!l||typeof l!="string"))try{let t=k(l,"Library");try{At(t).isSymbolicLink()&&Tt(t)}catch{}xt(l,{recursive:!0,force:!0})}catch{}}var ft=class extends Rt{constructor(){super("cursor","Cursor (CLI)",100)}canHandle(t){let e=[v(Y(),".local","bin","cursor-agent"),v(Y(),".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 e)try{if(r.startsWith("/")){ct(r,pt.X_OK);let s=M(`"${r}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(s&&s.length>0)return o.debug(`[Cursor] Found agent at: ${r} (version: ${s.trim().slice(0,50)})`),!0}else{let s=M(`which ${r}`,{encoding:"utf-8",timeout:2e3,stdio:"pipe"}).trim();if(!s)continue;let a=M(`${r} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(a&&a.length>0)return o.debug(`[Cursor] Found '${r}' in PATH at ${s} (version: ${a.trim().slice(0,50)})`),!0}}catch{continue}return o.warn("[Cursor] \u274C Cursor Agent CLI not found or not working. Run: agent --version"),!1}async invoke(t,e={}){let{workspace:r=process.cwd(),print:s=!1,schema:a=null,skills:n=null,sessionPath:u=null,nodeName:p=null,timeout:g=W.CURSOR_AGENT_DEFAULT,config:c={}}=e,f=c?.agent?.strictMode||!1,m=e.model??c?.agent?.cursor?.model??G.CURSOR;o.debug(`[Cursor] Invoking (model: ${m}, timeout: ${g/1e3}s, skills: ${JSON.stringify(n)})`);let A=(this._setupMcpConfig(u,r,c,n,p)||{}).isolatedMcpHome??null,I=[v(Y(),".local","bin","cursor-agent"),v(Y(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"],h=null;for(let i of I)try{if(i.startsWith("/"))ct(i,pt.X_OK),M(`"${i}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});else{if(!M(`which ${i}`,{encoding:"utf-8",timeout:2e3}).trim())throw new Error("not in PATH");M(`${i} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"})}h=i,o.debug(`[Agent] Using binary: ${i}`);break}catch(d){o.debug(`[Agent] Binary '${i}' check failed: ${d.message}`);continue}if(!h)throw new Error(`Cursor Agent CLI not found or not working.
|
|
42
|
+
Response: ${JSON.stringify(m)}`,{cause:c}):new Error(`Failed to format Cursor output: ${m?.error?.message||"Unknown error"}`,{cause:c})}throw o.error(`\u274C OpenAI proxy request failed: ${c.message}`),new Error(`Failed to format output: ${c.message}`,{cause:c})}}import{timeline as Q,Timeline as re,WORKFLOW_GRAPH_LOG_MARKER_PREFIX as ne}from"@zibby/agent-workflow";import{copyFileSync as bt,existsSync as tt,lstatSync as At,mkdirSync as rt,rmSync as xt,symlinkSync as It,unlinkSync as Tt}from"node:fs";import{join as k}from"node:path";import{homedir as wt}from"node:os";import{randomBytes as $t}from"node:crypto";var vt=["cli-config.json","config.json","auth.json","argv.json"];function nt(l){return!(!l||typeof l!="string"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="1"||process.env.ZIBBY_CURSOR_USE_GLOBAL_MCP==="true")}function st(l){let t=k(l||process.cwd(),".zibby","tmp");rt(t,{recursive:!0});let e=`${process.pid}-${Date.now()}-${$t(4).toString("hex")}`,r=k(t,`cursor-agent-home-${e}`),s=k(r,".cursor");rt(s,{recursive:!0});let a=wt(),n=k(a,".cursor");if(tt(n))for(let u of vt){let p=k(n,u);if(tt(p))try{bt(p,k(s,u))}catch{}}if(process.platform==="darwin"){let u=k(a,"Library");if(tt(u))try{It(u,k(r,"Library"))}catch{}}return r}function ot(l){if(!(!l||typeof l!="string"))try{let t=k(l,"Library");try{At(t).isSymbolicLink()&&Tt(t)}catch{}xt(l,{recursive:!0,force:!0})}catch{}}var ft=class extends Rt{constructor(){super("cursor","Cursor (CLI)",100)}canHandle(t){let e=[v(Y(),".local","bin","cursor-agent"),v(Y(),".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 e)try{if(r.startsWith("/")){ct(r,pt.X_OK);let s=M(`"${r}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(s&&s.length>0)return o.debug(`[Cursor] Found agent at: ${r} (version: ${s.trim().slice(0,50)})`),!0}else{let s=M(`which ${r}`,{encoding:"utf-8",timeout:2e3,stdio:"pipe"}).trim();if(!s)continue;let a=M(`${r} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});if(a&&a.length>0)return o.debug(`[Cursor] Found '${r}' in PATH at ${s} (version: ${a.trim().slice(0,50)})`),!0}}catch{continue}return o.warn("[Cursor] \u274C Cursor Agent CLI not found or not working. Run: agent --version"),!1}async invoke(t,e={}){let{workspace:r=process.cwd(),print:s=!1,schema:a=null,skills:n=null,sessionPath:u=null,nodeName:p=null,timeout:g=W.CURSOR_AGENT_DEFAULT,config:c={}}=e,f=c?.agent?.strictMode||!1,m=e.model??c?.agent?.cursor?.model??G.CURSOR;o.debug(`[Cursor] Invoking (model: ${m}, timeout: ${g/1e3}s, skills: ${JSON.stringify(n)})`);let A=(this._setupMcpConfig(u,r,c,n,p)||{}).isolatedMcpHome??null,I=[v(Y(),".local","bin","cursor-agent"),v(Y(),".cursor","bin","cursor-agent"),"/usr/local/bin/cursor-agent","/usr/local/bin/agent","/Applications/Cursor.app/Contents/Resources/app/bin/cursor","agent","cursor-agent"],h=null;for(let i of I)try{if(i.startsWith("/"))ct(i,pt.X_OK),M(`"${i}" --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"});else{if(!M(`which ${i}`,{encoding:"utf-8",timeout:2e3}).trim())throw new Error("not in PATH");M(`${i} --version 2>&1`,{encoding:"utf-8",timeout:3e3,stdio:"pipe"})}h=i,o.debug(`[Agent] Using binary: ${i}`);break}catch(d){o.debug(`[Agent] Binary '${i}' check failed: ${d.message}`);continue}if(!h)throw new Error(`Cursor Agent CLI not found or not working.
|
|
43
43
|
|
|
44
44
|
Checked paths:
|
|
45
45
|
${I.map(i=>` - ${i}`).join(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AgentStrategy as nt,getSkill as it}from"@zibby/workflow";import{execSync as ot,spawn as lt}from"node:child_process";import{zodToJsonSchema as ut}from"zod-to-json-schema";import{existsSync as H,mkdirSync as q,readFileSync as X,rmSync as ct,writeFileSync as Z}from"node:fs";import{join as N}from"node:path";import G from"chalk";var h={debug:0,info:1,warn:2,error:3,silent:4},F=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return h.debug;if(process.env.ZIBBY_VERBOSE==="true")return h.info;let t=process.env.LOG_LEVEL?.toLowerCase();return t&&t in h?h[t]:h.info}_shouldLog(t){return h[t]>=this._level}_formatMessage(t,e,s={}){let n=new Date().toISOString(),r=`${this._getPrefix(t)} ${e}`;return Object.keys(s).length>0&&(r+=G.dim(` ${JSON.stringify(s)}`)),r}_getPrefix(t){return{debug:G.gray("[DEBUG]"),info:G.cyan("[INFO]"),warn:G.yellow("[WARN]"),error:G.red("\u274C [ERROR]")}[t]||""}debug(t,e){this._shouldLog("debug")&&console.log(this._formatMessage("debug",t,e))}info(t,e){this._shouldLog("info")&&console.log(this._formatMessage("info",t,e))}warn(t,e){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",t,e))}error(t,e){this._shouldLog("error")&&console.error(this._formatMessage("error",t,e))}setLevel(t){t in h&&(this._level=h[t])}getLevel(){return Object.keys(h).find(t=>h[t]===this._level)}},u=new F;var B={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 W={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},ht={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};import{zodToJsonSchema as st}from"zod-to-json-schema";var M=class{static generateFileOutputInstructions(t,e){let s;typeof t?.parse=="function"?s=st(t,{target:"openApi3"}):s=t;let n=this._buildExample(s);return`
|
|
1
|
+
import{AgentStrategy as nt,getSkill as it}from"@zibby/agent-workflow";import{execSync as ot,spawn as lt}from"node:child_process";import{zodToJsonSchema as ut}from"zod-to-json-schema";import{existsSync as H,mkdirSync as q,readFileSync as X,rmSync as ct,writeFileSync as Z}from"node:fs";import{join as N}from"node:path";import G from"chalk";var h={debug:0,info:1,warn:2,error:3,silent:4},F=class{constructor(){this._level=this._getLogLevel()}_getLogLevel(){if(process.env.ZIBBY_DEBUG==="true")return h.debug;if(process.env.ZIBBY_VERBOSE==="true")return h.info;let t=process.env.LOG_LEVEL?.toLowerCase();return t&&t in h?h[t]:h.info}_shouldLog(t){return h[t]>=this._level}_formatMessage(t,e,s={}){let n=new Date().toISOString(),r=`${this._getPrefix(t)} ${e}`;return Object.keys(s).length>0&&(r+=G.dim(` ${JSON.stringify(s)}`)),r}_getPrefix(t){return{debug:G.gray("[DEBUG]"),info:G.cyan("[INFO]"),warn:G.yellow("[WARN]"),error:G.red("\u274C [ERROR]")}[t]||""}debug(t,e){this._shouldLog("debug")&&console.log(this._formatMessage("debug",t,e))}info(t,e){this._shouldLog("info")&&console.log(this._formatMessage("info",t,e))}warn(t,e){this._shouldLog("warn")&&console.warn(this._formatMessage("warn",t,e))}error(t,e){this._shouldLog("error")&&console.error(this._formatMessage("error",t,e))}setLevel(t){t in h&&(this._level=h[t])}getLevel(){return Object.keys(h).find(t=>h[t]===this._level)}},u=new F;var B={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 W={auto:"gemini-2.5-pro","gemini-2.5-pro":"gemini-2.5-pro","gemini-2.5-flash":"gemini-2.5-flash"},ht={CURSOR_AGENT_DEFAULT:1200*1e3,OPENAI_REQUEST:18e4};import{zodToJsonSchema as st}from"zod-to-json-schema";var M=class{static generateFileOutputInstructions(t,e){let s;typeof t?.parse=="function"?s=st(t,{target:"openApi3"}):s=t;let n=this._buildExample(s);return`
|
|
2
2
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
3
3
|
\u{1F6A8} MANDATORY: WRITE RESULT TO FILE \u{1F6A8}
|
|
4
4
|
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
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.44",
|
|
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';
|