ripplo 0.3.16 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -319,7 +319,7 @@ ${t.join(`
319
319
  newSlug
320
320
  }
321
321
  }
322
- `),Fd=Math.min(10,Mb()/2),$o=Hb(Fd),On=new Set;Gb=5e3});import{Box as Zb,Text as Vo}from"ink";import{jsx as qd,jsxs as Jd}from"react/jsx-runtime";function zd({maxConcurrency:e,queuedRunCount:t,runningRunCount:n}){return Jd(Zb,{paddingX:1,children:[qd(Vo,{dimColor:!0,children:"Activity "}),Jd(Vo,{children:[String(n),"/",String(e)," running"]}),t>0?qd(Vo,{dimColor:!0,children:` \xB7 ${String(t)} queued`}):null]})}var Xd=p(()=>{"use strict"});import{Box as ew,Text as _n}from"ink";import{jsx as jn,jsxs as nw}from"react/jsx-runtime";function Gd({check:e}){let{detail:t,label:n,tone:r}=Pn(e),o=tw[r];return nw(ew,{children:[jn(_n,{color:o,children:r==="info"?"\u25CB":"\u25CF"}),jn(_n,{children:" "}),jn(_n,{children:n.padEnd(18," ")}),jn(_n,{color:o,children:t})]})}var tw,Kd=p(()=>{"use strict";Eo();tw={error:"red",info:"gray",ok:"green",warn:"yellow"}});import{Box as rw,Text as Qd}from"ink";import{jsx as Wo,jsxs as ow}from"react/jsx-runtime";function Yd({checks:e}){return ow(rw,{borderColor:"gray",borderStyle:"round",flexDirection:"column",marginTop:1,paddingX:1,children:[Wo(Qd,{bold:!0,children:"Health"}),e.length===0?Wo(Qd,{dimColor:!0,children:"Running first pass..."}):e.map(t=>Wo(Gd,{check:t},t.type))]})}var Zd=p(()=>{"use strict";Kd()});import{Box as Un,Text as yt}from"ink";import{jsx as gt,jsxs as $n}from"react/jsx-runtime";function ec({appUrl:e,developerUrl:t,projectName:n}){return $n(Un,{borderColor:"gray",borderStyle:"round",flexDirection:"column",paddingX:1,children:[$n(Un,{children:[gt(yt,{dimColor:!0,children:"Project "}),gt(yt,{bold:!0,children:n})]}),$n(Un,{children:[gt(yt,{dimColor:!0,children:"App "}),gt(yt,{color:"cyan",children:e})]}),$n(Un,{children:[gt(yt,{dimColor:!0,children:"Dashboard "}),gt(yt,{color:"cyan",children:t})]})]})}var tc=p(()=>{"use strict"});import{Box as Fo,Text as Ie}from"ink";import{jsx as _e,jsxs as Mo}from"react/jsx-runtime";function nc({paused:e,scope:t}){let n=t.slice(0,iw),r=t.length-n.length;return Mo(Fo,{borderColor:"gray",borderStyle:"round",flexDirection:"column",marginTop:1,paddingX:1,children:[Mo(Fo,{children:[_e(Ie,{bold:!0,children:"Scope"}),_e(Ie,{dimColor:!0,children:` (${String(t.length)})`}),_e(Ie,{children:" "}),_e(Ie,{dimColor:!0,children:"Hooks "}),_e(Ie,{color:e?"yellow":"green",children:e?"paused":"active"})]}),t.length===0?_e(Ie,{dimColor:!0,children:"no scope items \u2014 add from the dashboard or `ripplo scope add`"}):n.map(o=>Mo(Fo,{children:[_e(Ie,{color:"cyan",children:"\u2022 "}),_e(Ie,{children:o.label})]},o.id)),r>0?_e(Ie,{dimColor:!0,children:` \u2026 +${String(r)} more`}):null]})}var iw,rc=p(()=>{"use strict";iw=8});import{Box as aw,Text as oc}from"ink";import{jsx as sw,jsxs as ic}from"react/jsx-runtime";function ac({preconditions:e,workflows:t}){let n=t?.type==="workflows"?t.total:0,r=t?.type==="workflows"?t.invalidNames.length:0,o=e?.type==="preconditions"?e.count:0;return ic(aw,{marginTop:1,paddingX:1,children:[sw(oc,{dimColor:!0,children:"Workflows "}),ic(oc,{children:[String(n)," tests \xB7 ",String(o)," preconditions",r>0?` \xB7 ${String(r)} invalid`:""]})]})}var sc=p(()=>{"use strict"});import mj from"chalk";import{z as lc}from"zod";async function dc(){let e=new AbortController,t=setTimeout(()=>{e.abort()},3e3);try{let n=await fetch(`https://registry.npmjs.org/${lw}/latest`,{headers:{accept:"application/json"},signal:e.signal});if(!n.ok)return;let r=await n.json();return dw.parse(r).version}catch{return}finally{clearTimeout(t)}}var Ho,lw,dw,cc=p(()=>{"use strict";M();Ho="0.3.16",lw="ripplo",dw=lc.object({version:lc.string()})});import{useEffect as cw,useState as pw}from"react";import{Text as ht}from"ink";import{jsx as It,jsxs as gw}from"react/jsx-runtime";function pc({connected:e,projectId:t,queuedRunCount:n,ripploServerUrl:r,runningRunCount:o,syncError:i,width:a}){let l=yw(),s=l!=null&&l!==Ho,d=uw({connected:e,syncError:i}),c=mw({queuedRunCount:n,runningRunCount:o}),u=`v${Ho}`,y=s?` \u2192 v${l}`:"",S=`project ${t} \xB7 q to quit`,b=` ripplo ${u}${y} | ${r} ${d}${c}`,k=Math.max(0,a-b.length-S.length-1);return gw(ht,{inverse:!0,children:[It(ht,{bold:!0,children:" ripplo "}),It(ht,{dimColor:!0,children:u}),s?It(ht,{color:"yellow",children:` \u2192 v${l}`}):null,` | ${r} `,It(ht,{color:fw({connected:e,syncError:i}),children:d}),c," ".repeat(k),It(ht,{dimColor:!0,children:S})," "]})}function uw({connected:e,syncError:t}){return t!=null?"sync failed":e?"connected":"connecting..."}function mw({queuedRunCount:e,runningRunCount:t}){if(t===0&&e===0)return"";let n=e>0?` (+${String(e)} queued)`:"";return` ${String(t)} running${n}`}function fw({connected:e,syncError:t}){return t!=null?"red":e?"green":"yellow"}function yw(){let[e,t]=pw();return cw(()=>{dc().then(n=>{n!=null&&t(n)})},[]),e}var uc=p(()=>{"use strict";cc()});import{useEffect as hw}from"react";import{Box as qo,Text as kw,useApp as Sw,useInput as bw}from"ink";import{jsx as Je,jsxs as mc}from"react/jsx-runtime";function fc({config:e,cwd:t}){let n=Sw(),{height:r,width:o}=ft(),{config:i,devSessionId:a,syncError:l}=vd({config:e,cwd:t}),{connected:s,maxConcurrency:d,queuedRunCount:c,runningRunCount:u}=Md({config:i,cwd:t,devSessionId:a}),{checks:y}=Pd({config:i,cwd:t}),{paused:S,projectName:b,scope:k}=Dd({devSessionId:a,projectId:e.projectId});Id({cwd:t,projectId:e.projectId}),hw(()=>Ol(t),[t]),bw($=>{$==="q"&&n.exit()});let N=`${i.ripploServerUrl}/projects/${i.projectId}/developer`,R=y.filter($=>ww.has($.type)),O=y.find($=>$.type==="workflows"),F=y.find($=>$.type==="preconditions"),U=b??"\u2026";return mc(qo,{flexDirection:"column",height:r,width:o,children:[Je(pc,{connected:s,projectId:i.projectId,queuedRunCount:c,ripploServerUrl:i.ripploServerUrl,runningRunCount:u,syncError:l,width:o}),mc(qo,{flexDirection:"column",flexGrow:1,paddingX:1,paddingY:1,children:[Je(ec,{appUrl:i.appUrl,developerUrl:N,projectName:U}),Je(nc,{paused:S,scope:k}),Je(Yd,{checks:R}),Je(ac,{preconditions:F,workflows:O}),Je(zd,{maxConcurrency:d,queuedRunCount:c,runningRunCount:u}),Je(qo,{marginTop:1,paddingX:1,children:Je(kw,{dimColor:!0,children:"q quit"})})]})]})}var ww,yc=p(()=>{"use strict";ko();xn();Cd();Io();_d();Bd();Bo();Xd();Zd();tc();rc();sc();uc();ww=new Set(["dev-server","preconditions","adapter-enabled","webhook-verification","lockfile","pre-commit-hook","browser"])});import{Text as gc}from"ink";import Aw from"ink-spinner";import{jsx as hc,jsxs as Tw}from"react/jsx-runtime";function kc({loading:e}){return e?Tw(gc,{color:Rw,children:[hc(Aw,{type:"dots"})," Starting..."]}):hc(gc,{children:""})}var Rw,Sc=p(()=>{"use strict";Rw="#24CFFF"});import{useEffect as Nw,useState as _t}from"react";import{Box as tt,Text as Jo,useInput as vw}from"ink";import{jsx as ze,jsxs as zo}from"react/jsx-runtime";function wc({onDismiss:e}){let{height:t,width:n}=ft(),[r,o]=_t(0),[i,a]=_t(!1),[l,s]=_t(!1),[d,c]=_t(!1),[u,y]=_t(!1);vw(()=>{u&&e()}),Nw(()=>{let k=80+Dn.length*70+80,N=[...Dn.map((R,O)=>setTimeout(()=>{o(O+1)},80+O*70)),setTimeout(()=>{a(!0)},k),setTimeout(()=>{s(!0)},k+200),setTimeout(()=>{c(!0)},k+400),setTimeout(()=>{c(!1),y(!0)},k+2e3),setTimeout(()=>{e()},k+2800)];return()=>{N.forEach(R=>{clearTimeout(R)})}},[e]);let S=Dn.length+5,b=Math.max(0,Math.floor((t-S)/2));return zo(tt,{flexDirection:"column",height:t,width:n,children:[ze(tt,{height:b}),zo(tt,{alignItems:"flex-start",flexDirection:"row",justifyContent:"center",children:[ze(tt,{flexDirection:"column",children:Dn.map((k,N)=>ze(Jo,{color:bc,children:N<r?k:""},k))}),zo(tt,{flexDirection:"column",paddingLeft:4,paddingTop:5,children:[ze(Jo,{bold:!0,color:bc,children:i?Cw:""}),ze(tt,{marginTop:1,children:ze(Jo,{color:"gray",dimColor:!0,children:l?"developer CLI":""})}),ze(tt,{marginTop:2,children:ze(kc,{loading:d})})]})]})]})}var Dn,bc,Cw,Ac=p(()=>{"use strict";xn();Sc();Dn=[" XXXX XXXXXXX "," XX XX X X "," XXX XX XX X X ","XXXXXX XX XX XXXXXXX ","XX XXX XX XX ","XX XXX XX XXXXXXXX "," XX XX XX XX "," XX XX XX XX "," XX XXXXX XX"," XX XX XX XX"," XX XX XXXX "," XXX XX "," XXXXXXXXX XX "," XXX XX "," XXXXXXX "],bc="#24CFFF",Cw="ripplo"});import{createAuthClient as Lw}from"better-auth/client";import{deviceAuthorizationClient as xw}from"better-auth/client/plugins";function Bn({baseURL:e}){return Lw({baseURL:e,fetchOptions:{headers:{"User-Agent":"Ripplo CLI"}},plugins:[xw()]})}var Xo=p(()=>{"use strict"});import{exec as Pw}from"child_process";async function Tc({cwd:e,onDeviceCode:t,url:n}){let r=n??xt().RIPPLO_SERVER_URL,o=Bn({baseURL:r}),i=await o.device.code({client_id:Rc});if(i.error!=null)throw new Error(`Failed to request device code: ${i.error.error_description}`);let{device_code:a,user_code:l,verification_uri_complete:s}=i.data;t({userCode:l,verificationUrl:s}),$w(s);let d=await Ow({authClient:o,deviceCode:a});return Hr(e,d),d}async function Ow({authClient:e,deviceCode:t}){for(;;){await jw(Ew);let n=await e.device.token({client_id:Rc,device_code:t,grant_type:"urn:ietf:params:oauth:grant-type:device_code"});if(n.data?.access_token!=null)return n.data.access_token;if(n.error==null)continue;if(!_w(n.error.error))throw new Error(`Authorization failed: ${n.error.error_description}`)}}function _w(e){return Iw.has(e)}function jw(e){return new Promise(t=>{setTimeout(t,e)})}function Uw(){return process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open"}function $w(e){let t=Uw();Pw(`${t} "${e}"`,()=>{})}var Ew,Rc,Iw,Nc=p(()=>{"use strict";M();Xo();Me();Ew=5e3,Rc="ripplo-cli";Iw=new Set(["authorization_pending","slow_down"])});import{useCallback as Vn,useEffect as Dw,useState as Xe}from"react";import{exec as Bw}from"child_process";import{promisify as Vw}from"util";import H from"fs";import W from"path";function Cc({cwd:e,initialToken:t,serverUrl:n}){let[r,o]=Xe(t==null?"login":"validating"),[i,a]=Xe(),[l,s]=Xe(),[d,c]=Xe(t),[u,y]=Xe(!1),[S,b]=Xe(),[k,N]=Xe(),[R,O]=Xe([]);Dw(()=>{if(t==null)return;Bn({baseURL:n}).getSession({fetchOptions:{headers:{Authorization:`Bearer ${t}`}}}).then(j=>{if(j.data==null){o("login");return}return Go({cwd:e,serverUrl:n,token:t})}).then(j=>{if(j==null){o("select-project");return}a(j),o("complete")}).catch(j=>{s(j instanceof Error?j.message:String(j)),o("login")})},[e,t,n]);let F=Vn(()=>{u||(y(!0),s(void 0),Tc({cwd:e,onDeviceCode:b,url:n}).then(q=>(c(q),Go({cwd:e,serverUrl:n,token:q}))).then(q=>{q==null?o("select-project"):(a(q),o("complete"))}).catch(q=>{y(!1),b(void 0),s(q instanceof Error?q.message:String(q))}))},[e,u,n]),U=Vn(q=>{let j=i?.token??d??t;if(j==null){s("No authentication token available");return}o("scaffolding"),s(void 0),Hw({cwd:e,onStep:N,projectId:q.id}).then(async G=>{O(G);let Ge=await Go({cwd:e,serverUrl:n,token:j});a(Ge??Ww({projectId:q.id,serverUrl:n,token:j})),o(G.length>0?"scaffolding-warnings":"complete")}).catch(G=>{s(G instanceof Error?G.message:String(G)),o("select-project")})},[i,e,t,n,d]),$=Vn(()=>{o("complete")},[]),se=Vn(()=>{a(void 0),o("login"),y(!1),b(void 0),s(void 0)},[]);return{config:i,deviceCodeInfo:S,dismissScaffoldWarnings:$,error:l,loginStarted:u,resetToLogin:se,scaffoldingStep:k,scaffoldWarnings:R,selectProject:U,setStage:o,stage:r,startLogin:F,token:d}}function Ww({projectId:e,serverUrl:t,token:n}){return{appUrl:"",engineUrl:"",projectId:e,ripploServerUrl:t,token:n,webhookSecret:""}}async function Go({cwd:e,serverUrl:t,token:n}){let r=await L(e);if(r.ok)return{...r.result.config,ripploServerUrl:t,token:n}}async function Hw({cwd:e,onStep:t,projectId:n}){t("Scaffolding project files..."),Zw({cwd:e,projectId:n}),t("Updating .gitignore..."),lA(e),t("Marking ripplo.lock as generated..."),Xw(e),t("Installing dependencies...");let r=await qw(e),o=[];if(r.ok||o.push({manualCommand:r.cmd,message:`Couldn't auto-install dev dependencies (${r.reason}). Run this manually, then re-run \`npx ripplo\`.`}),r.ok){t("Compiling initial lockfile...");let i=await Jw(e);i!=null&&o.push({manualCommand:void 0,message:i})}return t("Setting up browser..."),await vr(),o}async function qw(e){let t=Gw({cwd:e,pm:Yw(e)});g.info("Installing dependencies: %s",t);try{return await Mw(t,{cwd:e}),{ok:!0}}catch(n){let r=n instanceof Error?n.message.split(`
322
+ `),Fd=Math.min(10,Mb()/2),$o=Hb(Fd),On=new Set;Gb=5e3});import{Box as Zb,Text as Vo}from"ink";import{jsx as qd,jsxs as Jd}from"react/jsx-runtime";function zd({maxConcurrency:e,queuedRunCount:t,runningRunCount:n}){return Jd(Zb,{paddingX:1,children:[qd(Vo,{dimColor:!0,children:"Activity "}),Jd(Vo,{children:[String(n),"/",String(e)," running"]}),t>0?qd(Vo,{dimColor:!0,children:` \xB7 ${String(t)} queued`}):null]})}var Xd=p(()=>{"use strict"});import{Box as ew,Text as _n}from"ink";import{jsx as jn,jsxs as nw}from"react/jsx-runtime";function Gd({check:e}){let{detail:t,label:n,tone:r}=Pn(e),o=tw[r];return nw(ew,{children:[jn(_n,{color:o,children:r==="info"?"\u25CB":"\u25CF"}),jn(_n,{children:" "}),jn(_n,{children:n.padEnd(18," ")}),jn(_n,{color:o,children:t})]})}var tw,Kd=p(()=>{"use strict";Eo();tw={error:"red",info:"gray",ok:"green",warn:"yellow"}});import{Box as rw,Text as Qd}from"ink";import{jsx as Wo,jsxs as ow}from"react/jsx-runtime";function Yd({checks:e}){return ow(rw,{borderColor:"gray",borderStyle:"round",flexDirection:"column",marginTop:1,paddingX:1,children:[Wo(Qd,{bold:!0,children:"Health"}),e.length===0?Wo(Qd,{dimColor:!0,children:"Running first pass..."}):e.map(t=>Wo(Gd,{check:t},t.type))]})}var Zd=p(()=>{"use strict";Kd()});import{Box as Un,Text as yt}from"ink";import{jsx as gt,jsxs as $n}from"react/jsx-runtime";function ec({appUrl:e,developerUrl:t,projectName:n}){return $n(Un,{borderColor:"gray",borderStyle:"round",flexDirection:"column",paddingX:1,children:[$n(Un,{children:[gt(yt,{dimColor:!0,children:"Project "}),gt(yt,{bold:!0,children:n})]}),$n(Un,{children:[gt(yt,{dimColor:!0,children:"App "}),gt(yt,{color:"cyan",children:e})]}),$n(Un,{children:[gt(yt,{dimColor:!0,children:"Dashboard "}),gt(yt,{color:"cyan",children:t})]})]})}var tc=p(()=>{"use strict"});import{Box as Fo,Text as Ie}from"ink";import{jsx as _e,jsxs as Mo}from"react/jsx-runtime";function nc({paused:e,scope:t}){let n=t.slice(0,iw),r=t.length-n.length;return Mo(Fo,{borderColor:"gray",borderStyle:"round",flexDirection:"column",marginTop:1,paddingX:1,children:[Mo(Fo,{children:[_e(Ie,{bold:!0,children:"Scope"}),_e(Ie,{dimColor:!0,children:` (${String(t.length)})`}),_e(Ie,{children:" "}),_e(Ie,{dimColor:!0,children:"Hooks "}),_e(Ie,{color:e?"yellow":"green",children:e?"paused":"active"})]}),t.length===0?_e(Ie,{dimColor:!0,children:"no scope items \u2014 add from the dashboard or `ripplo scope add`"}):n.map(o=>Mo(Fo,{children:[_e(Ie,{color:"cyan",children:"\u2022 "}),_e(Ie,{children:o.label})]},o.id)),r>0?_e(Ie,{dimColor:!0,children:` \u2026 +${String(r)} more`}):null]})}var iw,rc=p(()=>{"use strict";iw=8});import{Box as aw,Text as oc}from"ink";import{jsx as sw,jsxs as ic}from"react/jsx-runtime";function ac({preconditions:e,workflows:t}){let n=t?.type==="workflows"?t.total:0,r=t?.type==="workflows"?t.invalidNames.length:0,o=e?.type==="preconditions"?e.count:0;return ic(aw,{marginTop:1,paddingX:1,children:[sw(oc,{dimColor:!0,children:"Workflows "}),ic(oc,{children:[String(n)," tests \xB7 ",String(o)," preconditions",r>0?` \xB7 ${String(r)} invalid`:""]})]})}var sc=p(()=>{"use strict"});import mj from"chalk";import{z as lc}from"zod";async function dc(){let e=new AbortController,t=setTimeout(()=>{e.abort()},3e3);try{let n=await fetch(`https://registry.npmjs.org/${lw}/latest`,{headers:{accept:"application/json"},signal:e.signal});if(!n.ok)return;let r=await n.json();return dw.parse(r).version}catch{return}finally{clearTimeout(t)}}var Ho,lw,dw,cc=p(()=>{"use strict";M();Ho="0.3.17",lw="ripplo",dw=lc.object({version:lc.string()})});import{useEffect as cw,useState as pw}from"react";import{Text as ht}from"ink";import{jsx as It,jsxs as gw}from"react/jsx-runtime";function pc({connected:e,projectId:t,queuedRunCount:n,ripploServerUrl:r,runningRunCount:o,syncError:i,width:a}){let l=yw(),s=l!=null&&l!==Ho,d=uw({connected:e,syncError:i}),c=mw({queuedRunCount:n,runningRunCount:o}),u=`v${Ho}`,y=s?` \u2192 v${l}`:"",S=`project ${t} \xB7 q to quit`,b=` ripplo ${u}${y} | ${r} ${d}${c}`,k=Math.max(0,a-b.length-S.length-1);return gw(ht,{inverse:!0,children:[It(ht,{bold:!0,children:" ripplo "}),It(ht,{dimColor:!0,children:u}),s?It(ht,{color:"yellow",children:` \u2192 v${l}`}):null,` | ${r} `,It(ht,{color:fw({connected:e,syncError:i}),children:d}),c," ".repeat(k),It(ht,{dimColor:!0,children:S})," "]})}function uw({connected:e,syncError:t}){return t!=null?"sync failed":e?"connected":"connecting..."}function mw({queuedRunCount:e,runningRunCount:t}){if(t===0&&e===0)return"";let n=e>0?` (+${String(e)} queued)`:"";return` ${String(t)} running${n}`}function fw({connected:e,syncError:t}){return t!=null?"red":e?"green":"yellow"}function yw(){let[e,t]=pw();return cw(()=>{dc().then(n=>{n!=null&&t(n)})},[]),e}var uc=p(()=>{"use strict";cc()});import{useEffect as hw}from"react";import{Box as qo,Text as kw,useApp as Sw,useInput as bw}from"ink";import{jsx as Je,jsxs as mc}from"react/jsx-runtime";function fc({config:e,cwd:t}){let n=Sw(),{height:r,width:o}=ft(),{config:i,devSessionId:a,syncError:l}=vd({config:e,cwd:t}),{connected:s,maxConcurrency:d,queuedRunCount:c,runningRunCount:u}=Md({config:i,cwd:t,devSessionId:a}),{checks:y}=Pd({config:i,cwd:t}),{paused:S,projectName:b,scope:k}=Dd({devSessionId:a,projectId:e.projectId});Id({cwd:t,projectId:e.projectId}),hw(()=>Ol(t),[t]),bw($=>{$==="q"&&n.exit()});let N=`${i.ripploServerUrl}/projects/${i.projectId}/developer`,R=y.filter($=>ww.has($.type)),O=y.find($=>$.type==="workflows"),F=y.find($=>$.type==="preconditions"),U=b??"\u2026";return mc(qo,{flexDirection:"column",height:r,width:o,children:[Je(pc,{connected:s,projectId:i.projectId,queuedRunCount:c,ripploServerUrl:i.ripploServerUrl,runningRunCount:u,syncError:l,width:o}),mc(qo,{flexDirection:"column",flexGrow:1,paddingX:1,paddingY:1,children:[Je(ec,{appUrl:i.appUrl,developerUrl:N,projectName:U}),Je(nc,{paused:S,scope:k}),Je(Yd,{checks:R}),Je(ac,{preconditions:F,workflows:O}),Je(zd,{maxConcurrency:d,queuedRunCount:c,runningRunCount:u}),Je(qo,{marginTop:1,paddingX:1,children:Je(kw,{dimColor:!0,children:"q quit"})})]})]})}var ww,yc=p(()=>{"use strict";ko();xn();Cd();Io();_d();Bd();Bo();Xd();Zd();tc();rc();sc();uc();ww=new Set(["dev-server","preconditions","adapter-enabled","webhook-verification","lockfile","pre-commit-hook","browser"])});import{Text as gc}from"ink";import Aw from"ink-spinner";import{jsx as hc,jsxs as Tw}from"react/jsx-runtime";function kc({loading:e}){return e?Tw(gc,{color:Rw,children:[hc(Aw,{type:"dots"})," Starting..."]}):hc(gc,{children:""})}var Rw,Sc=p(()=>{"use strict";Rw="#24CFFF"});import{useEffect as Nw,useState as _t}from"react";import{Box as tt,Text as Jo,useInput as vw}from"ink";import{jsx as ze,jsxs as zo}from"react/jsx-runtime";function wc({onDismiss:e}){let{height:t,width:n}=ft(),[r,o]=_t(0),[i,a]=_t(!1),[l,s]=_t(!1),[d,c]=_t(!1),[u,y]=_t(!1);vw(()=>{u&&e()}),Nw(()=>{let k=80+Dn.length*70+80,N=[...Dn.map((R,O)=>setTimeout(()=>{o(O+1)},80+O*70)),setTimeout(()=>{a(!0)},k),setTimeout(()=>{s(!0)},k+200),setTimeout(()=>{c(!0)},k+400),setTimeout(()=>{c(!1),y(!0)},k+2e3),setTimeout(()=>{e()},k+2800)];return()=>{N.forEach(R=>{clearTimeout(R)})}},[e]);let S=Dn.length+5,b=Math.max(0,Math.floor((t-S)/2));return zo(tt,{flexDirection:"column",height:t,width:n,children:[ze(tt,{height:b}),zo(tt,{alignItems:"flex-start",flexDirection:"row",justifyContent:"center",children:[ze(tt,{flexDirection:"column",children:Dn.map((k,N)=>ze(Jo,{color:bc,children:N<r?k:""},k))}),zo(tt,{flexDirection:"column",paddingLeft:4,paddingTop:5,children:[ze(Jo,{bold:!0,color:bc,children:i?Cw:""}),ze(tt,{marginTop:1,children:ze(Jo,{color:"gray",dimColor:!0,children:l?"developer CLI":""})}),ze(tt,{marginTop:2,children:ze(kc,{loading:d})})]})]})]})}var Dn,bc,Cw,Ac=p(()=>{"use strict";xn();Sc();Dn=[" XXXX XXXXXXX "," XX XX X X "," XXX XX XX X X ","XXXXXX XX XX XXXXXXX ","XX XXX XX XX ","XX XXX XX XXXXXXXX "," XX XX XX XX "," XX XX XX XX "," XX XXXXX XX"," XX XX XX XX"," XX XX XXXX "," XXX XX "," XXXXXXXXX XX "," XXX XX "," XXXXXXX "],bc="#24CFFF",Cw="ripplo"});import{createAuthClient as Lw}from"better-auth/client";import{deviceAuthorizationClient as xw}from"better-auth/client/plugins";function Bn({baseURL:e}){return Lw({baseURL:e,fetchOptions:{headers:{"User-Agent":"Ripplo CLI"}},plugins:[xw()]})}var Xo=p(()=>{"use strict"});import{exec as Pw}from"child_process";async function Tc({cwd:e,onDeviceCode:t,url:n}){let r=n??xt().RIPPLO_SERVER_URL,o=Bn({baseURL:r}),i=await o.device.code({client_id:Rc});if(i.error!=null)throw new Error(`Failed to request device code: ${i.error.error_description}`);let{device_code:a,user_code:l,verification_uri_complete:s}=i.data;t({userCode:l,verificationUrl:s}),$w(s);let d=await Ow({authClient:o,deviceCode:a});return Hr(e,d),d}async function Ow({authClient:e,deviceCode:t}){for(;;){await jw(Ew);let n=await e.device.token({client_id:Rc,device_code:t,grant_type:"urn:ietf:params:oauth:grant-type:device_code"});if(n.data?.access_token!=null)return n.data.access_token;if(n.error==null)continue;if(!_w(n.error.error))throw new Error(`Authorization failed: ${n.error.error_description}`)}}function _w(e){return Iw.has(e)}function jw(e){return new Promise(t=>{setTimeout(t,e)})}function Uw(){return process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open"}function $w(e){let t=Uw();Pw(`${t} "${e}"`,()=>{})}var Ew,Rc,Iw,Nc=p(()=>{"use strict";M();Xo();Me();Ew=5e3,Rc="ripplo-cli";Iw=new Set(["authorization_pending","slow_down"])});import{useCallback as Vn,useEffect as Dw,useState as Xe}from"react";import{exec as Bw}from"child_process";import{promisify as Vw}from"util";import H from"fs";import W from"path";function Cc({cwd:e,initialToken:t,serverUrl:n}){let[r,o]=Xe(t==null?"login":"validating"),[i,a]=Xe(),[l,s]=Xe(),[d,c]=Xe(t),[u,y]=Xe(!1),[S,b]=Xe(),[k,N]=Xe(),[R,O]=Xe([]);Dw(()=>{if(t==null)return;Bn({baseURL:n}).getSession({fetchOptions:{headers:{Authorization:`Bearer ${t}`}}}).then(j=>{if(j.data==null){o("login");return}return Go({cwd:e,serverUrl:n,token:t})}).then(j=>{if(j==null){o("select-project");return}a(j),o("complete")}).catch(j=>{s(j instanceof Error?j.message:String(j)),o("login")})},[e,t,n]);let F=Vn(()=>{u||(y(!0),s(void 0),Tc({cwd:e,onDeviceCode:b,url:n}).then(q=>(c(q),Go({cwd:e,serverUrl:n,token:q}))).then(q=>{q==null?o("select-project"):(a(q),o("complete"))}).catch(q=>{y(!1),b(void 0),s(q instanceof Error?q.message:String(q))}))},[e,u,n]),U=Vn(q=>{let j=i?.token??d??t;if(j==null){s("No authentication token available");return}o("scaffolding"),s(void 0),Hw({cwd:e,onStep:N,projectId:q.id}).then(async G=>{O(G);let Ge=await Go({cwd:e,serverUrl:n,token:j});a(Ge??Ww({projectId:q.id,serverUrl:n,token:j})),o(G.length>0?"scaffolding-warnings":"complete")}).catch(G=>{s(G instanceof Error?G.message:String(G)),o("select-project")})},[i,e,t,n,d]),$=Vn(()=>{o("complete")},[]),se=Vn(()=>{a(void 0),o("login"),y(!1),b(void 0),s(void 0)},[]);return{config:i,deviceCodeInfo:S,dismissScaffoldWarnings:$,error:l,loginStarted:u,resetToLogin:se,scaffoldingStep:k,scaffoldWarnings:R,selectProject:U,setStage:o,stage:r,startLogin:F,token:d}}function Ww({projectId:e,serverUrl:t,token:n}){return{appUrl:"",engineUrl:"",projectId:e,ripploServerUrl:t,token:n,webhookSecret:""}}async function Go({cwd:e,serverUrl:t,token:n}){let r=await L(e);if(r.ok)return{...r.result.config,ripploServerUrl:t,token:n}}async function Hw({cwd:e,onStep:t,projectId:n}){t("Scaffolding project files..."),Zw({cwd:e,projectId:n}),t("Updating .gitignore..."),lA(e),t("Marking ripplo.lock as generated..."),Xw(e),t("Installing dependencies...");let r=await qw(e),o=[];if(r.ok||o.push({manualCommand:r.cmd,message:`Couldn't auto-install dev dependencies (${r.reason}). Run this manually, then re-run \`npx ripplo\`.`}),r.ok){t("Compiling initial lockfile...");let i=await Jw(e);i!=null&&o.push({manualCommand:void 0,message:i})}return t("Setting up browser..."),await vr(),o}async function qw(e){let t=Gw({cwd:e,pm:Yw(e)});g.info("Installing dependencies: %s",t);try{return await Mw(t,{cwd:e}),{ok:!0}}catch(n){let r=n instanceof Error?n.message.split(`
323
323
  `)[0]??n.message:String(n);return g.warn("Install failed (%s): %s",t,r),{cmd:t,ok:!1,reason:r}}}async function Jw(e){try{await zw(e);return}catch(t){let n=t instanceof Error?t.message:String(t);return g.warn("Initial lockfile compile failed: %s",n),`Couldn't compile initial lockfile: ${n}. You can run \`npx ripplo\` again after fixing the DSL.`}}async function zw(e){let t=await L(e);if(!t.ok){g.warn("Initial compile failed, skipping lockfile write: %s",t.error);return}await me({cwd:e,result:t.result})}function Xw(e){let t=W.join(e,".gitattributes"),n=H.existsSync(t)?H.readFileSync(t,"utf8"):"";if(n.includes(vc))return;let r=n.length===0||n.endsWith(`
324
324
  `)?"":`
325
325
  `;H.writeFileSync(t,`${n}${r}${vc}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ripplo",
3
- "version": "0.3.16",
3
+ "version": "0.3.17",
4
4
  "description": "CLI for Ripplo — AI-powered end-to-end testing",
5
5
  "type": "module",
6
6
  "homepage": "https://ripplo.ai",
@@ -60,9 +60,9 @@
60
60
  "tsup": "^8.5.1",
61
61
  "@ripplo/eslint-config": "0.0.0",
62
62
  "@ripplo/spec": "^0.0.0",
63
- "@ripplo/testing": "^0.3.9",
63
+ "@ripplo/graphql": "^0.0.0",
64
64
  "@ripplo/runtime": "^0.0.0",
65
- "@ripplo/graphql": "^0.0.0"
65
+ "@ripplo/testing": "^0.3.10"
66
66
  },
67
67
  "scripts": {
68
68
  "dev": "tsx watch src/index.ts",