@kizenapps/cli 1.10.0-0a9fae5 → 1.10.0-e36fedb

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 (32) hide show
  1. package/README.md +172 -15
  2. package/dist/THIRD-PARTY-NOTICES.txt +4342 -0
  3. package/dist/index.js +24 -24
  4. package/dist/index.js.map +1 -1
  5. package/dist/viewer/assets/AppDetailPage-D9xr-bY8.js +1 -0
  6. package/dist/viewer/assets/{CodeStepsPage-BjnqiAQX.js → CodeStepsPage-CvCrJCQn.js} +1 -1
  7. package/dist/viewer/assets/{ConfigurationPage-XUysfO8v.js → ConfigurationPage-5qOX-sx0.js} +1 -1
  8. package/dist/viewer/assets/IconReferencePage-BxPfyqlV.js +1 -0
  9. package/dist/viewer/assets/SandboxPage-DuCHX1FY.js +1 -0
  10. package/dist/viewer/assets/{SecretsPage-BwDfBKbY.js → SecretsPage-Da55-e_S.js} +1 -1
  11. package/dist/viewer/assets/{SourceBrowserPage-D9z0jLNw.js → SourceBrowserPage-DluS8U4q.js} +1 -1
  12. package/dist/viewer/assets/blockDimensions-BhWxVVcK.js +1 -0
  13. package/dist/viewer/assets/{index-C570aZ49.js → index-Du4zThGL.js} +2 -2
  14. package/dist/viewer/assets/index-MRuQEa3q.css +2 -0
  15. package/dist/viewer/assets/{useCompleteSetup-3RGdCYrc.js → useCompleteSetup-DUHoBgca.js} +1 -1
  16. package/dist/viewer/assets/{usePluginConfig-XFnehL_S.js → usePluginConfig-C8d13THZ.js} +1 -1
  17. package/dist/viewer/assets/validIcons-D8mhuO5s.js +1 -0
  18. package/dist/viewer/index.html +2 -2
  19. package/package.json +27 -8
  20. package/dist/viewer/assets/AppDetailPage-CKDgNuvS.js +0 -1
  21. package/dist/viewer/assets/IconReferencePage-CN9Tha2W.js +0 -1
  22. package/dist/viewer/assets/SandboxPage-DbMklAzy.js +0 -1
  23. package/dist/viewer/assets/blockDimensions-XngD6WWh.js +0 -1
  24. package/dist/viewer/assets/fa-pro-icons-B6J9phvt.js +0 -1
  25. package/dist/viewer/assets/iconMap-B-cS2yrx.js +0 -1
  26. package/dist/viewer/assets/index-CortCmDi.css +0 -2
  27. /package/dist/viewer/assets/{CodeViewer-DpJLTTab.js → CodeViewer-CVECJY4e.js} +0 -0
  28. /package/dist/viewer/assets/{VersionsPage-CRnStnQ-.js → VersionsPage-yNilRkEf.js} +0 -0
  29. /package/dist/viewer/assets/{WhenBadge-Dm7YHpxd.js → WhenBadge-B7s7fns2.js} +0 -0
  30. /package/dist/viewer/assets/{formatBytes-BV6bvmhE.js → formatBytes-BXYIMbyB.js} +0 -0
  31. /package/dist/viewer/assets/{setupAssistant-C-3V_Vj3.js → setupAssistant-DtI9NWXr.js} +0 -0
  32. /package/dist/viewer/assets/{useLocalStorage-BZr9ZJI5.js → useLocalStorage-wp83IS34.js} +0 -0
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
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
- `).map(u=>u.trim());if(i.includes(o)||i.includes(".kizenapp"))return}let r=n.endsWith(`
2
+ import{readFileSync as xs}from"fs";import{dirname as bs,join as vs}from"path";import{fileURLToPath as ws}from"url";import{Command as Cs}from"commander";import{createElement as ko}from"react";import{render as _o}from"ink";import{useEffect as ar,useState as Oe}from"react";import{Box as je,Text as _e,useApp as To}from"ink";import{PluginValidationError as Eo}from"@kizenapps/packager";import{mkdir as to,writeFile as ro}from"fs/promises";import{join as no}from"path";import{PluginValidationError as oo,minifyFiles as io,packagePlugin as so,parseManifestFromFiles as ao,transformDeployablePlugin as lo,validatePluginApp as co}from"@kizenapps/packager";import{readdir as Gn,readFile as er}from"fs/promises";import{join as tr,relative as Kn}from"path";var Yn=new Set([".png",".svg"]),Xn=new Set([".kzn"]),Zn=new Set([".DS_Store"]),Qe=new Set(["node_modules",".git",".kizenapp",".github",".claude","__pycache__"]),Qn=8e3;function eo(e){return e.subarray(0,Qn).includes(0)}async function rr(e,t){let o=await Gn(e,{withFileTypes:!0}),n=[];for(let r of o)if(r.isDirectory()){if(Qe.has(r.name))continue;n.push(...await rr(tr(e,r.name),t))}else r.isFile()&&(Zn.has(r.name)||n.push(tr(e,r.name)));return n}async function et(e,{detectBinaryByContent:t=!1}={}){let o=await rr(e,e);return Promise.all(o.map(async n=>{let r=Kn(e,n).split("\\").join("/"),i=r.lastIndexOf("."),p=i>=0?r.slice(i).toLowerCase():"";if(Yn.has(p)){let m=await er(n);return{path:r,content:"",base64Image:m.toString("base64")}}let u=await er(n);return Xn.has(p)||t&&eo(u)?{path:r,content:"",binaryData:u}:{path:r,content:u.toString("utf-8")}}))}var po=(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 tt(e,t,o){await to(t,{recursive:!0}),o?.("reading-files");let n=await et(e);o?.("validating");let r=co(n);if(r.some(v=>v.severity==="error"))throw new oo(r);o?.("minifying");let i=await io(n);o?.("packaging");let p=ao(i),u=so(i,p),m=Object.values(u).map(lo);o?.("writing-bundle");let g=m.map(v=>{let c=v.release_notes_directory?.replace(/\/$/,""),x=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 po(v,x)}),h=JSON.stringify(g,null,2),S=(v,c)=>v==="allReleaseNotes"?void 0:c,I=Buffer.byteLength(JSON.stringify(g,S,2),"utf-8");return await ro(no(t,"bundle.json"),h,"utf-8"),{bundleSize:I}}function $e(e){return e<1024?`${String(e)} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(2)} MB`}import{Box as go,Text as yo}from"ink";import{Box as uo,Text as fo}from"ink";import{jsx as nr}from"react/jsx-runtime";var mo=[" :::::::: "," :::::: ::::::::::: "," :::::: :::::::::: "," :::::: :::::: ::::::: "," ::::: :::::: ::::::::::::::::: "," ::::: ::::: ::::::::::::::::::: "," ::::: ::::: :::::: ::::: ",":::: ::::: ::: ::::: :: ","::::: :::::: :::::::::: ","::::: :::::: ::::::::::: "," ::::: ::: ::::::: "," ::::::: ::: ::::: "," ::::::::::: :::::: :::::"," :::::::::: :::::: :::::"," :: ::::: ::: ::::: ::::"," ::::: :::::: ::::: ::::: ::: "," ::::::::::::::::::: ::::: ::::: "," ::::::::::::::::: ::::: ::::: "," ::::::::: :::::: :::::: "," :::::::::: :::::: "," ::::::::::: :::::: "," :::::::: "],or=()=>nr(uo,{flexDirection:"column",children:mo.map((e,t)=>nr(fo,{color:"cyan",children:e},t))});import{Fragment as ho,jsx as _t,jsxs as xo}from"react/jsx-runtime";var q=({marginBottom:e=0})=>xo(ho,{children:[_t(or,{}),_t(go,{flexDirection:"column",marginTop:1,marginBottom:e,children:_t(yo,{bold:!0,color:"cyan",children:"Kizen App Development Toolkit"})})]});import{useEffect as bo,useState as vo}from"react";import{Text as wo}from"ink";import{jsx as Co}from"react/jsx-runtime";var ir=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],ue=()=>{let[e,t]=vo(0);return bo(()=>{let o=setInterval(()=>{t(n=>(n+1)%ir.length)},80);return()=>{clearInterval(o)}},[]),Co(wo,{color:"cyan",children:ir[e]??"\u280B"})};import{Box as It,Text as rt}from"ink";import{jsx as sr,jsxs as Ae}from"react/jsx-runtime";var So=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},nt=({issues:e})=>{let t=e.filter(o=>o.severity==="error").length;return Ae(It,{flexDirection:"column",marginTop:1,children:[Ae(rt,{color:"red",children:["\u2717 ",t," validation ",t===1?"error":"errors"]}),[...So(e)].map(([o,n])=>Ae(It,{flexDirection:"column",marginTop:1,children:[sr(rt,{bold:!0,children:o}),n.map((r,i)=>sr(It,{paddingLeft:2,children:Ae(rt,{color:r.severity==="error"?"red":"yellow",children:[r.severity==="error"?"\u2717":"\u26A0"," ",r.message," ",Ae(rt,{dimColor:!0,children:["(",r.rule,")"]})]})},`${r.rule}-${String(i)}`))]},o))]})};import{Fragment as Po,jsx as fe,jsxs as Te}from"react/jsx-runtime";var lr=["creating-dir","reading-files","validating","minifying","packaging","writing-bundle"],ot={"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"},cr=({outputDir:e,pluginDir:t})=>{let o=To(),[n,r]=Oe("creating-dir"),[i,p]=Oe(!1),[u,m]=Oe(null),[g,h]=Oe(null),[S,I]=Oe(null);ar(()=>{tt(t,e,r).then(({bundleSize:x})=>{I(x),r("done")}).catch(x=>{x instanceof Eo?m(x.issues):h(x instanceof Error?x.message:String(x)),p(!0),process.exitCode=1})},[e,t]),ar(()=>{(n==="done"||i)&&o.exit()},[n,i,o]);let v=lr.indexOf(n),c=n==="done";return Te(je,{flexDirection:"column",paddingY:1,paddingX:2,children:[fe(q,{marginBottom:1}),Te(je,{flexDirection:"column",gap:0,children:[lr.map((x,T)=>{let E=n===x,b=c||v>T;return fe(je,{gap:1,children:i&&T===v?Te(_e,{color:"red",children:["\u2717 ",ot[x]]}):b?Te(_e,{color:"green",children:["\u2713 ",ot[x]]}):E?Te(Po,{children:[fe(ue,{}),fe(_e,{children:ot[x]})]}):Te(_e,{dimColor:!0,children:[" ",ot[x]]})},x)}),c&&S!==null&&fe(je,{marginTop:1,gap:1,children:Te(_e,{color:"green",children:["\u2713 bundle \u2014 ",$e(S)]})}),u!==null&&fe(nt,{issues:u}),g!==null&&fe(je,{marginTop:1,borderStyle:"single",borderColor:"red",paddingX:1,children:fe(_e,{color:"red",children:g})})]})]})};import*as Ie from"fs";import*as dr from"path";function Ne(e){let t=dr.join(e,".gitignore"),o=".kizenapp/",n="";if(Ie.existsSync(t)){n=Ie.readFileSync(t,"utf8");let i=n.split(`
3
+ `).map(p=>p.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}=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
7
+ `;Ie.writeFileSync(t,n+r)}function pr(e){e.command("build").description("Bundle the plugin app into .kizenapp directory").action(async()=>{let t=process.cwd(),o=`${t}/.kizenapp`;Ne(t);let{waitUntilExit:n}=_o(ko(cr,{outputDir:o,pluginDir:t}));await n()})}import{createElement as zo}from"react";import{render as Mo}from"ink";import{useCallback as st,useState as ze}from"react";import{Box as U,Text as R,useApp as Bo,useInput as Ro}from"ink";import{join as Ft}from"path";import{access as Io,mkdir as Nt,writeFile as No}from"fs/promises";import{join as Ee}from"path";async function it(e){try{return await Io(e),!0}catch{return!1}}async function ur(e){return await it(Ee(e,"kizen.json"))?"has-manifest":await it(Ee(e,".kizenapp"))?"has-kizenapp":"ok"}async function fr(e,t){let o=Ee(e,t);if(!await it(o))return o;for(let n=1;n<1e3;n++){let r=Ee(e,`${t}-${String(n)}`);if(!await it(r))return r}throw new Error(`Could not find an available directory name for "${t}"`)}function Bt(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 mr(e){await Nt(e.targetDir,{recursive:!0});let t=Bt(e);await No(Ee(e.targetDir,"kizen.json"),JSON.stringify(t,null,2)+`
8
+ `,"utf-8"),await Nt(Ee(e.targetDir,"src"),{recursive:!0}),await Nt(Ee(e.targetDir,"releaseNotes"),{recursive:!0}),Ne(e.targetDir)}var me=["name","apiName","externalLink","description","developerBusinessId"],Rt={name:"Name",apiName:"API name",externalLink:"External link",description:"Description",developerBusinessId:"Business ID"},Dt=["name","apiName"];function gr(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")}function yr(e){return{name:"",apiName:"",externalLink:"",description:"",developerBusinessId:e}}function hr(e,t){if(Dt.includes(e)&&!t.trim())return`${Rt[e]} is required`}function xr(e,t){return e==="description"?t:t.trim()}import{jsx as B,jsxs as z}from"react/jsx-runtime";var Be=({text:e})=>B(R,{dimColor:!0,children:e}),br=({parentDir:e,defaultBusinessId:t})=>{let o=Bo(),[n,r]=ze({type:"target-select",cursor:0}),[i,p]=ze("in-place"),[u,m]=ze(()=>yr(t)),[g,h]=ze(""),[S,I]=ze(e),v=st((E,b)=>{p(E),h(b.name),r({type:"field-entry",field:0,values:b})},[]),c=st(async E=>{let b=await ur(E);if(b!=="ok"){r({type:"precheck-error",targetDir:E,reason:b});return}I(E),v("in-place",u)},[u,v]),x=st(async E=>{try{let b=await fr(e,E.apiName);I(b),r({type:"confirm",values:E})}catch(b){r({type:"error",message:b instanceof Error?b.message:String(b)})}},[e]),T=st(async(E,b)=>{try{await mr({targetDir:b,name:E.name,apiName:E.apiName,externalLink:E.externalLink,description:E.description,developerBusinessId:E.developerBusinessId}),r({type:"done",targetDir:b})}catch(w){r({type:"error",message:w instanceof Error?w.message:String(w)})}},[]);if(Ro((E,b)=>{if(b.ctrl&&E==="c"){o.exit();return}if(n.type==="target-select"){b.upArrow?r({type:"target-select",cursor:0}):b.downArrow?r({type:"target-select",cursor:1}):b.return?n.cursor===0?c(e):v("sub-dir",u):b.escape&&o.exit();return}if(n.type==="precheck-error"){(b.return||b.escape)&&o.exit();return}if(n.type==="field-entry"){let{field:w,values:P}=n,f=me[w];if(!f)return;if(b.escape){o.exit();return}if(b.backspace||b.delete){h(l=>l.slice(0,-1));return}if(b.upArrow&&w>0){let l={...P,[f]:g},s=w-1,a=me[s];r({type:"field-entry",field:s,values:l}),m(l),h(a?l[a]:"");return}if(b.return||b.tab||b.downArrow){let l=hr(f,g);if(l!==void 0){r({type:"field-entry",field:w,values:P,fieldError:l});return}let s=xr(f,g),a={...P,[f]:s};m(a);let d=w+1;if(d>=me.length)h(""),i==="sub-dir"?(r({type:"resolving-target"}),x(a)):r({type:"confirm",values:a});else{let y=me[d],N=y?a[y]:"",k=y==="apiName"&&!N?gr(a.name):N;r({type:"field-entry",field:d,values:a}),h(k)}return}E&&!b.ctrl&&!b.meta&&h(l=>l+E);return}if(n.type==="confirm"){if(b.escape){let w=me.length-1,P=me[w];r({type:"field-entry",field:w,values:n.values}),h(P?n.values[P]:"");return}b.return&&(r({type:"writing"}),T(n.values,S));return}(n.type==="done"||n.type==="error")&&(b.return||b.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(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(U,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Where should the new plugin live?"}),E.map((b,w)=>{let P=n.cursor===w;return z(U,{gap:2,children:[B(R,{...P&&{color:"cyan"},children:P?"\u276F":" "}),B(R,{bold:P,...P&&{color:"cyan"},children:b.label}),B(R,{dimColor:!0,children:b.desc})]},b.label)})]}),B(Be,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel"})]})}if(n.type==="precheck-error"){let{targetDir:E,reason:b}=n;return z(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),B(R,{color:"red",bold:!0,children:"Cannot create plugin"}),z(U,{flexDirection:"column",gap:0,children:[z(R,{children:[E," already contains ",B(R,{bold:!0,children:b==="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(Be,{text:"Enter or Esc to exit"})]})}if(n.type==="field-entry"){let{field:E,fieldError:b}=n,w=i==="sub-dir"?`Target: sub-directory of ${e} (inferred from API name)`:`Target: ${S}`;return z(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(U,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Plugin details"}),B(R,{dimColor:!0,children:w})]}),b!==void 0&&z(R,{color:"red",children:["Error: ",b]}),B(U,{flexDirection:"column",gap:0,children:me.map((P,f)=>{let l=E===f,s=l?g:u[P],a=Dt.includes(P),d=`${Rt[P]}${a?"":" (optional)"}`;return z(U,{gap:2,children:[B(U,{width:24,children:B(R,{bold:l,...l&&{color:"cyan"},children:d})}),B(R,{...l&&{color:"cyan"},children:">"}),B(R,{children:s}),l&&B(R,{color:"cyan",children:"\u2588"})]},P)})}),B(Be,{text:"Enter/Tab/\u2193 next \xB7 \u2191 previous \xB7 Backspace delete \xB7 Esc cancel"})]})}if(n.type==="confirm"){let E=Bt({targetDir:S,name:n.values.name,apiName:n.values.apiName,externalLink:n.values.externalLink,description:n.values.description,developerBusinessId:n.values.developerBusinessId});return z(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(U,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"Ready to create"}),z(R,{dimColor:!0,children:["Target: ",S]})]}),z(U,{flexDirection:"column",gap:0,children:[B(R,{bold:!0,children:"kizen.json preview"}),B(R,{children:JSON.stringify(E,null,2)})]}),z(U,{flexDirection:"column",gap:0,children:[B(R,{dimColor:!0,children:"Also creates:"}),z(R,{dimColor:!0,children:[" ",Ft(S,"src/")]}),z(R,{dimColor:!0,children:[" ",Ft(S,"releaseNotes/")]}),z(R,{dimColor:!0,children:[" ",Ft(S,".gitignore")," (adds .kizenapp/)"]})]}),B(Be,{text:"Enter to create \xB7 Esc to go back"})]})}return n.type==="resolving-target"?B(U,{paddingY:1,paddingX:2,children:B(R,{dimColor:!0,children:"Finding available sub-directory\u2026"})}):n.type==="writing"?B(U,{paddingY:1,paddingX:2,children:B(R,{dimColor:!0,children:"Creating plugin\u2026"})}):n.type==="done"?z(U,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[B(q,{}),z(R,{color:"green",bold:!0,children:["Plugin created at ",n.targetDir]}),z(U,{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(Be,{text:"Enter or Esc to exit"})]}):z(U,{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(Be,{text:"Enter or Esc to exit"})]})};import{mkdir as vr,readFile as Do,readdir as Fo,writeFile as wr}from"fs/promises";import{homedir as Lo}from"os";import{dirname as $o,join as at}from"path";var re=["go","fmo","staging","integration","test1"];var Pe=at(Lo(),".kizenappbuilder"),Re=at(Pe,"credentials.json"),ge="credentials";function Ao(e){return re.includes(e)}function Oo(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:Ao(o)?o:"go"}}async function ye(e){let t=await Do(e,"utf-8");return Oo(JSON.parse(t))}async function Y(){try{return await ye(Re)}catch{return null}}async function jo(e){await vr($o(Re),{recursive:!0,mode:448}),await wr(Re,JSON.stringify(e,null,2),{encoding:"utf-8",mode:384})}function Cr(e){return at(Pe,`${e}.json`)}async function ke(){let e=[{name:ge,path:Re,isDefault:!0}];try{let t=await Fo(Pe);for(let o of t){if(!o.endsWith(".json"))continue;let n=o.slice(0,-5);n!==ge&&e.push({name:n,path:at(Pe,o),isDefault:!1})}}catch{}return e}async function Sr(e,t){if(e===ge){await jo(t);return}await vr(Pe,{recursive:!0,mode:448}),await wr(Cr(e),JSON.stringify(t,null,2),{encoding:"utf-8",mode:384})}async function le(e){try{return await ye(Cr(e))}catch{return null}}function Tr(e){e.command("create").description("Scaffold a new Kizen plugin project").action(async()=>{let t=process.cwd(),n=(await Y())?.businessId??"",{waitUntilExit:r}=Mo(zo(br,{parentDir:t,defaultBusinessId:n}),{exitOnCtrlC:!1});await r()})}import{createElement as nn}from"react";import{render as on}from"ink";import{useCallback as De,useEffect as mt,useRef as ce,useState as X}from"react";import{Box as W,Text as D,useInput as $i}from"ink";import{PluginValidationError as Ai}from"@kizenapps/packager";import{watch as Oi}from"fs";import{createServer as ji}from"http";import{join as en}from"path";import{WebSocketServer as zi}from"ws";import{createReadStream as jr,realpathSync as ii}from"fs";import{access as si,readdir as ai,readFile as li,realpath as ci,stat as zr}from"fs/promises";import{dirname as di,extname as Mr,join as Je,resolve as pi,sep as Ut}from"path";import{fileURLToPath as ui}from"url";var Ho=new Set(["set-cookie","strict-transport-security","content-security-policy","content-security-policy-report-only","x-frame-options","content-encoding","content-length"]);function lt(e){let t={};for(let[o,n]of Object.entries(e)){let r=o.toLowerCase();Ho.has(r)||r.startsWith("access-control-")||(t[o]=n)}return t}var Lt=10*1024*1024,Vo=6e4,Uo=200,Me=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 $t(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 Me(r,t);n.push(i)}return Buffer.concat(n)}async function Er(e){let t=lt(Object.fromEntries(e.headers)),o=await $t(e,Lt);return{status:e.status,headers:t,body:o}}function Pr(e={}){let{onChange:t,enabled:o=!0}=e;if(!o)return{async get(p,u){return{response:await Er(await u()),fromCache:!1}},clear(){}};let n=new Map,r=()=>{t?.(n.size)},i=p=>{n.delete(p)&&r()};return{get(p,u){let m=n.get(p);if(m!==void 0){if(Date.now()-m.insertedAt<Vo)return m.promise.then(h=>({response:h,fromCache:!0}));i(p)}if(n.size>=Uo){let h=n.keys().next().value;h!==void 0&&i(h)}let g=u().then(Er).catch(h=>{throw i(p),h});return n.set(p,{insertedAt:Date.now(),promise:g}),r(),g.then(h=>((h.status<200||h.status>=300)&&i(p),{response:h,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 qo,readFile as Jo,writeFile as Wo}from"fs/promises";import{join as kr}from"path";async function he(e){try{let t=await Jo(kr(e,"config.json"),"utf-8");return JSON.parse(t)}catch{return{}}}async function xe(e,t){await qo(e,{recursive:!0}),await Wo(kr(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 He(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 Br,rm as Mt,mkdtemp as Ko,access as Yo}from"fs/promises";import{join as Ue}from"path";import{tmpdir as Xo}from"os";var _r=`awslambdaric
9
9
  bcrypt
10
10
  fpdf2
11
11
  lxml
@@ -22,7 +22,8 @@ pytz
22
22
  requests
23
23
  sqlalchemy>=2.0,<2.1
24
24
  tzdata
25
- `;var Fo=`
25
+ `;function Ir(e){return e.split(`
26
+ `).map(t=>t.trim().replace(/\s+#.*$/,"")).filter(t=>t.length>0&&!t.startsWith("#"))}function Nr(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"}var Zo=`
26
27
  import sys, json, os, traceback
27
28
 
28
29
  # --- Inputs proxy (attribute access) ---
@@ -182,24 +183,23 @@ sys.stdout.write('\\n__KIZEN_RESULT_START__\\n')
182
183
  sys.stdout.write(json.dumps(result, ensure_ascii=False))
183
184
  sys.stdout.write('\\n__KIZEN_RESULT_END__\\n')
184
185
  sys.stdout.flush()
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(`
186
+ `.trim(),Qo=3e4,ct=Ue(process.cwd(),".kizenapp","venv"),Dr=["python-3-12","python-3-13"];function ei(e){return Dr.includes(e)}var Fr=Ir(_r);if(Fr.length===0)throw new Error("python-requirements.txt bundled no packages \u2014 check the build output");var Ve=null,qe=[3,10];function Lr([e,t]){return e>qe[0]||e===qe[0]&&t>=qe[1]}function jt(e){return`${String(e[0])}.${String(e[1])}`}function $r(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 ti(e){let t=Nr(e),o=t==="python3"?["python3"]:[t,"python3"],n=[];for(let r of o){let i=await $r(r);if(!i){n.push(`${r}: not found`);continue}if(Lr(i))return r;n.push(`${r}: ${jt(i)} (too old)`)}throw new Error(`No Python >= ${jt(qe)} found for runtime "${e}". The local runner needs Python ${jt(qe)}+ 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 Rr(e,t,o){return new Promise((n,r)=>{let i=Ht(e,t,{stdio:["ignore","pipe","pipe"]}),p=(m,g)=>{let h=[],S="";return m.on("data",I=>{S+=I.toString("utf-8");let v=S.indexOf(`
187
+ `);for(;v>=0;){let c=S.slice(0,v).replace(/\r$/,"");S=S.slice(v+1),h.push(c),o?.(c,g),v=S.indexOf(`
188
+ `)}}),m.on("end",()=>{if(S.length>0){let I=S.replace(/\r$/,"");h.push(I),o?.(I,g)}}),h},u=p(i.stderr,"stderr");p(i.stdout,"stdout"),i.on("error",r),i.on("close",m=>{if(m===0)n();else{let g=u.slice(-10).join(`
189
+ `).trim(),h=g.length>0?`: ${g}`:"";r(new Error(`${e} exited with code ${String(m)}${h}`))}})})}var zt=null;function ri(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 p of o)p(i)},r=Ue(ct,"bin","python");return Ve=(async()=>{try{let i=!1;try{await Yo(r);let p=await $r(r);i=p!==null&&Lr(p)}catch{i=!1}if(!i){await Mt(ct,{recursive:!0,force:!0}).catch(()=>{});let p=await ti(e);await Rr(p,["-m","venv",ct])}return n({kind:"start"}),await Rr(r,["-m","pip","install","--disable-pip-version-check",...Fr],(p,u)=>{n({kind:"log",line:p,stream:u})}),n({kind:"complete"}),r}catch(i){let p=i instanceof Error?i.message:String(i);throw n({kind:"error",message:p}),Ve=null,await Mt(ct,{recursive:!0,force:!0}).catch(()=>{}),i}finally{zt=null}})(),Ve}function ni(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(),p=e.slice(n+t.length,r).trim();try{let u=JSON.parse(p);return{userStdout:i,result:u}}catch{return{userStdout:e,result:null}}}function oi(e){return{success:!1,outputValues:{},logs:[],stdout:"",stderr:"",error:e,exitCode:1,durationMs:0}}async function Ar(e){let t=e.timeout??Qo;if(!ei(e.scriptRuntime))return oi(`Unsupported runtime "${e.scriptRuntime}". Supported runtimes: ${Dr.join(", ")}. Update the step's config.json "runtime" field (e.g. "python 3.13").`);let o=await ri(e.scriptRuntime,e.onInstallProgress),n=Date.now(),r;try{r=await Ko(Ue(Xo(),"kizen-step-"));let i=Ue(r,"wrapper.py"),p=Ue(r,"script.py");await Promise.all([Br(i,Zo,"utf-8"),Br(p,e.script,"utf-8")]);let u={...process.env,__KIZEN_INPUTS__:JSON.stringify(e.inputs),__KIZEN_SECRETS__:JSON.stringify(e.secrets),__KIZEN_SCRIPT_PATH__:p},{exitCode:m,stdout:g,stderr:h}=await new Promise(x=>{let T=[],E=[],b=!1,w=Ht(o,[i],{env:u,cwd:r,stdio:["ignore","pipe","pipe"]}),P=setTimeout(()=>{w.kill("SIGKILL")},t);w.stdout.on("data",l=>{T.push(l)}),w.stderr.on("data",l=>{E.push(l)});let f=l=>{b||(b=!0,clearTimeout(P),x({exitCode:l??1,stdout:Buffer.concat(T).toString("utf-8"),stderr:Buffer.concat(E).toString("utf-8")}))};w.on("close",f),w.on("error",l=>{b||(b=!0,clearTimeout(P),x({exitCode:1,stdout:"",stderr:l.message}))})}),S=Date.now()-n,{userStdout:I,result:v}=ni(g);if(v){let x={success:v.success,outputValues:v.outputValues,logs:v.logs,stdout:I,stderr:h,exitCode:m,durationMs:S};return v.error!==null&&(x.error=v.error),v.httpRequests&&(x.httpRequests=v.httpRequests),x}let c={success:!1,outputValues:{},logs:[],stdout:I,stderr:h,exitCode:m,durationMs:S};return m!==0&&(c.error=`Process exited with code ${String(m)}`),c}finally{r&&Mt(r,{recursive:!0,force:!0})}}var Or=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 Hr,CRYPTO_VERSION as Vr,deserializeEnvelope as fi,encrypt as mi,serializeEnvelope as gi}from"@kizenapps/packager";function Vt(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 yi=2*1024*1024,hi=new Set([".DS_Store",".gitignore"]);function xi(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 Wr=["kizen.com","kizen.dev"];function bi(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:Wr.some(n=>o===n||o.endsWith("."+n))}function vi(e){let t;try{t=new URL(e)}catch{return!1}if(t.protocol!=="https:")return!1;let o=t.hostname.toLowerCase();return Wr.some(n=>o===n||o.endsWith("."+n))}function wi(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 Ur(e,t){if(t.includes("\0"))return null;let o=t.replace(/^\/+/,""),n=pi(e,o);if(n!==e&&!n.startsWith(e+Ut))return null;try{let r=await ci(n);return r!==e&&!r.startsWith(e+Ut)?null:r}catch{return null}}function qr(e,t){let o=t===e?"":t.slice(e.length+1);return o===""?!1:o.split(Ut).some(r=>Qe.has(r))}function Gr(){let e=ui(import.meta.url);return Je(di(e),"viewer")}function Jr(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 si(e),!0}catch{return!1}}function Kr(e,t,o,n,r,i,p,u,m,g,h){let S=Pr({onChange:u,enabled:h}),I=ii(g);return(v,c)=>{(async()=>{let x=v.url??"/";try{if(!xi(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")&&!wi(v.headers.origin)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Forbidden"}));return}if(t(`Received request: ${x}`),x==="/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(x==="/api/credential-profiles"&&v.method==="GET"){let l=await ke();c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({profiles:l,active:r.current}));return}if(x==="/api/credentials/switch"&&v.method==="POST"){let l=[];for await(let y of v)l.push(y);let a=JSON.parse(Buffer.concat(l).toString("utf-8")||"{}").profile,d=a===void 0||a===""?await Y():await le(a);if(d!==null){n.current=d,r.current=a??void 0;let y=r.current,N=await he(i);await xe(i,{...N,credentialMode:"global",...y!==void 0&&{activeCredentialProfile:y}}),p({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(x==="/api/bundle"){let l=Je(process.cwd(),".kizenapp","bundle.json");try{let s=await li(l,"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(x==="/api/last-path"&&v.method==="POST"){let l=[];for await(let a of v)l.push(a);let s=JSON.parse(Buffer.concat(l).toString("utf-8")||"{}");if(typeof s.path=="string"){m.current=s.path;let a=await he(i);await xe(i,{...a,lastPath:s.path})}c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(x==="/api/encryption-target"&&v.method==="GET"){let s=(await he(i)).encryptionTarget==="dev"?"dev":"prod";c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({target:s}));return}if(x==="/api/encryption-target"&&v.method==="POST"){let l=[];for await(let y of v)l.push(y);let s=JSON.parse(Buffer.concat(l).toString("utf-8")||"{}"),a=s!==null&&typeof s=="object"?s:{};if(a.target!=="dev"&&a.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 he(i);await xe(i,{...d,encryptionTarget:a.target}),c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end('{"ok":true}');return}if(x==="/api/execute-step"&&v.method==="POST"){let l=[];for await(let y of v)l.push(y);let s=JSON.parse(Buffer.concat(l).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 a={script:s.script,scriptRuntime:s.scriptRuntime??"python-3-13",inputs:s.inputs??{},secrets:s.secrets??{},onInstallProgress:y=>{y.kind==="start"?p({type:"venv-install-start"}):y.kind==="log"?p({type:"venv-install-log",line:y.line,stream:y.stream}):y.kind==="complete"?p({type:"venv-install-complete"}):p({type:"venv-install-error",message:y.message})}};typeof s.timeout=="number"&&s.timeout>0&&(a.timeout=Math.min(s.timeout,300*1e3));let d=await Ar(a);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify(d));return}if(x==="/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(x==="/api/local/encrypt"&&v.method==="POST"){let l=[];for await(let a of v)l.push(a);let s=JSON.parse(Buffer.concat(l).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 a=mi(s.value,s.publicKeyPem),d=gi(a);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify(d))}catch(a){c.writeHead(400,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:a.message}))}return}if(x==="/api/local/validate"&&v.method==="POST"){let l=[];for await(let k of v)l.push(k);let s=JSON.parse(Buffer.concat(l).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 a,d;try{a=fi(s.value)}catch(k){d=k.message}if(d!==void 0||a===void 0){c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({valid:!1,checks:[],error:d}));return}let y=k=>Buffer.from(k,"base64").length,N=[{label:"Version",expected:String(Vr),actual:String(a.v),pass:a.v===Vr},{label:"Algorithm",expected:Hr,actual:a.alg,pass:a.alg===Hr},{label:"Wrapped key",expected:"384 bytes (RSA-3072)",actual:`${String(y(a.k))} bytes`,pass:y(a.k)===384},{label:"IV",expected:"12 bytes",actual:`${String(y(a.iv))} bytes`,pass:y(a.iv)===12},{label:"Auth tag",expected:"16 bytes",actual:`${String(y(a.tag))} bytes`,pass:y(a.tag)===16},{label:"Ciphertext",expected:"\u2265 1 byte",actual:`${String(y(a.ct))} bytes`,pass:y(a.ct)>=1}];c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({valid:N.every(k=>k.pass),checks:N}));return}if(x.startsWith("/api/wizard")){let l=v.headers["x-encryption-target"],a=(Array.isArray(l)?l[0]:l)==="dev"?"dev":"prod",d=He(a);if(!bi(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 y=x.slice(11)||"/",N=`${d}${y}`,k=v.method??"GET",A=[];for await(let we of v)A.push(we);let{host:M,"x-encryption-target":K,...Q}=v.headers,ne=A.length>0?Buffer.concat(A):void 0,oe=ne&&ne.length>0?ne:void 0,ee;try{ee=await fetch(N,{method:k,headers:Q,...oe!==void 0&&{body:oe}})}catch(we){let vt=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:vt}));return}let Z=lt(Object.fromEntries(ee.headers)),Fe=await ee.arrayBuffer();c.writeHead(ee.status,Z),c.end(Buffer.from(Fe));return}if(x.startsWith("/api/proxy")){let l=v.headers["x-proxy-target"];if(typeof l!="string"){c.writeHead(400),c.end("Missing x-proxy-target header");return}if(!vi(l)){c.writeHead(400),c.end("Invalid proxy target");return}let s=x.slice(10)||"/",a=`${l}${s}`,d=v.method??"GET",y=[];for await(let ee of v)y.push(ee);let{host:N,"x-proxy-target":k,...A}=v.headers;if(d==="GET"){let ee=`GET::${a}`,{response:Z,fromCache:Fe}=await S.get(ee,()=>fetch(a,{method:"GET",headers:A}));o({kind:"request",method:"GET",status:Z.status,upstreamStatus:Jr(s,Z.headers,Z.body),fromCache:Fe,url:s}),c.writeHead(Z.status,Z.headers),c.end(Z.body);return}let M=y.length>0?Buffer.concat(y):void 0,K=M&&M.length>0?M:void 0,Q=await fetch(a,{method:d,headers:A,...K!==void 0&&{body:K}}),ne=lt(Object.fromEntries(Q.headers)),oe=await $t(Q,Lt);o({kind:"request",method:d,status:Q.status,upstreamStatus:Jr(s,ne,oe),fromCache:!1,url:s}),c.writeHead(Q.status,ne),c.end(oe);return}if(x.startsWith("/api/source/tree")&&v.method==="GET"){let s=new URL(x,"http://localhost").searchParams.get("path")??"",a=await Ur(I,s);if(a===null){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Invalid path"}));return}if(qr(I,a)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Path is excluded"}));return}try{let d=await ai(a,{withFileTypes:!0}),y=await Promise.all(d.filter(k=>k.isDirectory()?!Qe.has(k.name):k.isFile()?!hi.has(k.name):!1).map(async k=>{let A=k.isDirectory()?"dir":"file",M={name:k.name,kind:A};if(A==="file")try{let K=await zr(Je(a,k.name));M.size=K.size}catch{}return M}));y.sort((k,A)=>k.kind!==A.kind?k.kind==="dir"?-1:1:k.name.localeCompare(A.name));let N=a===I?"":a.slice(I.length+1);c.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({path:N,entries:y}))}catch(d){let y=d instanceof Error?d.message:String(d);t(`source/tree failed (${s}): ${y}`),c.writeHead(404,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not found"}))}return}if(x.startsWith("/api/source/file")&&v.method==="GET"){let s=new URL(x,"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 a=await Ur(I,s);if(a===null){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Invalid path"}));return}if(qr(I,a)){c.writeHead(403,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Path is excluded"}));return}try{let d=await zr(a);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>yi){c.writeHead(413,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"File too large",size:d.size}));return}let y=Mr(a).toLowerCase(),N=At[y],k=Or.has(y),A=N??(k?"text/plain; charset=utf-8":"application/octet-stream");c.writeHead(200,{"Content-Type":A,"Content-Length":String(d.size)}),jr(a).pipe(c)}catch(d){let y=d instanceof Error?d.message:String(d);t(`source/file failed (${s}): ${y}`),c.writeHead(404,{"Content-Type":"application/json; charset=utf-8"}),c.end(JSON.stringify({error:"Not found"}))}return}let b=Je(e,x==="/"?"/index.html":x),w=await qt(b)?b:Je(e,"index.html"),P=Mr(w),f=At[P]??"application/octet-stream";c.writeHead(200,{"Content-Type":f}),jr(w).pipe(c)}catch(T){if(x.startsWith("/api/proxy")){let E=x.slice(10)||"/",b=v.method??"GET";T instanceof Me?o({kind:"info",message:`${b} ${E} \u2192 502 (response exceeded ${String(T.limit)} bytes)`}):o({kind:"request",method:b,status:502,fromCache:!1,url:E})}else o({kind:"info",message:`Error handling ${x}: ${T instanceof Error?T.message:String(T)}`});c.headersSent||(c.writeHead(502),c.end("Bad Gateway"))}})()}}import{launch as Ci}from"chrome-launcher";import{createRequire as Si}from"module";import{mkdirSync as Ti}from"fs";import{readFile as Ei}from"fs/promises";import{dirname as Pi,join as ki}from"path";import{fileURLToPath as _i}from"url";var Yr=Si(import.meta.url)("chrome-remote-interface"),Ii=new Set(["content-security-policy","content-security-policy-report-only","x-frame-options"]),Zr=["kizen.dev","kizen.com"];function Xr(e){try{let{hostname:t}=new URL(e);return Zr.some(o=>t===o||t.endsWith("."+o))}catch{return!1}}async function Ni(e){try{let t=ki(Pi(_i(import.meta.url)),"viewer","icon.png"),o=await Ei(t);await e.Browser.setDockTile({image:o.toString("base64")})}catch{}}async function Qr(e){Ti(e.userDataDir,{recursive:!0});let t=`http://localhost:${String(e.port)}`,o=await Ci({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,p=null,u=null,m=0,g=!1,h=w=>{e.debugLog?.(w)},S=w=>{e.verbose&&e.debugLog?.(w)},I=()=>{i!==null&&(clearInterval(i),i=null)},v=w=>w==="chrome://new-tab-page/"||w==="chrome://newtab/",c=async w=>{I(),p=null,await Ni(w),await w.Fetch.enable({patterns:Zr.flatMap(f=>[{urlPattern:`*://${f}/*`,requestStage:"Response"},{urlPattern:`*://*.${f}/*`,requestStage:"Response"}])}),w.on("Fetch.requestPaused",f=>{(async()=>{let l=f,{requestId:s,request:a,responseHeaders:d,responseStatusCode:y}=l,N=a.url;S(`Fetch ${String(y??"?")} ${N}`);let k=[],A=!1;for(let M of d??[])if(!Ii.has(M.name.toLowerCase()))if(M.name.toLowerCase()==="set-cookie"&&Xr(N)){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
- `);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
- `),t.out!==void 0)try{await cn(t.out,p),process.stderr.write(`Wrote encrypted envelope to ${t.out}
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(`
191
+ `);k.push({name:M.name,value:K}),A=!0}else k.push(M);A&&S(` rewrote Set-Cookie SameSite on ${N}`);try{let{body:M,base64Encoded:K}=await w.Fetch.getResponseBody({requestId:s});await w.Fetch.fulfillRequest({requestId:s,responseCode:y??200,responseHeaders:k,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(),l=0;for(let s of f){if(!Xr(`https://${s.domain??""}`)||s.sameSite==="None")continue;let a=s.domain??"",d=a.startsWith(".")?a.slice(1):a;await w.Network.setCookie({url:`https://${d}`,name:s.name,value:s.value,domain:a,path:s.path??"/",secure:!0,...s.httpOnly!==void 0&&{httpOnly:s.httpOnly},...s.expirationDate!==void 0&&{expires:s.expirationDate},sameSite:"None"}),l++}l>0&&S(`cookie-patch cycle: updated ${String(l)} cookie(s) to SameSite=None`)}catch(f){S(`cookie-patch cycle failed: ${f.message}`)}})()},2e3),await w.Target.setDiscoverTargets({discover:!0});let P=f=>{if(f.type==="page"){if(v(f.url)){h(`closed stray new-tab-page target ${f.targetId}`),p!==null&&w.Target.activateTarget({targetId:p}).catch(()=>{}),w.Target.closeTarget({targetId:f.targetId}).catch(()=>{});return}p===null&&(p=f.targetId,h(`captured main target ${f.targetId} (${f.url})`))}};w.on("Target.targetCreated",f=>{let{targetInfo:l}=f;S(`target +${l.type} ${l.targetId} ${l.url}`),P(l)}),w.on("Target.targetInfoChanged",f=>{let{targetInfo:l}=f;S(`target ~${l.type} ${l.targetId} ${l.url}`),P(l)}),w.on("disconnect",()=>{g||r!==w||(h("CDP disconnected"),r=null,I(),x())})},x=()=>{if(g||u!==null)return;let w=Math.min(1e3*2**m,1e4),P=m+1;m++,h(`CDP reconnect scheduled in ${String(w)}ms (attempt #${String(P)})`),u=setTimeout(()=>{u=null,(async()=>{let f;try{f=await Yr({port:n})}catch{h(`CDP reconnect attempt #${String(P)} failed`),x();return}if(g){try{await f.close()}catch{}return}r=f;try{await c(f),h(`CDP reconnected after ${String(P)} attempt(s)`),m=0}catch{r===f&&(r=null);try{await f.close()}catch{}h(`CDP reconnect attempt #${String(P)} failed during setup`),x()}})()},w)},T=30,E=300;for(let w=0;w<T;w++){await new Promise(P=>setTimeout(P,E)),h(`CDP connect attempt ${String(w+1)}/${String(T)}`);try{let P=await Yr({port:n});r=P,e.path&&P.send("Page.navigate",{url:`${t}${e.path}`});try{await c(P),h("CDP connected")}catch{r===P&&(r=null);try{await P.close()}catch{}h("CDP setup failed after connect")}break}catch{if(w===T-1){let P=`CDP unavailable after ${String(T)} attempts \u2014 viewer running without interception (CSP/cookie rewrites disabled)`;return h(P),e.onWarn?.(P),{kill:()=>{o.kill()}}}}}return r?{kill:()=>{if(h("CDP kill requested \u2014 tearing down"),g=!0,u!==null&&(clearTimeout(u),u=null),I(),r!==null){try{r.close()}catch{}r=null}o.kill()}}:{kill:()=>{o.kill()}}}import{useCallback as Bi,useState as Ri}from"react";function dt(e){let[t,o]=Ri([]),n=Bi(r=>{o(i=>[...i,`${new Date().toLocaleTimeString()}: ${r}`].slice(-e))},[e]);return[t,n]}import{useCallback as pt,useEffect as Jt,useState as ut}from"react";import{Box as V,Text as $,useInput as Di}from"ink";import{jsx as _,jsxs as J}from"react/jsx-runtime";var be=["apiKey","userId","businessId"],Fi={apiKey:"API Key",userId:"User ID",businessId:"Business ID"},We=({text:e})=>_($,{dimColor:!0,children:e}),ft=({initialMode:e,showProfileManager:t,onComplete:o,onCancel:n})=>{let[r,i]=ut(e==="global"&&!t?{type:"loading"}:e==="global"&&t?{type:"profile-loading"}:{type:"mode-select",cursor:0}),[p,u]=ut(""),[m,g]=ut(null),[h,S]=ut(void 0),I=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 a=await ke();i({type:"name-entry",nameBuffer:"",existingProfiles:a});return}S(f.isDefault?void 0:f.name),i({type:"loading"});let l=f.isDefault?await Y():await le(f.name),s=l?Math.max(0,re.indexOf(l.environment)):0;i({type:"creds-entry",field:0,values:l??{},envCursor:s})},[]),c=pt(async(f,l)=>{let s=re[l]??"go",a={apiKey:f.apiKey??"",userId:f.userId??"",businessId:f.businessId??"",environment:s};i({type:"saving"});try{await Sr(h??ge,a),o({mode:"global",credentials:a,...h!==void 0&&{profileName:h}})}catch(d){g(d instanceof Error?d.message:String(d)),i({type:"creds-entry",field:0,values:f,envCursor:l})}},[o,h]);Di((f,l)=>{if(l.ctrl&&f==="c"&&process.exit(0),l.escape){if((r.type==="creds-entry"||r.type==="name-entry")&&e==="global"&&t){i({type:"profile-loading"}),x();return}n?.();return}if(r.type==="mode-select"){if(l.upArrow)i({type:"mode-select",cursor:0});else if(l.downArrow)i({type:"mode-select",cursor:1});else if(l.return){let s=r.cursor===0?"global":"local";I(s)}return}if(r.type==="profile-select"){let{profiles:s,cursor:a}=r,d=s.length,y=s.length+1;if(l.upArrow)i({...r,cursor:(a-1+y)%y});else if(l.downArrow)i({...r,cursor:(a+1)%y});else if(l.return)if(a===d)i({type:"name-entry",nameBuffer:"",existingProfiles:s});else{let N=s[a]??s[0];N&&v(N)}return}if(r.type==="name-entry"){let{nameBuffer:s,existingProfiles:a}=r;if(l.backspace||l.delete)i({type:"name-entry",nameBuffer:s.slice(0,-1),existingProfiles:a});else if(l.return){let d=s.trim();if(!d){i({...r,nameError:"Name cannot be empty"});return}if(d===ge){i({...r,nameError:`"${ge}" is reserved`});return}if(a.some(y=>y.name===d)){i({...r,nameError:`Profile "${d}" already exists`});return}S(d),i({type:"creds-entry",field:0,values:{},envCursor:0}),u("")}else f&&!l.ctrl&&!l.meta&&i({type:"name-entry",nameBuffer:s+f,existingProfiles:a});return}if(r.type==="creds-entry"){let{field:s,values:a,envCursor:d}=r;if(s===be.length){l.leftArrow?i({...r,envCursor:(d-1+re.length)%re.length}):l.rightArrow?i({...r,envCursor:(d+1)%re.length}):l.upArrow?(i({...r,field:s-1}),u(a[be[s-1]]??"")):l.return&&c(a,d);return}let N=be[s];if(!N)return;if(l.backspace||l.delete)u(k=>k.slice(0,-1));else if(l.upArrow&&s>0){let k={...a,[N]:p},A=s-1;i({...r,field:A,values:k}),u(k[be[A]]??"")}else if(l.return||l.tab||l.downArrow){let k={...a,[N]:p},A=s+1;i({...r,field:A,values:k}),A<be.length?u(k[be[A]]??""):u("")}else f&&!l.ctrl&&!l.meta&&u(k=>k+f)}});let x=pt(async()=>{let f=await ke();i({type:"profile-select",profiles:f,cursor:0})},[]);if(Jt(()=>{r.type==="profile-loading"&&x()},[r.type,x]),Jt(()=>{e==="global"&&!t&&(async()=>{let f=await Y(),l=f?Math.max(0,re.indexOf(f.environment)):0;i({type:"creds-entry",field:0,values:f??{},envCursor:l})})()},[]),Jt(()=>{r.type==="creds-entry"&&r.field===0&&u(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 _(V,{paddingY:1,paddingX:2,children:_($,{dimColor:!0,children:f})})}if(r.type==="done")return null;if(r.type==="mode-select")return J(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(V,{flexDirection:"column",gap:0,children:[_($,{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((l,s)=>{let a=r.cursor===s;return J(V,{gap:2,children:[_($,{...a&&{color:"cyan"},children:a?"\u276F":" "}),_($,{bold:a,...a&&{color:"cyan"},children:l.label}),_($,{dimColor:!0,children:l.desc})]},l.mode)})]}),_(We,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to quit"})]});if(r.type==="profile-select"){let{profiles:f,cursor:l}=r,s=f.length;return J(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(V,{flexDirection:"column",gap:0,children:[_($,{bold:!0,children:"Credential profiles"}),f.map((a,d)=>{let y=l===d;return J(V,{gap:2,children:[_($,{...y&&{color:"cyan"},children:y?"\u276F":" "}),_($,{bold:y,...y&&{color:"cyan"},children:a.isDefault?"Default":a.name}),_($,{dimColor:!0,children:a.path})]},a.name)}),J(V,{gap:2,children:[_($,{...l===s&&{color:"cyan"},children:l===s?"\u276F":" "}),_($,{bold:l===s,...l===s&&{color:"cyan"},children:"+ Add new profile"})]})]}),_(We,{text:"\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel"})]})}if(r.type==="name-entry"){let{nameBuffer:f,nameError:l}=r;return J(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),_(V,{flexDirection:"column",gap:0,children:_($,{bold:!0,children:"New credential profile"})}),l&&J($,{color:"red",children:["Error: ",l]}),J(V,{gap:2,children:[_(V,{width:12,children:_($,{bold:!0,color:"cyan",children:"Profile name"})}),_($,{color:"cyan",children:">"}),_($,{children:f}),_($,{color:"cyan",children:"\u2588"})]}),_(We,{text:"Type a name \xB7 Enter to confirm \xB7 Esc to go back"})]})}let{field:T,values:E,envCursor:b}=r,w=T===be.length,P=h??ge;return J(V,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[_(q,{}),J(V,{flexDirection:"column",gap:0,children:[_($,{bold:!0,children:h!==void 0?`Profile: ${h}`:"Global credentials"}),J($,{dimColor:!0,children:["Saved to:"," ",h!==void 0?`~/.kizenappbuilder/${h}.json`:Re]})]}),m&&J($,{color:"red",children:["Error: ",m]}),J(V,{flexDirection:"column",gap:0,children:[be.map((f,l)=>{let s=T===l,a=s?p:E[f]??"";return J(V,{gap:2,children:[_(V,{width:12,children:_($,{bold:s,...s&&{color:"cyan"},children:Fi[f]})}),_($,{...s&&{color:"cyan"},children:">"}),_($,{children:a}),s&&_($,{color:"cyan",children:"\u2588"})]},f)}),J(V,{gap:2,children:[_(V,{width:12,children:_($,{bold:w,...w&&{color:"cyan"},children:"Environment"})}),_($,{...w&&{color:"cyan"},children:">"}),_(V,{gap:1,children:re.map((f,l)=>{let s=l===b;return w?_($,{bold:s,...s&&{color:"cyan"},children:s?`[${f}]`:f},f):_($,{dimColor:!s,bold:s,children:f},f)})})]})]}),w?_(We,{text:"\u2190\u2192 to select \xB7 \u2191\u2193 to move \xB7 Enter to save \xB7 Esc to cancel"}):_(We,{text:"\u2191\u2193 to move \xB7 Backspace to delete \xB7 Esc to cancel"}),J($,{dimColor:!0,children:["Profile: ",P]})]})};import{jsx as F,jsxs as H}from"react/jsx-runtime";var Mi=[".kizenapp",".git"],tn=({port:e,pluginDir:t,outputDir:o,credentials:n,credentialMode:r,activeCredentialProfile:i,lastPath:p,debug:u=!1,verbose:m=!1,autoViewer:g=!0,cacheEnabled:h=!0})=>{let S=ce(n),I=ce(i),v=ce(p),[c,x]=X("main"),[T,E]=X(r),[b,w]=X("starting"),[P,f]=X(null),[l,s]=dt(50),[a,d]=dt(50),[y,N]=dt(50),[k,A]=X([]),[M,K]=X("pending"),[Q,ne]=X(null),[oe,ee]=X(null),[Z,Fe]=X(null),[we,vt]=X(null),[wt,Ct]=X(0),[Yt,Mn]=X(0),[Hn,Vn]=X(0),[St,Un]=X(0),Tt=ce(!1),Xt=ce(!1),Ke=ce(null),Le=ce(null),de=ce(new Set),Ye=ce([]),te=De(C=>{let j=JSON.stringify(C);if(de.current.size===0){Ye.current=[...Ye.current,j].slice(-50);return}let pe=!1;for(let ie of de.current)if(ie.readyState===1)try{ie.send(j)}catch{de.current.delete(ie),pe=!0}pe&&Ct(de.current.size)},[]),Xe=s,Et=De(()=>{Ke.current?.kill(),Ke.current=null,Qr({port:e,userDataDir:en(o,".chrome"),broadcast:te,onWarn:C=>{s(`\u26A0 ${C}`)},...v.current!==void 0&&{path:v.current},...u&&{debugLog:N},...m&&{verbose:!0}}).then(C=>{Ke.current=C})},[e,o,te,u,m,N,s]);mt(()=>{let C=()=>{Ke.current?.kill()};return process.on("exit",C),()=>{process.off("exit",C)}},[]),$i((C,j)=>{(C==="q"||j.ctrl&&C==="c")&&process.exit(0),C==="c"&&x("editing"),C==="v"&&Et()},{isActive:c==="main"}),mt(()=>{b!=="running"||Xt.current||!g||(Xt.current=!0,Et())},[b,g,Et]);let qn=De(C=>{S.current=C.credentials,I.current=C.profileName,x("main"),E(C.mode);let j=C.profileName;xe(o,{credentialMode:C.mode,...j!==void 0&&{activeCredentialProfile:j}}),te({type:"credentials-updated",credentials:C.credentials})},[o,te]),Zt=De(C=>{A(j=>[...j,`${new Date().toLocaleTimeString()}: ${Vt(C)}`].slice(-50)),C.kind==="request"&&(C.fromCache?Vn(j=>j+1):Un(j=>j+1)),te({type:"proxy-log",entry:C})},[te]),Ce=De(C=>{d(C),te({type:"log",message:C})},[d,te]),Pt=De(()=>{Tt.current||(Tt.current=!0,K("building"),ne(null),ee(null),Ce("Build started"),tt(t,o).then(({bundleSize:C})=>{Ce(`Build finished \u2014 bundle: ${$e(C)}`),K("done"),Fe(new Date),vt(C),Ce("Notifying viewers to reload"),te({type:"rebuild"})}).catch(C=>{C instanceof Ai?(ee(C.issues),ne(null)):(ne(C instanceof Error?C.message:String(C)),ee(null)),K("error")}).finally(()=>{Tt.current=!1}))},[t,o,Ce,te]);if(mt(()=>{Pt();let C=Oi(t,{recursive:!0},(j,pe)=>{if(!pe)return;let ie=pe.replace(/\\/g,"/");Mi.some(Ze=>ie.startsWith(Ze))||(Ce(`File change detected: ${pe}`),Le.current!==null&&clearTimeout(Le.current),Le.current=setTimeout(Pt,150))});return C.on("error",j=>{Ce(`File watcher error \u2014 rebuilds have stopped: ${j.message}`)}),()=>{C.close(),Le.current!==null&&clearTimeout(Le.current)}},[t,Pt,Ce]),mt(()=>{let C=Gr();qt(en(C,"index.html")).then(j=>{if(!j){f("Viewer not built. Run 'pnpm build:viewer' first."),w("error");return}let pe=Kr(C,Xe,Zt,S,I,o,te,Mn,v,t,h),ie=ji(pe),Ze=new zi({server:ie});return Ze.on("connection",Se=>{for(let Wn of Ye.current)Se.readyState===1&&Se.send(Wn);Ye.current=[],Xe("Viewer connected for live reload"),de.current.add(Se),Ct(de.current.size),Se.on("close",()=>{de.current.delete(Se),Ct(de.current.size)})}),ie.listen(e,"127.0.0.1",()=>{w("running"),Xe(`Server started on 127.0.0.1:${String(e)}`)}),ie.on("error",Se=>{f(Se.message),w("error")}),()=>{Ze.close(),ie.close()}})},[e,Xe,Zt,te,o,t,h]),c==="editing")return F(ft,{...T!==void 0&&{initialMode:T},showProfileManager:T==="global",onComplete:qn,onCancel:()=>{x("main")}});let kt=Z!==null?Math.round((Date.now()-Z.getTime())/1e3):null,Jn=kt===null?"":kt<5?" (just now)":` (${String(kt)}s ago)`,Qt=oe?.filter(C=>C.severity==="error").length??0;return H(W,{flexDirection:"column",paddingY:1,paddingX:2,children:[F(q,{marginBottom:1}),H(W,{flexDirection:"column",children:[H(W,{gap:2,marginBottom:0,children:[F(D,{bold:!0,dimColor:!0,children:"App Build"}),M==="pending"&&F(D,{dimColor:!0,children:"waiting\u2026"}),M==="building"&&H(W,{gap:1,children:[F(ue,{}),F(D,{children:"Building plugin package\u2026"})]}),M==="done"&&H(W,{gap:1,children:[F(D,{color:"green",children:"\u2713 Built"}),Z!==null&&H(D,{dimColor:!0,children:["at ",Z.toLocaleTimeString(),Jn]}),we!==null&&H(D,{dimColor:!0,children:["\xB7 bundle: ",$e(we)]})]}),M==="error"&&(oe!==null?H(D,{color:"red",children:["\u2717 ",Qt," validation ",Qt===1?"error":"errors"]}):H(D,{color:"red",children:["\u2717 ",Q??"unknown error"]}))]}),oe!==null&&F(nt,{issues:oe}),F(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:a.slice(-8).map((C,j)=>F(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[F(D,{bold:!0,dimColor:!0,children:"Web Server"}),b==="starting"&&F(D,{dimColor:!0,children:"starting\u2026"}),b==="running"&&H(W,{gap:2,children:[F(D,{color:"green",children:"\u2713 Running"}),H(D,{dimColor:!0,children:["\u25CF ",wt," viewer",wt!==1?"s":""]})]}),b==="error"&&H(D,{color:"red",children:["\u2717 ",P??"Server error"]})]}),F(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:l.slice(-8).map((C,j)=>F(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[F(D,{bold:!0,dimColor:!0,children:"Network Proxy"}),F(D,{color:"green",children:"\u2713 Active"}),F(D,{dimColor:!0,children:h?`\u25CF ${String(Yt)} key${Yt!==1?"s":""} in the network cache \xB7 ${String(Hn)} hit \xB7 ${String(St)} miss`:`\u25CF network cache disabled \xB7 ${String(St)} request${St!==1?"s":""}`})]}),F(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:k.length===0?F(D,{dimColor:!0,children:" No requests yet."}):k.slice(-8).map((C,j)=>F(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),u&&H(W,{marginTop:1,flexDirection:"column",children:[H(W,{gap:2,children:[F(D,{bold:!0,dimColor:!0,children:"CDP Debug"}),H(D,{dimColor:!0,children:["\u25CF ",y.length," event(s)"]})]}),F(W,{flexDirection:"column",height:10,borderStyle:"single",borderColor:"gray",overflow:"hidden",children:y.length===0?F(D,{dimColor:!0,children:" No CDP events yet."}):y.slice(-8).map((C,j)=>F(D,{dimColor:!0,wrap:"truncate",children:C},j))})]}),H(W,{marginTop:1,gap:1,children:[F(D,{dimColor:!0,children:"["}),F(D,{children:"q"}),F(D,{dimColor:!0,children:"] quit ["}),F(D,{children:"c"}),F(D,{dimColor:!0,children:"] credentials ["}),F(D,{children:"v"}),H(D,{dimColor:!0,children:["] ",wt===0?"open viewer":"relaunch viewer"]})]})]})};async function rn(e){return new Promise(t=>{let o=null,n=i=>{o?.(),t(i)},{unmount:r}=on(nn(ft,{...e!==void 0&&{initialMode:e},onComplete:n}),{exitOnCtrlC:!1});o=r})}function sn(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`;Ne(n);let i=null,p,u,{lastPath:m}=await he(r);if(t.credentials)i=await ye(t.credentials);else{let c=await he(r);if(c.credentialMode==="local")p="local";else if(c.credentialMode==="global"){if(p="global",u=c.activeCredentialProfile,u?(i=await le(u),i||(i=await Y(),u=void 0)):i=await Y(),!i){let x=await rn("global");i=x.credentials,u=x.profileName}}else{let x=await rn();i=x.credentials,p=x.mode,u=x.profileName;let T=x.profileName;await xe(r,{credentialMode:x.mode,...T!==void 0&&{activeCredentialProfile:T}})}}let g=t.verbose===!0,h=g||t.debug===!0,S=t.viewer!==!1,I=t.cache!==!1,{waitUntilExit:v}=on(nn(tn,{port:o,pluginDir:n,outputDir:r,credentials:i,...p!==void 0&&{credentialMode:p},...u!==void 0&&{activeCredentialProfile:u},...m!==void 0&&{lastPath:m},debug:h,verbose:g,autoViewer:S,cacheEnabled:I}),{exitOnCtrlC:!1});await v()})}import{createElement as os}from"react";import{render as is}from"ink";import{useCallback as yt,useEffect as un,useState as ht}from"react";import{Box as se,Text as O,useApp as Zi,useInput as Qi}from"ink";import{encrypt as Hi,serializeEnvelope as Vi}from"@kizenapps/packager";function Ui(e){let t=e;return t.code==="ECONNREFUSED"||t.cause?.code==="ECONNREFUSED"}function an(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 ln(e,t,o){try{return await fetch(`${e}${t}`,o)}catch(n){throw new Error(Ui(n)?`Plugin-wizard is not running at ${e}`:`Failed to reach plugin-wizard: ${n.message}`)}}async function cn(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 qi(e,t,o){let n=He(e.stage),r=await ln(n,"/get-public-key",{method:"POST",headers:an(t),body:JSON.stringify({api_name:o})}),i=await cn(r);if(!r.ok||typeof i.public_key!="string"){let p=typeof i.error=="string"?i.error:`HTTP ${String(r.status)}`;throw new Error(`Failed to fetch public key: ${p}`)}return i.public_key}function Ji(e,t){let o=Hi(t,e),n=Vi(o);if(typeof n.value!="string")throw new Error("Unexpected serialized envelope shape from @kizenapps/packager");return n.value}async function Wi(e,t,o,n){let r=He(e.stage),i=await ln(r,"/encrypt",{method:"POST",headers:an(t),body:JSON.stringify({api_name:o,value:n})}),p=await cn(i);if(!i.ok||p.encrypted!==!0||typeof p.value!="string"){let u=typeof p.error=="string"?p.error:`HTTP ${String(i.status)}`;throw new Error(`Encryption via plugin-wizard failed: ${u}`)}return p.value}async function gt(e,t,o,n,r){if(e.isRemote)return r?.("encrypting"),Wi(e,t,o,n);r?.("fetching-key");let i=await qi(e,t,o);return r?.("encrypting"),Ji(i,n)}import{spawn as Gi}from"child_process";import{platform as dn}from"process";function Ki(){return dn==="darwin"?[{cmd:"pbcopy",args:[]}]:dn==="win32"?[{cmd:"clip",args:[]}]:[{cmd:"wl-copy",args:[]},{cmd:"xclip",args:["-selection","clipboard"]},{cmd:"xsel",args:["--clipboard","--input"]}]}var Yi=2e3;function Xi(e,{cmd:t,args:o}){return new Promise(n=>{let r;try{r=Gi(t,o,{stdio:["pipe","ignore","ignore"]})}catch{n(!1);return}let i=r,p=!1;function u(g){p||(p=!0,clearTimeout(m),n(g))}let m=setTimeout(()=>{i.kill(),u(!1)},Yi);m.unref(),i.on("error",()=>{u(!1)}),i.on("close",g=>{u(g===0)}),i.stdin.on("error",()=>{u(!1)});try{i.stdin.end(e)}catch{u(!1)}})}async function pn(e){for(let t of Ki())if(await Xi(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}),fn=({ctx:e,stageDefaulted:t,credentialsPath:o,initialApiName:n,defaultApiName:r,initialValue:i,onDone:p})=>{let u=Zi(),[m,g]=ht({type:"loading"}),[h,S]=ht(null),[I,v]=ht(n??""),[c,x]=ht(i??""),T=yt(s=>{process.exitCode=1,g({type:"error",message:s instanceof Error?s.message:String(s)})},[]),E=yt(async(s,a,d)=>{try{let y=await gt(e,s,a,d,A=>{g(A==="fetching-key"?{type:"fetching-key"}:{type:"encrypting"})}),N=JSON.stringify({encrypted:!0,value:y},null,2);p?.(y);let k=await pn(N);g({type:"done",envelope:N,copied:k})}catch(y){T(y)}},[e,T,p]),b=yt((s,a,d)=>{if(a.trim()===""){g({type:"api-name-entry",buffer:r??""});return}if(d===""){g({type:"value-entry",buffer:""});return}E(s,a.trim(),d)},[r,E]),w=yt(async s=>{try{g({type:"loading"});let a=s.isDefault?await Y():await le(s.name);if(a===null)throw new Error(`Could not load credential profile: ${s.name}`);S(a),b(a,I,c)}catch(a){T(a)}},[I,c,b,T]);un(()=>{(async()=>{try{if(o!==void 0){let d;try{d=await ye(o)}catch(y){throw new Error(`Could not load credentials from ${o}: ${y instanceof Error?y.message:String(y)}`)}S(d),b(d,I,c);return}let s=await ke();if(s.length===0)throw new Error("No credential profiles found. Create ~/.kizenappbuilder/credentials.json first.");let[a]=s;if(s.length===1&&a!==void 0){let d=a.isDefault?await Y():await le(a.name);if(d===null)throw new Error(`Could not load credential profile: ${a.name}`);S(d),b(d,I,c);return}g({type:"profile-select",profiles:s,cursor:0})}catch(s){T(s)}})()},[]),un(()=>{(m.type==="done"||m.type==="error")&&u.exit()},[m,u]),Qi((s,a)=>{if(a.ctrl&&s==="c"){process.exitCode=130,u.exit();return}if(m.type==="profile-select"){let{profiles:d,cursor:y}=m;if(a.upArrow)g({...m,cursor:(y-1+d.length)%d.length});else if(a.downArrow)g({...m,cursor:(y+1)%d.length});else if(a.return){let N=d[y];N!==void 0&&w(N)}return}if(m.type==="api-name-entry"){let{buffer:d}=m;if(a.backspace||a.delete)g({type:"api-name-entry",buffer:d.slice(0,-1)});else if(a.return){let y=d.trim();if(y===""){g({type:"api-name-entry",buffer:d,error:"api_name cannot be empty"});return}v(y),h?b(h,y,c):T(new Error("Internal error: credentials were not loaded"))}else s&&!a.ctrl&&!a.meta&&g({type:"api-name-entry",buffer:d+s});return}if(m.type==="value-entry"){let{buffer:d}=m;if(a.backspace||a.delete)g({type:"value-entry",buffer:d.slice(0,-1)});else if(a.return){if(d===""){g({type:"value-entry",buffer:d,error:"secret cannot be empty"});return}x(d),h?b(h,I,d):T(new Error("Internal error: credentials were not loaded"))}else s&&!a.ctrl&&!a.meta&&g({type:"value-entry",buffer:d+s});return}});let P=e.isRemote?"remote Kizen API":"on-machine",f=t===!0?`${e.stage} (default)`:e.stage,l=s=>G(se,{flexDirection:"column",paddingY:1,paddingX:2,gap:1,children:[L(q,{}),G(O,{dimColor:!0,children:["Mode: ",P," Stage: ",f]}),s]});if(m.type==="loading")return l(G(se,{gap:1,children:[L(ue,{}),L(O,{dimColor:!0,children:"Loading credentials\u2026"})]}));if(m.type==="profile-select"){let{profiles:s,cursor:a}=m;return l(G(xt,{children:[L(O,{bold:!0,children:"Credential profile"}),L(se,{flexDirection:"column",children:s.map((d,y)=>{let N=a===y;return G(se,{gap:2,children:[L(O,{...N&&{color:"cyan"},children:N?"\u276F":" "}),L(O,{bold:N,...N&&{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 m.type==="api-name-entry"?l(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(Wt,{text:"Type the api_name \xB7 Enter to confirm \xB7 Ctrl+C to quit"})]})):m.type==="value-entry"?l(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(Wt,{text:"Input hidden \xB7 Enter to encrypt \xB7 Ctrl+C to quit"})]})):m.type==="fetching-key"?l(G(se,{gap:1,children:[L(ue,{}),G(O,{children:["Fetching ",e.stage," public key for ",L(O,{bold:!0,children:I}),"\u2026"]})]})):m.type==="encrypting"?l(G(se,{gap:1,children:[L(ue,{}),L(O,{children:"Encrypting\u2026"})]})):m.type==="error"?l(G(se,{gap:1,children:[L(O,{color:"red",children:"\u2717"}),L(O,{color:"red",children:m.message})]})):l(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})]}))};import{readFile as es,writeFile as ts}from"fs/promises";import{join as rs}from"path";function mn(e){return{encrypted:!0,value:e}}function gn(e){return JSON.stringify(mn(e))}async function Gt(e,t){await ts(e,`${JSON.stringify(mn(t),null,2)}
192
+ `,"utf-8")}var ns="prod";function yn(e){return e==="dev"||e==="prod"}function hn(e){return`Error: --stage must be "dev" or "prod" (got: "${e}")`}function xn(e){return{stage:e==="dev"||e==="prod"?e:ns,wasDefaulted:e===void 0}}function bn(e){return`No --stage given; defaulting to ${e} encryption keys (pass --stage dev to override)
193
+ `}async function vn(e=process.cwd()){try{let t=await es(rs(e,"kizen.json"),"utf-8"),o=JSON.parse(t),n=Array.isArray(o)?o[0]:o,r=typeof n.api_name=="string"&&n.api_name!==""?n.api_name:void 0;return{...r!==void 0&&{apiName:r}}}catch{}return{}}function wn(e){return e.replace(/[\r\n]+$/,"")}async function Cn(){let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString("utf-8")}async function Sn(e,t,o,n,r){let i=t.credentials!==void 0?await r.loadCredentialsFromFile(t.credentials):await r.loadGlobalCredentials();if(i===null)throw new Error("No credentials found. Pass --credentials or create ~/.kizenappbuilder/credentials.json.");let p=t.apiName??o.apiName;if(p===void 0||p.trim()==="")throw new Error("api_name is required in non-interactive mode. Pass --api-name or run inside a plugin directory.");n&&r.writeStderr(bn(e.stage));let u=t.value;if(u===void 0){if(r.stdinIsTTY())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`).');r.writeStderr(`Reading secret from stdin (pass --value to skip)\u2026
194
+ `),u=wn(await r.readStdin())}if(u==="")throw new Error("A secret value is required. Pass --value or pipe it via stdin.");let m=await r.encryptSecret(e,i,p.trim(),u);if(r.writeStdout(`${gn(m)}
195
+ `),t.out!==void 0)try{await r.writeEnvelopeFile(t.out,m),r.writeStderr(`Wrote encrypted envelope to ${t.out}
196
+ `)}catch(g){r.writeStderr(`Error writing ${t.out}: ${g instanceof Error?g.message:String(g)}
197
+ `),r.setExitCode(1)}}function Tn(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&&!yn(t.stage)&&(console.error(hn(t.stage)),process.exit(1));let n=t.apiName===void 0?await vn():{},{stage:r,wasDefaulted:i}=xn(t.stage),p={isRemote:t.remote===!0,stage:r};if(!process.stdin.isTTY||!process.stdout.isTTY){try{await Sn(p,t,n,i,{loadCredentialsFromFile:ye,loadGlobalCredentials:Y,encryptSecret:gt,readStdin:Cn,stdinIsTTY:()=>process.stdin.isTTY,writeStdout:g=>{process.stdout.write(g)},writeStderr:g=>{process.stderr.write(g)},writeEnvelopeFile:Gt,setExitCode:g=>{process.exitCode=g}})}catch(g){console.error(`Error: ${g instanceof Error?g.message:String(g)}`),process.exit(1)}return}let u,{waitUntilExit:m}=is(os(fn,{ctx:p,stageDefaulted:i,onDone:g=>{u=g},...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(),u!==void 0&&t.out!==void 0)try{await Gt(t.out,u),process.stderr.write(`Wrote encrypted envelope to ${t.out}
198
+ `)}catch(g){console.error(`Error writing ${t.out}: ${g instanceof Error?g.message:String(g)}`),process.exitCode=1}})}var ss=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"]),as=[...ss].sort(),ls=new Set(["kizen-k","form-entity"]),En=[...as,...[...ls].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 En)console.log(t)})}import{mkdir as ys,writeFile as An,readFile as hs}from"fs/promises";import{join as bt}from"path";var cs=new Set(["developer_business_id"]);function ds(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}function _n(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,p)=>{r.children.has(i)||r.children.set(i,{name:i,children:new Map,isFile:p===n.length-1,filePath:n.slice(0,p+1).join("/")});let u=r.children.get(i);u&&(r=u)})}return t}function In(e){return[...e.children.values()].sort((t,o)=>t.isFile!==o.isFile?t.isFile?1:-1:t.name.localeCompare(o.name))}function Kt(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 Nn(e){let t=e.lastIndexOf(".");return t>=0?e.slice(t).toLowerCase():""}var ps={".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 us(e){return ps[Nn(e)]??""}function kn(e){let t=[...e.matchAll(/`+/g)].reduce((o,n)=>Math.max(o,n[0].length),0);return"`".repeat(Math.max(3,t+1))}function Bn(e,t=""){let o=In(e);return o.map((n,r)=>{let i=r===o.length-1,p=i?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",u=i?" ":"\u2502 ";return n.isFile?`${t}${p}${n.name}`:`${t}${p}${n.name}/
199
+ ${Bn(n,t+u)}`}).join(`
200
+ `)}var fs=/(^|\/)licen[cs]e(\.md|\.txt)?$/i;function Rn(e){return e.filter(t=>t.path!=="kizen.json"&&t.path!=="plugin-report.html"&&!fs.test(t.path))}function Dn(e){return Object.fromEntries(Object.entries(e).filter(([t])=>!cs.has(t)).map(([t,o])=>[t,t==="services"?ds(o):o]))}var ms={".png":"image/png",".svg":"image/svg+xml",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp"};function Fn(e){return`<ul>${In(e).map(n=>n.isFile?`<li class="tf"><a href="#${Kt(n.filePath)}" data-id="${Kt(n.filePath)}">${ae(n.name)}</a></li>`:`<li class="td"><span class="dn">${ae(n.name)}/</span>${Fn(n)}</li>`).join("")}</ul>`}function gs(e){let t;return e.base64Image!==void 0?t=`<img src="data:${ms[Nn(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="${Kt(e.path)}"><h2 class="fp">${ae(e.path)}</h2><div class="fb">${t}</div></section>`}function Ln(e,t){let o=Dn(e),n=typeof e.name=="string"?e.name:"Plugin",r=typeof e.version=="string"?e.version:"",i=typeof e.description=="string"?e.description:"",p=Rn(t),u=[];u.push(`# ${n}${r?` v${r}`:""}`),i&&u.push("",i);let m=JSON.stringify(o,null,2),g=kn(m);u.push("","## Configuration (`kizen.json`)","",`${g}json`,m,g),u.push("","## File Tree","","```",Bn(_n(p)),"```"),u.push("","## Files");for(let h of p)if(u.push("",`### \`${h.path}\``,""),h.base64Image!==void 0)u.push(`[Image file: ${h.path}]`);else if(h.binaryData!==void 0)u.push(`[Binary file: ${String(h.binaryData.length)} bytes]`);else{let S=kn(h.content);u.push(`${S}${us(h.path)}`,h.content,S)}return u.join(`
201
201
  `)+`
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(`
202
+ `}function $n(e,t){let o=Dn(e),n=typeof e.name=="string"?e.name:"Plugin",r=typeof e.version=="string"?e.version:"",i=typeof e.description=="string"?e.description:"",p=Rn(t),u=Fn(_n(p)),m=p.map(gs).join(`
203
203
  `);return`<!DOCTYPE html>
204
204
  <html lang="en">
205
205
  <head>
@@ -248,7 +248,7 @@ img{border:1px solid var(--bd);border-radius:4px}
248
248
  <div class="layout">
249
249
  <nav>
250
250
  <a href="#config" class="cfg" data-id="config">kizen.json (config)</a>
251
- ${p}
251
+ ${u}
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>
@@ -265,7 +265,7 @@ ${m}
265
265
  })();
266
266
  </script>
267
267
  </body>
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:
268
+ </html>`}var On=bt(Pe,"examples");function jn(e){e.command("report").description("Generate a self-contained HTML report of the plugin").option("-o, --output <path>",`output file path (default: ${On}/<api_name>.html)`).action(async t=>{let o=process.cwd(),n;try{let m=await hs(bt(o,"kizen.json"),"utf-8"),g=JSON.parse(m);n=Array.isArray(g)?g[0]:g}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??bt(On,`${r}.html`),p=i.replace(/\.html$/,".md"),u=await et(o,{detectBinaryByContent:!0});await ys(bt(i,".."),{recursive:!0}),await Promise.all([An(i,$n(n,u),"utf-8"),An(p,Ln(n,u),"utf-8")]),console.log(`Plugin report written to:
269
269
  ${i}
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();
270
+ ${p}`)})}function Ss(){let e=vs(bs(ws(import.meta.url)),"..","package.json");return JSON.parse(xs(e,"utf-8")).version}function zn(){let e=new Cs;return e.name("appbuilder").description("Kizen plugin app builder").version(Ss()),Tr(e),pr(e),sn(e),Tn(e),jn(e),Pn(e),e}zn().parse();
271
271
  //# sourceMappingURL=index.js.map