@crossdelta/platform-sdk 0.19.0 → 0.19.3

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.
Files changed (46) hide show
  1. package/README.md +27 -5
  2. package/bin/chunk-634PL24Z.mjs +20 -0
  3. package/bin/cli.mjs +604 -0
  4. package/bin/config-CKQHYOF4.mjs +2 -0
  5. package/bin/docs/generators/code-style.md +79 -0
  6. package/bin/docs/generators/natural-language.md +117 -0
  7. package/bin/docs/generators/service.md +129 -60
  8. package/bin/templates/hono-microservice/Dockerfile.hbs +3 -1
  9. package/bin/templates/hono-microservice/src/config/env.ts.hbs +3 -0
  10. package/bin/templates/nest-microservice/Dockerfile.hbs +6 -2
  11. package/bin/templates/nest-microservice/src/config/env.ts.hbs +17 -0
  12. package/bin/templates/nest-microservice/src/main.ts.hbs +2 -1
  13. package/bin/templates/workspace/.github/actions/prepare-build-context/action.yml +58 -6
  14. package/bin/templates/workspace/.github/workflows/build-and-deploy.yml.hbs +25 -3
  15. package/bin/templates/workspace/.github/workflows/publish-packages.yml +6 -8
  16. package/bin/templates/workspace/biome.json.hbs +4 -1
  17. package/bin/templates/workspace/infra/package.json.hbs +2 -2
  18. package/bin/templates/workspace/package.json.hbs +1 -0
  19. package/bin/templates/workspace/packages/contracts/README.md.hbs +5 -5
  20. package/bin/templates/workspace/packages/contracts/package.json.hbs +15 -6
  21. package/bin/templates/workspace/packages/contracts/src/index.ts +1 -1
  22. package/bin/templates/workspace/packages/contracts/tsconfig.json.hbs +6 -1
  23. package/bin/templates/workspace/turbo.json +8 -11
  24. package/bin/templates/workspace/turbo.json.hbs +6 -5
  25. package/dist/facade.d.mts +840 -0
  26. package/dist/facade.d.ts +840 -0
  27. package/dist/facade.js +2294 -0
  28. package/dist/facade.js.map +1 -0
  29. package/dist/facade.mjs +2221 -0
  30. package/dist/facade.mjs.map +1 -0
  31. package/dist/plugin-types-DQOv97Zh.d.mts +180 -0
  32. package/dist/plugin-types-DQOv97Zh.d.ts +180 -0
  33. package/dist/plugin-types.d.mts +1 -0
  34. package/dist/plugin-types.d.ts +1 -0
  35. package/dist/plugin-types.js +19 -0
  36. package/dist/plugin-types.js.map +1 -0
  37. package/dist/plugin-types.mjs +1 -0
  38. package/dist/plugin-types.mjs.map +1 -0
  39. package/dist/plugin.d.mts +31 -0
  40. package/dist/plugin.d.ts +31 -0
  41. package/dist/plugin.js +105 -0
  42. package/dist/plugin.js.map +1 -0
  43. package/dist/plugin.mjs +75 -0
  44. package/dist/plugin.mjs.map +1 -0
  45. package/package.json +118 -99
  46. package/bin/cli.js +0 -540
