@heygaia/cli 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +101 -20
  2. package/dist/index.js +21 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -15,45 +15,57 @@ The CLI checks prerequisites at startup and tells you what's missing.
15
15
 
16
16
  ## Installation
17
17
 
18
- ### curl (recommended)
18
+ **Global installation is required** to use the `gaia` command. Choose your preferred method:
19
19
 
20
- Downloads and installs the CLI globally. Uses npm if available, falls back to bun.
20
+ ### Quick Install (Recommended)
21
+
22
+ Downloads and installs the CLI globally using the install script:
21
23
 
22
24
  ```bash
23
25
  curl -fsSL https://heygaia.io/install.sh | sh
24
26
  ```
25
27
 
26
- ### npm
28
+ This automatically detects your system and installs using npm or bun.
29
+
30
+ ### Manual Installation
31
+
32
+ #### npm
27
33
 
28
34
  ```bash
29
35
  npm install -g @heygaia/cli
30
36
  ```
31
37
 
32
- ### npx (no install)
33
-
34
- Run directly without a global install:
38
+ #### pnpm
35
39
 
36
40
  ```bash
37
- npx @heygaia/cli init
41
+ pnpm add -g @heygaia/cli
38
42
  ```
39
43
 
40
- ### Other package managers
44
+ #### bun
41
45
 
42
46
  ```bash
43
- # pnpm
44
- pnpm add -g @heygaia/cli
45
-
46
- # bun
47
47
  bun add -g @heygaia/cli
48
48
  ```
49
49
 
50
- ### Verify
50
+ ### Verify Installation
51
+
52
+ After installation, verify the `gaia` command is available:
51
53
 
52
54
  ```bash
53
55
  gaia --version
54
56
  gaia --help
55
57
  ```
56
58
 
59
+ ### Alternative: Run Without Installing (Not Recommended)
60
+
61
+ You can run commands directly with `npx`, but this won't add the `gaia` command to your PATH:
62
+
63
+ ```bash
64
+ npx @heygaia/cli init
65
+ ```
66
+
67
+ **Note:** Using `npx` means you'll need to prefix every command with `npx @heygaia/cli` instead of just using `gaia`. We recommend installing globally for the best experience.
68
+
57
69
  ## What Happens When You Install
58
70
 
59
71
  1. The `@heygaia/cli` npm package is installed globally
@@ -64,6 +76,22 @@ The CLI itself is a single bundled JavaScript file (~300KB) with no native depen
64
76
 
65
77
  ## Commands
66
78
 
79
+ Once installed, you can use these commands from anywhere in your terminal:
80
+
81
+ ### Quick Reference
82
+
83
+ ```bash
84
+ gaia init # Full setup from scratch
85
+ gaia setup # Configure existing repo
86
+ gaia start # Start all services
87
+ gaia stop # Stop all services
88
+ gaia status # Check service health
89
+ gaia --version # Show CLI version
90
+ gaia --help # Show all commands
91
+ ```
92
+
93
+ ### Command Details
94
+
67
95
  | Command | Description |
68
96
  |---------|-------------|
69
97
  | `gaia init` | Full setup from scratch — clone repo, install tools, configure env, start services |
@@ -71,11 +99,19 @@ The CLI itself is a single bundled JavaScript file (~300KB) with no native depen
71
99
  | `gaia start` | Start all GAIA services (auto-detects selfhost vs developer mode) |
72
100
  | `gaia stop` | Stop all running GAIA services |
73
101
  | `gaia status` | Check health of all services with latency |
102
+ | `gaia --version` | Display the current CLI version |
103
+ | `gaia --help` | Show help and list all available commands |
74
104
 
75
105
  ### `gaia init`
76
106
 
77
107
  Interactive wizard for first-time setup. This is the main entry point for new users.
78
108
 
109
+ **Usage:**
110
+
111
+ ```bash
112
+ gaia init
113
+ ```
114
+
79
115
  **What it does:**
80
116
 
