@crossdelta/platform-sdk 0.26.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,19 @@ 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.26.1] - 2026-10-17
9
+
10
+ ### Fixed
11
+ - **`pf dev` reads a `.env.local` value containing `$` as written.** `generate-env` now writes such a
12
+ value as `"…\$…"` (`@crossdelta/infrastructure` 0.18.1), and dotenv's `parse` kept the backslash, so
13
+ the ports and env `pf` hands to the apps carried `\$` instead of `$`. `parseEnvFile` reads with
14
+ `parseEnvContent` from `@crossdelta/infrastructure/env-file`, the reader that pairs with that writer.
15
+ It reads what `generate-env` writes and is stricter than dotenv about hand-written lines: spaces
16
+ around `=`, a key with `.` or `-` and a comment after the value are not read as dotenv read them.
17
+
18
+ ### Removed
19
+ - The `dotenv` dependency, which only `parseEnvFile` used.
20
+
8
21
  ## [0.26.0] - 2026-10-11
9
22
 
10
23
  ### Removed
package/bin/cli.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  var $s=Object.defineProperty;var xt=(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 C=(e,t)=>()=>(e&&(t=e(e=0)),t);var Rs=(e,t)=>{for(var r in t)$s(e,r,{get:t[r],enumerable:!0})};var k,le=C(()=>{"use strict";k={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 W,Re,wt=C(()=>{"use strict";le();W=class extends Error{exitCode;category;hint;cause;constructor(t,r=k.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("")}},Re=class extends W{constructor(t="Operation cancelled",r={}){super(t,k.CANCELLED,{...r,category:"user"}),this.name="CancelledError"}}});import H from"chalk";var Ie,Rr,Ir,Is,Ns,Ne,As,Os,O,Nr=C(()=>{"use strict";wt();le();Ie=e=>e instanceof Error,Rr=["ExitPromptError"],Ir=["Cancelled prompt","User force closed"],Is=["ERR_USE_AFTER_CLOSE"],Ns=e=>Rr.some(t=>e.name?.includes(t))||Ir.some(t=>e.message?.includes(t)),Ne=e=>{if(e instanceof Re)return!0;if(!(e instanceof Error))return!1;if(Rr.some(r=>e.name?.includes(r))||Ir.some(r=>e.message?.includes(r)))return!0;let t=e.code;return t&&Is.includes(t)?Ns(e):!1},As=e=>{if(e instanceof W){let r=e.toUserMessage();return H.red(`\u2716 ${r||"Unexpected error (re-run with DEBUG=true for details)"}`)}if(e instanceof Error){let r=e.message?.trim();return r?H.red(`\u2716 ${r}`):H.red("\u2716 Unexpected error (re-run with DEBUG=true for details)")}let t=String(e);return!t||t==="undefined"||t==="null"?H.red("\u2716 Unexpected error (re-run with DEBUG=true for details)"):H.red(`\u2716 ${t}`)},Os=e=>e instanceof W?e.exitCode:Ne(e)?k.CANCELLED:k.GENERAL_ERROR,O=(e,t={})=>{let{debug:r=process.env.DEBUG==="true",exit:n=!0,logger:o=console.error}=t;if(Ne(e)){n&&process.exit(k.CANCELLED);return}o(As(e)),r&&e instanceof Error&&e.stack&&o(H.dim(e.stack)),e instanceof W&&e.hint&&o(H.dim(`
4
- Hint: ${e.hint}`)),n&&process.exit(Os(e))}});var z=C(()=>{"use strict";wt();Nr();le()});var fm,Ar,Pt,Ae=C(()=>{"use strict";fm=process.env.npm_package_version||"0.0.0",Ar=["bun.lock","bun.lockb","package-lock.json","yarn.lock","pnpm-lock.yaml"],Pt="start:dev"});import Oe from"chalk";function bt(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 p=_s(c.barColor??t?.barColor),l=Ds(c,i,o,p,s,t?.labelColor);a.push(l)}return n&&(a.push(""),a.push(n)),a.join(`
5
- `)}function _s(e){return e?Oe[e]("\u2587"):"\u2587"}function Ds(e,t,r,n,o,s){let i=Math.round(e.value/t*r),a=e.barColor?Oe[e.barColor](n.repeat(i)):n.repeat(i),c=e.color??s;return`${Oe.bold(c?Oe[c](e.label.padEnd(12)):e.label.padEnd(12))} ${a} ${e.value.toLocaleString()}${o?` ${o}`:""}`}var Or=C(()=>{"use strict"});import{existsSync as Tt,unlinkSync as Ls,writeFileSync as Ms}from"fs";import{join as Et}from"path";import St from"chokidar";var js,_e,Fs,_r,$t,Ws,Dr,Rt=C(()=>{"use strict";h();v();js=".pf-generating",_e=e=>Et(e,js),Fs=e=>Tt(_e(e)),_r=e=>{Ms(_e(e),"","utf-8")},$t=e=>{let t=_e(e);Tt(t)&&Ls(t)},Ws=e=>{let r=$(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"}]},Dr=(e,t)=>{$t(e);let r=Ws(e),n=_e(e),s=J(async()=>{Fs(e)||await t()},300),i=[];i.push(St.watch(n,{ignoreInitial:!0}).on("unlink",()=>t()));for(let a of r){let c=Et(e,a.path);if(!Tt(c))continue;let p=a.ignorePatterns?.map(l=>Et(c,l));i.push(St.watch(c,{ignoreInitial:!0,depth:0,ignored:p,usePolling:!0,interval:1e3}).on("addDir",l=>l!==c&&s()).on("unlinkDir",l=>l!==c&&s())),i.push(St.watch(`${c}/*/package.json`,{ignoreInitial:!0,ignored:p}).on("add",s).on("change",s))}return async()=>{await Promise.all(i.map(a=>a.close()))}}});import Lr from"chalk";import{Command as Hs}from"commander";import{Listr as Mr}from"listr2";var L,Gs,jr,Fr=C(()=>{"use strict";z();Rt();v();L=e=>{let t=new Hs(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",()=>`${Lr.cyan.bold(`
3
+ Hint: ${this.hint}`),t.join("")}},Re=class extends W{constructor(t="Operation cancelled",r={}){super(t,k.CANCELLED,{...r,category:"user"}),this.name="CancelledError"}}});import H from"chalk";var Ie,Rr,Ir,Is,Ns,Ne,Os,As,A,Nr=C(()=>{"use strict";wt();le();Ie=e=>e instanceof Error,Rr=["ExitPromptError"],Ir=["Cancelled prompt","User force closed"],Is=["ERR_USE_AFTER_CLOSE"],Ns=e=>Rr.some(t=>e.name?.includes(t))||Ir.some(t=>e.message?.includes(t)),Ne=e=>{if(e instanceof Re)return!0;if(!(e instanceof Error))return!1;if(Rr.some(r=>e.name?.includes(r))||Ir.some(r=>e.message?.includes(r)))return!0;let t=e.code;return t&&Is.includes(t)?Ns(e):!1},Os=e=>{if(e instanceof W){let r=e.toUserMessage();return H.red(`\u2716 ${r||"Unexpected error (re-run with DEBUG=true for details)"}`)}if(e instanceof Error){let r=e.message?.trim();return r?H.red(`\u2716 ${r}`):H.red("\u2716 Unexpected error (re-run with DEBUG=true for details)")}let t=String(e);return!t||t==="undefined"||t==="null"?H.red("\u2716 Unexpected error (re-run with DEBUG=true for details)"):H.red(`\u2716 ${t}`)},As=e=>e instanceof W?e.exitCode:Ne(e)?k.CANCELLED:k.GENERAL_ERROR,A=(e,t={})=>{let{debug:r=process.env.DEBUG==="true",exit:n=!0,logger:o=console.error}=t;if(Ne(e)){n&&process.exit(k.CANCELLED);return}o(Os(e)),r&&e instanceof Error&&e.stack&&o(H.dim(e.stack)),e instanceof W&&e.hint&&o(H.dim(`
4
+ Hint: ${e.hint}`)),n&&process.exit(As(e))}});var J=C(()=>{"use strict";wt();Nr();le()});var hm,Or,Pt,Oe=C(()=>{"use strict";hm=process.env.npm_package_version||"0.0.0",Or=["bun.lock","bun.lockb","package-lock.json","yarn.lock","pnpm-lock.yaml"],Pt="start:dev"});import Ae from"chalk";function bt(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 p=_s(c.barColor??t?.barColor),l=Ds(c,i,o,p,s,t?.labelColor);a.push(l)}return n&&(a.push(""),a.push(n)),a.join(`
5
+ `)}function _s(e){return e?Ae[e]("\u2587"):"\u2587"}function Ds(e,t,r,n,o,s){let i=Math.round(e.value/t*r),a=e.barColor?Ae[e.barColor](n.repeat(i)):n.repeat(i),c=e.color??s;return`${Ae.bold(c?Ae[c](e.label.padEnd(12)):e.label.padEnd(12))} ${a} ${e.value.toLocaleString()}${o?` ${o}`:""}`}var Ar=C(()=>{"use strict"});import{existsSync as Tt,unlinkSync as Ls,writeFileSync as Ms}from"fs";import{join as Et}from"path";import St from"chokidar";var js,_e,Fs,_r,$t,Ws,Dr,Rt=C(()=>{"use strict";h();v();js=".pf-generating",_e=e=>Et(e,js),Fs=e=>Tt(_e(e)),_r=e=>{Ms(_e(e),"","utf-8")},$t=e=>{let t=_e(e);Tt(t)&&Ls(t)},Ws=e=>{let r=$(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"}]},Dr=(e,t)=>{$t(e);let r=Ws(e),n=_e(e),s=z(async()=>{Fs(e)||await t()},300),i=[];i.push(St.watch(n,{ignoreInitial:!0}).on("unlink",()=>t()));for(let a of r){let c=Et(e,a.path);if(!Tt(c))continue;let p=a.ignorePatterns?.map(l=>Et(c,l));i.push(St.watch(c,{ignoreInitial:!0,depth:0,ignored:p,usePolling:!0,interval:1e3}).on("addDir",l=>l!==c&&s()).on("unlinkDir",l=>l!==c&&s())),i.push(St.watch(`${c}/*/package.json`,{ignoreInitial:!0,ignored:p}).on("add",s).on("change",s))}return async()=>{await Promise.all(i.map(a=>a.close()))}}});import Lr from"chalk";import{Command as Hs}from"commander";import{Listr as Mr}from"listr2";var L,Bs,jr,Fr=C(()=>{"use strict";J();Rt();v();L=e=>{let t=new Hs(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",()=>`${Lr.cyan.bold(`
6
6
  Example:`)}
7
7
  ${Lr.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 Mr(jr(e.prompts,o),{rendererOptions:{lazy:!0,showErrorMessage:!1}}).run(o),await new Mr(jr(e.actions,o),{rendererOptions:{lazy:!1,showErrorMessage:!1}}).run(o),await e.onComplete?.(o)},n=()=>{try{let o=d();return _r(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(),p=Gs(e.arguments??[],a),l=await e.buildContext(p,c);s=n(),await r(l)}catch(i){O(i,{exit:!1})}finally{s&&$t(s)}}),t},Gs=(e,t)=>{let r=e.map(([n],o)=>[n.replace(/[<>[\]]/g,""),t[o]]);return Object.fromEntries(r)},jr=(e,t)=>e.map(r=>typeof r=="function"?r(t):r)});var J,Wr=C(()=>{"use strict";J=(e,t)=>{let r=null;return(...n)=>(r&&clearTimeout(r),new Promise(o=>{r=setTimeout(async()=>{r=null,await e(...n),o()},t)}))}});var Hr=C(()=>{"use strict"});import{execaSync as Bs}from"execa";function me(e){try{return Bs(e,["--version"]),!0}catch{return!1}}var It=C(()=>{"use strict"});var Gr=C(()=>{"use strict";It()});import{readdirSync as Us}from"fs";import{dirname as Br,isAbsolute as Hm,join as Vs,normalize as Gm,resolve as Bm,sep as Um}from"path";import{fileURLToPath as zs}from"url";import{packageUpSync as Js}from"package-up";import{rimraf as Ks}from"rimraf";function Ur(){let e=Js({cwd:Br(qs())});if(!e)throw new Error("Could not find package.json");return Br(e)}var qs,_,De,Vr,zr=C(()=>{"use strict";z();v();qs=()=>typeof import.meta?.url=="string"?zs(import.meta.url):process.cwd(),_=e=>{let t=Nt()?d():process.cwd();return Vs(t,e)},De=e=>{try{return Us(e).length===0}catch{return!0}};Vr=e=>Ks(e)});import ue from"chalk";var Jr,Ys,Zs,Le,m,Kr=C(()=>{"use strict";Jr={debug:0,info:1,warn:2,error:3,silent:4},Ys=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",Zs=()=>{let e=process.env.LOG_LEVEL;return Ys(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},Le=e=>{let t=Zs();return Jr[e]>=Jr[t]},m={logs:[],breakLine:()=>(console.log(),m),success:(e,...t)=>(console.log(ue.green(`\u2714 ${e}`),...t),m),info:(e,...t)=>(Le("info")&&console.log(ue.cyan(`\u{1F6C8} ${e}`),...t),m),warn:(e,...t)=>(Le("warn")&&console.warn(ue.yellow(`\u26A0\uFE0E ${e}`),...t),m),error:(e,...t)=>(Le("error")&&console.error(ue.red(`\u2716 ${e}`),...t),m),debug:(e,...t)=>(Le("debug")&&console.log(ue.dim(`[debug] ${e}`),...t),m),log:(e,...t)=>(console.log(e,...t),m.logs.push({message:e,context:t.join()}),m),getStoredLogs:e=>e?m.logs.filter(t=>t.context?.includes(e)):m.logs,storeLog:(e,t)=>m.logs.push({message:e,context:t})}});var qr=C(()=>{"use strict"});import Xs from"chalk";async function R(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 Me(e,t,r){for(let n=0;n<t.length;n++){let o=t[n];e.output=Xs.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}var Yr=C(()=>{"use strict"});var h=C(()=>{"use strict";Or();Fr();Wr();Hr();Gr();zr();Kr();qr();It();Yr()});var rn={};Rs(rn,{discoverAvailableServices:()=>He,findWorkspaceRoot:()=>d,getContractsConfig:()=>x,getPackageJsonField:()=>mi,getPfConfig:()=>fe,getPkgJson:()=>tn,getRootPackageScope:()=>en,getWorkspacePackageJson:()=>$,getWorkspacePathsConfig:()=>I,isInWorkspace:()=>Nt,pkgJson:()=>E,readPackageConfig:()=>he,updatePackageJsonField:()=>We});import{existsSync as ge,readdirSync as Qs,readFileSync as Zr,writeFileSync as ei}from"fs";import{join as S,resolve as ti}from"path";var Ot,ri,ni,oi,de,Fe,je,si,ii,Xr,ai,ci,Qr,Nt,d,$,I,fe,x,en,pi,li,mi,We,he,At,tn,E,He,v=C(()=>{"use strict";Ae();h();Ot=e=>JSON.parse(Zr(e,"utf-8")),ri=Ot,ni=(e,t,r)=>ei(e,`${JSON.stringify(t,null,2)}
9
- `,"utf-8"),oi=["@crossdelta/cloudevents"],de={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Fe=e=>{if(!ge(e))return null;try{return JSON.parse(Zr(e,"utf-8"))}catch{return null}},je=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,si=e=>e.split("/").pop()||"workspace",ii=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},Xr=e=>e.split("."),ai=(e,t)=>{if(!e.workspaces)return!1;if(e.pf||ge(S(t,"turbo.json")))return!0;let r=Ar.some(o=>ge(S(t,o))),n=ge(S(t,"infra"));return r&&n},ci=e=>{let t=Fe(S(e,"package.json"));return t?ai(t,e):!1},Qr=e=>{let t=e;for(;t;){if(ci(t))return t;t=ii(t)}return null},Nt=()=>Qr(process.cwd())!==null,d=()=>{let e=Qr(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 Mr(jr(e.prompts,o),{rendererOptions:{lazy:!0,showErrorMessage:!1}}).run(o),await new Mr(jr(e.actions,o),{rendererOptions:{lazy:!1,showErrorMessage:!1}}).run(o),await e.onComplete?.(o)},n=()=>{try{let o=d();return _r(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(),p=Bs(e.arguments??[],a),l=await e.buildContext(p,c);s=n(),await r(l)}catch(i){A(i,{exit:!1})}finally{s&&$t(s)}}),t},Bs=(e,t)=>{let r=e.map(([n],o)=>[n.replace(/[<>[\]]/g,""),t[o]]);return Object.fromEntries(r)},jr=(e,t)=>e.map(r=>typeof r=="function"?r(t):r)});var z,Wr=C(()=>{"use strict";z=(e,t)=>{let r=null;return(...n)=>(r&&clearTimeout(r),new Promise(o=>{r=setTimeout(async()=>{r=null,await e(...n),o()},t)}))}});var Hr=C(()=>{"use strict"});import{execaSync as Gs}from"execa";function me(e){try{return Gs(e,["--version"]),!0}catch{return!1}}var It=C(()=>{"use strict"});var Br=C(()=>{"use strict";It()});import{readdirSync as Us}from"fs";import{dirname as Gr,isAbsolute as Bm,join as Vs,normalize as Gm,resolve as Um,sep as Vm}from"path";import{fileURLToPath as Js}from"url";import{packageUpSync as zs}from"package-up";import{rimraf as Ks}from"rimraf";function Ur(){let e=zs({cwd:Gr(qs())});if(!e)throw new Error("Could not find package.json");return Gr(e)}var qs,_,De,Vr,Jr=C(()=>{"use strict";J();v();qs=()=>typeof import.meta?.url=="string"?Js(import.meta.url):process.cwd(),_=e=>{let t=Nt()?d():process.cwd();return Vs(t,e)},De=e=>{try{return Us(e).length===0}catch{return!0}};Vr=e=>Ks(e)});import ue from"chalk";var zr,Ys,Zs,Le,m,Kr=C(()=>{"use strict";zr={debug:0,info:1,warn:2,error:3,silent:4},Ys=e=>e==="debug"||e==="info"||e==="warn"||e==="error"||e==="silent",Zs=()=>{let e=process.env.LOG_LEVEL;return Ys(e)?e:process.env.DEBUG==="true"||process.env.VERBOSE==="true"?"debug":"info"},Le=e=>{let t=Zs();return zr[e]>=zr[t]},m={logs:[],breakLine:()=>(console.log(),m),success:(e,...t)=>(console.log(ue.green(`\u2714 ${e}`),...t),m),info:(e,...t)=>(Le("info")&&console.log(ue.cyan(`\u{1F6C8} ${e}`),...t),m),warn:(e,...t)=>(Le("warn")&&console.warn(ue.yellow(`\u26A0\uFE0E ${e}`),...t),m),error:(e,...t)=>(Le("error")&&console.error(ue.red(`\u2716 ${e}`),...t),m),debug:(e,...t)=>(Le("debug")&&console.log(ue.dim(`[debug] ${e}`),...t),m),log:(e,...t)=>(console.log(e,...t),m.logs.push({message:e,context:t.join()}),m),getStoredLogs:e=>e?m.logs.filter(t=>t.context?.includes(e)):m.logs,storeLog:(e,t)=>m.logs.push({message:e,context:t})}});var qr=C(()=>{"use strict"});import Xs from"chalk";async function R(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 Me(e,t,r){for(let n=0;n<t.length;n++){let o=t[n];e.output=Xs.dim(`[${n+1}/${t.length}] ${o.title}`),await o.fn(r??{},e)}}var Yr=C(()=>{"use strict"});var h=C(()=>{"use strict";Ar();Fr();Wr();Hr();Br();Jr();Kr();qr();It();Yr()});var rn={};Rs(rn,{discoverAvailableServices:()=>He,findWorkspaceRoot:()=>d,getContractsConfig:()=>x,getPackageJsonField:()=>mi,getPfConfig:()=>fe,getPkgJson:()=>tn,getRootPackageScope:()=>en,getWorkspacePackageJson:()=>$,getWorkspacePathsConfig:()=>I,isInWorkspace:()=>Nt,pkgJson:()=>E,readPackageConfig:()=>he,updatePackageJsonField:()=>We});import{existsSync as ge,readdirSync as Qs,readFileSync as Zr,writeFileSync as ei}from"fs";import{join as S,resolve as ti}from"path";var At,ri,ni,oi,de,Fe,je,si,ii,Xr,ai,ci,Qr,Nt,d,$,I,fe,x,en,pi,li,mi,We,he,Ot,tn,E,He,v=C(()=>{"use strict";Oe();h();At=e=>JSON.parse(Zr(e,"utf-8")),ri=At,ni=(e,t,r)=>ei(e,`${JSON.stringify(t,null,2)}
9
+ `,"utf-8"),oi=["@crossdelta/cloudevents"],de={services:"services",apps:"apps",packages:"packages",contracts:"packages/contracts"},Fe=e=>{if(!ge(e))return null;try{return JSON.parse(Zr(e,"utf-8"))}catch{return null}},je=(e,t)=>typeof e=="string"?e:typeof e=="object"&&e!==null&&"path"in e?e.path:t,si=e=>e.split("/").pop()||"workspace",ii=e=>{let t=e.slice(0,e.lastIndexOf("/"));return t===e?null:t},Xr=e=>e.split("."),ai=(e,t)=>{if(!e.workspaces)return!1;if(e.pf||ge(S(t,"turbo.json")))return!0;let r=Or.some(o=>ge(S(t,o))),n=ge(S(t,"infra"));return r&&n},ci=e=>{let t=Fe(S(e,"package.json"));return t?ai(t,e):!1},Qr=e=>{let t=e;for(;t;){if(ci(t))return t;t=ii(t)}return null},Nt=()=>Qr(process.cwd())!==null,d=()=>{let e=Qr(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,23 +16,23 @@ 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},$=e=>{let t=e??d();return Fe(S(t,"package.json"))},I=e=>{let t=$(e);if(!t?.pf?.paths)return de;let{paths:r}=t.pf;return{services:je(r.services,de.services),apps:je(r.apps,de.apps),packages:je(r.packages,de.packages),contracts:je(r.contracts,de.contracts)}},fe=e=>{let t=$(e);return{plugins:t?.pf?.plugins??oi,dev:{filter:t?.pf?.dev?.filter??[]}}},x=e=>{let t=e??d(),r=I(t),n=S(t,r.contracts),s=Fe(S(n,"package.json"))?.name??`${en()}/contracts`;return{packagePath:n,eventsPath:S(n,"src","events"),indexPath:S(n,"src","index.ts"),relativePath:r.contracts,packageName:s}},en=()=>{let e=d(),t=Fe(S(e,"package.json")),r=`@${si(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:r},pi=(e,t)=>{let r=Xr(t),n=e;for(let o of r){if(n===null||typeof n!="object"||!(o in n))return;n=n[o]}return n},li=(e,t,r)=>{let n=Xr(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},mi=(e,t=process.cwd())=>{let r=Ot(S(t,"package.json"));return pi(r,e)},We=(e,t,r=process.cwd())=>{let n=S(r,"package.json"),o=Ot(n);li(o,e,t),ni(n,o,{spaces:2,EOL:`
20
- `,encoding:"utf-8"})},he=e=>{let t=Ur();return ri(ti(t,e))},At=null,tn=()=>(At||(At=he("package.json")),At),E=new Proxy({},{get:(e,t)=>tn()[t]}),He=e=>{let t=e??d(),r=I(t),n=S(t,r.services);if(!ge(n))return[];try{return Qs(n,{withFileTypes:!0}).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>`${r.services}/${s.name}`).sort()}catch{return[]}}});import{argv as Jl}from"process";import Te from"chalk";import{Command as Kl}from"commander";import ql from"terminal-link";z();v();import Ni from"chalk";import{Command as Ai}from"commander";h();import{existsSync as Si}from"fs";import{join as Ei}from"path";import{cwd as ln}from"process";import{execaSync as Ti}from"execa";h();import{spawn as Lt}from"child_process";import{resolve as vi}from"path";import{execa as ki}from"execa";import{existsSync as ui}from"fs";import{resolve as di}from"path";import{config as gi}from"dotenv";var _t=(e,t)=>{let r=di(t,e);return ui(r)?gi({path:r,processEnv:{}}).parsed||{}:{}},fi=e=>`${(e.includes("/")?e.split("/").pop()??e:e).toUpperCase().replace(/-/g,"_")}_PORT`,nn=(e,t)=>{let r=_t(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({key:o,port:i})}return n},hi=65535,yi=e=>{if(!e||!/^\d+$/.test(e))return;let t=Number.parseInt(e,10);return t>0&&t<=hi?t:void 0},on=(e,t,r)=>{let n=t.filter(i=>!i.startsWith("!"));if(n.length===0)return e.map(i=>i.port);let o=yi(r);if(o!==void 0&&n.length===1)return[o];let s=new Set(n.map(fi));return[...new Set(e.filter(i=>s.has(i.key)).map(i=>i.port))]};var Dt={...process.env,NODE_NO_WARNINGS:"1"},Ci=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",xi=(e,t,r)=>e?{...Dt,...e}:t||r?{...Dt,CI:"true"}:{...Dt},wi=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 p=ki(e,t,{cwd:r,stdio:Ci(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:xi(c,n,a)});p.all&&p.all.on("data",l=>{let u=l.toString().trim();n?(n.output=u,u.length&&m.storeLog(u,s)):a&&u.length&&console.log(u)}),await p}catch(p){let l=p instanceof Error?p.message:String(p);if(wi(l))return;throw new Error(Pi(l))}}var Pi=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function sn(e,t,r={}){let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:p}=r,l=o?_t(o,n):{},u=vi(n,"node_modules",".bin"),T=process.env.PATH||"",Ct=`${u}:${T}`,Ts={...process.env,...l,PATH:Ct,FORCE_COLOR:"1"},$e=Lt(e,t,{cwd:n,env:Ts,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&$e.stdout?.on("data",a),c&&$e.stderr?.on("data",c),p&&$e.on("exit",p),$e}function an(e,t,r={}){let{cwd:n=process.cwd()}=r;Lt(e,t,{cwd:n,stdio:"inherit"}).on("exit",s=>process.exit(s||0))}function cn(e,t,r={}){let{cwd:n=process.cwd()}=r,o=t.length>0?`${e} ${t.join(" ")}`:e;Lt(o,[],{cwd:n,env:process.env,stdio:"inherit",shell:!0}).on("exit",i=>process.exit(i||0))}async function pn(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{}}v();var Ge=e=>me(e);function Mt(e=process.cwd()){let t=r=>Si(Ei(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 w(e){return Mt(e)??$i()}function $i(){return Ge("bun")?"bun":Ge("pnpm")?"pnpm":Ge("yarn")?"yarn":"npm"}function mn(){return["bun","pnpm","yarn","npm"].filter(Ge)}async function M(e,t){let r=Ri(e,t),{mergedOptions:n,packages:o}=r,{cwd:s=process.cwd(),flags:i=[],task:a,quiet:c}=n,p=n.packageManager??w(),l=[],u=Array.isArray(o)?o:[o];p==="bun"&&(u=u.map(Ct=>Ct.replace("git+ssh://",""))),p==="pnpm"&&(l.push("--config.engine-strict=false"),l.push("--no-frozen-lockfile")),["yarn","npm"].includes(p)&&l.push("--ignore-engines");let T=u.length?p==="npm"?["install",...i,...l,...u]:["add",...i,...l,...u]:["install",...i,...l];await K(p,T,{cwd:s,task:a,quiet:c})}async function un(e){let t=["-g"],r=[...e.flags??[],...t];await M({...e,flags:r,packageManager:e.packageManager??w()})}function dn(e,t,r){let{args:n,mergedOptions:o}=fn(t??[],r),s=o.manager??w(),{command:i,args:a}=gn(s);console.log(`
19
+ `);return e},$=e=>{let t=e??d();return Fe(S(t,"package.json"))},I=e=>{let t=$(e);if(!t?.pf?.paths)return de;let{paths:r}=t.pf;return{services:je(r.services,de.services),apps:je(r.apps,de.apps),packages:je(r.packages,de.packages),contracts:je(r.contracts,de.contracts)}},fe=e=>{let t=$(e);return{plugins:t?.pf?.plugins??oi,dev:{filter:t?.pf?.dev?.filter??[]}}},x=e=>{let t=e??d(),r=I(t),n=S(t,r.contracts),s=Fe(S(n,"package.json"))?.name??`${en()}/contracts`;return{packagePath:n,eventsPath:S(n,"src","events"),indexPath:S(n,"src","index.ts"),relativePath:r.contracts,packageName:s}},en=()=>{let e=d(),t=Fe(S(e,"package.json")),r=`@${si(e)}`;return t?.name?t.name.startsWith("@")?t.name.split("/")[0]:`@${t.name}`:r},pi=(e,t)=>{let r=Xr(t),n=e;for(let o of r){if(n===null||typeof n!="object"||!(o in n))return;n=n[o]}return n},li=(e,t,r)=>{let n=Xr(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},mi=(e,t=process.cwd())=>{let r=At(S(t,"package.json"));return pi(r,e)},We=(e,t,r=process.cwd())=>{let n=S(r,"package.json"),o=At(n);li(o,e,t),ni(n,o,{spaces:2,EOL:`
20
+ `,encoding:"utf-8"})},he=e=>{let t=Ur();return ri(ti(t,e))},Ot=null,tn=()=>(Ot||(Ot=he("package.json")),Ot),E=new Proxy({},{get:(e,t)=>tn()[t]}),He=e=>{let t=e??d(),r=I(t),n=S(t,r.services);if(!ge(n))return[];try{return Qs(n,{withFileTypes:!0}).filter(s=>s.isDirectory()&&!s.name.startsWith(".")).map(s=>`${r.services}/${s.name}`).sort()}catch{return[]}}});import{argv as Kl}from"process";import Te from"chalk";import{Command as ql}from"commander";import Yl from"terminal-link";J();v();import Oi from"chalk";import{Command as Ai}from"commander";h();import{existsSync as Ei}from"fs";import{join as Ti}from"path";import{cwd as ln}from"process";import{execaSync as $i}from"execa";h();import{spawn as Lt}from"child_process";import{resolve as ki}from"path";import{execa as Ci}from"execa";import{existsSync as ui,readFileSync as di}from"fs";import{resolve as gi}from"path";import{parseEnvContent as fi}from"@crossdelta/infrastructure/env-file";var _t=(e,t)=>{let r=gi(t,e);return ui(r)?fi(di(r,"utf8")):{}},hi=e=>`${(e.includes("/")?e.split("/").pop()??e:e).toUpperCase().replace(/-/g,"_")}_PORT`,nn=(e,t)=>{let r=_t(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({key:o,port:i})}return n},yi=65535,vi=e=>{if(!e||!/^\d+$/.test(e))return;let t=Number.parseInt(e,10);return t>0&&t<=yi?t:void 0},on=(e,t,r)=>{let n=t.filter(i=>!i.startsWith("!"));if(n.length===0)return e.map(i=>i.port);let o=vi(r);if(o!==void 0&&n.length===1)return[o];let s=new Set(n.map(hi));return[...new Set(e.filter(i=>s.has(i.key)).map(i=>i.port))]};var Dt={...process.env,NODE_NO_WARNINGS:"1"},xi=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",wi=(e,t,r)=>e?{...Dt,...e}:t||r?{...Dt,CI:"true"}:{...Dt},Pi=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 p=Ci(e,t,{cwd:r,stdio:xi(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:wi(c,n,a)});p.all&&p.all.on("data",l=>{let u=l.toString().trim();n?(n.output=u,u.length&&m.storeLog(u,s)):a&&u.length&&console.log(u)}),await p}catch(p){let l=p instanceof Error?p.message:String(p);if(Pi(l))return;throw new Error(bi(l))}}var bi=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function sn(e,t,r={}){let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:p}=r,l=o?_t(o,n):{},u=ki(n,"node_modules",".bin"),T=process.env.PATH||"",Ct=`${u}:${T}`,Ts={...process.env,...l,PATH:Ct,FORCE_COLOR:"1"},$e=Lt(e,t,{cwd:n,env:Ts,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&$e.stdout?.on("data",a),c&&$e.stderr?.on("data",c),p&&$e.on("exit",p),$e}function an(e,t,r={}){let{cwd:n=process.cwd()}=r;Lt(e,t,{cwd:n,stdio:"inherit"}).on("exit",s=>process.exit(s||0))}function cn(e,t,r={}){let{cwd:n=process.cwd()}=r,o=t.length>0?`${e} ${t.join(" ")}`:e;Lt(o,[],{cwd:n,env:process.env,stdio:"inherit",shell:!0}).on("exit",i=>process.exit(i||0))}async function pn(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{}}v();var Be=e=>me(e);function Mt(e=process.cwd()){let t=r=>Ei(Ti(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 w(e){return Mt(e)??Ri()}function Ri(){return Be("bun")?"bun":Be("pnpm")?"pnpm":Be("yarn")?"yarn":"npm"}function mn(){return["bun","pnpm","yarn","npm"].filter(Be)}async function M(e,t){let r=Ii(e,t),{mergedOptions:n,packages:o}=r,{cwd:s=process.cwd(),flags:i=[],task:a,quiet:c}=n,p=n.packageManager??w(),l=[],u=Array.isArray(o)?o:[o];p==="bun"&&(u=u.map(Ct=>Ct.replace("git+ssh://",""))),p==="pnpm"&&(l.push("--config.engine-strict=false"),l.push("--no-frozen-lockfile")),["yarn","npm"].includes(p)&&l.push("--ignore-engines");let T=u.length?p==="npm"?["install",...i,...l,...u]:["add",...i,...l,...u]:["install",...i,...l];await K(p,T,{cwd:s,task:a,quiet:c})}async function un(e){let t=["-g"],r=[...e.flags??[],...t];await M({...e,flags:r,packageManager:e.packageManager??w()})}function dn(e,t,r){let{args:n,mergedOptions:o}=fn(t??[],r),s=o.manager??w(),{command:i,args:a}=gn(s);console.log(`
22
22
  Running command: ${i} ${[...a,e,...n].join(" ")}
23
- `),Ti(i,[...a,e,...n],{cwd:o.cwd??ln(),stdio:"inherit",preferLocal:!0})}async function jt(e,t,r){let{args:n,mergedOptions:o}=fn(t??[],r),s=o.manager??w(),{command:i,args:a}=gn(s);await K(i,[...a,e,...n],o)}async function ye(e,t){let{script:r,mergedOptions:n}=Ii(e,t),o=n.packageManager??w();await K(o,["run",r,...n.args??[]],{cwd:n.cwd??ln(),task:n.task})}function gn(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 Ri(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function fn(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function Ii(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var Oi=e=>e==="yarn"?["npm","audit"]:["audit"],hn=new Ai("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=d(),n=w(),o=Oi(n),s=t.args||[];console.log(Ni.dim(`Running ${n} ${[...o,...s].join(" ")}`)),an(n,[...o,...s],{cwd:r})}catch(r){O(r)}});import pe from"chalk";h();import{promises as Ft}from"fs";import Be from"path";import yn from"chalk";var vn=async e=>{await K("bash",["-c",`
23
+ `),$i(i,[...a,e,...n],{cwd:o.cwd??ln(),stdio:"inherit",preferLocal:!0})}async function jt(e,t,r){let{args:n,mergedOptions:o}=fn(t??[],r),s=o.manager??w(),{command:i,args:a}=gn(s);await K(i,[...a,e,...n],o)}async function ye(e,t){let{script:r,mergedOptions:n}=Ni(e,t),o=n.packageManager??w();await K(o,["run",r,...n.args??[]],{cwd:n.cwd??ln(),task:n.task})}function gn(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 Ii(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function fn(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function Ni(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var _i=e=>e==="yarn"?["npm","audit"]:["audit"],hn=new Ai("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=d(),n=w(),o=_i(n),s=t.args||[];console.log(Oi.dim(`Running ${n} ${[...o,...s].join(" ")}`)),an(n,[...o,...s],{cwd:r})}catch(r){A(r)}});import pe from"chalk";h();import{promises as Ft}from"fs";import Ge from"path";import yn from"chalk";var vn=async e=>{await K("bash",["-c",`
24
24
  curl -fsSL https://bun.sh/install | bash && if [ -f "$HOME/.bun/bin/bun" ]; then export PATH="$HOME/.bun/bin:$PATH"; fi
25
- `],{task:e,shell:!0}),await _i()},Wt=()=>me("bun"),kn=()=>bt([{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"}),Cn=()=>bt([{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:yn.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),_i=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){m.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let r=[Be.join(t,".zshrc"),Be.join(t,".bashrc"),Be.join(t,".bash_profile")];for(let n of r)try{if(await Ft.stat(n).then(()=>!0).catch(()=>!1)){(await Ft.readFile(n,"utf8")).includes(e)||(await Ft.appendFile(n,`
25
+ `],{task:e,shell:!0}),await Di()},Wt=()=>me("bun"),kn=()=>bt([{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"}),Cn=()=>bt([{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:yn.blackBright("* Installing dependencies from cache for a Remix app."),barColor:"blackBright"}),Di=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){m.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let r=[Ge.join(t,".zshrc"),Ge.join(t,".bashrc"),Ge.join(t,".bash_profile")];for(let n of r)try{if(await Ft.stat(n).then(()=>!0).catch(()=>!1)){(await Ft.readFile(n,"utf8")).includes(e)||(await Ft.appendFile(n,`
26
26
  # Added by platform installer
27
27
  ${e}
28
- `),m.log(`Added Bun path to ${Be.basename(n)}`));return}}catch(o){m.error(`Failed to update ${n}: ${o.message}`)}m.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),m.log(yn.cyan(e))};v();import{existsSync as ze,mkdirSync as ea,readFileSync as ta,renameSync as ra,statSync as Rn,unlinkSync as na,writeFileSync as oa}from"fs";import{join as Ce}from"path";import{existsSync as Di}from"fs";import{join as Li}from"path";import Ue from"chalk";v();import Ht from"chalk";var q=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` ${Ht.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Ht.cyan.bold(`
28
+ `),m.log(`Added Bun path to ${Ge.basename(n)}`));return}}catch(o){m.error(`Failed to update ${n}: ${o.message}`)}m.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),m.log(yn.cyan(e))};v();import{existsSync as Je,mkdirSync as ta,readFileSync as ra,renameSync as na,statSync as Rn,unlinkSync as oa,writeFileSync as sa}from"fs";import{join as Ce}from"path";import{existsSync as Li}from"fs";import{join as Mi}from"path";import Ue from"chalk";v();import Ht from"chalk";var q=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` ${Ht.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Ht.cyan.bold(`
29
29
  ${e.title}
30
30
  `),`Available commands:
31
31
  `,...r,"",Ht.dim(`${n}
32
32
  `)].join(`
33
- `)};var Mi=(e,t)=>t.some(r=>r.name()===e),ji=(e,t)=>t.pf?.commands?.[e]??null,Fi=(e,t)=>!!t.scripts?.[e],Wi=(e,t)=>t.cwd?Li(e,t.cwd):e,Hi=(e,t)=>t.command||e,Gi=(e,t,r,n)=>{let o=Wi(n,r),s=Hi(e,r);if(r.cwd&&!Di(o))return console.error(Ue.red(`
33
+ `)};var ji=(e,t)=>t.some(r=>r.name()===e),Fi=(e,t)=>t.pf?.commands?.[e]??null,Wi=(e,t)=>!!t.scripts?.[e],Hi=(e,t)=>t.cwd?Mi(e,t.cwd):e,Bi=(e,t)=>t.command||e,Gi=(e,t,r,n)=>{let o=Hi(n,r),s=Bi(e,r);if(r.cwd&&!Li(o))return console.error(Ue.red(`
34
34
  \u2716 Directory not found: ${o}
35
- `)),!0;let i=r.cwd?Ue.dim(` in ${r.cwd}/`):"";return console.log(Ue.dim(`Running ${s}${i}`)),cn(s,t,{cwd:o}),!0},Bi=(e,t,r)=>(console.log(Ue.dim(`Running workspace script: ${e}`)),ye(e,{args:t,cwd:r}),!0);async function Ui(e,t,r){if(Mi(e,r))return!1;let n;try{n=d()}catch{return!1}let o=$(n);if(!o)return!1;let s=ji(e,o);return s?Gi(e,t,s,n):Fi(e,o)?Bi(e,t,n):!1}function xn(){let e;try{e=$()}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 Gt(){let{configured:e,scripts:t}=xn();return[...e,...t]}function wn(){let{configured:e,scripts:t}=xn(),r=[...e,...t];if(r.length===0)return"";let o=$()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||Ve[i]||""}));return q({title:"Workspace Commands",commands:s,footer:""})}function Pn(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=Gt();for(let a of i)console.log(a);return}Ui(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}import{existsSync as Bt,readdirSync as Ji}from"fs";import{dirname as Ki,join as bn}from"path";import{dirname as Vi}from"path";import{fileURLToPath as zi}from"url";var j=e=>Vi(zi(e));Rt();var qi=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),G=e=>{let t=e??qi(),r=o=>Bt(bn(o,"package.json")),n=Ki(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return G(n)},Sn=(e,t)=>{let r=e.find(Bt);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},En=async e=>{let{getWorkspacePathsConfig:t}=await Promise.resolve().then(()=>(v(),rn)),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=bn(e,o);if(!Bt(s))return[];try{return Ji(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};v();var Tn={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"},Ve={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"},$n=(e,t)=>t?`${e}:${t}`:e,Yi=()=>Object.entries(Tn).map(([e,t])=>$n(e,t)),Zi=()=>{try{let e=Gt(),r=$()?.pf?.commands||{},n=Object.keys(Tn);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||Ve[o]||"";return $n(o,s)})}catch{return[]}},Xi=()=>{try{let e=d(),t=x(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=xt("@crossdelta/cloudevents");return n(r)}catch{return[]}},Qi=async()=>{try{let e=d();return await En(e)}catch{return[]}},Ut=async()=>({commands:[...Yi(),...Zi()],events:Xi(),services:await Qi()});var ve="node_modules/.cache/pf",ke="completion-cache";var sa=e=>{let t=E.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},ia=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:[]}},aa=e=>{let t=Ce(e,ve);return Ce(t,ke)},ca=(e,t=!1)=>{if(t)return!0;let r=aa(e);if(!ze(r))return!0;let n=ta(r,"utf-8").trim(),o=ia(n),s=E.version||"0.0.0";if(o.version!==s)return!0;let i=Ce(e,"package.json");if(!ze(i))return!1;let a=Rn(r).mtimeMs;return Rn(i).mtimeMs>a};var pa=(e,t)=>{let r=Ce(e,ve),n=Ce(r,ke),o=`${n}.tmp.${process.pid}`;ze(r)||ea(r,{recursive:!0});let s=sa(t);try{oa(o,s,"utf-8"),ra(o,n)}catch(i){try{ze(o)&&na(o)}catch{}throw i}},Je=async(e={})=>{let t;try{t=d()}catch{return!1}if(!t)return!1;if(!ca(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Ut();return pa(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},xe=async(e={})=>{await Je({...e,force:!0})};import{existsSync as zt,readFileSync as _n,writeFileSync as Dn}from"fs";import{homedir as Ln}from"os";import{join as Vt}from"path";import Y from"chalk";var In=`${ve}/${ke}`,Nn=e=>`# ${e} completion (workspace-local cache)
35
+ `)),!0;let i=r.cwd?Ue.dim(` in ${r.cwd}/`):"";return console.log(Ue.dim(`Running ${s}${i}`)),cn(s,t,{cwd:o}),!0},Ui=(e,t,r)=>(console.log(Ue.dim(`Running workspace script: ${e}`)),ye(e,{args:t,cwd:r}),!0);async function Vi(e,t,r){if(ji(e,r))return!1;let n;try{n=d()}catch{return!1}let o=$(n);if(!o)return!1;let s=Fi(e,o);return s?Gi(e,t,s,n):Wi(e,o)?Ui(e,t,n):!1}function xn(){let e;try{e=$()}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 Bt(){let{configured:e,scripts:t}=xn();return[...e,...t]}function wn(){let{configured:e,scripts:t}=xn(),r=[...e,...t];if(r.length===0)return"";let o=$()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||Ve[i]||""}));return q({title:"Workspace Commands",commands:s,footer:""})}function Pn(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=Bt();for(let a of i)console.log(a);return}Vi(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}import{existsSync as Gt,readdirSync as Ki}from"fs";import{dirname as qi,join as bn}from"path";import{dirname as Ji}from"path";import{fileURLToPath as zi}from"url";var j=e=>Ji(zi(e));Rt();var Yi=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),B=e=>{let t=e??Yi(),r=o=>Gt(bn(o,"package.json")),n=qi(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return B(n)},Sn=(e,t)=>{let r=e.find(Gt);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},En=async e=>{let{getWorkspacePathsConfig:t}=await Promise.resolve().then(()=>(v(),rn)),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=bn(e,o);if(!Gt(s))return[];try{return Ki(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};v();var Tn={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"},Ve={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"},$n=(e,t)=>t?`${e}:${t}`:e,Zi=()=>Object.entries(Tn).map(([e,t])=>$n(e,t)),Xi=()=>{try{let e=Bt(),r=$()?.pf?.commands||{},n=Object.keys(Tn);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||Ve[o]||"";return $n(o,s)})}catch{return[]}},Qi=()=>{try{let e=d(),t=x(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=xt("@crossdelta/cloudevents");return n(r)}catch{return[]}},ea=async()=>{try{let e=d();return await En(e)}catch{return[]}},Ut=async()=>({commands:[...Zi(),...Xi()],events:Qi(),services:await ea()});var ve="node_modules/.cache/pf",ke="completion-cache";var ia=e=>{let t=E.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},aa=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:[]}},ca=e=>{let t=Ce(e,ve);return Ce(t,ke)},pa=(e,t=!1)=>{if(t)return!0;let r=ca(e);if(!Je(r))return!0;let n=ra(r,"utf-8").trim(),o=aa(n),s=E.version||"0.0.0";if(o.version!==s)return!0;let i=Ce(e,"package.json");if(!Je(i))return!1;let a=Rn(r).mtimeMs;return Rn(i).mtimeMs>a};var la=(e,t)=>{let r=Ce(e,ve),n=Ce(r,ke),o=`${n}.tmp.${process.pid}`;Je(r)||ta(r,{recursive:!0});let s=ia(t);try{sa(o,s,"utf-8"),na(o,n)}catch(i){try{Je(o)&&oa(o)}catch{}throw i}},ze=async(e={})=>{let t;try{t=d()}catch{return!1}if(!t)return!1;if(!pa(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Ut();return la(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},xe=async(e={})=>{await ze({...e,force:!0})};import{existsSync as Jt,readFileSync as _n,writeFileSync as Dn}from"fs";import{homedir as Ln}from"os";import{join as Vt}from"path";import Y from"chalk";var In=`${ve}/${ke}`,Nn=e=>`# ${e} completion (workspace-local cache)
36
36
  # Generated: ${new Date().toISOString()}
37
37
 
38
38
  # Cache file path (relative to workspace root)
@@ -163,7 +163,7 @@ _${e}_completions() {
163
163
  esac
164
164
  }
165
165
 
166
- compdef _${e}_completions ${e}`,An=e=>`# ${e} completion (workspace-local cache)
166
+ compdef _${e}_completions ${e}`,On=e=>`# ${e} completion (workspace-local cache)
167
167
  # Generated: ${new Date().toISOString()}
168
168
 
169
169
  # Cache file path (relative to workspace root)
@@ -261,20 +261,20 @@ _${e}_completions() {
261
261
  return 0
262
262
  }
263
263
 
264
- complete -F _${e}_completions ${e}`;var la=(e,t)=>Vt(Ln(),`.${t}-completion.${e}`),Mn=e=>{let t=Ln();return e==="zsh"?Vt(t,".zshrc"):Vt(t,".bashrc")},ma=e=>`[[ -f "${e}" ]] && source "${e}"`,ua=(e,t)=>zt(e)?_n(e,"utf-8").includes(t):!1,da=(e,t)=>{let r=zt(e)?_n(e,"utf-8"):"",n=r.endsWith(`
264
+ complete -F _${e}_completions ${e}`;var ma=(e,t)=>Vt(Ln(),`.${t}-completion.${e}`),Mn=e=>{let t=Ln();return e==="zsh"?Vt(t,".zshrc"):Vt(t,".bashrc")},ua=e=>`[[ -f "${e}" ]] && source "${e}"`,da=(e,t)=>Jt(e)?_n(e,"utf-8").includes(t):!1,ga=(e,t)=>{let r=Jt(e)?_n(e,"utf-8"):"",n=r.endsWith(`
265
265
  `)?`${r}${t}
266
266
  `:`${r}
267
267
  ${t}
268
- `;Dn(e,n,"utf-8")},ga=(e,t)=>{let r=la(e,t),n=e==="zsh"?Nn(t):An(t);return Dn(r,n,"utf-8"),r},On=(e,t,r)=>{let n=ga(e,t),o=Mn(e),s=ma(n);return ua(o,s)?(r&&console.log(Y.dim(`[${e}] Already configured in ${o}`)),!1):(da(o,s),r&&console.log(Y.green(`[${e}] Added source line to ${o}`)),!0)},fa=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",Jt=(e,t=!1)=>{let r=fa();t&&console.log(Y.cyan(`Installing ${r} completion...`)),On(r,e,t);let n=r==="zsh"?"bash":"zsh",o=Mn(n);zt(o)&&On(n,e,t),t&&(console.log(Y.green("\u2713 Shell completion installed")),console.log(Y.dim(` Run: ${Y.cyan("exec $SHELL")} to reload`)))};z();import{readdir as Jf}from"fs/promises";import{dirname as qf,join as Yf}from"path";import{fileURLToPath as Xf}from"url";import{runFlow as eh}from"@crossdelta/flowcore";var ha={debug:()=>{},info:console.log,warn:console.warn,error:console.error},jn=e=>e!==null&&typeof e=="object",Fn=e=>typeof e=="string"&&e.length>0,Wn=e=>typeof e=="string",Kt=e=>typeof e=="function",ya=(e,t)=>jn(e)?[!Fn(e.name)&&`commands[${t}]: missing or invalid 'name'`,!Wn(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`,!Kt(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var Hn=e=>{if(!jn(e))return["Plugin must be an object"];let t=[!Fn(e.name)&&"Missing or invalid 'name'",!Wn(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!Kt(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>ya(n,o)):[];return[...t,...r]},Ke=(e,t=ha)=>({workspace:e,logger:t}),qe=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(!Kt(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=Hn(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
268
+ `;Dn(e,n,"utf-8")},fa=(e,t)=>{let r=ma(e,t),n=e==="zsh"?Nn(t):On(t);return Dn(r,n,"utf-8"),r},An=(e,t,r)=>{let n=fa(e,t),o=Mn(e),s=ua(n);return da(o,s)?(r&&console.log(Y.dim(`[${e}] Already configured in ${o}`)),!1):(ga(o,s),r&&console.log(Y.green(`[${e}] Added source line to ${o}`)),!0)},ha=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",zt=(e,t=!1)=>{let r=ha();t&&console.log(Y.cyan(`Installing ${r} completion...`)),An(r,e,t);let n=r==="zsh"?"bash":"zsh",o=Mn(n);Jt(o)&&An(n,e,t),t&&(console.log(Y.green("\u2713 Shell completion installed")),console.log(Y.dim(` Run: ${Y.cyan("exec $SHELL")} to reload`)))};J();import{readdir as Kf}from"fs/promises";import{dirname as Yf,join as Zf}from"path";import{fileURLToPath as Qf}from"url";import{runFlow as th}from"@crossdelta/flowcore";var ya={debug:()=>{},info:console.log,warn:console.warn,error:console.error},jn=e=>e!==null&&typeof e=="object",Fn=e=>typeof e=="string"&&e.length>0,Wn=e=>typeof e=="string",Kt=e=>typeof e=="function",va=(e,t)=>jn(e)?[!Fn(e.name)&&`commands[${t}]: missing or invalid 'name'`,!Wn(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`,!Kt(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var Hn=e=>{if(!jn(e))return["Plugin must be an object"];let t=[!Fn(e.name)&&"Missing or invalid 'name'",!Wn(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!Kt(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>va(n,o)):[];return[...t,...r]},Ke=(e,t=ya)=>({workspace:e,logger:t}),qe=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(!Kt(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=Hn(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
269
269
  - ${i.join(`
270
- - `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as oh}from"@crossdelta/cloudevents";import{z as f}from"zod";var Ye=f.object({dependencies:f.record(f.string(),f.string()).default({}),envVars:f.array(f.object({key:f.string(),description:f.string(),required:f.boolean().default(!0)})).default([]),adapterFile:f.string().optional()}),va=f.object({push:f.string().optional(),email:f.string().optional(),slack:f.string().optional(),sms:f.string().optional()}).optional(),ka=f.object({defaults:va,providers:f.object({push:f.record(f.string(),Ye).optional(),email:f.record(f.string(),Ye).optional(),slack:f.record(f.string(),Ye).optional(),sms:f.record(f.string(),Ye).optional()}).optional()}),qd=f.object({notifier:ka.optional()});import{z as g}from"zod";var Ca=g.object({type:g.literal("event"),eventType:g.string(),stream:g.string().optional()}),xa=g.object({type:g.literal("http"),method:g.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:g.string().optional()}),Gn=g.discriminatedUnion("type",[Ca,xa]),wa=g.object({type:g.literal("emit.event"),eventType:g.string()}),Pa=g.object({type:g.literal("notify"),channel:g.enum(["push","email","slack","sms"]),provider:g.string().optional()}),ba=g.object({type:g.literal("call.http"),name:g.string().optional(),baseUrl:g.string().optional()}),Sa=g.object({type:g.literal("persist"),store:g.enum(["db","kv","cache"]),entity:g.string().optional()}),Bn=g.discriminatedUnion("type",[wa,Pa,ba,Sa]),Un=g.object({serviceName:g.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:g.enum(["hono","nest"]).default("hono"),triggers:g.array(Gn).min(1),actions:g.array(Bn).default([])});v();import{existsSync as X,mkdirSync as Da,readFileSync as qt,writeFileSync as we}from"fs";import{dirname as zn,join as Z}from"path";import{deriveEventNames as La}from"@crossdelta/cloudevents";var Ma=(e,t)=>{let r=`export * from './${t}'`;if(!X(e)){let s=zn(e);X(s)||Da(s,{recursive:!0});let i=`/**
271
- * ${zn(e).split("/").pop()} Domain Events
270
+ - `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as sh}from"@crossdelta/cloudevents";import{z as f}from"zod";var Ye=f.object({dependencies:f.record(f.string(),f.string()).default({}),envVars:f.array(f.object({key:f.string(),description:f.string(),required:f.boolean().default(!0)})).default([]),adapterFile:f.string().optional()}),ka=f.object({push:f.string().optional(),email:f.string().optional(),slack:f.string().optional(),sms:f.string().optional()}).optional(),Ca=f.object({defaults:ka,providers:f.object({push:f.record(f.string(),Ye).optional(),email:f.record(f.string(),Ye).optional(),slack:f.record(f.string(),Ye).optional(),sms:f.record(f.string(),Ye).optional()}).optional()}),Yd=f.object({notifier:Ca.optional()});import{z as g}from"zod";var xa=g.object({type:g.literal("event"),eventType:g.string(),stream:g.string().optional()}),wa=g.object({type:g.literal("http"),method:g.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:g.string().optional()}),Bn=g.discriminatedUnion("type",[xa,wa]),Pa=g.object({type:g.literal("emit.event"),eventType:g.string()}),ba=g.object({type:g.literal("notify"),channel:g.enum(["push","email","slack","sms"]),provider:g.string().optional()}),Sa=g.object({type:g.literal("call.http"),name:g.string().optional(),baseUrl:g.string().optional()}),Ea=g.object({type:g.literal("persist"),store:g.enum(["db","kv","cache"]),entity:g.string().optional()}),Gn=g.discriminatedUnion("type",[Pa,ba,Sa,Ea]),Un=g.object({serviceName:g.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:g.enum(["hono","nest"]).default("hono"),triggers:g.array(Bn).min(1),actions:g.array(Gn).default([])});v();import{existsSync as X,mkdirSync as La,readFileSync as qt,writeFileSync as we}from"fs";import{dirname as Jn,join as Z}from"path";import{deriveEventNames as Ma}from"@crossdelta/cloudevents";var ja=(e,t)=>{let r=`export * from './${t}'`;if(!X(e)){let s=Jn(e);X(s)||La(s,{recursive:!0});let i=`/**
271
+ * ${Jn(e).split("/").pop()} Domain Events
272
272
  */
273
273
 
274
274
  `;return we(e,`${i+r}
275
275
  `,"utf-8"),!0}let n=qt(e,"utf-8");if(n.includes(`'./${t}'`))return!1;let o=`${n.trimEnd()}
276
276
  ${r}
277
- `;return we(e,o,"utf-8"),!0},ja=(e,t)=>{let r=`export * from './${t}'`;if(!X(e))return we(e,`/**
277
+ `;return we(e,o,"utf-8"),!0},Fa=(e,t)=>{let r=`export * from './${t}'`;if(!X(e))return we(e,`/**
278
278
  * Event Contracts Index
279
279
  *
280
280
  * Re-exports all event contracts for convenient importing.
@@ -283,20 +283,20 @@ ${r}
283
283
  ${r}
284
284
  `,"utf-8"),!0;let o=qt(e,"utf-8").split(`
285
285
  `);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),we(e,o.join(`
286
- `),"utf-8"),!0},Fa=e=>{if(!X(e))return!1;let t=qt(e,"utf-8"),r="export * from './events'";if(t.split(`
286
+ `),"utf-8"),!0},Wa=e=>{if(!X(e))return!1;let t=qt(e,"utf-8"),r="export * from './events'";if(t.split(`
287
287
  `).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()}
288
288
  ${r}
289
- `),o!==t?(we(e,o,"utf-8"),!0):!1},Jn=(e,t)=>{let{packagePath:r}=x(t),{domain:n,action:o}=La(e),s=Z(r,"src","events");if(!X(s))return!1;let i=Z(s,n),a=Z(i,"index.ts"),c=Z(s,"index.ts"),p=Z(r,"src","index.ts"),l=e.split(".")[0],u=Z(s,l);l!==n&&X(u)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${l}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${u} ${i}`));let T=!1;return Ma(a,o)&&(T=!0),ja(c,n)&&(T=!0),Fa(p)&&(T=!0),T};import{existsSync as Ze,readFileSync as Kn,writeFileSync as Wa}from"fs";import{join as Yt}from"path";import{getStreamName as Ha}from"@crossdelta/cloudevents";var Ga=(e,t)=>{let r=Yt(e,"src","index.ts");if(!Ze(r))return!1;let n=Kn(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)},Ba=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
289
+ `),o!==t?(we(e,o,"utf-8"),!0):!1},zn=(e,t)=>{let{packagePath:r}=x(t),{domain:n,action:o}=Ma(e),s=Z(r,"src","events");if(!X(s))return!1;let i=Z(s,n),a=Z(i,"index.ts"),c=Z(s,"index.ts"),p=Z(r,"src","index.ts"),l=e.split(".")[0],u=Z(s,l);l!==n&&X(u)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${l}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${u} ${i}`));let T=!1;return ja(a,o)&&(T=!0),Fa(c,n)&&(T=!0),Wa(p)&&(T=!0),T};import{existsSync as Ze,readFileSync as Kn,writeFileSync as Ha}from"fs";import{join as Yt}from"path";import{getStreamName as Ba}from"@crossdelta/cloudevents";var Ga=(e,t)=>{let r=Yt(e,"src","index.ts");if(!Ze(r))return!1;let n=Kn(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)},Ua=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
290
290
  `,r=e.match(/import\s+['"]@crossdelta\/telemetry['"]\s*\n/);if(r){let o=(r.index??0)+r[0].length;return`${e.slice(0,o)}
291
- ${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},Ua=(e,t)=>`
291
+ ${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},Va=(e,t)=>`
292
292
 
293
293
  // Consume from ${e} stream
294
294
  consumeJetStreams({
295
295
  streams: ['${e}'],
296
296
  consumer: '${t}-service',
297
297
  discover: './src/events/**/*.handler.ts',
298
- })`,qn=(e,t)=>{let r=Ha(t),n=Yt(e,"src","index.ts"),o=Yt(e,"src","main.ts");if(!Ze(n)&&Ze(o))return{added:!1,streamName:r};if(!Ze(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(Ga(e,r))return{added:!1,streamName:r};let s=Kn(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Ba(s));let a=Ua(r,i),c=`${s.trimEnd()+a}
299
- `;return Wa(n,c,"utf-8"),{added:!0,streamName:r}};var Va=(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=qn(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`})},za=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
298
+ })`,qn=(e,t)=>{let r=Ba(t),n=Yt(e,"src","index.ts"),o=Yt(e,"src","main.ts");if(!Ze(n)&&Ze(o))return{added:!1,streamName:r};if(!Ze(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(Ga(e,r))return{added:!1,streamName:r};let s=Kn(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Ua(s));let a=Va(r,i),c=`${s.trimEnd()+a}
299
+ `;return Ha(n,c,"utf-8"),{added:!0,streamName:r}};var Ja=(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=qn(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`})},za=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
300
300
  import { createContract } from '@crossdelta/cloudevents'
