@crossdelta/platform-sdk 0.21.12 → 0.21.13

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/bin/cli.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  var ea=Object.defineProperty;var Jt=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var S=(e,t)=>()=>(e&&(t=e(e=0)),t);var ta=(e,t)=>{for(var r in t)ea(e,r,{get:t[r],enumerable:!0})};var w,Ke=S(()=>{"use strict";w={SUCCESS:0,GENERAL_ERROR:1,USAGE_ERROR:2,WORKSPACE_ERROR:64,VALIDATION_ERROR:65,CONFIG_ERROR:66,IO_ERROR:74,PERMISSION_ERROR:77,CANCELLED:130}});var U,z,qe,Kt=S(()=>{"use strict";Ke();U=class extends Error{exitCode;category;hint;cause;constructor(t,r=w.GENERAL_ERROR,n={}){super(t),this.name="CliError",this.exitCode=r,this.category=n.category??"process",this.hint=n.hint,this.cause=n.cause}toUserMessage(){let t=[this.message];return this.hint&&t.push(`
3
- Hint: ${this.hint}`),t.join("")}},z=class extends U{path;constructor(t,r,n={}){super(t,w.IO_ERROR,{...n,category:"io"}),this.name="IoError",this.path=r}},qe=class extends U{constructor(t="Operation cancelled",r={}){super(t,w.CANCELLED,{...r,category:"user"}),this.name="CancelledError"}}});import Z from"chalk";var X,kn,Cn,xn,ra,na,Ye,oa,sa,$,wn=S(()=>{"use strict";Kt();Ke();X=e=>e instanceof Error,kn=e=>X(e)?e.message:typeof e=="string"?e:String(e),Cn=["ExitPromptError"],xn=["Cancelled prompt","User force closed"],ra=["ERR_USE_AFTER_CLOSE"],na=e=>Cn.some(t=>e.name?.includes(t))||xn.some(t=>e.message?.includes(t)),Ye=e=>{if(e instanceof qe)return!0;if(!(e instanceof Error))return!1;if(Cn.some(r=>e.name?.includes(r))||xn.some(r=>e.message?.includes(r)))return!0;let t=e.code;return t&&ra.includes(t)?na(e):!1},oa=e=>{if(e instanceof U){let r=e.toUserMessage();return Z.red(`\u2716 ${r||"Unexpected error (re-run with DEBUG=true for details)"}`)}if(e instanceof Error){let r=e.message?.trim();return r?Z.red(`\u2716 ${r}`):Z.red("\u2716 Unexpected error (re-run with DEBUG=true for details)")}let t=String(e);return!t||t==="undefined"||t==="null"?Z.red("\u2716 Unexpected error (re-run with DEBUG=true for details)"):Z.red(`\u2716 ${t}`)},sa=e=>e instanceof U?e.exitCode:Ye(e)?w.CANCELLED:w.GENERAL_ERROR,$=(e,t={})=>{let{debug:r=process.env.DEBUG==="true",exit:n=!0,logger:o=console.error}=t;if(Ye(e)){n&&process.exit(w.CANCELLED);return}o(oa(e)),r&&e instanceof Error&&e.stack&&o(Z.dim(e.stack)),e instanceof U&&e.hint&&o(Z.dim(`
4
- Hint: ${e.hint}`)),n&&process.exit(sa(e))}});var V=S(()=>{"use strict";Kt();wn();Ke()});var Vu,Pn,qt,Ze=S(()=>{"use strict";Vu=process.env.npm_package_version||"0.0.0",Pn=["bun.lock","bun.lockb","package-lock.json","yarn.lock","pnpm-lock.yaml"],qt="start:dev"});import Xe from"chalk";function Yt(e,t){if(e.length===0)return"No entries to display.";let r=t?.title||"Benchmark Results",n=t?.footer||"",o=t?.maxBarWidth||50,s=t?.unit||"",i=Math.max(...e.map(c=>c.value)),a=[];a.push(""),a.push(r),a.push("");for(let c of e){let l=ia(c.barColor??t?.barColor),p=aa(c,i,o,l,s,t?.labelColor);a.push(p)}return n&&(a.push(""),a.push(n)),a.join(`
3
+ Hint: ${this.hint}`),t.join("")}},z=class extends U{path;constructor(t,r,n={}){super(t,w.IO_ERROR,{...n,category:"io"}),this.name="IoError",this.path=r}},qe=class extends U{constructor(t="Operation cancelled",r={}){super(t,w.CANCELLED,{...r,category:"user"}),this.name="CancelledError"}}});import Z from"chalk";var X,Cn,kn,xn,ra,na,Ye,oa,sa,$,wn=S(()=>{"use strict";Kt();Ke();X=e=>e instanceof Error,Cn=e=>X(e)?e.message:typeof e=="string"?e:String(e),kn=["ExitPromptError"],xn=["Cancelled prompt","User force closed"],ra=["ERR_USE_AFTER_CLOSE"],na=e=>kn.some(t=>e.name?.includes(t))||xn.some(t=>e.message?.includes(t)),Ye=e=>{if(e instanceof qe)return!0;if(!(e instanceof Error))return!1;if(kn.some(r=>e.name?.includes(r))||xn.some(r=>e.message?.includes(r)))return!0;let t=e.code;return t&&ra.includes(t)?na(e):!1},oa=e=>{if(e instanceof U){let r=e.toUserMessage();return Z.red(`\u2716 ${r||"Unexpected error (re-run with DEBUG=true for details)"}`)}if(e instanceof Error){let r=e.message?.trim();return r?Z.red(`\u2716 ${r}`):Z.red("\u2716 Unexpected error (re-run with DEBUG=true for details)")}let t=String(e);return!t||t==="undefined"||t==="null"?Z.red("\u2716 Unexpected error (re-run with DEBUG=true for details)"):Z.red(`\u2716 ${t}`)},sa=e=>e instanceof U?e.exitCode:Ye(e)?w.CANCELLED:w.GENERAL_ERROR,$=(e,t={})=>{let{debug:r=process.env.DEBUG==="true",exit:n=!0,logger:o=console.error}=t;if(Ye(e)){n&&process.exit(w.CANCELLED);return}o(oa(e)),r&&e instanceof Error&&e.stack&&o(Z.dim(e.stack)),e instanceof U&&e.hint&&o(Z.dim(`
4
+ Hint: ${e.hint}`)),n&&process.exit(sa(e))}});var V=S(()=>{"use strict";Kt();wn();Ke()});var Ju,Pn,qt,Ze=S(()=>{"use strict";Ju=process.env.npm_package_version||"0.0.0",Pn=["bun.lock","bun.lockb","package-lock.json","yarn.lock","pnpm-lock.yaml"],qt="start:dev"});import Xe from"chalk";function Yt(e,t){if(e.length===0)return"No entries to display.";let r=t?.title||"Benchmark Results",n=t?.footer||"",o=t?.maxBarWidth||50,s=t?.unit||"",i=Math.max(...e.map(c=>c.value)),a=[];a.push(""),a.push(r),a.push("");for(let c of e){let l=ia(c.barColor??t?.barColor),p=aa(c,i,o,l,s,t?.labelColor);a.push(p)}return n&&(a.push(""),a.push(n)),a.join(`
5
5
  `)}function ia(e){return e?Xe[e]("\u2587"):"\u2587"}function aa(e,t,r,n,o,s){let i=Math.round(e.value/t*r),a=e.barColor?Xe[e.barColor](n.repeat(i)):n.repeat(i),c=e.color??s;return`${Xe.bold(c?Xe[c](e.label.padEnd(12)):e.label.padEnd(12))} ${a} ${e.value.toLocaleString()}${o?` ${o}`:""}`}var Sn=S(()=>{"use strict"});import{existsSync as Qt,unlinkSync as ca,writeFileSync as la}from"fs";import{join as Xt}from"path";import Zt from"chokidar";var er,Qe,pa,bn,tr,ma,En,rr=S(()=>{"use strict";v();f();er=".pf-generating",Qe=e=>Xt(e,er),pa=e=>Qt(Qe(e)),bn=e=>{la(Qe(e),"","utf-8")},tr=e=>{let t=Qe(e);Qt(t)&&ca(t)},ma=e=>{let r=F(e)?.pf?.paths;return r?Object.values(r).filter(n=>typeof n=="object"&&n!==null&&n.watch===!0&&typeof n.path=="string"):[{path:"services"},{path:"apps"}]},En=(e,t)=>{tr(e);let r=ma(e),n=Qe(e),s=ae(async()=>{pa(e)||await t()},300),i=[];i.push(Zt.watch(n,{ignoreInitial:!0}).on("unlink",()=>t()));for(let a of r){let c=Xt(e,a.path);if(!Qt(c))continue;let l=a.ignorePatterns?.map(p=>Xt(c,p));i.push(Zt.watch(c,{ignoreInitial:!0,depth:0,ignored:l,usePolling:!0,interval:1e3}).on("addDir",p=>p!==c&&s()).on("unlinkDir",p=>p!==c&&s())),i.push(Zt.watch(`${c}/*/package.json`,{ignoreInitial:!0,ignored:l}).on("add",s).on("change",s))}return async()=>{await Promise.all(i.map(a=>a.close()))}}});import Tn from"chalk";import{Command as da}from"commander";import{Listr as $n}from"listr2";var J,ga,An,In=S(()=>{"use strict";V();rr();f();J=e=>{let t=new da(e.name).description(e.description).showHelpAfterError();e.arguments?.forEach(([o,s])=>{t.argument(o,s)}),e.options?.forEach(([o,s])=>{t.option(o,s)}),e.exampleUsage&&t.addHelpText("after",()=>`${Tn.cyan.bold(`
6
6
  Example:`)}
7
7
  ${Tn.bold(e.exampleUsage)}
8
- `),e.additionalInfo&&t.addHelpText("after",()=>(typeof e.additionalInfo=="function"?e.additionalInfo():e.additionalInfo)??"");let r=async o=>{e.prompts?.length&&await new $n(An(e.prompts,o),{rendererOptions:{lazy:!0,showErrorMessage:!1}}).run(o),await new $n(An(e.actions,o),{rendererOptions:{lazy:!1,showErrorMessage:!1}}).run(o),await e.onComplete?.(o)},n=()=>{try{let o=g();return bn(o),o}catch{return null}};return t.action(async(...o)=>{let s=null;try{let i=o.at(-1),a=i.args,c=i.opts(),l=ga(e.arguments??[],a);if(e.shouldSkipWorkflow?.(l,c)){await e.onSkipWorkflow?.(l,c);return}let p=await e.buildContext(l,c);s=n(),await r(p)}catch(i){$(i,{exit:!1})}finally{s&&tr(s)}}),t},ga=(e,t)=>{let r=e.map(([n],o)=>[n.replace(/[<>[\]]/g,""),t[o]]);return Object.fromEntries(r)},An=(e,t)=>e.map(r=>typeof r=="function"?r(t):r)});var ae,Rn=S(()=>{"use strict";ae=(e,t)=>{let r=null;return(...n)=>(r&&clearTimeout(r),new Promise(o=>{r=setTimeout(async()=>{r=null,await e(...n),o()},t)}))}});var Nn=S(()=>{"use strict"});import{execaSync as ua}from"execa";function Ee(e){try{return ua(e,["--version"]),!0}catch{return!1}}var nr=S(()=>{"use strict"});var Fn=S(()=>{"use strict";nr()});import{readdirSync as fa}from"fs";import{dirname as On,isAbsolute as ha,join as ya,normalize as va,resolve as Mn,sep as ka}from"path";import{fileURLToPath as Ca}from"url";import{packageUpSync as xa}from"package-up";import{rimraf as wa}from"rimraf";function jn(){let e=xa({cwd:On(Pa())});if(!e)throw new Error("Could not find package.json");return On(e)}var Pa,O,Dn,et,_n,or=S(()=>{"use strict";V();f();Pa=()=>typeof import.meta?.url=="string"?Ca(import.meta.url):process.cwd(),O=e=>{let t=sr()?g():process.cwd();return ya(t,e)},Dn=(e,t)=>{if(!e||!e.trim())throw new z("Path cannot be empty",e,{hint:"Provide a valid relative path"});if(ha(e))throw new z(`Absolute paths are not allowed: ${e}`,e,{hint:"Use a relative path within the target directory"});if(/^[a-zA-Z]:/.test(e))throw new z(`Windows drive paths are not allowed: ${e}`,e,{hint:"Use a relative path within the target directory"});if(e.replace(/\\/g,"/").split("/").some(a=>a===".."))throw new z(`Path traversal not allowed: ${e}`,e,{hint:"The path must stay within the target directory"});let o=va(e),s=Mn(t),i=Mn(t,o);if(!i.startsWith(s+ka)&&i!==s)throw new z(`Path escapes target directory: ${e}`,e,{hint:"The path must stay within the target directory"});return i},et=e=>{try{return fa(e).length===0}catch{return!0}};_n=e=>wa(e)});import Te from"chalk";var Ln,Sa,ba,tt,d,Wn=S(()=>{"use strict";Ln={debug:0,info:1,warn:2,error:3,silent:4},Sa=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",ba=()=>{let e=process.env.LOG_LEVEL;return Sa(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},tt=e=>{let t=ba();return Ln[e]>=Ln[t]},d={logs:[],breakLine:()=>(console.log(),d),success:(e,...t)=>(console.log(Te.green(`\u2714 ${e}`),...t),d),info:(e,...t)=>(tt("info")&&console.log(Te.cyan(`\u{1F6C8} ${e}`),...t),d),warn:(e,...t)=>(tt("warn")&&console.warn(Te.yellow(`\u26A0\uFE0E ${e}`),...t),d),error:(e,...t)=>(tt("error")&&console.error(Te.red(`\u2716 ${e}`),...t),d),debug:(e,...t)=>(tt("debug")&&console.log(Te.dim(`[debug] ${e}`),...t),d),log:(e,...t)=>(console.log(e,...t),d.logs.push({message:e,context:t.join()}),d),getStoredLogs:e=>e?d.logs.filter(t=>t.context?.includes(e)):d.logs,storeLog:(e,t)=>d.logs.push({message:e,context:t})}});var Hn=S(()=>{"use strict"});import Ea from"chalk";async function M(e,t){let r=Date.now(),n=e.title,o=()=>Math.floor((Date.now()-r)/1e3),s=setInterval(()=>{o()>1&&(e.title=`${n} (${o()}s)`)},1e3);try{return await t(o)}finally{clearInterval(s)}}async function rt(e,t,r){for(let n=0;n<t.length;n++){let o=t[n];e.output=Ea.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}var Bn=S(()=>{"use strict"});var v=S(()=>{"use strict";Sn();In();Rn();Nn();Fn();or();Wn();Hn();nr();Bn()});var Vn={};ta(Vn,{discoverAvailableServices:()=>at,findWorkspaceRoot:()=>g,getContractsConfig:()=>x,getGeneratorConfig:()=>ce,getPackageJsonField:()=>Wa,getPfConfig:()=>Ie,getPkgJson:()=>cr,getRootPackageScope:()=>st,getWorkspacePackageJson:()=>F,getWorkspacePathsConfig:()=>E,isInWorkspace:()=>sr,pkgJson:()=>R,readPackageConfig:()=>Re,updatePackageJsonField:()=>it});import{existsSync as Ae,readdirSync as Ta,readFileSync as Gn,writeFileSync as $a}from"fs";import{join as I,resolve as Aa}from"path";var ar,Ia,Ra,Na,$e,Fa,ot,nt,Oa,Ma,Un,Da,ja,zn,sr,g,F,E,Ie,x,st,_a,La,Wa,it,Re,ir,cr,R,ce,at,f=S(()=>{"use strict";Ze();v();ar=e=>JSON.parse(Gn(e,"utf-8")),Ia=ar,Ra=(e,t,r)=>$a(e,`${JSON.stringify(t,null,2)}
8
+ `),e.additionalInfo&&t.addHelpText("after",()=>(typeof e.additionalInfo=="function"?e.additionalInfo():e.additionalInfo)??"");let r=async o=>{e.prompts?.length&&await new $n(An(e.prompts,o),{rendererOptions:{lazy:!0,showErrorMessage:!1}}).run(o),await new $n(An(e.actions,o),{rendererOptions:{lazy:!1,showErrorMessage:!1}}).run(o),await e.onComplete?.(o)},n=()=>{try{let o=g();return bn(o),o}catch{return null}};return t.action(async(...o)=>{let s=null;try{let i=o.at(-1),a=i.args,c=i.opts(),l=ga(e.arguments??[],a);if(e.shouldSkipWorkflow?.(l,c)){await e.onSkipWorkflow?.(l,c);return}let p=await e.buildContext(l,c);s=n(),await r(p)}catch(i){$(i,{exit:!1})}finally{s&&tr(s)}}),t},ga=(e,t)=>{let r=e.map(([n],o)=>[n.replace(/[<>[\]]/g,""),t[o]]);return Object.fromEntries(r)},An=(e,t)=>e.map(r=>typeof r=="function"?r(t):r)});var ae,Rn=S(()=>{"use strict";ae=(e,t)=>{let r=null;return(...n)=>(r&&clearTimeout(r),new Promise(o=>{r=setTimeout(async()=>{r=null,await e(...n),o()},t)}))}});var Nn=S(()=>{"use strict"});import{execaSync as ua}from"execa";function Ee(e){try{return ua(e,["--version"]),!0}catch{return!1}}var nr=S(()=>{"use strict"});var Fn=S(()=>{"use strict";nr()});import{readdirSync as fa}from"fs";import{dirname as On,isAbsolute as ha,join as ya,normalize as va,resolve as Mn,sep as Ca}from"path";import{fileURLToPath as ka}from"url";import{packageUpSync as xa}from"package-up";import{rimraf as wa}from"rimraf";function jn(){let e=xa({cwd:On(Pa())});if(!e)throw new Error("Could not find package.json");return On(e)}var Pa,O,Dn,et,_n,or=S(()=>{"use strict";V();f();Pa=()=>typeof import.meta?.url=="string"?ka(import.meta.url):process.cwd(),O=e=>{let t=sr()?g():process.cwd();return ya(t,e)},Dn=(e,t)=>{if(!e||!e.trim())throw new z("Path cannot be empty",e,{hint:"Provide a valid relative path"});if(ha(e))throw new z(`Absolute paths are not allowed: ${e}`,e,{hint:"Use a relative path within the target directory"});if(/^[a-zA-Z]:/.test(e))throw new z(`Windows drive paths are not allowed: ${e}`,e,{hint:"Use a relative path within the target directory"});if(e.replace(/\\/g,"/").split("/").some(a=>a===".."))throw new z(`Path traversal not allowed: ${e}`,e,{hint:"The path must stay within the target directory"});let o=va(e),s=Mn(t),i=Mn(t,o);if(!i.startsWith(s+Ca)&&i!==s)throw new z(`Path escapes target directory: ${e}`,e,{hint:"The path must stay within the target directory"});return i},et=e=>{try{return fa(e).length===0}catch{return!0}};_n=e=>wa(e)});import Te from"chalk";var Ln,Sa,ba,tt,d,Wn=S(()=>{"use strict";Ln={debug:0,info:1,warn:2,error:3,silent:4},Sa=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",ba=()=>{let e=process.env.LOG_LEVEL;return Sa(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},tt=e=>{let t=ba();return Ln[e]>=Ln[t]},d={logs:[],breakLine:()=>(console.log(),d),success:(e,...t)=>(console.log(Te.green(`\u2714 ${e}`),...t),d),info:(e,...t)=>(tt("info")&&console.log(Te.cyan(`\u{1F6C8} ${e}`),...t),d),warn:(e,...t)=>(tt("warn")&&console.warn(Te.yellow(`\u26A0\uFE0E ${e}`),...t),d),error:(e,...t)=>(tt("error")&&console.error(Te.red(`\u2716 ${e}`),...t),d),debug:(e,...t)=>(tt("debug")&&console.log(Te.dim(`[debug] ${e}`),...t),d),log:(e,...t)=>(console.log(e,...t),d.logs.push({message:e,context:t.join()}),d),getStoredLogs:e=>e?d.logs.filter(t=>t.context?.includes(e)):d.logs,storeLog:(e,t)=>d.logs.push({message:e,context:t})}});var Hn=S(()=>{"use strict"});import Ea from"chalk";async function M(e,t){let r=Date.now(),n=e.title,o=()=>Math.floor((Date.now()-r)/1e3),s=setInterval(()=>{o()>1&&(e.title=`${n} (${o()}s)`)},1e3);try{return await t(o)}finally{clearInterval(s)}}async function rt(e,t,r){for(let n=0;n<t.length;n++){let o=t[n];e.output=Ea.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}var Bn=S(()=>{"use strict"});var v=S(()=>{"use strict";Sn();In();Rn();Nn();Fn();or();Wn();Hn();nr();Bn()});var Vn={};ta(Vn,{discoverAvailableServices:()=>at,findWorkspaceRoot:()=>g,getContractsConfig:()=>x,getGeneratorConfig:()=>ce,getPackageJsonField:()=>Wa,getPfConfig:()=>Ie,getPkgJson:()=>cr,getRootPackageScope:()=>st,getWorkspacePackageJson:()=>F,getWorkspacePathsConfig:()=>E,isInWorkspace:()=>sr,pkgJson:()=>R,readPackageConfig:()=>Re,updatePackageJsonField:()=>it});import{existsSync as Ae,readdirSync as Ta,readFileSync as Gn,writeFileSync as $a}from"fs";import{join as I,resolve as Aa}from"path";var ar,Ia,Ra,Na,$e,Fa,ot,nt,Oa,Ma,Un,Da,ja,zn,sr,g,F,E,Ie,x,st,_a,La,Wa,it,Re,ir,cr,R,ce,at,f=S(()=>{"use strict";Ze();v();ar=e=>JSON.parse(Gn(e,"utf-8")),Ia=ar,Ra=(e,t,r)=>$a(e,`${JSON.stringify(t,null,2)}
9
9
  `,"utf-8"),Na=["@crossdelta/cloudevents"],$e={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Fa={docs:{base:["service.md"],frameworks:{}},serviceTypes:{hono:{commandType:"hono-micro",entryPoint:"src/index.ts",skipFiles:[]},nest:{commandType:"nest-micro",entryPoint:"src/main.ts",skipFiles:[]}}},ot=e=>{if(!Ae(e))return null;try{return JSON.parse(Gn(e,"utf-8"))}catch{return null}},nt=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,Oa=e=>e.split("/").pop()||"workspace",Ma=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},Un=e=>e.split("."),Da=(e,t)=>{if(!e.workspaces)return!1;if(e.pf||Ae(I(t,"turbo.json")))return!0;let r=Pn.some(o=>Ae(I(t,o))),n=Ae(I(t,"infra"));return r&&n},ja=e=>{let t=ot(I(e,"package.json"));return t?Da(t,e):!1},zn=e=>{let t=e;for(;t;){if(ja(t))return t;t=Ma(t)}return null},sr=()=>zn(process.cwd())!==null,g=()=>{let e=zn(process.cwd());if(!e)throw new Error(`
10
10
  \x1B[31m\u2716\x1B[0m Not in a workspace directory
11
11
 
@@ -17,10 +17,10 @@ To create a new workspace, run:
17
17
 
18
18
  \x1B[36mpf new workspace my-platform\x1B[0m
19
19
  `);return e},F=e=>{let t=e??g();return ot(I(t,"package.json"))},E=e=>{let t=F(e);if(!t?.pf?.paths)return $e;let{paths:r}=t.pf;return{services:nt(r.services,$e.services),apps:nt(r.apps,$e.apps),packages:nt(r.packages,$e.packages),contracts:nt(r.contracts,$e.contracts)}},Ie=e=>{let t=F(e);return{plugins:t?.pf?.plugins??Na,dev:{filter:t?.pf?.dev?.filter??[]}}},x=e=>{let t=e??g(),r=E(t),n=I(t,r.contracts),s=ot(I(n,"package.json"))?.name??`${st()}/contracts`;return{packagePath:n,eventsPath:I(n,"src","events"),indexPath:I(n,"src","index.ts"),relativePath:r.contracts,packageName:s}},st=()=>{let e=g(),t=ot(I(e,"package.json")),r=`@${Oa(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:r},_a=(e,t)=>{let r=Un(t),n=e;for(let o of r){if(n===null||typeof n!="object"||!(o in n))return;n=n[o]}return n},La=(e,t,r)=>{let n=Un(t),o=n[n.length-1],s=e;for(let i of n.slice(0,-1))(!(i in s)||typeof s[i]!="object"||s[i]===null)&&(s[i]={}),s=s[i];s[o]=r},Wa=(e,t=process.cwd())=>{let r=ar(I(t,"package.json"));return _a(r,e)},it=(e,t,r=process.cwd())=>{let n=I(r,"package.json"),o=ar(n);La(o,e,t),Ra(n,o,{spaces:2,EOL:`
20
- `,encoding:"utf-8"})},Re=e=>{let t=jn();return Ia(Aa(t,e))},ir=null,cr=()=>(ir||(ir=Re("package.json")),ir),R=new Proxy({},{get:(e,t)=>cr()[t]}),ce=()=>cr().generatorConfig??Fa,at=e=>{let t=e??g(),r=E(t),n=I(t,r.services);if(!Ae(n))return[];try{return Ta(n,{withFileTypes:!0}).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>`${r.services}/${s.name}`).sort()}catch{return[]}}});import{argv as Su}from"process";import Je from"chalk";import{Command as bu}from"commander";import Eu from"terminal-link";V();f();import nc from"chalk";import{Command as oc}from"commander";v();import{existsSync as Za}from"fs";import{join as Xa}from"path";import{cwd as Xn}from"process";import{execaSync as Qa}from"execa";v();import{spawn as mr}from"child_process";import{resolve as Ua}from"path";import{execa as za}from"execa";import{existsSync as Ha}from"fs";import{resolve as Ba}from"path";import{config as Ga}from"dotenv";var lr=(e,t)=>{let r=Ba(t,e);return Ha(r)?Ga({path:r,processEnv:{}}).parsed||{}:{}},Jn=(e,t)=>{let r=lr(e,t),n=[];for(let[o,s]of Object.entries(r))if(o.endsWith("_PORT")&&s){let i=Number.parseInt(s,10);!Number.isNaN(i)&&i>0&&n.push(i)}return n};var pr={...process.env,NODE_NO_WARNINGS:"1"},Va=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",Ja=(e,t,r)=>e?{...pr,...e}:t||r?{...pr,CI:"true"}:{...pr},Ka=e=>e.includes("EEXIST")||e.includes("failed to link package");async function K(e,t,{cwd:r=process.cwd(),task:n,shell:o,context:s=e,quiet:i=!1,nonInteractive:a=!1,env:c}={}){try{t.length===0&&(t=e.split(" ").slice(1));let l=za(e,t,{cwd:r,stdio:Va(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:Ja(c,n,a)});l.all&&l.all.on("data",p=>{let m=p.toString().trim();n?(n.output=m,m.length&&d.storeLog(m,s)):a&&m.length&&console.log(m)}),await l}catch(l){let p=l instanceof Error?l.message:String(l);if(Ka(p))return;throw new Error(qa(p))}}var qa=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function Kn(e,t,r={}){let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:l}=r,p=o?lr(o,n):{},m=Ua(n,"node_modules",".bin"),y=process.env.PATH||"",_=`${m}:${y}`,be={...process.env,...p,PATH:_,FORCE_COLOR:"1"},N=mr(e,t,{cwd:n,env:be,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&N.stdout?.on("data",a),c&&N.stderr?.on("data",c),l&&N.on("exit",l),N}function qn(e,t,r={}){let{cwd:n=process.cwd()}=r;mr(e,t,{cwd:n,stdio:"inherit"}).on("exit",s=>process.exit(s||0))}function Yn(e,t,r={}){let{cwd:n=process.cwd()}=r,o=t.length>0?`${e} ${t.join(" ")}`:e;mr(o,[],{cwd:n,stdio:"inherit",shell:!0}).on("exit",i=>process.exit(i||0))}async function Zn(e){let{execSync:t}=await import("child_process");for(let r of e)try{let o=t(`lsof -ti:${r}`,{encoding:"utf8",stdio:"pipe"}).trim().split(`
20
+ `,encoding:"utf-8"})},Re=e=>{let t=jn();return Ia(Aa(t,e))},ir=null,cr=()=>(ir||(ir=Re("package.json")),ir),R=new Proxy({},{get:(e,t)=>cr()[t]}),ce=()=>cr().generatorConfig??Fa,at=e=>{let t=e??g(),r=E(t),n=I(t,r.services);if(!Ae(n))return[];try{return Ta(n,{withFileTypes:!0}).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>`${r.services}/${s.name}`).sort()}catch{return[]}}});import{argv as bu}from"process";import Je from"chalk";import{Command as Eu}from"commander";import Tu from"terminal-link";V();f();import nc from"chalk";import{Command as oc}from"commander";v();import{existsSync as Za}from"fs";import{join as Xa}from"path";import{cwd as Xn}from"process";import{execaSync as Qa}from"execa";v();import{spawn as mr}from"child_process";import{resolve as Ua}from"path";import{execa as za}from"execa";import{existsSync as Ha}from"fs";import{resolve as Ba}from"path";import{config as Ga}from"dotenv";var lr=(e,t)=>{let r=Ba(t,e);return Ha(r)?Ga({path:r,processEnv:{}}).parsed||{}:{}},Jn=(e,t)=>{let r=lr(e,t),n=[];for(let[o,s]of Object.entries(r))if(o.endsWith("_PORT")&&s){let i=Number.parseInt(s,10);!Number.isNaN(i)&&i>0&&n.push(i)}return n};var pr={...process.env,NODE_NO_WARNINGS:"1"},Va=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",Ja=(e,t,r)=>e?{...pr,...e}:t||r?{...pr,CI:"true"}:{...pr},Ka=e=>e.includes("EEXIST")||e.includes("failed to link package");async function K(e,t,{cwd:r=process.cwd(),task:n,shell:o,context:s=e,quiet:i=!1,nonInteractive:a=!1,env:c}={}){try{t.length===0&&(t=e.split(" ").slice(1));let l=za(e,t,{cwd:r,stdio:Va(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:Ja(c,n,a)});l.all&&l.all.on("data",p=>{let m=p.toString().trim();n?(n.output=m,m.length&&d.storeLog(m,s)):a&&m.length&&console.log(m)}),await l}catch(l){let p=l instanceof Error?l.message:String(l);if(Ka(p))return;throw new Error(qa(p))}}var qa=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function Kn(e,t,r={}){let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:l}=r,p=o?lr(o,n):{},m=Ua(n,"node_modules",".bin"),y=process.env.PATH||"",_=`${m}:${y}`,be={...process.env,...p,PATH:_,FORCE_COLOR:"1"},N=mr(e,t,{cwd:n,env:be,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&N.stdout?.on("data",a),c&&N.stderr?.on("data",c),l&&N.on("exit",l),N}function qn(e,t,r={}){let{cwd:n=process.cwd()}=r;mr(e,t,{cwd:n,stdio:"inherit"}).on("exit",s=>process.exit(s||0))}function Yn(e,t,r={}){let{cwd:n=process.cwd()}=r,o=t.length>0?`${e} ${t.join(" ")}`:e;mr(o,[],{cwd:n,stdio:"inherit",shell:!0}).on("exit",i=>process.exit(i||0))}async function Zn(e){let{execSync:t}=await import("child_process");for(let r of e)try{let o=t(`lsof -ti:${r}`,{encoding:"utf8",stdio:"pipe"}).trim().split(`
21
21
  `).filter(Boolean);for(let s of o)try{process.kill(Number.parseInt(s,10),"SIGKILL")}catch{}}catch{}}f();var ct=e=>Ee(e);function dr(e=process.cwd()){let t=r=>Za(Xa(e,r));if(t("bun.lock")||t("bun.lockb"))return"bun";if(t("pnpm-lock.yaml"))return"pnpm";if(t("yarn.lock"))return"yarn";if(t("package-lock.json"))return"npm"}function b(e){return dr(e)??ec()}function ec(){return ct("bun")?"bun":ct("pnpm")?"pnpm":ct("yarn")?"yarn":"npm"}function Qn(){return["bun","pnpm","yarn","npm"].filter(ct)}async function L(e,t){let r=tc(e,t),{mergedOptions:n,packages:o}=r,{cwd:s=process.cwd(),flags:i=[],task:a,quiet:c}=n,l=n.packageManager??b(),p=[],m=Array.isArray(o)?o:[o];l==="bun"&&(m=m.map(_=>_.replace("git+ssh://",""))),l==="pnpm"&&(p.push("--config.engine-strict=false"),p.push("--no-frozen-lockfile")),["yarn","npm"].includes(l)&&p.push("--ignore-engines");let y=m.length?l==="npm"?["install",...i,...p,...m]:["add",...i,...p,...m]:["install",...i,...p];await K(l,y,{cwd:s,task:a,quiet:c})}async function eo(e){let t=["-g"],r=[...e.flags??[],...t];await L({...e,flags:r,packageManager:e.packageManager??b()})}function to(e,t,r){let{args:n,mergedOptions:o}=no(t??[],r),s=o.manager??b(),{command:i,args:a}=ro(s);console.log(`
22
22
  Running command: ${i} ${[...a,e,...n].join(" ")}
23
- `),Qa(i,[...a,e,...n],{cwd:o.cwd??Xn(),stdio:"inherit",preferLocal:!0})}async function Ne(e,t,r){let{args:n,mergedOptions:o}=no(t??[],r),s=o.manager??b(),{command:i,args:a}=ro(s);await K(i,[...a,e,...n],o)}async function Fe(e,t){let{script:r,mergedOptions:n}=rc(e,t),o=n.packageManager??b();await K(o,["run",r,...n.args??[]],{cwd:n.cwd??Xn(),task:n.task})}function ro(e){let r={bun:"bunx",pnpm:"npx",yarn:"npx",npm:"npx"}[e];if(!r)throw new Error(`No executor found for the detected package manager: ${e}`);let[n,...o]=r.split(" ");return{command:n,args:o}}function tc(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function no(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function rc(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var sc=e=>e==="yarn"?["npm","audit"]:["audit"],oo=new oc("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=g(),n=b(),o=sc(n),s=t.args||[];console.log(nc.dim(`Running ${n} ${[...o,...s].join(" ")}`)),qn(n,[...o,...s],{cwd:r})}catch(r){$(r)}});import q from"chalk";import{existsSync as kc,readFileSync as Cc,writeFileSync as xc}from"fs";import{homedir as wc}from"os";import{join as Pc}from"path";import{createCipheriv as ic,createDecipheriv as ac,createHash as cc,randomBytes as lc}from"crypto";import{existsSync as pc,readFileSync as mc,writeFileSync as dc}from"fs";import{homedir as so,hostname as gc,userInfo as uc}from"os";import{join as fc}from"path";var gr=fc(so(),".platform-sdk-keys"),io="aes-256-gcm",ao=()=>{let e=`${gc()}:${uc().username}:${so()}`;return cc("sha256").update(e).digest()},co=()=>{if(!pc(gr))return{};try{return JSON.parse(mc(gr,"utf-8"))}catch{return{}}},hc=e=>{dc(gr,JSON.stringify(e,null,2),{mode:384})},yc=e=>{let t=ao(),r=lc(16),n=ic(io,t,r),o=n.update(e,"utf8","hex");return o+=n.final("hex"),{iv:r.toString("hex"),tag:n.getAuthTag().toString("hex"),data:o}},vc=e=>{let t=ao(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),o=ac(io,t,r);o.setAuthTag(n);let s=o.update(e.data,"hex","utf8");return s+=o.final("utf8"),s};async function lo(e,t){let r=co();r[e]=yc(t),hc(r)}async function lt(e){let r=co()[e];if(!r)return null;try{return vc(r)}catch{return null}}var Oe={openai:{id:"openai",name:"OpenAI",defaultApiKeyEnvVar:"OPENAI_API_KEY",defaultModel:"gpt-4o-mini",modelsApiUrl:"https://api.openai.com/v1/models",apiKeyUrl:"https://platform.openai.com/api-keys",buildHeaders:e=>({Authorization:`Bearer ${e}`}),parseModelsResponse:e=>e.data??[],modelFilters:[/^gpt-4/,/^gpt-3\.5/,/^o1/,/^o3/]},anthropic:{id:"anthropic",name:"Anthropic (Claude)",defaultApiKeyEnvVar:"ANTHROPIC_API_KEY",defaultModel:"claude-sonnet-4-20250514",modelsApiUrl:"https://api.anthropic.com/v1/models",apiKeyUrl:"https://console.anthropic.com/settings/keys",buildHeaders:e=>({"x-api-key":e,"anthropic-version":"2023-06-01"}),parseModelsResponse:e=>(e.data??[]).map(r=>({id:r.id,created:new Date(r.created_at).getTime()})),modelFilters:[/^claude-/]}};function po(){return Object.entries(Oe).map(([e,t])=>({name:t.name,value:e}))}function Me(e){let t=Oe[e];if(!t)throw new Error(`Unknown AI provider: ${e}`);return t}var Q=Pc(wc(),".platform-sdk-ai.json"),Sc=()=>{let e="anthropic",t=Oe[e];return{provider:e,model:t.defaultModel}},ur=Sc();function De(){return kc(Q)}function pt(){if(!De())throw new Error("AI configuration not found. Please run 'pf ai:setup' to configure your AI provider.");try{let e=Cc(Q,"utf-8"),t=JSON.parse(e);return{...ur,...t}}catch{throw new Error(`Failed to load AI configuration from ${Q}. Please run 'pf setup --ai' again.`)}}function mo(e){let t=JSON.stringify(e,null,2);xc(Q,t,"utf-8")}async function go(e,t){await lo(e,t)}async function uo(e){let t=await lt(e.provider);if(t)return t;let r=Oe[e.provider],n=process.env[r.defaultApiKeyEnvVar];if(n)return n;throw new Error("API key not found. Please run 'pf setup --ai' to configure your API key.")}var bc=async(e,t,r,n)=>{let{createOpenAI:o}=await import("@ai-sdk/openai"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a},Ec=async(e,t,r,n)=>{let{createAnthropic:o}=await import("@ai-sdk/anthropic"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a};async function fo(e,t,r={}){let{system:n,maxTokens:o=4096,temperature:s=.7,onToken:i}=r,a=await uo(e);switch(e.provider){case"openai":return bc(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});case"anthropic":return Ec(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});default:throw new Error(`Unsupported AI provider: ${e.provider}`)}}V();import{existsSync as Zo,readFileSync as ep,unlinkSync as tp,writeFileSync as rp}from"fs";import{join as Xo,resolve as qo}from"path";import{input as np}from"@inquirer/prompts";import h from"chalk";import op from"ora";import{existsSync as fr,readdirSync as Ac}from"fs";import{dirname as Ic,join as ho}from"path";import{dirname as Tc}from"path";import{fileURLToPath as $c}from"url";var W=e=>Tc($c(e));rr();var Rc=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ee=e=>{let t=e??Rc(),r=o=>fr(ho(o,"package.json")),n=Ic(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return ee(n)},yo=(e,t)=>{let r=e.find(fr);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},vo=async e=>{let{getWorkspacePathsConfig:t}=await Promise.resolve().then(()=>(f(),Vn)),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=ho(e,o);if(!fr(s))return[];try{return Ac(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};import{existsSync as rl,readFileSync as nl}from"fs";import{join as ol}from"path";import{Project as sl}from"ts-morph";import{deriveEventNames as Fy,getContractPaths as Oy,getStreamName as My}from"@crossdelta/cloudevents";import{existsSync as mt,readFileSync as ko,writeFileSync as Nc}from"fs";import{join as hr}from"path";import{getStreamName as Fc}from"@crossdelta/cloudevents";var Co=(e,t)=>{let r=hr(e,"src","index.ts");if(!mt(r))return!1;let n=ko(r,"utf-8"),o=t.toLowerCase();return new RegExp(`streams:\\s*\\[[^\\]]*['"]${t}['"]`).test(n)||n.includes(`stream: '${t}'`)?!0:new RegExp(`subjects:\\s*\\[.*['"]${o}\\.[*>]`).test(n)},Oc=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
23
+ `),Qa(i,[...a,e,...n],{cwd:o.cwd??Xn(),stdio:"inherit",preferLocal:!0})}async function Ne(e,t,r){let{args:n,mergedOptions:o}=no(t??[],r),s=o.manager??b(),{command:i,args:a}=ro(s);await K(i,[...a,e,...n],o)}async function Fe(e,t){let{script:r,mergedOptions:n}=rc(e,t),o=n.packageManager??b();await K(o,["run",r,...n.args??[]],{cwd:n.cwd??Xn(),task:n.task})}function ro(e){let r={bun:"bunx",pnpm:"npx",yarn:"npx",npm:"npx"}[e];if(!r)throw new Error(`No executor found for the detected package manager: ${e}`);let[n,...o]=r.split(" ");return{command:n,args:o}}function tc(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function no(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function rc(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var sc=e=>e==="yarn"?["npm","audit"]:["audit"],oo=new oc("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=g(),n=b(),o=sc(n),s=t.args||[];console.log(nc.dim(`Running ${n} ${[...o,...s].join(" ")}`)),qn(n,[...o,...s],{cwd:r})}catch(r){$(r)}});import q from"chalk";import{existsSync as Cc,readFileSync as kc,writeFileSync as xc}from"fs";import{homedir as wc}from"os";import{join as Pc}from"path";import{createCipheriv as ic,createDecipheriv as ac,createHash as cc,randomBytes as lc}from"crypto";import{existsSync as pc,readFileSync as mc,writeFileSync as dc}from"fs";import{homedir as so,hostname as gc,userInfo as uc}from"os";import{join as fc}from"path";var gr=fc(so(),".platform-sdk-keys"),io="aes-256-gcm",ao=()=>{let e=`${gc()}:${uc().username}:${so()}`;return cc("sha256").update(e).digest()},co=()=>{if(!pc(gr))return{};try{return JSON.parse(mc(gr,"utf-8"))}catch{return{}}},hc=e=>{dc(gr,JSON.stringify(e,null,2),{mode:384})},yc=e=>{let t=ao(),r=lc(16),n=ic(io,t,r),o=n.update(e,"utf8","hex");return o+=n.final("hex"),{iv:r.toString("hex"),tag:n.getAuthTag().toString("hex"),data:o}},vc=e=>{let t=ao(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),o=ac(io,t,r);o.setAuthTag(n);let s=o.update(e.data,"hex","utf8");return s+=o.final("utf8"),s};async function lo(e,t){let r=co();r[e]=yc(t),hc(r)}async function lt(e){let r=co()[e];if(!r)return null;try{return vc(r)}catch{return null}}var Oe={openai:{id:"openai",name:"OpenAI",defaultApiKeyEnvVar:"OPENAI_API_KEY",defaultModel:"gpt-4o-mini",modelsApiUrl:"https://api.openai.com/v1/models",apiKeyUrl:"https://platform.openai.com/api-keys",buildHeaders:e=>({Authorization:`Bearer ${e}`}),parseModelsResponse:e=>e.data??[],modelFilters:[/^gpt-4/,/^gpt-3\.5/,/^o1/,/^o3/]},anthropic:{id:"anthropic",name:"Anthropic (Claude)",defaultApiKeyEnvVar:"ANTHROPIC_API_KEY",defaultModel:"claude-sonnet-4-20250514",modelsApiUrl:"https://api.anthropic.com/v1/models",apiKeyUrl:"https://console.anthropic.com/settings/keys",buildHeaders:e=>({"x-api-key":e,"anthropic-version":"2023-06-01"}),parseModelsResponse:e=>(e.data??[]).map(r=>({id:r.id,created:new Date(r.created_at).getTime()})),modelFilters:[/^claude-/]}};function po(){return Object.entries(Oe).map(([e,t])=>({name:t.name,value:e}))}function Me(e){let t=Oe[e];if(!t)throw new Error(`Unknown AI provider: ${e}`);return t}var Q=Pc(wc(),".platform-sdk-ai.json"),Sc=()=>{let e="anthropic",t=Oe[e];return{provider:e,model:t.defaultModel}},ur=Sc();function De(){return Cc(Q)}function pt(){if(!De())throw new Error("AI configuration not found. Please run 'pf ai:setup' to configure your AI provider.");try{let e=kc(Q,"utf-8"),t=JSON.parse(e);return{...ur,...t}}catch{throw new Error(`Failed to load AI configuration from ${Q}. Please run 'pf setup --ai' again.`)}}function mo(e){let t=JSON.stringify(e,null,2);xc(Q,t,"utf-8")}async function go(e,t){await lo(e,t)}async function uo(e){let t=await lt(e.provider);if(t)return t;let r=Oe[e.provider],n=process.env[r.defaultApiKeyEnvVar];if(n)return n;throw new Error("API key not found. Please run 'pf setup --ai' to configure your API key.")}var bc=async(e,t,r,n)=>{let{createOpenAI:o}=await import("@ai-sdk/openai"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a},Ec=async(e,t,r,n)=>{let{createAnthropic:o}=await import("@ai-sdk/anthropic"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a};async function fo(e,t,r={}){let{system:n,maxTokens:o=4096,temperature:s=.7,onToken:i}=r,a=await uo(e);switch(e.provider){case"openai":return bc(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});case"anthropic":return Ec(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});default:throw new Error(`Unsupported AI provider: ${e.provider}`)}}V();import{existsSync as Zo,readFileSync as ep,unlinkSync as tp,writeFileSync as rp}from"fs";import{join as Xo,resolve as qo}from"path";import{input as np}from"@inquirer/prompts";import h from"chalk";import op from"ora";import{existsSync as fr,readdirSync as Ac}from"fs";import{dirname as Ic,join as ho}from"path";import{dirname as Tc}from"path";import{fileURLToPath as $c}from"url";var W=e=>Tc($c(e));rr();var Rc=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ee=e=>{let t=e??Rc(),r=o=>fr(ho(o,"package.json")),n=Ic(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return ee(n)},yo=(e,t)=>{let r=e.find(fr);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},vo=async e=>{let{getWorkspacePathsConfig:t}=await Promise.resolve().then(()=>(f(),Vn)),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=ho(e,o);if(!fr(s))return[];try{return Ac(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};import{existsSync as rl,readFileSync as nl}from"fs";import{join as ol}from"path";import{Project as sl}from"ts-morph";import{deriveEventNames as Oy,getContractPaths as My,getStreamName as Dy}from"@crossdelta/cloudevents";import{existsSync as mt,readFileSync as Co,writeFileSync as Nc}from"fs";import{join as hr}from"path";import{getStreamName as Fc}from"@crossdelta/cloudevents";var ko=(e,t)=>{let r=hr(e,"src","index.ts");if(!mt(r))return!1;let n=Co(r,"utf-8"),o=t.toLowerCase();return new RegExp(`streams:\\s*\\[[^\\]]*['"]${t}['"]`).test(n)||n.includes(`stream: '${t}'`)?!0:new RegExp(`subjects:\\s*\\[.*['"]${o}\\.[*>]`).test(n)},Oc=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
24
24
  `,r=e.match(/import\s+['"]@crossdelta\/telemetry['"]\s*\n/);if(r){let o=(r.index??0)+r[0].length;return`${e.slice(0,o)}
25
25
  ${t}${e.slice(o)}`}let n=e.match(/import\s+.*\n/);if(n){let o=(n.index??0)+n[0].length;return e.slice(0,o)+t+e.slice(o)}return e},Mc=(e,t)=>`
26
26
 
@@ -29,8 +29,8 @@ consumeJetStreams({
29
29
  streams: ['${e}'],
30
30
  consumer: '${t}-service',
31
31
  discover: './src/events/**/*.handler.ts',
32
- })`,yr=(e,t)=>{let r=Fc(t),n=hr(e,"src","index.ts"),o=hr(e,"src","main.ts");if(!mt(n)&&mt(o))return{added:!1,streamName:r};if(!mt(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(Co(e,r))return{added:!1,streamName:r};let s=ko(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Oc(s));let a=Mc(r,i),c=`${s.trimEnd()+a}
33
- `;return Nc(n,c,"utf-8"),{added:!0,streamName:r}};f();import{existsSync as Kh,readFileSync as qh}from"fs";import{join as Zh}from"path";import{contractCreated as Qh,deriveEventNames as ey,generateContract as ty,getContractFilePath as ry}from"@crossdelta/cloudevents";import{readdirSync as Dc,readFileSync as jc}from"fs";import{join as xo}from"path";import{getStreamName as _c,pluralize as Lc,singularize as Wc}from"@crossdelta/cloudevents";var wo=e=>{try{return Dc(e,{withFileTypes:!0}).flatMap(r=>{let n=xo(e,r.name);return r.isDirectory()?wo(n):r.name.endsWith(".handler.ts")?[n]:[]})}catch{return[]}},vr=e=>{let t=xo(e,"src","events");return wo(t).flatMap(n=>{let o=jc(n,"utf-8");return Hc(n,o)})},Hc=(e,t)=>{let r=Gc(t);if(!r)return[];let n=Bc(r);return n?[{filePath:e,eventType:n,contractName:r}]:[]},Bc=e=>{let r=e.replace(/Contract$/,"").match(/[A-Z][a-z]*/g);if(!r||r.length<2)return null;let n=r[0].toLowerCase(),o=Wc(n),i=r.slice(1).map(a=>a.toLowerCase()).join("-");return`${o}.${i}`},Gc=e=>{let r=/import\s+{([^}]+)}\s+from\s+['"]@[\w-]+\/contracts['"]/.exec(e);return r?r[1].split(",").map(s=>s.trim()).filter(s=>s.endsWith("Contract")).map(s=>s.replace(/\s+as\s+.+$/,"").trim()).at(0)??null:null},kr=e=>{let t=e.reduce((r,n)=>{let o=n.eventType.split(".")[0],s=r.get(o)??[];return r.set(o,[...s,n]),r},new Map);return Array.from(t.entries()).map(([r,n])=>Uc(r,n)).sort((r,n)=>r.stream.localeCompare(n.stream))},Uc=(e,t)=>{let r=_c(t[0]?.eventType??`${e}.event`),o=`${Lc(e)}.>`;return{stream:r,subjects:[o],handlers:t}},Cr=(e,t)=>e.length===0?"":` // Development: pf dev auto-creates ephemeral streams from contracts
32
+ })`,yr=(e,t)=>{let r=Fc(t),n=hr(e,"src","index.ts"),o=hr(e,"src","main.ts");if(!mt(n)&&mt(o))return{added:!1,streamName:r};if(!mt(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(ko(e,r))return{added:!1,streamName:r};let s=Co(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Oc(s));let a=Mc(r,i),c=`${s.trimEnd()+a}
33
+ `;return Nc(n,c,"utf-8"),{added:!0,streamName:r}};f();import{existsSync as qh,readFileSync as Yh}from"fs";import{join as Xh}from"path";import{contractCreated as ey,deriveEventNames as ty,generateContract as ry,getContractFilePath as ny}from"@crossdelta/cloudevents";import{readdirSync as Dc,readFileSync as jc}from"fs";import{join as xo}from"path";import{getStreamName as _c,pluralize as Lc,singularize as Wc}from"@crossdelta/cloudevents";var wo=e=>{try{return Dc(e,{withFileTypes:!0}).flatMap(r=>{let n=xo(e,r.name);return r.isDirectory()?wo(n):r.name.endsWith(".handler.ts")?[n]:[]})}catch{return[]}},vr=e=>{let t=xo(e,"src","events");return wo(t).flatMap(n=>{let o=jc(n,"utf-8");return Hc(n,o)})},Hc=(e,t)=>{let r=Gc(t);if(!r)return[];let n=Bc(r);return n?[{filePath:e,eventType:n,contractName:r}]:[]},Bc=e=>{let r=e.replace(/Contract$/,"").match(/[A-Z][a-z]*/g);if(!r||r.length<2)return null;let n=r[0].toLowerCase(),o=Wc(n),i=r.slice(1).map(a=>a.toLowerCase()).join("-");return`${o}.${i}`},Gc=e=>{let r=/import\s+{([^}]+)}\s+from\s+['"]@[\w-]+\/contracts['"]/.exec(e);return r?r[1].split(",").map(s=>s.trim()).filter(s=>s.endsWith("Contract")).map(s=>s.replace(/\s+as\s+.+$/,"").trim()).at(0)??null:null},Cr=e=>{let t=e.reduce((r,n)=>{let o=n.eventType.split(".")[0],s=r.get(o)??[];return r.set(o,[...s,n]),r},new Map);return Array.from(t.entries()).map(([r,n])=>Uc(r,n)).sort((r,n)=>r.stream.localeCompare(n.stream))},Uc=(e,t)=>{let r=_c(t[0]?.eventType??`${e}.event`),o=`${Lc(e)}.>`;return{stream:r,subjects:[o],handlers:t}},kr=(e,t)=>e.length===0?"":` // Development: pf dev auto-creates ephemeral streams from contracts
34
34
  // Production: Pulumi materializes persistent streams
35
35
 
36
36
  consumeJetStreams({
@@ -58,12 +58,12 @@ ${r}
58
58
  ${r}
59
59
  `),o!==t?(pe(e,o,"utf-8"),!0):!1},xr=(e,t)=>{let{packagePath:r}=x(t),{domain:n,action:o}=Vc(e),s=le(r,"src","events");if(!te(s))return!1;let i=le(s,n),a=le(i,"index.ts"),c=le(s,"index.ts"),l=le(r,"src","index.ts"),p=e.split(".")[0],m=le(s,p);p!==n&&te(m)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${p}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${m} ${i}`));let y=!1;return Jc(a,o)&&(y=!0),Kc(c,n)&&(y=!0),qc(l)&&(y=!0),y},wr=(e,t)=>{if(!te(e))return!1;let r=`export * from './events/${t}'`,n=dt(e,"utf-8");if(n.includes(`'./events/${t}'`))return!1;let o=n.split(`
60
60
  `),s=o.findLastIndex(i=>i.startsWith("export"));return s>=0?o.splice(s+1,0,r):o.push("",r),pe(e,o.join(`
61
- `),"utf-8"),!0};f();import{existsSync as So,readdirSync as Zc,readFileSync as Xc}from"fs";import{join as bo}from"path";import{generateJsonMockFromContract as Qc,getJsonMockPath as el,initFaker as tl}from"@crossdelta/cloudevents";var Eo=e=>{let t=e.match(/handleEvent\s*\(\s*(\w+Contract)/m);if(t){let n=e.match(/type:\s*['"]([^'"]+)['"]/m);if(n)return n[1]}let r=e.match(/handleEvent\s*\(\s*\{[^}]*type:\s*['"]([^'"]+)['"]/m);if(r)return r[1];if(t){let s=t[1].replace(/Contract$/,"").split(/(?=[A-Z])/).filter(Boolean);if(s.length>=2){let i=s[0].toLowerCase(),a=s.slice(1).join("").toLowerCase();return`${i}.${a}`}}return null};var Pr=async(e,t={})=>{let r=bo(e,"src","events");if(!So(r))return{mockPaths:[],skippedHandlers:[]};await tl();let n=Zc(r).filter(i=>i.endsWith(".handler.ts")||i.endsWith(".event.ts")),o=[],s=[];for(let i of n){let a=bo(r,i),c=Xc(a,"utf-8"),l=Eo(c);if(!l){s.push(`${i} (Could not extract event type)`);continue}let p=t.outputDir??x().packagePath,m=el(l,p);if(So(m)&&!t.overwrite){s.push(`${i} (Mock already exists)`);continue}let y=Qc(l,p,{useFaker:!0});y&&y.status!=="skipped"&&"ref"in y?o.push(y.ref):s.push(`${i} (Contract not found or generation failed)`)}return{mockPaths:o,skippedHandlers:s}};var To=e=>{let t=e.split("/").pop()||"service",r=ol(e,"src","events","events.service.ts");if(!rl(r))return!1;let n=vr(e);if(n.length===0||nl(r,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").includes("consumeJetStreams"))return!1;let a=kr(n),c=Cr(a,t);if(!c)return!1;let l=new sl({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),p=l.addSourceFileAtPath(r),m=!1;for(let y of p.getClasses()){let _=y.getMethod("startConsumers");if(!_)continue;let N=[...c.split(`
61
+ `),"utf-8"),!0};f();import{existsSync as So,readdirSync as Zc,readFileSync as Xc}from"fs";import{join as bo}from"path";import{generateJsonMockFromContract as Qc,getJsonMockPath as el,initFaker as tl}from"@crossdelta/cloudevents";var Eo=e=>{let t=e.match(/handleEvent\s*\(\s*(\w+Contract)/m);if(t){let n=e.match(/type:\s*['"]([^'"]+)['"]/m);if(n)return n[1]}let r=e.match(/handleEvent\s*\(\s*\{[^}]*type:\s*['"]([^'"]+)['"]/m);if(r)return r[1];if(t){let s=t[1].replace(/Contract$/,"").split(/(?=[A-Z])/).filter(Boolean);if(s.length>=2){let i=s[0].toLowerCase(),a=s.slice(1).join("").toLowerCase();return`${i}.${a}`}}return null};var Pr=async(e,t={})=>{let r=bo(e,"src","events");if(!So(r))return{mockPaths:[],skippedHandlers:[]};await tl();let n=Zc(r).filter(i=>i.endsWith(".handler.ts")||i.endsWith(".event.ts")),o=[],s=[];for(let i of n){let a=bo(r,i),c=Xc(a,"utf-8"),l=Eo(c);if(!l){s.push(`${i} (Could not extract event type)`);continue}let p=t.outputDir??x().packagePath,m=el(l,p);if(So(m)&&!t.overwrite){s.push(`${i} (Mock already exists)`);continue}let y=Qc(l,p,{useFaker:!0});y&&y.status!=="skipped"&&"ref"in y?o.push(y.ref):s.push(`${i} (Contract not found or generation failed)`)}return{mockPaths:o,skippedHandlers:s}};var To=e=>{let t=e.split("/").pop()||"service",r=ol(e,"src","events","events.service.ts");if(!rl(r))return!1;let n=vr(e);if(n.length===0||nl(r,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").includes("consumeJetStreams"))return!1;let a=Cr(n),c=kr(a,t);if(!c)return!1;let l=new sl({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),p=l.addSourceFileAtPath(r),m=!1;for(let y of p.getClasses()){let _=y.getMethod("startConsumers");if(!_)continue;let N=[...c.split(`
62
62
  `),""," this.logger.log('Event consumers started successfully')"].join(`
63
63
  `);_.setBodyText(N),m=!0;break}return m&&l.saveSync(),m};f();var il=e=>{let t=e.split(/\s+/),r=t[0],n=t.slice(1);return r==="pf"&&(r=process.argv[1]),{executable:r,args:n}},al=async(e,t)=>{try{let{executable:r,args:n}=il(e.command);return await K(r,n,{cwd:t,shell:!1}),{command:e.command,success:!0}}catch(r){return{command:e.command,success:!1,error:r instanceof Error?r.message:String(r)}}},Sr=async(e,t)=>{let r=[];for(let n of e){let o=await al(n,t);if(r.push(o),!o.success)break}return r},br=e=>{let t=[/^pf\s+/,/^bun\s+pf\s+/,/^npx\s+pf\s+/,/^bunx\s+pf\s+/];return e.filter(r=>t.some(n=>n.test(r.command)))},$o=e=>{for(let t of e){let r=t.command.match(/(?:bun\s+)?pf\s+new\s+\S+\s+(\S+)/);if(r)return r[1]}return null};import{existsSync as Ro,readFileSync as dl}from"fs";import{join as Er}from"path";import B from"chalk";f();or();import{existsSync as Ao,mkdirSync as cl,writeFileSync as ll}from"fs";import{dirname as pl}from"path";var ml=(e,t)=>{let n=e.path.startsWith("packages/")&&t.workspaceRoot?t.workspaceRoot:t.baseDir,o;try{o=Dn(e.path,n)}catch(s){return{status:"failed",path:e.path,error:s.message}}try{if(Ao(o)&&!t.overwrite)return{status:"skipped",path:e.path};if(t.dryRun)return{status:"written",path:e.path};let s=pl(o);return Ao(s)||cl(s,{recursive:!0}),ll(o,e.content,"utf-8"),{status:"written",path:e.path}}catch(s){return{status:"failed",path:e.path,error:s.message}}},Io=(e,t)=>{let r=e.map(n=>ml(n,t));return{written:r.filter(n=>n.status==="written").map(n=>n.path),skipped:r.filter(n=>n.status==="skipped").map(n=>n.path),failed:r.filter(n=>n.status==="failed").map(n=>({path:n.path,error:n.error}))}};var gl=(e,t)=>{let r=E(t.workspaceRoot),n=Er(t.workspaceRoot,r.contracts);if(!Ro(n))return[];let o=/import\s+(?:type\s+)?{([^}]+)}\s+from\s+['"]@\w+\/contracts['"]/g,s=new Set;for(let i of e){let a=i.content.matchAll(o);for(let c of a){let p=c[1].split(",").map(m=>m.trim()).map(m=>m.replace(/^type\s+/,"").replace(/\s+as\s+.+$/,"").trim()).filter(m=>m.endsWith("Contract"));for(let m of p)s.add(m)}}return Array.from(s).sort()},ul=e=>{let t=Er(e,"packages/contracts/src/index.ts");if(!Ro(t))return new Set;try{let r=dl(t,"utf-8"),n=new Set,o=/export\s+(?:\*|{[^}]*Contract[^}]*})\s+from\s+['"]\.\/events\/([^'"]+)['"]/g,s=r.matchAll(o);for(let i of s){let a=i[0],c=/(\w+Contract)/g,l=a.matchAll(c);for(let p of l)n.add(p[1])}return n}catch{return new Set}},fl=e=>{let t=e.replace(/Contract$/,""),r=t.split(/(?=[A-Z])/).filter(Boolean);if(r.length<2)return t.toLowerCase();let n=r[0].toLowerCase(),o=r.slice(1).join("").toLowerCase();return`${n}.${o}`},hl=(e,t,r)=>{let n=ul(t),o=[],s=[],i=[];for(let a of e)if(n.has(a))o.push(a);else{s.push(a);let c=fl(a),l=r.replace(`${t}/`,"");i.push(`pf cloudevents add ${c} --service ${l}`)}return{existing:o,missing:s,suggestedCommands:i}},yl=(e,t)=>{if(e.length!==0){console.log(B.cyan(`\u{1F4E6} Using existing contracts:
64
- `));for(let r of e)console.log(B.dim(` ${t}/contracts \u2192 ${r}`));console.log()}},vl=(e,t)=>{let r=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,n=Er(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(r);s&&s[1]!=="index"&&wr(n,s[1])}},No=async(e,t)=>{t.start("Applying code formatting...");try{await Ne("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},kl=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:r,skippedHandlers:n}=await Pr(e);if(r.length+n.length===0){t.info("No event handlers found");return}if(r.length>0){t.succeed(`Generated ${r.length} event ${r.length===1?"mock":"mocks"}`),console.log();for(let s of r){let i=s.replace(`${e}/`,"");console.log(B.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(B.dim(` \u2139 Skipped: ${s}`));console.log()}},Fo=async(e,t,r,n)=>{n.start("Writing generated files...");let o=Io(e,{baseDir:t,workspaceRoot:r.workspaceRoot,overwrite:!0});if(o.written.length>0){n.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(B.dim(` ${l}`));console.log()}else n.succeed("No files to write");let s=gl(e,r),{existing:i,missing:a,suggestedCommands:c}=hl(s,r.workspaceRoot,t);if(i.length>0&&yl(i,r.scope),a.length>0){console.log(B.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${r.scope}/contracts):
64
+ `));for(let r of e)console.log(B.dim(` ${t}/contracts \u2192 ${r}`));console.log()}},vl=(e,t)=>{let r=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,n=Er(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(r);s&&s[1]!=="index"&&wr(n,s[1])}},No=async(e,t)=>{t.start("Applying code formatting...");try{await Ne("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},Cl=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:r,skippedHandlers:n}=await Pr(e);if(r.length+n.length===0){t.info("No event handlers found");return}if(r.length>0){t.succeed(`Generated ${r.length} event ${r.length===1?"mock":"mocks"}`),console.log();for(let s of r){let i=s.replace(`${e}/`,"");console.log(B.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(B.dim(` \u2139 Skipped: ${s}`));console.log()}},Fo=async(e,t,r,n)=>{n.start("Writing generated files...");let o=Io(e,{baseDir:t,workspaceRoot:r.workspaceRoot,overwrite:!0});if(o.written.length>0){n.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(B.dim(` ${l}`));console.log()}else n.succeed("No files to write");let s=gl(e,r),{existing:i,missing:a,suggestedCommands:c}=hl(s,r.workspaceRoot,t);if(i.length>0&&yl(i,r.scope),a.length>0){console.log(B.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${r.scope}/contracts):
65
65
  `));for(let l of a)console.log(B.yellow(` ${l}`));console.log(),console.log(B.cyan(`\u{1F4A1} Run these commands to create the missing contracts:
66
- `));for(let l of c)console.log(B.dim(` ${l}`));console.log()}return vl(o.written,r.workspaceRoot),o.written.length>0&&await kl(t,n),{missingContractCommands:c}};f();import{existsSync as Tl,readFileSync as $l}from"fs";import{join as je}from"path";f();f();import{existsSync as Cl,readdirSync as xl,readFileSync as wl}from"fs";import{join as Pl}from"path";var Oo=e=>{let{eventsPath:t}=x(e);if(!Cl(t))return[];let r=[];try{let n=xl(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of n){let s=Pl(t,o),i=wl(s,"utf-8"),a=Sl(i,s);a&&r.push(a)}}catch(n){return console.warn("Warning: Could not scan contracts package:",n),[]}return r},Sl=(e,t)=>{try{let r=e.match(/export const (\w+Contract) = createContract/);if(!r)return null;let n=r[1],o=e.match(/export type (\w+(?:Data|Event)) = z\.infer/);if(!o)return null;let s=o[1],i=e.match(/type:\s*['"]([^'"]+)['"]/);if(!i)return null;let a=i[1],c=El(e);return{name:n,typeName:s,eventType:a,fields:c,filePath:t}}catch{return null}},bl={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},El=e=>{let t=e.match(/z\.object\({([^}]+)\}/);if(!t)return[];let r=t[1],n=/(\w+):\s*z\.(\w+)\([^)]*\)/g,o=[...r.matchAll(n)].map(([,a,c])=>{let l=bl[c]||c;return`${a}: ${l}`});if(!e.includes("z.array("))return o;let s=/(\w+):\s*z\.array\(/g,i=[...e.matchAll(s)].map(([,a])=>a).filter(a=>!o.some(c=>c.startsWith(a))).map(a=>`${a}: array`);return[...o,...i]},Mo=(e,t)=>{if(e.length===0)return`
66
+ `));for(let l of c)console.log(B.dim(` ${l}`));console.log()}return vl(o.written,r.workspaceRoot),o.written.length>0&&await Cl(t,n),{missingContractCommands:c}};f();import{existsSync as Tl,readFileSync as $l}from"fs";import{join as je}from"path";f();f();import{existsSync as kl,readdirSync as xl,readFileSync as wl}from"fs";import{join as Pl}from"path";var Oo=e=>{let{eventsPath:t}=x(e);if(!kl(t))return[];let r=[];try{let n=xl(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of n){let s=Pl(t,o),i=wl(s,"utf-8"),a=Sl(i,s);a&&r.push(a)}}catch(n){return console.warn("Warning: Could not scan contracts package:",n),[]}return r},Sl=(e,t)=>{try{let r=e.match(/export const (\w+Contract) = createContract/);if(!r)return null;let n=r[1],o=e.match(/export type (\w+(?:Data|Event)) = z\.infer/);if(!o)return null;let s=o[1],i=e.match(/type:\s*['"]([^'"]+)['"]/);if(!i)return null;let a=i[1],c=El(e);return{name:n,typeName:s,eventType:a,fields:c,filePath:t}}catch{return null}},bl={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},El=e=>{let t=e.match(/z\.object\({([^}]+)\}/);if(!t)return[];let r=t[1],n=/(\w+):\s*z\.(\w+)\([^)]*\)/g,o=[...r.matchAll(n)].map(([,a,c])=>{let l=bl[c]||c;return`${a}: ${l}`});if(!e.includes("z.array("))return o;let s=/(\w+):\s*z\.array\(/g,i=[...e.matchAll(s)].map(([,a])=>a).filter(a=>!o.some(c=>c.startsWith(a))).map(a=>`${a}: array`);return[...o,...i]},Mo=(e,t)=>{if(e.length===0)return`
67
67
  **Available Contracts:**
68
68
 
69
69
  No contracts are currently defined. Use Basic Mode with inline schemas for all events.
@@ -164,19 +164,19 @@ Response preview:`),h.dim(t)].join(`
164
164
  `))},yt=async(e,t)=>{let{servicePath:r,description:n="",serviceType:o,packageManager:s}=e,i=r.split("/").pop()||r,a=sp(),c=Xo(a.workspaceRoot,er);rp(c,`generating:${r}`);let l=()=>{Zo(c)&&tp(c)},p=()=>{l(),process.exit(w.CANCELLED)};process.on("SIGINT",p),process.on("SIGTERM",p);try{console.log(h.cyan.bold(`
165
165
  \u{1F916} AI Generation
166
166
  `));let m=await ip(t,a,r,n,o,s),y=mp(m,i);if(!y)return!1;dp(y);let _=op({text:"Processing files...",color:"cyan"}).start(),be=ap(y.commands,o),N=gp(be,r,a.cwd),Zi=up(y.files,o);await zo(be,N,a.workspaceRoot);let{missingContractCommands:vn}=await Fo(Zi,N,a,_);if(y.postCommands.length>0)await Ar(y.postCommands,a.workspaceRoot);else if(vn.length>0){console.log(h.cyan(`\u{1F527} Auto-creating missing contracts...
167
- `));let Xi=vn.map(Qi=>({command:Qi,isPfCommand:!0}));await Ar(Xi,a.workspaceRoot)}return To(N),await Vo(y.dependencies,N,_),await No(N,_),!0}finally{process.off("SIGINT",p),process.off("SIGTERM",p),l()}};import{existsSync as Zv}from"fs";import{Project as fp,SyntaxKind as Qv}from"ts-morph";var ek=new fp({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0});v();import{promises as Ir}from"fs";import vt from"path";import Qo from"chalk";var es=async e=>{await K("bash",["-c",`
167
+ `));let Xi=vn.map(Qi=>({command:Qi,isPfCommand:!0}));await Ar(Xi,a.workspaceRoot)}return To(N),await Vo(y.dependencies,N,_),await No(N,_),!0}finally{process.off("SIGINT",p),process.off("SIGTERM",p),l()}};import{existsSync as Xv}from"fs";import{Project as fp,SyntaxKind as eC}from"ts-morph";var tC=new fp({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0});v();import{promises as Ir}from"fs";import vt from"path";import Qo from"chalk";var es=async e=>{await K("bash",["-c",`
168
168
  curl -fsSL https://bun.sh/install | bash && if [ -f "$HOME/.bun/bin/bun" ]; then export PATH="$HOME/.bun/bin:$PATH"; fi
169
- `],{task:e,shell:!0}),await Cp()},Rr=()=>Ee("bun"),ts=()=>Yt([{label:"Bun",value:59026,color:"magenta",barColor:"magenta"},{label:"Deno",value:25335},{label:"Node.js",value:19039}],{title:'Express.js "hello world" HTTP requests per second (Linux x64)',barColor:"blackBright"}),rs=()=>Yt([{label:"Bun",value:.36,color:"magenta",barColor:"magenta"},{label:"pnpm",value:6.44},{label:"npm",value:10.58},{label:"yarn",value:12.08}],{title:"Bun is an npm-compatible package manager.",unit:"s",footer:Qo.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),Cp=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){d.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let r=[vt.join(t,".zshrc"),vt.join(t,".bashrc"),vt.join(t,".bash_profile")];for(let n of r)try{if(await Ir.stat(n).then(()=>!0).catch(()=>!1)){(await Ir.readFile(n,"utf8")).includes(e)||(await Ir.appendFile(n,`
169
+ `],{task:e,shell:!0}),await kp()},Rr=()=>Ee("bun"),ts=()=>Yt([{label:"Bun",value:59026,color:"magenta",barColor:"magenta"},{label:"Deno",value:25335},{label:"Node.js",value:19039}],{title:'Express.js "hello world" HTTP requests per second (Linux x64)',barColor:"blackBright"}),rs=()=>Yt([{label:"Bun",value:.36,color:"magenta",barColor:"magenta"},{label:"pnpm",value:6.44},{label:"npm",value:10.58},{label:"yarn",value:12.08}],{title:"Bun is an npm-compatible package manager.",unit:"s",footer:Qo.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),kp=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){d.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let r=[vt.join(t,".zshrc"),vt.join(t,".bashrc"),vt.join(t,".bash_profile")];for(let n of r)try{if(await Ir.stat(n).then(()=>!0).catch(()=>!1)){(await Ir.readFile(n,"utf8")).includes(e)||(await Ir.appendFile(n,`
170
170
  # Added by platform installer
171
171
  ${e}
172
- `),d.log(`Added Bun path to ${vt.basename(n)}`));return}}catch(o){d.error(`Failed to update ${n}: ${o.message}`)}d.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),d.log(Qo.cyan(e))};f();import{existsSync as xt,mkdirSync as Mp,readFileSync as Dp,renameSync as jp,statSync as cs,unlinkSync as _p,writeFileSync as Lp}from"fs";import{join as We}from"path";import{existsSync as xp}from"fs";import{join as wp}from"path";import kt from"chalk";f();import Nr from"chalk";var ge=e=>{let t=Math.max(...e.commands.map(o=>o.name.length)),r=e.commands.map(o=>{let s=" ".repeat(t-o.name.length+3);return` ${Nr.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Nr.cyan.bold(`
172
+ `),d.log(`Added Bun path to ${vt.basename(n)}`));return}}catch(o){d.error(`Failed to update ${n}: ${o.message}`)}d.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),d.log(Qo.cyan(e))};f();import{existsSync as xt,mkdirSync as Mp,readFileSync as Dp,renameSync as jp,statSync as cs,unlinkSync as _p,writeFileSync as Lp}from"fs";import{join as We}from"path";import{existsSync as xp}from"fs";import{join as wp}from"path";import Ct from"chalk";f();import Nr from"chalk";var ge=e=>{let t=Math.max(...e.commands.map(o=>o.name.length)),r=e.commands.map(o=>{let s=" ".repeat(t-o.name.length+3);return` ${Nr.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Nr.cyan.bold(`
173
173
  ${e.title}
174
174
  `),`Available commands:
175
175
  `,...r,"",Nr.dim(`${n}
176
176
  `)].join(`
177
- `)};var Pp=(e,t)=>t.some(r=>r.name()===e),Sp=(e,t)=>t.pf?.commands?.[e]??null,bp=(e,t)=>!!t.scripts?.[e],Ep=(e,t)=>t.cwd?wp(e,t.cwd):e,Tp=(e,t)=>t.command||e,$p=(e,t,r,n)=>{let o=Ep(n,r),s=Tp(e,r);if(r.cwd&&!xp(o))return console.error(kt.red(`
177
+ `)};var Pp=(e,t)=>t.some(r=>r.name()===e),Sp=(e,t)=>t.pf?.commands?.[e]??null,bp=(e,t)=>!!t.scripts?.[e],Ep=(e,t)=>t.cwd?wp(e,t.cwd):e,Tp=(e,t)=>t.command||e,$p=(e,t,r,n)=>{let o=Ep(n,r),s=Tp(e,r);if(r.cwd&&!xp(o))return console.error(Ct.red(`
178
178
  \u2716 Directory not found: ${o}
179
- `)),!0;let i=r.cwd?kt.dim(` in ${r.cwd}/`):"";return console.log(kt.dim(`Running ${s}${i}`)),Yn(s,t,{cwd:o}),!0},Ap=(e,t,r)=>(console.log(kt.dim(`Running workspace script: ${e}`)),Fe(e,{args:t,cwd:r}),!0);async function Ip(e,t,r){if(Pp(e,r))return!1;let n;try{n=g()}catch{return!1}let o=F(n);if(!o)return!1;let s=Sp(e,o);return s?$p(e,t,s,n):bp(e,o)?Ap(e,t,n):!1}function ns(){let e;try{e=F()}catch{return{configured:[],scripts:[]}}if(!e)return{configured:[],scripts:[]};let t=Object.keys(e.pf?.commands??{}),n=Object.keys(e.scripts??{}).filter(o=>!t.includes(o));return{configured:t,scripts:n}}function Fr(){let{configured:e,scripts:t}=ns();return[...e,...t]}function os(){let{configured:e,scripts:t}=ns(),r=[...e,...t];if(r.length===0)return"";let o=F()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||Ct[i]||""}));return ge({title:"Workspace Commands",commands:s,footer:""})}function ss(e,t,r){let n=t.slice(2);if(n.length>0&&!n[0].startsWith("-")){let o=n[0],s=n.slice(1);if(o==="__workspace-commands"&&s.includes("--names-only")){let i=Fr();for(let a of i)console.log(a);return}Ip(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}f();var is={setup:"Configure platform settings",new:"Create a new project",dev:"Start development mode",event:"Event management commands",token:"Token management commands",audit:"Run security audit"},Ct={build:"Build all packages",test:"Run tests",lint:"Lint codebase",format:"Format code",preview:"Preview application",prepare:"Prepare workspace",pulumi:"Run Pulumi commands","pub-sdk":"Publish platform SDK","pub-cloudevents":"Publish cloudevents package","check-versions":"Check internal version consistency","sync-versions":"Sync internal package versions","sync-templates":"Sync service templates","generate-env":"Generate environment files",dev:"Start development environment"},as=(e,t)=>t?`${e}:${t}`:e,Rp=()=>Object.entries(is).map(([e,t])=>as(e,t)),Np=()=>{try{let e=Fr(),r=F()?.pf?.commands||{},n=Object.keys(is);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||Ct[o]||"";return as(o,s)})}catch{return[]}},Fp=()=>{try{let e=g(),t=x(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=Jt("@crossdelta/cloudevents");return n(r)}catch{return[]}},Op=async()=>{try{let e=g();return await vo(e)}catch{return[]}},Or=async()=>({commands:[...Rp(),...Np()],events:Fp(),services:await Op()});var _e="node_modules/.cache/pf",Le="completion-cache";var Wp=e=>{let t=R.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},Hp=e=>{let t=e.split(" ");if(t.length===4){let[o,s,i,a]=t;return{version:o,commands:s?s.split("|"):[],events:i?i.split("|"):[],services:a?a.split("|"):[]}}if(t.length===3){let[o,s,i]=t;return{version:o,commands:s?s.split("|"):[],events:i?i.split("|"):[],services:[]}}let[r,n]=t;return{commands:r?r.split("|"):[],events:n?n.split("|"):[],services:[]}},Bp=e=>{let t=We(e,_e);return We(t,Le)},Gp=(e,t=!1)=>{if(t)return!0;let r=Bp(e);if(!xt(r))return!0;let n=Dp(r,"utf-8").trim(),o=Hp(n),s=R.version||"0.0.0";if(o.version!==s)return!0;let i=We(e,"package.json");if(!xt(i))return!1;let a=cs(r).mtimeMs;return cs(i).mtimeMs>a};var Up=(e,t)=>{let r=We(e,_e),n=We(r,Le),o=`${n}.tmp.${process.pid}`;xt(r)||Mp(r,{recursive:!0});let s=Wp(t);try{Lp(o,s,"utf-8"),jp(o,n)}catch(i){try{xt(o)&&_p(o)}catch{}throw i}},wt=async(e={})=>{let t;try{t=g()}catch{return!1}if(!t)return!1;if(!Gp(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Or();return Up(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},He=async(e={})=>{await wt({...e,force:!0})};import{existsSync as Dr,readFileSync as gs,writeFileSync as us}from"fs";import{homedir as fs}from"os";import{join as Mr}from"path";import ue from"chalk";var ls=`${_e}/${Le}`,ps=e=>`# ${e} completion (workspace-local cache)
179
+ `)),!0;let i=r.cwd?Ct.dim(` in ${r.cwd}/`):"";return console.log(Ct.dim(`Running ${s}${i}`)),Yn(s,t,{cwd:o}),!0},Ap=(e,t,r)=>(console.log(Ct.dim(`Running workspace script: ${e}`)),Fe(e,{args:t,cwd:r}),!0);async function Ip(e,t,r){if(Pp(e,r))return!1;let n;try{n=g()}catch{return!1}let o=F(n);if(!o)return!1;let s=Sp(e,o);return s?$p(e,t,s,n):bp(e,o)?Ap(e,t,n):!1}function ns(){let e;try{e=F()}catch{return{configured:[],scripts:[]}}if(!e)return{configured:[],scripts:[]};let t=Object.keys(e.pf?.commands??{}),n=Object.keys(e.scripts??{}).filter(o=>!t.includes(o));return{configured:t,scripts:n}}function Fr(){let{configured:e,scripts:t}=ns();return[...e,...t]}function os(){let{configured:e,scripts:t}=ns(),r=[...e,...t];if(r.length===0)return"";let o=F()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||kt[i]||""}));return ge({title:"Workspace Commands",commands:s,footer:""})}function ss(e,t,r){let n=t.slice(2);if(n.length>0&&!n[0].startsWith("-")){let o=n[0],s=n.slice(1);if(o==="__workspace-commands"&&s.includes("--names-only")){let i=Fr();for(let a of i)console.log(a);return}Ip(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}f();var is={setup:"Configure platform settings",new:"Create a new project",dev:"Start development mode",event:"Event management commands",token:"Token management commands",audit:"Run security audit"},kt={build:"Build all packages",test:"Run tests",lint:"Lint codebase",format:"Format code",preview:"Preview application",prepare:"Prepare workspace",pulumi:"Run Pulumi commands","pub-sdk":"Publish platform SDK","pub-cloudevents":"Publish cloudevents package","check-versions":"Check internal version consistency","sync-versions":"Sync internal package versions","sync-templates":"Sync service templates","generate-env":"Generate environment files",dev:"Start development environment"},as=(e,t)=>t?`${e}:${t}`:e,Rp=()=>Object.entries(is).map(([e,t])=>as(e,t)),Np=()=>{try{let e=Fr(),r=F()?.pf?.commands||{},n=Object.keys(is);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||kt[o]||"";return as(o,s)})}catch{return[]}},Fp=()=>{try{let e=g(),t=x(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=Jt("@crossdelta/cloudevents");return n(r)}catch{return[]}},Op=async()=>{try{let e=g();return await vo(e)}catch{return[]}},Or=async()=>({commands:[...Rp(),...Np()],events:Fp(),services:await Op()});var _e="node_modules/.cache/pf",Le="completion-cache";var Wp=e=>{let t=R.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},Hp=e=>{let t=e.split(" ");if(t.length===4){let[o,s,i,a]=t;return{version:o,commands:s?s.split("|"):[],events:i?i.split("|"):[],services:a?a.split("|"):[]}}if(t.length===3){let[o,s,i]=t;return{version:o,commands:s?s.split("|"):[],events:i?i.split("|"):[],services:[]}}let[r,n]=t;return{commands:r?r.split("|"):[],events:n?n.split("|"):[],services:[]}},Bp=e=>{let t=We(e,_e);return We(t,Le)},Gp=(e,t=!1)=>{if(t)return!0;let r=Bp(e);if(!xt(r))return!0;let n=Dp(r,"utf-8").trim(),o=Hp(n),s=R.version||"0.0.0";if(o.version!==s)return!0;let i=We(e,"package.json");if(!xt(i))return!1;let a=cs(r).mtimeMs;return cs(i).mtimeMs>a};var Up=(e,t)=>{let r=We(e,_e),n=We(r,Le),o=`${n}.tmp.${process.pid}`;xt(r)||Mp(r,{recursive:!0});let s=Wp(t);try{Lp(o,s,"utf-8"),jp(o,n)}catch(i){try{xt(o)&&_p(o)}catch{}throw i}},wt=async(e={})=>{let t;try{t=g()}catch{return!1}if(!t)return!1;if(!Gp(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Or();return Up(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},He=async(e={})=>{await wt({...e,force:!0})};import{existsSync as Dr,readFileSync as gs,writeFileSync as us}from"fs";import{homedir as fs}from"os";import{join as Mr}from"path";import ue from"chalk";var ls=`${_e}/${Le}`,ps=e=>`# ${e} completion (workspace-local cache)
180
180
  # Generated: ${new Date().toISOString()}
181
181
 
182
182
  # Cache file path (relative to workspace root)
@@ -409,9 +409,9 @@ complete -F _${e}_completions ${e}`;var zp=(e,t)=>Mr(fs(),`.${t}-completion.${e}
409
409
  `)?`${r}${t}
410
410
  `:`${r}
411
411
  ${t}
412
- `;us(e,n,"utf-8")},qp=(e,t)=>{let r=zp(e,t),n=e==="zsh"?ps(t):ms(t);return us(r,n,"utf-8"),r},ds=(e,t,r)=>{let n=qp(e,t),o=hs(e),s=Vp(n);return Jp(o,s)?(r&&console.log(ue.dim(`[${e}] Already configured in ${o}`)),!1):(Kp(o,s),r&&console.log(ue.green(`[${e}] Added source line to ${o}`)),!0)},Yp=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",jr=(e,t=!1)=>{let r=Yp();t&&console.log(ue.cyan(`Installing ${r} completion...`)),ds(r,e,t);let n=r==="zsh"?"bash":"zsh",o=hs(n);Dr(o)&&ds(n,e,t),t&&(console.log(ue.green("\u2713 Shell completion installed")),console.log(ue.dim(` Run: ${ue.cyan("exec $SHELL")} to reload`)))};V();import{readdir as Wx}from"fs/promises";import{dirname as Bx,join as Gx}from"path";import{fileURLToPath as zx}from"url";import{runFlow as Jx}from"@crossdelta/flowcore";var Zp={debug:()=>{},info:console.log,warn:console.warn,error:console.error},ys=e=>e!==null&&typeof e=="object",vs=e=>typeof e=="string"&&e.length>0,ks=e=>typeof e=="string",_r=e=>typeof e=="function",Xp=(e,t)=>ys(e)?[!vs(e.name)&&`commands[${t}]: missing or invalid 'name'`,!ks(e.description)&&`commands[${t}]: missing or invalid 'description'`,!Array.isArray(e.args)&&`commands[${t}]: missing 'args' array`,!Array.isArray(e.options)&&`commands[${t}]: missing 'options' array`,!_r(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var Cs=e=>{if(!ys(e))return["Plugin must be an object"];let t=[!vs(e.name)&&"Missing or invalid 'name'",!ks(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!_r(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>Xp(n,o)):[];return[...t,...r]},Pt=(e,t=Zp)=>({workspace:e,logger:t}),St=async(e,t)=>{let{logger:r}=t;r.debug(`Loading plugin from module: ${e}`);let n=await import(e),o=n.createPfPlugin||n.default?.createPfPlugin;if(!_r(o))throw new Error(`Module ${e} does not export createPfPlugin`);let s=o({contractsPath:t.workspace.contracts.path,contractsPackage:t.workspace.contracts.packageName,availableServices:t.workspace.availableServices}),i=Cs(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
412
+ `;us(e,n,"utf-8")},qp=(e,t)=>{let r=zp(e,t),n=e==="zsh"?ps(t):ms(t);return us(r,n,"utf-8"),r},ds=(e,t,r)=>{let n=qp(e,t),o=hs(e),s=Vp(n);return Jp(o,s)?(r&&console.log(ue.dim(`[${e}] Already configured in ${o}`)),!1):(Kp(o,s),r&&console.log(ue.green(`[${e}] Added source line to ${o}`)),!0)},Yp=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",jr=(e,t=!1)=>{let r=Yp();t&&console.log(ue.cyan(`Installing ${r} completion...`)),ds(r,e,t);let n=r==="zsh"?"bash":"zsh",o=hs(n);Dr(o)&&ds(n,e,t),t&&(console.log(ue.green("\u2713 Shell completion installed")),console.log(ue.dim(` Run: ${ue.cyan("exec $SHELL")} to reload`)))};V();import{readdir as Hx}from"fs/promises";import{dirname as Gx,join as Ux}from"path";import{fileURLToPath as Vx}from"url";import{runFlow as Kx}from"@crossdelta/flowcore";var Zp={debug:()=>{},info:console.log,warn:console.warn,error:console.error},ys=e=>e!==null&&typeof e=="object",vs=e=>typeof e=="string"&&e.length>0,Cs=e=>typeof e=="string",_r=e=>typeof e=="function",Xp=(e,t)=>ys(e)?[!vs(e.name)&&`commands[${t}]: missing or invalid 'name'`,!Cs(e.description)&&`commands[${t}]: missing or invalid 'description'`,!Array.isArray(e.args)&&`commands[${t}]: missing 'args' array`,!Array.isArray(e.options)&&`commands[${t}]: missing 'options' array`,!_r(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var ks=e=>{if(!ys(e))return["Plugin must be an object"];let t=[!vs(e.name)&&"Missing or invalid 'name'",!Cs(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!_r(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>Xp(n,o)):[];return[...t,...r]},Pt=(e,t=Zp)=>({workspace:e,logger:t}),St=async(e,t)=>{let{logger:r}=t;r.debug(`Loading plugin from module: ${e}`);let n=await import(e),o=n.createPfPlugin||n.default?.createPfPlugin;if(!_r(o))throw new Error(`Module ${e} does not export createPfPlugin`);let s=o({contractsPath:t.workspace.contracts.path,contractsPackage:t.workspace.contracts.packageName,availableServices:t.workspace.availableServices}),i=ks(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
413
413
  - ${i.join(`
414
- - `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as Zx}from"@crossdelta/cloudevents";import{z as k}from"zod";var bt=k.object({dependencies:k.record(k.string(),k.string()).default({}),envVars:k.array(k.object({key:k.string(),description:k.string(),required:k.boolean().default(!0)})).default([]),adapterFile:k.string().optional()}),Qp=k.object({push:k.string().optional(),email:k.string().optional(),slack:k.string().optional(),sms:k.string().optional()}).optional(),em=k.object({defaults:Qp,providers:k.object({push:k.record(k.string(),bt).optional(),email:k.record(k.string(),bt).optional(),slack:k.record(k.string(),bt).optional(),sms:k.record(k.string(),bt).optional()}).optional()}),Qk=k.object({notifier:em.optional()});import{z as u}from"zod";var tm=u.object({type:u.literal("event"),eventType:u.string(),stream:u.string().optional()}),rm=u.object({type:u.literal("http"),method:u.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:u.string().optional()}),xs=u.discriminatedUnion("type",[tm,rm]),nm=u.object({type:u.literal("emit.event"),eventType:u.string()}),om=u.object({type:u.literal("notify"),channel:u.enum(["push","email","slack","sms"]),provider:u.string().optional()}),sm=u.object({type:u.literal("call.http"),name:u.string().optional(),baseUrl:u.string().optional()}),im=u.object({type:u.literal("persist"),store:u.enum(["db","kv","cache"]),entity:u.string().optional()}),ws=u.discriminatedUnion("type",[nm,om,sm,im]),Ps=u.object({serviceName:u.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:u.enum(["hono","nest"]).default("hono"),triggers:u.array(xs).min(1),actions:u.array(ws).default([])});var hm=(e,t,r)=>{let{stream:n,servicePath:o}=e,s=o.startsWith("/")?o:`${t.workspace.workspaceRoot}/${o}`;if(r?.dryRun)return{success:!0,message:`Would wire stream ${n} to ${o}`,changes:[{type:"update",path:s,description:`Wire ${n} stream to service`,preview:`consumeJetStreams({ streams: ['${n.toUpperCase()}'], ... })`}]};let i=yr(s,`${n.toLowerCase()}.event`);return i.warning?(t.logger.warn(i.warning),{success:!1,message:i.warning}):i.added?(t.logger.info(`Wired stream ${i.streamName} to service`),{success:!0,message:`Wired stream ${i.streamName}`}):(t.logger.debug(`Stream ${i.streamName} already wired`),{success:!0,message:`Stream ${i.streamName} already configured`})},ym=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
414
+ - `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as Xx}from"@crossdelta/cloudevents";import{z as C}from"zod";var bt=C.object({dependencies:C.record(C.string(),C.string()).default({}),envVars:C.array(C.object({key:C.string(),description:C.string(),required:C.boolean().default(!0)})).default([]),adapterFile:C.string().optional()}),Qp=C.object({push:C.string().optional(),email:C.string().optional(),slack:C.string().optional(),sms:C.string().optional()}).optional(),em=C.object({defaults:Qp,providers:C.object({push:C.record(C.string(),bt).optional(),email:C.record(C.string(),bt).optional(),slack:C.record(C.string(),bt).optional(),sms:C.record(C.string(),bt).optional()}).optional()}),ek=C.object({notifier:em.optional()});import{z as u}from"zod";var tm=u.object({type:u.literal("event"),eventType:u.string(),stream:u.string().optional()}),rm=u.object({type:u.literal("http"),method:u.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:u.string().optional()}),xs=u.discriminatedUnion("type",[tm,rm]),nm=u.object({type:u.literal("emit.event"),eventType:u.string()}),om=u.object({type:u.literal("notify"),channel:u.enum(["push","email","slack","sms"]),provider:u.string().optional()}),sm=u.object({type:u.literal("call.http"),name:u.string().optional(),baseUrl:u.string().optional()}),im=u.object({type:u.literal("persist"),store:u.enum(["db","kv","cache"]),entity:u.string().optional()}),ws=u.discriminatedUnion("type",[nm,om,sm,im]),Ps=u.object({serviceName:u.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:u.enum(["hono","nest"]).default("hono"),triggers:u.array(xs).min(1),actions:u.array(ws).default([])});var hm=(e,t,r)=>{let{stream:n,servicePath:o}=e,s=o.startsWith("/")?o:`${t.workspace.workspaceRoot}/${o}`;if(r?.dryRun)return{success:!0,message:`Would wire stream ${n} to ${o}`,changes:[{type:"update",path:s,description:`Wire ${n} stream to service`,preview:`consumeJetStreams({ streams: ['${n.toUpperCase()}'], ... })`}]};let i=yr(s,`${n.toLowerCase()}.event`);return i.warning?(t.logger.warn(i.warning),{success:!1,message:i.warning}):i.added?(t.logger.info(`Wired stream ${i.streamName} to service`),{success:!0,message:`Wired stream ${i.streamName}`}):(t.logger.debug(`Stream ${i.streamName} already wired`),{success:!0,message:`Stream ${i.streamName} already configured`})},ym=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
415
415
  import { createContract } from '@crossdelta/cloudevents'
416
416
  import { z } from 'zod'
417
417
 
@@ -427,7 +427,7 @@ export default handleEvent(${Lr(o)}Contract, async (data) => {
427
427
  console.log('Processing ${o}:', data)
428
428
  // TODO: Implement handler logic
429
429
  })
430
- `.trim();return{success:!0,message:`Would create handler for ${o}`,changes:[{type:"create",path:n,description:`Create event handler for ${o}`,preview:i.slice(0,500)}]}}return t.logger.debug(`Handler created: ${o} at ${n} (service: ${s})`),{success:!0}},km={"stream.wired":hm,"contract.created":ym,"handler.created":vm},Wr=(e,t,r)=>e.map(n=>{let o=km[n.kind];return o?o(n,t,r):(t.logger.warn(`Unknown effect kind: ${n.kind}`),{success:!1,message:`Unknown effect kind: ${n.kind}`})});import{join as It}from"path";import{deriveEventNames as cd}from"@crossdelta/cloudevents";var Hr=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});f();import{join as Gr}from"path";import{readFileSync as Cm}from"fs";import{join as xm}from"path";import wm from"handlebars";var fe=(e,t)=>yo(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),Br=(e,t={})=>{let r=Cm(e,"utf-8");return wm.compile(r)(t)},Et=e=>(t,r={})=>{let n=xm(e,t);return Br(n,r)};var G=e=>e.toUpperCase().replace(/-/g,"_");var bs=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Pm=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Sm=()=>{let e=Pm(),t=ee();return fe([Gr(e,"templates","hono-microservice"),Gr(e,"..","hono-microservice","templates"),Gr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Tt=(e,t={})=>Et(Sm())(e,t);function Es(){return Tt("tsconfig.json.hbs")}function Ts(e="1.2.23"){return Tt("Dockerfile.hbs",{bunVersion:e})}function $s(){return Tt("biome.json.hbs")}function As(e,t=[]){return Tt("src/config/env.ts.hbs",{envKey:G(e),envVars:t})}var bm=e=>{let t=["import './config/env'","import '@crossdelta/telemetry'",""];return e&&t.push("import { consumeJetStreams, isConsumerConnected } from '@crossdelta/cloudevents'"),t.push("import { Hono } from 'hono'"),t},Em=(e,t)=>{let r=[`const port = Number(process.env.${e}_PORT) || 8080`,"const app = new Hono()","","app.get('/health', (c) => {"," return c.json({ status: 'ok' })","})"];return t&&r.push("","app.get('/health/ready', (c) => {"," const ready = isConsumerConnected()"," return c.json({ status: ready ? 'ok' : 'not-ready' }, ready ? 200 : 503)","})"),r},Tm=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],$m=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],Am=e=>{let t=G(e.serviceName);return`${[...bm(e.hasEvents),"",...Em(t,e.hasEvents),...e.hasEvents?Tm(e.serviceName,e.streams):[],...$m()].join(`
430
+ `.trim();return{success:!0,message:`Would create handler for ${o}`,changes:[{type:"create",path:n,description:`Create event handler for ${o}`,preview:i.slice(0,500)}]}}return t.logger.debug(`Handler created: ${o} at ${n} (service: ${s})`),{success:!0}},Cm={"stream.wired":hm,"contract.created":ym,"handler.created":vm},Wr=(e,t,r)=>e.map(n=>{let o=Cm[n.kind];return o?o(n,t,r):(t.logger.warn(`Unknown effect kind: ${n.kind}`),{success:!1,message:`Unknown effect kind: ${n.kind}`})});import{join as It}from"path";import{deriveEventNames as cd}from"@crossdelta/cloudevents";var Hr=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});f();import{join as Gr}from"path";import{readFileSync as km}from"fs";import{join as xm}from"path";import wm from"handlebars";var fe=(e,t)=>yo(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),Br=(e,t={})=>{let r=km(e,"utf-8");return wm.compile(r)(t)},Et=e=>(t,r={})=>{let n=xm(e,t);return Br(n,r)};var G=e=>e.toUpperCase().replace(/-/g,"_");var bs=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Pm=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Sm=()=>{let e=Pm(),t=ee();return fe([Gr(e,"templates","hono-microservice"),Gr(e,"..","hono-microservice","templates"),Gr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Tt=(e,t={})=>Et(Sm())(e,t);function Es(){return Tt("tsconfig.json.hbs")}function Ts(e="1.2.23"){return Tt("Dockerfile.hbs",{bunVersion:e})}function $s(){return Tt("biome.json.hbs")}function As(e,t=[]){return Tt("src/config/env.ts.hbs",{envKey:G(e),envVars:t})}var bm=e=>{let t=["import './config/env'","import '@crossdelta/telemetry'",""];return e&&t.push("import { consumeJetStreams, isConsumerConnected } from '@crossdelta/cloudevents'"),t.push("import { Hono } from 'hono'"),t},Em=(e,t)=>{let r=[`const port = Number(process.env.${e}_PORT) || 8080`,"const app = new Hono()","","app.get('/health', (c) => {"," return c.json({ status: 'ok' })","})"];return t&&r.push("","app.get('/health/ready', (c) => {"," const ready = isConsumerConnected()"," return c.json({ status: ready ? 'ok' : 'not-ready' }, ready ? 200 : 503)","})"),r},Tm=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],$m=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],Am=e=>{let t=G(e.serviceName);return`${[...bm(e.hasEvents),"",...Em(t,e.hasEvents),...e.hasEvents?Tm(e.serviceName,e.streams):[],...$m()].join(`
431
431
  `)}
432
432
  `},Im=e=>{let t={hono:"^4.6.14","@crossdelta/telemetry":"workspace:*",zod:"^4.1.0",[`${e.workspaceScope}/contracts`]:"workspace:*"};e.hasEvents&&(t["@crossdelta/cloudevents"]="workspace:*");let r={name:e.packageName,version:"0.0.1",type:"module",scripts:{"start:dev":"bun --watch src/index.ts",start:"bun src/index.ts",test:"bun test"},dependencies:t,devDependencies:{"@types/bun":"^1.2.23"}};return JSON.stringify(r,null,2)},Rm=e=>`# ${e.serviceName}
433
433
 
@@ -519,9 +519,9 @@ export default handleEvent(${n}, async (data: ${o}) => {
519
519
  console.log('\u{1F4E6} [${e}] Event received:', data)
520
520
  // TODO: Inject and call service
521
521
  })
522
- `},td=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:he(r,"stub").delegateFromHandler?t.events.map(o=>{let s=Ge(o),i=he(r,s);return{kind:"file:write",path:Vr(e,i.filePath),content:Qm(o,t.workspaceScope)}}):[],rd=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=Jr(n),s=zr(r,o);return{kind:"file:write",path:Vr(e,s.filePath),content:ed(n,t.workspaceScope,r)}}),nd=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",Bs=(e,t,r,n)=>{let o=nd(n.framework),s=Ym(e,t),i=td(e,r,o),a=rd(e,r,o),c=Zm(r.serviceName,r.port,n),l=Xm(r.envVarName,r.port);return[...s,...i,...a,c,l]};import{existsSync as od,readdirSync as sd,readFileSync as id}from"fs";import{join as Gs}from"path";var Us=4001,ad=e=>{let t=e.match(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/);if(t)return Number.parseInt(t[1],10);let r=e.match(/containerPort:\s*(\d+)/);return r?Number.parseInt(r[1],10):null},zs=e=>{try{let t=Gs(e,"infra","services");return od(t)?sd(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=id(Gs(t,o),"utf-8"),i=ad(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},Kr=(e,t)=>e.has(t)?Kr(e,t+1):t;var ld=e=>{if(!e||e.trim().length===0)throw new Error("Service name cannot be empty");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e))throw new Error(`Service name '${e}' must be kebab-case (lowercase, alphanumeric, hyphens only)`)},pd=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return It(r,t);if(t.includes("/"))return It(r,t)}let n=E(r);return It(r,n.services,e)},md=e=>[...new Set(e.map(t=>cd(t).streamName))],dd=(e,t,r,n)=>{let s=x(t).packageName.split("/")[0],i=e.events??[],a=i.length>0||e.hasEvents||!1,c=i.length>0?md(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:G(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},gd=(e,t)=>e.files.filter(r=>!r.skip||!r.skip(t)).map(r=>({path:r.path,content:r.content(t)})),ud=(e,t,r)=>[...e.map(o=>({type:"file",path:It(r,o.path),description:`Service file: ${o.path}`})),{type:"config",path:`infra/services/${t}.ts`,description:"Infrastructure configuration"},{type:"env",path:".env.local",description:"Environment variables"}],fd=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],Vs=e=>{ld(e.name);let t=e.workspaceRoot??g(),r=pd(e.name,e.path,t),n=e.port??Kr(zs(t),Us),o=dd(e,t,r,n),s=Ws(e.type),i=gd(s,o),a=Bs(r,i,o,s),c=ud(i,e.name,r),l=fd(r);return Hr("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:l,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},Js=e=>{let t=Vs(e);if(!t.ok||!t.data)throw new Error(t.summary);return{serviceName:t.data.serviceName,servicePath:t.data.servicePath,port:t.data.port,effects:t.changes,vars:t.data.vars}};f();f();f();import A from"chalk";import{execa as hd}from"execa";import{createJiti as yd}from"jiti";var qr=async e=>{let{stdout:t}=await hd("sh",["-c",e]);return t.trim()},vd="pf-local-nats",kd="2.10-alpine",Cd=4222,xd=8222,wd=e=>({clientPort:e.clientPort??Cd,monitoringPort:e.monitoringPort??xd,containerName:e.containerName??vd,version:e.version??kd}),Pd=e=>["run","--rm","--detach",`--name=${e.containerName}`,`-p=${e.clientPort}:4222`,`-p=${e.monitoringPort}:8222`,`nats:${e.version}`,"--jetstream","--store_dir=/data","--http_port=8222"],Sd=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),bd=async()=>{try{return await qr("docker info"),!0}catch{return!1}},Ed=async e=>{try{return(await qr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var Td=async e=>{let t=Pd(e);try{return await qr(`docker ${t.join(" ")}`),{success:!0,value:Sd(e)}}catch{return{success:!1}}},$d=e=>{console.log(A.green("\u2713 NATS started")),console.log(A.dim(` Client: ${e.clientUrl}`)),console.log(A.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(A.dim(" Streams: ephemeral, auto-created by services")),console.log("")},Ks=async(e={})=>{let t=wd(e);if(!await bd())return console.log(A.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await Ed(t.containerName))return console.log(A.dim("\u2713 NATS already running")),!0;console.log(A.cyan("\u{1F680} Starting development infrastructure...")),console.log(A.dim(" NATS with JetStream (ephemeral)"));let r=await Td(t);return r.success?($d(r.value),!0):(console.error(A.red("\u2717 Failed to start NATS")),!1)},Ad=e=>e.map(t=>({stream:t,subjects:[`${t.toLowerCase()}.*`],config:{storage:"memory",retention:"limits",maxAge:36e5}})),Id=e=>Array.from(new Set(Object.values(e).filter(t=>t!==null&&typeof t=="object"&&"channel"in t).map(t=>t.channel?.stream).filter(t=>!!t))),Rd=e=>{if(!(e instanceof Error))return!0;let t=e.message.toLowerCase();return!t.includes("insufficient storage")&&!t.includes("connection refused")},Nd=e=>{if(!(e instanceof Error))return"Unknown error";let t=e.message.toLowerCase();return t.includes("insufficient storage")?["NATS has insufficient storage to create streams."," Your disk is likely full. Free space and restart:",""," docker system prune -af"," pf dev"].join(`
523
- `):t.includes("connection refused")?"Cannot connect to NATS \u2014 is the container running?":e.message},Yr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=x(e),o=await yd(e,{moduleCache:!1}).import(r,{default:!0}),s=Id(o);if(s.length===0){console.log(A.dim(" No streams found in contracts"));return}let i=Ad(s);await t({streams:i}),console.log(A.dim(` Created ${s.length} ephemeral stream(s): ${s.join(", ")}`))}catch(t){if(!Rd(t))throw console.error(A.red(`
524
- \u2717 ${Nd(t)}
522
+ `},td=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:he(r,"stub").delegateFromHandler?t.events.map(o=>{let s=Ge(o),i=he(r,s);return{kind:"file:write",path:Vr(e,i.filePath),content:Qm(o,t.workspaceScope)}}):[],rd=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=Jr(n),s=zr(r,o);return{kind:"file:write",path:Vr(e,s.filePath),content:ed(n,t.workspaceScope,r)}}),nd=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",Bs=(e,t,r,n)=>{let o=nd(n.framework),s=Ym(e,t),i=td(e,r,o),a=rd(e,r,o),c=Zm(r.serviceName,r.port,n),l=Xm(r.envVarName,r.port);return[...s,...i,...a,c,l]};import{existsSync as od,readdirSync as sd,readFileSync as id}from"fs";import{join as Gs}from"path";var Us=4001,ad=e=>{let t=e.match(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/);if(t)return Number.parseInt(t[1],10);let r=e.match(/containerPort:\s*(\d+)/);return r?Number.parseInt(r[1],10):null},zs=e=>{try{let t=Gs(e,"infra","services");return od(t)?sd(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=id(Gs(t,o),"utf-8"),i=ad(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},Kr=(e,t)=>e.has(t)?Kr(e,t+1):t;var ld=e=>{if(!e||e.trim().length===0)throw new Error("Service name cannot be empty");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(e))throw new Error(`Service name '${e}' must be kebab-case (lowercase, alphanumeric, hyphens only)`)},pd=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return It(r,t);if(t.includes("/"))return It(r,t)}let n=E(r);return It(r,n.services,e)},md=e=>[...new Set(e.map(t=>cd(t).streamName))],dd=(e,t,r,n)=>{let s=x(t).packageName.split("/")[0],i=e.events??[],a=i.length>0||e.hasEvents||!1,c=i.length>0?md(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:G(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},gd=(e,t)=>e.files.filter(r=>!r.skip||!r.skip(t)).map(r=>({path:r.path,content:r.content(t)})),ud=(e,t,r)=>[...e.map(o=>({type:"file",path:It(r,o.path),description:`Service file: ${o.path}`})),{type:"config",path:`infra/services/${t}.ts`,description:"Infrastructure configuration"},{type:"env",path:".env.local",description:"Environment variables"}],fd=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],Vs=e=>{ld(e.name);let t=e.workspaceRoot??g(),r=pd(e.name,e.path,t),n=e.port??Kr(zs(t),Us),o=dd(e,t,r,n),s=Ws(e.type),i=gd(s,o),a=Bs(r,i,o,s),c=ud(i,e.name,r),l=fd(r);return Hr("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:l,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},Js=e=>{let t=Vs(e);if(!t.ok||!t.data)throw new Error(t.summary);return{serviceName:t.data.serviceName,servicePath:t.data.servicePath,port:t.data.port,effects:t.changes,vars:t.data.vars}};f();import{isElicitInputEffect as hd}from"@crossdelta/shared/plugin-types";f();f();import A from"chalk";import{execa as yd}from"execa";import{createJiti as vd}from"jiti";var qr=async e=>{let{stdout:t}=await yd("sh",["-c",e]);return t.trim()},Cd="pf-local-nats",kd="2.10-alpine",xd=4222,wd=8222,Pd=e=>({clientPort:e.clientPort??xd,monitoringPort:e.monitoringPort??wd,containerName:e.containerName??Cd,version:e.version??kd}),Sd=e=>["run","--rm","--detach",`--name=${e.containerName}`,`-p=${e.clientPort}:4222`,`-p=${e.monitoringPort}:8222`,`nats:${e.version}`,"--jetstream","--store_dir=/data","--http_port=8222"],bd=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),Ed=async()=>{try{return await qr("docker info"),!0}catch{return!1}},Td=async e=>{try{return(await qr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var $d=async e=>{let t=Sd(e);try{return await qr(`docker ${t.join(" ")}`),{success:!0,value:bd(e)}}catch{return{success:!1}}},Ad=e=>{console.log(A.green("\u2713 NATS started")),console.log(A.dim(` Client: ${e.clientUrl}`)),console.log(A.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(A.dim(" Streams: ephemeral, auto-created by services")),console.log("")},Ks=async(e={})=>{let t=Pd(e);if(!await Ed())return console.log(A.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await Td(t.containerName))return console.log(A.dim("\u2713 NATS already running")),!0;console.log(A.cyan("\u{1F680} Starting development infrastructure...")),console.log(A.dim(" NATS with JetStream (ephemeral)"));let r=await $d(t);return r.success?(Ad(r.value),!0):(console.error(A.red("\u2717 Failed to start NATS")),!1)},Id=e=>e.map(t=>({stream:t,subjects:[`${t.toLowerCase()}.*`],config:{storage:"memory",retention:"limits",maxAge:36e5}})),Rd=e=>Array.from(new Set(Object.values(e).filter(t=>t!==null&&typeof t=="object"&&"channel"in t).map(t=>t.channel?.stream).filter(t=>!!t))),Nd=e=>{if(!(e instanceof Error))return!0;let t=e.message.toLowerCase();return!t.includes("insufficient storage")&&!t.includes("connection refused")},Fd=e=>{if(!(e instanceof Error))return"Unknown error";let t=e.message.toLowerCase();return t.includes("insufficient storage")?["NATS has insufficient storage to create streams."," Your disk is likely full. Free space and restart:",""," docker system prune -af"," pf dev"].join(`
523
+ `):t.includes("connection refused")?"Cannot connect to NATS \u2014 is the container running?":e.message},Yr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=x(e),o=await vd(e,{moduleCache:!1}).import(r,{default:!0}),s=Rd(o);if(s.length===0){console.log(A.dim(" No streams found in contracts"));return}let i=Id(s);await t({streams:i}),console.log(A.dim(` Created ${s.length} ephemeral stream(s): ${s.join(", ")}`))}catch(t){if(!Nd(t))throw console.error(A.red(`
524
+ \u2717 ${Fd(t)}
525
525
  `)),t;console.log(A.yellow(` \u26A0\uFE0F Stream creation failed: ${t instanceof Error?t.message:"Unknown error"}`)),console.log(A.dim(" Streams will be created when services connect"))}};function qs(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
526
526
  import { ports } from '@crossdelta/infrastructure'
527
527
 
@@ -564,53 +564,53 @@ const config: K8sServiceConfig = {
564
564
  }
565
565
 
566
566
  export default config
567
- `}v();import ne from"chalk";import Od from"terminal-link";var Rt="integrations-run";import{z as T}from"zod";var Fd=T.object({name:T.string(),description:T.string(),link:T.url().optional(),install:T.union([T.string(),T.array(T.string())]).transform(e=>Array.isArray(e)?e:[e]),installFlags:T.array(T.string()).optional(),run:T.array(T.string()).optional(),initial:T.boolean().optional(),interactive:T.boolean().optional()}),Zs=T.array(Fd);var Xs=e=>{try{return Zs.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
567
+ `}v();import ne from"chalk";import Md from"terminal-link";var Rt="integrations-run";import{z as T}from"zod";var Od=T.object({name:T.string(),description:T.string(),link:T.url().optional(),install:T.union([T.string(),T.array(T.string())]).transform(e=>Array.isArray(e)?e:[e]),installFlags:T.array(T.string()).optional(),run:T.array(T.string()).optional(),initial:T.boolean().optional(),interactive:T.boolean().optional()}),Zs=T.array(Od);var Xs=e=>{try{return Zs.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
568
568
  `))}};var D=()=>{try{let e=Re("bin/integration.collection.json");return Xs(e)}catch(e){throw new Error(`Failed to load integrations!
569
569
  Check your integration.collection.json:
570
- ${e.message}`)}},ye=()=>D().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),Md=e=>!!e?.name&&!!e?.link&&!!e?.description,Nt=e=>{let t=D();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(Md);r.length&&(d.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=d.getStoredLogs(`${Rt}:${n}`);o&&d.log(`${Od(ne.cyan(n),o)} - ${s}`),i.length&&d.log(i.map(a=>` \u203A ${ne.dim(a.message)}`).join(`
571
- `))}))},Dd=e=>e.toUpperCase().replace(/-/g,"_"),Qs=(e,t)=>{let r=Dd(e);d.breakLine().log(ne.bold("Environment variables:")).log(ne.dim(" Local (.env.local):")).log(ne.cyan(` ${r}_PORT=${t}`)).breakLine().log(ne.dim(" Production (auto-injected by infra):")).log(ne.cyan(` PORT=${t}`))};v();import ei from"chalk";var jd=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},ti=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=b(),task:o}=e;if(!t?.length||!o)return;let s=_d(t,r,n,o);await rt(o,s)},_d=(e,t,r,n)=>{let s=D()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:l,version:p}=jd(c);return{title:ei.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{it(`dependencies.${l}`,p,t)}}})),i={title:ei.cyanBright("Installing packages..."),fn:async()=>{await L({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};v();import Ld from"chalk";var ri=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=Wd(t,r,n,e.packageManager);await rt(n,o)},Wd=(e,t,r,n)=>D().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:Ld.cyanBright(`Running "${i}" for ${s.name}
572
- `),fn:()=>Hd(s,i,t,r,n)}))),Hd=async(e,t,r,n,o)=>{let s=`${Rt}:${e.name}`;try{if(e.interactive)return to(t,[],{cwd:r,context:s,task:n,manager:o});await Ne(t,[],{cwd:r,task:n,context:s})}catch(i){d.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};v();import{readFileSync as Vw,writeFileSync as Jw}from"fs";import{join as qw}from"path";v();import{join as Qw}from"path";import{ListrEnquirerPromptAdapter as Ue}from"@listr2/prompt-adapter-enquirer";var C=e=>({select:async t=>e.prompt(Ue).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Ue).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Ue).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Ue).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Ue).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});v();import{readFileSync as gP}from"fs";import{join as fP}from"path";import bP from"chalk";import TP from"cli-table3";v();function Ft(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function ni(e,t,r={},n=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=n.map(l=>t[l]).filter(l=>l!==void 0),i=o.map(l=>{let p=t[l];if(!(p===!1||p===void 0))return p===!0?`--${Ft(String(l))}`:`--${Ft(String(l))}=${String(p)}`}).filter(l=>l!==void 0),a=Object.entries(r).map(([l,p])=>{if(!(p===!1||p===void 0))return p===!0?`--${Ft(l)}`:`--${Ft(l)}=${String(p)}`}).filter(l=>l!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})}import{basename as mg}from"path";import oe from"chalk";f();var ve={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=C(t);if(e.userConfirmed=await r.toggle({initial:!0,message:"\u{1F680} Ready to launch your project?"}),!e.userConfirmed)throw new Error("Project creation was canceled by the user.")}};import{existsSync as Zr,readdirSync as Gd,readFileSync as Ud,writeFileSync as zd}from"fs";import{basename as Vd,join as Xr}from"path";var Jd=4001,Kd=4e3;function qd(e){let t=[],r=e.matchAll(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/g);for(let c of r)t.push(Number(c[1]));let n=e.matchAll(/\.add(?:Http|Grpc)?\((\d+)/g);for(let c of n)t.push(Number(c[1]));let o=e.match(/containerPort\s*:\s*(\d+)/);o&&t.push(Number(o[1]));let s=e.match(/internalPorts\s*:\s*\[([^\]]+)\]/);if(s){let c=s[1].match(/\d+/g);c&&t.push(...c.map(Number))}let i=e.match(/httpPort\s*:\s*(\d+)/);i&&t.push(Number(i[1]));let a=e.matchAll(/const\s+\w*[pP]ort\w*\s*=\s*(\d+)/g);for(let c of a)t.push(Number(c[1]));return t}function Yd(e,t){let r=t?Jd:Kd,n=new Set;if(!Zr(e))return r;let o=Gd(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=Xr(e,i);try{let c=Ud(a,"utf-8"),l=qd(c);for(let p of l)n.add(p)}catch{}}let s=r;for(;n.has(s);)s++;return s}function Zd(e){return Vd(e)}var Ot={title:"Creating infrastructure service config",task:async(e,t)=>{let r=Zd(e.projectName),n=g(),o=Xr(n,"infra","services");if(!Zr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=Xr(o,`${r}.ts`);if(Zr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=Yd(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?qs(r,i):Ys(r,i);zd(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as Mt}from"child_process";import{existsSync as Xd}from"fs";import{join as Qd}from"path";var eg=()=>{try{return Mt("git --version",{stdio:"ignore"}),!0}catch{return!1}},tg=e=>Xd(Qd(e,".git")),oi={title:"Initializing git repository",enabled:()=>eg(),skip:e=>tg(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{Mt("git init",{cwd:e.cwd,stdio:"ignore"}),Mt("git add -A",{cwd:e.cwd,stdio:"ignore"}),Mt('git commit -m "chore: initial commit"',{cwd:e.cwd,stdio:"ignore",env:{...process.env,GIT_AUTHOR_NAME:process.env.GIT_AUTHOR_NAME||"Platform SDK",GIT_AUTHOR_EMAIL:process.env.GIT_AUTHOR_EMAIL||"platform-sdk@localhost",GIT_COMMITTER_NAME:process.env.GIT_COMMITTER_NAME||"Platform SDK",GIT_COMMITTER_EMAIL:process.env.GIT_COMMITTER_EMAIL||"platform-sdk@localhost"}}),t.title="Git repository initialized with initial commit"}catch{t.title="Git initialization skipped (git error)"}}};import si from"chalk";v();var ke={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Rr(),task:async(e,t)=>M(t,async r=>{await es(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},Ce={enabled:e=>!Rr()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=C(t);console.log(["",`${si.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${si.underline("https://bun.sh")}`,ts(),rs()].join(`
573
- `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import ii from"chalk";v();var Dt={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>M(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await ti({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},jt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=C(t);e.selectedIntegrations=await r.multiSelect({hint:"\\nPress <space> to select/deselect, <enter> to confirm, <i> to invert selection",message:"Which integrations would you like to include?",initial:ye().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[ii.bold(n),o].join(" - "),value:n}))}),!e.selectedIntegrations||e.selectedIntegrations.length===0?t.title="No integrations selected.":t.title=["Selected integrations:",...e.selectedIntegrations.map(n=>ii.bold(`\u2022 ${n}`))].join("\\n")}};v();var ai={title:"Install Nest CLI",task:async(e,t)=>M(t,async r=>{await eo({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};v();var _t={title:"Install dependencies",task:async(e,t)=>M(t,async r=>{await L({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import rg from"chalk";v();var xe={enabled:e=>!e.removeDir&&!et(e.cwd),task:async(e,t)=>{let r=C(t);if(e.removeDir=await r.toggle({message:rg.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},we={enabled:e=>!!e.removeDir,task:async e=>_n(e.cwd)};v();var Lt={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>M(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await ri({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};v();var ng=["services/my-hono-service","services/my-nest-service","my-platform"],Pe={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?ng.includes(e.projectName):!0,task:async(e,t)=>{let r=C(t);e.projectName=await r.input({initial:e.projectName,message:"Enter project name",validate:n=>n?!0:"Project name is required."}),e.cwd&&(e.cwd=O(e.projectName))}};import ci from"chalk";var Se={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=dr(),e.packageManager){t.title=`Using ${ci.bold(e.packageManager)} as package manager.`;return}let r=C(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:Qn().map(n=>({name:n,value:n}))}),t.title=`Using ${ci.bold(e.packageManager)} as package manager.`}};import Wt from"chalk";var li={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${Wt.bold(e.githubOwner)}`;return}let r=C(t);e.githubOwner=await r.input({message:"Enter GitHub organization or username",initial:"my-org",validate:n=>n?.trim()?!0:"GitHub owner is required."}),t.title=`GitHub owner: ${Wt.bold(e.githubOwner)}`}},pi={title:"Include GitHub CI/CD",task:async(e,t)=>{if(e.includeGitHubCI!==void 0){t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD";return}let r=C(t);e.includeGitHubCI=await r.toggle({message:"Include GitHub Actions workflows and CI/CD?",initial:!0,enabled:"Yes",disabled:"No"}),t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD"}};var mi={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${Wt.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=C(t);e.pulumiStackBase=await s.input({message:"Enter Pulumi stack base name (org/project)",initial:o,validate:i=>i?.trim()?i.includes("/")?!0:"Format should be org/project (e.g., myorg/myproject)":"Pulumi stack name is required."}),t.title=`Pulumi stack: ${Wt.bold(e.pulumiStackBase)}`}};v();import{mkdirSync as og,writeFileSync as sg}from"fs";import{dirname as ig}from"path";v();var ag=e=>e==="hono"?"hono":"nestjs",cg=e=>{let t=ig(e.path);og(t,{recursive:!0}),sg(e.path,e.content,"utf-8")},lg=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=At(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
570
+ ${e.message}`)}},ye=()=>D().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),Dd=e=>!!e?.name&&!!e?.link&&!!e?.description,Nt=e=>{let t=D();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(Dd);r.length&&(d.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=d.getStoredLogs(`${Rt}:${n}`);o&&d.log(`${Md(ne.cyan(n),o)} - ${s}`),i.length&&d.log(i.map(a=>` \u203A ${ne.dim(a.message)}`).join(`
571
+ `))}))},jd=e=>e.toUpperCase().replace(/-/g,"_"),Qs=(e,t)=>{let r=jd(e);d.breakLine().log(ne.bold("Environment variables:")).log(ne.dim(" Local (.env.local):")).log(ne.cyan(` ${r}_PORT=${t}`)).breakLine().log(ne.dim(" Production (auto-injected by infra):")).log(ne.cyan(` PORT=${t}`))};v();import ei from"chalk";var _d=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},ti=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=b(),task:o}=e;if(!t?.length||!o)return;let s=Ld(t,r,n,o);await rt(o,s)},Ld=(e,t,r,n)=>{let s=D()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:l,version:p}=_d(c);return{title:ei.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{it(`dependencies.${l}`,p,t)}}})),i={title:ei.cyanBright("Installing packages..."),fn:async()=>{await L({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};v();import Wd from"chalk";var ri=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=Hd(t,r,n,e.packageManager);await rt(n,o)},Hd=(e,t,r,n)=>D().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:Wd.cyanBright(`Running "${i}" for ${s.name}
572
+ `),fn:()=>Bd(s,i,t,r,n)}))),Bd=async(e,t,r,n,o)=>{let s=`${Rt}:${e.name}`;try{if(e.interactive)return to(t,[],{cwd:r,context:s,task:n,manager:o});await Ne(t,[],{cwd:r,task:n,context:s})}catch(i){d.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};v();import{readFileSync as Jw,writeFileSync as Kw}from"fs";import{join as Yw}from"path";v();import{join as eP}from"path";import{ListrEnquirerPromptAdapter as Ue}from"@listr2/prompt-adapter-enquirer";var k=e=>({select:async t=>e.prompt(Ue).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Ue).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Ue).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Ue).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Ue).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});v();import{readFileSync as uP}from"fs";import{join as hP}from"path";import EP from"chalk";import $P from"cli-table3";v();function Ft(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function ni(e,t,r={},n=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=n.map(l=>t[l]).filter(l=>l!==void 0),i=o.map(l=>{let p=t[l];if(!(p===!1||p===void 0))return p===!0?`--${Ft(String(l))}`:`--${Ft(String(l))}=${String(p)}`}).filter(l=>l!==void 0),a=Object.entries(r).map(([l,p])=>{if(!(p===!1||p===void 0))return p===!0?`--${Ft(l)}`:`--${Ft(l)}=${String(p)}`}).filter(l=>l!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})}import{basename as dg}from"path";import oe from"chalk";f();var ve={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=k(t);if(e.userConfirmed=await r.toggle({initial:!0,message:"\u{1F680} Ready to launch your project?"}),!e.userConfirmed)throw new Error("Project creation was canceled by the user.")}};import{existsSync as Zr,readdirSync as Ud,readFileSync as zd,writeFileSync as Vd}from"fs";import{basename as Jd,join as Xr}from"path";var Kd=4001,qd=4e3;function Yd(e){let t=[],r=e.matchAll(/ports\(\)\.(?:http|https|grpc|primary)\((\d+)\)/g);for(let c of r)t.push(Number(c[1]));let n=e.matchAll(/\.add(?:Http|Grpc)?\((\d+)/g);for(let c of n)t.push(Number(c[1]));let o=e.match(/containerPort\s*:\s*(\d+)/);o&&t.push(Number(o[1]));let s=e.match(/internalPorts\s*:\s*\[([^\]]+)\]/);if(s){let c=s[1].match(/\d+/g);c&&t.push(...c.map(Number))}let i=e.match(/httpPort\s*:\s*(\d+)/);i&&t.push(Number(i[1]));let a=e.matchAll(/const\s+\w*[pP]ort\w*\s*=\s*(\d+)/g);for(let c of a)t.push(Number(c[1]));return t}function Zd(e,t){let r=t?Kd:qd,n=new Set;if(!Zr(e))return r;let o=Ud(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=Xr(e,i);try{let c=zd(a,"utf-8"),l=Yd(c);for(let p of l)n.add(p)}catch{}}let s=r;for(;n.has(s);)s++;return s}function Xd(e){return Jd(e)}var Ot={title:"Creating infrastructure service config",task:async(e,t)=>{let r=Xd(e.projectName),n=g(),o=Xr(n,"infra","services");if(!Zr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=Xr(o,`${r}.ts`);if(Zr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=Zd(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?qs(r,i):Ys(r,i);Vd(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as Mt}from"child_process";import{existsSync as Qd}from"fs";import{join as eg}from"path";var tg=()=>{try{return Mt("git --version",{stdio:"ignore"}),!0}catch{return!1}},rg=e=>Qd(eg(e,".git")),oi={title:"Initializing git repository",enabled:()=>tg(),skip:e=>rg(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{Mt("git init",{cwd:e.cwd,stdio:"ignore"}),Mt("git add -A",{cwd:e.cwd,stdio:"ignore"}),Mt('git commit -m "chore: initial commit"',{cwd:e.cwd,stdio:"ignore",env:{...process.env,GIT_AUTHOR_NAME:process.env.GIT_AUTHOR_NAME||"Platform SDK",GIT_AUTHOR_EMAIL:process.env.GIT_AUTHOR_EMAIL||"platform-sdk@localhost",GIT_COMMITTER_NAME:process.env.GIT_COMMITTER_NAME||"Platform SDK",GIT_COMMITTER_EMAIL:process.env.GIT_COMMITTER_EMAIL||"platform-sdk@localhost"}}),t.title="Git repository initialized with initial commit"}catch{t.title="Git initialization skipped (git error)"}}};import si from"chalk";v();var Ce={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Rr(),task:async(e,t)=>M(t,async r=>{await es(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},ke={enabled:e=>!Rr()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=k(t);console.log(["",`${si.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${si.underline("https://bun.sh")}`,ts(),rs()].join(`
573
+ `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import ii from"chalk";v();var Dt={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>M(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await ti({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},jt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=k(t);e.selectedIntegrations=await r.multiSelect({hint:"\\nPress <space> to select/deselect, <enter> to confirm, <i> to invert selection",message:"Which integrations would you like to include?",initial:ye().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[ii.bold(n),o].join(" - "),value:n}))}),!e.selectedIntegrations||e.selectedIntegrations.length===0?t.title="No integrations selected.":t.title=["Selected integrations:",...e.selectedIntegrations.map(n=>ii.bold(`\u2022 ${n}`))].join("\\n")}};v();var ai={title:"Install Nest CLI",task:async(e,t)=>M(t,async r=>{await eo({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};v();var _t={title:"Install dependencies",task:async(e,t)=>M(t,async r=>{await L({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import ng from"chalk";v();var xe={enabled:e=>!e.removeDir&&!et(e.cwd),task:async(e,t)=>{let r=k(t);if(e.removeDir=await r.toggle({message:ng.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},we={enabled:e=>!!e.removeDir,task:async e=>_n(e.cwd)};v();var Lt={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>M(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await ri({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};v();var og=["services/my-hono-service","services/my-nest-service","my-platform"],Pe={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?og.includes(e.projectName):!0,task:async(e,t)=>{let r=k(t);e.projectName=await r.input({initial:e.projectName,message:"Enter project name",validate:n=>n?!0:"Project name is required."}),e.cwd&&(e.cwd=O(e.projectName))}};import ci from"chalk";var Se={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=dr(),e.packageManager){t.title=`Using ${ci.bold(e.packageManager)} as package manager.`;return}let r=k(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:Qn().map(n=>({name:n,value:n}))}),t.title=`Using ${ci.bold(e.packageManager)} as package manager.`}};import Wt from"chalk";var li={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${Wt.bold(e.githubOwner)}`;return}let r=k(t);e.githubOwner=await r.input({message:"Enter GitHub organization or username",initial:"my-org",validate:n=>n?.trim()?!0:"GitHub owner is required."}),t.title=`GitHub owner: ${Wt.bold(e.githubOwner)}`}},pi={title:"Include GitHub CI/CD",task:async(e,t)=>{if(e.includeGitHubCI!==void 0){t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD";return}let r=k(t);e.includeGitHubCI=await r.toggle({message:"Include GitHub Actions workflows and CI/CD?",initial:!0,enabled:"Yes",disabled:"No"}),t.title=e.includeGitHubCI?"Including GitHub CI/CD workflows":"Skipping GitHub CI/CD"}};var mi={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${Wt.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=k(t);e.pulumiStackBase=await s.input({message:"Enter Pulumi stack base name (org/project)",initial:o,validate:i=>i?.trim()?i.includes("/")?!0:"Format should be org/project (e.g., myorg/myproject)":"Pulumi stack name is required."}),t.title=`Pulumi stack: ${Wt.bold(e.pulumiStackBase)}`}};v();import{mkdirSync as sg,writeFileSync as ig}from"fs";import{dirname as ag}from"path";v();var cg=e=>e==="hono"?"hono":"nestjs",lg=e=>{let t=ag(e.path);sg(t,{recursive:!0}),ig(e.path,e.content,"utf-8")},pg=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=At(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
574
574
  `);throw new Error(`Policy violation(s) detected:
575
- ${o}`)}e.forEach(cg)},pg=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,l=Js({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),p=l.effects.filter(y=>y.kind==="file:write"),m=ag(o);lg(p,m),e.assignedPort=l.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${l.port}, ${e.elapsedTime}s)`},Ht={title:"Generating service",task:async(e,t)=>M(t,async r=>{await pg(e,t,r)})};var dg=e=>{let t=(e||"my-hono-service").trim();return t.includes("/")||t.startsWith(".")?t:`${E().services}/${t}`},gg=async(e,t)=>{let{valid:r,config:n,error:o}=de();if(!r||!n){$(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=dg(e.name),i=t.packageManager||b(),a=await ft(t.description);if(ht(s,n,a),await yt({servicePath:s,description:a,serviceType:"hono",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(oe.dim("Next steps:")).log(oe.dim(` ${oe.cyan("pf dev")} - Start all services`)).log(oe.dim(` ${oe.cyan(`cd ${s} && bun dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},di=J({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new hono-micro my-service --ai -d "Payment processing service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:gg,buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${E().services}/${r}`);let n=O(r),o=t.packageManager??(t.yes&&b()),s=D(),i=t.yes?ye():[],a=t.packageManager==="bun",c=!!t.yes||!!e.name&&e.name!=="my-hono-service";return{cwd:n,projectName:r,packageManager:o,shouldInstallBun:a,availableIntegrations:s,selectedIntegrations:i,serviceType:"hono",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[Pe,xe,Ce,Se,jt,ve],actions:[we,ke,Ht,Ot,Dt,Lt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{d.breakLine().log(oe.bold.green("Hono Microservice created successfully!")),Nt(r),Qs(mg(e),n??8080);let o=t??b();d.breakLine().log(`To start the project, run:
576
- ${oe.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import se from"chalk";f();v();var ug=e=>{let t=(e||"my-nest-service").trim();return t.includes("/")||t.startsWith(".")?t:`${E().services}/${t}`},fg=async(e,t)=>{let{valid:r,config:n,error:o}=de();if(!r||!n){$(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=ug(e.name),i=t.packageManager||b(),a=await ft(t.description);if(ht(s,n,a),await yt({servicePath:s,description:a,serviceType:"nest",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(se.dim("Next steps:")).log(se.dim(` ${se.cyan("pf dev")} - Start all services`)).log(se.dim(` ${se.cyan(`cd ${s} && bun run start:dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},gi=J({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new nest-micro my-service --ai -d "User authentication service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:fg,buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${E().services}/${r}`);let n=O(r),o=t.packageManager??(t.yes&&b()),s=t.packageManager==="bun",i=D(),a=t.yes?ye():[],c=!!t.yes||!!e.name;return{cwd:n,projectName:r,shouldInstallBun:s,packageManager:o,availableIntegrations:i,selectedIntegrations:a,serviceType:"nest",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[Pe,xe,Ce,Se,jt,ve],actions:[we,ke,Ht,Ot,_t,ai,Dt,Lt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{d.breakLine().log(se.bold.green("NestJS Microservice created successfully!")),Nt(r),d.breakLine().log(`To start the project, run:
577
- ${se.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import j from"chalk";v();import{spawnSync as vg}from"child_process";import{chmodSync as kg,existsSync as tn,mkdirSync as Cg,readFileSync as xg,writeFileSync as rn}from"fs";import{dirname as wg,join as nn}from"path";import{existsSync as hg}from"fs";import{join as Bt}from"path";var yg=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),en=()=>{let e=yg(),t=ee();return fe([Bt(e,"templates","workspace"),Bt(e,"..","..","..","..","templates","workspace"),Bt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},ui=()=>{let e=en(),t=Bt(e,"packages","contracts");if(!hg(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},Gt=(e,t)=>Br(e,t);var fi=e=>{e.endsWith(".sh")&&kg(e,493)},Pg=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"pnpm-workspace.yaml.hbs",output:"pnpm-workspace.yaml",forPackageManager:"pnpm"},{template:"biome.json.hbs",output:"biome.json"},{template:"turbo.json.hbs",output:"turbo.json"},{template:"bunfig.toml.hbs",output:"bunfig.toml"},{template:"gitignore.hbs",output:".gitignore"},{template:"editorconfig.hbs",output:".editorconfig"},{template:"npmrc.hbs",output:".npmrc"},{template:".vscode/settings.json",output:".vscode/settings.json",isStatic:!0},{template:".vscode/extensions.json",output:".vscode/extensions.json",isStatic:!0},{template:"infra/package.json.hbs",output:"infra/package.json"},{template:"infra/index.ts.hbs",output:"infra/index.ts"},{template:"infra/tsconfig.json.hbs",output:"infra/tsconfig.json"},{template:"infra/Pulumi.yaml.hbs",output:"infra/Pulumi.yaml"},{template:"infra/Pulumi.dev.yaml.hbs",output:"infra/Pulumi.dev.yaml"},{template:"apps/.gitkeep",output:"apps/.gitkeep",isStatic:!0},{template:"services/.gitkeep",output:"services/.gitkeep",isStatic:!0},{template:"packages/.gitkeep",output:"packages/.gitkeep",isStatic:!0},{template:"docs/.gitkeep",output:"docs/.gitkeep",isStatic:!0},{template:"infra/services/.gitkeep",output:"infra/services/.gitkeep",isStatic:!0},{template:".github/README.md",output:".github/README.md",isStatic:!0,isGitHubCI:!0},{template:".github/dependabot.yml",output:".github/dependabot.yml",isStatic:!0,isGitHubCI:!0},{template:".github/workflows/lint-and-tests.yml.hbs",output:".github/workflows/lint-and-tests.yml",isGitHubCI:!0},{template:".github/workflows/build-and-deploy.yml.hbs",output:".github/workflows/build-and-deploy.yml",isGitHubCI:!0},{template:".github/workflows/publish-packages.yml",output:".github/workflows/publish-packages.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/setup-bun-install/action.yml.hbs",output:".github/actions/setup-bun-install/action.yml",isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/action.yml",output:".github/actions/check-image-tag-exists/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/index.js",output:".github/actions/check-image-tag-exists/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/copilot-instructions.md",output:".github/copilot-instructions.md",isStatic:!0},{template:".github/instructions/code-style.instructions.md",output:".github/instructions/code-style.instructions.md",isStatic:!0},{template:".github/instructions/testing.instructions.md",output:".github/instructions/testing.instructions.md",isStatic:!0},{template:".github/instructions/cloudevents.instructions.md",output:".github/instructions/cloudevents.instructions.md",isStatic:!0}],hi={title:"Creating workspace structure",task:async(e,t)=>{if(tn(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=en(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let m=vg(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(m&&/^\d+\.\d+/.test(m))return`${c}@${m}`}catch{}return{bun:"bun@1.2.7",npm:"npm@10.9.2",yarn:"yarn@4.6.0",pnpm:"pnpm@9.15.2"}[c]||`${c}@latest`},i={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},a=Pg.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let l=nn(e.cwd,c.output),p=wg(l);if(tn(p)||Cg(p,{recursive:!0}),c.isStatic){let m=nn(r,c.template);tn(m)?rn(l,xg(m)):rn(l,""),fi(l)}else{let m=nn(r,c.template),y=Gt(m,i);rn(l,y),fi(l)}}t.title="Workspace structure created"}};f();import{existsSync as vi,mkdirSync as yi,readFileSync as Sg,writeFileSync as bg}from"fs";import{join as Ut}from"path";import Eg from"chalk";var Tg=()=>{let e=Ut(process.cwd(),"package.json");if(!vi(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Sg(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},$g=()=>{let e=Tg(),{relativePath:t,packagePath:r}=x();if(vi(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=ui(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};yi(r,{recursive:!0}),yi(Ut(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"tsup.config.ts",output:"tsup.config.ts"},{template:"README.md.hbs",output:"README.md"},{template:"src/index.ts",output:"src/index.ts"},{template:"src/stream-policies.ts.hbs",output:"src/stream-policies.ts"},{template:"src/events/index.ts",output:"src/events/index.ts"}];for(let i of s){let a=Ut(n,i.template),c=Ut(r,i.output),l=Gt(a,o);bg(c,l,"utf-8")}},ki={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),$g(),t.title="Contracts package initialized"}catch(n){throw t.title=Eg.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import Ag from"chalk";var Ci={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await He(),t.title="Shell completion registered"}catch{t.title=Ag.dim("Shell completion skipped")}finally{process.chdir(r)}}};var xi=J({name:"workspace",description:"Create a new workspace with infrastructure setup",arguments:[["[name]","Name or path of the workspace"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["-o, --github-owner <owner>","GitHub organization or username"],["-s, --pulumi-stack <name>","Pulumi stack base name (org/project)"],["--no-github","Skip GitHub CI/CD workflows"],["--remove-dir","Remove existing directory before creating (internal use)"]],exampleUsage:"pf new workspace my-platform -o my-org",buildContext:(e,t)=>{let r=(e.name??"my-platform").trim(),n=O(r),o=!!t.yes,s=t.packageManager??(o?b():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,m=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:m,githubOwner:a,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=g();if(!await C(t).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${r}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");t.title=j.yellow("Warning: Creating nested workspace")}catch(r){if(X(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},Pe,xe,li,pi,mi,Ce,Se,ve],actions:[we,ke,hi,ki,_t,oi,Ci],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(j.bold.green("Workspace created successfully!")),d.breakLine().log(j.bold("Next steps:")).log(` 1. ${j.cyan(`cd ${e}`)}`).log(` 2. ${j.cyan("exec $SHELL")} ${j.dim("(enable tab completion)")}`),t&&d.breakLine().log(j.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${j.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${j.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${j.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(j.bold("Structure created:")).log(" apps/ # Frontend applications").log(" services/ # Backend microservices").log(" packages/").log(" \u2514\u2500\u2500 contracts/ # Shared event contracts").log(" infra/").log(" \u251C\u2500\u2500 index.ts # Pulumi entry point").log(" \u251C\u2500\u2500 services/ # Service configs").log(" \u251C\u2500\u2500 Pulumi.yaml # Pulumi project config").log(" \u2514\u2500\u2500 Pulumi.dev.yaml # Dev stack config"),t&&d.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),d.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var ze=[{name:"Hono Microservice",value:"hono-micro",command:di,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:gi,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:xi,supportsAi:!1}],wi=()=>{let e=J({name:"new",description:"Create a new project",arguments:[["[type]","Type of the project (e.g., nest-micro, hono-micro, workspace)"]],exampleUsage:"platform new hono-micro test-service",buildContext:t=>({projectType:t.type??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await C(r).select({message:"Select Project type",choices:ze});t.projectType=ze.find(s=>s.name===o)?.value||"",r.title=`Using ${q.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{g(),r.title="Workspace detected"}catch{let n=["Not in a workspace directory","",`Current directory: ${process.cwd()}`,"","This command must be run from within a workspace created with pf new workspace","","To create a new workspace, run:",""," pf new workspace my-platform"].join(`
578
- `);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=g();if(!await C(r).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${n}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");r.title=q.yellow("Warning: Creating nested workspace")}catch(n){if(X(n)&&n.message?.includes("cancelled"))throw n;r.title="No existing workspace detected"}}},{enabled:t=>!!t.projectType,task:async(t,r)=>{let o={"hono-micro":"services/my-hono-service","nest-micro":"services/my-nest-service",workspace:"my-platform"}[t.projectType]||"my-project",s=t.projectType==="workspace"?"\u{1F4E6} Workspace name:":"\u{1F4E6} Service path (e.g., services/my-service):",a=await C(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${q.dim(a)}`}},{enabled:t=>!!ze.find(n=>n.value===t.projectType)?.supportsAi&&de().valid,task:async(t,r)=>{let o=await C(r).toggle({message:"Use AI to generate service code?",initial:!1});t.useAi=o,r.title=o?q.cyan("\u{1F916} AI-powered generation"):"Standard scaffolding"}},{enabled:t=>t.useAi,task:async(t,r)=>{let o=await C(r).input({message:"Describe what this service should do:"});t.aiDescription=o,r.title=`Description: ${q.dim(o.slice(0,50))}${o.length>50?"...":""}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=O(t.servicePath);return!et(r)},task:async(t,r)=>{if(!await C(r).toggle({message:q.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=q.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await C(r).toggle({message:"\u{1F680} Ready to launch your project?",initial:!0}))throw new Error("Project creation was canceled by the user.")}}],actions:[],onComplete:async t=>{ze.find(s=>s.value===t.projectType)||e.error(q.red(`Project type ${t.projectType} is not supported.`));let r=e.commands.find(s=>s.name()===t.projectType),n={};t.projectType!=="workspace"&&(n.yes=!0);let o=[];t.servicePath&&o.push("servicePath"),t.shouldRemoveDir&&(n.removeDir=!0),t.useAi&&(n.ai=!0,n.description=t.aiDescription),await ni(r,t,n,o)}});for(let t of ze)e.addCommand(t.command);return e};import{Command as _g}from"commander";v();import{createHash as Ig}from"crypto";import{existsSync as ie,readdirSync as Pi,readFileSync as Si,unlinkSync as Rg,writeFileSync as Ng}from"fs";import{join as Y}from"path";import Fg from"chokidar";f();v();var Og=e=>{let t=Y(e,"infra","services");if(!ie(t))return[];let r=Pi(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=E(e),o=a=>{let c=Y(e,a);return ie(c)?Pi(c).filter(l=>ie(Y(c,l,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)Rg(Y(t,`${a}.ts`));return i},bi=".install-hash",Ei=e=>{let t=Si(e);return Ig("sha256").update(t).digest("hex")},Mg=e=>{let t=Y(e,"node_modules",bi),r=Y(e,"bun.lock");return!ie(r)||!ie(t)?!0:Si(t,"utf-8")!==Ei(r)},Dg=e=>{let t=Y(e,"bun.lock"),r=Y(e,"node_modules",bi);ie(t)&&Ng(r,Ei(t),"utf-8")},on=async e=>{let t=Og(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),Mg(e)&&(await L({cwd:e,quiet:!0}),Dg(e)),await Fe("generate-env",{cwd:e})},sn=async e=>{await Ks()&&await Yr(e)},Ti=e=>{let{eventsPath:t}=x(e);if(!ie(t))return async()=>{};let r=ae(async()=>{console.log(`
579
- \u{1F4E6} Contracts changed, updating streams...`),await Yr(e)},500),n=Fg.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};Ze();import $i from"chalk";f();var an=e=>new Promise(t=>setTimeout(t,e)),Ai=e=>process.stdout.write(`${e}
580
- `),jg=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},Ii=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),cn=async(e,t)=>{let r=Jn(".env.local",t);r.length>0&&(await Zn(r),await an(50));let{dev:n}=Ie(t),o=n.filter.flatMap(s=>["--filter",s]);Ai($i.cyan("\u{1F525} Starting services...")),Ai($i.dim(` Command: turbo run ${qt} --continue${o.length?` ${o.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1,e.turboProcess=Kn("turbo",["run",qt,"--continue","--no-daemon",...o],{cwd:t,envFile:".env.local",onExit:s=>{e.isRestarting||e.isShuttingDown||s===1&&process.exit(w.SUCCESS)}})},zt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await an(200);try{process.kill(-t,"SIGKILL")}catch{}await an(30)}catch{}e.turboProcess=null,jg()}};var Ri=new _g("dev").description("Start development mode with auto-reload").action(async()=>{let e;try{e=g()}catch(a){$(a);return}let t=Ii(),r=async()=>{await on(e),await sn(e),await cn(t,e)},o=ae(async()=>{if(!(t.isRestarting||t.isShuttingDown)){t.isRestarting=!0,console.log(`
575
+ ${o}`)}e.forEach(lg)},mg=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,l=Js({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),p=l.effects.filter(y=>y.kind==="file:write"),m=cg(o);pg(p,m),e.assignedPort=l.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${l.port}, ${e.elapsedTime}s)`},Ht={title:"Generating service",task:async(e,t)=>M(t,async r=>{await mg(e,t,r)})};var gg=e=>{let t=(e||"my-hono-service").trim();return t.includes("/")||t.startsWith(".")?t:`${E().services}/${t}`},ug=async(e,t)=>{let{valid:r,config:n,error:o}=de();if(!r||!n){$(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=gg(e.name),i=t.packageManager||b(),a=await ft(t.description);if(ht(s,n,a),await yt({servicePath:s,description:a,serviceType:"hono",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(oe.dim("Next steps:")).log(oe.dim(` ${oe.cyan("pf dev")} - Start all services`)).log(oe.dim(` ${oe.cyan(`cd ${s} && bun dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},di=J({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new hono-micro my-service --ai -d "Payment processing service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:ug,buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${E().services}/${r}`);let n=O(r),o=t.packageManager??(t.yes&&b()),s=D(),i=t.yes?ye():[],a=t.packageManager==="bun",c=!!t.yes||!!e.name&&e.name!=="my-hono-service";return{cwd:n,projectName:r,packageManager:o,shouldInstallBun:a,availableIntegrations:s,selectedIntegrations:i,serviceType:"hono",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[Pe,xe,ke,Se,jt,ve],actions:[we,Ce,Ht,Ot,Dt,Lt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{d.breakLine().log(oe.bold.green("Hono Microservice created successfully!")),Nt(r),Qs(dg(e),n??8080);let o=t??b();d.breakLine().log(`To start the project, run:
576
+ ${oe.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import se from"chalk";f();v();var fg=e=>{let t=(e||"my-nest-service").trim();return t.includes("/")||t.startsWith(".")?t:`${E().services}/${t}`},hg=async(e,t)=>{let{valid:r,config:n,error:o}=de();if(!r||!n){$(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=fg(e.name),i=t.packageManager||b(),a=await ft(t.description);if(ht(s,n,a),await yt({servicePath:s,description:a,serviceType:"nest",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(se.dim("Next steps:")).log(se.dim(` ${se.cyan("pf dev")} - Start all services`)).log(se.dim(` ${se.cyan(`cd ${s} && bun run start:dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},gi=J({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new nest-micro my-service --ai -d "User authentication service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:hg,buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${E().services}/${r}`);let n=O(r),o=t.packageManager??(t.yes&&b()),s=t.packageManager==="bun",i=D(),a=t.yes?ye():[],c=!!t.yes||!!e.name;return{cwd:n,projectName:r,shouldInstallBun:s,packageManager:o,availableIntegrations:i,selectedIntegrations:a,serviceType:"nest",elapsedTime:0,userConfirmed:!!t.yes,skipInputPrompts:c,removeDir:!!t.removeDir||!!t.yes}},prompts:[Pe,xe,ke,Se,jt,ve],actions:[we,Ce,Ht,Ot,_t,ai,Dt,Lt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{d.breakLine().log(se.bold.green("NestJS Microservice created successfully!")),Nt(r),d.breakLine().log(`To start the project, run:
577
+ ${se.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import j from"chalk";v();import{spawnSync as Cg}from"child_process";import{chmodSync as kg,existsSync as tn,mkdirSync as xg,readFileSync as wg,writeFileSync as rn}from"fs";import{dirname as Pg,join as nn}from"path";import{existsSync as yg}from"fs";import{join as Bt}from"path";var vg=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),en=()=>{let e=vg(),t=ee();return fe([Bt(e,"templates","workspace"),Bt(e,"..","..","..","..","templates","workspace"),Bt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},ui=()=>{let e=en(),t=Bt(e,"packages","contracts");if(!yg(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},Gt=(e,t)=>Br(e,t);var fi=e=>{e.endsWith(".sh")&&kg(e,493)},Sg=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"pnpm-workspace.yaml.hbs",output:"pnpm-workspace.yaml",forPackageManager:"pnpm"},{template:"biome.json.hbs",output:"biome.json"},{template:"turbo.json.hbs",output:"turbo.json"},{template:"bunfig.toml.hbs",output:"bunfig.toml"},{template:"gitignore.hbs",output:".gitignore"},{template:"editorconfig.hbs",output:".editorconfig"},{template:"npmrc.hbs",output:".npmrc"},{template:".vscode/settings.json",output:".vscode/settings.json",isStatic:!0},{template:".vscode/extensions.json",output:".vscode/extensions.json",isStatic:!0},{template:"infra/package.json.hbs",output:"infra/package.json"},{template:"infra/index.ts.hbs",output:"infra/index.ts"},{template:"infra/tsconfig.json.hbs",output:"infra/tsconfig.json"},{template:"infra/Pulumi.yaml.hbs",output:"infra/Pulumi.yaml"},{template:"infra/Pulumi.dev.yaml.hbs",output:"infra/Pulumi.dev.yaml"},{template:"apps/.gitkeep",output:"apps/.gitkeep",isStatic:!0},{template:"services/.gitkeep",output:"services/.gitkeep",isStatic:!0},{template:"packages/.gitkeep",output:"packages/.gitkeep",isStatic:!0},{template:"docs/.gitkeep",output:"docs/.gitkeep",isStatic:!0},{template:"infra/services/.gitkeep",output:"infra/services/.gitkeep",isStatic:!0},{template:".github/README.md",output:".github/README.md",isStatic:!0,isGitHubCI:!0},{template:".github/dependabot.yml",output:".github/dependabot.yml",isStatic:!0,isGitHubCI:!0},{template:".github/workflows/lint-and-tests.yml.hbs",output:".github/workflows/lint-and-tests.yml",isGitHubCI:!0},{template:".github/workflows/build-and-deploy.yml.hbs",output:".github/workflows/build-and-deploy.yml",isGitHubCI:!0},{template:".github/workflows/publish-packages.yml",output:".github/workflows/publish-packages.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/setup-bun-install/action.yml.hbs",output:".github/actions/setup-bun-install/action.yml",isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/action.yml",output:".github/actions/check-image-tag-exists/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-image-tag-exists/index.js",output:".github/actions/check-image-tag-exists/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/copilot-instructions.md",output:".github/copilot-instructions.md",isStatic:!0},{template:".github/instructions/code-style.instructions.md",output:".github/instructions/code-style.instructions.md",isStatic:!0},{template:".github/instructions/testing.instructions.md",output:".github/instructions/testing.instructions.md",isStatic:!0},{template:".github/instructions/cloudevents.instructions.md",output:".github/instructions/cloudevents.instructions.md",isStatic:!0}],hi={title:"Creating workspace structure",task:async(e,t)=>{if(tn(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=en(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let m=Cg(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(m&&/^\d+\.\d+/.test(m))return`${c}@${m}`}catch{}return{bun:"bun@1.2.7",npm:"npm@10.9.2",yarn:"yarn@4.6.0",pnpm:"pnpm@9.15.2"}[c]||`${c}@latest`},i={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},a=Sg.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let l=nn(e.cwd,c.output),p=Pg(l);if(tn(p)||xg(p,{recursive:!0}),c.isStatic){let m=nn(r,c.template);tn(m)?rn(l,wg(m)):rn(l,""),fi(l)}else{let m=nn(r,c.template),y=Gt(m,i);rn(l,y),fi(l)}}t.title="Workspace structure created"}};f();import{existsSync as vi,mkdirSync as yi,readFileSync as bg,writeFileSync as Eg}from"fs";import{join as Ut}from"path";import Tg from"chalk";var $g=()=>{let e=Ut(process.cwd(),"package.json");if(!vi(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(bg(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},Ag=()=>{let e=$g(),{relativePath:t,packagePath:r}=x();if(vi(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=ui(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};yi(r,{recursive:!0}),yi(Ut(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{template:"tsup.config.ts",output:"tsup.config.ts"},{template:"README.md.hbs",output:"README.md"},{template:"src/index.ts",output:"src/index.ts"},{template:"src/stream-policies.ts.hbs",output:"src/stream-policies.ts"},{template:"src/events/index.ts",output:"src/events/index.ts"}];for(let i of s){let a=Ut(n,i.template),c=Ut(r,i.output),l=Gt(a,o);Eg(c,l,"utf-8")}},Ci={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),Ag(),t.title="Contracts package initialized"}catch(n){throw t.title=Tg.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import Ig from"chalk";var ki={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await He(),t.title="Shell completion registered"}catch{t.title=Ig.dim("Shell completion skipped")}finally{process.chdir(r)}}};var xi=J({name:"workspace",description:"Create a new workspace with infrastructure setup",arguments:[["[name]","Name or path of the workspace"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["-o, --github-owner <owner>","GitHub organization or username"],["-s, --pulumi-stack <name>","Pulumi stack base name (org/project)"],["--no-github","Skip GitHub CI/CD workflows"],["--remove-dir","Remove existing directory before creating (internal use)"]],exampleUsage:"pf new workspace my-platform -o my-org",buildContext:(e,t)=>{let r=(e.name??"my-platform").trim(),n=O(r),o=!!t.yes,s=t.packageManager??(o?b():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,m=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:m,githubOwner:a,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=g();if(!await k(t).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${r}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");t.title=j.yellow("Warning: Creating nested workspace")}catch(r){if(X(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},Pe,xe,li,pi,mi,ke,Se,ve],actions:[we,Ce,hi,Ci,_t,oi,ki],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(j.bold.green("Workspace created successfully!")),d.breakLine().log(j.bold("Next steps:")).log(` 1. ${j.cyan(`cd ${e}`)}`).log(` 2. ${j.cyan("exec $SHELL")} ${j.dim("(enable tab completion)")}`),t&&d.breakLine().log(j.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${j.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${j.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${j.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(j.bold("Structure created:")).log(" apps/ # Frontend applications").log(" services/ # Backend microservices").log(" packages/").log(" \u2514\u2500\u2500 contracts/ # Shared event contracts").log(" infra/").log(" \u251C\u2500\u2500 index.ts # Pulumi entry point").log(" \u251C\u2500\u2500 services/ # Service configs").log(" \u251C\u2500\u2500 Pulumi.yaml # Pulumi project config").log(" \u2514\u2500\u2500 Pulumi.dev.yaml # Dev stack config"),t&&d.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),d.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var ze=[{name:"Hono Microservice",value:"hono-micro",command:di,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:gi,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:xi,supportsAi:!1}],wi=()=>{let e=J({name:"new",description:"Create a new project",arguments:[["[type]","Type of the project (e.g., nest-micro, hono-micro, workspace)"]],exampleUsage:"platform new hono-micro test-service",buildContext:t=>({projectType:t.type??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await k(r).select({message:"Select Project type",choices:ze});t.projectType=ze.find(s=>s.name===o)?.value||"",r.title=`Using ${q.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{g(),r.title="Workspace detected"}catch{let n=["Not in a workspace directory","",`Current directory: ${process.cwd()}`,"","This command must be run from within a workspace created with pf new workspace","","To create a new workspace, run:",""," pf new workspace my-platform"].join(`
578
+ `);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=g();if(!await k(r).toggle({message:`\u26A0\uFE0F You are inside an existing workspace (${n}). Create a nested workspace anyway?`,initial:!1}))throw new Error("Workspace creation cancelled - already inside a workspace");r.title=q.yellow("Warning: Creating nested workspace")}catch(n){if(X(n)&&n.message?.includes("cancelled"))throw n;r.title="No existing workspace detected"}}},{enabled:t=>!!t.projectType,task:async(t,r)=>{let o={"hono-micro":"services/my-hono-service","nest-micro":"services/my-nest-service",workspace:"my-platform"}[t.projectType]||"my-project",s=t.projectType==="workspace"?"\u{1F4E6} Workspace name:":"\u{1F4E6} Service path (e.g., services/my-service):",a=await k(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${q.dim(a)}`}},{enabled:t=>!!ze.find(n=>n.value===t.projectType)?.supportsAi&&de().valid,task:async(t,r)=>{let o=await k(r).toggle({message:"Use AI to generate service code?",initial:!1});t.useAi=o,r.title=o?q.cyan("\u{1F916} AI-powered generation"):"Standard scaffolding"}},{enabled:t=>t.useAi,task:async(t,r)=>{let o=await k(r).input({message:"Describe what this service should do:"});t.aiDescription=o,r.title=`Description: ${q.dim(o.slice(0,50))}${o.length>50?"...":""}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=O(t.servicePath);return!et(r)},task:async(t,r)=>{if(!await k(r).toggle({message:q.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=q.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await k(r).toggle({message:"\u{1F680} Ready to launch your project?",initial:!0}))throw new Error("Project creation was canceled by the user.")}}],actions:[],onComplete:async t=>{ze.find(s=>s.value===t.projectType)||e.error(q.red(`Project type ${t.projectType} is not supported.`));let r=e.commands.find(s=>s.name()===t.projectType),n={};t.projectType!=="workspace"&&(n.yes=!0);let o=[];t.servicePath&&o.push("servicePath"),t.shouldRemoveDir&&(n.removeDir=!0),t.useAi&&(n.ai=!0,n.description=t.aiDescription),await ni(r,t,n,o)}});for(let t of ze)e.addCommand(t.command);return e};import{Command as Lg}from"commander";v();import{createHash as Rg}from"crypto";import{existsSync as ie,readdirSync as Pi,readFileSync as Si,unlinkSync as Ng,writeFileSync as Fg}from"fs";import{join as Y}from"path";import Og from"chokidar";f();v();var Mg=e=>{let t=Y(e,"infra","services");if(!ie(t))return[];let r=Pi(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=E(e),o=a=>{let c=Y(e,a);return ie(c)?Pi(c).filter(l=>ie(Y(c,l,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)Ng(Y(t,`${a}.ts`));return i},bi=".install-hash",Ei=e=>{let t=Si(e);return Rg("sha256").update(t).digest("hex")},Dg=e=>{let t=Y(e,"node_modules",bi),r=Y(e,"bun.lock");return!ie(r)||!ie(t)?!0:Si(t,"utf-8")!==Ei(r)},jg=e=>{let t=Y(e,"bun.lock"),r=Y(e,"node_modules",bi);ie(t)&&Fg(r,Ei(t),"utf-8")},on=async e=>{let t=Mg(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),Dg(e)&&(await L({cwd:e,quiet:!0}),jg(e)),await Fe("generate-env",{cwd:e})},sn=async e=>{await Ks()&&await Yr(e)},Ti=e=>{let{eventsPath:t}=x(e);if(!ie(t))return async()=>{};let r=ae(async()=>{console.log(`
579
+ \u{1F4E6} Contracts changed, updating streams...`),await Yr(e)},500),n=Og.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};Ze();import $i from"chalk";f();var an=e=>new Promise(t=>setTimeout(t,e)),Ai=e=>process.stdout.write(`${e}
580
+ `),_g=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},Ii=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),cn=async(e,t)=>{let r=Jn(".env.local",t);r.length>0&&(await Zn(r),await an(50));let{dev:n}=Ie(t),o=n.filter.flatMap(s=>["--filter",s]);Ai($i.cyan("\u{1F525} Starting services...")),Ai($i.dim(` Command: turbo run ${qt} --continue${o.length?` ${o.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1,e.turboProcess=Kn("turbo",["run",qt,"--continue","--no-daemon",...o],{cwd:t,envFile:".env.local",onExit:s=>{e.isRestarting||e.isShuttingDown||s===1&&process.exit(w.SUCCESS)}})},zt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await an(200);try{process.kill(-t,"SIGKILL")}catch{}await an(30)}catch{}e.turboProcess=null,_g()}};var Ri=new Lg("dev").description("Start development mode with auto-reload").action(async()=>{let e;try{e=g()}catch(a){$(a);return}let t=Ii(),r=async()=>{await on(e),await sn(e),await cn(t,e)},o=ae(async()=>{if(!(t.isRestarting||t.isShuttingDown)){t.isRestarting=!0,console.log(`
581
581
  \u{1F504} Change detected, restarting...
582
582
  `);try{await zt(t),await on(e),await sn(e),await cn(t,e)}catch(a){$(a)}finally{t.isRestarting=!1}}},300),s=async()=>{t.isShuttingDown||(console.log(`
583
583
  \u{1F6D1} Shutting down...`),await zt(t),process.exit(w.SUCCESS))};process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",s),process.on("SIGTERM",s);let i;try{await r(),En(e,o),i=Ti(e),console.log(`
584
584
  \u{1F440} Watching for changes...`),console.log(` Press Ctrl+C twice to exit (first stops Turbo, second triggers cleanup)
585
- `)}catch(a){await i?.(),await zt(t),$(a)}});import Mi from"chalk";import{Command as Zg}from"commander";import{existsSync as Lg,readFileSync as Wg,writeFileSync as Hg}from"fs";import Bg from"os";import Ni from"path";import ln from"chalk";import{Command as Gg}from"commander";v();var{name:Ug,publishConfig:zg}=R,Vg=zg?.registry,Jg=Ug?.split("/")[0],RE=new Gg("token:set").description(ln.bold("Set a registry auth token in a .npmrc file")).argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",Jg).option("--registry <registry>","Registry URL",Vg).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action((e,t)=>Fi(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${ln.cyan(`
585
+ `)}catch(a){await i?.(),await zt(t),$(a)}});import Mi from"chalk";import{Command as Xg}from"commander";import{existsSync as Wg,readFileSync as Hg,writeFileSync as Bg}from"fs";import Gg from"os";import Ni from"path";import ln from"chalk";import{Command as Ug}from"commander";v();var{name:zg,publishConfig:Vg}=R,Jg=Vg?.registry,Kg=zg?.split("/")[0],NE=new Ug("token:set").description(ln.bold("Set a registry auth token in a .npmrc file")).argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",Kg).option("--registry <registry>","Registry URL",Jg).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action((e,t)=>Fi(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${ln.cyan(`
586
586
  Example:`)}
587
587
  ${ln.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
588
- `),Kg=e=>e?Ni.join(process.cwd(),".npmrc"):Ni.join(Bg.homedir(),".npmrc"),qg=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
589
- //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Yg=e=>Lg(e)?Wg(e,"utf8"):"",pn=(e,t)=>Hg(e,t),Fi=(e,t,r,n=!1,o=!1)=>{let s=Kg(n),i=qg(e,t,r),a=new URL(r).host,c=Yg(s),l=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){pn(s,`${i}
588
+ `),qg=e=>e?Ni.join(process.cwd(),".npmrc"):Ni.join(Gg.homedir(),".npmrc"),Yg=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
589
+ //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Zg=e=>Wg(e)?Hg(e,"utf8"):"",pn=(e,t)=>Bg(e,t),Fi=(e,t,r,n=!1,o=!1)=>{let s=qg(n),i=Yg(e,t,r),a=new URL(r).host,c=Zg(s),l=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){pn(s,`${i}
590
590
  `),d.success(`Created new .npmrc and set token for ${a}`);return}if(l.test(c)){if(!o){d.warn(`Token for ${a} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(l,i),pn(s,c),d.success(`Overwrote existing token for ${a} in ${s}`);return}c+=`
591
591
  ${i}
592
- `,pn(s,c),d.success(`Appended token for ${a} to ${s}`)},Oi=(e,t)=>Fi(e,t.scope||"",t.registry||"",t.local,t.force);var{name:Xg,publishConfig:Qg}=R,eu=Qg?.registry,tu=Xg?.split("/")[0],mn=new Zg("token").description("Token management commands");mn.command("set").description("Set a registry auth token in a .npmrc file").argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",tu).option("--registry <registry>","Registry URL",eu).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(Oi).addHelpText("after",()=>`${Mi.cyan(`
592
+ `,pn(s,c),d.success(`Appended token for ${a} to ${s}`)},Oi=(e,t)=>Fi(e,t.scope||"",t.registry||"",t.local,t.force);var{name:Qg,publishConfig:eu}=R,tu=eu?.registry,ru=Qg?.split("/")[0],mn=new Xg("token").description("Token management commands");mn.command("set").description("Set a registry auth token in a .npmrc file").argument("<token>","Authentication token (e.g. GitHub or npm token)").option("--scope <scope>","Package scope (e.g. @my-workspace)",ru).option("--registry <registry>","Registry URL",tu).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(Oi).addHelpText("after",()=>`${Mi.cyan(`
593
593
  Example:`)}
594
594
  ${Mi.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
595
- `);mn.action(()=>{let e=ge({title:"\u{1F511} Token Management",commands:[{name:"set",description:"Set a registry auth token in a .npmrc file"}],footer:'Run "pf token <command> --help" for more information'});console.log(e)});var Di=mn;import gn from"chalk";import{Command as uu}from"commander";f();Ze();var WE={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};import{confirm as _i,input as iu,password as au,select as Li}from"@inquirer/prompts";import P from"chalk";var ru=[/embed/i,/whisper/i,/tts/i,/dall-e/i,/davinci/i,/babbage/i,/curie/i,/ada(?!-)/i,/moderation/i,/realtime/i,/audio/i,/transcription/i,/search/i],nu=async(e,t,r=1e4)=>{let n=new AbortController,o=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}finally{clearTimeout(o)}},ou=e=>e.replace(/-(\d{8})$/," ($1)").replace(/^claude-/,"Claude ").replace(/^gpt-/,"GPT-").replace(/-/g," ").replace(/(\d)\.(\d)/g,"$1.$2").replace(/\s+/g," ").split(" ").map(t=>/^\d/.test(t)||/^\(\d+\)$/.test(t)?t:t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(" ").trim(),su=async(e,t)=>{let r=Me(e),n=await nu(r.modelsApiUrl,{headers:r.buildHeaders(t)});if(!n.ok)throw new Error(`${r.name} API error: ${n.status}`);let o=await n.json(),s=r.parseModelsResponse(o);if(!Array.isArray(s)||s.length===0)throw new Error(`No models returned from ${r.name} API`);let i=s.filter(a=>{let c=r.modelFilters.some(p=>p.test(a.id)),l=ru.some(p=>p.test(a.id));return c&&!l}).sort((a,c)=>{let l=typeof a.created=="number"?a.created:new Date(a.created).getTime();return(typeof c.created=="number"?c.created:new Date(c.created).getTime())-l}).map(a=>({name:ou(a.id),value:a.id}));if(i.length===0)throw new Error(`No chat models found from ${r.name} API`);return i};async function ji(e,t){if(!t)throw new Error("API key is required to fetch available models");return{models:await su(e,t),fromApi:!0}}V();function cu(){if(!De())return null;try{let e=pt();return console.log(P.dim(`Found existing configuration at ${Q}
595
+ `);mn.action(()=>{let e=ge({title:"\u{1F511} Token Management",commands:[{name:"set",description:"Set a registry auth token in a .npmrc file"}],footer:'Run "pf token <command> --help" for more information'});console.log(e)});var Di=mn;import gn from"chalk";import{Command as fu}from"commander";f();Ze();var HE={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};import{confirm as _i,input as au,password as cu,select as Li}from"@inquirer/prompts";import P from"chalk";var nu=[/embed/i,/whisper/i,/tts/i,/dall-e/i,/davinci/i,/babbage/i,/curie/i,/ada(?!-)/i,/moderation/i,/realtime/i,/audio/i,/transcription/i,/search/i],ou=async(e,t,r=1e4)=>{let n=new AbortController,o=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}finally{clearTimeout(o)}},su=e=>e.replace(/-(\d{8})$/," ($1)").replace(/^claude-/,"Claude ").replace(/^gpt-/,"GPT-").replace(/-/g," ").replace(/(\d)\.(\d)/g,"$1.$2").replace(/\s+/g," ").split(" ").map(t=>/^\d/.test(t)||/^\(\d+\)$/.test(t)?t:t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(" ").trim(),iu=async(e,t)=>{let r=Me(e),n=await ou(r.modelsApiUrl,{headers:r.buildHeaders(t)});if(!n.ok)throw new Error(`${r.name} API error: ${n.status}`);let o=await n.json(),s=r.parseModelsResponse(o);if(!Array.isArray(s)||s.length===0)throw new Error(`No models returned from ${r.name} API`);let i=s.filter(a=>{let c=r.modelFilters.some(p=>p.test(a.id)),l=nu.some(p=>p.test(a.id));return c&&!l}).sort((a,c)=>{let l=typeof a.created=="number"?a.created:new Date(a.created).getTime();return(typeof c.created=="number"?c.created:new Date(c.created).getTime())-l}).map(a=>({name:su(a.id),value:a.id}));if(i.length===0)throw new Error(`No chat models found from ${r.name} API`);return i};async function ji(e,t){if(!t)throw new Error("API key is required to fetch available models");return{models:await iu(e,t),fromApi:!0}}V();function lu(){if(!De())return null;try{let e=pt();return console.log(P.dim(`Found existing configuration at ${Q}
596
596
  `)),e}catch{return console.log(P.yellow(`Found corrupted configuration, starting fresh.
597
- `)),null}}async function lu(e,t){return console.log(P.dim(`
597
+ `)),null}}async function pu(e,t){return console.log(P.dim(`
598
598
  \u{1F4CB} Get your ${e} API key here:`)),console.log(P.cyan(` ${t}
599
- `)),au({message:`Enter your ${e} API key:`,mask:"*",validate:r=>r.trim()?r.length<10?"API key seems too short":!0:"API key cannot be empty"})}async function pu(e,t,r){let n=await Li({message:"Select model:",choices:e,default:t?.provider===r?t.model:void 0});return await _i({message:"Enter a custom model ID instead?",default:!1})?iu({message:"Enter custom model ID:",default:n,validate:s=>s.trim()?!0:"Model ID cannot be empty"}):n}function Wi(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function mu(e,t){console.log(P.green.bold(`
599
+ `)),cu({message:`Enter your ${e} API key:`,mask:"*",validate:r=>r.trim()?r.length<10?"API key seems too short":!0:"API key cannot be empty"})}async function mu(e,t,r){let n=await Li({message:"Select model:",choices:e,default:t?.provider===r?t.model:void 0});return await _i({message:"Enter a custom model ID instead?",default:!1})?au({message:"Enter custom model ID:",default:n,validate:s=>s.trim()?!0:"Model ID cannot be empty"}):n}function Wi(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function du(e,t){console.log(P.green.bold(`
600
600
  \u2705 AI configuration saved successfully!
601
601
  `)),console.log(P.dim(`Configuration file: ${Q}`)),console.log(P.dim("API Key: Stored securely in system keychain")),console.log(P.dim(`Provider: ${e.provider}`)),console.log(P.dim(`Model: ${e.model}`)),console.log(P.dim(`API Key: ${Wi(t)}
602
602
  `)),console.log(P.cyan("You can now use AI-powered service generation:")),console.log(P.dim(` pf new hono-micro services/my-service --ai
603
- `))}async function du(e){let t=await lt(e);if(t)return t;let r=Me(e);return process.env[r.defaultApiKeyEnvVar]??null}async function Hi(){console.log(P.cyan.bold(`
603
+ `))}async function gu(e){let t=await lt(e);if(t)return t;let r=Me(e);return process.env[r.defaultApiKeyEnvVar]??null}async function Hi(){console.log(P.cyan.bold(`
604
604
  \u{1F916} AI Configuration Setup
605
- `));let e=cu();try{let t=await Li({message:"Select AI provider:",choices:po(),default:e?.provider??ur.provider}),r=Me(t),n,o=await du(t);o&&(console.log(P.green(`
606
- \u2713 Found existing API key: ${Wi(o)}`)),await _i({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await lu(r.name,r.apiKeyUrl)),console.log(P.dim(`
605
+ `));let e=lu();try{let t=await Li({message:"Select AI provider:",choices:po(),default:e?.provider??ur.provider}),r=Me(t),n,o=await gu(t);o&&(console.log(P.green(`
606
+ \u2713 Found existing API key: ${Wi(o)}`)),await _i({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await pu(r.name,r.apiKeyUrl)),console.log(P.dim(`
607
607
  Fetching available models...`));let s;try{s=(await ji(t,n)).models,console.log(P.green(`\u2713 Loaded ${s.length} models from ${r.name} API
608
608
  `))}catch(c){console.error(P.red(`
609
- \u274C Failed to fetch models: ${kn(c)}`)),console.log(P.yellow(`
609
+ \u274C Failed to fetch models: ${Cn(c)}`)),console.log(P.yellow(`
610
610
  Please check your API key and try again.
611
- `)),process.exit(w.CONFIG_ERROR)}let i=await pu(s,e,t),a={provider:t,model:i.trim()};mo(a),await go(t,n),mu(a,n)}catch(t){throw X(t)&&t.name==="ExitPromptError"&&(console.log(P.yellow(`
611
+ `)),process.exit(w.CONFIG_ERROR)}let i=await mu(s,e,t),a={provider:t,model:i.trim()};mo(a),await go(t,n),du(a,n)}catch(t){throw X(t)&&t.name==="ExitPromptError"&&(console.log(P.yellow(`
612
612
  Setup cancelled.
613
- `)),process.exit(w.CANCELLED)),t}}import{existsSync as eT,readFileSync as tT}from"fs";import{homedir as nT}from"os";import{join as sT}from"path";var dn=async(e,t=!1)=>{try{return jr(e,t),await He({verbose:t}),!0}catch{return!1}};var Vt=e=>{let t=new uu("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
613
+ `)),process.exit(w.CANCELLED)),t}}import{existsSync as tT,readFileSync as rT}from"fs";import{homedir as oT}from"os";import{join as iT}from"path";var dn=async(e,t=!1)=>{try{return jr(e,t),await He({verbose:t}),!0}catch{return!1}};var Vt=e=>{let t=new fu("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
614
614
  Examples:
615
615
  $ pf setup completion
616
616
  $ pf setup completion --verbose
@@ -620,6 +620,6 @@ Examples:
620
620
  `)))}),t.command("ai").description("Configure AI provider and API key for code generation").addHelpText("after",`
621
621
  Example:
622
622
  $ pf setup ai
623
- `).action(async()=>{await Hi()}),t.action(()=>{let r=ge({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"},{name:"ai",description:"Configure AI provider"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},fu=Vt("pf");V();f();import yu from"chalk";import{Command as Gi}from"commander";import Bi from"chalk";var hu=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(Bi.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(Bi.red(` ${t}`))}),un=async e=>{let{command:t,args:r,options:n,context:o,silent:s=!1}=e,i=await t.run(r,n),a=i?.effects??[];if(a.length>0){let c={workspace:o.workspace,logger:hu(s)};Wr(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let l of c)console.log(l)}return{effects:a,output:i?.output}};var vu=e=>e.required?`<${e.name}>`:`[${e.name}]`,ku=(e,t)=>{e.argument(vu(t),t.description)},Cu=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},xu=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),wu=e=>e[e.length-2],Pu=(e,t)=>async(...r)=>{try{await un({command:e,args:xu(e,r),options:wu(r),context:t})}catch(n){console.error(yu.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Ui=(e,t)=>{let r=new Gi(e.name).description(e.description);return e.args.forEach(n=>{ku(r,n)}),e.options.forEach(n=>{Cu(r,n)}),r.action(Pu(e,t)),r},fn=(e,t,r,n)=>{let o=new Gi(e).description(t);return r.forEach(s=>{o.addCommand(Ui(s,n))}),o};wt();process.on("SIGINT",()=>{process.exit(w.CANCELLED)});process.on("unhandledRejection",e=>{throw Ye(e)&&process.exit(w.CANCELLED),e});process.on("uncaughtException",e=>{$(e)});var Ve=new bu,zi=Object.keys(R.bin||{}),[yn="pf",hn]=zi.length>0?zi:["pf"],{description:Vi,version:Tu,repository:Ji,homepage:$u}=R,Ki=Vi?.split(/ —|,|\./)[0]||Vi||"Platform CLI",Yi=Ji?.url?`https://${Ji.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,qi=Yi||$u,Au=Yi?"GitHub":"README",Iu=qi?[Je.bold(Ki),`
623
+ `).action(async()=>{await Hi()}),t.action(()=>{let r=ge({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"},{name:"ai",description:"Configure AI provider"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},hu=Vt("pf");V();f();import vu from"chalk";import{Command as Gi}from"commander";import Bi from"chalk";var yu=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(Bi.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(Bi.red(` ${t}`))}),un=async e=>{let{command:t,args:r,options:n,context:o,silent:s=!1}=e,i=await t.run(r,n),a=i?.effects??[];if(a.length>0){let c={workspace:o.workspace,logger:yu(s)};Wr(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let l of c)console.log(l)}return{effects:a,output:i?.output}};var Cu=e=>e.required?`<${e.name}>`:`[${e.name}]`,ku=(e,t)=>{e.argument(Cu(t),t.description)},xu=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},wu=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),Pu=e=>e[e.length-2],Su=(e,t)=>async(...r)=>{try{await un({command:e,args:wu(e,r),options:Pu(r),context:t})}catch(n){console.error(vu.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Ui=(e,t)=>{let r=new Gi(e.name).description(e.description);return e.args.forEach(n=>{ku(r,n)}),e.options.forEach(n=>{xu(r,n)}),r.action(Su(e,t)),r},fn=(e,t,r,n)=>{let o=new Gi(e).description(t);return r.forEach(s=>{o.addCommand(Ui(s,n))}),o};wt();process.on("SIGINT",()=>{process.exit(w.CANCELLED)});process.on("unhandledRejection",e=>{throw Ye(e)&&process.exit(w.CANCELLED),e});process.on("uncaughtException",e=>{$(e)});var Ve=new Eu,zi=Object.keys(R.bin||{}),[yn="pf",hn]=zi.length>0?zi:["pf"],{description:Vi,version:$u,repository:Ji,homepage:Au}=R,Ki=Vi?.split(/ —|,|\./)[0]||Vi||"Platform CLI",Yi=Ji?.url?`https://${Ji.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,qi=Yi||Au,Iu=Yi?"GitHub":"README",Ru=qi?[Je.bold(Ki),`
624
624
 
625
- `,Je.cyan("See more at: "),Je.bold(Eu(Au,String(qi)))].join(""):Je.bold(Ki),Ru=[Vt(yn),wi(),Ri,Di,oo],Nu=async()=>{try{let e=g(),t=Ie(e);if(!t.plugins?.length)return[];let r=x(e),n=Pt({workspaceRoot:e,availableServices:at(e),contracts:{path:`${r.relativePath}/src`,packageName:r.packageName}}),o=[];for(let s of t.plugins)try{let{plugin:i}=await St(s,n),a=fn(i.name,i.description??`Commands from ${i.name}`,i.commands,n);o.push(a)}catch(i){console.warn(`\u26A0\uFE0F Failed to load plugin '${s}':`,i.message)}return o}catch{return[]}},Fu=async()=>{let e=await Nu(),t=[...Ru,...e];Ve.name(yn).description(Iu).version(Tu||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Je.cyan(r.name())}).addHelpText("after",os),hn&&hn!==yn&&Ve.alias(hn);for(let r of t)Ve.addCommand(r);Ve.command("__workspace-hash",{hidden:!0}).action(()=>{let r=process.cwd(),n=Math.abs(r.split("").reduce((o,s)=>(o<<5)-o+s.charCodeAt(0)|0,0));console.log(n)}),ss(Ve,Su,t)};Fu();
625
+ `,Je.cyan("See more at: "),Je.bold(Tu(Iu,String(qi)))].join(""):Je.bold(Ki),Nu=[Vt(yn),wi(),Ri,Di,oo],Fu=async()=>{try{let e=g(),t=Ie(e);if(!t.plugins?.length)return[];let r=x(e),n=Pt({workspaceRoot:e,availableServices:at(e),contracts:{path:`${r.relativePath}/src`,packageName:r.packageName}}),o=[];for(let s of t.plugins)try{let{plugin:i}=await St(s,n),a=fn(i.name,i.description??`Commands from ${i.name}`,i.commands,n);o.push(a)}catch(i){console.warn(`\u26A0\uFE0F Failed to load plugin '${s}':`,i.message)}return o}catch{return[]}},Ou=async()=>{let e=await Fu(),t=[...Nu,...e];Ve.name(yn).description(Ru).version($u||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Je.cyan(r.name())}).addHelpText("after",os),hn&&hn!==yn&&Ve.alias(hn);for(let r of t)Ve.addCommand(r);Ve.command("__workspace-hash",{hidden:!0}).action(()=>{let r=process.cwd(),n=Math.abs(r.split("").reduce((o,s)=>(o<<5)-o+s.charCodeAt(0)|0,0));console.log(n)}),ss(Ve,bu,t)};Ou();
@@ -7,8 +7,8 @@
7
7
  "pulumi": "pulumi"
8
8
  },
9
9
  "dependencies": {
10
- "@crossdelta/cloudevents": "^0.7.20",
11
- "@crossdelta/infrastructure": "^0.11.5",
10
+ "@crossdelta/cloudevents": "^0.7.21",
11
+ "@crossdelta/infrastructure": "^0.11.6",
12
12
  "{{scope}}/contracts": "workspace:*",
13
13
  "@pulumi/digitalocean": "^4.55.0",
14
14
  "@pulumi/kubernetes": "^4.21.0",
@@ -19,8 +19,8 @@
19
19
  "clean": "rm -rf dist"
20
20
  },
21
21
  "dependencies": {
22
- "@crossdelta/cloudevents": "^0.7.20",
23
- "@crossdelta/infrastructure": "^0.11.5",
22
+ "@crossdelta/cloudevents": "^0.7.21",
23
+ "@crossdelta/infrastructure": "^0.11.6",
24
24
  "zod": "^4.0.0"
25
25
  },
26
26
  "devDependencies": {
package/dist/facade.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FlowContext, FlowRunOptions, FlowResult } from '@crossdelta/flowcore';
2
2
  export { FlowContext, FlowResult, FlowRunOptions } from '@crossdelta/flowcore';
3
- import { P as PfWorkspaceContext, g as PfEffect, a as PfPluginContext, L as LoadedPlugin, b as PfPlugin } from './plugin-types-DQOv97Zh.mjs';
4
- export { E as ElicitInputEffect, h as ElicitInputField, i as EnvAddEffect, F as FileWriteEffect, I as InfraAddEffect, c as PfCommand, d as PfCommandArg, e as PfCommandOption, j as PfCommandResult, k as isElicitInputEffect } from './plugin-types-DQOv97Zh.mjs';
3
+ import { PfWorkspaceContext, PfEffect, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
4
+ export { ElicitInputEffect, ElicitInputField, EnvAddEffect, FileWriteEffect, InfraAddEffect, LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfCommandResult, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, isElicitInputEffect } from '@crossdelta/shared/plugin-types';
5
5
  export { deriveEventNames } from '@crossdelta/cloudevents';
6
6
  import { z } from 'zod';
7
7
 
@@ -837,4 +837,4 @@ declare const getGeneratorDocsDir: () => string;
837
837
  */
838
838
  declare const listGeneratorDocs: () => Promise<string[]>;
839
839
 
840
- export { type Artifact, type CapabilitiesConfig, type Change, type CodingConstraints, type CommandLikeResult, type Diagnostic, type EffectHandlerOptions, type EffectResult, type EffectRuntimeContext, type ExecutableToolSpec, type ForbiddenPattern, type FrameworkLayout, LoadedPlugin, type NextAction, type OperationResult, type ParseResult, type PathGuards, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, type PlannedFile, type PolicyValidationResult, type PolicyViolation, type ProviderLookup, SERVICE_LAYOUT_POLICY_VERSION, type ServiceFramework, type ServiceGenerationInputs, type ServiceMeta, type ServiceMetadata, type ServiceSpec, type ToolInputSchema, type ToolPropertySchema, type ToolSpec, aggregateChanges, applyEffects, collectExecutableToolSpecs, collectToolSpecs, createContext, createContextFromWorkspace, err as createErrResult, ok as createOkResult, findWorkspaceRoot, formatChangeDetails, formatChangeSummary, getFrameworkPolicy, getGeneratorDocsDir, getRegisteredProviders, listGeneratorDocs, loadCapabilitiesConfig, loadCapabilitiesConfigFromWorkspace, loadPlugins, lookupProvider, lowerSpecToCapabilities, parseServicePrompt, planServiceGeneration, resolveProvider, runFlow, serviceLayoutPolicy, validateGeneratedFiles };
840
+ export { type Artifact, type CapabilitiesConfig, type Change, type CodingConstraints, type CommandLikeResult, type Diagnostic, type EffectHandlerOptions, type EffectResult, type EffectRuntimeContext, type ExecutableToolSpec, type ForbiddenPattern, type FrameworkLayout, type NextAction, type OperationResult, type ParseResult, type PathGuards, type PlannedFile, type PolicyValidationResult, type PolicyViolation, type ProviderLookup, SERVICE_LAYOUT_POLICY_VERSION, type ServiceFramework, type ServiceGenerationInputs, type ServiceMeta, type ServiceMetadata, type ServiceSpec, type ToolInputSchema, type ToolPropertySchema, type ToolSpec, aggregateChanges, applyEffects, collectExecutableToolSpecs, collectToolSpecs, createContext, createContextFromWorkspace, err as createErrResult, ok as createOkResult, findWorkspaceRoot, formatChangeDetails, formatChangeSummary, getFrameworkPolicy, getGeneratorDocsDir, getRegisteredProviders, listGeneratorDocs, loadCapabilitiesConfig, loadCapabilitiesConfigFromWorkspace, loadPlugins, lookupProvider, lowerSpecToCapabilities, parseServicePrompt, planServiceGeneration, resolveProvider, runFlow, serviceLayoutPolicy, validateGeneratedFiles };
package/dist/facade.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FlowContext, FlowRunOptions, FlowResult } from '@crossdelta/flowcore';
2
2
  export { FlowContext, FlowResult, FlowRunOptions } from '@crossdelta/flowcore';
3
- import { P as PfWorkspaceContext, g as PfEffect, a as PfPluginContext, L as LoadedPlugin, b as PfPlugin } from './plugin-types-DQOv97Zh.js';
4
- export { E as ElicitInputEffect, h as ElicitInputField, i as EnvAddEffect, F as FileWriteEffect, I as InfraAddEffect, c as PfCommand, d as PfCommandArg, e as PfCommandOption, j as PfCommandResult, k as isElicitInputEffect } from './plugin-types-DQOv97Zh.js';
3
+ import { PfWorkspaceContext, PfEffect, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
4
+ export { ElicitInputEffect, ElicitInputField, EnvAddEffect, FileWriteEffect, InfraAddEffect, LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfCommandResult, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, isElicitInputEffect } from '@crossdelta/shared/plugin-types';
5
5
  export { deriveEventNames } from '@crossdelta/cloudevents';
6
6
  import { z } from 'zod';
7
7
 
@@ -837,4 +837,4 @@ declare const getGeneratorDocsDir: () => string;
837
837
  */
838
838
  declare const listGeneratorDocs: () => Promise<string[]>;
839
839
 
840
- export { type Artifact, type CapabilitiesConfig, type Change, type CodingConstraints, type CommandLikeResult, type Diagnostic, type EffectHandlerOptions, type EffectResult, type EffectRuntimeContext, type ExecutableToolSpec, type ForbiddenPattern, type FrameworkLayout, LoadedPlugin, type NextAction, type OperationResult, type ParseResult, type PathGuards, PfEffect, PfPlugin, PfPluginContext, PfWorkspaceContext, type PlannedFile, type PolicyValidationResult, type PolicyViolation, type ProviderLookup, SERVICE_LAYOUT_POLICY_VERSION, type ServiceFramework, type ServiceGenerationInputs, type ServiceMeta, type ServiceMetadata, type ServiceSpec, type ToolInputSchema, type ToolPropertySchema, type ToolSpec, aggregateChanges, applyEffects, collectExecutableToolSpecs, collectToolSpecs, createContext, createContextFromWorkspace, err as createErrResult, ok as createOkResult, findWorkspaceRoot, formatChangeDetails, formatChangeSummary, getFrameworkPolicy, getGeneratorDocsDir, getRegisteredProviders, listGeneratorDocs, loadCapabilitiesConfig, loadCapabilitiesConfigFromWorkspace, loadPlugins, lookupProvider, lowerSpecToCapabilities, parseServicePrompt, planServiceGeneration, resolveProvider, runFlow, serviceLayoutPolicy, validateGeneratedFiles };
840
+ export { type Artifact, type CapabilitiesConfig, type Change, type CodingConstraints, type CommandLikeResult, type Diagnostic, type EffectHandlerOptions, type EffectResult, type EffectRuntimeContext, type ExecutableToolSpec, type ForbiddenPattern, type FrameworkLayout, type NextAction, type OperationResult, type ParseResult, type PathGuards, type PlannedFile, type PolicyValidationResult, type PolicyViolation, type ProviderLookup, SERVICE_LAYOUT_POLICY_VERSION, type ServiceFramework, type ServiceGenerationInputs, type ServiceMeta, type ServiceMetadata, type ServiceSpec, type ToolInputSchema, type ToolPropertySchema, type ToolSpec, aggregateChanges, applyEffects, collectExecutableToolSpecs, collectToolSpecs, createContext, createContextFromWorkspace, err as createErrResult, ok as createOkResult, findWorkspaceRoot, formatChangeDetails, formatChangeSummary, getFrameworkPolicy, getGeneratorDocsDir, getRegisteredProviders, listGeneratorDocs, loadCapabilitiesConfig, loadCapabilitiesConfigFromWorkspace, loadPlugins, lookupProvider, lowerSpecToCapabilities, parseServicePrompt, planServiceGeneration, resolveProvider, runFlow, serviceLayoutPolicy, validateGeneratedFiles };
package/dist/facade.js CHANGED
@@ -383,7 +383,7 @@ __export(facade_exports, {
383
383
  getFrameworkPolicy: () => getFrameworkPolicy,
384
384
  getGeneratorDocsDir: () => getGeneratorDocsDir,
385
385
  getRegisteredProviders: () => getRegisteredProviders,
386
- isElicitInputEffect: () => isElicitInputEffect,
386
+ isElicitInputEffect: () => import_plugin_types.isElicitInputEffect,
387
387
  listGeneratorDocs: () => listGeneratorDocs,
388
388
  loadCapabilitiesConfig: () => loadCapabilitiesConfig,
389
389
  loadCapabilitiesConfigFromWorkspace: () => loadCapabilitiesConfigFromWorkspace,
@@ -2166,7 +2166,7 @@ var planServiceGeneration = (inputs) => {
2166
2166
  init_config();
2167
2167
 
2168
2168
  // cli/src/core/plugins/types.ts
2169
- var isElicitInputEffect = (effect) => effect.kind === "elicit:input";
2169
+ var import_plugin_types = require("@crossdelta/shared/plugin-types");
2170
2170
 
2171
2171
  // cli/src/core/facade/context.ts
2172
2172
  init_config();
package/dist/facade.mjs CHANGED
@@ -2095,7 +2095,9 @@ var planServiceGeneration = (inputs) => {
2095
2095
  init_config();
2096
2096
 
2097
2097
  // cli/src/core/plugins/types.ts
2098
- var isElicitInputEffect = (effect) => effect.kind === "elicit:input";
2098
+ import {
2099
+ isElicitInputEffect
2100
+ } from "@crossdelta/shared/plugin-types";
2099
2101
 
2100
2102
  // cli/src/core/facade/context.ts
2101
2103
  init_config();
@@ -1 +1 @@
1
- export { L as LoadedPlugin, c as PfCommand, d as PfCommandArg, e as PfCommandOption, f as PfFlow, b as PfPlugin, a as PfPluginContext } from './plugin-types-DQOv97Zh.mjs';
1
+ export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext } from '@crossdelta/shared/plugin-types';
@@ -1 +1 @@
1
- export { L as LoadedPlugin, c as PfCommand, d as PfCommandArg, e as PfCommandOption, f as PfFlow, b as PfPlugin, a as PfPluginContext } from './plugin-types-DQOv97Zh.js';
1
+ export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext } from '@crossdelta/shared/plugin-types';
package/dist/plugin.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PfWorkspaceContext, a as PfPluginContext, L as LoadedPlugin, b as PfPlugin } from './plugin-types-DQOv97Zh.mjs';
2
- export { c as PfCommand, d as PfCommandArg, e as PfCommandOption, f as PfFlow } from './plugin-types-DQOv97Zh.mjs';
1
+ import { PfWorkspaceContext, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
2
+ export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext, PfWorkspaceContext } from '@crossdelta/shared/plugin-types';
3
3
 
4
4
  /**
5
5
  * Plugin Loader
@@ -28,4 +28,4 @@ declare const createPluginContext: (workspace: PfWorkspaceContext, logger?: PfPl
28
28
  */
29
29
  declare const loadPluginFromModule: (moduleName: string, context: PfPluginContext) => Promise<LoadedPlugin>;
30
30
 
31
- export { LoadedPlugin, PfPlugin, PfPluginContext, PfWorkspaceContext, createPluginContext, loadPluginFromModule, validatePlugin, validatePluginStrict };
31
+ export { createPluginContext, loadPluginFromModule, validatePlugin, validatePluginStrict };
package/dist/plugin.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PfWorkspaceContext, a as PfPluginContext, L as LoadedPlugin, b as PfPlugin } from './plugin-types-DQOv97Zh.js';
2
- export { c as PfCommand, d as PfCommandArg, e as PfCommandOption, f as PfFlow } from './plugin-types-DQOv97Zh.js';
1
+ import { PfWorkspaceContext, PfPluginContext, LoadedPlugin, PfPlugin } from '@crossdelta/shared/plugin-types';
2
+ export { LoadedPlugin, PfCommand, PfCommandArg, PfCommandOption, PfFlow, PfPlugin, PfPluginContext, PfWorkspaceContext } from '@crossdelta/shared/plugin-types';
3
3
 
4
4
  /**
5
5
  * Plugin Loader
@@ -28,4 +28,4 @@ declare const createPluginContext: (workspace: PfWorkspaceContext, logger?: PfPl
28
28
  */
29
29
  declare const loadPluginFromModule: (moduleName: string, context: PfPluginContext) => Promise<LoadedPlugin>;
30
30
 
31
- export { LoadedPlugin, PfPlugin, PfPluginContext, PfWorkspaceContext, createPluginContext, loadPluginFromModule, validatePlugin, validatePluginStrict };
31
+ export { createPluginContext, loadPluginFromModule, validatePlugin, validatePluginStrict };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.21.12",
3
+ "version": "0.21.13",
4
4
  "description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
5
5
  "keywords": [
6
6
  "cli",
@@ -118,8 +118,9 @@
118
118
  "@ai-sdk/anthropic": "^2.0.53",
119
119
  "@ai-sdk/openai": "^2.0.79",
120
120
  "@angular-devkit/core": "^21.0.0",
121
- "@crossdelta/cloudevents": "^0.7.20",
121
+ "@crossdelta/cloudevents": "^0.7.21",
122
122
  "@crossdelta/flowcore": "^0.1.2",
123
+ "@crossdelta/shared": "^0.1.0",
123
124
  "@faker-js/faker": "^9.8.0",
124
125
  "@inquirer/prompts": "^7.5.0",
125
126
  "@listr2/prompt-adapter-enquirer": "^2.0.15",
@@ -144,7 +145,7 @@
144
145
  "zod": "^4.0.0"
145
146
  },
146
147
  "peerDependencies": {
147
- "@crossdelta/infrastructure": "^0.11.5",
148
+ "@crossdelta/infrastructure": "^0.11.6",
148
149
  "@nestjs/schematics": "^11.0.5",
149
150
  "turbo": "^2.0.0"
150
151
  },
@@ -1,180 +0,0 @@
1
- /**
2
- * Plugin System Types
3
- *
4
- * pf owns and defines these interfaces.
5
- * Plugins MUST adapt to these interfaces.
6
- * pf is strict and predictable - no duck-typing, no fallbacks.
7
- */
8
- /**
9
- * Base effect type - all domain effects must have a kind
10
- * pf handles effects generically via kind-based handler registry
11
- */
12
- interface PfEffect {
13
- readonly kind: string;
14
- }
15
- /**
16
- * File write effect - write content to a file
17
- */
18
- interface FileWriteEffect extends PfEffect {
19
- readonly kind: 'file:write';
20
- readonly path: string;
21
- readonly content: string;
22
- }
23
- /**
24
- * Infrastructure service configuration effect
25
- */
26
- interface InfraAddEffect extends PfEffect {
27
- readonly kind: 'infra:add';
28
- readonly serviceName: string;
29
- readonly port: number;
30
- readonly framework: string;
31
- readonly runtime: string;
32
- }
33
- /**
34
- * Environment variable effect
35
- */
36
- interface EnvAddEffect extends PfEffect {
37
- readonly kind: 'env:add';
38
- readonly key: string;
39
- readonly value: string;
40
- }
41
- /**
42
- * Field definition for input elicitation
43
- *
44
- * Describes a single field that needs user input.
45
- * Host-agnostic - CLI and MCP interpret this differently.
46
- */
47
- interface ElicitInputField {
48
- /** Field name (used as key in response) */
49
- readonly name: string;
50
- /** Human-readable prompt/question */
51
- readonly prompt: string;
52
- /** Whether the field is required */
53
- readonly required?: boolean;
54
- /** Detailed description (shown as help text) */
55
- readonly description?: string;
56
- /** Default value if user provides nothing */
57
- readonly defaultValue?: unknown;
58
- /** Allowed values (enum constraint) */
59
- readonly enum?: readonly string[];
60
- /** Field type hint */
61
- readonly type?: 'string' | 'number' | 'boolean';
62
- }
63
- /**
64
- * Input elicitation effect
65
- *
66
- * Returned by tools when required inputs are missing.
67
- * Pure data - no MCP SDK imports, no host-specific logic.
68
- *
69
- * Hosts interpret this effect differently:
70
- * - CLI: Interactive prompt
71
- * - MCP: server.elicitInput() or structured error
72
- */
73
- interface ElicitInputEffect extends PfEffect {
74
- readonly kind: 'elicit:input';
75
- /** Message explaining what's needed */
76
- readonly message: string;
77
- /** Fields to collect from user */
78
- readonly fields: readonly ElicitInputField[];
79
- }
80
- /**
81
- * Type guard for ElicitInputEffect
82
- */
83
- declare const isElicitInputEffect: (effect: PfEffect) => effect is ElicitInputEffect;
84
- /**
85
- * Result of running a command
86
- */
87
- interface PfCommandResult {
88
- /** Domain effects to be applied by the runtime */
89
- effects: PfEffect[];
90
- /** Optional output to display (for read-only commands) */
91
- output?: string | string[];
92
- }
93
- /**
94
- * Command argument definition
95
- */
96
- interface PfCommandArg {
97
- name: string;
98
- description: string;
99
- required: boolean;
100
- }
101
- /**
102
- * Command option definition
103
- */
104
- interface PfCommandOption {
105
- flags: string;
106
- description: string;
107
- default?: unknown;
108
- }
109
- /**
110
- * A CLI command provided by a plugin
111
- *
112
- * Plugins MUST implement this exact interface.
113
- */
114
- interface PfCommand {
115
- name: string;
116
- description: string;
117
- args: PfCommandArg[];
118
- options: PfCommandOption[];
119
- run(args: Record<string, unknown>, options: Record<string, unknown>): Promise<PfCommandResult>;
120
- }
121
- /**
122
- * An interactive flow provided by a plugin
123
- */
124
- interface PfFlow {
125
- name: string;
126
- description: string;
127
- getSteps(initialContext?: Record<string, unknown>): Promise<unknown[]>;
128
- }
129
- /**
130
- * Workspace context with all discovered information
131
- * pf owns this - plugins receive it during setup
132
- */
133
- interface PfWorkspaceContext {
134
- /** Absolute path to workspace root */
135
- workspaceRoot: string;
136
- /** Discovered services (relative paths like 'services/api-gateway') */
137
- availableServices: string[];
138
- /** Contracts package configuration */
139
- contracts: {
140
- /** Relative path to contracts source (e.g., 'packages/contracts/src') */
141
- path: string;
142
- /** Package name (e.g., '@my-platform/contracts') */
143
- packageName?: string;
144
- };
145
- }
146
- /**
147
- * Plugin context provided by pf during setup
148
- */
149
- interface PfPluginContext {
150
- workspace: PfWorkspaceContext;
151
- logger: {
152
- debug: (message: string) => void;
153
- info: (message: string) => void;
154
- warn: (message: string) => void;
155
- error: (message: string) => void;
156
- };
157
- }
158
- /**
159
- * A plugin that can be loaded by pf
160
- *
161
- * Plugins MUST implement this exact interface.
162
- * If a plugin has a different internal API, it must provide an adapter.
163
- */
164
- interface PfPlugin {
165
- name: string;
166
- version: string;
167
- description?: string;
168
- commands: PfCommand[];
169
- flows: PfFlow[];
170
- setup: (context: PfPluginContext) => Promise<void> | void;
171
- }
172
- /**
173
- * Result of loading a plugin
174
- */
175
- interface LoadedPlugin {
176
- plugin: PfPlugin;
177
- source: string;
178
- }
179
-
180
- export { type ElicitInputEffect as E, type FileWriteEffect as F, type InfraAddEffect as I, type LoadedPlugin as L, type PfWorkspaceContext as P, type PfPluginContext as a, type PfPlugin as b, type PfCommand as c, type PfCommandArg as d, type PfCommandOption as e, type PfFlow as f, type PfEffect as g, type ElicitInputField as h, type EnvAddEffect as i, type PfCommandResult as j, isElicitInputEffect as k };
@@ -1,180 +0,0 @@
1
- /**
2
- * Plugin System Types
3
- *
4
- * pf owns and defines these interfaces.
5
- * Plugins MUST adapt to these interfaces.
6
- * pf is strict and predictable - no duck-typing, no fallbacks.
7
- */
8
- /**
9
- * Base effect type - all domain effects must have a kind
10
- * pf handles effects generically via kind-based handler registry
11
- */
12
- interface PfEffect {
13
- readonly kind: string;
14
- }
15
- /**
16
- * File write effect - write content to a file
17
- */
18
- interface FileWriteEffect extends PfEffect {
19
- readonly kind: 'file:write';
20
- readonly path: string;
21
- readonly content: string;
22
- }
23
- /**
24
- * Infrastructure service configuration effect
25
- */
26
- interface InfraAddEffect extends PfEffect {
27
- readonly kind: 'infra:add';
28
- readonly serviceName: string;
29
- readonly port: number;
30
- readonly framework: string;
31
- readonly runtime: string;
32
- }
33
- /**
34
- * Environment variable effect
35
- */
36
- interface EnvAddEffect extends PfEffect {
37
- readonly kind: 'env:add';
38
- readonly key: string;
39
- readonly value: string;
40
- }
41
- /**
42
- * Field definition for input elicitation
43
- *
44
- * Describes a single field that needs user input.
45
- * Host-agnostic - CLI and MCP interpret this differently.
46
- */
47
- interface ElicitInputField {
48
- /** Field name (used as key in response) */
49
- readonly name: string;
50
- /** Human-readable prompt/question */
51
- readonly prompt: string;
52
- /** Whether the field is required */
53
- readonly required?: boolean;
54
- /** Detailed description (shown as help text) */
55
- readonly description?: string;
56
- /** Default value if user provides nothing */
57
- readonly defaultValue?: unknown;
58
- /** Allowed values (enum constraint) */
59
- readonly enum?: readonly string[];
60
- /** Field type hint */
61
- readonly type?: 'string' | 'number' | 'boolean';
62
- }
63
- /**
64
- * Input elicitation effect
65
- *
66
- * Returned by tools when required inputs are missing.
67
- * Pure data - no MCP SDK imports, no host-specific logic.
68
- *
69
- * Hosts interpret this effect differently:
70
- * - CLI: Interactive prompt
71
- * - MCP: server.elicitInput() or structured error
72
- */
73
- interface ElicitInputEffect extends PfEffect {
74
- readonly kind: 'elicit:input';
75
- /** Message explaining what's needed */
76
- readonly message: string;
77
- /** Fields to collect from user */
78
- readonly fields: readonly ElicitInputField[];
79
- }
80
- /**
81
- * Type guard for ElicitInputEffect
82
- */
83
- declare const isElicitInputEffect: (effect: PfEffect) => effect is ElicitInputEffect;
84
- /**
85
- * Result of running a command
86
- */
87
- interface PfCommandResult {
88
- /** Domain effects to be applied by the runtime */
89
- effects: PfEffect[];
90
- /** Optional output to display (for read-only commands) */
91
- output?: string | string[];
92
- }
93
- /**
94
- * Command argument definition
95
- */
96
- interface PfCommandArg {
97
- name: string;
98
- description: string;
99
- required: boolean;
100
- }
101
- /**
102
- * Command option definition
103
- */
104
- interface PfCommandOption {
105
- flags: string;
106
- description: string;
107
- default?: unknown;
108
- }
109
- /**
110
- * A CLI command provided by a plugin
111
- *
112
- * Plugins MUST implement this exact interface.
113
- */
114
- interface PfCommand {
115
- name: string;
116
- description: string;
117
- args: PfCommandArg[];
118
- options: PfCommandOption[];
119
- run(args: Record<string, unknown>, options: Record<string, unknown>): Promise<PfCommandResult>;
120
- }
121
- /**
122
- * An interactive flow provided by a plugin
123
- */
124
- interface PfFlow {
125
- name: string;
126
- description: string;
127
- getSteps(initialContext?: Record<string, unknown>): Promise<unknown[]>;
128
- }
129
- /**
130
- * Workspace context with all discovered information
131
- * pf owns this - plugins receive it during setup
132
- */
133
- interface PfWorkspaceContext {
134
- /** Absolute path to workspace root */
135
- workspaceRoot: string;
136
- /** Discovered services (relative paths like 'services/api-gateway') */
137
- availableServices: string[];
138
- /** Contracts package configuration */
139
- contracts: {
140
- /** Relative path to contracts source (e.g., 'packages/contracts/src') */
141
- path: string;
142
- /** Package name (e.g., '@my-platform/contracts') */
143
- packageName?: string;
144
- };
145
- }
146
- /**
147
- * Plugin context provided by pf during setup
148
- */
149
- interface PfPluginContext {
150
- workspace: PfWorkspaceContext;
151
- logger: {
152
- debug: (message: string) => void;
153
- info: (message: string) => void;
154
- warn: (message: string) => void;
155
- error: (message: string) => void;
156
- };
157
- }
158
- /**
159
- * A plugin that can be loaded by pf
160
- *
161
- * Plugins MUST implement this exact interface.
162
- * If a plugin has a different internal API, it must provide an adapter.
163
- */
164
- interface PfPlugin {
165
- name: string;
166
- version: string;
167
- description?: string;
168
- commands: PfCommand[];
169
- flows: PfFlow[];
170
- setup: (context: PfPluginContext) => Promise<void> | void;
171
- }
172
- /**
173
- * Result of loading a plugin
174
- */
175
- interface LoadedPlugin {
176
- plugin: PfPlugin;
177
- source: string;
178
- }
179
-
180
- export { type ElicitInputEffect as E, type FileWriteEffect as F, type InfraAddEffect as I, type LoadedPlugin as L, type PfWorkspaceContext as P, type PfPluginContext as a, type PfPlugin as b, type PfCommand as c, type PfCommandArg as d, type PfCommandOption as e, type PfFlow as f, type PfEffect as g, type ElicitInputField as h, type EnvAddEffect as i, type PfCommandResult as j, isElicitInputEffect as k };