@crossdelta/platform-sdk 0.21.29 → 0.22.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to `@crossdelta/platform-sdk` will be documented in this fil
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.22.0] - 2026-08-24
9
+
10
+ ### Changed
11
+ - **`pf new workspace` scaffolds a Claude Code setup.** A new workspace gets a root `CLAUDE.md` and
12
+ `.claude/rules/cloudevents.md` instead of `.github/copilot-instructions.md` and three files under
13
+ `.github/instructions/`. Existing workspaces need no migration: their
14
+ `.github/copilot-instructions.md` is still read.
15
+ - **`loadProjectInstructions` reads every agent-instruction convention a workspace carries**, not
16
+ one: `CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md` and `docs/ai-guidelines.md`.
17
+ Missing files are skipped, and the token budget is divided among the files that actually
18
+ contribute after compression.
19
+
20
+ ### Fixed
21
+ - **`pf new workspace` aborted at `bun install`** with
22
+ `Workspace dependency "@<scope>/types" not found`. The scaffolded contracts package declared a
23
+ workspace dependency that the template does not create.
24
+
8
25
  ## [0.21.29] - 2026-08-23
9
26
 
10
27
  ### Changed
package/bin/cli.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- var ta=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 ra=(e,t)=>{for(var r in t)ta(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,Cn,kn,xn,na,oa,Ye,sa,ia,$,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"],na=["ERR_USE_AFTER_CLOSE"],oa=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&&na.includes(t)?oa(e):!1},sa=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}`)},ia=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(sa(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(ia(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=aa(c.barColor??t?.barColor),p=ca(c,i,o,l,s,t?.labelColor);a.push(p)}return n&&(a.push(""),a.push(n)),a.join(`
5
- `)}function aa(e){return e?Xe[e]("\u2587"):"\u2587"}function ca(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 la,writeFileSync as pa}from"fs";import{join as Xt}from"path";import Zt from"chokidar";var er,Qe,ma,bn,tr,da,En,rr=S(()=>{"use strict";v();f();er=".pf-generating",Qe=e=>Xt(e,er),ma=e=>Qt(Qe(e)),bn=e=>{pa(Qe(e),"","utf-8")},tr=e=>{let t=Qe(e);Qt(t)&&la(t)},da=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=da(e),n=Qe(e),s=ae(async()=>{ma(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 ga}from"commander";import{Listr as $n}from"listr2";var J,ua,An,In=S(()=>{"use strict";V();rr();f();J=e=>{let t=new ga(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(`
2
+ var ra=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 na=(e,t)=>{for(var r in t)ra(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,Cn,kn,xn,oa,sa,Ye,ia,aa,$,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"],oa=["ERR_USE_AFTER_CLOSE"],sa=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&&oa.includes(t)?sa(e):!1},ia=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}`)},aa=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(ia(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(aa(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=ca(c.barColor??t?.barColor),p=la(c,i,o,l,s,t?.labelColor);a.push(p)}return n&&(a.push(""),a.push(n)),a.join(`
5
+ `)}function ca(e){return e?Xe[e]("\u2587"):"\u2587"}function la(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 pa,writeFileSync as ma}from"fs";import{join as Xt}from"path";import Zt from"chokidar";var er,Qe,da,bn,tr,ga,En,rr=S(()=>{"use strict";v();f();er=".pf-generating",Qe=e=>Xt(e,er),da=e=>Qt(Qe(e)),bn=e=>{ma(Qe(e),"","utf-8")},tr=e=>{let t=Qe(e);Qt(t)&&pa(t)},ga=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=ga(e),n=Qe(e),s=ae(async()=>{da(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 ua}from"commander";import{Listr as $n}from"listr2";var J,fa,An,In=S(()=>{"use strict";V();rr();f();J=e=>{let t=new ua(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=ua(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},ua=(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 fa}from"execa";function Ee(e){try{return fa(e,["--version"]),!0}catch{return!1}}var nr=S(()=>{"use strict"});var Fn=S(()=>{"use strict";nr()});import{readdirSync as ha}from"fs";import{dirname as On,isAbsolute as ya,join as va,normalize as Ca,resolve as Mn,sep as ka}from"path";import{fileURLToPath as xa}from"url";import{packageUpSync as wa}from"package-up";import{rimraf as Pa}from"rimraf";function _n(){let e=wa({cwd:On(Sa())});if(!e)throw new Error("Could not find package.json");return On(e)}var Sa,O,Dn,et,jn,or=S(()=>{"use strict";V();f();Sa=()=>typeof import.meta?.url=="string"?xa(import.meta.url):process.cwd(),O=e=>{let t=sr()?g():process.cwd();return va(t,e)},Dn=(e,t)=>{if(!e?.trim())throw new z("Path cannot be empty",e,{hint:"Provide a valid relative path"});if(ya(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=Ca(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 ha(e).length===0}catch{return!0}};jn=e=>Pa(e)});import Te from"chalk";var Ln,ba,Ea,tt,d,Wn=S(()=>{"use strict";Ln={debug:0,info:1,warn:2,error:3,silent:4},ba=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",Ea=()=>{let e=process.env.LOG_LEVEL;return ba(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},tt=e=>{let t=Ea();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 Ta 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=Ta.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}var Gn=S(()=>{"use strict"});var v=S(()=>{"use strict";Sn();In();Rn();Nn();Fn();or();Wn();Hn();nr();Gn()});var Vn={};ra(Vn,{discoverAvailableServices:()=>at,findWorkspaceRoot:()=>g,getContractsConfig:()=>x,getGeneratorConfig:()=>ce,getPackageJsonField:()=>Ha,getPfConfig:()=>Ie,getPkgJson:()=>cr,getRootPackageScope:()=>st,getWorkspacePackageJson:()=>F,getWorkspacePathsConfig:()=>E,isInWorkspace:()=>sr,pkgJson:()=>R,readPackageConfig:()=>Re,updatePackageJsonField:()=>it});import{existsSync as Ae,readdirSync as $a,readFileSync as Bn,writeFileSync as Aa}from"fs";import{join as I,resolve as Ia}from"path";var ar,Ra,Na,Fa,$e,Oa,ot,nt,Ma,Da,Un,_a,ja,zn,sr,g,F,E,Ie,x,st,La,Wa,Ha,it,Re,ir,cr,R,ce,at,f=S(()=>{"use strict";Ze();v();ar=e=>JSON.parse(Bn(e,"utf-8")),Ra=ar,Na=(e,t,r)=>Aa(e,`${JSON.stringify(t,null,2)}
9
- `,"utf-8"),Fa=["@crossdelta/cloudevents"],$e={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Oa={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(Bn(e,"utf-8"))}catch{return null}},nt=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,Ma=e=>e.split("/").pop()||"workspace",Da=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},Un=e=>e.split("."),_a=(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?_a(t,e):!1},zn=e=>{let t=e;for(;t;){if(ja(t))return t;t=Da(t)}return null},sr=()=>zn(process.cwd())!==null,g=()=>{let e=zn(process.cwd());if(!e)throw new Error(`
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=fa(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},fa=(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 ha}from"execa";function Ee(e){try{return ha(e,["--version"]),!0}catch{return!1}}var nr=S(()=>{"use strict"});var Fn=S(()=>{"use strict";nr()});import{readdirSync as ya}from"fs";import{dirname as On,isAbsolute as va,join as Ca,normalize as ka,resolve as Mn,sep as xa}from"path";import{fileURLToPath as wa}from"url";import{packageUpSync as Pa}from"package-up";import{rimraf as Sa}from"rimraf";function _n(){let e=Pa({cwd:On(ba())});if(!e)throw new Error("Could not find package.json");return On(e)}var ba,O,Dn,et,jn,or=S(()=>{"use strict";V();f();ba=()=>typeof import.meta?.url=="string"?wa(import.meta.url):process.cwd(),O=e=>{let t=sr()?g():process.cwd();return Ca(t,e)},Dn=(e,t)=>{if(!e?.trim())throw new z("Path cannot be empty",e,{hint:"Provide a valid relative path"});if(va(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=ka(e),s=Mn(t),i=Mn(t,o);if(!i.startsWith(s+xa)&&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 ya(e).length===0}catch{return!0}};jn=e=>Sa(e)});import Te from"chalk";var Ln,Ea,Ta,tt,d,Wn=S(()=>{"use strict";Ln={debug:0,info:1,warn:2,error:3,silent:4},Ea=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",Ta=()=>{let e=process.env.LOG_LEVEL;return Ea(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},tt=e=>{let t=Ta();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 $a 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=$a.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}var Gn=S(()=>{"use strict"});var v=S(()=>{"use strict";Sn();In();Rn();Nn();Fn();or();Wn();Hn();nr();Gn()});var Vn={};na(Vn,{discoverAvailableServices:()=>at,findWorkspaceRoot:()=>g,getContractsConfig:()=>x,getGeneratorConfig:()=>ce,getPackageJsonField:()=>Ga,getPfConfig:()=>Ie,getPkgJson:()=>cr,getRootPackageScope:()=>st,getWorkspacePackageJson:()=>F,getWorkspacePathsConfig:()=>E,isInWorkspace:()=>sr,pkgJson:()=>R,readPackageConfig:()=>Re,updatePackageJsonField:()=>it});import{existsSync as Ae,readdirSync as Aa,readFileSync as Bn,writeFileSync as Ia}from"fs";import{join as I,resolve as Ra}from"path";var ar,Na,Fa,Oa,$e,Ma,ot,nt,Da,_a,Un,ja,La,zn,sr,g,F,E,Ie,x,st,Wa,Ha,Ga,it,Re,ir,cr,R,ce,at,f=S(()=>{"use strict";Ze();v();ar=e=>JSON.parse(Bn(e,"utf-8")),Na=ar,Fa=(e,t,r)=>Ia(e,`${JSON.stringify(t,null,2)}
9
+ `,"utf-8"),Oa=["@crossdelta/cloudevents"],$e={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Ma={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(Bn(e,"utf-8"))}catch{return null}},nt=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,Da=e=>e.split("/").pop()||"workspace",_a=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},Un=e=>e.split("."),ja=(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},La=e=>{let t=ot(I(e,"package.json"));return t?ja(t,e):!1},zn=e=>{let t=e;for(;t;){if(La(t))return t;t=_a(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
 
12
12
  Current directory: ${process.cwd()}
@@ -16,35 +16,35 @@ This command must be run from within a workspace created with \x1B[36mpf new wor
16
16
  To create a new workspace, run:
17
17
 
18
18
  \x1B[36mpf new workspace my-platform\x1B[0m
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??Fa,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=`@${Ma(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:r},La=(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},Wa=(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},Ha=(e,t=process.cwd())=>{let r=ar(I(t,"package.json"));return La(r,e)},it=(e,t,r=process.cwd())=>{let n=I(r,"package.json"),o=ar(n);Wa(o,e,t),Na(n,o,{spaces:2,EOL:`
20
- `,encoding:"utf-8"})},Re=e=>{let t=_n();return Ra(Ia(t,e))},ir=null,cr=()=>(ir||(ir=Re("package.json")),ir),R=new Proxy({},{get:(e,t)=>cr()[t]}),ce=()=>cr().generatorConfig??Oa,at=e=>{let t=e??g(),r=E(t),n=I(t,r.services);if(!Ae(n))return[];try{return $a(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 oc from"chalk";import{Command as sc}from"commander";v();import{existsSync as Xa}from"fs";import{join as Qa}from"path";import{cwd as Xn}from"process";import{execaSync as ec}from"execa";v();import{spawn as mr}from"child_process";import{resolve as za}from"path";import{execa as Va}from"execa";import{existsSync as Ga}from"fs";import{resolve as Ba}from"path";import{config as Ua}from"dotenv";var lr=(e,t)=>{let r=Ba(t,e);return Ga(r)?Ua({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"},Ja=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",Ka=(e,t,r)=>e?{...pr,...e}:t||r?{...pr,CI:"true"}:{...pr},qa=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=Va(e,t,{cwd:r,stdio:Ja(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:Ka(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(qa(p))return;throw new Error(Ya(p))}}var Ya=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=za(n,"node_modules",".bin"),y=process.env.PATH||"",j=`${m}:${y}`,be={...process.env,...p,PATH:j,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,env:process.env,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
- `).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=>Xa(Qa(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)??tc()}function tc(){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=rc(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(j=>j.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(`
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??Oa,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=`@${Da(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:r},Wa=(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},Ha=(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},Ga=(e,t=process.cwd())=>{let r=ar(I(t,"package.json"));return Wa(r,e)},it=(e,t,r=process.cwd())=>{let n=I(r,"package.json"),o=ar(n);Ha(o,e,t),Fa(n,o,{spaces:2,EOL:`
20
+ `,encoding:"utf-8"})},Re=e=>{let t=_n();return Na(Ra(t,e))},ir=null,cr=()=>(ir||(ir=Re("package.json")),ir),R=new Proxy({},{get:(e,t)=>cr()[t]}),ce=()=>cr().generatorConfig??Ma,at=e=>{let t=e??g(),r=E(t),n=I(t,r.services);if(!Ae(n))return[];try{return Aa(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 sc from"chalk";import{Command as ic}from"commander";v();import{existsSync as Qa}from"fs";import{join as ec}from"path";import{cwd as Xn}from"process";import{execaSync as tc}from"execa";v();import{spawn as mr}from"child_process";import{resolve as Va}from"path";import{execa as Ja}from"execa";import{existsSync as Ba}from"fs";import{resolve as Ua}from"path";import{config as za}from"dotenv";var lr=(e,t)=>{let r=Ua(t,e);return Ba(r)?za({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"},Ka=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",qa=(e,t,r)=>e?{...pr,...e}:t||r?{...pr,CI:"true"}:{...pr},Ya=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=Ja(e,t,{cwd:r,stdio:Ka(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:qa(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(Ya(p))return;throw new Error(Za(p))}}var Za=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=Va(n,"node_modules",".bin"),y=process.env.PATH||"",j=`${m}:${y}`,be={...process.env,...p,PATH:j,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,env:process.env,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
+ `).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=>Qa(ec(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)??rc()}function rc(){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=nc(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(j=>j.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
- `),ec(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}=nc(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 rc(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 nc(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var ic=e=>e==="yarn"?["npm","audit"]:["audit"],oo=new sc("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=g(),n=b(),o=ic(n),s=t.args||[];console.log(oc.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 xc,writeFileSync as wc}from"fs";import{homedir as Pc}from"os";import{join as Sc}from"path";import{createCipheriv as ac,createDecipheriv as cc,createHash as lc,randomBytes as pc}from"crypto";import{existsSync as mc,readFileSync as dc,writeFileSync as gc}from"fs";import{homedir as so,hostname as uc,userInfo as fc}from"os";import{join as hc}from"path";var gr=hc(so(),".platform-sdk-keys"),io="aes-256-gcm",ao=()=>{let e=`${uc()}:${fc().username}:${so()}`;return lc("sha256").update(e).digest()},co=()=>{if(!mc(gr))return{};try{return JSON.parse(dc(gr,"utf-8"))}catch{return{}}},yc=e=>{gc(gr,JSON.stringify(e,null,2),{mode:384})},vc=e=>{let t=ao(),r=pc(16),n=ac(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}},Cc=e=>{let t=ao(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),o=cc(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]=vc(t),yc(r)}async function lt(e){let r=co()[e];if(!r)return null;try{return Cc(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=Sc(Pc(),".platform-sdk-ai.json"),bc=()=>{let e="anthropic",t=Oe[e];return{provider:e,model:t.defaultModel}},ur=bc();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=xc(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);wc(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 Ec=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},Tc=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 Ec(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});case"anthropic":return Tc(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 Ic}from"fs";import{dirname as Rc,join as ho}from"path";import{dirname as $c}from"path";import{fileURLToPath as Ac}from"url";var W=e=>$c(Ac(e));rr();var Nc=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ee=e=>{let t=e??Nc(),r=o=>fr(ho(o,"package.json")),n=Rc(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 Ic(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 Co,writeFileSync as Fc}from"fs";import{join as hr}from"path";import{getStreamName as Oc}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)},Mc=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
23
+ `),tc(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}=oc(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 nc(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 oc(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var ac=e=>e==="yarn"?["npm","audit"]:["audit"],oo=new ic("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=g(),n=b(),o=ac(n),s=t.args||[];console.log(sc.dim(`Running ${n} ${[...o,...s].join(" ")}`)),qn(n,[...o,...s],{cwd:r})}catch(r){$(r)}});import q from"chalk";import{existsSync as xc,readFileSync as wc,writeFileSync as Pc}from"fs";import{homedir as Sc}from"os";import{join as bc}from"path";import{createCipheriv as cc,createDecipheriv as lc,createHash as pc,randomBytes as mc}from"crypto";import{existsSync as dc,readFileSync as gc,writeFileSync as uc}from"fs";import{homedir as so,hostname as fc,userInfo as hc}from"os";import{join as yc}from"path";var gr=yc(so(),".platform-sdk-keys"),io="aes-256-gcm",ao=()=>{let e=`${fc()}:${hc().username}:${so()}`;return pc("sha256").update(e).digest()},co=()=>{if(!dc(gr))return{};try{return JSON.parse(gc(gr,"utf-8"))}catch{return{}}},vc=e=>{uc(gr,JSON.stringify(e,null,2),{mode:384})},Cc=e=>{let t=ao(),r=mc(16),n=cc(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}},kc=e=>{let t=ao(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),o=lc(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]=Cc(t),vc(r)}async function lt(e){let r=co()[e];if(!r)return null;try{return kc(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=bc(Sc(),".platform-sdk-ai.json"),Ec=()=>{let e="anthropic",t=Oe[e];return{provider:e,model:t.defaultModel}},ur=Ec();function De(){return xc(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=wc(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);Pc(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 Tc=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},$c=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 Tc(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});case"anthropic":return $c(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 Xo,readFileSync as tp,unlinkSync as rp,writeFileSync as np}from"fs";import{join as Qo,resolve as Yo}from"path";import{input as op}from"@inquirer/prompts";import h from"chalk";import sp from"ora";import{existsSync as fr,readdirSync as Rc}from"fs";import{dirname as Nc,join as ho}from"path";import{dirname as Ac}from"path";import{fileURLToPath as Ic}from"url";var W=e=>Ac(Ic(e));rr();var Fc=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ee=e=>{let t=e??Fc(),r=o=>fr(ho(o,"package.json")),n=Nc(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 Rc(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};import{existsSync as nl,readFileSync as ol}from"fs";import{join as sl}from"path";import{Project as il}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 Oc}from"fs";import{join as hr}from"path";import{getStreamName as Mc}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)},Dc=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
- ${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},Dc=(e,t)=>`
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},_c=(e,t)=>`
26
26
 
27
27
  // Consume from ${e} stream
28
28
  consumeJetStreams({
29
29
  streams: ['${e}'],
30
30
  consumer: '${t}-service',
31
31
  discover: './src/events/**/*.handler.ts',
32
- })`,yr=(e,t)=>{let r=Oc(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=Mc(s));let a=Dc(r,i),c=`${s.trimEnd()+a}
33
- `;return Fc(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 _c,readFileSync as jc}from"fs";import{join as xo}from"path";import{getStreamName as Lc,singularize as Wc}from"@crossdelta/cloudevents";var wo=e=>{try{return _c(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=Bc(t);if(!r)return[];let n=Gc(r);return n?[{filePath:e,eventType:n,contractName:r}]:[]},Gc=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}`},Bc=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=Lc(t[0]?.eventType??`${e}.event`),n=`${e}.>`;return{stream:r,subjects:[n],handlers:t}},kr=(e,t)=>e.length===0?"":` // Development: pf dev auto-creates ephemeral streams from contracts
32
+ })`,yr=(e,t)=>{let r=Mc(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=Dc(s));let a=_c(r,i),c=`${s.trimEnd()+a}
33
+ `;return Oc(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 jc,readFileSync as Lc}from"fs";import{join as xo}from"path";import{getStreamName as Wc,singularize as Hc}from"@crossdelta/cloudevents";var wo=e=>{try{return jc(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=Lc(n,"utf-8");return Gc(n,o)})},Gc=(e,t)=>{let r=Uc(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=Hc(n),i=r.slice(1).map(a=>a.toLowerCase()).join("-");return`${o}.${i}`},Uc=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])=>zc(r,n)).sort((r,n)=>r.stream.localeCompare(n.stream))},zc=(e,t)=>{let r=Wc(t[0]?.eventType??`${e}.event`),n=`${e}.>`;return{stream:r,subjects:[n],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({
37
37
  streams: [${e.map(r=>`'${r.stream}'`).join(", ")}],
38
38
  consumer: '${t}',
39
39
  discover: './src/events/**/*.handler.ts',
40
- })`;f();import{existsSync as te,mkdirSync as zc,readFileSync as dt,writeFileSync as pe}from"fs";import{dirname as Po,join as le}from"path";import{deriveEventNames as Vc}from"@crossdelta/cloudevents";var Jc=(e,t)=>{let r=`export * from './${t}'`;if(!te(e)){let s=Po(e);te(s)||zc(s,{recursive:!0});let i=`/**
40
+ })`;f();import{existsSync as te,mkdirSync as Vc,readFileSync as dt,writeFileSync as pe}from"fs";import{dirname as Po,join as le}from"path";import{deriveEventNames as Jc}from"@crossdelta/cloudevents";var Kc=(e,t)=>{let r=`export * from './${t}'`;if(!te(e)){let s=Po(e);te(s)||Vc(s,{recursive:!0});let i=`/**
41
41
  * ${Po(e).split("/").pop()} Domain Events
42
42
  */
43
43
 
44
44
  `;return pe(e,`${i+r}
45
45
  `,"utf-8"),!0}let n=dt(e,"utf-8");if(n.includes(`'./${t}'`))return!1;let o=`${n.trimEnd()}
46
46
  ${r}
47
- `;return pe(e,o,"utf-8"),!0},Kc=(e,t)=>{let r=`export * from './${t}'`;if(!te(e))return pe(e,`/**
47
+ `;return pe(e,o,"utf-8"),!0},qc=(e,t)=>{let r=`export * from './${t}'`;if(!te(e))return pe(e,`/**
48
48
  * Event Contracts Index
49
49
  *
50
50
  * Re-exports all event contracts for convenient importing.
@@ -53,17 +53,17 @@ ${r}
53
53
  ${r}
54
54
  `,"utf-8"),!0;let o=dt(e,"utf-8").split(`
55
55
  `);if(o.some(i=>i.trim()===r))return!1;let s=o.findLastIndex(i=>i.startsWith("export"));return s>=0?o.splice(s+1,0,r):o.push(r),pe(e,o.join(`
56
- `),"utf-8"),!0},qc=e=>{if(!te(e))return!1;let t=dt(e,"utf-8"),r="export * from './events'";if(t.split(`
56
+ `),"utf-8"),!0},Yc=e=>{if(!te(e))return!1;let t=dt(e,"utf-8"),r="export * from './events'";if(t.split(`
57
57
  `).some(s=>s.trim()===r||s.trim().startsWith(r)))return!1;let o=t;return o=o.replace(/\/\/\s*export \* from '\.\/events'/,r),o=o.replace(/\/\/\s*export \* from '\.\/stream-policies'/,"export * from './stream-policies'"),/export \* from '\.\/events\/\w+\/\w+'/.test(o)&&(o=o.replace(/export \* from '\.\/events\/\w+\/\w+'\n?/g,"")),o.includes(r)||(o=`${o.trimEnd()}
58
58
  ${r}
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(`
59
+ `),o!==t?(pe(e,o,"utf-8"),!0):!1},xr=(e,t)=>{let{packagePath:r}=x(t),{domain:n,action:o}=Jc(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 Kc(a,o)&&(y=!0),qc(c,n)&&(y=!0),Yc(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=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 j=y.getMethod("startConsumers");if(!j)continue;let N=[...c.split(`
61
+ `),"utf-8"),!0};f();import{existsSync as So,readdirSync as Xc,readFileSync as Qc}from"fs";import{join as bo}from"path";import{generateJsonMockFromContract as el,getJsonMockPath as tl,initFaker as rl}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 rl();let n=Xc(r).filter(i=>i.endsWith(".handler.ts")||i.endsWith(".event.ts")),o=[],s=[];for(let i of n){let a=bo(r,i),c=Qc(a,"utf-8"),l=Eo(c);if(!l){s.push(`${i} (Could not extract event type)`);continue}let p=t.outputDir??x().packagePath,m=tl(l,p);if(So(m)&&!t.overwrite){s.push(`${i} (Mock already exists)`);continue}let y=el(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=sl(e,"src","events","events.service.ts");if(!nl(r))return!1;let n=vr(e);if(n.length===0||ol(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 il({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),p=l.addSourceFileAtPath(r),m=!1;for(let y of p.getClasses()){let j=y.getMethod("startConsumers");if(!j)continue;let N=[...c.split(`
62
62
  `),""," this.logger.log('Event consumers started successfully')"].join(`
63
- `);j.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 G 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(G.cyan(`\u{1F4E6} Using existing contracts:
64
- `));for(let r of e)console.log(G.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(G.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(G.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(G.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(G.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${r.scope}/contracts):
63
+ `);j.setBodyText(N),m=!0;break}return m&&l.saveSync(),m};f();var al=e=>{let t=e.split(/\s+/),r=t[0],n=t.slice(1);return r==="pf"&&(r=process.argv[1]),{executable:r,args:n}},cl=async(e,t)=>{try{let{executable:r,args:n}=al(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 cl(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 gl}from"fs";import{join as Er}from"path";import G from"chalk";f();or();import{existsSync as Ao,mkdirSync as ll,writeFileSync as pl}from"fs";import{dirname as ml}from"path";var dl=(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=ml(o);return Ao(s)||ll(s,{recursive:!0}),pl(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=>dl(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 ul=(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()},fl=e=>{let t=Er(e,"packages/contracts/src/index.ts");if(!Ro(t))return new Set;try{let r=gl(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}},hl=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}`},yl=(e,t,r)=>{let n=fl(t),o=[],s=[],i=[];for(let a of e)if(n.has(a))o.push(a);else{s.push(a);let c=hl(a),l=r.replace(`${t}/`,"");i.push(`pf cloudevents add ${c} --service ${l}`)}return{existing:o,missing:s,suggestedCommands:i}},vl=(e,t)=>{if(e.length!==0){console.log(G.cyan(`\u{1F4E6} Using existing contracts:
64
+ `));for(let r of e)console.log(G.dim(` ${t}/contracts \u2192 ${r}`));console.log()}},Cl=(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(G.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(G.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(G.dim(` ${l}`));console.log()}else n.succeed("No files to write");let s=ul(e,r),{existing:i,missing:a,suggestedCommands:c}=yl(s,r.workspaceRoot,t);if(i.length>0&&vl(i,r.scope),a.length>0){console.log(G.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${r.scope}/contracts):
65
65
  `));for(let l of a)console.log(G.yellow(` ${l}`));console.log(),console.log(G.cyan(`\u{1F4A1} Run these commands to create the missing contracts:
66
- `));for(let l of c)console.log(G.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 _e}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`
66
+ `));for(let l of c)console.log(G.dim(` ${l}`));console.log()}return Cl(o.written,r.workspaceRoot),o.written.length>0&&await kl(t,n),{missingContractCommands:c}};f();import{existsSync as $l,readFileSync as Al}from"fs";import{join as _e}from"path";f();f();import{existsSync as xl,readdirSync as wl,readFileSync as Pl}from"fs";import{join as Sl}from"path";var Oo=e=>{let{eventsPath:t}=x(e);if(!xl(t))return[];let r=[];try{let n=wl(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of n){let s=Sl(t,o),i=Pl(s,"utf-8"),a=bl(i,s);a&&r.push(a)}}catch(n){return console.warn("Warning: Could not scan contracts package:",n),[]}return r},bl=(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=Tl(e);return{name:n,typeName:s,eventType:a,fields:c,filePath:t}}catch{return null}},El={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},Tl=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=El[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.
@@ -84,15 +84,15 @@ The following event contracts are available in \`${t}/contracts\`:
84
84
  ${r}
85
85
 
86
86
  If the event type your service consumes matches one of these, **you MUST use Advanced Mode**.
87
- `.trim()};var Al=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Il=(e,t)=>{let r=_e(Al(),"docs","generators"),n=ce(),o=[];for(let s of n.docs.base)o.push(_e(r,s));if(e&&n.docs.frameworks[e]){let s=n.docs.frameworks[e];if(typeof s=="string")o.push(_e(r,s));else{let i=t==="bun"?"bun":"node";s[i]&&o.push(_e(r,s[i]))}}return o},Do={copilot:".github/copilot-instructions.md",projectGuidelines:"docs/ai-guidelines.md"},Rl=1500,_o=e=>{try{return Tl(e)?$l(e,"utf-8"):null}catch{return null}},Nl=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/\n{3,}/g,`
87
+ `.trim()};var Il=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Rl=(e,t)=>{let r=_e(Il(),"docs","generators"),n=ce(),o=[];for(let s of n.docs.base)o.push(_e(r,s));if(e&&n.docs.frameworks[e]){let s=n.docs.frameworks[e];if(typeof s=="string")o.push(_e(r,s));else{let i=t==="bun"?"bun":"node";s[i]&&o.push(_e(r,s[i]))}}return o},Nl=["CLAUDE.md","AGENTS.md",".github/copilot-instructions.md","docs/ai-guidelines.md"],Do=1500,_o=50,jo=e=>{try{return $l(e)?Al(e,"utf-8"):null}catch{return null}},Fl=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/\n{3,}/g,`
88
88
 
89
- `).replace(/[ \t]+$/gm,"").trim(),Fl=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/```[\s\S]*?```/g,"").replace(/`[^`]{50,}`/g,"`...`").replace(/\n{3,}/g,`
89
+ `).replace(/[ \t]+$/gm,"").trim(),Ol=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/```[\s\S]*?```/g,"").replace(/`[^`]{50,}`/g,"`...`").replace(/\n{3,}/g,`
90
90
 
91
- `).replace(/[ \t]+$/gm,"").trim(),Ol=e=>Math.ceil(e.length/4),Ml=(e,t)=>{let r=e.split(/(?=^## )/m),n="",o=0;for(let s of r){let i=Ol(s);if(o+i<=t)n+=s,o+=i;else if(o===0){n=s.slice(0,t*4);break}else break}return n.trim()},Dl=(e,t)=>{let{workspaceRoot:r,scope:n}=t,o=Oo(r),s=Mo(o,n);return e.replace(/\{\{scope\}\}/g,n).replace(/\{\{AVAILABLE_CONTRACTS\}\}/g,s)},jo=e=>{let{workspaceRoot:t,scope:r}=e,n=[],o=Il(e.serviceType,e.packageManager);for(let a of o){let c=_o(a);if(c){let l=Dl(c,e),p=Nl(l);n.push(p)}}let s=[Do.copilot,Do.projectGuidelines],i=Math.floor(Rl/s.length);for(let a of s){let c=_o(_e(t,a));if(c){let l=Fl(c),p=Ml(l,i);p.length>50&&n.push(p)}}return n.length===0?(console.warn("\u26A0\uFE0F No instruction files found."),`Use ${r}/contracts for shared types.`):n.join(`
91
+ `).replace(/[ \t]+$/gm,"").trim(),Ml=e=>Math.ceil(e.length/4),Dl=(e,t)=>{let r=e.split(/(?=^## )/m),n="",o=0;for(let s of r){let i=Ml(s);if(o+i<=t)n+=s,o+=i;else if(o===0){n=s.slice(0,t*4);break}else break}return n.trim()},_l=(e,t)=>{let{workspaceRoot:r,scope:n}=t,o=Oo(r),s=Mo(o,n);return e.replace(/\{\{scope\}\}/g,n).replace(/\{\{AVAILABLE_CONTRACTS\}\}/g,s)},Lo=e=>{let{workspaceRoot:t,scope:r}=e,n=[],o=Rl(e.serviceType,e.packageManager);for(let a of o){let c=jo(a);if(c){let l=_l(c,e),p=Fl(l);n.push(p)}}let s=[...new Set(Nl.map(a=>jo(_e(t,a))).filter(a=>a!==null).map(Ol).filter(a=>a.length>_o))],i=s.length?Math.floor(Do/s.length):Do;for(let a of s){let c=Dl(a,i);c.length>_o&&n.push(c)}return n.length===0?(console.warn("\u26A0\uFE0F No instruction files found."),`Use ${r}/contracts for shared types.`):n.join(`
92
92
 
93
93
  ---
94
94
 
95
- `)};var _l=`You are an expert code generator. Generate clean, production-ready code.
95
+ `)};var jl=`You are an expert code generator. Generate clean, production-ready code.
96
96
 
97
97
  ## Output Format
98
98
 
@@ -106,13 +106,13 @@ Format your code blocks with the file path on the line before the code block:
106
106
  **IMPORTANT:** Always generate:
107
107
  - Source code files (src/**)
108
108
  - Test files (src/**/*.test.ts) for all business logic
109
- - README.md with service documentation`,jl=e=>e.replace(/-/g,"_").toUpperCase(),Ll=e=>e.split("/").pop()||"my-service",Lo=(e,t,r)=>{let n=jo({...e,serviceType:t,packageManager:r});return`${_l}
109
+ - README.md with service documentation`,Ll=e=>e.replace(/-/g,"_").toUpperCase(),Wl=e=>e.split("/").pop()||"my-service",Wo=(e,t,r)=>{let n=Lo({...e,serviceType:t,packageManager:r});return`${jl}
110
110
 
111
111
  ## Project Guidelines & Patterns
112
112
 
113
113
  Follow these project-specific conventions and patterns when generating code:
114
114
 
115
- ${n}`},Wo=(e,t,r,n)=>{let o=Ll(e),s=`${jl(o)}_PORT`,i=st();return`Generate source code for a microservice at path "${e}".
115
+ ${n}`},Ho=(e,t,r,n)=>{let o=Wl(e),s=`${Ll(o)}_PORT`,i=st();return`Generate source code for a microservice at path "${e}".
116
116
 
117
117
  Use the patterns and conventions from the Project Guidelines above.
118
118
 
@@ -127,11 +127,11 @@ Service purpose: ${t}
127
127
  - BUT you MUST keep the existing port configuration line unchanged!
128
128
 
129
129
  Do NOT include the service path in file headers (use \`src/...\`, NOT \`${e}/src/...\`).
130
- `};var Wl=()=>!!process.env.DEBUG,Ho=(e,t)=>{Wl()&&console.log(`[AI Parser] ${e}`,t??"")},gt={commandsBlock:/```commands\n([\s\S]*?)```/gi,postCommandsBlock:/```post-commands\n([\s\S]*?)```/gi,dependenciesBlock:/```dependencies\n([\s\S]*?)```/gi,fileHeader:/^#{1,4}\s+`([^`]+)`\s*$/},$r=(e,t)=>[...e.matchAll(t)].flatMap(n=>n[1].split(`
131
- `).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#"))),Go=e=>({command:e,isPfCommand:e.startsWith("pf ")||e.includes(" pf ")}),Hl=e=>$r(e,gt.commandsBlock).map(Go),Gl=e=>$r(e,gt.postCommandsBlock).map(Go),Bl=e=>$r(e,gt.dependenciesBlock).filter(t=>!t.startsWith("@crossdelta/")&&t!=="zod"),Ul=e=>{let t={ts:"typescript",js:"javascript",md:"markdown",yml:"yaml"},r=(e||"typescript").toLowerCase();return t[r]||r},zl=e=>{let t=e.split(".").pop()?.toLowerCase();return{ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",json:"json",yaml:"yaml",yml:"yaml",md:"markdown"}[t||""]||"plaintext"},Vl=e=>e.replace(/^\s*\/\/ \.{3,}.*$/gm,"").replace(/^\s*\/\/ Lines? \d+.*omitted.*$/gim,"").replace(/^\s*\/\* Lines? \d+.*omitted.*\*\/$/gim,"").trim(),Jl=e=>{let t=e.split(`
132
- `),r=[],n=0;for(let o of t){let s=gt.fileHeader.exec(o);s&&r.push({path:s[1],index:n}),n+=o.length+1}return r},Kl=(e,t)=>{let n=e.slice(t).match(/```(\w+)?\n([\s\S]*?)```/);return n?{language:n[1]?Ul(n[1]):void 0,content:Vl(n[2])}:null},ql=e=>Jl(e).map(r=>{let n=Kl(e,r.index);return!n||n.content.length===0?null:{path:r.path,language:n.language||zl(r.path),content:n.content,startIndex:r.index}}).filter(r=>r!==null),Tr=e=>e.includes("packages/contracts")||e.includes("contracts/src"),Yl=e=>{let t=e.filter(n=>Tr(n.path)),r=e.filter(n=>!Tr(n.path));return[...t,...r]},Zl=e=>{let t=e.replace(/^\/+/,"").replace(/\/{2,}/g,"/");if(Tr(t))return t;let r=t.match(/^services\/[^/]+\/(.+)$/);return r?r[1]:t},Bo=(e,t)=>{Ho("Parsing AI response",{length:e.length});let r=Hl(e),n=Gl(e),o=Bl(e),s=ql(e),i=Yl(s.map(a=>({path:Zl(a.path),content:a.content,language:a.language})));return Ho("Parsed response",{commands:r.length,postCommands:n.length,dependencies:o.length,files:i.length}),{commands:r,files:i,dependencies:o,postCommands:n}},Uo=e=>{let t=e.filter(s=>!s.content||s.content.trim().length===0),r=e.length===0?["No files could be extracted from the AI response"]:t.map(s=>`File ${s.path} is empty`),n=e.some(s=>["src/index.ts","src/main.ts","index.ts"].includes(s.path)),o=e.length>0&&!n?["No entry point file (src/index.ts or src/main.ts) found - assuming it exists from scaffolding"]:[];return{valid:r.length===0,errors:r,warnings:o}};import{mkdirSync as Xl}from"fs";import H from"chalk";var zo=async(e,t,r)=>{if(e.length===0){Xl(t,{recursive:!0}),console.log(H.yellow(`\u26A0 No scaffolding command found - creating empty directory
130
+ `};var Hl=()=>!!process.env.DEBUG,Go=(e,t)=>{Hl()&&console.log(`[AI Parser] ${e}`,t??"")},gt={commandsBlock:/```commands\n([\s\S]*?)```/gi,postCommandsBlock:/```post-commands\n([\s\S]*?)```/gi,dependenciesBlock:/```dependencies\n([\s\S]*?)```/gi,fileHeader:/^#{1,4}\s+`([^`]+)`\s*$/},$r=(e,t)=>[...e.matchAll(t)].flatMap(n=>n[1].split(`
131
+ `).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#"))),Bo=e=>({command:e,isPfCommand:e.startsWith("pf ")||e.includes(" pf ")}),Gl=e=>$r(e,gt.commandsBlock).map(Bo),Bl=e=>$r(e,gt.postCommandsBlock).map(Bo),Ul=e=>$r(e,gt.dependenciesBlock).filter(t=>!t.startsWith("@crossdelta/")&&t!=="zod"),zl=e=>{let t={ts:"typescript",js:"javascript",md:"markdown",yml:"yaml"},r=(e||"typescript").toLowerCase();return t[r]||r},Vl=e=>{let t=e.split(".").pop()?.toLowerCase();return{ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",json:"json",yaml:"yaml",yml:"yaml",md:"markdown"}[t||""]||"plaintext"},Jl=e=>e.replace(/^\s*\/\/ \.{3,}.*$/gm,"").replace(/^\s*\/\/ Lines? \d+.*omitted.*$/gim,"").replace(/^\s*\/\* Lines? \d+.*omitted.*\*\/$/gim,"").trim(),Kl=e=>{let t=e.split(`
132
+ `),r=[],n=0;for(let o of t){let s=gt.fileHeader.exec(o);s&&r.push({path:s[1],index:n}),n+=o.length+1}return r},ql=(e,t)=>{let n=e.slice(t).match(/```(\w+)?\n([\s\S]*?)```/);return n?{language:n[1]?zl(n[1]):void 0,content:Jl(n[2])}:null},Yl=e=>Kl(e).map(r=>{let n=ql(e,r.index);return!n||n.content.length===0?null:{path:r.path,language:n.language||Vl(r.path),content:n.content,startIndex:r.index}}).filter(r=>r!==null),Tr=e=>e.includes("packages/contracts")||e.includes("contracts/src"),Zl=e=>{let t=e.filter(n=>Tr(n.path)),r=e.filter(n=>!Tr(n.path));return[...t,...r]},Xl=e=>{let t=e.replace(/^\/+/,"").replace(/\/{2,}/g,"/");if(Tr(t))return t;let r=t.match(/^services\/[^/]+\/(.+)$/);return r?r[1]:t},Uo=(e,t)=>{Go("Parsing AI response",{length:e.length});let r=Gl(e),n=Bl(e),o=Ul(e),s=Yl(e),i=Zl(s.map(a=>({path:Xl(a.path),content:a.content,language:a.language})));return Go("Parsed response",{commands:r.length,postCommands:n.length,dependencies:o.length,files:i.length}),{commands:r,files:i,dependencies:o,postCommands:n}},zo=e=>{let t=e.filter(s=>!s.content||s.content.trim().length===0),r=e.length===0?["No files could be extracted from the AI response"]:t.map(s=>`File ${s.path} is empty`),n=e.some(s=>["src/index.ts","src/main.ts","index.ts"].includes(s.path)),o=e.length>0&&!n?["No entry point file (src/index.ts or src/main.ts) found - assuming it exists from scaffolding"]:[];return{valid:r.length===0,errors:r,warnings:o}};import{mkdirSync as Ql}from"fs";import H from"chalk";var Vo=async(e,t,r)=>{if(e.length===0){Ql(t,{recursive:!0}),console.log(H.yellow(`\u26A0 No scaffolding command found - creating empty directory
133
133
  `));return}let o=(await Sr(e,r)).find(s=>!s.success);if(o)throw console.log(H.red(`
134
- \u2717 Scaffolding failed: ${o.command}`)),o.error&&console.log(H.red(` Error: ${o.error}`)),new Error(`Command failed: ${o.command}${o.error?` - ${o.error}`:""}`)},Vo=async(e,t,r)=>{if(e.length===0)return;r.stop();let n=e.length===1?"package":"packages";console.log(H.cyan(`
134
+ \u2717 Scaffolding failed: ${o.command}`)),o.error&&console.log(H.red(` Error: ${o.error}`)),new Error(`Command failed: ${o.command}${o.error?` - ${o.error}`:""}`)},Jo=async(e,t,r)=>{if(e.length===0)return;r.stop();let n=e.length===1?"package":"packages";console.log(H.cyan(`
135
135
  \u25B6 Installing ${e.length} additional ${n}...
136
136
  `));try{await L({packages:e,cwd:t,flags:["--silent"]}),console.log(H.green(`\u2713 Installed ${e.length} ${n}
137
137
  `))}catch(o){throw console.log(H.red(`\u2717 Package installation failed
@@ -139,48 +139,48 @@ Do NOT include the service path in file headers (use \`src/...\`, NOT \`${e}/src
139
139
  \u25B6 Running post-generation commands...
140
140
  `));let n=(await Sr(e,t)).find(o=>!o.success);if(n){console.log(H.yellow(`
141
141
  \u26A0 Post-command failed: ${n.command}`)),n.error&&console.log(H.yellow(` Error: ${n.error}`));return}console.log(H.green(`\u2713 Post-generation commands complete
142
- `))};import ut from"chalk";var Ql=e=>`${ut.dim(" \u2022 ")+ut.cyan(e)}
143
- `,Jo=e=>ut.dim(` \u2728 Generated ${ut.white.bold(e)} tokens
144
- `),Ko=()=>{let e="",t=0,r=Date.now(),n=[],o=()=>{let i=e.match(/####\s+`([^`]+)`/);if(!i)return!1;n.push(i[1]),process.stdout.write(Ql(i[1]));let a=e.indexOf(i[0])+i[0].length;return e=e.slice(a),!0},s=i=>{e+=i,t++,o(),e.length>500&&(e=e.slice(-200))};return s.getStats=()=>{let i=((Date.now()-r)/1e3).toFixed(2),a=(t/Number.parseFloat(i)).toFixed(0);return{tokenCount:t,duration:i,tokensPerSec:a}},s.getFiles=()=>n,s};var sp=()=>{let e=g(),t=Xo(e,"package.json"),r=(()=>{if(!Zo(t))throw new Error("No package.json found in workspace root. Run from a valid workspace.");try{let o=JSON.parse(ep(t,"utf-8")).name;if(!o)throw new Error('package.json has no "name" field. Please add a name to your root package.json.');return o.startsWith("@")?o:`@${o}`}catch(n){throw n instanceof SyntaxError?new Error("Invalid JSON in package.json"):n}})();return{workspaceRoot:e,scope:r,cwd:process.cwd()}},ip=async(e,t,r,n,o,s)=>{let i=Wo(r,n,o,t.workspaceRoot),a=Lo(t,o,s),c=Ko(),l=await fo(e,i,{system:a,maxTokens:16384,temperature:.7,onToken:c}),p=c.getStats();return console.log(Jo(p.tokenCount)),console.log(),l},ap=(e,t)=>{let{serviceTypes:r}=ce(),n=r[t]?.commandType;if(!n)return e;let o=Object.values(r).map(s=>s.commandType);return e.map(s=>{for(let i of o)if(i!==n&&s.command.includes(`pf new ${i}`))return{...s,command:s.command.replace(`pf new ${i}`,`pf new ${n}`)};return s})},cp=e=>e.length===0?"":`${[h.cyan(`
142
+ `))};import ut from"chalk";var ep=e=>`${ut.dim(" \u2022 ")+ut.cyan(e)}
143
+ `,Ko=e=>ut.dim(` \u2728 Generated ${ut.white.bold(e)} tokens
144
+ `),qo=()=>{let e="",t=0,r=Date.now(),n=[],o=()=>{let i=e.match(/####\s+`([^`]+)`/);if(!i)return!1;n.push(i[1]),process.stdout.write(ep(i[1]));let a=e.indexOf(i[0])+i[0].length;return e=e.slice(a),!0},s=i=>{e+=i,t++,o(),e.length>500&&(e=e.slice(-200))};return s.getStats=()=>{let i=((Date.now()-r)/1e3).toFixed(2),a=(t/Number.parseFloat(i)).toFixed(0);return{tokenCount:t,duration:i,tokensPerSec:a}},s.getFiles=()=>n,s};var ip=()=>{let e=g(),t=Qo(e,"package.json"),r=(()=>{if(!Xo(t))throw new Error("No package.json found in workspace root. Run from a valid workspace.");try{let o=JSON.parse(tp(t,"utf-8")).name;if(!o)throw new Error('package.json has no "name" field. Please add a name to your root package.json.');return o.startsWith("@")?o:`@${o}`}catch(n){throw n instanceof SyntaxError?new Error("Invalid JSON in package.json"):n}})();return{workspaceRoot:e,scope:r,cwd:process.cwd()}},ap=async(e,t,r,n,o,s)=>{let i=Ho(r,n,o,t.workspaceRoot),a=Wo(t,o,s),c=qo(),l=await fo(e,i,{system:a,maxTokens:16384,temperature:.7,onToken:c}),p=c.getStats();return console.log(Ko(p.tokenCount)),console.log(),l},cp=(e,t)=>{let{serviceTypes:r}=ce(),n=r[t]?.commandType;if(!n)return e;let o=Object.values(r).map(s=>s.commandType);return e.map(s=>{for(let i of o)if(i!==n&&s.command.includes(`pf new ${i}`))return{...s,command:s.command.replace(`pf new ${i}`,`pf new ${n}`)};return s})},lp=e=>e.length===0?"":`${[h.cyan(`
145
145
  \u{1F4C1} Files to create:`),...e.map(t=>` ${h.green("\u2022")} ${h.white(t.path)} ${h.dim(`(${t.language})`)}`)].join(`
146
146
  `)}
147
- `,Yo=(e,t,r)=>e.length===0?"":`${[h.cyan(`
147
+ `,Zo=(e,t,r)=>e.length===0?"":`${[h.cyan(`
148
148
  ${r} ${t}:`),...e.map(n=>` ${h.yellow("$")} ${h.white(n.command)}`)].join(`
149
149
  `)}
150
- `,lp=e=>e.length===0?"":`${[h.cyan(`
150
+ `,pp=e=>e.length===0?"":`${[h.cyan(`
151
151
  \u{1F4E6} Dependencies to install:`),...e.map(t=>` ${h.magenta("+")} ${h.white(t)}`)].join(`
152
152
  `)}
153
- `,pp=(e,t)=>`${[h.yellow(`
153
+ `,mp=(e,t)=>`${[h.yellow(`
154
154
  Validation errors:`),...e.map(r=>h.yellow(` \u26A0 ${r}`)),h.dim(`
155
155
  Response preview:`),h.dim(t)].join(`
156
156
  `)}
157
- `,me=e=>{e&&process.stdout.write(e)},mp=(e,t)=>{let r=Bo(e,t),n=br(r.commands),o=br(r.postCommands),s=Uo(r.files);return s.valid?{files:r.files,commands:n,dependencies:r.dependencies,postCommands:o}:(console.log(`${h.yellow("\u26A0")} Could not extract structured files from AI response`),me(pp(s.errors,e.slice(0,500))),null)},dp=e=>{console.log(`${h.green("\u2714")} Extracted ${e.files.length} files`),me(cp(e.files)),me(Yo(e.commands,"Commands to run","\u{1F527}")),me(Yo(e.postCommands,"Post-generation commands","\u{1F4DD}")),me(lp(e.dependencies)),me(`
158
- `)},gp=(e,t,r)=>{let n=$o(e);return n&&!n.includes("/")&&!n.startsWith(".")&&(n=`${E().services}/${n}`),n?qo(r,n):qo(r,t)},up=(e,t)=>{let{serviceTypes:r}=ce(),n=r[t]?.skipFiles||["package.json","tsconfig.json","Dockerfile"];return e.filter(o=>!n.includes(o.path))},de=()=>{if(!De())return{valid:!1,error:h.red.bold(`\u274C AI configuration not found.
157
+ `,me=e=>{e&&process.stdout.write(e)},dp=(e,t)=>{let r=Uo(e,t),n=br(r.commands),o=br(r.postCommands),s=zo(r.files);return s.valid?{files:r.files,commands:n,dependencies:r.dependencies,postCommands:o}:(console.log(`${h.yellow("\u26A0")} Could not extract structured files from AI response`),me(mp(s.errors,e.slice(0,500))),null)},gp=e=>{console.log(`${h.green("\u2714")} Extracted ${e.files.length} files`),me(lp(e.files)),me(Zo(e.commands,"Commands to run","\u{1F527}")),me(Zo(e.postCommands,"Post-generation commands","\u{1F4DD}")),me(pp(e.dependencies)),me(`
158
+ `)},up=(e,t,r)=>{let n=$o(e);return n&&!n.includes("/")&&!n.startsWith(".")&&(n=`${E().services}/${n}`),n?Yo(r,n):Yo(r,t)},fp=(e,t)=>{let{serviceTypes:r}=ce(),n=r[t]?.skipFiles||["package.json","tsconfig.json","Dockerfile"];return e.filter(o=>!n.includes(o.path))},de=()=>{if(!De())return{valid:!1,error:h.red.bold(`\u274C AI configuration not found.
159
159
  `)+h.yellow("Please run ")+h.cyan.bold("pf setup --ai")+h.yellow(` first to configure your AI provider.
160
160
  `)};try{return{valid:!0,config:pt()}}catch(e){return{valid:!1,error:h.red.bold(`\u274C ${e.message}
161
- `)}}},ft=async e=>e||np({message:"\u{1F4DD} Describe what this service should do:",validate:t=>t.trim().length>0||"Please provide a description for the AI to generate code"}),ht=(e,t,r)=>{console.log(h.cyan.bold(`
161
+ `)}}},ft=async e=>e||op({message:"\u{1F4DD} Describe what this service should do:",validate:t=>t.trim().length>0||"Please provide a description for the AI to generate code"}),ht=(e,t,r)=>{console.log(h.cyan.bold(`
162
162
  \u{1F916} AI-Powered Generation
163
163
  `)),console.log(h.dim(`Service: ${e.split("/").pop()}`)),console.log(h.dim(`Path: ${e}`)),console.log(h.dim(`Model: ${t.model}`)),console.log(h.dim(`Description: ${r}
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(`
164
+ `))},yt=async(e,t)=>{let{servicePath:r,description:n="",serviceType:o,packageManager:s}=e,i=r.split("/").pop()||r,a=ip(),c=Qo(a.workspaceRoot,er);np(c,`generating:${r}`);let l=()=>{Xo(c)&&rp(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
- `));let m=await ip(t,a,r,n,o,s),y=mp(m,i);if(!y)return!1;dp(y);let j=op({text:"Processing files...",color:"cyan"}).start(),be=ap(y.commands,o),N=gp(be,r,a.cwd),Xi=up(y.files,o);await zo(be,N,a.workspaceRoot);let{missingContractCommands:vn}=await Fo(Xi,N,a,j);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 Qi=vn.map(ea=>({command:ea,isPfCommand:!0}));await Ar(Qi,a.workspaceRoot)}return To(N),await Vo(y.dependencies,N,j),await No(N,j),!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 eC=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",`
166
+ `));let m=await ap(t,a,r,n,o,s),y=dp(m,i);if(!y)return!1;gp(y);let j=sp({text:"Processing files...",color:"cyan"}).start(),be=cp(y.commands,o),N=up(be,r,a.cwd),Qi=fp(y.files,o);await Vo(be,N,a.workspaceRoot);let{missingContractCommands:vn}=await Fo(Qi,N,a,j);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 ea=vn.map(ta=>({command:ta,isPfCommand:!0}));await Ar(ea,a.workspaceRoot)}return To(N),await Jo(y.dependencies,N,j),await No(N,j),!0}finally{process.off("SIGINT",p),process.off("SIGTERM",p),l()}};import{existsSync as Xv}from"fs";import{Project as hp,SyntaxKind as eC}from"ts-morph";var tC=new hp({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0});v();import{promises as Ir}from"fs";import vt from"path";import es from"chalk";var ts=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 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,`
169
+ `],{task:e,shell:!0}),await xp()},Rr=()=>Ee("bun"),rs=()=>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"}),ns=()=>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:es.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),xp=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 _p,statSync as cs,unlinkSync as jp,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(`
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(es.cyan(e))};f();import{existsSync as xt,mkdirSync as Dp,readFileSync as _p,renameSync as jp,statSync as ls,unlinkSync as Lp,writeFileSync as Wp}from"fs";import{join as We}from"path";import{existsSync as wp}from"fs";import{join as Pp}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(Ct.red(`
177
+ `)};var Sp=(e,t)=>t.some(r=>r.name()===e),bp=(e,t)=>t.pf?.commands?.[e]??null,Ep=(e,t)=>!!t.scripts?.[e],Tp=(e,t)=>t.cwd?Pp(e,t.cwd):e,$p=(e,t)=>t.command||e,Ap=(e,t,r,n)=>{let o=Tp(n,r),s=$p(e,r);if(r.cwd&&!wp(o))return console.error(Ct.red(`
178
178
  \u2716 Directory not found: ${o}
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 je="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:[]}},Gp=e=>{let t=We(e,je);return We(t,Le)},Bp=(e,t=!1)=>{if(t)return!0;let r=Gp(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,je),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"),_p(o,n)}catch(i){try{xt(o)&&jp(o)}catch{}throw i}},wt=async(e={})=>{let t;try{t=g()}catch{return!1}if(!t)return!1;if(!Bp(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=`${je}/${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},Ip=(e,t,r)=>(console.log(Ct.dim(`Running workspace script: ${e}`)),Fe(e,{args:t,cwd:r}),!0);async function Rp(e,t,r){if(Sp(e,r))return!1;let n;try{n=g()}catch{return!1}let o=F(n);if(!o)return!1;let s=bp(e,o);return s?Ap(e,t,s,n):Ep(e,o)?Ip(e,t,n):!1}function os(){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}=os();return[...e,...t]}function ss(){let{configured:e,scripts:t}=os(),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 is(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}Rp(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}f();var as={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"},cs=(e,t)=>t?`${e}:${t}`:e,Np=()=>Object.entries(as).map(([e,t])=>cs(e,t)),Fp=()=>{try{let e=Fr(),r=F()?.pf?.commands||{},n=Object.keys(as);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||kt[o]||"";return cs(o,s)})}catch{return[]}},Op=()=>{try{let e=g(),t=x(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=Jt("@crossdelta/cloudevents");return n(r)}catch{return[]}},Mp=async()=>{try{let e=g();return await vo(e)}catch{return[]}},Or=async()=>({commands:[...Np(),...Fp()],events:Op(),services:await Mp()});var je="node_modules/.cache/pf",Le="completion-cache";var Hp=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}`},Gp=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,je);return We(t,Le)},Up=(e,t=!1)=>{if(t)return!0;let r=Bp(e);if(!xt(r))return!0;let n=_p(r,"utf-8").trim(),o=Gp(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=ls(r).mtimeMs;return ls(i).mtimeMs>a};var zp=(e,t)=>{let r=We(e,je),n=We(r,Le),o=`${n}.tmp.${process.pid}`;xt(r)||Dp(r,{recursive:!0});let s=Hp(t);try{Wp(o,s,"utf-8"),jp(o,n)}catch(i){try{xt(o)&&Lp(o)}catch{}throw i}},wt=async(e={})=>{let t;try{t=g()}catch{return!1}if(!t)return!1;if(!Up(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Or();return zp(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 us,writeFileSync as fs}from"fs";import{homedir as hs}from"os";import{join as Mr}from"path";import ue from"chalk";var ps=`${je}/${Le}`,ms=e=>`# ${e} completion (workspace-local cache)
180
180
  # Generated: ${new Date().toISOString()}
181
181
 
182
182
  # Cache file path (relative to workspace root)
183
- _${e}_cache_path="${ls}"
183
+ _${e}_cache_path="${ps}"
184
184
 
185
185
  # Find workspace root (walk up to find monorepo package.json)
186
186
  _${e}_find_workspace() {
@@ -307,11 +307,11 @@ _${e}_completions() {
307
307
  esac
308
308
  }
309
309
 
310
- compdef _${e}_completions ${e}`,ms=e=>`# ${e} completion (workspace-local cache)
310
+ compdef _${e}_completions ${e}`,ds=e=>`# ${e} completion (workspace-local cache)
311
311
  # Generated: ${new Date().toISOString()}
312
312
 
313
313
  # Cache file path (relative to workspace root)
314
- _${e}_cache_path="${ls}"
314
+ _${e}_cache_path="${ps}"
315
315
 
316
316
  # Find workspace root
317
317
  _${e}_find_workspace() {
@@ -405,13 +405,13 @@ _${e}_completions() {
405
405
  return 0
406
406
  }
407
407
 
408
- complete -F _${e}_completions ${e}`;var zp=(e,t)=>Mr(fs(),`.${t}-completion.${e}`),hs=e=>{let t=fs();return e==="zsh"?Mr(t,".zshrc"):Mr(t,".bashrc")},Vp=e=>`[[ -f "${e}" ]] && source "${e}"`,Jp=(e,t)=>Dr(e)?gs(e,"utf-8").includes(t):!1,Kp=(e,t)=>{let r=Dr(e)?gs(e,"utf-8"):"",n=r.endsWith(`
408
+ complete -F _${e}_completions ${e}`;var Vp=(e,t)=>Mr(hs(),`.${t}-completion.${e}`),ys=e=>{let t=hs();return e==="zsh"?Mr(t,".zshrc"):Mr(t,".bashrc")},Jp=e=>`[[ -f "${e}" ]] && source "${e}"`,Kp=(e,t)=>Dr(e)?us(e,"utf-8").includes(t):!1,qp=(e,t)=>{let r=Dr(e)?us(e,"utf-8"):"",n=r.endsWith(`
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",_r=(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 Bx,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",jr=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`,!jr(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",!jr(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(!jr(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:
412
+ `;fs(e,n,"utf-8")},Yp=(e,t)=>{let r=Vp(e,t),n=e==="zsh"?ms(t):ds(t);return fs(r,n,"utf-8"),r},gs=(e,t,r)=>{let n=Yp(e,t),o=ys(e),s=Jp(n);return Kp(o,s)?(r&&console.log(ue.dim(`[${e}] Already configured in ${o}`)),!1):(qp(o,s),r&&console.log(ue.green(`[${e}] Added source line to ${o}`)),!0)},Zp=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",_r=(e,t=!1)=>{let r=Zp();t&&console.log(ue.cyan(`Installing ${r} completion...`)),gs(r,e,t);let n=r==="zsh"?"bash":"zsh",o=ys(n);Dr(o)&&gs(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 Gx}from"fs/promises";import{dirname as Ux,join as zx}from"path";import{fileURLToPath as Jx}from"url";import{runFlow as qx}from"@crossdelta/flowcore";var Xp={debug:()=>{},info:console.log,warn:console.warn,error:console.error},vs=e=>e!==null&&typeof e=="object",Cs=e=>typeof e=="string"&&e.length>0,ks=e=>typeof e=="string",jr=e=>typeof e=="function",Qp=(e,t)=>vs(e)?[!Cs(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`,!jr(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var xs=e=>{if(!vs(e))return["Plugin must be an object"];let t=[!Cs(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",!jr(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>Qp(n,o)):[];return[...t,...r]},Pt=(e,t=Xp)=>({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(!jr(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=xs(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 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()}),QC=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=`
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 Qx}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()}),em=C.object({push:C.string().optional(),email:C.string().optional(),slack:C.string().optional(),sms:C.string().optional()}).optional(),tm=C.object({defaults:em,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:tm.optional()});import{z as u}from"zod";var rm=u.object({type:u.literal("event"),eventType:u.string(),stream:u.string().optional()}),nm=u.object({type:u.literal("http"),method:u.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:u.string().optional()}),ws=u.discriminatedUnion("type",[rm,nm]),om=u.object({type:u.literal("emit.event"),eventType:u.string()}),sm=u.object({type:u.literal("notify"),channel:u.enum(["push","email","slack","sms"]),provider:u.string().optional()}),im=u.object({type:u.literal("call.http"),name:u.string().optional(),baseUrl:u.string().optional()}),am=u.object({type:u.literal("persist"),store:u.enum(["db","kv","cache"]),entity:u.string().optional()}),Ps=u.discriminatedUnion("type",[om,sm,im,am]),Ss=u.object({serviceName:u.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:u.enum(["hono","nest"]).default("hono"),triggers:u.array(ws).min(1),actions:u.array(Ps).default([])});var ym=(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`})},vm=(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
 
@@ -419,7 +419,7 @@ export const ${Lr(o)}Contract = createContract({
419
419
  type: '${o}',
420
420
  schema: z.object({ ... }),
421
421
  })
422
- `.trim();return{success:!0,message:`Would create contract ${o}`,changes:[{type:"create",path:n,description:`Create event contract for ${o}`,preview:i.slice(0,500)}]}}let s=xr(o,t.workspace.workspaceRoot);return s&&t.logger.debug(`Added export for ${o} to contracts index`),t.logger.debug(`Contract created: ${o} at ${n}`),{success:!0,message:s?`Contract ${o} created with exports`:`Contract ${o} created`}},Lr=e=>e.split(".").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(""),vm=(e,t,r)=>{let{path:n,eventType:o,servicePath:s}=e;if(r?.dryRun){let i=`
422
+ `.trim();return{success:!0,message:`Would create contract ${o}`,changes:[{type:"create",path:n,description:`Create event contract for ${o}`,preview:i.slice(0,500)}]}}let s=xr(o,t.workspace.workspaceRoot);return s&&t.logger.debug(`Added export for ${o} to contracts index`),t.logger.debug(`Contract created: ${o} at ${n}`),{success:!0,message:s?`Contract ${o} created with exports`:`Contract ${o} created`}},Lr=e=>e.split(".").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(""),Cm=(e,t,r)=>{let{path:n,eventType:o,servicePath:s}=e;if(r?.dryRun){let i=`
423
423
  import { handleEvent } from '@crossdelta/cloudevents'
424
424
  import { ${Lr(o)}Contract } from '@your-scope/contracts'
425
425
 
@@ -427,9 +427,9 @@ 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}},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 Br}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(", ")}`),Gr=(e,t={})=>{let r=km(e,"utf-8");return wm.compile(r)(t)},Et=e=>(t,r={})=>{let n=xm(e,t);return Gr(n,r)};var B=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([Br(e,"templates","hono-microservice"),Br(e,"..","hono-microservice","templates"),Br(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:B(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=B(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}},km={"stream.wired":ym,"contract.created":vm,"handler.created":Cm},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 ld}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 Br}from"path";import{readFileSync as xm}from"fs";import{join as wm}from"path";import Pm from"handlebars";var fe=(e,t)=>yo(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),Gr=(e,t={})=>{let r=xm(e,"utf-8");return Pm.compile(r)(t)},Et=e=>(t,r={})=>{let n=wm(e,t);return Gr(n,r)};var B=e=>e.toUpperCase().replace(/-/g,"_");var Es=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Sm=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),bm=()=>{let e=Sm(),t=ee();return fe([Br(e,"templates","hono-microservice"),Br(e,"..","hono-microservice","templates"),Br(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Tt=(e,t={})=>Et(bm())(e,t);function Ts(){return Tt("tsconfig.json.hbs")}function $s(e="1.2.23"){return Tt("Dockerfile.hbs",{bunVersion:e})}function As(){return Tt("biome.json.hbs")}function Is(e,t=[]){return Tt("src/config/env.ts.hbs",{envKey:B(e),envVars:t})}var Em=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},Tm=(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},$m=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],Am=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],Im=e=>{let t=B(e.serviceName);return`${[...Em(e.hasEvents),"",...Tm(t,e.hasEvents),...e.hasEvents?$m(e.serviceName,e.streams):[],...Am()].join(`
431
431
  `)}
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}
432
+ `},Rm=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)},Nm=e=>`# ${e.serviceName}
433
433
 
434
434
  ## Development
435
435
 
@@ -449,7 +449,7 @@ ${e.hasEvents?`
449
449
  This service consumes from:
450
450
  ${e.streams.map(t=>`- ${t}`).join(`
451
451
  `)}`:""}
452
- `,Nm=()=>"",Is={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:Am},{path:"src/config/env.ts",content:e=>As(e.serviceName,e.envVars)},{path:"package.json",content:Im},{path:"tsconfig.json",content:()=>Es()},{path:"Dockerfile",content:()=>Ts()},{path:"biome.json",content:()=>$s()},{path:"README.md",content:Rm},{path:"src/events/.gitkeep",content:Nm,skip:e=>!e.hasEvents}]};import{join as Ur}from"path";var Fm=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Om=()=>{let e=Fm(),t=ee();return fe([Ur(e,"templates","nest-microservice"),Ur(e,"..","nest-microservice","templates"),Ur(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},re=(e,t={})=>Et(Om())(e,t);function Rs(e,t=3e3){return re("src/main.ts.hbs",{serviceName:e,envKey:B(e),displayName:bs(e),defaultPort:t})}function Ns(){return re("src/app.context.ts.hbs",{})}function Fs(){return re("src/events/events.module.ts.hbs",{})}function Os(e){return re("src/events/events.service.ts.hbs",{serviceName:e})}function Ms(e="24",t="1.2.23"){return re("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function Ds(){return re("biome.json.hbs",{})}function _s(e,t=[]){return re("src/config/env.ts.hbs",{envKey:B(e),envVars:t})}var Mm=e=>{let t={"@nestjs/common":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/platform-express":"^11.0.0","@crossdelta/telemetry":"workspace:*","reflect-metadata":"^0.2.0",rxjs:"^7.8.0",zod:"^4.1.0",[`${e.workspaceScope}/contracts`]:"workspace:*"};e.hasEvents&&(t["@crossdelta/cloudevents"]="workspace:*");let r={name:e.packageName,version:"0.0.1",scripts:{"start:dev":"bun --watch src/main.ts",start:"node dist/main.js",build:"tsc",test:"bun test"},dependencies:t,devDependencies:{"@nestjs/cli":"^11.0.0","@types/node":"^24.0.0",typescript:"^5.7.0"}};return JSON.stringify(r,null,2)},Dm=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),_m=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
452
+ `,Fm=()=>"",Rs={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:Im},{path:"src/config/env.ts",content:e=>Is(e.serviceName,e.envVars)},{path:"package.json",content:Rm},{path:"tsconfig.json",content:()=>Ts()},{path:"Dockerfile",content:()=>$s()},{path:"biome.json",content:()=>As()},{path:"README.md",content:Nm},{path:"src/events/.gitkeep",content:Fm,skip:e=>!e.hasEvents}]};import{join as Ur}from"path";var Om=()=>typeof import.meta?.url=="string"?W(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Mm=()=>{let e=Om(),t=ee();return fe([Ur(e,"templates","nest-microservice"),Ur(e,"..","nest-microservice","templates"),Ur(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},re=(e,t={})=>Et(Mm())(e,t);function Ns(e,t=3e3){return re("src/main.ts.hbs",{serviceName:e,envKey:B(e),displayName:Es(e),defaultPort:t})}function Fs(){return re("src/app.context.ts.hbs",{})}function Os(){return re("src/events/events.module.ts.hbs",{})}function Ms(e){return re("src/events/events.service.ts.hbs",{serviceName:e})}function Ds(e="24",t="1.2.23"){return re("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function _s(){return re("biome.json.hbs",{})}function js(e,t=[]){return re("src/config/env.ts.hbs",{envKey:B(e),envVars:t})}var Dm=e=>{let t={"@nestjs/common":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/platform-express":"^11.0.0","@crossdelta/telemetry":"workspace:*","reflect-metadata":"^0.2.0",rxjs:"^7.8.0",zod:"^4.1.0",[`${e.workspaceScope}/contracts`]:"workspace:*"};e.hasEvents&&(t["@crossdelta/cloudevents"]="workspace:*");let r={name:e.packageName,version:"0.0.1",scripts:{"start:dev":"bun --watch src/main.ts",start:"node dist/main.js",build:"tsc",test:"bun test"},dependencies:t,devDependencies:{"@nestjs/cli":"^11.0.0","@types/node":"^24.0.0",typescript:"^5.7.0"}};return JSON.stringify(r,null,2)},_m=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),jm=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
453
453
  ${e.hasEvents?"import { EventsModule } from './events/events.module'":""}
454
454
 
455
455
  @Module({
@@ -462,7 +462,7 @@ export class AppModule${e.hasEvents?" implements OnModuleInit":""} {
462
462
  // Events module initializes NATS consumer
463
463
  }`:""}
464
464
  }
465
- `},jm=()=>`import { Controller, Get } from '@nestjs/common'
465
+ `},Lm=()=>`import { Controller, Get } from '@nestjs/common'
466
466
 
467
467
  @Controller()
468
468
  export class AppController {
@@ -471,7 +471,7 @@ export class AppController {
471
471
  return { status: 'ok' }
472
472
  }
473
473
  }
474
- `,Lm=e=>`# ${e.serviceName}
474
+ `,Wm=e=>`# ${e.serviceName}
475
475
 
476
476
  ## Development
477
477
 
@@ -491,8 +491,8 @@ ${e.hasEvents?`
491
491
  This service consumes from:
492
492
  ${e.streams.map(t=>`- ${t}`).join(`
493
493
  `)}`:""}
494
- `,Wm=()=>"",js={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>_s(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>Rs(e.serviceName,e.port)},{path:"src/app.module.ts",content:_m},{path:"src/app.controller.ts",content:()=>jm()},{path:"src/app.context.ts",content:()=>Ns()},{path:"package.json",content:Mm},{path:"tsconfig.json",content:()=>Dm()},{path:"Dockerfile",content:()=>Ms()},{path:"biome.json",content:()=>Ds()},{path:"README.md",content:Lm},{path:"src/events/events.module.ts",content:()=>Fs(),skip:e=>!e.hasEvents},{path:"src/events/events.service.ts",content:e=>Os(e.serviceName),skip:e=>!e.hasEvents},{path:"src/events/handlers/.gitkeep",content:Wm,skip:e=>!e.hasEvents}]};var Ls=[Is,js],Ws=e=>{let t=Hm(e),r=Ls.find(n=>n.name===t);if(!r)throw new Error(`Template '${e}' not found. Available: ${Ls.map(n=>n.name).join(", ")}`);return r},Hm=e=>({"hono-micro":"hono-bun","nest-micro":"nest"})[e]||e;import{join as Vr}from"path";import{deriveEventNames as Jr}from"@crossdelta/cloudevents";var Hs={appliesTo:["src/domain","src/use-cases"],forbiddenPatterns:[{pattern:"console\\.(log|error|warn|info|debug)\\s*\\(",description:"console.* is forbidden in business logic (use structured logging)",code:"CONSOLE_IN_DOMAIN"},{pattern:"process\\.env\\b",description:"process.env is forbidden in business logic (use dependency injection)",code:"PROCESS_ENV_IN_DOMAIN"},{pattern:"\\bfetch\\s*\\(",description:"fetch() is forbidden in business logic (use adapters/services)",code:"FETCH_IN_DOMAIN"}]},Ge={hono:{businessLogicDir:"use-cases",eventsDir:"events",filePattern:"{name}.use-case.ts",suffix:"use-case",handlerDelegatesToBusinessLogic:!0,pathGuards:{forbidDirs:["src/services"]},codingConstraints:Hs},nestjs:{businessLogicDir:"",eventsDir:"events",filePattern:"{name}.service.ts",suffix:"service",handlerDelegatesToBusinessLogic:!1,pathGuards:{forbidDirs:[]},codingConstraints:{appliesTo:["src/domain"],forbiddenPatterns:Hs.forbiddenPatterns}}},Gm=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),Bm=(e,t)=>`../${e}/${t}`,he=(e,t)=>{let r=Ge[e],n=r.filePattern.replace("{name}",t),o=n.replace(/\.ts$/,""),s=r.businessLogicDir?`src/${r.businessLogicDir}`:"src";return{filePath:s?`${s}/${n}`:`src/${n}`,dirPath:s,fileName:n,functionName:Gm(t),delegateFromHandler:r.handlerDelegatesToBusinessLogic,importFromEvents:r.businessLogicDir?Bm(r.businessLogicDir,o):`./${o}`}},zr=(e,t)=>{let n=`src/${Ge[e].eventsDir}`,o=`${t}.handler.ts`;return{filePath:`${n}/${o}`,dirPath:n,fileName:o}},Be=e=>`handle-${e.replace(/\./g,"-")}`,$t=e=>{let t=e.replace(/\\/g,"/");t=t.replace(/^\.\//,"").replace(/^\//,"");let r=t.split("/"),n=[];for(let o of r)o===".."?n.pop():o!=="."&&o!==""&&n.push(o);return n.join("/")},Um=(e,t)=>{let r=$t(e);for(let n of t){let o=$t(n);if(r.startsWith(`${o}/`)||r===o)return n}return null},zm=(e,t)=>{let r=$t(e);return t.some(n=>{let o=$t(n);return r.startsWith(`${o}/`)||r===o})},Vm=(e,t,r)=>{let n=[],o=e.split(`
495
- `);for(let{pattern:s,description:i,code:a}of t){let c=new RegExp(s,"g");for(let l=0;l<o.length;l++)c.test(o[l])&&n.push({code:a,message:i,path:r,line:l+1}),c.lastIndex=0}return n},Jm=(e,t)=>{let r=[],n=Um(e.path,t.pathGuards.forbidDirs);if(n&&r.push({code:"FORBIDDEN_DIR",message:`Path '${e.path}' is in forbidden directory '${n}'`,path:e.path}),zm(e.path,t.codingConstraints.appliesTo)){let o=Vm(e.content,t.codingConstraints.forbiddenPatterns,e.path);r.push(...o)}return r},At=(e,t)=>{let r=Ge[e],n=[];for(let o of t)n.push(...Jm(o,r));return{valid:n.length===0,violations:n}};var Ym=(e,t)=>t.map(r=>({kind:"file:write",path:Vr(e,r.path),content:r.content})),Zm=(e,t,r)=>({kind:"infra:add",serviceName:e,port:t,framework:r.framework,runtime:r.runtime}),Xm=(e,t)=>({kind:"env:add",key:`${e}_PORT`,value:t.toString()}),Qm=(e,t)=>{let{typeName:r}=Jr(e),n=Be(e),o=he("hono",n);return`import type { ${r} } from '${t}/contracts'
494
+ `,Hm=()=>"",Ls={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>js(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>Ns(e.serviceName,e.port)},{path:"src/app.module.ts",content:jm},{path:"src/app.controller.ts",content:()=>Lm()},{path:"src/app.context.ts",content:()=>Fs()},{path:"package.json",content:Dm},{path:"tsconfig.json",content:()=>_m()},{path:"Dockerfile",content:()=>Ds()},{path:"biome.json",content:()=>_s()},{path:"README.md",content:Wm},{path:"src/events/events.module.ts",content:()=>Os(),skip:e=>!e.hasEvents},{path:"src/events/events.service.ts",content:e=>Ms(e.serviceName),skip:e=>!e.hasEvents},{path:"src/events/handlers/.gitkeep",content:Hm,skip:e=>!e.hasEvents}]};var Ws=[Rs,Ls],Hs=e=>{let t=Gm(e),r=Ws.find(n=>n.name===t);if(!r)throw new Error(`Template '${e}' not found. Available: ${Ws.map(n=>n.name).join(", ")}`);return r},Gm=e=>({"hono-micro":"hono-bun","nest-micro":"nest"})[e]||e;import{join as Vr}from"path";import{deriveEventNames as Jr}from"@crossdelta/cloudevents";var Gs={appliesTo:["src/domain","src/use-cases"],forbiddenPatterns:[{pattern:"console\\.(log|error|warn|info|debug)\\s*\\(",description:"console.* is forbidden in business logic (use structured logging)",code:"CONSOLE_IN_DOMAIN"},{pattern:"process\\.env\\b",description:"process.env is forbidden in business logic (use dependency injection)",code:"PROCESS_ENV_IN_DOMAIN"},{pattern:"\\bfetch\\s*\\(",description:"fetch() is forbidden in business logic (use adapters/services)",code:"FETCH_IN_DOMAIN"}]},Ge={hono:{businessLogicDir:"use-cases",eventsDir:"events",filePattern:"{name}.use-case.ts",suffix:"use-case",handlerDelegatesToBusinessLogic:!0,pathGuards:{forbidDirs:["src/services"]},codingConstraints:Gs},nestjs:{businessLogicDir:"",eventsDir:"events",filePattern:"{name}.service.ts",suffix:"service",handlerDelegatesToBusinessLogic:!1,pathGuards:{forbidDirs:[]},codingConstraints:{appliesTo:["src/domain"],forbiddenPatterns:Gs.forbiddenPatterns}}},Bm=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),Um=(e,t)=>`../${e}/${t}`,he=(e,t)=>{let r=Ge[e],n=r.filePattern.replace("{name}",t),o=n.replace(/\.ts$/,""),s=r.businessLogicDir?`src/${r.businessLogicDir}`:"src";return{filePath:s?`${s}/${n}`:`src/${n}`,dirPath:s,fileName:n,functionName:Bm(t),delegateFromHandler:r.handlerDelegatesToBusinessLogic,importFromEvents:r.businessLogicDir?Um(r.businessLogicDir,o):`./${o}`}},zr=(e,t)=>{let n=`src/${Ge[e].eventsDir}`,o=`${t}.handler.ts`;return{filePath:`${n}/${o}`,dirPath:n,fileName:o}},Be=e=>`handle-${e.replace(/\./g,"-")}`,$t=e=>{let t=e.replace(/\\/g,"/");t=t.replace(/^\.\//,"").replace(/^\//,"");let r=t.split("/"),n=[];for(let o of r)o===".."?n.pop():o!=="."&&o!==""&&n.push(o);return n.join("/")},zm=(e,t)=>{let r=$t(e);for(let n of t){let o=$t(n);if(r.startsWith(`${o}/`)||r===o)return n}return null},Vm=(e,t)=>{let r=$t(e);return t.some(n=>{let o=$t(n);return r.startsWith(`${o}/`)||r===o})},Jm=(e,t,r)=>{let n=[],o=e.split(`
495
+ `);for(let{pattern:s,description:i,code:a}of t){let c=new RegExp(s,"g");for(let l=0;l<o.length;l++)c.test(o[l])&&n.push({code:a,message:i,path:r,line:l+1}),c.lastIndex=0}return n},Km=(e,t)=>{let r=[],n=zm(e.path,t.pathGuards.forbidDirs);if(n&&r.push({code:"FORBIDDEN_DIR",message:`Path '${e.path}' is in forbidden directory '${n}'`,path:e.path}),Vm(e.path,t.codingConstraints.appliesTo)){let o=Jm(e.content,t.codingConstraints.forbiddenPatterns,e.path);r.push(...o)}return r},At=(e,t)=>{let r=Ge[e],n=[];for(let o of t)n.push(...Km(o,r));return{valid:n.length===0,violations:n}};var Zm=(e,t)=>t.map(r=>({kind:"file:write",path:Vr(e,r.path),content:r.content})),Xm=(e,t,r)=>({kind:"infra:add",serviceName:e,port:t,framework:r.framework,runtime:r.runtime}),Qm=(e,t)=>({kind:"env:add",key:`${e}_PORT`,value:t.toString()}),ed=(e,t)=>{let{typeName:r}=Jr(e),n=Be(e),o=he("hono",n);return`import type { ${r} } from '${t}/contracts'
496
496
 
497
497
  /**
498
498
  * Handle ${e} event
@@ -504,7 +504,7 @@ export const ${o.functionName} = async (data: ${r}): Promise<void> => {
504
504
  // TODO: Implement business logic
505
505
  // Example: validate data, transform, call external services
506
506
  }
507
- `},ed=(e,t,r)=>{let{contractName:n,typeName:o}=Jr(e),s=Be(e),i=he(r,s);return i.delegateFromHandler?`import { handleEvent } from '@crossdelta/cloudevents'
507
+ `},td=(e,t,r)=>{let{contractName:n,typeName:o}=Jr(e),s=Be(e),i=he(r,s);return i.delegateFromHandler?`import { handleEvent } from '@crossdelta/cloudevents'
508
508
  import { ${n}, type ${o} } from '${t}/contracts'
509
509
  import { ${i.functionName} } from '${i.importFromEvents}'
510
510
 
@@ -519,12 +519,12 @@ 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=Be(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",Gs=(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 Bs}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=Bs(e,"infra","services");return od(t)?sd(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=id(Bs(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:B(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},gd=(e,t)=>e.files.filter(r=>!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=Gs(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 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(({stream:t,subjects:r})=>({stream:t,subjects:r,config:{storage:"memory",retention:"limits",maxAge:36e5}})),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 vd(e,{moduleCache:!1}).import(r,{default:!0}),{collectStreamDefinitions:s}=await import("@crossdelta/infrastructure/streams"),i=s(o);if(i.length===0){console.log(A.dim(" No streams found in contracts"));return}let a=Id(i);await t({streams:a});let c=i.map(l=>l.stream);console.log(A.dim(` Created ${i.length} ephemeral stream(s): ${c.join(", ")}`))}catch(t){if(!Rd(t))throw console.error(A.red(`
524
- \u2717 ${Nd(t)}
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"))}};var qs=`// env: string literals \u2192 written to .env.local by generate-env (use for values meaningful locally)
522
+ `},rd=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:he(r,"stub").delegateFromHandler?t.events.map(o=>{let s=Be(o),i=he(r,s);return{kind:"file:write",path:Vr(e,i.filePath),content:ed(o,t.workspaceScope)}}):[],nd=(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:td(n,t.workspaceScope,r)}}),od=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",Bs=(e,t,r,n)=>{let o=od(n.framework),s=Zm(e,t),i=rd(e,r,o),a=nd(e,r,o),c=Xm(r.serviceName,r.port,n),l=Qm(r.envVarName,r.port);return[...s,...i,...a,c,l]};import{existsSync as sd,readdirSync as id,readFileSync as ad}from"fs";import{join as Us}from"path";var zs=4001,cd=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},Vs=e=>{try{let t=Us(e,"infra","services");return sd(t)?id(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=ad(Us(t,o),"utf-8"),i=cd(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 pd=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)`)},md=(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)},dd=e=>[...new Set(e.map(t=>ld(t).streamName))],gd=(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?dd(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:B(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},ud=(e,t)=>e.files.filter(r=>!r.skip?.(t)).map(r=>({path:r.path,content:r.content(t)})),fd=(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"}],hd=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],Js=e=>{pd(e.name);let t=e.workspaceRoot??g(),r=md(e.name,e.path,t),n=e.port??Kr(Vs(t),zs),o=gd(e,t,r,n),s=Hs(e.type),i=ud(s,o),a=Bs(r,i,o,s),c=fd(i,e.name,r),l=hd(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}})},Ks=e=>{let t=Js(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 vd}from"execa";import{createJiti as Cd}from"jiti";var qr=async e=>{let{stdout:t}=await vd("sh",["-c",e]);return t.trim()},kd="pf-local-nats",xd="2.10-alpine",wd=4222,Pd=8222,Sd=e=>({clientPort:e.clientPort??wd,monitoringPort:e.monitoringPort??Pd,containerName:e.containerName??kd,version:e.version??xd}),bd=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"],Ed=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),Td=async()=>{try{return await qr("docker info"),!0}catch{return!1}},$d=async e=>{try{return(await qr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var Ad=async e=>{let t=bd(e);try{return await qr(`docker ${t.join(" ")}`),{success:!0,value:Ed(e)}}catch{return{success:!1}}},Id=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("")},qs=async(e={})=>{let t=Sd(e);if(!await Td())return console.log(A.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await $d(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 Ad(t);return r.success?(Id(r.value),!0):(console.error(A.red("\u2717 Failed to start NATS")),!1)},Rd=e=>e.map(({stream:t,subjects:r})=>({stream:t,subjects:r,config:{storage:"memory",retention:"limits",maxAge:36e5}})),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 Cd(e,{moduleCache:!1}).import(r,{default:!0}),{collectStreamDefinitions:s}=await import("@crossdelta/infrastructure/streams"),i=s(o);if(i.length===0){console.log(A.dim(" No streams found in contracts"));return}let a=Rd(i);await t({streams:a});let c=i.map(l=>l.stream);console.log(A.dim(` Created ${i.length} ephemeral stream(s): ${c.join(", ")}`))}catch(t){if(!Nd(t))throw console.error(A.red(`
524
+ \u2717 ${Fd(t)}
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"))}};var Ys=`// env: string literals \u2192 written to .env.local by generate-env (use for values meaningful locally)
526
526
  // containerEnv: \u2192 only applied in the K8s container, never in .env.local
527
- // (use for deployment-specific values like ORIGIN or NODE_OPTIONS)`;function Ys(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
527
+ // (use for deployment-specific values like ORIGIN or NODE_OPTIONS)`;function Zs(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
528
528
  import { ports } from '@crossdelta/infrastructure'
529
529
 
530
530
  /**
@@ -533,7 +533,7 @@ import { ports } from '@crossdelta/infrastructure'
533
533
  * Internal-only service - accessed via cluster DNS:
534
534
  * http://${e}.{namespace}.svc.cluster.local:${t}
535
535
  */
536
- ${qs}
536
+ ${Ys}
537
537
  const config: K8sServiceConfig = {
538
538
  name: '${e}',
539
539
  ports: ports().http(${t}).build(),
@@ -546,7 +546,7 @@ const config: K8sServiceConfig = {
546
546
  }
547
547
 
548
548
  export default config
549
- `}function Zs(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
549
+ `}function Xs(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
550
550
  import { ports } from '@crossdelta/infrastructure'
551
551
 
552
552
  /**
@@ -555,7 +555,7 @@ import { ports } from '@crossdelta/infrastructure'
555
555
  * Internal-only service - accessed via cluster DNS:
556
556
  * http://${e}.{namespace}.svc.cluster.local:${t}
557
557
  */
558
- ${qs}
558
+ ${Ys}
559
559
  const config: K8sServiceConfig = {
560
560
  name: '${e}',
561
561
  ports: ports().http(${t}).build(),
@@ -568,53 +568,53 @@ const config: K8sServiceConfig = {
568
568
  }
569
569
 
570
570
  export default config
571
- `}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()}),Xs=T.array(Fd);var Qs=e=>{try{return Xs.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
572
- `))}};var D=()=>{try{let e=Re("bin/integration.collection.json");return Qs(e)}catch(e){throw new Error(`Failed to load integrations!
571
+ `}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()}),Qs=T.array(Od);var ei=e=>{try{return Qs.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
572
+ `))}};var D=()=>{try{let e=Re("bin/integration.collection.json");return ei(e)}catch(e){throw new Error(`Failed to load integrations!
573
573
  Check your integration.collection.json:
574
- ${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(`
575
- `))}))},Dd=e=>e.toUpperCase().replace(/-/g,"_"),ei=(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 ti from"chalk";var _d=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},ri=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=b(),task:o}=e;if(!t?.length||!o)return;let s=jd(t,r,n,o);await rt(o,s)},jd=(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:ti.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{it(`dependencies.${l}`,p,t)}}})),i={title:ti.cyanBright("Installing packages..."),fn:async()=>{await L({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};v();import Ld from"chalk";var ni=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}
576
- `),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 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 oi(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=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 Bd,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=Bd(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"?Ys(r,i):Zs(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")),si={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 ii 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(["",`${ii.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${ii.underline("https://bun.sh")}`,ts(),rs()].join(`
577
- `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import ai 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 ri({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},_t={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:[ai.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=>ai.bold(`\u2022 ${n}`))].join("\\n")}};v();var ci={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 jt={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=k(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=>jn(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 ni({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=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 li from"chalk";var Se={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=dr(),e.packageManager){t.title=`Using ${li.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 ${li.bold(e.packageManager)} as package manager.`}};import Wt from"chalk";var pi={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)}`}},mi={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 di={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 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(`
574
+ ${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(`
575
+ `))}))},_d=e=>e.toUpperCase().replace(/-/g,"_"),ti=(e,t)=>{let r=_d(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 ri from"chalk";var jd=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},ni=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}=jd(c);return{title:ri.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{it(`dependencies.${l}`,p,t)}}})),i={title:ri.cyanBright("Installing packages..."),fn:async()=>{await L({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};v();import Wd from"chalk";var oi=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}
576
+ `),fn:()=>Gd(s,i,t,r,n)}))),Gd=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 Kw,writeFileSync as qw}from"fs";import{join as Zw}from"path";v();import{join as tP}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 fP}from"fs";import{join as yP}from"path";import TP from"chalk";import AP from"cli-table3";v();function Ft(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function si(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"?Zs(r,i):Xs(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")),ii={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 ai from"chalk";v();var Ce={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Rr(),task:async(e,t)=>M(t,async r=>{await ts(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(["",`${ai.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${ai.underline("https://bun.sh")}`,rs(),ns()].join(`
577
+ `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import ci 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 ni({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},_t={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:[ci.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=>ci.bold(`\u2022 ${n}`))].join("\\n")}};v();var li={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 jt={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=>jn(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 oi({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 pi from"chalk";var Se={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=dr(),e.packageManager){t.title=`Using ${pi.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 ${pi.bold(e.packageManager)} as package manager.`}};import Wt from"chalk";var mi={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)}`}},di={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 gi={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(`
578
578
  `);throw new Error(`Policy violation(s) detected:
579
- ${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")},gi=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,ke,Se,_t,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),ei(mg(e),n??8080);let o=t??b();d.breakLine().log(`To start the project, run:
580
- ${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")},ui=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,ke,Se,_t,ve],actions:[we,Ce,Ht,Ot,jt,ci,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:
581
- ${se.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import _ from"chalk";v();import{spawnSync as vg}from"child_process";import{chmodSync as Cg,existsSync as tn,mkdirSync as kg,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 Gt}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([Gt(e,"templates","workspace"),Gt(e,"..","..","..","..","templates","workspace"),Gt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},fi=()=>{let e=en(),t=Gt(e,"packages","contracts");if(!hg(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},Bt=(e,t)=>Gr(e,t);var hi=e=>{e.endsWith(".sh")&&Cg(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}],yi={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)||kg(p,{recursive:!0}),c.isStatic){let m=nn(r,c.template);tn(m)?rn(l,xg(m)):rn(l,""),hi(l)}else{let m=nn(r,c.template),y=Bt(m,i);rn(l,y),hi(l)}}t.title="Workspace structure created"}};f();import{existsSync as Ci,mkdirSync as vi,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(!Ci(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(Ci(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=fi(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};vi(r,{recursive:!0}),vi(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=Bt(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 xi={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 wi=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=_.yellow("Warning: Creating nested workspace")}catch(r){if(X(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},Pe,xe,pi,mi,di,ke,Se,ve],actions:[we,Ce,yi,ki,jt,si,xi],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(_.bold.green("Workspace created successfully!")),d.breakLine().log(_.bold("Next steps:")).log(` 1. ${_.cyan(`cd ${e}`)}`).log(` 2. ${_.cyan("exec $SHELL")} ${_.dim("(enable tab completion)")}`),t&&d.breakLine().log(_.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${_.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${_.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${_.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(_.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:gi,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:ui,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:wi,supportsAi:!1}],Pi=()=>{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(`
582
- `);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 oi(r,t,n,o)}});for(let t of ze)e.addCommand(t.command);return e};import{Command as jg}from"commander";v();import{createHash as Ig}from"crypto";import{existsSync as ie,readdirSync as Si,readFileSync as bi,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=Si(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)?Si(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},Ei=".install-hash",Ti=e=>{let t=bi(e);return Ig("sha256").update(t).digest("hex")},Mg=e=>{let t=Y(e,"node_modules",Ei),r=Y(e,"bun.lock");return!ie(r)||!ie(t)?!0:bi(t,"utf-8")!==Ti(r)},Dg=e=>{let t=Y(e,"bun.lock"),r=Y(e,"node_modules",Ei);ie(t)&&Ng(r,Ti(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)},$i=e=>{let{eventsPath:t}=x(e);if(!ie(t))return async()=>{};let r=ae(async()=>{console.log(`
583
- \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 Ai from"chalk";f();var an=e=>new Promise(t=>setTimeout(t,e)),Ii=e=>process.stdout.write(`${e}
584
- `),_g=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},Ri=()=>({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]);Ii(Ai.cyan("\u{1F525} Starting services...")),Ii(Ai.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 Ni=new jg("dev").description("Start development mode with auto-reload").action(async()=>{let e;try{e=g()}catch(a){$(a);return}let t=Ri(),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(`
579
+ ${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=Ks({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")},ui=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,_t,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),ti(dg(e),n??8080);let o=t??b();d.breakLine().log(`To start the project, run:
580
+ ${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")},fi=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,_t,ve],actions:[we,Ce,Ht,Ot,jt,li,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:
581
+ ${se.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import _ 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 Gt}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([Gt(e,"templates","workspace"),Gt(e,"..","..","..","..","templates","workspace"),Gt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},hi=()=>{let e=en(),t=Gt(e,"packages","contracts");if(!yg(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},Bt=(e,t)=>Gr(e,t);var yi=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:"CLAUDE.md",output:"CLAUDE.md",isStatic:!0},{template:".claude/rules/cloudevents.md",output:".claude/rules/cloudevents.md",isStatic:!0}],vi={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,""),yi(l)}else{let m=nn(r,c.template),y=Bt(m,i);rn(l,y),yi(l)}}t.title="Workspace structure created"}};f();import{existsSync as ki,mkdirSync as Ci,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(!ki(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(ki(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=hi(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};Ci(r,{recursive:!0}),Ci(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=Bt(a,o);Eg(c,l,"utf-8")}},xi={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 wi={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 Pi=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=_.yellow("Warning: Creating nested workspace")}catch(r){if(X(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},Pe,xe,mi,di,gi,ke,Se,ve],actions:[we,Ce,vi,xi,jt,ii,wi],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(_.bold.green("Workspace created successfully!")),d.breakLine().log(_.bold("Next steps:")).log(` 1. ${_.cyan(`cd ${e}`)}`).log(` 2. ${_.cyan("exec $SHELL")} ${_.dim("(enable tab completion)")}`),t&&d.breakLine().log(_.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${_.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${_.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${_.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(_.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:ui,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:fi,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:Pi,supportsAi:!1}],Si=()=>{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(`
582
+ `);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 si(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 bi,readFileSync as Ei,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=bi(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)?bi(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},Ti=".install-hash",$i=e=>{let t=Ei(e);return Rg("sha256").update(t).digest("hex")},Dg=e=>{let t=Y(e,"node_modules",Ti),r=Y(e,"bun.lock");return!ie(r)||!ie(t)?!0:Ei(t,"utf-8")!==$i(r)},_g=e=>{let t=Y(e,"bun.lock"),r=Y(e,"node_modules",Ti);ie(t)&&Fg(r,$i(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}),_g(e)),await Fe("generate-env",{cwd:e})},sn=async e=>{await qs()&&await Yr(e)},Ai=e=>{let{eventsPath:t}=x(e);if(!ie(t))return async()=>{};let r=ae(async()=>{console.log(`
583
+ \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 Ii from"chalk";f();var an=e=>new Promise(t=>setTimeout(t,e)),Ri=e=>process.stdout.write(`${e}
584
+ `),jg=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},Ni=()=>({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]);Ri(Ii.cyan("\u{1F525} Starting services...")),Ri(Ii.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 Fi=new Lg("dev").description("Start development mode with auto-reload").action(async()=>{let e;try{e=g()}catch(a){$(a);return}let t=Ni(),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(`
585
585
  \u{1F504} Change detected, restarting...
586
586
  `);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(`
587
- \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=$i(e),console.log(`
587
+ \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=Ai(e),console.log(`
588
588
  \u{1F440} Watching for changes...`),console.log(` Press Ctrl+C twice to exit (first stops Turbo, second triggers cleanup)
589
- `)}catch(a){await i?.(),await zt(t),$(a)}});import Di from"chalk";import{Command as Zg}from"commander";import{existsSync as Lg,readFileSync as Wg,writeFileSync as Hg}from"fs";import Gg from"os";import Fi from"path";import ln from"chalk";import{Command as Bg}from"commander";v();var{name:Ug,publishConfig:zg}=R,Vg=zg?.registry,Jg=Ug?.split("/")[0],NE=new Bg("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)=>Oi(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${ln.cyan(`
589
+ `)}catch(a){await i?.(),await zt(t),$(a)}});import _i from"chalk";import{Command as Xg}from"commander";import{existsSync as Wg,readFileSync as Hg,writeFileSync as Gg}from"fs";import Bg from"os";import Oi 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],FE=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)=>Mi(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${ln.cyan(`
590
590
  Example:`)}
591
591
  ${ln.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
592
- `),Kg=e=>e?Fi.join(process.cwd(),".npmrc"):Fi.join(Gg.homedir(),".npmrc"),qg=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
593
- //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Yg=e=>Lg(e)?Wg(e,"utf8"):"",pn=(e,t)=>Hg(e,t),Oi=(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}
592
+ `),qg=e=>e?Oi.join(process.cwd(),".npmrc"):Oi.join(Bg.homedir(),".npmrc"),Yg=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
593
+ //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Zg=e=>Wg(e)?Hg(e,"utf8"):"",pn=(e,t)=>Gg(e,t),Mi=(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}
594
594
  `),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+=`
595
595
  ${i}
596
- `,pn(s,c),d.success(`Appended token for ${a} to ${s}`)},Mi=(e,t)=>Oi(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(Mi).addHelpText("after",()=>`${Di.cyan(`
596
+ `,pn(s,c),d.success(`Appended token for ${a} to ${s}`)},Di=(e,t)=>Mi(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(Di).addHelpText("after",()=>`${_i.cyan(`
597
597
  Example:`)}
598
- ${Di.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
599
- `);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 _i=mn;import gn from"chalk";import{Command as uu}from"commander";f();Ze();var HE={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};import{confirm as Li,input as iu,password as au,select as Wi}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}
598
+ ${_i.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
599
+ `);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 ji=mn;import gn from"chalk";import{Command as fu}from"commander";f();Ze();var GE={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};import{confirm as Wi,input as au,password as cu,select as Hi}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 Li(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}
600
600
  `)),e}catch{return console.log(P.yellow(`Found corrupted configuration, starting fresh.
601
- `)),null}}async function lu(e,t){return console.log(P.dim(`
601
+ `)),null}}async function pu(e,t){return console.log(P.dim(`
602
602
  \u{1F4CB} Get your ${e} API key here:`)),console.log(P.cyan(` ${t}
603
- `)),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 Wi({message:"Select model:",choices:e,default:t?.provider===r?t.model:void 0});return await Li({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 Hi(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function mu(e,t){console.log(P.green.bold(`
603
+ `)),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 Hi({message:"Select model:",choices:e,default:t?.provider===r?t.model:void 0});return await Wi({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 Gi(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function du(e,t){console.log(P.green.bold(`
604
604
  \u2705 AI configuration saved successfully!
605
- `)),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: ${Hi(t)}
605
+ `)),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: ${Gi(t)}
606
606
  `)),console.log(P.cyan("You can now use AI-powered service generation:")),console.log(P.dim(` pf new hono-micro services/my-service --ai
607
- `))}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 Gi(){console.log(P.cyan.bold(`
607
+ `))}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 Bi(){console.log(P.cyan.bold(`
608
608
  \u{1F916} AI Configuration Setup
609
- `));let e=cu();try{let t=await Wi({message:"Select AI provider:",choices:po(),default:e?.provider??ur.provider}),r=Me(t),n,o=await du(t);o&&(console.log(P.green(`
610
- \u2713 Found existing API key: ${Hi(o)}`)),await Li({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await lu(r.name,r.apiKeyUrl)),console.log(P.dim(`
611
- 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
609
+ `));let e=lu();try{let t=await Hi({message:"Select AI provider:",choices:po(),default:e?.provider??ur.provider}),r=Me(t),n,o=await gu(t);o&&(console.log(P.green(`
610
+ \u2713 Found existing API key: ${Gi(o)}`)),await Wi({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await pu(r.name,r.apiKeyUrl)),console.log(P.dim(`
611
+ Fetching available models...`));let s;try{s=(await Li(t,n)).models,console.log(P.green(`\u2713 Loaded ${s.length} models from ${r.name} API
612
612
  `))}catch(c){console.error(P.red(`
613
613
  \u274C Failed to fetch models: ${Cn(c)}`)),console.log(P.yellow(`
614
614
  Please check your API key and try again.
615
- `)),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(`
615
+ `)),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(`
616
616
  Setup cancelled.
617
- `)),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 _r(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",`
617
+ `)),process.exit(w.CANCELLED)),t}}import{existsSync as rT,readFileSync as nT}from"fs";import{homedir as sT}from"os";import{join as aT}from"path";var dn=async(e,t=!1)=>{try{return _r(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",`
618
618
  Examples:
619
619
  $ pf setup completion
620
620
  $ pf setup completion --verbose
@@ -624,6 +624,6 @@ Examples:
624
624
  `)))}),t.command("ai").description("Configure AI provider and API key for code generation").addHelpText("after",`
625
625
  Example:
626
626
  $ pf setup ai
627
- `).action(async()=>{await Gi()}),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 Ui}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}]`,Cu=(e,t)=>{e.argument(vu(t),t.description)},ku=(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)}},zi=(e,t)=>{let r=new Ui(e.name).description(e.description);return e.args.forEach(n=>{Cu(r,n)}),e.options.forEach(n=>{ku(r,n)}),r.action(Pu(e,t)),r},fn=(e,t,r,n)=>{let o=new Ui(e).description(t);return r.forEach(s=>{o.addCommand(zi(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,Vi=Object.keys(R.bin||{}),[yn="pf",hn]=Vi.length>0?Vi:["pf"],{description:Ji,version:Tu,repository:Ki,homepage:$u}=R,qi=Ji?.split(/ —|,|\./)[0]||Ji||"Platform CLI",Zi=Ki?.url?`https://${Ki.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Yi=Zi||$u,Au=Zi?"GitHub":"README",Iu=Yi?[Je.bold(qi),`
627
+ `).action(async()=>{await Bi()}),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 zi}from"commander";import Ui from"chalk";var yu=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(Ui.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(Ui.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)}},Vi=(e,t)=>{let r=new zi(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 zi(e).description(t);return r.forEach(s=>{o.addCommand(Vi(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,Ji=Object.keys(R.bin||{}),[yn="pf",hn]=Ji.length>0?Ji:["pf"],{description:Ki,version:$u,repository:qi,homepage:Au}=R,Yi=Ki?.split(/ —|,|\./)[0]||Ki||"Platform CLI",Xi=qi?.url?`https://${qi.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Zi=Xi||Au,Iu=Xi?"GitHub":"README",Ru=Zi?[Je.bold(Yi),`
628
628
 
629
- `,Je.cyan("See more at: "),Je.bold(Eu(Au,String(Yi)))].join(""):Je.bold(qi),Ru=[Vt(yn),Pi(),Ni,_i,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();
629
+ `,Je.cyan("See more at: "),Je.bold(Tu(Iu,String(Zi)))].join(""):Je.bold(Yi),Nu=[Vt(yn),Si(),Fi,ji,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",ss),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)}),is(Ve,bu,t)};Ou();
@@ -36,7 +36,7 @@ Instructions are configured in `package.json` under `generatorConfig.docs`:
36
36
  **Load Order:**
37
37
  1. **Base docs** - Always loaded (service.md, code-style.md, testing.md)
38
38
  2. **Framework-specific** - Based on `serviceType` and `packageManager`
39
- 3. **Workspace instructions** - `.github/copilot-instructions.md`, `docs/ai-guidelines.md`
39
+ 3. **Workspace instructions** - every one of `CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md`, `docs/ai-guidelines.md` that the workspace carries. Missing files are skipped; the token budget is split across the ones found.
40
40
 
41
41
  ## Adding New Generators
42
42
 
@@ -0,0 +1,76 @@
1
+ # Project Instructions (Project-Agnostic, TypeScript-Focused)
2
+
3
+ You are assisting in TypeScript-first monorepos using modern TypeScript tooling such as Bun or Node, Turborepo, Hono, NestJS, Zod, event-driven patterns, and Pulumi/Kubernetes infrastructure.
4
+
5
+ ## Core Principles
6
+
7
+ - Functional style: pure functions, composition over inheritance, side effects isolated in adapters.
8
+ - Separation of concerns: validation → logic → I/O. Domain logic separate from transport.
9
+ - Minimal diffs: change only what's needed, no full rewrites, no extra abstractions.
10
+ - Configuration over constants: avoid hard-coded values.
11
+
12
+ ## Safety Rules
13
+
14
+ - **NEVER** echo secrets/credentials into terminal output: they become conversation context sent to the AI provider.
15
+ - Use `source .env.local 2>/dev/null`. Never inline secrets as command arguments.
16
+ - **Never commit or push without explicit user confirmation.**
17
+
18
+ ## Before Writing Code
19
+
20
+ - **Search first**: Check the codebase for existing utilities before implementing new ones. Reuse > reinvent.
21
+ - **Check installed versions**: Verify the actual API of installed packages (`package.json`, `node_modules/`), don't assume.
22
+ - **Check generators**: Look for `gen`/`generate`/`codegen` scripts in `package.json` before editing files that might be auto-generated.
23
+
24
+ ## After Writing Code
25
+
26
+ - **Test consumers**: When changing a shared package (`packages/*`), run tests in **all consuming services**, not just the package itself. Changes to shared code have blast radius.
27
+ - **Push before publish**: Always push commits to remote before triggering npm publish workflows. The CI reads from the repo, not your local machine.
28
+ - **Pre-commit hooks exist**: The repo has a `sync-templates` hook that auto-updates downstream `package.json` refs after version bumps. Never bypass with `--no-verify`.
29
+ - **Capture lessons**: When a convention or pitfall emerges, propose updating a scoped `.claude/rules/` file. Ask before creating new files. Keep `CLAUDE.md` project-agnostic; domain-specific rules go in scoped files with `paths:`.
30
+
31
+ ## Monorepo Awareness
32
+
33
+ - Internal dependencies use `workspace:*` protocol. Never pin specific versions for workspace packages.
34
+ - Docker builds use `prepare-build-context` which flattens the monorepo, so root `package.json` `overrides` are **lost** in the Docker build. If a transitive dependency needs pinning, the fix must be in the package's own `package.json`.
35
+ - Turborepo caches builds. When debugging stale output, try `turbo run build --force`.
36
+
37
+ ## Scoped Rules
38
+
39
+ This workspace comes with one rule:
40
+
41
+ - [CloudEvents & Event Handling](.claude/rules/cloudevents.md): handler pattern, wildcard handlers, JetStream vs Core, contracts, NATS migrations (`services/*/src/events/**`, `packages/contracts/**`)
42
+
43
+ Add your own as they earn their place. A rule is worth writing once a convention has cost you
44
+ something: a pitfall someone hit, a boundary someone crossed. Rules written ahead of that describe
45
+ a codebase that does not exist yet, and get ignored.
46
+
47
+ To add one: create `.claude/rules/<name>.md`, give it a `paths:` list of globs the repo actually
48
+ has, and keep it to what the code cannot say about itself. A rule with `paths:` loads when a
49
+ matching file is touched. Leave `paths:` out only for something that binds in every session
50
+ regardless of which file is open, because that cost is paid on every turn.
51
+
52
+ Code style and testing conventions are not rules here: the `pf` generators carry their own, and they
53
+ load whenever the generator writes code.
54
+
55
+ ## Key Packages
56
+
57
+ Installed from npm, not vendored into this repo. Read their APIs in `node_modules/`, not from memory.
58
+
59
+ - `@crossdelta/cloudevents` - Event handling with NATS and CloudEvents
60
+ - `@crossdelta/telemetry` - OpenTelemetry instrumentation
61
+ - `@crossdelta/infrastructure` - Pulumi/K8s configuration
62
+
63
+ ## AI Output Format
64
+
65
+ - Provide only necessary files.
66
+ - Use relative paths.
67
+ - Keep comments minimal.
68
+ - Do not generate abstractions not already present.
69
+
70
+ ## Writing Style for Documentation
71
+
72
+ When writing to files (README, docs, plan documents, comments):
73
+
74
+ - No em dashes (`—`). Use a colon or restructure the sentence.
75
+ - No AI-speak: avoid "ships with", "wired up", "out of the box", "seamlessly", "ready to use", "powerful", "robust".
76
+ - Plain sentences. If a phrase sounds like marketing copy, rewrite it as a statement of fact.
@@ -21,7 +21,6 @@
21
21
  "dependencies": {
22
22
  "@crossdelta/cloudevents": "^0.8.4",
23
23
  "@crossdelta/infrastructure": "^0.15.2",
24
- "{{scope}}/types": "workspace:*",
25
24
  "zod": "^4.0.0"
26
25
  },
27
26
  "devDependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.21.29",
3
+ "version": "0.22.0",
4
4
  "description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
5
5
  "keywords": [
6
6
  "cli",