301
301
  import { z } from 'zod'
302
302
 
@@ -304,7 +304,7 @@ export const ${Zt(o)}Contract = createContract({
304
304
  type: '${o}',
305
305
  schema: z.object({ ... }),
306
306
  })
307
- `.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=Jn(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`}},Zt=e=>e.split(".").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(""),Ja=(e,t,r)=>{let{path:n,eventType:o,servicePath:s}=e;if(r?.dryRun){let i=`
307
+ `.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=zn(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`}},Zt=e=>e.split(".").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(""),Ka=(e,t,r)=>{let{path:n,eventType:o,servicePath:s}=e;if(r?.dryRun){let i=`
308
308
  import { handleEvent } from '@crossdelta/cloudevents'
309
309
  import { ${Zt(o)}Contract } from '@your-scope/contracts'
310
310
 
@@ -312,9 +312,9 @@ export default handleEvent(${Zt(o)}Contract, async (data) => {
312
312
  console.log('Processing ${o}:', data)
313
313
  // TODO: Implement handler logic
314
314
  })
315
- `.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}},Ka={"stream.wired":Va,"contract.created":za,"handler.created":Ja},Xt=(e,t,r)=>e.map(n=>{let o=Ka[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 rt}from"path";import{deriveEventNames as Mc}from"@crossdelta/cloudevents";var Qt=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});v();import{join as tr}from"path";import{readFileSync as qa}from"fs";import{join as Ya}from"path";import Za from"handlebars";var Q=(e,t)=>Sn(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),er=(e,t={})=>{let r=qa(e,"utf-8");return Za.compile(r)(t)},Xe=e=>(t,r={})=>{let n=Ya(e,t);return er(n,r)};var D=e=>e.toUpperCase().replace(/-/g,"_");var Yn=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Xa=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Qa=()=>{let e=Xa(),t=G();return Q([tr(e,"templates","hono-microservice"),tr(e,"..","hono-microservice","templates"),tr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Qe=(e,t={})=>Xe(Qa())(e,t);function Zn(){return Qe("tsconfig.json.hbs")}function Xn(e="1.2.23"){return Qe("Dockerfile.hbs",{bunVersion:e})}function Qn(){return Qe("biome.json.hbs")}function eo(e,t=[]){return Qe("src/config/env.ts.hbs",{envKey:D(e),envVars:t})}var ec=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},tc=(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},rc=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],nc=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],oc=e=>{let t=D(e.serviceName);return`${[...ec(e.hasEvents),"",...tc(t,e.hasEvents),...e.hasEvents?rc(e.serviceName,e.streams):[],...nc()].join(`
315
+ `.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}},qa={"stream.wired":Ja,"contract.created":za,"handler.created":Ka},Xt=(e,t,r)=>e.map(n=>{let o=qa[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 rt}from"path";import{deriveEventNames as jc}from"@crossdelta/cloudevents";var Qt=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});v();import{join as tr}from"path";import{readFileSync as Ya}from"fs";import{join as Za}from"path";import Xa from"handlebars";var Q=(e,t)=>Sn(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),er=(e,t={})=>{let r=Ya(e,"utf-8");return Xa.compile(r)(t)},Xe=e=>(t,r={})=>{let n=Za(e,t);return er(n,r)};var D=e=>e.toUpperCase().replace(/-/g,"_");var Yn=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Qa=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),ec=()=>{let e=Qa(),t=B();return Q([tr(e,"templates","hono-microservice"),tr(e,"..","hono-microservice","templates"),tr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},Qe=(e,t={})=>Xe(ec())(e,t);function Zn(){return Qe("tsconfig.json.hbs")}function Xn(e="1.2.23"){return Qe("Dockerfile.hbs",{bunVersion:e})}function Qn(){return Qe("biome.json.hbs")}function eo(e,t=[]){return Qe("src/config/env.ts.hbs",{envKey:D(e),envVars:t})}var tc=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},rc=(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},nc=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],oc=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],sc=e=>{let t=D(e.serviceName);return`${[...tc(e.hasEvents),"",...rc(t,e.hasEvents),...e.hasEvents?nc(e.serviceName,e.streams):[],...oc()].join(`
316
316
  `)}
317
- `},sc=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)},ic=e=>`# ${e.serviceName}
317
+ `},ic=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)},ac=e=>`# ${e.serviceName}
318
318
 
319
319
  ## Development
320
320
 
@@ -334,7 +334,7 @@ ${e.hasEvents?`
334
334
  This service consumes from:
