@zibby/cli 0.4.29 → 0.4.31
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
var d=new Set(["claude","cursor","codex","gemini","assistant"]);function u(e,
|
|
1
|
+
var d=new Set(["claude","cursor","codex","gemini","assistant"]);function u(e,s={}){let r=[],o=s.location||"workflow.json";return!e||typeof e!="object"?(r.push({severity:"error",code:"workflow-json-missing-or-invalid",message:"workflow.json is missing or not a JSON object",location:o}),r):(!e.name||typeof e.name!="string"?r.push({severity:"error",code:"workflow-json-missing-name",message:"workflow.json must have a string `name`",location:o}):/^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/.test(e.name)||r.push({severity:"error",code:"workflow-json-bad-name",message:`workflow.json \`name\` must match [a-z][a-z0-9_-]*[a-z0-9] (got "${e.name}")`,location:o}),(!e.description||typeof e.description!="string")&&r.push({severity:"warning",code:"workflow-json-missing-description",message:"workflow.json should have a `description` (one-line, what the workflow does)",location:o}),e.defaultAgent!=null&&!d.has(e.defaultAgent)&&r.push({severity:"error",code:"workflow-json-bad-agent",message:`workflow.json \`defaultAgent\` must be one of ${[...d].join(", ")} (got "${e.defaultAgent}")`,location:o}),e.entryClass!=null&&typeof e.entryClass!="string"&&r.push({severity:"error",code:"workflow-json-bad-entry-class",message:"workflow.json `entryClass` must be a string (the class name in graph.mjs)",location:o}),e.triggers!=null&&typeof e.triggers!="object"&&r.push({severity:"error",code:"workflow-json-bad-triggers",message:'workflow.json `triggers` must be an object (e.g. {"api": true})',location:o}),r)}function g(e){return!!e&&typeof e=="object"&&typeof e._def<"u"&&typeof e.parse=="function"}function h(e,s,r={}){let o=[],t=r.location||`node "${e}"`;if(!s||typeof s!="object")return o.push({severity:"error",code:"node-missing",message:`Node "${e}" is missing or not an object`,location:t}),o;let n=typeof s.workflow=="string"&&s.workflow.length>0;s.outputSchema?g(s.outputSchema)||o.push({severity:"warning",code:"node-non-zod-output-schema",message:`Node "${e}" \`outputSchema\` is not a recognizable Zod schema (no _def + parse). Plain-object schemas will be coerced via OutputParser, which is more permissive than the Zod path.`,location:t}):n||o.push({severity:"error",code:"node-missing-output-schema",message:`Node "${e}" has no \`outputSchema\` \u2014 every node needs a Zod schema`,location:t});let i=s.prompt!=null||s.config&&s.config.prompt!=null,a=typeof s.customExecute=="function";return!n&&!i&&!a&&o.push({severity:"error",code:"node-no-prompt-or-execute",message:`Node "${e}" has neither \`prompt\` nor \`execute\` \u2014 needs one of them (prompt for LLM nodes, execute for custom-code nodes)`,location:t}),i&&a&&o.push({severity:"warning",code:"node-both-prompt-and-execute",message:`Node "${e}" defines both \`prompt\` and \`execute\` \u2014 \`execute\` always wins (LLM is skipped). Probably want to drop one.`,location:t}),o}var c=new Set(["END","__end__","end"]);function p(e){let s=[];if(!e||!(e.nodes instanceof Map)||!(e.edges instanceof Map))return s.push({severity:"error",code:"graph-not-a-workflow-graph",message:"buildGraph() did not return a WorkflowGraph instance (or returned an unrecognizable shape)"}),s;e.entryPoint?e.nodes.has(e.entryPoint)||s.push({severity:"error",code:"graph-entry-point-unknown",message:`Graph entry point "${e.entryPoint}" is not a registered node`}):s.push({severity:"error",code:"graph-no-entry-point",message:'Graph has no entry point \u2014 call `graph.setEntryPoint("nodeName")` before returning'});let r=[];for(let[t,n]of e.edges)if(e.nodes.has(t)||s.push({severity:"error",code:"graph-edge-from-unknown",message:`Edge starts from "${t}" but no such node is registered`,location:`addEdge("${t}", \u2026)`}),typeof n=="string")r.push({from:t,to:n});else if(n&&n.conditional&&typeof n.routes=="function"){let a=n.routes.toString().match(/['"`]([A-Za-z_][\w-]*)['"`]/g)||[];for(let f of a){let l=f.slice(1,-1);r.push({from:t,to:l})}}else s.push({severity:"error",code:"graph-bad-edge-target",message:`Edge from "${t}" has an unrecognizable target shape`,location:`addEdge / addConditionalEdges from "${t}"`});for(let{from:t,to:n}of r)c.has(n)||e.nodes.has(n)||s.push({severity:"error",code:"graph-edge-to-unknown",message:`Edge from "${t}" goes to "${n}" but no such node is registered (and it isn't the END sentinel)`,location:`addEdge("${t}", "${n}")`});if(e.entryPoint){let t=new Set([e.entryPoint]),n=!0;for(;n;){n=!1;for(let{from:i,to:a}of r)t.has(i)&&!c.has(a)&&!t.has(a)&&e.nodes.has(a)&&(t.add(a),n=!0)}for(let i of e.nodes.keys())t.has(i)||s.push({severity:"warning",code:"graph-orphan-node",message:`Node "${i}" is registered but unreachable from the entry point "${e.entryPoint}". Add an edge or remove the node.`})}let o=new Set(c);for(let t=0;t<e.nodes.size+1;t++){let n=!1;for(let{from:i,to:a}of r)o.has(a)&&!o.has(i)&&(o.add(i),n=!0);if(!n)break}for(let t of e.nodes.keys())o.has(t)||s.push({severity:"warning",code:"graph-dead-end",message:`Node "${t}" has no path that reaches END \u2014 the workflow will run forever or crash. Add an edge to END (or another terminal-reaching node).`});return s}function m(e,s){let r=[];if(!(e instanceof Map))return r;for(let[o,t]of e){let n=t.config?.skills||[];if(!Array.isArray(n)){r.push({severity:"error",code:"node-skills-not-array",message:`Node "${o}".skills must be an array of strings (got ${typeof n})`,location:`node "${o}"`});continue}for(let i of n){if(typeof i!="string"){r.push({severity:"error",code:"node-skill-not-string",message:`Node "${o}".skills contains a non-string entry: ${JSON.stringify(i)}`,location:`node "${o}"`});continue}s.has(i)||r.push({severity:"error",code:"node-skill-not-registered",message:`Node "${o}" references skill "${i}" which is not registered. Import the skill file in graph.mjs (e.g. import "./skills/${i}.mjs") BEFORE creating the WorkflowGraph.`,location:`node "${o}"`})}}return r}function w({workflowJson:e,graph:s,registeredSkills:r}){let o=[];if(o.push(...u(e)),o.push(...p(s)),s&&s.nodes instanceof Map){for(let[t,n]of s.nodes)o.push(...h(t,n));o.push(...m(s.nodes,r||new Set))}return o}export{w as runAllValidators,p as validateGraphTopology,h as validateNode,m as validateSkillReferences,u as validateWorkflowJson};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import a from"chalk";import{readFileSync as j,existsSync as g}from"fs";import{join as u}from"path";import{pathToFileURL as E}from"url";var w=new Set(["claude","cursor","codex","gemini","assistant"]);function m(e,r={}){let s=[],t=r.location||"workflow.json";return!e||typeof e!="object"?(s.push({severity:"error",code:"workflow-json-missing-or-invalid",message:"workflow.json is missing or not a JSON object",location:t}),s):(!e.name||typeof e.name!="string"?s.push({severity:"error",code:"workflow-json-missing-name",message:"workflow.json must have a string `name`",location:t}):/^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/.test(e.name)||s.push({severity:"error",code:"workflow-json-bad-name",message:`workflow.json \`name\` must match [a-z][a-z0-9_-]*[a-z0-9] (got "${e.name}")`,location:t}),(!e.description||typeof e.description!="string")&&s.push({severity:"warning",code:"workflow-json-missing-description",message:"workflow.json should have a `description` (one-line, what the workflow does)",location:t}),e.defaultAgent!=null&&!w.has(e.defaultAgent)&&s.push({severity:"error",code:"workflow-json-bad-agent",message:`workflow.json \`defaultAgent\` must be one of ${[...w].join(", ")} (got "${e.defaultAgent}")`,location:t}),e.entryClass!=null&&typeof e.entryClass!="string"&&s.push({severity:"error",code:"workflow-json-bad-entry-class",message:"workflow.json `entryClass` must be a string (the class name in graph.mjs)",location:t}),e.triggers!=null&&typeof e.triggers!="object"&&s.push({severity:"error",code:"workflow-json-bad-triggers",message:'workflow.json `triggers` must be an object (e.g. {"api": true})',location:t}),s)}function k(e){return!!e&&typeof e=="object"&&typeof e._def<"u"&&typeof e.parse=="function"}function b(e,r,s={}){let t=[],o=s.location||`node "${e}"`;if(!r||typeof r!="object")return t.push({severity:"error",code:"node-missing",message:`Node "${e}" is missing or not an object`,location:o}),t;r.outputSchema?k(r.outputSchema)||t.push({severity:"warning",code:"node-non-zod-output-schema",message:`Node "${e}" \`outputSchema\` is not a recognizable Zod schema (no _def + parse). Plain-object schemas will be coerced via OutputParser, which is more permissive than the Zod path.`,location:o}):t.push({severity:"error",code:"node-missing-output-schema",message:`Node "${e}" has no \`outputSchema\` \u2014 every node needs a Zod schema`,location:o});let
|
|
1
|
+
import a from"chalk";import{readFileSync as j,existsSync as g}from"fs";import{join as u}from"path";import{pathToFileURL as E}from"url";var w=new Set(["claude","cursor","codex","gemini","assistant"]);function m(e,r={}){let s=[],t=r.location||"workflow.json";return!e||typeof e!="object"?(s.push({severity:"error",code:"workflow-json-missing-or-invalid",message:"workflow.json is missing or not a JSON object",location:t}),s):(!e.name||typeof e.name!="string"?s.push({severity:"error",code:"workflow-json-missing-name",message:"workflow.json must have a string `name`",location:t}):/^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/.test(e.name)||s.push({severity:"error",code:"workflow-json-bad-name",message:`workflow.json \`name\` must match [a-z][a-z0-9_-]*[a-z0-9] (got "${e.name}")`,location:t}),(!e.description||typeof e.description!="string")&&s.push({severity:"warning",code:"workflow-json-missing-description",message:"workflow.json should have a `description` (one-line, what the workflow does)",location:t}),e.defaultAgent!=null&&!w.has(e.defaultAgent)&&s.push({severity:"error",code:"workflow-json-bad-agent",message:`workflow.json \`defaultAgent\` must be one of ${[...w].join(", ")} (got "${e.defaultAgent}")`,location:t}),e.entryClass!=null&&typeof e.entryClass!="string"&&s.push({severity:"error",code:"workflow-json-bad-entry-class",message:"workflow.json `entryClass` must be a string (the class name in graph.mjs)",location:t}),e.triggers!=null&&typeof e.triggers!="object"&&s.push({severity:"error",code:"workflow-json-bad-triggers",message:'workflow.json `triggers` must be an object (e.g. {"api": true})',location:t}),s)}function k(e){return!!e&&typeof e=="object"&&typeof e._def<"u"&&typeof e.parse=="function"}function b(e,r,s={}){let t=[],o=s.location||`node "${e}"`;if(!r||typeof r!="object")return t.push({severity:"error",code:"node-missing",message:`Node "${e}" is missing or not an object`,location:o}),t;let n=typeof r.workflow=="string"&&r.workflow.length>0;r.outputSchema?k(r.outputSchema)||t.push({severity:"warning",code:"node-non-zod-output-schema",message:`Node "${e}" \`outputSchema\` is not a recognizable Zod schema (no _def + parse). Plain-object schemas will be coerced via OutputParser, which is more permissive than the Zod path.`,location:o}):n||t.push({severity:"error",code:"node-missing-output-schema",message:`Node "${e}" has no \`outputSchema\` \u2014 every node needs a Zod schema`,location:o});let i=r.prompt!=null||r.config&&r.config.prompt!=null,l=typeof r.customExecute=="function";return!n&&!i&&!l&&t.push({severity:"error",code:"node-no-prompt-or-execute",message:`Node "${e}" has neither \`prompt\` nor \`execute\` \u2014 needs one of them (prompt for LLM nodes, execute for custom-code nodes)`,location:o}),i&&l&&t.push({severity:"warning",code:"node-both-prompt-and-execute",message:`Node "${e}" defines both \`prompt\` and \`execute\` \u2014 \`execute\` always wins (LLM is skipped). Probably want to drop one.`,location:o}),t}var h=new Set(["END","__end__","end"]);function $(e){let r=[];if(!e||!(e.nodes instanceof Map)||!(e.edges instanceof Map))return r.push({severity:"error",code:"graph-not-a-workflow-graph",message:"buildGraph() did not return a WorkflowGraph instance (or returned an unrecognizable shape)"}),r;e.entryPoint?e.nodes.has(e.entryPoint)||r.push({severity:"error",code:"graph-entry-point-unknown",message:`Graph entry point "${e.entryPoint}" is not a registered node`}):r.push({severity:"error",code:"graph-no-entry-point",message:'Graph has no entry point \u2014 call `graph.setEntryPoint("nodeName")` before returning'});let s=[];for(let[o,n]of e.edges)if(e.nodes.has(o)||r.push({severity:"error",code:"graph-edge-from-unknown",message:`Edge starts from "${o}" but no such node is registered`,location:`addEdge("${o}", \u2026)`}),typeof n=="string")s.push({from:o,to:n});else if(n&&n.conditional&&typeof n.routes=="function"){let l=n.routes.toString().match(/['"`]([A-Za-z_][\w-]*)['"`]/g)||[];for(let f of l){let d=f.slice(1,-1);s.push({from:o,to:d})}}else r.push({severity:"error",code:"graph-bad-edge-target",message:`Edge from "${o}" has an unrecognizable target shape`,location:`addEdge / addConditionalEdges from "${o}"`});for(let{from:o,to:n}of s)h.has(n)||e.nodes.has(n)||r.push({severity:"error",code:"graph-edge-to-unknown",message:`Edge from "${o}" goes to "${n}" but no such node is registered (and it isn't the END sentinel)`,location:`addEdge("${o}", "${n}")`});if(e.entryPoint){let o=new Set([e.entryPoint]),n=!0;for(;n;){n=!1;for(let{from:i,to:l}of s)o.has(i)&&!h.has(l)&&!o.has(l)&&e.nodes.has(l)&&(o.add(l),n=!0)}for(let i of e.nodes.keys())o.has(i)||r.push({severity:"warning",code:"graph-orphan-node",message:`Node "${i}" is registered but unreachable from the entry point "${e.entryPoint}". Add an edge or remove the node.`})}let t=new Set(h);for(let o=0;o<e.nodes.size+1;o++){let n=!1;for(let{from:i,to:l}of s)t.has(l)&&!t.has(i)&&(t.add(i),n=!0);if(!n)break}for(let o of e.nodes.keys())t.has(o)||r.push({severity:"warning",code:"graph-dead-end",message:`Node "${o}" has no path that reaches END \u2014 the workflow will run forever or crash. Add an edge to END (or another terminal-reaching node).`});return r}function v(e,r){let s=[];if(!(e instanceof Map))return s;for(let[t,o]of e){let n=o.config?.skills||[];if(!Array.isArray(n)){s.push({severity:"error",code:"node-skills-not-array",message:`Node "${t}".skills must be an array of strings (got ${typeof n})`,location:`node "${t}"`});continue}for(let i of n){if(typeof i!="string"){s.push({severity:"error",code:"node-skill-not-string",message:`Node "${t}".skills contains a non-string entry: ${JSON.stringify(i)}`,location:`node "${t}"`});continue}r.has(i)||s.push({severity:"error",code:"node-skill-not-registered",message:`Node "${t}" references skill "${i}" which is not registered. Import the skill file in graph.mjs (e.g. import "./skills/${i}.mjs") BEFORE creating the WorkflowGraph.`,location:`node "${t}"`})}}return s}function y({workflowJson:e,graph:r,registeredSkills:s}){let t=[];if(t.push(...m(e)),t.push(...$(r)),r&&r.nodes instanceof Map){for(let[o,n]of r.nodes)t.push(...b(o,n));t.push(...v(r.nodes,s||new Set))}return t}async function x(e,r){let s=null;try{let o=u(e,".zibby.config.mjs");if(g(o)){let{loadUserConfig:n}=await import("../../utils/user-config.js").catch(()=>({}));if(typeof n=="function"){let i=await n(e);i?.paths?.workflows&&(s=i.paths.workflows)}}}catch{}let t=[...s?[u(e,s,r)]:[],u(e,"workflows",r),u(e,".zibby","workflows",r),u(e,r)];for(let o of t)if(g(u(o,"workflow.json"))&&g(u(o,"graph.mjs")))return o;return null}function N(e){let r=u(e,"workflow.json");if(!g(r))return null;try{return JSON.parse(j(r,"utf-8"))}catch(s){return{__parseError:s.message}}}async function S(e,r){let s=u(e,"graph.mjs");if(!g(s))throw new Error(`graph.mjs not found at ${s}`);let o=await import(`${E(s).href}?ts=${Date.now()}`),n=r?.entryClass,i=n&&o[n]||Object.values(o).find(f=>typeof f=="function"&&f.prototype&&typeof f.prototype.buildGraph=="function");if(i){let d=new i().buildGraph();if(!d)throw new Error(`${i.name}.buildGraph() returned undefined`);return d}let l=o.default||o.buildGraph;if(typeof l=="function")return l();throw new Error("graph.mjs must EITHER export a class extending WorkflowAgent (with `buildGraph()` method, named via workflow.json `entryClass`), OR export a default function that returns a WorkflowGraph.")}async function z(){try{let{listSkillIds:e}=await import("@zibby/agent-workflow");return new Set(e())}catch{return null}}function A(e){let r=e.severity==="error"?a.red("\u2717 ERROR "):a.yellow("\u26A0 WARN "),s=a.gray(`[${e.code}]`),t=e.location?a.gray(` (${e.location})`):"";return` ${r}${s}${t}
|
|
2
2
|
${e.message}`}async function O(e,r={}){let s=r.cwd||process.cwd();e||(console.error(a.red("Workflow name required.")),console.error(a.gray("Usage: zibby workflow validate <name>")),console.error(a.gray(" e.g. zibby workflow validate code-review")),process.exit(1));let t=await x(s,e);t||(console.error(a.red(`Workflow "${e}" not found.`)),console.error(a.gray(" Looked for workflow.json + graph.mjs in:")),console.error(a.gray(` <paths.workflows>/${e}/ (from .zibby.config.mjs)`)),console.error(a.gray(` workflows/${e}/`)),console.error(a.gray(` .zibby/workflows/${e}/`)),console.error(a.gray(" Run `zibby workflow new <name>` to scaffold one, or `zibby workflow list` to see what exists.")),process.exit(1)),console.log(a.bold(`
|
|
3
3
|
Validating workflow: ${a.cyan(e)}`)),console.log(a.gray(` at ${t}
|
|
4
4
|
`));let o=N(t);o?.__parseError&&(console.error(a.red(`\u2717 workflow.json is not valid JSON: ${o.__parseError}`)),process.exit(1));let n;try{n=await S(t,o)}catch(c){console.error(a.red(`\u2717 Failed to load graph.mjs: ${c.message}`)),c.stack&&r.verbose&&console.error(a.gray(c.stack)),process.exit(1)}let i=await z(),l=y({workflowJson:o,graph:n,registeredSkills:i||new Set}),f=i===null?l.filter(c=>c.code!=="node-skill-not-registered"):l,d=f.filter(c=>c.severity==="error"),p=f.filter(c=>c.severity==="warning");for(let c of f)console.log(A(c));console.log(""),d.length===0&&p.length===0?console.log(a.green(`\u2714 ${e} is valid. Ready for \`zibby workflow run\`.`)):console.log(`${d.length>0?a.red(`${d.length} error(s)`):a.gray("0 errors")}, ${p.length>0?a.yellow(`${p.length} warning(s)`):a.gray("0 warnings")}`),i===null&&console.log(a.gray(" (skill-registration checks skipped \u2014 @zibby/agent-workflow not resolvable; run `npm install` in the workflow folder first)")),console.log(""),d.length>0&&process.exit(1)}export{O as validateCommand};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.31",
|
|
4
4
|
"description": "Zibby CLI - Test automation generator and runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@aws-sdk/client-sqs": "^3.1038.0",
|
|
37
|
-
"@zibby/agent-workflow": "^0.4.
|
|
38
|
-
"@zibby/core": "^0.5.
|
|
37
|
+
"@zibby/agent-workflow": "^0.4.2",
|
|
38
|
+
"@zibby/core": "^0.5.2",
|
|
39
39
|
"@zibby/skills": "^0.1.11",
|
|
40
40
|
"@zibby/ui-memory": "^1.0.0",
|
|
41
|
-
"@zibby/workflow-templates": "^0.
|
|
41
|
+
"@zibby/workflow-templates": "^0.3.0",
|
|
42
42
|
"adm-zip": "^0.5.17",
|
|
43
43
|
"chalk": "^5.3.0",
|
|
44
44
|
"cli-highlight": "^2.1.11",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zibby/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.31",
|
|
4
4
|
"description": "Zibby CLI - Test automation generator and runner",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@aws-sdk/client-sqs": "^3.1038.0",
|
|
37
|
-
"@zibby/agent-workflow": "^0.4.
|
|
38
|
-
"@zibby/core": "^0.5.
|
|
37
|
+
"@zibby/agent-workflow": "^0.4.2",
|
|
38
|
+
"@zibby/core": "^0.5.2",
|
|
39
39
|
"@zibby/skills": "^0.1.11",
|
|
40
40
|
"@zibby/ui-memory": "^1.0.0",
|
|
41
|
-
"@zibby/workflow-templates": "^0.
|
|
41
|
+
"@zibby/workflow-templates": "^0.3.0",
|
|
42
42
|
"adm-zip": "^0.5.17",
|
|
43
43
|
"chalk": "^5.3.0",
|
|
44
44
|
"cli-highlight": "^2.1.11",
|