@kizenapps/cli 1.9.0-5d4160b → 1.10.0-0a9fae5

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 (39) hide show
  1. package/dist/index.js +22 -22
  2. package/dist/index.js.map +1 -1
  3. package/dist/viewer/assets/AppDetailPage-CKDgNuvS.js +1 -0
  4. package/dist/viewer/assets/CodeStepsPage-BjnqiAQX.js +1 -0
  5. package/dist/viewer/assets/ConfigurationPage-XUysfO8v.js +1 -0
  6. package/dist/viewer/assets/SandboxPage-DbMklAzy.js +1 -0
  7. package/dist/viewer/assets/{SecretsPage-GbNJAR3u.js → SecretsPage-BwDfBKbY.js} +1 -1
  8. package/dist/viewer/assets/{SourceBrowserPage-DluS8U4q.js → SourceBrowserPage-D9z0jLNw.js} +1 -1
  9. package/dist/viewer/assets/{WhenBadge-BD_2mB-N.js → WhenBadge-Dm7YHpxd.js} +1 -1
  10. package/dist/viewer/assets/api--Ax6VWLq.js +11 -0
  11. package/dist/viewer/assets/{bootstrapQuery-DQckmnki.js → bootstrapQuery-CyYWFe68.js} +1 -1
  12. package/dist/viewer/assets/calendarSource.worker-CTgMuhqr.js +31 -0
  13. package/dist/viewer/assets/floatingFrame.worker-zn66fKUA.js +31 -0
  14. package/dist/viewer/assets/generic.worker-gJPrf_ED.js +31 -0
  15. package/dist/viewer/assets/{index-B7mInhXv.js → index-C570aZ49.js} +3 -3
  16. package/dist/viewer/assets/index-CortCmDi.css +2 -0
  17. package/dist/viewer/assets/recordDetail.worker-CGLG0Evq.js +31 -0
  18. package/dist/viewer/assets/setupAssistant-C-3V_Vj3.js +1 -0
  19. package/dist/viewer/assets/useCompleteSetup-3RGdCYrc.js +40 -0
  20. package/dist/viewer/assets/usePluginConfig-XFnehL_S.js +1 -0
  21. package/dist/viewer/index.html +4 -4
  22. package/package.json +3 -3
  23. package/dist/viewer/assets/AppDetailPage-B4lZl1Nu.js +0 -1
  24. package/dist/viewer/assets/CodeStepsPage-C5l1pu51.js +0 -1
  25. package/dist/viewer/assets/ConfigurationPage-DMUqeW2V.js +0 -1
  26. package/dist/viewer/assets/SandboxPage-qLFGQ_Lg.js +0 -1
  27. package/dist/viewer/assets/api-ViOFtzH7.js +0 -11
  28. package/dist/viewer/assets/calendarSource.worker-mLICe-Oi.js +0 -31
  29. package/dist/viewer/assets/configStorage-CfwJ8JQJ.js +0 -1
  30. package/dist/viewer/assets/floatingFrame.worker-C8edGbiJ.js +0 -31
  31. package/dist/viewer/assets/generic.worker-DSYVvVm0.js +0 -31
  32. package/dist/viewer/assets/index-ZrNbBIqA.css +0 -2
  33. package/dist/viewer/assets/recordDetail.worker-Bsa6yMRD.js +0 -31
  34. package/dist/viewer/assets/useCriticalExceptionDialog-CncFngL7.js +0 -40
  35. /package/dist/viewer/assets/{CodeViewer-CVECJY4e.js → CodeViewer-DpJLTTab.js} +0 -0
  36. /package/dist/viewer/assets/{IconReferencePage-DxhBoReE.js → IconReferencePage-CN9Tha2W.js} +0 -0
  37. /package/dist/viewer/assets/{VersionsPage-yNilRkEf.js → VersionsPage-CRnStnQ-.js} +0 -0
  38. /package/dist/viewer/assets/{formatBytes-BXYIMbyB.js → formatBytes-BV6bvmhE.js} +0 -0
  39. /package/dist/viewer/assets/{useLocalStorage-wp83IS34.js → useLocalStorage-BZr9ZJI5.js} +0 -0
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import{readFileSync as ss}from"fs";import{dirname as as,join as ls}from"path";import{fileURLToPath as cs}from"url";import{program as ve}from"commander";import{createElement as io}from"react";import{render as so}from"ink";import{useEffect as ir,useState as je}from"react";import{Box as ze,Text as Ie,useApp as ro}from"ink";import{PluginValidationError as no}from"@kizenapps/packager";import{mkdir as $n,writeFile as Ln}from"fs/promises";import{join as Fn}from"path";import{PluginValidationError as An,minifyFiles as On,packagePlugin as jn,parseManifestFromFiles as zn,transformDeployablePlugin as Mn,validatePluginApp as Hn}from"@kizenapps/packager";import{readdir as In,readFile as It}from"fs/promises";import{join as Qt,relative as Nn}from"path";var Bn=new Set([".png",".svg"]),Rn=new Set([".kzn"]),Dn=new Set([".DS_Store"]),et=new Set(["node_modules",".git",".kizenapp",".github"]);async function er(e,t){let o=await In(e,{withFileTypes:!0}),n=[];for(let r of o)if(r.isDirectory()){if(et.has(r.name))continue;n.push(...await er(Qt(e,r.name),t))}else r.isFile()&&(Dn.has(r.name)||n.push(Qt(e,r.name)));return n}async function tt(e){let t=await er(e,e);return Promise.all(t.map(async o=>{let n=Nn(e,o).split("\\").join("/"),r=n.lastIndexOf("."),i=r>=0?n.slice(r).toLowerCase():"";if(Bn.has(i)){let p=await It(o);return{path:n,content:"",base64Image:p.toString("base64")}}if(Rn.has(i)){let p=await It(o);return{path:n,content:"",binaryData:p}}let u=await It(o,"utf-8");return{path:n,content:u}}))}var Un=(e,t)=>({...e,thumbnail:e.thumbnail?Buffer.from(e.thumbnail).toString("base64"):null,kznFile:e.kznFile?Buffer.from(e.kznFile).toString("base64"):null,allReleaseNotes:t});async function rt(e,t,o){await $n(t,{recursive:!0}),o?.("reading-files");let n=await tt(e);o?.("validating");let r=Hn(n);if(r.some(b=>b.severity==="error"))throw new An(r);o?.("minifying");let i=await On(n);o?.("packaging");let u=zn(i),p=jn(i,u),f=Object.values(p).map(Mn);o?.("writing-bundle");let x=f.map(b=>{let c=b.release_notes_directory?.replace(/\/$/,""),y=c?n.filter(T=>T.path.startsWith(c+"/")&&T.path.endsWith(".md")&&T.content).map(T=>({version:T.path.slice(T.path.lastIndexOf("/")+1,-3),notes:T.content})).sort((T,E)=>E.version.localeCompare(T.version,void 0,{numeric:!0})):[];return Un(b,y)}),w=JSON.stringify(x,null,2),S=(b,c)=>b==="allReleaseNotes"?void 0:c,N=Buffer.byteLength(JSON.stringify(x,S,2),"utf-8");return await Ln(Fn(t,"bundle.json"),w,"utf-8"),{bundleSize:N}}function Ae(e){return e<1024?`${String(e)} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(2)} MB`}import{Box as Wn,Text as Gn}from"ink";import{Box as Vn,Text as qn}from"ink";import{jsx as tr}from"react/jsx-runtime";var Jn=[" :::::::: "," :::::: ::::::::::: "," :::::: :::::::::: "," :::::: :::::: ::::::: "," ::::: :::::: ::::::::::::::::: "," ::::: ::::: ::::::::::::::::::: "," ::::: ::::: :::::: ::::: ",":::: ::::: ::: ::::: :: ","::::: :::::: :::::::::: ","::::: :::::: ::::::::::: "," ::::: ::: ::::::: "," ::::::: ::: ::::: "," ::::::::::: :::::: :::::"," :::::::::: :::::: :::::"," :: ::::: ::: ::::: ::::"," ::::: :::::: ::::: ::::: ::: "," ::::::::::::::::::: ::::: ::::: "," ::::::::::::::::: ::::: ::::: "," ::::::::: :::::: :::::: "," :::::::::: :::::: "," ::::::::::: :::::: "," :::::::: "],rr=()=>tr(Vn,{flexDirection:"column",children:Jn.map((e,t)=>tr(qn,{color:"cyan",children:e},t))});import{Fragment as Kn,jsx as Nt,jsxs as Yn}from"react/jsx-runtime";var q=({marginBottom:e=0})=>Yn(Kn,{children:[Nt(rr,{}),Nt(Wn,{flexDirection:"column",marginTop:1,marginBottom:e,children:Nt(Gn,{bold:!0,color:"cyan",children:"Kizen App Development Toolkit"})})]});import{useEffect as Xn,useState as Zn}from"react";import{Text as Qn}from"ink";import{jsx as eo}from"react/jsx-runtime";var nr=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],pe=()=>{let[e,t]=Zn(0);return Xn(()=>{let o=setInterval(()=>{t(n=>(n+1)%nr.length)},80);return()=>{clearInterval(o)}},[]),eo(Qn,{color:"cyan",children:nr[e]??"\u280B"})};import{Box as Bt,Text as nt}from"ink";import{jsx as or,jsxs as Oe}from"react/jsx-runtime";var to=e=>{let t=new Map;for(let o of e){let n=o.path??o.pluginApiName??"general",r=t.get(n)??[];r.push(o),t.set(n,r)}return t},ot=({issues:e})=>{let t=e.filter(o=>o.severity==="error").length;return Oe(Bt,{flexDirection:"column",marginTop:1,children:[Oe(nt,{color:"red",children:["\u2717 ",t," validation ",t===1?"error":"errors"]}),[...to(e)].map(([o,n])=>Oe(Bt,{flexDirection:"column",marginTop:1,children:[or(nt,{bold:!0,children:o}),n.map((r,i)=>or(Bt,{paddingLeft:2,children:Oe(nt,{color:r.severity==="error"?"red":"yellow",children:[r.severity==="error"?"\u2717":"\u26A0"," ",r.message," ",Oe(nt,{dimColor:!0,children:["(",r.rule,")"]})]})},`${r.rule}-${String(i)}`))]},o))]})};import{Fragment as oo,jsx as fe,jsxs as Te}from"react/jsx-runtime";var sr=["creating-dir","reading-files","validating","minifying","packaging","writing-bundle"],it={"creating-dir":"Creating .kizenapp directory","reading-files":"Reading plugin files",validating:"Validating plugin app",minifying:"Minifying scripts",packaging:"Packaging plugin","writing-bundle":"Writing bundle.json"},ar=({outputDir:e,pluginDir:t})=>{let o=ro(),[n,r]=je("creating-dir"),[i,u]=je(!1),[p,f]=je(null),[x,w]=je(null),[S,N]=je(null);ir(()=>{rt(t,e,r).then(({bundleSize:y})=>{N(y),r("done")}).catch(y=>{y instanceof no?f(y.issues):w(y instanceof Error?y.message:String(y)),u(!0),process.exitCode=1})},[e,t]),ir(()=>{(n==="done"||i)&&o.exit()},[n,i,o]);let b=sr.indexOf(n),c=n==="done";return Te(ze,{flexDirection:"column",paddingY:1,paddingX:2,children:[fe(q,{marginBottom:1}),Te(ze,{flexDirection:"column",gap:0,children:[sr.map((y,T)=>{let E=n===y,h=c||b>T;return fe(ze,{gap:1,children:i&&T===b?Te(Ie,{color:"red",children:["\u2717 ",it[y]]}):h?Te(Ie,{color:"green",children:["\u2713 ",it[y]]}):E?Te(oo,{children:[fe(pe,{}),fe(Ie,{children:it[y]})]}):Te(Ie,{dimColor:!0,children:[" ",it[y]]})},y)}),c&&S!==null&&fe(ze,{marginTop:1,gap:1,children:Te(Ie,{color:"green",children:["\u2713 bundle \u2014 ",Ae(S)]})}),p!==null&&fe(ot,{issues:p}),x!==null&&fe(ze,{marginTop:1,borderStyle:"single",borderColor:"red",paddingX:1,children:fe(Ie,{color:"red",children:x})})]})]})};import*as Ne from"fs";import*as lr from"path";function Be(e){let t=lr.join(e,".gitignore"),o=".kizenapp/",n="";if(Ne.existsSync(t)){n=Ne.readFileSync(t,"utf8");let i=n.split(`
2
+ import{readFileSync as ds}from"fs";import{dirname as us,join as ps}from"path";import{fileURLToPath as fs}from"url";import{program as ve}from"commander";import{createElement as lo}from"react";import{render as co}from"ink";import{useEffect as ir,useState as je}from"react";import{Box as ze,Text as Ie,useApp as io}from"ink";import{PluginValidationError as so}from"@kizenapps/packager";import{mkdir as An,writeFile as On}from"fs/promises";import{join as jn}from"path";import{PluginValidationError as zn,minifyFiles as Mn,packagePlugin as Hn,parseManifestFromFiles as Un,transformDeployablePlugin as Vn,validatePluginApp as qn}from"@kizenapps/packager";import{readdir as Nn,readFile as Zt}from"fs/promises";import{join as Qt,relative as Bn}from"path";var Rn=new Set([".png",".svg"]),Dn=new Set([".kzn"]),$n=new Set([".DS_Store"]),et=new Set(["node_modules",".git",".kizenapp",".github",".claude","__pycache__"]),Ln=8e3;function Fn(e){return e.subarray(0,Ln).includes(0)}async function er(e,t){let o=await Nn(e,{withFileTypes:!0}),n=[];for(let r of o)if(r.isDirectory()){if(et.has(r.name))continue;n.push(...await er(Qt(e,r.name),t))}else r.isFile()&&($n.has(r.name)||n.push(Qt(e,r.name)));return n}async function tt(e,{detectBinaryByContent:t=!1}={}){let o=await er(e,e);return Promise.all(o.map(async n=>{let r=Bn(e,n).split("\\").join("/"),i=r.lastIndexOf("."),u=i>=0?r.slice(i).toLowerCase():"";if(Rn.has(u)){let m=await Zt(n);return{path:r,content:"",base64Image:m.toString("base64")}}let p=await Zt(n);return Dn.has(u)||t&&Fn(p)?{path:r,content:"",binaryData:p}:{path:r,content:p.toString("utf-8")}}))}var Jn=(e,t)=>({...e,thumbnail:e.thumbnail?Buffer.from(e.thumbnail).toString("base64"):null,kznFile:e.kznFile?Buffer.from(e.kznFile).toString("base64"):null,allReleaseNotes:t});async function rt(e,t,o){await An(t,{recursive:!0}),o?.("reading-files");let n=await tt(e);o?.("validating");let r=qn(n);if(r.some(v=>v.severity==="error"))throw new zn(r);o?.("minifying");let i=await Mn(n);o?.("packaging");let u=Un(i),p=Hn(i,u),m=Object.values(p).map(Vn);o?.("writing-bundle");let b=m.map(v=>{let c=v.release_notes_directory?.replace(/\/$/,""),h=c?n.filter(T=>T.path.startsWith(c+"/")&&T.path.endsWith(".md")&&T.content).map(T=>({version:T.path.slice(T.path.lastIndexOf("/")+1,-3),notes:T.content})).sort((T,P)=>P.version.localeCompare(T.version,void 0,{numeric:!0})):[];return Jn(v,h)}),y=JSON.stringify(b,null,2),S=(v,c)=>v==="allReleaseNotes"?void 0:c,N=Buffer.byteLength(JSON.stringify(b,S,2),"utf-8");return await On(jn(t,"bundle.json"),y,"utf-8"),{bundleSize:N}}function Ae(e){return e<1024?`${String(e)} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(2)} MB`}import{Box as Yn,Text as Xn}from"ink";import{Box as Wn,Text as Gn}from"ink";import{jsx as tr}from"react/jsx-runtime";var Kn=[" :::::::: "," :::::: ::::::::::: "," :::::: :::::::::: "," :::::: :::::: ::::::: "," ::::: :::::: ::::::::::::::::: "," ::::: ::::: ::::::::::::::::::: "," ::::: ::::: :::::: ::::: ",":::: ::::: ::: ::::: :: ","::::: :::::: :::::::::: ","::::: :::::: ::::::::::: "," ::::: ::: ::::::: "," ::::::: ::: ::::: "," ::::::::::: :::::: :::::"," :::::::::: :::::: :::::"," :: ::::: ::: ::::: ::::"," ::::: :::::: ::::: ::::: ::: "," ::::::::::::::::::: ::::: ::::: "," ::::::::::::::::: ::::: ::::: "," ::::::::: :::::: :::::: "," :::::::::: :::::: "," ::::::::::: :::::: "," :::::::: "],rr=()=>tr(Wn,{flexDirection:"column",children:Kn.map((e,t)=>tr(Gn,{color:"cyan",children:e},t))});import{Fragment as Zn,jsx as It,jsxs as Qn}from"react/jsx-runtime";var q=({marginBottom:e=0})=>Qn(Zn,{children:[It(rr,{}),It(Yn,{flexDirection:"column",marginTop:1,marginBottom:e,children:It(Xn,{bold:!0,color:"cyan",children:"Kizen App Development Toolkit"})})]});import{useEffect as eo,useState as to}from"react";import{Text as ro}from"ink";import{jsx as no}from"react/jsx-runtime";var nr=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],pe=()=>{let[e,t]=to(0);return eo(()=>{let o=setInterval(()=>{t(n=>(n+1)%nr.length)},80);return()=>{clearInterval(o)}},[]),no(ro,{color:"cyan",children:nr[e]??"\u280B"})};import{Box as Nt,Text as nt}from"ink";import{jsx as or,jsxs as Oe}from"react/jsx-runtime";var oo=e=>{let t=new Map;for(let o of e){let n=o.path??o.pluginApiName??"general",r=t.get(n)??[];r.push(o),t.set(n,r)}return t},ot=({issues:e})=>{let t=e.filter(o=>o.severity==="error").length;return Oe(Nt,{flexDirection:"column",marginTop:1,children:[Oe(nt,{color:"red",children:["\u2717 ",t," validation ",t===1?"error":"errors"]}),[...oo(e)].map(([o,n])=>Oe(Nt,{flexDirection:"column",marginTop:1,children:[or(nt,{bold:!0,children:o}),n.map((r,i)=>or(Nt,{paddingLeft:2,children:Oe(nt,{color:r.severity==="error"?"red":"yellow",children:[r.severity==="error"?"\u2717":"\u26A0"," ",r.message," ",Oe(nt,{dimColor:!0,children:["(",r.rule,")"]})]})},`${r.rule}-${String(i)}`))]},o))]})};import{Fragment as ao,jsx as fe,jsxs as Te}from"react/jsx-runtime";var sr=["creating-dir","reading-files","validating","minifying","packaging","writing-bundle"],it={"creating-dir":"Creating .kizenapp directory","reading-files":"Reading plugin files",validating:"Validating plugin app",minifying:"Minifying scripts",packaging:"Packaging plugin","writing-bundle":"Writing bundle.json"},ar=({outputDir:e,pluginDir:t})=>{let o=io(),[n,r]=je("creating-dir"),[i,u]=je(!1),[p,m]=je(null),[b,y]=je(null),[S,N]=je(null);ir(()=>{rt(t,e,r).then(({bundleSize:h})=>{N(h),r("done")}).catch(h=>{h instanceof so?m(h.issues):y(h instanceof Error?h.message:String(h)),u(!0),process.exitCode=1})},[e,t]),ir(()=>{(n==="done"||i)&&o.exit()},[n,i,o]);let v=sr.indexOf(n),c=n==="done";return Te(ze,{flexDirection:"column",paddingY:1,paddingX:2,children:[fe(q,{marginBottom:1}),Te(ze,{flexDirection:"column",gap:0,children:[sr.map((h,T)=>{let P=n===h,x=c||v>T;return fe(ze,{gap:1,children:i&&T===v?Te(Ie,{color:"red",children:["\u2717 ",it[h]]}):x?Te(Ie,{color:"green",children:["\u2713 ",it[h]]}):P?Te(ao,{children:[fe(pe,{}),fe(Ie,{children:it[h]})]}):Te(Ie,{dimColor:!0,children:[" ",it[h]]})},h)}),c&&S!==null&&fe(ze,{marginTop:1,gap:1,children:Te(Ie,{color:"green",children:["\u2713 bundle \u2014 ",Ae(S)]})}),p!==null&&fe(ot,{issues:p}),b!==null&&fe(ze,{marginTop:1,borderStyle:"single",borderColor:"red",paddingX:1,children:fe(Ie,{color:"red",children:b})})]})]})};import*as Ne from"fs";import*as lr from"path";function Be(e){let t=lr.join(e,".gitignore"),o=".kizenapp/",n="";if(Ne.existsSync(t)){n=Ne.readFileSync(t,"utf8");let i=n.split(`
3
3
  `).map(u=>u.trim());if(i.includes(o)||i.includes(".kizenapp"))return}let r=n.endsWith(`
4
4
  `)?o+`
5
5
  `:`
6
6
  `+o+`
7
- `;Ne.writeFileSync(t,n+r)}function cr(e){e.command("build").description("Bundle the plugin app into .kizenapp directory").action(async()=>{let t=process.cwd(),o=`${t}/.kizenapp`;Be(t);let{waitUntilExit:n}=so(io(ar,{outputDir:o,pluginDir:t}));await n()})}import{createElement as wo}from"react";import{render as Co}from"ink";import{useCallback as at,useState as Me}from"react";import{Box as V,Text as R,useApp as co,useInput as uo}from"ink";import{join as $t}from"path";import{access as ao,mkdir as Rt,writeFile as lo}from"fs/promises";import{join as Pe}from"path";async function st(e){try{return await ao(e),!0}catch{return!1}}async function dr(e){return await st(Pe(e,"kizen.json"))?"has-manifest":await st(Pe(e,".kizenapp"))?"has-kizenapp":"ok"}async function ur(e,t){let o=Pe(e,t);if(!await st(o))return o;for(let n=1;n<1e3;n++){let r=Pe(e,`${t}-${String(n)}`);if(!await st(r))return r}throw new Error(`Could not find an available directory name for "${t}"`)}function Dt(e){return{name:e.name,version:"1.0.0",published:!0,api_name:e.apiName,external_link:e.externalLink,description:e.description,entry:"src/",engine:"1.0.0",release_notes_directory:"releaseNotes/",release_environments:["prod"],config_template:{},base_config:{},developer_business_id:e.developerBusinessId}}async function pr(e){await Rt(e.targetDir,{recursive:!0});let t=Dt(e);await lo(Pe(e.targetDir,"kizen.json"),JSON.stringify(t,null,2)+`
8
- `,"utf-8"),await Rt(Pe(e.targetDir,"src"),{recursive:!0}),await Rt(Pe(e.targetDir,"releaseNotes"),{recursive:!0}),Be(e.targetDir)}import{jsx as B,jsxs as z}from"react/jsx-runtime";var Ee=["name","apiName","externalLink","description","developerBusinessId"],fr={name:"Name",apiName:"API name",externalLink:"External link",description:"Description",developerBusinessId:"Business ID"},mr=["name","apiName"];function po(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")}var Re=({text:e})=>B(R,{dimColor:!0,children:e});function fo(e){return{name:"",apiName:"",externalLink:"",description:"",developerBusinessId:e}}var gr=({parentDir:e,defaultBusinessId:t})=>{let o=co(),[n,r]=Me({type:"target-select",cursor:0}),[i,u]=Me("in-place"),[p,f]=Me(()=>fo(t)),[x,w]=Me(""),[S,N]=Me(e),b=at((E,h)=>{u(E),w(h.name),r({type:"field-entry",field:0,values:h})},[]),c=at(async E=>{let h=await dr(E);if(h!=="ok"){r({type:"precheck-error",targetDir:E,reason:h});return}N(E),b("in-place",p)},[p,b]),y=at(async E=>{try{let h=await ur(e,E.apiName);N(h),r({type:"confirm",values:E})}catch(h){r({type:"error",message:h instanceof Error?h.message:String(h)})}},[e]),T=at(async(E,h)=>{try{await pr({targetDir:h,name:E.name,apiName:E.apiName,externalLink:E.externalLink,description:E.description,developerBusinessId:E.developerBusinessId}),r({type:"done",targetDir:h})}catch(v){r({type:"error",message:v instanceof Error?v.message:String(v)})}},[]);if(uo((E,h)=>{if(h.ctrl&&E==="c"){o.exit();return}if(n.type==="target-select"){h.upArrow?r({type:"target-select",cursor:0}):h.downArrow?r({type:"target-select",cursor:1}):h.return?n.cursor===0?c(e):b("sub-dir",p):h.escape&&o.exit();return}if(n.type==="precheck-error"){(h.return||h.escape)&&o.exit();return}if(n.type==="field-entry"){let{field:v,values:k}=n,m=Ee[v];if(!m)return;if(h.escape){o.exit();return}if(h.backspace||h.delete){w(a=>a.slice(0,-1));return}if(h.upArrow&&v>0){let a={...k,[m]:x},s=v-1,l=Ee[s];r({type:"field-entry",field:s,values:a}),f(a),w(l?a[l]:"");return}if(h.return||h.tab||h.downArrow){let a=x.trim();if(mr.includes(m)&&!a){r({type:"field-entry",field:v,values:k,fieldError:`${fr[m]} is required`});return}let l=m==="description"?x:a,d={...k,[m]:l};f(d);let g=v+1;if(g>=Ee.length)w(""),i==="sub-dir"?(r({type:"resolving-target"}),y(d)):r({type:"confirm",values:d});else{let I=Ee[g],P=I?d[I]:"",F=I==="apiName"&&!P?po(d.name):P;r({type:"field-entry",field:g,values:d}),w(F)}return}E&&!h.ctrl&&!h.meta&&w(a=>a+E);return}if(n.type==="confirm"){if(h.escape){let v=Ee.length-1,k=Ee[v];r({type:"field-entry",field:v,values:n.values}),w(k?n.values[k]:"");return}h.return&&(r({type:"writing"}),T(n.values,S));return}(n.type==="done"||n.type==="error")&&(h.return||h.escape)&&o.exit()}),n.type==="target-select"){let E=[{label:"Use current directory",desc:e},{label:"Create new sub-directory",desc:`${e}/<inferred from API name>`}];return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Where should the new plugin live?"}),E.map((h,v)=>{let k=n.cursor===v;return z(V,{gap:2,children:[B(R,{...k&&{color:"cyan"},children:k?"\u276F":" "}),B(R,{bold:k,...k&&{color:"cyan"},children:h.label}),B(R,{dimColor:!0,children:h.desc})]},h.label)})]}),B(Re,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel"})]})}if(n.type==="precheck-error"){let{targetDir:E,reason:h}=n;return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),B(R,{color:"red",bold:!0,children:"Cannot create plugin"}),z(V,{flexDirection:"column",gap:0,children:[z(R,{children:[E," already contains ",B(R,{bold:!0,children:h==="has-manifest"?"kizen.json":".kizenapp/"}),"."]}),B(R,{dimColor:!0,children:"Remove the conflicting file/directory or choose a different target to avoid overwriting an existing plugin."})]}),B(Re,{text:"Enter or Esc to exit"})]})}if(n.type==="field-entry"){let{field:E,fieldError:h}=n,v=i==="sub-dir"?`Target: sub-directory of ${e} (inferred from API name)`:`Target: ${S}`;return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Plugin details"}),B(R,{dimColor:!0,children:v})]}),h!==void 0&&z(R,{color:"red",children:["Error: ",h]}),B(V,{flexDirection:"column",gap:0,children:Ee.map((k,m)=>{let a=E===m,s=a?x:p[k],l=mr.includes(k),d=`${fr[k]}${l?"":" (optional)"}`;return z(V,{gap:2,children:[B(V,{width:24,children:B(R,{bold:a,...a&&{color:"cyan"},children:d})}),B(R,{...a&&{color:"cyan"},children:">"}),B(R,{children:s}),a&&B(R,{color:"cyan",children:"\u2588"})]},k)})}),B(Re,{text:"Enter/Tab/\u2193 next \xB7 \u2191 previous \xB7 Backspace delete \xB7 Esc cancel"})]})}if(n.type==="confirm"){let E=Dt({targetDir:S,name:n.values.name,apiName:n.values.apiName,externalLink:n.values.externalLink,description:n.values.description,developerBusinessId:n.values.developerBusinessId});return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Ready to create"}),z(R,{dimColor:!0,children:["Target: ",S]})]}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"kizen.json preview"}),B(R,{children:JSON.stringify(E,null,2)})]}),z(V,{flexDirection:"column",gap:0,children:[B(R,{dimColor:!0,children:"Also creates:"}),z(R,{dimColor:!0,children:[" ",$t(S,"src/")]}),z(R,{dimColor:!0,children:[" ",$t(S,"releaseNotes/")]}),z(R,{dimColor:!0,children:[" ",$t(S,".gitignore")," (adds .kizenapp/)"]})]}),B(Re,{text:"Enter to create \xB7 Esc to go back"})]})}return n.type==="resolving-target"?B(V,{paddingY:1,paddingX:2,children:B(R,{dimColor:!0,children:"Finding available sub-directory\u2026"})}):n.type==="writing"?B(V,{paddingY:1,paddingX:2,children:B(R,{dimColor:!0,children:"Creating plugin\u2026"})}):n.type==="done"?z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(R,{color:"green",bold:!0,children:["Plugin created at ",n.targetDir]}),z(V,{flexDirection:"column",gap:0,children:[B(R,{dimColor:!0,children:"Next steps:"}),z(R,{children:[" ","cd ",n.targetDir]}),z(R,{children:[" ","appbuilder dev"]})]}),B(Re,{text:"Enter or Esc to exit"})]}):z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),B(R,{color:"red",bold:!0,children:"Failed to create plugin"}),B(R,{children:n.message}),B(Re,{text:"Enter or Esc to exit"})]})};import{mkdir as yr,readFile as mo,readdir as go,writeFile as hr}from"fs/promises";import{homedir as yo}from"os";import{dirname as ho,join as lt}from"path";var re=["go","fmo","staging","integration","test1"];var ke=lt(yo(),".kizenappbuilder"),De=lt(ke,"credentials.json"),me="credentials";function bo(e){return re.includes(e)}function xo(e){if(typeof e!="object"||e===null)throw new Error("Credentials must be a JSON object");let t=e,o=t.environment;return{apiKey:typeof t.apiKey=="string"?t.apiKey:"",userId:typeof t.userId=="string"?t.userId:"",businessId:typeof t.businessId=="string"?t.businessId:"",environment:bo(o)?o:"go"}}async function ge(e){let t=await mo(e,"utf-8");return xo(JSON.parse(t))}async function Y(){try{return await ge(De)}catch{return null}}async function vo(e){await yr(ho(De),{recursive:!0,mode:448}),await hr(De,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384})}function br(e){return lt(ke,`${e}.json`)}async function _e(){let e=[{name:me,path:De,isDefault:!0}];try{let t=await go(ke);for(let o of t){if(!o.endsWith(".json"))continue;let n=o.slice(0,-5);n!==me&&e.push({name:n,path:lt(ke,o),isDefault:!1})}}catch{}return e}async function xr(e,t){if(e===me){await vo(t);return}await yr(ke,{recursive:!0,mode:448}),await hr(br(e),JSON.stringify(t,null,2),{encoding:"utf-8",mode:384})}async function le(e){try{return await ge(br(e))}catch{return null}}function vr(e){e.command("create").description("Scaffold a new Kizen plugin project").action(async()=>{let t=process.cwd(),n=(await Y())?.businessId??"",{waitUntilExit:r}=Co(wo(gr,{parentDir:t,defaultBusinessId:n}),{exitOnCtrlC:!1});await r()})}import{createElement as Xr}from"react";import{render as Zr}from"ink";import{useCallback as $e,useEffect as gt,useRef as ce,useState as X}from"react";import{Box as W,Text as D,useInput as xi}from"ink";import{PluginValidationError as vi}from"@kizenapps/packager";import{watch as wi}from"fs";import{createServer as Ci}from"http";import{join as Gr}from"path";import{WebSocketServer as Si}from"ws";import{createReadStream as Dr,realpathSync as Ho}from"fs";import{access as Uo,readdir as Vo,readFile as qo,realpath as Jo,stat as $r}from"fs/promises";import{dirname as Wo,extname as Lr,join as We,resolve as Go,sep as Vt}from"path";import{fileURLToPath as Ko}from"url";var So=new Set(["set-cookie","strict-transport-security","content-security-policy","content-security-policy-report-only","x-frame-options","content-encoding","content-length"]);function ct(e){let t={};for(let[o,n]of Object.entries(e)){let r=o.toLowerCase();So.has(r)||r.startsWith("access-control-")||(t[o]=n)}return t}var Lt=10*1024*1024,To=6e4,Po=200,He=class extends Error{bytesRead;limit;constructor(t,o){super(`Upstream response exceeded ${String(o)} bytes (read ${String(t)}).`),this.name="ProxyResponseTooLargeError",this.bytesRead=t,this.limit=o}};async function Ft(e,t){let o=e.body;if(o===null)return Buffer.alloc(0);let n=[],r=0;for await(let i of o){if(r+=i.length,r>t)throw new He(r,t);n.push(i)}return Buffer.concat(n)}async function wr(e){let t=ct(Object.fromEntries(e.headers)),o=await Ft(e,Lt);return{status:e.status,headers:t,body:o}}function Cr(e={}){let{onChange:t,enabled:o=!0}=e;if(!o)return{async get(u,p){return{response:await wr(await p()),fromCache:!1}},clear(){}};let n=new Map,r=()=>{t?.(n.size)},i=u=>{n.delete(u)&&r()};return{get(u,p){let f=n.get(u);if(f!==void 0){if(Date.now()-f.insertedAt<To)return f.promise.then(w=>({response:w,fromCache:!0}));i(u)}if(n.size>=Po){let w=n.keys().next().value;w!==void 0&&i(w)}let x=p().then(wr).catch(w=>{throw i(u),w});return n.set(u,{insertedAt:Date.now(),promise:x}),r(),x.then(w=>((w.status<200||w.status>=300)&&i(u),{response:w,fromCache:!1}))},clear(){n.clear(),r()}}}var At={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".svg":"image/svg+xml",".ico":"image/x-icon",".json":"application/json; charset=utf-8",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".map":"application/json"};import{mkdir as Eo,readFile as ko,writeFile as _o}from"fs/promises";import{join as Sr}from"path";async function ye(e){try{let t=await ko(Sr(e,"config.json"),"utf-8");return JSON.parse(t)}catch{return{}}}async function he(e,t){await Eo(e,{recursive:!0}),await _o(Sr(e,"config.json"),JSON.stringify(t,null,2),"utf-8")}var Ot={prod:"https://plugin-wizard.kizen.com",dev:"https://plugin-wizard.kizen.dev",localDev:"http://localhost:9823"};function Ue(e){let t=process.env.PLUGIN_WIZARD_URL;return t!==void 0&&t!==""?t:e==="prod"?process.env.PLUGIN_WIZARD_URL_PROD||Ot.prod:process.env.PLUGIN_WIZARD_URL_DEV!==void 0&&process.env.PLUGIN_WIZARD_URL_DEV!==""?process.env.PLUGIN_WIZARD_URL_DEV:process.env.APPBUILDER_LOCAL_DEV!==void 0&&process.env.APPBUILDER_LOCAL_DEV!==""?Ot.localDev:Ot.dev}import{spawn as Ht}from"child_process";import{writeFile as Pr,rm as Mt,mkdtemp as No,access as Bo}from"fs/promises";import{join as qe}from"path";import{tmpdir as Ro}from"os";var Tr=`awslambdaric
7
+ `;Ne.writeFileSync(t,n+r)}function cr(e){e.command("build").description("Bundle the plugin app into .kizenapp directory").action(async()=>{let t=process.cwd(),o=`${t}/.kizenapp`;Be(t);let{waitUntilExit:n}=co(lo(ar,{outputDir:o,pluginDir:t}));await n()})}import{createElement as To}from"react";import{render as Eo}from"ink";import{useCallback as at,useState as Me}from"react";import{Box as V,Text as R,useApp as fo,useInput as mo}from"ink";import{join as Dt}from"path";import{access as uo,mkdir as Bt,writeFile as po}from"fs/promises";import{join as Ee}from"path";async function st(e){try{return await uo(e),!0}catch{return!1}}async function dr(e){return await st(Ee(e,"kizen.json"))?"has-manifest":await st(Ee(e,".kizenapp"))?"has-kizenapp":"ok"}async function ur(e,t){let o=Ee(e,t);if(!await st(o))return o;for(let n=1;n<1e3;n++){let r=Ee(e,`${t}-${String(n)}`);if(!await st(r))return r}throw new Error(`Could not find an available directory name for "${t}"`)}function Rt(e){return{name:e.name,version:"1.0.0",published:!0,api_name:e.apiName,external_link:e.externalLink,description:e.description,entry:"src/",engine:"1.0.0",release_notes_directory:"releaseNotes/",release_environments:["prod"],config_template:{},base_config:{},developer_business_id:e.developerBusinessId}}async function pr(e){await Bt(e.targetDir,{recursive:!0});let t=Rt(e);await po(Ee(e.targetDir,"kizen.json"),JSON.stringify(t,null,2)+`
8
+ `,"utf-8"),await Bt(Ee(e.targetDir,"src"),{recursive:!0}),await Bt(Ee(e.targetDir,"releaseNotes"),{recursive:!0}),Be(e.targetDir)}import{jsx as B,jsxs as z}from"react/jsx-runtime";var Pe=["name","apiName","externalLink","description","developerBusinessId"],fr={name:"Name",apiName:"API name",externalLink:"External link",description:"Description",developerBusinessId:"Business ID"},mr=["name","apiName"];function go(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")}var Re=({text:e})=>B(R,{dimColor:!0,children:e});function yo(e){return{name:"",apiName:"",externalLink:"",description:"",developerBusinessId:e}}var gr=({parentDir:e,defaultBusinessId:t})=>{let o=fo(),[n,r]=Me({type:"target-select",cursor:0}),[i,u]=Me("in-place"),[p,m]=Me(()=>yo(t)),[b,y]=Me(""),[S,N]=Me(e),v=at((P,x)=>{u(P),y(x.name),r({type:"field-entry",field:0,values:x})},[]),c=at(async P=>{let x=await dr(P);if(x!=="ok"){r({type:"precheck-error",targetDir:P,reason:x});return}N(P),v("in-place",p)},[p,v]),h=at(async P=>{try{let x=await ur(e,P.apiName);N(x),r({type:"confirm",values:P})}catch(x){r({type:"error",message:x instanceof Error?x.message:String(x)})}},[e]),T=at(async(P,x)=>{try{await pr({targetDir:x,name:P.name,apiName:P.apiName,externalLink:P.externalLink,description:P.description,developerBusinessId:P.developerBusinessId}),r({type:"done",targetDir:x})}catch(w){r({type:"error",message:w instanceof Error?w.message:String(w)})}},[]);if(mo((P,x)=>{if(x.ctrl&&P==="c"){o.exit();return}if(n.type==="target-select"){x.upArrow?r({type:"target-select",cursor:0}):x.downArrow?r({type:"target-select",cursor:1}):x.return?n.cursor===0?c(e):v("sub-dir",p):x.escape&&o.exit();return}if(n.type==="precheck-error"){(x.return||x.escape)&&o.exit();return}if(n.type==="field-entry"){let{field:w,values:k}=n,f=Pe[w];if(!f)return;if(x.escape){o.exit();return}if(x.backspace||x.delete){y(a=>a.slice(0,-1));return}if(x.upArrow&&w>0){let a={...k,[f]:b},s=w-1,l=Pe[s];r({type:"field-entry",field:s,values:a}),m(a),y(l?a[l]:"");return}if(x.return||x.tab||x.downArrow){let a=b.trim();if(mr.includes(f)&&!a){r({type:"field-entry",field:w,values:k,fieldError:`${fr[f]} is required`});return}let l=f==="description"?b:a,d={...k,[f]:l};m(d);let g=w+1;if(g>=Pe.length)y(""),i==="sub-dir"?(r({type:"resolving-target"}),h(d)):r({type:"confirm",values:d});else{let I=Pe[g],E=I?d[I]:"",F=I==="apiName"&&!E?go(d.name):E;r({type:"field-entry",field:g,values:d}),y(F)}return}P&&!x.ctrl&&!x.meta&&y(a=>a+P);return}if(n.type==="confirm"){if(x.escape){let w=Pe.length-1,k=Pe[w];r({type:"field-entry",field:w,values:n.values}),y(k?n.values[k]:"");return}x.return&&(r({type:"writing"}),T(n.values,S));return}(n.type==="done"||n.type==="error")&&(x.return||x.escape)&&o.exit()}),n.type==="target-select"){let P=[{label:"Use current directory",desc:e},{label:"Create new sub-directory",desc:`${e}/<inferred from API name>`}];return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Where should the new plugin live?"}),P.map((x,w)=>{let k=n.cursor===w;return z(V,{gap:2,children:[B(R,{...k&&{color:"cyan"},children:k?"\u276F":" "}),B(R,{bold:k,...k&&{color:"cyan"},children:x.label}),B(R,{dimColor:!0,children:x.desc})]},x.label)})]}),B(Re,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel"})]})}if(n.type==="precheck-error"){let{targetDir:P,reason:x}=n;return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),B(R,{color:"red",bold:!0,children:"Cannot create plugin"}),z(V,{flexDirection:"column",gap:0,children:[z(R,{children:[P," already contains ",B(R,{bold:!0,children:x==="has-manifest"?"kizen.json":".kizenapp/"}),"."]}),B(R,{dimColor:!0,children:"Remove the conflicting file/directory or choose a different target to avoid overwriting an existing plugin."})]}),B(Re,{text:"Enter or Esc to exit"})]})}if(n.type==="field-entry"){let{field:P,fieldError:x}=n,w=i==="sub-dir"?`Target: sub-directory of ${e} (inferred from API name)`:`Target: ${S}`;return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Plugin details"}),B(R,{dimColor:!0,children:w})]}),x!==void 0&&z(R,{color:"red",children:["Error: ",x]}),B(V,{flexDirection:"column",gap:0,children:Pe.map((k,f)=>{let a=P===f,s=a?b:p[k],l=mr.includes(k),d=`${fr[k]}${l?"":" (optional)"}`;return z(V,{gap:2,children:[B(V,{width:24,children:B(R,{bold:a,...a&&{color:"cyan"},children:d})}),B(R,{...a&&{color:"cyan"},children:">"}),B(R,{children:s}),a&&B(R,{color:"cyan",children:"\u2588"})]},k)})}),B(Re,{text:"Enter/Tab/\u2193 next \xB7 \u2191 previous \xB7 Backspace delete \xB7 Esc cancel"})]})}if(n.type==="confirm"){let P=Rt({targetDir:S,name:n.values.name,apiName:n.values.apiName,externalLink:n.values.externalLink,description:n.values.description,developerBusinessId:n.values.developerBusinessId});return z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Ready to create"}),z(R,{dimColor:!0,children:["Target: ",S]})]}),z(V,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"kizen.json preview"}),B(R,{children:JSON.stringify(P,null,2)})]}),z(V,{flexDirection:"column",gap:0,children:[B(R,{dimColor:!0,children:"Also creates:"}),z(R,{dimColor:!0,children:[" ",Dt(S,"src/")]}),z(R,{dimColor:!0,children:[" ",Dt(S,"releaseNotes/")]}),z(R,{dimColor:!0,children:[" ",Dt(S,".gitignore")," (adds .kizenapp/)"]})]}),B(Re,{text:"Enter to create \xB7 Esc to go back"})]})}return n.type==="resolving-target"?B(V,{paddingY:1,paddingX:2,children:B(R,{dimColor:!0,children:"Finding available sub-directory\u2026"})}):n.type==="writing"?B(V,{paddingY:1,paddingX:2,children:B(R,{dimColor:!0,children:"Creating plugin\u2026"})}):n.type==="done"?z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(R,{color:"green",bold:!0,children:["Plugin created at ",n.targetDir]}),z(V,{flexDirection:"column",gap:0,children:[B(R,{dimColor:!0,children:"Next steps:"}),z(R,{children:[" ","cd ",n.targetDir]}),z(R,{children:[" ","npx --yes @kizenapps/cli dev"]})]}),B(Re,{text:"Enter or Esc to exit"})]}):z(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),B(R,{color:"red",bold:!0,children:"Failed to create plugin"}),B(R,{children:n.message}),B(Re,{text:"Enter or Esc to exit"})]})};import{mkdir as yr,readFile as ho,readdir as bo,writeFile as hr}from"fs/promises";import{homedir as xo}from"os";import{dirname as vo,join as lt}from"path";var re=["go","fmo","staging","integration","test1"];var ke=lt(xo(),".kizenappbuilder"),De=lt(ke,"credentials.json"),me="credentials";function wo(e){return re.includes(e)}function Co(e){if(typeof e!="object"||e===null)throw new Error("Credentials must be a JSON object");let t=e,o=t.environment;return{apiKey:typeof t.apiKey=="string"?t.apiKey:"",userId:typeof t.userId=="string"?t.userId:"",businessId:typeof t.businessId=="string"?t.businessId:"",environment:wo(o)?o:"go"}}async function ge(e){let t=await ho(e,"utf-8");return Co(JSON.parse(t))}async function Y(){try{return await ge(De)}catch{return null}}async function So(e){await yr(vo(De),{recursive:!0,mode:448}),await hr(De,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384})}function br(e){return lt(ke,`${e}.json`)}async function _e(){let e=[{name:me,path:De,isDefault:!0}];try{let t=await bo(ke);for(let o of t){if(!o.endsWith(".json"))continue;let n=o.slice(0,-5);n!==me&&e.push({name:n,path:lt(ke,o),isDefault:!1})}}catch{}return e}async function xr(e,t){if(e===me){await So(t);return}await yr(ke,{recursive:!0,mode:448}),await hr(br(e),JSON.stringify(t,null,2),{encoding:"utf-8",mode:384})}async function le(e){try{return await ge(br(e))}catch{return null}}function vr(e){e.command("create").description("Scaffold a new Kizen plugin project").action(async()=>{let t=process.cwd(),n=(await Y())?.businessId??"",{waitUntilExit:r}=Eo(To(gr,{parentDir:t,defaultBusinessId:n}),{exitOnCtrlC:!1});await r()})}import{createElement as Xr}from"react";import{render as Zr}from"ink";import{useCallback as $e,useEffect as gt,useRef as ce,useState as X}from"react";import{Box as W,Text as D,useInput as Ci}from"ink";import{PluginValidationError as Si}from"@kizenapps/packager";import{watch as Ti}from"fs";import{createServer as Ei}from"http";import{join as Gr}from"path";import{WebSocketServer as Pi}from"ws";import{createReadStream as Dr,realpathSync as qo}from"fs";import{access as Jo,readdir as Wo,readFile as Go,realpath as Ko,stat as $r}from"fs/promises";import{dirname as Yo,extname as Lr,join as We,resolve as Xo,sep as Ut}from"path";import{fileURLToPath as Zo}from"url";var Po=new Set(["set-cookie","strict-transport-security","content-security-policy","content-security-policy-report-only","x-frame-options","content-encoding","content-length"]);function ct(e){let t={};for(let[o,n]of Object.entries(e)){let r=o.toLowerCase();Po.has(r)||r.startsWith("access-control-")||(t[o]=n)}return t}var $t=10*1024*1024,ko=6e4,_o=200,He=class extends Error{bytesRead;limit;constructor(t,o){super(`Upstream response exceeded ${String(o)} bytes (read ${String(t)}).`),this.name="ProxyResponseTooLargeError",this.bytesRead=t,this.limit=o}};async function Lt(e,t){let o=e.body;if(o===null)return Buffer.alloc(0);let n=[],r=0;for await(let i of o){if(r+=i.length,r>t)throw new He(r,t);n.push(i)}return Buffer.concat(n)}async function wr(e){let t=ct(Object.fromEntries(e.headers)),o=await Lt(e,$t);return{status:e.status,headers:t,body:o}}function Cr(e={}){let{onChange:t,enabled:o=!0}=e;if(!o)return{async get(u,p){return{response:await wr(await p()),fromCache:!1}},clear(){}};let n=new Map,r=()=>{t?.(n.size)},i=u=>{n.delete(u)&&r()};return{get(u,p){let m=n.get(u);if(m!==void 0){if(Date.now()-m.insertedAt<ko)return m.promise.then(y=>({response:y,fromCache:!0}));i(u)}if(n.size>=_o){let y=n.keys().next().value;y!==void 0&&i(y)}let b=p().then(wr).catch(y=>{throw i(u),y});return n.set(u,{insertedAt:Date.now(),promise:b}),r(),b.then(y=>((y.status<200||y.status>=300)&&i(u),{response:y,fromCache:!1}))},clear(){n.clear(),r()}}}var Ft={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".png":"image/png",".jpg":"image/jpeg",".svg":"image/svg+xml",".ico":"image/x-icon",".json":"application/json; charset=utf-8",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".map":"application/json"};import{mkdir as Io,readFile as No,writeFile as Bo}from"fs/promises";import{join as Sr}from"path";async function ye(e){try{let t=await No(Sr(e,"config.json"),"utf-8");return JSON.parse(t)}catch{return{}}}async function he(e,t){await Io(e,{recursive:!0}),await Bo(Sr(e,"config.json"),JSON.stringify(t,null,2),"utf-8")}var At={prod:"https://plugin-wizard.kizen.com",dev:"https://plugin-wizard.kizen.dev",localDev:"http://localhost:9823"};function Ue(e){let t=process.env.PLUGIN_WIZARD_URL;return t!==void 0&&t!==""?t:e==="prod"?process.env.PLUGIN_WIZARD_URL_PROD||At.prod:process.env.PLUGIN_WIZARD_URL_DEV!==void 0&&process.env.PLUGIN_WIZARD_URL_DEV!==""?process.env.PLUGIN_WIZARD_URL_DEV:process.env.APPBUILDER_LOCAL_DEV!==void 0&&process.env.APPBUILDER_LOCAL_DEV!==""?At.localDev:At.dev}import{spawn as Mt}from"child_process";import{writeFile as Er,rm as zt,mkdtemp as Do,access as $o}from"fs/promises";import{join as qe}from"path";import{tmpdir as Lo}from"os";var Tr=`awslambdaric
9
9
  bcrypt
10
10
  fpdf2
11
11
  lxml
@@ -22,7 +22,7 @@ pytz
22
22
  requests
23
23
  sqlalchemy>=2.0,<2.1
24
24
  tzdata
25
- `;var Do=`
25
+ `;var Fo=`
26
26
  import sys, json, os, traceback
27
27
 
28
28
  # --- Inputs proxy (attribute access) ---
@@ -182,24 +182,24 @@ sys.stdout.write('\\n__KIZEN_RESULT_START__\\n')
182
182
  sys.stdout.write(json.dumps(result, ensure_ascii=False))
183
183
  sys.stdout.write('\\n__KIZEN_RESULT_END__\\n')
184
184
  sys.stdout.flush()
185
- `.trim(),$o=3e4,dt=qe(process.cwd(),".kizenapp","venv"),kr=["python-3-12","python-3-13"];function Lo(e){return kr.includes(e)}function Fo(e){return e.split(`
186
- `).map(t=>t.trim().replace(/\s+#.*$/,"")).filter(t=>t.length>0&&!t.startsWith("#"))}var _r=Fo(Tr);if(_r.length===0)throw new Error("python-requirements.txt bundled no packages \u2014 check the build output");var Ve=null,Je=[3,10];function Ir([e,t]){return e>Je[0]||e===Je[0]&&t>=Je[1]}function jt(e){return`${String(e[0])}.${String(e[1])}`}function Ao(e){let t=/^python-(\d+)[.-](\d+)$/.exec(e),o=t?.[1],n=t?.[2];return o!==void 0&&n!==void 0?`python${o}.${n}`:"python3"}function Nr(e){return new Promise(t=>{let o=Ht(e,["-c","import sys; print('%d.%d' % sys.version_info[:2])"],{stdio:["ignore","pipe","ignore"]}),n="";o.stdout.on("data",r=>{n+=r.toString("utf-8")}),o.on("error",()=>{t(null)}),o.on("close",r=>{let i=/(\d+)\.(\d+)/.exec(n);if(r!==0||!i){t(null);return}t([Number(i[1]),Number(i[2])])})})}async function Oo(e){let t=Ao(e),o=t==="python3"?["python3"]:[t,"python3"],n=[];for(let r of o){let i=await Nr(r);if(!i){n.push(`${r}: not found`);continue}if(Ir(i))return r;n.push(`${r}: ${jt(i)} (too old)`)}throw new Error(`No Python >= ${jt(Je)} found for runtime "${e}". The local runner needs Python ${jt(Je)}+ to install the bundled packages (e.g. psycopg 3.3), matching the remote code-runner (3.12 / 3.13). Tried ${n.join(", ")}. Install Python 3.12 or 3.13 and retry.`)}function Er(e,t,o){return new Promise((n,r)=>{let i=Ht(e,t,{stdio:["ignore","pipe","pipe"]}),u=(f,x)=>{let w=[],S="";return f.on("data",N=>{S+=N.toString("utf-8");let b=S.indexOf(`
187
- `);for(;b>=0;){let c=S.slice(0,b).replace(/\r$/,"");S=S.slice(b+1),w.push(c),o?.(c,x),b=S.indexOf(`
188
- `)}}),f.on("end",()=>{if(S.length>0){let N=S.replace(/\r$/,"");w.push(N),o?.(N,x)}}),w},p=u(i.stderr,"stderr");u(i.stdout,"stdout"),i.on("error",r),i.on("close",f=>{if(f===0)n();else{let x=p.slice(-10).join(`
189
- `).trim(),w=x.length>0?`: ${x}`:"";r(new Error(`${e} exited with code ${String(f)}${w}`))}})})}var zt=null;function jo(e,t){if(Ve)return t&&zt?.add(t),Ve;let o=new Set;t&&o.add(t),zt=o;let n=i=>{for(let u of o)u(i)},r=qe(dt,"bin","python");return Ve=(async()=>{try{let i=!1;try{await Bo(r);let u=await Nr(r);i=u!==null&&Ir(u)}catch{i=!1}if(!i){await Mt(dt,{recursive:!0,force:!0}).catch(()=>{});let u=await Oo(e);await Er(u,["-m","venv",dt])}return n({kind:"start"}),await Er(r,["-m","pip","install","--disable-pip-version-check",..._r],(u,p)=>{n({kind:"log",line:u,stream:p})}),n({kind:"complete"}),r}catch(i){let u=i instanceof Error?i.message:String(i);throw n({kind:"error",message:u}),Ve=null,await Mt(dt,{recursive:!0,force:!0}).catch(()=>{}),i}finally{zt=null}})(),Ve}function zo(e){let t="__KIZEN_RESULT_START__",o="__KIZEN_RESULT_END__",n=e.indexOf(t),r=e.indexOf(o);if(n===-1||r===-1)return{userStdout:e,result:null};let i=e.slice(0,n).trimEnd(),u=e.slice(n+t.length,r).trim();try{let p=JSON.parse(u);return{userStdout:i,result:p}}catch{return{userStdout:e,result:null}}}function Mo(e){return{success:!1,outputValues:{},logs:[],stdout:"",stderr:"",error:e,exitCode:1,durationMs:0}}async function Br(e){let t=e.timeout??$o;if(!Lo(e.scriptRuntime))return Mo(`Unsupported runtime "${e.scriptRuntime}". Supported runtimes: ${kr.join(", ")}. Update the step's config.json "runtime" field (e.g. "python 3.13").`);let o=await jo(e.scriptRuntime,e.onInstallProgress),n=Date.now(),r;try{r=await No(qe(Ro(),"kizen-step-"));let i=qe(r,"wrapper.py"),u=qe(r,"script.py");await Promise.all([Pr(i,Do,"utf-8"),Pr(u,e.script,"utf-8")]);let p={...process.env,__KIZEN_INPUTS__:JSON.stringify(e.inputs),__KIZEN_SECRETS__:JSON.stringify(e.secrets),__KIZEN_SCRIPT_PATH__:u},{exitCode:f,stdout:x,stderr:w}=await new Promise(y=>{let T=[],E=[],h=!1,v=Ht(o,[i],{env:p,cwd:r,stdio:["ignore","pipe","pipe"]}),k=setTimeout(()=>{v.kill("SIGKILL")},t);v.stdout.on("data",a=>{T.push(a)}),v.stderr.on("data",a=>{E.push(a)});let m=a=>{h||(h=!0,clearTimeout(k),y({exitCode:a??1,stdout:Buffer.concat(T).toString("utf-8"),stderr:Buffer.concat(E).toString("utf-8")}))};v.on("close",m),v.on("error",a=>{h||(h=!0,clearTimeout(k),y({exitCode:1,stdout:"",stderr:a.message}))})}),S=Date.now()-n,{userStdout:N,result:b}=zo(x);if(b){let y={success:b.success,outputValues:b.outputValues,logs:b.logs,stdout:N,stderr:w,exitCode:f,durationMs:S};return b.error!==null&&(y.error=b.error),b.httpRequests&&(y.httpRequests=b.httpRequests),y}let c={success:!1,outputValues:{},logs:[],stdout:N,stderr:w,exitCode:f,durationMs:S};return f!==0&&(c.error=`Process exited with code ${String(f)}`),c}finally{r&&Mt(r,{recursive:!0,force:!0})}}var Rr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".json",".md",".mdx",".yml",".yaml",".toml",".css",".scss",".html",".htm",".xml",".svg",".txt",".sh",".py",".env",".gitignore",".prettierrc",".eslintrc"]);import{CRYPTO_ALG as Fr,CRYPTO_VERSION as Ar,deserializeEnvelope as Yo,encrypt as Xo,serializeEnvelope as Zo}from"@kizenapps/packager";function Ut(e){if(e.kind==="info")return e.message;let t=e.fromCache?" [cache]":"",o=e.upstreamStatus!==void 0?` (upstream ${String(e.upstreamStatus)})`:"";return`${e.method} ${e.url} \u2192 ${String(e.status)}${o}${t}`}var Qo=2*1024*1024,ei=new Set([".DS_Store",".gitignore"]);function ti(e){if(e===void 0||e==="")return!1;let t=e.startsWith("[")?e.slice(0,e.indexOf("]")+1):e.split(":")[0]??"";return t==="localhost"||t==="127.0.0.1"||t==="[::1]"}var Mr=["kizen.com","kizen.dev"];function ri(e){let t;try{t=new URL(e)}catch{return!1}let o=t.hostname.toLowerCase();return o==="localhost"||o==="127.0.0.1"||o==="[::1]"?!0:t.protocol!=="https:"?!1:Mr.some(n=>o===n||o.endsWith("."+n))}function ni(e){let t;try{t=new URL(e)}catch{return!1}if(t.protocol!=="https:")return!1;let o=t.hostname.toLowerCase();return Mr.some(n=>o===n||o.endsWith("."+n))}function oi(e){if(e===void 0||e==="")return!1;try{let{hostname:t}=new URL(e);return t==="localhost"||t==="127.0.0.1"||t==="::1"}catch{return!1}}async function Or(e,t){if(t.includes("\0"))return null;let o=t.replace(/^\/+/,""),n=Go(e,o);if(n!==e&&!n.startsWith(e+Vt))return null;try{let r=await Jo(n);return r!==e&&!r.startsWith(e+Vt)?null:r}catch{return null}}function jr(e,t){let o=t===e?"":t.slice(e.length+1);return o===""?!1:o.split(Vt).some(r=>et.has(r))}function Hr(){let e=Ko(import.meta.url);return We(Wo(e),"viewer")}function zr(e,t,o){if(e.includes("/external-integrations/proxy")&&t["content-type"]?.includes("application/json"))try{let n=JSON.parse(o.toString("utf8"));return typeof n.status_code=="number"?n.status_code:void 0}catch{return}}async function qt(e){try{return await Uo(e),!0}catch{return!1}}function Ur(e,t,o,n,r,i,u,p,f,x,w){let S=Cr({onChange:p,enabled:w}),N=Ho(x);return(b,c)=>{(async()=>{let y=b.url??"/";try{if(!ti(b.headers.host)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Forbidden"}));return}if((b.method==="POST"||b.method==="PATCH"||b.method==="DELETE")&&!oi(b.headers.origin)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Forbidden"}));return}if(t(`Received request: ${y}`),y==="/api/credentials"){c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({credentials:n.current??null,activeProfile:r.current??null}));return}if(y==="/api/credential-profiles"&&b.method==="GET"){let a=await _e();c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({profiles:a,active:r.current}));return}if(y==="/api/credentials/switch"&&b.method==="POST"){let a=[];for await(let g of b)a.push(g);let l=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}").profile,d=l===void 0||l===""?await Y():await le(l);if(d!==null){n.current=d,r.current=l??void 0;let g=r.current,I=await ye(i);await he(i,{...I,credentialMode:"global",...g!==void 0&&{activeCredentialProfile:g}}),u({type:"credentials-updated",credentials:d,activeProfile:r.current??null})}c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({ok:d!==null}));return}if(y==="/api/bundle"){let a=We(process.cwd(),".kizenapp","bundle.json");try{let s=await qo(a,"utf-8");c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(s)}catch{c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end("{}")}return}if(y==="/api/last-path"&&b.method==="POST"){let a=[];for await(let l of b)a.push(l);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.path=="string"){f.current=s.path;let l=await ye(i);await he(i,{...l,lastPath:s.path})}c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(y==="/api/encryption-target"&&b.method==="GET"){let s=(await ye(i)).encryptionTarget==="dev"?"dev":"prod";c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({target:s}));return}if(y==="/api/encryption-target"&&b.method==="POST"){let a=[];for await(let g of b)a.push(g);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}"),l=s!==null&&typeof s=="object"?s:{};if(l.target!=="dev"&&l.target!=="prod"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"target must be one of: 'dev', 'prod'"}));return}let d=await ye(i);await he(i,{...d,encryptionTarget:l.target}),c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(y==="/api/execute-step"&&b.method==="POST"){let a=[];for await(let g of b)a.push(g);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.script!="string"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing required field: script"}));return}let l={script:s.script,scriptRuntime:s.scriptRuntime??"python-3-13",inputs:s.inputs??{},secrets:s.secrets??{},onInstallProgress:g=>{g.kind==="start"?u({type:"venv-install-start"}):g.kind==="log"?u({type:"venv-install-log",line:g.line,stream:g.stream}):g.kind==="complete"?u({type:"venv-install-complete"}):u({type:"venv-install-error",message:g.message})}};typeof s.timeout=="number"&&s.timeout>0&&(l.timeout=Math.min(s.timeout,300*1e3));let d=await Br(l);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify(d));return}if(y==="/api/proxy-cache/clear"){S.clear(),o({kind:"info",message:"Proxy cache cleared"}),c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(y==="/api/local/encrypt"&&b.method==="POST"){let a=[];for await(let l of b)a.push(l);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.publicKeyPem!="string"||typeof s.value!="string"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing required fields: publicKeyPem, value"}));return}try{let l=Xo(s.value,s.publicKeyPem),d=Zo(l);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify(d))}catch(l){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:l.message}))}return}if(y==="/api/local/validate"&&b.method==="POST"){let a=[];for await(let P of b)a.push(P);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.value!="string"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing required field: value"}));return}let l,d;try{l=Yo(s.value)}catch(P){d=P.message}if(d!==void 0||l===void 0){c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({valid:!1,checks:[],error:d}));return}let g=P=>Buffer.from(P,"base64").length,I=[{label:"Version",expected:String(Ar),actual:String(l.v),pass:l.v===Ar},{label:"Algorithm",expected:Fr,actual:l.alg,pass:l.alg===Fr},{label:"Wrapped key",expected:"384 bytes (RSA-3072)",actual:`${String(g(l.k))} bytes`,pass:g(l.k)===384},{label:"IV",expected:"12 bytes",actual:`${String(g(l.iv))} bytes`,pass:g(l.iv)===12},{label:"Auth tag",expected:"16 bytes",actual:`${String(g(l.tag))} bytes`,pass:g(l.tag)===16},{label:"Ciphertext",expected:"\u2265 1 byte",actual:`${String(g(l.ct))} bytes`,pass:g(l.ct)>=1}];c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({valid:I.every(P=>P.pass),checks:I}));return}if(y.startsWith("/api/wizard")){let a=b.headers["x-encryption-target"],l=(Array.isArray(a)?a[0]:a)==="dev"?"dev":"prod",d=Ue(l);if(!ri(d)){c.writeHead(500,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:`Encryption API host is not allowed: ${d}`}));return}let g=y.slice(11)||"/",I=`${d}${g}`,P=b.method??"GET",F=[];for await(let we of b)F.push(we);let{host:M,"x-encryption-target":K,...Q}=b.headers,ne=F.length>0?Buffer.concat(F):void 0,oe=ne&&ne.length>0?ne:void 0,ee;try{ee=await fetch(I,{method:P,headers:Q,...oe!==void 0&&{body:oe}})}catch(we){let wt=we.code==="ECONNREFUSED"?`plugin-wizard is not running at ${d}`:`Failed to reach plugin-wizard: ${we.message}`;c.writeHead(503,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:wt}));return}let Z=ct(Object.fromEntries(ee.headers)),Le=await ee.arrayBuffer();c.writeHead(ee.status,Z),c.end(Buffer.from(Le));return}if(y.startsWith("/api/proxy")){let a=b.headers["x-proxy-target"];if(typeof a!="string"){c.writeHead(400),c.end("Missing x-proxy-target header");return}if(!ni(a)){c.writeHead(400),c.end("Invalid proxy target");return}let s=y.slice(10)||"/",l=`${a}${s}`,d=b.method??"GET",g=[];for await(let ee of b)g.push(ee);let{host:I,"x-proxy-target":P,...F}=b.headers;if(d==="GET"){let ee=`GET::${l}`,{response:Z,fromCache:Le}=await S.get(ee,()=>fetch(l,{method:"GET",headers:F}));o({kind:"request",method:"GET",status:Z.status,upstreamStatus:zr(s,Z.headers,Z.body),fromCache:Le,url:s}),c.writeHead(Z.status,Z.headers),c.end(Z.body);return}let M=g.length>0?Buffer.concat(g):void 0,K=M&&M.length>0?M:void 0,Q=await fetch(l,{method:d,headers:F,...K!==void 0&&{body:K}}),ne=ct(Object.fromEntries(Q.headers)),oe=await Ft(Q,Lt);o({kind:"request",method:d,status:Q.status,upstreamStatus:zr(s,ne,oe),fromCache:!1,url:s}),c.writeHead(Q.status,ne),c.end(oe);return}if(y.startsWith("/api/source/tree")&&b.method==="GET"){let s=new URL(y,"http://localhost").searchParams.get("path")??"",l=await Or(N,s);if(l===null){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Invalid path"}));return}if(jr(N,l)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Path is excluded"}));return}try{let d=await Vo(l,{withFileTypes:!0}),g=await Promise.all(d.filter(P=>P.isDirectory()?!et.has(P.name):P.isFile()?!ei.has(P.name):!1).map(async P=>{let F=P.isDirectory()?"dir":"file",M={name:P.name,kind:F};if(F==="file")try{let K=await $r(We(l,P.name));M.size=K.size}catch{}return M}));g.sort((P,F)=>P.kind!==F.kind?P.kind==="dir"?-1:1:P.name.localeCompare(F.name));let I=l===N?"":l.slice(N.length+1);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({path:I,entries:g}))}catch(d){let g=d instanceof Error?d.message:String(d);t(`source/tree failed (${s}): ${g}`),c.writeHead(404,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not found"}))}return}if(y.startsWith("/api/source/file")&&b.method==="GET"){let s=new URL(y,"http://localhost").searchParams.get("path")??"";if(s===""){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing path"}));return}let l=await Or(N,s);if(l===null){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Invalid path"}));return}if(jr(N,l)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Path is excluded"}));return}try{let d=await $r(l);if(!d.isFile()){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not a file"}));return}if(d.size>Qo){c.writeHead(413,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"File too large",size:d.size}));return}let g=Lr(l).toLowerCase(),I=At[g],P=Rr.has(g),F=I??(P?"text/plain; charset=utf-8":"application/octet-stream");c.writeHead(200,{"Content-Type":F,"Content-Length":String(d.size)}),Dr(l).pipe(c)}catch(d){let g=d instanceof Error?d.message:String(d);t(`source/file failed (${s}): ${g}`),c.writeHead(404,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not found"}))}return}let h=We(e,y==="/"?"/index.html":y),v=await qt(h)?h:We(e,"index.html"),k=Lr(v),m=At[k]??"application/octet-stream";c.writeHead(200,{"Content-Type":m}),Dr(v).pipe(c)}catch(T){if(y.startsWith("/api/proxy")){let E=y.slice(10)||"/",h=b.method??"GET";T instanceof He?o({kind:"info",message:`${h} ${E} \u2192 502 (response exceeded ${String(T.limit)} bytes)`}):o({kind:"request",method:h,status:502,fromCache:!1,url:E})}else o({kind:"info",message:`Error handling ${y}: ${T instanceof Error?T.message:String(T)}`});c.headersSent||(c.writeHead(502),c.end("Bad Gateway"))}})()}}import{launch as ii}from"chrome-launcher";import{createRequire as si}from"module";import{mkdirSync as ai}from"fs";import{readFile as li}from"fs/promises";import{dirname as ci,join as di}from"path";import{fileURLToPath as ui}from"url";var Vr=si(import.meta.url)("chrome-remote-interface"),pi=new Set(["content-security-policy","content-security-policy-report-only","x-frame-options"]),Jr=["kizen.dev","kizen.com"];function qr(e){try{let{hostname:t}=new URL(e);return Jr.some(o=>t===o||t.endsWith("."+o))}catch{return!1}}async function fi(e){try{let t=di(ci(ui(import.meta.url)),"viewer","icon.png"),o=await li(t);await e.Browser.setDockTile({image:o.toString("base64")})}catch{}}async function Wr(e){ai(e.userDataDir,{recursive:!0});let t=`http://localhost:${String(e.port)}`,o=await ii({startingUrl:t,chromeFlags:[`--app=${t}`,"--no-first-run","--no-default-browser-check","--disable-extensions","--disable-features=DeviceBoundSessions"],userDataDir:e.userDataDir,handleSIGINT:!1,logLevel:"silent"}),n=o.port,r=null,i=null,u=null,p=null,f=0,x=!1,w=v=>{e.debugLog?.(v)},S=v=>{e.verbose&&e.debugLog?.(v)},N=()=>{i!==null&&(clearInterval(i),i=null)},b=v=>v==="chrome://new-tab-page/"||v==="chrome://newtab/",c=async v=>{N(),u=null,await fi(v),await v.Fetch.enable({patterns:Jr.flatMap(m=>[{urlPattern:`*://${m}/*`,requestStage:"Response"},{urlPattern:`*://*.${m}/*`,requestStage:"Response"}])}),v.on("Fetch.requestPaused",m=>{(async()=>{let a=m,{requestId:s,request:l,responseHeaders:d,responseStatusCode:g}=a,I=l.url;S(`Fetch ${String(g??"?")} ${I}`);let P=[],F=!1;for(let M of d??[])if(!pi.has(M.name.toLowerCase()))if(M.name.toLowerCase()==="set-cookie"&&qr(I)){let K=M.value.split(`
185
+ `.trim(),Ao=3e4,dt=qe(process.cwd(),".kizenapp","venv"),kr=["python-3-12","python-3-13"];function Oo(e){return kr.includes(e)}function jo(e){return e.split(`
186
+ `).map(t=>t.trim().replace(/\s+#.*$/,"")).filter(t=>t.length>0&&!t.startsWith("#"))}var _r=jo(Tr);if(_r.length===0)throw new Error("python-requirements.txt bundled no packages \u2014 check the build output");var Ve=null,Je=[3,10];function Ir([e,t]){return e>Je[0]||e===Je[0]&&t>=Je[1]}function Ot(e){return`${String(e[0])}.${String(e[1])}`}function zo(e){let t=/^python-(\d+)[.-](\d+)$/.exec(e),o=t?.[1],n=t?.[2];return o!==void 0&&n!==void 0?`python${o}.${n}`:"python3"}function Nr(e){return new Promise(t=>{let o=Mt(e,["-c","import sys; print('%d.%d' % sys.version_info[:2])"],{stdio:["ignore","pipe","ignore"]}),n="";o.stdout.on("data",r=>{n+=r.toString("utf-8")}),o.on("error",()=>{t(null)}),o.on("close",r=>{let i=/(\d+)\.(\d+)/.exec(n);if(r!==0||!i){t(null);return}t([Number(i[1]),Number(i[2])])})})}async function Mo(e){let t=zo(e),o=t==="python3"?["python3"]:[t,"python3"],n=[];for(let r of o){let i=await Nr(r);if(!i){n.push(`${r}: not found`);continue}if(Ir(i))return r;n.push(`${r}: ${Ot(i)} (too old)`)}throw new Error(`No Python >= ${Ot(Je)} found for runtime "${e}". The local runner needs Python ${Ot(Je)}+ to install the bundled packages (e.g. psycopg 3.3), matching the remote code-runner (3.12 / 3.13). Tried ${n.join(", ")}. Install Python 3.12 or 3.13 and retry.`)}function Pr(e,t,o){return new Promise((n,r)=>{let i=Mt(e,t,{stdio:["ignore","pipe","pipe"]}),u=(m,b)=>{let y=[],S="";return m.on("data",N=>{S+=N.toString("utf-8");let v=S.indexOf(`
187
+ `);for(;v>=0;){let c=S.slice(0,v).replace(/\r$/,"");S=S.slice(v+1),y.push(c),o?.(c,b),v=S.indexOf(`
188
+ `)}}),m.on("end",()=>{if(S.length>0){let N=S.replace(/\r$/,"");y.push(N),o?.(N,b)}}),y},p=u(i.stderr,"stderr");u(i.stdout,"stdout"),i.on("error",r),i.on("close",m=>{if(m===0)n();else{let b=p.slice(-10).join(`
189
+ `).trim(),y=b.length>0?`: ${b}`:"";r(new Error(`${e} exited with code ${String(m)}${y}`))}})})}var jt=null;function Ho(e,t){if(Ve)return t&&jt?.add(t),Ve;let o=new Set;t&&o.add(t),jt=o;let n=i=>{for(let u of o)u(i)},r=qe(dt,"bin","python");return Ve=(async()=>{try{let i=!1;try{await $o(r);let u=await Nr(r);i=u!==null&&Ir(u)}catch{i=!1}if(!i){await zt(dt,{recursive:!0,force:!0}).catch(()=>{});let u=await Mo(e);await Pr(u,["-m","venv",dt])}return n({kind:"start"}),await Pr(r,["-m","pip","install","--disable-pip-version-check",..._r],(u,p)=>{n({kind:"log",line:u,stream:p})}),n({kind:"complete"}),r}catch(i){let u=i instanceof Error?i.message:String(i);throw n({kind:"error",message:u}),Ve=null,await zt(dt,{recursive:!0,force:!0}).catch(()=>{}),i}finally{jt=null}})(),Ve}function Uo(e){let t="__KIZEN_RESULT_START__",o="__KIZEN_RESULT_END__",n=e.indexOf(t),r=e.indexOf(o);if(n===-1||r===-1)return{userStdout:e,result:null};let i=e.slice(0,n).trimEnd(),u=e.slice(n+t.length,r).trim();try{let p=JSON.parse(u);return{userStdout:i,result:p}}catch{return{userStdout:e,result:null}}}function Vo(e){return{success:!1,outputValues:{},logs:[],stdout:"",stderr:"",error:e,exitCode:1,durationMs:0}}async function Br(e){let t=e.timeout??Ao;if(!Oo(e.scriptRuntime))return Vo(`Unsupported runtime "${e.scriptRuntime}". Supported runtimes: ${kr.join(", ")}. Update the step's config.json "runtime" field (e.g. "python 3.13").`);let o=await Ho(e.scriptRuntime,e.onInstallProgress),n=Date.now(),r;try{r=await Do(qe(Lo(),"kizen-step-"));let i=qe(r,"wrapper.py"),u=qe(r,"script.py");await Promise.all([Er(i,Fo,"utf-8"),Er(u,e.script,"utf-8")]);let p={...process.env,__KIZEN_INPUTS__:JSON.stringify(e.inputs),__KIZEN_SECRETS__:JSON.stringify(e.secrets),__KIZEN_SCRIPT_PATH__:u},{exitCode:m,stdout:b,stderr:y}=await new Promise(h=>{let T=[],P=[],x=!1,w=Mt(o,[i],{env:p,cwd:r,stdio:["ignore","pipe","pipe"]}),k=setTimeout(()=>{w.kill("SIGKILL")},t);w.stdout.on("data",a=>{T.push(a)}),w.stderr.on("data",a=>{P.push(a)});let f=a=>{x||(x=!0,clearTimeout(k),h({exitCode:a??1,stdout:Buffer.concat(T).toString("utf-8"),stderr:Buffer.concat(P).toString("utf-8")}))};w.on("close",f),w.on("error",a=>{x||(x=!0,clearTimeout(k),h({exitCode:1,stdout:"",stderr:a.message}))})}),S=Date.now()-n,{userStdout:N,result:v}=Uo(b);if(v){let h={success:v.success,outputValues:v.outputValues,logs:v.logs,stdout:N,stderr:y,exitCode:m,durationMs:S};return v.error!==null&&(h.error=v.error),v.httpRequests&&(h.httpRequests=v.httpRequests),h}let c={success:!1,outputValues:{},logs:[],stdout:N,stderr:y,exitCode:m,durationMs:S};return m!==0&&(c.error=`Process exited with code ${String(m)}`),c}finally{r&&zt(r,{recursive:!0,force:!0})}}var Rr=new Set([".ts",".tsx",".js",".jsx",".mjs",".cjs",".json",".md",".mdx",".yml",".yaml",".toml",".css",".scss",".html",".htm",".xml",".svg",".txt",".sh",".py",".env",".gitignore",".prettierrc",".eslintrc"]);import{CRYPTO_ALG as Fr,CRYPTO_VERSION as Ar,deserializeEnvelope as Qo,encrypt as ei,serializeEnvelope as ti}from"@kizenapps/packager";function Ht(e){if(e.kind==="info")return e.message;let t=e.fromCache?" [cache]":"",o=e.upstreamStatus!==void 0?` (upstream ${String(e.upstreamStatus)})`:"";return`${e.method} ${e.url} \u2192 ${String(e.status)}${o}${t}`}var ri=2*1024*1024,ni=new Set([".DS_Store",".gitignore"]);function oi(e){if(e===void 0||e==="")return!1;let t=e.startsWith("[")?e.slice(0,e.indexOf("]")+1):e.split(":")[0]??"";return t==="localhost"||t==="127.0.0.1"||t==="[::1]"}var Mr=["kizen.com","kizen.dev"];function ii(e){let t;try{t=new URL(e)}catch{return!1}let o=t.hostname.toLowerCase();return o==="localhost"||o==="127.0.0.1"||o==="[::1]"?!0:t.protocol!=="https:"?!1:Mr.some(n=>o===n||o.endsWith("."+n))}function si(e){let t;try{t=new URL(e)}catch{return!1}if(t.protocol!=="https:")return!1;let o=t.hostname.toLowerCase();return Mr.some(n=>o===n||o.endsWith("."+n))}function ai(e){if(e===void 0||e==="")return!1;try{let{hostname:t}=new URL(e);return t==="localhost"||t==="127.0.0.1"||t==="::1"}catch{return!1}}async function Or(e,t){if(t.includes("\0"))return null;let o=t.replace(/^\/+/,""),n=Xo(e,o);if(n!==e&&!n.startsWith(e+Ut))return null;try{let r=await Ko(n);return r!==e&&!r.startsWith(e+Ut)?null:r}catch{return null}}function jr(e,t){let o=t===e?"":t.slice(e.length+1);return o===""?!1:o.split(Ut).some(r=>et.has(r))}function Hr(){let e=Zo(import.meta.url);return We(Yo(e),"viewer")}function zr(e,t,o){if(e.includes("/external-integrations/proxy")&&t["content-type"]?.includes("application/json"))try{let n=JSON.parse(o.toString("utf8"));return typeof n.status_code=="number"?n.status_code:void 0}catch{return}}async function Vt(e){try{return await Jo(e),!0}catch{return!1}}function Ur(e,t,o,n,r,i,u,p,m,b,y){let S=Cr({onChange:p,enabled:y}),N=qo(b);return(v,c)=>{(async()=>{let h=v.url??"/";try{if(!oi(v.headers.host)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Forbidden"}));return}if((v.method==="POST"||v.method==="PATCH"||v.method==="DELETE")&&!ai(v.headers.origin)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Forbidden"}));return}if(t(`Received request: ${h}`),h==="/api/credentials"){c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({credentials:n.current??null,activeProfile:r.current??null}));return}if(h==="/api/credential-profiles"&&v.method==="GET"){let a=await _e();c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({profiles:a,active:r.current}));return}if(h==="/api/credentials/switch"&&v.method==="POST"){let a=[];for await(let g of v)a.push(g);let l=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}").profile,d=l===void 0||l===""?await Y():await le(l);if(d!==null){n.current=d,r.current=l??void 0;let g=r.current,I=await ye(i);await he(i,{...I,credentialMode:"global",...g!==void 0&&{activeCredentialProfile:g}}),u({type:"credentials-updated",credentials:d,activeProfile:r.current??null})}c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({ok:d!==null}));return}if(h==="/api/bundle"){let a=We(process.cwd(),".kizenapp","bundle.json");try{let s=await Go(a,"utf-8");c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(s)}catch{c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end("{}")}return}if(h==="/api/last-path"&&v.method==="POST"){let a=[];for await(let l of v)a.push(l);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.path=="string"){m.current=s.path;let l=await ye(i);await he(i,{...l,lastPath:s.path})}c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(h==="/api/encryption-target"&&v.method==="GET"){let s=(await ye(i)).encryptionTarget==="dev"?"dev":"prod";c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({target:s}));return}if(h==="/api/encryption-target"&&v.method==="POST"){let a=[];for await(let g of v)a.push(g);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}"),l=s!==null&&typeof s=="object"?s:{};if(l.target!=="dev"&&l.target!=="prod"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"target must be one of: 'dev', 'prod'"}));return}let d=await ye(i);await he(i,{...d,encryptionTarget:l.target}),c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(h==="/api/execute-step"&&v.method==="POST"){let a=[];for await(let g of v)a.push(g);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.script!="string"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing required field: script"}));return}let l={script:s.script,scriptRuntime:s.scriptRuntime??"python-3-13",inputs:s.inputs??{},secrets:s.secrets??{},onInstallProgress:g=>{g.kind==="start"?u({type:"venv-install-start"}):g.kind==="log"?u({type:"venv-install-log",line:g.line,stream:g.stream}):g.kind==="complete"?u({type:"venv-install-complete"}):u({type:"venv-install-error",message:g.message})}};typeof s.timeout=="number"&&s.timeout>0&&(l.timeout=Math.min(s.timeout,300*1e3));let d=await Br(l);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify(d));return}if(h==="/api/proxy-cache/clear"){S.clear(),o({kind:"info",message:"Proxy cache cleared"}),c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(h==="/api/local/encrypt"&&v.method==="POST"){let a=[];for await(let l of v)a.push(l);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.publicKeyPem!="string"||typeof s.value!="string"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing required fields: publicKeyPem, value"}));return}try{let l=ei(s.value,s.publicKeyPem),d=ti(l);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify(d))}catch(l){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:l.message}))}return}if(h==="/api/local/validate"&&v.method==="POST"){let a=[];for await(let E of v)a.push(E);let s=JSON.parse(Buffer.concat(a).toString("utf-8")||"{}");if(typeof s.value!="string"){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing required field: value"}));return}let l,d;try{l=Qo(s.value)}catch(E){d=E.message}if(d!==void 0||l===void 0){c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({valid:!1,checks:[],error:d}));return}let g=E=>Buffer.from(E,"base64").length,I=[{label:"Version",expected:String(Ar),actual:String(l.v),pass:l.v===Ar},{label:"Algorithm",expected:Fr,actual:l.alg,pass:l.alg===Fr},{label:"Wrapped key",expected:"384 bytes (RSA-3072)",actual:`${String(g(l.k))} bytes`,pass:g(l.k)===384},{label:"IV",expected:"12 bytes",actual:`${String(g(l.iv))} bytes`,pass:g(l.iv)===12},{label:"Auth tag",expected:"16 bytes",actual:`${String(g(l.tag))} bytes`,pass:g(l.tag)===16},{label:"Ciphertext",expected:"\u2265 1 byte",actual:`${String(g(l.ct))} bytes`,pass:g(l.ct)>=1}];c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({valid:I.every(E=>E.pass),checks:I}));return}if(h.startsWith("/api/wizard")){let a=v.headers["x-encryption-target"],l=(Array.isArray(a)?a[0]:a)==="dev"?"dev":"prod",d=Ue(l);if(!ii(d)){c.writeHead(500,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:`Encryption API host is not allowed: ${d}`}));return}let g=h.slice(11)||"/",I=`${d}${g}`,E=v.method??"GET",F=[];for await(let we of v)F.push(we);let{host:M,"x-encryption-target":K,...Q}=v.headers,ne=F.length>0?Buffer.concat(F):void 0,oe=ne&&ne.length>0?ne:void 0,ee;try{ee=await fetch(I,{method:E,headers:Q,...oe!==void 0&&{body:oe}})}catch(we){let wt=we.code==="ECONNREFUSED"?`plugin-wizard is not running at ${d}`:`Failed to reach plugin-wizard: ${we.message}`;c.writeHead(503,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:wt}));return}let Z=ct(Object.fromEntries(ee.headers)),Le=await ee.arrayBuffer();c.writeHead(ee.status,Z),c.end(Buffer.from(Le));return}if(h.startsWith("/api/proxy")){let a=v.headers["x-proxy-target"];if(typeof a!="string"){c.writeHead(400),c.end("Missing x-proxy-target header");return}if(!si(a)){c.writeHead(400),c.end("Invalid proxy target");return}let s=h.slice(10)||"/",l=`${a}${s}`,d=v.method??"GET",g=[];for await(let ee of v)g.push(ee);let{host:I,"x-proxy-target":E,...F}=v.headers;if(d==="GET"){let ee=`GET::${l}`,{response:Z,fromCache:Le}=await S.get(ee,()=>fetch(l,{method:"GET",headers:F}));o({kind:"request",method:"GET",status:Z.status,upstreamStatus:zr(s,Z.headers,Z.body),fromCache:Le,url:s}),c.writeHead(Z.status,Z.headers),c.end(Z.body);return}let M=g.length>0?Buffer.concat(g):void 0,K=M&&M.length>0?M:void 0,Q=await fetch(l,{method:d,headers:F,...K!==void 0&&{body:K}}),ne=ct(Object.fromEntries(Q.headers)),oe=await Lt(Q,$t);o({kind:"request",method:d,status:Q.status,upstreamStatus:zr(s,ne,oe),fromCache:!1,url:s}),c.writeHead(Q.status,ne),c.end(oe);return}if(h.startsWith("/api/source/tree")&&v.method==="GET"){let s=new URL(h,"http://localhost").searchParams.get("path")??"",l=await Or(N,s);if(l===null){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Invalid path"}));return}if(jr(N,l)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Path is excluded"}));return}try{let d=await Wo(l,{withFileTypes:!0}),g=await Promise.all(d.filter(E=>E.isDirectory()?!et.has(E.name):E.isFile()?!ni.has(E.name):!1).map(async E=>{let F=E.isDirectory()?"dir":"file",M={name:E.name,kind:F};if(F==="file")try{let K=await $r(We(l,E.name));M.size=K.size}catch{}return M}));g.sort((E,F)=>E.kind!==F.kind?E.kind==="dir"?-1:1:E.name.localeCompare(F.name));let I=l===N?"":l.slice(N.length+1);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({path:I,entries:g}))}catch(d){let g=d instanceof Error?d.message:String(d);t(`source/tree failed (${s}): ${g}`),c.writeHead(404,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not found"}))}return}if(h.startsWith("/api/source/file")&&v.method==="GET"){let s=new URL(h,"http://localhost").searchParams.get("path")??"";if(s===""){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Missing path"}));return}let l=await Or(N,s);if(l===null){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Invalid path"}));return}if(jr(N,l)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Path is excluded"}));return}try{let d=await $r(l);if(!d.isFile()){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not a file"}));return}if(d.size>ri){c.writeHead(413,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"File too large",size:d.size}));return}let g=Lr(l).toLowerCase(),I=Ft[g],E=Rr.has(g),F=I??(E?"text/plain; charset=utf-8":"application/octet-stream");c.writeHead(200,{"Content-Type":F,"Content-Length":String(d.size)}),Dr(l).pipe(c)}catch(d){let g=d instanceof Error?d.message:String(d);t(`source/file failed (${s}): ${g}`),c.writeHead(404,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not found"}))}return}let x=We(e,h==="/"?"/index.html":h),w=await Vt(x)?x:We(e,"index.html"),k=Lr(w),f=Ft[k]??"application/octet-stream";c.writeHead(200,{"Content-Type":f}),Dr(w).pipe(c)}catch(T){if(h.startsWith("/api/proxy")){let P=h.slice(10)||"/",x=v.method??"GET";T instanceof He?o({kind:"info",message:`${x} ${P} \u2192 502 (response exceeded ${String(T.limit)} bytes)`}):o({kind:"request",method:x,status:502,fromCache:!1,url:P})}else o({kind:"info",message:`Error handling ${h}: ${T instanceof Error?T.message:String(T)}`});c.headersSent||(c.writeHead(502),c.end("Bad Gateway"))}})()}}import{launch as li}from"chrome-launcher";import{createRequire as ci}from"module";import{mkdirSync as di}from"fs";import{readFile as ui}from"fs/promises";import{dirname as pi,join as fi}from"path";import{fileURLToPath as mi}from"url";var Vr=ci(import.meta.url)("chrome-remote-interface"),gi=new Set(["content-security-policy","content-security-policy-report-only","x-frame-options"]),Jr=["kizen.dev","kizen.com"];function qr(e){try{let{hostname:t}=new URL(e);return Jr.some(o=>t===o||t.endsWith("."+o))}catch{return!1}}async function yi(e){try{let t=fi(pi(mi(import.meta.url)),"viewer","icon.png"),o=await ui(t);await e.Browser.setDockTile({image:o.toString("base64")})}catch{}}async function Wr(e){di(e.userDataDir,{recursive:!0});let t=`http://localhost:${String(e.port)}`,o=await li({startingUrl:t,chromeFlags:[`--app=${t}`,"--no-first-run","--no-default-browser-check","--disable-extensions","--disable-features=DeviceBoundSessions"],userDataDir:e.userDataDir,handleSIGINT:!1,logLevel:"silent"}),n=o.port,r=null,i=null,u=null,p=null,m=0,b=!1,y=w=>{e.debugLog?.(w)},S=w=>{e.verbose&&e.debugLog?.(w)},N=()=>{i!==null&&(clearInterval(i),i=null)},v=w=>w==="chrome://new-tab-page/"||w==="chrome://newtab/",c=async w=>{N(),u=null,await yi(w),await w.Fetch.enable({patterns:Jr.flatMap(f=>[{urlPattern:`*://${f}/*`,requestStage:"Response"},{urlPattern:`*://*.${f}/*`,requestStage:"Response"}])}),w.on("Fetch.requestPaused",f=>{(async()=>{let a=f,{requestId:s,request:l,responseHeaders:d,responseStatusCode:g}=a,I=l.url;S(`Fetch ${String(g??"?")} ${I}`);let E=[],F=!1;for(let M of d??[])if(!gi.has(M.name.toLowerCase()))if(M.name.toLowerCase()==="set-cookie"&&qr(I)){let K=M.value.split(`
190
190
  `).map(Q=>/SameSite=/i.test(Q)?Q.replace(/SameSite=\w+/i,"SameSite=None"):Q+"; SameSite=None; Secure").join(`
191
- `);P.push({name:M.name,value:K}),F=!0}else P.push(M);F&&S(` rewrote Set-Cookie SameSite on ${I}`);try{let{body:M,base64Encoded:K}=await v.Fetch.getResponseBody({requestId:s});await v.Fetch.fulfillRequest({requestId:s,responseCode:g??200,responseHeaders:P,body:M,...K&&{base64Encoded:!0}})}catch(M){S(` fulfillRequest failed (${M.message}), falling through`);try{await v.Fetch.continueRequest({requestId:s})}catch(K){S(` continueRequest also failed (${K.message})`)}}})()}),i=setInterval(()=>{(async()=>{try{let{cookies:m}=await v.Network.getAllCookies(),a=0;for(let s of m){if(!qr(`https://${s.domain??""}`)||s.sameSite==="None")continue;let l=s.domain??"",d=l.startsWith(".")?l.slice(1):l;await v.Network.setCookie({url:`https://${d}`,name:s.name,value:s.value,domain:l,path:s.path??"/",secure:!0,...s.httpOnly!==void 0&&{httpOnly:s.httpOnly},...s.expirationDate!==void 0&&{expires:s.expirationDate},sameSite:"None"}),a++}a>0&&S(`cookie-patch cycle: updated ${String(a)} cookie(s) to SameSite=None`)}catch(m){S(`cookie-patch cycle failed: ${m.message}`)}})()},2e3),await v.Target.setDiscoverTargets({discover:!0});let k=m=>{if(m.type==="page"){if(b(m.url)){w(`closed stray new-tab-page target ${m.targetId}`),u!==null&&v.Target.activateTarget({targetId:u}).catch(()=>{}),v.Target.closeTarget({targetId:m.targetId}).catch(()=>{});return}u===null&&(u=m.targetId,w(`captured main target ${m.targetId} (${m.url})`))}};v.on("Target.targetCreated",m=>{let{targetInfo:a}=m;S(`target +${a.type} ${a.targetId} ${a.url}`),k(a)}),v.on("Target.targetInfoChanged",m=>{let{targetInfo:a}=m;S(`target ~${a.type} ${a.targetId} ${a.url}`),k(a)}),v.on("disconnect",()=>{x||r!==v||(w("CDP disconnected"),r=null,N(),y())})},y=()=>{if(x||p!==null)return;let v=Math.min(1e3*2**f,1e4),k=f+1;f++,w(`CDP reconnect scheduled in ${String(v)}ms (attempt #${String(k)})`),p=setTimeout(()=>{p=null,(async()=>{let m;try{m=await Vr({port:n})}catch{w(`CDP reconnect attempt #${String(k)} failed`),y();return}if(x){try{await m.close()}catch{}return}r=m;try{await c(m),w(`CDP reconnected after ${String(k)} attempt(s)`),f=0}catch{r===m&&(r=null);try{await m.close()}catch{}w(`CDP reconnect attempt #${String(k)} failed during setup`),y()}})()},v)},T=30,E=300;for(let v=0;v<T;v++){await new Promise(k=>setTimeout(k,E)),w(`CDP connect attempt ${String(v+1)}/${String(T)}`);try{let k=await Vr({port:n});r=k,e.path&&k.send("Page.navigate",{url:`${t}${e.path}`});try{await c(k),w("CDP connected")}catch{r===k&&(r=null);try{await k.close()}catch{}w("CDP setup failed after connect")}break}catch{if(v===T-1){let k=`CDP unavailable after ${String(T)} attempts \u2014 viewer running without interception (CSP/cookie rewrites disabled)`;return w(k),e.onWarn?.(k),{kill:()=>{o.kill()}}}}}return r?{kill:()=>{if(w("CDP kill requested \u2014 tearing down"),x=!0,p!==null&&(clearTimeout(p),p=null),N(),r!==null){try{r.close()}catch{}r=null}o.kill()}}:{kill:()=>{o.kill()}}}import{useCallback as mi,useState as gi}from"react";function ut(e){let[t,o]=gi([]),n=mi(r=>{o(i=>[...i,`${new Date().toLocaleTimeString()}: ${r}`].slice(-e))},[e]);return[t,n]}import{useCallback as pt,useEffect as Jt,useState as ft}from"react";import{Box as U,Text as A,useInput as yi}from"ink";import{jsx as _,jsxs as J}from"react/jsx-runtime";var be=["apiKey","userId","businessId"],hi={apiKey:"API Key",userId:"User ID",businessId:"Business ID"},Ge=({text:e})=>_(A,{dimColor:!0,children:e}),mt=({initialMode:e,showProfileManager:t,onComplete:o,onCancel:n})=>{let[r,i]=ft(e==="global"&&!t?{type:"loading"}:e==="global"&&t?{type:"profile-loading"}:{type:"mode-select",cursor:0}),[u,p]=ft(""),[f,x]=ft(null),[w,S]=ft(void 0),N=pt(m=>{if(m==="local"){o({mode:"local",credentials:null});return}i({type:"profile-loading"})},[o]),b=pt(async m=>{if(m===null){i({type:"profile-loading"});let l=await _e();i({type:"name-entry",nameBuffer:"",existingProfiles:l});return}S(m.isDefault?void 0:m.name),i({type:"loading"});let a=m.isDefault?await Y():await le(m.name),s=a?Math.max(0,re.indexOf(a.environment)):0;i({type:"creds-entry",field:0,values:a??{},envCursor:s})},[]),c=pt(async(m,a)=>{let s=re[a]??"go",l={apiKey:m.apiKey??"",userId:m.userId??"",businessId:m.businessId??"",environment:s};i({type:"saving"});try{await xr(w??me,l),o({mode:"global",credentials:l,...w!==void 0&&{profileName:w}})}catch(d){x(d instanceof Error?d.message:String(d)),i({type:"creds-entry",field:0,values:m,envCursor:a})}},[o,w]);yi((m,a)=>{if(a.ctrl&&m==="c"&&process.exit(0),a.escape){if((r.type==="creds-entry"||r.type==="name-entry")&&e==="global"&&t){i({type:"profile-loading"}),y();return}n?.();return}if(r.type==="mode-select"){if(a.upArrow)i({type:"mode-select",cursor:0});else if(a.downArrow)i({type:"mode-select",cursor:1});else if(a.return){let s=r.cursor===0?"global":"local";N(s)}return}if(r.type==="profile-select"){let{profiles:s,cursor:l}=r,d=s.length,g=s.length+1;if(a.upArrow)i({...r,cursor:(l-1+g)%g});else if(a.downArrow)i({...r,cursor:(l+1)%g});else if(a.return)if(l===d)i({type:"name-entry",nameBuffer:"",existingProfiles:s});else{let I=s[l]??s[0];I&&b(I)}return}if(r.type==="name-entry"){let{nameBuffer:s,existingProfiles:l}=r;if(a.backspace||a.delete)i({type:"name-entry",nameBuffer:s.slice(0,-1),existingProfiles:l});else if(a.return){let d=s.trim();if(!d){i({...r,nameError:"Name cannot be empty"});return}if(d===me){i({...r,nameError:`"${me}" is reserved`});return}if(l.some(g=>g.name===d)){i({...r,nameError:`Profile "${d}" already exists`});return}S(d),i({type:"creds-entry",field:0,values:{},envCursor:0}),p("")}else m&&!a.ctrl&&!a.meta&&i({type:"name-entry",nameBuffer:s+m,existingProfiles:l});return}if(r.type==="creds-entry"){let{field:s,values:l,envCursor:d}=r;if(s===be.length){a.leftArrow?i({...r,envCursor:(d-1+re.length)%re.length}):a.rightArrow?i({...r,envCursor:(d+1)%re.length}):a.upArrow?(i({...r,field:s-1}),p(l[be[s-1]]??"")):a.return&&c(l,d);return}let I=be[s];if(!I)return;if(a.backspace||a.delete)p(P=>P.slice(0,-1));else if(a.upArrow&&s>0){let P={...l,[I]:u},F=s-1;i({...r,field:F,values:P}),p(P[be[F]]??"")}else if(a.return||a.tab||a.downArrow){let P={...l,[I]:u},F=s+1;i({...r,field:F,values:P}),F<be.length?p(P[be[F]]??""):p("")}else m&&!a.ctrl&&!a.meta&&p(P=>P+m)}});let y=pt(async()=>{let m=await _e();i({type:"profile-select",profiles:m,cursor:0})},[]);if(Jt(()=>{r.type==="profile-loading"&&y()},[r.type,y]),Jt(()=>{e==="global"&&!t&&(async()=>{let m=await Y(),a=m?Math.max(0,re.indexOf(m.environment)):0;i({type:"creds-entry",field:0,values:m??{},envCursor:a})})()},[]),Jt(()=>{r.type==="creds-entry"&&r.field===0&&p(r.values.apiKey??"")},[r.type]),r.type==="loading"||r.type==="saving"||r.type==="profile-loading"){let m=r.type==="saving"?"Saving credentials\u2026":r.type==="profile-loading"?"Loading profiles\u2026":"Loading credentials\u2026";return _(U,{paddingY:1,paddingX:2,children:_(A,{dimColor:!0,children:m})})}if(r.type==="done")return null;if(r.type==="mode-select")return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(U,{flexDirection:"column",gap:0,children:[_(A,{bold:!0,children:"Credential mode"}),[{label:"Global",desc:"~/.kizenappbuilder/credentials.json",mode:"global"},{label:"Local",desc:"Enter credentials in the browser dev tools",mode:"local"}].map((a,s)=>{let l=r.cursor===s;return J(U,{gap:2,children:[_(A,{...l&&{color:"cyan"},children:l?"\u276F":" "}),_(A,{bold:l,...l&&{color:"cyan"},children:a.label}),_(A,{dimColor:!0,children:a.desc})]},a.mode)})]}),_(Ge,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to quit"})]});if(r.type==="profile-select"){let{profiles:m,cursor:a}=r,s=m.length;return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(U,{flexDirection:"column",gap:0,children:[_(A,{bold:!0,children:"Credential profiles"}),m.map((l,d)=>{let g=a===d;return J(U,{gap:2,children:[_(A,{...g&&{color:"cyan"},children:g?"\u276F":" "}),_(A,{bold:g,...g&&{color:"cyan"},children:l.isDefault?"Default":l.name}),_(A,{dimColor:!0,children:l.path})]},l.name)}),J(U,{gap:2,children:[_(A,{...a===s&&{color:"cyan"},children:a===s?"\u276F":" "}),_(A,{bold:a===s,...a===s&&{color:"cyan"},children:"+ Add new profile"})]})]}),_(Ge,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel"})]})}if(r.type==="name-entry"){let{nameBuffer:m,nameError:a}=r;return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),_(U,{flexDirection:"column",gap:0,children:_(A,{bold:!0,children:"New credential profile"})}),a&&J(A,{color:"red",children:["Error: ",a]}),J(U,{gap:2,children:[_(U,{width:12,children:_(A,{bold:!0,color:"cyan",children:"Profile name"})}),_(A,{color:"cyan",children:">"}),_(A,{children:m}),_(A,{color:"cyan",children:"\u2588"})]}),_(Ge,{text:"Type a name \xB7 Enter to confirm \xB7 Esc to go back"})]})}let{field:T,values:E,envCursor:h}=r,v=T===be.length,k=w??me;return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(U,{flexDirection:"column",gap:0,children:[_(A,{bold:!0,children:w!==void 0?`Profile: ${w}`:"Global credentials"}),J(A,{dimColor:!0,children:["Saved to:"," ",w!==void 0?`~/.kizenappbuilder/${w}.json`:De]})]}),f&&J(A,{color:"red",children:["Error: ",f]}),J(U,{flexDirection:"column",gap:0,children:[be.map((m,a)=>{let s=T===a,l=s?u:E[m]??"";return J(U,{gap:2,children:[_(U,{width:12,children:_(A,{bold:s,...s&&{color:"cyan"},children:hi[m]})}),_(A,{...s&&{color:"cyan"},children:">"}),_(A,{children:l}),s&&_(A,{color:"cyan",children:"\u2588"})]},m)}),J(U,{gap:2,children:[_(U,{width:12,children:_(A,{bold:v,...v&&{color:"cyan"},children:"Environment"})}),_(A,{...v&&{color:"cyan"},children:">"}),_(U,{gap:1,children:re.map((m,a)=>{let s=a===h;return v?_(A,{bold:s,...s&&{color:"cyan"},children:s?`[${m}]`:m},m):_(A,{dimColor:!s,bold:s,children:m},m)})})]})]}),v?_(Ge,{text:"\u2190\u2192 to select \xB7 \u2191\u2193 to move \xB7 Enter to save \xB7 Esc to cancel"}):_(Ge,{text:"\u2191\u2193 to move \xB7 Backspace to delete \xB7 Esc to cancel"}),J(A,{dimColor:!0,children:["Profile: ",k]})]})};import{jsx as $,jsxs as H}from"react/jsx-runtime";var Ti=[".kizenapp",".git"],Kr=({port:e,pluginDir:t,outputDir:o,credentials:n,credentialMode:r,activeCredentialProfile:i,lastPath:u,debug:p=!1,verbose:f=!1,autoViewer:x=!0,cacheEnabled:w=!0})=>{let S=ce(n),N=ce(i),b=ce(u),[c,y]=X("main"),[T,E]=X(r),[h,v]=X("starting"),[k,m]=X(null),[a,s]=ut(50),[l,d]=ut(50),[g,I]=ut(50),[P,F]=X([]),[M,K]=X("pending"),[Q,ne]=X(null),[oe,ee]=X(null),[Z,Le]=X(null),[we,wt]=X(null),[Ct,St]=X(0),[Kt,Cn]=X(0),[Sn,Tn]=X(0),[Tt,Pn]=X(0),Pt=ce(!1),Yt=ce(!1),Ye=ce(null),Fe=ce(null),de=ce(new Set),Xe=ce([]),te=$e(C=>{let j=JSON.stringify(C);if(de.current.size===0){Xe.current=[...Xe.current,j].slice(-50);return}let ue=!1;for(let ie of de.current)if(ie.readyState===1)try{ie.send(j)}catch{de.current.delete(ie),ue=!0}ue&&St(de.current.size)},[]),Ze=s,Et=$e(()=>{Ye.current?.kill(),Ye.current=null,Wr({port:e,userDataDir:Gr(o,".chrome"),broadcast:te,onWarn:C=>{s(`\u26A0 ${C}`)},...b.current!==void 0&&{path:b.current},...p&&{debugLog:I},...f&&{verbose:!0}}).then(C=>{Ye.current=C})},[e,o,te,p,f,I,s]);gt(()=>{let C=()=>{Ye.current?.kill()};return process.on("exit",C),()=>{process.off("exit",C)}},[]),xi((C,j)=>{(C==="q"||j.ctrl&&C==="c")&&process.exit(0),C==="c"&&y("editing"),C==="v"&&Et()},{isActive:c==="main"}),gt(()=>{h!=="running"||Yt.current||!x||(Yt.current=!0,Et())},[h,x,Et]);let En=$e(C=>{S.current=C.credentials,N.current=C.profileName,y("main"),E(C.mode);let j=C.profileName;he(o,{credentialMode:C.mode,...j!==void 0&&{activeCredentialProfile:j}}),te({type:"credentials-updated",credentials:C.credentials})},[o,te]),Xt=$e(C=>{F(j=>[...j,`${new Date().toLocaleTimeString()}: ${Ut(C)}`].slice(-50)),C.kind==="request"&&(C.fromCache?Tn(j=>j+1):Pn(j=>j+1)),te({type:"proxy-log",entry:C})},[te]),Ce=$e(C=>{d(C),te({type:"log",message:C})},[d,te]),kt=$e(()=>{Pt.current||(Pt.current=!0,K("building"),ne(null),ee(null),Ce("Build started"),rt(t,o).then(({bundleSize:C})=>{Ce(`Build finished \u2014 bundle: ${Ae(C)}`),K("done"),Le(new Date),wt(C),Ce("Notifying viewers to reload"),te({type:"rebuild"})}).catch(C=>{C instanceof vi?(ee(C.issues),ne(null)):(ne(C instanceof Error?C.message:String(C)),ee(null)),K("error")}).finally(()=>{Pt.current=!1}))},[t,o,Ce,te]);if(gt(()=>{kt();let C=wi(t,{recursive:!0},(j,ue)=>{if(!ue)return;let ie=ue.replace(/\\/g,"/");Ti.some(Qe=>ie.startsWith(Qe))||(Ce(`File change detected: ${ue}`),Fe.current!==null&&clearTimeout(Fe.current),Fe.current=setTimeout(kt,150))});return C.on("error",j=>{Ce(`File watcher error \u2014 rebuilds have stopped: ${j.message}`)}),()=>{C.close(),Fe.current!==null&&clearTimeout(Fe.current)}},[t,kt,Ce]),gt(()=>{let C=Hr();qt(Gr(C,"index.html")).then(j=>{if(!j){m("Viewer not built. Run 'pnpm build:viewer' first."),v("error");return}let ue=Ur(C,Ze,Xt,S,N,o,te,Cn,b,t,w),ie=Ci(ue),Qe=new Si({server:ie});return Qe.on("connection",Se=>{for(let _n of Xe.current)Se.readyState===1&&Se.send(_n);Xe.current=[],Ze("Viewer connected for live reload"),de.current.add(Se),St(de.current.size),Se.on("close",()=>{de.current.delete(Se),St(de.current.size)})}),ie.listen(e,"127.0.0.1",()=>{v("running"),Ze(`Server started on 127.0.0.1:${String(e)}`)}),ie.on("error",Se=>{m(Se.message),v("error")}),()=>{Qe.close(),ie.close()}})},[e,Ze,Xt,te,o,t,w]),c==="editing")return $(mt,{...T!==void 0&&{initialMode:T},showProfileManager:T==="global",onComplete:En,onCancel:()=>{y("main")}});let _t=Z!==null?Math.round((Date.now()-Z.getTime())/1e3):null,kn=_t===null?"":_t<5?" (just now)":` (${String(_t)}s ago)`,Zt=oe?.filter(C=>C.severity==="error").length??0;return H(W,{flexDirection:"column",paddingY:1,paddingX:2,children:[$(q,{marginBottom:1}),H(W,{flexDirection:"column",children:[H(W,{gap:2,marginBottom:0,children:[$(D,{bold:!0,dimColor:!0,children:"App Build"}),M==="pending"&&$(D,{dimColor:!0,children:"waiting\u2026"}),M==="building"&&H(W,{gap:1,children:[$(pe,{}),$(D,{children:"Building plugin package\u2026"})]}),M==="done"&&H(W,{gap:1,children:[$(D,{color:"green",children:"\u2713 Built"}),Z!==null&&H(D,{dimColor:!0,children:["at ",Z.toLocaleTimeString(),kn]}),we!==null&&H(D,{dimColor:!0,children:["\xB7 bundle: ",Ae(we)]})]}),M==="error"&&(oe!==null?H(D,{color:"red",children:["\u2717 ",Zt," validation ",Zt===1?"error":"errors"]}):H(D,{color:"red",children:["\u2717 ",Q??"unknown error"]}))]}),oe!==null&&$(ot,{issues:oe}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:l.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[$(D,{bold:!0,dimColor:!0,children:"Web Server"}),h==="starting"&&$(D,{dimColor:!0,children:"starting\u2026"}),h==="running"&&H(W,{gap:2,children:[$(D,{color:"green",children:"\u2713 Running"}),H(D,{dimColor:!0,children:["\u25CF ",Ct," viewer",Ct!==1?"s":""]})]}),h==="error"&&H(D,{color:"red",children:["\u2717 ",k??"Server error"]})]}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:a.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[$(D,{bold:!0,dimColor:!0,children:"Network Proxy"}),$(D,{color:"green",children:"\u2713 Active"}),$(D,{dimColor:!0,children:w?`\u25CF ${String(Kt)} key${Kt!==1?"s":""} in the network cache \xB7 ${String(Sn)} hit \xB7 ${String(Tt)} miss`:`\u25CF network cache disabled \xB7 ${String(Tt)} request${Tt!==1?"s":""}`})]}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:P.length===0?$(D,{dimColor:!0,children:" No requests yet."}):P.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),p&&H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[$(D,{bold:!0,dimColor:!0,children:"CDP Debug"}),H(D,{dimColor:!0,children:["\u25CF ",g.length," event(s)"]})]}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:g.length===0?$(D,{dimColor:!0,children:" No CDP events yet."}):g.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,gap:1,children:[$(D,{dimColor:!0,children:"["}),$(D,{children:"q"}),$(D,{dimColor:!0,children:"] quit ["}),$(D,{children:"c"}),$(D,{dimColor:!0,children:"] credentials ["}),$(D,{children:"v"}),H(D,{dimColor:!0,children:["] ",Ct===0?"open viewer":"relaunch viewer"]})]})]})};async function Yr(e){return new Promise(t=>{let o=null,n=i=>{o?.(),t(i)},{unmount:r}=Zr(Xr(mt,{...e!==void 0&&{initialMode:e},onComplete:n}),{exitOnCtrlC:!1});o=r})}function Qr(e){e.command("dev").description("Start the plugin viewer dev server").option("-p, --port <port>","port to listen on","3121").option("-c, --credentials <path>","path to a credentials JSON file").option("-d, --debug","Enable CDP lifecycle logs in the TUI").option("-v, --verbose","Log every CDP event and handled error (implies --debug)").option("--no-viewer","Don't auto-launch the viewer on startup (press [v] to launch manually)").option("--no-cache","Disable the network proxy cache (always fetch upstream)").action(async t=>{let o=parseInt(t.port,10),n=process.cwd(),r=`${n}/.kizenapp`;Be(n);let i=null,u,p,{lastPath:f}=await ye(r);if(t.credentials)i=await ge(t.credentials);else{let c=await ye(r);if(c.credentialMode==="local")u="local";else if(c.credentialMode==="global"){if(u="global",p=c.activeCredentialProfile,p?(i=await le(p),i||(i=await Y(),p=void 0)):i=await Y(),!i){let y=await Yr("global");i=y.credentials,p=y.profileName}}else{let y=await Yr();i=y.credentials,u=y.mode,p=y.profileName;let T=y.profileName;await he(r,{credentialMode:y.mode,...T!==void 0&&{activeCredentialProfile:T}})}}let x=t.verbose===!0,w=x||t.debug===!0,S=t.viewer!==!1,N=t.cache!==!1,{waitUntilExit:b}=Zr(Xr(Kr,{port:o,pluginDir:n,outputDir:r,credentials:i,...u!==void 0&&{credentialMode:u},...p!==void 0&&{activeCredentialProfile:p},...f!==void 0&&{lastPath:f},debug:w,verbose:x,autoViewer:S,cacheEnabled:N}),{exitOnCtrlC:!1});await b()})}import{createElement as Ai}from"react";import{readFile as Oi,writeFile as ji}from"fs/promises";import{join as zi}from"path";import{render as Mi}from"ink";import{useCallback as ht,useEffect as sn,useState as bt}from"react";import{Box as se,Text as O,useApp as Li,useInput as Fi}from"ink";import{encrypt as Pi,serializeEnvelope as Ei}from"@kizenapps/packager";function ki(e){let t=e;return t.code==="ECONNREFUSED"||t.cause?.code==="ECONNREFUSED"}function en(e){return{"Content-Type":"application/json","x-api-key":e.apiKey,"x-user-id":e.userId,"x-business-id":e.businessId,"x-auth-environment":e.environment}}async function tn(e,t,o){try{return await fetch(`${e}${t}`,o)}catch(n){throw new Error(ki(n)?`Plugin-wizard is not running at ${e}`:`Failed to reach plugin-wizard: ${n.message}`)}}async function rn(e){let t=await e.text();if(t==="")return{};try{let o=JSON.parse(t);return typeof o=="object"&&o!==null?o:{}}catch{return{}}}async function _i(e,t,o){let n=Ue(e.stage),r=await tn(n,"/get-public-key",{method:"POST",headers:en(t),body:JSON.stringify({api_name:o})}),i=await rn(r);if(!r.ok||typeof i.public_key!="string"){let u=typeof i.error=="string"?i.error:`HTTP ${String(r.status)}`;throw new Error(`Failed to fetch public key: ${u}`)}return i.public_key}function Ii(e,t){let o=Pi(t,e),n=Ei(o);if(typeof n.value!="string")throw new Error("Unexpected serialized envelope shape from @kizenapps/packager");return n.value}async function Ni(e,t,o,n){let r=Ue(e.stage),i=await tn(r,"/encrypt",{method:"POST",headers:en(t),body:JSON.stringify({api_name:o,value:n})}),u=await rn(i);if(!i.ok||u.encrypted!==!0||typeof u.value!="string"){let p=typeof u.error=="string"?u.error:`HTTP ${String(i.status)}`;throw new Error(`Encryption via plugin-wizard failed: ${p}`)}return u.value}async function yt(e,t,o,n,r){if(e.isRemote)return r?.("encrypting"),Ni(e,t,o,n);r?.("fetching-key");let i=await _i(e,t,o);return r?.("encrypting"),Ii(i,n)}import{spawn as Bi}from"child_process";import{platform as nn}from"process";function Ri(){return nn==="darwin"?[{cmd:"pbcopy",args:[]}]:nn==="win32"?[{cmd:"clip",args:[]}]:[{cmd:"wl-copy",args:[]},{cmd:"xclip",args:["-selection","clipboard"]},{cmd:"xsel",args:["--clipboard","--input"]}]}var Di=2e3;function $i(e,{cmd:t,args:o}){return new Promise(n=>{let r;try{r=Bi(t,o,{stdio:["pipe","ignore","ignore"]})}catch{n(!1);return}let i=r,u=!1;function p(x){u||(u=!0,clearTimeout(f),n(x))}let f=setTimeout(()=>{i.kill(),p(!1)},Di);f.unref(),i.on("error",()=>{p(!1)}),i.on("close",x=>{p(x===0)}),i.stdin.on("error",()=>{p(!1)});try{i.stdin.end(e)}catch{p(!1)}})}async function on(e){for(let t of Ri())if(await $i(e,t))return!0;return!1}import{Fragment as xt,jsx as L,jsxs as G}from"react/jsx-runtime";var Wt=({text:e})=>L(O,{dimColor:!0,children:e}),an=({ctx:e,stageDefaulted:t,credentialsPath:o,initialApiName:n,defaultApiName:r,initialValue:i,onDone:u})=>{let p=Li(),[f,x]=bt({type:"loading"}),[w,S]=bt(null),[N,b]=bt(n??""),[c,y]=bt(i??""),T=ht(s=>{process.exitCode=1,x({type:"error",message:s instanceof Error?s.message:String(s)})},[]),E=ht(async(s,l,d)=>{try{let g=await yt(e,s,l,d,F=>{x(F==="fetching-key"?{type:"fetching-key"}:{type:"encrypting"})}),I=JSON.stringify({encrypted:!0,value:g},null,2);u?.(g);let P=await on(I);x({type:"done",envelope:I,copied:P})}catch(g){T(g)}},[e,T,u]),h=ht((s,l,d)=>{if(l.trim()===""){x({type:"api-name-entry",buffer:r??""});return}if(d===""){x({type:"value-entry",buffer:""});return}E(s,l.trim(),d)},[r,E]),v=ht(async s=>{try{x({type:"loading"});let l=s.isDefault?await Y():await le(s.name);if(l===null)throw new Error(`Could not load credential profile: ${s.name}`);S(l),h(l,N,c)}catch(l){T(l)}},[N,c,h,T]);sn(()=>{(async()=>{try{if(o!==void 0){let d;try{d=await ge(o)}catch(g){throw new Error(`Could not load credentials from ${o}: ${g instanceof Error?g.message:String(g)}`)}S(d),h(d,N,c);return}let s=await _e();if(s.length===0)throw new Error("No credential profiles found. Create ~/.kizenappbuilder/credentials.json first.");let[l]=s;if(s.length===1&&l!==void 0){let d=l.isDefault?await Y():await le(l.name);if(d===null)throw new Error(`Could not load credential profile: ${l.name}`);S(d),h(d,N,c);return}x({type:"profile-select",profiles:s,cursor:0})}catch(s){T(s)}})()},[]),sn(()=>{(f.type==="done"||f.type==="error")&&p.exit()},[f,p]),Fi((s,l)=>{if(l.ctrl&&s==="c"){process.exitCode=130,p.exit();return}if(f.type==="profile-select"){let{profiles:d,cursor:g}=f;if(l.upArrow)x({...f,cursor:(g-1+d.length)%d.length});else if(l.downArrow)x({...f,cursor:(g+1)%d.length});else if(l.return){let I=d[g];I!==void 0&&v(I)}return}if(f.type==="api-name-entry"){let{buffer:d}=f;if(l.backspace||l.delete)x({type:"api-name-entry",buffer:d.slice(0,-1)});else if(l.return){let g=d.trim();if(g===""){x({type:"api-name-entry",buffer:d,error:"api_name cannot be empty"});return}b(g),w?h(w,g,c):T(new Error("Internal error: credentials were not loaded"))}else s&&!l.ctrl&&!l.meta&&x({type:"api-name-entry",buffer:d+s});return}if(f.type==="value-entry"){let{buffer:d}=f;if(l.backspace||l.delete)x({type:"value-entry",buffer:d.slice(0,-1)});else if(l.return){if(d===""){x({type:"value-entry",buffer:d,error:"secret cannot be empty"});return}y(d),w?h(w,N,d):T(new Error("Internal error: credentials were not loaded"))}else s&&!l.ctrl&&!l.meta&&x({type:"value-entry",buffer:d+s});return}});let k=e.isRemote?"remote Kizen API":"on-machine",m=t===!0?`${e.stage} (default)`:e.stage,a=s=>G(se,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[L(q,{}),G(O,{dimColor:!0,children:["Mode: ",k," Stage: ",m]}),s]});if(f.type==="loading")return a(G(se,{gap:1,children:[L(pe,{}),L(O,{dimColor:!0,children:"Loading credentials\u2026"})]}));if(f.type==="profile-select"){let{profiles:s,cursor:l}=f;return a(G(xt,{children:[L(O,{bold:!0,children:"Credential profile"}),L(se,{flexDirection:"column",children:s.map((d,g)=>{let I=l===g;return G(se,{gap:2,children:[L(O,{...I&&{color:"cyan"},children:I?"\u276F":" "}),L(O,{bold:I,...I&&{color:"cyan"},children:d.isDefault?"Default":d.name}),L(O,{dimColor:!0,children:d.path})]},d.name)})}),L(Wt,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to quit"})]}))}return f.type==="api-name-entry"?a(G(xt,{children:[L(O,{bold:!0,children:"Plugin api_name"}),f.error!==void 0&&G(O,{color:"red",children:["Error: ",f.error]}),G(se,{gap:1,children:[L(O,{color:"cyan",children:">"}),L(O,{children:f.buffer}),L(O,{color:"cyan",children:"\u2588"})]}),L(Wt,{text:"Type the api_name \xB7 Enter to confirm \xB7 Ctrl+C to quit"})]})):f.type==="value-entry"?a(G(xt,{children:[L(O,{bold:!0,children:"Secret value"}),f.error!==void 0&&G(O,{color:"red",children:["Error: ",f.error]}),G(se,{gap:1,children:[L(O,{color:"cyan",children:">"}),L(O,{children:"\u2022".repeat(f.buffer.length)}),L(O,{color:"cyan",children:"\u2588"})]}),L(Wt,{text:"Input hidden \xB7 Enter to encrypt \xB7 Ctrl+C to quit"})]})):f.type==="fetching-key"?a(G(se,{gap:1,children:[L(pe,{}),G(O,{children:["Fetching ",e.stage," public key for ",L(O,{bold:!0,children:N}),"\u2026"]})]})):f.type==="encrypting"?a(G(se,{gap:1,children:[L(pe,{}),L(O,{children:"Encrypting\u2026"})]})):f.type==="error"?a(G(se,{gap:1,children:[L(O,{color:"red",children:"\u2717"}),L(O,{color:"red",children:f.message})]})):a(G(xt,{children:[G(se,{gap:1,children:[L(O,{color:"green",children:"\u2713"}),L(O,{bold:!0,children:"Encrypted secret ready"})]}),f.copied?L(O,{color:"green",children:"\u2713 Copied to clipboard \u2014 paste it into the secret value in your kizen.json."}):L(O,{dimColor:!0,children:"Paste this into the secret value in your kizen.json (re-run with --out <path> to save it to a file; selecting it here may capture line wraps):"}),L(O,{children:f.envelope})]}))};function ln(e){return{encrypted:!0,value:e}}function Hi(e){return JSON.stringify(ln(e))}async function cn(e,t){await ji(e,`${JSON.stringify(ln(t),null,2)}
192
- `,"utf-8")}var Ui="prod";async function Vi(){try{let e=await Oi(zi(process.cwd(),"kizen.json"),"utf-8"),t=JSON.parse(e),o=Array.isArray(t)?t[0]:t,n=typeof o.api_name=="string"&&o.api_name!==""?o.api_name:void 0;return{...n!==void 0&&{apiName:n}}}catch{}return{}}async function qi(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Ji(e,t,o,n){let r=t.credentials!==void 0?await ge(t.credentials):await Y();if(r===null)throw new Error("No credentials found. Pass --credentials or create ~/.kizenappbuilder/credentials.json.");let i=t.apiName??o.apiName;if(i===void 0||i.trim()==="")throw new Error("api_name is required in non-interactive mode. Pass --api-name or run inside a plugin directory.");n&&process.stderr.write(`No --stage given; defaulting to ${e.stage} encryption keys (pass --stage dev to override)
193
- `);let u=t.value;if(u===void 0){if(process.stdin.isTTY)throw new Error('No secret provided and stdin is a terminal. Pass --value, or pipe the secret in (e.g. `printf %s "$SECRET" | appbuilder encrypt \u2026`).');process.stderr.write(`Reading secret from stdin (pass --value to skip)\u2026
194
- `),u=(await qi()).replace(/[\r\n]+$/,"")}if(u==="")throw new Error("A secret value is required. Pass --value or pipe it via stdin.");let p=await yt(e,r,i.trim(),u);if(process.stdout.write(`${Hi(p)}
191
+ `);E.push({name:M.name,value:K}),F=!0}else E.push(M);F&&S(` rewrote Set-Cookie SameSite on ${I}`);try{let{body:M,base64Encoded:K}=await w.Fetch.getResponseBody({requestId:s});await w.Fetch.fulfillRequest({requestId:s,responseCode:g??200,responseHeaders:E,body:M,...K&&{base64Encoded:!0}})}catch(M){S(` fulfillRequest failed (${M.message}), falling through`);try{await w.Fetch.continueRequest({requestId:s})}catch(K){S(` continueRequest also failed (${K.message})`)}}})()}),i=setInterval(()=>{(async()=>{try{let{cookies:f}=await w.Network.getAllCookies(),a=0;for(let s of f){if(!qr(`https://${s.domain??""}`)||s.sameSite==="None")continue;let l=s.domain??"",d=l.startsWith(".")?l.slice(1):l;await w.Network.setCookie({url:`https://${d}`,name:s.name,value:s.value,domain:l,path:s.path??"/",secure:!0,...s.httpOnly!==void 0&&{httpOnly:s.httpOnly},...s.expirationDate!==void 0&&{expires:s.expirationDate},sameSite:"None"}),a++}a>0&&S(`cookie-patch cycle: updated ${String(a)} cookie(s) to SameSite=None`)}catch(f){S(`cookie-patch cycle failed: ${f.message}`)}})()},2e3),await w.Target.setDiscoverTargets({discover:!0});let k=f=>{if(f.type==="page"){if(v(f.url)){y(`closed stray new-tab-page target ${f.targetId}`),u!==null&&w.Target.activateTarget({targetId:u}).catch(()=>{}),w.Target.closeTarget({targetId:f.targetId}).catch(()=>{});return}u===null&&(u=f.targetId,y(`captured main target ${f.targetId} (${f.url})`))}};w.on("Target.targetCreated",f=>{let{targetInfo:a}=f;S(`target +${a.type} ${a.targetId} ${a.url}`),k(a)}),w.on("Target.targetInfoChanged",f=>{let{targetInfo:a}=f;S(`target ~${a.type} ${a.targetId} ${a.url}`),k(a)}),w.on("disconnect",()=>{b||r!==w||(y("CDP disconnected"),r=null,N(),h())})},h=()=>{if(b||p!==null)return;let w=Math.min(1e3*2**m,1e4),k=m+1;m++,y(`CDP reconnect scheduled in ${String(w)}ms (attempt #${String(k)})`),p=setTimeout(()=>{p=null,(async()=>{let f;try{f=await Vr({port:n})}catch{y(`CDP reconnect attempt #${String(k)} failed`),h();return}if(b){try{await f.close()}catch{}return}r=f;try{await c(f),y(`CDP reconnected after ${String(k)} attempt(s)`),m=0}catch{r===f&&(r=null);try{await f.close()}catch{}y(`CDP reconnect attempt #${String(k)} failed during setup`),h()}})()},w)},T=30,P=300;for(let w=0;w<T;w++){await new Promise(k=>setTimeout(k,P)),y(`CDP connect attempt ${String(w+1)}/${String(T)}`);try{let k=await Vr({port:n});r=k,e.path&&k.send("Page.navigate",{url:`${t}${e.path}`});try{await c(k),y("CDP connected")}catch{r===k&&(r=null);try{await k.close()}catch{}y("CDP setup failed after connect")}break}catch{if(w===T-1){let k=`CDP unavailable after ${String(T)} attempts \u2014 viewer running without interception (CSP/cookie rewrites disabled)`;return y(k),e.onWarn?.(k),{kill:()=>{o.kill()}}}}}return r?{kill:()=>{if(y("CDP kill requested \u2014 tearing down"),b=!0,p!==null&&(clearTimeout(p),p=null),N(),r!==null){try{r.close()}catch{}r=null}o.kill()}}:{kill:()=>{o.kill()}}}import{useCallback as hi,useState as bi}from"react";function ut(e){let[t,o]=bi([]),n=hi(r=>{o(i=>[...i,`${new Date().toLocaleTimeString()}: ${r}`].slice(-e))},[e]);return[t,n]}import{useCallback as pt,useEffect as qt,useState as ft}from"react";import{Box as U,Text as A,useInput as xi}from"ink";import{jsx as _,jsxs as J}from"react/jsx-runtime";var be=["apiKey","userId","businessId"],vi={apiKey:"API Key",userId:"User ID",businessId:"Business ID"},Ge=({text:e})=>_(A,{dimColor:!0,children:e}),mt=({initialMode:e,showProfileManager:t,onComplete:o,onCancel:n})=>{let[r,i]=ft(e==="global"&&!t?{type:"loading"}:e==="global"&&t?{type:"profile-loading"}:{type:"mode-select",cursor:0}),[u,p]=ft(""),[m,b]=ft(null),[y,S]=ft(void 0),N=pt(f=>{if(f==="local"){o({mode:"local",credentials:null});return}i({type:"profile-loading"})},[o]),v=pt(async f=>{if(f===null){i({type:"profile-loading"});let l=await _e();i({type:"name-entry",nameBuffer:"",existingProfiles:l});return}S(f.isDefault?void 0:f.name),i({type:"loading"});let a=f.isDefault?await Y():await le(f.name),s=a?Math.max(0,re.indexOf(a.environment)):0;i({type:"creds-entry",field:0,values:a??{},envCursor:s})},[]),c=pt(async(f,a)=>{let s=re[a]??"go",l={apiKey:f.apiKey??"",userId:f.userId??"",businessId:f.businessId??"",environment:s};i({type:"saving"});try{await xr(y??me,l),o({mode:"global",credentials:l,...y!==void 0&&{profileName:y}})}catch(d){b(d instanceof Error?d.message:String(d)),i({type:"creds-entry",field:0,values:f,envCursor:a})}},[o,y]);xi((f,a)=>{if(a.ctrl&&f==="c"&&process.exit(0),a.escape){if((r.type==="creds-entry"||r.type==="name-entry")&&e==="global"&&t){i({type:"profile-loading"}),h();return}n?.();return}if(r.type==="mode-select"){if(a.upArrow)i({type:"mode-select",cursor:0});else if(a.downArrow)i({type:"mode-select",cursor:1});else if(a.return){let s=r.cursor===0?"global":"local";N(s)}return}if(r.type==="profile-select"){let{profiles:s,cursor:l}=r,d=s.length,g=s.length+1;if(a.upArrow)i({...r,cursor:(l-1+g)%g});else if(a.downArrow)i({...r,cursor:(l+1)%g});else if(a.return)if(l===d)i({type:"name-entry",nameBuffer:"",existingProfiles:s});else{let I=s[l]??s[0];I&&v(I)}return}if(r.type==="name-entry"){let{nameBuffer:s,existingProfiles:l}=r;if(a.backspace||a.delete)i({type:"name-entry",nameBuffer:s.slice(0,-1),existingProfiles:l});else if(a.return){let d=s.trim();if(!d){i({...r,nameError:"Name cannot be empty"});return}if(d===me){i({...r,nameError:`"${me}" is reserved`});return}if(l.some(g=>g.name===d)){i({...r,nameError:`Profile "${d}" already exists`});return}S(d),i({type:"creds-entry",field:0,values:{},envCursor:0}),p("")}else f&&!a.ctrl&&!a.meta&&i({type:"name-entry",nameBuffer:s+f,existingProfiles:l});return}if(r.type==="creds-entry"){let{field:s,values:l,envCursor:d}=r;if(s===be.length){a.leftArrow?i({...r,envCursor:(d-1+re.length)%re.length}):a.rightArrow?i({...r,envCursor:(d+1)%re.length}):a.upArrow?(i({...r,field:s-1}),p(l[be[s-1]]??"")):a.return&&c(l,d);return}let I=be[s];if(!I)return;if(a.backspace||a.delete)p(E=>E.slice(0,-1));else if(a.upArrow&&s>0){let E={...l,[I]:u},F=s-1;i({...r,field:F,values:E}),p(E[be[F]]??"")}else if(a.return||a.tab||a.downArrow){let E={...l,[I]:u},F=s+1;i({...r,field:F,values:E}),F<be.length?p(E[be[F]]??""):p("")}else f&&!a.ctrl&&!a.meta&&p(E=>E+f)}});let h=pt(async()=>{let f=await _e();i({type:"profile-select",profiles:f,cursor:0})},[]);if(qt(()=>{r.type==="profile-loading"&&h()},[r.type,h]),qt(()=>{e==="global"&&!t&&(async()=>{let f=await Y(),a=f?Math.max(0,re.indexOf(f.environment)):0;i({type:"creds-entry",field:0,values:f??{},envCursor:a})})()},[]),qt(()=>{r.type==="creds-entry"&&r.field===0&&p(r.values.apiKey??"")},[r.type]),r.type==="loading"||r.type==="saving"||r.type==="profile-loading"){let f=r.type==="saving"?"Saving credentials\u2026":r.type==="profile-loading"?"Loading profiles\u2026":"Loading credentials\u2026";return _(U,{paddingY:1,paddingX:2,children:_(A,{dimColor:!0,children:f})})}if(r.type==="done")return null;if(r.type==="mode-select")return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(U,{flexDirection:"column",gap:0,children:[_(A,{bold:!0,children:"Credential mode"}),[{label:"Global",desc:"~/.kizenappbuilder/credentials.json",mode:"global"},{label:"Local",desc:"Enter credentials in the browser dev tools",mode:"local"}].map((a,s)=>{let l=r.cursor===s;return J(U,{gap:2,children:[_(A,{...l&&{color:"cyan"},children:l?"\u276F":" "}),_(A,{bold:l,...l&&{color:"cyan"},children:a.label}),_(A,{dimColor:!0,children:a.desc})]},a.mode)})]}),_(Ge,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to quit"})]});if(r.type==="profile-select"){let{profiles:f,cursor:a}=r,s=f.length;return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(U,{flexDirection:"column",gap:0,children:[_(A,{bold:!0,children:"Credential profiles"}),f.map((l,d)=>{let g=a===d;return J(U,{gap:2,children:[_(A,{...g&&{color:"cyan"},children:g?"\u276F":" "}),_(A,{bold:g,...g&&{color:"cyan"},children:l.isDefault?"Default":l.name}),_(A,{dimColor:!0,children:l.path})]},l.name)}),J(U,{gap:2,children:[_(A,{...a===s&&{color:"cyan"},children:a===s?"\u276F":" "}),_(A,{bold:a===s,...a===s&&{color:"cyan"},children:"+ Add new profile"})]})]}),_(Ge,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel"})]})}if(r.type==="name-entry"){let{nameBuffer:f,nameError:a}=r;return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),_(U,{flexDirection:"column",gap:0,children:_(A,{bold:!0,children:"New credential profile"})}),a&&J(A,{color:"red",children:["Error: ",a]}),J(U,{gap:2,children:[_(U,{width:12,children:_(A,{bold:!0,color:"cyan",children:"Profile name"})}),_(A,{color:"cyan",children:">"}),_(A,{children:f}),_(A,{color:"cyan",children:"\u2588"})]}),_(Ge,{text:"Type a name \xB7 Enter to confirm \xB7 Esc to go back"})]})}let{field:T,values:P,envCursor:x}=r,w=T===be.length,k=y??me;return J(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(U,{flexDirection:"column",gap:0,children:[_(A,{bold:!0,children:y!==void 0?`Profile: ${y}`:"Global credentials"}),J(A,{dimColor:!0,children:["Saved to:"," ",y!==void 0?`~/.kizenappbuilder/${y}.json`:De]})]}),m&&J(A,{color:"red",children:["Error: ",m]}),J(U,{flexDirection:"column",gap:0,children:[be.map((f,a)=>{let s=T===a,l=s?u:P[f]??"";return J(U,{gap:2,children:[_(U,{width:12,children:_(A,{bold:s,...s&&{color:"cyan"},children:vi[f]})}),_(A,{...s&&{color:"cyan"},children:">"}),_(A,{children:l}),s&&_(A,{color:"cyan",children:"\u2588"})]},f)}),J(U,{gap:2,children:[_(U,{width:12,children:_(A,{bold:w,...w&&{color:"cyan"},children:"Environment"})}),_(A,{...w&&{color:"cyan"},children:">"}),_(U,{gap:1,children:re.map((f,a)=>{let s=a===x;return w?_(A,{bold:s,...s&&{color:"cyan"},children:s?`[${f}]`:f},f):_(A,{dimColor:!s,bold:s,children:f},f)})})]})]}),w?_(Ge,{text:"\u2190\u2192 to select \xB7 \u2191\u2193 to move \xB7 Enter to save \xB7 Esc to cancel"}):_(Ge,{text:"\u2191\u2193 to move \xB7 Backspace to delete \xB7 Esc to cancel"}),J(A,{dimColor:!0,children:["Profile: ",k]})]})};import{jsx as $,jsxs as H}from"react/jsx-runtime";var ki=[".kizenapp",".git"],Kr=({port:e,pluginDir:t,outputDir:o,credentials:n,credentialMode:r,activeCredentialProfile:i,lastPath:u,debug:p=!1,verbose:m=!1,autoViewer:b=!0,cacheEnabled:y=!0})=>{let S=ce(n),N=ce(i),v=ce(u),[c,h]=X("main"),[T,P]=X(r),[x,w]=X("starting"),[k,f]=X(null),[a,s]=ut(50),[l,d]=ut(50),[g,I]=ut(50),[E,F]=X([]),[M,K]=X("pending"),[Q,ne]=X(null),[oe,ee]=X(null),[Z,Le]=X(null),[we,wt]=X(null),[Ct,St]=X(0),[Gt,Sn]=X(0),[Tn,En]=X(0),[Tt,Pn]=X(0),Et=ce(!1),Kt=ce(!1),Ye=ce(null),Fe=ce(null),de=ce(new Set),Xe=ce([]),te=$e(C=>{let j=JSON.stringify(C);if(de.current.size===0){Xe.current=[...Xe.current,j].slice(-50);return}let ue=!1;for(let ie of de.current)if(ie.readyState===1)try{ie.send(j)}catch{de.current.delete(ie),ue=!0}ue&&St(de.current.size)},[]),Ze=s,Pt=$e(()=>{Ye.current?.kill(),Ye.current=null,Wr({port:e,userDataDir:Gr(o,".chrome"),broadcast:te,onWarn:C=>{s(`\u26A0 ${C}`)},...v.current!==void 0&&{path:v.current},...p&&{debugLog:I},...m&&{verbose:!0}}).then(C=>{Ye.current=C})},[e,o,te,p,m,I,s]);gt(()=>{let C=()=>{Ye.current?.kill()};return process.on("exit",C),()=>{process.off("exit",C)}},[]),Ci((C,j)=>{(C==="q"||j.ctrl&&C==="c")&&process.exit(0),C==="c"&&h("editing"),C==="v"&&Pt()},{isActive:c==="main"}),gt(()=>{x!=="running"||Kt.current||!b||(Kt.current=!0,Pt())},[x,b,Pt]);let kn=$e(C=>{S.current=C.credentials,N.current=C.profileName,h("main"),P(C.mode);let j=C.profileName;he(o,{credentialMode:C.mode,...j!==void 0&&{activeCredentialProfile:j}}),te({type:"credentials-updated",credentials:C.credentials})},[o,te]),Yt=$e(C=>{F(j=>[...j,`${new Date().toLocaleTimeString()}: ${Ht(C)}`].slice(-50)),C.kind==="request"&&(C.fromCache?En(j=>j+1):Pn(j=>j+1)),te({type:"proxy-log",entry:C})},[te]),Ce=$e(C=>{d(C),te({type:"log",message:C})},[d,te]),kt=$e(()=>{Et.current||(Et.current=!0,K("building"),ne(null),ee(null),Ce("Build started"),rt(t,o).then(({bundleSize:C})=>{Ce(`Build finished \u2014 bundle: ${Ae(C)}`),K("done"),Le(new Date),wt(C),Ce("Notifying viewers to reload"),te({type:"rebuild"})}).catch(C=>{C instanceof Si?(ee(C.issues),ne(null)):(ne(C instanceof Error?C.message:String(C)),ee(null)),K("error")}).finally(()=>{Et.current=!1}))},[t,o,Ce,te]);if(gt(()=>{kt();let C=Ti(t,{recursive:!0},(j,ue)=>{if(!ue)return;let ie=ue.replace(/\\/g,"/");ki.some(Qe=>ie.startsWith(Qe))||(Ce(`File change detected: ${ue}`),Fe.current!==null&&clearTimeout(Fe.current),Fe.current=setTimeout(kt,150))});return C.on("error",j=>{Ce(`File watcher error \u2014 rebuilds have stopped: ${j.message}`)}),()=>{C.close(),Fe.current!==null&&clearTimeout(Fe.current)}},[t,kt,Ce]),gt(()=>{let C=Hr();Vt(Gr(C,"index.html")).then(j=>{if(!j){f("Viewer not built. Run 'pnpm build:viewer' first."),w("error");return}let ue=Ur(C,Ze,Yt,S,N,o,te,Sn,v,t,y),ie=Ei(ue),Qe=new Pi({server:ie});return Qe.on("connection",Se=>{for(let In of Xe.current)Se.readyState===1&&Se.send(In);Xe.current=[],Ze("Viewer connected for live reload"),de.current.add(Se),St(de.current.size),Se.on("close",()=>{de.current.delete(Se),St(de.current.size)})}),ie.listen(e,"127.0.0.1",()=>{w("running"),Ze(`Server started on 127.0.0.1:${String(e)}`)}),ie.on("error",Se=>{f(Se.message),w("error")}),()=>{Qe.close(),ie.close()}})},[e,Ze,Yt,te,o,t,y]),c==="editing")return $(mt,{...T!==void 0&&{initialMode:T},showProfileManager:T==="global",onComplete:kn,onCancel:()=>{h("main")}});let _t=Z!==null?Math.round((Date.now()-Z.getTime())/1e3):null,_n=_t===null?"":_t<5?" (just now)":` (${String(_t)}s ago)`,Xt=oe?.filter(C=>C.severity==="error").length??0;return H(W,{flexDirection:"column",paddingY:1,paddingX:2,children:[$(q,{marginBottom:1}),H(W,{flexDirection:"column",children:[H(W,{gap:2,marginBottom:0,children:[$(D,{bold:!0,dimColor:!0,children:"App Build"}),M==="pending"&&$(D,{dimColor:!0,children:"waiting\u2026"}),M==="building"&&H(W,{gap:1,children:[$(pe,{}),$(D,{children:"Building plugin package\u2026"})]}),M==="done"&&H(W,{gap:1,children:[$(D,{color:"green",children:"\u2713 Built"}),Z!==null&&H(D,{dimColor:!0,children:["at ",Z.toLocaleTimeString(),_n]}),we!==null&&H(D,{dimColor:!0,children:["\xB7 bundle: ",Ae(we)]})]}),M==="error"&&(oe!==null?H(D,{color:"red",children:["\u2717 ",Xt," validation ",Xt===1?"error":"errors"]}):H(D,{color:"red",children:["\u2717 ",Q??"unknown error"]}))]}),oe!==null&&$(ot,{issues:oe}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:l.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[$(D,{bold:!0,dimColor:!0,children:"Web Server"}),x==="starting"&&$(D,{dimColor:!0,children:"starting\u2026"}),x==="running"&&H(W,{gap:2,children:[$(D,{color:"green",children:"\u2713 Running"}),H(D,{dimColor:!0,children:["\u25CF ",Ct," viewer",Ct!==1?"s":""]})]}),x==="error"&&H(D,{color:"red",children:["\u2717 ",k??"Server error"]})]}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:a.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[$(D,{bold:!0,dimColor:!0,children:"Network Proxy"}),$(D,{color:"green",children:"\u2713 Active"}),$(D,{dimColor:!0,children:y?`\u25CF ${String(Gt)} key${Gt!==1?"s":""} in the network cache \xB7 ${String(Tn)} hit \xB7 ${String(Tt)} miss`:`\u25CF network cache disabled \xB7 ${String(Tt)} request${Tt!==1?"s":""}`})]}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:E.length===0?$(D,{dimColor:!0,children:" No requests yet."}):E.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),p&&H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[$(D,{bold:!0,dimColor:!0,children:"CDP Debug"}),H(D,{dimColor:!0,children:["\u25CF ",g.length," event(s)"]})]}),$(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:g.length===0?$(D,{dimColor:!0,children:" No CDP events yet."}):g.slice(-8).map((C,j)=>$(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,gap:1,children:[$(D,{dimColor:!0,children:"["}),$(D,{children:"q"}),$(D,{dimColor:!0,children:"] quit ["}),$(D,{children:"c"}),$(D,{dimColor:!0,children:"] credentials ["}),$(D,{children:"v"}),H(D,{dimColor:!0,children:["] ",Ct===0?"open viewer":"relaunch viewer"]})]})]})};async function Yr(e){return new Promise(t=>{let o=null,n=i=>{o?.(),t(i)},{unmount:r}=Zr(Xr(mt,{...e!==void 0&&{initialMode:e},onComplete:n}),{exitOnCtrlC:!1});o=r})}function Qr(e){e.command("dev").description("Start the plugin viewer dev server").option("-p, --port <port>","port to listen on","3121").option("-c, --credentials <path>","path to a credentials JSON file").option("-d, --debug","Enable CDP lifecycle logs in the TUI").option("-v, --verbose","Log every CDP event and handled error (implies --debug)").option("--no-viewer","Don't auto-launch the viewer on startup (press [v] to launch manually)").option("--no-cache","Disable the network proxy cache (always fetch upstream)").action(async t=>{let o=parseInt(t.port,10),n=process.cwd(),r=`${n}/.kizenapp`;Be(n);let i=null,u,p,{lastPath:m}=await ye(r);if(t.credentials)i=await ge(t.credentials);else{let c=await ye(r);if(c.credentialMode==="local")u="local";else if(c.credentialMode==="global"){if(u="global",p=c.activeCredentialProfile,p?(i=await le(p),i||(i=await Y(),p=void 0)):i=await Y(),!i){let h=await Yr("global");i=h.credentials,p=h.profileName}}else{let h=await Yr();i=h.credentials,u=h.mode,p=h.profileName;let T=h.profileName;await he(r,{credentialMode:h.mode,...T!==void 0&&{activeCredentialProfile:T}})}}let b=t.verbose===!0,y=b||t.debug===!0,S=t.viewer!==!1,N=t.cache!==!1,{waitUntilExit:v}=Zr(Xr(Kr,{port:o,pluginDir:n,outputDir:r,credentials:i,...u!==void 0&&{credentialMode:u},...p!==void 0&&{activeCredentialProfile:p},...m!==void 0&&{lastPath:m},debug:y,verbose:b,autoViewer:S,cacheEnabled:N}),{exitOnCtrlC:!1});await v()})}import{createElement as zi}from"react";import{readFile as Mi,writeFile as Hi}from"fs/promises";import{join as Ui}from"path";import{render as Vi}from"ink";import{useCallback as ht,useEffect as sn,useState as bt}from"react";import{Box as se,Text as O,useApp as Oi,useInput as ji}from"ink";import{encrypt as _i,serializeEnvelope as Ii}from"@kizenapps/packager";function Ni(e){let t=e;return t.code==="ECONNREFUSED"||t.cause?.code==="ECONNREFUSED"}function en(e){return{"Content-Type":"application/json","x-api-key":e.apiKey,"x-user-id":e.userId,"x-business-id":e.businessId,"x-auth-environment":e.environment}}async function tn(e,t,o){try{return await fetch(`${e}${t}`,o)}catch(n){throw new Error(Ni(n)?`Plugin-wizard is not running at ${e}`:`Failed to reach plugin-wizard: ${n.message}`)}}async function rn(e){let t=await e.text();if(t==="")return{};try{let o=JSON.parse(t);return typeof o=="object"&&o!==null?o:{}}catch{return{}}}async function Bi(e,t,o){let n=Ue(e.stage),r=await tn(n,"/get-public-key",{method:"POST",headers:en(t),body:JSON.stringify({api_name:o})}),i=await rn(r);if(!r.ok||typeof i.public_key!="string"){let u=typeof i.error=="string"?i.error:`HTTP ${String(r.status)}`;throw new Error(`Failed to fetch public key: ${u}`)}return i.public_key}function Ri(e,t){let o=_i(t,e),n=Ii(o);if(typeof n.value!="string")throw new Error("Unexpected serialized envelope shape from @kizenapps/packager");return n.value}async function Di(e,t,o,n){let r=Ue(e.stage),i=await tn(r,"/encrypt",{method:"POST",headers:en(t),body:JSON.stringify({api_name:o,value:n})}),u=await rn(i);if(!i.ok||u.encrypted!==!0||typeof u.value!="string"){let p=typeof u.error=="string"?u.error:`HTTP ${String(i.status)}`;throw new Error(`Encryption via plugin-wizard failed: ${p}`)}return u.value}async function yt(e,t,o,n,r){if(e.isRemote)return r?.("encrypting"),Di(e,t,o,n);r?.("fetching-key");let i=await Bi(e,t,o);return r?.("encrypting"),Ri(i,n)}import{spawn as $i}from"child_process";import{platform as nn}from"process";function Li(){return nn==="darwin"?[{cmd:"pbcopy",args:[]}]:nn==="win32"?[{cmd:"clip",args:[]}]:[{cmd:"wl-copy",args:[]},{cmd:"xclip",args:["-selection","clipboard"]},{cmd:"xsel",args:["--clipboard","--input"]}]}var Fi=2e3;function Ai(e,{cmd:t,args:o}){return new Promise(n=>{let r;try{r=$i(t,o,{stdio:["pipe","ignore","ignore"]})}catch{n(!1);return}let i=r,u=!1;function p(b){u||(u=!0,clearTimeout(m),n(b))}let m=setTimeout(()=>{i.kill(),p(!1)},Fi);m.unref(),i.on("error",()=>{p(!1)}),i.on("close",b=>{p(b===0)}),i.stdin.on("error",()=>{p(!1)});try{i.stdin.end(e)}catch{p(!1)}})}async function on(e){for(let t of Li())if(await Ai(e,t))return!0;return!1}import{Fragment as xt,jsx as L,jsxs as G}from"react/jsx-runtime";var Jt=({text:e})=>L(O,{dimColor:!0,children:e}),an=({ctx:e,stageDefaulted:t,credentialsPath:o,initialApiName:n,defaultApiName:r,initialValue:i,onDone:u})=>{let p=Oi(),[m,b]=bt({type:"loading"}),[y,S]=bt(null),[N,v]=bt(n??""),[c,h]=bt(i??""),T=ht(s=>{process.exitCode=1,b({type:"error",message:s instanceof Error?s.message:String(s)})},[]),P=ht(async(s,l,d)=>{try{let g=await yt(e,s,l,d,F=>{b(F==="fetching-key"?{type:"fetching-key"}:{type:"encrypting"})}),I=JSON.stringify({encrypted:!0,value:g},null,2);u?.(g);let E=await on(I);b({type:"done",envelope:I,copied:E})}catch(g){T(g)}},[e,T,u]),x=ht((s,l,d)=>{if(l.trim()===""){b({type:"api-name-entry",buffer:r??""});return}if(d===""){b({type:"value-entry",buffer:""});return}P(s,l.trim(),d)},[r,P]),w=ht(async s=>{try{b({type:"loading"});let l=s.isDefault?await Y():await le(s.name);if(l===null)throw new Error(`Could not load credential profile: ${s.name}`);S(l),x(l,N,c)}catch(l){T(l)}},[N,c,x,T]);sn(()=>{(async()=>{try{if(o!==void 0){let d;try{d=await ge(o)}catch(g){throw new Error(`Could not load credentials from ${o}: ${g instanceof Error?g.message:String(g)}`)}S(d),x(d,N,c);return}let s=await _e();if(s.length===0)throw new Error("No credential profiles found. Create ~/.kizenappbuilder/credentials.json first.");let[l]=s;if(s.length===1&&l!==void 0){let d=l.isDefault?await Y():await le(l.name);if(d===null)throw new Error(`Could not load credential profile: ${l.name}`);S(d),x(d,N,c);return}b({type:"profile-select",profiles:s,cursor:0})}catch(s){T(s)}})()},[]),sn(()=>{(m.type==="done"||m.type==="error")&&p.exit()},[m,p]),ji((s,l)=>{if(l.ctrl&&s==="c"){process.exitCode=130,p.exit();return}if(m.type==="profile-select"){let{profiles:d,cursor:g}=m;if(l.upArrow)b({...m,cursor:(g-1+d.length)%d.length});else if(l.downArrow)b({...m,cursor:(g+1)%d.length});else if(l.return){let I=d[g];I!==void 0&&w(I)}return}if(m.type==="api-name-entry"){let{buffer:d}=m;if(l.backspace||l.delete)b({type:"api-name-entry",buffer:d.slice(0,-1)});else if(l.return){let g=d.trim();if(g===""){b({type:"api-name-entry",buffer:d,error:"api_name cannot be empty"});return}v(g),y?x(y,g,c):T(new Error("Internal error: credentials were not loaded"))}else s&&!l.ctrl&&!l.meta&&b({type:"api-name-entry",buffer:d+s});return}if(m.type==="value-entry"){let{buffer:d}=m;if(l.backspace||l.delete)b({type:"value-entry",buffer:d.slice(0,-1)});else if(l.return){if(d===""){b({type:"value-entry",buffer:d,error:"secret cannot be empty"});return}h(d),y?x(y,N,d):T(new Error("Internal error: credentials were not loaded"))}else s&&!l.ctrl&&!l.meta&&b({type:"value-entry",buffer:d+s});return}});let k=e.isRemote?"remote Kizen API":"on-machine",f=t===!0?`${e.stage} (default)`:e.stage,a=s=>G(se,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[L(q,{}),G(O,{dimColor:!0,children:["Mode: ",k," Stage: ",f]}),s]});if(m.type==="loading")return a(G(se,{gap:1,children:[L(pe,{}),L(O,{dimColor:!0,children:"Loading credentials\u2026"})]}));if(m.type==="profile-select"){let{profiles:s,cursor:l}=m;return a(G(xt,{children:[L(O,{bold:!0,children:"Credential profile"}),L(se,{flexDirection:"column",children:s.map((d,g)=>{let I=l===g;return G(se,{gap:2,children:[L(O,{...I&&{color:"cyan"},children:I?"\u276F":" "}),L(O,{bold:I,...I&&{color:"cyan"},children:d.isDefault?"Default":d.name}),L(O,{dimColor:!0,children:d.path})]},d.name)})}),L(Jt,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to quit"})]}))}return m.type==="api-name-entry"?a(G(xt,{children:[L(O,{bold:!0,children:"Plugin api_name"}),m.error!==void 0&&G(O,{color:"red",children:["Error: ",m.error]}),G(se,{gap:1,children:[L(O,{color:"cyan",children:">"}),L(O,{children:m.buffer}),L(O,{color:"cyan",children:"\u2588"})]}),L(Jt,{text:"Type the api_name \xB7 Enter to confirm \xB7 Ctrl+C to quit"})]})):m.type==="value-entry"?a(G(xt,{children:[L(O,{bold:!0,children:"Secret value"}),m.error!==void 0&&G(O,{color:"red",children:["Error: ",m.error]}),G(se,{gap:1,children:[L(O,{color:"cyan",children:">"}),L(O,{children:"\u2022".repeat(m.buffer.length)}),L(O,{color:"cyan",children:"\u2588"})]}),L(Jt,{text:"Input hidden \xB7 Enter to encrypt \xB7 Ctrl+C to quit"})]})):m.type==="fetching-key"?a(G(se,{gap:1,children:[L(pe,{}),G(O,{children:["Fetching ",e.stage," public key for ",L(O,{bold:!0,children:N}),"\u2026"]})]})):m.type==="encrypting"?a(G(se,{gap:1,children:[L(pe,{}),L(O,{children:"Encrypting\u2026"})]})):m.type==="error"?a(G(se,{gap:1,children:[L(O,{color:"red",children:"\u2717"}),L(O,{color:"red",children:m.message})]})):a(G(xt,{children:[G(se,{gap:1,children:[L(O,{color:"green",children:"\u2713"}),L(O,{bold:!0,children:"Encrypted secret ready"})]}),m.copied?L(O,{color:"green",children:"\u2713 Copied to clipboard \u2014 paste it into the secret value in your kizen.json."}):L(O,{dimColor:!0,children:"Paste this into the secret value in your kizen.json (re-run with --out <path> to save it to a file; selecting it here may capture line wraps):"}),L(O,{children:m.envelope})]}))};function ln(e){return{encrypted:!0,value:e}}function qi(e){return JSON.stringify(ln(e))}async function cn(e,t){await Hi(e,`${JSON.stringify(ln(t),null,2)}
192
+ `,"utf-8")}var Ji="prod";async function Wi(){try{let e=await Mi(Ui(process.cwd(),"kizen.json"),"utf-8"),t=JSON.parse(e),o=Array.isArray(t)?t[0]:t,n=typeof o.api_name=="string"&&o.api_name!==""?o.api_name:void 0;return{...n!==void 0&&{apiName:n}}}catch{}return{}}async function Gi(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Ki(e,t,o,n){let r=t.credentials!==void 0?await ge(t.credentials):await Y();if(r===null)throw new Error("No credentials found. Pass --credentials or create ~/.kizenappbuilder/credentials.json.");let i=t.apiName??o.apiName;if(i===void 0||i.trim()==="")throw new Error("api_name is required in non-interactive mode. Pass --api-name or run inside a plugin directory.");n&&process.stderr.write(`No --stage given; defaulting to ${e.stage} encryption keys (pass --stage dev to override)
193
+ `);let u=t.value;if(u===void 0){if(process.stdin.isTTY)throw new Error('No secret provided and stdin is a terminal. Pass --value, or pipe the secret in (e.g. `printf %s "$SECRET" | npx --yes @kizenapps/cli encrypt \u2026`).');process.stderr.write(`Reading secret from stdin (pass --value to skip)\u2026
194
+ `),u=(await Gi()).replace(/[\r\n]+$/,"")}if(u==="")throw new Error("A secret value is required. Pass --value or pipe it via stdin.");let p=await yt(e,r,i.trim(),u);if(process.stdout.write(`${qi(p)}
195
195
  `),t.out!==void 0)try{await cn(t.out,p),process.stderr.write(`Wrote encrypted envelope to ${t.out}
196
- `)}catch(f){process.stderr.write(`Error writing ${t.out}: ${f instanceof Error?f.message:String(f)}
197
- `),process.exitCode=1}}function dn(e){e.command("encrypt").description("Encrypt a secret for a plugin against its encryption keys").option("--remote","encrypt via the plugin-wizard's remote API instead of on-machine").option("-c, --credentials <path>","path to a credentials JSON file").option("-a, --api-name <name>","plugin api_name the secret belongs to").option("-v, --value <value>","plaintext secret value to encrypt").option("-s, --stage <stage>","which encryption API to use: dev or prod (default: prod)").option("-o, --out <path>","also write the encrypted envelope to a file").action(async t=>{t.stage!==void 0&&t.stage!=="dev"&&t.stage!=="prod"&&(console.error(`Error: --stage must be "dev" or "prod" (got: "${t.stage}")`),process.exit(1));let n=t.apiName===void 0?await Vi():{},r=t.stage===void 0,i=t.stage==="dev"||t.stage==="prod"?t.stage:Ui,u={isRemote:t.remote===!0,stage:i};if(!process.stdin.isTTY||!process.stdout.isTTY){try{await Ji(u,t,n,r)}catch(x){console.error(`Error: ${x instanceof Error?x.message:String(x)}`),process.exit(1)}return}let p,{waitUntilExit:f}=Mi(Ai(an,{ctx:u,stageDefaulted:r,onDone:x=>{p=x},...t.credentials!==void 0&&{credentialsPath:t.credentials},...t.apiName!==void 0&&{initialApiName:t.apiName},...n.apiName!==void 0&&{defaultApiName:n.apiName},...t.value!==void 0&&{initialValue:t.value}}),{exitOnCtrlC:!1});if(await f(),p!==void 0&&t.out!==void 0)try{await cn(t.out,p),process.stderr.write(`Wrote encrypted envelope to ${t.out}
198
- `)}catch(x){console.error(`Error writing ${t.out}: ${x instanceof Error?x.message:String(x)}`),process.exitCode=1}})}var Wi=new Set(["phone","envelope","pen-nib","calendar-days","paperclip","file","clipboard","pen","tag","book","print","pen-to-square","folder","folder-open","thumbtack","globe","city","briefcase","compass","address-book","business-time","computer-classic","pen-fancy","badge-check","mug-saucer","landmark","chart-simple","envelopes","diagram-venn","calendar","pencil","phone-volume","copy","table","building","network-wired","address-card","tags","registered","signature","phone-office","projector","sitemap","marker","badge","wallet","copyright","bullseye","calculator","certificate","percent","eraser","file-spreadsheet","glasses","industry","vault","user-tie-hair-long","user-tie-hair","user-hair-mullet","trademark","timeline-arrow","timeline","table-tree","table-rows","table-pivot","table-layout","table-columns","stapler","square-poll-vertical","square-poll-horizontal","square-phone-flip","square-phone","square-pen","square-kanban","square-envelope","socks","slot-machine","signature-slash","signature-lock","shredder","scissors","scanner-image","scale-unbalanced-flip","scale-unbalanced","scale-balanced","router","rectangle-pro","print-slash","print-magnifying-glass","presentation-screen","podium","phone-slash","phone-intercom","phone-flip","person-chalkboard","pen-nib-slash","pen-clip","paste","paperclip-vertical","notebook","note-sticky","money-check-pen","money-check-dollar-pen","magnifying-glass-chart","magnifying-glass-arrow-right","list-tree","list-timeline","list-radio","list-dropdown","list-check","laptop-file","lamp-desk","keynote","industry-windows","inboxes","inbox-full","house-laptop","highlighter","folders","folder-xmark","folder-tree","folder-plus","folder-minus","folder-arrow-up","folder-arrow-down","floppy-disk-circle-xmark","floppy-disk-circle-arrow-right","floppy-disk","file-user","file-lines","file-circle-plus","file-circle-info","file-chart-pie","file-chart-column","fax","envelope-open","envelope-dot","envelope-circle-check","coffee-pot","cloud-word","clipboard-question","chart-user","chart-tree-map","chart-simple-horizontal","chart-pyramid","chart-pie-simple","chart-pie","chart-line-up","chart-line-down","chart-line","cake-candles","cabinet-filing","bullhorn","briefcase-blank","briefcase-arrow-right","brain-arrow-curved-right","boxes-packing","box-archive","book-section","bars-staggered","bars-progress","badge-percent","badge-dollar","arrows-to-eye","arrows-to-dot","arrows-spin","sparkles","megaphone","block-question","lightbulb-slash","comments-dollar","comments","bullseye-pointer","lightbulb","user-group-crown","user-crown","signal-stream-slash","signal-stream","rectangle-ad","ranking-star","person-rays","people-group","messages-dollar","message-dollar","magnifying-glass-location","magnifying-glass-dollar","lightbulb-on","lightbulb-exclamation","lightbulb-dollar","lightbulb-cfl-on","lightbulb-cfl","hundred-points","group-arrows-rotate","gift-card","filter-circle-dollar","envelopes-bulk","envelope-open-text","envelope-open-dollar","comment-dollar","chart-mixed","bullseye-arrow","star","heart","camera-retro","truck-fast","bell","cart-shopping","gift","barcode","bookmark","camera","thumbs-up","thumbs-down","key","truck","balloons","handshake","shop","shirt","bag-shopping","moped","cart-plus","credit-card","store","cash-register","booth-curtain","trophy","receipt","truck-container","truck-clock","truck-bolt","trophy-star","store-slash","store-lock","star-exclamation","shop-slash","shop-lock","rectangle-barcode","person-booth","nfc-trash","nfc-symbol","nfc-slash","nfc-signal","nfc-pen","nfc-magnifying-glass","nfc-lock","nfc","money-check-dollar","money-check","mobile-signal-out","mobile-signal","hexagon-vertical-nft-slanted","hexagon-vertical-nft","hexagon-image","hand-holding-box","gifts","gem","credit-card-front","credit-card-blank","cart-xmark","cart-shopping-fast","cart-minus","cart-circle-xmark","cart-circle-plus","cart-circle-exclamation","cart-circle-check","cart-circle-arrow-up","cart-circle-arrow-down","cart-arrow-up","cart-arrow-down","box-open-full","basket-shopping-simple","basket-shopping","barcode-scan","barcode-read","balloon","bags-shopping","bars","browser","chart-bar","cog","database","calendar-alt","play","kizen-k","add","book-alt","form-entity","arrows-to-circle","question-circle","chevron-down","chevron-up","window-restore","forward"]),Gi=[...Wi].sort(),Ki=new Set(["kizen-k","form-entity"]),un=[...Gi,...[...Ki].sort()];function pn(e){e.command("icons").description("List all valid icon names accepted by toolbar items, pages, and adornments").action(()=>{for(let t of un)console.log(t)})}import{mkdir as Yi,writeFile as fn,readFile as Xi}from"fs/promises";import{join as vt}from"path";var Zi=new Set(["developer_business_id"]);function Qi(e){return Array.isArray(e)?e.map(t=>{if(typeof t!="object"||t===null)return t;let o=t;if(typeof o.auth_credentials!="object"||o.auth_credentials===null)return o;let n=Object.fromEntries(Object.keys(o.auth_credentials).map(r=>[r,"*****"]));return{...o,auth_credentials:n}}):e}var es={".png":"image/png",".svg":"image/svg+xml",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp"};function gn(e){let t={name:"",children:new Map,isFile:!1,filePath:""};for(let o of e){let n=o.path.split("/"),r=t;n.forEach((i,u)=>{r.children.has(i)||r.children.set(i,{name:i,children:new Map,isFile:u===n.length-1,filePath:n.slice(0,u+1).join("/")});let p=r.children.get(i);p&&(r=p)})}return t}function Gt(e){return"file-"+e.replace(/[^a-zA-Z0-9]/g,"-")}function ae(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function yn(e){return`<ul>${[...e.children.values()].sort((n,r)=>n.isFile!==r.isFile?n.isFile?1:-1:n.name.localeCompare(r.name)).map(n=>n.isFile?`<li class="tf"><a href="#${Gt(n.filePath)}" data-id="${Gt(n.filePath)}">${ae(n.name)}</a></li>`:`<li class="td"><span class="dn">${ae(n.name)}/</span>${yn(n)}</li>`).join("")}</ul>`}function hn(e){let t=e.lastIndexOf(".");return t>=0?e.slice(t).toLowerCase():""}function ts(e){let t;return e.base64Image!==void 0?t=`<img src="data:${es[hn(e.path)]??"image/png"};base64,${e.base64Image}" alt="${ae(e.path)}" style="max-width:100%">`:e.binaryData!==void 0?t=`<p class="bin">[Binary file: ${String(e.binaryData.length)} bytes]</p>`:t=`<pre><code>${ae(e.content)}</code></pre>`,`<section id="${Gt(e.path)}"><h2 class="fp">${ae(e.path)}</h2><div class="fb">${t}</div></section>`}var rs={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".json":"json",".css":"css",".scss":"scss",".html":"html",".htm":"html",".md":"markdown",".mdx":"markdown",".py":"python",".sh":"bash",".yml":"yaml",".yaml":"yaml",".xml":"xml",".toml":"toml"};function ns(e){return rs[hn(e)]??""}function bn(e,t=""){let o=[...e.children.values()].sort((n,r)=>n.isFile!==r.isFile?n.isFile?1:-1:n.name.localeCompare(r.name));return o.map((n,r)=>{let i=r===o.length-1,u=i?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",p=i?" ":"\u2502 ";return n.isFile?`${t}${u}${n.name}`:`${t}${u}${n.name}/
199
- ${bn(n,t+p)}`}).join(`
200
- `)}function xn(e){return e.filter(t=>t.path!=="kizen.json"&&t.path!=="plugin-report.html")}function vn(e){return Object.fromEntries(Object.entries(e).filter(([t])=>!Zi.has(t)).map(([t,o])=>[t,t==="services"?Qi(o):o]))}function os(e,t){let o=vn(e),n=typeof e.name=="string"?e.name:"Plugin",r=typeof e.version=="string"?e.version:"",i=typeof e.description=="string"?e.description:"",u=xn(t),p=[];p.push(`# ${n}${r?` v${r}`:""}`),i&&p.push("",i),p.push("","## Configuration (`kizen.json`)","","```json",JSON.stringify(o,null,2),"```"),p.push("","## File Tree","","```",bn(gn(u)),"```"),p.push("","## Files");for(let f of u)p.push("",`### \`${f.path}\``,""),f.base64Image!==void 0?p.push(`[Image file: ${f.path}]`):f.binaryData!==void 0?p.push(`[Binary file: ${String(f.binaryData.length)} bytes]`):p.push(`\`\`\`${ns(f.path)}`,f.content,"```");return p.join(`
196
+ `)}catch(m){process.stderr.write(`Error writing ${t.out}: ${m instanceof Error?m.message:String(m)}
197
+ `),process.exitCode=1}}function dn(e){e.command("encrypt").description("Encrypt a secret for a plugin against its encryption keys").option("--remote","encrypt via the plugin-wizard's remote API instead of on-machine").option("-c, --credentials <path>","path to a credentials JSON file").option("-a, --api-name <name>","plugin api_name the secret belongs to").option("-v, --value <value>","plaintext secret value to encrypt").option("-s, --stage <stage>","which encryption API to use: dev or prod (default: prod)").option("-o, --out <path>","also write the encrypted envelope to a file").action(async t=>{t.stage!==void 0&&t.stage!=="dev"&&t.stage!=="prod"&&(console.error(`Error: --stage must be "dev" or "prod" (got: "${t.stage}")`),process.exit(1));let n=t.apiName===void 0?await Wi():{},r=t.stage===void 0,i=t.stage==="dev"||t.stage==="prod"?t.stage:Ji,u={isRemote:t.remote===!0,stage:i};if(!process.stdin.isTTY||!process.stdout.isTTY){try{await Ki(u,t,n,r)}catch(b){console.error(`Error: ${b instanceof Error?b.message:String(b)}`),process.exit(1)}return}let p,{waitUntilExit:m}=Vi(zi(an,{ctx:u,stageDefaulted:r,onDone:b=>{p=b},...t.credentials!==void 0&&{credentialsPath:t.credentials},...t.apiName!==void 0&&{initialApiName:t.apiName},...n.apiName!==void 0&&{defaultApiName:n.apiName},...t.value!==void 0&&{initialValue:t.value}}),{exitOnCtrlC:!1});if(await m(),p!==void 0&&t.out!==void 0)try{await cn(t.out,p),process.stderr.write(`Wrote encrypted envelope to ${t.out}
198
+ `)}catch(b){console.error(`Error writing ${t.out}: ${b instanceof Error?b.message:String(b)}`),process.exitCode=1}})}var Yi=new Set(["phone","envelope","pen-nib","calendar-days","paperclip","file","clipboard","pen","tag","book","print","pen-to-square","folder","folder-open","thumbtack","globe","city","briefcase","compass","address-book","business-time","computer-classic","pen-fancy","badge-check","mug-saucer","landmark","chart-simple","envelopes","diagram-venn","calendar","pencil","phone-volume","copy","table","building","network-wired","address-card","tags","registered","signature","phone-office","projector","sitemap","marker","badge","wallet","copyright","bullseye","calculator","certificate","percent","eraser","file-spreadsheet","glasses","industry","vault","user-tie-hair-long","user-tie-hair","user-hair-mullet","trademark","timeline-arrow","timeline","table-tree","table-rows","table-pivot","table-layout","table-columns","stapler","square-poll-vertical","square-poll-horizontal","square-phone-flip","square-phone","square-pen","square-kanban","square-envelope","socks","slot-machine","signature-slash","signature-lock","shredder","scissors","scanner-image","scale-unbalanced-flip","scale-unbalanced","scale-balanced","router","rectangle-pro","print-slash","print-magnifying-glass","presentation-screen","podium","phone-slash","phone-intercom","phone-flip","person-chalkboard","pen-nib-slash","pen-clip","paste","paperclip-vertical","notebook","note-sticky","money-check-pen","money-check-dollar-pen","magnifying-glass-chart","magnifying-glass-arrow-right","list-tree","list-timeline","list-radio","list-dropdown","list-check","laptop-file","lamp-desk","keynote","industry-windows","inboxes","inbox-full","house-laptop","highlighter","folders","folder-xmark","folder-tree","folder-plus","folder-minus","folder-arrow-up","folder-arrow-down","floppy-disk-circle-xmark","floppy-disk-circle-arrow-right","floppy-disk","file-user","file-lines","file-circle-plus","file-circle-info","file-chart-pie","file-chart-column","fax","envelope-open","envelope-dot","envelope-circle-check","coffee-pot","cloud-word","clipboard-question","chart-user","chart-tree-map","chart-simple-horizontal","chart-pyramid","chart-pie-simple","chart-pie","chart-line-up","chart-line-down","chart-line","cake-candles","cabinet-filing","bullhorn","briefcase-blank","briefcase-arrow-right","brain-arrow-curved-right","boxes-packing","box-archive","book-section","bars-staggered","bars-progress","badge-percent","badge-dollar","arrows-to-eye","arrows-to-dot","arrows-spin","sparkles","megaphone","block-question","lightbulb-slash","comments-dollar","comments","bullseye-pointer","lightbulb","user-group-crown","user-crown","signal-stream-slash","signal-stream","rectangle-ad","ranking-star","person-rays","people-group","messages-dollar","message-dollar","magnifying-glass-location","magnifying-glass-dollar","lightbulb-on","lightbulb-exclamation","lightbulb-dollar","lightbulb-cfl-on","lightbulb-cfl","hundred-points","group-arrows-rotate","gift-card","filter-circle-dollar","envelopes-bulk","envelope-open-text","envelope-open-dollar","comment-dollar","chart-mixed","bullseye-arrow","star","heart","camera-retro","truck-fast","bell","cart-shopping","gift","barcode","bookmark","camera","thumbs-up","thumbs-down","key","truck","balloons","handshake","shop","shirt","bag-shopping","moped","cart-plus","credit-card","store","cash-register","booth-curtain","trophy","receipt","truck-container","truck-clock","truck-bolt","trophy-star","store-slash","store-lock","star-exclamation","shop-slash","shop-lock","rectangle-barcode","person-booth","nfc-trash","nfc-symbol","nfc-slash","nfc-signal","nfc-pen","nfc-magnifying-glass","nfc-lock","nfc","money-check-dollar","money-check","mobile-signal-out","mobile-signal","hexagon-vertical-nft-slanted","hexagon-vertical-nft","hexagon-image","hand-holding-box","gifts","gem","credit-card-front","credit-card-blank","cart-xmark","cart-shopping-fast","cart-minus","cart-circle-xmark","cart-circle-plus","cart-circle-exclamation","cart-circle-check","cart-circle-arrow-up","cart-circle-arrow-down","cart-arrow-up","cart-arrow-down","box-open-full","basket-shopping-simple","basket-shopping","barcode-scan","barcode-read","balloon","bags-shopping","bars","browser","chart-bar","cog","database","calendar-alt","play","kizen-k","add","book-alt","form-entity","arrows-to-circle","question-circle","chevron-down","chevron-up","window-restore","forward"]),Xi=[...Yi].sort(),Zi=new Set(["kizen-k","form-entity"]),un=[...Xi,...[...Zi].sort()];function pn(e){e.command("icons").description("List all valid icon names accepted by toolbar items, pages, and adornments").action(()=>{for(let t of un)console.log(t)})}import{mkdir as Qi,writeFile as fn,readFile as es}from"fs/promises";import{join as vt}from"path";var ts=new Set(["developer_business_id"]);function rs(e){return Array.isArray(e)?e.map(t=>{if(typeof t!="object"||t===null)return t;let o=t;if(typeof o.auth_credentials!="object"||o.auth_credentials===null)return o;let n=Object.fromEntries(Object.keys(o.auth_credentials).map(r=>[r,"*****"]));return{...o,auth_credentials:n}}):e}var ns={".png":"image/png",".svg":"image/svg+xml",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp"};function yn(e){let t={name:"",children:new Map,isFile:!1,filePath:""};for(let o of e){let n=o.path.split("/"),r=t;n.forEach((i,u)=>{r.children.has(i)||r.children.set(i,{name:i,children:new Map,isFile:u===n.length-1,filePath:n.slice(0,u+1).join("/")});let p=r.children.get(i);p&&(r=p)})}return t}function Wt(e){return"file-"+e.replace(/[^a-zA-Z0-9]/g,"-")}function ae(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function hn(e){return`<ul>${[...e.children.values()].sort((n,r)=>n.isFile!==r.isFile?n.isFile?1:-1:n.name.localeCompare(r.name)).map(n=>n.isFile?`<li class="tf"><a href="#${Wt(n.filePath)}" data-id="${Wt(n.filePath)}">${ae(n.name)}</a></li>`:`<li class="td"><span class="dn">${ae(n.name)}/</span>${hn(n)}</li>`).join("")}</ul>`}function bn(e){let t=e.lastIndexOf(".");return t>=0?e.slice(t).toLowerCase():""}function os(e){let t;return e.base64Image!==void 0?t=`<img src="data:${ns[bn(e.path)]??"image/png"};base64,${e.base64Image}" alt="${ae(e.path)}" style="max-width:100%">`:e.binaryData!==void 0?t=`<p class="bin">[Binary file: ${String(e.binaryData.length)} bytes]</p>`:t=`<pre><code>${ae(e.content)}</code></pre>`,`<section id="${Wt(e.path)}"><h2 class="fp">${ae(e.path)}</h2><div class="fb">${t}</div></section>`}var is={".ts":"typescript",".tsx":"typescript",".js":"javascript",".jsx":"javascript",".mjs":"javascript",".cjs":"javascript",".json":"json",".css":"css",".scss":"scss",".html":"html",".htm":"html",".md":"markdown",".mdx":"markdown",".py":"python",".sh":"bash",".yml":"yaml",".yaml":"yaml",".xml":"xml",".toml":"toml"};function ss(e){return is[bn(e)]??""}function mn(e){let t=[...e.matchAll(/`+/g)].reduce((o,n)=>Math.max(o,n[0].length),0);return"`".repeat(Math.max(3,t+1))}function xn(e,t=""){let o=[...e.children.values()].sort((n,r)=>n.isFile!==r.isFile?n.isFile?1:-1:n.name.localeCompare(r.name));return o.map((n,r)=>{let i=r===o.length-1,u=i?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",p=i?" ":"\u2502 ";return n.isFile?`${t}${u}${n.name}`:`${t}${u}${n.name}/
199
+ ${xn(n,t+p)}`}).join(`
200
+ `)}var as=/(^|\/)licen[cs]e(\.md|\.txt)?$/i;function vn(e){return e.filter(t=>t.path!=="kizen.json"&&t.path!=="plugin-report.html"&&!as.test(t.path))}function wn(e){return Object.fromEntries(Object.entries(e).filter(([t])=>!ts.has(t)).map(([t,o])=>[t,t==="services"?rs(o):o]))}function ls(e,t){let o=wn(e),n=typeof e.name=="string"?e.name:"Plugin",r=typeof e.version=="string"?e.version:"",i=typeof e.description=="string"?e.description:"",u=vn(t),p=[];p.push(`# ${n}${r?` v${r}`:""}`),i&&p.push("",i);let m=JSON.stringify(o,null,2),b=mn(m);p.push("","## Configuration (`kizen.json`)","",`${b}json`,m,b),p.push("","## File Tree","","```",xn(yn(u)),"```"),p.push("","## Files");for(let y of u)if(p.push("",`### \`${y.path}\``,""),y.base64Image!==void 0)p.push(`[Image file: ${y.path}]`);else if(y.binaryData!==void 0)p.push(`[Binary file: ${String(y.binaryData.length)} bytes]`);else{let S=mn(y.content);p.push(`${S}${ss(y.path)}`,y.content,S)}return p.join(`
201
201
  `)+`
202
- `}function is(e,t){let o=vn(e),n=typeof e.name=="string"?e.name:"Plugin",r=typeof e.version=="string"?e.version:"",i=typeof e.description=="string"?e.description:"",u=xn(t),p=yn(gn(u)),f=u.map(ts).join(`
202
+ `}function cs(e,t){let o=wn(e),n=typeof e.name=="string"?e.name:"Plugin",r=typeof e.version=="string"?e.version:"",i=typeof e.description=="string"?e.description:"",u=vn(t),p=hn(yn(u)),m=u.map(os).join(`
203
203
  `);return`<!DOCTYPE html>
204
204
  <html lang="en">
205
205
  <head>
@@ -252,7 +252,7 @@ img{border:1px solid var(--bd);border-radius:4px}
252
252
  </nav>
253
253
  <main>
254
254
  <section id="config"><h2 class="fp">kizen.json \u2014 Plugin Configuration</h2><div class="fb"><pre><code>${ae(JSON.stringify(o,null,2))}</code></pre></div></section>
255
- ${f}
255
+ ${m}
256
256
  </main>
257
257
  </div>
258
258
  <script>
@@ -265,7 +265,7 @@ ${f}
265
265
  })();
266
266
  </script>
267
267
  </body>
268
- </html>`}var mn=vt(ke,"examples");function wn(e){e.command("report").description("Generate a self-contained HTML report of the plugin").option("-o, --output <path>",`output file path (default: ${mn}/<api_name>.html)`).action(async t=>{let o=process.cwd(),n;try{let f=await Xi(vt(o,"kizen.json"),"utf-8"),x=JSON.parse(f);n=Array.isArray(x)?x[0]:x}catch{console.error("Error: kizen.json not found. Run this command from a plugin directory."),process.exit(1)}let r=typeof n.api_name=="string"?n.api_name:"plugin",i=t.output??vt(mn,`${r}.html`),u=i.replace(/\.html$/,".md"),p=await tt(o);await Yi(vt(i,".."),{recursive:!0}),await Promise.all([fn(i,is(n,p),"utf-8"),fn(u,os(n,p),"utf-8")]),console.log(`Plugin report written to:
268
+ </html>`}var gn=vt(ke,"examples");function Cn(e){e.command("report").description("Generate a self-contained HTML report of the plugin").option("-o, --output <path>",`output file path (default: ${gn}/<api_name>.html)`).action(async t=>{let o=process.cwd(),n;try{let m=await es(vt(o,"kizen.json"),"utf-8"),b=JSON.parse(m);n=Array.isArray(b)?b[0]:b}catch{console.error("Error: kizen.json not found. Run this command from a plugin directory."),process.exit(1)}let r=typeof n.api_name=="string"?n.api_name:"plugin",i=t.output??vt(gn,`${r}.html`),u=i.replace(/\.html$/,".md"),p=await tt(o,{detectBinaryByContent:!0});await Qi(vt(i,".."),{recursive:!0}),await Promise.all([fn(i,cs(n,p),"utf-8"),fn(u,ls(n,p),"utf-8")]),console.log(`Plugin report written to:
269
269
  ${i}
270
- ${u}`)})}var ds=ls(as(cs(import.meta.url)),"..","package.json"),us=JSON.parse(ss(ds,"utf-8"));ve.name("appbuilder").description("Kizen plugin app builder").version(us.version);vr(ve);cr(ve);Qr(ve);dn(ve);wn(ve);pn(ve);ve.parse();
270
+ ${u}`)})}var ms=ps(us(fs(import.meta.url)),"..","package.json"),gs=JSON.parse(ds(ms,"utf-8"));ve.name("npx @kizenapps/cli").description("Kizen plugin app builder").version(gs.version);vr(ve);cr(ve);Qr(ve);dn(ve);Cn(ve);pn(ve);ve.parse();
271
271
  //# sourceMappingURL=index.js.map