package/bin/cli.mjs ADDED
@@ -0,0 +1,604 @@
1
+ #!/usr/bin/env node
2
+ import{A as Ur,C as Tt,D as Et,F as I,G as ue,H as $t,a as Or,b as T,c as Y,d as _r,e as Lr,f as A,g as wt,h as bt,i as Wr,j as Hr,k as W,l as Re,m as Ne,n as E,o as Gr,p as Fe,q as Br,r as d,s as $,t as Me,v as h,w as B,x as S,y as De,z as C}from"./chunk-634PL24Z.mjs";import{argv as Td}from"process";import Ae from"chalk";import{Command as Ed}from"commander";import $d from"terminal-link";import mi from"chalk";import{Command as di}from"commander";import{existsSync as si}from"fs";import{join as ii}from"path";import{cwd as qr}from"process";import{execaSync as ai}from"execa";import{spawn as Vr}from"child_process";import{resolve as Xs}from"path";import{execa as Qs}from"execa";import{existsSync as qs}from"fs";import{resolve as Ys}from"path";import{config as Zs}from"dotenv";var It=(e,t)=>{let r=Ys(t,e);return qs(r)?Zs({path:r,processEnv:{}}).parsed||{}:{}},zr=(e,t)=>{let r=It(e,t),n=[];for(let[o,s]of Object.entries(r))if(o.endsWith("_PORT")&&s){let i=Number.parseInt(s,10);!Number.isNaN(i)&&i>0&&n.push(i)}return n};var At={...process.env,NODE_NO_WARNINGS:"1"},ei=(e,t,r)=>e?"pipe":t||r?["ignore","pipe","pipe"]:"inherit",ti=(e,t,r)=>e?{...At,...e}:t||r?{...At,CI:"true"}:{...At},ri=e=>e.includes("EEXIST")||e.includes("failed to link package");async function H(e,t,{cwd:r=process.cwd(),task:n,shell:o,context:s=e,quiet:i=!1,nonInteractive:a=!1,env:c}={}){try{t.length===0&&(t=e.split(" ").slice(1));let l=Qs(e,t,{cwd:r,stdio:ei(i,n,a),all:n||a?!0:void 0,shell:o??!0,env:ti(c,n,a)});l.all&&l.all.on("data",p=>{let m=p.toString().trim();n?(n.output=m,m.length&&d.storeLog(m,s)):a&&m.length&&console.log(m)}),await l}catch(l){let p=l instanceof Error?l.message:String(l);if(ri(p))return;throw new Error(ni(p))}}var ni=e=>{let t=e.match(/error: (.+)/);return t?t[1].trim():e};function Kr(e,t,r={}){let{cwd:n=process.cwd(),envFile:o,detached:s=!0,pipeStdout:i=!1,onStdout:a,onStderr:c,onExit:l}=r,p=o?It(o,n):{},m=Xs(n,"node_modules",".bin"),f=process.env.PATH||"",F=`${m}:${f}`,ge={...process.env,...p,PATH:F,FORCE_COLOR:"1"},b=Vr(e,t,{cwd:n,env:ge,stdio:["inherit",i?"pipe":"inherit","pipe"],detached:s});return a&&i&&b.stdout?.on("data",a),c&&b.stderr?.on("data",c),l&&b.on("exit",l),b}function je(e,t,r={}){let{cwd:n=process.cwd()}=r;Vr(e,t,{cwd:n,stdio:"inherit",shell:!0}).on("exit",s=>process.exit(s||0))}async function Jr(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(`
3
+ `).filter(Boolean);for(let s of o)try{process.kill(Number.parseInt(s,10),"SIGKILL")}catch{}}catch{}}var Oe=e=>Ne(e);function Rt(e=process.cwd()){let t=r=>si(ii(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 x(e){return Rt(e)??ci()}function ci(){return Oe("bun")?"bun":Oe("pnpm")?"pnpm":Oe("yarn")?"yarn":"npm"}function Yr(){return["bun","pnpm","yarn","npm"].filter(Oe)}async function M(e,t){let r=li(e,t),{mergedOptions:n,packages:o}=r,{cwd:s=process.cwd(),flags:i=[],task:a,quiet:c}=n,l=n.packageManager??x(),p=[],m=Array.isArray(o)?o:[o];l==="bun"&&(m=m.map(F=>F.replace("git+ssh://",""))),l==="pnpm"&&(p.push("--config.engine-strict=false"),p.push("--no-frozen-lockfile")),["yarn","npm"].includes(l)&&p.push("--ignore-engines");let f=m.length?l==="npm"?["install",...i,...p,...m]:["add",...i,...p,...m]:["install",...i,...p];await H(l,f,{cwd:s,task:a,quiet:c})}async function Zr(e){let t=["-g"],r=[...e.flags??[],...t];await M({...e,flags:r,packageManager:e.packageManager??x()})}function Xr(e,t,r){let{args:n,mergedOptions:o}=en(t??[],r),s=o.manager??x(),{command:i,args:a}=Qr(s);console.log(`
4
+ Running command: ${i} ${[...a,e,...n].join(" ")}
5
+ `),ai(i,[...a,e,...n],{cwd:o.cwd??qr(),stdio:"inherit",preferLocal:!0})}async function fe(e,t,r){let{args:n,mergedOptions:o}=en(t??[],r),s=o.manager??x(),{command:i,args:a}=Qr(s);await H(i,[...a,e,...n],o)}async function he(e,t){let{script:r,mergedOptions:n}=pi(e,t),o=n.packageManager??x();await H(o,["run",r,...n.args??[]],{cwd:n.cwd??qr(),task:n.task})}function Qr(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 li(e,t){return Array.isArray(e)?{packages:e,mergedOptions:{...t,packages:e}}:{packages:e.packages??[],mergedOptions:e}}function en(e,t){return Array.isArray(e)?{args:e,mergedOptions:t??{}}:{args:[],mergedOptions:e}}function pi(e,t){return typeof e=="string"?{script:e,mergedOptions:t??{}}:{script:e.script,mergedOptions:e}}var gi=e=>e==="yarn"?["npm","audit"]:["audit"],tn=new di("audit").description("Run security audit on dependencies").allowUnknownOption(!0).action((e,t)=>{try{let r=h(),n=x(),o=gi(n),s=t.args||[];console.log(mi.dim(`Running ${n} ${[...o,...s].join(" ")}`)),je(n,[...o,...s],{cwd:r})}catch(r){A(r)}});import G from"chalk";import{existsSync as Ei,readFileSync as $i,writeFileSync as Ii}from"fs";import{homedir as Ai}from"os";import{join as Ri}from"path";import{createCipheriv as ui,createDecipheriv as fi,createHash as hi,randomBytes as yi}from"crypto";import{existsSync as vi,readFileSync as Ci,writeFileSync as ki}from"fs";import{homedir as rn,hostname as xi,userInfo as Pi}from"os";import{join as Si}from"path";var Nt=Si(rn(),".platform-sdk-keys"),nn="aes-256-gcm",on=()=>{let e=`${xi()}:${Pi().username}:${rn()}`;return hi("sha256").update(e).digest()},sn=()=>{if(!vi(Nt))return{};try{return JSON.parse(Ci(Nt,"utf-8"))}catch{return{}}},wi=e=>{ki(Nt,JSON.stringify(e,null,2),{mode:384})},bi=e=>{let t=on(),r=yi(16),n=ui(nn,t,r),o=n.update(e,"utf8","hex");return o+=n.final("hex"),{iv:r.toString("hex"),tag:n.getAuthTag().toString("hex"),data:o}},Ti=e=>{let t=on(),r=Buffer.from(e.iv,"hex"),n=Buffer.from(e.tag,"hex"),o=fi(nn,t,r);o.setAuthTag(n);let s=o.update(e.data,"hex","utf8");return s+=o.final("utf8"),s};async function an(e,t){let r=sn();r[e]=bi(t),wi(r)}async function _e(e){let r=sn()[e];if(!r)return null;try{return Ti(r)}catch{return null}}var ye={openai:{id:"openai",name:"OpenAI",defaultApiKeyEnvVar:"OPENAI_API_KEY",defaultModel:"gpt-4o-mini",modelsApiUrl:"https://api.openai.com/v1/models",apiKeyUrl:"https://platform.openai.com/api-keys",buildHeaders:e=>({Authorization:`Bearer ${e}`}),parseModelsResponse:e=>e.data??[],modelFilters:[/^gpt-4/,/^gpt-3\.5/,/^o1/,/^o3/]},anthropic:{id:"anthropic",name:"Anthropic (Claude)",defaultApiKeyEnvVar:"ANTHROPIC_API_KEY",defaultModel:"claude-sonnet-4-20250514",modelsApiUrl:"https://api.anthropic.com/v1/models",apiKeyUrl:"https://console.anthropic.com/settings/keys",buildHeaders:e=>({"x-api-key":e,"anthropic-version":"2023-06-01"}),parseModelsResponse:e=>(e.data??[]).map(r=>({id:r.id,created:new Date(r.created_at).getTime()})),modelFilters:[/^claude-/]}};function cn(){return Object.entries(ye).map(([e,t])=>({name:t.name,value:e}))}function ve(e){let t=ye[e];if(!t)throw new Error(`Unknown AI provider: ${e}`);return t}var U=Ri(Ai(),".platform-sdk-ai.json"),Ni=()=>{let e="anthropic",t=ye[e];return{provider:e,model:t.defaultModel}},Ft=Ni();function Ce(){return Ei(U)}function Le(){if(!Ce())throw new Error("AI configuration not found. Please run 'pf ai:setup' to configure your AI provider.");try{let e=$i(U,"utf-8"),t=JSON.parse(e);return{...Ft,...t}}catch{throw new Error(`Failed to load AI configuration from ${U}. Please run 'pf setup --ai' again.`)}}function ln(e){let t=JSON.stringify(e,null,2);Ii(U,t,"utf-8")}async function pn(e,t){await an(e,t)}async function mn(e){let t=await _e(e.provider);if(t)return t;let r=ye[e.provider],n=process.env[r.defaultApiKeyEnvVar];if(n)return n;throw new Error("API key not found. Please run 'pf setup --ai' to configure your API key.")}var Fi=async(e,t,r,n)=>{let{createOpenAI:o}=await import("@ai-sdk/openai"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a},Mi=async(e,t,r,n)=>{let{createAnthropic:o}=await import("@ai-sdk/anthropic"),s=o({apiKey:r});if(n.onToken){let{streamText:c}=await import("ai"),l=c({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature}),p="";for await(let m of(await l).textStream)p+=m,n.onToken(m);return p}let{generateText:i}=await import("ai"),{text:a}=await i({model:s(t),prompt:e,system:n.system,maxOutputTokens:n.maxTokens,temperature:n.temperature});return a};async function dn(e,t,r={}){let{system:n,maxTokens:o=4096,temperature:s=.7,onToken:i}=r,a=await mn(e);switch(e.provider){case"openai":return Fi(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});case"anthropic":return Mi(t,e.model,a,{system:n,maxTokens:o,temperature:s,onToken:i});default:throw new Error(`Unsupported AI provider: ${e.provider}`)}}import{existsSync as Jn,readFileSync as cc,unlinkSync as lc,writeFileSync as pc}from"fs";import{join as qn,resolve as Vn}from"path";import{input as mc}from"@inquirer/prompts";import u from"chalk";import dc from"ora";import{existsSync as Mt,readdirSync as Oi}from"fs";import{dirname as _i,join as gn}from"path";import{dirname as Di}from"path";import{fileURLToPath as ji}from"url";var D=e=>Di(ji(e));var Li=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),z=e=>{let t=e??Li(),r=o=>Mt(gn(o,"package.json")),n=_i(t);if(r(t))return t;if(t==="/")throw new Error("Could not find package.json (package root)");return z(n)},un=(e,t)=>{let r=e.find(Mt);if(!r)throw new Error(t??`Directory not found. Searched in: ${e.join(", ")}`);return r},fn=async e=>{let{getWorkspacePathsConfig:t}=await import("./config-CKQHYOF4.mjs"),r=t(e);return[r.services,r.apps].flatMap(o=>{let s=gn(e,o);if(!Mt(s))return[];try{return Oi(s,{withFileTypes:!0}).filter(i=>i.isDirectory()&&i.name!==".gitkeep").map(i=>`${o}/${i.name}`)}catch{return[]}})};import{existsSync as pa,readFileSync as ma}from"fs";import{join as da}from"path";import{Project as ga}from"ts-morph";import{deriveEventNames as bu,getContractPaths as Tu,getStreamName as Eu}from"@crossdelta/cloudevents";import{existsSync as We,readFileSync as hn,writeFileSync as Wi}from"fs";import{join as Dt}from"path";import{getStreamName as Hi}from"@crossdelta/cloudevents";var yn=(e,t)=>{let r=Dt(e,"src","index.ts");if(!We(r))return!1;let n=hn(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)},Gi=e=>{if(e.includes("@crossdelta/cloudevents"))return e;let t=`import { consumeJetStreams } from '@crossdelta/cloudevents'
6
+ `,r=e.match(/import\s+['"]@crossdelta\/telemetry['"]\s*\n/);if(r){let o=(r.index??0)+r[0].length;return`${e.slice(0,o)}
7
+ ${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},Bi=(e,t)=>`
8
+
9
+ // Consume from ${e} stream
10
+ consumeJetStreams({
11
+ streams: ['${e}'],
12
+ consumer: '${t}-service',
13
+ discover: './src/events/**/*.handler.ts',
14
+ })`,jt=(e,t)=>{let r=Hi(t),n=Dt(e,"src","index.ts"),o=Dt(e,"src","main.ts");if(!We(n)&&We(o))return{added:!1,streamName:r};if(!We(n))return{added:!1,streamName:r,warning:"Entry point not found (index.ts or main.ts)"};if(yn(e,r))return{added:!1,streamName:r};let s=hn(n,"utf-8"),i=e.split("/").pop()||"unknown";s.includes("consumeJetStreams")||(s=Gi(s));let a=Bi(r,i),c=`${s.trimEnd()+a}
15
+ `;return Wi(n,c,"utf-8"),{added:!0,streamName:r}};import{existsSync as Wg,readFileSync as Hg}from"fs";import{join as Bg}from"path";import{contractCreated as zg,deriveEventNames as Vg,generateContract as Kg,getContractFilePath as Jg}from"@crossdelta/cloudevents";import{readdirSync as Ui,readFileSync as zi}from"fs";import{join as vn}from"path";import{getStreamName as Vi,pluralize as Ki,singularize as Ji}from"@crossdelta/cloudevents";var Cn=e=>{try{return Ui(e,{withFileTypes:!0}).flatMap(r=>{let n=vn(e,r.name);return r.isDirectory()?Cn(n):r.name.endsWith(".handler.ts")?[n]:[]})}catch{return[]}},Ot=e=>{let t=vn(e,"src","events");return Cn(t).flatMap(n=>{let o=zi(n,"utf-8");return qi(n,o)})},qi=(e,t)=>{let r=Zi(t);if(!r)return[];let n=Yi(r);return n?[{filePath:e,eventType:n,contractName:r}]:[]},Yi=e=>{let r=e.replace(/Contract$/,"").match(/[A-Z][a-z]*/g);if(!r||r.length<2)return null;let n=r[0].toLowerCase(),o=Ji(n),i=r.slice(1).map(a=>a.toLowerCase()).join("-");return`${o}.${i}`},Zi=e=>{let r=/import\s+{([^}]+)}\s+from\s+['"]@[\w-]+\/contracts['"]/.exec(e);return r?r[1].split(",").map(s=>s.trim()).filter(s=>s.endsWith("Contract")).map(s=>s.replace(/\s+as\s+.+$/,"").trim()).at(0)??null:null},_t=e=>{let t=e.reduce((r,n)=>{let o=n.eventType.split(".")[0],s=r.get(o)??[];return r.set(o,[...s,n]),r},new Map);return Array.from(t.entries()).map(([r,n])=>Xi(r,n)).sort((r,n)=>r.stream.localeCompare(n.stream))},Xi=(e,t)=>{let r=Vi(t[0]?.eventType??`${e}.event`),o=`${Ki(e)}.>`;return{stream:r,subjects:[o],handlers:t}},Lt=(e,t)=>e.length===0?"":` // Development: pf dev auto-creates ephemeral streams from contracts
16
+ // Production: Pulumi materializes persistent streams
17
+
18
+ consumeJetStreams({
19
+ streams: [${e.map(r=>`'${r.stream}'`).join(", ")}],
20
+ consumer: '${t}',
21
+ discover: './src/events/**/*.handler.ts',
22
+ })`;import{existsSync as V,mkdirSync as Qi,readFileSync as He,writeFileSync as X}from"fs";import{dirname as kn,join as Z}from"path";import{deriveEventNames as ea}from"@crossdelta/cloudevents";var ta=(e,t)=>{let r=`export * from './${t}'`;if(!V(e)){let s=kn(e);V(s)||Qi(s,{recursive:!0});let i=`/**
23
+ * ${kn(e).split("/").pop()} Domain Events
24
+ */
25
+
26
+ `;return X(e,`${i+r}
27
+ `,"utf-8"),!0}let n=He(e,"utf-8");if(n.includes(`'./${t}'`))return!1;let o=`${n.trimEnd()}
28
+ ${r}
29
+ `;return X(e,o,"utf-8"),!0},ra=(e,t)=>{let r=`export * from './${t}'`;if(!V(e))return X(e,`/**
30
+ * Event Contracts Index
31
+ *
32
+ * Re-exports all event contracts for convenient importing.
33
+ */
34
+
35
+ `+r+`
36
+ `,"utf-8"),!0;let o=He(e,"utf-8").split(`
37
+ `);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),X(e,o.join(`
38
+ `),"utf-8"),!0},na=e=>{if(!V(e))return!1;let t=He(e,"utf-8"),r="export * from './events'";if(t.split(`
39
+ `).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()}
40
+ ${r}
41
+ `),o!==t?(X(e,o,"utf-8"),!0):!1},Wt=(e,t)=>{let{packagePath:r}=C(t),{domain:n,action:o}=ea(e),s=Z(r,"src","events");if(!V(s))return!1;let i=Z(s,n),a=Z(i,"index.ts"),c=Z(s,"index.ts"),l=Z(r,"src","index.ts"),p=e.split(".")[0],m=Z(s,p);p!==n&&V(m)&&(console.warn(`\u26A0\uFE0F Warning: Legacy folder '${p}/' found. Please migrate to '${n}/' to avoid conflicts.`),console.warn(` Run: mv ${m} ${i}`));let f=!1;return ta(a,o)&&(f=!0),ra(c,n)&&(f=!0),na(l)&&(f=!0),f},Ht=(e,t)=>{if(!V(e))return!1;let r=`export * from './events/${t}'`,n=He(e,"utf-8");if(n.includes(`'./events/${t}'`))return!1;let o=n.split(`
42
+ `),s=o.findLastIndex(i=>i.startsWith("export"));return s>=0?o.splice(s+1,0,r):o.push("",r),X(e,o.join(`
43
+ `),"utf-8"),!0};import{existsSync as xn,readdirSync as sa,readFileSync as ia}from"fs";import{join as Pn}from"path";import{generateJsonMockFromContract as aa,getJsonMockPath as ca,initFaker as la}from"@crossdelta/cloudevents";var Sn=e=>{let t=e.match(/handleEvent\s*\(\s*(\w+Contract)/m);if(t){let n=e.match(/type:\s*['"]([^'"]+)['"]/m);if(n)return n[1]}let r=e.match(/handleEvent\s*\(\s*\{[^}]*type:\s*['"]([^'"]+)['"]/m);if(r)return r[1];if(t){let s=t[1].replace(/Contract$/,"").split(/(?=[A-Z])/).filter(Boolean);if(s.length>=2){let i=s[0].toLowerCase(),a=s.slice(1).join("").toLowerCase();return`${i}.${a}`}}return null};var Gt=async(e,t={})=>{let r=Pn(e,"src","events");if(!xn(r))return{mockPaths:[],skippedHandlers:[]};await la();let n=sa(r).filter(i=>i.endsWith(".handler.ts")||i.endsWith(".event.ts")),o=[],s=[];for(let i of n){let a=Pn(r,i),c=ia(a,"utf-8"),l=Sn(c);if(!l){s.push(`${i} (Could not extract event type)`);continue}let p=t.outputDir??C().packagePath,m=ca(l,p);if(xn(m)&&!t.overwrite){s.push(`${i} (Mock already exists)`);continue}let f=aa(l,p,{useFaker:!0});f&&f.status!=="skipped"&&"ref"in f?o.push(f.ref):s.push(`${i} (Contract not found or generation failed)`)}return{mockPaths:o,skippedHandlers:s}};var wn=e=>{let t=e.split("/").pop()||"service",r=da(e,"src","events","events.service.ts");if(!pa(r))return!1;let n=Ot(e);if(n.length===0||ma(r,"utf-8").replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").includes("consumeJetStreams"))return!1;let a=_t(n),c=Lt(a,t);if(!c)return!1;let l=new ga({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0}),p=l.addSourceFileAtPath(r),m=!1;for(let f of p.getClasses()){let F=f.getMethod("startConsumers");if(!F)continue;let b=[...c.split(`
44
+ `),""," this.logger.log('Event consumers started successfully')"].join(`
45
+ `);F.setBodyText(b),m=!0;break}return m&&l.saveSync(),m};var ua=e=>{let t=e.split(/\s+/),r=t[0],n=t.slice(1);return r==="pf"&&(r=process.argv[1]),{executable:r,args:n}},fa=async(e,t)=>{try{let{executable:r,args:n}=ua(e.command);return await H(r,n,{cwd:t,shell:!1}),{command:e.command,success:!0}}catch(r){return{command:e.command,success:!1,error:r instanceof Error?r.message:String(r)}}},Bt=async(e,t)=>{let r=[];for(let n of e){let o=await fa(n,t);if(r.push(o),!o.success)break}return r},Ut=e=>{let t=[/^pf\s+/,/^bun\s+pf\s+/,/^npx\s+pf\s+/,/^bunx\s+pf\s+/];return e.filter(r=>t.some(n=>n.test(r.command)))},bn=e=>{for(let t of e){let r=t.command.match(/(?:bun\s+)?pf\s+new\s+\S+\s+(\S+)/);if(r)return r[1]}return null};import{existsSync as $n,readFileSync as ka}from"fs";import{join as zt}from"path";import O from"chalk";import{existsSync as Tn,mkdirSync as ha,writeFileSync as ya}from"fs";import{dirname as va}from"path";var Ca=(e,t)=>{let n=e.path.startsWith("packages/")&&t.workspaceRoot?t.workspaceRoot:t.baseDir,o;try{o=Gr(e.path,n)}catch(s){return{status:"failed",path:e.path,error:s.message}}try{if(Tn(o)&&!t.overwrite)return{status:"skipped",path:e.path};if(t.dryRun)return{status:"written",path:e.path};let s=va(o);return Tn(s)||ha(s,{recursive:!0}),ya(o,e.content,"utf-8"),{status:"written",path:e.path}}catch(s){return{status:"failed",path:e.path,error:s.message}}},En=(e,t)=>{let r=e.map(n=>Ca(n,t));return{written:r.filter(n=>n.status==="written").map(n=>n.path),skipped:r.filter(n=>n.status==="skipped").map(n=>n.path),failed:r.filter(n=>n.status==="failed").map(n=>({path:n.path,error:n.error}))}};var xa=(e,t)=>{let r=S(t.workspaceRoot),n=zt(t.workspaceRoot,r.contracts);if(!$n(n))return[];let o=/import\s+(?:type\s+)?{([^}]+)}\s+from\s+['"]@\w+\/contracts['"]/g,s=new Set;for(let i of e){let a=i.content.matchAll(o);for(let c of a){let p=c[1].split(",").map(m=>m.trim()).map(m=>m.replace(/^type\s+/,"").replace(/\s+as\s+.+$/,"").trim()).filter(m=>m.endsWith("Contract"));for(let m of p)s.add(m)}}return Array.from(s).sort()},Pa=e=>{let t=zt(e,"packages/contracts/src/index.ts");if(!$n(t))return new Set;try{let r=ka(t,"utf-8"),n=new Set,o=/export\s+(?:\*|{[^}]*Contract[^}]*})\s+from\s+['"]\.\/events\/([^'"]+)['"]/g,s=r.matchAll(o);for(let i of s){let a=i[0],c=/(\w+Contract)/g,l=a.matchAll(c);for(let p of l)n.add(p[1])}return n}catch{return new Set}},Sa=e=>{let t=e.replace(/Contract$/,""),r=t.split(/(?=[A-Z])/).filter(Boolean);if(r.length<2)return t.toLowerCase();let n=r[0].toLowerCase(),o=r.slice(1).join("").toLowerCase();return`${n}.${o}`},wa=(e,t,r)=>{let n=Pa(t),o=[],s=[],i=[];for(let a of e)if(n.has(a))o.push(a);else{s.push(a);let c=Sa(a),l=r.replace(`${t}/`,"");i.push(`pf cloudevents add ${c} --service ${l}`)}return{existing:o,missing:s,suggestedCommands:i}},ba=(e,t)=>{if(e.length!==0){console.log(O.cyan(`\u{1F4E6} Using existing contracts:
46
+ `));for(let r of e)console.log(O.dim(` ${t}/contracts \u2192 ${r}`));console.log()}},Ta=(e,t)=>{let r=/^packages\/contracts\/src\/events\/([^/]+)\.ts$/,n=zt(t,"packages/contracts/src/index.ts");for(let o of e){let s=o.match(r);s&&s[1]!=="index"&&Ht(n,s[1])}},In=async(e,t)=>{t.start("Applying code formatting...");try{await fe("biome",["check","--fix","--unsafe","."],{cwd:e,quiet:!0}),t.succeed("Code formatted!")}catch{t.warn("Code formatting completed with warnings")}},Ea=async(e,t)=>{t.start("Scanning for event handlers...");let{mockPaths:r,skippedHandlers:n}=await Gt(e);if(r.length+n.length===0){t.info("No event handlers found");return}if(r.length>0){t.succeed(`Generated ${r.length} event ${r.length===1?"mock":"mocks"}`),console.log();for(let s of r){let i=s.replace(`${e}/`,"");console.log(O.dim(` ${i}`))}console.log()}else t.succeed("Event handlers found");if(n.length>0){for(let s of n)console.log(O.dim(` \u2139 Skipped: ${s}`));console.log()}},An=async(e,t,r,n)=>{n.start("Writing generated files...");let o=En(e,{baseDir:t,workspaceRoot:r.workspaceRoot,overwrite:!0});if(o.written.length>0){n.succeed(`Created ${o.written.length} files`),console.log();for(let l of o.written)console.log(O.dim(` ${l}`));console.log()}else n.succeed("No files to write");let s=xa(e,r),{existing:i,missing:a,suggestedCommands:c}=wa(s,r.workspaceRoot,t);if(i.length>0&&ba(i,r.scope),a.length>0){console.log(O.yellow(`\u26A0\uFE0F Missing contracts (not exported from @${r.scope}/contracts):
47
+ `));for(let l of a)console.log(O.yellow(` ${l}`));console.log(),console.log(O.cyan(`\u{1F4A1} Run these commands to create the missing contracts:
48
+ `));for(let l of c)console.log(O.dim(` ${l}`));console.log()}return Ta(o.written,r.workspaceRoot),o.written.length>0&&await Ea(t,n),{missingContractCommands:c}};import{existsSync as Da,readFileSync as ja}from"fs";import{join as ke}from"path";import{existsSync as $a,readdirSync as Ia,readFileSync as Aa}from"fs";import{join as Ra}from"path";var Rn=e=>{let{eventsPath:t}=C(e);if(!$a(t))return[];let r=[];try{let n=Ia(t).filter(o=>o.endsWith(".ts")&&!o.endsWith(".mock.json")&&o!=="index.ts");for(let o of n){let s=Ra(t,o),i=Aa(s,"utf-8"),a=Na(i,s);a&&r.push(a)}}catch(n){return console.warn("Warning: Could not scan contracts package:",n),[]}return r},Na=(e,t)=>{try{let r=e.match(/export const (\w+Contract) = createContract/);if(!r)return null;let n=r[1],o=e.match(/export type (\w+(?:Data|Event)) = z\.infer/);if(!o)return null;let s=o[1],i=e.match(/type:\s*['"]([^'"]+)['"]/);if(!i)return null;let a=i[1],c=Ma(e);return{name:n,typeName:s,eventType:a,fields:c,filePath:t}}catch{return null}},Fa={string:"string",number:"number",boolean:"boolean",array:"array",object:"object",date:"date"},Ma=e=>{let t=e.match(/z\.object\({([^}]+)\}/);if(!t)return[];let r=t[1],n=/(\w+):\s*z\.(\w+)\([^)]*\)/g,o=[...r.matchAll(n)].map(([,a,c])=>{let l=Fa[c]||c;return`${a}: ${l}`});if(!e.includes("z.array("))return o;let s=/(\w+):\s*z\.array\(/g,i=[...e.matchAll(s)].map(([,a])=>a).filter(a=>!o.some(c=>c.startsWith(a))).map(a=>`${a}: array`);return[...o,...i]},Nn=(e,t)=>{if(e.length===0)return`
49
+ **Available Contracts:**
50
+
51
+ No contracts are currently defined. Use Basic Mode with inline schemas for all events.
52
+ `.trim();let r=e.map((n,o)=>{let s=n.fields.length>0?n.fields.map(i=>` - ${i}`).join(`
53
+ `):" - (no fields detected)";return`
54
+ ${o+1}. **${n.name}** (\`${n.eventType}\`)
55
+ - Type: \`${n.typeName}\`
56
+ - Fields:
57
+ ${s}
58
+ - **USE THIS** when consuming ${n.eventType} or similar event names
59
+ `.trim()}).join(`
60
+
61
+ `);return`
62
+ **Available Contracts** (ALWAYS check this list first!):
63
+
64
+ The following event contracts are available in \`${t}/contracts\`:
65
+
66
+ ${r}
67
+
68
+ If the event type your service consumes matches one of these, **you MUST use Advanced Mode**.
69
+ `.trim()};var Oa=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),_a=(e,t)=>{let r=ke(Oa(),"docs","generators"),n=ue(),o=[];for(let s of n.docs.base)o.push(ke(r,s));if(e&&n.docs.frameworks[e]){let s=n.docs.frameworks[e];if(typeof s=="string")o.push(ke(r,s));else{let i=t==="bun"?"bun":"node";s[i]&&o.push(ke(r,s[i]))}}return o},Fn={copilot:".github/copilot-instructions.md",projectGuidelines:"docs/ai-guidelines.md"},La=1500,Mn=e=>{try{return Da(e)?ja(e,"utf-8"):null}catch{return null}},Wa=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/\n{3,}/g,`
70
+
71
+ `).replace(/[ \t]+$/gm,"").trim(),Ha=e=>e.replace(/<!--[\s\S]*?-->/g,"").replace(/^\[.+\]:\s*.+$/gm,"").replace(/```[\s\S]*?```/g,"").replace(/`[^`]{50,}`/g,"`...`").replace(/\n{3,}/g,`
72
+
73
+ `).replace(/[ \t]+$/gm,"").trim(),Ga=e=>Math.ceil(e.length/4),Ba=(e,t)=>{let r=e.split(/(?=^## )/m),n="",o=0;for(let s of r){let i=Ga(s);if(o+i<=t)n+=s,o+=i;else if(o===0){n=s.slice(0,t*4);break}else break}return n.trim()},Ua=(e,t)=>{let{workspaceRoot:r,scope:n}=t,o=Rn(r),s=Nn(o,n);return e.replace(/\{\{scope\}\}/g,n).replace(/\{\{AVAILABLE_CONTRACTS\}\}/g,s)},Dn=e=>{let{workspaceRoot:t,scope:r}=e,n=[],o=_a(e.serviceType,e.packageManager);for(let a of o){let c=Mn(a);if(c){let l=Ua(c,e),p=Wa(l);n.push(p)}}let s=[Fn.copilot,Fn.projectGuidelines],i=Math.floor(La/s.length);for(let a of s){let c=Mn(ke(t,a));if(c){let l=Ha(c),p=Ba(l,i);p.length>50&&n.push(p)}}return n.length===0?(console.warn("\u26A0\uFE0F No instruction files found."),`Use ${r}/contracts for shared types.`):n.join(`
74
+
75
+ ---
76
+
77
+ `)};var za=`You are an expert code generator. Generate clean, production-ready code.
78
+
79
+ ## Output Format
80
+
81
+ Format your code blocks with the file path on the line before the code block:
82
+
83
+ #### \`src/index.ts\`
84
+ \`\`\`typescript
85
+ // code here
86
+ \`\`\`
87
+
88
+ **IMPORTANT:** Always generate:
89
+ - Source code files (src/**)
90
+ - Test files (src/**/*.test.ts) for all business logic
91
+ - README.md with service documentation`,Va=e=>e.replace(/-/g,"_").toUpperCase(),Ka=e=>e.split("/").pop()||"my-service",jn=(e,t,r)=>{let n=Dn({...e,serviceType:t,packageManager:r});return`${za}
92
+
93
+ ## Project Guidelines & Patterns
94
+
95
+ Follow these project-specific conventions and patterns when generating code:
96
+
97
+ ${n}`},On=(e,t,r,n)=>{let o=Ka(e),s=`${Va(o)}_PORT`,i=Ur();return`Generate source code for a microservice at path "${e}".
98
+
99
+ Use the patterns and conventions from the Project Guidelines above.
100
+
101
+ Service purpose: ${t}
102
+
103
+ **CRITICAL:**
104
+ - Service name: "${o}"
105
+ - Workspace scope: "${i}" (use this for imports like \`${i}/contracts\`)
106
+ - Port env var: Use \`process.env.${s}\` (NOT SERVICE_NAME_PORT)
107
+ - Consumer name: Use "${o}" as the consumer name in consumeJetStreams
108
+ - You MAY modify \`src/index.ts\` or \`src/main.ts\` to add consumeJetStreams, env validation, or middleware
109
+ - BUT you MUST keep the existing port configuration line unchanged!
110
+
111
+ Do NOT include the service path in file headers (use \`src/...\`, NOT \`${e}/src/...\`).
112
+ `};var Ja=()=>!!process.env.DEBUG,_n=(e,t)=>{Ja()&&console.log(`[AI Parser] ${e}`,t??"")},Ge={commandsBlock:/```commands\n([\s\S]*?)```/gi,postCommandsBlock:/```post-commands\n([\s\S]*?)```/gi,dependenciesBlock:/```dependencies\n([\s\S]*?)```/gi,fileHeader:/^#{1,4}\s+`([^`]+)`\s*$/},Kt=(e,t)=>[...e.matchAll(t)].flatMap(n=>n[1].split(`
113
+ `).map(o=>o.trim()).filter(o=>o.length>0&&!o.startsWith("#"))),Ln=e=>({command:e,isPfCommand:e.startsWith("pf ")||e.includes(" pf ")}),qa=e=>Kt(e,Ge.commandsBlock).map(Ln),Ya=e=>Kt(e,Ge.postCommandsBlock).map(Ln),Za=e=>Kt(e,Ge.dependenciesBlock).filter(t=>!t.startsWith("@crossdelta/")&&t!=="zod"),Xa=e=>{let t={ts:"typescript",js:"javascript",md:"markdown",yml:"yaml"},r=(e||"typescript").toLowerCase();return t[r]||r},Qa=e=>{let t=e.split(".").pop()?.toLowerCase();return{ts:"typescript",tsx:"typescript",js:"javascript",jsx:"javascript",json:"json",yaml:"yaml",yml:"yaml",md:"markdown"}[t||""]||"plaintext"},ec=e=>e.replace(/^\s*\/\/ \.{3,}.*$/gm,"").replace(/^\s*\/\/ Lines? \d+.*omitted.*$/gim,"").replace(/^\s*\/\* Lines? \d+.*omitted.*\*\/$/gim,"").trim(),tc=e=>{let t=e.split(`
114
+ `),r=[],n=0;for(let o of t){let s=Ge.fileHeader.exec(o);s&&r.push({path:s[1],index:n}),n+=o.length+1}return r},rc=(e,t)=>{let n=e.slice(t).match(/```(\w+)?\n([\s\S]*?)```/);return n?{language:n[1]?Xa(n[1]):void 0,content:ec(n[2])}:null},nc=e=>tc(e).map(r=>{let n=rc(e,r.index);return!n||n.content.length===0?null:{path:r.path,language:n.language||Qa(r.path),content:n.content,startIndex:r.index}}).filter(r=>r!==null),Vt=e=>e.includes("packages/contracts")||e.includes("contracts/src"),oc=e=>{let t=e.filter(n=>Vt(n.path)),r=e.filter(n=>!Vt(n.path));return[...t,...r]},sc=e=>{let t=e.replace(/^\/+/,"").replace(/\/{2,}/g,"/");if(Vt(t))return t;let r=t.match(/^services\/[^/]+\/(.+)$/);return r?r[1]:t},Wn=(e,t)=>{_n("Parsing AI response",{length:e.length});let r=qa(e),n=Ya(e),o=Za(e),s=nc(e),i=oc(s.map(a=>({path:sc(a.path),content:a.content,language:a.language})));return _n("Parsed response",{commands:r.length,postCommands:n.length,dependencies:o.length,files:i.length}),{commands:r,files:i,dependencies:o,postCommands:n}},Hn=e=>{let t=e.filter(s=>!s.content||s.content.trim().length===0),r=e.length===0?["No files could be extracted from the AI response"]:t.map(s=>`File ${s.path} is empty`),n=e.some(s=>["src/index.ts","src/main.ts","index.ts"].includes(s.path)),o=e.length>0&&!n?["No entry point file (src/index.ts or src/main.ts) found - assuming it exists from scaffolding"]:[];return{valid:r.length===0,errors:r,warnings:o}};import{mkdirSync as ic}from"fs";import j from"chalk";var Gn=async(e,t,r)=>{if(e.length===0){ic(t,{recursive:!0}),console.log(j.yellow(`\u26A0 No scaffolding command found - creating empty directory
115
+ `));return}let o=(await Bt(e,r)).find(s=>!s.success);if(o)throw console.log(j.red(`
116
+ \u2717 Scaffolding failed: ${o.command}`)),o.error&&console.log(j.red(` Error: ${o.error}`)),new Error(`Command failed: ${o.command}${o.error?` - ${o.error}`:""}`)},Bn=async(e,t,r)=>{if(e.length===0)return;r.stop();let n=e.length===1?"package":"packages";console.log(j.cyan(`
117
+ \u25B6 Installing ${e.length} additional ${n}...
118
+ `));try{await M({packages:e,cwd:t,flags:["--silent"]}),console.log(j.green(`\u2713 Installed ${e.length} ${n}
119
+ `))}catch(o){throw console.log(j.red(`\u2717 Package installation failed
120
+ `)),o}},Jt=async(e,t)=>{if(e.length===0)return;console.log(j.cyan(`
121
+ \u25B6 Running post-generation commands...
122
+ `));let n=(await Bt(e,t)).find(o=>!o.success);if(n){console.log(j.yellow(`
123
+ \u26A0 Post-command failed: ${n.command}`)),n.error&&console.log(j.yellow(` Error: ${n.error}`));return}console.log(j.green(`\u2713 Post-generation commands complete
124
+ `))};import Be from"chalk";var ac=e=>`${Be.dim(" \u2022 ")+Be.cyan(e)}
125
+ `,Un=e=>Be.dim(` \u2728 Generated ${Be.white.bold(e)} tokens
126
+ `),zn=()=>{let e="",t=0,r=Date.now(),n=[],o=()=>{let i=e.match(/####\s+`([^`]+)`/);if(!i)return!1;n.push(i[1]),process.stdout.write(ac(i[1]));let a=e.indexOf(i[0])+i[0].length;return e=e.slice(a),!0},s=i=>{e+=i,t++,o(),e.length>500&&(e=e.slice(-200))};return s.getStats=()=>{let i=((Date.now()-r)/1e3).toFixed(2),a=(t/Number.parseFloat(i)).toFixed(0);return{tokenCount:t,duration:i,tokensPerSec:a}},s.getFiles=()=>n,s};var gc=()=>{let e=h(),t=qn(e,"package.json"),r=(()=>{if(!Jn(t))throw new Error("No package.json found in workspace root. Run from a valid workspace.");try{let o=JSON.parse(cc(t,"utf-8")).name;if(!o)throw new Error('package.json has no "name" field. Please add a name to your root package.json.');return o.startsWith("@")?o:`@${o}`}catch(n){throw n instanceof SyntaxError?new Error("Invalid JSON in package.json"):n}})();return{workspaceRoot:e,scope:r,cwd:process.cwd()}},uc=async(e,t,r,n,o,s)=>{let i=On(r,n,o,t.workspaceRoot),a=jn(t,o,s),c=zn(),l=await dn(e,i,{system:a,maxTokens:16384,temperature:.7,onToken:c}),p=c.getStats();return console.log(Un(p.tokenCount)),console.log(),l},fc=(e,t)=>{let{serviceTypes:r}=ue(),n=r[t]?.commandType;if(!n)return e;let o=Object.values(r).map(s=>s.commandType);return e.map(s=>{for(let i of o)if(i!==n&&s.command.includes(`pf new ${i}`))return{...s,command:s.command.replace(`pf new ${i}`,`pf new ${n}`)};return s})},hc=e=>e.length===0?"":`${[u.cyan(`
127
+ \u{1F4C1} Files to create:`),...e.map(t=>` ${u.green("\u2022")} ${u.white(t.path)} ${u.dim(`(${t.language})`)}`)].join(`
128
+ `)}
129
+ `,Kn=(e,t,r)=>e.length===0?"":`${[u.cyan(`
130
+ ${r} ${t}:`),...e.map(n=>` ${u.yellow("$")} ${u.white(n.command)}`)].join(`
131
+ `)}
132
+ `,yc=e=>e.length===0?"":`${[u.cyan(`
133
+ \u{1F4E6} Dependencies to install:`),...e.map(t=>` ${u.magenta("+")} ${u.white(t)}`)].join(`
134
+ `)}
135
+ `,vc=(e,t)=>`${[u.yellow(`
136
+ Validation errors:`),...e.map(r=>u.yellow(` \u26A0 ${r}`)),u.dim(`
137
+ Response preview:`),u.dim(t)].join(`
138
+ `)}
139
+ `,Q=e=>{e&&process.stdout.write(e)},Cc=(e,t)=>{let r=Wn(e,t),n=Ut(r.commands),o=Ut(r.postCommands),s=Hn(r.files);return s.valid?{files:r.files,commands:n,dependencies:r.dependencies,postCommands:o}:(console.log(`${u.yellow("\u26A0")} Could not extract structured files from AI response`),Q(vc(s.errors,e.slice(0,500))),null)},kc=e=>{console.log(`${u.green("\u2714")} Extracted ${e.files.length} files`),Q(hc(e.files)),Q(Kn(e.commands,"Commands to run","\u{1F527}")),Q(Kn(e.postCommands,"Post-generation commands","\u{1F4DD}")),Q(yc(e.dependencies)),Q(`
140
+ `)},xc=(e,t,r)=>{let n=bn(e);return n&&!n.includes("/")&&!n.startsWith(".")&&(n=`${S().services}/${n}`),n?Vn(r,n):Vn(r,t)},Pc=(e,t)=>{let{serviceTypes:r}=ue(),n=r[t]?.skipFiles||["package.json","tsconfig.json","Dockerfile"];return e.filter(o=>!n.includes(o.path))},ee=()=>{if(!Ce())return{valid:!1,error:u.red.bold(`\u274C AI configuration not found.
141
+ `)+u.yellow("Please run ")+u.cyan.bold("pf setup --ai")+u.yellow(` first to configure your AI provider.
142
+ `)};try{return{valid:!0,config:Le()}}catch(e){return{valid:!1,error:u.red.bold(`\u274C ${e.message}
143
+ `)}}},Ue=async e=>e||mc({message:"\u{1F4DD} Describe what this service should do:",validate:t=>t.trim().length>0||"Please provide a description for the AI to generate code"}),ze=(e,t,r)=>{console.log(u.cyan.bold(`
144
+ \u{1F916} AI-Powered Generation
145
+ `)),console.log(u.dim(`Service: ${e.split("/").pop()}`)),console.log(u.dim(`Path: ${e}`)),console.log(u.dim(`Model: ${t.model}`)),console.log(u.dim(`Description: ${r}
146
+ `))},Ve=async(e,t)=>{let{servicePath:r,description:n="",serviceType:o,packageManager:s}=e,i=r.split("/").pop()||r,a=gc(),c=qn(a.workspaceRoot,Wr);pc(c,`generating:${r}`);let l=()=>{Jn(c)&&lc(c)},p=()=>{l(),process.exit(T.CANCELLED)};process.on("SIGINT",p),process.on("SIGTERM",p);try{console.log(u.cyan.bold(`
147
+ \u{1F916} AI Generation
148
+ `));let m=await uc(t,a,r,n,o,s),f=Cc(m,i);if(!f)return!1;kc(f);let F=dc({text:"Processing files...",color:"cyan"}).start(),ge=fc(f.commands,o),b=xc(ge,r,a.cwd),Vs=Pc(f.files,o);await Gn(ge,b,a.workspaceRoot);let{missingContractCommands:jr}=await An(Vs,b,a,F);if(f.postCommands.length>0)await Jt(f.postCommands,a.workspaceRoot);else if(jr.length>0){console.log(u.cyan(`\u{1F527} Auto-creating missing contracts...
149
+ `));let Ks=jr.map(Js=>({command:Js,isPfCommand:!0}));await Jt(Ks,a.workspaceRoot)}return wn(b),await Bn(f.dependencies,b,F),await In(b,F),!0}finally{process.off("SIGINT",p),process.off("SIGTERM",p),l()}};import{existsSync as Uf}from"fs";import{Project as Sc,SyntaxKind as Vf}from"ts-morph";var Kf=new Sc({skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0});import{promises as qt}from"fs";import Ke from"path";import Yn from"chalk";var Zn=async e=>{await H("bash",["-c",`
150
+ curl -fsSL https://bun.sh/install | bash && if [ -f "$HOME/.bun/bin/bun" ]; then export PATH="$HOME/.bun/bin:$PATH"; fi
151
+ `],{task:e,shell:!0}),await $c()},Yt=()=>Ne("bun"),Xn=()=>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"}),Qn=()=>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"}),$c=async()=>{let e='export PATH="$HOME/.bun/bin:$PATH"',t=process.env.HOME;if(!t){d.error("Could not detect $HOME environment variable. Cannot update shell config.");return}let r=[Ke.join(t,".zshrc"),Ke.join(t,".bashrc"),Ke.join(t,".bash_profile")];for(let n of r)try{if(await qt.stat(n).then(()=>!0).catch(()=>!1)){(await qt.readFile(n,"utf8")).includes(e)||(await qt.appendFile(n,`
152
+ # Added by platform installer
153
+ ${e}
154
+ `),d.log(`Added Bun path to ${Ke.basename(n)}`));return}}catch(o){d.error(`Failed to update ${n}: ${o.message}`)}d.warn("No shell config file (.zshrc, .bashrc, .bash_profile) found. Please add the following manually:"),d.log(Yn.cyan(e))};import{existsSync as Ye,mkdirSync as Bc,readFileSync as Uc,renameSync as zc,statSync as so,unlinkSync as Vc,writeFileSync as Kc}from"fs";import{join as Se}from"path";import{existsSync as Ic}from"fs";import{join as Ac}from"path";import Je from"chalk";import Zt from"chalk";var te=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` ${Zt.cyan(o.name)}${s}${o.description}`}),n=e.footer||'Run "<command> --help" for more information';return[Zt.cyan.bold(`
155
+ ${e.title}
156
+ `),`Available commands:
157
+ `,...r,"",Zt.dim(`${n}
158
+ `)].join(`
159
+ `)};var Rc=(e,t)=>t.some(r=>r.name()===e),Nc=(e,t)=>t.pf?.commands?.[e]??null,Fc=(e,t)=>!!t.scripts?.[e],Mc=(e,t)=>t.cwd?Ac(e,t.cwd):e,Dc=(e,t)=>t.command||e,jc=(e,t,r,n)=>{let o=Mc(n,r),s=Dc(e,r);if(r.cwd&&!Ic(o))return console.error(Je.red(`
160
+ \u2716 Directory not found: ${o}
161
+ `)),!0;let i=r.cwd?Je.dim(` in ${r.cwd}/`):"";return console.log(Je.dim(`Running ${s}${i}`)),je(s,t,{cwd:o}),!0},Oc=(e,t,r)=>(console.log(Je.dim(`Running workspace script: ${e}`)),he(e,{args:t,cwd:r}),!0);async function _c(e,t,r){if(Rc(e,r))return!1;let n;try{n=h()}catch{return!1}let o=B(n);if(!o)return!1;let s=Nc(e,o);return s?jc(e,t,s,n):Fc(e,o)?Oc(e,t,n):!1}function eo(){let e;try{e=B()}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 Xt(){let{configured:e,scripts:t}=eo();return[...e,...t]}function to(){let{configured:e,scripts:t}=eo(),r=[...e,...t];if(r.length===0)return"";let o=B()?.pf?.commands||{},s=r.map(i=>({name:i,description:o[i]?.description||qe[i]||""}));return te({title:"Workspace Commands",commands:s,footer:""})}function ro(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=Xt();for(let a of i)console.log(a);return}_c(o,s,r).then(i=>{i||e.parse(t)})}else e.parse(t)}var no={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"},qe={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"},oo=(e,t)=>t?`${e}:${t}`:e,Lc=()=>Object.entries(no).map(([e,t])=>oo(e,t)),Wc=()=>{try{let e=Xt(),r=B()?.pf?.commands||{},n=Object.keys(no);return e.filter(o=>!n.includes(o)).map(o=>{let s=r[o]?.description||qe[o]||"";return oo(o,s)})}catch{return[]}},Hc=()=>{try{let e=h(),t=C(e),r=`${e}/${t.relativePath}/src`,{discoverEventTypes:n}=Or("@crossdelta/cloudevents");return n(r)}catch{return[]}},Gc=async()=>{try{let e=h();return await fn(e)}catch{return[]}},Qt=async()=>({commands:[...Lc(),...Wc()],events:Hc(),services:await Gc()});var xe="node_modules/.cache/pf",Pe="completion-cache";var Jc=e=>{let t=I.version||"0.0.0",r=e.commands.join("|"),n=e.events.join("|"),o=e.services.join("|");return`${t} ${r} ${n} ${o}`},qc=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:[]}},Yc=e=>{let t=Se(e,xe);return Se(t,Pe)},Zc=(e,t=!1)=>{if(t)return!0;let r=Yc(e);if(!Ye(r))return!0;let n=Uc(r,"utf-8").trim(),o=qc(n),s=I.version||"0.0.0";if(o.version!==s)return!0;let i=Se(e,"package.json");if(!Ye(i))return!1;let a=so(r).mtimeMs;return so(i).mtimeMs>a};var Xc=(e,t)=>{let r=Se(e,xe),n=Se(r,Pe),o=`${n}.tmp.${process.pid}`;Ye(r)||Bc(r,{recursive:!0});let s=Jc(t);try{Kc(o,s,"utf-8"),zc(o,n)}catch(i){try{Ye(o)&&Vc(o)}catch{}throw i}},Ze=async(e={})=>{let t;try{t=h()}catch{return!1}if(!t)return!1;if(!Zc(t,e.force))return e.verbose&&console.log("[completion] Cache is up to date"),!1;let r=await Qt();return Xc(t,r),e.verbose&&console.log(`[completion] Cache regenerated: ${r.commands.length} commands, ${r.events.length} events`),!0},we=async(e={})=>{await Ze({...e,force:!0})};import{existsSync as tr,readFileSync as po,writeFileSync as mo}from"fs";import{homedir as go}from"os";import{join as er}from"path";import re from"chalk";var io=`${xe}/${Pe}`,ao=e=>`# ${e} completion (workspace-local cache)
162
+ # Generated: ${new Date().toISOString()}
163
+
164
+ # Cache file path (relative to workspace root)
165
+ _${e}_cache_path="${io}"
166
+
167
+ # Find workspace root (walk up to find monorepo package.json)
168
+ _${e}_find_workspace() {
169
+ local dir="$PWD"
170
+ while [[ "$dir" != "/" ]]; do
171
+ if [[ -f "$dir/package.json" ]] && grep -q '"workspaces"' "$dir/package.json" 2>/dev/null; then
172
+ echo "$dir"
173
+ return
174
+ fi
175
+ dir="\${dir:h}"
176
+ done
177
+ }
178
+
179
+ # Read cache file from workspace
180
+ _${e}_read_cache() {
181
+ local ws="$1"
182
+ local cache="$ws/$_${e}_cache_path"
183
+ [[ -f "$cache" ]] && cat "$cache"
184
+ }
185
+
186
+ # Main completion function
187
+ _${e}_completions() {
188
+ local line state
189
+
190
+ _arguments -C \\
191
+ "1: :->cmds" \\
192
+ "*::arg:->args"
193
+
194
+ # Find workspace and read cache
195
+ local ws_root=$(_${e}_find_workspace)
196
+ local cache_data=""
197
+ local in_workspace=0
198
+
199
+ if [[ -n "$ws_root" ]]; then
200
+ in_workspace=1
201
+ cache_data=$(_${e}_read_cache "$ws_root")
202
+ fi
203
+
204
+ # Parse data: "version cmd1:desc1|cmd2:desc2 events services"
205
+ # Split by tabs, skip first field (version)
206
+ local -a parts
207
+ parts=("\${(@s: :)cache_data}")
208
+
209
+ local commands_str=""
210
+ local events_str=""
211
+ local services_str=""
212
+
213
+ if [[ \${#parts[@]} -eq 4 ]]; then
214
+ # New format with services: version commands events services
215
+ commands_str="\${parts[2]}"
216
+ events_str="\${parts[3]}"
217
+ services_str="\${parts[4]}"
218
+ elif [[ \${#parts[@]} -eq 3 ]]; then
219
+ # Format without services: version commands events
220
+ commands_str="\${parts[2]}"
221
+ events_str="\${parts[3]}"
222
+ elif [[ \${#parts[@]} -eq 2 ]]; then
223
+ # Legacy format: commands events
224
+ commands_str="\${parts[1]}"
225
+ events_str="\${parts[2]}"
226
+ fi
227
+
228
+ case "$state" in
229
+ cmds)
230
+ if [[ -n "$commands_str" ]]; then
231
+ # Cache exists \u2192 all commands
232
+ local -a subcmds
233
+ subcmds=("\${(@s:|:)commands_str}")
234
+ _describe 'command' subcmds
235
+ elif [[ $in_workspace -eq 1 ]]; then
236
+ # Workspace but no cache \u2192 main commands
237
+ local -a main_cmds
238
+ main_cmds=(
239
+ "setup:Configure platform settings"
240
+ "new:Create a new project"
241
+ "dev:Start development mode"
242
+ "event:Event management commands"
243
+ "token:Token management commands"
244
+ "audit:Run security audit"
245
+ )
246
+ _describe 'command' main_cmds
247
+ else
248
+ # No workspace \u2192 only new
249
+ local -a fallback_cmds
250
+ fallback_cmds=(
251
+ "new:Create a new project"
252
+ )
253
+ _describe 'command' fallback_cmds
254
+ fi
255
+ ;;
256
+ args)
257
+ case $line[1] in
258
+ new)
259
+ local -a new_commands
260
+ new_commands=(
261
+ "workspace:Create a new workspace"
262
+ "hono-micro:Create a Hono microservice"
263
+ "nest-micro:Create a NestJS microservice"
264
+ )
265
+ _describe 'new commands' new_commands
266
+ ;;
267
+ event)
268
+ case $line[2] in
269
+ publish)
270
+ if [[ -n "$events_str" ]]; then
271
+ local -a events
272
+ events=("\${(@s:|:)events_str}")
273
+ _describe 'event type' events
274
+ fi
275
+ ;;
276
+ *)
277
+ local -a event_commands
278
+ event_commands=(
279
+ "add:Add event contract and handler"
280
+ "list:List all event mocks"
281
+ "publish:Publish to NATS JetStream"
282
+ )
283
+ _describe 'event commands' event_commands
284
+ ;;
285
+ esac
286
+ ;;
287
+ esac
288
+ ;;
289
+ esac
290
+ }
291
+
292
+ compdef _${e}_completions ${e}`,co=e=>`# ${e} completion (workspace-local cache)
293
+ # Generated: ${new Date().toISOString()}
294
+
295
+ # Cache file path (relative to workspace root)
296
+ _${e}_cache_path="${io}"
297
+
298
+ # Find workspace root
299
+ _${e}_find_workspace() {
300
+ local dir="$PWD"
301
+ while [[ "$dir" != "/" ]]; do
302
+ if [[ -f "$dir/package.json" ]] && grep -q '"workspaces"' "$dir/package.json" 2>/dev/null; then
303
+ echo "$dir"
304
+ return
305
+ fi
306
+ dir="$(dirname "$dir")"
307
+ done
308
+ }
309
+
310
+ # Read cache file
311
+ _${e}_read_cache() {
312
+ local ws="$1"
313
+ local cache="$ws/$_${e}_cache_path"
314
+ [[ -f "$cache" ]] && cat "$cache"
315
+ }
316
+
317
+ # Main completion function
318
+ _${e}_completions() {
319
+ local cur prev opts
320
+ COMPREPLY=()
321
+ cur="\${COMP_WORDS[COMP_CWORD]}"
322
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
323
+
324
+ # Find workspace and read cache
325
+ local ws_root=$(_${e}_find_workspace)
326
+ local cache_data=""
327
+ local commands_str=""
328
+ local events_str=""
329
+ local services_str=""
330
+ local in_workspace=0
331
+
332
+ if [[ -n "$ws_root" ]]; then
333
+ in_workspace=1
334
+ cache_data=$(_${e}_read_cache "$ws_root")
335
+
336
+ # Parse data: "version cmd1:desc1|cmd2:desc2 events services"
337
+ IFS=$'\\t' read -ra parts <<< "$cache_data"
338
+
339
+ if [[ \${#parts[@]} -eq 4 ]]; then
340
+ # New format with services: version commands events services
341
+ commands_str="\${parts[1]}"
342
+ events_str="\${parts[2]}"
343
+ services_str="\${parts[3]}"
344
+ elif [[ \${#parts[@]} -eq 3 ]]; then
345
+ # Format without services: version commands events
346
+ commands_str="\${parts[1]}"
347
+ events_str="\${parts[2]}"
348
+ elif [[ \${#parts[@]} -eq 2 ]]; then
349
+ # Legacy format: commands events
350
+ commands_str="\${parts[0]}"
351
+ events_str="\${parts[1]}"
352
+ fi
353
+ fi
354
+
355
+ # Extract command names
356
+ local cmd_names=""
357
+ if [[ -n "$commands_str" ]]; then
358
+ cmd_names=$(echo "$commands_str" | tr '|' '\\n' | cut -d: -f1 | tr '\\n' ' ')
359
+ elif [[ $in_workspace -eq 1 ]]; then
360
+ cmd_names="setup new dev event token audit"
361
+ else
362
+ cmd_names="new"
363
+ fi
364
+
365
+ opts="$cmd_names"
366
+
367
+ # Subcommand completion
368
+ case "\${COMP_WORDS[1]}" in
369
+ new)
370
+ opts="workspace hono-micro nest-micro"
371
+ ;;
372
+ event)
373
+ case "\${COMP_WORDS[2]}" in
374
+ publish)
375
+ if [[ -n "$events_str" ]]; then
376
+ opts=$(echo "$events_str" | tr '|' ' ')
377
+ fi
378
+ ;;
379
+ *)
380
+ opts="add list publish"
381
+ ;;
382
+ esac
383
+ ;;
384
+ esac
385
+
386
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
387
+ return 0
388
+ }
389
+
390
+ complete -F _${e}_completions ${e}`;var Qc=(e,t)=>er(go(),`.${t}-completion.${e}`),uo=e=>{let t=go();return e==="zsh"?er(t,".zshrc"):er(t,".bashrc")},el=e=>`[[ -f "${e}" ]] && source "${e}"`,tl=(e,t)=>tr(e)?po(e,"utf-8").includes(t):!1,rl=(e,t)=>{let r=tr(e)?po(e,"utf-8"):"",n=r.endsWith(`
391
+ `)?`${r}${t}
392
+ `:`${r}
393
+ ${t}
394
+ `;mo(e,n,"utf-8")},nl=(e,t)=>{let r=Qc(e,t),n=e==="zsh"?ao(t):co(t);return mo(r,n,"utf-8"),r},lo=(e,t,r)=>{let n=nl(e,t),o=uo(e),s=el(n);return tl(o,s)?(r&&console.log(re.dim(`[${e}] Already configured in ${o}`)),!1):(rl(o,s),r&&console.log(re.green(`[${e}] Added source line to ${o}`)),!0)},ol=()=>(process.env.SHELL||"").includes("zsh")?"zsh":"bash",rr=(e,t=!1)=>{let r=ol();t&&console.log(re.cyan(`Installing ${r} completion...`)),lo(r,e,t);let n=r==="zsh"?"bash":"zsh",o=uo(n);tr(o)&&lo(n,e,t),t&&(console.log(re.green("\u2713 Shell completion installed")),console.log(re.dim(` Run: ${re.cyan("exec $SHELL")} to reload`)))};import{readdir as Fv}from"fs/promises";import{dirname as Dv,join as jv}from"path";import{fileURLToPath as _v}from"url";import{runFlow as Wv}from"@crossdelta/flowcore";var sl={debug:()=>{},info:console.log,warn:console.warn,error:console.error},fo=e=>e!==null&&typeof e=="object",ho=e=>typeof e=="string"&&e.length>0,yo=e=>typeof e=="string",nr=e=>typeof e=="function",il=(e,t)=>fo(e)?[!ho(e.name)&&`commands[${t}]: missing or invalid 'name'`,!yo(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`,!nr(e.run)&&`commands[${t}]: missing 'run' function`].filter(r=>r!==!1):[`commands[${t}]: must be an object`];var vo=e=>{if(!fo(e))return["Plugin must be an object"];let t=[!ho(e.name)&&"Missing or invalid 'name'",!yo(e.version)&&"Missing or invalid 'version'",!Array.isArray(e.commands)&&"Missing 'commands' array",!Array.isArray(e.flows)&&"Missing 'flows' array",!nr(e.setup)&&"Missing 'setup' function"].filter(n=>n!==!1),r=Array.isArray(e.commands)?e.commands.flatMap((n,o)=>il(n,o)):[];return[...t,...r]},Xe=(e,t=sl)=>({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(!nr(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=vo(s);if(i.length>0)throw new Error(`Plugin from ${e} does not conform to PfPlugin interface:
395
+ - ${i.join(`
396
+ - `)}`);let a=s;return r.debug(`Loaded plugin: ${a.name} v${a.version}`),await a.setup(t),{plugin:a,source:e}};import{deriveEventNames as Uv}from"@crossdelta/cloudevents";import{z as y}from"zod";var et=y.object({dependencies:y.record(y.string(),y.string()).default({}),envVars:y.array(y.object({key:y.string(),description:y.string(),required:y.boolean().default(!0)})).default([]),adapterFile:y.string().optional()}),al=y.object({push:y.string().optional(),email:y.string().optional(),slack:y.string().optional(),sms:y.string().optional()}).optional(),cl=y.object({defaults:al,providers:y.object({push:y.record(y.string(),et).optional(),email:y.record(y.string(),et).optional(),slack:y.record(y.string(),et).optional(),sms:y.record(y.string(),et).optional()}).optional()}),Vh=y.object({notifier:cl.optional()});import{z as g}from"zod";var ll=g.object({type:g.literal("event"),eventType:g.string(),stream:g.string().optional()}),pl=g.object({type:g.literal("http"),method:g.enum(["GET","POST","PUT","DELETE","PATCH"]).optional(),path:g.string().optional()}),Co=g.discriminatedUnion("type",[ll,pl]),ml=g.object({type:g.literal("emit.event"),eventType:g.string()}),dl=g.object({type:g.literal("notify"),channel:g.enum(["push","email","slack","sms"]),provider:g.string().optional()}),gl=g.object({type:g.literal("call.http"),name:g.string().optional(),baseUrl:g.string().optional()}),ul=g.object({type:g.literal("persist"),store:g.enum(["db","kv","cache"]),entity:g.string().optional()}),ko=g.discriminatedUnion("type",[ml,dl,gl,ul]),xo=g.object({serviceName:g.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/),framework:g.enum(["hono","nest"]).default("hono"),triggers:g.array(Co).min(1),actions:g.array(ko).default([])});var wl=(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=jt(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`})},bl=(e,t,r)=>{let{path:n,eventType:o}=e;if(r?.dryRun){let i=`
397
+ import { createContract } from '@crossdelta/cloudevents'
398
+ import { z } from 'zod'
399
+
400
+ export const ${or(o)}Contract = createContract({
401
+ type: '${o}',
402
+ schema: z.object({ ... }),
403
+ })
404
+ `.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=Wt(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`}},or=e=>e.split(".").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(""),Tl=(e,t,r)=>{let{path:n,eventType:o,servicePath:s}=e;if(r?.dryRun){let i=`
405
+ import { handleEvent } from '@crossdelta/cloudevents'
406
+ import { ${or(o)}Contract } from '@your-scope/contracts'
407
+
408
+ export default handleEvent(${or(o)}Contract, async (data) => {
409
+ console.log('Processing ${o}:', data)
410
+ // TODO: Implement handler logic
411
+ })
412
+ `.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}},El={"stream.wired":wl,"contract.created":bl,"handler.created":Tl},sr=(e,t,r)=>e.map(n=>{let o=El[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 st}from"path";import{deriveEventNames as hp}from"@crossdelta/cloudevents";var ir=(e,t,r={})=>({ok:!0,operation:e,summary:t,artifacts:r.artifacts??[],changes:r.changes??[],diagnostics:r.diagnostics??[],next:r.next,data:r.data});import{join as cr}from"path";import{readFileSync as $l}from"fs";import{join as Il}from"path";import Al from"handlebars";var ne=(e,t)=>un(e,t??`Templates directory not found. Searched in: ${e.join(", ")}`),ar=(e,t={})=>{let r=$l(e,"utf-8");return Al.compile(r)(t)},tt=e=>(t,r={})=>{let n=Il(e,t);return ar(n,r)};var _=e=>e.toUpperCase().replace(/-/g,"_");var So=e=>e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ");var Rl=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Nl=()=>{let e=Rl(),t=z();return ne([cr(e,"templates","hono-microservice"),cr(e,"..","hono-microservice","templates"),cr(t,"bin","templates","hono-microservice")],"Hono templates directory not found.")},rt=(e,t={})=>tt(Nl())(e,t);function wo(){return rt("tsconfig.json.hbs")}function bo(e="1.2.23"){return rt("Dockerfile.hbs",{bunVersion:e})}function To(){return rt("biome.json.hbs")}function Eo(e,t=[]){return rt("src/config/env.ts.hbs",{envKey:_(e),envVars:t})}var Fl=e=>{let t=["import './config/env'","import '@crossdelta/telemetry'",""];return e&&t.push("import { consumeJetStreams } from '@crossdelta/cloudevents'"),t.push("import { Hono } from 'hono'"),t},Ml=e=>[`const port = Number(process.env.${e}_PORT) || 8080`,"const app = new Hono()","","app.get('/health', (c) => {"," return c.json({ status: 'ok' })","})"],Dl=(e,t)=>["","// Start NATS JetStream consumer","consumeJetStreams({",` streams: [${t.map(r=>`'${r}'`).join(", ")}],`,` consumer: '${e}',`," discover: './src/events/**/*.handler.ts',","})"],jl=()=>["","Bun.serve({"," port,"," fetch: app.fetch,","})","","console.log(`\u{1F680} Service ready at http://localhost:${port}`)"],Ol=e=>{let t=_(e.serviceName);return`${[...Fl(e.hasEvents),"",...Ml(t),...e.hasEvents?Dl(e.serviceName,e.streams):[],...jl()].join(`
413
+ `)}
414
+ `},_l=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)},Ll=e=>`# ${e.serviceName}
415
+
416
+ ## Development
417
+
418
+ \`\`\`bash
419
+ bun install
420
+ bun dev
421
+ \`\`\`
422
+
423
+ Service runs on port: \`${e.port}\`
424
+
425
+ ## Environment Variables
426
+
427
+ - \`${e.envVarName}_PORT\`: Service port (default: ${e.port})
428
+ ${e.hasEvents?`
429
+ ## Events
430
+
431
+ This service consumes from:
432
+ ${e.streams.map(t=>`- ${t}`).join(`
433
+ `)}`:""}
434
+ `,Wl=()=>"",$o={name:"hono-bun",runtime:"bun",framework:"hono",files:[{path:"src/index.ts",content:Ol},{path:"src/config/env.ts",content:e=>Eo(e.serviceName,e.envVars)},{path:"package.json",content:_l},{path:"tsconfig.json",content:()=>wo()},{path:"Dockerfile",content:()=>bo()},{path:"biome.json",content:()=>To()},{path:"README.md",content:Ll},{path:"src/events/.gitkeep",content:Wl,skip:e=>!e.hasEvents}]};import{join as lr}from"path";var Hl=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Gl=()=>{let e=Hl(),t=z();return ne([lr(e,"templates","nest-microservice"),lr(e,"..","nest-microservice","templates"),lr(t,"bin","templates","nest-microservice")],"NestJS templates directory not found.")},K=(e,t={})=>tt(Gl())(e,t);function Io(e,t=3e3){return K("src/main.ts.hbs",{serviceName:e,envKey:_(e),displayName:So(e),defaultPort:t})}function Ao(){return K("src/app.context.ts.hbs",{})}function Ro(){return K("src/events/events.module.ts.hbs",{})}function No(e){return K("src/events/events.service.ts.hbs",{serviceName:e})}function Fo(e="24",t="1.2.23"){return K("Dockerfile.hbs",{nodeVersion:e,bunVersion:t})}function Mo(){return K("biome.json.hbs",{})}function Do(e,t=[]){return K("src/config/env.ts.hbs",{envKey:_(e),envVars:t})}var Bl=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)},Ul=()=>JSON.stringify({extends:"../../../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",experimentalDecorators:!0,emitDecoratorMetadata:!0},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]},null,2),zl=e=>{let t=["Module","HttpModule"],r=["HttpModule"];return e.hasEvents&&(t.push("OnModuleInit"),r.push("EventsModule")),`import { ${t.join(", ")} } from '@nestjs/common'
435
+ ${e.hasEvents?"import { EventsModule } from './events/events.module'":""}
436
+
437
+ @Module({
438
+ imports: [${r.join(", ")}],
439
+ controllers: [],
440
+ providers: [],
441
+ })
442
+ export class AppModule${e.hasEvents?" implements OnModuleInit":""} {
443
+ ${e.hasEvents?`async onModuleInit() {
444
+ // Events module initializes NATS consumer
445
+ }`:""}
446
+ }
447
+ `},Vl=()=>`import { Controller, Get } from '@nestjs/common'
448
+
449
+ @Controller()
450
+ export class AppController {
451
+ @Get('health')
452
+ health() {
453
+ return { status: 'ok' }
454
+ }
455
+ }
456
+ `,Kl=e=>`# ${e.serviceName}
457
+
458
+ ## Development
459
+
460
+ \`\`\`bash
461
+ bun install
462
+ bun dev
463
+ \`\`\`
464
+
465
+ Service runs on port: \`${e.port}\`
466
+
467
+ ## Environment Variables
468
+
469
+ - \`${e.envVarName}_PORT\`: Service port (default: ${e.port})
470
+ ${e.hasEvents?`
471
+ ## Events
472
+
473
+ This service consumes from:
474
+ ${e.streams.map(t=>`- ${t}`).join(`
475
+ `)}`:""}
476
+ `,Jl=()=>"",jo={name:"nest",runtime:"node",framework:"nest",files:[{path:"src/config/env.ts",content:e=>Do(e.serviceName,e.envVars)},{path:"src/main.ts",content:e=>Io(e.serviceName,e.port)},{path:"src/app.module.ts",content:zl},{path:"src/app.controller.ts",content:()=>Vl()},{path:"src/app.context.ts",content:()=>Ao()},{path:"package.json",content:Bl},{path:"tsconfig.json",content:()=>Ul()},{path:"Dockerfile",content:()=>Fo()},{path:"biome.json",content:()=>Mo()},{path:"README.md",content:Kl},{path:"src/events/events.module.ts",content:()=>Ro(),skip:e=>!e.hasEvents},{path:"src/events/events.service.ts",content:e=>No(e.serviceName),skip:e=>!e.hasEvents},{path:"src/events/handlers/.gitkeep",content:Jl,skip:e=>!e.hasEvents}]};var Oo=[$o,jo],_o=e=>{let t=ql(e),r=Oo.find(n=>n.name===t);if(!r)throw new Error(`Template '${e}' not found. Available: ${Oo.map(n=>n.name).join(", ")}`);return r},ql=e=>({"hono-micro":"hono-bun","nest-micro":"nest"})[e]||e;import{join as mr}from"path";import{deriveEventNames as dr}from"@crossdelta/cloudevents";var Lo={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"}]},be={hono:{businessLogicDir:"use-cases",eventsDir:"events",filePattern:"{name}.use-case.ts",suffix:"use-case",handlerDelegatesToBusinessLogic:!0,pathGuards:{forbidDirs:["src/services"]},codingConstraints:Lo},nestjs:{businessLogicDir:"",eventsDir:"events",filePattern:"{name}.service.ts",suffix:"service",handlerDelegatesToBusinessLogic:!1,pathGuards:{forbidDirs:[]},codingConstraints:{appliesTo:["src/domain"],forbiddenPatterns:Lo.forbiddenPatterns}}},Yl=e=>e.replace(/-([a-z])/g,(t,r)=>r.toUpperCase()),Zl=(e,t)=>`../${e}/${t}`,oe=(e,t)=>{let r=be[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:Yl(t),delegateFromHandler:r.handlerDelegatesToBusinessLogic,importFromEvents:r.businessLogicDir?Zl(r.businessLogicDir,o):`./${o}`}},pr=(e,t)=>{let n=`src/${be[e].eventsDir}`,o=`${t}.handler.ts`;return{filePath:`${n}/${o}`,dirPath:n,fileName:o}},Te=e=>`handle-${e.replace(/\./g,"-")}`,nt=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("/")},Xl=(e,t)=>{let r=nt(e);for(let n of t){let o=nt(n);if(r.startsWith(`${o}/`)||r===o)return n}return null},Ql=(e,t)=>{let r=nt(e);return t.some(n=>{let o=nt(n);return r.startsWith(`${o}/`)||r===o})},ep=(e,t,r)=>{let n=[],o=e.split(`
477
+ `);for(let{pattern:s,description:i,code:a}of t){let c=new RegExp(s,"g");for(let l=0;l<o.length;l++)c.test(o[l])&&n.push({code:a,message:i,path:r,line:l+1}),c.lastIndex=0}return n},tp=(e,t)=>{let r=[],n=Xl(e.path,t.pathGuards.forbidDirs);if(n&&r.push({code:"FORBIDDEN_DIR",message:`Path '${e.path}' is in forbidden directory '${n}'`,path:e.path}),Ql(e.path,t.codingConstraints.appliesTo)){let o=ep(e.content,t.codingConstraints.forbiddenPatterns,e.path);r.push(...o)}return r},ot=(e,t)=>{let r=be[e],n=[];for(let o of t)n.push(...tp(o,r));return{valid:n.length===0,violations:n}};var op=(e,t)=>t.map(r=>({kind:"file:write",path:mr(e,r.path),content:r.content})),sp=(e,t,r)=>({kind:"infra:add",serviceName:e,port:t,framework:r.framework,runtime:r.runtime}),ip=(e,t)=>({kind:"env:add",key:`${e}_PORT`,value:t.toString()}),ap=(e,t)=>{let{typeName:r}=dr(e),n=Te(e),o=oe("hono",n);return`import type { ${r} } from '${t}/contracts'
478
+
479
+ /**
480
+ * Handle ${e} event
481
+ *
482
+ * Business logic for processing the event.
483
+ * Keep this pure where possible - side effects via returned data or adapters.
484
+ */
485
+ export const ${o.functionName} = async (data: ${r}): Promise<void> => {
486
+ // TODO: Implement business logic
487
+ // Example: validate data, transform, call external services
488
+ }
489
+ `},cp=(e,t,r)=>{let{contractName:n,typeName:o}=dr(e),s=Te(e),i=oe(r,s);return i.delegateFromHandler?`import { handleEvent } from '@crossdelta/cloudevents'
490
+ import { ${n}, type ${o} } from '${t}/contracts'
491
+ import { ${i.functionName} } from '${i.importFromEvents}'
492
+
493
+ export default handleEvent(${n}, async (data: ${o}) => {
494
+ console.log('\u{1F4E6} [${e}] Event received:', data)
495
+ await ${i.functionName}(data)
496
+ })
497
+ `:`import { handleEvent } from '@crossdelta/cloudevents'
498
+ import { ${n}, type ${o} } from '${t}/contracts'
499
+
500
+ export default handleEvent(${n}, async (data: ${o}) => {
501
+ console.log('\u{1F4E6} [${e}] Event received:', data)
502
+ // TODO: Inject and call service
503
+ })
504
+ `},lp=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:oe(r,"stub").delegateFromHandler?t.events.map(o=>{let s=Te(o),i=oe(r,s);return{kind:"file:write",path:mr(e,i.filePath),content:ap(o,t.workspaceScope)}}):[],pp=(e,t,r)=>!t.hasEvents||t.events.length===0?[]:t.events.map(n=>{let{kebab:o}=dr(n),s=pr(r,o);return{kind:"file:write",path:mr(e,s.filePath),content:cp(n,t.workspaceScope,r)}}),mp=e=>e==="hono"?"hono":e==="nest"?"nestjs":"hono",Wo=(e,t,r,n)=>{let o=mp(n.framework),s=op(e,t),i=lp(e,r,o),a=pp(e,r,o),c=sp(r.serviceName,r.port,n),l=ip(r.envVarName,r.port);return[...s,...i,...a,c,l]};import{existsSync as dp,readdirSync as gp,readFileSync as up}from"fs";import{join as Ho}from"path";var Go=4001,fp=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},Bo=e=>{try{let t=Ho(e,"infra","services");return dp(t)?gp(t).filter(n=>n.endsWith(".ts")).reduce((n,o)=>{let s=up(Ho(t,o),"utf-8"),i=fp(s);return i!==null&&n.add(i),n},new Set):new Set}catch(t){return console.warn("Failed to scan ports:",t),new Set}},gr=(e,t)=>e.has(t)?gr(e,t+1):t;var yp=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)`)},vp=(e,t,r)=>{if(t){if(t.startsWith("/"))return t;if(t.startsWith("."))return st(r,t);if(t.includes("/"))return st(r,t)}let n=S(r);return st(r,n.services,e)},Cp=e=>[...new Set(e.map(t=>hp(t).streamName))],kp=(e,t,r,n)=>{let s=C(t).packageName.split("/")[0],i=e.events??[],a=i.length>0||e.hasEvents||!1,c=i.length>0?Cp(i):e.streams??[];return{serviceName:e.name,packageName:`${s}/${e.name}`,servicePath:r.replace(`${t}/`,""),port:n,envVarName:_(e.name),hasEvents:a,streams:c,events:i,workspaceScope:s,envVars:e.envVars}},xp=(e,t)=>e.files.filter(r=>!r.skip||!r.skip(t)).map(r=>({path:r.path,content:r.content(t)})),Pp=(e,t,r)=>[...e.map(o=>({type:"file",path:st(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"}],Sp=e=>[{command:`cd ${e} && bun dev`,description:"Start this service"},{command:"pf dev",description:"Start all services"}],Uo=e=>{yp(e.name);let t=e.workspaceRoot??h(),r=vp(e.name,e.path,t),n=e.port??gr(Bo(t),Go),o=kp(e,t,r,n),s=_o(e.type),i=xp(s,o),a=Wo(r,i,o,s),c=Pp(i,e.name,r),l=Sp(r);return ir("service.generate",`Generated ${e.name} service (port ${n})`,{artifacts:c,changes:a,next:l,data:{serviceName:e.name,servicePath:r,port:n,vars:o}})},zo=e=>{let t=Uo(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}};import w from"chalk";import{execa as wp}from"execa";import{createJiti as bp}from"jiti";var ur=async e=>{let{stdout:t}=await wp("sh",["-c",e]);return t.trim()},Tp="pf-local-nats",Ep="2.10-alpine",$p=4222,Ip=8222,Ap=e=>({clientPort:e.clientPort??$p,monitoringPort:e.monitoringPort??Ip,containerName:e.containerName??Tp,version:e.version??Ep}),Rp=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"],Np=e=>({containerName:e.containerName,clientUrl:`nats://localhost:${e.clientPort}`,monitoringUrl:`http://localhost:${e.monitoringPort}`}),Fp=async()=>{try{return await ur("docker info"),!0}catch{return!1}},Mp=async e=>{try{return(await ur(`docker ps -q -f name=${e}`)).length>0}catch{return!1}};var Dp=async e=>{let t=Rp(e);try{return await ur(`docker ${t.join(" ")}`),{success:!0,value:Np(e)}}catch{return{success:!1}}},jp=e=>{console.log(w.green("\u2713 NATS started")),console.log(w.dim(` Client: ${e.clientUrl}`)),console.log(w.dim(` Monitoring: ${e.monitoringUrl}`)),console.log(w.dim(" Streams: ephemeral, auto-created by services")),console.log("")},Vo=async(e={})=>{let t=Ap(e);if(!await Fp())return console.log(w.yellow("\u26A0\uFE0F Docker not available - skipping NATS (services may fail)")),!1;if(await Mp(t.containerName))return console.log(w.dim("\u2713 NATS already running")),!0;console.log(w.cyan("\u{1F680} Starting development infrastructure...")),console.log(w.dim(" NATS with JetStream (ephemeral)"));let r=await Dp(t);return r.success?(jp(r.value),!0):(console.error(w.red("\u2717 Failed to start NATS")),!1)},Op=e=>e.map(t=>({stream:t,subjects:[`${t.toLowerCase()}.*`],config:{storage:"memory",retention:"limits",maxAge:36e5}})),_p=e=>Array.from(new Set(Object.values(e).filter(t=>t!==null&&typeof t=="object"&&"channel"in t).map(t=>t.channel?.stream).filter(t=>!!t))),fr=async e=>{try{let{ensureJetStreams:t}=await import("@crossdelta/cloudevents"),{indexPath:r}=C(e),o=await bp(e,{moduleCache:!1}).import(r,{default:!0}),s=_p(o);if(s.length===0){console.log(w.dim(" No streams found in contracts"));return}let i=Op(s);await t({streams:i}),console.log(w.dim(` Created ${s.length} ephemeral stream(s): ${s.join(", ")}`))}catch(t){console.log(w.yellow(` \u26A0\uFE0F Stream creation failed: ${t instanceof Error?t.message:"Unknown error"}`)),console.log(w.dim(" Stream auto-creation will happen on first publish"))}};function Ko(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
505
+ import { ports } from '@crossdelta/infrastructure'
506
+
507
+ /**
508
+ * ${e} service configuration.
509
+ *
510
+ * Internal-only service - accessed via cluster DNS:
511
+ * http://${e}.{namespace}.svc.cluster.local:${t}
512
+ */
513
+ const config: K8sServiceConfig = {
514
+ name: '${e}',
515
+ ports: ports().http(${t}).build(),
516
+ replicas: 1,
517
+ healthCheck: { httpPath: '/health' },
518
+ resources: {
519
+ requests: { cpu: '25m', memory: '64Mi' },
520
+ limits: { cpu: '100m', memory: '128Mi' },
521
+ },
522
+ }
523
+
524
+ export default config
525
+ `}function Jo(e,t){return`import type { K8sServiceConfig } from '@crossdelta/infrastructure'
526
+ import { ports } from '@crossdelta/infrastructure'
527
+
528
+ /**
529
+ * ${e} service configuration.
530
+ *
531
+ * Internal-only service - accessed via cluster DNS:
532
+ * http://${e}.{namespace}.svc.cluster.local:${t}
533
+ */
534
+ const config: K8sServiceConfig = {
535
+ name: '${e}',
536
+ ports: ports().http(${t}).build(),
537
+ replicas: 1,
538
+ healthCheck: { httpPath: '/health' },
539
+ resources: {
540
+ requests: { cpu: '50m', memory: '64Mi' },
541
+ limits: { cpu: '150m', memory: '128Mi' },
542
+ },
543
+ }
544
+
545
+ export default config
546
+ `}import L from"chalk";import Wp from"terminal-link";var it="integrations-run";import{z as P}from"zod";var Lp=P.object({name:P.string(),description:P.string(),link:P.string().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()}),qo=P.array(Lp);var Yo=e=>{try{return qo.parse(e)}catch(t){throw new Error(t.issues.map(r=>` - Path ${r.path.join(". ")} : ${r.message}`).join(`
547
+ `))}};var R=()=>{try{let e=Et("bin/integration.collection.json");return Yo(e)}catch(e){throw new Error(`Failed to load integrations!
548
+ Check your integration.collection.json:
549
+ ${e.message}`)}},se=()=>R().reduce((t,r)=>(r.initial&&t.push(r.name),t),[]),Hp=e=>!!e?.name&&!!e?.link&&!!e?.description,at=e=>{let t=R();if(!t?.length||!e?.length)return;let r=e.map(n=>t.find(o=>o.name===n)).filter(Hp);r.length&&(d.breakLine().log("\u{1F50C} Installed Integrations:"),r.forEach(({name:n,link:o,description:s})=>{let i=d.getStoredLogs(`${it}:${n}`);o&&d.log(`${Wp(L.cyan(n),o)} - ${s}`),i.length&&d.log(i.map(a=>` \u203A ${L.dim(a.message)}`).join(`
550
+ `))}))},Gp=e=>e.toUpperCase().replace(/-/g,"_"),Zo=(e,t)=>{let r=Gp(e);d.breakLine().log(L.bold("Environment variables:")).log(L.dim(" Local:")).log(L.cyan(` ${r}_PORT=${t}`)).log(L.cyan(` ${r}_URL=http://localhost:${t}`)).breakLine().log(L.dim(" Production (auto-configured):")).log(L.cyan(` ${r}_PORT=${t}`)).log(L.cyan(` ${r}_URL=http://${e}:${t}`))};import Xo from"chalk";var Bp=e=>{let t=e.match(/^(@?[^@]+)@(.+)$/);return t?{name:t[1],version:t[2]}:{name:e,version:"latest"}},Qo=async e=>{let{selectedIntegrations:t,cwd:r,packageManager:n=x(),task:o}=e;if(!t?.length||!o)return;let s=Up(t,r,n,o);await Me(o,s)},Up=(e,t,r,n)=>{let s=R()?.filter(a=>e.includes(a.name))?.flatMap(a=>a.install.map(c=>{let{name:l,version:p}=Bp(c);return{title:Xo.cyanBright(`Adding ${c} (${a.name})`),fn:async()=>{Tt(`dependencies.${l}`,p,t)}}})),i={title:Xo.cyanBright("Installing packages..."),fn:async()=>{await M({cwd:t,packageManager:r,task:n})}};return[...s??[],i]};import zp from"chalk";var es=async e=>{let{selectedIntegrations:t,cwd:r,task:n}=e;if(!t?.length||!n)return;let o=Vp(t,r,n,e.packageManager);await Me(n,o)},Vp=(e,t,r,n)=>R().filter(s=>e.includes(s.name)&&s.run?.length).flatMap(s=>(s.run||[]).map(i=>({title:zp.cyanBright(`Running "${i}" for ${s.name}
551
+ `),fn:()=>Kp(s,i,t,r,n)}))),Kp=async(e,t,r,n,o)=>{let s=`${it}:${e.name}`;try{if(e.interactive)return Xr(t,[],{cwd:r,context:s,task:n,manager:o});await fe(t,[],{cwd:r,task:n,context:s})}catch(i){d.error(`Failed to run command "${t}" for ${e.name}: ${i.message}`)}};import{readFileSync as WC,writeFileSync as HC}from"fs";import{join as BC}from"path";import{join as KC}from"path";import{ListrEnquirerPromptAdapter as Ee}from"@listr2/prompt-adapter-enquirer";var v=e=>({select:async t=>e.prompt(Ee).run({type:"select",message:t.message,choices:t.choices}),confirm:async t=>e.prompt(Ee).run({type:"confirm",message:t.message,initial:t.initial??!1}),toggle:async t=>e.prompt(Ee).run({type:"toggle",message:t.message,enabled:t.enabled??"Yes",disabled:t.disabled??"No",initial:t.initial??!1}),input:async t=>e.prompt(Ee).run({type:"input",message:t.message,initial:t.initial,validate:t.validate}),multiSelect:async t=>e.prompt(Ee).run({type:"MultiSelect",message:t.message,hint:t.hint,initial:t.initial,choices:t.choices})});import{readFileSync as ak}from"fs";import{join as lk}from"path";import Ck from"chalk";import xk from"cli-table3";function ct(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}async function ts(e,t,r={},n=[],o=[]){if(!e){console.error("Subcommand is not defined.");return}let s=n.map(l=>t[l]).filter(l=>l!==void 0),i=o.map(l=>{let p=t[l];if(!(p===!1||p===void 0))return p===!0?`--${ct(String(l))}`:`--${ct(String(l))}=${String(p)}`}).filter(l=>l!==void 0),a=Object.entries(r).map(([l,p])=>{if(!(p===!1||p===void 0))return p===!0?`--${ct(l)}`:`--${ct(l)}=${String(p)}`}).filter(l=>l!==void 0),c=[...s,...i,...a].map(String);await e.parseAsync(c,{from:"user"})}import{basename as ym}from"path";import J from"chalk";var ie={title:"Confirm creation",enabled:e=>!e.userConfirmed,task:async(e,t)=>{let r=v(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 hr,readdirSync as qp,readFileSync as Yp,writeFileSync as Zp}from"fs";import{basename as Xp,join as yr}from"path";var Qp=4001,em=4e3;function tm(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 rm(e,t){let r=t?Qp:em,n=new Set;if(!hr(e))return r;let o=qp(e).filter(i=>i.endsWith(".ts"));for(let i of o){let a=yr(e,i);try{let c=Yp(a,"utf-8"),l=tm(c);for(let p of l)n.add(p)}catch{}}let s=r;for(;n.has(s);)s++;return s}function nm(e){return Xp(e)}var lt={title:"Creating infrastructure service config",task:async(e,t)=>{let r=nm(e.projectName),n=h(),o=yr(n,"infra","services");if(!hr(o)){t.title="Skipping infra config (no infra/services directory found)";return}let s=yr(o,`${r}.ts`);if(hr(s)){t.title=`Service config already exists: infra/services/${r}.ts`;return}let i=rm(o,!0);e.assignedPort=i;let a=e.serviceType==="hono"?Ko(r,i):Jo(r,i);Zp(s,a),t.title=`Created infra/services/${r}.ts (port: ${i})`}};import{execSync as pt}from"child_process";import{existsSync as om}from"fs";import{join as sm}from"path";var im=()=>{try{return pt("git --version",{stdio:"ignore"}),!0}catch{return!1}},am=e=>om(sm(e,".git")),rs={title:"Initializing git repository",enabled:()=>im(),skip:e=>am(e.cwd)?"Already a git repository":!1,task:async(e,t)=>{try{pt("git init",{cwd:e.cwd,stdio:"ignore"}),pt("git add -A",{cwd:e.cwd,stdio:"ignore"}),pt('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 ns from"chalk";var ae={title:"Installing Bun",enabled:e=>!!e.shouldInstallBun&&!Yt(),task:async(e,t)=>$(t,async r=>{await Zn(t),e.elapsedTime+=r(),t.title=`Bun installed successfully. (${e.elapsedTime}s)`})},ce={enabled:e=>!Yt()&&!e.shouldInstallBun&&!e.packageManager,task:async(e,t)=>{let r=v(t);console.log(["",`${ns.magenta.bold("Bun")} is a fast JavaScript runtime, package manager, bundler, and test runner: ${ns.underline("https://bun.sh")}`,Xn(),Qn()].join(`
552
+ `)),e.shouldInstallBun=await r.toggle({message:"Would you like to use Bun? (recommended)",initial:!0}),e.shouldInstallBun&&(e.packageManager="bun")}};import os from"chalk";var mt={title:"Install integrations",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>$(t,async r=>{let{selectedIntegrations:n,cwd:o,packageManager:s}=e;await Qo({selectedIntegrations:n,packageManager:s,cwd:o,task:t}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}},dt={title:"Select integrations",enabled:e=>e.selectedIntegrations.length===0,task:async(e,t)=>{let r=v(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:se().map((n,o)=>o),choices:e.availableIntegrations.map(({name:n,description:o})=>({name:n,message:[os.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=>os.bold(`\u2022 ${n}`))].join("\\n")}};var ss={title:"Install Nest CLI",task:async(e,t)=>$(t,async r=>{await Zr({packages:["@nestjs/cli"],task:t,cwd:e.cwd}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1e3}};var gt={title:"Install dependencies",task:async(e,t)=>$(t,async r=>{await M({cwd:e.cwd,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()})};import cm from"chalk";var le={enabled:e=>!e.removeDir&&!Fe(e.cwd),task:async(e,t)=>{let r=v(t);if(e.removeDir=await r.toggle({message:cm.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}),!e.removeDir)throw new Error("Project creation was canceled by the user.")}},pe={enabled:e=>!!e.removeDir,task:async e=>Br(e.cwd)};var ut={title:"Run integration commands",enabled:e=>e.selectedIntegrations.length>0,task:async(e,t)=>$(t,async r=>{let{selectedIntegrations:n,cwd:o}=e;await es({selectedIntegrations:n,cwd:o,task:t,packageManager:e.packageManager}),e.elapsedTime+=r()}),rendererOptions:{outputBar:1}};var lm=["services/my-hono-service","services/my-nest-service","my-platform"],me={enabled:e=>e.skipInputPrompts||e.userConfirmed?!1:e.projectName?lm.includes(e.projectName):!0,task:async(e,t)=>{let r=v(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(e.projectName))}};import is from"chalk";var de={title:"Select Package manager",task:async(e,t)=>{if(e.packageManager??=Rt(),e.packageManager){t.title=`Using ${is.bold(e.packageManager)} as package manager.`;return}let r=v(t);e.packageManager=await r.select({message:"Which package manager would you like to use?",choices:Yr().map(n=>({name:n,value:n}))}),t.title=`Using ${is.bold(e.packageManager)} as package manager.`}};import ft from"chalk";var as={title:"GitHub repository owner",task:async(e,t)=>{if(e.githubOwner){t.title=`GitHub owner: ${ft.bold(e.githubOwner)}`;return}let r=v(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: ${ft.bold(e.githubOwner)}`}},cs={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=v(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 ls={title:"Pulumi stack name",task:async(e,t)=>{if(e.pulumiStackBase){t.title=`Pulumi stack: ${ft.bold(e.pulumiStackBase)}`;return}let r=e.githubOwner||"myorg",n=e.projectName?.replace(/[^a-zA-Z0-9-]/g,"-")||"myproject",o=`${r}/${n}`,s=v(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: ${ft.bold(e.pulumiStackBase)}`}};import{mkdirSync as pm,writeFileSync as mm}from"fs";import{dirname as dm}from"path";var gm=e=>e==="hono"?"hono":"nestjs",um=e=>{let t=dm(e.path);pm(t,{recursive:!0}),mm(e.path,e.content,"utf-8")},fm=(e,t)=>{let r=e.map(o=>{let s=o.path.match(/services\/[^/]+\/(.+)$/);return{path:s?s[1]:o.path,content:o.content}}),n=ot(t,r);if(!n.valid){let o=n.violations.map(s=>` - ${s.code}: ${s.message} (${s.path})`).join(`
553
+ `);throw new Error(`Policy violation(s) detected:
554
+ ${o}`)}e.forEach(um)},hm=async(e,t,r)=>{let{projectName:n,serviceType:o,hasEvents:s,streams:i}=e,a=n.split("/").pop()||n,l=zo({type:o==="hono"?"hono-micro":"nest",name:a,path:n,hasEvents:s,streams:i}),p=l.effects.filter(f=>f.kind==="file:write"),m=gm(o);fm(p,m),e.assignedPort=l.port,e.elapsedTime+=r(),t.title=`Generated ${a} (port ${l.port}, ${e.elapsedTime}s)`},ht={title:"Generating service",task:async(e,t)=>$(t,async r=>{await hm(e,t,r)})};var vm=e=>{let t=(e||"my-hono-service").trim();return t.includes("/")||t.startsWith(".")?t:`${S().services}/${t}`},Cm=async(e,t)=>{let{valid:r,config:n,error:o}=ee();if(!r||!n){A(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=vm(e.name),i=t.packageManager||x(),a=await Ue(t.description);if(ze(s,n,a),await Ve({servicePath:s,description:a,serviceType:"hono",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(J.dim("Next steps:")).log(J.dim(` ${J.cyan("pf dev")} - Start all services`)).log(J.dim(` ${J.cyan(`cd ${s} && bun dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},ps=W({name:"hono-micro",description:"Create a new Hono microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new hono-micro my-service --ai -d "Payment processing service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:Cm,buildContext:async(e,t)=>{let r=(e.name??"my-hono-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${S().services}/${r}`);let n=E(r),o=t.packageManager??(t.yes&&x()),s=R(),i=t.yes?se():[],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:[me,le,ce,de,dt,ie],actions:[pe,ae,ht,lt,mt,ut],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r,assignedPort:n})=>{d.breakLine().log(J.bold.green("Hono Microservice created successfully!")),at(r),Zo(ym(e),n??8080);let o=t??x();d.breakLine().log(`To start the project, run:
555
+ ${J.bold(`cd ${e} && ${o} run dev`)}`).breakLine().log("Happy shipping with Hono! \u26A1\uFE0F").breakLine()}});import q from"chalk";var km=e=>{let t=(e||"my-nest-service").trim();return t.includes("/")||t.startsWith(".")?t:`${S().services}/${t}`},xm=async(e,t)=>{let{valid:r,config:n,error:o}=ee();if(!r||!n){A(new Error(o||"AI configuration is invalid"),{exit:!1});return}let s=km(e.name),i=t.packageManager||x(),a=await Ue(t.description);if(ze(s,n,a),await Ve({servicePath:s,description:a,serviceType:"nest",packageManager:i},n))d.breakLine().success("Service generated successfully!").breakLine().log(q.dim("Next steps:")).log(q.dim(` ${q.cyan("pf dev")} - Start all services`)).log(q.dim(` ${q.cyan(`cd ${s} && bun run start:dev`)} - Start this service only`)).breakLine();else throw new Error("Service generation failed")},ms=W({name:"nest-micro",description:"Create a new NestJS microservice with the Crossdelta setup. Use --ai for AI-powered generation.",arguments:[["[name]","Name or path of the service"]],options:[["-P, --package-manager <manager>","Specify the package manager (e.g., npm, yarn, pnpm, bun)"],["-y, --yes","Skip all prompts and use default values"],["--ai","Use AI to generate service code based on a description"],["-d, --description <description>","Service description for AI generation (requires --ai)"],["--remove-dir","Remove existing directory before creating (used internally)"]],exampleUsage:'platform new nest-micro my-service --ai -d "User authentication service"',shouldSkipWorkflow:(e,t)=>!!t.ai,onSkipWorkflow:xm,buildContext:async(e,t)=>{let r=(e.name??"my-nest-service").trim();!r.includes("/")&&!r.startsWith(".")&&(r=`${S().services}/${r}`);let n=E(r),o=t.packageManager??(t.yes&&x()),s=t.packageManager==="bun",i=R(),a=t.yes?se():[],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:[me,le,ce,de,dt,ie],actions:[pe,ae,ht,lt,gt,ss,mt,ut],onComplete:({projectName:e,packageManager:t,selectedIntegrations:r})=>{d.breakLine().log(q.bold.green("NestJS Microservice created successfully!")),at(r),d.breakLine().log(`To start the project, run:
556
+ ${q.bold(`cd ${e} && ${t} run start:dev`)}`).breakLine().log("Happy coding! \u{1F389}").breakLine()}});import N from"chalk";import{spawnSync as wm}from"child_process";import{chmodSync as bm,existsSync as kr,mkdirSync as Tm,readFileSync as Em,writeFileSync as xr}from"fs";import{dirname as $m,join as Pr}from"path";import{existsSync as Pm}from"fs";import{join as yt}from"path";var Sm=()=>typeof import.meta?.url=="string"?D(import.meta.url):typeof __dirname=="string"?__dirname:process.cwd(),Cr=()=>{let e=Sm(),t=z();return ne([yt(e,"templates","workspace"),yt(e,"..","..","..","..","templates","workspace"),yt(t,"bin","templates","workspace")],"Workspace templates directory not found.")},ds=()=>{let e=Cr(),t=yt(e,"packages","contracts");if(!Pm(t))throw new Error(`Contracts templates directory not found at: ${t}`);return t},vt=(e,t)=>ar(e,t);var gs=e=>{e.endsWith(".sh")&&bm(e,493)},Im=[{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/check-path-changes/action.yml",output:".github/actions/check-path-changes/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/check-path-changes/index.js",output:".github/actions/check-path-changes/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/detect-skipped-services/action.yml",output:".github/actions/detect-skipped-services/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/action.yml",output:".github/actions/generate-scope-matrix/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/generate-scope-matrix/index.js",output:".github/actions/generate-scope-matrix/index.js",isStatic:!0,isGitHubCI:!0},{template:".github/actions/prepare-build-context/action.yml",output:".github/actions/prepare-build-context/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/action.yml",output:".github/actions/resolve-scope-tags/action.yml",isStatic:!0,isGitHubCI:!0},{template:".github/actions/resolve-scope-tags/index.js",output:".github/actions/resolve-scope-tags/index.js",isStatic:!0,isGitHubCI:!0}],us={title:"Creating workspace structure",task:async(e,t)=>{if(kr(e.cwd)){t.title="Workspace directory already exists, skipping...";return}let r=Cr(),n=e.includeGitHubCI??!0,o=e.packageManager||"bun",s=c=>{try{let m=wm(c,["--version"],{encoding:"utf-8",timeout:5e3}).stdout?.trim();if(m&&/^\d+\.\d+/.test(m))return`${c}@${m}`}catch{}return{bun:"bun@1.2.7",npm:"npm@10.9.2",yarn:"yarn@4.6.0",pnpm:"pnpm@9.15.2"}[c]||`${c}@latest`},i={projectName:e.projectName,scope:`@${e.projectName}`,githubOwner:e.githubOwner||"",pulumiStackBase:e.pulumiStackBase||e.projectName,packageManager:o,packageManagerVersion:s(o)},a=Im.filter(c=>!(c.isGitHubCI&&!n||c.forPackageManager&&c.forPackageManager!==o));for(let c of a){let l=Pr(e.cwd,c.output),p=$m(l);if(kr(p)||Tm(p,{recursive:!0}),c.isStatic){let m=Pr(r,c.template);kr(m)?xr(l,Em(m)):xr(l,""),gs(l)}else{let m=Pr(r,c.template),f=vt(m,i);xr(l,f),gs(l)}}t.title="Workspace structure created"}};import{existsSync as hs,mkdirSync as fs,readFileSync as Am,writeFileSync as Rm}from"fs";import{join as Ct}from"path";import Nm from"chalk";var Fm=()=>{let e=Ct(process.cwd(),"package.json");if(!hs(e))throw new Error("Root package.json not found. Please run this command from the workspace root.");let r=JSON.parse(Am(e,"utf-8")).name;if(!r)throw new Error('package.json must have a "name" field');return r.startsWith("@")?r:`@${r}`},Mm=()=>{let e=Fm(),{relativePath:t,packagePath:r}=C();if(hs(r))throw new Error(`${t} already exists. Remove it first if you want to regenerate.`);let n=ds(),o={scope:e,workspaceName:e.replace("@","").replace("/","-")};fs(r,{recursive:!0}),fs(Ct(r,"src","events"),{recursive:!0});let s=[{template:"package.json.hbs",output:"package.json"},{template:"tsconfig.json.hbs",output:"tsconfig.json"},{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=Ct(n,i.template),c=Ct(r,i.output),l=vt(a,o);Rm(c,l,"utf-8")}},ys={title:"Initializing contracts package",task:(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),Mm(),t.title="Contracts package initialized"}catch(n){throw t.title=Nm.red(`Contracts package failed: ${n.message}`),n}finally{process.chdir(r)}}};import Dm from"chalk";var vs={title:"Registering shell completion",task:async(e,t)=>{let r=process.cwd();try{process.chdir(e.cwd),await we(),t.title="Shell completion registered"}catch{t.title=Dm.dim("Shell completion skipped")}finally{process.chdir(r)}}};var Cs=W({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=E(r),o=!!t.yes,s=t.packageManager??(o?x():void 0),i=t.packageManager==="bun",a=t.githubOwner??(o?"my-org":void 0),c=t.pulumiStack??(o?`${a}/${r}`:void 0),l=t.github===!1?!1:o?!0:void 0,p=!!e.name,m=t.removeDir||o;return{cwd:n,projectName:r,shouldInstallBun:i,packageManager:s,elapsedTime:0,userConfirmed:o,skipInputPrompts:p&&!o,removeDir:m,githubOwner:a,pulumiStackBase:c,includeGitHubCI:l}},prompts:[{enabled:e=>!e.userConfirmed,task:async(e,t)=>{try{let r=h();if(!await v(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=N.yellow("Warning: Creating nested workspace")}catch(r){if(Y(r)&&r.message?.includes("cancelled"))throw r;t.title="No existing workspace detected"}}},me,le,as,cs,ls,ce,de,ie],actions:[pe,ae,us,ys,gt,rs,vs],onComplete:({projectName:e,includeGitHubCI:t})=>{d.breakLine().log(N.bold.green("Workspace created successfully!")),d.breakLine().log(N.bold("Next steps:")).log(` 1. ${N.cyan(`cd ${e}`)}`).log(` 2. ${N.cyan("exec $SHELL")} ${N.dim("(enable tab completion)")}`),t&&d.breakLine().log(N.bold("GitHub Setup:")).log(" Configure these secrets in your GitHub repository:").log(` \u2022 ${N.yellow("PULUMI_ACCESS_TOKEN")} - Pulumi Cloud access token`).log(` \u2022 ${N.yellow("DIGITALOCEAN_TOKEN")} - DigitalOcean API token`).log(` \u2022 ${N.yellow("NPM_TOKEN")} - (optional) NPM token for private packages`),d.breakLine().log(N.bold("Structure created:")).log(" apps/ # Frontend applications").log(" services/ # Backend microservices").log(" packages/").log(" \u2514\u2500\u2500 contracts/ # Shared event contracts").log(" infra/").log(" \u251C\u2500\u2500 index.ts # Pulumi entry point").log(" \u251C\u2500\u2500 services/ # Service configs").log(" \u251C\u2500\u2500 Pulumi.yaml # Pulumi project config").log(" \u2514\u2500\u2500 Pulumi.dev.yaml # Dev stack config"),t&&d.log(" .github/").log(" \u251C\u2500\u2500 workflows/ # CI/CD workflows").log(" \u2514\u2500\u2500 actions/ # Custom actions"),d.breakLine().log("Happy coding! \u{1F389}").breakLine()}});var $e=[{name:"Hono Microservice",value:"hono-micro",command:ps,supportsAi:!0},{name:"Nest Microservice",value:"nest-micro",command:ms,supportsAi:!0},{name:"Workspace (Infrastructure)",value:"workspace",command:Cs,supportsAi:!1}],ks=()=>{let e=W({name:"new",description:"Create a new project",arguments:[["[type]","Type of the project (e.g., nest-micro, hono-micro, workspace)"]],exampleUsage:"platform new hono-micro test-service",buildContext:t=>({projectType:t.type??"",useAi:!1,aiDescription:"",elapsedTime:0,cwd:process.cwd()}),prompts:[{enabled:t=>!t.projectType,task:async(t,r)=>{let o=await v(r).select({message:"Select Project type",choices:$e});t.projectType=$e.find(s=>s.name===o)?.value||"",r.title=`Using ${G.bold(o)}`}},{enabled:t=>t.projectType!=="workspace"&&t.projectType!=="",task:async(t,r)=>{try{h(),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(`
557
+ `);throw new Error(n)}}},{enabled:t=>t.projectType==="workspace",task:async(t,r)=>{try{let n=h();if(!await v(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=G.yellow("Warning: Creating nested workspace")}catch(n){if(Y(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 v(r).input({message:s,initial:o});t.servicePath=a.trim(),r.title=`Path: ${G.dim(a)}`}},{enabled:t=>!!$e.find(n=>n.value===t.projectType)?.supportsAi&&ee().valid,task:async(t,r)=>{let o=await v(r).toggle({message:"Use AI to generate service code?",initial:!1});t.useAi=o,r.title=o?G.cyan("\u{1F916} AI-powered generation"):"Standard scaffolding"}},{enabled:t=>t.useAi,task:async(t,r)=>{let o=await v(r).input({message:"Describe what this service should do:"});t.aiDescription=o,r.title=`Description: ${G.dim(o.slice(0,50))}${o.length>50?"...":""}`}},{enabled:t=>{if(!t.servicePath)return!1;let r=E(t.servicePath);return!Fe(r)},task:async(t,r)=>{if(!await v(r).toggle({message:G.bold("\u26A0\uFE0F Overwrite existing directory?"),initial:!1}))throw new Error("Project creation was canceled by the user.");t.shouldRemoveDir=!0,r.title=G.yellow("Will overwrite existing directory")}},{title:"Confirm creation",enabled:t=>t.projectType!=="workspace",task:async(t,r)=>{if(!await v(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=>{$e.find(s=>s.value===t.projectType)||e.error(G.red(`Project type ${t.projectType} is not supported.`));let r=e.commands.find(s=>s.name()===t.projectType),n={};t.projectType!=="workspace"&&(n.yes=!0);let o=[];t.servicePath&&o.push("servicePath"),t.shouldRemoveDir&&(n.removeDir=!0),t.useAi&&(n.ai=!0,n.description=t.aiDescription),await ts(r,t,n,o)}});for(let t of $e)e.addCommand(t.command);return e};import{Command as Wm}from"commander";import{existsSync as xt,readdirSync as xs,unlinkSync as jm}from"fs";import{join as kt}from"path";import Om from"chokidar";var _m=e=>{let t=kt(e,"infra","services");if(!xt(t))return[];let r=xs(t).filter(a=>a.endsWith(".ts")&&a!=="index.ts").map(a=>a.replace(".ts","")),n=S(e),o=a=>{let c=kt(e,a);return xt(c)?xs(c).filter(l=>xt(kt(c,l,"package.json"))):[]},s=[...o(n.services),...o(n.apps)],i=r.filter(a=>!s.includes(a));for(let a of i)jm(kt(t,`${a}.ts`));return i},Sr=async e=>{let t=_m(e);t.length>0&&console.log(`\u{1F9F9} Cleaned ${t.length} orphaned infra config(s): ${t.join(", ")}`),await M({cwd:e,quiet:!0}),await he("generate-env",{cwd:e})},wr=async e=>{await Vo()&&await fr(e)},Ps=e=>{let{eventsPath:t}=C(e);if(!xt(t))return async()=>{};let r=Re(async()=>{console.log(`
558
+ \u{1F4E6} Contracts changed, updating streams...`),await fr(e)},500),n=Om.watch(`${t}/**/*.ts`,{ignoreInitial:!0,ignored:["**/index.ts","**/*.test.ts","**/*.spec.ts"]});return n.on("add",r).on("change",r),async()=>{await n.close()}};import Ss from"chalk";var br=e=>new Promise(t=>setTimeout(t,e)),ws=e=>process.stdout.write(`${e}
559
+ `),Lm=()=>{process.stdout.write("\x1B[2J\x1B[3J\x1B[H"),process.stdout.isTTY&&process.stdout.write("\x1Bc")},bs=()=>({turboProcess:null,isRestarting:!1,isShuttingDown:!1}),Tr=async(e,t)=>{let r=zr(".env.local",t);r.length>0&&(await Jr(r),await br(50));let{dev:n}=De(t),o=n.filter.flatMap(s=>["--filter",s]);ws(Ss.cyan("\u{1F525} Starting services...")),ws(Ss.dim(` Command: turbo run ${wt} --continue${o.length?` ${o.join(" ")}`:""}`)),e.isShuttingDown=!1,e.isRestarting=!1,e.turboProcess=Kr("turbo",["run",wt,"--continue","--no-daemon",...o],{cwd:t,envFile:".env.local",onExit:s=>{e.isRestarting||e.isShuttingDown||s===1&&process.exit(T.SUCCESS)}})},Pt=async e=>{let t=e.turboProcess?.pid;if(t){e.isShuttingDown=!0;try{try{process.kill(-t,"SIGTERM")}catch{e.turboProcess?.kill("SIGTERM")}await br(200);try{process.kill(-t,"SIGKILL")}catch{}await br(30)}catch{}e.turboProcess=null,Lm()}};var Ts=new Wm("dev").description("Start development mode with auto-reload").action(async()=>{let e;try{e=h()}catch(a){A(a);return}let t=bs(),r=async()=>{await Sr(e),await wr(e),await Tr(t,e)},o=Re(async()=>{t.isRestarting||t.isShuttingDown||(t.isRestarting=!0,console.log(`
560
+ \u{1F504} Change detected, restarting...
561
+ `),await Pt(t),await Sr(e),await wr(e),await Tr(t,e),t.isRestarting=!1)},300),s=async()=>{t.isShuttingDown||(console.log(`
562
+ \u{1F6D1} Shutting down...`),await Pt(t),process.exit(T.SUCCESS))};process.removeAllListeners("SIGINT"),process.removeAllListeners("SIGTERM"),process.on("SIGINT",s),process.on("SIGTERM",s);let i;try{await r(),Hr(e,o),i=Ps(e),console.log(`
563
+ \u{1F440} Watching for changes...`),console.log(` Press Ctrl+C twice to exit (first stops Turbo, second triggers cleanup)
564
+ `)}catch(a){await i?.(),await Pt(t),A(a)}});import As from"chalk";import{Command as Qm}from"commander";import{existsSync as Hm,readFileSync as Gm,writeFileSync as Bm}from"fs";import Es from"path";import Er from"chalk";import{Command as Um}from"commander";import zm from"os";var{name:Vm,publishConfig:Km}=I,Jm=Km?.registry,qm=Vm?.split("/")[0],wS=new Um("token:set").description(Er.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)",qm).option("--registry <registry>","Registry URL",Jm).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)=>$s(e,t.scope||"",t.registry||"",t.local,t.force)).addHelpText("after",()=>`${Er.cyan(`
565
+ Example:`)}
566
+ ${Er.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
567
+ `),Ym=e=>e?Es.join(process.cwd(),".npmrc"):Es.join(zm.homedir(),".npmrc"),Zm=(e,t,r)=>{let n=new URL(r).host;return t?`${t}:registry=https://${n}
568
+ //${n}/:_authToken=${e}`:`//${n}/:_authToken=${e}`},Xm=e=>Hm(e)?Gm(e,"utf8"):"",$r=(e,t)=>Bm(e,t),$s=(e,t,r,n=!1,o=!1)=>{let s=Ym(n),i=Zm(e,t,r),a=new URL(r).host,c=Xm(s),l=new RegExp(`//${a}/:_authToken=\\S+`);if(!c){$r(s,`${i}
569
+ `),d.success(`Created new .npmrc and set token for ${a}`);return}if(l.test(c)){if(!o){d.warn(`Token for ${a} already exists in ${s}. Use --force to overwrite.`);return}c=c.replace(l,i),$r(s,c),d.success(`Overwrote existing token for ${a} in ${s}`);return}c+=`
570
+ ${i}
571
+ `,$r(s,c),d.success(`Appended token for ${a} to ${s}`)},Is=(e,t)=>$s(e,t.scope||"",t.registry||"",t.local,t.force);var{name:ed,publishConfig:td}=I,rd=td?.registry,nd=ed?.split("/")[0],Ir=new Qm("token").description("Token management commands");Ir.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)",nd).option("--registry <registry>","Registry URL",rd).option("--local","Write token to a local .npmrc in the current directory",!1).option("--force","Force overwrite existing token if already present",!1).action(Is).addHelpText("after",()=>`${As.cyan(`
572
+ Example:`)}
573
+ ${As.bold("pf token set <token> --scope @my-workspace --registry https://npm.pkg.github.com")}
574
+ `);Ir.action(()=>{let e=te({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 Rs=Ir;import Rr from"chalk";import{Command as hd}from"commander";var FS={AI_GENERATION:!0,DEBUG:process.env.PF_DEBUG==="true"};import{confirm as Fs,input as cd,password as ld,select as Ms}from"@inquirer/prompts";import k from"chalk";var od=[/embed/i,/whisper/i,/tts/i,/dall-e/i,/davinci/i,/babbage/i,/curie/i,/ada(?!-)/i,/moderation/i,/realtime/i,/audio/i,/transcription/i,/search/i],sd=async(e,t,r=1e4)=>{let n=new AbortController,o=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...t,signal:n.signal})}finally{clearTimeout(o)}},id=e=>e.replace(/-(\d{8})$/," ($1)").replace(/^claude-/,"Claude ").replace(/^gpt-/,"GPT-").replace(/-/g," ").replace(/(\d)\.(\d)/g,"$1.$2").replace(/\s+/g," ").split(" ").map(t=>/^\d/.test(t)||/^\(\d+\)$/.test(t)?t:t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()).join(" ").trim(),ad=async(e,t)=>{let r=ve(e),n=await sd(r.modelsApiUrl,{headers:r.buildHeaders(t)});if(!n.ok)throw new Error(`${r.name} API error: ${n.status}`);let o=await n.json(),s=r.parseModelsResponse(o);if(!Array.isArray(s)||s.length===0)throw new Error(`No models returned from ${r.name} API`);let i=s.filter(a=>{let c=r.modelFilters.some(p=>p.test(a.id)),l=od.some(p=>p.test(a.id));return c&&!l}).sort((a,c)=>{let l=typeof a.created=="number"?a.created:new Date(a.created).getTime();return(typeof c.created=="number"?c.created:new Date(c.created).getTime())-l}).map(a=>({name:id(a.id),value:a.id}));if(i.length===0)throw new Error(`No chat models found from ${r.name} API`);return i};async function Ns(e,t){if(!t)throw new Error("API key is required to fetch available models");return{models:await ad(e,t),fromApi:!0}}function pd(){if(!Ce())return null;try{let e=Le();return console.log(k.dim(`Found existing configuration at ${U}
575
+ `)),e}catch{return console.log(k.yellow(`Found corrupted configuration, starting fresh.
576
+ `)),null}}async function md(e,t){return console.log(k.dim(`
577
+ \u{1F4CB} Get your ${e} API key here:`)),console.log(k.cyan(` ${t}
578
+ `)),ld({message:`Enter your ${e} API key:`,mask:"*",validate:r=>r.trim()?r.length<10?"API key seems too short":!0:"API key cannot be empty"})}async function dd(e,t,r){let n=await Ms({message:"Select model:",choices:e,default:t?.provider===r?t.model:void 0});return await Fs({message:"Enter a custom model ID instead?",default:!1})?cd({message:"Enter custom model ID:",default:n,validate:s=>s.trim()?!0:"Model ID cannot be empty"}):n}function Ds(e){return e.length<=12?"****":`${e.slice(0,4)}...${e.slice(-4)}`}function gd(e,t){console.log(k.green.bold(`
579
+ \u2705 AI configuration saved successfully!
580
+ `)),console.log(k.dim(`Configuration file: ${U}`)),console.log(k.dim("API Key: Stored securely in system keychain")),console.log(k.dim(`Provider: ${e.provider}`)),console.log(k.dim(`Model: ${e.model}`)),console.log(k.dim(`API Key: ${Ds(t)}
581
+ `)),console.log(k.cyan("You can now use AI-powered service generation:")),console.log(k.dim(` pf new hono-micro services/my-service --ai
582
+ `))}async function ud(e){let t=await _e(e);if(t)return t;let r=ve(e);return process.env[r.defaultApiKeyEnvVar]??null}async function js(){console.log(k.cyan.bold(`
583
+ \u{1F916} AI Configuration Setup
584
+ `));let e=pd();try{let t=await Ms({message:"Select AI provider:",choices:cn(),default:e?.provider??Ft.provider}),r=ve(t),n,o=await ud(t);o&&(console.log(k.green(`
585
+ \u2713 Found existing API key: ${Ds(o)}`)),await Fs({message:"Use this existing API key?",default:!0})&&(n=o)),n||(n=await md(r.name,r.apiKeyUrl)),console.log(k.dim(`
586
+ Fetching available models...`));let s;try{s=(await Ns(t,n)).models,console.log(k.green(`\u2713 Loaded ${s.length} models from ${r.name} API
587
+ `))}catch(c){console.error(k.red(`
588
+ \u274C Failed to fetch models: ${_r(c)}`)),console.log(k.yellow(`
589
+ Please check your API key and try again.
590
+ `)),process.exit(T.CONFIG_ERROR)}let i=await dd(s,e,t),a={provider:t,model:i.trim()};ln(a),await pn(t,n),gd(a,n)}catch(t){throw Y(t)&&t.name==="ExitPromptError"&&(console.log(k.yellow(`
591
+ Setup cancelled.
592
+ `)),process.exit(T.CANCELLED)),t}}import{existsSync as KS,readFileSync as JS}from"fs";import{homedir as YS}from"os";import{join as XS}from"path";var Ar=async(e,t=!1)=>{try{return rr(e,t),await we({verbose:t}),!0}catch{return!1}};var St=e=>{let t=new hd("setup").description("Configure platform settings");return t.command("completion").description("Install shell autocompletion").option("--verbose","Enable verbose logging").addHelpText("after",`
593
+ Examples:
594
+ $ pf setup completion
595
+ $ pf setup completion --verbose
596
+ `).action(async r=>{await Ar(e,r.verbose),r.verbose||(console.log(Rr.green(`
597
+ \u2714 Shell autocompletion installed!`)),console.log(Rr.dim(` Restart your shell:
598
+ `)),console.log(Rr.cyan(` exec $SHELL
599
+ `)))}),t.command("ai").description("Configure AI provider and API key for code generation").addHelpText("after",`
600
+ Example:
601
+ $ pf setup ai
602
+ `).action(async()=>{await js()}),t.action(()=>{let r=te({title:"\u2699\uFE0F Platform Setup",commands:[{name:"completion",description:"Install shell autocompletion"},{name:"ai",description:"Configure AI provider"}],footer:'Run "pf setup <command> --help" for more information'});console.log(r)}),t},yd=St("pf");import Cd from"chalk";import{Command as _s}from"commander";import Os from"chalk";var vd=e=>({debug:()=>{},info:e?()=>{}:t=>console.log(` ${t}`),warn:e?()=>{}:t=>console.log(Os.yellow(` ${t}`)),error:e?()=>{}:t=>console.error(Os.red(` ${t}`))}),Nr=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:vd(s)};sr(a,c)}if(!s&&i?.output){let c=Array.isArray(i.output)?i.output:[i.output];for(let l of c)console.log(l)}return{effects:a,output:i?.output}};var kd=e=>e.required?`<${e.name}>`:`[${e.name}]`,xd=(e,t)=>{e.argument(kd(t),t.description)},Pd=(e,t)=>{t.default!==void 0?e.option(t.flags,t.description,t.default):e.option(t.flags,t.description)},Sd=(e,t)=>Object.fromEntries(e.args.map((r,n)=>[r.name,t[n]])),wd=e=>e[e.length-2],bd=(e,t)=>async(...r)=>{try{await Nr({command:e,args:Sd(e,r),options:wd(r),context:t})}catch(n){console.error(Cd.red(`Error executing ${e.name}:`),n instanceof Error?n.message:n),process.exit(1)}},Ls=(e,t)=>{let r=new _s(e.name).description(e.description);return e.args.forEach(n=>{xd(r,n)}),e.options.forEach(n=>{Pd(r,n)}),r.action(bd(e,t)),r},Fr=(e,t,r,n)=>{let o=new _s(e).description(t);return r.forEach(s=>{o.addCommand(Ls(s,n))}),o};Ze();process.on("SIGINT",()=>{process.exit(T.CANCELLED)});process.on("unhandledRejection",e=>{throw Lr(e)&&process.exit(T.CANCELLED),e});process.on("uncaughtException",e=>{A(e)});var Ie=new Ed,Ws=Object.keys(I.bin||{}),[Dr="pf",Mr]=Ws.length>0?Ws:["pf"],{description:Hs,version:Id,repository:Gs,homepage:Ad}=I,Bs=Hs?.split(/ —|,|\./)[0]||Hs||"Platform CLI",zs=Gs?.url?`https://${Gs.url.replace(/^(git\+|git@)/,"").replace(/\.git$/,"").replace(":","/")}`:null,Us=zs||Ad,Rd=zs?"GitHub":"README",Nd=Us?[Ae.bold(Bs),`
603
+
604
+ `,Ae.cyan("See more at: "),Ae.bold($d(Rd,String(Us)))].join(""):Ae.bold(Bs),Fd=[St(Dr),ks(),Ts,Rs,tn],Md=async()=>{try{let e=h(),t=De(e);if(!t.plugins?.length)return[];let r=C(e),n=Xe({workspaceRoot:e,availableServices:$t(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=Fr(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[]}},Dd=async()=>{let e=await Md(),t=[...Fd,...e];Ie.name(Dr).description(Nd).version(Id||"0.0.1").helpCommand(!1).configureHelp({subcommandTerm:r=>Ae.cyan(r.name())}).addHelpText("after",to),Mr&&Mr!==Dr&&Ie.alias(Mr);for(let r of t)Ie.addCommand(r);Ie.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)}),ro(Ie,Td,t)};Dd();