335
335
  ${e.streams.map(t=>`- ${t}`).join(`
336
336
  `)}`:""}
337
- `,ac=()=>"",to={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:oc},{path:"src/config/env.ts",content:e=>eo(e.serviceName,e.envVars)},{path:"package.json",content:sc},{path:"tsconfig.json",content:()=>Zn()},{path:"Dockerfile",content:()=>Xn()},{path:"biome.json",content:()=>Qn()},{path:"README.md",content:ic},{path:"src/events/.gitkeep",content:ac,skip:e=>!e.hasEvents}]};import{join as rr}from"path";var cc=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),pc=()=>{let e=cc(),t=G();return Q([rr(e,"templates","nest-microservice"),rr(e,"..","nest-microservice","templates"),rr(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},B=(e,t={})=>Xe(pc())(e,t);function ro(e,t=3e3){return B("src/main.ts.hbs",{serviceName:e,envKey:D(e),displayName:Yn(e),defaultPort:t})}function no(){return B("src/app.context.ts.hbs",{})}function oo(){return B("src/events/events.module.ts.hbs",{})}function so(e){return B("src/events/events.service.ts.hbs",{serviceName:e})}function io(e="24",t="1.2.23"){return B("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function ao(){return B("biome.json.hbs",{})}function co(e,t=[]){return B("src/config/env.ts.hbs",{envKey:D(e),envVars:t})}var lc=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)},mc=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),uc=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
337
+ `,cc=()=>"",to={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:sc},{path:"src/config/env.ts",content:e=>eo(e.serviceName,e.envVars)},{path:"package.json",content:ic},{path:"tsconfig.json",content:()=>Zn()},{path:"Dockerfile",content:()=>Xn()},{path:"biome.json",content:()=>Qn()},{path:"README.md",content:ac},{path:"src/events/.gitkeep",content:cc,skip:e=>!e.hasEvents}]};import{join as rr}from"path";var pc=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),lc=()=>{let e=pc(),t=B();return Q([rr(e,"templates","nest-microservice"),rr(e,"..","nest-microservice","templates"),rr(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},G=(e,t={})=>Xe(lc())(e,t);function ro(e,t=3e3){return G("src/main.ts.hbs",{serviceName:e,envKey:D(e),displayName:Yn(e),defaultPort:t})}function no(){return G("src/app.context.ts.hbs",{})}function oo(){return G("src/events/events.module.ts.hbs",{})}function so(e){return G("src/events/events.service.ts.hbs",{serviceName:e})}function io(e="24",t="1.2.23"){return G("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function ao(){return G("biome.json.hbs",{})}function co(e,t=[]){return G("src/config/env.ts.hbs",{envKey:D(e),envVars:t})}var mc=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)},uc=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),dc=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
338
338
  ${e.hasEvents?"import { EventsModule } from './events/events.module'":""}
339
339
 
340
340
  @Module({
@@ -347,7 +347,7 @@ export class AppModule${e.hasEvents?" implements OnModuleInit":""} {
347
347
  // Events module initializes NATS consumer
348
348
  }`:""}
349
349
  }
350
- `},dc=()=>`import { Controller, Get } from '@nestjs/common'
350
+ `},gc=()=>`import { Controller, Get } from '@nestjs/common'
351
351
 
352
352
  @Controller()
353
353
  export class AppController {
@@ -356,7 +356,7 @@ export class AppController {
356
356
  return { status: 'ok' }
357
357
  }
358
358
  }
359
- `,gc=e=>`# ${e.serviceName}
359
+ `,fc=e=>`# ${e.serviceName}
360
360
 
361
361
  ## Development
362
362
 
@@ -376,8 +376,8 @@ ${e.hasEvents?`
376
376
  This service consumes from:
377
377
  ${e.streams.map(t=>`- ${t}`).join(`
378
378
  `)}`:""}
379
- `,fc=()=>"",po={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>co(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>ro(e.serviceName,e.port)},{path:"src/app.module.ts",content:uc},{path:"src/app.controller.ts",content:()=>dc()},{path:"src/app.context.ts",content:()=>no()},{path:"package.json",content:lc},{path:"tsconfig.json",content:()=>mc()},{path:"Dockerfile",content:()=>io()},{path:"biome.json",content:()=>ao()},{path:"README.md",content:gc},{path:"src/events/events.module.ts",content:()=>oo(),skip:e=>!e.hasEvents},{path:"src/events/events.service.ts",content:e=>so(e.serviceName),skip:e=>!e.hasEvents},{path:"src/events/handlers/.gitkeep",content:fc,skip:e=>!e.hasEvents}]};var lo=[to,po],mo=e=>{let t=hc(e),r=lo.find(n=>n.name===t);if(!r)throw new Error(`Template '${e}' not found. Available: ${lo.map(n=>n.name).join(", ")}`);return r},hc=e=>({"hono-micro":"hono-bun","nest-micro":"nest"})[e]||e;import{join as or}from"path";import{deriveEventNames as sr}from"@crossdelta/cloudevents";var uo={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"}]},Pe={hono:{businessLogicDir:"use-cases",eventsDir:"events",filePattern:"{name}.use-case.ts",suffix:"use-case",handlerDelegatesToBusinessLogic:!0,pathGuards:{forbidDirs:["src/services"]},codingConstraints:uo},nestjs:{businessLogicDir:"",eventsDir:"events",filePattern:"{name}.service.ts",suffix:"service",handlerDelegatesToBusinessLogic:!1,pathGuards:{forbidDirs:[]},codingConstraints:{appliesTo:["src/domain"],forbiddenPatterns:uo.forbiddenPatterns}}},yc=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),vc=(e,t)=>`../${e}/${t}`,ee=(e,t)=>{let r=Pe[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:yc(t),delegateFromHandler:r.handlerDelegatesToBusinessLogic,importFromEvents:r.businessLogicDir?vc(r.businessLogicDir,o):`./${o}`}},nr=(e,t)=>{let n=`src/${Pe[e].eventsDir}`,o=`${t}.handler.ts`;return{filePath:`${n}/${o}`,dirPath:n,fileName:o}},be=e=>`handle-${e.replace(/\./g,"-")}`,et=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("/")},kc=(e,t)=>{let r=et(e);for(let n of t){let o=et(n);if(r.startsWith(`${o}/`)||r===o)return n}return null},Cc=(e,t)=>{let r=et(e);return t.some(n=>{let o=et(n);return r.startsWith(`${o}/`)||r===o})},xc=(e,t,r)=>{let n=[],o=e.split(`
380
- `);for(let{pattern:s,description:i,code:a}of t){let c=new RegExp(s,"g");for(let p=0;p<o.length;p++)c.test(o[p])&&n.push({code:a,message:i,path:r,line:p+1}),c.lastIndex=0}return n},wc=(e,t)=>{let r=[],n=kc(e.path,t.pathGuards.forbidDirs);if(n&&r.push({code:"FORBIDDEN_DIR",message:`Path '${e.path}' is in forbidden directory '${n}'`,path:e.path}),Cc(e.path,t.codingConstraints.appliesTo)){let o=xc(e.content,t.codingConstraints.forbiddenPatterns,e.path);r.push(...o)}return r},tt=(e,t)=>{let r=Pe[e],n=[];for(let o of t)n.push(...wc(o,r));return{valid:n.length===0,violations:n}};var Sc=(e,t)=>t.map(r=>({kind:"file:write",path:or(e,r.path),content:r.content})),Ec=(e,t,r)=>({kind:"infra:add",serviceName:e,port:t,framework:r.framework,runtime:r.runtime}),Tc=(e,t)=>({kind:"env:add",key:`${e}_PORT`,value:t.toString()}),$c=(e,t)=>{let{typeName:r}=sr(e),n=be(e),o=ee("hono",n);return`import type { ${r} } from '${t}/contracts'
379
+ `,hc=()=>"",po={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>co(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>ro(e.serviceName,e.port)},{path:"src/app.module.ts",content:dc},{path:"src/app.controller.ts",content:()=>gc()},{path:"src/app.context.ts",content:()=>no()},{path:"package.json",content:mc},{path:"tsconfig.json",content:()=>uc()},{path:"Dockerfile",content:()=>io()},{path:"biome.json",content:()=>ao()},{path:"README.md",content:fc},{path:"src/events/events.module.ts",content:()=>oo(),skip:e=>!e.hasEvents},{path:"src/events/events.service.ts",content:e=>so(e.serviceName),skip:e=>!e.hasEvents},{path:"src/events/handlers/.gitkeep",content:hc,skip:e=>!e.hasEvents}]};var lo=[to,po],mo=e=>{let t=yc(e),r=lo.find(n=>n.name===t);if(!r)throw new Error(`Template '${e}' not found. Available: ${lo.map(n=>n.name).join(", ")}`);return r},yc=e=>({"hono-micro":"hono-bun","nest-micro":"nest"})[e]||e;import{join as or}from"path";import{deriveEventNames as sr}from"@crossdelta/cloudevents";var uo={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"}]},Pe={hono:{businessLogicDir:"use-cases",eventsDir:"events",filePattern:"{name}.use-case.ts",suffix:"use-case",handlerDelegatesToBusinessLogic:!0,pathGuards:{forbidDirs:["src/services"]},codingConstraints:uo},nestjs:{businessLogicDir:"",eventsDir:"events",filePattern:"{name}.service.ts",suffix:"service",handlerDelegatesToBusinessLogic:!1,pathGuards:{forbidDirs:[]},codingConstraints:{appliesTo:["src/domain"],forbiddenPatterns:uo.forbiddenPatterns}}},vc=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),kc=(e,t)=>`../${e}/${t}`,ee=(e,t)=>{let r=Pe[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:vc(t),delegateFromHandler:r.handlerDelegatesToBusinessLogic,importFromEvents:r.businessLogicDir?kc(r.businessLogicDir,o):`./${o}`}},nr=(e,t)=>{let n=`src/${Pe[e].eventsDir}`,o=`${t}.handler.ts`;return{filePath:`${n}/${o}`,dirPath:n,fileName:o}},be=e=>`handle-${e.replace(/\./g,"-")}`,et=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("/")},Cc=(e,t)=>{let r=et(e);for(let n of t){let o=et(n);if(r.startsWith(`${o}/`)||r===o)return n}return null},xc=(e,t)=>{let r=et(e);return t.some(n=>{let o=et(n);return r.startsWith(`${o}/`)||r===o})},wc=(e,t,r)=>{let n=[],o=e.split(`
380
+ `);for(let{pattern:s,description:i,code:a}of t){let c=new RegExp(s,"g");for(let p=0;p<o.length;p++)c.test(o[p])&&n.push({code:a,message:i,path:r,line:p+1}),c.lastIndex=0}return n},Pc=(e,t)=>{let r=[],n=Cc(e.path,t.pathGuards.forbidDirs);if(n&&r.push({code:"FORBIDDEN_DIR",message:`Path '${e.path}' is in forbidden directory '${n}'`,path:e.path}),xc(e.path,t.codingConstraints.appliesTo)){let o=wc(e.content,t.codingConstraints.forbiddenPatterns,e.path);r.push(...o)}return r},tt=(e,t)=>{let r=Pe[e],n=[];for(let o of t)n.push(...Pc(o,r));return{valid:n.length===0,violations:n}};var Ec=(e,t)=>t.map(r=>({kind:"file:write",path:or(e,r.path),content:r.content})),Tc=(e,t,r)=>({kind:"infra:add",serviceName:e,port:t,framework:r.framework,runtime:r.runtime}),$c=(e,t)=>({kind:"env:add",key:`${e}_PORT`,value:t.toString()}),Rc=(e,t)=>{let{typeName:r}=sr(e),n=be(e),o=ee("hono",n);return`import type { ${r} } from '${t}/contracts'
381
381
 
382
382
  /**
383
383
  * Handle ${e} event
@@ -389,7 +389,7 @@ export const ${o.functionName} = async (data: ${r}): Promise<void> => {
389
389
  // TODO: Implement business logic
390
390
  // Example: validate data, transform, call external services
391
391
  }
392
- `},Rc=(e,t,r)=>{let{contractName:n,typeName:o}=sr(e),s=be(e),i=ee(r,s);return i.delegateFromHandler?`import { handleEvent } from '@crossdelta/cloudevents'
392
+ `},Ic=(e,t,r)=>{let{contractName:n,typeName:o}=sr(e),s=be(e),i=ee(r,s);return i.delegateFromHandler?`import { handleEvent } from '@crossdelta/cloudevents'
393
393
  import { ${n}, type ${o} } from '${t}/contracts'
394
394
  import { ${i.functionName} } from '${i.importFromEvents}'
395
395
 
@@ -404,10 +404,10 @@ export default handleEvent(${n}, async (data: ${o}) => {
404
404
  console.log('\u{1F4E6} [${e}] Event received:', data)
405
405
  // TODO: Inject and call service
406
406
  })
407
- `},Ic=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:ee(r,"stub").delegateFromHandler?t.events.map(o=>{let s=be(o),i=ee(r,s);return{kind:"file:write",path:or(e,i.filePath),content:$c(o,t.workspaceScope)}}):[],Nc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=sr(n),s=nr(r,o);return{kind:"file:write",path:or(e,s.filePath),content:Rc(n,t.workspaceScope,r)}}),Ac=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",go=(e,t,r,n)=>{let o=Ac(n.framework),s=Sc(e,t),i=Ic(e,r,o),a=Nc(e,r,o),c=Ec(r.serviceName,r.port,n),p=Tc(r.envVarName,r.port);return[...s,...i,...a,c,p]};import{existsSync as Oc,readdirSync as _c,readFileSync as Dc}from"fs";import{join as fo}from"path";var ho=4001,Lc=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},yo=e=>{try{let t=fo(e,"infra","services");return Oc(t)?_c(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=Dc(fo(t,o),"utf-8"),i=Lc(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},ir=(e,t)=>e.has(t)?ir(e,t+1):t;var jc=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)`)},Fc=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return rt(r,t);if(t.includes("/"))return rt(r,t)}let n=I(r);return rt(r,n.services,e)},Wc=e=>[...new Set(e.map(t=>Mc(t).streamName))],Hc=(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?Wc(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:D(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},Gc=(e,t)=>e.files.filter(r=>!r.skip?.(t)).map(r=>({path:r.path,content:r.content(t)})),Bc=(e,t,r)=>[...e.map(o=>({type:"file",path:rt(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"}],Uc=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],vo=e=>{jc(e.name);let t=e.workspaceRoot??d(),r=Fc(e.name,e.path,t),n=e.port??ir(yo(t),ho),o=Hc(e,t,r,n),s=mo(e.type),i=Gc(s,o),a=go(r,i,o,s),c=Bc(i,e.name,r),p=Uc(r);return Qt("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:p,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},ko=e=>{let t=vo(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}};v();v();v();import b from"chalk";import{execa as zc}from"execa";import{createJiti as Jc}from"jiti";var cr=async e=>{let{stdout:t}=await zc("sh",["-c",e]);return t.trim()},Co="pf-local-nats",Kc="2.10-alpine",qc=4222,Yc=8222,Zc=64*1024*1024,Xc={storage:"memory",retention:"limits",maxAge:36e5,maxBytes:Zc},Qc=e=>({clientPort:e.clientPort??qc,monitoringPort:e.monitoringPort??Yc,containerName:e.containerName??Co,version:e.version??Kc}),ep=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"],tp=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),rp=async()=>{try{return await cr("docker info"),!0}catch{return!1}},np=async e=>{try{return(await cr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var op=async e=>{let t=ep(e);try{return await cr(`docker ${t.join(" ")}`),{success:!0,value:tp(e)}}catch{return{success:!1}}},sp=e=>{console.log(b.green("\u2713 NATS started")),console.log(b.dim(` Client: ${e.clientUrl}`)),console.log(b.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(b.dim(" Streams: ephemeral, auto-created by services")),console.log("")},xo=async(e={})=>{let t=Qc(e);if(!await rp())return console.log(b.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await np(t.containerName))return console.log(b.dim("\u2713 NATS already running")),!0;console.log(b.cyan("\u{1F680} Starting development infrastructure...")),console.log(b.dim(" NATS with JetStream (ephemeral)"));let r=await op(t);return r.success?(sp(r.value),!0):(console.error(b.red("\u2717 Failed to start NATS")),!1)},ip=e=>e.map(({stream:t,subjects:r})=>({stream:t,subjects:r,config:Xc})),ar="@crossdelta/infrastructure",wo=e=>e.includes(ar)&&(e.includes("is not defined by")||e.includes("Cannot find module")||e.includes("Cannot find package")),Po=e=>{if(typeof e!="object"||e===null)return null;let{message:t}=e;return typeof t=="string"?t:null},ap=e=>{let t=Po(e);if(t===null)return!0;if(wo(t))return!1;let r=t.toLowerCase();return!r.includes("insufficient storage")&&!r.includes("connection refused")},cp=e=>{let t=Po(e);if(t===null)return"Unknown error";let r=t.toLowerCase();return r.includes("insufficient storage")?["NATS has insufficient storage to create streams."," JetStream fixes its storage limit when the server starts, at 75% of the free space it"," sees then, and never recomputes it. So a disk that was full when the container started"," keeps the old limit even after you free space. Restart the container first:","",` docker restart ${Co}`," pf dev",""," If it still fails, the disk is full now as well:",""," docker system prune -af"].join(`
407
+ `},Nc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:ee(r,"stub").delegateFromHandler?t.events.map(o=>{let s=be(o),i=ee(r,s);return{kind:"file:write",path:or(e,i.filePath),content:Rc(o,t.workspaceScope)}}):[],Oc=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=sr(n),s=nr(r,o);return{kind:"file:write",path:or(e,s.filePath),content:Ic(n,t.workspaceScope,r)}}),Ac=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",go=(e,t,r,n)=>{let o=Ac(n.framework),s=Ec(e,t),i=Nc(e,r,o),a=Oc(e,r,o),c=Tc(r.serviceName,r.port,n),p=$c(r.envVarName,r.port);return[...s,...i,...a,c,p]};import{existsSync as _c,readdirSync as Dc,readFileSync as Lc}from"fs";import{join as fo}from"path";var ho=4001,Mc=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},yo=e=>{try{let t=fo(e,"infra","services");return _c(t)?Dc(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=Lc(fo(t,o),"utf-8"),i=Mc(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},ir=(e,t)=>e.has(t)?ir(e,t+1):t;var Fc=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)`)},Wc=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return rt(r,t);if(t.includes("/"))return rt(r,t)}let n=I(r);return rt(r,n.services,e)},Hc=e=>[...new Set(e.map(t=>jc(t).streamName))],Bc=(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?Hc(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:D(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},Gc=(e,t)=>e.files.filter(r=>!r.skip?.(t)).map(r=>({path:r.path,content:r.content(t)})),Uc=(e,t,r)=>[...e.map(o=>({type:"file",path:rt(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"}],Vc=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],vo=e=>{Fc(e.name);let t=e.workspaceRoot??d(),r=Wc(e.name,e.path,t),n=e.port??ir(yo(t),ho),o=Bc(e,t,r,n),s=mo(e.type),i=Gc(s,o),a=go(r,i,o,s),c=Uc(i,e.name,r),p=Vc(r);return Qt("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:p,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},ko=e=>{let t=vo(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}};v();v();v();import b from"chalk";import{execa as zc}from"execa";import{createJiti as Kc}from"jiti";var cr=async e=>{let{stdout:t}=await zc("sh",["-c",e]);return t.trim()},Co="pf-local-nats",qc="2.10-alpine",Yc=4222,Zc=8222,Xc=64*1024*1024,Qc={storage:"memory",retention:"limits",maxAge:36e5,maxBytes:Xc},ep=e=>({clientPort:e.clientPort??Yc,monitoringPort:e.monitoringPort??Zc,containerName:e.containerName??Co,version:e.version??qc}),tp=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"],rp=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),np=async()=>{try{return await cr("docker info"),!0}catch{return!1}},op=async e=>{try{return(await cr(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var sp=async e=>{let t=tp(e);try{return await cr(`docker ${t.join(" ")}`),{success:!0,value:rp(e)}}catch{return{success:!1}}},ip=e=>{console.log(b.green("\u2713 NATS started")),console.log(b.dim(` Client: ${e.clientUrl}`)),console.log(b.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(b.dim(" Streams: ephemeral, auto-created by services")),console.log("")},xo=async(e={})=>{let t=ep(e);if(!await np())return console.log(b.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await op(t.containerName))return console.log(b.dim("\u2713 NATS already running")),!0;console.log(b.cyan("\u{1F680} Starting development infrastructure...")),console.log(b.dim(" NATS with JetStream (ephemeral)"));let r=await sp(t);return r.success?(ip(r.value),!0):(console.error(b.red("\u2717 Failed to start NATS")),!1)},ap=e=>e.map(({stream:t,subjects:r})=>({stream:t,subjects:r,config:Qc})),ar="@crossdelta/infrastructure",wo=e=>e.includes(ar)&&(e.includes("is not defined by")||e.includes("Cannot find module")||e.includes("Cannot find package")),Po=e=>{if(typeof e!="object"||e===null)return null;let{message:t}=e;return typeof t=="string"?t:null},cp=e=>{let t=Po(e);if(t===null)return!0;if(wo(t))return!1;let r=t.toLowerCase();return!r.includes("insufficient storage")&&!r.includes("connection refused")},pp=e=>{let t=Po(e);if(t===null)return"Unknown error";let r=t.toLowerCase();return r.includes("insufficient storage")?["NATS has insufficient storage to create streams."," JetStream fixes its storage limit when the server starts, at 75% of the free space it"," sees then, and never recomputes it. So a disk that was full when the container started"," keeps the old limit even after you free space. Restart the container first:","",` docker restart ${Co}`," pf dev",""," If it still fails, the disk is full now as well:",""," docker system prune -af"].join(`
408
408
  `):r.includes("connection refused")?"Cannot connect to NATS \u2014 is the container running?":wo(t)?[`${ar} is missing or too old to provide its /streams entry point.`,""," It is a peer dependency of this CLI, so neither `bun add -g` nor `npm i -g` installs it"," alongside pf, and bun reports nothing when it is absent. Install it explicitly:","",` bun add -g ${ar}`,""," Not continuing without it: letting the services create the streams instead leaves them in"," whatever shape they already had, so a corrected contract subject never takes effect and"," its events are dropped without an error."].join(`
409
- `):t},pr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=x(e),o=await Jc(e,{moduleCache:!1}).import(r,{default:!0}),{collectStreamDefinitions:s}=await import("@crossdelta/infrastructure/streams"),i=s(o);if(i.length===0){console.log(b.dim(" No streams found in contracts"));return}let a=ip(i);await t({streams:a});let c=i.map(p=>p.stream);console.log(b.dim(` Ensured ${i.length} ephemeral stream(s): ${c.join(", ")}`))}catch(t){if(!ap(t))throw console.error(b.red(`
410
- \u2717 ${cp(t)}
409
+ `):t},pr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=x(e),o=await Kc(e,{moduleCache:!1}).import(r,{default:!0}),{collectStreamDefinitions:s}=await import("@crossdelta/infrastructure/streams"),i=s(o);if(i.length===0){console.log(b.dim(" No streams found in contracts"));return}let a=ap(i);await t({streams:a});let c=i.map(p=>p.stream);console.log(b.dim(` Ensured ${i.length} ephemeral stream(s): ${c.join(", ")}`))}catch(t){if(!cp(t))throw console.error(b.red(`
410
+ \u2717 ${pp(t)}
411
411
  `)),t;console.log(b.yellow(` \u26A0\uFE0F Stream creation failed: ${t instanceof Error?t.message:"Unknown error"}`)),console.log(b.dim(" Streams will be created when services connect"))}};var bo=`// env: string literals \u2192 written to .env.local by generate-env (use for values meaningful locally)
412
412
  // containerEnv: \u2192 only applied in the K8s container, never in .env.local
413
413
  // (use for deployment-specific values like ORIGIN or NODE_OPTIONS)`;function So(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
@@ -454,41 +454,41 @@ const config: K8sServiceConfig = {
454
454
  }
455
455
 
456
456
  export default config
457
- `}h();import U from"chalk";import lp from"terminal-link";var nt="integrations-run";import{z as P}from"zod";var pp=P.object({name:P.string(),description:P.string(),link:P.url().optional(),install:P.union([P.string(),P.array(P.string())]).transform(e=>Array.isArray(e)?e:[e]),installFlags:P.array(P.string()).optional(),run:P.array(P.string()).optional(),initial:P.boolean().optional(),interactive:P.boolean().optional()}),To=P.array(pp);var $o=e=>{try{return To.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
457
+ `}h();import U from"chalk";import mp from"terminal-link";var nt="integrations-run";import{z as P}from"zod";var lp=P.object({name:P.string(),description:P.string(),link:P.url().optional(),install:P.union([P.string(),P.array(P.string())]).transform(e=>Array.isArray(e)?e:[e]),installFlags:P.array(P.string()).optional(),run:P.array(P.string()).optional(),initial:P.boolean().optional(),interactive:P.boolean().optional()}),To=P.array(lp);var $o=e=>{try{return To.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
458
458
  `))}};var N=()=>{try{let e=he("bin/integration.collection.json");return $o(e)}catch(e){throw new Error(`Failed to load integrations!
459
459
  Check your integration.collection.json:
460
- ${e.message}`)}},te=()=>N().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),mp=e=>!!e?.name&&!!e?.link&&!!e?.description,ot=e=>{let t=N();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(mp);r.length&&(m.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=m.getStoredLogs(`${nt}:${n}`);o&&m.log(`${lp(U.cyan(n),o)} - ${s}`),i.length&&m.log(i.map(a=>` \u203A ${U.dim(a.message)}`).join(`
461
- `))}))},up=e=>e.toUpperCase().replace(/-/g,"_"),Ro=(e,t)=>{let r=up(e);m.breakLine().log(U.bold("Environment variables:")).log(U.dim(" Local (.env.local):")).log(U.cyan(` ${r}_PORT=${t}`)).breakLine().log(U.dim(" Production (auto-injected by infra):")).log(U.cyan(` PORT=${t}`))};h();import Io from"chalk";var dp=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},No=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=w(),task:o}=e;if(!t?.length||!o)return;let s=gp(t,r,n,o);await Me(o,s)},gp=(e,t,r,n)=>{let s=N()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:p,version:l}=dp(c);return{title:Io.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{We(`dependencies.${p}`,l,t)}}})),i={title:Io.cyanBright("Installing packages..."),fn:async()=>{await M({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};h();import fp from"chalk";var Ao=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=hp(t,r,n,e.packageManager);await Me(n,o)},hp=(e,t,r,n)=>N().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:fp.cyanBright(`Running "${i}" for ${s.name}
462
- `),fn:()=>yp(s,i,t,r,n)}))),yp=async(e,t,r,n,o)=>{let s=`${nt}:${e.name}`;try{if(e.interactive)return dn(t,[],{cwd:r,context:s,task:n,manager:o});await jt(t,[],{cwd:r,task:n,context:s})}catch(i){m.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};import{ListrEnquirerPromptAdapter as Se}from"@listr2/prompt-adapter-enquirer";var y=e=>({select:async t=>e.prompt(Se).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Se).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Se).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Se).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Se).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});h();import{readFileSync as oy}from"fs";import{join as iy}from"path";import hy from"chalk";import vy from"cli-table3";h();function st(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function Oo(e,t,r={},n=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=n.map(p=>t[p]).filter(p=>p!==void 0),i=o.map(p=>{let l=t[p];if(!(l===!1||l===void 0))return l===!0?`--${st(String(p))}`:`--${st(String(p))}=${String(l)}`}).filter(p=>p!==void 0),a=Object.entries(r).map(([p,l])=>{if(!(l===!1||l===void 0))return l===!0?`--${st(p)}`:`--${st(p)}=${String(l)}`}).filter(p=>p!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})}import{basename as Hp}from"path";import Go from"chalk";v();var re={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=y(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 lr,readdirSync as kp,readFileSync as Cp,writeFileSync as xp}from"fs";import{basename as wp,join as mr}from"path";var Pp=4001,bp=4e3;function Sp(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 Ep(e,t){let r=t?Pp:bp,n=new Set;if(!lr(e))return r;let o=kp(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=mr(e,i);try{let c=Cp(a,"utf-8"),p=Sp(c);for(let l of p)n.add(l)}catch{}}let s=r;for(;n.has(s);)s++;return s}function Tp(e){return wp(e)}var it={title:"Creating infrastructure service config",task:async(e,t)=>{let r=Tp(e.projectName),n=d(),o=mr(n,"infra","services");if(!lr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=mr(o,`${r}.ts`);if(lr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=Ep(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?So(r,i):Eo(r,i);xp(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as at}from"child_process";import{existsSync as $p}from"fs";import{join as Rp}from"path";var Ip=()=>{try{return at("git --version",{stdio:"ignore"}),!0}catch{return!1}},Np=e=>$p(Rp(e,".git")),_o={title:"Initializing git repository",enabled:()=>Ip(),skip:e=>Np(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{at("git init",{cwd:e.cwd,stdio:"ignore"}),at("git add -A",{cwd:e.cwd,stdio:"ignore"}),at('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 Do from"chalk";h();var ne={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Wt(),task:async(e,t)=>R(t,async r=>{await vn(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},oe={enabled:e=>!Wt()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=y(t);console.log(["",`${Do.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${Do.underline("https://bun.sh")}`,kn(),Cn()].join(`
463
- `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import Lo from"chalk";h();var ct={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>R(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await No({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},pt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=y(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:te().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[Lo.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=>Lo.bold(`\u2022 ${n}`))].join("\\n")}};h();var Mo={title:"Install Nest CLI",task:async(e,t)=>R(t,async r=>{await un({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};h();var lt={title:"Install dependencies",task:async(e,t)=>R(t,async r=>{await M({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import Ap from"chalk";h();var se={enabled:e=>!e.removeDir&&!De(e.cwd),task:async(e,t)=>{let r=y(t);if(e.removeDir=await r.toggle({message:Ap.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},ie={enabled:e=>!!e.removeDir,task:async e=>Vr(e.cwd)};h();var mt={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>R(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await Ao({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};h();var Op=["services/my-hono-service","services/my-nest-service","my-platform"],ae={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?Op.includes(e.projectName):!0,task:async(e,t)=>{let r=y(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=_(e.projectName))}};import jo from"chalk";var ce={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=Mt(),e.packageManager){t.title=`Using ${jo.bold(e.packageManager)} as package manager.`;return}let r=y(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:mn().map(n=>({name:n,value:n}))}),t.title=`Using ${jo.bold(e.packageManager)} as package manager.`}};import ut from"chalk";var Fo={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${ut.bold(e.githubOwner)}`;return}let r=y(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: ${ut.bold(e.githubOwner)}`}},Wo={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=y(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 Ho={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${ut.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=y(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: ${ut.bold(e.pulumiStackBase)}`}};h();import{mkdirSync as _p,writeFileSync as Dp}from"fs";import{dirname as Lp}from"path";h();var Mp=e=>e==="hono"?"hono":"nestjs",jp=e=>{let t=Lp(e.path);_p(t,{recursive:!0}),Dp(e.path,e.content,"utf-8")},Fp=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=tt(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
460
+ ${e.message}`)}},te=()=>N().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),up=e=>!!e?.name&&!!e?.link&&!!e?.description,ot=e=>{let t=N();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(up);r.length&&(m.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=m.getStoredLogs(`${nt}:${n}`);o&&m.log(`${mp(U.cyan(n),o)} - ${s}`),i.length&&m.log(i.map(a=>` \u203A ${U.dim(a.message)}`).join(`
461
+ `))}))},dp=e=>e.toUpperCase().replace(/-/g,"_"),Ro=(e,t)=>{let r=dp(e);m.breakLine().log(U.bold("Environment variables:")).log(U.dim(" Local (.env.local):")).log(U.cyan(` ${r}_PORT=${t}`)).breakLine().log(U.dim(" Production (auto-injected by infra):")).log(U.cyan(` PORT=${t}`))};h();import Io from"chalk";var gp=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},No=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=w(),task:o}=e;if(!t?.length||!o)return;let s=fp(t,r,n,o);await Me(o,s)},fp=(e,t,r,n)=>{let s=N()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:p,version:l}=gp(c);return{title:Io.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{We(`dependencies.${p}`,l,t)}}})),i={title:Io.cyanBright("Installing packages..."),fn:async()=>{await M({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};h();import hp from"chalk";var Oo=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=yp(t,r,n,e.packageManager);await Me(n,o)},yp=(e,t,r,n)=>N().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:hp.cyanBright(`Running "${i}" for ${s.name}
462
+ `),fn:()=>vp(s,i,t,r,n)}))),vp=async(e,t,r,n,o)=>{let s=`${nt}:${e.name}`;try{if(e.interactive)return dn(t,[],{cwd:r,context:s,task:n,manager:o});await jt(t,[],{cwd:r,task:n,context:s})}catch(i){m.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};import{ListrEnquirerPromptAdapter as Se}from"@listr2/prompt-adapter-enquirer";var y=e=>({select:async t=>e.prompt(Se).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Se).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Se).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Se).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Se).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});h();import{readFileSync as sy}from"fs";import{join as ay}from"path";import yy from"chalk";import ky from"cli-table3";h();function st(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function Ao(e,t,r={},n=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=n.map(p=>t[p]).filter(p=>p!==void 0),i=o.map(p=>{let l=t[p];if(!(l===!1||l===void 0))return l===!0?`--${st(String(p))}`:`--${st(String(p))}=${String(l)}`}).filter(p=>p!==void 0),a=Object.entries(r).map(([p,l])=>{if(!(l===!1||l===void 0))return l===!0?`--${st(p)}`:`--${st(p)}=${String(l)}`}).filter(p=>p!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})}import{basename as Bp}from"path";import Bo from"chalk";v();var re={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=y(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 lr,readdirSync as Cp,readFileSync as xp,writeFileSync as wp}from"fs";import{basename as Pp,join as mr}from"path";var bp=4001,Sp=4e3;function Ep(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 Tp(e,t){let r=t?bp:Sp,n=new Set;if(!lr(e))return r;let o=Cp(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=mr(e,i);try{let c=xp(a,"utf-8"),p=Ep(c);for(let l of p)n.add(l)}catch{}}let s=r;for(;n.has(s);)s++;return s}function $p(e){return Pp(e)}var it={title:"Creating infrastructure service config",task:async(e,t)=>{let r=$p(e.projectName),n=d(),o=mr(n,"infra","services");if(!lr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=mr(o,`${r}.ts`);if(lr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=Tp(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?So(r,i):Eo(r,i);wp(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as at}from"child_process";import{existsSync as Rp}from"fs";import{join as Ip}from"path";var Np=()=>{try{return at("git --version",{stdio:"ignore"}),!0}catch{return!1}},Op=e=>Rp(Ip(e,".git")),_o={title:"Initializing git repository",enabled:()=>Np(),skip:e=>Op(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{at("git init",{cwd:e.cwd,stdio:"ignore"}),at("git add -A",{cwd:e.cwd,stdio:"ignore"}),at('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 Do from"chalk";h();var ne={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Wt(),task:async(e,t)=>R(t,async r=>{await vn(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},oe={enabled:e=>!Wt()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=y(t);console.log(["",`${Do.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${Do.underline("https://bun.sh")}`,kn(),Cn()].join(`
463
+ `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import Lo from"chalk";h();var ct={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>R(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await No({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},pt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=y(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:te().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[Lo.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=>Lo.bold(`\u2022 ${n}`))].join("\\n")}};h();var Mo={title:"Install Nest CLI",task:async(e,t)=>R(t,async r=>{await un({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};h();var lt={title:"Install dependencies",task:async(e,t)=>R(t,async r=>{await M({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import Ap from"chalk";h();var se={enabled:e=>!e.removeDir&&!De(e.cwd),task:async(e,t)=>{let r=y(t);if(e.removeDir=await r.toggle({message:Ap.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},ie={enabled:e=>!!e.removeDir,task:async e=>Vr(e.cwd)};h();var mt={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>R(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await Oo({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};h();var _p=["services/my-hono-service","services/my-nest-service","my-platform"],ae={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?_p.includes(e.projectName):!0,task:async(e,t)=>{let r=y(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=_(e.projectName))}};import jo from"chalk";var ce={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=Mt(),e.packageManager){t.title=`Using ${jo.bold(e.packageManager)} as package manager.`;return}let r=y(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:mn().map(n=>({name:n,value:n}))}),t.title=`Using ${jo.bold(e.packageManager)} as package manager.`}};import ut from"chalk";var Fo={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${ut.bold(e.githubOwner)}`;return}let r=y(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: ${ut.bold(e.githubOwner)}`}},Wo={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=y(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 Ho={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${ut.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=y(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: ${ut.bold(e.pulumiStackBase)}`}};h();import{mkdirSync as Dp,writeFileSync as Lp}from"fs";import{dirname as Mp}from"path";h();var jp=e=>e==="hono"?"hono":"nestjs",Fp=e=>{let t=Mp(e.path);Dp(t,{recursive:!0}),Lp(e.path,e.content,"utf-8")},Wp=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=tt(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
464
464
  `);throw new Error(`Policy violation(s) detected:
465
- ${o}`)}e.forEach(jp)},Wp=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,p=ko({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),l=p.effects.filter(T=>T.kind==="file:write"),u=Mp(o);Fp(l,u),e.assignedPort=p.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${p.port}, ${e.elapsedTime}s)`},dt={title:"Generating service",task:async(e,t)=>R(t,async r=>{await Wp(e,t,r)})};var Bo=L({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup.",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"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:"platform new hono-micro my-service",buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${I().services}/${r}`);let n=_(r),o=t.packageManager??(t.yes&&w()),s=N(),i=t.yes?te():[],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:[ae,se,oe,ce,pt,re],actions:[ie,ne,dt,it,ct,mt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{m.breakLine().log(Go.bold.green("Hono Microservice created successfully!")),ot(r),Ro(Hp(e),n??8080);let o=t??w();m.breakLine().log(`To start the project, run:
466
- ${Go.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import Uo from"chalk";v();h();var Vo=L({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup.",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"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:"platform new nest-micro my-service",buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${I().services}/${r}`);let n=_(r),o=t.packageManager??(t.yes&&w()),s=t.packageManager==="bun",i=N(),a=t.yes?te():[],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:[ae,se,oe,ce,pt,re],actions:[ie,ne,dt,it,lt,Mo,ct,mt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{m.breakLine().log(Uo.bold.green("NestJS Microservice created successfully!")),ot(r),m.breakLine().log(`To start the project, run:
467
- ${Uo.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import A from"chalk";h();import{spawnSync as Up}from"child_process";import{chmodSync as Vp,existsSync as gr,mkdirSync as zp,readFileSync as Jp,writeFileSync as fr}from"fs";import{dirname as Kp,join as hr}from"path";import{existsSync as Gp}from"fs";import{join as gt}from"path";var Bp=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),dr=()=>{let e=Bp(),t=G();return Q([gt(e,"templates","workspace"),gt(e,"..","..","..","..","templates","workspace"),gt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},zo=()=>{let e=dr(),t=gt(e,"packages","contracts");if(!Gp(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},ft=(e,t)=>er(e,t);var Jo=e=>{e.endsWith(".sh")&&Vp(e,493)},qp=[{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}],Ko={title:"Creating workspace structure",task:async(e,t)=>{if(gr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=dr(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let u=Up(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(u&&/^\d+\.\d+/.test(u))return`${c}@${u}`}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=qp.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let p=hr(e.cwd,c.output),l=Kp(p);if(gr(l)||zp(l,{recursive:!0}),c.isStatic){let u=hr(r,c.template);gr(u)?fr(p,Jp(u)):fr(p,""),Jo(p)}else{let u=hr(r,c.template),T=ft(u,i);fr(p,T),Jo(p)}}t.title="Workspace structure created"}};import{spawnSync as Yp}from"child_process";import Zp from"chalk";var Xp=["bunx","@crossdelta/agent-kit","init"],Qp=([e,...t],r)=>{let n=Yp(e,t,{cwd:r,encoding:"utf-8"}),o=`${n.error?.message??""} ${n.stdout??""}${n.stderr??""}`.trim();return{exitCode:n.status??1,output:o}},el=(e,t=Qp)=>{let{exitCode:r,output:n}=t(Xp,e);if(r!==0)throw new Error(`agent-kit init failed (exit ${r}): ${n}`)},qo={title:"Installing agent skills and rules",task:(e,t)=>{try{el(e.cwd),t.title="Agent skills and rules installed"}catch(r){throw t.title=Zp.red(r.message),r}}};v();import{existsSync as Zo,mkdirSync as Yo,readFileSync as tl,writeFileSync as rl}from"fs";import{join as ht}from"path";import nl from"chalk";var ol=()=>{let e=ht(process.cwd(),"package.json");if(!Zo(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(tl(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},sl=()=>{let e=ol(),{relativePath:t,packagePath:r}=x();if(Zo(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=zo(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};Yo(r,{recursive:!0}),Yo(ht(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=ht(n,i.template),c=ht(r,i.output),p=ft(a,o);rl(c,p,"utf-8")}},Xo={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),sl(),t.title="Contracts package initialized"}catch(n){throw t.title=nl.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import il from"chalk";var Qo={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await xe(),t.title="Shell completion registered"}catch{t.title=il.dim("Shell completion skipped")}finally{process.chdir(r)}}};var es=L({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=_(r),o=!!t.yes,s=t.packageManager??(o?w():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),p=t.github===!1?!1:o?!0:void 0,l=!!e.name,u=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:l&&!o,removeDir:u,githubOwner:a,pulumiStackBase:c,includeGitHubCI:p}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=d();if(!await y(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=A.yellow("Warning: Creating nested workspace")}catch(r){if(Ie(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},ae,se,Fo,Wo,Ho,oe,ce,re],actions:[ie,ne,Ko,Xo,lt,qo,_o,Qo],onComplete:({projectName:e,includeGitHubCI:t})=>{m.breakLine().log(A.bold.green("Workspace created successfully!")),m.breakLine().log(A.bold("Next steps:")).log(` 1. ${A.cyan(`cd ${e}`)}`).log(` 2. ${A.cyan("exec $SHELL")} ${A.dim("(enable tab completion)")}`),t&&m.breakLine().log(A.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${A.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${A.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${A.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),m.breakLine().log(A.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&&m.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),m.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var yt=[{name:"Hono Microservice",value:"hono-micro",command:Bo},{name:"Nest Microservice",value:"nest-micro",command:Vo},{name:"Workspace (Infrastructure)",value:"workspace",command:es}],ts=()=>{let e=L({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??"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await y(r).select({message:"Select Project type",choices:yt});t.projectType=yt.find(s=>s.name===o)?.value||"",r.title=`Using ${pe.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{d(),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(`
468
- `);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=d();if(!await y(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=pe.yellow("Warning: Creating nested workspace")}catch(n){if(Ie(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 y(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${pe.dim(a)}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=_(t.servicePath);return!De(r)},task:async(t,r)=>{if(!await y(r).toggle({message:pe.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=pe.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await y(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=>{yt.find(s=>s.value===t.projectType)||e.error(pe.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),await Oo(r,t,n,o)}});for(let t of yt)e.addCommand(t.command);return e};import{Command as vl}from"commander";h();import{createHash as al}from"crypto";import{existsSync as V,readdirSync as rs,readFileSync as ns,unlinkSync as cl,writeFileSync as pl}from"fs";import{join as F}from"path";import ll from"chokidar";v();h();var ml=e=>{let t=F(e,"infra","services");if(!V(t))return[];let r=rs(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=I(e),o=a=>{let c=F(e,a);return V(c)?rs(c).filter(p=>V(F(c,p,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)cl(F(t,`${a}.ts`));return i},os=".install-hash",ss=e=>{let t=ns(e);return al("sha256").update(t).digest("hex")},ul=e=>{let t=F(e,"node_modules",os),r=F(e,"bun.lock");return!V(r)||!V(t)?!0:ns(t,"utf-8")!==ss(r)},dl=e=>{let t=F(e,"bun.lock"),r=F(e,"node_modules",os);V(t)&&pl(r,ss(t),"utf-8")},yr=async e=>{let t=ml(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),ul(e)&&(await M({cwd:e,quiet:!0}),dl(e)),await ye("generate-env",{cwd:e})},vr=async e=>{await xo()&&await pr(e)},is=e=>{let{eventsPath:t}=x(e);if(!V(t))return async()=>{};let r=J(async()=>{console.log(`
469
- \u{1F4E6} Contracts changed, updating streams...`),await pr(e)},500),n=ll.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};Ae();import cs from"chalk";v();le();var gl=["SIGINT","SIGTERM"],fl=[k.SUCCESS,k.GENERAL_ERROR,k.CANCELLED],hl=({code:e,signal:t})=>t?gl.includes(t)?k.SUCCESS:k.GENERAL_ERROR:e===null||fl.includes(e)?k.SUCCESS:e,as=e=>!e.isCurrentProcess||e.isRestarting||e.isShuttingDown?{action:"continue"}:{action:"shutdown",exitCode:hl(e)};var kr=e=>new Promise(t=>setTimeout(t,e)),ps=e=>process.stdout.write(`${e}
470
- `),yl=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},ls=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),ms=async(e,t,r,n)=>{let{dev:o}=fe(t),s=r.length>0?[...r]:o.filter,i=on(nn(".env.local",t),s,process.env.PORT);i.length>0&&(await pn(i),await kr(50));let a=s.flatMap(p=>["--filter",p]);ps(cs.cyan("\u{1F525} Starting services...")),ps(cs.dim(` Command: turbo run ${Pt} --continue${a.length?` ${a.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1;let c=sn("turbo",["run",Pt,"--continue","--no-daemon",...a],{cwd:t,envFile:".env.local",onExit:(p,l)=>{let u=as({code:p,signal:l,isRestarting:e.isRestarting,isShuttingDown:e.isShuttingDown,isCurrentProcess:e.turboProcess===c});u.action==="shutdown"&&n(u.exitCode)}});e.turboProcess=c},vt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await kr(200);try{process.kill(-t,"SIGKILL")}catch{}await kr(30)}catch{}e.turboProcess=null,yl()}};var us=new vl("dev").description("Start development mode with auto-reload").option("-f, --filter <packages...>","Only start these workspace packages (e.g. @orderboss/website). Overrides pf.dev.filter, and narrows the ports freed on start so a second worktree does not kill the first one.").action(async e=>{let t=e.filter??[],r;try{r=d()}catch(u){O(u);return}let n=ls(),o,s,i=async(u=k.SUCCESS)=>{n.isShuttingDown||(console.log(`
471
- \u{1F6D1} Shutting down...`),await vt(n),await Promise.all([o?.(),s?.()]),process.exit(u))},a=()=>ms(n,r,t,i),c=async()=>{await yr(r),await vr(r),await a()},l=J(async()=>{if(!(n.isRestarting||n.isShuttingDown)){n.isRestarting=!0,console.log(`
465
+ ${o}`)}e.forEach(Fp)},Hp=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,p=ko({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),l=p.effects.filter(T=>T.kind==="file:write"),u=jp(o);Wp(l,u),e.assignedPort=p.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${p.port}, ${e.elapsedTime}s)`},dt={title:"Generating service",task:async(e,t)=>R(t,async r=>{await Hp(e,t,r)})};var Go=L({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup.",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"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:"platform new hono-micro my-service",buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${I().services}/${r}`);let n=_(r),o=t.packageManager??(t.yes&&w()),s=N(),i=t.yes?te():[],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:[ae,se,oe,ce,pt,re],actions:[ie,ne,dt,it,ct,mt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{m.breakLine().log(Bo.bold.green("Hono Microservice created successfully!")),ot(r),Ro(Bp(e),n??8080);let o=t??w();m.breakLine().log(`To start the project, run:
466
+ ${Bo.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import Uo from"chalk";v();h();var Vo=L({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup.",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"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:"platform new nest-micro my-service",buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${I().services}/${r}`);let n=_(r),o=t.packageManager??(t.yes&&w()),s=t.packageManager==="bun",i=N(),a=t.yes?te():[],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:[ae,se,oe,ce,pt,re],actions:[ie,ne,dt,it,lt,Mo,ct,mt],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{m.breakLine().log(Uo.bold.green("NestJS Microservice created successfully!")),ot(r),m.breakLine().log(`To start the project, run:
467
+ ${Uo.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import O from"chalk";h();import{spawnSync as Vp}from"child_process";import{chmodSync as Jp,existsSync as gr,mkdirSync as zp,readFileSync as Kp,writeFileSync as fr}from"fs";import{dirname as qp,join as hr}from"path";import{existsSync as Gp}from"fs";import{join as gt}from"path";var Up=()=>typeof import.meta?.url=="string"?j(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),dr=()=>{let e=Up(),t=B();return Q([gt(e,"templates","workspace"),gt(e,"..","..","..","..","templates","workspace"),gt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},Jo=()=>{let e=dr(),t=gt(e,"packages","contracts");if(!Gp(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},ft=(e,t)=>er(e,t);var zo=e=>{e.endsWith(".sh")&&Jp(e,493)},Yp=[{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}],Ko={title:"Creating workspace structure",task:async(e,t)=>{if(gr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=dr(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let u=Vp(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(u&&/^\d+\.\d+/.test(u))return`${c}@${u}`}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=Yp.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let p=hr(e.cwd,c.output),l=qp(p);if(gr(l)||zp(l,{recursive:!0}),c.isStatic){let u=hr(r,c.template);gr(u)?fr(p,Kp(u)):fr(p,""),zo(p)}else{let u=hr(r,c.template),T=ft(u,i);fr(p,T),zo(p)}}t.title="Workspace structure created"}};v();import{existsSync as Yo,mkdirSync as qo,readFileSync as Zp,writeFileSync as Xp}from"fs";import{join as ht}from"path";import Qp from"chalk";var el=()=>{let e=ht(process.cwd(),"package.json");if(!Yo(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Zp(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},tl=()=>{let e=el(),{relativePath:t,packagePath:r}=x();if(Yo(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=Jo(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};qo(r,{recursive:!0}),qo(ht(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=ht(n,i.template),c=ht(r,i.output),p=ft(a,o);Xp(c,p,"utf-8")}},Zo={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),tl(),t.title="Contracts package initialized"}catch(n){throw t.title=Qp.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import{spawnSync as rl}from"child_process";import nl from"chalk";var ol=["bunx","jackherd","init"],sl=([e,...t],r)=>{let n=rl(e,t,{cwd:r,encoding:"utf-8"}),o=`${n.error?.message??""} ${n.stdout??""}${n.stderr??""}`.trim();return{exitCode:n.status??1,output:o}},il=(e,t=sl)=>{let{exitCode:r,output:n}=t(ol,e);if(r!==0)throw new Error(`jackherd init failed (exit ${r}): ${n}`)},Xo={title:"Installing agent skills and rules",task:(e,t)=>{try{il(e.cwd),t.title="Agent skills and rules installed"}catch(r){throw t.title=nl.red(r.message),r}}};import al from"chalk";var Qo={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await xe(),t.title="Shell completion registered"}catch{t.title=al.dim("Shell completion skipped")}finally{process.chdir(r)}}};var es=L({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=_(r),o=!!t.yes,s=t.packageManager??(o?w():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),p=t.github===!1?!1:o?!0:void 0,l=!!e.name,u=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:l&&!o,removeDir:u,githubOwner:a,pulumiStackBase:c,includeGitHubCI:p}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=d();if(!await y(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=O.yellow("Warning: Creating nested workspace")}catch(r){if(Ie(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},ae,se,Fo,Wo,Ho,oe,ce,re],actions:[ie,ne,Ko,Zo,lt,Xo,_o,Qo],onComplete:({projectName:e,includeGitHubCI:t})=>{m.breakLine().log(O.bold.green("Workspace created successfully!")),m.breakLine().log(O.bold("Next steps:")).log(` 1. ${O.cyan(`cd ${e}`)}`).log(` 2. ${O.cyan("exec $SHELL")} ${O.dim("(enable tab completion)")}`),t&&m.breakLine().log(O.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${O.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${O.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${O.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),m.breakLine().log(O.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&&m.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),m.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var yt=[{name:"Hono Microservice",value:"hono-micro",command:Go},{name:"Nest Microservice",value:"nest-micro",command:Vo},{name:"Workspace (Infrastructure)",value:"workspace",command:es}],ts=()=>{let e=L({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??"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await y(r).select({message:"Select Project type",choices:yt});t.projectType=yt.find(s=>s.name===o)?.value||"",r.title=`Using ${pe.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{d(),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(`
468
+ `);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=d();if(!await y(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=pe.yellow("Warning: Creating nested workspace")}catch(n){if(Ie(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 y(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${pe.dim(a)}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=_(t.servicePath);return!De(r)},task:async(t,r)=>{if(!await y(r).toggle({message:pe.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=pe.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await y(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=>{yt.find(s=>s.value===t.projectType)||e.error(pe.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),await Ao(r,t,n,o)}});for(let t of yt)e.addCommand(t.command);return e};import{Command as kl}from"commander";h();import{createHash as cl}from"crypto";import{existsSync as V,readdirSync as rs,readFileSync as ns,unlinkSync as pl,writeFileSync as ll}from"fs";import{join as F}from"path";import ml from"chokidar";v();h();var ul=e=>{let t=F(e,"infra","services");if(!V(t))return[];let r=rs(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=I(e),o=a=>{let c=F(e,a);return V(c)?rs(c).filter(p=>V(F(c,p,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)pl(F(t,`${a}.ts`));return i},os=".install-hash",ss=e=>{let t=ns(e);return cl("sha256").update(t).digest("hex")},dl=e=>{let t=F(e,"node_modules",os),r=F(e,"bun.lock");return!V(r)||!V(t)?!0:ns(t,"utf-8")!==ss(r)},gl=e=>{let t=F(e,"bun.lock"),r=F(e,"node_modules",os);V(t)&&ll(r,ss(t),"utf-8")},yr=async e=>{let t=ul(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),dl(e)&&(await M({cwd:e,quiet:!0}),gl(e)),await ye("generate-env",{cwd:e})},vr=async e=>{await xo()&&await pr(e)},is=e=>{let{eventsPath:t}=x(e);if(!V(t))return async()=>{};let r=z(async()=>{console.log(`
469
+ \u{1F4E6} Contracts changed, updating streams...`),await pr(e)},500),n=ml.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};Oe();import cs from"chalk";v();le();var fl=["SIGINT","SIGTERM"],hl=[k.SUCCESS,k.GENERAL_ERROR,k.CANCELLED],yl=({code:e,signal:t})=>t?fl.includes(t)?k.SUCCESS:k.GENERAL_ERROR:e===null||hl.includes(e)?k.SUCCESS:e,as=e=>!e.isCurrentProcess||e.isRestarting||e.isShuttingDown?{action:"continue"}:{action:"shutdown",exitCode:yl(e)};var kr=e=>new Promise(t=>setTimeout(t,e)),ps=e=>process.stdout.write(`${e}
470
+ `),vl=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},ls=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),ms=async(e,t,r,n)=>{let{dev:o}=fe(t),s=r.length>0?[...r]:o.filter,i=on(nn(".env.local",t),s,process.env.PORT);i.length>0&&(await pn(i),await kr(50));let a=s.flatMap(p=>["--filter",p]);ps(cs.cyan("\u{1F525} Starting services...")),ps(cs.dim(` Command: turbo run ${Pt} --continue${a.length?` ${a.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1;let c=sn("turbo",["run",Pt,"--continue","--no-daemon",...a],{cwd:t,envFile:".env.local",onExit:(p,l)=>{let u=as({code:p,signal:l,isRestarting:e.isRestarting,isShuttingDown:e.isShuttingDown,isCurrentProcess:e.turboProcess===c});u.action==="shutdown"&&n(u.exitCode)}});e.turboProcess=c},vt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await kr(200);try{process.kill(-t,"SIGKILL")}catch{}await kr(30)}catch{}e.turboProcess=null,vl()}};var us=new kl("dev").description("Start development mode with auto-reload").option("-f, --filter <packages...>","Only start these workspace packages (e.g. @orderboss/website). Overrides pf.dev.filter, and narrows the ports freed on start so a second worktree does not kill the first one.").action(async e=>{let t=e.filter??[],r;try{r=d()}catch(u){A(u);return}let n=ls(),o,s,i=async(u=k.SUCCESS)=>{n.isShuttingDown||(console.log(`
471
+ \u{1F6D1} Shutting down...`),await vt(n),await Promise.all([o?.(),s?.()]),process.exit(u))},a=()=>ms(n,r,t,i),c=async()=>{await yr(r),await vr(r),await a()},l=z(async()=>{if(!(n.isRestarting||n.isShuttingDown)){n.isRestarting=!0,console.log(`
472
472
  \u{1F504} Change detected, restarting...
473
- `);try{await vt(n),await yr(r),await vr(r),await a()}catch(u){O(u)}finally{n.isRestarting=!1}}},300);process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",()=>i()),process.on("SIGTERM",()=>i());try{await c(),o=Dr(r,l),s=is(r),console.log(`
473
+ `);try{await vt(n),await yr(r),await vr(r),await a()}catch(u){A(u)}finally{n.isRestarting=!1}}},300);process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",()=>i()),process.on("SIGTERM",()=>i());try{await c(),o=Dr(r,l),s=is(r),console.log(`
474
474
  \u{1F440} Watching for changes...`),console.log(` Press Ctrl+C to exit
475
- `)}catch(u){await Promise.all([o?.(),s?.()]),await vt(n),O(u)}});import hs from"chalk";import{Command as Nl}from"commander";import{existsSync as kl,readFileSync as Cl,writeFileSync as xl}from"fs";import wl from"os";import ds from"path";import Cr from"chalk";import{Command as Pl}from"commander";h();var{name:bl,publishConfig:Sl}=E,El=Sl?.registry,Tl=bl?.split("/")[0],EC=new Pl("token:set").description(Cr.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)",Tl).option("--registry <registry>","Registry URL",El).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)=>gs(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${Cr.cyan(`
475
+ `)}catch(u){await Promise.all([o?.(),s?.()]),await vt(n),A(u)}});import hs from"chalk";import{Command as Ol}from"commander";import{existsSync as Cl,readFileSync as xl,writeFileSync as wl}from"fs";import Pl from"os";import ds from"path";import Cr from"chalk";import{Command as bl}from"commander";h();var{name:Sl,publishConfig:El}=E,Tl=El?.registry,$l=Sl?.split("/")[0],TC=new bl("token:set").description(Cr.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)",$l).option("--registry <registry>","Registry URL",Tl).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)=>gs(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${Cr.cyan(`
476
476
  Example:`)}
477
477
  ${Cr.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
478
- `),$l=e=>e?ds.join(process.cwd(),".npmrc"):ds.join(wl.homedir(),".npmrc"),Rl=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
479
- //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Il=e=>kl(e)?Cl(e,"utf8"):"",xr=(e,t)=>xl(e,t),gs=(e,t,r,n=!1,o=!1)=>{let s=$l(n),i=Rl(e,t,r),a=new URL(r).host,c=Il(s),p=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){xr(s,`${i}
478
+ `),Rl=e=>e?ds.join(process.cwd(),".npmrc"):ds.join(Pl.homedir(),".npmrc"),Il=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
479
+ //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Nl=e=>Cl(e)?xl(e,"utf8"):"",xr=(e,t)=>wl(e,t),gs=(e,t,r,n=!1,o=!1)=>{let s=Rl(n),i=Il(e,t,r),a=new URL(r).host,c=Nl(s),p=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){xr(s,`${i}
480
480
  `),m.success(`Created new .npmrc and set token for ${a}`);return}if(p.test(c)){if(!o){m.warn(`Token for ${a} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(p,i),xr(s,c),m.success(`Overwrote existing token for ${a} in ${s}`);return}c+=`
481
481
  ${i}
482
- `,xr(s,c),m.success(`Appended token for ${a} to ${s}`)},fs=(e,t)=>gs(e,t.scope||"",t.registry||"",t.local,t.force);var{name:Al,publishConfig:Ol}=E,_l=Ol?.registry,Dl=Al?.split("/")[0],wr=new Nl("token").description("Token management commands");wr.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)",Dl).option("--registry <registry>","Registry URL",_l).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(fs).addHelpText("after",()=>`${hs.cyan(`
482
+ `,xr(s,c),m.success(`Appended token for ${a} to ${s}`)},fs=(e,t)=>gs(e,t.scope||"",t.registry||"",t.local,t.force);var{name:Al,publishConfig:_l}=E,Dl=_l?.registry,Ll=Al?.split("/")[0],wr=new Ol("token").description("Token management commands");wr.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)",Ll).option("--registry <registry>","Registry URL",Dl).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(fs).addHelpText("after",()=>`${hs.cyan(`
483
483
  Example:`)}
484
484
  ${hs.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
485
- `);wr.action(()=>{let e=q({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 ys=wr;import br from"chalk";import{Command as Ml}from"commander";v();Ae();var DC={DEBUG:process.env.PF_DEBUG==="true"};import{existsSync as FC,readFileSync as WC}from"fs";import{homedir as GC}from"os";import{join as UC}from"path";var Pr=async(e,t=!1)=>{try{return Jt(e,t),await xe({verbose:t}),!0}catch{return!1}};var kt=e=>{let t=new Ml("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
485
+ `);wr.action(()=>{let e=q({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 ys=wr;import br from"chalk";import{Command as jl}from"commander";v();Oe();var LC={DEBUG:process.env.PF_DEBUG==="true"};import{existsSync as WC,readFileSync as HC}from"fs";import{homedir as GC}from"os";import{join as VC}from"path";var Pr=async(e,t=!1)=>{try{return zt(e,t),await xe({verbose:t}),!0}catch{return!1}};var kt=e=>{let t=new jl("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
486
486
  Examples:
487
487
  $ pf setup completion
488
488
  $ pf setup completion --verbose
489
489
  `).action(async r=>{await Pr(e,r.verbose),r.verbose||(console.log(br.green(`
490
490
  \u2714 Shell autocompletion installed!`)),console.log(br.dim(` Restart your shell:
491
491
  `)),console.log(br.cyan(` exec $SHELL
492
- `)))}),t.action(()=>{let r=q({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},jl=kt("pf");z();v();import Wl from"chalk";import{Command as ks}from"commander";import vs from"chalk";var Fl=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(vs.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(vs.red(` ${t}`))}),Sr=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:Fl(s)};Xt(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let p of c)console.log(p)}return{effects:a,output:i?.output}};var Hl=e=>e.required?`<${e.name}>`:`[${e.name}]`,Gl=(e,t)=>{e.argument(Hl(t),t.description)},Bl=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},Ul=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),Vl=e=>e[e.length-2],zl=(e,t)=>async(...r)=>{try{await Sr({command:e,args:Ul(e,r),options:Vl(r),context:t})}catch(n){console.error(Wl.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Cs=(e,t)=>{let r=new ks(e.name).description(e.description);return e.args.forEach(n=>{Gl(r,n)}),e.options.forEach(n=>{Bl(r,n)}),r.action(zl(e,t)),r},Er=(e,t,r,n)=>{let o=new ks(e).description(t);return r.forEach(s=>{o.addCommand(Cs(s,n))}),o};Je();process.on("SIGINT",()=>{process.exit(k.CANCELLED)});process.on("unhandledRejection",e=>{throw Ne(e)&&process.exit(k.CANCELLED),e});process.on("uncaughtException",e=>{O(e)});var Ee=new Kl,xs=Object.keys(E.bin||{}),[$r="pf",Tr]=xs.length>0?xs:["pf"],{description:ws,version:Yl,repository:Ps,homepage:Zl}=E,bs=ws?.split(/ —|,|\./)[0]||ws||"Platform CLI",Es=Ps?.url?`https://${Ps.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Ss=Es||Zl,Xl=Es?"GitHub":"README",Ql=Ss?[Te.bold(bs),`
492
+ `)))}),t.action(()=>{let r=q({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},Fl=kt("pf");J();v();import Hl from"chalk";import{Command as ks}from"commander";import vs from"chalk";var Wl=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(vs.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(vs.red(` ${t}`))}),Sr=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:Wl(s)};Xt(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let p of c)console.log(p)}return{effects:a,output:i?.output}};var Bl=e=>e.required?`<${e.name}>`:`[${e.name}]`,Gl=(e,t)=>{e.argument(Bl(t),t.description)},Ul=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},Vl=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),Jl=e=>e[e.length-2],zl=(e,t)=>async(...r)=>{try{await Sr({command:e,args:Vl(e,r),options:Jl(r),context:t})}catch(n){console.error(Hl.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Cs=(e,t)=>{let r=new ks(e.name).description(e.description);return e.args.forEach(n=>{Gl(r,n)}),e.options.forEach(n=>{Ul(r,n)}),r.action(zl(e,t)),r},Er=(e,t,r,n)=>{let o=new ks(e).description(t);return r.forEach(s=>{o.addCommand(Cs(s,n))}),o};ze();process.on("SIGINT",()=>{process.exit(k.CANCELLED)});process.on("unhandledRejection",e=>{throw Ne(e)&&process.exit(k.CANCELLED),e});process.on("uncaughtException",e=>{A(e)});var Ee=new ql,xs=Object.keys(E.bin||{}),[$r="pf",Tr]=xs.length>0?xs:["pf"],{description:ws,version:Zl,repository:Ps,homepage:Xl}=E,bs=ws?.split(/ —|,|\./)[0]||ws||"Platform CLI",Es=Ps?.url?`https://${Ps.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Ss=Es||Xl,Ql=Es?"GitHub":"README",em=Ss?[Te.bold(bs),`
493
493
 
494
- `,Te.cyan("See more at: "),Te.bold(ql(Xl,String(Ss)))].join(""):Te.bold(bs),em=[kt($r),ts(),us,ys,hn],tm=async()=>{try{let e=d(),t=fe(e);if(!t.plugins?.length)return[];let r=x(e),n=Ke({workspaceRoot:e,availableServices:He(e),contracts:{path:`${r.relativePath}/src`,packageName:r.packageName}}),o=[];for(let s of t.plugins)try{let{plugin:i}=await qe(s,n),a=Er(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[]}},rm=async()=>{let e=await tm(),t=[...em,...e];Ee.name($r).description(Ql).version(Yl||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Te.cyan(r.name())}).addHelpText("after",wn),Tr&&Tr!==$r&&Ee.alias(Tr);for(let r of t)Ee.addCommand(r);Ee.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)}),Pn(Ee,Jl,t)};rm();
494
+ `,Te.cyan("See more at: "),Te.bold(Yl(Ql,String(Ss)))].join(""):Te.bold(bs),tm=[kt($r),ts(),us,ys,hn],rm=async()=>{try{let e=d(),t=fe(e);if(!t.plugins?.length)return[];let r=x(e),n=Ke({workspaceRoot:e,availableServices:He(e),contracts:{path:`${r.relativePath}/src`,packageName:r.packageName}}),o=[];for(let s of t.plugins)try{let{plugin:i}=await qe(s,n),a=Er(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[]}},nm=async()=>{let e=await rm(),t=[...tm,...e];Ee.name($r).description(em).version(Zl||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Te.cyan(r.name())}).addHelpText("after",wn),Tr&&Tr!==$r&&Ee.alias(Tr);for(let r of t)Ee.addCommand(r);Ee.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)}),Pn(Ee,Kl,t)};nm();
@@ -295,6 +295,20 @@ jobs:
295
295
  pattern: changed-*
296
296
  path: .artifacts
297
297
 
298
+ # download-artifact puts each matching artifact into its own `changed-<scope>/` directory only
299
+ # when it matches several. A single match is extracted straight into `.artifacts/`, where no
300
+ # later step looks for it: the scope's image tag then came from GHCR instead of its marker, and
301
+ # the Studio smoke check and client broadcast were skipped (stage run 38151120673, 11.10.2026).
302
+ - name: Normalize change marker layout
303
+ run: |
304
+ if [ -f .artifacts/metadata.json ]; then
305
+ SHORT=$(jq -er '.shortName' .artifacts/metadata.json)
306
+ mkdir -p ".artifacts/changed-${SHORT}"
307
+ for marker_file in metadata.json scope.txt; do
308
+ if [ -f ".artifacts/${marker_file}" ]; then mv ".artifacts/${marker_file}" ".artifacts/changed-${SHORT}/"; fi
309
+ done
310
+ fi
311
+
298
312
  - name: Resolve scope image tags
299
313
  id: resolve_scope_tags
300
314
  shell: bash
@@ -371,6 +385,7 @@ jobs:
371
385
  # mid-update: DigitalOcean finishes the resize server-side anyway, while Pulumi never writes
372
386
  # the result back and leaves a stack lock and a pending operation behind.
373
387
  - name: Pulumi up
388
+ id: pulumi-up
374
389
  uses: pulumi/actions@v7
375
390
  timeout-minutes: 15
376
391
  with:
@@ -417,3 +432,8 @@ jobs:
417
432
  done
418
433
  curl "${curl_opts[@]}" "${STUDIO_URL}/health" || exit 1
419
434
 
435
+ # The topic carries no `realtime:` prefix: the REST endpoint adds it, and a client subscribed to
436
+ # `system:deploy` listens on `realtime:system:deploy`. With the prefix spelled out the message
437
+ # went to `realtime:realtime:system:deploy`, a channel nobody listened on (listener log, stage,
438
+ # 11.10.2026). `-f` makes a refused broadcast fail the command, so the warning below can fire.
439
+
@@ -26,6 +26,14 @@ jobs:
26
26
  - name: Run Linter
27
27
  run: bun run --if-present lint
28
28
 
29
+ - name: Component manifest
30
+ run: |
31
+ git fetch --depth=1 origin main
32
+ bun run --if-present manifest:check
33
+
34
+ - name: Pattern manifest
35
+ run: bun run --if-present patterns:check
36
+
29
37
  test:
30
38
  runs-on: ubuntu-latest
31
39
  env:
@@ -16,9 +16,9 @@ on:
16
16
  default: all
17
17
  required: true
18
18
 
19
+ # id-token: write only where it is used: the publish job sets it itself.
19
20
  permissions:
20
21
  contents: read
21
- id-token: write
22
22
 
23
23
  jobs:
24
24
  determine-packages:
@@ -211,6 +211,25 @@ jobs:
211
211
  fi
212
212
  echo "✅ Workspace template complete"
213
213
 
214
+ # The kit is published for other people's repositories: nothing of this one may ride along. The check packs
215
+ # the package as npm receives it and scans every text file against the kit's built-in patterns.
216
+ - name: Setup Bun for the leak check
217
+ if: matrix.package.name == 'jackherd' || matrix.package.name == '@crossdelta/agent-kit'
218
+ # Pinned to a commit: this job holds id-token: write, which npm Trusted Publishing accepts.
219
+ uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
220
+ with:
221
+ bun-version-file: package.json
222
+
223
+ - name: Leak check on the jackherd tarball
224
+ if: matrix.package.name == 'jackherd'
225
+ working-directory: ${{ matrix.package.dir }}
226
+ run: bun scripts/check-package-leaks.ts
227
+
228
+ - name: Leak check on the agent-kit shell tarball
229
+ if: matrix.package.name == '@crossdelta/agent-kit'
230
+ working-directory: ${{ matrix.package.dir }}
231
+ run: bun ../jackherd/scripts/check-package-leaks.ts .
232
+
214
233
  - name: Publish to npm
215
234
  working-directory: ${{ matrix.package.dir }}
216
235
  run: |
@@ -52,9 +52,9 @@ regardless of which file is open, because that cost is paid on every turn.
52
52
  Code style and testing conventions are not rules here: the `pf` generators carry their own, and they
53
53
  load whenever the generator writes code.
54
54
 
55
- ## Agent Kit
55
+ ## jackherd
56
56
 
57
- Skills, agents and general rules under `.claude/` come from `@crossdelta/agent-kit` and are listed in `.claude/agent-kit.lock.json`. Project values (languages, plan directory, models, checks) live in `.claude/agent-kit.json`. Update with `pf agents sync`; a conflicting local edit lands as `<file>.kit-new`. Put project knowledge into `.claude/project/<skill>.md` or a rule beside `.claude/rules/kit/`, so the kit files stay updatable. `pf plans` shows the plan progress of the current sprint.
57
+ Skills, agents and general rules under `.claude/` come from `jackherd` and are listed in `.jackherd/lock.json`. Project values (languages, plan directory, models, checks) live in `.jackherd/config.json`. Update with `pf agents sync`; a conflicting local edit lands as `<file>.kit-new`. Put project knowledge into `.claude/project/<skill>.md` or a rule beside `.claude/rules/kit/`, so the kit files stay updatable. `pf plans` shows the plan progress of the current sprint.
58
58
 
59
59
  ## Key Packages
60
60
 
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@crossdelta/cloudevents": "^0.10.0",
11
- "@crossdelta/infrastructure": "^0.16.0",
11
+ "@crossdelta/infrastructure": "^0.18.1",
12
12
  "{{scope}}/contracts": "workspace:*",
13
13
  "@pulumi/digitalocean": "^4.55.0",
14
14
  "@pulumi/kubernetes": "^4.21.0",
@@ -19,11 +19,11 @@
19
19
  "cwd": "infra"
20
20
  },
21
21
  "agents": {
22
- "command": "bunx @crossdelta/agent-kit",
23
- "description": "Agent kit: init, sync, check, plans"
22
+ "command": "bunx jackherd",
23
+ "description": "jackherd: init, sync, check, plans"
24
24
  },
25
25
  "plans": {
26
- "command": "bunx @crossdelta/agent-kit plans",
26
+ "command": "bunx jackherd plans",
27
27
  "description": "Live view of the sprint's lanes and their plan progress"
28
28
  }
29
29
  },
@@ -51,9 +51,9 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@biomejs/biome": "2.3.7",
54
- "@crossdelta/agent-kit": "latest",
55
54
  "@crossdelta/platform-sdk": "latest",
56
55
  "dotenv-cli": "^8.0.0",
56
+ "jackherd": "latest",
57
57
  "turbo": "^2.5.6"
58
58
  },
59
59
  "packageManager": "{{packageManagerVersion}}",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@crossdelta/cloudevents": "^0.10.0",
23
- "@crossdelta/infrastructure": "^0.16.0",
23
+ "@crossdelta/infrastructure": "^0.18.1",
24
24
  "zod": "^4.0.0"
25
25
  },
26
26
  "devDependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.26.0",
3
+ "version": "0.26.1",
4
4
  "description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
5
5
  "keywords": [
6
6
  "cli",
@@ -88,7 +88,6 @@
88
88
  "chokidar": "^5.0.0",
89
89
  "cli-table3": "^0.6.5",
90
90
  "commander": "^13.1.0",
91
- "dotenv": "^17.2.3",
92
91
  "enquirer": "^2.4.1",
93
92
  "execa": "^9.5.2",
94
93
  "fs-extra": "^11.3.0",
@@ -100,7 +99,7 @@
100
99
  "rimraf": "^6.1.2",
101
100
  "terminal-link": "^4.0.0",
102
101
  "zod": "^4.0.0",
103
- "@crossdelta/infrastructure": "^0.16.0"
102
+ "@crossdelta/infrastructure": "^0.18.1"
104
103
  },
105
104
  "peerDependencies": {
106
105
  "@nestjs/schematics": "^11.0.5",