@culvii/cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,844 @@
1
+ #!/usr/bin/env node
2
+ import {a as a$5}from'./chunk-JFIFRAAR.js';import {a as a$4,b as b$1,c as c$1}from'./chunk-KZG5CFSB.js';import {n,e,a as a$2,j as j$1,d,f,c,q,r,s,o,k,l}from'./chunk-7XZL4X4V.js';import {a as a$3}from'./chunk-HX54IFSD.js';import'./chunk-57XLDHK6.js';import {x,w,y,z}from'./chunk-YKFGEPLO.js';import {a as a$1}from'./chunk-YPLDPHHD.js';import {a,b}from'./chunk-7UWDMECF.js';import {Command}from'commander';import Ee,{realpathSync,existsSync}from'fs';import {fileURLToPath}from'url';import ge from'react';import {render}from'ink';import tt from'ws';import X,{dirname,join}from'path';import ne from'fs/promises';import {createHash}from'crypto';import {spawn}from'child_process';import hn from'chokidar';import {createRequire}from'module';import Ut from'readline';import ut from'os';import {createInterface}from'readline/promises';import {stdout,stdin}from'process';import {jsx}from'react/jsx-runtime';var Tt=a(F=>{Object.defineProperty(F,"__esModule",{value:true});F.SINGLE_CHILD_SURFACE_COMPONENTS=F.SURFACE_COMPONENT_TYPES=F.SURFACE_COMPONENT_CATALOG=F.SURFACE_SLOTS=F.SURFACE_SLOT_POLICY=void 0;F.getSurfaceBindingPaths=_t;F.validateSurfaceDefinition=It;F.validateSurfaceResource=yn;F.SURFACE_SLOT_POLICY={output:{actions:["navigate"],form:false},wait:{actions:["navigate","node.resume","node.stop"],form:true}};F.SURFACE_SLOTS=Object.keys(F.SURFACE_SLOT_POLICY);F.SURFACE_COMPONENT_CATALOG={Stack:{children:"list"},Row:{children:"list"},Grid:{children:"list"},Card:{children:"single"},Section:{children:"single"},Tabs:{children:"list"},Accordion:{children:"single"},Divider:{children:"none"},Spacer:{children:"none"},Text:{children:"none"},Heading:{children:"none"},Markdown:{children:"none"},Badge:{children:"none"},KeyValue:{children:"none"},Stat:{children:"none"},Avatar:{children:"none"},Icon:{children:"none"},Image:{children:"none"},Code:{children:"none"},Timestamp:{children:"none"},Duration:{children:"none"},Money:{children:"none"},Table:{children:"none"},List:{children:"list"},Tree:{children:"none"},JsonInspector:{children:"none"},FileChip:{children:"none",interaction:"single-action"},StatusPill:{children:"none"},ProgressBar:{children:"none"},Spinner:{children:"none"},ErrorPanel:{children:"none"},Timeline:{children:"list"},Button:{children:"none",interaction:"single-action"},TextField:{children:"none",interaction:"input"},TextArea:{children:"none",interaction:"input"},Select:{children:"none",interaction:"input"},Checkbox:{children:"none",interaction:"input"},RadioGroup:{children:"none",interaction:"input"},DatePicker:{children:"none",interaction:"input"},Form:{children:"list"},DiffView:{children:"none"},ApproveRejectBar:{children:"none",interaction:"multi-action"},EmailMessageCard:{children:"none"},SlackMessageCard:{children:"none"},SlackThread:{children:"list"},CalendarEventCard:{children:"none"},AgentRunPanel:{children:"none"},ToolCallCard:{children:"none"}};F.SURFACE_COMPONENT_TYPES=Object.keys(F.SURFACE_COMPONENT_CATALOG);F.SINGLE_CHILD_SURFACE_COMPONENTS=F.SURFACE_COMPONENT_TYPES.filter(e=>F.SURFACE_COMPONENT_CATALOG[e].children==="single");var Et=300,At=12,dn=new Set(F.SURFACE_COMPONENT_TYPES),un=new Set(["$output","$input","$binary"]),pn=new Set(["text","number","date","datetime","json"]),fn=new Set(["text","textarea","number","email","url","checkbox","select","file"]);function gn(e){return (e.startsWith("/")?e.slice(1):e).split("/",1)[0]}function Ce(e,t){if(Array.isArray(e))for(let n of e)Ce(n,t);else if(e&&typeof e=="object"){let n=e;if(typeof n.path=="string")t.push(n.path);else for(let r of Object.values(n))Ce(r,t);}}function Re(e,t){if(Array.isArray(e)){for(let r of e)Re(r,t);return}if(!e||typeof e!="object")return;let n=e;if("path"in n){typeof n.path!="string"&&t.push("Surface binding path must be a string."),n.format!==void 0&&!pn.has(String(n.format))&&t.push(`Unknown surface binding format "${String(n.format)}".`);return}for(let r of Object.values(n))Re(r,t);}function _t(e){let t=[];for(let n of e.components??[])!n||typeof n!="object"||(Ce(n.props,t),Ce(n.actions,t));return Ce(e.form,t),Array.from(new Set(t))}function It(e,t){let n=[];try{new TextEncoder().encode(JSON.stringify(e)).byteLength>256*1024&&n.push("Surface definition exceeds 256 KiB.");}catch{return ["Surface definition must be JSON serializable."]}if(e?.schema!=="kit.ui/v1"&&n.push('Surface schema must be "kit.ui/v1".'),!Array.isArray(e?.components)||e.components.length===0)return [...n,"Surface requires at least one component."];e.components.length>Et&&n.push(`Surface cannot exceed ${Et} components.`);let r=new Map;for(let o of e.components){if(!o||typeof o!="object"||Array.isArray(o)){n.push("Every surface component must be an object.");continue}let a=o;if(typeof a.id!="string"||!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(a.id)||typeof a.type!="string"){n.push("Every surface component requires id and type.");continue}r.has(a.id)&&n.push(`Duplicate component id "${a.id}".`),r.set(a.id,a),dn.has(a.type)||n.push(`Unknown component type "${a.type}".`);let l=F.SURFACE_COMPONENT_CATALOG[a.type];a.props!==void 0&&(!a.props||typeof a.props!="object"||Array.isArray(a.props))&&n.push(`Component "${a.id}" props must be an object.`),a.children!==void 0&&!Array.isArray(a.children)?n.push(`Component "${a.id}" children must be an array.`):a.children?.length&&l?.children==="none"?n.push(`Component "${a.id}" cannot have children.`):a.children&&a.children.length>1&&l?.children==="single"&&n.push(`Component "${a.id}" can have at most one child.`);let c=a.props?.bind;if(c!==void 0&&(l?.interaction!=="input"?n.push(`Component "${a.id}" cannot bind form state.`):(!F.SURFACE_SLOT_POLICY[t].form||typeof c!="string"||!(c==="/$form"||c.startsWith("/$form/")||c.startsWith("$form.")))&&n.push(`Component "${a.id}" requires a wait-surface $form binding.`)),a.actions!==void 0&&(!a.actions||typeof a.actions!="object"||Array.isArray(a.actions))){n.push(`Component "${a.id}" actions must be an object.`);continue}let w=Object.keys(a.actions??{}).length;w&&!["single-action","multi-action"].includes(l?.interaction??"")?n.push(`Component "${a.id}" cannot have actions.`):w>1&&l?.interaction==="single-action"&&n.push(`Component "${a.id}" can have at most one action.`),Re(a.props,n);for(let p of Object.values(a.actions??{})){if(!p||typeof p!="object"||Array.isArray(p)){n.push(`Component "${a.id}" has an invalid action.`);continue}let y=p;if(!["navigate","node.resume","node.stop"].includes(y.type)){n.push(`Unknown surface action "${String(y.type)}".`);continue}F.SURFACE_SLOT_POLICY[t].actions.includes(y.type)||n.push(`Action "${y.type}" is not allowed on "${t}" surfaces.`),y.type==="navigate"&&(!y.href||typeof y.href!="object"||typeof y.href.path!="string")&&n.push("Navigate actions require an href binding."),Re(y,n);}}(typeof e.root!="string"||!r.has(e.root))&&n.push(`Surface root "${String(e.root)}" is missing.`);let i=new Set,s=new Set,u=(o,a)=>{if(a>At)return void n.push(`Surface component depth exceeds ${At}.`);if(s.has(o))return void n.push(`Surface component cycle includes "${o}".`);if(i.has(o))return;let l=r.get(o);if(l){s.add(o);for(let c of Array.isArray(l.children)?l.children:[]){if(typeof c!="string"){n.push(`Component "${o}" has a non-string child reference.`);continue}r.has(c)?u(c,a+1):n.push(`Component "${o}" references missing child "${c}".`);}s.delete(o),i.add(o);}};typeof e.root=="string"&&u(e.root,1);for(let o of r.keys())i.has(o)||n.push(`Component "${o}" is unreachable from root.`);for(let o of _t(e)){let a=gn(o);a==="$form"&&!F.SURFACE_SLOT_POLICY[t].form?n.push(`Binding "${o}" is only allowed on wait surfaces.`):a!=="$form"&&!un.has(a)&&n.push(`Invalid surface binding path "${o}".`);}if(e.form!==void 0)if(F.SURFACE_SLOT_POLICY[t].form||n.push("Forms are only allowed on wait surfaces."),!Array.isArray(e.form?.fields))n.push("Surface form fields must be an array.");else {let o=new Set;for(let a of e.form.fields){if(!a||typeof a!="object"||Array.isArray(a)){n.push("Every surface form field must be an object.");continue}let l=a,c=l?.name,w=l?.type;typeof c!="string"||!c||o.has(c)?n.push(`Surface form field name "${String(c)}" is invalid or duplicated.`):o.add(c),fn.has(String(w))||n.push(`Unknown surface form field type "${String(w)}".`),(typeof l.label!="string"||!l.label.trim())&&n.push(`Surface form field "${String(c)}" requires a label.`),w==="file"&&"default"in l&&n.push(`File field "${String(c)}" cannot have a default binding.`),w==="file"&&(l.maxFiles!==void 0&&(!Number.isInteger(l.maxFiles)||Number(l.maxFiles)<1||Number(l.maxFiles)>5)&&n.push(`File field "${String(c)}" maxFiles must be between 1 and 5.`),l.maxBytes!==void 0&&(!Number.isInteger(l.maxBytes)||Number(l.maxBytes)<1||Number(l.maxBytes)>10*1024*1024)&&n.push(`File field "${String(c)}" maxBytes exceeds platform limits.`),l.accept!==void 0&&(!Array.isArray(l.accept)||l.accept.some(p=>typeof p!="string"||!/^[a-z0-9.+-]+\/(?:[a-z0-9.+-]+|\*)$/i.test(p)))&&n.push(`File field "${String(c)}" has invalid MIME types.`)),w==="select"&&(!Array.isArray(l.options)||l.options.length===0?n.push(`Select field "${String(c)}" requires options.`):l.options.some(p=>!p||typeof p!="object"||typeof p.label!="string"||typeof p.value!="string")&&n.push(`Select field "${String(c)}" has invalid options.`));}Re(e.form,n);}return Array.from(new Set(n))}function yn(e){let t=e;if(!t||typeof t!="object")return ["Surface must be an object."];let n=[];return (typeof t.id!="string"||!/^[a-z0-9][a-z0-9-]{0,62}$/.test(t.id))&&n.push("Surface requires a kebab-case id."),(typeof t.name!="string"||!t.name.trim())&&n.push("Surface requires a name."),F.SURFACE_SLOTS.includes(t.slot)?n.push(...It(t.definition,t.slot)):n.push(`Surface requires slot ${F.SURFACE_SLOTS.map(r=>`"${r}"`).join(" or ")}.`),Array.from(new Set(n))}});var St=a(ke=>{var wn=ke&&ke.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||("get"in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:true,get:function(){return t[n]}}),Object.defineProperty(e,r,i);}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n];})),mn=ke&&ke.__exportStar||function(e,t){for(var n in e)n!=="default"&&!Object.prototype.hasOwnProperty.call(t,n)&&wn(t,e,n);};Object.defineProperty(ke,"__esModule",{value:true});mn(Tt(),ke);});var Ue=class extends Error{constructor(){super("401 Unauthorized"),this.name="UnauthorizedError";}};function ln(e,t=Date.now()){return e-t<3e4}async function B(e$1){let t=new a$4,r=await(async()=>await t.withLock(async()=>{b$1.info("Tokens read from disk for auth check");let i=await t.get();if(i||(b$1.error("No tokens found on disk"),render(ge.createElement(c$1,{state:{type:"login_error",message:"Not logged in",detail:"run `culvii login`"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1)),!ln(i.expiresAt))return b$1.info("Access token valid, skipping refresh"),i.accessToken;b$1.info("Access token expired, attempting refresh");let s=`https://${q.cognitoDomain}/oauth2/token`,u=new URLSearchParams;u.set("grant_type","refresh_token"),u.set("refresh_token",i.refreshToken),u.set("client_id",q.clientId);let o;try{o=await fetch(s,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:u.toString()});}catch(w){b$1.error("Network error during refresh",{error:w.message}),render(ge.createElement(c$1,{state:{type:"login_error",message:"Refresh failed",detail:"Cannot reach auth server \u2014 check your connection"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1);}let a=await o.json();(!o.ok||a.error==="invalid_grant")&&(b$1.warn("Refresh failed with invalid_grant"),await t.delete(),render(ge.createElement(c$1,{state:{type:"login_error",message:"Session expired",detail:"run `culvii login` to authenticate"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1));let l=Date.now(),c=l+a.expires_in*1e3;return b$1.info("Refresh succeeded",{expiresAt:c}),await t.set({accessToken:a.access_token,refreshToken:a.refresh_token||i.refreshToken,idToken:a.id_token||i.idToken,expiresAt:c,tokenType:"Bearer",scope:i.scope,issuedAt:l,issuer:i.issuer}),a.access_token}))();try{await e$1(r);}catch(i){if(!(i instanceof Ue))throw i;b$1.info("Mid-session 401 detected, attempting refresh");let s=await t.withLock(async()=>{b$1.info("Tokens read from disk for retry");let u=await t.get();u||(b$1.error("No tokens found on disk during retry"),render(ge.createElement(c$1,{state:{type:"login_error",message:"Not logged in",detail:"run `culvii login`"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1)),b$1.info("Access token expired (forced by 401), attempting refresh");let o=`https://${q.cognitoDomain}/oauth2/token`,a=new URLSearchParams;a.set("grant_type","refresh_token"),a.set("refresh_token",u.refreshToken),a.set("client_id",q.clientId);let l;try{l=await fetch(o,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:a.toString()});}catch(y){b$1.error("Network error during refresh retry",{error:y.message}),render(ge.createElement(c$1,{state:{type:"login_error",message:"Refresh failed",detail:"Cannot reach auth server \u2014 check your connection"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1);}let c=await l.json();(!l.ok||c.error==="invalid_grant")&&(b$1.warn("Refresh retry failed with invalid_grant"),await t.delete(),render(ge.createElement(c$1,{state:{type:"login_error",message:"Session expired",detail:"run `culvii login` to authenticate"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1));let w=Date.now(),p=w+c.expires_in*1e3;return b$1.info("Refresh retry succeeded",{expiresAt:p}),await t.set({accessToken:c.access_token,refreshToken:c.refresh_token||u.refreshToken,idToken:c.id_token||u.idToken,expiresAt:p,tokenType:"Bearer",scope:u.scope,issuedAt:w,issuer:u.issuer}),c.access_token});try{b$1.info("Retry after refresh succeeded"),await e$1(s);}catch(u){throw u instanceof Ue&&(b$1.error("Retry after refresh failed (still 401)"),await t.withLock(async()=>{await t.delete();}),render(ge.createElement(c$1,{state:{type:"login_error",message:"Session invalidated",detail:"run `culvii login` to authenticate"}})),await e(a$2.LOGIN_FAILED,{reason:"session_expired"}),await j$1(),process.exit(1)),u}}}async function et(){let e=new a$4;return e.withLock(async()=>{let t=await e.get();if(!t)return null;let n=`https://${q.cognitoDomain}/oauth2/token`,r=new URLSearchParams;r.set("grant_type","refresh_token"),r.set("refresh_token",t.refreshToken),r.set("client_id",q.clientId);let i;try{i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r.toString()});}catch(a){return b$1.error("Network error during silent refresh",{error:a.message}),null}let s=await i.json();if(!i.ok||s.error==="invalid_grant")return b$1.warn("Silent refresh failed",{error:s.error}),null;let u=Date.now(),o=u+s.expires_in*1e3;return await e.set({accessToken:s.access_token,refreshToken:s.refresh_token||t.refreshToken,idToken:s.id_token||t.idToken,expiresAt:o,tokenType:"Bearer",scope:t.scope,issuedAt:u,issuer:t.issuer}),s.access_token})}async function Y(e){let t=await e.text();try{let n=JSON.parse(t);if(n.error)return n.error}catch{}return t}async function j(e,t,n={}){let{skipEnvironmentHeader:r,...i}=n,u=await new a$3().read({exitOnError:false}),o$1=u.contexts[u.active],a=o$1?.tenant_id,l=o$1?.environment||"dev",c=o()??l,w=o$1?.environment_ids?.[c]??(c===l?o$1?.environment_id:void 0),p=k[c],y=r?{}:w?{"x-environment-id":w}:{"x-environment-slug":p},k$1={Authorization:`Bearer ${t}`,...a?{"x-tenant-id":a}:{},...y,...i.headers||{}};return fetch(e,{...i,headers:k$1})}function kt(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}function ht(e$1){let t=e$1.command("workspace").description("Workspace commands").option("--env <env>","Target environment (sandbox or prod)");t.command("create").description("Create a new workspace").requiredOption("--name <name>","Workspace name").requiredOption("--slug <slug>","Workspace slug").action(async n=>{if(kt()){let u=function(){let[o,a]=ge.useState({type:"loading"});return ge.useEffect(()=>(s$1=a,()=>{s$1=null;}),[]),ge.createElement(i,{state:o})};let{WorkspaceCreateView:i}=await import('./WorkspaceView-RNFALIPM.js'),s$1=null;await V(Promise.resolve(ge.createElement(u))),await B(async o=>{let{apiUrl:a,context:l}=await r({env:t.opts().env}),c=s(l);try{let w=await j(`${a}/api/workspaces`,o,{method:"POST",headers:{...c,"Content-Type":"application/json"},body:JSON.stringify({name:n.name,slug:n.slug,tenantId:l.tenant_id})});if(!w.ok){let A=await Y(w);s$1?.({type:"error",message:"Failed to create workspace",detail:`Server responded with ${w.status}: ${A}`});let{userId:v,tenantId:D}=await d();v?await f(a$2.WORKSPACE_CREATE_FAILED,v,D,{error_class:"ApiError",slug:n.slug,env:l.environment}):await e(a$2.WORKSPACE_CREATE_FAILED,{error_class:"ApiError",slug:n.slug,env:l.environment}),await j$1();return}let p=await w.json();s$1?.({type:"success",id:p?.data?.workspaceId,slug:p?.data?.workspaceSlug||n.slug,name:n.name});let{userId:y,tenantId:k}=await d();y?await f(a$2.WORKSPACE_CREATED,y,k,{slug:n.slug,env:l.environment}):await e(a$2.WORKSPACE_CREATED,{slug:n.slug,env:l.environment}),await j$1();}catch(w){s$1?.({type:"error",message:"Unexpected error",detail:w.message});let{userId:p,tenantId:y}=await d();p?await f(a$2.WORKSPACE_CREATE_FAILED,p,y,{error_class:w?.constructor?.name,env:l.environment}):await e(a$2.WORKSPACE_CREATE_FAILED,{error_class:w?.constructor?.name,env:l.environment}),await j$1();}});return}await B(async i=>{let{apiUrl:s$1,context:u}=await r({env:t.opts().env}),o=s(u);console.log(`tenant: ${u.tenant_slug} | workspace: N/A | env: ${u.environment}`);try{let a=await j(`${s$1}/api/workspaces`,i,{method:"POST",headers:{...o,"Content-Type":"application/json"},body:JSON.stringify({name:n.name,slug:n.slug,tenantId:u.tenant_id})});if(!a.ok){let p=await Y(a);console.error(`Error: Failed to create workspace. Server responded with ${a.status}: ${p}`);let{userId:y,tenantId:k}=await d();y?await f(a$2.WORKSPACE_CREATE_FAILED,y,k,{error_class:"ApiError",slug:n.slug,env:u.environment}):await e(a$2.WORKSPACE_CREATE_FAILED,{error_class:"ApiError",slug:n.slug,env:u.environment}),await j$1(),process.exit(1);}let l=await a.json();console.log(`${w} Workspace created successfully.`),console.log(` ID: ${l?.data?.workspaceId}`),l?.data?.workspaceSlug&&console.log(` Slug: ${l?.data?.workspaceSlug}`);let{userId:c,tenantId:w$1}=await d();c?await f(a$2.WORKSPACE_CREATED,c,w$1,{slug:n.slug,env:u.environment}):await e(a$2.WORKSPACE_CREATED,{slug:n.slug,env:u.environment}),await j$1();}catch(a){console.error(`Error: Network or unexpected error: ${a.message}`);let{userId:l,tenantId:c}=await d();l?await f(a$2.WORKSPACE_CREATE_FAILED,l,c,{error_class:a?.constructor?.name,env:u.environment}):await e(a$2.WORKSPACE_CREATE_FAILED,{error_class:a?.constructor?.name,env:u.environment}),await j$1(),process.exit(1);}});}),t.command("list").description("List workspaces").action(async()=>{if(kt()){let s$1=function(){let[u,o]=ge.useState({type:"loading"});return ge.useEffect(()=>(i=o,()=>{i=null;}),[]),ge.createElement(r$1,{state:u})};let{WorkspaceListView:r$1}=await import('./WorkspaceView-RNFALIPM.js'),i=null;await V(Promise.resolve(ge.createElement(s$1))),await B(async u=>{let{apiUrl:o,context:a}=await r({env:t.opts().env}),l=s(a);try{let c=await j(`${o}/api/workspaces?tenantId=${a.tenant_id}`,u,{headers:l});if(!c.ok){let A=await Y(c);i?.({type:"error",message:"Failed to list workspaces",detail:`Server responded with ${c.status}: ${A}`});let{userId:v,tenantId:D}=await d();v?await f(a$2.WORKSPACE_LIST_FAILED,v,D,{error_class:"ApiError",env:a.environment}):await e(a$2.WORKSPACE_LIST_FAILED,{error_class:"ApiError",env:a.environment}),await j$1();return}let p=(await c.json())?.data?.workspaces;if(!Array.isArray(p)){i?.({type:"error",message:"Unexpected response format"});let{userId:A,tenantId:v}=await d();A?await f(a$2.WORKSPACE_LIST_FAILED,A,v,{error_class:"UnexpectedResponse",env:a.environment}):await e(a$2.WORKSPACE_LIST_FAILED,{error_class:"UnexpectedResponse",env:a.environment}),await j$1();return}i?.({type:"success",workspaces:p.map(A=>({id:A.id,name:A.name,slug:A.slug??""}))});let{userId:y,tenantId:k}=await d();y?await f(a$2.WORKSPACE_LISTED,y,k,{env:a.environment}):await e(a$2.WORKSPACE_LISTED,{env:a.environment}),await j$1();}catch(c){i?.({type:"error",message:"Unexpected error",detail:c.message});let{userId:w,tenantId:p}=await d();w?await f(a$2.WORKSPACE_LIST_FAILED,w,p,{error_class:c?.constructor?.name,env:a.environment}):await e(a$2.WORKSPACE_LIST_FAILED,{error_class:c?.constructor?.name,env:a.environment}),await j$1();}});return}await B(async r$1=>{let{apiUrl:i,context:s$1}=await r({env:t.opts().env}),u=s(s$1);console.log(`tenant: ${s$1.tenant_slug} | workspace: N/A | env: ${s$1.environment}`);try{let o=await j(`${i}/api/workspaces?tenantId=${s$1.tenant_id}`,r$1,{headers:u});if(!o.ok){let p=await Y(o);console.error(`Error: Failed to list workspaces. Server responded with ${o.status}: ${p}`);let{userId:y,tenantId:k}=await d();y?await f(a$2.WORKSPACE_LIST_FAILED,y,k,{error_class:"ApiError",env:s$1.environment}):await e(a$2.WORKSPACE_LIST_FAILED,{error_class:"ApiError",env:s$1.environment}),await j$1(),process.exit(1);}let l=(await o.json())?.data?.workspaces;if(!Array.isArray(l)){console.error("Error: Unexpected response format");let{userId:p,tenantId:y}=await d();p?await f(a$2.WORKSPACE_LIST_FAILED,p,y,{error_class:"UnexpectedResponse",env:s$1.environment}):await e(a$2.WORKSPACE_LIST_FAILED,{error_class:"UnexpectedResponse",env:s$1.environment}),await j$1(),process.exit(1);}for(let p of l)console.log(`${p.id} ${p.name} ${p.slug}`);let{userId:c,tenantId:w}=await d();c?await f(a$2.WORKSPACE_LISTED,c,w,{env:s$1.environment}):await e(a$2.WORKSPACE_LISTED,{env:s$1.environment}),await j$1();}catch(o){console.error(`Error: Network or unexpected error: ${o.message}`);let{userId:a,tenantId:l}=await d();a?await f(a$2.WORKSPACE_LIST_FAILED,a,l,{error_class:o?.constructor?.name,env:s$1.environment}):await e(a$2.WORKSPACE_LIST_FAILED,{error_class:o?.constructor?.name,env:s$1.environment}),await j$1(),process.exit(1);}});});}function nt(e,t,n){let r=null,i=0,s=false,u=[],o=new Map,a=null,l=null,c=0,w=[1e3,2e3,4e3,8e3,16e3];function p(){a&&(clearInterval(a),a=null),l&&(clearTimeout(l),l=null),c=0;}function y(){p(),a=setInterval(()=>{if(!r||r.readyState!==tt.OPEN)return;let R=Date.now().toString()+"-"+Math.random().toString();r.send(JSON.stringify({type:"client-ping",requestId:R})),l=setTimeout(()=>{c++,c>=2&&(b$1.warn("devSync WebSocket dead (missed 2 pongs), terminating"),p(),r?.terminate());},5e3);},2e4);}function k(R){R.removeAllListeners(),R.on("error",()=>{});try{R.terminate();}catch(L){b$1.warn("devSync error terminating stale socket",{error:L.message});}}let A=0;async function v(){if(s)return;let R=++A,L;try{L=await t();}catch(I){b$1.error("devSync failed to obtain headers for connection",{error:I.message}),R===A&&D();return}if(s||R!==A)return;r&&k(r);let f=new tt(e,{headers:L});r=f,f.on("open",()=>{if(r===f){i=0,b$1.info("devSync WebSocket connected",{url:e}),n.onOpen();for(let I of u)f.send(JSON.stringify(I));u=[],y();}}),f.on("message",I=>{if(r!==f)return;let E=Buffer.isBuffer(I)?I.toString("utf-8"):I instanceof ArrayBuffer?Buffer.from(I).toString("utf-8"):Buffer.concat(I).toString("utf-8"),g;try{g=JSON.parse(E);}catch{b$1.warn("Received invalid JSON from devSync",{raw:E});return}if(g.ok===true&&g.slug&&typeof g.warning=="string"){n.onWarning?.(g.slug,g.warning);return}if(g.type==="session-probe"&&typeof g.requestId=="string"){f.send(JSON.stringify({type:"session-pong",requestId:g.requestId}));return}if(g.type==="client-pong"){l&&(clearTimeout(l),l=null),c=0;return}if(g.ok===true&&g.slug&&g.type==="validation-error"){n.onValidationErrorAck?.(g.slug);return}if(g.ok===true&&g.slug){g.resourceId&&o.set(g.slug,g.resourceId),n.onAck(g.slug,g.resourceId,g.orphaned===true);return}if(g.ok===false&&g.slug){n.onError(g.slug,g.error||"Unknown error");return}if(g.ok===false&&!g.slug){n.onFatal(g.error||"Fatal error from server"),s=true,p(),f.close();return}}),f.on("unexpected-response",(I,E)=>{if(r===f){if(E.statusCode===401){b$1.error("devSync credentials rejected (401)"),s=true,p(),f.terminate(),n.onAuthFailure?n.onAuthFailure():n.onFatal("Credentials rejected by server (401)");return}b$1.warn("devSync unexpected handshake response",{statusCode:E.statusCode}),p(),f.terminate(),D();}}),f.on("close",I=>{r!==f||s||(b$1.warn("devSync WebSocket closed",{code:I}),p(),D());}),f.on("error",I=>{r===f&&b$1.error("devSync WebSocket error",{error:I.message});});}function D(){if(p(),s)return;if(i>=w.length){let f=`devSync PERMANENT FAILURE: giving up after ${w.length} retries`;b$1.error(f,{retryCount:i,retryDelaysMs:w}),n.onFatal(f),s=true;return}let R=w[i];i++;let L=w.length-i;b$1.info(`devSync reconnecting in ${R}ms (attempt ${i}/${w.length}, ${L} left before permanent failure)`),setTimeout(()=>{v();},R);}function $(R){r&&r.readyState===tt.OPEN?r.send(JSON.stringify(R)):u.push(R);}function M(){s=true,p(),r&&k(r),b$1.info("devSync WebSocket closed by client");}function S(){s||(p(),i=0,r&&k(r),v());}return v(),{send:$,close:M,reconnectNow:S}}var Ct=b(St(),1);var Tn=fileURLToPath(import.meta.url),Sn=dirname(Tn),Dn=join(Sn,"lib","evaluator.js"),Cn=createRequire(import.meta.url),Rn=Cn.resolve("tsx/cli");function Pe(e){return (0, Ct.validateSurfaceResource)(e)}function st(e){if(Array.isArray(e))return e.map(st);if(e!==null&&typeof e=="object"){let t={};for(let n of Object.keys(e).sort())t[n]=st(e[n]);return t}return e}function xn(e){if(!e||typeof e!="object")return e;let t={...e};return Array.isArray(t.nodes)&&(t.nodes=t.nodes.map(({id:n,...r})=>r)),t}function Ln(e){return createHash("sha256").update(JSON.stringify(st(xn(e)))).digest("hex")}function ye(e){return (Array.isArray(e?.nodes)?e.nodes:[]).filter(n=>n?.type==="core.agent").map(n=>n?.nodeParams?.agentReferenceKey??n?.nodeParams?.agentId).filter(n=>typeof n=="string"&&!n.startsWith("agt_"))}function Fe(e){return (Array.isArray(e?.nodes)?e.nodes:[]).flatMap(n=>["output","wait"].map(r=>n?.ui?.[r]).filter(r=>r?.kind==="custom"&&typeof r.surfaceKey=="string").map(r=>({surfaceKey:r.surfaceKey,...Number.isInteger(r.version)?{version:r.version}:{}})))}function $n(e){return Array.isArray(e)?e:e&&typeof e=="object"?Object.entries(e).map(([t,n])=>n&&typeof n=="object"&&!Array.isArray(n)?{name:t,...n}:n):[]}function Ie(e){return $n(e?.tools).filter(t=>t&&typeof t=="object"&&!Array.isArray(t)).map(t=>({referenceKey:t.workflowReferenceKey??t.workflowId,toolName:t.name,triggerNodeName:t.triggerNodeName})).filter(t=>typeof t.referenceKey=="string"&&!t.referenceKey.startsWith("wfl_"))}function Te(e){return Ie(e).map(t=>t.referenceKey)}function bn(e){return typeof e?.type=="string"&&e.type!=="manualTrigger"&&e.type.endsWith("Trigger")}function On(e,t){return e.get(t)??e.get(W(t))}function Rt(e){let t=new Set,n=[];for(let r of e.values())t.has(r.id)||(t.add(r.id),n.push(r));return n}function xt(e,t){let n=typeof e?.id=="string"?e.id:"unknown";if(Ie(e).length>0)return {id:n,definition:e};let r=n==="unknown"?void 0:On(t,n);return r?{id:n,definition:r.definition}:e&&typeof e=="object"&&!Array.isArray(e)?{id:n,definition:e}:null}function at(e,t){let n=[e];for(let r of e.definition?.secondaryAgents??[]){let i=xt(r,t);i&&n.push(i);}return n}function We(e){let t=new Map,n=new Map;for(let s of e){let u=s.definition?.id;typeof u=="string"&&(s.type==="agent"?(t.set(u,{id:u,definition:s.definition}),t.set(W(u),{id:u,definition:s.definition})):s.type==="workflow"&&(n.set(u,s.definition),n.set(W(u),s.definition)));}let r=new Set;for(let s of Rt(t))for(let u of at(s,t))for(let o of Te(u.definition))r.add(W(o));let i=new Set;for(let s of r){let u=n.get(s);if(u)for(let o of ye(u))i.add(W(o));}for(let s of i){let u=t.get(s);if(u){if(Ie(u.definition).length>0)return `agent '${u.id}' cannot define workflow tools when invoked by an agent workflow tool.`;for(let o of u.definition?.secondaryAgents??[]){let a=xt(o,t);if(a&&Ie(a.definition).length>0)return `secondary agent '${a.id}' referenced by agent '${u.id}' cannot define workflow tools when '${u.id}' is invoked by an agent workflow tool.`}}}return null}function Me(e){let t=new Map,n=new Map;for(let i of e){let s=i.definition?.id;typeof s=="string"&&(i.type==="agent"?(t.set(s,{id:s,definition:i.definition}),t.set(W(s),{id:s,definition:i.definition})):i.type==="workflow"&&(n.set(s,i.definition),n.set(W(s),i.definition)));}let r=new Set;for(let i of n.values())for(let s of ye(i))r.add(W(s));for(let i of r){let s=t.get(i);if(!s)continue;let u=at(s,t);for(let o of u)for(let a of Ie(o.definition)){let l=n.get(a.referenceKey)??n.get(W(a.referenceKey));if(!(!l||ye(l).length===0))return `workflow tool '${a.toolName??"unknown"}' on agent '${o.id}' cannot reference workflow '${a.referenceKey}' because '${s.id}' is invoked by a workflow and the target workflow contains an agent node.`}}return null}function je(e){let t=new Map,n=new Map;for(let r of e){let i=r.definition?.id;typeof i=="string"&&(r.type==="agent"?(t.set(i,{id:i,definition:r.definition}),t.set(W(i),{id:i,definition:r.definition})):r.type==="workflow"&&(n.set(i,r.definition),n.set(W(i),r.definition)));}for(let r of Rt(t))for(let i of at(r,t))for(let s of Ie(i.definition)){let u=n.get(s.referenceKey)??n.get(W(s.referenceKey));if(!u)continue;let o=Array.isArray(u.nodes)?u.nodes:[],a=o.find(bn);if(a)return `workflow tool '${s.toolName??"unknown"}' on agent '${i.id}' references workflow '${s.referenceKey}' with non-manual trigger '${a.name??a.type}'.`;if(s.triggerNodeName){if(o.find(w=>w?.name===s.triggerNodeName)?.type==="manualTrigger")continue;return `workflow tool '${s.toolName??"unknown"}' on agent '${i.id}' must use a manual trigger in workflow '${s.referenceKey}'.`}let l=o.filter(c=>c?.type==="manualTrigger");if(l.length!==1)return l.length===0?`workflow tool '${s.toolName??"unknown"}' on agent '${i.id}' references workflow '${s.referenceKey}' without a manual trigger.`:`workflow tool '${s.toolName??"unknown"}' on agent '${i.id}' must specify triggerNodeName because workflow '${s.referenceKey}' has multiple manual triggers.`}return null}function Ve(e){let t=[],n=(r,i)=>{let s=i&&typeof i=="object"&&!Array.isArray(i)?i.credentialId:void 0;(typeof s!="string"||!s.trim())&&t.push(`agent '${r}' model must include a credentialId \u2014 use model: { provider, modelId, credentialId }.`);};e?.modelConfig!==void 0&&e?.modelConfig!==null&&n(e?.id,e.modelConfig);for(let r of e?.secondaryAgents??[])r?.modelConfig!==void 0&&r?.modelConfig!==null&&n(r?.id??e?.id,r.modelConfig);return t}function Ke(e){let t=new Map;for(let i of e){let s=i.definition?.id;if(!s)continue;let u=i.type==="agent"?Te(i.definition).map(o=>`workflow:${o}`):i.type==="workflow"?ye(i.definition).map(o=>`agent:${o}`):[];t.set(`${i.type}:${s}`,u);}let n=null;function r(i,s){if(!n)for(let u of t.get(i)??[]){if(!t.has(u))continue;let o=[...s,u];if(s.length>=3){n=`Unsupported nested SDK reference chain: ${o.join(" -> ")}. Only workflow -> agent -> workflow or agent -> workflow -> agent is supported.`;return}r(u,o);}}for(let i of t.keys())r(i,[i]);return n}async function Nn(e){try{let r=X.join(e,"culvii.yaml"),s=(await ne.readFile(r,"utf-8")).split(`
3
+ `),u=[],o=!1;for(let a of s){if(a.trim().startsWith("entrypoints:")){o=!0;continue}if(o){let l=a.match(/^\s+-\s+(.+)$/);l?u.push(X.resolve(e,l[1].trim())):a.trim()&&!a.trim().startsWith("#")&&(o=!1);}}if(u.length>0)return b$1.info("Using entrypoints from culvii.yaml",{count:u.length}),u}catch{}let t=[];async function n(r){let i;try{i=await ne.readdir(r,{withFileTypes:!0});}catch{return}for(let s of i){if(s.name==="node_modules"||s.name==="dist"||s.name===".git")continue;let u=X.join(r,s.name);s.isDirectory()?await n(u):s.isFile()&&s.name.endsWith(".culvii.ts")&&t.push(u);}}return await n(e),b$1.info("Found .culvii.ts entrypoints",{count:t.length}),t}function Un(e,t){return new Promise((n,r)=>{if(e.length===0){n([]);return}let i=spawn(process.execPath,[Rn,Dn,...e],{env:{...process.env,...t,CULVII_DEV:"true"},stdio:["ignore","pipe","pipe"]}),s="",u="";i.stdout.on("data",o=>{s+=o.toString();}),i.stderr.on("data",o=>{u+=o.toString();}),i.on("close",o=>{if(u.trim()&&b$1.warn("Evaluator stderr",{stderr:u.trim()}),o!==0){r(new Error(`Evaluator exited with code ${o}. ${u.trim()||"Check your files for syntax errors."}`));return}let a=s.split(`
4
+ `).filter(w=>w.includes("__culvii_dev_definitions__"));if(a.length===0){n([]);return}let l=[],c=new Set;for(let w of a)try{let p=JSON.parse(w);for(let y of p.__culvii_dev_definitions__||[]){let k=y?.definition?.id,A=y?.type&&k?`${y.type}:${k}`:null;if(A){if(c.has(A))continue;c.add(A);}l.push(y);}}catch{b$1.warn("Failed to parse evaluator output",{line:w});}n(l);});})}function W(e){return e.toLowerCase().replace(/\s+/g,"-").replace(/[^a-z0-9-]/g,"").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-").slice(0,63)}function ot(e){let t=process.cwd(),n=new Map,r=null,i=false,s=false,u=false;async function o(){if(i){s=true;return}i=true;try{u&&(u=!1,n.clear()),await l();}catch(p){b$1.error("Evaluation failed",{error:p.message});}finally{i=false,s&&(s=false,o());}}function a(p,y,k){e.onLog?e.onLog(y,k):(k==="error"?process.stderr:process.stdout).write(`${p} ${y}
5
+ `);}async function l(){let p=await Nn(t),y$1;try{y$1=await Un(p,{});}catch(g){a(x,`Evaluation failed, skipping this sync cycle: ${g.message}`,"error");return}let k=new Map,A=new Set,v=new Set(y$1.map(g=>g.definition.id).filter(Boolean)),D=new Set(y$1.filter(g=>g.type==="surface").flatMap(g=>{let C=g.definition.id;return typeof C=="string"?[C,W(C)]:[]})),$=false,M=false;for(let g of y$1){let C=g.definition.id;if(!C){a(y,`Skipping ${g.type}: referenced resources require an explicit id.`,"warn");continue}let x$1=typeof C=="string"?W(C):String(C);if(!x$1){a(y,`Skipping definition: could not derive a valid slug from "${C}". Add an explicit id field.`,"warn");continue}if(g.type==="surface"){let P=Pe(g.definition);if(P.length){a(x,`Invalid surface '${x$1}': ${P.join("; ")}.`,"error");return}}let N=`${g.type}:${x$1}`;if(A.has(N)){a(x,`Duplicate slug '${x$1}' detected in ${g.type}s. Fix all collisions before syncing.`,"error");return}A.add(N);let G=Ln(g.definition);k.set(N,{slug:x$1,type:g.type,definition:g.definition,hash:G});let re=g.type==="agent"?Te(g.definition):[],pe=g.type==="workflow"?ye(g.definition):[],ee=g.type==="workflow"?Fe(g.definition):[];if(g.type==="agent"){for(let P of Ve(g.definition))a(x,P,"error"),M=true;for(let P of g.definition.secondaryAgents||[]){let K=P?.id,O=!!(P?.systemPrompt||P?.modelConfig);if(typeof K=="string"&&!O&&!v.has(K)){let te=`Dangling ref: agent '${x$1}' references secondary agent '${K}' which is not defined locally.`;a(x,te,"error"),$=true,e.onValidationError?.({resourceType:"agent",slug:x$1,missingReferenceId:K,message:te});}}}for(let P of re)if(!v.has(P)){let K=`Dangling ref: agent '${x$1}' references workflow '${P}' which is not defined locally.`;a(x,K,"error"),$=true,e.onValidationError?.({resourceType:"agent",slug:x$1,missingReferenceId:P,message:K});}for(let P of pe)if(!v.has(P)){let K=`Dangling ref: workflow '${x$1}' references agent '${P}' which is not defined locally.`;a(x,K,"error"),$=true,e.onValidationError?.({resourceType:"workflow",slug:x$1,missingReferenceId:P,message:K});}for(let P of ee)if(P.version===void 0&&!D.has(P.surfaceKey)){let K=`Dangling ref: workflow '${x$1}' references local surface '${P.surfaceKey}' which is not defined locally. Pin a published version or define the surface.`;a(x,K,"error"),$=true,e.onValidationError?.({resourceType:"workflow",slug:x$1,missingReferenceId:P.surfaceKey,message:K});}}if($){a(x,"Fix all dangling references before syncing.","error");return}if(M){a(x,"Fix the model configuration before syncing.","error");return}let S=We(y$1);if(S){a(x,S,"error"),a(x,"Fix the secondary agent tools before syncing.","error");return}let R=je(y$1);if(R){a(x,R,"error"),a(x,"Fix the workflow tool trigger before syncing.","error");return}let L=Me(y$1);if(L){a(x,L,"error"),a(x,"Fix the workflow tool target before syncing.","error");return}let f=Ke(y$1);if(f){a(x,f,"error"),a(x,"Fix the reference chain before syncing.","error");return}let I=0;for(let[g,{hash:C,type:x}]of n.entries())if(!k.has(g)){let N=g.slice(g.indexOf(":")+1),G=x==="surface"?void 0:[...k.values()].find(re=>re.hash===C&&re.type===x);G?a(y,`Looks like '${N}' was renamed to '${G.slug}'.
6
+ Run: culvii rename ${N} ${G.slug} --resource-type ${x}`,"warn"):(e.onOrphan(N,x),n.delete(g),I++);}let E=[...k.entries()].sort(([,g],[,C])=>+(C.type==="surface")-+(g.type==="surface"));for(let[g,{slug:C,type:x,definition:N,hash:G}]of E){let re=n.get(g);(!re||re.hash!==G)&&(n.set(g,{hash:G,type:x}),e.onSync({type:x,slug:C,definition:N,configHash:G}),I++);}I===0&&a(z,"No changes to sync.","info");}let c=hn.watch(t,{ignored:p=>p.includes("node_modules")||p.includes("/dist/")||p.includes("/.git/"),ignoreInitial:true,persistent:true});c.on("all",(p,y)=>{y.endsWith(".ts")&&(r&&clearTimeout(r),r=setTimeout(()=>{o();},500));});let w=false;return {close:()=>c.close(),triggerFullSync:()=>{if(w){o();return}if(w=true,i){u=true,s=true;return}n.clear(),o();}}}function Pn(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}var Se="https://console.culvii.com/";function Lt(){let e=new Date,t=n=>String(n).padStart(2,"0");return `${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}async function Fn(){let{DevView:e$1}=await import('./DevView-SOPAMSZ4.js'),t=null;function n(){let[r,i]=ge.useState({type:"provisioning",message:"Starting dev server\u2026"});return ge.useEffect(()=>(t=i,()=>{t=null;}),[]),ge.createElement(e$1,{state:r})}await V(Promise.resolve(ge.createElement(n))),await B(async r$1=>{let i=new a$3,s$1=await i.read({exitOnError:!1}),u=Date.now();if(!s$1.active||!s$1.contexts[s$1.active]){t?.({type:"error",message:"No active context. Run culvii login first."});let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEV_FAILED,f$1,I,{error_class:"NoActiveContext",workspace:a?.workspace_slug,env:a?.environment}):await e(a$2.DEV_FAILED,{error_class:"NoActiveContext",workspace:a?.workspace_slug,env:a?.environment}),await j$1();return}let{apiUrl:o,context:a}=await r({env:"dev"}),l=s(a),c=a.workspace_id,w=a.workspace_slug;t?.({type:"provisioning",message:"Provisioning dev workspace\u2026"});try{let f$1=await j(`${o}/api/workspaces`,r$1,{method:"POST",headers:{...l,"Content-Type":"application/json"},body:JSON.stringify({name:`dev-${a.user_id.slice(0,12)}`,slug:`dev-${a.user_id.slice(0,12)}`,tenantId:a.tenant_id})});if(!f$1.ok){let E=await Y(f$1);t?.({type:"error",message:`Failed to auto-provision workspace: ${E}`});let{userId:g,tenantId:C}=await d();g?await f(a$2.DEV_FAILED,g,C,{error_class:"WorkspaceProvisionError",workspace:a?.workspace_slug,env:a?.environment}):await e(a$2.DEV_FAILED,{error_class:"WorkspaceProvisionError",workspace:a?.workspace_slug,env:a?.environment}),await j$1();return}let I=await f$1.json();await i.withLock(async()=>{s$1=await i.read();let E=s$1.contexts[s$1.active];E.workspace_ids={...E.workspace_ids||{},dev:I?.data?.workspaceId},E.workspace_slugs={...E.workspace_slugs||{},dev:I?.data?.workspaceSlug},E.workspace_id=I?.data?.workspaceId,E.workspace_slug=I?.data?.workspaceSlug,await i.write(s$1);}),a={...s$1.contexts[s$1.active],environment:"dev"},c=a.workspace_id,w=a.workspace_slug;}catch(f$1){t?.({type:"error",message:`Failed to auto-provision workspace: ${f$1.message}`});let{userId:I,tenantId:E}=await d();I?await f(a$2.DEV_FAILED,I,E,{error_class:f$1?.constructor?.name,workspace:a?.workspace_slug,env:a?.environment}):await e(a$2.DEV_FAILED,{error_class:f$1?.constructor?.name,workspace:a?.workspace_slug,env:a?.environment}),await j$1();return}let{userId:p,tenantId:y}=await d();p?await f(a$2.DEV_STARTED,p,y,{workspace:a.workspace_slug,env:a.environment}):await e(a$2.DEV_STARTED,{workspace:a.workspace_slug,env:a.environment});let k=[];function A(f){return {Authorization:`Bearer ${f}`,...l}}let v=r$1;async function D(){let f=await et();return f&&(v=f),A(v)}let $=o.replace(/^http/,"ws")+"/api/dev/sync?workspaceId="+encodeURIComponent(c),M,S=nt($,D,{onOpen:()=>{t?.({type:"connected",workspace:w??`dev-${a.user_id.slice(0,12)}`,env:"dev",log:[...k],consoleUrl:Se}),M?.triggerFullSync();},onAck:(f,I,E)=>{let g={type:E?"orphaned":"synced",message:`${E?"orphaned":"synced"} ${f}`,timestamp:Lt()};k.push(g),t?.({type:"connected",workspace:w??`dev-${a.user_id.slice(0,12)}`,env:"dev",log:[...k],consoleUrl:Se});},onValidationErrorAck:()=>{},onWarning:(f,I)=>{let E={type:"warning",message:I};k.push(E),t?.({type:"connected",workspace:w??`dev-${a.user_id.slice(0,12)}`,env:"dev",log:[...k],consoleUrl:Se});},onError:(f,I)=>{let E={type:"error",message:`Sync failed for ${f}: ${I}`};k.push(E),t?.({type:"connected",workspace:w??`dev-${a.user_id.slice(0,12)}`,env:"dev",log:[...k],consoleUrl:Se});},onFatal:async f$1=>{clearInterval(L);let I=`Fatal error: ${f$1}. Shutting down...`;t?.({type:"error",message:I});let{userId:E,tenantId:g}=await d();E?await f(a$2.DEV_FAILED,E,g,{error_class:"FatalWebSocketError",workspace:a.workspace_slug,workspace:a?.workspace_slug,env:a?.environment}):await e(a$2.DEV_FAILED,{error_class:"FatalWebSocketError",workspace:a.workspace_slug,workspace:a?.workspace_slug,env:a?.environment}),M?.close(),S?.close(),he(1,I);},onAuthFailure:async()=>{clearInterval(L);let f$1="Your session was rejected by the server. Run `culvii login` to re-authenticate. Shutting down...";t?.({type:"error",message:f$1});let{userId:I,tenantId:E}=await d();I?await f(a$2.DEV_FAILED,I,E,{error_class:"ApiKeyRejected",workspace:a.workspace_slug,workspace:a?.workspace_slug,env:a?.environment}):await e(a$2.DEV_FAILED,{error_class:"ApiKeyRejected",workspace:a.workspace_slug,workspace:a?.workspace_slug,env:a?.environment}),M?.close(),S?.close(),he(1,f$1);}});M=ot({workspaceId:c,onSync:f=>{S.send({type:"sync",slug:f.slug,resourceType:f.type,definition:f.definition,workspaceId:c});},onOrphan:(f,I)=>{S.send({type:"orphan",slug:f,resourceType:I,workspaceId:c});},onValidationError:({resourceType:f,slug:I,missingReferenceId:E,message:g})=>{S.send({type:"validation-error",slug:I,resourceType:f,workspaceId:c,missingReferenceId:E,message:g});},onLog:(f,I)=>{let E={type:I==="error"?"error":I==="warn"?"warning":"info",message:f};k.push(E),t?.({type:"connected",workspace:w??`dev-${a.user_id.slice(0,12)}`,env:"dev",log:[...k],consoleUrl:Se});}});let R=3e3*1e3,L=setInterval(()=>{S.reconnectNow();},R);process.on("SIGINT",async()=>{clearInterval(L),S.close(),M.close(),t?.({type:"disconnected"});let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEV_STOPPED,f$1,I,{duration_ms:Date.now()-u,workspace:a.workspace_slug,env:a.environment}):await e(a$2.DEV_STOPPED,{duration_ms:Date.now()-u,workspace:a.workspace_slug,env:a.environment}),await j$1(),process.exit(0);});});}function $t(e$1){e$1.command("dev").description("Start the development server and file watcher").action(async()=>{if(Pn()){await Fn();return}await B(async t=>{let n=new a$3,r$1=await n.read({exitOnError:!1});if(!r$1.active||!r$1.contexts[r$1.active]){console.error("No active context. Run culvii login first.");let{userId:S,tenantId:R}=await d();S?await f(a$2.DEV_FAILED,S,R,{error_class:"NoActiveContext",workspace:s$1?.workspace_slug,env:s$1?.environment}):await e(a$2.DEV_FAILED,{error_class:"NoActiveContext",workspace:s$1?.workspace_slug,env:s$1?.environment}),await j$1(),process.exit(1);}let{apiUrl:i,context:s$1}=await r({env:"dev"}),u=s(s$1),o=Date.now(),a=s$1.workspace_id,l=s$1.workspace_slug;try{let S=await j(`${i}/api/workspaces`,t,{method:"POST",headers:{...u,"Content-Type":"application/json"},body:JSON.stringify({name:`dev-${s$1.user_id.slice(0,12)}`,slug:`dev-${s$1.user_id.slice(0,12)}`,tenantId:s$1.tenant_id})});if(!S.ok){let L=await Y(S);console.error(`Failed to auto-provision workspace: ${L}`);let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEV_FAILED,f$1,I,{error_class:"WorkspaceProvisionError",workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}):await e(a$2.DEV_FAILED,{error_class:"WorkspaceProvisionError",workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}),await j$1(),process.exit(1);}let R=await S.json();await n.withLock(async()=>{r$1=await n.read();let L=r$1.contexts[r$1.active];L.workspace_ids={...L.workspace_ids||{},dev:R?.data?.workspaceId},L.workspace_slugs={...L.workspace_slugs||{},dev:R?.data?.workspaceSlug},L.workspace_id=R?.data?.workspaceId,L.workspace_slug=R?.data?.workspaceSlug,await n.write(r$1);}),s$1={...r$1.contexts[r$1.active],environment:"dev"},a=s$1.workspace_id,l=s$1.workspace_slug;}catch(S){console.error(`Failed to auto-provision workspace: ${S.message}`);let{userId:R,tenantId:L}=await d();R?await f(a$2.DEV_FAILED,R,L,{error_class:S?.constructor?.name,workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}):await e(a$2.DEV_FAILED,{error_class:S?.constructor?.name,workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}),await j$1(),process.exit(1);}console.log(`tenant: ${s$1.tenant_slug} | workspace: ${l||"unknown"} | env: dev`);let{userId:c,tenantId:w$1}=await d();c?await f(a$2.DEV_STARTED,c,w$1,{workspace:s$1.workspace_slug,env:s$1.environment}):await e(a$2.DEV_STARTED,{workspace:s$1.workspace_slug,env:s$1.environment});function p(S){return {Authorization:`Bearer ${S}`,...u}}let y$1=t;async function k(){let S=await et();return S&&(y$1=S),p(y$1)}let A=i.replace(/^http/,"ws")+"/api/dev/sync?workspaceId="+encodeURIComponent(a),v,D=nt(A,k,{onOpen:()=>{console.log(`Watching ./... Connected to ${l??`dev-${s$1.user_id.slice(0,12)}`} (dev)`),console.log(`Console: ${Se}`),v?.triggerFullSync();},onAck:(S,R,L)=>{let f=Lt();console.log(L?`${w} [${f}] orphaned ${S}`:`${w} [${f}] synced ${S}`);},onValidationErrorAck:()=>{},onWarning:(S,R)=>{console.log(`${y} ${R}`);},onError:(S,R)=>{console.log(`${y} Sync failed for ${S}: ${R}`);},onFatal:async S=>{clearInterval(M),console.error(`Fatal error: ${S}. Shutting down...`);let{userId:R,tenantId:L}=await d();R?await f(a$2.DEV_FAILED,R,L,{error_class:"FatalWebSocketError",workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}):await e(a$2.DEV_FAILED,{error_class:"FatalWebSocketError",workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}),await j$1(),v?.close(),D?.close(),process.exit(1);},onAuthFailure:async()=>{clearInterval(M),console.error(`${x} Your session was rejected by the server. Run \`culvii login\` to re-authenticate. Shutting down...`);let{userId:S,tenantId:R}=await d();S?await f(a$2.DEV_FAILED,S,R,{error_class:"ApiKeyRejected",workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}):await e(a$2.DEV_FAILED,{error_class:"ApiKeyRejected",workspace:s$1.workspace_slug,workspace:s$1?.workspace_slug,env:s$1?.environment}),await j$1(),v?.close(),D?.close(),process.exit(1);}});v=ot({workspaceId:a,onSync:S=>{let R={type:"sync",slug:S.slug,resourceType:S.type,definition:S.definition,workspaceId:a};D.send(R);},onOrphan:(S,R)=>{let L={type:"orphan",slug:S,resourceType:R,workspaceId:a};D.send(L);},onValidationError:({resourceType:S,slug:R,missingReferenceId:L,message:f})=>{let I={type:"validation-error",slug:R,resourceType:S,workspaceId:a,missingReferenceId:L,message:f};D.send(I);}});let $=3e3*1e3,M=setInterval(()=>{D.reconnectNow();},$);process.on("SIGINT",async()=>{clearInterval(M),D.close(),v.close(),console.log("Disconnected. Draft state discarded.");let{userId:S,tenantId:R}=await d();S?await f(a$2.DEV_STOPPED,S,R,{duration_ms:Date.now()-o,workspace:s$1.workspace_slug,env:s$1.environment}):await e(a$2.DEV_STOPPED,{duration_ms:Date.now()-o,workspace:s$1.workspace_slug,env:s$1.environment}),await j$1(),process.exit(0);});});});}function Hn(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}function ct(e){if(Array.isArray(e))return e.map(ct);if(e!==null&&typeof e=="object"){let t={};for(let n of Object.keys(e).sort())t[n]=ct(e[n]);return t}return e}function Bn(e){if(!e||typeof e!="object")return e;let t={...e};return Array.isArray(t.nodes)&&(t.nodes=t.nodes.map(({id:n,...r})=>r)),t}function Pt(e){return createHash("sha256").update(JSON.stringify(ct(Bn(e)))).digest("hex")}async function Ft(e){try{let r=X.join(e,"culvii.yaml"),s=(await ne.readFile(r,"utf-8")).split(`
7
+ `),u=[],o=!1;for(let a of s){if(a.trim().startsWith("entrypoints:")){o=!0;continue}if(o){let l=a.match(/^\s+-\s+(.+)$/);l?u.push(X.resolve(e,l[1].trim())):a.trim()&&!a.trim().startsWith("#")&&(o=!1);}}if(u.length>0)return u}catch{}let t=[];async function n(r){let i;try{i=await ne.readdir(r,{withFileTypes:!0});}catch{return}for(let s of i){if(s.name==="node_modules"||s.name==="dist"||s.name===".git")continue;let u=X.join(r,s.name);s.isDirectory()?await n(u):s.isFile()&&s.name.endsWith(".culvii.ts")&&t.push(u);}}return await n(e),t}function Wt(e,t){return new Promise(n=>{if(e.length===0){n([]);return}let r=fileURLToPath(import.meta.url),i=dirname(r),s=join(i,"lib","evaluator.js"),o=createRequire(import.meta.url).resolve("tsx/cli"),a=spawn(process.execPath,[o,s,...e],{env:{...process.env,...t,CULVII_DEV:"true"},stdio:["ignore","pipe","pipe"]}),l="",c="";a.stdout.on("data",w=>{l+=w.toString();}),a.stderr.on("data",w=>{c+=w.toString();}),a.on("close",()=>{let w=l.split(`
8
+ `).filter(k=>k.includes("__culvii_dev_definitions__")),p=[],y=new Set;for(let k of w)try{let A=JSON.parse(k);for(let v of A.__culvii_dev_definitions__||[]){let D=v?.definition?.id,$=v?.type&&D?`${v.type}:${D}`:null;if($){if(y.has($))continue;y.add($);}p.push(v);}}catch{}n(p);});})}function qn(e){return new Promise(t=>{let n=Ut.createInterface({input:process.stdin,output:process.stdout});n.question(e,r=>{n.close(),t(r.toLowerCase()==="y"||r.toLowerCase()==="yes");});})}function Gn(e,t){return new Promise(n=>{let r=Ut.createInterface({input:process.stdin,output:process.stdout});r.question(e,i=>{r.close();let s=i.trim().toLowerCase();n(t.includes(s)?s:t[0]);});})}function Jn(e){if(e.type==="surface")return ` - ${e.slug}: marks inactive; published versions are retained`;let t=e.versionCount??1,n=e.activeVersion??e.previousVersion;return ` - ${e.slug}: deletes all ${t} ${t===1?"version":"versions"}${n?`; active is v${n}`:""}`}function Ot(e){console.log(`${y} Selected removals:`);for(let t of e)console.log(Jn(t));}function Nt(e){let t=e.executions??0,n=e.activeExecutions??0,r=e.activeVersion??e.previousVersion;return `${t} total, active${r?` v${r}`:""}: ${n} executions`}async function zn(e){return e.destroyed.length===0?{deleteMissing:false}:e.allowDestroy?(Ot(e.destroyed),{deleteMissing:true}):(console.log(""),console.log(`${y} ${e.destroyed.length} missing resource(s) found in ${e.env}.`),console.log(" k: keep them active"),console.log(" d: delete all missing resources"),await Gn("Delete missing resources? [k/d] ",["k","d"])==="d"?(Ot(e.destroyed),{deleteMissing:false,deleteMissingReferences:e.destroyed.map(n=>({type:n.type,referenceKey:n.referenceKey??n.slug}))}):{deleteMissing:false})}async function Xn(e$1){let{DeployView:t}=await import('./DeployView-GEJNL26A.js'),n=null,r$1=null;function i(){let[s,u]=ge.useState({type:"planning"});return ge.useEffect(()=>(n=u,()=>{n=null;}),[]),ge.createElement(t,{state:s,onConfirm:(o,a=false)=>{r$1?.({confirmed:o,deleteMissing:a});}})}await V(Promise.resolve(ge.createElement(i))),await B(async s$1=>{if(e$1.env==="dev"){n?.({type:"error",message:"Use culvii dev for local iteration"}),await j$1();return}if(e$1.env!=="sandbox"&&e$1.env!=="prod"){n?.({type:"error",message:"Environment must be sandbox or prod"}),await j$1();return}let{apiUrl:u,context:o}=await r({env:e$1.env}),a=s(o);if(!e$1.workspaceSlug){n?.({type:"error",message:"--workspace-slug <slug> is required for deploy",detail:"Run `culvii workspace list` to see available workspaces."});let{userId:E,tenantId:g}=await d();E?await f(a$2.DEPLOY_FAILED,E,g,{error_class:"NoWorkspace",workspace:e$1.workspaceSlug}):await e(a$2.DEPLOY_FAILED,{error_class:"NoWorkspace",workspace:e$1.workspaceSlug}),await j$1();return}let l=await j(`${u}/api/workspaces?tenantId=${o.tenant_id}`,s$1,{headers:a});if(!l.ok){n?.({type:"error",message:"Failed to fetch workspaces",detail:await Y(l)});let{userId:E,tenantId:g}=await d();E?await f(a$2.DEPLOY_FAILED,E,g,{env:e$1.env,error_class:"WorkspaceFetchError",workspace:e$1.workspaceSlug}):await e(a$2.DEPLOY_FAILED,{env:e$1.env,error_class:"WorkspaceFetchError",workspace:e$1.workspaceSlug}),await j$1();return}let p=((await l.json())?.data?.workspaces||[]).find(E=>E.slug===e$1.workspaceSlug);if(!p){n?.({type:"error",message:`Workspace not found: ${e$1.workspaceSlug}`});let{userId:E,tenantId:g}=await d();E?await f(a$2.DEPLOY_FAILED,E,g,{env:e$1.env,workspace:e$1.workspaceSlug,error_class:"WorkspaceNotFound"}):await e(a$2.DEPLOY_FAILED,{env:e$1.env,workspace:e$1.workspaceSlug,error_class:"WorkspaceNotFound"}),await j$1();return}let y=p.id,k=process.cwd(),A=await Ft(k),v=(await Wt(A,{})).sort((E,g)=>+(g.type==="surface")-+(E.type==="surface")),D=[],$=new Set,M=new Set(v.filter(E=>E.type==="surface").map(E=>W(E.definition.id??"")).filter(Boolean)),S=async E=>{n?.({type:"error",message:E});let{userId:g,tenantId:C}=await d();g?await f(a$2.DEPLOY_FAILED,g,C,{env:e$1.env,workspace:p?.slug,error_class:"ValidationError"}):await e(a$2.DEPLOY_FAILED,{env:e$1.env,workspace:p?.slug,error_class:"ValidationError"}),await j$1();};for(let E of v){let g=E.definition.id;g&&$.add(typeof g=="string"?W(g):String(g));}for(let E of v){let g=E.definition.id;if(!g){n?.({type:"error",message:`Deploy failed: ${E.type} is missing an explicit id.`}),await j$1();return}let C=typeof g=="string"?W(g):String(g);if(E.type==="surface"){let x=Pe(E.definition);if(x.length)return S(`Deploy failed: surface '${C}' ${x.join("; ")}.`)}if(E.type==="agent"){for(let N of Ve(E.definition))return S(`Deploy failed: ${N}`);let x=E.definition.secondaryAgents||[];for(let N of x){let G=N.id,re=!!(N?.systemPrompt||N?.modelConfig);if(G&&!re&&!$.has(G))return S(`Deploy failed: agent '${C}' references secondary agent '${G}' which is not defined.`)}for(let N of Te(E.definition))if(!$.has(W(N)))return S(`Deploy failed: agent '${C}' references workflow '${N}' which is not defined.`)}if(E.type==="workflow"){for(let x of ye(E.definition))if(!$.has(W(x)))return S(`Deploy failed: workflow '${C}' references agent '${x}' which is not defined.`);for(let x of Fe(E.definition))if(x.version===void 0&&!M.has(W(x.surfaceKey)))return S(`Deploy failed: workflow '${C}' references local surface '${x.surfaceKey}' which is not defined. Pin a published version or define the surface.`)}D.push({type:E.type,slug:C,definition:E.definition,configHash:Pt(E.definition)});}let R=We(v);if(R)return S(`Deploy failed: ${R}`);let L=je(v);if(L)return S(`Deploy failed: ${L}`);let f$1=Me(v);if(f$1)return S(`Deploy failed: ${f$1}`);let I=Ke(v);if(I)return S(`Deploy failed: ${I}`);try{let{userId:E,tenantId:g}=await d();E?await f(a$2.DEPLOY_STARTED,E,g,{env:e$1.env,workspace:p.slug}):await e(a$2.DEPLOY_STARTED,{env:e$1.env,workspace:p.slug});let C=await j(`${u}/api/workspaces/${y}/deploys/plan`,s$1,{method:"POST",headers:{...a,"Content-Type":"application/json"},body:JSON.stringify({environment:e$1.env,definitions:D})});if(!C.ok){let z=await Y(C);n?.({type:"error",message:"Failed to plan deploy",detail:z});let{userId:ce,tenantId:Ze}=await d();ce?await f(a$2.DEPLOY_FAILED,ce,Ze,{env:e$1.env,workspace:p?.slug,error_class:"PlanError"}):await e(a$2.DEPLOY_FAILED,{env:e$1.env,workspace:p?.slug,error_class:"PlanError"}),await j$1();return}let x=await C.json(),N=x.plan,G=x.planToken;if(!((N.created||[]).length>0||(N.versioned||[]).length>0||(N.destroyed||[]).length>0)){n?.({type:"no_changes"}),await j$1();return}let pe=await new Promise(z=>{r$1=z,n?.({type:"confirming",plan:{created:N.created||[],versioned:N.versioned||[],destroyed:(N.destroyed||[]).map(ce=>({...ce,renameHint:ce.renameHint?.suggestedCommand}))},env:e$1.env,allowDestroy:!!e$1.allowDestroy});});if(!pe.confirmed){n?.({type:"aborted",reason:"user_cancelled"});let{userId:z,tenantId:ce}=await d();z?await f(a$2.DEPLOY_ABORTED,z,ce,{env:e$1.env,workspace:p?.slug,reason:"user_cancelled"}):await e(a$2.DEPLOY_ABORTED,{env:e$1.env,workspace:p?.slug,reason:"user_cancelled"}),await j$1();return}let ee=e$1.allowDestroy||(N.destroyed||[]).length===0?{deleteMissing:!!e$1.allowDestroy}:pe.deleteMissing?{deleteMissing:!1,deleteMissingReferences:(N.destroyed||[]).map(z=>({type:z.type,referenceKey:z.referenceKey??z.slug}))}:{deleteMissing:!1};n?.({type:"applying"});let P=await j(`${u}/api/workspaces/${y}/deploys/apply`,s$1,{method:"POST",headers:{...a,"Content-Type":"application/json"},body:JSON.stringify({planToken:G,...ee})});if(!P.ok){let z=await Y(P);n?.({type:"error",message:"Failed to apply deploy",detail:z});let{userId:ce,tenantId:Ze}=await d();ce?await f(a$2.DEPLOY_FAILED,ce,Ze,{env:e$1.env,workspace:p?.slug,error_class:"ApplyError"}):await e(a$2.DEPLOY_FAILED,{env:e$1.env,workspace:p?.slug,error_class:"ApplyError"}),await j$1();return}let K=await P.json();n?.({type:"success",env:e$1.env,created:(K.created||[]).length,versioned:(K.versioned||[]).length,destroyed:(K.destroyed||[]).length,createdItems:K.created||[],versionedItems:K.versioned||[],destroyedItems:K.destroyed||[],skippedDestroyedItems:K.skippedDestroyed||[]});let{userId:O,tenantId:te}=await d();O?await f(a$2.DEPLOY_SUCCEEDED,O,te,{env:e$1.env,workspace:p.slug,created:N.created.length,versioned:N.versioned.length,destroyed:N.destroyed.length}):await e(a$2.DEPLOY_SUCCEEDED,{env:e$1.env,workspace:p.slug,created:N.created.length,versioned:N.versioned.length,destroyed:N.destroyed.length});}catch(E){n?.({type:"error",message:"Unexpected error",detail:E.message});let{userId:g,tenantId:C}=await d();g?await f(a$2.DEPLOY_FAILED,g,C,{env:e$1.env,workspace:p?.slug,error_class:E?.constructor?.name}):await e(a$2.DEPLOY_FAILED,{env:e$1.env,workspace:p?.slug,error_class:E?.constructor?.name}),await j$1();}});}function Mt(e$1){e$1.command("deploy").description("Deploy an agent").requiredOption("--env <env>","Environment (sandbox or prod)").option("--workspace-slug <slug>","Target workspace slug (overrides config)").option("--allow-destroy","Allow destructive changes").action(async t=>{if(Hn()){await Xn(t);return}await B(async n=>{t.env==="dev"&&(console.log("Use culvii dev for local iteration"),await j$1(),process.exit(1)),t.env!=="sandbox"&&t.env!=="prod"&&(console.error("Environment must be sandbox or prod"),await j$1(),process.exit(1));let{apiUrl:r$1,context:i}=await r({env:t.env}),s$1=s(i);if(!t.workspaceSlug){console.error("Error: --workspace-slug <slug> is required for deploy. Run `culvii workspace list` to see available workspaces.");let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEPLOY_FAILED,f$1,I,{error_class:"NoWorkspace",workspace:t.workspaceSlug}):await e(a$2.DEPLOY_FAILED,{error_class:"NoWorkspace",workspace:t.workspaceSlug}),await j$1(),process.exit(1);}let u=null,o=await j(`${r$1}/api/workspaces?tenantId=${i.tenant_id}`,n,{headers:s$1});if(!o.ok){console.error(`Failed to fetch workspaces: ${await Y(o)}`);let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEPLOY_FAILED,f$1,I,{env:t.env,error_class:"WorkspaceFetchError",workspace:t.workspaceSlug}):await e(a$2.DEPLOY_FAILED,{env:t.env,error_class:"WorkspaceFetchError",workspace:t.workspaceSlug}),await j$1(),process.exit(1);}let c=((await o.json())?.data?.workspaces||[]).find(f=>f.slug===t.workspaceSlug);if(!c){console.error("Workspace not found: "+t.workspaceSlug);let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEPLOY_FAILED,f$1,I,{env:t.env,workspace:t.workspaceSlug,error_class:"WorkspaceNotFound"}):await e(a$2.DEPLOY_FAILED,{env:t.env,workspace:t.workspaceSlug,error_class:"WorkspaceNotFound"}),await j$1(),process.exit(1);}u=c.id;let w$1=t.workspaceSlug;console.log(`tenant: ${i.tenant_slug} | workspace: ${w$1} | env: ${t.env}`);let p=process.cwd(),y$1=await Ft(p),k=(await Wt(y$1,{})).sort((f,I)=>+(I.type==="surface")-+(f.type==="surface")),A=[],v=new Set,D=new Set(k.filter(f=>f.type==="surface").map(f=>W(f.definition.id??"")).filter(Boolean)),$=async f$1=>{console.error(f$1);let{userId:I,tenantId:E}=await d();I?await f(a$2.DEPLOY_FAILED,I,E,{env:t.env,workspace:c?.slug,error_class:"ValidationError"}):await e(a$2.DEPLOY_FAILED,{env:t.env,workspace:c?.slug,error_class:"ValidationError"}),await j$1(),process.exit(1);};for(let f of k){let I=f.definition.id;I&&v.add(typeof I=="string"?W(I):String(I));}for(let f of k){let I=f.definition.id;I||(console.error(`Deploy failed: ${f.type} is missing an explicit id.`),await j$1(),process.exit(1));let E=typeof I=="string"?W(I):String(I);if(f.type==="surface"){let g=Pe(f.definition);g.length&&await $(`Deploy failed: surface '${E}' ${g.join("; ")}.`);}if(f.type==="agent"){for(let C of Ve(f.definition))await $(`Deploy failed: ${C}`);let g=f.definition.secondaryAgents||[];for(let C of g){let x=C.id,N=!!(C?.systemPrompt||C?.modelConfig);x&&!N&&!v.has(x)&&await $(`Deploy failed: agent '${E}' references secondary agent '${x}' which is not defined in this workspace. Define '${x}' before deploying.`);}for(let C of Te(f.definition))v.has(W(C))||await $(`Deploy failed: agent '${E}' references workflow '${C}' which is not defined in this workspace. Define '${C}' before deploying.`);}if(f.type==="workflow"){for(let g of ye(f.definition))v.has(W(g))||await $(`Deploy failed: workflow '${E}' references agent '${g}' which is not defined in this workspace. Define '${g}' before deploying.`);for(let g of Fe(f.definition))g.version===void 0&&!D.has(W(g.surfaceKey))&&await $(`Deploy failed: workflow '${E}' references local surface '${g.surfaceKey}' which is not defined. Pin a published version or define the surface.`);}A.push({type:f.type,slug:E,definition:f.definition,configHash:Pt(f.definition)});}let M=We(k);M&&await $(`Deploy failed: ${M}`);let S=je(k);S&&await $(`Deploy failed: ${S}`);let R=Me(k);R&&await $(`Deploy failed: ${R}`);let L=Ke(k);L&&await $(`Deploy failed: ${L}`);try{let{userId:f$1,tenantId:I}=await d();f$1?await f(a$2.DEPLOY_STARTED,f$1,I,{env:t.env,workspace:c.slug}):await e(a$2.DEPLOY_STARTED,{env:t.env,workspace:c.slug});let E=await j(`${r$1}/api/workspaces/${u}/deploys/plan`,n,{method:"POST",headers:{...s$1,"Content-Type":"application/json"},body:JSON.stringify({environment:t.env,definitions:A})});if(!E.ok){let O=await Y(E);console.error(`Error: Failed to plan deploy. ${O}`);let{userId:te,tenantId:z}=await d();te?await f(a$2.DEPLOY_FAILED,te,z,{env:t.env,workspace:c?.slug,error_class:"PlanError"}):await e(a$2.DEPLOY_FAILED,{env:t.env,workspace:c?.slug,error_class:"PlanError"}),await j$1(),process.exit(1);}let g=await E.json(),C=g.plan,x=g.planToken;(C.created||[]).length>0||(C.versioned||[]).length>0||(C.destroyed||[]).length>0||(console.log("Nothing to deploy. All resources are up to date."),await j$1(),process.exit(0)),console.log(`Plan for ${t.env}:`);for(let O of C.created||[])console.log(` + ${O.slug} CREATED`);for(let O of C.versioned||[])console.log(` ~ ${O.slug} VERSIONED (${Nt(O)})`);for(let O of C.destroyed||[])console.log(` - ${O.slug} DELETE CANDIDATE (${Nt(O)})`),O.renameHint&&console.log(`${y} Rename hint: ${O.renameHint.suggestedCommand}`);let G=await zn({env:t.env,allowDestroy:t.allowDestroy,destroyed:C.destroyed||[]});if(!await qn(`Deploy to ${t.env}? [y/N] `)){console.log("Deployment cancelled.");let{userId:O,tenantId:te}=await d();O?await f(a$2.DEPLOY_ABORTED,O,te,{env:t.env,workspace:c?.slug,reason:"user_cancelled"}):await e(a$2.DEPLOY_ABORTED,{env:t.env,workspace:c?.slug,reason:"user_cancelled"}),await j$1(),process.exit(0);}let pe=await j(`${r$1}/api/workspaces/${u}/deploys/apply`,n,{method:"POST",headers:{...s$1,"Content-Type":"application/json"},body:JSON.stringify({planToken:x,...G})});if(!pe.ok){let O=await Y(pe);console.error(`Error: Failed to apply deploy. ${O}`);let{userId:te,tenantId:z}=await d();te?await f(a$2.DEPLOY_FAILED,te,z,{env:t.env,workspace:c?.slug,error_class:"ApplyError"}):await e(a$2.DEPLOY_FAILED,{env:t.env,workspace:c?.slug,error_class:"ApplyError"}),await j$1(),process.exit(1);}let ee=await pe.json();console.log(`${w} Deployed to ${t.env}`),console.log(` Created: ${(ee.created||[]).length} resource(s)`);for(let O of ee.created||[])console.log(` + ${O.slug||O.referenceKey||O.id}`);console.log(` Versioned: ${(ee.versioned||[]).length} resource(s)`);for(let O of ee.versioned||[])console.log(` ~ ${O.slug||O.referenceKey||O.id}`);console.log(` Destroyed: ${(ee.destroyed||[]).length} resource(s)`);for(let O of ee.destroyed||[])console.log(` - ${O.slug||O.referenceKey||O.id}`);if((ee.skippedDestroyed||[]).length>0){console.log(` Skipped deletion: ${(ee.skippedDestroyed||[]).length} resource(s)`);for(let O of ee.skippedDestroyed||[])console.log(` k ${O.slug||O.referenceKey||O.id}`);}let{userId:P,tenantId:K}=await d();P?await f(a$2.DEPLOY_SUCCEEDED,P,K,{env:t.env,workspace:c.slug,created:C.created.length,versioned:C.versioned.length,destroyed:C.destroyed.length}):await e(a$2.DEPLOY_SUCCEEDED,{env:t.env,workspace:c.slug,created:C.created.length,versioned:C.versioned.length,destroyed:C.destroyed.length});}catch(f$1){console.error(`Error: Network or unexpected error: ${f$1.message}`);let{userId:I,tenantId:E}=await d();I?await f(a$2.DEPLOY_FAILED,I,E,{env:t.env,workspace:c?.slug,error_class:f$1?.constructor?.name}):await e(a$2.DEPLOY_FAILED,{env:t.env,workspace:c?.slug,error_class:f$1?.constructor?.name}),await j$1(),process.exit(1);}});});}function Zn(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}function jt(e$1){e$1.command("rename").description("Rename a resource").argument("<old-slug>","Current slug").argument("<new-slug>","New slug").requiredOption("--resource-type <type>","Type of resource (agent|workflow)").option("--env <env>","Target environment (sandbox or prod)").option("--workspace-slug <slug>","Target workspace slug (overrides config)").action(async(t,n,r$1)=>{if(Zn()){let o=function(){let[a,l]=ge.useState({type:"loading"});return ge.useEffect(()=>(u.current=l,()=>{u.current=null;}),[]),ge.createElement(s$1,{state:a})};let{RenameView:s$1}=await import('./RenameView-3BABATL6.js'),u={current:null};if(await V(Promise.resolve(ge.createElement(o))),!["agent","workflow"].includes(r$1.resourceType)){u.current?.({type:"error",message:"Invalid resource type",detail:`'${r$1.resourceType}' \u2014 must be one of: agent, workflow`}),await e(a$2.RENAME_FAILED,{error_class:"InvalidResourceType",resourceType:r$1.resourceType,env:r$1.env,workspace:r$1.workspaceSlug}),await j$1();return}await B(async a=>{let{apiUrl:l,context:c}=await r({env:r$1.env}),w=s(c),{userId:p,tenantId:y}=await d();p?await f(a$2.RENAME_STARTED,p,y,{resourceType:r$1.resourceType,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_STARTED,{resourceType:r$1.resourceType,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();let k=c.workspace_id;if(r$1.workspaceSlug){let A=await j(`${l}/api/workspaces?tenantId=${c.tenant_id}`,a,{headers:w});if(!A.ok){u.current?.({type:"error",message:"Failed to fetch workspaces",detail:await Y(A)}),p?await f(a$2.RENAME_FAILED,p,y,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceFetchError",env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceFetchError",env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();return}let D=((await A.json())?.data?.workspaces||[]).find($=>$.slug===r$1.workspaceSlug);if(!D){u.current?.({type:"error",message:`Workspace not found: ${r$1.workspaceSlug}`}),p?await f(a$2.RENAME_FAILED,p,y,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceNotFound",env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceNotFound",env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();return}k=D.id;}if(!k){u.current?.({type:"error",message:"No workspace configured",detail:"Run culvii dev first, or provide --workspace-slug <slug>."}),p?await f(a$2.RENAME_FAILED,p,y,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"NoWorkspace",env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"NoWorkspace",env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();return}try{let A=await j(`${l}/api/workspaces/${k}/resources/${t}/rename`,a,{method:"PATCH",headers:{...w,"Content-Type":"application/json"},body:JSON.stringify({newSlug:n,resourceType:r$1.resourceType})});if(!A.ok){let v=await Y(A);u.current?.({type:"error",message:"Failed to rename resource",detail:`Server responded with ${A.status}: ${v}`}),p?await f(a$2.RENAME_FAILED,p,y,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:v,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:v,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();return}u.current?.({type:"success",oldSlug:t,newSlug:n}),p?await f(a$2.RENAME_SUCCEEDED,p,y,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_SUCCEEDED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();}catch(A){u.current?.({type:"error",message:"Unexpected error",detail:A.message}),p?await f(a$2.RENAME_FAILED,p,y,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:A.message,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:A.message,env:c.environment,workspace:r$1.workspaceSlug??c.workspace_slug}),await j$1();}});return}await B(async s$1=>{["agent","workflow"].includes(r$1.resourceType)||(console.error(`Error: Invalid resource type '${r$1.resourceType}'. Must be one of: agent, workflow`),await e(a$2.RENAME_FAILED,{error_class:"InvalidResourceType",resourceType:r$1.resourceType,env:r$1.env,workspace:r$1.workspaceSlug}),await j$1(),process.exit(1));let{apiUrl:u,context:o}=await r({env:r$1.env}),a=s(o),{userId:l,tenantId:c}=await d();l?await f(a$2.RENAME_STARTED,l,c,{resourceType:r$1.resourceType,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_STARTED,{resourceType:r$1.resourceType,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1(),console.log(`tenant: ${o.tenant_slug} | workspace: ${r$1.workspaceSlug||o.workspace_slug||"unknown"} | env: ${o.environment}`);let w$1=o.workspace_id;if(r$1.workspaceSlug){let p=await j(`${u}/api/workspaces?tenantId=${o.tenant_id}`,s$1,{headers:a});p.ok||(console.error(`Failed to fetch workspaces: ${await Y(p)}`),l?await f(a$2.RENAME_FAILED,l,c,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceFetchError",env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceFetchError",env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1(),process.exit(1));let A=((await p.json())?.data?.workspaces||[]).find(v=>v.slug===r$1.workspaceSlug);A||(console.error("Workspace not found: "+r$1.workspaceSlug),l?await f(a$2.RENAME_FAILED,l,c,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceNotFound",env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"WorkspaceNotFound",env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1(),process.exit(1)),w$1=A.id;}w$1||(console.error("Error: No workspace configured. Run culvii dev first, or provide --workspace-slug <slug>."),l?await f(a$2.RENAME_FAILED,l,c,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"NoWorkspace",env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error_class:"NoWorkspace",env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1(),process.exit(1));try{let p=await j(`${u}/api/workspaces/${w$1}/resources/${t}/rename`,s$1,{method:"PATCH",headers:{...a,"Content-Type":"application/json"},body:JSON.stringify({newSlug:n,resourceType:r$1.resourceType})});if(!p.ok){let y=await Y(p);console.error(`Error: Failed to rename resource. Server responded with ${p.status}: ${y}`),l?await f(a$2.RENAME_FAILED,l,c,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:y,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:y,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1(),process.exit(1);}console.log(`${w} Renamed ${t} ${z} ${n}`),console.log(" Immutable ID preserved. All execution history retained."),l?await f(a$2.RENAME_SUCCEEDED,l,c,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_SUCCEEDED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1();}catch(p){console.error(`Error: Network or unexpected error: ${p.message}`),l?await f(a$2.RENAME_FAILED,l,c,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:p.message,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}):await e(a$2.RENAME_FAILED,{oldSlug:t,newSlug:n,resourceType:r$1.resourceType,error:p.message,env:o.environment,workspace:r$1.workspaceSlug??o.workspace_slug}),await j$1(),process.exit(1);}});});}async function Kt(e,t,n){let r=await j(`${t}/auth/me`,e,{skipEnvironmentHeader:true});if(!r.ok)return {ok:false,status:r.status,error:await Y(r)};let i=await r.json(),s=i?.user||i?.data?.user||i,u=i?.tenant||i?.data?.tenant||{},o=u?.slug||n.tenant_slug||"Unknown",a=u?.name||n.tenant_slug||"Unknown",l$1=Array.isArray(i?.tenants)?i.tenants.find(A=>A.id===u?.id):void 0,c=Array.isArray(l$1?.environments)?l$1.environments:[],w=n.environment||"dev",p=k[w],y=c.find(A=>A.slug===p),k$1=[];if(y){let A=await j(`${t}/auth/me`,e,{skipEnvironmentHeader:true,headers:{"x-environment-id":y.id}});if(A.ok){let v=await A.json(),D=v?.user||v?.data?.user||v;Array.isArray(v?.roles)?k$1=v.roles:Array.isArray(D?.roles)?k$1=D.roles:typeof D?.roles=="string"&&(k$1=[D.roles]);}}return {ok:true,email:s?.email||"Unknown",name:s?.name||"Unknown",tenant:o,tenantName:a,workspace:n.workspace_slug||null,env:w,envAccessible:!!y,accessibleEnvs:c.map(A=>l(A.slug)??A.slug),roles:k$1}}async function xe(e$1,t){let{userId:n,tenantId:r}=await d(),i=e$1?{error:true,...t}:t?{...t}:void 0;n?await f(a$2.WHOAMI_VIEWED,n,r,i):await e(a$2.WHOAMI_VIEWED,i),await j$1();}function Yt(e){e.command("whoami").description("Show current authenticated user context").option("--json","Output as JSON").option("--env <env>","Environment to report (dev, sandbox, or prod); overrides the active env").action(async t=>{let{getCapabilities:n}=await import('./terminalCapabilities-LJTRMVG4.js'),r=n();if(t.json||!r.isTTY||r.isCI||!r.supportsColor||!r.supportsUnicode){await Qn();return}await er();});}async function Qn(){await B(async e=>{let{apiUrl:t,context:n}=await r(),r$1=await Kt(e,t,n);r$1.ok||(process.stderr.write(JSON.stringify({error:r$1.error})+`
9
+ `),await xe(!0),process.exit(1)),process.stdout.write(JSON.stringify({email:r$1.email,name:r$1.name,tenant:r$1.tenant,tenant_name:r$1.tenantName,workspace:r$1.workspace,env:r$1.env,env_accessible:r$1.envAccessible,accessible_environments:r$1.accessibleEnvs,roles:r$1.roles})+`
10
+ `),await xe(!1,{env:r$1.env,workspace:r$1.workspace});});}async function er(){let{WhoamiView:e}=await import('./WhoamiView-67HV2L5J.js'),t={type:"loading"},n=null,{useState:r$1,useEffect:i}=await import('react');function s(){let[u,o]=r$1(t);return i(()=>(n=o,()=>{n=null;}),[]),ge.createElement(e,{state:u})}await V(Promise.resolve(ge.createElement(s))),await B(async u=>{try{let{apiUrl:o,context:a}=await r(),l=await Kt(u,o,a);if(!l.ok){n?.({type:"error",message:"Failed to fetch identity",detail:`Server responded with ${l.status}: ${l.error}`}),await xe(!0);return}n?.({type:"success",email:l.email,name:l.name,tenant:l.tenant,tenantName:l.tenantName,workspace:l.workspace,env:l.env,envAccessible:l.envAccessible,accessibleEnvs:l.accessibleEnvs,roles:l.roles}),await xe(!1,{env:l.env,workspace:l.workspace});}catch(o){n?.({type:"error",message:"Unexpected error",detail:o.message}),await xe(!0);}});}function tr(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}function Ge(e){return e.workspace_slugs?.[e.environment]??e.workspace_slug??null}function Ht(e$1){e$1.command("switch [tenant-slug]").description("Switch the active tenant context").action(async t=>{try{let n=new a$3,r;try{r=await n.read({exitOnError:!1});}catch(l){if(l.message==="Active context key not found"){let c=X.join(ut.homedir(),".culvii","config"),w=await ne.readFile(c,"utf-8");r=JSON.parse(w);}else if(l.code==="ENOENT"){console.error("No configuration found. Please run `culvii login` first.");let{userId:c,tenantId:w}=await d();c?await f(a$2.TENANT_SWITCH_FAILED,c,w,{error_class:"ENOENT",slug:t}):await e(a$2.TENANT_SWITCH_FAILED,{error_class:"ENOENT",slug:t}),await j$1(),process.exit(1);}else throw l}if(!r||!r.contexts){console.error("No configuration found. Please run `culvii login` first.");let{userId:l,tenantId:c}=await d();l?await f(a$2.TENANT_SWITCH_FAILED,l,c,{error_class:"NoConfig",slug:t}):await e(a$2.TENANT_SWITCH_FAILED,{error_class:"NoConfig",slug:t}),await j$1(),process.exit(1);}let i=r.contexts,s=Object.keys(i);if(s.length===0){console.error("No tenants available. Please run `culvii login` first.");let{userId:l,tenantId:c}=await d();l?await f(a$2.TENANT_SWITCH_FAILED,l,c,{error_class:"NoTenants",slug:t}):await e(a$2.TENANT_SWITCH_FAILED,{error_class:"NoTenants",slug:t}),await j$1(),process.exit(1);}if(tr()){let{SwitchView:l}=await import('./SwitchView-PS3ICKZT.js');if(s.length===1&&!t&&(await V(Promise.resolve(ge.createElement(l,{state:{type:"only_one",slug:s[0]}}))),process.exit(0)),!t){let y=s.map(k=>({slug:k,tenantId:i[k].tenant_id,workspaceSlug:Ge(i[k]),environment:i[k].environment,isActive:k===r.active}));await V(Promise.resolve(ge.createElement(l,{state:{type:"list",tenants:y}}))),process.exit(0);}if(!i[t]){let y=s.map(v=>({slug:v,tenantId:i[v].tenant_id,workspaceSlug:Ge(i[v]),environment:i[v].environment,isActive:v===r.active}));await V(Promise.resolve(ge.createElement(l,{state:{type:"error",message:`Tenant '${t}' not found.`}})));let{userId:k,tenantId:A}=await d();k?await f(a$2.TENANT_SWITCH_FAILED,k,A,{error_class:"TenantNotFound",slug:t}):await e(a$2.TENANT_SWITCH_FAILED,{error_class:"TenantNotFound",slug:t}),await j$1(),process.exit(1);}await n.withLock(async()=>{let y=X.join(ut.homedir(),".culvii","config"),k=await ne.readFile(y,"utf-8"),A=JSON.parse(k);await n.write({...A,active:t});});let c$1=i[t];await V(Promise.resolve(ge.createElement(l,{state:{type:"success",slug:t,workspaceSlug:Ge(c$1),environment:c$1.environment}}))),c();let{userId:w,tenantId:p}=await d();w?await f(a$2.TENANT_SWITCHED,w,p,{to:t}):await e(a$2.TENANT_SWITCHED,{to:t}),await j$1();return}if(s.length===1&&!t&&(console.log(`Only one tenant available: ${s[0]}`),process.exit(0)),t||(console.log("Available tenants:"),s.forEach((l,c)=>{let w=i[l],p=l===r.active?"*":" ";console.log(`${c+1}. ${p} ${l} (Tenant ID: ${w.tenant_id})`);}),console.log(`
11
+ To switch, run: culvii switch <tenant-slug>`),process.exit(0)),!i[t]){console.error(`Error: Tenant '${t}' not found.`),console.log(`
12
+ Available tenants:`),s.forEach((w,p)=>{let y=i[w],k=w===r.active?"*":" ";console.log(`${p+1}. ${k} ${w} (Tenant ID: ${y.tenant_id})`);});let{userId:l,tenantId:c}=await d();l?await f(a$2.TENANT_SWITCH_FAILED,l,c,{error_class:"TenantNotFound",slug:t}):await e(a$2.TENANT_SWITCH_FAILED,{error_class:"TenantNotFound",slug:t}),await j$1(),process.exit(1);}await n.withLock(async()=>{let l=X.join(ut.homedir(),".culvii","config"),c=await ne.readFile(l,"utf-8"),w=JSON.parse(c);await n.write({...w,active:t});});let u=i[t];console.log(`tenant: ${t} | workspace: ${Ge(u)||"none"} | env: ${u.environment}`),console.log(`Switched to tenant: ${t}`),c();let{userId:o,tenantId:a}=await d();o?await f(a$2.TENANT_SWITCHED,o,a,{to:t}):await e(a$2.TENANT_SWITCHED,{to:t}),await j$1();}catch(n){n.code==="ENOENT"?console.error("No configuration found. Please run `culvii login` first."):console.error(`Failed to switch context: ${n.message}`);let{userId:r,tenantId:i}=await d();r?await f(a$2.TENANT_SWITCH_FAILED,r,i,{error_class:n.code||n.constructor?.name||"UnknownError",slug:t}):await e(a$2.TENANT_SWITCH_FAILED,{error_class:n.code||n.constructor?.name||"UnknownError",slug:t}),await j$1(),process.exit(1);}});}var Bt=["dev","sandbox","prod"];function or(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}async function Je(e){if(!or())return false;let{EnvView:t}=await import('./EnvView-MCZC2NBO.js');return await V(Promise.resolve(ge.createElement(t,{state:e}))),true}async function ir(e,t,n){let r=await j(`${t}/auth/me`,e,{skipEnvironmentHeader:true});if(!r.ok)return [];let i=await r.json(),s=i?.tenant||{};return ((Array.isArray(i?.tenants)?i.tenants.find(o=>o.id===(n??s?.id)):void 0)?.environments??[]).map(o=>l(o.slug)).filter(o=>o!==null)}function qt(e$1){e$1.command("env [environment]").description("Show or switch the active environment (dev, sandbox, prod)").action(async t=>{await B(async n=>{let{apiUrl:r$1,context:i}=await r(),s=await ir(n,r$1,i.tenant_id);if(!t){if(await Je({type:"show",current:i.environment,tenant:i.tenant_slug,accessible:s}))return;let w=s.includes(i.environment)?"":" (no access)";process.stdout.write(`current: ${i.environment}${w}
13
+ `),process.stdout.write(`tenant: ${i.tenant_slug}
14
+ `),process.stdout.write(`available: ${s.length?s.join(", "):"none"}
15
+ `),!s.includes(i.environment)&&s.length>0&&process.stdout.write(`
16
+ Switch with: culvii env ${s[0]}
17
+ `);return}let u=t.toLowerCase();if(!Bt.includes(u)){let w=`Invalid environment '${t}'.`,p=`Valid values: ${Bt.join(", ")}.`;if(await e(a$2.ENV_SWITCH_FAILED,{error_class:"InvalidEnv",env:t}),await j$1(),await Je({type:"error",message:w,detail:p})){process.exitCode=1;return}process.stderr.write(`${w} ${p}
18
+ `),process.exit(1);}let o=u;if(s.length&&!s.includes(o)){let w=`You don't have access to '${o}' in this tenant.`,p=`Accessible: ${s.join(", ")}.`;if(await e(a$2.ENV_SWITCH_FAILED,{error_class:"NoAccess",env:o}),await j$1(),await Je({type:"error",message:w,detail:p})){process.exitCode=1;return}process.stderr.write(`${w} ${p}
19
+ `),process.exit(1);}let a=new a$3;await a.withLock(async()=>{let w=X.join(ut.homedir(),".culvii","config"),p=await ne.readFile(w,"utf-8"),y=JSON.parse(p),k=y.contexts[y.active];k&&(k.environment=o,k.environment_id=k.environment_ids?.[o]??k.environment_id),await a.write(y);}),await Je({type:"success",env:o,tenant:i.tenant_slug})||(process.stdout.write(`env: ${o} | tenant: ${i.tenant_slug}
20
+ `),process.stdout.write(`Switched environment to ${o}
21
+ `)),c();let{userId:l,tenantId:c$1}=await d();l?await f(a$2.ENV_SWITCHED,l,c$1,{to:o}):await e(a$2.ENV_SWITCHED,{to:o}),await j$1();});});}var pt=`---
22
+ name: culvii
23
+ description: Use this skill when the user wants to write, test, or deploy Culvii agents or workflows using the @culvii/kit SDK and CLI.
24
+ ---
25
+
26
+ # Culvii SDK & CLI Guide
27
+
28
+ Culvii is a platform for authoring, running, and observing AI agents and workflows. You define agents and workflows in TypeScript using \`@culvii/kit\`, then use the \`culvii\` CLI to sync and deploy them to the cloud.
29
+
30
+ ---
31
+
32
+ ## File Structure
33
+
34
+ Every \`.culvii.ts\` file must follow this exact pattern:
35
+
36
+ 1. Import from \`@culvii/kit\`
37
+ 2. Declare \`MODEL_CREDENTIAL_ID\` and \`MODEL\` as top-level constants
38
+ 3. Define each resource inside a \`function createXxx()\` wrapper
39
+ 4. Call every function at the bottom of the file (bare call, no export)
40
+
41
+ \`\`\`typescript
42
+ import { MultiAgentEngine, Workflow, Step, createAgentModelConfigFromRef } from '@culvii/kit';
43
+
44
+ const MODEL_CREDENTIAL_ID = 'YOUR_CREDENTIAL_ID';
45
+ const MODEL = createAgentModelConfigFromRef('YOUR_PROVIDER/YOUR_MODEL_ID', MODEL_CREDENTIAL_ID);
46
+
47
+ function createMyAgent() {
48
+ return new MultiAgentEngine({ ... });
49
+ }
50
+
51
+ function createMyWorkflow() {
52
+ // ...
53
+ return new Workflow({ ... });
54
+ }
55
+
56
+ createMyAgent();
57
+ createMyWorkflow();
58
+ \`\`\`
59
+
60
+ **Valid providers:** \`openai\`, \`anthropic\`, \`gemini\`, \`google-vertex\`, \`vertexai\`
61
+
62
+ **Never use raw API keys.** \`MODEL_CREDENTIAL_ID\` is a UUID from the Culvii console that points to a stored credential \u2014 never a raw API key string.
63
+
64
+ ---
65
+
66
+ ## Defining Agents
67
+
68
+ Use \`MultiAgentEngine\` from \`@culvii/kit\`.
69
+
70
+ **Required fields:**
71
+ - \`id\` \u2014 unique slug, kebab-case, matches what workflow \`core.agent\` steps reference via \`agentReferenceKey\`
72
+ - \`name\` \u2014 display name
73
+ - \`role\` \u2014 \`'primary'\` for standalone/root agents, \`'secondary'\` for agents defined inline inside \`secondaryAgents\`
74
+ - \`description\` \u2014 what the agent does (always include this)
75
+ - \`systemPrompt\` \u2014 the agent's instructions
76
+ - \`model\` \u2014 use the top-level \`MODEL\` constant
77
+ - \`secondaryAgents\` \u2014 always include, set to \`[]\` if none
78
+
79
+ **Optional fields:**
80
+ - \`goal\` (string) \u2014 agent's objective
81
+ - \`backstory\` (string) \u2014 agent background context
82
+ - \`maxIterations\` (number) \u2014 max LLM turns per execution
83
+ - \`temperature\` (number) \u2014 LLM temperature
84
+ - \`permissions\` (Record<string, boolean>) \u2014 grants access to built-in platform tools (e.g. \`{ '*': true }\`)
85
+ - \`allowedTools\` (boolean | string[]) \u2014 controls which built-in tools the agent can use
86
+ - \`delegationGuidance\` (string, primary agents only) \u2014 instructions for how the primary agent should delegate to secondaries
87
+ - \`mcp\` (any) \u2014 MCP server configuration
88
+ - \`metadata\` (Record<string, unknown>) \u2014 arbitrary metadata
89
+
90
+ **Omit \`tools\` entirely when the agent has no tools.** Never write \`tools: {}\`.
91
+
92
+ **Minimal agent (no tools, no secondaries):**
93
+ \`\`\`typescript
94
+ function createReviewAgent() {
95
+ return new MultiAgentEngine({
96
+ id: 'review-agent',
97
+ name: 'Review Agent',
98
+ role: 'primary',
99
+ description: 'Reviews workflow context and returns a recommendation.',
100
+ systemPrompt: 'Review the context and return a final recommendation.',
101
+ model: MODEL,
102
+ secondaryAgents: [],
103
+ });
104
+ }
105
+ \`\`\`
106
+
107
+ **Agent with secondary agents:**
108
+ \`\`\`typescript
109
+ function createSupportAgent() {
110
+ return new MultiAgentEngine({
111
+ id: 'support-agent',
112
+ name: 'Support Agent',
113
+ role: 'primary',
114
+ description: 'Primary support agent that delegates to specialist secondary agents.',
115
+ systemPrompt: 'Triage the request, delegate to specialists, then answer concisely.',
116
+ model: MODEL,
117
+ secondaryAgents: [
118
+ // role: 'secondary' is inferred automatically when defined inline here.
119
+ // If defining a secondary agent as a standalone variable outside the constructor,
120
+ // use \`role: 'secondary' as const\` to prevent TypeScript from widening to string.
121
+ {
122
+ id: 'research-agent',
123
+ name: 'Research Agent',
124
+ role: 'secondary',
125
+ description: 'Gathers supporting evidence.',
126
+ systemPrompt: 'You are the research specialist. Gather the requested evidence and return it directly.',
127
+ model: MODEL,
128
+ },
129
+ {
130
+ id: 'reviewer-agent',
131
+ name: 'Reviewer Agent',
132
+ role: 'secondary',
133
+ description: 'Reviews draft responses before they are returned.',
134
+ systemPrompt: 'You are the review specialist. Check drafts for completeness and flag gaps.',
135
+ model: MODEL,
136
+ },
137
+ ],
138
+ });
139
+ }
140
+ \`\`\`
141
+
142
+ **Agent with workflow tools:**
143
+ \`\`\`typescript
144
+ function createPlannerAgent() {
145
+ return new MultiAgentEngine({
146
+ id: 'planner-agent',
147
+ name: 'Planner Agent',
148
+ role: 'primary',
149
+ description: 'Planner agent that invokes a summary workflow as a tool.',
150
+ systemPrompt: 'Use the summarize_context tool to prepare context, then return a concise plan.',
151
+ model: MODEL,
152
+ tools: {
153
+ summarize_context: defineWorkflowTool({
154
+ name: 'summarize_context',
155
+ description: 'Runs the summary workflow to prepare context.',
156
+ workflowId: 'summary-workflow',
157
+ inputSchema: {
158
+ type: 'object',
159
+ properties: {
160
+ account: { type: 'string' },
161
+ },
162
+ additionalProperties: false,
163
+ },
164
+ }),
165
+ },
166
+ secondaryAgents: [],
167
+ });
168
+ }
169
+ \`\`\`
170
+
171
+ ---
172
+
173
+ ## Defining Workflows
174
+
175
+ Use \`Workflow\` and \`Step\` from \`@culvii/kit\`.
176
+
177
+ **Workflow fields:**
178
+ - \`id\` (string, required) \u2014 unique slug
179
+ - \`name\` (string, required) \u2014 display name
180
+ - \`steps\` (Array<Step>, required) \u2014 array of connected steps
181
+ - \`active\` (boolean, optional, default \`true\`) \u2014 whether the workflow is active. Inactive workflows are not triggered.
182
+
183
+ **Rules:**
184
+ - Every \`Step\` must have an explicit \`id\` in kebab-case
185
+ - All steps must be connected with \`step.connectTo(nextStep)\` before being passed to \`Workflow\`
186
+ - All steps must be listed in the \`steps\` array in connection order
187
+ - \`core.agent\` steps must always include \`agentReferenceKey\`, \`prompt\`, and \`autoCloseSession\`
188
+ - Use \`agentReferenceKey\` \u2014 never \`agentId\` (TypeScript won't catch this mistake)
189
+ - Steps and Workflows do not have a \`description\` field \u2014 omit it entirely. Description is only valid on agents (\`MultiAgentEngine\`).
190
+ - Integration steps (\`slack\`, \`gmail\`, \`googleCalendar\`, etc.) require a \`credentials\` field: \`credentials: { name: 'My Credential', id: 'credential-uuid' }\`
191
+ - \`disabled\` (boolean, optional) \u2014 set \`true\` to skip this step during execution without removing it
192
+ - \`onError\` (\`'continueErrorOutput' | 'continueRegularOutput' | 'stopWorkflow'\`, optional) \u2014 controls execution behaviour when this step throws
193
+
194
+ **Step types:**
195
+ - \`manualTrigger\` \u2014 starts the workflow manually
196
+ - \`cronTrigger\` \u2014 starts the workflow on a schedule (\`params: { pollIntervalMs: 10000 }\` or \`params: { cronExpression: '0 9 * * *' }\`)
197
+ - \`core.set\` \u2014 sets values, optionally pauses for human review (\`params: { values: {...}, pauseAfterExecution: true }\`)
198
+ - \`core.agent\` \u2014 invokes an agent node
199
+ - \`outputFormat\` (optional) \u2014 JSON schema defining expected output shape. Defaults to \`{ status: string, response: string }\`. If the LLM output does not match, the platform falls back to \`{ status: 'completed', response: <raw output> }\`.
200
+ \`\`\`typescript
201
+ const agentStep = new Step({
202
+ id: 'structured-agent-node',
203
+ name: 'Structured Agent',
204
+ type: 'core.agent',
205
+ params: {
206
+ agentReferenceKey: 'my-agent',
207
+ prompt: 'Process the request.',
208
+ autoCloseSession: true,
209
+ outputFormat: {
210
+ type: 'object',
211
+ properties: {
212
+ status: { type: 'string' },
213
+ response: { type: 'string' },
214
+ summary: { type: 'string' },
215
+ },
216
+ required: ['status', 'response'],
217
+ },
218
+ },
219
+ });
220
+ \`\`\`
221
+ - \`core.if\` \u2014 conditional branching. Routes to true (output 0) or false (output 1) branch. Params: \`conditions\` (array of \`{ value1, operation, value2 }\` objects), \`combineOperation\` (\`'all'\` | \`'any'\`). Operations include: \`equal\`, \`notEqual\`, \`contains\`, \`startsWith\`, \`endsWith\`, \`larger\`, \`smaller\`, \`isEmpty\`, \`regex\`.
222
+ - \`core.http\` \u2014 make HTTP requests. Params: \`method\` (GET/POST/PUT/PATCH/DELETE), \`url\`, \`authentication\` (\`'none'\` | \`'bearerToken'\` | \`'basicAuth'\`), \`bearerToken\`, \`username\`, \`password\`, \`queryParameters\` (object), \`headers\` (object), \`bodyContentType\` (\`'json'\` | \`'form'\` | \`'form-urlencoded'\` | \`'raw'\`), \`body\`, \`responseFormat\` (\`'json'\` | \`'text'\` | \`'autodetect'\`), \`options\` (\`{ timeout, followRedirects, ignoreSSL }\`). Output: \`{ statusCode, statusMessage, headers, body }\`.
223
+ - \`core.code\` \u2014 run arbitrary JavaScript
224
+ - \`core.jwt\` \u2014 JWT operations
225
+ - \`waitTimer\` \u2014 pause execution for a duration
226
+ - \`webhookTrigger\` \u2014 trigger workflow via incoming HTTP webhook. Params: \`method\` (default \`'POST'\`). Output includes \`body\`, \`headers\`, \`query\`, \`params\`. Cannot be used as a workflow tool target.
227
+ - \`slack\`, \`gmail\`, \`googleCalendar\`, \`googleDocs\`, \`microsoftOutlook\`, \`microsoftSharepoint\`, \`s3\` \u2014 integration nodes. Require a \`credentials\` field on the Step: \`credentials: { name: 'My Credential', id: 'credential-uuid' }\`.
228
+ - \`core.browserAutomation\` \u2014 browser automation node
229
+ - \`gmailTrigger\` \u2014 trigger workflow when a Gmail email is received. Requires \`credentials\`.
230
+ - \`microsoftOutlookTrigger\` \u2014 trigger workflow when an Outlook email is received. Requires \`credentials\`.
231
+ - \`slackTrigger\` \u2014 trigger workflow when a Slack event occurs. Requires \`credentials\`.
232
+
233
+ **Workflow triggered manually, invoking an agent:**
234
+ \`\`\`typescript
235
+ function createGreetingWorkflow() {
236
+ const trigger = new Step({
237
+ id: 'manual-trigger',
238
+ name: 'Manual Trigger',
239
+ type: 'manualTrigger',
240
+ });
241
+
242
+ const collect = new Step({
243
+ id: 'collect-input',
244
+ name: 'Collect Input',
245
+ type: 'core.set',
246
+ params: {
247
+ values: {
248
+ customer: 'Acme Corp',
249
+ request: 'Generate a greeting.',
250
+ },
251
+ },
252
+ });
253
+
254
+ const agentStep = new Step({
255
+ id: 'greeter-agent-node',
256
+ name: 'Greeter Agent',
257
+ type: 'core.agent',
258
+ params: {
259
+ agentReferenceKey: 'greeter-agent',
260
+ prompt: "Greet {{ $('Collect Input').json.customer }}.",
261
+ autoCloseSession: true,
262
+ },
263
+ });
264
+
265
+ const persist = new Step({
266
+ id: 'persist-response',
267
+ name: 'Persist Response',
268
+ type: 'core.set',
269
+ params: {
270
+ values: {
271
+ response: "={{ $('Greeter Agent').json.response }}",
272
+ },
273
+ },
274
+ });
275
+
276
+ trigger.connectTo(collect);
277
+ collect.connectTo(agentStep);
278
+ agentStep.connectTo(persist);
279
+
280
+ return new Workflow({
281
+ id: 'greeting-workflow',
282
+ name: 'Greeting Workflow',
283
+ steps: [trigger, collect, agentStep, persist],
284
+ });
285
+ }
286
+ \`\`\`
287
+
288
+ **Scheduled workflow (cron trigger):**
289
+ \`\`\`typescript
290
+ function createScheduledWorkflow() {
291
+ const trigger = new Step({
292
+ id: 'cron-trigger',
293
+ name: 'Cron Trigger',
294
+ type: 'cronTrigger',
295
+ params: {
296
+ pollIntervalMs: 10_000,
297
+ },
298
+ });
299
+
300
+ const agentStep = new Step({
301
+ id: 'digest-agent-node',
302
+ name: 'Digest Agent',
303
+ type: 'core.agent',
304
+ params: {
305
+ agentReferenceKey: 'digest-agent',
306
+ prompt: 'Produce the daily digest.',
307
+ autoCloseSession: true,
308
+ },
309
+ });
310
+
311
+ trigger.connectTo(agentStep);
312
+
313
+ return new Workflow({
314
+ id: 'scheduled-workflow',
315
+ name: 'Scheduled Workflow',
316
+ steps: [trigger, agentStep],
317
+ });
318
+ }
319
+ \`\`\`
320
+
321
+ **Workflow used as a tool (invoked by an agent via \`defineWorkflowTool\`):**
322
+
323
+ The workflow must have exactly one \`manualTrigger\` step and must NOT contain a \`core.agent\` step.
324
+
325
+ \`\`\`typescript
326
+ function createSummaryWorkflow() {
327
+ const trigger = new Step({
328
+ id: 'manual-trigger',
329
+ name: 'Manual Trigger',
330
+ type: 'manualTrigger',
331
+ });
332
+
333
+ const summarize = new Step({
334
+ id: 'summarize-context',
335
+ name: 'Summarize Context',
336
+ type: 'core.set',
337
+ params: {
338
+ values: {
339
+ status: 'ready',
340
+ summary: 'Context prepared.',
341
+ },
342
+ },
343
+ });
344
+
345
+ trigger.connectTo(summarize);
346
+
347
+ return new Workflow({
348
+ id: 'summary-workflow',
349
+ name: 'Summary Workflow',
350
+ steps: [trigger, summarize],
351
+ });
352
+ }
353
+ \`\`\`
354
+
355
+ **Human-in-the-loop (HITL) pause:**
356
+
357
+ Add \`pauseAfterExecution: true\` to any step's \`params\` to pause execution and wait for a human decision before continuing. This works on all step types, not just \`core.set\`.
358
+
359
+ \`\`\`typescript
360
+ const approvalStep = new Step({
361
+ id: 'approval-gate',
362
+ name: 'Approval Gate',
363
+ type: 'core.set',
364
+ params: {
365
+ values: {
366
+ stage: 'awaiting-approval',
367
+ note: 'Please review before continuing.',
368
+ },
369
+ pauseAfterExecution: true,
370
+ },
371
+ });
372
+ \`\`\`
373
+
374
+ ---
375
+
376
+ ## Defining Workflow Tools
377
+
378
+ Use \`defineWorkflowTool\` from \`@culvii/kit\` inside an agent's \`tools\` object.
379
+
380
+ \`\`\`typescript
381
+ import { defineWorkflowTool } from '@culvii/kit';
382
+
383
+ tools: {
384
+ run_search: defineWorkflowTool({
385
+ name: 'run_search',
386
+ description: 'Runs the search workflow to find relevant information.',
387
+ workflowId: 'search-workflow', // must match the \`id\` of the target Workflow
388
+ inputSchema: {
389
+ type: 'object',
390
+ properties: {
391
+ query: { type: 'string' },
392
+ },
393
+ additionalProperties: false,
394
+ },
395
+ }),
396
+ }
397
+ \`\`\`
398
+
399
+ \`workflowId\` must exactly match the \`id\` field of the \`Workflow\` being targeted. The target workflow must have exactly one \`manualTrigger\` step. If it has multiple manual triggers, add \`triggerNodeName\` matching the target trigger's \`name\` field.
400
+
401
+ ---
402
+
403
+ ## Referencing Step Output
404
+
405
+ Use expressions to reference the output of previous steps. Two formats:
406
+
407
+ **Whole expression** \u2014 preserves value type (object, array, number, boolean):
408
+ \`\`\`typescript
409
+ "={{ $('Step Name').json.fieldName }}"
410
+ \`\`\`
411
+
412
+ **Inline template** \u2014 interpolated into a string:
413
+ \`\`\`typescript
414
+ "Handle the ticket for {{ $('Collect Input').json.customer }}."
415
+ \`\`\`
416
+
417
+ **\`.json\` is optional** \u2014 these are equivalent:
418
+ \`\`\`typescript
419
+ "={{ $('Step Name').json.response }}"
420
+ "={{ $('Step Name').response }}"
421
+ \`\`\`
422
+
423
+ **All supported expression formats:**
424
+ - \`$('Node Name').json.field\` \u2014 output of a step by name, default port, index 0
425
+ - \`$('Node Name').field\` \u2014 same, \`.json\` omitted
426
+ - \`$('Node Name')[2].json.field\` \u2014 specific array index
427
+ - \`$('Node Name:portName').json.field\` \u2014 specific output port (e.g. \`main\`, \`ai_tool\`)
428
+ - \`$json.field\` \u2014 current node's input data
429
+ - \`$system.execId\` \u2014 current execution ID
430
+ - \`$system.workflowId\` \u2014 current workflow ID
431
+ - \`$system.node.id\` \u2014 current node ID
432
+
433
+ **Agent step output** always includes at minimum:
434
+ - \`.json.response\` \u2014 the agent's text output
435
+ - \`.json.status\` \u2014 completion status (e.g. \`'completed'\`)
436
+
437
+ Additional fields may be present if \`outputFormat\` was specified on the agent step.
438
+
439
+ **Example:**
440
+ \`\`\`typescript
441
+ const persist = new Step({
442
+ id: 'persist-result',
443
+ name: 'Persist Result',
444
+ type: 'core.set',
445
+ params: {
446
+ values: {
447
+ response: "={{ $('My Agent Step').json.response }}",
448
+ status: "={{ $('My Agent Step').json.status }}",
449
+ execId: "={{ $system.execId }}",
450
+ },
451
+ },
452
+ });
453
+ \`\`\`
454
+
455
+ ---
456
+
457
+ ## Patterns at a Glance
458
+
459
+ **Pattern 1 \u2014 Workflow triggers agent** (workflow orchestrates an agent):
460
+ - Workflow has a trigger step \u2192 optional \`core.set\` steps \u2192 \`core.agent\` step
461
+ - Agent has no \`tools\`, \`secondaryAgents: []\`
462
+
463
+ **Pattern 2 \u2014 Agent invokes workflow as tool** (agent calls a workflow):
464
+ - Agent has \`tools: { myTool: defineWorkflowTool({...}) }\`
465
+ - Target workflow has exactly one \`manualTrigger\`, no \`core.agent\` steps
466
+ - The workflow is NOT the entry point \u2014 the agent is
467
+
468
+ **Pattern 3 \u2014 Secondary agents** (primary delegates to specialists):
469
+ - Agent has \`secondaryAgents: [{ id, name, role: 'secondary', description, systemPrompt, model }]\`
470
+ - Secondary agents are defined inline, not as separate top-level resources
471
+ - Secondary agents inherit all \`AgentBaseConfig\` fields including \`tools\` \u2014 they CAN define workflow tools in most cases
472
+ - Secondary agents must NOT define \`tools\` if the primary is itself invoked by a workflow tool (platform validation blocks this)
473
+ - Secondary agents cannot have their own \`secondaryAgents\` \u2014 nesting is not supported
474
+
475
+ **Pattern 4 \u2014 Scheduled workflow** (cron trigger):
476
+ - Workflow has a \`cronTrigger\` step instead of \`manualTrigger\`
477
+ - Cannot be used as a workflow tool target (tool targets require \`manualTrigger\`)
478
+
479
+ **Pattern 5 \u2014 HITL (human-in-the-loop)**:
480
+ - Any step can pause with \`pauseAfterExecution: true\` \u2014 not just \`core.set\`
481
+ - Can appear in any workflow \u2014 parent or tool-target workflow
482
+
483
+ ---
484
+
485
+ ## Constraints (Validation Rules)
486
+
487
+ These are enforced by \`culvii dev\` and \`culvii deploy\` and will block sync or deployment:
488
+
489
+ 1. **\`agentReferenceKey\` not \`agentId\`** \u2014 \`core.agent\` step params must use \`agentReferenceKey\`. TypeScript will NOT catch this.
490
+
491
+ 2. **Workflow tools require \`manualTrigger\`** \u2014 a workflow used as a tool must have exactly one \`manualTrigger\` step. \`cronTrigger\` or other triggers are invalid targets.
492
+
493
+ 3. **Workflow tool targets must not contain \`core.agent\` steps** \u2014 if agent A calls workflow W as a tool, W must not invoke any agent. The chain A \u2192 W \u2192 agent is forbidden.
494
+
495
+ 4. **Agents invoked via workflow tool cannot define workflow tools that target agent-containing workflows** \u2014 if a workflow node calls agent A, then agent A (and its secondaries) cannot use \`defineWorkflowTool\` to target a workflow that itself contains a \`core.agent\` step. The chain W \u2192 A \u2192 W(with agent) is forbidden.
496
+
497
+ 5. **Max reference depth is 3** \u2014 supported chains are \`workflow \u2192 agent \u2192 workflow\` or \`agent \u2192 workflow \u2192 agent\`. Deeper nesting is rejected.
498
+
499
+ 6. **All \`agentReferenceKey\` values must resolve** \u2014 every \`agentReferenceKey\` in a \`core.agent\` step must match the \`id\` of a defined \`MultiAgentEngine\` in your local files.
500
+
501
+ 7. **All \`workflowId\` values must resolve** \u2014 every \`workflowId\` in a \`defineWorkflowTool\` must match the \`id\` of a defined \`Workflow\` in your local files.
502
+
503
+ 8. **Model config must include a \`credentialId\`** \u2014 \`createAgentModelConfigFromRef\` requires two arguments: the model ref string and the credential ID. Never pass just the model string.
504
+
505
+ ---
506
+
507
+ ## CLI Commands
508
+
509
+ \`\`\`bash
510
+ culvii login # authenticate via browser OAuth
511
+ culvii dev # start file watcher + sync drafts to cloud
512
+ culvii deploy --env sandbox --workspace-slug <slug> # deploy to sandbox
513
+ culvii deploy --env prod --workspace-slug <slug> # deploy to prod
514
+ culvii deploy ... --allow-destroy # allow deletion of removed resources
515
+ culvii init [project-name] # scaffold a new project
516
+ culvii whoami # show current user and context
517
+ culvii switch <tenant-slug> # switch active tenant
518
+ \`\`\`
519
+
520
+ \`culvii dev\` auto-provisions a dev workspace and API key on first run. It watches all \`*.culvii.ts\` files recursively, skipping \`node_modules/\`, \`dist/\`, \`.git/\`. On Ctrl+C it cleans up all draft definitions from the cloud.
521
+
522
+ ---
523
+
524
+ ## Dev Session Lifecycle
525
+
526
+ - **File saved** \u2192 CLI evaluates the file, extracts all \`MultiAgentEngine\` and \`Workflow\` instances registered via \`DevRegistry\`, validates references, and syncs each as a draft to the platform
527
+ - **File deleted / definition removed** \u2192 CLI sends an orphan signal; the platform immediately deactivates any live triggers (webhooks, schedules) for that resource, but keeps its data \u2014 including run history \u2014 until the session ends
528
+ - **Ctrl+C** \u2192 platform deletes all draft definitions and soft-deletes all associated execution records for this session
529
+
530
+ ---
531
+
532
+ ## Complete Example \u2014 All Patterns Combined
533
+
534
+ \`\`\`typescript
535
+ import {
536
+ MultiAgentEngine,
537
+ Step,
538
+ Workflow,
539
+ defineWorkflowTool,
540
+ createAgentModelConfigFromRef,
541
+ } from '@culvii/kit';
542
+
543
+ const MODEL_CREDENTIAL_ID = 'YOUR_CREDENTIAL_ID';
544
+ const MODEL = createAgentModelConfigFromRef('YOUR_PROVIDER/YOUR_MODEL_ID', MODEL_CREDENTIAL_ID);
545
+
546
+ // Tool-target workflow (no agent nodes, one manualTrigger)
547
+ function createLookupWorkflow() {
548
+ const trigger = new Step({
549
+ id: 'manual-trigger',
550
+ name: 'Manual Trigger',
551
+ type: 'manualTrigger',
552
+ });
553
+
554
+ const lookup = new Step({
555
+ id: 'lookup-account',
556
+ name: 'Lookup Account',
557
+ type: 'core.set',
558
+ params: {
559
+ values: { plan: 'Enterprise', seats: '250' },
560
+ },
561
+ });
562
+
563
+ trigger.connectTo(lookup);
564
+
565
+ return new Workflow({
566
+ id: 'lookup-workflow',
567
+ name: 'Lookup Workflow',
568
+ steps: [trigger, lookup],
569
+ });
570
+ }
571
+
572
+ // Primary agent with a workflow tool and a secondary agent
573
+ function createConciergeAgent() {
574
+ return new MultiAgentEngine({
575
+ id: 'concierge-agent',
576
+ name: 'Concierge Agent',
577
+ role: 'primary',
578
+ description: 'Looks up account context and delegates review to a specialist.',
579
+ systemPrompt: 'Call lookup_account first, then delegate detailed review to your specialist.',
580
+ model: MODEL,
581
+ tools: {
582
+ lookup_account: defineWorkflowTool({
583
+ name: 'lookup_account',
584
+ description: 'Fetches account context.',
585
+ workflowId: 'lookup-workflow',
586
+ inputSchema: {
587
+ type: 'object',
588
+ properties: { account: { type: 'string' } },
589
+ additionalProperties: false,
590
+ },
591
+ }),
592
+ },
593
+ secondaryAgents: [
594
+ {
595
+ id: 'specialist-agent',
596
+ name: 'Specialist Agent',
597
+ role: 'secondary',
598
+ description: 'Reviews account context and provides a recommendation.',
599
+ systemPrompt: 'You are a specialist. Review the account data and provide a clear recommendation.',
600
+ model: MODEL,
601
+ },
602
+ ],
603
+ });
604
+ }
605
+
606
+ // Parent workflow: collects input, runs agent, HITL pause, persists
607
+ function createParentWorkflow() {
608
+ const trigger = new Step({
609
+ id: 'manual-trigger',
610
+ name: 'Manual Trigger',
611
+ type: 'manualTrigger',
612
+ });
613
+
614
+ const collect = new Step({
615
+ id: 'collect-ticket',
616
+ name: 'Collect Ticket',
617
+ type: 'core.set',
618
+ params: {
619
+ values: { customer: 'Acme Corp', request: 'Review account before renewal.' },
620
+ },
621
+ });
622
+
623
+ const agentStep = new Step({
624
+ id: 'concierge-agent-node',
625
+ name: 'Concierge Agent',
626
+ type: 'core.agent',
627
+ params: {
628
+ agentReferenceKey: 'concierge-agent',
629
+ prompt: "Handle the renewal request for {{ $('Collect Ticket').json.customer }}.",
630
+ autoCloseSession: true,
631
+ },
632
+ });
633
+
634
+ const review = new Step({
635
+ id: 'manager-review',
636
+ name: 'Manager Review',
637
+ type: 'core.set',
638
+ params: {
639
+ values: { stage: 'awaiting-manager-approval' },
640
+ pauseAfterExecution: true,
641
+ },
642
+ });
643
+
644
+ const persist = new Step({
645
+ id: 'persist-response',
646
+ name: 'Persist Response',
647
+ type: 'core.set',
648
+ params: {
649
+ values: { response: "={{ $('Concierge Agent').json.response }}" },
650
+ },
651
+ });
652
+
653
+ trigger.connectTo(collect);
654
+ collect.connectTo(agentStep);
655
+ agentStep.connectTo(review);
656
+ review.connectTo(persist);
657
+
658
+ return new Workflow({
659
+ id: 'parent-workflow',
660
+ name: 'Parent Workflow',
661
+ steps: [trigger, collect, agentStep, review, persist],
662
+ });
663
+ }
664
+
665
+ createLookupWorkflow();
666
+ createConciergeAgent();
667
+ createParentWorkflow();
668
+ \`\`\`
669
+ `;function lr(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}var Le={claude:{projectDir:".claude/skills/culvii",globalDir:".claude/skills/culvii",detect:".claude"},cursor:{projectDir:".cursor/skills/culvii",globalDir:".cursor/skills/culvii",detect:".cursor"},windsurf:{projectDir:".windsurf/skills/culvii",globalDir:".codeium/windsurf/skills/culvii",detect:".windsurf"},github:{projectDir:".github/skills/culvii",globalDir:".copilot/skills/culvii",detect:".github"},opencode:{projectDir:".opencode/skills/culvii",globalDir:".config/opencode/skills/culvii",detect:".opencode"},gemini:{projectDir:".gemini/skills/culvii",globalDir:".gemini/skills/culvii",detect:".gemini"},kiro:{projectDir:".kiro/skills/culvii",globalDir:".kiro/skills/culvii",detect:".kiro"},agents:{projectDir:".agents/skills/culvii",globalDir:".agents/skills/culvii",detect:".agents"}};function Gt(e){let t=process.cwd(),n=new Set;if(e){let i=e.toLowerCase();if(i==="codex"&&(i="agents"),!Le[i]){let s=[...Object.keys(Le),"codex"].sort();return {error:`Invalid agent: ${e}. Must be one of: ${s.join(", ")}.`}}return n.add(i),{targets:n}}let r=false;for(let[i,s]of Object.entries(Le))i!=="agents"&&Ee.existsSync(X.join(t,s.detect))&&(n.add(i),r=true);return n.add("agents"),r?{targets:n}:(n.add("claude"),{targets:n,fallbackWarning:"No specific agent directories detected. Defaulting to Claude Code and Universal Fallback paths."})}function Jt(e){e.command("skill").description("Manage AI agent skills").command("install").description("Install the culvii SDK & CLI skill for AI agents").option("--agent <agent>","Specify agent (claude|cursor|windsurf|github|opencode|gemini|kiro|codex|agents) to skip auto-detection").option("--global","Install globally to your home directory instead of the current project").action(async n=>{let r=process.cwd(),i=ut.homedir();if(lr()){let w=function(){let[v,D]=ge.useState({type:"loading"});return ge.useEffect(()=>(c.current=D,()=>{c.current=null;}),[]),ge.createElement(l,{state:v})};let{SkillView:l}=await import('./SkillView-N27S3VSV.js'),c={current:null};await V(Promise.resolve(ge.createElement(w)));let p=Gt(n.agent);if("error"in p){c.current?.({type:"error",message:"Invalid agent",detail:p.error});return}let{targets:y,fallbackWarning:k}=p,A=[];for(let v of y){let D=Le[v],$=n.global?i:r,M=n.global?D.globalDir:D.projectDir,S=X.join($,M),R=X.join(S,"SKILL.md");try{Ee.existsSync(S)||Ee.mkdirSync(S,{recursive:!0}),Ee.writeFileSync(R,pt,"utf8");let L=n.global?X.join("~",M,"SKILL.md"):X.join(M,"SKILL.md"),f=v==="agents"?"Universal/Codex":v;A.push({agentName:f,displayPath:L});}catch(L){c.current?.({type:"error",message:`Failed to install skill for ${v}`,detail:L.message});return}}c.current?.({type:"success",installed:A,fallbackWarning:k});return}let s=Gt(n.agent);"error"in s&&(console.error(`${x} ${s.error}`),process.exit(1));let{targets:u,fallbackWarning:o}=s;o&&console.log(`${w} ${o}`);for(let l of u){let c=Le[l],w$1=n.global?i:r,p=n.global?c.globalDir:c.projectDir,y=X.join(w$1,p),k=X.join(y,"SKILL.md");try{Ee.existsSync(y)||Ee.mkdirSync(y,{recursive:!0}),Ee.writeFileSync(k,pt,"utf8");let A=n.global?X.join("~",p,"SKILL.md"):X.join(p,"SKILL.md");console.log(`${w} Installed skill for ${l==="agents"?"Universal/Codex":l} at ${A}`);}catch(A){console.error(`${x} Failed to install skill for ${l}: ${A.message}`),process.exit(1);}}});}function ft({label:e,items:t,defaultIndex:n,onSelect:r}){let i=t.map((u,o)=>({key:String(o+1),label:u.label,description:u.description})),s=n!==void 0?String(n+1):void 0;return jsx(a$5,{label:e,options:i,defaultKey:s,onSubmit:u=>{let o=parseInt(u,10)-1,a=t[o];a&&r(a.value);}})}function gr(){let e=a$1();return e.isTTY&&!e.isCI&&e.supportsColor&&e.supportsUnicode}var ae=["agent-only","agent-workflow","agent-workflow-tool","multi-agent"],oe=["openai","anthropic","gemini","google-vertex"],Xt={"agent-only":"A single standalone AI agent","agent-workflow":"An AI agent triggered by a manual workflow","agent-workflow-tool":"An agent that invokes a workflow as a callable tool","multi-agent":"A coordinator agent that delegates to a specialist agent"},Zt={openai:"openai/YOUR_MODEL_ID",anthropic:"anthropic/YOUR_MODEL_ID",gemini:"gemini/YOUR_MODEL_ID","google-vertex":"google-vertex/YOUR_MODEL_ID"},Qt=`{
670
+ "compilerOptions": {
671
+ "target": "ES2022",
672
+ "module": "NodeNext",
673
+ "moduleResolution": "NodeNext",
674
+ "strict": true,
675
+ "skipLibCheck": true,
676
+ "esModuleInterop": true
677
+ },
678
+ "include": ["src/**/*.ts"]
679
+ }`;function en(e){return JSON.stringify({name:e,version:"0.1.0",type:"commonjs",private:true,scripts:{dev:"culvii dev",deploy:"culvii deploy"},dependencies:{"@culvii/kit":"latest",tsx:"^4.22.3"},engines:{node:">=22.0.0"}},null,2)}function Xe(e){return `// Generated by culvii init \u2014 replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console
680
+ import { MultiAgentEngine, createAgentModelConfigFromRef } from '@culvii/kit';
681
+
682
+ const MODEL_CREDENTIAL_ID = 'YOUR_CREDENTIAL_ID';
683
+ const MODEL = createAgentModelConfigFromRef('${e}', MODEL_CREDENTIAL_ID);
684
+
685
+ function createGreeterAgent() {
686
+ return new MultiAgentEngine({
687
+ id: 'greeter-agent',
688
+ name: 'Greeter Agent',
689
+ role: 'primary',
690
+ description: 'A helpful greeting assistant.',
691
+ systemPrompt: 'You are a helpful greeting assistant. Greet the user warmly based on their input.',
692
+ model: MODEL,
693
+ secondaryAgents: [],
694
+ });
695
+ }
696
+
697
+ createGreeterAgent();
698
+ `}var tn=`// Generated by culvii init \u2014 replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console
699
+ import { Workflow, Step } from '@culvii/kit';
700
+
701
+ function createGreetingWorkflow() {
702
+ const trigger = new Step({
703
+ id: 'manual-trigger',
704
+ name: 'Manual Trigger',
705
+ type: 'manualTrigger',
706
+ });
707
+
708
+ const agentStep = new Step({
709
+ id: 'greeter-agent-node',
710
+ name: 'Greeter Agent',
711
+ type: 'core.agent',
712
+ params: {
713
+ agentReferenceKey: 'greeter-agent',
714
+ prompt: 'Greet the user.',
715
+ autoCloseSession: true,
716
+ },
717
+ });
718
+
719
+ trigger.connectTo(agentStep);
720
+
721
+ return new Workflow({
722
+ id: 'greeting-workflow',
723
+ name: 'Greeting Workflow',
724
+ steps: [trigger, agentStep],
725
+ });
726
+ }
727
+
728
+ createGreetingWorkflow();
729
+ `;function nn(e){return `// Generated by culvii init \u2014 replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console
730
+ import { MultiAgentEngine, createAgentModelConfigFromRef } from '@culvii/kit';
731
+
732
+ const MODEL_CREDENTIAL_ID = 'YOUR_CREDENTIAL_ID';
733
+ const MODEL = createAgentModelConfigFromRef('${e}', MODEL_CREDENTIAL_ID);
734
+
735
+ function createCoordinatorAgent() {
736
+ return new MultiAgentEngine({
737
+ id: 'coordinator-agent',
738
+ name: 'Coordinator Agent',
739
+ role: 'primary',
740
+ description: 'A coordinator that delegates to a specialist agent.',
741
+ systemPrompt: 'You are a coordinator. Analyse the request and delegate to the specialist when domain expertise is needed.',
742
+ model: MODEL,
743
+ secondaryAgents: [
744
+ {
745
+ id: 'specialist-agent',
746
+ name: 'Specialist Agent',
747
+ role: 'secondary' as const,
748
+ description: 'A domain specialist.',
749
+ systemPrompt: 'You are a domain specialist. Provide detailed, expert answers to questions delegated to you.',
750
+ model: MODEL,
751
+ },
752
+ ],
753
+ });
754
+ }
755
+
756
+ createCoordinatorAgent();
757
+ `}function rn(e){return `// Generated by culvii init \u2014 replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console
758
+ import { MultiAgentEngine, createAgentModelConfigFromRef, defineWorkflowTool } from '@culvii/kit';
759
+
760
+ const MODEL_CREDENTIAL_ID = 'YOUR_CREDENTIAL_ID';
761
+ const MODEL = createAgentModelConfigFromRef('${e}', MODEL_CREDENTIAL_ID);
762
+
763
+ function createResearchAgent() {
764
+ return new MultiAgentEngine({
765
+ id: 'research-agent',
766
+ name: 'Research Agent',
767
+ role: 'primary',
768
+ description: 'A research assistant that invokes a workflow as a callable tool.',
769
+ systemPrompt: 'You are a research assistant. Use the run_research_workflow tool to kick off a structured research workflow when the user asks you to research a topic.',
770
+ model: MODEL,
771
+ tools: {
772
+ run_research_workflow: defineWorkflowTool({
773
+ name: 'run_research_workflow',
774
+ description: 'Runs the structured research workflow for a given topic.',
775
+ workflowId: 'research-workflow',
776
+ inputSchema: {
777
+ type: 'object',
778
+ properties: {
779
+ topic: { type: 'string' },
780
+ },
781
+ additionalProperties: false,
782
+ },
783
+ }),
784
+ },
785
+ secondaryAgents: [],
786
+ });
787
+ }
788
+
789
+ createResearchAgent();
790
+ `}var sn=`// Generated by culvii init \u2014 replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console
791
+ import { Workflow, Step } from '@culvii/kit';
792
+
793
+ function createResearchWorkflow() {
794
+ const trigger = new Step({
795
+ id: 'manual-trigger',
796
+ name: 'Manual Trigger',
797
+ type: 'manualTrigger',
798
+ });
799
+
800
+ return new Workflow({
801
+ id: 'research-workflow',
802
+ name: 'Research Workflow',
803
+ steps: [trigger],
804
+ });
805
+ }
806
+
807
+ createResearchWorkflow();
808
+ `;function an(){return `// Generated by culvii init \u2014 replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console
809
+ import { Workflow, Step } from '@culvii/kit';
810
+
811
+ function createCoordinationWorkflow() {
812
+ const trigger = new Step({
813
+ id: 'manual-trigger',
814
+ name: 'Manual Trigger',
815
+ type: 'manualTrigger',
816
+ });
817
+
818
+ const coordinatorStep = new Step({
819
+ id: 'coordinator-agent-node',
820
+ name: 'Coordinator Agent',
821
+ type: 'core.agent',
822
+ params: {
823
+ agentReferenceKey: 'coordinator-agent',
824
+ prompt: 'Handle the request using your specialist agent as needed.',
825
+ autoCloseSession: true,
826
+ },
827
+ });
828
+
829
+ trigger.connectTo(coordinatorStep);
830
+
831
+ return new Workflow({
832
+ id: 'coordination-workflow',
833
+ name: 'Coordination Workflow',
834
+ steps: [trigger, coordinatorStep],
835
+ });
836
+ }
837
+
838
+ createCoordinationWorkflow();
839
+ `}async function gt(e,t){return (await e.question(t)).trim()}async function yr(e$1,t){let{userId:n,tenantId:r}=await d(),i=async(p,y={})=>{n?await f(p,n,r,y):await e(p,y);};await i(a$2.INIT_STARTED);let s=e$1,u=t.template,o=t.provider;if(u&&!ae.includes(u)&&(console.error(`${x} Invalid template '${u}'. Valid options: ${ae.join(", ")}`),await i(a$2.INIT_FAILED,{error_class:"InvalidTemplate"}),await j$1(),process.exit(1)),o&&!oe.includes(o)&&(console.error(`${x} Invalid provider '${o}'. Valid options: ${oe.join(", ")}`),await i(a$2.INIT_FAILED,{error_class:"InvalidProvider"}),await j$1(),process.exit(1)),!t.yes&&process.stdout.isTTY&&process.stdin.isTTY){let{render:p}=await import('ink');if(!s&&!t.here&&(s=await new Promise(y=>{let{unmount:k}=p(ge.createElement(a$5,{label:"Project name [Enter = my-culvii-project]",defaultValue:"my-culvii-project",onSubmit:A=>{k(),y(A||"my-culvii-project");}}));})),!u){let y=ae.indexOf("agent-workflow");u=await new Promise(k=>{let{unmount:A}=p(ge.createElement(ft,{label:"Select a template [Enter = agent-workflow]",items:ae.map(v=>({value:v,label:v.padEnd(16),description:Xt[v]})),defaultIndex:y,onSelect:v=>{A(),k(v);}}));});}if(!o){let y=oe.indexOf("openai");o=await new Promise(k=>{let{unmount:A}=p(ge.createElement(ft,{label:"Select a model provider [Enter = openai]",items:oe.map(v=>({value:v,label:v})),defaultIndex:y,onSelect:v=>{A(),k(v);}}));});}}else !s&&!t.here&&(s="my-culvii-project"),u||(u="agent-workflow"),o||(o="openai");let{InitView:l}=await import('./InitView-TI2HU6VV.js'),c={update:null};function w(){let[p,y]=ge.useState({type:"scaffolding",message:"Scaffolding project\u2026"});return ge.useEffect(()=>(c.update=y,()=>{c.update=null;}),[]),ge.createElement(l,{state:p})}await V(Promise.resolve(ge.createElement(w)));try{let p=t.here?process.cwd():X.join(process.cwd(),s);if(existsSync(p)){if((await ne.readdir(p)).filter(S=>!S.startsWith(".")).length>0){c.update?.({type:"error",message:`Directory '${X.relative(process.cwd(),p)||"."}' already exists and is not empty.`}),await i(a$2.INIT_FAILED,{error_class:"DirectoryNotEmpty"}),await j$1();return}}else await ne.mkdir(p,{recursive:!0});let y=X.join(p,"src");await ne.mkdir(y,{recursive:!0});let k=Zt[o],A=[];await ne.writeFile(X.join(p,"package.json"),en(t.here?X.basename(p):s),"utf-8"),await ne.writeFile(X.join(p,"tsconfig.json"),Qt,"utf-8"),A.push("package.json"),A.push("tsconfig.json");let v=async($,M)=>{await ne.writeFile(X.join(y,$),M,"utf-8"),A.push(X.join("src",$));};u==="agent-only"?await v("greeter-agent.culvii.ts",Xe(k)):u==="agent-workflow"?(await v("greeter-agent.culvii.ts",Xe(k)),await v("greeting-workflow.culvii.ts",tn)):u==="agent-workflow-tool"?(await v("research-agent.culvii.ts",rn(k)),await v("research-workflow.culvii.ts",sn)):u==="multi-agent"&&(await v("coordinator-agent.culvii.ts",nn(k)),await v("coordination-workflow.culvii.ts",an()));let D=t.here?".":`./${s}`;c.update?.({type:"success",template:u,projectDir:D,written:A,here:!!t.here,projectName:s}),await i(a$2.INIT_SUCCEEDED,{template:u,provider:o}),await j$1();}catch(p){c.update?.({type:"error",message:`Initialization failed: ${p.message}`}),await i(a$2.INIT_FAILED,{error_class:p?.constructor?.name??"UnknownError"}),await j$1();return}}function on(e$1){e$1.command("init [project-name]").description("Scaffold a new Culvii project with working agent and workflow files").option("--template <template>",`Template: ${ae.join(" | ")}`).option("--provider <provider>",`Model provider: ${oe.join(" | ")}`).option("--here","Scaffold into the current directory instead of a named subdirectory").option("-y, --yes","Accept all defaults non-interactively").action(async(t,n)=>{if(gr()){await yr(t,n);return}let{userId:r,tenantId:i}=await d(),s=async(l,c={})=>{r?await f(l,r,i,c):await e(l,c);};await s(a$2.INIT_STARTED);let u=t,o=n.template,a=n.provider;o&&!ae.includes(o)&&(console.error(`${x} Invalid template '${o}'. Valid options: ${ae.join(", ")}`),await s(a$2.INIT_FAILED,{error_class:"InvalidTemplate"}),await j$1(),process.exit(1)),a&&!oe.includes(a)&&(console.error(`${x} Invalid provider '${a}'. Valid options: ${oe.join(", ")}`),await s(a$2.INIT_FAILED,{error_class:"InvalidProvider"}),await j$1(),process.exit(1));try{if(!n.yes&&process.stdout.isTTY&&process.stdin.isTTY){let A=createInterface({input:stdin,output:stdout});try{if(!u&&!n.here&&(u=await gt(A,"Project name (my-culvii-project): ")||"my-culvii-project"),!o)for(console.log(`
840
+ Select a template:`),ae.forEach((v,D)=>{console.log(` ${D+1}) ${v.padEnd(16)} ${Xt[v]}`);});!o;){let v=await gt(A,"Template [1-4] (2): "),D=v?parseInt(v,10)-1:1;D>=0&&D<ae.length?o=ae[D]:console.log(` Please enter a number between 1 and ${ae.length}.`);}if(!a)for(console.log(`
841
+ Select a model provider:`),oe.forEach((v,D)=>{console.log(` ${D+1}) ${v}`);});!a;){let v=await gt(A,"Provider [1-4] (1): "),D=v?parseInt(v,10)-1:0;D>=0&&D<oe.length?a=oe[D]:console.log(` Please enter a number between 1 and ${oe.length}.`);}}finally{A.close();}}else !u&&!n.here&&(u="my-culvii-project"),o||(o="agent-workflow"),a||(a="openai");let c=n.here?process.cwd():X.join(process.cwd(),u);existsSync(c)?(await ne.readdir(c)).filter(D=>!D.startsWith(".")).length>0&&(console.error(`${x} Directory '${X.relative(process.cwd(),c)||"."}' already exists and is not empty.`),await s(a$2.INIT_FAILED,{error_class:"DirectoryNotEmpty"}),await j$1(),process.exit(1)):await ne.mkdir(c,{recursive:!0});let w$1=X.join(c,"src");await ne.mkdir(w$1,{recursive:!0});let p=Zt[a],y=[];await ne.writeFile(X.join(c,"package.json"),en(n.here?X.basename(c):u),"utf-8"),await ne.writeFile(X.join(c,"tsconfig.json"),Qt,"utf-8"),y.push("package.json"),y.push("tsconfig.json");let k=async(A,v)=>{await ne.writeFile(X.join(w$1,A),v,"utf-8"),y.push(X.join("src",A));};o==="agent-only"?await k("greeter-agent.culvii.ts",Xe(p)):o==="agent-workflow"?(await k("greeter-agent.culvii.ts",Xe(p)),await k("greeting-workflow.culvii.ts",tn)):o==="agent-workflow-tool"?(await k("research-agent.culvii.ts",rn(p)),await k("research-workflow.culvii.ts",sn)):o==="multi-agent"&&(await k("coordinator-agent.culvii.ts",nn(p)),await k("coordination-workflow.culvii.ts",an())),console.log(`${w} Initialized '${o}' project${n.here?"":` in ./${u}`}`),y.forEach(A=>console.log(` + ${A}`)),n.here||console.log(` cd ${u}`),console.log(" 1. Run `npm install`"),console.log(" 2. Replace YOUR_CREDENTIAL_ID and YOUR_MODEL_ID with your actual values from the Culvii console"),console.log(" 3. Run `culvii dev`"),await s(a$2.INIT_SUCCEEDED,{template:o,provider:a}),await j$1();}catch(l){console.error(`${x} Initialization failed: ${l.message}`),await s(a$2.INIT_FAILED,{error_class:l?.constructor?.name??"UnknownError"}),await j$1(),process.exit(1);}});}var yt=a$1();yt.noColor&&(process.env.FORCE_COLOR="0");var _e=null;function kr(e){_e=e;}async function he(e=0,t){t&&process.stderr.write(t.endsWith(`
842
+ `)?t:`${t}
843
+ `),_e&&(_e(),_e=null),await j$1(),process.exit(e);}var J=new Command;J.exitOverride(e=>{(e.code==="commander.helpDisplayed"||e.code==="commander.version")&&he(0),he(e.exitCode);});J.hook("preAction",(e,t)=>{n(t.optsWithGlobals().env);});J.name("culvii").description("Culvii CLI").version("0.0.1").option("--debug","Enable debug logging to ~/.culvii/logs/cli.log").configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e)});async function V(e){if(_e&&(_e(),_e=null),(!yt.isTTY||yt.isCI)&&!(ie.includes("--help")||ie.includes("-h"))){console.log("Running in non-interactive mode.");return}let{render:t}=await import('ink'),n=await e,{unmount:r}=t(n);kr(r);}var ie=process.argv.slice(2);(async()=>{try{let{ConfigStore:e}=await import('./config-store-WSXGIIJ4.js');await new e().read({exitOnError:!1});}catch{await e(a$2.CLI_INSTALLED),await j$1();}})();if(ie.length===0)import('./OnboardingView-QWEF3FJU.js').then(async({OnboardingView:e})=>{let t=await import('react');await V(Promise.resolve(t.createElement(e)));});else if(ie.includes("--help")||ie.includes("-h"))import('./HelpView-PWNQ4RV6.js').then(async({HelpView:e$1})=>{let t=ie[0]&&!ie[0].startsWith("-")?ie[0]:"culvii";await e(a$2.CLI_HELP_VIEWED,{command:t}),await j$1();let n=await import('react');await V(Promise.resolve(n.createElement(e$1)));});else if(ie.includes("--version")||ie.includes("-V")||ie.includes("-v"))await e(a$2.CLI_VERSION_VIEWED),process.stdout.write(J.version()+`
844
+ `),he(0);else {let e$1=J.command("auth").description("Authentication commands");e$1.command("login").description("Login to Culvii").action(async()=>{let{login:n}=await import('./login-3I6NWIOP.js');await n();}),e$1.command("logout").description("Logout of Culvii").action(async()=>{let{logout:n}=await import('./logout-4OORM3VA.js');await n();}),J.command("login").description("Login to Culvii").action(async()=>{let{login:n}=await import('./login-3I6NWIOP.js');await n();}),J.command("logout").description("Logout of Culvii").action(async()=>{let{logout:n}=await import('./logout-4OORM3VA.js');await n();}),ht(J),$t(J),Mt(J),jt(J),Yt(J),Ht(J),qt(J),Jt(J),on(J);let t=false;try{t=!!process.argv[1]&&realpathSync(process.argv[1])===fileURLToPath(import.meta.url);}catch{t=false;}t&&J.parseAsync(process.argv).catch(async n=>{let{userId:r,tenantId:i}=await d();r?await f(a$2.CLI_UNHANDLED_ERROR,r,i,{error_class:n?.constructor?.name||"UnknownError",command:process.argv.slice(2).join(" ")}):await e(a$2.CLI_UNHANDLED_ERROR,{error_class:n?.constructor?.name||"UnknownError",command:process.argv.slice(2).join(" ")}),await j$1(),console.error(n),await he(1);});}export{_e as activeUnmount,he as exit,J as program,V as renderApp,kr as setActiveUnmount};