@heygaia/cli 0.1.0 → 0.1.1
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/dist/index.js +13 -9
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{Command as Or}from"commander";import{render as Er}from"ink";import wr from"react";import{Box as me,Text as z}from"ink";import ir from"react";import{ProgressBar as Qe,Select as Ke,Spinner as Je}from"@inkjs/ui";import{Box as l,Text as s,useInput as J}from"ink";import se from"ink-text-input";import{useEffect as de,useState as L}from"react";import{Box as ie,Text as Xe}from"ink";var S="#00bbff";import{Box as Gt,Text as Ce}from"ink";import{jsx as He,jsxs as We}from"react/jsx-runtime";var Ue=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:We(Gt,{width:"100%",borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[We(Ce,{color:S,children:[He(Ce,{bold:!0,children:"Status:"})," ",t]}),He(Ce,{color:"white",dimColor:!0,children:e})]});import{Box as Ot}from"ink";import qt from"ink-big-text";import $t from"ink-gradient";import{jsx as Ie}from"react/jsx-runtime";var ee=()=>Ie(Ot,{flexDirection:"column",marginTop:1,marginBottom:1,children:Ie($t,{colors:[S,"#b0eaff",S],children:Ie(qt,{text:"GAIA",font:"3d"})})});import{jsx as te,jsxs as ue}from"react/jsx-runtime";var jt=["Welcome","Prerequisites","Repository Setup","Install Tools","Environment Setup","Project Setup","Finished"],Ye=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Vt=({currentStep:e,steps:t})=>{let o=t.indexOf(e);return te(ie,{marginBottom:1,children:t.map((r,n)=>{let i=r===e,p=o>n;return ue(ie,{marginRight:2,children:[ue(Xe,{color:i?S:p?"green":"gray",children:[p?"\u2713 ":i?"\u25CF ":"\u25CB ",r]}),n<t.length-1&&te(Xe,{color:"gray",children:" \u203A "})]},r)})})},pe=({children:e,status:t,step:o,steps:r=jt})=>ue(ie,{flexDirection:"column",height:"100%",width:"100%",children:[ue(ie,{flexGrow:1,flexDirection:"column",children:[te(ee,{}),te(Vt,{currentStep:o,steps:r}),te(ie,{flexDirection:"column",flexGrow:1,children:e})]}),te(Ue,{status:t,step:o})]});import{Fragment as uo,jsx as a,jsxs as c}from"react/jsx-runtime";var Ee=({label:e,status:t})=>c(l,{children:[a(l,{marginRight:1,children:t==="pending"?a(Je,{type:"dots"}):t==="success"?a(s,{color:S,children:"\u2714"}):t==="error"?a(s,{color:"red",children:"\u2716"}):a(s,{color:"yellow",children:"\u26A0"})}),a(s,{children:e})]}),Ht=({onConfirm:e})=>(J((t,o)=>{o.return&&e()}),c(l,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:S,children:[a(s,{bold:!0,children:"Welcome to the Interactive GAIA Setup"}),c(l,{flexDirection:"column",marginTop:1,marginBottom:1,children:[a(s,{children:"This wizard will guide you through the setup process:"}),a(s,{children:" 1. Check Prerequisites (Git, Docker, Mise)"}),a(s,{children:" 2. Clone Repository (from GitHub)"}),a(s,{children:" 3. Install Tools (node, python, uv via mise)"}),a(s,{children:" 4. Configure Env Vars (databases, API keys, etc.)"}),a(s,{children:" 5. Setup Project (install all dependencies)"})]}),a(s,{color:S,children:"Press Enter to start..."})]})),Wt=({portResults:e,onAccept:t,onAbort:o})=>{J((n,i)=>{i.return?t():i.escape&&o()});let r=e.filter(n=>!n.available);return c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[a(l,{marginBottom:1,children:a(s,{bold:!0,color:"yellow",children:"Port Conflicts Detected"})}),e.map(n=>c(l,{children:[c(s,{color:n.available?"green":n.alternative?"yellow":"red",children:[n.available?"\u2714":n.alternative?"\u26A0":"\u2716"," "]}),c(s,{children:[n.service," (:",n.port,")"]}),!n.available&&c(s,{color:n.alternative?"gray":"red",children:[" ","- in use",n.usedBy?` by ${n.usedBy}`:"",n.alternative?` \u2192 will use :${n.alternative}`:" \u2014 NO ALTERNATIVE FOUND"]})]},n.port)),c(l,{marginTop:1,flexDirection:"column",children:[r.some(n=>!n.alternative)&&a(l,{borderStyle:"single",borderColor:"red",paddingX:1,marginBottom:1,children:a(s,{color:"red",children:"Some ports have no available alternative. Free them and retry."})}),!r.some(n=>!n.alternative)&&r.some(n=>n.alternative)&&a(s,{color:"gray",children:"Alternative ports will be used for conflicting services."}),a(l,{marginTop:1,children:c(s,{children:[a(s,{color:"green",bold:!0,children:"Enter"})," to continue with alternatives ",a(s,{color:"yellow",bold:!0,children:"Escape"})," to abort"]})})]})]})},Ut=({defaultValue:e,onSubmit:t})=>{let[o,r]=L(e);return c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(s,{children:"Where should we clone the repository?"}),c(l,{children:[a(s,{color:S,children:"\u279C "}),a(se,{value:o,onChange:r,onSubmit:t})]}),c(s,{color:"gray",children:["(Press Enter for default: ",e,")"]})]})},Xt=({setupMode:e,repoPath:t,portOverrides:o,onConfirm:r})=>{J((m,f)=>{f.return&&r()});let n=e||"developer",i=t||"./gaia",p=o?.[3e3]??3e3,u=o?.[8e3]??8e3;return c(l,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:S,padding:1,children:[a(s,{color:S,bold:!0,children:"You are all set!"}),c(l,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"To start GAIA, run:"}),c(l,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[c(s,{color:"cyan",children:["$ cd ",i]}),a(s,{color:"cyan",children:"$ gaia start"})]}),a(l,{marginTop:1,children:a(s,{color:"gray",dimColor:!0,children:n==="selfhost"?"Runs: docker compose --profile all up -d (background)":"Runs: mise dev (interactive \u2014 keep terminal open)"})})]}),c(l,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"Access GAIA at:"}),c(l,{marginLeft:2,flexDirection:"column",children:[c(s,{children:["Web:"," ",c(s,{color:"cyan",bold:!0,children:["http://localhost:",p]})]}),c(s,{children:["API:"," ",c(s,{color:"cyan",bold:!0,children:["http://localhost:",u]})]})]})]}),a(we,{}),a(l,{marginTop:1,children:a(s,{dimColor:!0,children:"Press Enter to exit"})})]})},we=()=>c(l,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"Available commands:"}),c(l,{marginLeft:2,flexDirection:"column",children:[c(s,{children:[c(s,{color:S,bold:!0,children:["gaia start"," "]}),a(s,{color:"gray",children:" Start all services"})]}),c(s,{children:[c(s,{color:S,bold:!0,children:["gaia stop"," "]}),a(s,{color:"gray",children:" Stop all services"})]}),c(s,{children:[a(s,{color:S,bold:!0,children:"gaia status"}),a(s,{color:"gray",children:" Check service health"})]}),c(s,{children:[c(s,{color:S,bold:!0,children:["gaia setup"," "]}),a(s,{color:"gray",children:" Reconfigure environment"})]})]})]}),Yt=({phase:e,progress:t,isComplete:o,logs:r,title:n})=>c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(l,{marginBottom:1,children:a(s,{bold:!0,color:S,children:n||"Installing Dependencies"})}),c(l,{flexDirection:"column",gap:1,children:[a(l,{children:o?c(s,{color:"green",children:["\u2713 ",e]}):a(Je,{label:e||"Preparing..."})}),!o&&t>0&&a(l,{width:50,children:a(Qe,{value:t})}),!o&&r&&r.length>0&&a(l,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,paddingY:0,minHeight:6,children:r.map((i,p)=>a(s,{color:"gray",wrap:"truncate",children:i},p))})]})]});var Pe=({onSelect:e})=>c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(s,{bold:!0,children:"Setup Mode"}),a(l,{marginTop:1,children:a(s,{color:"gray",children:"How do you want to run GAIA?"})}),a(l,{marginTop:1,children:a(Ke,{options:[{label:"Self-Host (Docker)",value:"selfhost"},{label:"Developer Mode (Local)",value:"developer"}],onChange:o=>e(o)})}),c(l,{marginTop:1,flexDirection:"column",children:[a(s,{color:"gray",dimColor:!0,children:"Self-Host: Run everything in Docker containers (recommended for deployment)"}),a(s,{color:"gray",dimColor:!0,children:"Developer: Run backend locally with Docker services (recommended for contributing)"})]})]}),De=({onSelect:e})=>c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(s,{bold:!0,children:"Environment Variables Setup"}),a(l,{marginTop:1,children:a(s,{color:"gray",children:"Choose how you want to configure environment variables:"})}),a(l,{marginTop:1,children:a(Ke,{options:[{label:"Manual Setup (Recommended)",value:"manual"},{label:"Infisical (Advanced)",value:"infisical"}],onChange:o=>e(o)})}),c(l,{marginTop:1,flexDirection:"column",children:[a(s,{color:"gray",dimColor:!0,children:"Manual Setup: Configure variables interactively (recommended for most users)"}),a(s,{color:"gray",dimColor:!0,children:"Infisical: All secrets managed in Infisical dashboard (requires pre-configuration)"})]})]}),Re=({onSubmit:e})=>{let[t,o]=L({INFISICAL_TOKEN:"",INFISICAL_PROJECT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET:""}),[r,n]=L(0),[i,p]=L(null),u=[{key:"INFISICAL_TOKEN",description:"Service token from project settings (st.xxx...)"},{key:"INFISICAL_PROJECT_ID",description:"Found in your Infisical project settings"},{key:"INFISICAL_MACHINE_IDENTITY_CLIENT_ID",description:"From Access Control \u2192 Machine Identities"},{key:"INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET",description:"Generated when creating the machine identity"}];J((f,g)=>{if(g.tab||g.downArrow)n(d=>d<u.length-1?d+1:d);else if(g.upArrow)n(d=>d>0?d-1:d);else if(g.return){if(r<u.length-1){n(y=>y+1);return}let d=u.filter(y=>!t[y.key].trim());if(d.length>0){p(`Required: ${d.map(h=>h.key).join(", ")}`);let y=u.findIndex(h=>!t[h.key].trim());y>=0&&n(y);return}e(t)}});let m=u[r];return c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(l,{marginBottom:1,children:a(s,{bold:!0,color:S,children:"Infisical Configuration"})}),a(l,{marginBottom:1,borderStyle:"single",borderColor:"cyan",paddingX:1,children:a(s,{color:"cyan",children:"All environment variables (API keys, auth secrets, etc.) must be configured in your Infisical project. Only Infisical credentials will be stored locally."})}),c(l,{marginBottom:1,flexDirection:"column",children:[a(s,{color:"gray",children:"Configure your Infisical credentials."}),c(s,{color:"gray",dimColor:!0,children:["Visit"," ",a(s,{color:"cyan",underline:!0,children:"app.infisical.com"})," ","to get these values."]})]}),u.map((f,g)=>{let d=f.key.includes("SECRET")||f.key.includes("TOKEN");return c(l,{flexDirection:"column",marginBottom:1,children:[a(l,{children:c(s,{color:g===r?S:"white",children:[g===r?"\u25B8 ":" ",f.key,":"]})}),a(l,{marginLeft:2,children:a(s,{color:"gray",dimColor:!0,children:f.description})}),g===r?a(l,{marginLeft:2,children:a(se,{value:t[f.key],onChange:y=>{o(h=>({...h,[f.key]:y})),p(null)},placeholder:"Enter value...",mask:d?"*":void 0})}):a(l,{marginLeft:2,children:a(s,{color:t[f.key]?"green":"gray",children:t[f.key]?d?`\u2713 ${"*".repeat(8)}`:`\u2713 ${t[f.key]}`:"(not set)"})})]},f.key)}),i&&a(l,{marginTop:1,children:a(s,{color:"red",children:i})}),a(l,{marginTop:1,children:a(s,{color:"gray",dimColor:!0,children:"\u2191\u2193/Tab to navigate \u2022 Enter to confirm"})})]})},Be=({category:e,currentIndex:t,totalGroups:o,onSubmit:r})=>{let[n,i]=L(()=>{let y={};for(let h of e.variables)y[h.name]=h.defaultValue||"";return y}),[p,u]=L(0),[m,f]=L(null);de(()=>{let y={};for(let h of e.variables)y[h.name]=h.defaultValue||"";i(y),u(0),f(null)},[e.name]),J((y,h)=>{if(h.tab||h.downArrow)u(x=>x<e.variables.length-1?x+1:x);else if(h.upArrow)u(x=>x>0?x-1:x);else if(h.escape){let x=e.variables.filter(v=>v.required&&!n[v.name]?.trim());if(x.length>0){f(`Required fields cannot be skipped: ${x.map(v=>v.name).join(", ")}`);return}r(n)}});let g=()=>{if(p<e.variables.length-1)u(p+1);else{let y=e.variables.filter(h=>h.required&&!n[h.name]?.trim());if(y.length>0){f(`Required fields are missing: ${y.map(h=>h.name).join(", ")}`);return}f(null),r(n)}},d=e.variables.some(y=>y.required);return c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:m?"red":S,children:[c(l,{justifyContent:"space-between",children:[c(s,{bold:!0,children:["Configure ",e.name]}),c(s,{color:"gray",children:["Group ",t+1," / ",o]})]}),c(l,{marginTop:1,flexDirection:"column",children:[c(l,{children:[c(s,{color:"cyan",bold:!0,children:["Purpose:"," "]}),a(s,{color:"white",children:e.description})]}),e.affectedFeatures&&c(l,{children:[c(s,{color:"cyan",bold:!0,children:["Affects:"," "]}),a(s,{color:"gray",children:e.affectedFeatures})]}),e.docsUrl&&c(l,{marginTop:1,children:[a(s,{color:"green",children:"\u{1F4D6} Docs: "}),a(s,{color:"blue",underline:!0,children:e.docsUrl})]})]}),a(l,{marginTop:1,flexDirection:"column",children:e.variables.map((y,h)=>{let x=h===p,v=!!y.defaultValue;return c(l,{flexDirection:"column",marginBottom:1,children:[c(l,{children:[c(s,{color:x?S:"gray",bold:x,children:[x?"\u279C ":" ",y.name]}),y.required&&c(s,{color:"red",bold:!0,children:[" ","*"]}),v&&!x&&c(s,{color:"gray",dimColor:!0,children:[" ","(default: ",y.defaultValue,")"]})]}),x&&a(l,{marginLeft:2,children:a(se,{value:n[y.name]||"",onChange:T=>{i(C=>({...C,[y.name]:T})),m&&f(null)},onSubmit:g,placeholder:v?`Default: ${y.defaultValue}`:y.required?"Enter a value (required)":"Press Enter to skip"})})]},y.name)})}),m&&a(l,{marginTop:1,children:c(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),a(l,{marginTop:1,flexDirection:"column",children:c(s,{color:"gray",dimColor:!0,children:["\u21B5 Enter to next field \u2022 Tab/\u2193 move down \u2022 \u2191 move up",!d&&" \u2022 ESC skip group"]})})]})},Ae=({alternatives:e,onSubmit:t})=>{let[o,r]=L(new Set),[n,i]=L({}),[p,u]=L(0),[m,f]=L(null);de(()=>{let T={};for(let C of e)for(let I of C.variables)T[I.name]=I.defaultValue||"";i(T)},[e]);let g=[];for(let T=0;T<e.length;T++)if(g.push({type:"provider",categoryIndex:T}),o.has(T)){let C=e[T];if(C)for(let I=0;I<C.variables.length;I++)g.push({type:"field",categoryIndex:T,fieldIndex:I})}g.push({type:"submit"});let d=g[p],y=d?.type==="field",h=d?.type==="submit";J((T,C)=>{let I=Math.min(p,g.length-1);if(I!==p){u(I);return}if(y)C.upArrow?u(E=>Math.max(0,E-1)):(C.downArrow||C.tab)&&u(E=>Math.min(g.length-1,E+1));else if(h)C.upArrow?u(E=>Math.max(0,E-1)):(C.return||T===" ")&&v();else if(C.upArrow)u(E=>Math.max(0,E-1));else if(C.downArrow||C.tab)u(E=>Math.min(g.length-1,E+1));else if((C.return||T===" ")&&d?.type==="provider"){let E=d.categoryIndex;r(V=>{let R=new Set(V);return R.has(E)?R.delete(E):R.add(E),R}),m&&f(null)}});let x=()=>{m&&f(null),u(T=>Math.min(g.length-1,T+1))},v=()=>{let T=[],C={};for(let I of o){let E=e[I];if(!E)continue;if(E.variables.some(R=>n[R.name]?.trim())){T.push(E.name);for(let R of E.variables){let le=n[R.name];le&&(C[R.name]=le)}}}if(T.length===0){o.size===0?f("Enable at least one provider (press Space or Enter)"):f("Enter a value for at least one field");return}t(T,C)};return c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:m?"red":S,children:[c(l,{justifyContent:"space-between",children:[a(s,{bold:!0,children:"Configure AI Provider"}),a(s,{color:"yellow",children:"* At least one required"})]}),a(l,{marginTop:1,children:a(s,{color:"gray",children:"Enable and configure at least one AI provider below:"})}),a(l,{marginTop:1,flexDirection:"column",children:e.map((T,C)=>{let I=o.has(C),E=g.findIndex(R=>R.type==="provider"&&R.categoryIndex===C),V=p===E;return c(l,{flexDirection:"column",marginBottom:1,children:[c(l,{children:[a(s,{color:V?S:void 0,bold:V,children:V?"\u279C ":" "}),a(s,{color:I?"green":"gray",children:I?"[\u2714]":"[ ]"}),c(s,{color:I?S:"gray",bold:I,children:[" ",T.name]}),T.description&&c(s,{color:"gray",dimColor:!0,children:[" ","- ",T.description]})]}),V&&T.docsUrl&&c(l,{marginLeft:6,children:[a(s,{color:"yellow",children:"\u{1F4D6} "}),a(s,{color:"blue",underline:!0,children:T.docsUrl})]}),I&&a(l,{marginLeft:4,flexDirection:"column",marginTop:1,children:T.variables.map((R,le)=>{let Mt=g.findIndex(ae=>ae.type==="field"&&ae.categoryIndex===C&&ae.fieldIndex===le),Z=p===Mt,Ve=!!R.defaultValue,Te=n[R.name]||"";return c(l,{flexDirection:"column",marginBottom:1,children:[c(l,{children:[c(s,{color:Z?S:"gray",bold:Z,children:[Z?" \u279C ":" ",R.name]}),!Z&&Te&&a(s,{color:"green",children:" \u2713"}),!Z&&!Te&&Ve&&c(s,{color:"gray",dimColor:!0,children:[" ","(default: ",R.defaultValue,")"]})]}),Z&&a(l,{marginLeft:4,children:a(se,{value:Te,onChange:ae=>{i(Nt=>({...Nt,[R.name]:ae})),m&&f(null)},onSubmit:x,placeholder:Ve?`Default: ${R.defaultValue}`:"Enter value..."})})]},R.name)})})]},T.name)})}),m&&a(l,{marginTop:1,children:c(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),c(l,{marginTop:1,children:[a(s,{color:h?S:void 0,bold:h,children:h?"\u279C ":" "}),a(l,{borderStyle:"round",borderColor:h?S:"gray",paddingX:2,children:a(s,{color:h?S:"gray",bold:h,children:"Continue \u2192"})})]}),a(l,{marginTop:1,children:a(s,{color:"gray",dimColor:!0,children:"\u2191/\u2193 navigate \u2022 Space/Enter toggle/select \u2022 Tab skip field"})})]})},ke=({currentVar:e,currentIndex:t,totalCount:o,onSubmit:r,onSkip:n})=>{let[i,p]=L(e.defaultValue||""),[u,m]=L(null);de(()=>{p(e.defaultValue||""),m(null)},[e.name]),J((d,y)=>{if(y.escape){if(e.required&&!i.trim()){m("This field is required and cannot be skipped");return}n()}});let f=d=>{if(e.required&&!d.trim()){m("This field is required");return}m(null),r(d)},g=!!e.defaultValue;return c(l,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:u?"red":S,children:[c(l,{justifyContent:"space-between",children:[a(s,{bold:!0,children:"Configure Environment Variables"}),c(s,{color:"gray",children:[t+1," / ",o]})]}),c(l,{marginTop:1,flexDirection:"column",children:[c(l,{children:[a(s,{color:S,bold:!0,children:e.name}),e.required?c(s,{color:"red",bold:!0,children:[" ","* required"]}):c(s,{color:"gray",dimColor:!0,children:[" ","(optional)"]})]}),c(l,{marginTop:1,children:[c(s,{color:"cyan",bold:!0,children:["Category:"," "]}),a(s,{color:"white",children:e.category})]}),c(l,{children:[c(s,{color:"cyan",bold:!0,children:["Purpose:"," "]}),a(s,{color:"white",children:e.description})]}),e.affectedFeatures&&c(l,{children:[c(s,{color:"cyan",bold:!0,children:["Affects:"," "]}),a(s,{color:"gray",children:e.affectedFeatures})]}),e.docsUrl&&c(l,{marginTop:1,children:[a(s,{color:"green",children:"\u{1F4D6} Docs: "}),a(s,{color:"blue",underline:!0,children:e.docsUrl})]}),g&&c(l,{marginTop:1,children:[c(s,{color:"green",bold:!0,children:["Default:"," "]}),a(s,{color:"white",children:e.defaultValue})]})]}),c(l,{marginTop:1,children:[a(s,{color:S,children:"\u279C "}),a(se,{value:i,onChange:d=>{p(d),u&&m(null)},onSubmit:f,placeholder:g?"Press Enter to use default":e.required?"Enter a value (required)":"Press Enter to skip"})]}),u&&a(l,{marginTop:1,children:c(s,{color:"red",bold:!0,children:["\u26A0 ",u]})}),a(l,{marginTop:1,flexDirection:"column",children:e.required?a(s,{color:"yellow",dimColor:!0,children:"\u21B5 Enter to confirm (required field)"}):g?a(s,{color:"green",dimColor:!0,children:"\u21B5 Enter to use default \u2022 ESC to skip"}):a(s,{color:"gray",dimColor:!0,children:"\u21B5 Enter to confirm \u2022 ESC to skip"})})]})},ze=({store:e})=>{let[t,o]=L(e.currentState);return de(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),c(pe,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&a(Ht,{onConfirm:()=>e.submitInput(!0)}),t.step==="Prerequisites"&&t.data.checks&&c(l,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:S,children:[a(s,{bold:!0,children:"System Checks"}),c(l,{flexDirection:"column",marginTop:1,children:[a(Ee,{label:"Git",status:t.data.checks.git}),a(Ee,{label:"Docker",status:t.data.checks.docker}),a(Ee,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&a(Wt,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="repo_path"&&a(Ut,{defaultValue:t.inputRequest.meta.default,onSubmit:r=>e.submitInput(r)}),t.step==="Repository Setup"&&c(l,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:S,children:[a(s,{bold:!0,children:"Cloning Repository"}),c(l,{marginTop:1,flexDirection:"column",children:[a(Qe,{value:t.data.repoProgress||0}),t.data.repoPhase&&a(l,{marginTop:1,children:a(s,{color:"gray",children:t.data.repoPhase})})]})]}),t.inputRequest?.id==="setup_mode"&&a(Pe,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&a(De,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&a(Re,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&a(ke,{categories:t.data.envCategories||[],currentVar:t.data.currentEnvVar,currentIndex:t.data.envVarIndex||0,totalCount:t.data.envVarTotal||0,onSubmit:r=>e.submitInput(r),onSkip:()=>e.submitInput("")}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_group"&&t.data.currentEnvGroup&&a(Be,{category:t.data.currentEnvGroup,currentIndex:t.data.envGroupIndex||0,totalGroups:t.data.envGroupTotal||0,onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_alternatives"&&t.data.alternativeGroups&&a(Ae,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Finished"&&a(Xt,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput(!0)}),(t.step==="Install Tools"||t.step==="Project Setup")&&a(Yt,{title:t.step==="Install Tools"?"Installing Tools":"Project Setup",phase:t.data.dependencyPhase||"",progress:t.data.dependencyProgress||0,isComplete:t.step==="Install Tools"?t.data.toolComplete||!1:t.data.dependencyComplete||!1,logs:t.data.dependencyLogs||[]}),t.error&&a(l,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:c(s,{color:"red",children:["Error: ",t.error.message]})})]})};import{Spinner as Qt}from"@inkjs/ui";import{Box as G,Text as F,useInput as Kt}from"ink";import{useEffect as Jt,useState as zt}from"react";import{jsx as N,jsxs as A}from"react/jsx-runtime";var Ze=({store:e,command:t})=>{let[o,r]=zt(e.currentState);Jt(()=>{let i=()=>r({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),Kt((i,p)=>{(p.return||p.escape)&&(o.data.started||o.data.stopped||o.error)&&e.submitInput("exit")});let n=t==="start";return A(G,{flexDirection:"column",width:"100%",children:[N(ee,{}),(o.step==="Starting"||o.step==="Stopping")&&A(G,{flexDirection:"column",marginTop:1,paddingX:2,borderStyle:"round",borderColor:S,children:[N(Qt,{label:o.status||"Working..."}),o.data.repoPath&&N(G,{marginTop:1,children:A(F,{color:"gray",children:["Repository: ",o.data.repoPath]})}),o.data.setupMode&&N(G,{children:A(F,{color:"gray",children:["Mode: ",o.data.setupMode]})})]}),o.step==="Running"&&o.data.started&&A(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:"green",children:[A(F,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),o.data.setupMode!=="developer"&&A(G,{marginTop:1,flexDirection:"column",children:[A(F,{children:["Web:"," ",A(F,{color:"cyan",bold:!0,children:["http://localhost:",o.data.webPort||3e3]})]}),A(F,{children:["API:"," ",A(F,{color:"cyan",bold:!0,children:["http://localhost:",o.data.apiPort||8e3]})]})]}),o.data.setupMode==="developer"&&A(G,{marginTop:1,flexDirection:"column",children:[N(F,{color:"gray",children:"Dev servers started in background."}),A(F,{color:"gray",children:["Logs: ",N(F,{color:S,children:"dev-start.log"})," in your repo root."]}),A(F,{color:"gray",children:["Run ",N(F,{color:S,children:"gaia stop"})," to shut down."]})]}),N(G,{marginTop:1,children:N(F,{dimColor:!0,children:"Press Enter to exit"})})]}),o.step==="Stopped"&&o.data.stopped&&A(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:S,children:[A(F,{color:S,bold:!0,children:["\u2713"," All GAIA services stopped."]}),N(G,{marginTop:1,children:N(F,{dimColor:!0,children:"Press Enter to exit"})})]}),o.error&&A(G,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[A(F,{color:"red",children:["Error: ",o.error.message]}),N(G,{marginTop:1,children:N(F,{dimColor:!0,children:"Press Enter to exit"})})]})]})};import{ProgressBar as Zt,Spinner as Fe}from"@inkjs/ui";import{Box as D,Text as w,useInput as et}from"ink";import{useEffect as er,useState as tr}from"react";import{jsx as b,jsxs as B}from"react/jsx-runtime";var tt=({store:e})=>{let[t,o]=tr(e.currentState);return er(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),B(pe,{status:t.status,step:t.step,steps:Ye,children:[t.step==="Detect Repo"&&B(D,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:S,children:[b(w,{bold:!0,children:"Detecting GAIA Repository"}),b(D,{marginTop:1,children:b(Fe,{label:"Searching for repository..."})}),t.data.repoPath&&b(D,{marginTop:1,children:B(w,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&B(D,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:S,children:[b(w,{bold:!0,children:"System Checks"}),B(D,{flexDirection:"column",marginTop:1,children:[b(_e,{label:"Git",status:t.data.checks.git}),b(_e,{label:"Docker",status:t.data.checks.docker}),b(_e,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&b(rr,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="setup_mode"&&b(Pe,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&b(De,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&b(Re,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&b(ke,{categories:t.data.envCategories||[],currentVar:t.data.currentEnvVar,currentIndex:t.data.envVarIndex||0,totalCount:t.data.envVarTotal||0,onSubmit:r=>e.submitInput(r),onSkip:()=>e.submitInput("")}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_group"&&t.data.currentEnvGroup&&b(Be,{category:t.data.currentEnvGroup,currentIndex:t.data.envGroupIndex||0,totalGroups:t.data.envGroupTotal||0,onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_alternatives"&&t.data.alternativeGroups&&b(Ae,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Project Setup"&&B(D,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[b(D,{marginBottom:1,children:b(w,{bold:!0,color:S,children:"Project Setup"})}),B(D,{flexDirection:"column",gap:1,children:[b(D,{children:t.data.dependencyComplete?B(w,{color:"green",children:["\u2713"," ",t.data.dependencyPhase]}):b(Fe,{label:t.data.dependencyPhase||"Preparing..."})}),!t.data.dependencyComplete&&t.data.dependencyProgress>0&&b(D,{width:50,children:b(Zt,{value:t.data.dependencyProgress})}),!t.data.dependencyComplete&&t.data.dependencyLogs?.length>0&&b(D,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,minHeight:6,children:t.data.dependencyLogs.map((r,n)=>b(w,{color:"gray",wrap:"truncate",children:r},n))})]})]}),t.step==="Finished"&&b(or,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,onConfirm:()=>e.submitInput(!0)}),t.error&&b(D,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:B(w,{color:"red",children:["Error: ",t.error.message]})})]})},_e=({label:e,status:t})=>B(D,{children:[b(D,{marginRight:1,children:t==="pending"?b(Fe,{type:"dots"}):t==="success"?b(w,{color:S,children:"\u2714"}):t==="error"?b(w,{color:"red",children:"\u2716"}):b(w,{color:"yellow",children:"\u26A0"})}),b(w,{children:e})]}),rr=({portResults:e,onAccept:t,onAbort:o})=>(et((r,n)=>{n.return?t():n.escape&&o()}),B(D,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[b(w,{bold:!0,color:"yellow",children:"Port Conflicts Detected"}),e.map(r=>B(D,{children:[B(w,{color:r.available?"green":"red",children:[r.available?"\u2714":"\u2716"," "]}),B(w,{children:[r.service," (:",r.port,")"]}),!r.available&&B(w,{color:"gray",children:[" ","- in use",r.usedBy?` by ${r.usedBy}`:"",r.alternative?` (alt: :${r.alternative})`:""]})]},r.port)),b(D,{marginTop:1,children:B(w,{children:[b(w,{color:"green",bold:!0,children:"Enter"})," continue ",b(w,{color:"yellow",bold:!0,children:"Escape"})," abort"]})})]})),or=({setupMode:e,repoPath:t,onConfirm:o})=>(et((i,p)=>{p.return&&o()}),B(D,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:S,padding:1,children:[b(w,{color:S,bold:!0,children:"Setup Complete!"}),B(D,{marginTop:1,flexDirection:"column",children:[b(w,{bold:!0,children:"To start GAIA, run:"}),B(D,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[B(w,{color:"cyan",children:["$ cd ",t||"."]}),b(w,{color:"cyan",children:"$ gaia start"})]}),b(D,{marginTop:1,children:b(w,{color:"gray",dimColor:!0,children:(e||"developer")==="selfhost"?"Runs: docker compose --profile all up -d (background)":"Runs: mise dev (interactive \u2014 keep terminal open)"})})]}),b(we,{}),b(D,{marginTop:1,children:b(w,{dimColor:!0,children:"Press Enter to exit"})})]}));import{Spinner as nr}from"@inkjs/ui";import{Box as k,Text as _,useInput as ar}from"ink";import{useEffect as rt,useState as ot}from"react";import{jsx as P,jsxs as M}from"react/jsx-runtime";var nt=({store:e})=>{let[t,o]=ot(e.currentState),[r,n]=ot(!1);return rt(()=>{let i=()=>o({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),rt(()=>{t.step==="Results"&&n(!1)},[t.step]),ar((i,p)=>{(p.return||p.escape)&&t.step==="Results"&&e.submitInput("exit"),i==="r"&&t.step==="Results"&&t.data.refreshable&&!r&&(n(!0),e.submitInput("refresh"))}),M(k,{flexDirection:"column",width:"100%",children:[P(ee,{}),t.step==="Checking"&&P(k,{marginTop:1,children:P(nr,{label:t.data.services?"Refreshing service health...":"Checking service health..."})}),t.step==="Results"&&t.data.services&&M(k,{flexDirection:"column",children:[M(k,{flexDirection:"column",borderStyle:"round",borderColor:S,paddingX:2,paddingY:1,children:[P(_,{bold:!0,color:S,children:"GAIA Service Status"}),M(k,{marginTop:1,flexDirection:"column",children:[M(k,{children:[P(k,{width:22,children:P(_,{bold:!0,children:"Service"})}),P(k,{width:10,children:P(_,{bold:!0,children:"Status"})}),P(k,{width:10,children:P(_,{bold:!0,children:"Latency"})})]}),P(_,{color:"gray",children:"\u2500".repeat(42)}),t.data.services.map(i=>M(k,{children:[P(k,{width:22,children:M(_,{children:[i.name," (:",i.port,")"]})}),P(k,{width:10,children:P(_,{color:i.status==="up"?"green":"red",bold:!0,children:i.status==="up"?"\u2713 UP":"\u2717 DOWN"})}),P(k,{width:10,children:P(_,{color:"gray",children:i.latency?`${i.latency}ms`:"--"})})]},i.name))]})]}),t.data.docker&&M(k,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:2,paddingY:1,marginTop:1,children:[P(_,{bold:!0,children:"Docker Containers"}),M(_,{color:"gray",children:["Docker:"," ",t.data.docker.running?P(_,{color:"green",children:"Running"}):P(_,{color:"red",children:"Not running"})]}),t.data.docker.containers?.length>0&&P(k,{marginTop:1,flexDirection:"column",children:t.data.docker.containers.map(i=>M(k,{children:[M(_,{color:i.status==="running"?"green":"red",children:[i.status==="running"?"\u2713":"\u2717"," "]}),P(_,{children:i.name}),i.health&&M(_,{color:"gray",children:[" (",i.health,")"]})]},i.name))})]}),P(k,{marginTop:1,children:M(_,{dimColor:!0,children:["Press Enter or Escape to exit \xB7 Press"," ",P(_,{color:S,children:"r"})," to refresh"]})})]}),t.error&&P(k,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:M(_,{color:"red",children:["Error: ",t.error.message]})})]})};import{jsx as O,jsxs as ce}from"react/jsx-runtime";var sr=["init","setup","status","start","stop"],Le=class extends ir.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?ce(me,{flexDirection:"column",padding:1,children:[O(z,{color:"red",bold:!0,children:"An unexpected error occurred:"}),O(z,{color:"red",children:this.state.error.message}),this.state.error.stack&&O(me,{marginTop:1,children:O(z,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},cr=({store:e,command:t})=>{switch(t){case"init":return O(ze,{store:e});case"setup":return O(tt,{store:e});case"status":return O(nt,{store:e});case"start":case"stop":return O(Ze,{store:e,command:t});default:return ce(me,{flexDirection:"column",padding:1,children:[ce(z,{color:"red",children:["Unknown command: ",t]}),ce(me,{marginTop:1,flexDirection:"column",children:[O(z,{bold:!0,children:"Available commands:"}),sr.map(o=>ce(z,{children:[" ",O(z,{color:"cyan",children:o})]},o))]})]})}},$=({store:e,command:t})=>O(Le,{children:O(cr,{store:e,command:t})});import{EventEmitter as lr}from"events";var Me=class extends lr{state={step:"init",status:"",error:null,data:{},inputRequest:null};inputResolver=null;get currentState(){return this.state}setStep(t){this.state.step=t,this.emit("change",this.state)}setStatus(t){this.state.status=t,this.emit("change",this.state)}setError(t){this.state.error=t,t!==null&&this.inputResolver&&(this.inputResolver(null),this.inputResolver=null,this.state.inputRequest=null),this.emit("change",this.state)}updateData(t,o){this.state.data={...this.state.data,[t]:o},this.emit("change",this.state)}waitForInput(t,o){return this.state.inputRequest={id:t,meta:o},this.emit("change",this.state),new Promise(r=>{this.inputResolver=r})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emit("change",this.state))}},j=()=>new Me;import*as ne from"fs";import*as ht from"path";import*as oe from"node:fs";import*as re from"node:path";import{execa as at}from"execa";var it={selfhost:{MONGO_DB:"mongodb://mongo:27017/gaia",REDIS_URL:"redis://redis:6379",POSTGRES_URL:"postgresql://postgres:postgres@postgres:5432/langgraph",CHROMADB_HOST:"chromadb",CHROMADB_PORT:"8000",RABBITMQ_URL:"amqp://guest:guest@rabbitmq:5672/"},developer:{MONGO_DB:"mongodb://localhost:27017/gaia",REDIS_URL:"redis://localhost:6379",POSTGRES_URL:"postgresql://postgres:postgres@localhost:5432/postgres",CHROMADB_HOST:"localhost",CHROMADB_PORT:"8080",RABBITMQ_URL:"amqp://guest:guest@localhost:5672/"}},st={selfhost:{HOST:"http://localhost:8000",FRONTEND_URL:"http://localhost:3000",GAIA_BACKEND_URL:"http://gaia-backend:80",SETUP_MODE:"selfhost"},developer:{HOST:"http://localhost:8000",FRONTEND_URL:"http://localhost:3000",GAIA_BACKEND_URL:"http://host.docker.internal:8000",SETUP_MODE:"developer"}};function Ne(e,t){return it[t][e]??st[t][e]}async function ct(e){let t=re.join(e,"apps/api/scripts/dump_config_schema.py"),o=re.join(e,"apps/api/app/config/settings_validator.py"),r=re.join(e,"apps/api/app/config/settings.py");if(!oe.existsSync(t))throw new Error("dump_config_schema.py not found in apps/api/scripts");try{try{let{stdout:n}=await at("python3",[t,o,r],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await at("python",[t,o,r],{cwd:e});return JSON.parse(n)}}catch(n){throw new Error(`Failed to parse settings schema: ${n.message}. Ensure python is installed.`)}}function lt(e){let t=re.join(e,"apps","web",".env.local"),o=oe.existsSync(t)?t:re.join(e,"apps","web",".env");if(!oe.existsSync(o))return[];let r=oe.readFileSync(o,"utf-8"),n=[],i="General";for(let p of r.split(`
|
|
3
|
-
`)){let u
|
|
4
|
-
`),"utf-8")}function
|
|
5
|
-
`),"utf-8")}var
|
|
6
|
-
`);for(let i of n)if(i.includes(`:${e}`)&&i.includes("LISTENING")){let
|
|
7
|
-
`);if(n.length>1)return n[1]?.split(/\s+/)?.[0]||void 0}catch{}}async function
|
|
8
|
-
`).filter(
|
|
9
|
-
|
|
10
|
-
`))
|
|
2
|
+
import{Command as Or}from"commander";import{render as wr}from"ink";import Dr from"react";import{Box as fe,Text as Z}from"ink";import sr from"react";import{ProgressBar as Ke,Select as Je,Spinner as ze}from"@inkjs/ui";import{Box as p,Text as s,useInput as z}from"ink";import ce from"ink-text-input";import{useEffect as me,useState as M}from"react";import{Box as se,Text as Ye}from"ink";var h="#00bbff";import{Box as qt,Text as Ce}from"ink";import{jsx as He,jsxs as We}from"react/jsx-runtime";var Xe=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:We(qt,{width:"100%",borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[We(Ce,{color:h,children:[He(Ce,{bold:!0,children:"Status:"})," ",t]}),He(Ce,{color:"white",dimColor:!0,children:e})]});import{Box as Ot}from"ink";import $t from"ink-big-text";import jt from"ink-gradient";import{jsx as Ee}from"react/jsx-runtime";var te=()=>Ee(Ot,{flexDirection:"column",marginTop:1,marginBottom:1,children:Ee(jt,{colors:[h,"#b0eaff",h],children:Ee($t,{text:"GAIA",font:"3d"})})});import{jsx as re,jsxs as pe}from"react/jsx-runtime";var Ut=["Welcome","Prerequisites","Repository Setup","Install Tools","Environment Setup","Project Setup","Finished"],Qe=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Vt=({currentStep:e,steps:t})=>{let o=t.indexOf(e);return re(se,{marginBottom:1,children:t.map((r,n)=>{let i=r===e,u=o>n;return pe(se,{marginRight:2,children:[pe(Ye,{color:i?h:u?"green":"gray",children:[u?"\u2713 ":i?"\u25CF ":"\u25CB ",r]}),n<t.length-1&&re(Ye,{color:"gray",children:" \u203A "})]},r)})})},de=({children:e,status:t,step:o,steps:r=Ut})=>pe(se,{flexDirection:"column",height:"100%",width:"100%",children:[pe(se,{flexGrow:1,flexDirection:"column",children:[re(te,{}),re(Vt,{currentStep:o,steps:r}),re(se,{flexDirection:"column",flexGrow:1,children:e})]}),re(Xe,{status:t,step:o})]});import{Fragment as po,jsx as a,jsxs as l}from"react/jsx-runtime";var we=({label:e,status:t})=>l(p,{children:[a(p,{marginRight:1,children:t==="pending"?a(ze,{type:"dots"}):t==="success"?a(s,{color:h,children:"\u2714"}):t==="error"?a(s,{color:"red",children:"\u2716"}):a(s,{color:"yellow",children:"\u26A0"})}),a(s,{children:e})]}),Ht=({onConfirm:e})=>(z((t,o)=>{o.return&&e()}),l(p,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:h,children:[a(s,{bold:!0,children:"Welcome to the Interactive GAIA Setup"}),l(p,{flexDirection:"column",marginTop:1,marginBottom:1,children:[a(s,{children:"This wizard will guide you through the setup process:"}),a(s,{children:" 1. Check Prerequisites (Git, Docker, Mise)"}),a(s,{children:" 2. Clone Repository (from GitHub)"}),a(s,{children:" 3. Install Tools (node, python, uv via mise)"}),a(s,{children:" 4. Configure Env Vars (databases, API keys, etc.)"}),a(s,{children:" 5. Setup Project (install all dependencies)"})]}),a(s,{color:h,children:"Press Enter to start..."})]})),Wt=({portResults:e,onAccept:t,onAbort:o})=>{z((n,i)=>{i.return?t():i.escape&&o()});let r=e.filter(n=>!n.available);return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[a(p,{marginBottom:1,children:a(s,{bold:!0,color:"yellow",children:"Port Conflicts Detected"})}),e.map(n=>l(p,{children:[l(s,{color:n.available?"green":n.alternative?"yellow":"red",children:[n.available?"\u2714":n.alternative?"\u26A0":"\u2716"," "]}),l(s,{children:[n.service," (:",n.port,")"]}),!n.available&&l(s,{color:n.alternative?"gray":"red",children:[" ","- in use",n.usedBy?` by ${n.usedBy}`:"",n.alternative?` \u2192 will use :${n.alternative}`:" \u2014 NO ALTERNATIVE FOUND"]})]},n.port)),l(p,{marginTop:1,flexDirection:"column",children:[r.some(n=>!n.alternative)&&a(p,{borderStyle:"single",borderColor:"red",paddingX:1,marginBottom:1,children:a(s,{color:"red",children:"Some ports have no available alternative. Free them and retry."})}),!r.some(n=>!n.alternative)&&r.some(n=>n.alternative)&&a(s,{color:"gray",children:"Alternative ports will be used for conflicting services."}),a(p,{marginTop:1,children:l(s,{children:[a(s,{color:"green",bold:!0,children:"Enter"})," to continue with alternatives ",a(s,{color:"yellow",bold:!0,children:"Escape"})," to abort"]})})]})]})},Xt=({defaultValue:e,onSubmit:t})=>{let[o,r]=M(e);return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[a(s,{children:"Where should we clone the repository?"}),l(p,{children:[a(s,{color:h,children:"\u279C "}),a(ce,{value:o,onChange:r,onSubmit:t})]}),l(s,{color:"gray",children:["(Press Enter for default: ",e,")"]})]})},Yt=({setupMode:e,repoPath:t,portOverrides:o,onConfirm:r})=>{z((f,g)=>{g.return&&r()});let n=e||"developer",i=t||"./gaia",u=o?.[3e3]??3e3,m=o?.[8e3]??8e3;return l(p,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:h,padding:1,children:[a(s,{color:h,bold:!0,children:"You are all set!"}),l(p,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"To start GAIA, run:"}),l(p,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[l(s,{color:"cyan",children:["$ cd ",i]}),a(s,{color:"cyan",children:"$ gaia start"})]}),a(p,{marginTop:1,children:a(s,{color:"gray",dimColor:!0,children:n==="selfhost"?"Runs: docker compose --profile all up -d (background)":"Runs: mise dev (interactive \u2014 keep terminal open)"})})]}),l(p,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"Access GAIA at:"}),l(p,{marginLeft:2,flexDirection:"column",children:[l(s,{children:["Web:"," ",l(s,{color:"cyan",bold:!0,children:["http://localhost:",u]})]}),l(s,{children:["API:"," ",l(s,{color:"cyan",bold:!0,children:["http://localhost:",m]})]})]})]}),a(De,{}),a(p,{marginTop:1,children:a(s,{dimColor:!0,children:"Press Enter to exit"})})]})},De=()=>l(p,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"Available commands:"}),l(p,{marginLeft:2,flexDirection:"column",children:[l(s,{children:[l(s,{color:h,bold:!0,children:["gaia start"," "]}),a(s,{color:"gray",children:" Start all services"})]}),l(s,{children:[l(s,{color:h,bold:!0,children:["gaia stop"," "]}),a(s,{color:"gray",children:" Stop all services"})]}),l(s,{children:[a(s,{color:h,bold:!0,children:"gaia status"}),a(s,{color:"gray",children:" Check service health"})]}),l(s,{children:[l(s,{color:h,bold:!0,children:["gaia setup"," "]}),a(s,{color:"gray",children:" Reconfigure environment"})]})]})]}),Qt=({phase:e,progress:t,isComplete:o,logs:r,title:n})=>l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[a(p,{marginBottom:1,children:a(s,{bold:!0,color:h,children:n||"Installing Dependencies"})}),l(p,{flexDirection:"column",gap:1,children:[a(p,{children:o?l(s,{color:"green",children:["\u2713 ",e]}):a(ze,{label:e||"Preparing..."})}),!o&&t>0&&a(p,{width:50,children:a(Ke,{value:t})}),!o&&r&&r.length>0&&a(p,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,paddingY:0,minHeight:6,children:r.map((i,u)=>a(s,{color:"gray",wrap:"truncate",children:i},u))})]})]});var Pe=({onSelect:e})=>l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[a(s,{bold:!0,children:"Setup Mode"}),a(p,{marginTop:1,children:a(s,{color:"gray",children:"How do you want to run GAIA?"})}),a(p,{marginTop:1,children:a(Je,{options:[{label:"Self-Host (Docker)",value:"selfhost"},{label:"Developer Mode (Local)",value:"developer"}],onChange:o=>e(o)})}),l(p,{marginTop:1,flexDirection:"column",children:[a(s,{color:"gray",dimColor:!0,children:"Self-Host: Run everything in Docker containers (recommended for deployment)"}),a(s,{color:"gray",dimColor:!0,children:"Developer: Run backend locally with Docker services (recommended for contributing)"})]})]}),Re=({onSelect:e})=>l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[a(s,{bold:!0,children:"Environment Variables Setup"}),a(p,{marginTop:1,children:a(s,{color:"gray",children:"Choose how you want to configure environment variables:"})}),a(p,{marginTop:1,children:a(Je,{options:[{label:"Manual Setup (Recommended)",value:"manual"},{label:"Infisical (Advanced)",value:"infisical"}],onChange:o=>e(o)})}),l(p,{marginTop:1,flexDirection:"column",children:[a(s,{color:"gray",dimColor:!0,children:"Manual Setup: Configure variables interactively (recommended for most users)"}),a(s,{color:"gray",dimColor:!0,children:"Infisical: All secrets managed in Infisical dashboard (requires pre-configuration)"})]})]}),ke=({onSubmit:e})=>{let[t,o]=M({INFISICAL_TOKEN:"",INFISICAL_PROJECT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET:""}),[r,n]=M(0),[i,u]=M(null),m=[{key:"INFISICAL_TOKEN",description:"Service token from project settings (st.xxx...)"},{key:"INFISICAL_PROJECT_ID",description:"Found in your Infisical project settings"},{key:"INFISICAL_MACHINE_IDENTITY_CLIENT_ID",description:"From Access Control \u2192 Machine Identities"},{key:"INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET",description:"Generated when creating the machine identity"}];z((g,y)=>{if(y.tab||y.downArrow)n(x=>x<m.length-1?x+1:x);else if(y.upArrow)n(x=>x>0?x-1:x);else if(y.return){if(r<m.length-1){n(c=>c+1);return}let x=m.filter(c=>!t[c.key].trim());if(x.length>0){u(`Required: ${x.map(S=>S.key).join(", ")}`);let c=m.findIndex(S=>!t[S.key].trim());c>=0&&n(c);return}e(t)}});let f=m[r];return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[a(p,{marginBottom:1,children:a(s,{bold:!0,color:h,children:"Infisical Configuration"})}),a(p,{marginBottom:1,borderStyle:"single",borderColor:"cyan",paddingX:1,children:a(s,{color:"cyan",children:"All environment variables (API keys, auth secrets, etc.) must be configured in your Infisical project. Only Infisical credentials will be stored locally."})}),l(p,{marginBottom:1,flexDirection:"column",children:[a(s,{color:"gray",children:"Configure your Infisical credentials."}),l(s,{color:"gray",dimColor:!0,children:["Visit"," ",a(s,{color:"cyan",underline:!0,children:"app.infisical.com"})," ","to get these values."]})]}),m.map((g,y)=>{let x=g.key.includes("SECRET")||g.key.includes("TOKEN");return l(p,{flexDirection:"column",marginBottom:1,children:[a(p,{children:l(s,{color:y===r?h:"white",children:[y===r?"\u25B8 ":" ",g.key,":"]})}),a(p,{marginLeft:2,children:a(s,{color:"gray",dimColor:!0,children:g.description})}),y===r?a(p,{marginLeft:2,children:a(ce,{value:t[g.key],onChange:c=>{o(S=>({...S,[g.key]:c})),u(null)},placeholder:"Enter value...",mask:x?"*":void 0})}):a(p,{marginLeft:2,children:a(s,{color:t[g.key]?"green":"gray",children:t[g.key]?x?`\u2713 ${"*".repeat(8)}`:`\u2713 ${t[g.key]}`:"(not set)"})})]},g.key)}),i&&a(p,{marginTop:1,children:a(s,{color:"red",children:i})}),a(p,{marginTop:1,children:a(s,{color:"gray",dimColor:!0,children:"\u2191\u2193/Tab to navigate \u2022 Enter to confirm"})})]})},Be=({category:e,currentIndex:t,totalGroups:o,onSubmit:r})=>{let[n,i]=M(()=>{let c={};for(let S of e.variables)c[S.name]=S.defaultValue||"";return c}),[u,m]=M(0),[f,g]=M(null);me(()=>{let c={};for(let S of e.variables)c[S.name]=S.defaultValue||"";i(c),m(0),g(null)},[e.name]),z((c,S)=>{if(S.tab||S.downArrow)m(d=>d<e.variables.length-1?d+1:d);else if(S.upArrow)m(d=>d>0?d-1:d);else if(S.escape){let d=e.variables.filter(T=>T.required&&!n[T.name]?.trim());if(d.length>0){g(`Required fields cannot be skipped: ${d.map(T=>T.name).join(", ")}`);return}r(n)}});let y=()=>{if(u<e.variables.length-1)m(u+1);else{let c=e.variables.filter(S=>S.required&&!n[S.name]?.trim());if(c.length>0){g(`Required fields are missing: ${c.map(S=>S.name).join(", ")}`);return}g(null),r(n)}},x=e.variables.some(c=>c.required);return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:f?"red":h,children:[l(p,{justifyContent:"space-between",children:[l(s,{bold:!0,children:["Configure ",e.name]}),l(s,{color:"gray",children:["Group ",t+1," / ",o]})]}),l(p,{marginTop:1,flexDirection:"column",children:[l(p,{children:[l(s,{color:"cyan",bold:!0,children:["Purpose:"," "]}),a(s,{color:"white",children:e.description})]}),e.affectedFeatures&&l(p,{children:[l(s,{color:"cyan",bold:!0,children:["Affects:"," "]}),a(s,{color:"gray",children:e.affectedFeatures})]}),e.docsUrl&&l(p,{marginTop:1,children:[a(s,{color:"green",children:"\u{1F4D6} Docs: "}),a(s,{color:"blue",underline:!0,children:e.docsUrl})]})]}),a(p,{marginTop:1,flexDirection:"column",children:e.variables.map((c,S)=>{let d=S===u,T=!!c.defaultValue;return l(p,{flexDirection:"column",marginBottom:1,children:[l(p,{children:[l(s,{color:d?h:"gray",bold:d,children:[d?"\u279C ":" ",c.name]}),c.required&&l(s,{color:"red",bold:!0,children:[" ","*"]}),T&&!d&&l(s,{color:"gray",dimColor:!0,children:[" ","(default: ",c.defaultValue,")"]})]}),d&&a(p,{marginLeft:2,children:a(ce,{value:n[c.name]||"",onChange:b=>{i(I=>({...I,[c.name]:b})),f&&g(null)},onSubmit:y,placeholder:T?`Default: ${c.defaultValue}`:c.required?"Enter a value (required)":"Press Enter to skip"})})]},c.name)})}),f&&a(p,{marginTop:1,children:l(s,{color:"red",bold:!0,children:["\u26A0 ",f]})}),a(p,{marginTop:1,flexDirection:"column",children:l(s,{color:"gray",dimColor:!0,children:["\u21B5 Enter to next field \u2022 Tab/\u2193 move down \u2022 \u2191 move up",!x&&" \u2022 ESC skip group"]})})]})},Ae=({alternatives:e,onSubmit:t})=>{let[o,r]=M(new Set),[n,i]=M({}),[u,m]=M(0),[f,g]=M(null);me(()=>{let b={};for(let I of e)for(let C of I.variables)b[C.name]=C.defaultValue||"";i(b)},[e]);let y=[];for(let b=0;b<e.length;b++)if(y.push({type:"provider",categoryIndex:b}),o.has(b)){let I=e[b];if(I)for(let C=0;C<I.variables.length;C++)y.push({type:"field",categoryIndex:b,fieldIndex:C})}y.push({type:"submit"});let x=y[u],c=x?.type==="field",S=x?.type==="submit";z((b,I)=>{let C=Math.min(u,y.length-1);if(C!==u){m(C);return}if(c)I.upArrow?m(E=>Math.max(0,E-1)):(I.downArrow||I.tab)&&m(E=>Math.min(y.length-1,E+1));else if(S)I.upArrow?m(E=>Math.max(0,E-1)):(I.return||b===" ")&&T();else if(I.upArrow)m(E=>Math.max(0,E-1));else if(I.downArrow||I.tab)m(E=>Math.min(y.length-1,E+1));else if((I.return||b===" ")&&x?.type==="provider"){let E=x.categoryIndex;r(V=>{let R=new Set(V);return R.has(E)?R.delete(E):R.add(E),R}),f&&g(null)}});let d=()=>{f&&g(null),m(b=>Math.min(y.length-1,b+1))},T=()=>{let b=[],I={};for(let C of o){let E=e[C];if(!E)continue;if(E.variables.some(R=>n[R.name]?.trim())){b.push(E.name);for(let R of E.variables){let ue=n[R.name];ue&&(I[R.name]=ue)}}}if(b.length===0){o.size===0?g("Enable at least one provider (press Space or Enter)"):g("Enter a value for at least one field");return}t(b,I)};return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:f?"red":h,children:[l(p,{justifyContent:"space-between",children:[a(s,{bold:!0,children:"Configure AI Provider"}),a(s,{color:"yellow",children:"* At least one required"})]}),a(p,{marginTop:1,children:a(s,{color:"gray",children:"Enable and configure at least one AI provider below:"})}),a(p,{marginTop:1,flexDirection:"column",children:e.map((b,I)=>{let C=o.has(I),E=y.findIndex(R=>R.type==="provider"&&R.categoryIndex===I),V=u===E;return l(p,{flexDirection:"column",marginBottom:1,children:[l(p,{children:[a(s,{color:V?h:void 0,bold:V,children:V?"\u279C ":" "}),a(s,{color:C?"green":"gray",children:C?"[\u2714]":"[ ]"}),l(s,{color:C?h:"gray",bold:C,children:[" ",b.name]}),b.description&&l(s,{color:"gray",dimColor:!0,children:[" ","- ",b.description]})]}),V&&b.docsUrl&&l(p,{marginLeft:6,children:[a(s,{color:"yellow",children:"\u{1F4D6} "}),a(s,{color:"blue",underline:!0,children:b.docsUrl})]}),C&&a(p,{marginLeft:4,flexDirection:"column",marginTop:1,children:b.variables.map((R,ue)=>{let Nt=y.findIndex(ie=>ie.type==="field"&&ie.categoryIndex===I&&ie.fieldIndex===ue),ee=u===Nt,Ve=!!R.defaultValue,Ie=n[R.name]||"";return l(p,{flexDirection:"column",marginBottom:1,children:[l(p,{children:[l(s,{color:ee?h:"gray",bold:ee,children:[ee?" \u279C ":" ",R.name]}),!ee&&Ie&&a(s,{color:"green",children:" \u2713"}),!ee&&!Ie&&Ve&&l(s,{color:"gray",dimColor:!0,children:[" ","(default: ",R.defaultValue,")"]})]}),ee&&a(p,{marginLeft:4,children:a(ce,{value:Ie,onChange:ie=>{i(Gt=>({...Gt,[R.name]:ie})),f&&g(null)},onSubmit:d,placeholder:Ve?`Default: ${R.defaultValue}`:"Enter value..."})})]},R.name)})})]},b.name)})}),f&&a(p,{marginTop:1,children:l(s,{color:"red",bold:!0,children:["\u26A0 ",f]})}),l(p,{marginTop:1,children:[a(s,{color:S?h:void 0,bold:S,children:S?"\u279C ":" "}),a(p,{borderStyle:"round",borderColor:S?h:"gray",paddingX:2,children:a(s,{color:S?h:"gray",bold:S,children:"Continue \u2192"})})]}),a(p,{marginTop:1,children:a(s,{color:"gray",dimColor:!0,children:"\u2191/\u2193 navigate \u2022 Space/Enter toggle/select \u2022 Tab skip field"})})]})},_e=({currentVar:e,currentIndex:t,totalCount:o,onSubmit:r,onSkip:n})=>{let[i,u]=M(e.defaultValue||""),[m,f]=M(null);me(()=>{u(e.defaultValue||""),f(null)},[e.name]),z((x,c)=>{if(c.escape){if(e.required&&!i.trim()){f("This field is required and cannot be skipped");return}n()}});let g=x=>{if(e.required&&!x.trim()){f("This field is required");return}f(null),r(x)},y=!!e.defaultValue;return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:m?"red":h,children:[l(p,{justifyContent:"space-between",children:[a(s,{bold:!0,children:"Configure Environment Variables"}),l(s,{color:"gray",children:[t+1," / ",o]})]}),l(p,{marginTop:1,flexDirection:"column",children:[l(p,{children:[a(s,{color:h,bold:!0,children:e.name}),e.required?l(s,{color:"red",bold:!0,children:[" ","* required"]}):l(s,{color:"gray",dimColor:!0,children:[" ","(optional)"]})]}),l(p,{marginTop:1,children:[l(s,{color:"cyan",bold:!0,children:["Category:"," "]}),a(s,{color:"white",children:e.category})]}),l(p,{children:[l(s,{color:"cyan",bold:!0,children:["Purpose:"," "]}),a(s,{color:"white",children:e.description})]}),e.affectedFeatures&&l(p,{children:[l(s,{color:"cyan",bold:!0,children:["Affects:"," "]}),a(s,{color:"gray",children:e.affectedFeatures})]}),e.docsUrl&&l(p,{marginTop:1,children:[a(s,{color:"green",children:"\u{1F4D6} Docs: "}),a(s,{color:"blue",underline:!0,children:e.docsUrl})]}),y&&l(p,{marginTop:1,children:[l(s,{color:"green",bold:!0,children:["Default:"," "]}),a(s,{color:"white",children:e.defaultValue})]})]}),l(p,{marginTop:1,children:[a(s,{color:h,children:"\u279C "}),a(ce,{value:i,onChange:x=>{u(x),m&&f(null)},onSubmit:g,placeholder:y?"Press Enter to use default":e.required?"Enter a value (required)":"Press Enter to skip"})]}),m&&a(p,{marginTop:1,children:l(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),a(p,{marginTop:1,flexDirection:"column",children:e.required?a(s,{color:"yellow",dimColor:!0,children:"\u21B5 Enter to confirm (required field)"}):y?a(s,{color:"green",dimColor:!0,children:"\u21B5 Enter to use default \u2022 ESC to skip"}):a(s,{color:"gray",dimColor:!0,children:"\u21B5 Enter to confirm \u2022 ESC to skip"})})]})},Ze=({store:e})=>{let[t,o]=M(e.currentState);return me(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),l(de,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&a(Ht,{onConfirm:()=>e.submitInput(!0)}),t.step==="Prerequisites"&&t.data.checks&&l(p,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:h,children:[a(s,{bold:!0,children:"System Checks"}),l(p,{flexDirection:"column",marginTop:1,children:[a(we,{label:"Git",status:t.data.checks.git}),a(we,{label:"Docker",status:t.data.checks.docker}),a(we,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&a(Wt,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="repo_path"&&a(Xt,{defaultValue:t.inputRequest.meta.default,onSubmit:r=>e.submitInput(r)}),t.step==="Repository Setup"&&l(p,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:h,children:[a(s,{bold:!0,children:"Cloning Repository"}),l(p,{marginTop:1,flexDirection:"column",children:[a(Ke,{value:t.data.repoProgress||0}),t.data.repoPhase&&a(p,{marginTop:1,children:a(s,{color:"gray",children:t.data.repoPhase})})]})]}),t.inputRequest?.id==="setup_mode"&&a(Pe,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&a(Re,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&a(ke,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&a(_e,{categories:t.data.envCategories||[],currentVar:t.data.currentEnvVar,currentIndex:t.data.envVarIndex||0,totalCount:t.data.envVarTotal||0,onSubmit:r=>e.submitInput(r),onSkip:()=>e.submitInput("")}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_group"&&t.data.currentEnvGroup&&a(Be,{category:t.data.currentEnvGroup,currentIndex:t.data.envGroupIndex||0,totalGroups:t.data.envGroupTotal||0,onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_alternatives"&&t.data.alternativeGroups&&a(Ae,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Finished"&&a(Yt,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput(!0)}),(t.step==="Install Tools"||t.step==="Project Setup")&&a(Qt,{title:t.step==="Install Tools"?"Installing Tools":"Project Setup",phase:t.data.dependencyPhase||"",progress:t.data.dependencyProgress||0,isComplete:t.step==="Install Tools"?t.data.toolComplete||!1:t.data.dependencyComplete||!1,logs:t.data.dependencyLogs||[]}),t.error&&a(p,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:l(s,{color:"red",children:["Error: ",t.error.message]})})]})};import{Spinner as Kt}from"@inkjs/ui";import{Box as G,Text as L,useInput as Jt}from"ink";import{useEffect as zt,useState as Zt}from"react";import{jsx as N,jsxs as B}from"react/jsx-runtime";var et=({store:e,command:t})=>{let[o,r]=Zt(e.currentState);zt(()=>{let i=()=>r({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),Jt((i,u)=>{(u.return||u.escape)&&(o.data.started||o.data.stopped||o.error)&&e.submitInput("exit")});let n=t==="start";return B(G,{flexDirection:"column",width:"100%",children:[N(te,{}),(o.step==="Starting"||o.step==="Stopping")&&B(G,{flexDirection:"column",marginTop:1,paddingX:2,borderStyle:"round",borderColor:h,children:[N(Kt,{label:o.status||"Working..."}),o.data.repoPath&&N(G,{marginTop:1,children:B(L,{color:"gray",children:["Repository: ",o.data.repoPath]})}),o.data.setupMode&&N(G,{children:B(L,{color:"gray",children:["Mode: ",o.data.setupMode]})})]}),o.step==="Running"&&o.data.started&&B(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:"green",children:[B(L,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),o.data.setupMode!=="developer"&&B(G,{marginTop:1,flexDirection:"column",children:[B(L,{children:["Web:"," ",B(L,{color:"cyan",bold:!0,children:["http://localhost:",o.data.webPort||3e3]})]}),B(L,{children:["API:"," ",B(L,{color:"cyan",bold:!0,children:["http://localhost:",o.data.apiPort||8e3]})]})]}),o.data.setupMode==="developer"&&B(G,{marginTop:1,flexDirection:"column",children:[N(L,{color:"gray",children:"Dev servers started in background."}),B(L,{color:"gray",children:["Logs: ",N(L,{color:h,children:"dev-start.log"})," in your repo root."]}),B(L,{color:"gray",children:["Run ",N(L,{color:h,children:"gaia stop"})," to shut down."]})]}),N(G,{marginTop:1,children:N(L,{dimColor:!0,children:"Press Enter to exit"})})]}),o.step==="Stopped"&&o.data.stopped&&B(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:h,children:[B(L,{color:h,bold:!0,children:["\u2713"," All GAIA services stopped."]}),N(G,{marginTop:1,children:N(L,{dimColor:!0,children:"Press Enter to exit"})})]}),o.error&&B(G,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[B(L,{color:"red",children:["Error: ",o.error.message]}),N(G,{marginTop:1,children:N(L,{dimColor:!0,children:"Press Enter to exit"})})]})]})};import{ProgressBar as er,Spinner as Me}from"@inkjs/ui";import{Box as P,Text as w,useInput as tt}from"ink";import{useEffect as tr,useState as rr}from"react";import{jsx as v,jsxs as k}from"react/jsx-runtime";var rt=({store:e})=>{let[t,o]=rr(e.currentState);return tr(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),k(de,{status:t.status,step:t.step,steps:Qe,children:[t.step==="Detect Repo"&&k(P,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:h,children:[v(w,{bold:!0,children:"Detecting GAIA Repository"}),v(P,{marginTop:1,children:v(Me,{label:"Searching for repository..."})}),t.data.repoPath&&v(P,{marginTop:1,children:k(w,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&k(P,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:h,children:[v(w,{bold:!0,children:"System Checks"}),k(P,{flexDirection:"column",marginTop:1,children:[v(Le,{label:"Git",status:t.data.checks.git}),v(Le,{label:"Docker",status:t.data.checks.docker}),v(Le,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&v(or,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="setup_mode"&&v(Pe,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&v(Re,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&v(ke,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&v(_e,{categories:t.data.envCategories||[],currentVar:t.data.currentEnvVar,currentIndex:t.data.envVarIndex||0,totalCount:t.data.envVarTotal||0,onSubmit:r=>e.submitInput(r),onSkip:()=>e.submitInput("")}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_group"&&t.data.currentEnvGroup&&v(Be,{category:t.data.currentEnvGroup,currentIndex:t.data.envGroupIndex||0,totalGroups:t.data.envGroupTotal||0,onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_alternatives"&&t.data.alternativeGroups&&v(Ae,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Project Setup"&&k(P,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[v(P,{marginBottom:1,children:v(w,{bold:!0,color:h,children:"Project Setup"})}),k(P,{flexDirection:"column",gap:1,children:[v(P,{children:t.data.dependencyComplete?k(w,{color:"green",children:["\u2713"," ",t.data.dependencyPhase]}):v(Me,{label:t.data.dependencyPhase||"Preparing..."})}),!t.data.dependencyComplete&&t.data.dependencyProgress>0&&v(P,{width:50,children:v(er,{value:t.data.dependencyProgress})}),!t.data.dependencyComplete&&t.data.dependencyLogs?.length>0&&v(P,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,minHeight:6,children:t.data.dependencyLogs.map((r,n)=>v(w,{color:"gray",wrap:"truncate",children:r},n))})]})]}),t.step==="Finished"&&v(nr,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,onConfirm:()=>e.submitInput(!0)}),t.error&&v(P,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:k(w,{color:"red",children:["Error: ",t.error.message]})})]})},Le=({label:e,status:t})=>k(P,{children:[v(P,{marginRight:1,children:t==="pending"?v(Me,{type:"dots"}):t==="success"?v(w,{color:h,children:"\u2714"}):t==="error"?v(w,{color:"red",children:"\u2716"}):v(w,{color:"yellow",children:"\u26A0"})}),v(w,{children:e})]}),or=({portResults:e,onAccept:t,onAbort:o})=>(tt((r,n)=>{n.return?t():n.escape&&o()}),k(P,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[v(w,{bold:!0,color:"yellow",children:"Port Conflicts Detected"}),e.map(r=>k(P,{children:[k(w,{color:r.available?"green":"red",children:[r.available?"\u2714":"\u2716"," "]}),k(w,{children:[r.service," (:",r.port,")"]}),!r.available&&k(w,{color:"gray",children:[" ","- in use",r.usedBy?` by ${r.usedBy}`:"",r.alternative?` (alt: :${r.alternative})`:""]})]},r.port)),v(P,{marginTop:1,children:k(w,{children:[v(w,{color:"green",bold:!0,children:"Enter"})," continue ",v(w,{color:"yellow",bold:!0,children:"Escape"})," abort"]})})]})),nr=({setupMode:e,repoPath:t,onConfirm:o})=>(tt((i,u)=>{u.return&&o()}),k(P,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:h,padding:1,children:[v(w,{color:h,bold:!0,children:"Setup Complete!"}),k(P,{marginTop:1,flexDirection:"column",children:[v(w,{bold:!0,children:"To start GAIA, run:"}),k(P,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[k(w,{color:"cyan",children:["$ cd ",t||"."]}),v(w,{color:"cyan",children:"$ gaia start"})]}),v(P,{marginTop:1,children:v(w,{color:"gray",dimColor:!0,children:(e||"developer")==="selfhost"?"Runs: docker compose --profile all up -d (background)":"Runs: mise dev (interactive \u2014 keep terminal open)"})})]}),v(De,{}),v(P,{marginTop:1,children:v(w,{dimColor:!0,children:"Press Enter to exit"})})]}));import{Spinner as ar}from"@inkjs/ui";import{Box as A,Text as _,useInput as ir}from"ink";import{useEffect as ot,useState as nt}from"react";import{jsx as D,jsxs as F}from"react/jsx-runtime";var at=({store:e})=>{let[t,o]=nt(e.currentState),[r,n]=nt(!1);return ot(()=>{let i=()=>o({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),ot(()=>{t.step==="Results"&&n(!1)},[t.step]),ir((i,u)=>{(u.return||u.escape)&&t.step==="Results"&&e.submitInput("exit"),i==="r"&&t.step==="Results"&&t.data.refreshable&&!r&&(n(!0),e.submitInput("refresh"))}),F(A,{flexDirection:"column",width:"100%",children:[D(te,{}),t.step==="Checking"&&D(A,{marginTop:1,children:D(ar,{label:t.data.services?"Refreshing service health...":"Checking service health..."})}),t.step==="Results"&&t.data.services&&F(A,{flexDirection:"column",children:[F(A,{flexDirection:"column",borderStyle:"round",borderColor:h,paddingX:2,paddingY:1,children:[D(_,{bold:!0,color:h,children:"GAIA Service Status"}),F(A,{marginTop:1,flexDirection:"column",children:[F(A,{children:[D(A,{width:22,children:D(_,{bold:!0,children:"Service"})}),D(A,{width:10,children:D(_,{bold:!0,children:"Status"})}),D(A,{width:10,children:D(_,{bold:!0,children:"Latency"})})]}),D(_,{color:"gray",children:"\u2500".repeat(42)}),t.data.services.map(i=>F(A,{children:[D(A,{width:22,children:F(_,{children:[i.name," (:",i.port,")"]})}),D(A,{width:10,children:D(_,{color:i.status==="up"?"green":"red",bold:!0,children:i.status==="up"?"\u2713 UP":"\u2717 DOWN"})}),D(A,{width:10,children:D(_,{color:"gray",children:i.latency?`${i.latency}ms`:"--"})})]},i.name))]})]}),t.data.docker&&F(A,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:2,paddingY:1,marginTop:1,children:[D(_,{bold:!0,children:"Docker Containers"}),F(_,{color:"gray",children:["Docker:"," ",t.data.docker.running?D(_,{color:"green",children:"Running"}):D(_,{color:"red",children:"Not running"})]}),t.data.docker.containers?.length>0&&D(A,{marginTop:1,flexDirection:"column",children:t.data.docker.containers.map(i=>F(A,{children:[F(_,{color:i.status==="running"?"green":"red",children:[i.status==="running"?"\u2713":"\u2717"," "]}),D(_,{children:i.name}),i.health&&F(_,{color:"gray",children:[" (",i.health,")"]})]},i.name))})]}),D(A,{marginTop:1,children:F(_,{dimColor:!0,children:["Press Enter or Escape to exit \xB7 Press"," ",D(_,{color:h,children:"r"})," to refresh"]})})]}),t.error&&D(A,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:F(_,{color:"red",children:["Error: ",t.error.message]})})]})};import{jsx as q,jsxs as le}from"react/jsx-runtime";var cr=["init","setup","status","start","stop"],Fe=class extends sr.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?le(fe,{flexDirection:"column",padding:1,children:[q(Z,{color:"red",bold:!0,children:"An unexpected error occurred:"}),q(Z,{color:"red",children:this.state.error.message}),this.state.error.stack&&q(fe,{marginTop:1,children:q(Z,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},lr=({store:e,command:t})=>{switch(t){case"init":return q(Ze,{store:e});case"setup":return q(rt,{store:e});case"status":return q(at,{store:e});case"start":case"stop":return q(et,{store:e,command:t});default:return le(fe,{flexDirection:"column",padding:1,children:[le(Z,{color:"red",children:["Unknown command: ",t]}),le(fe,{marginTop:1,flexDirection:"column",children:[q(Z,{bold:!0,children:"Available commands:"}),cr.map(o=>le(Z,{children:[" ",q(Z,{color:"cyan",children:o})]},o))]})]})}},$=({store:e,command:t})=>q(Fe,{children:q(lr,{store:e,command:t})});import{EventEmitter as ur}from"events";var Ne=class extends ur{state={step:"init",status:"",error:null,data:{},inputRequest:null};inputResolver=null;get currentState(){return this.state}setStep(t){this.state.step=t,this.emit("change",this.state)}setStatus(t){this.state.status=t,this.emit("change",this.state)}setError(t){this.state.error=t,t!==null&&this.inputResolver&&(this.inputResolver(null),this.inputResolver=null,this.state.inputRequest=null),this.emit("change",this.state)}updateData(t,o){this.state.data={...this.state.data,[t]:o},this.emit("change",this.state)}waitForInput(t,o){return this.state.inputRequest={id:t,meta:o},this.emit("change",this.state),new Promise(r=>{this.inputResolver=r})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emit("change",this.state))}},j=()=>new Ne;import*as ae from"fs";import*as St from"path";import*as ne from"node:fs";import*as oe from"node:path";import{execa as it}from"execa";var st={selfhost:{MONGO_DB:"mongodb://mongo:27017/gaia",REDIS_URL:"redis://redis:6379",POSTGRES_URL:"postgresql://postgres:postgres@postgres:5432/langgraph",CHROMADB_HOST:"chromadb",CHROMADB_PORT:"8000",RABBITMQ_URL:"amqp://guest:guest@rabbitmq:5672/"},developer:{MONGO_DB:"mongodb://localhost:27017/gaia",REDIS_URL:"redis://localhost:6379",POSTGRES_URL:"postgresql://postgres:postgres@localhost:5432/postgres",CHROMADB_HOST:"localhost",CHROMADB_PORT:"8080",RABBITMQ_URL:"amqp://guest:guest@localhost:5672/"}},ct={selfhost:{HOST:"http://localhost:8000",FRONTEND_URL:"http://localhost:3000",GAIA_BACKEND_URL:"http://gaia-backend:80",SETUP_MODE:"selfhost"},developer:{HOST:"http://localhost:8000",FRONTEND_URL:"http://localhost:3000",GAIA_BACKEND_URL:"http://host.docker.internal:8000",SETUP_MODE:"developer"}};function Ge(e,t){return st[t][e]??ct[t][e]}async function lt(e){let t=oe.join(e,"apps/api/scripts/dump_config_schema.py"),o=oe.join(e,"apps/api/app/config/settings_validator.py"),r=oe.join(e,"apps/api/app/config/settings.py");if(!ne.existsSync(t))throw new Error("dump_config_schema.py not found in apps/api/scripts");try{try{let{stdout:n}=await it("python3",[t,o,r],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await it("python",[t,o,r],{cwd:e});return JSON.parse(n)}}catch(n){throw new Error(`Failed to parse settings schema: ${n.message}. Ensure python is installed.`)}}function ut(e){let t=oe.join(e,"apps","web",".env.local"),o=ne.existsSync(t)?t:oe.join(e,"apps","web",".env");if(!ne.existsSync(o))return[];let r=ne.readFileSync(o,"utf-8"),n=[],i="General";for(let u of r.split(`
|
|
3
|
+
`)){let m=u.trim();if(m.startsWith("#")&&!m.startsWith("#=")){let x=m.replace(/^#+\s*/,"").trim();x&&!x.startsWith("These are")&&(i=x);continue}if(!m||m.startsWith("#"))continue;let f=m.indexOf("=");if(f===-1)continue;let g=m.substring(0,f).trim(),y=m.substring(f+1).trim();n.push({name:g,value:y,category:i})}return n}function pt(e,t){let o=t?.[8e3]??8e3,r=t?.[3e3]??3e3,n={NEXT_PUBLIC_API_BASE_URL:`http://localhost:${o}/api/v1/`,NEXT_PUBLIC_WS_URL:`ws://localhost:${o}/api/v1/`};return r!==3e3&&(n.NEXT_PUBLIC_APP_URL=`http://localhost:${r}`),n}function dt(e,t){for(let[o,r]of Object.entries(t)){let n=Number(o);for(let[i,u]of Object.entries(e)){let m=new RegExp(`:${n}(?=[/\\s]|$)`,"g");e[i]=u.replaceAll(m,`:${r}`)}}}function mt(e,t){return e.map(o=>({...o,variables:o.variables.map(r=>{let n=Ge(r.name,t);return{...r,defaultValue:n||r.defaultValue}})}))}function qe(){return Object.keys(st.selfhost)}function ft(e){return{...ct[e]}}import*as Y from"fs";import*as Oe from"path";function gt(e){Y.existsSync(e)&&Y.copyFileSync(e,`${e}.bak`)}function xt(e,t){let o=Oe.join(e,".env");gt(o);let r=["# GAIA Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],n=["MONGO","REDIS","POSTGRES","CHROMADB","RABBITMQ","WORKOS","GOOGLE","OPENAI","INFISICAL","LANGSMITH","DISCORD","SLACK","TELEGRAM","CLOUDINARY","COMPOSIO","FIRECRAWL","LIVEKIT","DEEPGRAM","ELEVENLABS","RESEND","SENTRY","POSTHOG","MEM0","E2B","DODO","NEXT_PUBLIC","GAIA"];function i(m){for(let g of n)if(m===g||m.startsWith(`${g}_`))return g;let f=m.split("_");return f.length===1?"Core":f[0]||"Core"}let u=new Map;for(let[m,f]of Object.entries(t)){let g=i(m);u.has(g)||u.set(g,[]);let x=/[\s#"'\\]/.test(f)||f===""?`"${f.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:f;u.get(g).push(`${m}=${x}`)}for(let[m,f]of u.entries())r.push(`# ${m} Configuration`),r.push(...f),r.push("");Y.writeFileSync(o,r.join(`
|
|
4
|
+
`),"utf-8")}function ht(e,t,o){let r=Oe.join(e,"apps","web",".env.local");gt(r);let n=ut(e),i=pt(t,o),u=["# GAIA Web App Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],m=new Map;for(let f of n){m.has(f.category)||m.set(f.category,[]);let g=i[f.name]??f.value;m.get(f.category).push({name:f.name,value:g})}if(n.length===0){u.push("# Core URLs");for(let[f,g]of Object.entries(i))u.push(`${f}=${g}`);u.push("")}else for(let[f,g]of m.entries()){u.push(`# ${f}`);for(let{name:y,value:x}of g)u.push(`${y}=${x}`);u.push("")}Y.writeFileSync(r,u.join(`
|
|
5
|
+
`),"utf-8")}var mr=e=>new Promise(t=>setTimeout(t,e));async function ge(e,t,o){e.setStep("Environment Setup"),e.setStatus("Configuring environment...");let r=await e.waitForInput("setup_mode");e.updateData("setupMode",r),e.setStatus("Configuring environment variables...");let n=await e.waitForInput("env_method"),i={};i.ENV=r==="selfhost"?"production":"development";let u=qe();for(let f of u){let g=Ge(f,r);g&&(i[f]=g)}let m=ft(r);for(let[f,g]of Object.entries(m))i[f]=g;if(n==="infisical")await fr(e,i),e.setStatus("Infisical credentials saved. Ensure your Infisical project contains all required variables.");else try{await gr(e,t,i,r)}catch(f){e.setError(f);return}o&&dt(i,o);try{await xr(e,t,i,r,o)}catch(f){e.setError(f);return}await mr(1e3)}async function fr(e,t){e.setStatus("Configuring Infisical...");let o=await e.waitForInput("env_infisical");t.INFISICAL_PROJECT_ID=o.INFISICAL_PROJECT_ID,t.INFISICAL_MACHINE_IDENTITY_CLIENT_ID=o.INFISICAL_MACHINE_IDENTITY_CLIENT_ID,t.INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET=o.INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET}async function gr(e,t,o,r){e.setStatus("Parsing environment variables...");let n;try{n=await lt(t),n=mt(n,r)}catch(d){throw new Error(`Failed to parse settings: ${d.message}`)}let i=new Set,u=[],m=new Set;for(let d of n)if(d.alternativeGroup&&!m.has(d.name)){let T=n.find(b=>b.name===d.alternativeGroup);T&&(u.push([d,T]),i.add(d.name),i.add(T.name),m.add(d.name),m.add(T.name))}let f=n.filter(d=>d.variables.length===1&&!i.has(d.name)),g=n.filter(d=>d.variables.length>1&&!i.has(d.name));for(let d of u){e.updateData("alternativeGroups",d),e.setStatus("Choose an AI provider...");let T=await e.waitForInput("env_alternatives");for(let[b,I]of Object.entries(T.values))I&&(o[b]=I)}let y=qe(),c=[...f.flatMap(d=>d.variables).filter(d=>!y.includes(d.name))].sort((d,T)=>d.required&&!T.required?-1:!d.required&&T.required?1:0);e.updateData("envVarTotal",c.length);for(let d=0;d<c.length;d++){let T=c[d];if(!T)continue;e.updateData("currentEnvVar",T),e.updateData("envVarIndex",d),e.setStatus(`Configuring ${T.name}...`);let b=await e.waitForInput("env_var",{varName:T.name});(b||T.required||T.defaultValue)&&(o[T.name]=b||T.defaultValue||"")}let S=[...g].filter(d=>!d.variables.every(T=>y.includes(T.name))).sort((d,T)=>{let b=d.variables.some(C=>C.required),I=T.variables.some(C=>C.required);return b&&!I?-1:!b&&I?1:0});e.updateData("envGroupTotal",S.length);for(let d=0;d<S.length;d++){let T=S[d];if(!T)continue;e.updateData("currentEnvGroup",T),e.updateData("envGroupIndex",d),e.setStatus(`Configuring ${T.name}...`);let b=await e.waitForInput("env_group",{groupName:T.name});for(let[I,C]of Object.entries(b)){let E=T.variables.find(V=>V.name===I);(C||E?.required||E?.defaultValue)&&(o[I]=C||E?.defaultValue||"")}}}async function xr(e,t,o,r,n){e.setStatus("Writing API environment file...");try{let i=St.join(t,"apps","api");xt(i,o),e.setStatus("API environment variables configured!")}catch(i){throw new Error(`Failed to write API .env file: ${i.message}`)}e.setStatus("Writing web environment file...");try{ht(t,r,n),e.setStatus("Web environment variables configured!")}catch(i){throw new Error(`Failed to write web .env file: ${i.message}`)}}import{execa as hr}from"execa";import xe from"fs";import Sr from"simple-git";async function yt(e,t,o){if(xe.existsSync(e)){let r=`${e}/.git`;if(!xe.existsSync(r))throw new Error(`Directory ${e} exists but is not a git repository`);await Sr().cwd(e).pull(),o(100,"Already exists, pulled latest")}else try{let r=hr("git",["clone","--progress",t,e]);r.stderr?.on("data",n=>{let i=n.toString();i.includes("Counting objects")?o(5,"Counting objects"):i.includes("Compressing objects")&&o(10,"Compressing objects");let u=i.match(/Receiving objects:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(u?.[1]){let f=Math.min(100,parseInt(u[1],10)),g=u[2],y=u[3];o(10+Math.floor(f*.5),`Receiving objects: ${g}/${y}`)}let m=i.match(/Resolving deltas:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(m?.[1]){let f=Math.min(100,parseInt(m[1],10)),g=m[2],y=m[3];o(60+Math.floor(f*.4),`Resolving deltas: ${g}/${y}`)}}),await r,o(100,"Clone complete")}catch(r){throw xe.existsSync(e)&&xe.rmSync(e,{recursive:!0,force:!0}),r}}import{execa as H}from"execa";var U={git:"https://git-scm.com/downloads",docker:"https://docs.docker.com/get-docker/",mise:"https://mise.jdx.dev/getting-started.html"},br={8e3:"API Server",5432:"PostgreSQL",6379:"Redis",27017:"MongoDB",5672:"RabbitMQ",3e3:"Web Frontend",8080:"ChromaDB",8083:"Mongo Express"};async function he(){try{return await H("git",["--version"]),"success"}catch{return"error"}}async function Se(){let e=!1,t=!1,o;try{await H("docker",["--version"]),e=!0}catch{return{name:"Docker",installUrl:U.docker,installed:!1,working:!1,errorMessage:"Docker is not installed"}}try{await H("docker",["info"],{timeout:5e3}),t=!0}catch{o="Docker is installed but the daemon is not running. Please start Docker Desktop or the Docker daemon."}return{name:"Docker",installUrl:U.docker,installed:e,working:t,errorMessage:o}}async function ye(){try{return await H("mise",["--version"]),"success"}catch{return"missing"}}async function be(){if((await import("node:os")).platform()==="win32")try{return await H("powershell",["-Command","irm https://mise.jdx.dev/install.ps1 | iex"]),!0}catch{return!1}try{return await H("sh",["-c","curl https://mise.jdx.dev/install.sh | sh"]),!0}catch{return!1}}async function ve(e){let t=await import("node:net"),o=[],r=n=>new Promise(i=>{let u=t.createServer();u.once("error",()=>i(!1)),u.once("listening",()=>{u.close(()=>i(!0))}),u.listen(n)});for(let n of e){let i=br[n]||`Port ${n}`;if(await r(n))o.push({port:n,service:i,available:!0});else{let m=await vr(n),f=await Tr(n+1,n+100,r);o.push({port:n,service:i,available:!1,usedBy:m,alternative:f||void 0})}}return o}async function vr(e){if((await import("node:os")).platform()==="win32"){try{let{stdout:r}=await H("netstat",["-ano","-p","TCP"]),n=r.trim().split(`
|
|
6
|
+
`);for(let i of n)if(i.includes(`:${e}`)&&i.includes("LISTENING")){let u=i.trim().split(/\s+/),m=u[u.length-1];if(m)try{let{stdout:f}=await H("tasklist",["/FI",`PID eq ${m}`,"/FO","CSV","/NH"]);return f.trim().split(",")[0]?.replace(/"/g,"")||`PID ${m}`}catch{return`PID ${m}`}}}catch{}return}try{let{stdout:r}=await H("lsof",["-i",`:${e}`,"-sTCP:LISTEN","-P","-n"]),n=r.trim().split(`
|
|
7
|
+
`);if(n.length>1)return n[1]?.split(/\s+/)?.[0]||void 0}catch{}}async function Tr(e,t,o){for(let r=e;r<=t;r++)if(await o(r))return r;return null}import*as X from"fs";import*as W from"path";var Ir=e=>new Promise(t=>setTimeout(t,e)),Cr="dev-start.log";async function vt(e,t,o){if(t==="selfhost"){o?.("Starting all services in Docker (selfhost mode)...");let r=W.join(e,"infra/docker");await O("docker",["compose","-f","docker-compose.prod.yml","--profile","backend","--profile","web","up","-d","--build","--remove-orphans"],r),o?.("All services started in Docker!")}else{o?.("Starting development servers...");let{spawn:r}=await import("child_process"),n=W.join(e,Cr),i=X.openSync(n,"a"),u;try{u=r("mise",["dev"],{cwd:e,stdio:["ignore",i,i],detached:!0,shell:!0}),u.unref()}finally{X.closeSync(i)}if(await Ir(1500),u.pid!=null)try{process.kill(u.pid,0)}catch{throw new Error(`Development servers crashed on startup. Check logs at: ${n}`)}o?.(`Development servers started! Logs: ${n}`)}}async function Tt(e,t,o){let r=W.join(e,"infra/docker"),n=await $e(e);t?.("Stopping Docker services...");try{await O("docker",n==="selfhost"?["compose","-f","docker-compose.prod.yml","down"]:["compose","down"],r)}catch{}t?.("Stopping local processes...");try{let i=o?.[8e3]??8e3,u=o?.[3e3]??3e3;if(process.platform==="win32")for(let m of[i,u])try{await O("powershell",["-Command",`Get-NetTCPConnection -LocalPort ${m} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`],e)}catch{}else for(let m of[i,u])try{await O("sh",["-c",`lsof -ti :${m} -sTCP:LISTEN | xargs kill 2>/dev/null || true`],e)}catch{}}catch{}t?.("All services stopped.")}async function $e(e){let t=W.join(e,"apps","api",".env");if(!X.existsSync(t))return null;let o=X.readFileSync(t,"utf-8"),r=o.match(/^SETUP_MODE=(.+)$/m);if(r?.[1]){let n=r[1].trim().replace(/^["']|["']$/g,"");if(n==="selfhost"||n==="developer")return n}return o.includes("mongodb://mongo:")?"selfhost":(o.includes("mongodb://localhost:"),"developer")}async function O(e,t,o,r,n){let{spawn:i}=await import("child_process");return new Promise((u,m)=>{let f=i(e,t,{cwd:o,stdio:["ignore","pipe","pipe"],shell:!0}),g="",y=0;f.stdout?.on("data",x=>{let c=x.toString();g+=c,n?.(c),y=Math.min(y+5,95),r?.(y)}),f.stderr?.on("data",x=>{let c=x.toString();g+=c,n?.(c),y=Math.min(y+5,95),r?.(y)}),f.on("close",x=>{x===0?(r?.(100),u()):m(new Error(`Command failed with code ${x}: ${g.slice(-500)}`))}),f.on("error",x=>{m(x)})})}function Q(e){let t=e||process.cwd();for(;t!==W.dirname(t);){if(X.existsSync(W.join(t,"apps/api/app/config/settings_validator.py")))return t;t=W.dirname(t)}return null}var Er=process.env.GAIA_CLI_DEV==="true",K=e=>new Promise(t=>setTimeout(t,e));async function It(e){e.setStep("Welcome"),e.setStatus("Waiting for user input..."),await e.waitForInput("welcome");let t=c=>{let S=e.currentState.data.dependencyLogs||[],d=c.split(`
|
|
8
|
+
`).filter(b=>b.trim()!==""),T=[...S,...d].slice(-20);e.updateData("dependencyLogs",T)};e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await K(800),e.setStatus("Checking Git...");let o=await he();e.updateData("checks",{...e.currentState.data.checks,git:o}),e.setStatus("Checking Docker...");let r=await Se(),n=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:n}),r.working||e.updateData("dockerError",r.errorMessage),e.setStatus("Checking Mise...");let i=await ye();e.updateData("checks",{...e.currentState.data.checks,mise:i}),i==="missing"&&(e.setStatus("Installing Mise..."),i=await be()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:i}));let u=[];if(o==="error"&&u.push({name:"Git"}),n==="error"&&u.push({name:"Docker",message:r.errorMessage}),i==="error"&&u.push({name:"Mise"}),u.length>0){let c=[];c.push("Prerequisites failed:");for(let S of u)c.push(` \u2022 ${S.name}: ${S.message||"Not installed or not working"}`);c.push(`
|
|
9
|
+
Installation guides:`),o==="error"&&c.push(` \u2022 Git: ${U.git}`),n==="error"&&(r.installed?c.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):c.push(` \u2022 Docker: ${U.docker}`)),i==="error"&&c.push(` \u2022 Mise: ${U.mise}`),e.setError(new Error(c.join(`
|
|
10
|
+
`)));return}e.setStatus("Checking Ports...");let f=await ve([8e3,5432,6379,27017,5672,3e3,8080,8083]),g={},y=f.filter(c=>!c.available);if(y.length>0){let c=y.filter(d=>!d.alternative);if(c.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${c.map(d=>`${d.port} (${d.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",f),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let d of f)!d.available&&d.alternative&&(g[d.port]=d.alternative)}e.updateData("portOverrides",g),e.setStatus("Prerequisites check complete!"),await K(1e3);let x="";if(Er){if(x=Q()||"",!x){e.setError(new Error("DEV_MODE: Could not find workspace root. Run from within the gaia repo."));return}e.setStep("Repository Setup"),e.setStatus("[DEV MODE] Using current workspace..."),await K(500),e.setStatus("Repository ready!")}else{for(e.setStep("Repository Setup");;){if(x=await e.waitForInput("repo_path",{default:"./gaia"}),ae.existsSync(x)){if(!ae.statSync(x).isDirectory()){e.setError(new Error(`Path ${x} exists and is not a directory.`)),await K(2e3),e.setError(null);continue}if(ae.readdirSync(x).length>0){e.setError(new Error(`Directory ${x} is not empty. Please choose another path.`)),await K(2e3),e.setError(null);continue}}break}e.setStep("Repository Setup"),e.setStatus("Preparing repository..."),e.updateData("repoProgress",0),e.updateData("repoPhase","");try{await yt(x,"https://github.com/theexperiencecompany/gaia.git",(c,S)=>{e.updateData("repoProgress",c),S?(e.updateData("repoPhase",S),e.setStatus(`${S}...`)):e.setStatus(`Cloning repository to ${x}... ${c}%`)}),e.setStatus("Repository ready!")}catch(c){e.setError(c);return}}await K(1e3),e.setStep("Install Tools"),e.setStatus("Installing toolchain..."),e.updateData("dependencyPhase","Initializing mise..."),e.updateData("dependencyProgress",0),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyPhase","Trusting mise configuration..."),await O("mise",["trust"],x,void 0,t),e.updateData("dependencyProgress",50),e.updateData("dependencyPhase","Installing tools (node, python, uv, nx)..."),await O("mise",["install"],x,c=>{e.updateData("dependencyProgress",50+c*.5)},t),e.updateData("dependencyProgress",100),e.updateData("toolComplete",!0)}catch(c){e.setError(new Error(`Failed to install tools: ${c.message}`));return}if(await K(1e3),await ge(e,x,g),!e.currentState.error){e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("repoPath",x),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyProgress",0),e.updateData("dependencyPhase","Running mise setup (all dependencies)..."),await O("mise",["setup"],x,c=>{e.updateData("dependencyProgress",c)},t),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(c){e.setError(new Error(`Failed to setup project: ${c.message}`));return}await K(1e3),e.setStep("Finished"),e.setStatus("Setup complete!")}}async function Ct(){let e=j(),{unmount:t}=wr(Dr.createElement($,{store:e,command:"init"}));try{await It(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Pr}from"ink";import Rr from"react";var Te=e=>new Promise(t=>setTimeout(t,e));async function Et(e){e.setStep("Detect Repo"),e.setStatus("Looking for GAIA repository...");let t=Q();if(!t){e.setError(new Error("Could not find GAIA repository. Run this command from within a cloned gaia repo, or use 'gaia init' to set up from scratch."));return}e.updateData("repoPath",t),e.setStatus(`Found repository at ${t}`),await Te(1e3),e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await Te(500);let o=await he();e.updateData("checks",{...e.currentState.data.checks,git:o});let r=await Se(),n=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:n}),r.working||e.updateData("dockerError",r.errorMessage);let i=await ye();e.updateData("checks",{...e.currentState.data.checks,mise:i}),i==="missing"&&(e.setStatus("Installing Mise..."),i=await be()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:i}));let u=[];if(o==="error"&&u.push({name:"Git"}),n==="error"&&u.push({name:"Docker",message:r.errorMessage}),i==="error"&&u.push({name:"Mise"}),u.length>0){let c=[];c.push("Prerequisites failed:");for(let S of u)c.push(` \u2022 ${S.name}: ${S.message||"Not installed or not working"}`);c.push(`
|
|
11
|
+
Installation guides:`),o==="error"&&c.push(` \u2022 Git: ${U.git}`),n==="error"&&(r.installed?c.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):c.push(` \u2022 Docker: ${U.docker}`)),i==="error"&&c.push(` \u2022 Mise: ${U.mise}`),e.setError(new Error(c.join(`
|
|
12
|
+
`)));return}e.setStatus("Checking Ports...");let f=await ve([8e3,5432,6379,27017,5672,3e3,8080,8083]),g={},y=f.filter(c=>!c.available);if(y.length>0){let c=y.filter(d=>!d.alternative);if(c.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${c.map(d=>`${d.port} (${d.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",f),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let d of f)!d.available&&d.alternative&&(g[d.port]=d.alternative)}if(e.updateData("portOverrides",g),e.setStatus("Prerequisites check complete!"),await Te(1e3),await ge(e,t,g),e.currentState.error)return;e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("dependencyLogs",[]);let x=c=>{let S=e.currentState.data.dependencyLogs||[],d=c.split(`
|
|
13
|
+
`).filter(b=>b.trim()!==""),T=[...S,...d].slice(-20);e.updateData("dependencyLogs",T)};try{e.updateData("dependencyPhase","Trusting mise configuration..."),await O("mise",["trust"],t,void 0,x),e.updateData("dependencyProgress",20),e.updateData("dependencyPhase","Installing tools..."),await O("mise",["install"],t,c=>{e.updateData("dependencyProgress",20+c*.3)},x),e.updateData("dependencyPhase","Running mise setup..."),await O("mise",["setup"],t,c=>{e.updateData("dependencyProgress",50+c*.5)},x),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(c){e.setError(new Error(`Failed to setup project: ${c.message}`));return}await Te(1e3),e.setStep("Finished"),e.setStatus("Setup complete!")}async function wt(){let e=j(),{unmount:t}=Pr(Rr.createElement($,{store:e,command:"setup"}));try{await Et(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as kr}from"ink";import Br from"react";async function Dt(e){e.setStep("Starting"),e.setStatus("Locating GAIA repository...");let t=Q();if(!t){e.setError(new Error("Could not find GAIA repository. Run from within a cloned gaia repo."));return}e.updateData("repoPath",t);let o=await $e(t);if(!o){e.setError(new Error("No .env file found. Run 'gaia setup' first to configure the environment."));return}e.updateData("setupMode",o),e.setStatus(`Starting GAIA in ${o} mode...`);try{await vt(t,o,r=>{e.setStatus(r)}),e.setStep("Running"),e.setStatus("GAIA is running!"),e.updateData("started",!0)}catch(r){e.setError(new Error(`Failed to start services: ${r.message}`));return}await e.waitForInput("exit")}async function Pt(){let e=j(),{unmount:t}=kr(Br.createElement($,{store:e,command:"start"}));await new Promise(o=>setTimeout(o,50));try{await Dt(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Fr}from"ink";import Nr from"react";import{execa as Ue}from"execa";var je=["gaia-backend","gaia-web","chromadb","postgres","redis","mongo","rabbitmq","arq_worker"];async function Rt(){try{let{stdout:e}=await Ue("docker",["inspect","--format","{{.Name}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",...je]),t=new Map;for(let o of e.trim().split(`
|
|
14
|
+
`)){if(!o)continue;let[r,n,i]=o.split("|"),u=r?.replace(/^\//,"")??"";t.set(u,{name:u,status:n==="running"?"running":"stopped",health:i!=="none"?i:void 0})}return je.map(o=>t.get(o)??{name:o,status:"not_found"})}catch{let e=je.map(async t=>{try{let{stdout:o}=await Ue("docker",["inspect","--format","{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",t]),[r,n]=o.trim().split("|");return{name:t,status:r==="running"?"running":"stopped",health:n!=="none"?n:void 0}}catch{return{name:t,status:"not_found"}}});return Promise.all(e)}}async function kt(){try{return await Ue("docker",["info"]),!0}catch{return!1}}var Ar=[{name:"API",port:8e3,type:"http",path:"/health"},{name:"Web",port:3e3,type:"http",path:"/"},{name:"PostgreSQL",port:5432,type:"tcp"},{name:"Redis",port:6379,type:"tcp"},{name:"MongoDB",port:27017,type:"tcp"},{name:"RabbitMQ",port:5672,type:"tcp"},{name:"ChromaDB",port:8080,type:"tcp"}];async function Bt(e){let o=Ar.map(r=>({...r,port:e?.[r.port]??r.port})).map(r=>r.type==="http"?_r(r.name,r.port,r.path):Lr(r.name,r.port));return Promise.all(o)}async function _r(e,t,o){let r=Date.now();try{let n=await fetch(`http://localhost:${t}${o}`,{signal:AbortSignal.timeout(5e3)}),i=Date.now()-r;return{name:e,port:t,status:"up",latency:i,details:n.ok?`HTTP ${n.status}`:`HTTP ${n.status} (error)`}}catch{return{name:e,port:t,status:"down",details:"Connection failed"}}}async function Lr(e,t){let o=await import("node:net"),r=Date.now();return new Promise(n=>{let i=new o.Socket;i.setTimeout(3e3),i.on("connect",()=>{let u=Date.now()-r;i.destroy(),n({name:e,port:t,status:"up",latency:u})}),i.on("timeout",()=>{i.destroy(),n({name:e,port:t,status:"down"})}),i.on("error",()=>{i.destroy(),n({name:e,port:t,status:"down"})}),i.connect(t,"localhost")})}async function At(){return await kt()?{running:!0,containers:await Rt()}:{running:!1,containers:[]}}async function Mr(e){e.setStep("Checking"),e.setStatus("Checking service health..."),e.updateData("refreshable",!1);let[t,o]=await Promise.all([Bt(),At()]);e.updateData("services",t),e.updateData("docker",o);let r=t.filter(i=>i.status==="up").length,n=t.length;e.setStep("Results"),e.setStatus(`${r}/${n} services running`),e.updateData("refreshable",!0)}async function _t(e){for(;await Mr(e),await e.waitForInput("exit_or_refresh")==="refresh";);}async function Lt(){let e=j(),{unmount:t}=Fr(Nr.createElement($,{store:e,command:"status"}));await new Promise(o=>setTimeout(o,50));try{await _t(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Gr}from"ink";import qr from"react";async function Mt(e){e.setStep("Stopping"),e.setStatus("Locating GAIA repository...");let t=Q();if(!t){e.setError(new Error("Could not find GAIA repository. Run from within a cloned gaia repo."));return}e.updateData("repoPath",t);try{await Tt(t,o=>{e.setStatus(o)}),e.setStep("Stopped"),e.setStatus("All services stopped."),e.updateData("stopped",!0)}catch(o){e.setError(new Error(`Failed to stop services: ${o.message}`));return}await e.waitForInput("exit")}async function Ft(){let e=j(),{unmount:t}=Gr(qr.createElement($,{store:e,command:"stop"}));await new Promise(o=>setTimeout(o,50));try{await Mt(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}var J=new Or;J.name("gaia").description("CLI tool for setting up and managing GAIA").version("0.1.0");J.command("init").description("Full setup from scratch (clone, configure, start)").action(async()=>{await Ct()});J.command("setup").description("Configure an existing GAIA repository").action(async()=>{await wt()});J.command("status").description("Check health of all GAIA services").action(async()=>{await Lt()});J.command("start").description("Start GAIA services").action(async()=>{await Pt()});J.command("stop").description("Stop all GAIA services").action(async()=>{await Ft()});process.argv.slice(2).length||(J.outputHelp(),process.exit(0));J.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heygaia/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "CLI tool for setting up and managing GAIA",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
"dev": "tsx watch src/index.ts",
|
|
15
15
|
"build": "esbuild src/index.ts --bundle --platform=node --target=node18 --format=esm --packages=external --outfile=dist/index.js --minify && chmod +x dist/index.js",
|
|
16
16
|
"start": "NODE_ENV=production node dist/index.js",
|
|
17
|
+
"type-check": "tsc --noEmit",
|
|
18
|
+
"check": "biome check src",
|
|
19
|
+
"fix": "biome check --write src",
|
|
20
|
+
"lint": "pnpm run check",
|
|
21
|
+
"lint:fix": "pnpm run fix",
|
|
22
|
+
"format": "biome format --write src",
|
|
17
23
|
"prepublishOnly": "pnpm run build"
|
|
18
24
|
},
|
|
19
25
|
"engines": {
|
|
@@ -50,10 +56,12 @@
|
|
|
50
56
|
"simple-git": "^3.30.0"
|
|
51
57
|
},
|
|
52
58
|
"devDependencies": {
|
|
59
|
+
"@biomejs/biome": "2.3.7",
|
|
53
60
|
"@types/node": "^25.2.2",
|
|
54
61
|
"@types/react": "^19",
|
|
55
62
|
"@types/react-dom": "^19",
|
|
56
63
|
"esbuild": "latest",
|
|
57
|
-
"tsx": "latest"
|
|
64
|
+
"tsx": "latest",
|
|
65
|
+
"typescript": "^5.9.2"
|
|
58
66
|
}
|
|
59
67
|
}
|