81
117
  1. **Prerequisites check** — Verifies Git, Docker, and [Mise](https://mise.jdx.dev) are installed. Auto-installs Mise if missing.
@@ -86,31 +122,73 @@ Interactive wizard for first-time setup. This is the main entry point for new us
86
122
  6. **Project setup** — Runs `mise setup` to install all dependencies, start Docker services, and seed the database.
87
123
  7. **Service startup** — Optionally starts all services immediately.
88
124
 
125
+ **First-time users:** This is the command you want! It handles everything from zero to a running GAIA instance.
126
+
89
127
  ### `gaia setup`
90
128
 
91
129
  For existing repos that need configuration or reconfiguration. Skips cloning and tool installation, goes straight to environment setup.
92
130
 
131
+ **Usage:**
132
+
93
133
  ```bash
94
134
  cd /path/to/gaia
95
135
  gaia setup
96
136
  ```
97
137
 
138
+ **When to use:**
139
+ - You already have the GAIA repo cloned
140
+ - You want to reconfigure environment variables
141
+ - You need to switch between self-host and developer modes
142
+ - Dependencies need to be reinstalled
143
+
98
144
  ### `gaia start`
99
145
 
100
- Starts all services. Auto-detects the setup mode from your `.env` configuration:
146
+ Starts all GAIA services. Auto-detects the setup mode from your `.env` configuration.
147
+
148
+ **Usage:**
149
+
150
+ ```bash
151
+ gaia start
152
+ ```
153
+
154
+ **What it does:**
155
+
156
+ - **Self-host mode**: Runs `docker compose --profile all up -d` (everything in Docker, runs in background)
157
+ - **Developer mode**: Runs `mise dev` (databases in Docker, API + web locally with hot reload)
101
158
 
102
- - **Self-host mode**: Runs `docker compose --profile all up -d`
103
- - **Developer mode**: Runs `mise dev` for local API + web, Docker for databases
159
+ **Access your instance:**
160
+ - Web: http://localhost:3000
161
+ - API: http://localhost:8000
162
+ - API Docs: http://localhost:8000/docs
104
163
 
105
164
  ### `gaia stop`
106
165
 
107
- Stops all running services:
108
- - Docker containers in the GAIA compose stack
166
+ Stops all running GAIA services gracefully.
167
+
168
+ **Usage:**
169
+
170
+ ```bash
171
+ gaia stop
172
+ ```
173
+
174
+ **What it stops:**
175
+ - All Docker containers in the GAIA compose stack
109
176
  - Local processes on ports 8000 (API) and 3000 (Web)
177
+ - Background workers and services
178
+
179
+ **Note:** Your data is preserved — stopping services doesn't delete any databases or configurations.
110
180
 
111
181
  ### `gaia status`
112
182
 
113
- Shows a live health dashboard with latency for all services:
183
+ Shows a live health dashboard with latency for all services.
184
+
185
+ **Usage:**
186
+
187
+ ```bash
188
+ gaia status
189
+ ```
190
+
191
+ **Service checks:**
114
192
 
115
193
  | Service | Port | Health Check |
116
194
  |---------|------|--------------|
@@ -122,7 +200,10 @@ Shows a live health dashboard with latency for all services:
122
200
  | RabbitMQ | 5672 | TCP connection |
123
201
  | ChromaDB | 8080 | TCP connection |
124
202
 
125
- Press `r` to refresh.
203
+ **Interactive controls:**
204
+ - Press `r` to refresh status
205
+ - Status indicators: ✓ (healthy), ✗ (down), - (checking)
206
+ - Shows response time for each service
126
207
 
127
208
  ## Setup Modes
128
209
 
package/dist/index.js CHANGED
@@ -1,16 +1,22 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Qr}from"commander";import{render as Or}from"ink";import Mr from"react";import{Box as he,Text as Z}from"ink";import fr from"react";import{ProgressBar as Ze,Select as et,Spinner as tt}from"@inkjs/ui";import{Box as p,Text as s,useInput as z}from"ink";import pe from"ink-text-input";import{useEffect as xe,useState as M}from"react";import{Box as ue,Text as Je}from"ink";var S="#00bbff";import{Box as Ut,Text as we}from"ink";import{jsx as Qe,jsxs as Ye}from"react/jsx-runtime";var Ke=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:Ye(Ut,{width:"100%",borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[Ye(we,{color:S,children:[Qe(we,{bold:!0,children:"Status:"})," ",t]}),Qe(we,{color:"white",dimColor:!0,children:e})]});import{Box as Xt}from"ink";import Qt from"ink-big-text";import Yt from"ink-gradient";import{jsx as Re}from"react/jsx-runtime";var te=()=>Re(Xt,{flexDirection:"column",marginTop:1,marginBottom:1,children:Re(Yt,{colors:[S,"#b0eaff",S],children:Re(Qt,{text:"GAIA",font:"3d"})})});import{jsx as re,jsxs as fe}from"react/jsx-runtime";var Kt=["Welcome","Prerequisites","Repository Setup","Install Tools","Environment Setup","Project Setup","Finished"],ze=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Jt=({currentStep:e,steps:t})=>{let o=t.indexOf(e);return re(ue,{marginBottom:1,children:t.map((r,n)=>{let i=r===e,c=o>n;return fe(ue,{marginRight:2,children:[fe(Je,{color:i?S:c?"green":"gray",children:[c?"\u2713 ":i?"\u25CF ":"\u25CB ",r]}),n<t.length-1&&re(Je,{color:"gray",children:" \u203A "})]},r)})})},ge=({children:e,status:t,step:o,steps:r=Kt})=>fe(ue,{flexDirection:"column",height:"100%",width:"100%",children:[fe(ue,{flexGrow:1,flexDirection:"column",children:[re(te,{}),re(Jt,{currentStep:o,steps:r}),re(ue,{flexDirection:"column",flexGrow:1,children:e})]}),re(Ke,{status:t,step:o})]});import{Fragment as To,jsx as a,jsxs as u}from"react/jsx-runtime";var De=({label:e,status:t})=>u(p,{children:[a(p,{marginRight:1,children:t==="pending"?a(tt,{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})]}),zt=({onConfirm:e})=>(z((t,o)=>{o.return&&e()}),u(p,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:S,children:[a(s,{bold:!0,children:"Welcome to the Interactive GAIA Setup"}),u(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:S,children:"Press Enter to start..."})]})),Zt=({portResults:e,onAccept:t,onAbort:o})=>{z((n,i)=>{i.return?t():i.escape&&o()});let r=e.filter(n=>!n.available);return u(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=>u(p,{children:[u(s,{color:n.available?"green":n.alternative?"yellow":"red",children:[n.available?"\u2714":n.alternative?"\u26A0":"\u2716"," "]}),u(s,{children:[n.service," (:",n.port,")"]}),!n.available&&u(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)),u(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:u(s,{children:[a(s,{color:"green",bold:!0,children:"Enter"})," to continue with alternatives ",a(s,{color:"yellow",bold:!0,children:"Escape"})," to abort"]})})]})]})},er=({defaultValue:e,onSubmit:t})=>{let[o,r]=M(e);return u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(s,{children:"Where should we clone the repository?"}),u(p,{children:[a(s,{color:S,children:"\u279C "}),a(pe,{value:o,onChange:r,onSubmit:t})]}),u(s,{color:"gray",children:["(Press Enter for default: ",e,")"]})]})},tr=({setupMode:e,repoPath:t,portOverrides:o,onConfirm:r})=>{z((m,g)=>{g.return&&r()});let n=e||"developer",i=t||"./gaia",c=o?.[3e3]??3e3,d=o?.[8e3]??8e3;return u(p,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:S,padding:1,children:[a(s,{color:S,bold:!0,children:"You are all set!"}),u(p,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"To start GAIA, run:"}),u(p,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[u(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)"})})]}),u(p,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"Access GAIA at:"}),u(p,{marginLeft:2,flexDirection:"column",children:[u(s,{children:["Web:"," ",u(s,{color:"cyan",bold:!0,children:["http://localhost:",c]})]}),u(s,{children:["API:"," ",u(s,{color:"cyan",bold:!0,children:["http://localhost:",d]})]})]})]}),a(ke,{}),a(p,{marginTop:1,children:a(s,{dimColor:!0,children:"Press Enter to exit"})})]})},ke=()=>u(p,{marginTop:1,flexDirection:"column",children:[a(s,{bold:!0,children:"Available commands:"}),u(p,{marginLeft:2,flexDirection:"column",children:[u(s,{children:[u(s,{color:S,bold:!0,children:["gaia start"," "]}),a(s,{color:"gray",children:" Start all services"})]}),u(s,{children:[u(s,{color:S,bold:!0,children:["gaia stop"," "]}),a(s,{color:"gray",children:" Stop all services"})]}),u(s,{children:[a(s,{color:S,bold:!0,children:"gaia status"}),a(s,{color:"gray",children:" Check service health"})]}),u(s,{children:[u(s,{color:S,bold:!0,children:["gaia setup"," "]}),a(s,{color:"gray",children:" Reconfigure environment"})]})]})]}),rr=({phase:e,progress:t,isComplete:o,logs:r,title:n})=>u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(p,{marginBottom:1,children:a(s,{bold:!0,color:S,children:n||"Installing Dependencies"})}),u(p,{flexDirection:"column",gap:1,children:[a(p,{children:o?u(s,{color:"green",children:["\u2713 ",e]}):a(tt,{label:e||"Preparing..."})}),!o&&t>0&&a(p,{width:50,children:a(Ze,{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,c)=>a(s,{color:"gray",wrap:"truncate",children:i},c))})]})]});var Be=({onSelect:e})=>u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,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(et,{options:[{label:"Self-Host (Docker)",value:"selfhost"},{label:"Developer Mode (Local)",value:"developer"}],onChange:o=>e(o)})}),u(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)"})]})]}),Ae=({onSelect:e})=>u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,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(et,{options:[{label:"Manual Setup (Recommended)",value:"manual"},{label:"Infisical (Advanced)",value:"infisical"}],onChange:o=>e(o)})}),u(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)"})]})]}),_e=({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,c]=M(null),d=[{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,v)=>{if(v.tab||v.downArrow)n(h=>h<d.length-1?h+1:h);else if(v.upArrow)n(h=>h>0?h-1:h);else if(v.return){if(r<d.length-1){n(l=>l+1);return}let h=d.filter(l=>!t[l.key].trim());if(h.length>0){c(`Required: ${h.map(x=>x.key).join(", ")}`);let l=d.findIndex(x=>!t[x.key].trim());l>=0&&n(l);return}e(t)}});let m=d[r];return u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[a(p,{marginBottom:1,children:a(s,{bold:!0,color:S,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."})}),u(p,{marginBottom:1,flexDirection:"column",children:[a(s,{color:"gray",children:"Configure your Infisical credentials."}),u(s,{color:"gray",dimColor:!0,children:["Visit"," ",a(s,{color:"cyan",underline:!0,children:"app.infisical.com"})," ","to get these values."]})]}),d.map((g,v)=>{let h=g.key.includes("SECRET")||g.key.includes("TOKEN");return u(p,{flexDirection:"column",marginBottom:1,children:[a(p,{children:u(s,{color:v===r?S:"white",children:[v===r?"\u25B8 ":" ",g.key,":"]})}),a(p,{marginLeft:2,children:a(s,{color:"gray",dimColor:!0,children:g.description})}),v===r?a(p,{marginLeft:2,children:a(pe,{value:t[g.key],onChange:l=>{o(x=>({...x,[g.key]:l})),c(null)},placeholder:"Enter value...",mask:h?"*":void 0})}):a(p,{marginLeft:2,children:a(s,{color:t[g.key]?"green":"gray",children:t[g.key]?h?`\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"})})]})},Oe=({category:e,currentIndex:t,totalGroups:o,onSubmit:r})=>{let[n,i]=M(()=>{let l={};for(let x of e.variables)l[x.name]=x.defaultValue||"";return l}),[c,d]=M(0),[m,g]=M(null);xe(()=>{let l={};for(let x of e.variables)l[x.name]=x.defaultValue||"";i(l),d(0),g(null)},[e.name]),z((l,x)=>{if(x.tab||x.downArrow)d(f=>f<e.variables.length-1?f+1:f);else if(x.upArrow)d(f=>f>0?f-1:f);else if(x.escape){let f=e.variables.filter(b=>b.required&&!n[b.name]?.trim());if(f.length>0){g(`Required fields cannot be skipped: ${f.map(b=>b.name).join(", ")}`);return}r(n)}});let v=()=>{if(c<e.variables.length-1)d(c+1);else{let l=e.variables.filter(x=>x.required&&!n[x.name]?.trim());if(l.length>0){g(`Required fields are missing: ${l.map(x=>x.name).join(", ")}`);return}g(null),r(n)}},h=e.variables.some(l=>l.required);return u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:m?"red":S,children:[u(p,{justifyContent:"space-between",children:[u(s,{bold:!0,children:["Configure ",e.name]}),u(s,{color:"gray",children:["Group ",t+1," / ",o]})]}),u(p,{marginTop:1,flexDirection:"column",children:[u(p,{children:[u(s,{color:"cyan",bold:!0,children:["Purpose:"," "]}),a(s,{color:"white",children:e.description})]}),e.affectedFeatures&&u(p,{children:[u(s,{color:"cyan",bold:!0,children:["Affects:"," "]}),a(s,{color:"gray",children:e.affectedFeatures})]}),e.docsUrl&&u(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((l,x)=>{let f=x===c,b=!!l.defaultValue;return u(p,{flexDirection:"column",marginBottom:1,children:[u(p,{children:[u(s,{color:f?S:"gray",bold:f,children:[f?"\u279C ":" ",l.name]}),l.required&&u(s,{color:"red",bold:!0,children:[" ","*"]}),b&&!f&&u(s,{color:"gray",dimColor:!0,children:[" ","(default: ",l.defaultValue,")"]})]}),f&&a(p,{marginLeft:2,children:a(pe,{value:n[l.name]||"",onChange:T=>{i(C=>({...C,[l.name]:T})),m&&g(null)},onSubmit:v,placeholder:b?`Default: ${l.defaultValue}`:l.required?"Enter a value (required)":"Press Enter to skip"})})]},l.name)})}),m&&a(p,{marginTop:1,children:u(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),a(p,{marginTop:1,flexDirection:"column",children:u(s,{color:"gray",dimColor:!0,children:["\u21B5 Enter to next field \u2022 Tab/\u2193 move down \u2022 \u2191 move up",!h&&" \u2022 ESC skip group"]})})]})},Me=({alternatives:e,onSubmit:t})=>{let[o,r]=M(new Set),[n,i]=M({}),[c,d]=M(0),[m,g]=M(null);xe(()=>{let T={};for(let C of e)for(let I of C.variables)T[I.name]=I.defaultValue||"";i(T)},[e]);let v=[];for(let T=0;T<e.length;T++)if(v.push({type:"provider",categoryIndex:T}),o.has(T)){let C=e[T];if(C)for(let I=0;I<C.variables.length;I++)v.push({type:"field",categoryIndex:T,fieldIndex:I})}v.push({type:"submit"});let h=v[c],l=h?.type==="field",x=h?.type==="submit";z((T,C)=>{let I=Math.min(c,v.length-1);if(I!==c){d(I);return}if(l)C.upArrow?d(E=>Math.max(0,E-1)):(C.downArrow||C.tab)&&d(E=>Math.min(v.length-1,E+1));else if(x)C.upArrow?d(E=>Math.max(0,E-1)):(C.return||T===" ")&&b();else if(C.upArrow)d(E=>Math.max(0,E-1));else if(C.downArrow||C.tab)d(E=>Math.min(v.length-1,E+1));else if((C.return||T===" ")&&h?.type==="provider"){let E=h.categoryIndex;r(Q=>{let D=new Set(Q);return D.has(E)?D.delete(E):D.add(E),D}),m&&g(null)}});let f=()=>{m&&g(null),d(T=>Math.min(v.length-1,T+1))},b=()=>{let T=[],C={};for(let I of o){let E=e[I];if(!E)continue;if(E.variables.some(D=>n[D.name]?.trim())){T.push(E.name);for(let D of E.variables){let me=n[D.name];me&&(C[D.name]=me)}}}if(T.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(T,C)};return u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:m?"red":S,children:[u(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((T,C)=>{let I=o.has(C),E=v.findIndex(D=>D.type==="provider"&&D.categoryIndex===C),Q=c===E;return u(p,{flexDirection:"column",marginBottom:1,children:[u(p,{children:[a(s,{color:Q?S:void 0,bold:Q,children:Q?"\u279C ":" "}),a(s,{color:I?"green":"gray",children:I?"[\u2714]":"[ ]"}),u(s,{color:I?S:"gray",bold:I,children:[" ",T.name]}),T.description&&u(s,{color:"gray",dimColor:!0,children:[" ","- ",T.description]})]}),Q&&T.docsUrl&&u(p,{marginLeft:6,children:[a(s,{color:"yellow",children:"\u{1F4D6} "}),a(s,{color:"blue",underline:!0,children:T.docsUrl})]}),I&&a(p,{marginLeft:4,flexDirection:"column",marginTop:1,children:T.variables.map((D,me)=>{let Vt=v.findIndex(le=>le.type==="field"&&le.categoryIndex===C&&le.fieldIndex===me),ee=c===Vt,Xe=!!D.defaultValue,Pe=n[D.name]||"";return u(p,{flexDirection:"column",marginBottom:1,children:[u(p,{children:[u(s,{color:ee?S:"gray",bold:ee,children:[ee?" \u279C ":" ",D.name]}),!ee&&Pe&&a(s,{color:"green",children:" \u2713"}),!ee&&!Pe&&Xe&&u(s,{color:"gray",dimColor:!0,children:[" ","(default: ",D.defaultValue,")"]})]}),ee&&a(p,{marginLeft:4,children:a(pe,{value:Pe,onChange:le=>{i(Wt=>({...Wt,[D.name]:le})),m&&g(null)},onSubmit:f,placeholder:Xe?`Default: ${D.defaultValue}`:"Enter value..."})})]},D.name)})})]},T.name)})}),m&&a(p,{marginTop:1,children:u(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),u(p,{marginTop:1,children:[a(s,{color:x?S:void 0,bold:x,children:x?"\u279C ":" "}),a(p,{borderStyle:"round",borderColor:x?S:"gray",paddingX:2,children:a(s,{color:x?S:"gray",bold:x,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"})})]})},Le=({currentVar:e,currentIndex:t,totalCount:o,onSubmit:r,onSkip:n})=>{let[i,c]=M(e.defaultValue||""),[d,m]=M(null);xe(()=>{c(e.defaultValue||""),m(null)},[e.name]),z((h,l)=>{if(l.escape){if(e.required&&!i.trim()){m("This field is required and cannot be skipped");return}n()}});let g=h=>{if(e.required&&!h.trim()){m("This field is required");return}m(null),r(h)},v=!!e.defaultValue;return u(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:d?"red":S,children:[u(p,{justifyContent:"space-between",children:[a(s,{bold:!0,children:"Configure Environment Variables"}),u(s,{color:"gray",children:[t+1," / ",o]})]}),u(p,{marginTop:1,flexDirection:"column",children:[u(p,{children:[a(s,{color:S,bold:!0,children:e.name}),e.required?u(s,{color:"red",bold:!0,children:[" ","* required"]}):u(s,{color:"gray",dimColor:!0,children:[" ","(optional)"]})]}),u(p,{marginTop:1,children:[u(s,{color:"cyan",bold:!0,children:["Category:"," "]}),a(s,{color:"white",children:e.category})]}),u(p,{children:[u(s,{color:"cyan",bold:!0,children:["Purpose:"," "]}),a(s,{color:"white",children:e.description})]}),e.affectedFeatures&&u(p,{children:[u(s,{color:"cyan",bold:!0,children:["Affects:"," "]}),a(s,{color:"gray",children:e.affectedFeatures})]}),e.docsUrl&&u(p,{marginTop:1,children:[a(s,{color:"green",children:"\u{1F4D6} Docs: "}),a(s,{color:"blue",underline:!0,children:e.docsUrl})]}),v&&u(p,{marginTop:1,children:[u(s,{color:"green",bold:!0,children:["Default:"," "]}),a(s,{color:"white",children:e.defaultValue})]})]}),u(p,{marginTop:1,children:[a(s,{color:S,children:"\u279C "}),a(pe,{value:i,onChange:h=>{c(h),d&&m(null)},onSubmit:g,placeholder:v?"Press Enter to use default":e.required?"Enter a value (required)":"Press Enter to skip"})]}),d&&a(p,{marginTop:1,children:u(s,{color:"red",bold:!0,children:["\u26A0 ",d]})}),a(p,{marginTop:1,flexDirection:"column",children:e.required?a(s,{color:"yellow",dimColor:!0,children:"\u21B5 Enter to confirm (required field)"}):v?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"})})]})},rt=({store:e})=>{let[t,o]=M(e.currentState);return xe(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),u(ge,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&a(zt,{onConfirm:()=>e.submitInput(!0)}),t.step==="Prerequisites"&&t.data.checks&&u(p,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:S,children:[a(s,{bold:!0,children:"System Checks"}),u(p,{flexDirection:"column",marginTop:1,children:[a(De,{label:"Git",status:t.data.checks.git}),a(De,{label:"Docker",status:t.data.checks.docker}),a(De,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&a(Zt,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="repo_path"&&a(er,{defaultValue:t.inputRequest.meta.default,onSubmit:r=>e.submitInput(r)}),t.step==="Repository Setup"&&u(p,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:S,children:[a(s,{bold:!0,children:"Cloning Repository"}),u(p,{marginTop:1,flexDirection:"column",children:[a(Ze,{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(Be,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&a(Ae,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&a(_e,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&a(Le,{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(Oe,{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(Me,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Finished"&&a(tr,{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(rr,{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:u(s,{color:"red",children:["Error: ",t.error.message]})})]})};import{Spinner as or}from"@inkjs/ui";import{Box as G,Text as O,useInput as nr}from"ink";import{useEffect as ir,useState as ar}from"react";import{jsx as N,jsxs as B}from"react/jsx-runtime";var ot=({store:e,command:t})=>{let[o,r]=ar(e.currentState);ir(()=>{let i=()=>r({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),nr((i,c)=>{(c.return||c.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:S,children:[N(or,{label:o.status||"Working..."}),o.data.repoPath&&N(G,{marginTop:1,children:B(O,{color:"gray",children:["Repository: ",o.data.repoPath]})}),o.data.setupMode&&N(G,{children:B(O,{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(O,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),o.data.setupMode!=="developer"&&B(G,{marginTop:1,flexDirection:"column",children:[B(O,{children:["Web:"," ",B(O,{color:"cyan",bold:!0,children:["http://localhost:",o.data.webPort||3e3]})]}),B(O,{children:["API:"," ",B(O,{color:"cyan",bold:!0,children:["http://localhost:",o.data.apiPort||8e3]})]})]}),o.data.setupMode==="developer"&&B(G,{marginTop:1,flexDirection:"column",children:[N(O,{color:"gray",children:"Dev servers started in background."}),B(O,{color:"gray",children:["Logs: ",N(O,{color:S,children:"dev-start.log"})," in your repo root."]}),B(O,{color:"gray",children:["Run ",N(O,{color:S,children:"gaia stop"})," to shut down."]})]}),N(G,{marginTop:1,children:N(O,{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:S,children:[B(O,{color:S,bold:!0,children:["\u2713"," All GAIA services stopped."]}),N(G,{marginTop:1,children:N(O,{dimColor:!0,children:"Press Enter to exit"})})]}),o.error&&B(G,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[B(O,{color:"red",children:["Error: ",o.error.message]}),N(G,{marginTop:1,children:N(O,{dimColor:!0,children:"Press Enter to exit"})})]})]})};import{ProgressBar as sr,Spinner as Ne}from"@inkjs/ui";import{Box as R,Text as P,useInput as nt}from"ink";import{useEffect as cr,useState as lr}from"react";import{jsx as y,jsxs as k}from"react/jsx-runtime";var it=({store:e})=>{let[t,o]=lr(e.currentState);return cr(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),k(ge,{status:t.status,step:t.step,steps:ze,children:[t.step==="Detect Repo"&&k(R,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:S,children:[y(P,{bold:!0,children:"Detecting GAIA Repository"}),y(R,{marginTop:1,children:y(Ne,{label:"Searching for repository..."})}),t.data.repoPath&&y(R,{marginTop:1,children:k(P,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&k(R,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:S,children:[y(P,{bold:!0,children:"System Checks"}),k(R,{flexDirection:"column",marginTop:1,children:[y(Fe,{label:"Git",status:t.data.checks.git}),y(Fe,{label:"Docker",status:t.data.checks.docker}),y(Fe,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&y(ur,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="setup_mode"&&y(Be,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&y(Ae,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&y(_e,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&y(Le,{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&&y(Oe,{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&&y(Me,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Project Setup"&&k(R,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:S,children:[y(R,{marginBottom:1,children:y(P,{bold:!0,color:S,children:"Project Setup"})}),k(R,{flexDirection:"column",gap:1,children:[y(R,{children:t.data.dependencyComplete?k(P,{color:"green",children:["\u2713"," ",t.data.dependencyPhase]}):y(Ne,{label:t.data.dependencyPhase||"Preparing..."})}),!t.data.dependencyComplete&&t.data.dependencyProgress>0&&y(R,{width:50,children:y(sr,{value:t.data.dependencyProgress})}),!t.data.dependencyComplete&&t.data.dependencyLogs?.length>0&&y(R,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,minHeight:6,children:t.data.dependencyLogs.map((r,n)=>y(P,{color:"gray",wrap:"truncate",children:r},n))})]})]}),t.step==="Finished"&&y(pr,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,onConfirm:()=>e.submitInput(!0)}),t.error&&y(R,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:k(P,{color:"red",children:["Error: ",t.error.message]})})]})},Fe=({label:e,status:t})=>k(R,{children:[y(R,{marginRight:1,children:t==="pending"?y(Ne,{type:"dots"}):t==="success"?y(P,{color:S,children:"\u2714"}):t==="error"?y(P,{color:"red",children:"\u2716"}):y(P,{color:"yellow",children:"\u26A0"})}),y(P,{children:e})]}),ur=({portResults:e,onAccept:t,onAbort:o})=>(nt((r,n)=>{n.return?t():n.escape&&o()}),k(R,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[y(P,{bold:!0,color:"yellow",children:"Port Conflicts Detected"}),e.map(r=>k(R,{children:[k(P,{color:r.available?"green":"red",children:[r.available?"\u2714":"\u2716"," "]}),k(P,{children:[r.service," (:",r.port,")"]}),!r.available&&k(P,{color:"gray",children:[" ","- in use",r.usedBy?` by ${r.usedBy}`:"",r.alternative?` (alt: :${r.alternative})`:""]})]},r.port)),y(R,{marginTop:1,children:k(P,{children:[y(P,{color:"green",bold:!0,children:"Enter"})," continue ",y(P,{color:"yellow",bold:!0,children:"Escape"})," abort"]})})]})),pr=({setupMode:e,repoPath:t,onConfirm:o})=>(nt((i,c)=>{c.return&&o()}),k(R,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:S,padding:1,children:[y(P,{color:S,bold:!0,children:"Setup Complete!"}),k(R,{marginTop:1,flexDirection:"column",children:[y(P,{bold:!0,children:"To start GAIA, run:"}),k(R,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[k(P,{color:"cyan",children:["$ cd ",t||"."]}),y(P,{color:"cyan",children:"$ gaia start"})]}),y(R,{marginTop:1,children:y(P,{color:"gray",dimColor:!0,children:(e||"developer")==="selfhost"?"Runs: docker compose --profile all up -d (background)":"Runs: mise dev (interactive \u2014 keep terminal open)"})})]}),y(ke,{}),y(R,{marginTop:1,children:y(P,{dimColor:!0,children:"Press Enter to exit"})})]}));import{Spinner as dr}from"@inkjs/ui";import{Box as A,Text as _,useInput as mr}from"ink";import{useEffect as at,useState as st}from"react";import{jsx as w,jsxs as L}from"react/jsx-runtime";var ct=({store:e})=>{let[t,o]=st(e.currentState),[r,n]=st(!1);return at(()=>{let i=()=>o({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),at(()=>{t.step==="Results"&&n(!1)},[t.step]),mr((i,c)=>{(c.return||c.escape)&&t.step==="Results"&&e.submitInput("exit"),i==="r"&&t.step==="Results"&&t.data.refreshable&&!r&&(n(!0),e.submitInput("refresh"))}),L(A,{flexDirection:"column",width:"100%",children:[w(te,{}),t.step==="Checking"&&w(A,{marginTop:1,children:w(dr,{label:t.data.services?"Refreshing service health...":"Checking service health..."})}),t.step==="Results"&&t.data.services&&L(A,{flexDirection:"column",children:[L(A,{flexDirection:"column",borderStyle:"round",borderColor:S,paddingX:2,paddingY:1,children:[w(_,{bold:!0,color:S,children:"GAIA Service Status"}),L(A,{marginTop:1,flexDirection:"column",children:[L(A,{children:[w(A,{width:22,children:w(_,{bold:!0,children:"Service"})}),w(A,{width:10,children:w(_,{bold:!0,children:"Status"})}),w(A,{width:10,children:w(_,{bold:!0,children:"Latency"})})]}),w(_,{color:"gray",children:"\u2500".repeat(42)}),t.data.services.map(i=>L(A,{children:[w(A,{width:22,children:L(_,{children:[i.name," (:",i.port,")"]})}),w(A,{width:10,children:w(_,{color:i.status==="up"?"green":"red",bold:!0,children:i.status==="up"?"\u2713 UP":"\u2717 DOWN"})}),w(A,{width:10,children:w(_,{color:"gray",children:i.latency?`${i.latency}ms`:"--"})})]},i.name))]})]}),t.data.docker&&L(A,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:2,paddingY:1,marginTop:1,children:[w(_,{bold:!0,children:"Docker Containers"}),L(_,{color:"gray",children:["Docker:"," ",t.data.docker.running?w(_,{color:"green",children:"Running"}):w(_,{color:"red",children:"Not running"})]}),t.data.docker.containers?.length>0&&w(A,{marginTop:1,flexDirection:"column",children:t.data.docker.containers.map(i=>L(A,{children:[L(_,{color:i.status==="running"?"green":"red",children:[i.status==="running"?"\u2713":"\u2717"," "]}),w(_,{children:i.name}),i.health&&L(_,{color:"gray",children:[" (",i.health,")"]})]},i.name))})]}),w(A,{marginTop:1,children:L(_,{dimColor:!0,children:["Press Enter or Escape to exit \xB7 Press"," ",w(_,{color:S,children:"r"})," to refresh"]})})]}),t.error&&w(A,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:L(_,{color:"red",children:["Error: ",t.error.message]})})]})};import{jsx as $,jsxs as de}from"react/jsx-runtime";var gr=["init","setup","status","start","stop"],Ge=class extends fr.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?de(he,{flexDirection:"column",padding:1,children:[$(Z,{color:"red",bold:!0,children:"An unexpected error occurred:"}),$(Z,{color:"red",children:this.state.error.message}),this.state.error.stack&&$(he,{marginTop:1,children:$(Z,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},xr=({store:e,command:t})=>{switch(t){case"init":return $(rt,{store:e});case"setup":return $(it,{store:e});case"status":return $(ct,{store:e});case"start":case"stop":return $(ot,{store:e,command:t});default:return de(he,{flexDirection:"column",padding:1,children:[de(Z,{color:"red",children:["Unknown command: ",t]}),de(he,{marginTop:1,flexDirection:"column",children:[$(Z,{bold:!0,children:"Available commands:"}),gr.map(o=>de(Z,{children:[" ",$(Z,{color:"cyan",children:o})]},o))]})]})}},j=({store:e,command:t})=>$(Ge,{children:$(xr,{store:e,command:t})});import{EventEmitter as hr}from"events";var Sr=150,$e=class extends hr{state={step:"init",status:"",error:null,data:{},inputRequest:null};inputResolver=null;emitTimer=null;emitPending=!1;get currentState(){return this.state}scheduleEmit(){this.emitPending=!0,this.emitTimer||(this.emitTimer=setTimeout(()=>{this.emitTimer=null,this.emitPending&&(this.emitPending=!1,this.emit("change",this.state))},Sr))}emitNow(){this.emitTimer&&(clearTimeout(this.emitTimer),this.emitTimer=null),this.emitPending=!1,this.emit("change",this.state)}setStep(t){this.state.step=t,this.emitNow()}setStatus(t){this.state.status=t,this.scheduleEmit()}setError(t){this.state.error=t,t!==null&&this.inputResolver&&(this.inputResolver(null),this.inputResolver=null,this.state.inputRequest=null),this.emitNow()}updateData(t,o){this.state.data={...this.state.data,[t]:o},this.scheduleEmit()}waitForInput(t,o){return this.state.inputRequest={id:t,meta:o},this.emitNow(),new Promise(r=>{this.inputResolver=r})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emitNow())}},H=()=>new $e;import*as ce from"fs";import*as Ct from"path";import*as ne from"node:fs";import*as oe from"node:path";import{execa as lt}from"execa";var qe={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/"}},ut={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 je(e,t){return qe[t][e]??ut[t][e]}async function pt(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 lt("python3",[t,o,r],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await lt("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 dt(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 c of r.split(`
3
- `)){let d=c.trim();if(d.startsWith("#")&&!d.startsWith("#=")){let h=d.replace(/^#+\s*/,"").trim();h&&!h.startsWith("These are")&&(i=h);continue}if(!d||d.startsWith("#"))continue;let m=d.indexOf("=");if(m===-1)continue;let g=d.substring(0,m).trim(),v=d.substring(m+1).trim();n.push({name:g,value:v,category:i})}return n}function mt(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 ft(e,t,o){let r=o==="selfhost"?new Set(Object.keys(qe.selfhost)):new Set;for(let[n,i]of Object.entries(t)){let c=Number(n),d=Number(i);for(let[m,g]of Object.entries(e)){if(r.has(m))continue;if(g===String(c)){e[m]=String(d);continue}let v=new RegExp(`:${c}(?=[/\\s]|$)`,"g");e[m]=g.replaceAll(v,`:${d}`)}}}function gt(e,t){return e.map(o=>({...o,variables:o.variables.map(r=>{let n=je(r.name,t);return{...r,defaultValue:n||r.defaultValue}})}))}function He(){return Object.keys(qe.selfhost)}function xt(e){return{...ut[e]}}import*as F from"fs";import*as ie from"path";function Ve(e){F.existsSync(e)&&F.copyFileSync(e,`${e}.bak`)}function St(e,t){let o=ie.join(e,".env");Ve(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(d){for(let g of n)if(d===g||d.startsWith(`${g}_`))return g;let m=d.split("_");return m.length===1?"Core":m[0]||"Core"}let c=new Map;for(let[d,m]of Object.entries(t)){let g=i(d);c.has(g)||c.set(g,[]);let h=/[\s#"'\\]/.test(m)||m===""?`"${m.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:m;c.get(g).push(`${d}=${h}`)}for(let[d,m]of c.entries())r.push(`# ${d} Configuration`),r.push(...m),r.push("");F.writeFileSync(o,r.join(`
4
- `),"utf-8")}function vt(e,t,o){let r=ie.join(e,"apps","web",".env.local");Ve(r);let n=dt(e),i=mt(t,o),c=["# GAIA Web App Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],d=new Map;for(let m of n){d.has(m.category)||d.set(m.category,[]);let g=i[m.name]??m.value;d.get(m.category).push({name:m.name,value:g})}if(n.length===0){c.push("# Core URLs");for(let[m,g]of Object.entries(i))c.push(`${m}=${g}`);c.push("")}else for(let[m,g]of d.entries()){c.push(`# ${m}`);for(let{name:v,value:h}of g)c.push(`${v}=${h}`);c.push("")}F.writeFileSync(r,c.join(`
5
- `),"utf-8")}var Tt={8e3:"API_HOST_PORT",5432:"POSTGRES_HOST_PORT",6379:"REDIS_HOST_PORT",27017:"MONGO_HOST_PORT",5672:"RABBITMQ_HOST_PORT",8080:"CHROMADB_HOST_PORT",8083:"MONGO_EXPRESS_HOST_PORT",3e3:"WEB_HOST_PORT"};function yt(e,t){let o=ie.join(e,"infra","docker",".env");Ve(o);let r=["# Docker Compose port overrides","# Generated by GAIA CLI to resolve port conflicts",`# Created: ${new Date().toISOString()}`,""];for(let[n,i]of Object.entries(t)){let c=Number(n),d=Tt[c];d&&r.push(`${d}=${i}`)}r.push(""),F.writeFileSync(o,r.join(`
6
- `),"utf-8")}function ae(e){let t={};for(let[o,r]of Object.entries(e)){let n=Number(o),i=Tt[n];i&&(t[i]=String(r))}return t}function bt(e){let t=ie.join(e,"infra","docker","docker-compose.yml");if(!F.existsSync(t))return;let o=F.readFileSync(t,"utf-8"),r=[{varName:"API_HOST_PORT",hostPort:8e3,containerPort:80},{varName:"CHROMADB_HOST_PORT",hostPort:8080,containerPort:8e3},{varName:"POSTGRES_HOST_PORT",hostPort:5432,containerPort:5432},{varName:"REDIS_HOST_PORT",hostPort:6379,containerPort:6379},{varName:"MONGO_HOST_PORT",hostPort:27017,containerPort:27017},{varName:"RABBITMQ_HOST_PORT",hostPort:5672,containerPort:5672},{varName:"MONGO_EXPRESS_HOST_PORT",hostPort:8083,containerPort:8081}],n=!1;for(let{varName:i,hostPort:c,containerPort:d}of r){let m=`"${c}:${d}"`,g=`"\${${i}:-${c}}:${d}"`;o.includes(m)&&(o=o.replace(m,g),n=!0)}n&&F.writeFileSync(t,o,"utf-8")}var ht={API_HOST_PORT:8e3,POSTGRES_HOST_PORT:5432,REDIS_HOST_PORT:6379,MONGO_HOST_PORT:27017,RABBITMQ_HOST_PORT:5672,CHROMADB_HOST_PORT:8080,MONGO_EXPRESS_HOST_PORT:8083,WEB_HOST_PORT:3e3};function se(e){let t=ie.join(e,"infra","docker",".env"),o={};if(!F.existsSync(t))return o;let r=F.readFileSync(t,"utf-8");for(let n of r.split(`
7
- `)){let i=n.trim();if(i&&!i.startsWith("#")){let[c,...d]=i.split("=");if(c&&ht[c]){let m=Number(d.join("=").trim());!Number.isNaN(m)&&m>0&&(o[ht[c]]=m)}}}return o}var yr=e=>new Promise(t=>setTimeout(t,e));async function Se(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="development";let c=He();for(let m of c){let g=je(m,r);g&&(i[m]=g)}let d=xt(r);for(let[m,g]of Object.entries(d))i[m]=g;if(n==="infisical")await br(e,i),e.setStatus("Infisical credentials saved. Ensure your Infisical project contains all required variables.");else try{await Cr(e,t,i,r)}catch(m){e.setError(m);return}o&&ft(i,o,r);try{await Ir(e,t,i,r,o)}catch(m){e.setError(m);return}await yr(1e3)}async function br(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 Cr(e,t,o,r){e.setStatus("Parsing environment variables...");let n;try{n=await pt(t),n=gt(n,r)}catch(f){throw new Error(`Failed to parse settings: ${f.message}`)}let i=new Set,c=[],d=new Set;for(let f of n)if(f.alternativeGroup&&!d.has(f.name)){let b=n.find(T=>T.name===f.alternativeGroup);b&&(c.push([f,b]),i.add(f.name),i.add(b.name),d.add(f.name),d.add(b.name))}let m=n.filter(f=>f.variables.length===1&&!i.has(f.name)),g=n.filter(f=>f.variables.length>1&&!i.has(f.name));for(let f of c){e.updateData("alternativeGroups",f),e.setStatus("Choose an AI provider...");let b=await e.waitForInput("env_alternatives");for(let[T,C]of Object.entries(b.values))C&&(o[T]=C)}let v=He(),l=[...m.flatMap(f=>f.variables).filter(f=>!v.includes(f.name))].sort((f,b)=>f.required&&!b.required?-1:!f.required&&b.required?1:0);e.updateData("envVarTotal",l.length);for(let f=0;f<l.length;f++){let b=l[f];if(!b)continue;e.updateData("currentEnvVar",b),e.updateData("envVarIndex",f),e.setStatus(`Configuring ${b.name}...`);let T=await e.waitForInput("env_var",{varName:b.name});(T||b.required||b.defaultValue)&&(o[b.name]=T||b.defaultValue||"")}let x=[...g].filter(f=>!f.variables.every(b=>v.includes(b.name))).sort((f,b)=>{let T=f.variables.some(I=>I.required),C=b.variables.some(I=>I.required);return T&&!C?-1:!T&&C?1:0});e.updateData("envGroupTotal",x.length);for(let f=0;f<x.length;f++){let b=x[f];if(!b)continue;e.updateData("currentEnvGroup",b),e.updateData("envGroupIndex",f),e.setStatus(`Configuring ${b.name}...`);let T=await e.waitForInput("env_group",{groupName:b.name});for(let[C,I]of Object.entries(T)){let E=b.variables.find(Q=>Q.name===C);(I||E?.required||E?.defaultValue)&&(o[C]=I||E?.defaultValue||"")}}}async function Ir(e,t,o,r,n){e.setStatus("Writing API environment file...");try{let i=Ct.join(t,"apps","api");St(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{vt(t,r,n),e.setStatus("Web environment variables configured!")}catch(i){throw new Error(`Failed to write web .env file: ${i.message}`)}if(n&&Object.keys(n).length>0){e.setStatus("Writing Docker Compose port overrides...");try{bt(t),yt(t,n),e.setStatus("Docker Compose ports configured!")}catch(i){throw new Error(`Failed to write Docker Compose .env: ${i.message}`)}}}import{execa as Er}from"execa";import ve from"fs";import Pr from"simple-git";async function It(e,t,o){if(ve.existsSync(e)){let r=`${e}/.git`;if(!ve.existsSync(r))throw new Error(`Directory ${e} exists but is not a git repository`);await Pr().cwd(e).pull(),o(100,"Already exists, pulled latest")}else try{let r=Er("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 c=i.match(/Receiving objects:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(c?.[1]){let m=Math.min(100,parseInt(c[1],10)),g=c[2],v=c[3];o(10+Math.floor(m*.5),`Receiving objects: ${g}/${v}`)}let d=i.match(/Resolving deltas:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(d?.[1]){let m=Math.min(100,parseInt(d[1],10)),g=d[2],v=d[3];o(60+Math.floor(m*.4),`Resolving deltas: ${g}/${v}`)}}),await r,o(100,"Clone complete")}catch(r){throw ve.existsSync(e)&&ve.rmSync(e,{recursive:!0,force:!0}),r}}import{execa as Y}from"execa";var V={git:"https://git-scm.com/downloads",docker:"https://docs.docker.com/get-docker/",mise:"https://mise.jdx.dev/getting-started.html"},Rr={8e3:"API Server",5432:"PostgreSQL",6379:"Redis",27017:"MongoDB",5672:"RabbitMQ",3e3:"Web Frontend",8080:"ChromaDB",8083:"Mongo Express"};async function Te(){try{return await Y("git",["--version"]),"success"}catch{return"error"}}async function ye(){let e=!1,t=!1,o;try{await Y("docker",["--version"]),e=!0}catch{return{name:"Docker",installUrl:V.docker,installed:!1,working:!1,errorMessage:"Docker is not installed"}}try{await Y("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:V.docker,installed:e,working:t,errorMessage:o}}async function be(){try{return await Y("mise",["--version"]),"success"}catch{return"missing"}}async function Ce(){if((await import("node:os")).platform()==="win32")try{return await Y("powershell",["-Command","irm https://mise.jdx.dev/install.ps1 | iex"]),!0}catch{return!1}try{return await Y("sh",["-c","curl https://mise.jdx.dev/install.sh | sh"]),!0}catch{return!1}}async function Ie(e){let t=await import("node:net"),o=[],r=n=>new Promise(i=>{let c=t.createServer();c.once("error",()=>i(!1)),c.once("listening",()=>{c.close(()=>i(!0))}),c.listen(n)});for(let n of e){let i=Rr[n]||`Port ${n}`;if(await r(n))o.push({port:n,service:i,available:!0});else{let d=await Dr(n),m=await kr(n+1,n+100,r);o.push({port:n,service:i,available:!1,usedBy:d,alternative:m||void 0})}}return o}async function Dr(e){if((await import("node:os")).platform()==="win32"){try{let{stdout:r}=await Y("netstat",["-ano","-p","TCP"]),n=r.trim().split(`
8
- `);for(let i of n)if(i.includes(`:${e}`)&&i.includes("LISTENING")){let c=i.trim().split(/\s+/),d=c[c.length-1];if(d)try{let{stdout:m}=await Y("tasklist",["/FI",`PID eq ${d}`,"/FO","CSV","/NH"]);return m.trim().split(",")[0]?.replace(/"/g,"")||`PID ${d}`}catch{return`PID ${d}`}}}catch{}return}try{let{stdout:r}=await Y("lsof",["-i",`:${e}`,"-sTCP:LISTEN","-P","-n"]),n=r.trim().split(`
9
- `);if(n.length>1)return n[1]?.split(/\s+/)?.[0]||void 0}catch{}}async function kr(e,t,o){for(let r=e;r<=t;r++)if(await o(r))return r;return null}import*as U from"fs";import*as W from"path";var Br=e=>new Promise(t=>setTimeout(t,e)),Ar="dev-start.log";function Pt(e){let t=W.join(e,".env");return U.existsSync(t)?["--env-file",".env"]:[]}async function wt(e,t,o,r){if(t==="selfhost"){o?.("Starting all services in Docker (selfhost mode)...");let n=W.join(e,"infra/docker"),i=Pt(n),c=r&&Object.keys(r).length>0?ae(r):void 0;await q("docker",["compose",...i,"--profile","backend","--profile","worker","up","-d","--build","--remove-orphans"],n,void 0,void 0,c),o?.("All services started in Docker!")}else{o?.("Starting development servers...");let{spawn:n}=await import("child_process"),i=W.join(e,Ar),c=U.openSync(i,"a"),d;try{d=n("mise",["dev"],{cwd:e,stdio:["ignore",c,c],detached:!0,shell:!0}),d.unref()}finally{U.closeSync(c)}if(await Br(1500),d.pid!=null)try{process.kill(d.pid,0)}catch{throw new Error(`Development servers crashed on startup. Check logs at: ${i}`)}o?.(`Development servers started! Logs: ${i}`)}}async function Rt(e,t,o){let r=W.join(e,"infra/docker");t?.("Stopping Docker services...");try{let i=["compose",...Pt(r),"down"];await q("docker",i,r)}catch{}t?.("Stopping local processes...");try{let n=o?.[8e3]??8e3,i=o?.[3e3]??3e3;if(process.platform==="win32")for(let c of[n,i])try{await q("powershell",["-Command",`Get-NetTCPConnection -LocalPort ${c} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`],e)}catch{}else for(let c of[n,i])try{await q("sh",["-c",`lsof -ti :${c} -sTCP:LISTEN | xargs kill 2>/dev/null || true`],e)}catch{}}catch{}t?.("All services stopped.")}async function Dt(e){let t=W.join(e,"apps","api",".env");if(!U.existsSync(t))return null;let o=U.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 q(e,t,o,r,n,i){let{spawn:c}=await import("child_process");return new Promise((d,m)=>{let g=c(e,t,{cwd:o,stdio:["ignore","pipe","pipe"],shell:!0,env:i?{...process.env,...i}:void 0}),v="",h=0;g.stdout?.on("data",l=>{let x=l.toString();v+=x,n?.(x),h=Math.min(h+5,95),r?.(h)}),g.stderr?.on("data",l=>{let x=l.toString();v+=x,n?.(x),h=Math.min(h+5,95),r?.(h)}),g.on("close",l=>{l===0?(r?.(100),d()):m(new Error(`Command failed with code ${l}: ${v.slice(-500)}`))}),g.on("error",l=>{m(l)})})}function X(e){let t=e||process.cwd();for(;t!==W.dirname(t);){if(U.existsSync(W.join(t,"apps/api/app/config/settings_validator.py")))return t;t=W.dirname(t)}return null}var _r=process.env.GAIA_CLI_DEV==="true",K=e=>new Promise(t=>setTimeout(t,e));async function kt(e){e.setStep("Welcome"),e.setStatus("Waiting for user input..."),await e.waitForInput("welcome");let t=l=>{let x=e.currentState.data.dependencyLogs||[],f=l.split(`
10
- `).filter(T=>T.trim()!==""),b=[...x,...f].slice(-20);e.updateData("dependencyLogs",b)};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 Te();e.updateData("checks",{...e.currentState.data.checks,git:o}),e.setStatus("Checking Docker...");let r=await ye(),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 be();e.updateData("checks",{...e.currentState.data.checks,mise:i}),i==="missing"&&(e.setStatus("Installing Mise..."),i=await Ce()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:i}));let c=[];if(o==="error"&&c.push({name:"Git"}),n==="error"&&c.push({name:"Docker",message:r.errorMessage}),i==="error"&&c.push({name:"Mise"}),c.length>0){let l=[];l.push("Prerequisites failed:");for(let x of c)l.push(` \u2022 ${x.name}: ${x.message||"Not installed or not working"}`);l.push(`
11
- Installation guides:`),o==="error"&&l.push(` \u2022 Git: ${V.git}`),n==="error"&&(r.installed?l.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):l.push(` \u2022 Docker: ${V.docker}`)),i==="error"&&l.push(` \u2022 Mise: ${V.mise}`),e.setError(new Error(l.join(`
12
- `)));return}e.setStatus("Checking Ports...");let m=await Ie([8e3,5432,6379,27017,5672,3e3,8080,8083]),g={},v=m.filter(l=>!l.available);if(v.length>0){let l=v.filter(f=>!f.alternative);if(l.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${l.map(f=>`${f.port} (${f.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",m),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let f of m)!f.available&&f.alternative&&(g[f.port]=f.alternative)}e.updateData("portOverrides",g),e.setStatus("Prerequisites check complete!"),await K(1e3);let h="";if(_r){if(h=X()||"",!h){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(h=await e.waitForInput("repo_path",{default:"./gaia"}),ce.existsSync(h)){if(!ce.statSync(h).isDirectory()){e.setError(new Error(`Path ${h} exists and is not a directory.`)),await K(2e3),e.setError(null);continue}if(ce.readdirSync(h).length>0){e.setError(new Error(`Directory ${h} 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 It(h,"https://github.com/theexperiencecompany/gaia.git",(l,x)=>{e.updateData("repoProgress",l),x?(e.updateData("repoPhase",x),e.setStatus(`${x}...`)):e.setStatus(`Cloning repository to ${h}... ${l}%`)}),e.setStatus("Repository ready!")}catch(l){e.setError(l);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 q("mise",["trust"],h,void 0,t),e.updateData("dependencyProgress",50),e.updateData("dependencyPhase","Installing tools (node, python, uv, nx)..."),await q("mise",["install"],h,l=>{e.updateData("dependencyProgress",50+l*.5)},t),e.updateData("dependencyProgress",100),e.updateData("toolComplete",!0)}catch(l){e.setError(new Error(`Failed to install tools: ${l.message}`));return}if(await K(1e3),await Se(e,h,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",h),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyProgress",0),e.updateData("dependencyPhase","Running mise setup (all dependencies)...");let l=Object.keys(g).length>0?ae(g):void 0;await q("mise",["setup"],h,x=>{e.updateData("dependencyProgress",x)},t,l),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(l){e.setError(new Error(`Failed to setup project: ${l.message}`));return}await K(1e3),e.setStep("Finished"),e.setStatus("Setup complete!")}}async function Bt(){let e=H(),{unmount:t}=Or(Mr.createElement(j,{store:e,command:"init"}));try{await kt(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Lr}from"ink";import Fr from"react";var Ee=e=>new Promise(t=>setTimeout(t,e));async function At(e){e.setStep("Detect Repo"),e.setStatus("Looking for GAIA repository...");let t=X();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 Ee(1e3),e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await Ee(500);let o=await Te();e.updateData("checks",{...e.currentState.data.checks,git:o});let r=await ye(),n=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:n}),r.working||e.updateData("dockerError",r.errorMessage);let i=await be();e.updateData("checks",{...e.currentState.data.checks,mise:i}),i==="missing"&&(e.setStatus("Installing Mise..."),i=await Ce()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:i}));let c=[];if(o==="error"&&c.push({name:"Git"}),n==="error"&&c.push({name:"Docker",message:r.errorMessage}),i==="error"&&c.push({name:"Mise"}),c.length>0){let l=[];l.push("Prerequisites failed:");for(let x of c)l.push(` \u2022 ${x.name}: ${x.message||"Not installed or not working"}`);l.push(`
13
- Installation guides:`),o==="error"&&l.push(` \u2022 Git: ${V.git}`),n==="error"&&(r.installed?l.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):l.push(` \u2022 Docker: ${V.docker}`)),i==="error"&&l.push(` \u2022 Mise: ${V.mise}`),e.setError(new Error(l.join(`
14
- `)));return}e.setStatus("Checking Ports...");let m=await Ie([8e3,5432,6379,27017,5672,3e3,8080,8083]),g={},v=m.filter(l=>!l.available);if(v.length>0){let l=v.filter(f=>!f.alternative);if(l.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${l.map(f=>`${f.port} (${f.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",m),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let f of m)!f.available&&f.alternative&&(g[f.port]=f.alternative)}if(e.updateData("portOverrides",g),e.setStatus("Prerequisites check complete!"),await Ee(1e3),await Se(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 h=l=>{let x=e.currentState.data.dependencyLogs||[],f=l.split(`
15
- `).filter(T=>T.trim()!==""),b=[...x,...f].slice(-20);e.updateData("dependencyLogs",b)};try{e.updateData("dependencyPhase","Trusting mise configuration..."),await q("mise",["trust"],t,void 0,h),e.updateData("dependencyProgress",20),e.updateData("dependencyPhase","Installing tools..."),await q("mise",["install"],t,x=>{e.updateData("dependencyProgress",20+x*.3)},h),e.updateData("dependencyPhase","Running mise setup...");let l=Object.keys(g).length>0?ae(g):void 0;await q("mise",["setup"],t,x=>{e.updateData("dependencyProgress",50+x*.5)},h,l),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(l){e.setError(new Error(`Failed to setup project: ${l.message}`));return}await Ee(1e3),e.setStep("Finished"),e.setStatus("Setup complete!")}async function _t(){let e=H(),{unmount:t}=Lr(Fr.createElement(j,{store:e,command:"setup"}));try{await At(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Nr}from"ink";import Gr from"react";async function Ot(e){e.setStep("Starting"),e.setStatus("Locating GAIA repository...");let t=X();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 Dt(t);if(!o){e.setError(new Error("No .env file found. Run 'gaia setup' first to configure the environment."));return}let r=se(t),n=r[3e3]??3e3,i=r[8e3]??8e3;e.updateData("setupMode",o),e.updateData("webPort",n),e.updateData("apiPort",i),e.setStatus(`Starting GAIA in ${o} mode...`);try{await wt(t,o,c=>{e.setStatus(c)},r),e.setStep("Running"),e.setStatus("GAIA is running!"),e.updateData("started",!0)}catch(c){e.setError(new Error(`Failed to start services: ${c.message}`));return}await e.waitForInput("exit")}async function Mt(){let e=H(),{unmount:t}=Nr(Gr.createElement(j,{store:e,command:"start"}));await new Promise(o=>setTimeout(o,50));try{await Ot(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Vr}from"ink";import Wr from"react";import{execa as Ue}from"execa";var We=["gaia-backend","gaia-web","chromadb","postgres","redis","mongo","rabbitmq","arq_worker"];async function Lt(){try{let{stdout:e}=await Ue("docker",["inspect","--format","{{.Name}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",...We]),t=new Map;for(let o of e.trim().split(`
16
- `)){if(!o)continue;let[r,n,i]=o.split("|"),c=r?.replace(/^\//,"")??"";t.set(c,{name:c,status:n==="running"?"running":"stopped",health:i!=="none"?i:void 0})}return We.map(o=>t.get(o)??{name:o,status:"not_found"})}catch{let e=We.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 Ft(){try{return await Ue("docker",["info"]),!0}catch{return!1}}var $r=[{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 Nt(e){let o=$r.map(r=>({...r,port:e?.[r.port]??r.port})).map(r=>r.type==="http"?qr(r.name,r.port,r.path):jr(r.name,r.port));return Promise.all(o)}async function qr(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 jr(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 c=Date.now()-r;i.destroy(),n({name:e,port:t,status:"up",latency:c})}),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 Gt(){return await Ft()?{running:!0,containers:await Lt()}:{running:!1,containers:[]}}async function Hr(e){e.setStep("Checking"),e.setStatus("Checking service health..."),e.updateData("refreshable",!1);let t=X(),o=t?se(t):void 0,[r,n]=await Promise.all([Nt(o),Gt()]);e.updateData("services",r),e.updateData("docker",n);let i=r.filter(d=>d.status==="up").length,c=r.length;e.setStep("Results"),e.setStatus(`${i}/${c} services running`),e.updateData("refreshable",!0)}async function $t(e){for(;await Hr(e),await e.waitForInput("exit_or_refresh")==="refresh";);}async function qt(){let e=H(),{unmount:t}=Vr(Wr.createElement(j,{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 Ur}from"ink";import Xr from"react";async function jt(e){e.setStep("Stopping"),e.setStatus("Locating GAIA repository...");let t=X();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=se(t);try{await Rt(t,r=>{e.setStatus(r)},o),e.setStep("Stopped"),e.setStatus("All services stopped."),e.updateData("stopped",!0)}catch(r){e.setError(new Error(`Failed to stop services: ${r.message}`));return}await e.waitForInput("exit")}async function Ht(){let e=H(),{unmount:t}=Ur(Xr.createElement(j,{store:e,command:"stop"}));await new Promise(o=>setTimeout(o,50));try{await jt(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}var J=new Qr;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 Bt()});J.command("setup").description("Configure an existing GAIA repository").action(async()=>{await _t()});J.command("status").description("Check health of all GAIA services").action(async()=>{await qt()});J.command("start").description("Start GAIA services").action(async()=>{await Mt()});J.command("stop").description("Stop all GAIA services").action(async()=>{await Ht()});process.argv.slice(2).length||(J.outputHelp(),process.exit(0));J.parse();
2
+ import{Command as Qr}from"commander";import{render as Or}from"ink";import Mr from"react";import{Box as Se,Text as Z}from"ink";import fr from"react";import{ProgressBar as tt,Select as rt,Spinner as Be}from"@inkjs/ui";import{Box as p,Text as s,useInput as z}from"ink";import pe from"ink-text-input";import{useEffect as xe,useState as M}from"react";import{Box as ue,Text as Ze}from"ink";var h="#00bbff";import{Box as Ut,Text as Re}from"ink";import{jsx as Ke,jsxs as Je}from"react/jsx-runtime";var ze=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:Je(Ut,{width:"100%",borderStyle:"single",borderColor:"gray",paddingX:1,justifyContent:"space-between",children:[Je(Re,{color:h,children:[Ke(Re,{bold:!0,children:"Status:"})," ",t]}),Ke(Re,{color:"white",dimColor:!0,children:e})]});import{Box as Xt}from"ink";import Qt from"ink-big-text";import Yt from"ink-gradient";import{jsx as De}from"react/jsx-runtime";var te=()=>De(Xt,{flexDirection:"column",marginTop:1,marginBottom:1,children:De(Yt,{colors:[h,"#b0eaff",h],children:De(Qt,{text:"GAIA",font:"3d"})})});import{jsx as re,jsxs as fe}from"react/jsx-runtime";var Kt=["Welcome","Prerequisites","Repository Setup","Install Tools","Environment Setup","Project Setup","Finished"],et=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Jt=({currentStep:e,steps:t})=>{let o=t.indexOf(e);return re(ue,{marginBottom:1,children:t.map((r,n)=>{let i=r===e,c=o>n;return fe(ue,{marginRight:2,children:[fe(Ze,{color:i?h:c?"green":"gray",children:[c?"\u2713 ":i?"\u25CF ":"\u25CB ",r]}),n<t.length-1&&re(Ze,{color:"gray",children:" \u203A "})]},r)})})},ge=({children:e,status:t,step:o,steps:r=Kt})=>fe(ue,{flexDirection:"column",height:"100%",width:"100%",children:[fe(ue,{flexGrow:1,flexDirection:"column",children:[re(te,{}),re(Jt,{currentStep:o,steps:r}),re(ue,{flexDirection:"column",flexGrow:1,children:e})]}),re(ze,{status:t,step:o})]});import{Fragment as To,jsx as a,jsxs as l}from"react/jsx-runtime";var ke=({label:e,status:t})=>l(p,{children:[a(p,{marginRight:1,children:t==="pending"?a(Be,{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})]}),zt=({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..."})]})),Zt=({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"]})})]})]})},er=({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(pe,{value:o,onChange:r,onSubmit:t})]}),l(s,{color:"gray",children:["(Press Enter for default: ",e,")"]})]})},tr=({setupMode:e,repoPath:t,portOverrides:o,onConfirm:r})=>{z((m,g)=>{g.return&&r()});let n=e||"developer",i=t||"./gaia",c=o?.[3e3]??3e3,u=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:",c]})]}),l(s,{children:["API:"," ",l(s,{color:"cyan",bold:!0,children:["http://localhost:",u]})]})]})]}),a(Ae,{}),a(p,{marginTop:1,children:a(s,{dimColor:!0,children:"Press Enter to exit"})})]})},Ae=()=>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"})]})]})]}),rr=({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(Be,{label:e||"Preparing..."})}),!o&&t>0&&a(p,{width:50,children:a(tt,{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,c)=>a(s,{color:"gray",wrap:"truncate",children:i},c))})]})]});var _e=({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(rt,{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)"})]})]}),Oe=({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(rt,{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)"})]})]}),Me=({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,c]=M(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"}];z((g,T)=>{if(T.tab||T.downArrow)n(S=>S<u.length-1?S+1:S);else if(T.upArrow)n(S=>S>0?S-1:S);else if(T.return){if(r<u.length-1){n(v=>v+1);return}let S=u.filter(v=>!t[v.key].trim());if(S.length>0){c(`Required: ${S.map(d=>d.key).join(", ")}`);let v=u.findIndex(d=>!t[d.key].trim());v>=0&&n(v);return}e(t)}});let m=u[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."]})]}),u.map((g,T)=>{let S=g.key.includes("SECRET")||g.key.includes("TOKEN");return l(p,{flexDirection:"column",marginBottom:1,children:[a(p,{children:l(s,{color:T===r?h:"white",children:[T===r?"\u25B8 ":" ",g.key,":"]})}),a(p,{marginLeft:2,children:a(s,{color:"gray",dimColor:!0,children:g.description})}),T===r?a(p,{marginLeft:2,children:a(pe,{value:t[g.key],onChange:v=>{o(d=>({...d,[g.key]:v})),c(null)},placeholder:"Enter value...",mask:S?"*":void 0})}):a(p,{marginLeft:2,children:a(s,{color:t[g.key]?"green":"gray",children:t[g.key]?S?`\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"})})]})},Fe=({category:e,currentIndex:t,totalGroups:o,onSubmit:r})=>{let[n,i]=M(()=>{let v={};for(let d of e.variables)v[d.name]=d.defaultValue||"";return v}),[c,u]=M(0),[m,g]=M(null);xe(()=>{let v={};for(let d of e.variables)v[d.name]=d.defaultValue||"";i(v),u(0),g(null)},[e.name]),z((v,d)=>{if(d.tab||d.downArrow)u(f=>f<e.variables.length-1?f+1:f);else if(d.upArrow)u(f=>f>0?f-1:f);else if(d.escape){let f=e.variables.filter(x=>x.required&&!n[x.name]?.trim());if(f.length>0){g(`Required fields cannot be skipped: ${f.map(x=>x.name).join(", ")}`);return}r(n)}});let T=()=>{if(c<e.variables.length-1)u(c+1);else{let v=e.variables.filter(d=>d.required&&!n[d.name]?.trim());if(v.length>0){g(`Required fields are missing: ${v.map(d=>d.name).join(", ")}`);return}g(null),r(n)}},S=e.variables.some(v=>v.required);return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:m?"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((v,d)=>{let f=d===c,x=!!v.defaultValue;return l(p,{flexDirection:"column",marginBottom:1,children:[l(p,{children:[l(s,{color:f?h:"gray",bold:f,children:[f?"\u279C ":" ",v.name]}),v.required&&l(s,{color:"red",bold:!0,children:[" ","*"]}),x&&!f&&l(s,{color:"gray",dimColor:!0,children:[" ","(default: ",v.defaultValue,")"]})]}),f&&a(p,{marginLeft:2,children:a(pe,{value:n[v.name]||"",onChange:b=>{i(I=>({...I,[v.name]:b})),m&&g(null)},onSubmit:T,placeholder:x?`Default: ${v.defaultValue}`:v.required?"Enter a value (required)":"Press Enter to skip"})})]},v.name)})}),m&&a(p,{marginTop:1,children:l(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),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",!S&&" \u2022 ESC skip group"]})})]})},Le=({alternatives:e,onSubmit:t})=>{let[o,r]=M(new Set),[n,i]=M({}),[c,u]=M(0),[m,g]=M(null);xe(()=>{let b={};for(let I of e)for(let w of I.variables)b[w.name]=w.defaultValue||"";i(b)},[e]);let T=[];for(let b=0;b<e.length;b++)if(T.push({type:"provider",categoryIndex:b}),o.has(b)){let I=e[b];if(I)for(let w=0;w<I.variables.length;w++)T.push({type:"field",categoryIndex:b,fieldIndex:w})}T.push({type:"submit"});let S=T[c],v=S?.type==="field",d=S?.type==="submit";z((b,I)=>{let w=Math.min(c,T.length-1);if(w!==c){u(w);return}if(v)I.upArrow?u(R=>Math.max(0,R-1)):(I.downArrow||I.tab)&&u(R=>Math.min(T.length-1,R+1));else if(d)I.upArrow?u(R=>Math.max(0,R-1)):(I.return||b===" ")&&x();else if(I.upArrow)u(R=>Math.max(0,R-1));else if(I.downArrow||I.tab)u(R=>Math.min(T.length-1,R+1));else if((I.return||b===" ")&&S?.type==="provider"){let R=S.categoryIndex;r(Q=>{let k=new Set(Q);return k.has(R)?k.delete(R):k.add(R),k}),m&&g(null)}});let f=()=>{m&&g(null),u(b=>Math.min(T.length-1,b+1))},x=()=>{let b=[],I={};for(let w of o){let R=e[w];if(!R)continue;if(R.variables.some(k=>n[k.name]?.trim())){b.push(R.name);for(let k of R.variables){let me=n[k.name];me&&(I[k.name]=me)}}}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:m?"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 w=o.has(I),R=T.findIndex(k=>k.type==="provider"&&k.categoryIndex===I),Q=c===R;return l(p,{flexDirection:"column",marginBottom:1,children:[l(p,{children:[a(s,{color:Q?h:void 0,bold:Q,children:Q?"\u279C ":" "}),a(s,{color:w?"green":"gray",children:w?"[\u2714]":"[ ]"}),l(s,{color:w?h:"gray",bold:w,children:[" ",b.name]}),b.description&&l(s,{color:"gray",dimColor:!0,children:[" ","- ",b.description]})]}),Q&&b.docsUrl&&l(p,{marginLeft:6,children:[a(s,{color:"yellow",children:"\u{1F4D6} "}),a(s,{color:"blue",underline:!0,children:b.docsUrl})]}),w&&a(p,{marginLeft:4,flexDirection:"column",marginTop:1,children:b.variables.map((k,me)=>{let Wt=T.findIndex(le=>le.type==="field"&&le.categoryIndex===I&&le.fieldIndex===me),ee=c===Wt,Ye=!!k.defaultValue,we=n[k.name]||"";return l(p,{flexDirection:"column",marginBottom:1,children:[l(p,{children:[l(s,{color:ee?h:"gray",bold:ee,children:[ee?" \u279C ":" ",k.name]}),!ee&&we&&a(s,{color:"green",children:" \u2713"}),!ee&&!we&&Ye&&l(s,{color:"gray",dimColor:!0,children:[" ","(default: ",k.defaultValue,")"]})]}),ee&&a(p,{marginLeft:4,children:a(pe,{value:we,onChange:le=>{i(Vt=>({...Vt,[k.name]:le})),m&&g(null)},onSubmit:f,placeholder:Ye?`Default: ${k.defaultValue}`:"Enter value..."})})]},k.name)})})]},b.name)})}),m&&a(p,{marginTop:1,children:l(s,{color:"red",bold:!0,children:["\u26A0 ",m]})}),l(p,{marginTop:1,children:[a(s,{color:d?h:void 0,bold:d,children:d?"\u279C ":" "}),a(p,{borderStyle:"round",borderColor:d?h:"gray",paddingX:2,children:a(s,{color:d?h:"gray",bold:d,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"})})]})},Ne=({currentVar:e,currentIndex:t,totalCount:o,onSubmit:r,onSkip:n})=>{let[i,c]=M(e.defaultValue||""),[u,m]=M(null);xe(()=>{c(e.defaultValue||""),m(null)},[e.name]),z((S,v)=>{if(v.escape){if(e.required&&!i.trim()){m("This field is required and cannot be skipped");return}n()}});let g=S=>{if(e.required&&!S.trim()){m("This field is required");return}m(null),r(S)},T=!!e.defaultValue;return l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:u?"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})]}),T&&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(pe,{value:i,onChange:S=>{c(S),u&&m(null)},onSubmit:g,placeholder:T?"Press Enter to use default":e.required?"Enter a value (required)":"Press Enter to skip"})]}),u&&a(p,{marginTop:1,children:l(s,{color:"red",bold:!0,children:["\u26A0 ",u]})}),a(p,{marginTop:1,flexDirection:"column",children:e.required?a(s,{color:"yellow",dimColor:!0,children:"\u21B5 Enter to confirm (required field)"}):T?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"})})]})},ot=({store:e})=>{let[t,o]=M(e.currentState);return xe(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),l(ge,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&a(zt,{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(ke,{label:"Git",status:t.data.checks.git}),a(ke,{label:"Docker",status:t.data.checks.docker}),a(ke,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&a(Zt,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="repo_path"&&a(er,{defaultValue:t.inputRequest.meta.default,onSubmit:r=>e.submitInput(r)}),t.step==="Repository Setup"&&!t.inputRequest&&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(tt,{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(_e,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&a(Oe,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&a(Me,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&a(Ne,{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(Fe,{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(Le,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Environment Setup"&&!t.inputRequest&&l(p,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[a(s,{bold:!0,children:"Environment Setup"}),a(p,{marginTop:1,children:a(Be,{label:t.status||"Configuring environment..."})})]}),t.step==="Finished"&&a(tr,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),(t.step==="Install Tools"||t.step==="Project Setup")&&a(rr,{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 or}from"@inkjs/ui";import{Box as G,Text as O,useInput as nr}from"ink";import{useEffect as ir,useState as ar}from"react";import{jsx as N,jsxs as B}from"react/jsx-runtime";var nt=({store:e,command:t})=>{let[o,r]=ar(e.currentState);ir(()=>{let i=()=>r({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),nr((i,c)=>{(c.return||c.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(or,{label:o.status||"Working..."}),o.data.repoPath&&N(G,{marginTop:1,children:B(O,{color:"gray",children:["Repository: ",o.data.repoPath]})}),o.data.setupMode&&N(G,{children:B(O,{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(O,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),o.data.setupMode!=="developer"&&B(G,{marginTop:1,flexDirection:"column",children:[B(O,{children:["Web:"," ",B(O,{color:"cyan",bold:!0,children:["http://localhost:",o.data.webPort||3e3]})]}),B(O,{children:["API:"," ",B(O,{color:"cyan",bold:!0,children:["http://localhost:",o.data.apiPort||8e3]})]})]}),o.data.setupMode==="developer"&&B(G,{marginTop:1,flexDirection:"column",children:[N(O,{color:"gray",children:"Dev servers started in background."}),B(O,{color:"gray",children:["Logs: ",N(O,{color:h,children:"dev-start.log"})," in your repo root."]}),B(O,{color:"gray",children:["Run ",N(O,{color:h,children:"gaia stop"})," to shut down."]})]}),N(G,{marginTop:1,children:N(O,{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(O,{color:h,bold:!0,children:["\u2713"," All GAIA services stopped."]}),N(G,{marginTop:1,children:N(O,{dimColor:!0,children:"Press Enter to exit"})})]}),o.error&&B(G,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[B(O,{color:"red",children:["Error: ",o.error.message]}),N(G,{marginTop:1,children:N(O,{dimColor:!0,children:"Press Enter to exit"})})]})]})};import{ProgressBar as sr,Spinner as he}from"@inkjs/ui";import{Box as P,Text as C,useInput as it}from"ink";import{useEffect as cr,useState as lr}from"react";import{jsx as y,jsxs as E}from"react/jsx-runtime";var at=({store:e})=>{let[t,o]=lr(e.currentState);return cr(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),E(ge,{status:t.status,step:t.step,steps:et,children:[t.step==="Detect Repo"&&E(P,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:h,children:[y(C,{bold:!0,children:"Detecting GAIA Repository"}),y(P,{marginTop:1,children:y(he,{label:"Searching for repository..."})}),t.data.repoPath&&y(P,{marginTop:1,children:E(C,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&E(P,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:h,children:[y(C,{bold:!0,children:"System Checks"}),E(P,{flexDirection:"column",marginTop:1,children:[y(Ge,{label:"Git",status:t.data.checks.git}),y(Ge,{label:"Docker",status:t.data.checks.docker}),y(Ge,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&y(ur,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="setup_mode"&&y(_e,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&y(Oe,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&y(Me,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&y(Ne,{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&&y(Fe,{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&&y(Le,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Environment Setup"&&!t.inputRequest&&E(P,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[y(C,{bold:!0,children:"Environment Setup"}),y(P,{marginTop:1,children:y(he,{label:t.status||"Configuring environment..."})})]}),t.step==="Project Setup"&&E(P,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:h,children:[y(P,{marginBottom:1,children:y(C,{bold:!0,color:h,children:"Project Setup"})}),E(P,{flexDirection:"column",gap:1,children:[y(P,{children:t.data.dependencyComplete?E(C,{color:"green",children:["\u2713"," ",t.data.dependencyPhase]}):y(he,{label:t.data.dependencyPhase||"Preparing..."})}),!t.data.dependencyComplete&&t.data.dependencyProgress>0&&y(P,{width:50,children:y(sr,{value:t.data.dependencyProgress})}),!t.data.dependencyComplete&&t.data.dependencyLogs?.length>0&&y(P,{flexDirection:"column",marginTop:1,borderStyle:"single",borderColor:"gray",paddingX:1,minHeight:6,children:t.data.dependencyLogs.map((r,n)=>y(C,{color:"gray",wrap:"truncate",children:r},n))})]})]}),t.step==="Finished"&&y(pr,{setupMode:t.data.setupMode,repoPath:t.data.repoPath,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),t.error&&y(P,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:E(C,{color:"red",children:["Error: ",t.error.message]})})]})},Ge=({label:e,status:t})=>E(P,{children:[y(P,{marginRight:1,children:t==="pending"?y(he,{type:"dots"}):t==="success"?y(C,{color:h,children:"\u2714"}):t==="error"?y(C,{color:"red",children:"\u2716"}):y(C,{color:"yellow",children:"\u26A0"})}),y(C,{children:e})]}),ur=({portResults:e,onAccept:t,onAbort:o})=>(it((r,n)=>{n.return?t():n.escape&&o()}),E(P,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[y(C,{bold:!0,color:"yellow",children:"Port Conflicts Detected"}),e.map(r=>E(P,{children:[E(C,{color:r.available?"green":"red",children:[r.available?"\u2714":"\u2716"," "]}),E(C,{children:[r.service," (:",r.port,")"]}),!r.available&&E(C,{color:"gray",children:[" ","- in use",r.usedBy?` by ${r.usedBy}`:"",r.alternative?` (alt: :${r.alternative})`:""]})]},r.port)),y(P,{marginTop:1,children:E(C,{children:[y(C,{color:"green",bold:!0,children:"Enter"})," continue ",y(C,{color:"yellow",bold:!0,children:"Escape"})," abort"]})})]})),pr=({setupMode:e,repoPath:t,portOverrides:o,onConfirm:r})=>{it((m,g)=>{g.return&&r()});let n=e||"developer",i=t||".",c=o?.[3e3]??3e3,u=o?.[8e3]??8e3;return E(P,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:h,padding:1,children:[y(C,{color:h,bold:!0,children:"Setup Complete!"}),E(P,{marginTop:1,flexDirection:"column",children:[y(C,{bold:!0,children:"To start GAIA, run:"}),E(P,{marginTop:1,padding:1,borderStyle:"single",borderColor:"gray",flexDirection:"column",children:[E(C,{color:"cyan",children:["$ cd ",i]}),y(C,{color:"cyan",children:"$ gaia start"})]}),y(P,{marginTop:1,children:y(C,{color:"gray",dimColor:!0,children:n==="selfhost"?"Runs: docker compose --profile all up -d (background)":"Runs: mise dev (interactive \u2014 keep terminal open)"})})]}),E(P,{marginTop:1,flexDirection:"column",children:[y(C,{bold:!0,children:"Access GAIA at:"}),E(P,{marginLeft:2,flexDirection:"column",children:[E(C,{children:["Web:"," ",E(C,{color:"cyan",bold:!0,children:["http://localhost:",c]})]}),E(C,{children:["API:"," ",E(C,{color:"cyan",bold:!0,children:["http://localhost:",u]})]})]})]}),y(Ae,{}),y(P,{marginTop:1,children:y(C,{dimColor:!0,children:"Press Enter to exit"})})]})};import{Spinner as dr}from"@inkjs/ui";import{Box as A,Text as _,useInput as mr}from"ink";import{useEffect as st,useState as ct}from"react";import{jsx as D,jsxs as F}from"react/jsx-runtime";var lt=({store:e})=>{let[t,o]=ct(e.currentState),[r,n]=ct(!1);return st(()=>{let i=()=>o({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),st(()=>{t.step==="Results"&&n(!1)},[t.step]),mr((i,c)=>{(c.return||c.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(dr,{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 $,jsxs as de}from"react/jsx-runtime";var gr=["init","setup","status","start","stop"],$e=class extends fr.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?de(Se,{flexDirection:"column",padding:1,children:[$(Z,{color:"red",bold:!0,children:"An unexpected error occurred:"}),$(Z,{color:"red",children:this.state.error.message}),this.state.error.stack&&$(Se,{marginTop:1,children:$(Z,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},xr=({store:e,command:t})=>{switch(t){case"init":return $(ot,{store:e});case"setup":return $(at,{store:e});case"status":return $(lt,{store:e});case"start":case"stop":return $(nt,{store:e,command:t});default:return de(Se,{flexDirection:"column",padding:1,children:[de(Z,{color:"red",children:["Unknown command: ",t]}),de(Se,{marginTop:1,flexDirection:"column",children:[$(Z,{bold:!0,children:"Available commands:"}),gr.map(o=>de(Z,{children:[" ",$(Z,{color:"cyan",children:o})]},o))]})]})}},j=({store:e,command:t})=>$($e,{children:$(xr,{store:e,command:t})});import{EventEmitter as hr}from"events";var Sr=150,qe=class extends hr{state={step:"init",status:"",error:null,data:{},inputRequest:null};inputResolver=null;emitTimer=null;emitPending=!1;get currentState(){return this.state}scheduleEmit(){this.emitPending=!0,this.emitTimer||(this.emitTimer=setTimeout(()=>{this.emitTimer=null,this.emitPending&&(this.emitPending=!1,this.emit("change",this.state))},Sr))}emitNow(){this.emitTimer&&(clearTimeout(this.emitTimer),this.emitTimer=null),this.emitPending=!1,this.emit("change",this.state)}setStep(t){this.state.step=t,this.emitNow()}setStatus(t){this.state.status=t,this.scheduleEmit()}setError(t){this.state.error=t,t!==null&&this.inputResolver&&(this.inputResolver(null),this.inputResolver=null,this.state.inputRequest=null),this.emitNow()}updateData(t,o){this.state.data={...this.state.data,[t]:o},this.scheduleEmit()}waitForInput(t,o){return this.state.inputRequest={id:t,meta:o},this.emitNow(),new Promise(r=>{this.inputResolver=r})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emitNow())}},H=()=>new qe;import*as ce from"fs";import*as Ct from"path";import*as ne from"node:fs";import*as oe from"node:path";import{execa as ut}from"execa";var je={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/"}},pt={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 He(e,t){return je[t][e]??pt[t][e]}async function dt(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 ut("python3",[t,o,r],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await ut("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 mt(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 c of r.split(`
3
+ `)){let u=c.trim();if(u.startsWith("#")&&!u.startsWith("#=")){let S=u.replace(/^#+\s*/,"").trim();S&&!S.startsWith("These are")&&(i=S);continue}if(!u||u.startsWith("#"))continue;let m=u.indexOf("=");if(m===-1)continue;let g=u.substring(0,m).trim(),T=u.substring(m+1).trim();n.push({name:g,value:T,category:i})}return n}function ft(e,t){return{NEXT_PUBLIC_API_BASE_URL:`http://localhost:${t?.[8e3]??8e3}/api/v1/`}}function gt(e,t,o){let r=o==="selfhost"?new Set(Object.keys(je.selfhost)):new Set;for(let[n,i]of Object.entries(t)){let c=Number(n),u=Number(i);for(let[m,g]of Object.entries(e)){if(r.has(m))continue;if(g===String(c)){e[m]=String(u);continue}let T=new RegExp(`:${c}(?=[/\\s]|$)`,"g");e[m]=g.replaceAll(T,`:${u}`)}}}function xt(e,t){return e.map(o=>({...o,variables:o.variables.map(r=>{let n=He(r.name,t);return{...r,defaultValue:n||r.defaultValue}})}))}function We(){return Object.keys(je.selfhost)}function ht(e){return{...pt[e]}}import*as L from"fs";import*as ie from"path";function Ve(e){L.existsSync(e)&&L.copyFileSync(e,`${e}.bak`)}function vt(e,t){let o=ie.join(e,".env");Ve(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(u){for(let g of n)if(u===g||u.startsWith(`${g}_`))return g;let m=u.split("_");return m.length===1?"Core":m[0]||"Core"}let c=new Map;for(let[u,m]of Object.entries(t)){let g=i(u);c.has(g)||c.set(g,[]);let S=/[\s#"'\\]/.test(m)||m===""?`"${m.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:m;c.get(g).push(`${u}=${S}`)}for(let[u,m]of c.entries())r.push(`# ${u} Configuration`),r.push(...m),r.push("");L.writeFileSync(o,r.join(`
4
+ `),"utf-8")}function Tt(e,t,o){let r=ie.join(e,"apps","web",".env.local");Ve(r);let n=mt(e),i=ft(t,o),c=["# GAIA Web App Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],u=new Map;for(let m of n){u.has(m.category)||u.set(m.category,[]);let g=i[m.name]??m.value;u.get(m.category).push({name:m.name,value:g})}if(n.length===0){c.push("# Core URLs");for(let[m,g]of Object.entries(i))c.push(`${m}=${g}`);c.push("")}else for(let[m,g]of u.entries()){c.push(`# ${m}`);for(let{name:T,value:S}of g)c.push(`${T}=${S}`);c.push("")}L.writeFileSync(r,c.join(`
5
+ `),"utf-8")}var yt={8e3:"API_HOST_PORT",5432:"POSTGRES_HOST_PORT",6379:"REDIS_HOST_PORT",27017:"MONGO_HOST_PORT",5672:"RABBITMQ_HOST_PORT",8080:"CHROMADB_HOST_PORT",8083:"MONGO_EXPRESS_HOST_PORT",3e3:"WEB_HOST_PORT"};function bt(e,t,o){let r=ie.join(e,"infra","docker",".env");Ve(r);let n=["# Docker Compose environment overrides","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""];for(let[i,c]of Object.entries(t)){let u=Number(i),m=yt[u];m&&n.push(`${m}=${c}`)}if(o==="selfhost"){let i=t[8e3]??8e3;n.push(""),n.push("# Web build args"),n.push(`NEXT_PUBLIC_API_BASE_URL=http://localhost:${i}/api/v1/`)}n.push(""),L.writeFileSync(r,n.join(`
6
+ `),"utf-8")}function ae(e){let t={};for(let[o,r]of Object.entries(e)){let n=Number(o),i=yt[n];i&&(t[i]=String(r))}return t}function It(e){let t=ie.join(e,"infra","docker","docker-compose.yml");if(!L.existsSync(t))return;let o=L.readFileSync(t,"utf-8"),r=[{varName:"API_HOST_PORT",hostPort:8e3,containerPort:80},{varName:"CHROMADB_HOST_PORT",hostPort:8080,containerPort:8e3},{varName:"POSTGRES_HOST_PORT",hostPort:5432,containerPort:5432},{varName:"REDIS_HOST_PORT",hostPort:6379,containerPort:6379},{varName:"MONGO_HOST_PORT",hostPort:27017,containerPort:27017},{varName:"RABBITMQ_HOST_PORT",hostPort:5672,containerPort:5672},{varName:"MONGO_EXPRESS_HOST_PORT",hostPort:8083,containerPort:8081},{varName:"WEB_HOST_PORT",hostPort:3e3,containerPort:3e3}],n=!1;for(let{varName:i,hostPort:c,containerPort:u}of r){let m=`"${c}:${u}"`,g=`"\${${i}:-${c}}:${u}"`;o.includes(m)&&(o=o.replace(m,g),n=!0)}n&&L.writeFileSync(t,o,"utf-8")}var St={API_HOST_PORT:8e3,POSTGRES_HOST_PORT:5432,REDIS_HOST_PORT:6379,MONGO_HOST_PORT:27017,RABBITMQ_HOST_PORT:5672,CHROMADB_HOST_PORT:8080,MONGO_EXPRESS_HOST_PORT:8083,WEB_HOST_PORT:3e3};function se(e){let t=ie.join(e,"infra","docker",".env"),o={};if(!L.existsSync(t))return o;let r=L.readFileSync(t,"utf-8");for(let n of r.split(`
7
+ `)){let i=n.trim();if(i&&!i.startsWith("#")){let[c,...u]=i.split("=");if(c&&St[c]){let m=Number(u.join("=").trim());!Number.isNaN(m)&&m>0&&(o[St[c]]=m)}}}return o}var yr=e=>new Promise(t=>setTimeout(t,e));async function ve(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="development";let c=We();for(let m of c){let g=He(m,r);g&&(i[m]=g)}let u=ht(r);for(let[m,g]of Object.entries(u))i[m]=g;if(n==="infisical")await br(e,i),e.setStatus("Infisical credentials saved. Ensure your Infisical project contains all required variables.");else try{await Ir(e,t,i,r)}catch(m){e.setError(m);return}o&&gt(i,o,r);try{await Cr(e,t,i,r,o)}catch(m){e.setError(m);return}await yr(1e3)}async function br(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 Ir(e,t,o,r){e.setStatus("Parsing environment variables...");let n;try{n=await dt(t),n=xt(n,r)}catch(f){throw r==="selfhost"?new Error(`Manual environment setup requires Python to parse config schema.
8
+ For self-host mode, we recommend using Infisical for secret management.
9
+ Alternatively, install Python 3.11+ and try again.
10
+
11
+ Original error: ${f.message}`):new Error(`Failed to parse settings: ${f.message}`)}let i=new Set,c=[],u=new Set;for(let f of n)if(f.alternativeGroup&&!u.has(f.name)){let x=n.find(b=>b.name===f.alternativeGroup);x&&(c.push([f,x]),i.add(f.name),i.add(x.name),u.add(f.name),u.add(x.name))}let m=n.filter(f=>f.variables.length===1&&!i.has(f.name)),g=n.filter(f=>f.variables.length>1&&!i.has(f.name));for(let f of c){e.updateData("alternativeGroups",f),e.setStatus("Choose an AI provider...");let x=await e.waitForInput("env_alternatives");for(let[b,I]of Object.entries(x.values))I&&(o[b]=I)}let T=We(),v=[...m.flatMap(f=>f.variables).filter(f=>!T.includes(f.name))].sort((f,x)=>f.required&&!x.required?-1:!f.required&&x.required?1:0);e.updateData("envVarTotal",v.length);for(let f=0;f<v.length;f++){let x=v[f];if(!x)continue;e.updateData("currentEnvVar",x),e.updateData("envVarIndex",f),e.setStatus(`Configuring ${x.name}...`);let b=await e.waitForInput("env_var",{varName:x.name});(b||x.required||x.defaultValue)&&(o[x.name]=b||x.defaultValue||"")}let d=[...g].filter(f=>!f.variables.every(x=>T.includes(x.name))).sort((f,x)=>{let b=f.variables.some(w=>w.required),I=x.variables.some(w=>w.required);return b&&!I?-1:!b&&I?1:0});e.updateData("envGroupTotal",d.length);for(let f=0;f<d.length;f++){let x=d[f];if(!x)continue;e.updateData("currentEnvGroup",x),e.updateData("envGroupIndex",f),e.setStatus(`Configuring ${x.name}...`);let b=await e.waitForInput("env_group",{groupName:x.name});for(let[I,w]of Object.entries(b)){let R=x.variables.find(Q=>Q.name===I);(w||R?.required||R?.defaultValue)&&(o[I]=w||R?.defaultValue||"")}}}async function Cr(e,t,o,r,n){e.setStatus("Writing API environment file...");try{let c=Ct.join(t,"apps","api");vt(c,o),e.setStatus("API environment variables configured!")}catch(c){throw new Error(`Failed to write API .env file: ${c.message}`)}e.setStatus("Writing web environment file...");try{Tt(t,r,n),e.setStatus("Web environment variables configured!")}catch(c){throw new Error(`Failed to write web .env file: ${c.message}`)}let i=n&&Object.keys(n).length>0;if(i||r==="selfhost"){e.setStatus("Writing Docker Compose environment...");try{i&&It(t),bt(t,n??{},r),e.setStatus("Docker Compose environment configured!")}catch(c){throw new Error(`Failed to write Docker Compose .env: ${c.message}`)}}}import{execa as Er}from"execa";import Te from"fs";import Pr from"simple-git";async function Et(e,t,o){if(Te.existsSync(e)){let r=`${e}/.git`;if(!Te.existsSync(r))throw new Error(`Directory ${e} exists but is not a git repository`);await Pr().cwd(e).pull(),o(100,"Already exists, pulled latest")}else try{let r=Er("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 c=i.match(/Receiving objects:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(c?.[1]){let m=Math.min(100,parseInt(c[1],10)),g=c[2],T=c[3];o(10+Math.floor(m*.5),`Receiving objects: ${g}/${T}`)}let u=i.match(/Resolving deltas:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(u?.[1]){let m=Math.min(100,parseInt(u[1],10)),g=u[2],T=u[3];o(60+Math.floor(m*.4),`Resolving deltas: ${g}/${T}`)}}),await r,o(100,"Clone complete")}catch(r){throw Te.existsSync(e)&&Te.rmSync(e,{recursive:!0,force:!0}),r}}import{execa as Y}from"execa";var W={git:"https://git-scm.com/downloads",docker:"https://docs.docker.com/get-docker/",mise:"https://mise.jdx.dev/getting-started.html"},Rr={8e3:"API Server",5432:"PostgreSQL",6379:"Redis",27017:"MongoDB",5672:"RabbitMQ",3e3:"Web Frontend",8080:"ChromaDB",8083:"Mongo Express"};async function ye(){try{return await Y("git",["--version"]),"success"}catch{return"error"}}async function be(){let e=!1,t=!1,o;try{await Y("docker",["--version"]),e=!0}catch{return{name:"Docker",installUrl:W.docker,installed:!1,working:!1,errorMessage:"Docker is not installed"}}try{await Y("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:W.docker,installed:e,working:t,errorMessage:o}}async function Ie(){try{return await Y("mise",["--version"]),"success"}catch{return"missing"}}async function Ce(){if((await import("node:os")).platform()==="win32")try{return await Y("powershell",["-Command","irm https://mise.jdx.dev/install.ps1 | iex"]),!0}catch{return!1}try{return await Y("sh",["-c","curl https://mise.jdx.dev/install.sh | sh"]),!0}catch{return!1}}async function Ee(e){let t=await import("node:net"),o=[],r=n=>new Promise(i=>{let c=t.createServer();c.once("error",()=>i(!1)),c.once("listening",()=>{c.close(()=>i(!0))}),c.listen(n)});for(let n of e){let i=Rr[n]||`Port ${n}`;if(await r(n))o.push({port:n,service:i,available:!0});else{let u=await Dr(n),m=await kr(n+1,n+100,r);o.push({port:n,service:i,available:!1,usedBy:u,alternative:m||void 0})}}return o}async function Dr(e){if((await import("node:os")).platform()==="win32"){try{let{stdout:r}=await Y("netstat",["-ano","-p","TCP"]),n=r.trim().split(`
12
+ `);for(let i of n)if(i.includes(`:${e}`)&&i.includes("LISTENING")){let c=i.trim().split(/\s+/),u=c[c.length-1];if(u)try{let{stdout:m}=await Y("tasklist",["/FI",`PID eq ${u}`,"/FO","CSV","/NH"]);return m.trim().split(",")[0]?.replace(/"/g,"")||`PID ${u}`}catch{return`PID ${u}`}}}catch{}return}try{let{stdout:r}=await Y("lsof",["-i",`:${e}`,"-sTCP:LISTEN","-P","-n"]),n=r.trim().split(`
13
+ `);if(n.length>1)return n[1]?.split(/\s+/)?.[0]||void 0}catch{}}async function kr(e,t,o){for(let r=e;r<=t;r++)if(await o(r))return r;return null}import*as U from"fs";import*as V from"path";var Br=e=>new Promise(t=>setTimeout(t,e)),Ar="dev-start.log";function wt(e){let t=V.join(e,".env");return U.existsSync(t)?["--env-file",".env"]:[]}async function Rt(e,t,o,r){if(t==="selfhost"){o?.("Starting all services in Docker (selfhost mode)...");let n=V.join(e,"infra/docker"),i=wt(n),c=r&&Object.keys(r).length>0?ae(r):void 0;await q("docker",["compose","-f","docker-compose.selfhost.yml",...i,"up","-d","--build","--remove-orphans"],n,void 0,void 0,c),o?.("All services started in Docker!")}else{o?.("Starting development servers...");let{spawn:n}=await import("child_process"),i=V.join(e,Ar),c=U.openSync(i,"a"),u;try{u=n("mise",["dev"],{cwd:e,stdio:["ignore",c,c],detached:!0,shell:!0}),u.unref()}finally{U.closeSync(c)}if(await Br(1500),u.pid!=null)try{process.kill(u.pid,0)}catch{throw new Error(`Development servers crashed on startup. Check logs at: ${i}`)}o?.(`Development servers started! Logs: ${i}`)}}async function Dt(e,t,o){let r=V.join(e,"infra/docker"),n=await Ue(e);t?.("Stopping Docker services...");try{let i=wt(r),c=n==="selfhost"?["compose","-f","docker-compose.selfhost.yml",...i,"down"]:["compose",...i,"down"];await q("docker",c,r)}catch{}if(n!=="selfhost"){t?.("Stopping local processes...");try{let i=o?.[8e3]??8e3,c=o?.[3e3]??3e3;if(process.platform==="win32")for(let u of[i,c])try{await q("powershell",["-Command",`Get-NetTCPConnection -LocalPort ${u} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`],e)}catch{}else for(let u of[i,c])try{await q("sh",["-c",`lsof -ti :${u} -sTCP:LISTEN | xargs kill 2>/dev/null || true`],e)}catch{}}catch{}}t?.("All services stopped.")}async function Ue(e){let t=V.join(e,"apps","api",".env");if(!U.existsSync(t))return null;let o=U.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 q(e,t,o,r,n,i){let{spawn:c}=await import("child_process");return new Promise((u,m)=>{let g=c(e,t,{cwd:o,stdio:["ignore","pipe","pipe"],shell:!0,env:i?{...process.env,...i}:void 0}),T="",S=0;g.stdout?.on("data",v=>{let d=v.toString();T+=d,n?.(d),S=Math.min(S+5,95),r?.(S)}),g.stderr?.on("data",v=>{let d=v.toString();T+=d,n?.(d),S=Math.min(S+5,95),r?.(S)}),g.on("close",v=>{v===0?(r?.(100),u()):m(new Error(`Command failed with code ${v}: ${T.slice(-500)}`))}),g.on("error",v=>{m(v)})})}function X(e){let t=e||process.cwd();for(;t!==V.dirname(t);){if(U.existsSync(V.join(t,"apps/api/app/config/settings_validator.py")))return t;t=V.dirname(t)}return null}var _r=process.env.GAIA_CLI_DEV==="true",K=e=>new Promise(t=>setTimeout(t,e));async function kt(e){e.setStep("Welcome"),e.setStatus("Waiting for user input..."),await e.waitForInput("welcome");let t=d=>{let f=e.currentState.data.dependencyLogs||[],x=d.split(`
14
+ `).filter(I=>I.trim()!==""),b=[...f,...x].slice(-20);e.updateData("dependencyLogs",b)};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 ye();e.updateData("checks",{...e.currentState.data.checks,git:o}),e.setStatus("Checking Docker...");let r=await be(),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 Ie();e.updateData("checks",{...e.currentState.data.checks,mise:i}),i==="missing"&&(e.setStatus("Installing Mise..."),i=await Ce()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:i}));let c=[];if(o==="error"&&c.push({name:"Git"}),n==="error"&&c.push({name:"Docker",message:r.errorMessage}),c.length>0){let d=[];d.push("Prerequisites failed:");for(let f of c)d.push(` \u2022 ${f.name}: ${f.message||"Not installed or not working"}`);d.push(`
15
+ Installation guides:`),o==="error"&&d.push(` \u2022 Git: ${W.git}`),n==="error"&&(r.installed?d.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):d.push(` \u2022 Docker: ${W.docker}`)),e.setError(new Error(d.join(`
16
+ `)));return}e.setStatus("Checking Ports...");let m=await Ee([8e3,5432,6379,27017,5672,3e3,8080,8083]),g={},T=m.filter(d=>!d.available);if(T.length>0){let d=T.filter(x=>!x.alternative);if(d.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${d.map(x=>`${x.port} (${x.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",m),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let x of m)!x.available&&x.alternative&&(g[x.port]=x.alternative)}e.updateData("portOverrides",g),e.setStatus("Prerequisites check complete!"),await K(1e3);let S="";if(_r){if(S=X()||"",!S){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(S=await e.waitForInput("repo_path",{default:"./gaia"}),ce.existsSync(S)){if(!ce.statSync(S).isDirectory()){e.setError(new Error(`Path ${S} exists and is not a directory.`)),await K(2e3),e.setError(null);continue}if(ce.readdirSync(S).length>0){e.setError(new Error(`Directory ${S} 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 Et(S,"https://github.com/theexperiencecompany/gaia.git",(d,f)=>{e.updateData("repoProgress",d),f?(e.updateData("repoPhase",f),e.setStatus(`${f}...`)):e.setStatus(`Cloning repository to ${S}... ${d}%`)}),e.setStatus("Repository ready!")}catch(d){e.setError(d);return}}if(await K(1e3),await ve(e,S,g),e.currentState.error)return;if(e.currentState.data.setupMode==="selfhost"){e.setStep("Finished"),e.setStatus("Setup complete! Run 'gaia start' to build and start all services in Docker."),await e.waitForInput("exit");return}if(i==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
17
+ \u2022 Mise: ${W.mise}`));return}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 q("mise",["trust"],S,void 0,t),e.updateData("dependencyProgress",50),e.updateData("dependencyPhase","Installing tools (node, python, uv, nx)..."),await q("mise",["install"],S,d=>{e.updateData("dependencyProgress",50+d*.5)},t),e.updateData("dependencyProgress",100),e.updateData("toolComplete",!0)}catch(d){e.setError(new Error(`Failed to install tools: ${d.message}`));return}await K(1e3),e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("repoPath",S),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyProgress",0),e.updateData("dependencyPhase","Running mise setup (all dependencies)...");let d=Object.keys(g).length>0?ae(g):void 0;await q("mise",["setup"],S,f=>{e.updateData("dependencyProgress",f)},t,d),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(d){e.setError(new Error(`Failed to setup project: ${d.message}`));return}await K(1e3),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function Bt(){let e=H(),{unmount:t}=Or(Mr.createElement(j,{store:e,command:"init"}));try{await kt(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 Lr from"react";var Pe=e=>new Promise(t=>setTimeout(t,e));async function At(e){e.setStep("Detect Repo"),e.setStatus("Looking for GAIA repository...");let t=X();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 Pe(1e3),e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await Pe(500);let o=await ye();e.updateData("checks",{...e.currentState.data.checks,git:o});let r=await be(),n=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:n}),r.working||e.updateData("dockerError",r.errorMessage);let i=await Ie();e.updateData("checks",{...e.currentState.data.checks,mise:i}),i==="missing"&&(e.setStatus("Installing Mise..."),i=await Ce()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:i}));let c=[];if(o==="error"&&c.push({name:"Git"}),n==="error"&&c.push({name:"Docker",message:r.errorMessage}),c.length>0){let d=[];d.push("Prerequisites failed:");for(let f of c)d.push(` \u2022 ${f.name}: ${f.message||"Not installed or not working"}`);d.push(`
18
+ Installation guides:`),o==="error"&&d.push(` \u2022 Git: ${W.git}`),n==="error"&&(r.installed?d.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):d.push(` \u2022 Docker: ${W.docker}`)),e.setError(new Error(d.join(`
19
+ `)));return}e.setStatus("Checking Ports...");let m=await Ee([8e3,5432,6379,27017,5672,3e3,8080,8083]),g={},T=m.filter(d=>!d.available);if(T.length>0){let d=T.filter(x=>!x.alternative);if(d.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${d.map(x=>`${x.port} (${x.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",m),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let x of m)!x.available&&x.alternative&&(g[x.port]=x.alternative)}if(e.updateData("portOverrides",g),e.setStatus("Prerequisites check complete!"),await Pe(1e3),await ve(e,t,g),e.currentState.error)return;if(e.currentState.data.setupMode==="selfhost"){e.setStep("Finished"),e.setStatus("Setup complete! Run 'gaia start' to build and start all services in Docker."),await e.waitForInput("exit");return}if(i==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
20
+ \u2022 Mise: ${W.mise}`));return}e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("dependencyLogs",[]);let v=d=>{let f=e.currentState.data.dependencyLogs||[],x=d.split(`
21
+ `).filter(I=>I.trim()!==""),b=[...f,...x].slice(-20);e.updateData("dependencyLogs",b)};try{e.updateData("dependencyPhase","Trusting mise configuration..."),await q("mise",["trust"],t,void 0,v),e.updateData("dependencyProgress",20),e.updateData("dependencyPhase","Installing tools..."),await q("mise",["install"],t,f=>{e.updateData("dependencyProgress",20+f*.3)},v),e.updateData("dependencyPhase","Running mise setup...");let d=Object.keys(g).length>0?ae(g):void 0;await q("mise",["setup"],t,f=>{e.updateData("dependencyProgress",50+f*.5)},v,d),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(d){e.setError(new Error(`Failed to setup project: ${d.message}`));return}await Pe(1e3),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function _t(){let e=H(),{unmount:t}=Fr(Lr.createElement(j,{store:e,command:"setup"}));try{await At(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Nr}from"ink";import Gr from"react";async function Ot(e){e.setStep("Starting"),e.setStatus("Locating GAIA repository...");let t=X();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 Ue(t);if(!o){e.setError(new Error("No .env file found. Run 'gaia setup' first to configure the environment."));return}let r=se(t),n=r[3e3]??3e3,i=r[8e3]??8e3;e.updateData("setupMode",o),e.updateData("webPort",n),e.updateData("apiPort",i),e.setStatus(`Starting GAIA in ${o} mode...`);try{await Rt(t,o,c=>{e.setStatus(c)},r),e.setStep("Running"),e.setStatus("GAIA is running!"),e.updateData("started",!0)}catch(c){e.setError(new Error(`Failed to start services: ${c.message}`));return}await e.waitForInput("exit")}async function Mt(){let e=H(),{unmount:t}=Nr(Gr.createElement(j,{store:e,command:"start"}));await new Promise(o=>setTimeout(o,50));try{await Ot(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Wr}from"ink";import Vr from"react";import{execa as Qe}from"execa";var Xe=["gaia-backend","gaia-web","chromadb","postgres","redis","mongo","rabbitmq","arq_worker"];async function Ft(){try{let{stdout:e}=await Qe("docker",["inspect","--format","{{.Name}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",...Xe]),t=new Map;for(let o of e.trim().split(`
22
+ `)){if(!o)continue;let[r,n,i]=o.split("|"),c=r?.replace(/^\//,"")??"";t.set(c,{name:c,status:n==="running"?"running":"stopped",health:i!=="none"?i:void 0})}return Xe.map(o=>t.get(o)??{name:o,status:"not_found"})}catch{let e=Xe.map(async t=>{try{let{stdout:o}=await Qe("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 Lt(){try{return await Qe("docker",["info"]),!0}catch{return!1}}var $r=[{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 Nt(e){let o=$r.map(r=>({...r,port:e?.[r.port]??r.port})).map(r=>r.type==="http"?qr(r.name,r.port,r.path):jr(r.name,r.port));return Promise.all(o)}async function qr(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 jr(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 c=Date.now()-r;i.destroy(),n({name:e,port:t,status:"up",latency:c})}),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 Gt(){return await Lt()?{running:!0,containers:await Ft()}:{running:!1,containers:[]}}async function Hr(e){e.setStep("Checking"),e.setStatus("Checking service health..."),e.updateData("refreshable",!1);let t=X(),o=t?se(t):void 0,[r,n]=await Promise.all([Nt(o),Gt()]);e.updateData("services",r),e.updateData("docker",n);let i=r.filter(u=>u.status==="up").length,c=r.length;e.setStep("Results"),e.setStatus(`${i}/${c} services running`),e.updateData("refreshable",!0)}async function $t(e){for(;await Hr(e),await e.waitForInput("exit_or_refresh")==="refresh";);}async function qt(){let e=H(),{unmount:t}=Wr(Vr.createElement(j,{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 Ur}from"ink";import Xr from"react";async function jt(e){e.setStep("Stopping"),e.setStatus("Locating GAIA repository...");let t=X();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=se(t);try{await Dt(t,r=>{e.setStatus(r)},o),e.setStep("Stopped"),e.setStatus("All services stopped."),e.updateData("stopped",!0)}catch(r){e.setError(new Error(`Failed to stop services: ${r.message}`));return}await e.waitForInput("exit")}async function Ht(){let e=H(),{unmount:t}=Ur(Xr.createElement(j,{store:e,command:"stop"}));await new Promise(o=>setTimeout(o,50));try{await jt(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}var J=new Qr;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 Bt()});J.command("setup").description("Configure an existing GAIA repository").action(async()=>{await _t()});J.command("status").description("Check health of all GAIA services").action(async()=>{await qt()});J.command("start").description("Start GAIA services").action(async()=>{await Mt()});J.command("stop").description("Stop all GAIA services").action(async()=>{await Ht()});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.6",
3
+ "version": "0.1.8",
4
4
  "description": "CLI tool for setting up and managing GAIA",
5
5
  "type": "module",
6
6
  "bin": {