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