@heygaia/cli 0.1.14 → 0.1.15

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 +88 -121
  2. package/dist/index.js +26 -29
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -15,12 +15,8 @@ The CLI checks prerequisites at startup and tells you what's missing.
15
15
 
16
16
  ## Installation
17
17
 
18
- **Global installation is required** to use the `gaia` command. Choose your preferred method:
19
-
20
18
  ### Quick Install (Recommended)
21
19
 
22
- Downloads and installs the CLI globally using the install script:
23
-
24
20
  ```bash
25
21
  curl -fsSL https://heygaia.io/install.sh | sh
26
22
  ```
@@ -29,57 +25,24 @@ This automatically detects your system and installs using npm or bun.
29
25
 
30
26
  ### Manual Installation
31
27
 
32
- #### npm
33
-
34
28
  ```bash
35
29
  npm install -g @heygaia/cli
36
- ```
37
-
38
- #### pnpm
39
-
40
- ```bash
30
+ # or
41
31
  pnpm add -g @heygaia/cli
42
- ```
43
-
44
- #### bun
45
-
46
- ```bash
32
+ # or
47
33
  bun add -g @heygaia/cli
48
34
  ```
49
35
 
50
- ### Verify Installation
51
-
52
- After installation, verify the `gaia` command is available:
53
-
54
- ```bash
55
- gaia --version
56
- gaia --help
57
- ```
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:
36
+ ### Alternative: Run Without Installing
62
37
 
63
38
  ```bash
64
39
  npx @heygaia/cli init
65
40
  ```
66
41
 
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
-
69
- ## What Happens When You Install
70
-
71
- 1. The `@heygaia/cli` npm package is installed globally
72
- 2. A `gaia` binary is added to your PATH (points to `dist/index.js`)
73
- 3. No background processes, daemons, or services are started — the CLI only runs when you invoke it
74
-
75
- The CLI itself is a single bundled JavaScript file (~300KB) with no native dependencies.
42
+ You'll need to prefix every command with `npx @heygaia/cli` instead of just `gaia`. Global installation is recommended.
76
43
 
77
44
  ## Commands
78
45
 
79
- Once installed, you can use these commands from anywhere in your terminal:
80
-
81
- ### Quick Reference
82
-
83
46
  ```bash
84
47
  gaia init # Full setup from scratch
85
48
  gaia setup # Configure existing repo
@@ -90,27 +53,15 @@ gaia --version # Show CLI version
90
53
  gaia --help # Show all commands
91
54
  ```
92
55
 
93
- ### Command Details
94
-
95
- | Command | Description |
96
- |---------|-------------|
97
- | `gaia init` | Full setup from scratch — clone repo, install tools, configure env, start services |
98
- | `gaia setup` | Configure an existing GAIA repository (env vars, dependencies) |
99
- | `gaia start` | Start all GAIA services (auto-detects selfhost vs developer mode) |
100
- | `gaia stop` | Stop all running GAIA services |
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 |
104
-
105
56
  ### `gaia init`
106
57
 
107
- Interactive wizard for first-time setup. This is the main entry point for new users.
58
+ Interactive wizard for first-time setup. Handles everything from zero to a running GAIA instance.
108
59
 
109
- **Usage:**
60
+ **Options:**
110
61
 
111
- ```bash
112
- gaia init
113
- ```
62
+ | Flag | Description |
63
+ |------|-------------|
64
+ | `--branch <name>` | Clone a specific branch instead of the default |
114
65
 
115
66
  **What it does:**
116
67
 
@@ -122,39 +73,34 @@ gaia init
122
73
  6. **Project setup** — Runs `mise setup` to install all dependencies, start Docker services, and seed the database.
123
74
  7. **Service startup** — Optionally starts all services immediately.
124
75
 
125
- **First-time users:** This is the command you want! It handles everything from zero to a running GAIA instance.
126
-
127
76
  ### `gaia setup`
128
77
 
129
- For existing repos that need configuration or reconfiguration. Skips cloning and tool installation, goes straight to environment setup.
130
-
131
- **Usage:**
78
+ For existing repos skips cloning and tool installation, goes straight to environment setup. Use when you want to reconfigure environment variables, switch between self-host and developer modes, or reinstall dependencies.
132
79
 
133
80
  ```bash
134
81
  cd /path/to/gaia
135
82
  gaia setup
136
83
  ```
137
84
 
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
-
144
85
  ### `gaia start`
145
86
 
146
87
  Starts all GAIA services. Auto-detects the setup mode from your `.env` configuration.
147
88
 
148
- **Usage:**
89
+ **Options:**
149
90
 
150
- ```bash
151
- gaia start
152
- ```
91
+ | Flag | Description |
92
+ |------|-------------|
93
+ | `--build` | Rebuild Docker images before starting |
94
+ | `--pull` | Pull latest base images before starting |
153
95
 
154
96
  **What it does:**
155
97
 
156
98
  - **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)
99
+ - **Developer mode**: Runs `mise dev` (databases in Docker, API + web locally with hot reload). Logs are written to `dev-start.log` in the repo root:
100
+
101
+ ```bash
102
+ tail -f dev-start.log
103
+ ```
158
104
 
159
105
  **Access your instance:**
160
106
  - Web: http://localhost:3000
@@ -163,33 +109,12 @@ gaia start
163
109
 
164
110
  ### `gaia stop`
165
111
 
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
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.
112
+ Stops all running GAIA services gracefully — Docker containers, local processes on ports 8000 and 3000, and background workers. Your data is preserved.
180
113
 
181
114
  ### `gaia status`
182
115
 
183
116
  Shows a live health dashboard with latency for all services.
184
117
 
185
- **Usage:**
186
-
187
- ```bash
188
- gaia status
189
- ```
190
-
191
- **Service checks:**
192
-
193
118
  | Service | Port | Health Check |
194
119
  |---------|------|--------------|
195
120
  | API | 8000 | HTTP `GET /health` |
@@ -200,10 +125,7 @@ gaia status
200
125
  | RabbitMQ | 5672 | TCP connection |
201
126
  | ChromaDB | 8080 | TCP connection |
202
127
 
203
- **Interactive controls:**
204
- - Press `r` to refresh status
205
- - Status indicators: ✓ (healthy), ✗ (down), - (checking)
206
- - Shows response time for each service
128
+ Press `r` to refresh. Status indicators: ✓ (healthy), ✗ (down), - (checking).
207
129
 
208
130
  ## Setup Modes
209
131
 
@@ -212,12 +134,28 @@ During `gaia init` or `gaia setup`, you choose a mode:
212
134
  - **Self-Host (Docker)** — Everything runs in Docker containers. Best for deployment and non-developers.
213
135
  - **Developer (Local)** — Databases in Docker, API + web run locally with hot reload. Best for contributing.
214
136
 
137
+ ### Port Overrides
138
+
139
+ When the CLI detects port conflicts, it automatically selects alternative ports and writes them to `infra/docker/.env`. These persist across `gaia start` / `gaia stop` cycles. To change port assignments after setup, edit `infra/docker/.env` directly:
140
+
141
+ | Variable | Service |
142
+ |----------|---------|
143
+ | `API_HOST_PORT` | FastAPI backend |
144
+ | `WEB_HOST_PORT` | Next.js web app |
145
+ | `POSTGRES_HOST_PORT` | PostgreSQL |
146
+ | `REDIS_HOST_PORT` | Redis |
147
+ | `MONGO_HOST_PORT` | MongoDB |
148
+ | `RABBITMQ_HOST_PORT` | RabbitMQ |
149
+ | `CHROMA_HOST_PORT` | ChromaDB |
150
+
151
+ After editing, run `gaia stop` and `gaia start` to apply changes.
152
+
215
153
  ## Environment Variable Configuration
216
154
 
217
155
  Two methods are available:
218
156
 
219
157
  - **Manual** — Interactive prompts for each variable with descriptions, documentation links, and defaults.
220
- - **Infisical** — Enter your Infisical credentials (token, project ID, machine identity) for centralized secret management.
158
+ - **Infisical** — Enter your Infisical credentials for centralized secret management.
221
159
 
222
160
  ### Auto-Discovery
223
161
 
@@ -228,6 +166,52 @@ The CLI discovers environment variables from the codebase at runtime:
228
166
 
229
167
  When a developer adds a new variable to either location, the CLI picks it up automatically — no CLI updates needed.
230
168
 
169
+ ## Upgrading
170
+
171
+ ### Updating GAIA
172
+
173
+ ```bash
174
+ cd /path/to/gaia
175
+ git pull
176
+ gaia setup # if dependencies changed
177
+ ```
178
+
179
+ ### Updating the CLI
180
+
181
+ ```bash
182
+ npm install -g @heygaia/cli
183
+ # or
184
+ pnpm add -g @heygaia/cli
185
+ # or
186
+ bun add -g @heygaia/cli
187
+ ```
188
+
189
+ ## Uninstalling
190
+
191
+ 1. Stop all running services: `gaia stop`
192
+ 2. Remove the repo: `rm -rf /path/to/gaia`
193
+ 3. Remove CLI metadata: `rm -rf ~/.gaia`
194
+ 4. Uninstall the CLI:
195
+
196
+ ```bash
197
+ npm uninstall -g @heygaia/cli
198
+ # or
199
+ pnpm remove -g @heygaia/cli
200
+ # or
201
+ bun remove -g @heygaia/cli
202
+ ```
203
+
204
+ ## Troubleshooting
205
+
206
+ | Issue | Fix |
207
+ |-------|-----|
208
+ | `command not found: gaia` | Ensure the global bin directory is in PATH. For npm: `export PATH="$(npm config get prefix)/bin:$PATH"`. For bun: `export PATH="$HOME/.bun/bin:$PATH"` |
209
+ | Raw mode not supported | The CLI requires an interactive terminal — don't run in background or pipe |
210
+ | Port conflicts not detected | Ensure `lsof` is available (macOS/Linux). Windows requires WSL2 |
211
+ | Env vars not discovered | Check that `settings_validator.py` and `apps/web/.env` exist in the repo |
212
+ | `Python 3 not found` | The CLI requires Python 3 to parse API environment variables. Install it or run `mise install python` |
213
+ | Docker prerequisite fails | Ensure Docker Desktop/Engine is running, not just installed |
214
+
231
215
  ## Development
232
216
 
233
217
  ```bash
@@ -246,31 +230,14 @@ cd packages/cli && pnpm run build
246
230
 
247
231
  ### Install Script
248
232
 
249
- Source of truth: `packages/cli/install.sh`. After modifying, sync to the web app:
250
-
251
- ```bash
252
- ./packages/cli/sync-install.sh
253
- ```
254
-
255
- This copies the script to `apps/web/public/install.sh`, which is served at `https://heygaia.io/install.sh`.
233
+ Source of truth: `packages/cli/install.sh`. The web app serves it at `https://heygaia.io/install.sh` by fetching directly from GitHub — no manual sync needed.
256
234
 
257
235
  ### Publishing
258
236
 
259
237
  1. Update version in `package.json`
260
238
  2. Build: `pnpm run build`
261
- 3. Sync install script: `./sync-install.sh`
262
- 4. Commit and tag: `git tag cli-v<version>`
263
- 5. Push tag — GitHub Actions publishes to npm
264
-
265
- ## Troubleshooting
266
-
267
- | Issue | Fix |
268
- |-------|-----|
269
- | `command not found: gaia` | Ensure the global bin directory is in PATH. For npm: `export PATH="$(npm config get prefix)/bin:$PATH"`. For bun: `export PATH="$HOME/.bun/bin:$PATH"` |
270
- | Raw mode not supported | The CLI requires an interactive terminal — don't run in background or pipe |
271
- | Port conflicts not detected | Ensure `lsof` is available (macOS/Linux). Windows requires WSL2 |
272
- | Env vars not discovered | Check that `settings_validator.py` and `apps/web/.env` exist in the repo |
273
- | Docker prerequisite fails | Ensure Docker Desktop/Engine is running, not just installed |
239
+ 3. Commit and tag: `git tag cli-v<version>`
240
+ 4. Push tag GitHub Actions publishes to npm
274
241
 
275
242
  ## License
276
243
 
package/dist/index.js CHANGED
@@ -1,37 +1,34 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Mo}from"commander";import{render as bo}from"ink";import Io from"react";import{Box as Me,Text as pe}from"ink";import Yr from"react";import{ProgressBar as Et,Select as Ke,Spinner as Ye}from"@inkjs/ui";import{Box as f,Text as u,useInput as ie}from"ink";import we from"ink-text-input";import{useEffect as Pe,useRef as _r,useState as H}from"react";import{Box as Ce,Text as _e}from"ink";var b="#00bbff";import{Box as Ir,Text as Cr}from"ink";import{jsx as bt}from"react/jsx-runtime";var It=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:bt(Ir,{width:"100%",paddingX:1,marginTop:1,children:bt(Cr,{color:"gray",dimColor:!0,children:e})});import{Box as Er}from"ink";import wr from"ink-big-text";import Pr from"ink-gradient";import{jsx as Qe}from"react/jsx-runtime";var fe=()=>Qe(Er,{flexDirection:"column",marginTop:1,marginBottom:1,children:Qe(Pr,{colors:[b,"#b0eaff",b],children:Qe(wr,{text:"GAIA",font:"3d"})})});import{jsx as le,jsxs as Ee}from"react/jsx-runtime";var Rr=["Welcome","Prerequisites","Setup Mode","Repository Setup","Environment Setup","Install Tools","Project Setup","Installing CLI","Finished"],Ct=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Dr={Welcome:"Welcome",Prerequisites:"Prereqs","Setup Mode":"Mode","Repository Setup":"Repo","Environment Setup":"Env","Install Tools":"Tools","Project Setup":"Setup","Installing CLI":"CLI","Detect Repo":"Detect",Finished:"Done"},kr=({currentStep:e,steps:t})=>{let o=t.indexOf(e);return le(Ce,{marginBottom:1,flexWrap:"nowrap",children:t.map((r,n)=>{let s=n<o,c=n===o,a=Dr[r]??r;return Ee(Ce,{flexShrink:0,children:[n>0&&Ee(_e,{color:"gray",dimColor:!0,children:[" ","\xB7"," "]}),s&&Ee(_e,{color:"green",children:["\u2713 ",a]}),c&&le(_e,{color:b,bold:!0,children:a}),!s&&!c&&le(_e,{color:"gray",dimColor:!0,children:a})]},r)})})},Le=({children:e,status:t,step:o,steps:r=Rr})=>Ee(Ce,{flexDirection:"column",height:"100%",width:"100%",children:[Ee(Ce,{flexGrow:1,flexDirection:"column",children:[le(fe,{}),le(kr,{currentStep:o,steps:r}),le(Ce,{flexDirection:"column",flexGrow:1,children:e})]}),le(It,{status:t,step:o})]});import{Spinner as Ar}from"@inkjs/ui";import{Box as oe,Text as U,useInput as Br}from"ink";import{jsx as j,jsxs as ue}from"react/jsx-runtime";var ne=({label:e,status:t})=>ue(oe,{children:[j(oe,{marginRight:1,children:t==="pending"?j(Ar,{type:"dots"}):t==="success"?j(U,{color:"green",children:"\u2714"}):t==="error"?j(U,{color:"red",children:"\u2716"}):j(U,{color:"yellow",children:"\u26A0"})}),j(U,{children:e})]}),Oe=({portResults:e,onAccept:t,onAbort:o})=>{Br((n,s)=>{s.return?t():s.escape&&o()});let r=e.filter(n=>!n.available);return ue(oe,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[j(oe,{marginBottom:1,children:j(U,{bold:!0,color:"yellow",children:"Port Conflicts Detected"})}),e.map(n=>ue(oe,{children:[ue(U,{color:n.available?"green":n.alternative?"yellow":"red",children:[n.available?"\u2714":n.alternative?"\u26A0":"\u2716"," "]}),ue(U,{children:[n.service," (:",n.port,")"]}),!n.available&&ue(U,{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)),r.some(n=>!n.alternative)&&j(oe,{marginTop:1,children:j(U,{color:"red",children:"Some ports have no available alternative. Free them and retry."})}),!r.some(n=>!n.alternative)&&r.some(n=>n.alternative)&&j(oe,{marginTop:1,children:j(U,{color:"gray",children:"Alternative ports will be used for conflicting services."})}),j(oe,{marginTop:1,children:ue(U,{dimColor:!0,children:[j(U,{bold:!0,children:"Enter"})," continue \xB7 ",j(U,{bold:!0,children:"ESC"})," abort"]})})]})};import{Fragment as dn,jsx as i,jsxs as g}from"react/jsx-runtime";var Lr=({onConfirm:e})=>(ie((t,o)=>{o.return&&e()}),g(f,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:b,children:[i(u,{bold:!0,children:"Welcome to GAIA Setup"}),g(f,{flexDirection:"column",marginTop:1,marginBottom:1,children:[i(u,{children:"This wizard will guide you through the setup process:"}),i(u,{children:" 1. Check prerequisites and choose setup mode"}),i(u,{children:" 2. Clone repository"}),i(u,{children:" 3. Configure environment variables"}),i(u,{children:" 4. Install tools and dependencies"})]}),i(u,{dimColor:!0,children:"~5-15 min depending on network speed"}),i(f,{marginTop:1,children:g(u,{color:b,children:[i(u,{bold:!0,children:"Enter"})," to start"]})})]})),Or=({defaultValue:e,onSubmit:t})=>{let[o,r]=H(e);return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[i(u,{children:"Clone repository to:"}),i(u,{color:"gray",dimColor:!0,children:"Press Enter for default, or type a custom path"}),g(f,{marginTop:1,children:[i(u,{color:b,children:"\u2192 "}),i(we,{value:o,onChange:r,onSubmit:t})]})]})},Mr=({repoPath:e,onAction:t})=>g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[i(f,{marginBottom:1,children:i(u,{bold:!0,color:"yellow",children:"Existing Installation Found"})}),g(u,{children:["Found a GAIA installation at"," ",i(u,{color:"cyan",bold:!0,children:e})]}),i(f,{marginTop:1,children:i(u,{color:"gray",children:"What would you like to do?"})}),i(f,{marginTop:1,children:i(Ke,{options:[{label:"Use existing installation",value:"use_existing"},{label:"Delete and re-clone",value:"delete_reclone"},{label:"Choose a different path",value:"different_path"},{label:"Exit setup",value:"exit"}],onChange:r=>t(r)})})]}),Fr=({setupMode:e,portOverrides:t,onConfirm:o})=>{ie((s,c)=>{c.return&&o()});let r=t?.[3e3]??3e3,n=t?.[8e3]??8e3;return e==="selfhost"?g(f,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:"green",padding:1,children:[i(u,{bold:!0,color:"green",children:"GAIA is Running!"}),i(f,{marginTop:1,children:i(u,{color:"green",children:"\u2713 All services started"})}),g(f,{marginTop:1,flexDirection:"column",children:[g(u,{children:["Web:"," ",g(u,{color:"cyan",bold:!0,children:["http://localhost:",r]})]}),g(u,{children:["API:"," ",g(u,{color:"cyan",bold:!0,children:["http://localhost:",n]})]})]}),i(f,{marginTop:1,children:i(u,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),i(f,{marginTop:1,children:g(u,{dimColor:!0,children:[i(u,{bold:!0,children:"Enter"})," to exit"]})})]}):g(f,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:b,padding:1,children:[i(u,{color:b,bold:!0,children:"You're all set!"}),g(f,{marginTop:1,children:[i(u,{bold:!0,children:"Run: "}),i(u,{color:"cyan",children:"$ gaia start"})]}),g(f,{marginTop:1,flexDirection:"column",children:[g(u,{children:["Web:"," ",g(u,{color:"cyan",bold:!0,children:["http://localhost:",r]})]}),g(u,{children:["API:"," ",g(u,{color:"cyan",bold:!0,children:["http://localhost:",n]})]})]}),i(f,{marginTop:1,children:i(u,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),i(f,{marginTop:1,children:g(u,{dimColor:!0,children:[i(u,{bold:!0,children:"Enter"})," to exit"]})})]})},Nr=8,wt=({logs:e,height:t=Nr})=>{let[o,r]=H(0),n=_r(e.length);Pe(()=>{e.length!==n.current&&(n.current=e.length,r(0))},[e.length]),ie((T,y)=>{y.upArrow?r(S=>Math.min(S+1,Math.max(0,e.length-t))):y.downArrow&&r(S=>Math.max(0,S-1))});let s=e.length,c=Math.max(0,s-t-o),a=Math.max(0,s-o),l=e.slice(c,a),p=c,x=o;return g(f,{flexDirection:"column",marginTop:1,marginLeft:1,children:[p>0&&g(u,{color:"gray",dimColor:!0,children:["\u2191 ",p," more line",p!==1?"s":""]}),i(f,{flexDirection:"column",height:t,overflow:"hidden",children:l.map((T,y)=>i(u,{color:"gray",wrap:"truncate",children:T},`${c}-${y}`))}),x>0?g(u,{color:"gray",dimColor:!0,children:["\u2193 ",x," more line",x!==1?"s":""]}):i(u,{color:"gray",dimColor:!0,children:"\u2191\u2193 scroll"})]})},Gr=({phase:e,progress:t,isComplete:o,logs:r,title:n})=>g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[i(f,{marginBottom:1,children:i(u,{bold:!0,color:b,children:n||"Installing Dependencies"})}),g(f,{flexDirection:"column",gap:1,children:[i(f,{children:o?g(u,{color:"green",children:["\u2713 ",e]}):i(Ye,{label:e||"Preparing..."})}),!o&&t>0&&i(f,{width:50,children:i(Et,{value:t})}),!o&&r&&r.length>0&&i(wt,{logs:r}),!o&&i(f,{marginTop:1,children:i(u,{color:"gray",dimColor:!0,children:"This may take a few minutes..."})})]})]});var Je=({onSelect:e})=>g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[i(u,{bold:!0,children:"Setup Mode"}),i(f,{marginTop:1,children:i(u,{color:"gray",children:"How do you want to run GAIA?"})}),i(f,{marginTop:1,children:i(Ke,{options:[{label:"Self-Host \u2014 run everything in Docker",value:"selfhost"},{label:"Developer \u2014 local dev with hot reload",value:"developer"}],onChange:o=>e(o)})})]}),ze=({onSelect:e})=>g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[i(u,{bold:!0,children:"Environment Variables Setup"}),i(f,{marginTop:1,children:i(u,{color:"gray",children:"Choose how you want to configure environment variables:"})}),i(f,{marginTop:1,children:i(Ke,{options:[{label:"Manual Setup (Recommended)",value:"manual"},{label:"Infisical (Advanced)",value:"infisical"}],onChange:o=>e(o)})}),g(f,{marginTop:1,flexDirection:"column",children:[i(u,{color:"gray",dimColor:!0,children:"Manual Setup: Configure variables interactively (recommended for most users)"}),i(u,{color:"gray",dimColor:!0,children:"Infisical: All secrets managed in Infisical dashboard (requires pre-configuration)"})]})]}),Ze=({onSubmit:e})=>{let[t,o]=H({INFISICAL_TOKEN:"",INFISICAL_PROJECT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET:""}),[r,n]=H(0),[s,c]=H(null),a=[{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"}];ie((p,x)=>{if(x.tab||x.downArrow)n(T=>T<a.length-1?T+1:T);else if(x.upArrow)n(T=>T>0?T-1:T);else if(x.return){if(r<a.length-1){n(y=>y+1);return}let T=a.filter(y=>!t[y.key].trim());if(T.length>0){c(`Required: ${T.map(S=>S.key).join(", ")}`);let y=a.findIndex(S=>!t[S.key].trim());y>=0&&n(y);return}e(t)}});let l=a[r];return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[i(f,{marginBottom:1,children:i(u,{bold:!0,color:b,children:"Infisical Configuration"})}),i(f,{marginBottom:1,children:i(u,{color:"gray",children:"All secrets managed in your Infisical project. Only credentials stored locally."})}),g(f,{marginBottom:1,flexDirection:"column",children:[i(u,{color:"gray",children:"Configure your Infisical credentials."}),g(u,{color:"gray",dimColor:!0,children:["Visit"," ",i(u,{color:"cyan",underline:!0,children:"app.infisical.com"})," ","to get these values."]})]}),a.map((p,x)=>{let T=p.key.includes("SECRET")||p.key.includes("TOKEN");return g(f,{flexDirection:"column",marginBottom:1,children:[i(f,{children:g(u,{color:x===r?b:"white",children:[x===r?"\u25B8 ":" ",p.key,":"]})}),i(f,{marginLeft:2,children:i(u,{color:"gray",dimColor:!0,children:p.description})}),x===r?i(f,{marginLeft:2,children:i(we,{value:t[p.key],onChange:y=>{o(S=>({...S,[p.key]:y})),c(null)},placeholder:"Enter value...",mask:T?"*":void 0})}):i(f,{marginLeft:2,children:i(u,{color:t[p.key]?"green":"gray",children:t[p.key]?T?`\u2713 ${"*".repeat(8)}`:`\u2713 ${t[p.key]}`:"(not set)"})})]},p.key)}),s&&i(f,{marginTop:1,children:i(u,{color:"red",children:s})}),i(f,{marginTop:1,children:g(u,{dimColor:!0,children:[i(u,{bold:!0,children:"Enter"})," confirm \xB7 ",i(u,{bold:!0,children:"\u2191\u2193"})," navigate"]})})]})},et=({category:e,currentIndex:t,totalGroups:o,onSubmit:r})=>{let[n,s]=H(()=>{let y={};for(let S of e.variables)y[S.name]=S.defaultValue||"";return y}),[c,a]=H(0),[l,p]=H(null);Pe(()=>{let y={};for(let S of e.variables)y[S.name]=S.defaultValue||"";s(y),a(0),p(null)},[e.name]),ie((y,S)=>{if(S.tab||S.downArrow)a(m=>m<e.variables.length-1?m+1:m);else if(S.upArrow)a(m=>m>0?m-1:m);else if(S.escape){let m=e.variables.filter(d=>d.required&&!n[d.name]?.trim());if(m.length>0){p(`Required fields cannot be skipped: ${m.map(d=>d.name).join(", ")}`);return}r(n)}});let x=()=>{if(c<e.variables.length-1)a(c+1);else{let y=e.variables.filter(S=>S.required&&!n[S.name]?.trim());if(y.length>0){p(`Required fields are missing: ${y.map(S=>S.name).join(", ")}`);return}p(null),r(n)}},T=e.variables.some(y=>y.required);return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:l?"red":b,children:[g(f,{justifyContent:"space-between",children:[g(u,{bold:!0,children:["Configure ",e.name]}),g(u,{color:"gray",children:["Group ",t+1," / ",o]})]}),i(f,{marginTop:1,children:i(u,{color:"gray",children:e.description})}),i(f,{marginTop:1,flexDirection:"column",children:e.variables.map((y,S)=>{let m=S===c,d=!!y.defaultValue;return g(f,{flexDirection:"column",marginBottom:1,children:[g(f,{children:[g(u,{color:m?b:"gray",bold:m,children:[m?"\u279C ":" ",y.name]}),y.required&&g(u,{color:"red",bold:!0,children:[" ","*"]}),d&&!m&&g(u,{color:"gray",dimColor:!0,children:[" ","(default: ",y.defaultValue,")"]})]}),m&&i(f,{marginLeft:2,children:i(we,{value:n[y.name]||"",onChange:h=>{s(v=>({...v,[y.name]:h})),l&&p(null)},onSubmit:x,placeholder:d?`Default: ${y.defaultValue}`:y.required?"Enter a value (required)":"Press Enter to skip"})})]},y.name)})}),l&&i(f,{marginTop:1,children:g(u,{color:"red",bold:!0,children:["\u26A0 ",l]})}),i(f,{marginTop:1,children:g(u,{dimColor:!0,children:[i(u,{bold:!0,children:"Enter"})," next \xB7 ",i(u,{bold:!0,children:"\u2191\u2193"})," navigate",!T&&g(u,{children:[" ","\xB7 ",i(u,{bold:!0,children:"ESC"})," skip"]})]})})]})},tt=({alternatives:e,onSubmit:t})=>{let[o,r]=H(new Set),[n,s]=H({}),[c,a]=H(0),[l,p]=H(null);Pe(()=>{let h={};for(let v of e)for(let I of v.variables)h[I.name]=I.defaultValue||"";s(h)},[e]);let x=[];for(let h=0;h<e.length;h++)if(x.push({type:"provider",categoryIndex:h}),o.has(h)){let v=e[h];if(v)for(let I=0;I<v.variables.length;I++)x.push({type:"field",categoryIndex:h,fieldIndex:I})}x.push({type:"submit"});let T=x[c],y=T?.type==="field",S=T?.type==="submit";ie((h,v)=>{let I=Math.min(c,x.length-1);if(I!==c){a(I);return}if(y)v.upArrow?a(C=>Math.max(0,C-1)):(v.downArrow||v.tab)&&a(C=>Math.min(x.length-1,C+1));else if(S)v.upArrow?a(C=>Math.max(0,C-1)):(v.return||h===" ")&&d();else if(v.upArrow)a(C=>Math.max(0,C-1));else if(v.downArrow||v.tab)a(C=>Math.min(x.length-1,C+1));else if((v.return||h===" ")&&T?.type==="provider"){let C=T.categoryIndex;r(k=>{let P=new Set(k);return P.has(C)?P.delete(C):P.add(C),P}),l&&p(null)}});let m=()=>{l&&p(null),a(h=>Math.min(x.length-1,h+1))},d=()=>{let h=[],v={};for(let I of o){let C=e[I];if(!C)continue;if(C.variables.some(P=>n[P.name]?.trim())){h.push(C.name);for(let P of C.variables){let de=n[P.name];de&&(v[P.name]=de)}}}if(h.length===0){o.size===0?p("Enable at least one provider (press Space or Enter)"):p("Enter a value for at least one field");return}t(h,v)};return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:l?"red":b,children:[g(f,{justifyContent:"space-between",children:[i(u,{bold:!0,children:"Configure AI Provider"}),i(u,{color:"yellow",children:"* At least one required"})]}),i(f,{marginTop:1,children:i(u,{color:"gray",children:"Enable and configure at least one AI provider below:"})}),i(f,{marginTop:1,flexDirection:"column",children:e.map((h,v)=>{let I=o.has(v),C=x.findIndex(P=>P.type==="provider"&&P.categoryIndex===v),k=c===C;return g(f,{flexDirection:"column",marginBottom:1,children:[g(f,{children:[i(u,{color:k?b:void 0,bold:k,children:k?"\u279C ":" "}),i(u,{color:I?"green":"gray",children:I?"[\u2714]":"[ ]"}),g(u,{color:I?b:"gray",bold:I,children:[" ",h.name]}),h.description&&g(u,{color:"gray",dimColor:!0,children:[" ","- ",h.description]})]}),k&&h.docsUrl&&g(f,{marginLeft:6,children:[i(u,{color:"yellow",children:"\u{1F4D6} "}),i(u,{color:"blue",underline:!0,children:h.docsUrl})]}),I&&i(f,{marginLeft:4,flexDirection:"column",marginTop:1,children:h.variables.map((P,de)=>{let be=x.findIndex(Ie=>Ie.type==="field"&&Ie.categoryIndex===v&&Ie.fieldIndex===de),me=c===be,vt=!!P.defaultValue,Xe=n[P.name]||"";return g(f,{flexDirection:"column",marginBottom:1,children:[g(f,{children:[g(u,{color:me?b:"gray",bold:me,children:[me?" \u279C ":" ",P.name]}),!me&&Xe&&i(u,{color:"green",children:" \u2713"}),!me&&!Xe&&vt&&g(u,{color:"gray",dimColor:!0,children:[" ","(default: ",P.defaultValue,")"]})]}),me&&i(f,{marginLeft:4,children:i(we,{value:Xe,onChange:Ie=>{s(br=>({...br,[P.name]:Ie})),l&&p(null)},onSubmit:m,placeholder:vt?`Default: ${P.defaultValue}`:"Enter value..."})})]},P.name)})})]},h.name)})}),l&&i(f,{marginTop:1,children:g(u,{color:"red",bold:!0,children:["\u26A0 ",l]})}),g(f,{marginTop:1,children:[i(u,{color:S?b:void 0,bold:S,children:S?"\u279C ":" "}),i(f,{borderStyle:"round",borderColor:S?b:"gray",paddingX:2,children:i(u,{color:S?b:"gray",bold:S,children:"Continue \u2192"})})]}),i(f,{marginTop:1,children:i(u,{color:"gray",dimColor:!0,children:"\u2191/\u2193 navigate \u2022 Space/Enter toggle/select \u2022 Tab skip field"})})]})},rt=({currentVar:e,currentIndex:t,totalCount:o,onSubmit:r,onSkip:n})=>{let[s,c]=H(e.defaultValue||""),[a,l]=H(null);Pe(()=>{c(e.defaultValue||""),l(null)},[e.name]),ie((T,y)=>{if(y.escape){if(e.required&&!s.trim()){l("This field is required and cannot be skipped");return}n()}});let p=T=>{if(e.required&&!T.trim()){l("This field is required");return}l(null),r(T)},x=!!e.defaultValue;return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:a?"red":b,children:[g(f,{justifyContent:"space-between",children:[g(f,{children:[i(u,{color:b,bold:!0,children:e.name}),e.required?i(u,{color:"red",children:" *"}):g(u,{color:"gray",dimColor:!0,children:[" ","optional"]})]}),g(u,{color:"gray",children:[t+1,"/",o]})]}),i(f,{marginLeft:1,children:i(u,{color:"gray",children:e.description})}),g(f,{marginTop:1,children:[i(u,{color:b,children:"\u2192 "}),i(we,{value:s,onChange:T=>{c(T),a&&l(null)},onSubmit:p,placeholder:x?`Default: ${e.defaultValue}`:e.required?"required":"skip with Enter"})]}),a&&i(f,{marginTop:1,children:i(u,{color:"red",children:a})}),i(f,{marginTop:1,children:g(u,{dimColor:!0,children:[i(u,{bold:!0,children:"Enter"})," confirm",!e.required&&g(u,{children:[" ","\xB7 ",i(u,{bold:!0,children:"ESC"})," skip"]})]})})]})},Pt=({store:e})=>{let[t,o]=H(e.currentState);return Pe(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),ie((r,n)=>{(n.return||n.escape)&&t.error&&e.submitInput("exit")}),g(Le,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&i(Lr,{onConfirm:()=>e.submitInput(!0)}),t.step==="Prerequisites"&&t.data.checks&&g(f,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:b,children:[i(u,{bold:!0,children:"System Checks"}),g(f,{flexDirection:"column",marginTop:1,children:[i(ne,{label:"Git",status:t.data.checks.git}),i(ne,{label:"Docker",status:t.data.checks.docker}),i(ne,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&i(Oe,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="repo_path"&&i(Or,{defaultValue:t.inputRequest.meta.default,onSubmit:r=>e.submitInput(r)}),t.inputRequest?.id==="existing_repo"&&t.data.existingRepoPath&&i(Mr,{repoPath:t.data.existingRepoPath,onAction:r=>e.submitInput(r)}),t.step==="Repository Setup"&&!t.inputRequest&&g(f,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:b,children:[i(u,{bold:!0,children:"Cloning Repository"}),g(f,{marginTop:1,flexDirection:"column",children:[i(Et,{value:t.data.repoProgress||0}),t.data.repoPhase&&i(f,{marginTop:1,children:i(u,{color:"gray",children:t.data.repoPhase})})]})]}),t.inputRequest?.id==="setup_mode"&&i(Je,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&i(ze,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&i(Ze,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&i(rt,{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&&i(et,{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&&i(tt,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Environment Setup"&&!t.inputRequest&&g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[i(u,{bold:!0,children:"Environment Setup"}),i(f,{marginTop:1,children:i(Ye,{label:t.status||"Configuring environment..."})})]}),t.step==="Finished"&&i(Fr,{setupMode:t.data.setupMode,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),(t.step==="Install Tools"||t.step==="Project Setup")&&i(Gr,{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.step==="Installing CLI"&&g(f,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:b,children:[i(u,{bold:!0,color:b,children:"Installing CLI"}),i(f,{marginTop:1,children:i(Ye,{label:t.status||"Installing gaia CLI globally..."})}),t.data.cliInstallLogs&&t.data.cliInstallLogs.length>0&&i(wt,{logs:t.data.cliInstallLogs})]}),t.error&&g(f,{flexDirection:"column",borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[g(u,{color:"red",children:["Error: ",t.error.message]}),i(f,{marginTop:1,children:g(u,{dimColor:!0,children:[i(u,{bold:!0,children:"Enter"})," to exit"]})})]})]})};import{Spinner as $r}from"@inkjs/ui";import{Box as G,Text as R,useInput as Rt}from"ink";import{useEffect as Dt,useRef as qr,useState as kt}from"react";import{jsx as F,jsxs as w}from"react/jsx-runtime";var ot=8,jr=({logs:e})=>{let[t,o]=kt(0),r=qr(e.length);Dt(()=>{e.length!==r.current&&(r.current=e.length,o(0))},[e.length]),Rt((x,T)=>{T.upArrow?o(y=>Math.min(y+1,Math.max(0,e.length-ot))):T.downArrow&&o(y=>Math.max(0,y-1))});let n=e.length,s=Math.max(0,n-ot-t),c=Math.max(0,n-t),a=e.slice(s,c),l=s,p=t;return w(G,{flexDirection:"column",marginTop:1,marginLeft:1,children:[l>0&&w(R,{color:"gray",dimColor:!0,children:["\u2191 ",l," more line",l!==1?"s":""]}),F(G,{flexDirection:"column",height:ot,overflow:"hidden",children:a.map((x,T)=>F(R,{color:"gray",wrap:"truncate",children:x},s+T))}),p>0?w(R,{color:"gray",dimColor:!0,children:["\u2193 ",p," more line",p!==1?"s":""]}):F(R,{color:"gray",dimColor:!0,children:"\u2191\u2193 scroll"})]})},At=({store:e})=>{let[t,o]=kt(e.currentState);return Dt(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),Rt((r,n)=>{(n.return||n.escape)&&(t.data.started||t.data.stopped||t.error)&&e.submitInput("exit")}),w(G,{flexDirection:"column",width:"100%",children:[F(fe,{}),(t.step==="Starting"||t.step==="Stopping")&&w(G,{flexDirection:"column",marginTop:1,paddingX:2,borderStyle:"round",borderColor:b,children:[F($r,{label:t.status||"Working..."}),t.data.repoPath&&F(G,{marginTop:1,children:w(R,{color:"gray",children:["Repository: ",t.data.repoPath]})}),t.data.setupMode&&F(G,{children:w(R,{color:"gray",children:["Mode: ",t.data.setupMode]})}),t.data.dockerLogs&&t.data.dockerLogs.length>0&&F(jr,{logs:t.data.dockerLogs})]}),t.step==="Running"&&t.data.started&&w(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:"green",children:[w(R,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),t.data.setupMode!=="developer"&&w(G,{marginTop:1,flexDirection:"column",children:[w(R,{children:["Web:"," ",w(R,{color:"cyan",bold:!0,children:["http://localhost:",t.data.webPort||3e3]})]}),w(R,{children:["API:"," ",w(R,{color:"cyan",bold:!0,children:["http://localhost:",t.data.apiPort||8e3]})]})]}),t.data.setupMode==="developer"&&w(G,{marginTop:1,flexDirection:"column",children:[w(G,{flexDirection:"column",children:[w(R,{children:["Web:"," ",w(R,{color:"cyan",bold:!0,children:["http://localhost:",t.data.webPort||3e3]})]}),w(R,{children:["API:"," ",w(R,{color:"cyan",bold:!0,children:["http://localhost:",t.data.apiPort||8e3]})]})]}),w(G,{marginTop:1,flexDirection:"column",children:[F(R,{color:"gray",children:"Dev servers started in background."}),w(R,{color:"gray",children:["Logs: ",F(R,{color:b,children:"dev-start.log"})," in your repo root."]}),w(R,{color:"gray",children:["Run ",F(R,{color:b,children:"gaia stop"})," to shut down."]})]})]}),F(G,{marginTop:1,children:w(R,{dimColor:!0,children:[F(R,{bold:!0,children:"Enter"})," to exit"]})})]}),t.step==="Stopped"&&t.data.stopped&&w(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:b,children:[w(R,{color:b,bold:!0,children:["\u2713"," All GAIA services stopped."]}),F(G,{marginTop:1,children:w(R,{dimColor:!0,children:[F(R,{bold:!0,children:"Enter"})," to exit"]})})]}),t.error&&w(G,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[w(R,{color:"red",children:["Error: ",t.error.message]}),F(G,{marginTop:1,children:w(R,{dimColor:!0,children:[F(R,{bold:!0,children:"Enter"})," to exit"]})})]})]})};import{ProgressBar as Hr,Spinner as nt}from"@inkjs/ui";import{Box as B,Text as L,useInput as Bt}from"ink";import{useEffect as Wr,useState as Vr}from"react";import{jsx as E,jsxs as _}from"react/jsx-runtime";var _t=({store:e})=>{let[t,o]=Vr(e.currentState);return Wr(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),Bt((r,n)=>{(n.return||n.escape)&&t.error&&e.submitInput("exit")}),_(Le,{status:t.status,step:t.step,steps:Ct,children:[t.step==="Detect Repo"&&_(B,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:b,children:[E(L,{bold:!0,children:"Detecting GAIA Repository"}),E(B,{marginTop:1,children:E(nt,{label:"Searching for repository..."})}),t.data.repoPath&&E(B,{marginTop:1,children:_(L,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&_(B,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:b,children:[E(L,{bold:!0,children:"System Checks"}),_(B,{flexDirection:"column",marginTop:1,children:[E(ne,{label:"Git",status:t.data.checks.git}),E(ne,{label:"Docker",status:t.data.checks.docker}),E(ne,{label:"Mise",status:t.data.checks.mise})]})]}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&E(Oe,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="setup_mode"&&E(Je,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&E(ze,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&E(Ze,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&E(rt,{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&&E(et,{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&&E(tt,{alternatives:t.data.alternativeGroups,onSubmit:(r,n)=>e.submitInput({selectedGroups:r,values:n})}),t.step==="Environment Setup"&&!t.inputRequest&&_(B,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[E(L,{bold:!0,children:"Environment Setup"}),E(B,{marginTop:1,children:E(nt,{label:t.status||"Configuring environment..."})})]}),t.step==="Project Setup"&&_(B,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:b,children:[E(B,{marginBottom:1,children:E(L,{bold:!0,color:b,children:"Project Setup"})}),_(B,{flexDirection:"column",gap:1,children:[E(B,{children:t.data.dependencyComplete?_(L,{color:"green",children:["\u2713"," ",t.data.dependencyPhase]}):E(nt,{label:t.data.dependencyPhase||"Preparing..."})}),!t.data.dependencyComplete&&t.data.dependencyProgress>0&&E(B,{width:50,children:E(Hr,{value:t.data.dependencyProgress})}),!t.data.dependencyComplete&&t.data.dependencyLogs?.length>0&&E(B,{flexDirection:"column",marginTop:1,marginLeft:1,children:t.data.dependencyLogs.map((r,n)=>E(L,{color:"gray",wrap:"truncate",children:r},n))})]})]}),t.step==="Finished"&&E(Ur,{setupMode:t.data.setupMode,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),t.error&&_(B,{flexDirection:"column",borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[_(L,{color:"red",children:["Error: ",t.error.message]}),E(B,{marginTop:1,children:_(L,{dimColor:!0,children:[E(L,{bold:!0,children:"Enter"})," to exit"]})})]})]})},Ur=({portOverrides:e,onConfirm:t})=>{Bt((n,s)=>{s.return&&t()});let o=e?.[3e3]??3e3,r=e?.[8e3]??8e3;return _(B,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:b,padding:1,children:[E(L,{color:b,bold:!0,children:"Setup Complete!"}),_(B,{marginTop:1,children:[E(L,{bold:!0,children:"Run: "}),E(L,{color:"cyan",children:"$ gaia start"})]}),_(B,{marginTop:1,flexDirection:"column",children:[_(L,{children:["Web:"," ",_(L,{color:"cyan",bold:!0,children:["http://localhost:",o]})]}),_(L,{children:["API:"," ",_(L,{color:"cyan",bold:!0,children:["http://localhost:",r]})]})]}),E(B,{marginTop:1,children:E(L,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),E(B,{marginTop:1,children:_(L,{dimColor:!0,children:[E(L,{bold:!0,children:"Enter"})," to exit"]})})]})};import{Spinner as Xr}from"@inkjs/ui";import{Box as O,Text as A,useInput as Qr}from"ink";import{useEffect as Lt,useState as it}from"react";import{jsx as D,jsxs as $}from"react/jsx-runtime";var Ot=({store:e})=>{let[t,o]=it(e.currentState),[r,n]=it(!1),[s,c]=it(null);return Lt(()=>{let a=()=>o({...e.currentState});return e.on("change",a),()=>{e.off("change",a)}},[e]),Lt(()=>{n(!1),c(new Date().toLocaleTimeString())},[t.data.services]),Qr((a,l)=>{(l.return||l.escape)&&t.step==="Results"&&e.submitInput("exit"),a==="r"&&t.step==="Results"&&t.data.refreshable&&!r&&(n(!0),e.submitInput("refresh"))}),$(O,{flexDirection:"column",width:"100%",children:[D(fe,{}),t.step==="Checking"&&D(O,{marginTop:1,children:D(Xr,{label:t.data.services?"Refreshing service health...":"Checking service health..."})}),t.step==="Results"&&t.data.services&&$(O,{flexDirection:"column",children:[$(O,{flexDirection:"column",borderStyle:"round",borderColor:b,paddingX:2,paddingY:1,children:[$(O,{justifyContent:"space-between",children:[D(A,{bold:!0,color:b,children:"GAIA Service Status"}),s&&$(A,{color:"gray",dimColor:!0,children:["checked ",s," \xB7 ",D(A,{bold:!0,children:"r"})," refresh"]})]}),$(O,{marginTop:1,flexDirection:"column",children:[$(O,{children:[D(O,{width:22,children:D(A,{bold:!0,children:"Service"})}),D(O,{width:10,children:D(A,{bold:!0,children:"Status"})}),D(O,{width:10,children:D(A,{bold:!0,children:"Latency"})})]}),D(A,{color:"gray",children:"\u2500".repeat(42)}),[...t.data.services].sort((a,l)=>a.status==="down"&&l.status!=="down"?-1:a.status!=="down"&&l.status==="down"?1:a.name.localeCompare(l.name)).map(a=>$(O,{children:[D(O,{width:22,children:$(A,{children:[a.name," (:",a.port,")"]})}),D(O,{width:10,children:D(A,{color:a.status==="up"?"green":"red",bold:!0,children:a.status==="up"?"\u2713 UP":"\u2717 DOWN"})}),D(O,{width:10,children:D(A,{color:"gray",children:a.latency?`${a.latency}ms`:"--"})})]},a.name))]})]}),t.data.docker&&$(O,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:2,paddingY:1,marginTop:1,children:[D(A,{bold:!0,children:"Docker Containers"}),$(A,{color:"gray",children:["Docker:"," ",t.data.docker.running?D(A,{color:"green",children:"Running"}):D(A,{color:"red",children:"Not running"})]}),t.data.docker.containers?.length>0&&D(O,{marginTop:1,flexDirection:"column",children:t.data.docker.containers.map(a=>$(O,{children:[$(A,{color:a.status==="running"?"green":"red",children:[a.status==="running"?"\u2713":"\u2717"," "]}),D(A,{children:a.name}),a.health&&$(A,{color:"gray",children:[" (",a.health,")"]})]},a.name))})]}),D(O,{marginTop:1,children:$(A,{dimColor:!0,children:[D(A,{bold:!0,children:"Enter"})," exit \xB7 ",D(A,{bold:!0,children:"r"})," refresh"]})})]}),t.error&&D(O,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:$(A,{color:"red",children:["Error: ",t.error.message]})})]})};import{jsx as Y,jsxs as Re}from"react/jsx-runtime";var Kr=["init","setup","status","start","stop"],at=class extends Yr.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?Re(Me,{flexDirection:"column",padding:1,children:[Y(pe,{color:"red",bold:!0,children:"An unexpected error occurred:"}),Y(pe,{color:"red",children:this.state.error.message}),this.state.error.stack&&Y(Me,{marginTop:1,children:Y(pe,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},Jr=({store:e,command:t})=>{switch(t){case"init":return Y(Pt,{store:e});case"setup":return Y(_t,{store:e});case"status":return Y(Ot,{store:e});case"start":case"stop":return Y(At,{store:e,command:t});default:return Re(Me,{flexDirection:"column",padding:1,children:[Re(pe,{color:"red",children:["Unknown command: ",t]}),Re(Me,{marginTop:1,flexDirection:"column",children:[Y(pe,{bold:!0,children:"Available commands:"}),Kr.map(o=>Re(pe,{children:[" ",Y(pe,{color:"cyan",children:o})]},o))]})]})}},K=({store:e,command:t})=>Y(at,{children:Y(Jr,{store:e,command:t})});import{EventEmitter as zr}from"events";var Zr=150,st=class extends zr{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))},Zr))}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,r){return this.state.inputRequest={id:t,meta:o},this.emitNow(),new Promise(n=>{if(this.inputResolver=n,r!=null){let s=setTimeout(()=>{this.inputResolver&&(this.inputResolver=null,this.state.inputRequest=null,this.emitNow(),n(null))},r),c=this.inputResolver;this.inputResolver=a=>{clearTimeout(s),c(a)}}})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emitNow())}},J=()=>new st;import*as re from"fs";import*as sr from"os";import*as se from"path";import*as ee from"fs";import*as Mt from"os";import*as ut from"path";var ct=ut.join(Mt.homedir(),".gaia"),lt=ut.join(ct,"config.json"),Fe="0.1.10";function eo(){ee.existsSync(ct)||ee.mkdirSync(ct,{recursive:!0})}function pt(){try{if(!ee.existsSync(lt))return null;let e=ee.readFileSync(lt,"utf-8");return JSON.parse(e)}catch{return null}}function Ne(e){eo(),ee.writeFileSync(lt,`${JSON.stringify(e,null,2)}
3
- `)}function De(e){let o={...pt()??{version:Fe,setupComplete:!1,setupMethod:"manual",repoPath:"",createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()},...e,updatedAt:new Date().toISOString()};Ne(o)}import*as Jt from"path";import*as he from"node:fs";import*as ge from"node:path";import{execa as Ft}from"execa";var dt={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/"}},Nt={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 mt(e,t){return dt[t][e]??Nt[t][e]}async function Gt(e){let t=ge.join(e,"apps/api/scripts/dump_config_schema.py"),o=ge.join(e,"apps/api/app/config/settings_validator.py"),r=ge.join(e,"apps/api/app/config/settings.py");if(!he.existsSync(t))throw new Error("dump_config_schema.py not found in apps/api/scripts");try{try{let{stdout:n}=await Ft("python3",[t,o,r],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await Ft("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 $t(e){let t=ge.join(e,"apps","web",".env.local"),o=he.existsSync(t)?t:ge.join(e,"apps","web",".env");if(!he.existsSync(o))return[];let r=he.readFileSync(o,"utf-8"),n=[],s="General";for(let c of r.split(`
4
- `)){let a=c.trim();if(a.startsWith("#")&&!a.startsWith("#=")){let T=a.replace(/^#+\s*/,"").trim();T&&!T.startsWith("These are")&&(s=T);continue}if(!a||a.startsWith("#"))continue;let l=a.indexOf("=");if(l===-1)continue;let p=a.substring(0,l).trim(),x=a.substring(l+1).trim();n.push({name:p,value:x,category:s})}return n}function qt(e,t){return{NEXT_PUBLIC_API_BASE_URL:`http://localhost:${t?.[8e3]??8e3}/api/v1/`}}function jt(e,t,o){let r=o==="selfhost"?new Set(Object.keys(dt.selfhost)):new Set;for(let[n,s]of Object.entries(t)){let c=Number(n),a=Number(s);for(let[l,p]of Object.entries(e)){if(r.has(l))continue;if(p===String(c)){e[l]=String(a);continue}let x=new RegExp(`:${c}(?=[/\\s]|$)`,"g");e[l]=p.replaceAll(x,`:${a}`)}}}function Ht(e,t){return e.map(o=>({...o,variables:o.variables.map(r=>{let n=mt(r.name,t);return{...r,defaultValue:n||r.defaultValue}})}))}function ft(){return Object.keys(dt.selfhost)}function Wt(e){return{...Nt[e]}}import*as W from"fs";import*as Se from"path";function gt(e){W.existsSync(e)&&W.copyFileSync(e,`${e}.bak`)}function Ut(e,t){let o=Se.join(e,".env");gt(o);let r=["# GAIA Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],n=["MONGO","REDIS","POSTGRES","CHROMADB","RABBITMQ","WORKOS","GOOGLE","OPENAI","INFISICAL","LANGSMITH","DISCORD","SLACK","TELEGRAM","CLOUDINARY","COMPOSIO","FIRECRAWL","LIVEKIT","DEEPGRAM","ELEVENLABS","RESEND","SENTRY","POSTHOG","MEM0","E2B","DODO","NEXT_PUBLIC","GAIA"];function s(a){for(let p of n)if(a===p||a.startsWith(`${p}_`))return p;let l=a.split("_");return l.length===1?"Core":l[0]||"Core"}let c=new Map;for(let[a,l]of Object.entries(t)){let p=s(a);c.has(p)||c.set(p,[]);let T=/[\s#"'\\]/.test(l)||l===""?`"${l.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:l;c.get(p).push(`${a}=${T}`)}for(let[a,l]of c.entries())r.push(`# ${a} Configuration`),r.push(...l),r.push("");W.writeFileSync(o,r.join(`
5
- `),"utf-8")}function Xt(e,t,o){let r=Se.join(e,"apps","web",".env.local");gt(r);let n=$t(e),s=qt(t,o),c=["# GAIA Web App Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],a=new Map;for(let l of n){a.has(l.category)||a.set(l.category,[]);let p=s[l.name]??l.value;a.get(l.category).push({name:l.name,value:p})}if(n.length===0){c.push("# Core URLs");for(let[l,p]of Object.entries(s))c.push(`${l}=${p}`);c.push("")}else for(let[l,p]of a.entries()){c.push(`# ${l}`);for(let{name:x,value:T}of p)c.push(`${x}=${T}`);c.push("")}W.writeFileSync(r,c.join(`
6
- `),"utf-8")}var Qt={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,o){let r=Se.join(e,"infra","docker",".env");gt(r);let n=["# Docker Compose environment overrides","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""];for(let[s,c]of Object.entries(t)){let a=Number(s),l=Qt[a];l&&n.push(`${l}=${c}`)}if(o==="selfhost"){let s=t[8e3]??8e3;n.push(""),n.push("# Web build args"),n.push(`NEXT_PUBLIC_API_BASE_URL=http://localhost:${s}/api/v1/`)}n.push(""),W.writeFileSync(r,n.join(`
7
- `),"utf-8")}function xe(e){let t={};for(let[o,r]of Object.entries(e)){let n=Number(o),s=Qt[n];s&&(t[s]=String(r))}return t}function Kt(e){let t=Se.join(e,"infra","docker","docker-compose.yml");if(!W.existsSync(t))return;let o=W.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:s,hostPort:c,containerPort:a}of r){let l=`"${c}:${a}"`,p=`"\${${s}:-${c}}:${a}"`;o.includes(l)&&(o=o.replaceAll(l,p),n=!0)}n&&W.writeFileSync(t,o,"utf-8")}var Vt={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 ye(e){let t=Se.join(e,"infra","docker",".env"),o={};if(!W.existsSync(t))return o;let r=W.readFileSync(t,"utf-8");for(let n of r.split(`
8
- `)){let s=n.trim();if(s&&!s.startsWith("#")){let[c,...a]=s.split("=");if(c&&Vt[c]){let l=a.join("=").trim().replace(/^["']|["']$/g,""),p=Number(l);!Number.isNaN(p)&&p>0&&p<=65535&&(o[Vt[c]]=p)}}}return o}var oo=e=>new Promise(t=>setTimeout(t,e));async function Ge(e){e.setStep("Setup Mode"),e.setStatus("Choose how to run GAIA...");let t=await e.waitForInput("setup_mode");return e.updateData("setupMode",t),t}async function $e(e,t,o,r){e.setStep("Environment Setup"),e.setStatus("Configuring environment..."),e.updateData("setupMode",o),e.setStatus("Configuring environment variables...");let n=await e.waitForInput("env_method");e.updateData("envMethod",n);let s={};s.ENV="development";let c=ft();for(let l of c){let p=mt(l,o);p&&(s[l]=p)}let a=Wt(o);for(let[l,p]of Object.entries(a))s[l]=p;if(n==="infisical")await no(e,s),e.setStatus("Infisical credentials saved. Ensure your Infisical project contains all required variables.");else try{await io(e,t,s,o)}catch(l){e.setError(l);return}r&&jt(s,r,o);try{await ao(e,t,s,o,r)}catch(l){e.setError(l);return}await oo(1e3)}async function no(e,t){e.setStatus("Configuring Infisical...");let o=await e.waitForInput("env_infisical");t.INFISICAL_TOKEN=o.INFISICAL_TOKEN,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 io(e,t,o,r){e.setStatus("Parsing environment variables...");let n;try{n=await Gt(t),n=Ht(n,r)}catch(m){throw r==="selfhost"?new Error(`Manual environment setup requires Python to parse config schema.
2
+ import{Command as jo}from"commander";import{render as Ro}from"ink";import Do from"react";import{Box as Le,Text as le}from"ink";import to from"react";import{ProgressBar as Rt,Select as Ke,Spinner as Dt}from"@inkjs/ui";import{Box as d,Text as p,useInput as ne}from"ink";import ve from"ink-text-input";import{useEffect as be,useRef as $r,useState as $}from"react";import{Box as ye,Text as De}from"ink";var T="#00bbff";import{Box as kr,Text as _r}from"ink";import{jsx as Ct}from"react/jsx-runtime";var Et=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:Ct(kr,{width:"100%",paddingX:1,marginTop:1,children:Ct(_r,{color:"gray",dimColor:!0,children:e})});import{Box as Br}from"ink";import Or from"ink-big-text";import Lr from"ink-gradient";import{jsx as Qe}from"react/jsx-runtime";var de=()=>Qe(Br,{flexDirection:"column",marginTop:1,marginBottom:1,children:Qe(Lr,{colors:[T,"#b0eaff",T],children:Qe(Or,{text:"GAIA",font:"3d"})})});import{jsx as ce,jsxs as Te}from"react/jsx-runtime";var Mr=["Welcome","Prerequisites","Setup Mode","Repository Setup","Environment Setup","Install Tools","Project Setup","Installing CLI","Finished"],Pt=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Fr={Welcome:"Welcome",Prerequisites:"Prereqs","Setup Mode":"Mode","Repository Setup":"Repo","Environment Setup":"Env","Install Tools":"Tools","Project Setup":"Setup","Installing CLI":"CLI","Detect Repo":"Detect",Finished:"Done"},Nr=({currentStep:e,steps:t})=>{let r=t.indexOf(e);return ce(ye,{marginBottom:1,flexWrap:"nowrap",children:t.map((o,n)=>{let a=n<r,c=n===r,i=Fr[o]??o;return Te(ye,{flexShrink:0,children:[n>0&&Te(De,{color:"gray",dimColor:!0,children:[" ","\xB7"," "]}),a&&Te(De,{color:"green",children:["\u2713 ",i]}),c&&ce(De,{color:T,bold:!0,children:i}),!a&&!c&&ce(De,{color:"gray",dimColor:!0,children:i})]},o)})})},Ae=({children:e,status:t,step:r,steps:o=Mr})=>Te(ye,{flexDirection:"column",height:"100%",width:"100%",children:[Te(ye,{flexGrow:1,flexDirection:"column",children:[ce(de,{}),ce(Nr,{currentStep:r,steps:o}),ce(ye,{flexDirection:"column",flexGrow:1,children:e})]}),ce(Et,{status:t,step:r})]});import{Spinner as wt}from"@inkjs/ui";import{Box as q,Text as O,useInput as Gr}from"ink";import{jsx as R,jsxs as V}from"react/jsx-runtime";var ke=({checks:e})=>V(q,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:T,children:[R(O,{bold:!0,children:"System Checks"}),V(q,{flexDirection:"column",marginTop:1,children:[R(Ye,{label:"Git",status:e.git}),R(Ye,{label:"Docker",status:e.docker}),R(Ye,{label:"Mise",status:e.mise})]})]}),_e=({status:e})=>V(q,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:T,children:[R(O,{bold:!0,children:"Environment Setup"}),R(q,{marginTop:1,children:R(wt,{label:e||"Configuring environment..."})})]}),Be=({message:e})=>V(q,{flexDirection:"column",borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[V(O,{color:"red",children:["Error: ",e]}),R(q,{marginTop:1,children:V(O,{dimColor:!0,children:[R(O,{bold:!0,children:"Enter"})," to exit"]})})]}),Ye=({label:e,status:t})=>V(q,{children:[R(q,{marginRight:1,children:t==="pending"?R(wt,{type:"dots"}):t==="success"?R(O,{color:"green",children:"\u2714"}):t==="error"?R(O,{color:"red",children:"\u2716"}):R(O,{color:"yellow",children:"\u26A0"})}),R(O,{children:e})]}),Oe=({portResults:e,onAccept:t,onAbort:r})=>{Gr((n,a)=>{a.return?t():a.escape&&r()});let o=e.filter(n=>!n.available);return V(q,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[R(q,{marginBottom:1,children:R(O,{bold:!0,color:"yellow",children:"Port Conflicts Detected"})}),e.map(n=>V(q,{children:[V(O,{color:n.available?"green":n.alternative?"yellow":"red",children:[n.available?"\u2714":n.alternative?"\u26A0":"\u2716"," "]}),V(O,{children:[n.service," (:",n.port,")"]}),!n.available&&V(O,{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)),o.some(n=>!n.alternative)&&R(q,{marginTop:1,children:R(O,{color:"red",children:"Some ports have no available alternative. Free them and retry."})}),!o.some(n=>!n.alternative)&&o.some(n=>n.alternative)&&R(q,{marginTop:1,children:R(O,{color:"gray",children:"Alternative ports will be used for conflicting services."})}),R(q,{marginTop:1,children:V(O,{dimColor:!0,children:[R(O,{bold:!0,children:"Enter"})," continue \xB7 ",R(O,{bold:!0,children:"ESC"})," abort"]})})]})};import{Fragment as Tn,jsx as s,jsxs as h}from"react/jsx-runtime";var qr=({onConfirm:e})=>(ne((t,r)=>{r.return&&e()}),h(d,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:T,children:[s(p,{bold:!0,children:"Welcome to GAIA Setup"}),h(d,{flexDirection:"column",marginTop:1,marginBottom:1,children:[s(p,{children:"This wizard will guide you through the setup process:"}),s(p,{children:" 1. Check prerequisites and choose setup mode"}),s(p,{children:" 2. Clone repository"}),s(p,{children:" 3. Configure environment variables"}),s(p,{children:" 4. Install tools and dependencies"})]}),s(p,{dimColor:!0,children:"~5-15 min depending on network speed"}),s(d,{marginTop:1,children:h(p,{color:T,children:[s(p,{bold:!0,children:"Enter"})," to start"]})})]})),Hr=({defaultValue:e,onSubmit:t})=>{let[r,o]=$(e);return h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:T,children:[s(p,{children:"Clone repository to:"}),s(p,{color:"gray",dimColor:!0,children:"Press Enter for default, or type a custom path"}),h(d,{marginTop:1,children:[s(p,{color:T,children:"\u2192 "}),s(ve,{value:r,onChange:o,onSubmit:t})]})]})},jr=({repoPath:e,onAction:t})=>h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:"yellow",children:[s(d,{marginBottom:1,children:s(p,{bold:!0,color:"yellow",children:"Existing Installation Found"})}),h(p,{children:["Found a GAIA installation at"," ",s(p,{color:"cyan",bold:!0,children:e})]}),s(d,{marginTop:1,children:s(p,{color:"gray",children:"What would you like to do?"})}),s(d,{marginTop:1,children:s(Ke,{options:[{label:"Use existing installation",value:"use_existing"},{label:"Delete and re-clone",value:"delete_reclone"},{label:"Choose a different path",value:"different_path"},{label:"Exit setup",value:"exit"}],onChange:o=>t(o)})})]}),Wr=({setupMode:e,portOverrides:t,onConfirm:r})=>{ne((a,c)=>{c.return&&r()});let o=t?.[3e3]??3e3,n=t?.[8e3]??8e3;return e==="selfhost"?h(d,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:"green",padding:1,children:[s(p,{bold:!0,color:"green",children:"GAIA is Running!"}),s(d,{marginTop:1,children:s(p,{color:"green",children:"\u2713 All services started"})}),h(d,{marginTop:1,flexDirection:"column",children:[h(p,{children:["Web:"," ",h(p,{color:"cyan",bold:!0,children:["http://localhost:",o]})]}),h(p,{children:["API:"," ",h(p,{color:"cyan",bold:!0,children:["http://localhost:",n]})]})]}),s(d,{marginTop:1,children:s(p,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),s(d,{marginTop:1,children:h(p,{dimColor:!0,children:[s(p,{bold:!0,children:"Enter"})," to exit"]})})]}):h(d,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:T,padding:1,children:[s(p,{color:T,bold:!0,children:"You're all set!"}),h(d,{marginTop:1,children:[s(p,{bold:!0,children:"Run: "}),s(p,{color:"cyan",children:"$ gaia start"})]}),h(d,{marginTop:1,flexDirection:"column",children:[h(p,{children:["Web:"," ",h(p,{color:"cyan",bold:!0,children:["http://localhost:",o]})]}),h(p,{children:["API:"," ",h(p,{color:"cyan",bold:!0,children:["http://localhost:",n]})]})]}),s(d,{marginTop:1,children:s(p,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),s(d,{marginTop:1,children:h(p,{dimColor:!0,children:[s(p,{bold:!0,children:"Enter"})," to exit"]})})]})},Vr=8,At=({logs:e,height:t=Vr})=>{let[r,o]=$(0),n=$r(e.length);be(()=>{e.length!==n.current&&(n.current=e.length,o(0))},[e.length]),ne((S,m)=>{m.upArrow?o(x=>Math.min(x+1,Math.max(0,e.length-t))):m.downArrow&&o(x=>Math.max(0,x-1))});let a=e.length,c=Math.max(0,a-t-r),i=Math.max(0,a-r),l=e.slice(c,i),u=c,g=r;return h(d,{flexDirection:"column",marginTop:1,marginLeft:1,children:[u>0&&h(p,{color:"gray",dimColor:!0,children:["\u2191 ",u," more line",u!==1?"s":""]}),s(d,{flexDirection:"column",height:t,overflow:"hidden",children:l.map((S,m)=>s(p,{color:"gray",wrap:"truncate",children:S},`${c}-${m}`))}),g>0?h(p,{color:"gray",dimColor:!0,children:["\u2193 ",g," more line",g!==1?"s":""]}):s(p,{color:"gray",dimColor:!0,children:"\u2191\u2193 scroll"})]})},Je=({phase:e,progress:t,isComplete:r,logs:o,title:n})=>h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:T,children:[s(d,{marginBottom:1,children:s(p,{bold:!0,color:T,children:n||"Installing Dependencies"})}),h(d,{flexDirection:"column",gap:1,children:[s(d,{children:r?h(p,{color:"green",children:["\u2713 ",e]}):s(Dt,{label:e||"Preparing..."})}),!r&&t>0&&s(d,{width:50,children:s(Rt,{value:t})}),!r&&o&&o.length>0&&s(At,{logs:o}),!r&&s(d,{marginTop:1,children:s(p,{color:"gray",dimColor:!0,children:"This may take a few minutes..."})})]})]});var ze=({onSelect:e})=>h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:T,children:[s(p,{bold:!0,children:"Setup Mode"}),s(d,{marginTop:1,children:s(p,{color:"gray",children:"How do you want to run GAIA?"})}),s(d,{marginTop:1,children:s(Ke,{options:[{label:"Self-Host \u2014 run everything in Docker",value:"selfhost"},{label:"Developer \u2014 local dev with hot reload",value:"developer"}],onChange:r=>e(r)})})]}),Ze=({onSelect:e})=>h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:T,children:[s(p,{bold:!0,children:"Environment Variables Setup"}),s(d,{marginTop:1,children:s(p,{color:"gray",children:"Choose how you want to configure environment variables:"})}),s(d,{marginTop:1,children:s(Ke,{options:[{label:"Manual Setup (Recommended)",value:"manual"},{label:"Infisical (Advanced)",value:"infisical"}],onChange:r=>e(r)})}),h(d,{marginTop:1,flexDirection:"column",children:[s(p,{color:"gray",dimColor:!0,children:"Manual Setup: Configure variables interactively (recommended for most users)"}),s(p,{color:"gray",dimColor:!0,children:"Infisical: All secrets managed in Infisical dashboard (requires pre-configuration)"})]})]}),et=({onSubmit:e})=>{let[t,r]=$({INFISICAL_TOKEN:"",INFISICAL_PROJECT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_ID:"",INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET:""}),[o,n]=$(0),[a,c]=$(null),i=[{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"}];ne((u,g)=>{if(g.tab||g.downArrow)n(S=>S<i.length-1?S+1:S);else if(g.upArrow)n(S=>S>0?S-1:S);else if(g.return){if(o<i.length-1){n(m=>m+1);return}let S=i.filter(m=>!t[m.key].trim());if(S.length>0){c(`Required: ${S.map(x=>x.key).join(", ")}`);let m=i.findIndex(x=>!t[x.key].trim());m>=0&&n(m);return}e(t)}});let l=i[o];return h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:T,children:[s(d,{marginBottom:1,children:s(p,{bold:!0,color:T,children:"Infisical Configuration"})}),s(d,{marginBottom:1,children:s(p,{color:"gray",children:"All secrets managed in your Infisical project. Only credentials stored locally."})}),h(d,{marginBottom:1,flexDirection:"column",children:[s(p,{color:"gray",children:"Configure your Infisical credentials."}),h(p,{color:"gray",dimColor:!0,children:["Visit"," ",s(p,{color:"cyan",underline:!0,children:"app.infisical.com"})," ","to get these values."]})]}),i.map((u,g)=>{let S=u.key.includes("SECRET")||u.key.includes("TOKEN");return h(d,{flexDirection:"column",marginBottom:1,children:[s(d,{children:h(p,{color:g===o?T:"white",children:[g===o?"\u25B8 ":" ",u.key,":"]})}),s(d,{marginLeft:2,children:s(p,{color:"gray",dimColor:!0,children:u.description})}),g===o?s(d,{marginLeft:2,children:s(ve,{value:t[u.key],onChange:m=>{r(x=>({...x,[u.key]:m})),c(null)},placeholder:"Enter value...",mask:S?"*":void 0})}):s(d,{marginLeft:2,children:s(p,{color:t[u.key]?"green":"gray",children:t[u.key]?S?`\u2713 ${"*".repeat(8)}`:`\u2713 ${t[u.key]}`:"(not set)"})})]},u.key)}),a&&s(d,{marginTop:1,children:s(p,{color:"red",children:a})}),s(d,{marginTop:1,children:h(p,{dimColor:!0,children:[s(p,{bold:!0,children:"Enter"})," confirm \xB7 ",s(p,{bold:!0,children:"\u2191\u2193"})," navigate"]})})]})},tt=({category:e,currentIndex:t,totalGroups:r,onSubmit:o})=>{let[n,a]=$(()=>{let m={};for(let x of e.variables)m[x.name]=x.defaultValue||"";return m}),[c,i]=$(0),[l,u]=$(null);be(()=>{let m={};for(let x of e.variables)m[x.name]=x.defaultValue||"";a(m),i(0),u(null)},[e.name]),ne((m,x)=>{if(x.tab||x.downArrow)i(f=>f<e.variables.length-1?f+1:f);else if(x.upArrow)i(f=>f>0?f-1:f);else if(x.escape){let f=e.variables.filter(y=>y.required&&!n[y.name]?.trim());if(f.length>0){u(`Required fields cannot be skipped: ${f.map(y=>y.name).join(", ")}`);return}o(n)}});let g=()=>{if(c<e.variables.length-1)i(c+1);else{let m=e.variables.filter(x=>x.required&&!n[x.name]?.trim());if(m.length>0){u(`Required fields are missing: ${m.map(x=>x.name).join(", ")}`);return}u(null),o(n)}},S=e.variables.some(m=>m.required);return h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:l?"red":T,children:[h(d,{justifyContent:"space-between",children:[h(p,{bold:!0,children:["Configure ",e.name]}),h(p,{color:"gray",children:["Group ",t+1," / ",r]})]}),s(d,{marginTop:1,children:s(p,{color:"gray",children:e.description})}),s(d,{marginTop:1,flexDirection:"column",children:e.variables.map((m,x)=>{let f=x===c,y=!!m.defaultValue;return h(d,{flexDirection:"column",marginBottom:1,children:[h(d,{children:[h(p,{color:f?T:"gray",bold:f,children:[f?"\u279C ":" ",m.name]}),m.required&&h(p,{color:"red",bold:!0,children:[" ","*"]}),y&&!f&&h(p,{color:"gray",dimColor:!0,children:[" ","(default: ",m.defaultValue,")"]})]}),f&&s(d,{marginLeft:2,children:s(ve,{value:n[m.name]||"",onChange:v=>{a(b=>({...b,[m.name]:v})),l&&u(null)},onSubmit:g,placeholder:y?`Default: ${m.defaultValue}`:m.required?"Enter a value (required)":"Press Enter to skip"})})]},m.name)})}),l&&s(d,{marginTop:1,children:h(p,{color:"red",bold:!0,children:["\u26A0 ",l]})}),s(d,{marginTop:1,children:h(p,{dimColor:!0,children:[s(p,{bold:!0,children:"Enter"})," next \xB7 ",s(p,{bold:!0,children:"\u2191\u2193"})," navigate",!S&&h(p,{children:[" ","\xB7 ",s(p,{bold:!0,children:"ESC"})," skip"]})]})})]})},rt=({alternatives:e,onSubmit:t})=>{let[r,o]=$(new Set),[n,a]=$({}),[c,i]=$(0),[l,u]=$(null);be(()=>{let v={};for(let b of e)for(let P of b.variables)v[P.name]=P.defaultValue||"";a(v)},[e]);let g=[];for(let v=0;v<e.length;v++)if(g.push({type:"provider",categoryIndex:v}),r.has(v)){let b=e[v];if(b)for(let P=0;P<b.variables.length;P++)g.push({type:"field",categoryIndex:v,fieldIndex:P})}g.push({type:"submit"});let S=g[c],m=S?.type==="field",x=S?.type==="submit";ne((v,b)=>{let P=Math.min(c,g.length-1);if(P!==c){i(P);return}if(m)b.upArrow?i(w=>Math.max(0,w-1)):(b.downArrow||b.tab)&&i(w=>Math.min(g.length-1,w+1));else if(x)b.upArrow?i(w=>Math.max(0,w-1)):(b.return||v===" ")&&y();else if(b.upArrow)i(w=>Math.max(0,w-1));else if(b.downArrow||b.tab)i(w=>Math.min(g.length-1,w+1));else if((b.return||v===" ")&&S?.type==="provider"){let w=S.categoryIndex;o(ee=>{let k=new Set(ee);return k.has(w)?k.delete(w):k.add(w),k}),l&&u(null)}});let f=()=>{l&&u(null),i(v=>Math.min(g.length-1,v+1))},y=()=>{let v=[],b={};for(let P of r){let w=e[P];if(!w)continue;if(w.variables.some(k=>n[k.name]?.trim())){v.push(w.name);for(let k of w.variables){let Re=n[k.name];Re&&(b[k.name]=Re)}}}if(v.length===0){r.size===0?u("Enable at least one provider (press Space or Enter)"):u("Enter a value for at least one field");return}t(v,b)};return h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:l?"red":T,children:[h(d,{justifyContent:"space-between",children:[s(p,{bold:!0,children:"Configure AI Provider"}),s(p,{color:"yellow",children:"* At least one required"})]}),s(d,{marginTop:1,children:s(p,{color:"gray",children:"Enable and configure at least one AI provider below:"})}),s(d,{marginTop:1,flexDirection:"column",children:e.map((v,b)=>{let P=r.has(b),w=g.findIndex(k=>k.type==="provider"&&k.categoryIndex===b),ee=c===w;return h(d,{flexDirection:"column",marginBottom:1,children:[h(d,{children:[s(p,{color:ee?T:void 0,bold:ee,children:ee?"\u279C ":" "}),s(p,{color:P?"green":"gray",children:P?"[\u2714]":"[ ]"}),h(p,{color:P?T:"gray",bold:P,children:[" ",v.name]}),v.description&&h(p,{color:"gray",dimColor:!0,children:[" ","- ",v.description]})]}),ee&&v.docsUrl&&h(d,{marginLeft:6,children:[s(p,{color:"yellow",children:"\u{1F4D6} "}),s(p,{color:"blue",underline:!0,children:v.docsUrl})]}),P&&s(d,{marginLeft:4,flexDirection:"column",marginTop:1,children:v.variables.map((k,Re)=>{let Dr=g.findIndex(xe=>xe.type==="field"&&xe.categoryIndex===b&&xe.fieldIndex===Re),pe=c===Dr,It=!!k.defaultValue,Xe=n[k.name]||"";return h(d,{flexDirection:"column",marginBottom:1,children:[h(d,{children:[h(p,{color:pe?T:"gray",bold:pe,children:[pe?" \u279C ":" ",k.name]}),!pe&&Xe&&s(p,{color:"green",children:" \u2713"}),!pe&&!Xe&&It&&h(p,{color:"gray",dimColor:!0,children:[" ","(default: ",k.defaultValue,")"]})]}),pe&&s(d,{marginLeft:4,children:s(ve,{value:Xe,onChange:xe=>{a(Ar=>({...Ar,[k.name]:xe})),l&&u(null)},onSubmit:f,placeholder:It?`Default: ${k.defaultValue}`:"Enter value..."})})]},k.name)})})]},v.name)})}),l&&s(d,{marginTop:1,children:h(p,{color:"red",bold:!0,children:["\u26A0 ",l]})}),h(d,{marginTop:1,children:[s(p,{color:x?T:void 0,bold:x,children:x?"\u279C ":" "}),s(d,{borderStyle:"round",borderColor:x?T:"gray",paddingX:2,children:s(p,{color:x?T:"gray",bold:x,children:"Continue \u2192"})})]}),s(d,{marginTop:1,children:s(p,{color:"gray",dimColor:!0,children:"\u2191/\u2193 navigate \u2022 Space/Enter toggle/select \u2022 Tab skip field"})})]})},ot=({currentVar:e,currentIndex:t,totalCount:r,onSubmit:o,onSkip:n})=>{let[a,c]=$(e.defaultValue||""),[i,l]=$(null);be(()=>{c(e.defaultValue||""),l(null)},[e.name]),ne((S,m)=>{if(m.escape){if(e.required&&!a.trim()){l("This field is required and cannot be skipped");return}n()}});let u=S=>{if(e.required&&!S.trim()){l("This field is required");return}l(null),o(S)},g=!!e.defaultValue;return h(d,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:i?"red":T,children:[h(d,{justifyContent:"space-between",children:[h(d,{children:[s(p,{color:T,bold:!0,children:e.name}),e.required?s(p,{color:"red",children:" *"}):h(p,{color:"gray",dimColor:!0,children:[" ","optional"]})]}),h(p,{color:"gray",children:[t+1,"/",r]})]}),s(d,{marginLeft:1,children:s(p,{color:"gray",children:e.description})}),h(d,{marginTop:1,children:[s(p,{color:T,children:"\u2192 "}),s(ve,{value:a,onChange:S=>{c(S),i&&l(null)},onSubmit:u,placeholder:g?`Default: ${e.defaultValue}`:e.required?"required":"skip with Enter"})]}),i&&s(d,{marginTop:1,children:s(p,{color:"red",children:i})}),s(d,{marginTop:1,children:h(p,{dimColor:!0,children:[s(p,{bold:!0,children:"Enter"})," confirm",!e.required&&h(p,{children:[" ","\xB7 ",s(p,{bold:!0,children:"ESC"})," skip"]})]})})]})},kt=({store:e})=>{let[t,r]=$(e.currentState);return be(()=>{let o=()=>r({...e.currentState});return e.on("change",o),()=>{e.off("change",o)}},[e]),ne((o,n)=>{(n.return||n.escape)&&t.error&&e.submitInput("exit")}),h(Ae,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&s(qr,{onConfirm:()=>e.submitInput(!0)}),t.step==="Prerequisites"&&t.data.checks&&s(ke,{checks:t.data.checks}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&s(Oe,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="repo_path"&&s(Hr,{defaultValue:t.inputRequest.meta.default,onSubmit:o=>e.submitInput(o)}),t.inputRequest?.id==="existing_repo"&&t.data.existingRepoPath&&s(jr,{repoPath:t.data.existingRepoPath,onAction:o=>e.submitInput(o)}),t.step==="Repository Setup"&&!t.inputRequest&&h(d,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:T,children:[s(p,{bold:!0,children:"Cloning Repository"}),h(d,{marginTop:1,flexDirection:"column",children:[s(Rt,{value:t.data.repoProgress||0}),t.data.repoPhase&&s(d,{marginTop:1,children:s(p,{color:"gray",children:t.data.repoPhase})})]})]}),t.inputRequest?.id==="setup_mode"&&s(ze,{onSelect:o=>e.submitInput(o)}),t.inputRequest?.id==="env_method"&&s(Ze,{onSelect:o=>e.submitInput(o)}),t.inputRequest?.id==="env_infisical"&&s(et,{onSubmit:o=>e.submitInput(o)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&s(ot,{categories:t.data.envCategories||[],currentVar:t.data.currentEnvVar,currentIndex:t.data.envVarIndex||0,totalCount:t.data.envVarTotal||0,onSubmit:o=>e.submitInput(o),onSkip:()=>e.submitInput("")}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_group"&&t.data.currentEnvGroup&&s(tt,{category:t.data.currentEnvGroup,currentIndex:t.data.envGroupIndex||0,totalGroups:t.data.envGroupTotal||0,onSubmit:o=>e.submitInput(o)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_alternatives"&&t.data.alternativeGroups&&s(rt,{alternatives:t.data.alternativeGroups,onSubmit:(o,n)=>e.submitInput({selectedGroups:o,values:n})}),t.step==="Environment Setup"&&!t.inputRequest&&s(_e,{status:t.status}),t.step==="Finished"&&s(Wr,{setupMode:t.data.setupMode,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),(t.step==="Install Tools"||t.step==="Project Setup")&&s(Je,{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.step==="Installing CLI"&&h(d,{flexDirection:"column",borderStyle:"round",padding:1,borderColor:T,children:[s(p,{bold:!0,color:T,children:"Installing CLI"}),s(d,{marginTop:1,children:s(Dt,{label:t.status||"Installing gaia CLI globally..."})}),t.data.cliInstallLogs&&t.data.cliInstallLogs.length>0&&s(At,{logs:t.data.cliInstallLogs})]}),t.error&&s(Be,{message:t.error.message})]})};import{Spinner as Ur}from"@inkjs/ui";import{Box as F,Text as C,useInput as _t}from"ink";import{useEffect as Bt,useRef as Xr,useState as Ot}from"react";import{jsx as L,jsxs as I}from"react/jsx-runtime";var nt=8,Qr=({logs:e})=>{let[t,r]=Ot(0),o=Xr(e.length);Bt(()=>{e.length!==o.current&&(o.current=e.length,r(0))},[e.length]),_t((g,S)=>{S.upArrow?r(m=>Math.min(m+1,Math.max(0,e.length-nt))):S.downArrow&&r(m=>Math.max(0,m-1))});let n=e.length,a=Math.max(0,n-nt-t),c=Math.max(0,n-t),i=e.slice(a,c),l=a,u=t;return I(F,{flexDirection:"column",marginTop:1,marginLeft:1,children:[l>0&&I(C,{color:"gray",dimColor:!0,children:["\u2191 ",l," more line",l!==1?"s":""]}),L(F,{flexDirection:"column",height:nt,overflow:"hidden",children:i.map((g,S)=>L(C,{color:"gray",wrap:"truncate",children:g},a+S))}),u>0?I(C,{color:"gray",dimColor:!0,children:["\u2193 ",u," more line",u!==1?"s":""]}):L(C,{color:"gray",dimColor:!0,children:"\u2191\u2193 scroll"})]})},Lt=({store:e})=>{let[t,r]=Ot(e.currentState);return Bt(()=>{let o=()=>r({...e.currentState});return e.on("change",o),()=>{e.off("change",o)}},[e]),_t((o,n)=>{(n.return||n.escape)&&(t.data.started||t.data.stopped||t.error)&&e.submitInput("exit")}),I(F,{flexDirection:"column",width:"100%",children:[L(de,{}),(t.step==="Starting"||t.step==="Stopping")&&I(F,{flexDirection:"column",marginTop:1,paddingX:2,borderStyle:"round",borderColor:T,children:[L(Ur,{label:t.status||"Working..."}),t.data.repoPath&&L(F,{marginTop:1,children:I(C,{color:"gray",children:["Repository: ",t.data.repoPath]})}),t.data.setupMode&&L(F,{children:I(C,{color:"gray",children:["Mode: ",t.data.setupMode]})}),t.data.dockerLogs&&t.data.dockerLogs.length>0&&L(Qr,{logs:t.data.dockerLogs})]}),t.step==="Running"&&t.data.started&&I(F,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:"green",children:[I(C,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),t.data.setupMode!=="developer"&&I(F,{marginTop:1,flexDirection:"column",children:[I(C,{children:["Web:"," ",I(C,{color:"cyan",bold:!0,children:["http://localhost:",t.data.webPort||3e3]})]}),I(C,{children:["API:"," ",I(C,{color:"cyan",bold:!0,children:["http://localhost:",t.data.apiPort||8e3]})]})]}),t.data.setupMode==="developer"&&I(F,{marginTop:1,flexDirection:"column",children:[I(F,{flexDirection:"column",children:[I(C,{children:["Web:"," ",I(C,{color:"cyan",bold:!0,children:["http://localhost:",t.data.webPort||3e3]})]}),I(C,{children:["API:"," ",I(C,{color:"cyan",bold:!0,children:["http://localhost:",t.data.apiPort||8e3]})]})]}),I(F,{marginTop:1,flexDirection:"column",children:[L(C,{color:"gray",children:"Dev servers started in background."}),I(C,{color:"gray",children:["Logs: ",L(C,{color:T,children:"dev-start.log"})," in your repo root."]}),I(C,{color:"gray",children:["Run ",L(C,{color:T,children:"gaia stop"})," to shut down."]})]})]}),L(F,{marginTop:1,children:I(C,{dimColor:!0,children:[L(C,{bold:!0,children:"Enter"})," to exit"]})})]}),t.step==="Stopped"&&t.data.stopped&&I(F,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:T,children:[I(C,{color:T,bold:!0,children:["\u2713"," All GAIA services stopped."]}),L(F,{marginTop:1,children:I(C,{dimColor:!0,children:[L(C,{bold:!0,children:"Enter"})," to exit"]})})]}),t.error&&I(F,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[I(C,{color:"red",children:["Error: ",t.error.message]}),L(F,{marginTop:1,children:I(C,{dimColor:!0,children:[L(C,{bold:!0,children:"Enter"})," to exit"]})})]})]})};import{Spinner as Yr}from"@inkjs/ui";import{Box as ie,Text as X,useInput as Mt}from"ink";import{useEffect as Kr,useState as Jr}from"react";import{jsx as D,jsxs as K}from"react/jsx-runtime";var Ft=({store:e})=>{let[t,r]=Jr(e.currentState);return Kr(()=>{let o=()=>r({...e.currentState});return e.on("change",o),()=>{e.off("change",o)}},[e]),Mt((o,n)=>{(n.return||n.escape)&&t.error&&e.submitInput("exit")}),K(Ae,{status:t.status,step:t.step,steps:Pt,children:[t.step==="Detect Repo"&&K(ie,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:T,children:[D(X,{bold:!0,children:"Detecting GAIA Repository"}),D(ie,{marginTop:1,children:D(Yr,{label:"Searching for repository..."})}),t.data.repoPath&&D(ie,{marginTop:1,children:K(X,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&D(ke,{checks:t.data.checks}),t.inputRequest?.id==="port_conflicts"&&t.data.portConflicts&&D(Oe,{portResults:t.data.portConflicts,onAccept:()=>e.submitInput("accept"),onAbort:()=>e.submitInput("abort")}),t.inputRequest?.id==="setup_mode"&&D(ze,{onSelect:o=>e.submitInput(o)}),t.inputRequest?.id==="env_method"&&D(Ze,{onSelect:o=>e.submitInput(o)}),t.inputRequest?.id==="env_infisical"&&D(et,{onSubmit:o=>e.submitInput(o)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&D(ot,{categories:t.data.envCategories||[],currentVar:t.data.currentEnvVar,currentIndex:t.data.envVarIndex||0,totalCount:t.data.envVarTotal||0,onSubmit:o=>e.submitInput(o),onSkip:()=>e.submitInput("")}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_group"&&t.data.currentEnvGroup&&D(tt,{category:t.data.currentEnvGroup,currentIndex:t.data.envGroupIndex||0,totalGroups:t.data.envGroupTotal||0,onSubmit:o=>e.submitInput(o)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_alternatives"&&t.data.alternativeGroups&&D(rt,{alternatives:t.data.alternativeGroups,onSubmit:(o,n)=>e.submitInput({selectedGroups:o,values:n})}),t.step==="Environment Setup"&&!t.inputRequest&&D(_e,{status:t.status}),t.step==="Project Setup"&&D(Je,{title:"Project Setup",phase:t.data.dependencyPhase||"",progress:t.data.dependencyProgress||0,isComplete:t.data.dependencyComplete||!1,logs:t.data.dependencyLogs||[]}),t.step==="Finished"&&D(zr,{setupMode:t.data.setupMode,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),t.error&&D(Be,{message:t.error.message})]})},zr=({portOverrides:e,onConfirm:t})=>{Mt((n,a)=>{a.return&&t()});let r=e?.[3e3]??3e3,o=e?.[8e3]??8e3;return K(ie,{flexDirection:"column",marginTop:2,borderStyle:"round",borderColor:T,padding:1,children:[D(X,{color:T,bold:!0,children:"Setup Complete!"}),K(ie,{marginTop:1,children:[D(X,{bold:!0,children:"Run: "}),D(X,{color:"cyan",children:"$ gaia start"})]}),K(ie,{marginTop:1,flexDirection:"column",children:[K(X,{children:["Web:"," ",K(X,{color:"cyan",bold:!0,children:["http://localhost:",r]})]}),K(X,{children:["API:"," ",K(X,{color:"cyan",bold:!0,children:["http://localhost:",o]})]})]}),D(ie,{marginTop:1,children:D(X,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),D(ie,{marginTop:1,children:K(X,{dimColor:!0,children:[D(X,{bold:!0,children:"Enter"})," to exit"]})})]})};import{Spinner as Zr}from"@inkjs/ui";import{Box as _,Text as A,useInput as eo}from"ink";import{useEffect as Nt,useState as it}from"react";import{jsx as E,jsxs as N}from"react/jsx-runtime";var Gt=({store:e})=>{let[t,r]=it(e.currentState),[o,n]=it(!1),[a,c]=it(null);return Nt(()=>{let i=()=>r({...e.currentState});return e.on("change",i),()=>{e.off("change",i)}},[e]),Nt(()=>{n(!1),c(new Date().toLocaleTimeString())},[t.data.services]),eo((i,l)=>{(l.return||l.escape)&&t.step==="Results"&&e.submitInput("exit"),i==="r"&&t.step==="Results"&&t.data.refreshable&&!o&&(n(!0),e.submitInput("refresh"))}),N(_,{flexDirection:"column",width:"100%",children:[E(de,{}),t.step==="Checking"&&E(_,{marginTop:1,children:E(Zr,{label:t.data.services?"Refreshing service health...":"Checking service health..."})}),t.step==="Results"&&t.data.services&&N(_,{flexDirection:"column",children:[N(_,{flexDirection:"column",borderStyle:"round",borderColor:T,paddingX:2,paddingY:1,children:[N(_,{justifyContent:"space-between",children:[E(A,{bold:!0,color:T,children:"GAIA Service Status"}),a&&N(A,{color:"gray",dimColor:!0,children:["checked ",a," \xB7 ",E(A,{bold:!0,children:"r"})," refresh"]})]}),N(_,{marginTop:1,flexDirection:"column",children:[N(_,{children:[E(_,{width:22,children:E(A,{bold:!0,children:"Service"})}),E(_,{width:10,children:E(A,{bold:!0,children:"Status"})}),E(_,{width:10,children:E(A,{bold:!0,children:"Latency"})})]}),E(A,{color:"gray",children:"\u2500".repeat(42)}),[...t.data.services].sort((i,l)=>i.status==="down"&&l.status!=="down"?-1:i.status!=="down"&&l.status==="down"?1:i.name.localeCompare(l.name)).map(i=>N(_,{children:[E(_,{width:22,children:N(A,{children:[i.name," (:",i.port,")"]})}),E(_,{width:10,children:E(A,{color:i.status==="up"?"green":"red",bold:!0,children:i.status==="up"?"\u2713 UP":"\u2717 DOWN"})}),E(_,{width:10,children:E(A,{color:"gray",children:i.latency?`${i.latency}ms`:"--"})})]},i.name))]})]}),t.data.docker&&N(_,{flexDirection:"column",borderStyle:"round",borderColor:"gray",paddingX:2,paddingY:1,marginTop:1,children:[E(A,{bold:!0,children:"Docker Containers"}),N(A,{color:"gray",children:["Docker:"," ",t.data.docker.running?E(A,{color:"green",children:"Running"}):E(A,{color:"red",children:"Not running"})]}),t.data.docker.containers?.length>0&&E(_,{marginTop:1,flexDirection:"column",children:t.data.docker.containers.map(i=>N(_,{children:[N(A,{color:i.status==="running"?"green":"red",children:[i.status==="running"?"\u2713":"\u2717"," "]}),E(A,{children:i.name}),i.health&&N(A,{color:"gray",children:[" (",i.health,")"]})]},i.name))})]}),E(_,{marginTop:1,children:N(A,{dimColor:!0,children:[E(A,{bold:!0,children:"Enter"})," exit \xB7 ",E(A,{bold:!0,children:"r"})," refresh"]})})]}),t.error&&E(_,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:N(A,{color:"red",children:["Error: ",t.error.message]})})]})};import{jsx as Q,jsxs as Ie}from"react/jsx-runtime";var ro=["init","setup","status","start","stop"],at=class extends to.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?Ie(Le,{flexDirection:"column",padding:1,children:[Q(le,{color:"red",bold:!0,children:"An unexpected error occurred:"}),Q(le,{color:"red",children:this.state.error.message}),this.state.error.stack&&Q(Le,{marginTop:1,children:Q(le,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},oo=({store:e,command:t})=>{switch(t){case"init":return Q(kt,{store:e});case"setup":return Q(Ft,{store:e});case"status":return Q(Gt,{store:e});case"start":case"stop":return Q(Lt,{store:e,command:t});default:return Ie(Le,{flexDirection:"column",padding:1,children:[Ie(le,{color:"red",children:["Unknown command: ",t]}),Ie(Le,{marginTop:1,flexDirection:"column",children:[Q(le,{bold:!0,children:"Available commands:"}),ro.map(r=>Ie(le,{children:[" ",Q(le,{color:"cyan",children:r})]},r))]})]})}},J=({store:e,command:t})=>Q(at,{children:Q(oo,{store:e,command:t})});import{EventEmitter as no}from"events";var io=150,st=class extends no{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))},io))}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,r){this.state.data={...this.state.data,[t]:r},this.scheduleEmit()}waitForInput(t,r,o){return this.state.inputRequest={id:t,meta:r},this.emitNow(),new Promise(n=>{if(this.inputResolver=n,o!=null){let a=setTimeout(()=>{this.inputResolver&&(this.inputResolver=null,this.state.inputRequest=null,this.emitNow(),n(null))},o),c=this.inputResolver;this.inputResolver=i=>{clearTimeout(a),c(i)}}})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emitNow())}},z=()=>new st;import*as oe from"fs";import*as fr from"os";import*as ae from"path";import*as te from"fs";import*as $t from"os";import*as ut from"path";var ct=ut.join($t.homedir(),".gaia"),lt=ut.join(ct,"config.json"),Me="0.1.10";function ao(){te.existsSync(ct)||te.mkdirSync(ct,{recursive:!0})}function pt(){try{if(!te.existsSync(lt))return null;let e=te.readFileSync(lt,"utf-8");return JSON.parse(e)}catch{return null}}function Fe(e){ao(),te.writeFileSync(lt,`${JSON.stringify(e,null,2)}
3
+ `)}function Ce(e){let r={...pt()??{version:Me,setupComplete:!1,setupMethod:"manual",repoPath:"",createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()},...e,updatedAt:new Date().toISOString()};Fe(r)}import*as tr from"path";import*as fe from"node:fs";import*as me from"node:path";import{execa as qt}from"execa";var dt={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/"}},Ht={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 mt(e,t){return dt[t][e]??Ht[t][e]}async function jt(e){let t=me.join(e,"apps/api/scripts/dump_config_schema.py"),r=me.join(e,"apps/api/app/config/settings_validator.py"),o=me.join(e,"apps/api/app/config/settings.py");if(!fe.existsSync(t))throw new Error("dump_config_schema.py not found in apps/api/scripts");try{try{let{stdout:n}=await qt("python3",[t,r,o],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await qt("python",[t,r,o],{cwd:e});return JSON.parse(n)}}catch(n){throw new Error(`Failed to parse settings schema: ${n.message}. Ensure python is installed.`)}}function Wt(e){let t=me.join(e,"apps","web",".env.local"),r=fe.existsSync(t)?t:me.join(e,"apps","web",".env");if(!fe.existsSync(r))return[];let o=fe.readFileSync(r,"utf-8"),n=[],a="General";for(let c of o.split(`
4
+ `)){let i=c.trim();if(i.startsWith("#")&&!i.startsWith("#=")){let S=i.replace(/^#+\s*/,"").trim();S&&!S.startsWith("These are")&&(a=S);continue}if(!i||i.startsWith("#"))continue;let l=i.indexOf("=");if(l===-1)continue;let u=i.substring(0,l).trim(),g=i.substring(l+1).trim();n.push({name:u,value:g,category:a})}return n}function Vt(e,t){return{NEXT_PUBLIC_API_BASE_URL:`http://localhost:${t?.[8e3]??8e3}/api/v1/`}}function Ut(e,t,r){let o=r==="selfhost"?new Set(Object.keys(dt.selfhost)):new Set;for(let[n,a]of Object.entries(t)){let c=Number(n),i=Number(a);for(let[l,u]of Object.entries(e)){if(o.has(l))continue;if(u===String(c)){e[l]=String(i);continue}let g=new RegExp(`:${c}(?=[/\\s]|$)`,"g");e[l]=u.replaceAll(g,`:${i}`)}}}function Xt(e,t){return e.map(r=>({...r,variables:r.variables.map(o=>{let n=mt(o.name,t);return{...o,defaultValue:n||o.defaultValue}})}))}function ft(){return Object.keys(dt.selfhost)}function Qt(e){return{...Ht[e]}}import*as H from"fs";import*as ge from"path";function gt(e){H.existsSync(e)&&H.copyFileSync(e,`${e}.bak`)}function Kt(e,t){let r=ge.join(e,".env");gt(r);let o=["# 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 a(i){for(let u of n)if(i===u||i.startsWith(`${u}_`))return u;let l=i.split("_");return l.length===1?"Core":l[0]||"Core"}let c=new Map;for(let[i,l]of Object.entries(t)){let u=a(i);c.has(u)||c.set(u,[]);let S=/[\s#"'\\]/.test(l)||l===""?`"${l.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:l;c.get(u).push(`${i}=${S}`)}for(let[i,l]of c.entries())o.push(`# ${i} Configuration`),o.push(...l),o.push("");H.writeFileSync(r,o.join(`
5
+ `),"utf-8")}function Jt(e,t,r){let o=ge.join(e,"apps","web",".env.local");gt(o);let n=Wt(e),a=Vt(t,r),c=["# GAIA Web App Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],i=new Map;for(let l of n){i.has(l.category)||i.set(l.category,[]);let u=a[l.name]??l.value;i.get(l.category).push({name:l.name,value:u})}if(n.length===0){c.push("# Core URLs");for(let[l,u]of Object.entries(a))c.push(`${l}=${u}`);c.push("")}else for(let[l,u]of i.entries()){c.push(`# ${l}`);for(let{name:g,value:S}of u)c.push(`${g}=${S}`);c.push("")}H.writeFileSync(o,c.join(`
6
+ `),"utf-8")}var zt={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 Zt(e,t,r){let o=ge.join(e,"infra","docker",".env");gt(o);let n=["# Docker Compose environment overrides","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""];for(let[a,c]of Object.entries(t)){let i=Number(a),l=zt[i];l&&n.push(`${l}=${c}`)}if(r==="selfhost"){let a=t[8e3]??8e3;n.push(""),n.push("# Web build args"),n.push(`NEXT_PUBLIC_API_BASE_URL=http://localhost:${a}/api/v1/`)}n.push(""),H.writeFileSync(o,n.join(`
7
+ `),"utf-8")}function he(e){let t={};for(let[r,o]of Object.entries(e)){let n=Number(r),a=zt[n];a&&(t[a]=String(o))}return t}function er(e){let t=ge.join(e,"infra","docker","docker-compose.yml");if(!H.existsSync(t))return;let r=H.readFileSync(t,"utf-8"),o=[{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:a,hostPort:c,containerPort:i}of o){let l=`"${c}:${i}"`,u=`"\${${a}:-${c}}:${i}"`;r.includes(l)&&(r=r.replaceAll(l,u),n=!0)}n&&H.writeFileSync(t,r,"utf-8")}var Yt={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=ge.join(e,"infra","docker",".env"),r={};if(!H.existsSync(t))return r;let o=H.readFileSync(t,"utf-8");for(let n of o.split(`
8
+ `)){let a=n.trim();if(a&&!a.startsWith("#")){let[c,...i]=a.split("=");if(c&&Yt[c]){let l=i.join("=").trim().replace(/^["']|["']$/g,""),u=Number(l);!Number.isNaN(u)&&u>0&&u<=65535&&(r[Yt[c]]=u)}}}return r}var lo=e=>new Promise(t=>setTimeout(t,e));async function Ne(e){e.setStep("Setup Mode"),e.setStatus("Choose how to run GAIA...");let t=await e.waitForInput("setup_mode");return e.updateData("setupMode",t),t}async function Ge(e,t,r,o){e.setStep("Environment Setup"),e.setStatus("Configuring environment..."),e.updateData("setupMode",r),e.setStatus("Configuring environment variables...");let n=await e.waitForInput("env_method");e.updateData("envMethod",n);let a={};a.ENV="development";let c=ft();for(let l of c){let u=mt(l,r);u&&(a[l]=u)}let i=Qt(r);for(let[l,u]of Object.entries(i))a[l]=u;if(n==="infisical")await uo(e,a),e.setStatus("Infisical credentials saved. Ensure your Infisical project contains all required variables.");else try{await po(e,t,a,r)}catch(l){e.setError(l);return}o&&Ut(a,o,r);try{await mo(e,t,a,r,o)}catch(l){e.setError(l);return}await lo(1e3)}async function uo(e,t){e.setStatus("Configuring Infisical...");let r=await e.waitForInput("env_infisical");t.INFISICAL_TOKEN=r.INFISICAL_TOKEN,t.INFISICAL_PROJECT_ID=r.INFISICAL_PROJECT_ID,t.INFISICAL_MACHINE_IDENTITY_CLIENT_ID=r.INFISICAL_MACHINE_IDENTITY_CLIENT_ID,t.INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET=r.INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET}async function po(e,t,r,o){e.setStatus("Parsing environment variables...");let n;try{n=await jt(t),n=Xt(n,o)}catch(f){throw o==="selfhost"?new Error(`Manual environment setup requires Python to parse config schema.
9
9
  For self-host mode, we recommend using Infisical for secret management.
10
10
  Alternatively, install Python 3.11+ and try again.
11
11
 
12
- Original error: ${m.message}`):new Error(`Failed to parse settings: ${m.message}`)}let s=new Set,c=[],a=new Set;for(let m of n)if(m.alternativeGroup&&!a.has(m.name)){let d=n.find(h=>h.name===m.alternativeGroup);d&&(c.push([m,d]),s.add(m.name),s.add(d.name),a.add(m.name),a.add(d.name))}let l=n.filter(m=>m.variables.length===1&&!s.has(m.name)),p=n.filter(m=>m.variables.length>1&&!s.has(m.name));for(let m of c){e.updateData("alternativeGroups",m),e.setStatus("Choose an AI provider...");let d=await e.waitForInput("env_alternatives");for(let[h,v]of Object.entries(d.values))v&&(o[h]=v)}let x=ft(),y=[...l.flatMap(m=>m.variables).filter(m=>!x.includes(m.name))].sort((m,d)=>m.required&&!d.required?-1:!m.required&&d.required?1:0);e.updateData("envVarTotal",y.length);for(let m=0;m<y.length;m++){let d=y[m];if(!d)continue;e.updateData("currentEnvVar",d),e.updateData("envVarIndex",m),e.setStatus(`Configuring ${d.name}...`);let h=await e.waitForInput("env_var",{varName:d.name});(h||d.required||d.defaultValue)&&(o[d.name]=h||d.defaultValue||"")}let S=[...p].filter(m=>!m.variables.every(d=>x.includes(d.name))).sort((m,d)=>{let h=m.variables.some(I=>I.required),v=d.variables.some(I=>I.required);return h&&!v?-1:!h&&v?1:0});e.updateData("envGroupTotal",S.length);for(let m=0;m<S.length;m++){let d=S[m];if(!d)continue;e.updateData("currentEnvGroup",d),e.updateData("envGroupIndex",m),e.setStatus(`Configuring ${d.name}...`);let h=await e.waitForInput("env_group",{groupName:d.name});for(let[v,I]of Object.entries(h)){let C=d.variables.find(k=>k.name===v);(I||C?.required||C?.defaultValue)&&(o[v]=I||C?.defaultValue||"")}}}async function ao(e,t,o,r,n){e.setStatus("Writing API environment file...");try{let c=Jt.join(t,"apps","api");Ut(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{Xt(t,r,n),e.setStatus("Web environment variables configured!")}catch(c){throw new Error(`Failed to write web .env file: ${c.message}`)}let s=n&&Object.keys(n).length>0;if(s||r==="selfhost"){e.setStatus("Writing Docker Compose environment...");try{s&&Kt(t),Yt(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 so}from"execa";import qe from"fs";import co from"simple-git";async function zt(e,t,o,r){if(qe.existsSync(e)){let n=`${e}/.git`;if(!qe.existsSync(n))throw new Error(`Directory ${e} exists but is not a git repository`);await co().cwd(e).pull(),o(100,"Already exists, pulled latest")}else try{let n=["clone","--progress"];r&&n.push("--branch",r),n.push(t,e);let s=so("git",n);s.stderr?.on("data",c=>{let a=c.toString();a.includes("Counting objects")?o(5,"Counting objects"):a.includes("Compressing objects")&&o(10,"Compressing objects");let l=a.match(/Receiving objects:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(l?.[1]){let x=Math.min(100,parseInt(l[1],10)),T=l[2],y=l[3];o(10+Math.floor(x*.5),`Receiving objects: ${T}/${y}`)}let p=a.match(/Resolving deltas:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(p?.[1]){let x=Math.min(100,parseInt(p[1],10)),T=p[2],y=p[3];o(60+Math.floor(x*.4),`Resolving deltas: ${T}/${y}`)}}),await s,o(100,"Clone complete")}catch(n){throw qe.existsSync(e)&&qe.rmSync(e,{recursive:!0,force:!0}),n}}import{execSync as ht}from"child_process";import*as M from"fs";import*as je from"os";import*as q from"path";var ke=process.platform==="win32";function Ae(e){try{return ht(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return null}}function Zt(){let e=Ae("npm config get prefix");return e?ke?e:q.join(e,"bin"):null}function er(){let e=Ae("pnpm bin -g");if(e&&M.existsSync(e))return e;let t=Ae("pnpm root -g");if(t){let o=q.join(q.dirname(t),"bin");if(M.existsSync(o))return o}return null}function tr(){let e=q.join(je.homedir(),".bun","bin");return M.existsSync(e)?e:null}function rr(){let e=Ae("yarn global bin");return e&&M.existsSync(e)?e:null}function uo(){let e=ke?"gaia.cmd":"gaia";for(let t of[Zt,er,tr,rr]){let o=t();if(o&&M.existsSync(q.join(o,e)))return o}if(ke)for(let t of[Zt,er,tr,rr]){let o=t();if(o&&M.existsSync(q.join(o,"gaia")))return o}return null}function po(){try{return ht(ke?"where gaia":"command -v gaia",{stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function mo(){let e=process.env.SHELL||"",t=je.homedir();if(e.includes("zsh"))return q.join(t,".zshrc");if(e.includes("bash")){let o=q.join(t,".bashrc"),r=q.join(t,".bash_profile");return M.existsSync(o)?o:r}return e.includes("fish")?q.join(t,".config","fish","config.fish"):null}function fo(e,t){try{if((M.existsSync(t)?M.readFileSync(t,"utf-8"):"").includes(e))return!0;let n=t.includes("fish")?`
12
+ Original error: ${f.message}`):new Error(`Failed to parse settings: ${f.message}`)}let a=new Set,c=[],i=new Set;for(let f of n)if(f.alternativeGroup&&!i.has(f.name)){let y=n.find(v=>v.name===f.alternativeGroup);y&&(c.push([f,y]),a.add(f.name),a.add(y.name),i.add(f.name),i.add(y.name))}let l=n.filter(f=>f.variables.length===1&&!a.has(f.name)),u=n.filter(f=>f.variables.length>1&&!a.has(f.name));for(let f of c){e.updateData("alternativeGroups",f),e.setStatus("Choose an AI provider...");let y=await e.waitForInput("env_alternatives");for(let[v,b]of Object.entries(y.values))b&&(r[v]=b)}let g=ft(),m=[...l.flatMap(f=>f.variables).filter(f=>!g.includes(f.name))].sort((f,y)=>f.required&&!y.required?-1:!f.required&&y.required?1:0);e.updateData("envVarTotal",m.length);for(let f=0;f<m.length;f++){let y=m[f];if(!y)continue;e.updateData("currentEnvVar",y),e.updateData("envVarIndex",f),e.setStatus(`Configuring ${y.name}...`);let v=await e.waitForInput("env_var",{varName:y.name});(v||y.required||y.defaultValue)&&(r[y.name]=v||y.defaultValue||"")}let x=[...u].filter(f=>!f.variables.every(y=>g.includes(y.name))).sort((f,y)=>{let v=f.variables.some(P=>P.required),b=y.variables.some(P=>P.required);return v&&!b?-1:!v&&b?1:0});e.updateData("envGroupTotal",x.length);for(let f=0;f<x.length;f++){let y=x[f];if(!y)continue;e.updateData("currentEnvGroup",y),e.updateData("envGroupIndex",f),e.setStatus(`Configuring ${y.name}...`);let v=await e.waitForInput("env_group",{groupName:y.name});for(let[b,P]of Object.entries(v)){let w=y.variables.find(ee=>ee.name===b);(P||w?.required||w?.defaultValue)&&(r[b]=P||w?.defaultValue||"")}}}async function mo(e,t,r,o,n){e.setStatus("Writing API environment file...");try{let c=tr.join(t,"apps","api");Kt(c,r),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{Jt(t,o,n),e.setStatus("Web environment variables configured!")}catch(c){throw new Error(`Failed to write web .env file: ${c.message}`)}let a=n&&Object.keys(n).length>0;if(a||o==="selfhost"){e.setStatus("Writing Docker Compose environment...");try{a&&er(t),Zt(t,n??{},o),e.setStatus("Docker Compose environment configured!")}catch(c){throw new Error(`Failed to write Docker Compose .env: ${c.message}`)}}}import{execa as re}from"execa";var Y={git:"https://git-scm.com/downloads",docker:"https://docs.docker.com/get-docker/",mise:"https://mise.jdx.dev/getting-started.html"},fo={8e3:"API Server",5432:"PostgreSQL",6379:"Redis",27017:"MongoDB",5672:"RabbitMQ",3e3:"Web Frontend",8080:"ChromaDB",8083:"Mongo Express"};async function rr(){try{return await re("git",["--version"]),"success"}catch{return"error"}}async function $e(){let e=!1,t=!1,r;try{await re("docker",["--version"]),e=!0}catch{return{name:"Docker",installUrl:Y.docker,installed:!1,working:!1,errorMessage:"Docker is not installed"}}try{await re("docker",["info"],{timeout:5e3}),t=!0}catch{r="Docker is installed but the daemon is not running. Please start Docker Desktop or the Docker daemon."}return{name:"Docker",installUrl:Y.docker,installed:e,working:t,errorMessage:r}}async function qe(){try{return await re("mise",["--version"]),"success"}catch{return"missing"}}async function or(){if((await import("node:os")).platform()==="win32")try{return await re("powershell",["-Command","irm https://mise.jdx.dev/install.ps1 | iex"]),!0}catch{return!1}try{return await re("sh",["-c","curl https://mise.jdx.dev/install.sh | sh"]),!0}catch{return!1}}async function nr(e){let t=await import("node:net"),r=[],o=n=>new Promise(a=>{let c=t.createServer();c.once("error",()=>a(!1)),c.once("listening",()=>{c.close(()=>a(!0))}),c.listen(n)});for(let n of e){let a=fo[n]||`Port ${n}`;if(await o(n))r.push({port:n,service:a,available:!0});else{let i=await go(n),l=await ho(n+1,n+100,o);r.push({port:n,service:a,available:!1,usedBy:i,alternative:l||void 0})}}return r}async function go(e){if((await import("node:os")).platform()==="win32"){try{let{stdout:o}=await re("netstat",["-ano","-p","TCP"]),n=o.trim().split(`
13
+ `);for(let a of n)if(a.includes(`:${e}`)&&a.includes("LISTENING")){let c=a.trim().split(/\s+/),i=c[c.length-1];if(i)try{let{stdout:l}=await re("tasklist",["/FI",`PID eq ${i}`,"/FO","CSV","/NH"]);return l.trim().split(",")[0]?.replace(/"/g,"")||`PID ${i}`}catch{return`PID ${i}`}}}catch{}return}try{let{stdout:o}=await re("lsof",["-i",`:${e}`,"-sTCP:LISTEN","-P","-n"]),n=o.trim().split(`
14
+ `);if(n.length>1)return n[1]?.split(/\s+/)?.[0]||void 0}catch{}}async function ho(e,t,r){for(let o=e;o<=t;o++)if(await r(o))return o;return null}import*as M from"fs";import*as U from"path";var So=e=>new Promise(t=>setTimeout(t,e)),xo="dev-start.log";var ir=".gaia-dev.pid";function ar(e){let t=U.join(e,".env");return M.existsSync(t)?["--env-file",".env"]:[]}async function Ee(e,t,r,o,n,a){if(t==="selfhost"){let c=a?.build??!1,i=a?.pull??!1;r?.(c?"Building and starting all services in Docker...":"Starting all services in Docker (selfhost mode)...");let l=U.join(e,"infra/docker"),u=ar(l),g=o&&Object.keys(o).length>0?he(o):void 0,S=["compose","-f","docker-compose.selfhost.yml",...u,"up","-d","--remove-orphans"];c&&S.push("--build"),i&&S.push("--pull","always");let m=c?900*1e3:300*1e3;await j("docker",S,l,void 0,n,g,m),r?.("All services started in Docker!")}else{r?.("Starting development servers...");let{spawn:c}=await import("child_process"),i=U.join(e,xo),l=U.join(e,ir),u=M.openSync(i,"w"),g;try{g=c("mise",["dev"],{cwd:e,stdio:["ignore",u,u],detached:!0,shell:!0}),g.unref()}finally{M.closeSync(u)}if(g.pid!=null&&M.writeFileSync(l,String(g.pid),"utf-8"),await So(1500),g.pid!=null)try{process.kill(g.pid,0)}catch{throw new Error(`Development servers crashed on startup. Check logs at: ${i}`)}r?.(`Development servers started! Logs: ${i}`)}}async function sr(e,t,r){let o=U.join(e,"infra/docker"),n=await St(e);t?.("Stopping Docker services...");try{let a=ar(o),c=n==="selfhost"?["compose","-f","docker-compose.selfhost.yml",...a,"down"]:["compose",...a,"down"];await j("docker",c,o)}catch{}if(n!=="selfhost"){t?.("Stopping local processes...");let a=U.join(e,ir),c=!1;if(M.existsSync(a)){try{let i=Number.parseInt(M.readFileSync(a,"utf-8").trim(),10);if(!Number.isNaN(i)&&i>0)try{process.kill(-i,"SIGTERM"),c=!0}catch{}}catch{}try{M.unlinkSync(a)}catch{}}if(!c)try{let i=r?.[8e3]??8e3,l=r?.[3e3]??3e3;if(process.platform==="win32")for(let u of[i,l])try{await j("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,l])try{await j("sh",["-c",`lsof -ti :${u} -sTCP:LISTEN | xargs kill 2>/dev/null || true`],e)}catch{}}catch{}}t?.("All services stopped.")}async function St(e){let t=U.join(e,"apps","api",".env");if(!M.existsSync(t))return null;let r=M.readFileSync(t,"utf-8"),o=r.match(/^SETUP_MODE=(.+)$/m);if(o?.[1]){let n=o[1].trim().replace(/^["']|["']$/g,"");if(n==="selfhost"||n==="developer")return n}return r.includes("mongodb://mongo:")?"selfhost":(r.includes("mongodb://localhost:"),"developer")}async function j(e,t,r,o,n,a,c){let{spawn:i}=await import("child_process");return new Promise((l,u)=>{let g=i(e,t,{cwd:r,stdio:["ignore","pipe","pipe"],shell:!0,env:a?{...process.env,...a}:void 0}),S="",m=0,x=!1,f;c&&(f=setTimeout(()=>{x=!0,g.kill("SIGTERM"),u(new Error(`Command timed out after ${Math.round(c/6e4)}m. Check \`docker compose logs\` to debug.`))},c)),g.stdout?.on("data",y=>{let v=y.toString();S+=v,n?.(v),m=Math.min(m+5,95),o?.(m)}),g.stderr?.on("data",y=>{let v=y.toString();S+=v,n?.(v),m=Math.min(m+5,95),o?.(m)}),g.on("close",y=>{f&&clearTimeout(f),!x&&(y===0?(o?.(100),l()):u(new Error(`Command failed with code ${y}: ${S.slice(-500)}`)))}),g.on("error",y=>{f&&clearTimeout(f),!x&&u(y)})})}function Z(e){let t=e||process.cwd();for(;t!==U.dirname(t);){if(M.existsSync(U.join(t,"apps/api/app/config/settings_validator.py")))return t;t=U.dirname(t)}let r=pt();if(r?.repoPath){if(M.existsSync(U.join(r.repoPath,"apps/api/app/config/settings_validator.py")))return r.repoPath;console.warn(`Warning: Saved repo path "${r.repoPath}" is no longer a valid GAIA installation. Resetting config.`),Ce({repoPath:"",setupComplete:!1})}return null}var W=e=>new Promise(t=>setTimeout(t,e)),He=(e,t="dependencyLogs")=>r=>{let o=e.currentState.data[t]||[],n=r.split(`
15
+ `).filter(a=>a.trim()!=="");e.updateData(t,[...o,...n].slice(-30))};async function je(e){e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await W(500);let t=await rr();e.updateData("checks",{...e.currentState.data.checks,git:t});let r=await $e(),o=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:o}),r.working||e.updateData("dockerError",r.errorMessage);let n=await qe();e.updateData("checks",{...e.currentState.data.checks,mise:n}),n==="missing"&&(e.setStatus("Installing Mise..."),n=await or()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:n}));let a=[];if(t==="error"&&a.push({name:"Git"}),o==="error"&&a.push({name:"Docker",message:r.errorMessage}),a.length>0){let c=["Prerequisites failed:"];for(let i of a)c.push(` \u2022 ${i.name}: ${i.message||"Not installed or not working"}`);return c.push(`
16
+ Installation guides:`),t==="error"&&c.push(` \u2022 Git: ${Y.git}`),o==="error"&&(r.installed?c.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):c.push(` \u2022 Docker: ${Y.docker}`)),e.setError(new Error(c.join(`
17
+ `))),null}return{gitStatus:t,dockerStatus:o,dockerInfo:r,miseStatus:n}}async function We(e){e.setStatus("Checking Ports...");let r=await nr([8e3,5432,6379,27017,5672,3e3,8080,8083]),o={},n=r.filter(a=>!a.available);if(n.length>0){let a=n.filter(i=>!i.alternative);if(a.length>0)return e.setError(new Error(`Cannot find free alternative ports for: ${a.map(i=>`${i.port} (${i.service})`).join(", ")}. Free these ports and try again.`)),null;if(e.updateData("portConflicts",r),await e.waitForInput("port_conflicts")==="abort")return e.setError(new Error("Port conflicts not resolved. Please free the ports and try again.")),null;for(let i of r)!i.available&&i.alternative&&(o[i.port]=i.alternative)}return e.updateData("portOverrides",o),e.setStatus("Prerequisites check complete!"),await W(1e3),o}async function cr(e,t,r,o){e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyPhase","Trusting mise configuration..."),await j("mise",["trust"],t,void 0,o),e.updateData("dependencyProgress",20),e.updateData("dependencyPhase","Installing tools..."),await j("mise",["install"],t,a=>{e.updateData("dependencyProgress",20+a*.3)},o),e.updateData("dependencyPhase","Running mise setup...");let n=Object.keys(r).length>0?he(r):void 0;return await j("mise",["setup"],t,a=>{e.updateData("dependencyProgress",50+a*.5)},o,n),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0),!0}catch(n){return e.setError(new Error(`Failed to setup project: ${n.message}`)),!1}}import{execa as yo}from"execa";import Ve from"fs";import To from"simple-git";async function lr(e,t,r,o){if(Ve.existsSync(e)){let n=`${e}/.git`;if(!Ve.existsSync(n))throw new Error(`Directory ${e} exists but is not a git repository`);await To().cwd(e).pull(),r(100,"Already exists, pulled latest")}else try{let n=["clone","--progress"];o&&n.push("--branch",o),n.push(t,e);let a=yo("git",n);a.stderr?.on("data",c=>{let i=c.toString();i.includes("Counting objects")?r(5,"Counting objects"):i.includes("Compressing objects")&&r(10,"Compressing objects");let l=i.match(/Receiving objects:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(l?.[1]){let g=Math.min(100,parseInt(l[1],10)),S=l[2],m=l[3];r(10+Math.floor(g*.5),`Receiving objects: ${S}/${m}`)}let u=i.match(/Resolving deltas:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(u?.[1]){let g=Math.min(100,parseInt(u[1],10)),S=u[2],m=u[3];r(60+Math.floor(g*.4),`Resolving deltas: ${S}/${m}`)}}),await a,r(100,"Clone complete")}catch(n){throw Ve.existsSync(e)&&Ve.rmSync(e,{recursive:!0,force:!0}),n}}import{execSync as xt}from"child_process";import*as B from"fs";import*as Ue from"os";import*as G from"path";var Pe=process.platform==="win32";function we(e){try{return xt(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return null}}function ur(){let e=we("npm config get prefix");return e?Pe?e:G.join(e,"bin"):null}function pr(){let e=we("pnpm bin -g");if(e&&B.existsSync(e))return e;let t=we("pnpm root -g");if(t){let r=G.join(G.dirname(t),"bin");if(B.existsSync(r))return r}return null}function dr(){let e=G.join(Ue.homedir(),".bun","bin");return B.existsSync(e)?e:null}function mr(){let e=we("yarn global bin");return e&&B.existsSync(e)?e:null}function bo(){let e=Pe?"gaia.cmd":"gaia";for(let t of[ur,pr,dr,mr]){let r=t();if(r&&B.existsSync(G.join(r,e)))return r}if(Pe)for(let t of[ur,pr,dr,mr]){let r=t();if(r&&B.existsSync(G.join(r,"gaia")))return r}return null}function Io(){try{return xt(Pe?"where gaia":"command -v gaia",{stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Co(){let e=process.env.SHELL||"",t=Ue.homedir();if(e.includes("zsh"))return G.join(t,".zshrc");if(e.includes("bash")){let r=G.join(t,".bashrc"),o=G.join(t,".bash_profile");return B.existsSync(r)?r:o}return e.includes("fish")?G.join(t,".config","fish","config.fish"):null}function Eo(e,t){try{if((B.existsSync(t)?B.readFileSync(t,"utf-8"):"").includes(e))return!0;let n=t.includes("fish")?`
13
18
  set -gx PATH "${e}" $PATH # Added by GAIA CLI
14
19
  `:`
15
20
  export PATH="${e}:$PATH" # Added by GAIA CLI
16
- `;return M.appendFileSync(t,n),!0}catch{return!1}}function go(e){try{let t=Ae(`powershell -Command "[Environment]::GetEnvironmentVariable('Path', 'User')"`);if(t&&t.includes(e))return!0;ht(`setx PATH "${e};${t||""}"`,{stdio:["pipe","pipe","pipe"]});let o=q.join(je.homedir(),"Documents","PowerShell","Microsoft.PowerShell_profile.ps1"),r=q.dirname(o);return M.existsSync(r)||M.mkdirSync(r,{recursive:!0}),(M.existsSync(o)?M.readFileSync(o,"utf-8"):"").includes(e)||M.appendFileSync(o,`
21
+ `;return B.appendFileSync(t,n),!0}catch{return!1}}function Po(e){try{let t=we(`powershell -Command "[Environment]::GetEnvironmentVariable('Path', 'User')"`);if(t&&t.includes(e))return!0;xt(`setx PATH "${e};${t||""}"`,{stdio:["pipe","pipe","pipe"]});let r=G.join(Ue.homedir(),"Documents","PowerShell","Microsoft.PowerShell_profile.ps1"),o=G.dirname(r);return B.existsSync(o)||B.mkdirSync(o,{recursive:!0}),(B.existsSync(r)?B.readFileSync(r,"utf-8"):"").includes(e)||B.appendFileSync(r,`
17
22
  $env:Path = "${e};" + $env:Path # Added by GAIA CLI
18
- `),!0}catch{return!1}}async function St(){if(po())return{success:!0,message:"gaia command is ready.",inPath:!0,pathAdded:!1};let e=uo();if(!e)return{success:!1,message:"Could not find gaia binary. Run manually: npm install -g @heygaia/cli",inPath:!1,pathAdded:!1};if(ke)return go(e)?{success:!0,message:"Added to PATH. Restart your terminal for the 'gaia' command to be available.",inPath:!1,pathAdded:!0}:{success:!1,message:`Add to your PATH manually: setx PATH "${e};%PATH%"`,inPath:!1,pathAdded:!1};let t=mo();if(!t)return{success:!1,message:`Add to your PATH: export PATH="${e}:$PATH"`,inPath:!1,pathAdded:!1};if(fo(e,t)){let r=q.basename(t);return{success:!0,message:`Added to PATH via ~/${r}. Restart terminal or run: source ~/${r}`,inPath:!1,pathAdded:!0}}return{success:!1,message:`Could not write to ${t}. Add manually: export PATH="${e}:$PATH"`,inPath:!1,pathAdded:!1}}import{execa as te}from"execa";var X={git:"https://git-scm.com/downloads",docker:"https://docs.docker.com/get-docker/",mise:"https://mise.jdx.dev/getting-started.html"},ho={8e3:"API Server",5432:"PostgreSQL",6379:"Redis",27017:"MongoDB",5672:"RabbitMQ",3e3:"Web Frontend",8080:"ChromaDB",8083:"Mongo Express"};async function He(){try{return await te("git",["--version"]),"success"}catch{return"error"}}async function Te(){let e=!1,t=!1,o;try{await te("docker",["--version"]),e=!0}catch{return{name:"Docker",installUrl:X.docker,installed:!1,working:!1,errorMessage:"Docker is not installed"}}try{await te("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:X.docker,installed:e,working:t,errorMessage:o}}async function ve(){try{return await te("mise",["--version"]),"success"}catch{return"missing"}}async function We(){if((await import("node:os")).platform()==="win32")try{return await te("powershell",["-Command","irm https://mise.jdx.dev/install.ps1 | iex"]),!0}catch{return!1}try{return await te("sh",["-c","curl https://mise.jdx.dev/install.sh | sh"]),!0}catch{return!1}}async function Ve(e){let t=await import("node:net"),o=[],r=n=>new Promise(s=>{let c=t.createServer();c.once("error",()=>s(!1)),c.once("listening",()=>{c.close(()=>s(!0))}),c.listen(n)});for(let n of e){let s=ho[n]||`Port ${n}`;if(await r(n))o.push({port:n,service:s,available:!0});else{let a=await So(n),l=await xo(n+1,n+100,r);o.push({port:n,service:s,available:!1,usedBy:a,alternative:l||void 0})}}return o}async function So(e){if((await import("node:os")).platform()==="win32"){try{let{stdout:r}=await te("netstat",["-ano","-p","TCP"]),n=r.trim().split(`
19
- `);for(let s of n)if(s.includes(`:${e}`)&&s.includes("LISTENING")){let c=s.trim().split(/\s+/),a=c[c.length-1];if(a)try{let{stdout:l}=await te("tasklist",["/FI",`PID eq ${a}`,"/FO","CSV","/NH"]);return l.trim().split(",")[0]?.replace(/"/g,"")||`PID ${a}`}catch{return`PID ${a}`}}}catch{}return}try{let{stdout:r}=await te("lsof",["-i",`:${e}`,"-sTCP:LISTEN","-P","-n"]),n=r.trim().split(`
20
- `);if(n.length>1)return n[1]?.split(/\s+/)?.[0]||void 0}catch{}}async function xo(e,t,o){for(let r=e;r<=t;r++)if(await o(r))return r;return null}import*as N from"fs";import*as Q from"path";var yo=e=>new Promise(t=>setTimeout(t,e)),To="dev-start.log";var nr=".gaia-dev.pid";function ir(e){let t=Q.join(e,".env");return N.existsSync(t)?["--env-file",".env"]:[]}async function Be(e,t,o,r,n,s){if(t==="selfhost"){let c=s?.build??!1,a=s?.pull??!1;o?.(c?"Building and starting all services in Docker...":"Starting all services in Docker (selfhost mode)...");let l=Q.join(e,"infra/docker"),p=ir(l),x=r&&Object.keys(r).length>0?xe(r):void 0,T=["compose","-f","docker-compose.selfhost.yml",...p,"up","-d","--remove-orphans"];c&&T.push("--build"),a&&T.push("--pull","always");let y=c?900*1e3:300*1e3;await V("docker",T,l,void 0,n,x,y),o?.("All services started in Docker!")}else{o?.("Starting development servers...");let{spawn:c}=await import("child_process"),a=Q.join(e,To),l=Q.join(e,nr),p=N.openSync(a,"w"),x;try{x=c("mise",["dev"],{cwd:e,stdio:["ignore",p,p],detached:!0,shell:!0}),x.unref()}finally{N.closeSync(p)}if(x.pid!=null&&N.writeFileSync(l,String(x.pid),"utf-8"),await yo(1500),x.pid!=null)try{process.kill(x.pid,0)}catch{throw new Error(`Development servers crashed on startup. Check logs at: ${a}`)}o?.(`Development servers started! Logs: ${a}`)}}async function ar(e,t,o){let r=Q.join(e,"infra/docker"),n=await xt(e);t?.("Stopping Docker services...");try{let s=ir(r),c=n==="selfhost"?["compose","-f","docker-compose.selfhost.yml",...s,"down"]:["compose",...s,"down"];await V("docker",c,r)}catch{}if(n!=="selfhost"){t?.("Stopping local processes...");let s=Q.join(e,nr),c=!1;if(N.existsSync(s)){try{let a=Number.parseInt(N.readFileSync(s,"utf-8").trim(),10);if(!Number.isNaN(a)&&a>0)try{process.kill(-a,"SIGTERM"),c=!0}catch{}}catch{}try{N.unlinkSync(s)}catch{}}if(!c)try{let a=o?.[8e3]??8e3,l=o?.[3e3]??3e3;if(process.platform==="win32")for(let p of[a,l])try{await V("powershell",["-Command",`Get-NetTCPConnection -LocalPort ${p} -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }`],e)}catch{}else for(let p of[a,l])try{await V("sh",["-c",`lsof -ti :${p} -sTCP:LISTEN | xargs kill 2>/dev/null || true`],e)}catch{}}catch{}}t?.("All services stopped.")}async function xt(e){let t=Q.join(e,"apps","api",".env");if(!N.existsSync(t))return null;let o=N.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 V(e,t,o,r,n,s,c){let{spawn:a}=await import("child_process");return new Promise((l,p)=>{let x=a(e,t,{cwd:o,stdio:["ignore","pipe","pipe"],shell:!0,env:s?{...process.env,...s}:void 0}),T="",y=0,S=!1,m;c&&(m=setTimeout(()=>{S=!0,x.kill("SIGTERM"),p(new Error(`Command timed out after ${Math.round(c/6e4)}m. Check \`docker compose logs\` to debug.`))},c)),x.stdout?.on("data",d=>{let h=d.toString();T+=h,n?.(h),y=Math.min(y+5,95),r?.(y)}),x.stderr?.on("data",d=>{let h=d.toString();T+=h,n?.(h),y=Math.min(y+5,95),r?.(y)}),x.on("close",d=>{m&&clearTimeout(m),!S&&(d===0?(r?.(100),l()):p(new Error(`Command failed with code ${d}: ${T.slice(-500)}`)))}),x.on("error",d=>{m&&clearTimeout(m),!S&&p(d)})})}function z(e){let t=e||process.cwd();for(;t!==Q.dirname(t);){if(N.existsSync(Q.join(t,"apps/api/app/config/settings_validator.py")))return t;t=Q.dirname(t)}let o=pt();if(o?.repoPath){if(N.existsSync(Q.join(o.repoPath,"apps/api/app/config/settings_validator.py")))return o.repoPath;console.warn(`Warning: Saved repo path "${o.repoPath}" is no longer a valid GAIA installation. Resetting config.`),De({repoPath:"",setupComplete:!1})}return null}var vo=process.env.GAIA_CLI_DEV==="true",Z=e=>new Promise(t=>setTimeout(t,e));async function cr(e,t){e.setStep("Welcome"),e.setStatus("Waiting for user input..."),await e.waitForInput("welcome");let o=d=>{let h=e.currentState.data.dependencyLogs||[],v=d.split(`
21
- `).filter(C=>C.trim()!==""),I=[...h,...v].slice(-30);e.updateData("dependencyLogs",I)};e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await Z(800),e.setStatus("Checking Git...");let r=await He();e.updateData("checks",{...e.currentState.data.checks,git:r}),e.setStatus("Checking Docker...");let n=await Te(),s=n.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:s}),n.working||e.updateData("dockerError",n.errorMessage),e.setStatus("Checking Mise...");let c=await ve();e.updateData("checks",{...e.currentState.data.checks,mise:c}),c==="missing"&&(e.setStatus("Installing Mise..."),c=await We()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:c}));let a=[];if(r==="error"&&a.push({name:"Git"}),s==="error"&&a.push({name:"Docker",message:n.errorMessage}),a.length>0){let d=[];d.push("Prerequisites failed:");for(let h of a)d.push(` \u2022 ${h.name}: ${h.message||"Not installed or not working"}`);d.push(`
22
- Installation guides:`),r==="error"&&d.push(` \u2022 Git: ${X.git}`),s==="error"&&(n.installed?d.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):d.push(` \u2022 Docker: ${X.docker}`)),e.setError(new Error(d.join(`
23
- `)));return}e.setStatus("Checking Ports...");let p=await Ve([8e3,5432,6379,27017,5672,3e3,8080,8083]),x={},T=p.filter(d=>!d.available);if(T.length>0){let d=T.filter(v=>!v.alternative);if(d.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${d.map(v=>`${v.port} (${v.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",p),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let v of p)!v.available&&v.alternative&&(x[v.port]=v.alternative)}e.updateData("portOverrides",x),e.setStatus("Prerequisites check complete!"),await Z(1e3);let y=await Ge(e),S="";if(vo){if(S=z()||"",!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 Z(500),e.setStatus("Repository ready!")}else{e.setStep("Repository Setup");let d=y==="selfhost"?se.join(sr.homedir(),"gaia"):se.resolve("gaia"),h=!0;for(S=d;;){if(S=await e.waitForInput("repo_path",{default:d}),se.isAbsolute(S)||(S=se.resolve(S)),re.existsSync(S)){if(!re.statSync(S).isDirectory()){e.setError(new Error(`Path ${S} exists and is not a directory.`)),await Z(2e3),e.setError(null);continue}if(re.existsSync(se.join(S,"apps/api/app/config/settings_validator.py"))){e.updateData("existingRepoPath",S);let k=await e.waitForInput("existing_repo");if(k==="use_existing"){h=!1;break}else if(k==="delete_reclone"){e.setStatus("Removing existing installation...");try{re.rmSync(S,{recursive:!0,force:!0})}catch(P){e.setError(new Error(`Failed to remove directory: ${P.message}
24
- Try removing it manually: rm -rf "${S}"`));return}break}else{if(k==="different_path")continue;e.setError(new Error("Setup cancelled by user."));return}}if(re.readdirSync(S).length>0){e.setError(new Error(`Directory ${S} is not empty and is not a GAIA installation. Please choose another path.`)),await Z(2e3),e.setError(null);continue}}break}if(h){e.setStep("Repository Setup"),e.setStatus("Preparing repository..."),e.updateData("repoProgress",0),e.updateData("repoPhase","");try{await zt(S,"https://github.com/theexperiencecompany/gaia.git",(v,I)=>{e.updateData("repoProgress",v),I?(e.updateData("repoPhase",I),e.setStatus(`${I}...`)):e.setStatus(`Cloning repository to ${S}... ${v}%`)},t),e.setStatus("Repository ready!")}catch(v){e.setError(v);return}}else e.setStatus("Using existing repository!")}if(await Z(1e3),await $e(e,S,y,x),e.currentState.error)return;if(y==="selfhost"){e.setStep("Installing CLI"),e.setStatus("Installing gaia CLI globally...");try{await V("npm",["install","-g","@heygaia/cli"],S,void 0,k=>{let P=k.split(`
25
- `).map(be=>be.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(be=>be.length>0);if(P.length===0)return;let de=e.currentState.data.cliInstallLogs||[];e.updateData("cliInstallLogs",[...de,...P].slice(-30))}),e.setStatus("Verifying PATH...");let C=await St();C.inPath?e.setStatus("CLI installed! gaia command is ready."):(C.pathAdded,e.setStatus(C.message))}catch{e.setStatus("CLI install failed. Install manually: npm install -g @heygaia/cli")}await Z(500),e.setStep("Project Setup"),e.setStatus("Building and starting all services in Docker..."),e.updateData("dependencyPhase","Building and starting Docker services..."),e.updateData("dependencyProgress",0),e.updateData("dependencyLogs",[]),e.updateData("dependencyComplete",!1);let d=I=>{let C=I.split(`
26
- `).map(P=>P.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(P=>P.length>0);if(C.length===0)return;let k=e.currentState.data.dependencyLogs||[];e.updateData("dependencyLogs",[...k,...C].slice(-30))},h=!1;try{e.setStatus("Pulling pre-built images from registry..."),await Be(S,"selfhost",I=>e.setStatus(I),x,d,{pull:!0}),h=!0}catch(I){let C=I.message?.split(`
27
- `)[0]??"unknown error";e.setStatus(`Registry pull failed (${C}) \u2014 building images locally (this takes a few minutes)...`)}if(!h)try{await Be(S,"selfhost",I=>e.setStatus(I),x,d,{build:!0})}catch(I){e.setError(new Error(`Failed to start services: ${I.message}`));return}e.updateData("dependencyProgress",100),e.updateData("dependencyComplete",!0);let v=e.currentState.data.envMethod||"manual";Ne({version:Fe,setupComplete:!0,setupMethod:v,repoPath:S,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}),e.updateData("setupMode",y),e.setStep("Finished"),e.setStatus("Setup complete! GAIA is running."),await e.waitForInput("exit");return}if(c==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
28
- \u2022 Mise: ${X.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 V("mise",["trust"],S,void 0,o),e.updateData("dependencyProgress",50),e.updateData("dependencyPhase","Installing tools (node, python, uv, nx)..."),await V("mise",["install"],S,d=>{e.updateData("dependencyProgress",50+d*.5)},o),e.updateData("dependencyProgress",100),e.updateData("toolComplete",!0)}catch(d){e.setError(new Error(`Failed to install tools: ${d.message}`));return}await Z(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(x).length>0?xe(x):void 0;await V("mise",["setup"],S,h=>{e.updateData("dependencyProgress",h)},o,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 Z(1e3);let m=e.currentState.data.envMethod||"manual";Ne({version:Fe,setupComplete:!0,setupMethod:m,repoPath:S,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}),e.setStep("Installing CLI"),e.setStatus("Installing gaia CLI globally...");try{await V("npm",["install","-g","@heygaia/cli"],S,void 0,v=>{let I=v.split(`
29
- `).map(k=>k.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(k=>k.length>0);if(I.length===0)return;let C=e.currentState.data.cliInstallLogs||[];e.updateData("cliInstallLogs",[...C,...I].slice(-30))}),e.setStatus("Verifying PATH...");let h=await St();h.inPath?e.setStatus("CLI installed! gaia command is ready."):(h.pathAdded,e.setStatus(h.message))}catch{e.setStatus("CLI install failed. Install manually: npm install -g @heygaia/cli")}await Z(500),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function lr(e={}){let t=J(),{unmount:o}=bo(Io.createElement(K,{store:t,command:"init"})),r=()=>{o(),process.exit(130)};process.once("SIGINT",r),process.once("SIGTERM",r);try{await cr(t,e.branch)}catch(n){t.setError(n)}finally{process.off("SIGINT",r),process.off("SIGTERM",r)}t.currentState.error&&await t.waitForInput("exit"),o(),process.exit(t.currentState.error?1:0)}import{render as Co}from"ink";import Eo from"react";var Ue=e=>new Promise(t=>setTimeout(t,e));async function ur(e){e.setStep("Detect Repo"),e.setStatus("Looking for GAIA repository...");let t=z();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 Ue(1e3),e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await Ue(500);let o=await He();e.updateData("checks",{...e.currentState.data.checks,git:o});let r=await Te(),n=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:n}),r.working||e.updateData("dockerError",r.errorMessage);let s=await ve();e.updateData("checks",{...e.currentState.data.checks,mise:s}),s==="missing"&&(e.setStatus("Installing Mise..."),s=await We()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:s}));let c=[];if(o==="error"&&c.push({name:"Git"}),n==="error"&&c.push({name:"Docker",message:r.errorMessage}),c.length>0){let m=[];m.push("Prerequisites failed:");for(let d of c)m.push(` \u2022 ${d.name}: ${d.message||"Not installed or not working"}`);m.push(`
30
- Installation guides:`),o==="error"&&m.push(` \u2022 Git: ${X.git}`),n==="error"&&(r.installed?m.push(" \u2022 Docker: Start Docker Desktop or run 'sudo systemctl start docker'"):m.push(` \u2022 Docker: ${X.docker}`)),e.setError(new Error(m.join(`
31
- `)));return}e.setStatus("Checking Ports...");let l=await Ve([8e3,5432,6379,27017,5672,3e3,8080,8083]),p={},x=l.filter(m=>!m.available);if(x.length>0){let m=x.filter(h=>!h.alternative);if(m.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${m.map(h=>`${h.port} (${h.service})`).join(", ")}. Free these ports and try again.`));return}if(e.updateData("portConflicts",l),await e.waitForInput("port_conflicts")==="abort"){e.setError(new Error("Port conflicts not resolved. Please free the ports and try again."));return}for(let h of l)!h.available&&h.alternative&&(p[h.port]=h.alternative)}e.updateData("portOverrides",p),e.setStatus("Prerequisites check complete!"),await Ue(1e3);let T=await Ge(e);if(await $e(e,t,T,p),e.currentState.error)return;if(T==="selfhost"){let m=e.currentState.data.envMethod||"manual";De({setupComplete:!0,setupMethod:m,repoPath:t}),e.setStep("Finished"),e.setStatus("Setup complete! Run 'gaia start' to build and start all services in Docker."),await e.waitForInput("exit");return}if(s==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
32
- \u2022 Mise: ${X.mise}`));return}e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("dependencyLogs",[]);let y=m=>{let d=e.currentState.data.dependencyLogs||[],h=m.split(`
33
- `).filter(I=>I.trim()!==""),v=[...d,...h].slice(-30);e.updateData("dependencyLogs",v)};try{e.updateData("dependencyPhase","Trusting mise configuration..."),await V("mise",["trust"],t,void 0,y),e.updateData("dependencyProgress",20),e.updateData("dependencyPhase","Installing tools..."),await V("mise",["install"],t,d=>{e.updateData("dependencyProgress",20+d*.3)},y),e.updateData("dependencyPhase","Running mise setup...");let m=Object.keys(p).length>0?xe(p):void 0;await V("mise",["setup"],t,d=>{e.updateData("dependencyProgress",50+d*.5)},y,m),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(m){e.setError(new Error(`Failed to setup project: ${m.message}`));return}await Ue(1e3);let S=e.currentState.data.envMethod||"manual";De({setupComplete:!0,setupMethod:S,repoPath:t}),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function pr(){let e=J(),{unmount:t}=Co(Eo.createElement(K,{store:e,command:"setup"})),o=()=>{t(),process.exit(130)};process.once("SIGINT",o),process.once("SIGTERM",o);try{await ur(e)}catch(r){e.setError(r)}finally{process.off("SIGINT",o),process.off("SIGTERM",o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as wo}from"ink";import Po from"react";async function dr(e,t){e.setStep("Starting"),e.setStatus("Locating GAIA repository...");let o=z();if(!o){e.setError(new Error("Could not find GAIA repository. Run from within a cloned gaia repo."));return}e.updateData("repoPath",o);let r=await xt(o);if(!r){e.setError(new Error("No .env file found. Run 'gaia init' for fresh setup, or 'gaia setup' to configure an existing repo."));return}if(r==="selfhost"){e.setStatus("Checking Docker...");let l=await Te();if(!l.working){e.setError(new Error(l.errorMessage||`Docker is not running. Please start Docker and try again.
34
- ${X.docker}`));return}}else{e.setStatus("Checking Mise...");let l=await ve();if(l==="missing"||l==="error"){e.setError(new Error(`Developer mode requires Mise but it is not installed.
35
- Install: ${X.mise}`));return}}let n=ye(o),s=n[3e3]??3e3,c=n[8e3]??8e3;e.updateData("setupMode",r),e.updateData("webPort",s),e.updateData("apiPort",c),e.updateData("dockerLogs",[]),e.setStatus(`Starting GAIA in ${r} mode...`);let a=l=>{let p=l.split(`
36
- `).map(T=>T.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(T=>T.length>0);if(p.length===0)return;let x=e.currentState.data.dockerLogs||[];e.updateData("dockerLogs",[...x,...p].slice(-30))};try{await Be(o,r,l=>{e.setStatus(l)},n,a,t),e.setStep("Running"),e.setStatus("GAIA is running!"),e.updateData("started",!0)}catch(l){e.setError(new Error(`Failed to start services: ${l.message}`));return}await e.waitForInput("exit")}async function mr(e){let t=J(),{unmount:o}=wo(Po.createElement(K,{store:t,command:"start"})),r=()=>{o(),process.exit(130)};process.once("SIGINT",r),process.once("SIGTERM",r),await new Promise(n=>setTimeout(n,50));try{await dr(t,e)}catch(n){t.setError(n)}finally{process.off("SIGINT",r),process.off("SIGTERM",r)}t.currentState.error&&await t.waitForInput("exit"),o(),process.exit(t.currentState.error?1:0)}import{render as Bo}from"ink";import _o from"react";import{execa as Tt}from"execa";var yt=["gaia-backend","gaia-web","chromadb","postgres","redis","mongo","rabbitmq","arq_worker"];async function fr(){try{let{stdout:e}=await Tt("docker",["inspect","--format","{{.Name}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",...yt]),t=new Map;for(let o of e.trim().split(`
37
- `)){if(!o)continue;let[r,n,s]=o.split("|"),c=r?.replace(/^\//,"")??"";t.set(c,{name:c,status:n==="running"?"running":"stopped",health:s!=="none"?s:void 0})}return yt.map(o=>t.get(o)??{name:o,status:"not_found"})}catch{let e=yt.map(async t=>{try{let{stdout:o}=await Tt("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 gr(){try{return await Tt("docker",["info"]),!0}catch{return!1}}var Ro=[{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 hr(e){let o=Ro.map(r=>({...r,port:e?.[r.port]??r.port})).map(r=>r.type==="http"?Do(r.name,r.port,r.path):ko(r.name,r.port));return Promise.all(o)}async function Do(e,t,o){let r=Date.now();try{let n=await fetch(`http://localhost:${t}${o}`,{signal:AbortSignal.timeout(5e3)}),s=Date.now()-r;return{name:e,port:t,status:n.ok?"up":"down",latency:s,details:n.ok?`HTTP ${n.status}`:`HTTP ${n.status} (error)`}}catch{return{name:e,port:t,status:"down",details:"Connection failed"}}}async function ko(e,t){let o=await import("node:net"),r=Date.now();return new Promise(n=>{let s=new o.Socket;s.setTimeout(3e3),s.on("connect",()=>{let c=Date.now()-r;s.destroy(),n({name:e,port:t,status:"up",latency:c})}),s.on("timeout",()=>{s.destroy(),n({name:e,port:t,status:"down"})}),s.on("error",()=>{s.destroy(),n({name:e,port:t,status:"down"})}),s.connect(t,"localhost")})}async function Sr(){return await gr()?{running:!0,containers:await fr()}:{running:!1,containers:[]}}async function Ao(e){e.setStep("Checking"),e.setStatus("Checking service health..."),e.updateData("refreshable",!1);let t=z(),o=t?ye(t):void 0,[r,n]=await Promise.all([hr(o),Sr()]);e.updateData("services",r),e.updateData("docker",n);let s=r.filter(a=>a.status==="up").length,c=r.length;e.setStep("Results"),e.setStatus(`${s}/${c} services running`),e.updateData("refreshable",!0)}async function xr(e){for(;await Ao(e),await e.waitForInput("exit_or_refresh")==="refresh";);}async function yr(){let e=J(),{unmount:t}=Bo(_o.createElement(K,{store:e,command:"status"}));await new Promise(o=>setTimeout(o,50));try{await xr(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Lo}from"ink";import Oo from"react";async function Tr(e){e.setStep("Stopping"),e.setStatus("Locating GAIA repository...");let t=z();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=ye(t);try{await ar(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 vr(){let e=J(),{unmount:t}=Lo(Oo.createElement(K,{store:e,command:"stop"})),o=()=>{t(),process.exit(130)};process.once("SIGINT",o),process.once("SIGTERM",o),await new Promise(r=>setTimeout(r,50));try{await Tr(e)}catch(r){e.setError(r)}finally{process.off("SIGINT",o),process.off("SIGTERM",o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}var ce=new Mo;ce.name("gaia").description("CLI tool for setting up and managing GAIA").version("0.1.0");ce.command("init").description("Full setup from scratch (clone, configure, start)").option("--branch <branch>","Git branch to clone").action(async e=>{await lr({branch:e.branch})});ce.command("setup").description("Configure an existing GAIA repository").action(async()=>{await pr()});ce.command("status").description("Check health of all GAIA services").action(async()=>{await yr()});ce.command("start").description("Start GAIA services").option("-b, --build","Rebuild Docker images before starting").option("--pull","Pull latest base images before starting").action(async e=>{await mr({build:e.build,pull:e.pull})});ce.command("stop").description("Stop all GAIA services").action(async()=>{await vr()});process.argv.slice(2).length||(ce.outputHelp(),process.exit(0));ce.parse();
23
+ `),!0}catch{return!1}}async function yt(){if(Io())return{success:!0,message:"gaia command is ready.",inPath:!0,pathAdded:!1};let e=bo();if(!e)return{success:!1,message:"Could not find gaia binary. Run manually: npm install -g @heygaia/cli",inPath:!1,pathAdded:!1};if(Pe)return Po(e)?{success:!0,message:"Added to PATH. Restart your terminal for the 'gaia' command to be available.",inPath:!1,pathAdded:!0}:{success:!1,message:`Add to your PATH manually: setx PATH "${e};%PATH%"`,inPath:!1,pathAdded:!1};let t=Co();if(!t)return{success:!1,message:`Add to your PATH: export PATH="${e}:$PATH"`,inPath:!1,pathAdded:!1};if(Eo(e,t)){let o=G.basename(t);return{success:!0,message:`Added to PATH via ~/${o}. Restart terminal or run: source ~/${o}`,inPath:!1,pathAdded:!0}}return{success:!1,message:`Could not write to ${t}. Add manually: export PATH="${e}:$PATH"`,inPath:!1,pathAdded:!1}}var wo=process.env.GAIA_CLI_DEV==="true",Tt=new RegExp("\x1B\\[[0-9;]*m","g");async function gr(e,t){e.setStep("Welcome"),e.setStatus("Waiting for user input..."),await e.waitForInput("welcome");let r=He(e);e.setStep("Prerequisites"),e.setStatus("Checking system requirements...");let o=await je(e);if(!o)return;let{miseStatus:n}=o,a=await We(e);if(a===null)return;let c=await Ne(e),i="";if(wo){if(i=Z()||"",!i){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 W(500),e.setStatus("Repository ready!")}else{e.setStep("Repository Setup");let u=c==="selfhost"?ae.join(fr.homedir(),"gaia"):ae.resolve("gaia"),g=!0;for(i=u;;){if(i=await e.waitForInput("repo_path",{default:u}),ae.isAbsolute(i)||(i=ae.resolve(i)),oe.existsSync(i)){if(!oe.statSync(i).isDirectory()){e.setError(new Error(`Path ${i} exists and is not a directory.`)),await W(2e3),e.setError(null);continue}if(oe.existsSync(ae.join(i,"apps/api/app/config/settings_validator.py"))){e.updateData("existingRepoPath",i);let f=await e.waitForInput("existing_repo");if(f==="use_existing"){g=!1;break}else if(f==="delete_reclone"){e.setStatus("Removing existing installation...");try{oe.rmSync(i,{recursive:!0,force:!0})}catch(y){e.setError(new Error(`Failed to remove directory: ${y.message}
24
+ Try removing it manually: rm -rf "${i}"`));return}break}else{if(f==="different_path")continue;e.setError(new Error("Setup cancelled by user."));return}}if(oe.readdirSync(i).length>0){e.setError(new Error(`Directory ${i} is not empty and is not a GAIA installation. Please choose another path.`)),await W(2e3),e.setError(null);continue}}break}if(g){e.setStep("Repository Setup"),e.setStatus("Preparing repository..."),e.updateData("repoProgress",0),e.updateData("repoPhase","");try{await lr(i,"https://github.com/theexperiencecompany/gaia.git",(S,m)=>{e.updateData("repoProgress",S),m?(e.updateData("repoPhase",m),e.setStatus(`${m}...`)):e.setStatus(`Cloning repository to ${i}... ${S}%`)},t),e.setStatus("Repository ready!")}catch(S){e.setError(S);return}}else e.setStatus("Using existing repository!")}if(await W(1e3),await Ge(e,i,c,a),e.currentState.error)return;if(c==="selfhost"){e.setStep("Installing CLI"),e.setStatus("Installing gaia CLI globally...");try{await j("npm",["install","-g","@heygaia/cli"],i,void 0,f=>{let y=f.split(`
25
+ `).map(b=>b.replace(Tt,"").trim()).filter(b=>b.length>0);if(y.length===0)return;let v=e.currentState.data.cliInstallLogs||[];e.updateData("cliInstallLogs",[...v,...y].slice(-30))}),e.setStatus("Verifying PATH...");let x=await yt();x.inPath?e.setStatus("CLI installed! gaia command is ready."):(x.pathAdded,e.setStatus(x.message))}catch{e.setStatus("CLI install failed. Install manually: npm install -g @heygaia/cli")}await W(500),e.setStep("Project Setup"),e.setStatus("Building and starting all services in Docker..."),e.updateData("dependencyPhase","Building and starting Docker services..."),e.updateData("dependencyProgress",0),e.updateData("dependencyLogs",[]),e.updateData("dependencyComplete",!1);let u=m=>{let x=m.split(`
26
+ `).map(y=>y.replace(Tt,"").trim()).filter(y=>y.length>0);if(x.length===0)return;let f=e.currentState.data.dependencyLogs||[];e.updateData("dependencyLogs",[...f,...x].slice(-30))},g=!1;try{e.setStatus("Pulling pre-built images from registry..."),await Ee(i,"selfhost",m=>e.setStatus(m),a,u,{pull:!0}),g=!0}catch(m){let x=m.message?.split(`
27
+ `)[0]??"unknown error";e.setStatus(`Registry pull failed (${x}) \u2014 building images locally (this takes a few minutes)...`)}if(!g)try{await Ee(i,"selfhost",m=>e.setStatus(m),a,u,{build:!0})}catch(m){e.setError(new Error(`Failed to start services: ${m.message}`));return}e.updateData("dependencyProgress",100),e.updateData("dependencyComplete",!0);let S=e.currentState.data.envMethod||"manual";Fe({version:Me,setupComplete:!0,setupMethod:S,repoPath:i,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}),e.updateData("setupMode",c),e.setStep("Finished"),e.setStatus("Setup complete! GAIA is running."),await e.waitForInput("exit");return}if(n==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
28
+ \u2022 Mise: ${Y.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 j("mise",["trust"],i,void 0,r),e.updateData("dependencyProgress",50),e.updateData("dependencyPhase","Installing tools (node, python, uv, nx)..."),await j("mise",["install"],i,u=>{e.updateData("dependencyProgress",50+u*.5)},r),e.updateData("dependencyProgress",100),e.updateData("toolComplete",!0)}catch(u){e.setError(new Error(`Failed to install tools: ${u.message}`));return}await W(1e3),e.setStep("Project Setup"),e.updateData("dependencyPhase","Setting up project..."),e.updateData("dependencyProgress",0),e.updateData("dependencyComplete",!1),e.updateData("repoPath",i),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyProgress",0),e.updateData("dependencyPhase","Running mise setup (all dependencies)...");let u=Object.keys(a).length>0?he(a):void 0;await j("mise",["setup"],i,g=>{e.updateData("dependencyProgress",g)},r,u),e.updateData("dependencyProgress",100),e.updateData("dependencyPhase","Setup complete!"),e.updateData("dependencyComplete",!0)}catch(u){e.setError(new Error(`Failed to setup project: ${u.message}`));return}await W(1e3);let l=e.currentState.data.envMethod||"manual";Fe({version:Me,setupComplete:!0,setupMethod:l,repoPath:i,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}),e.setStep("Installing CLI"),e.setStatus("Installing gaia CLI globally...");try{await j("npm",["install","-g","@heygaia/cli"],i,void 0,S=>{let m=S.split(`
29
+ `).map(f=>f.replace(Tt,"").trim()).filter(f=>f.length>0);if(m.length===0)return;let x=e.currentState.data.cliInstallLogs||[];e.updateData("cliInstallLogs",[...x,...m].slice(-30))}),e.setStatus("Verifying PATH...");let g=await yt();g.inPath?e.setStatus("CLI installed! gaia command is ready."):(g.pathAdded,e.setStatus(g.message))}catch{e.setStatus("CLI install failed. Install manually: npm install -g @heygaia/cli")}await W(500),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function hr(e={}){let t=z(),{unmount:r}=Ro(Do.createElement(J,{store:t,command:"init"})),o=()=>{r(),process.exit(130)};process.once("SIGINT",o),process.once("SIGTERM",o);try{await gr(t,e.branch)}catch(n){t.setError(n)}finally{process.off("SIGINT",o),process.off("SIGTERM",o)}t.currentState.error&&await t.waitForInput("exit"),r(),process.exit(t.currentState.error?1:0)}import{render as Ao}from"ink";import ko from"react";async function Sr(e){e.setStep("Detect Repo"),e.setStatus("Looking for GAIA repository...");let t=Z();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 W(1e3),e.setStep("Prerequisites"),e.setStatus("Checking system requirements...");let r=await je(e);if(!r)return;let{miseStatus:o}=r,n=await We(e);if(n===null)return;let a=await Ne(e);if(await Ge(e,t,a,n),e.currentState.error)return;if(a==="selfhost"){let u=e.currentState.data.envMethod||"manual";Ce({setupComplete:!0,setupMethod:u,repoPath:t}),e.setStep("Finished"),e.setStatus("Setup complete! Run 'gaia start' to build and start all services in Docker."),await e.waitForInput("exit");return}if(o==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
30
+ \u2022 Mise: ${Y.mise}`));return}let c=He(e);if(!await cr(e,t,n,c))return;await W(1e3);let l=e.currentState.data.envMethod||"manual";Ce({setupComplete:!0,setupMethod:l,repoPath:t}),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function xr(){let e=z(),{unmount:t}=Ao(ko.createElement(J,{store:e,command:"setup"})),r=()=>{t(),process.exit(130)};process.once("SIGINT",r),process.once("SIGTERM",r);try{await Sr(e)}catch(o){e.setError(o)}finally{process.off("SIGINT",r),process.off("SIGTERM",r)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Bo}from"ink";import Oo from"react";var _o=new RegExp("\x1B\\[[0-9;]*m","g");async function yr(e,t){e.setStep("Starting"),e.setStatus("Locating GAIA repository...");let r=Z();if(!r){e.setError(new Error("Could not find GAIA repository. Run from within a cloned gaia repo."));return}e.updateData("repoPath",r);let o=await St(r);if(!o){e.setError(new Error("No .env file found. Run 'gaia init' for fresh setup, or 'gaia setup' to configure an existing repo."));return}if(o==="selfhost"){e.setStatus("Checking Docker...");let l=await $e();if(!l.working){e.setError(new Error(l.errorMessage||`Docker is not running. Please start Docker and try again.
31
+ ${Y.docker}`));return}}else{e.setStatus("Checking Mise...");let l=await qe();if(l==="missing"||l==="error"){e.setError(new Error(`Developer mode requires Mise but it is not installed.
32
+ Install: ${Y.mise}`));return}}let n=Se(r),a=n[3e3]??3e3,c=n[8e3]??8e3;e.updateData("setupMode",o),e.updateData("webPort",a),e.updateData("apiPort",c),e.updateData("dockerLogs",[]),e.setStatus(`Starting GAIA in ${o} mode...`);let i=l=>{let u=l.split(`
33
+ `).map(S=>S.replace(_o,"").trim()).filter(S=>S.length>0);if(u.length===0)return;let g=e.currentState.data.dockerLogs||[];e.updateData("dockerLogs",[...g,...u].slice(-30))};try{await Ee(r,o,l=>{e.setStatus(l)},n,i,t),e.setStep("Running"),e.setStatus("GAIA is running!"),e.updateData("started",!0)}catch(l){e.setError(new Error(`Failed to start services: ${l.message}`));return}await e.waitForInput("exit")}async function Tr(e){let t=z(),{unmount:r}=Bo(Oo.createElement(J,{store:t,command:"start"})),o=()=>{r(),process.exit(130)};process.once("SIGINT",o),process.once("SIGTERM",o),await new Promise(n=>setTimeout(n,50));try{await yr(t,e)}catch(n){t.setError(n)}finally{process.off("SIGINT",o),process.off("SIGTERM",o)}t.currentState.error&&await t.waitForInput("exit"),r(),process.exit(t.currentState.error?1:0)}import{render as Go}from"ink";import $o from"react";import{execa as bt}from"execa";var vt=["gaia-backend","gaia-web","chromadb","postgres","redis","mongo","rabbitmq","arq_worker"];async function vr(){try{let{stdout:e}=await bt("docker",["inspect","--format","{{.Name}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",...vt]),t=new Map;for(let r of e.trim().split(`
34
+ `)){if(!r)continue;let[o,n,a]=r.split("|"),c=o?.replace(/^\//,"")??"";t.set(c,{name:c,status:n==="running"?"running":"stopped",health:a!=="none"?a:void 0})}return vt.map(r=>t.get(r)??{name:r,status:"not_found"})}catch{let e=vt.map(async t=>{try{let{stdout:r}=await bt("docker",["inspect","--format","{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",t]),[o,n]=r.trim().split("|");return{name:t,status:o==="running"?"running":"stopped",health:n!=="none"?n:void 0}}catch{return{name:t,status:"not_found"}}});return Promise.all(e)}}async function br(){try{return await bt("docker",["info"]),!0}catch{return!1}}var Lo=[{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 Ir(e){let r=Lo.map(o=>({...o,port:e?.[o.port]??o.port})).map(o=>o.type==="http"?Mo(o.name,o.port,o.path):Fo(o.name,o.port));return Promise.all(r)}async function Mo(e,t,r){let o=Date.now();try{let n=await fetch(`http://localhost:${t}${r}`,{signal:AbortSignal.timeout(5e3)}),a=Date.now()-o;return{name:e,port:t,status:n.ok?"up":"down",latency:a,details:n.ok?`HTTP ${n.status}`:`HTTP ${n.status} (error)`}}catch{return{name:e,port:t,status:"down",details:"Connection failed"}}}async function Fo(e,t){let r=await import("node:net"),o=Date.now();return new Promise(n=>{let a=new r.Socket;a.setTimeout(3e3),a.on("connect",()=>{let c=Date.now()-o;a.destroy(),n({name:e,port:t,status:"up",latency:c})}),a.on("timeout",()=>{a.destroy(),n({name:e,port:t,status:"down"})}),a.on("error",()=>{a.destroy(),n({name:e,port:t,status:"down"})}),a.connect(t,"localhost")})}async function Cr(){return await br()?{running:!0,containers:await vr()}:{running:!1,containers:[]}}async function No(e){e.setStep("Checking"),e.setStatus("Checking service health..."),e.updateData("refreshable",!1);let t=Z(),r=t?Se(t):void 0,[o,n]=await Promise.all([Ir(r),Cr()]);e.updateData("services",o),e.updateData("docker",n);let a=o.filter(i=>i.status==="up").length,c=o.length;e.setStep("Results"),e.setStatus(`${a}/${c} services running`),e.updateData("refreshable",!0)}async function Er(e){for(;await No(e),await e.waitForInput("exit_or_refresh")==="refresh";);}async function Pr(){let e=z(),{unmount:t}=Go($o.createElement(J,{store:e,command:"status"}));await new Promise(r=>setTimeout(r,50));try{await Er(e)}catch(r){e.setError(r)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as qo}from"ink";import Ho from"react";async function wr(e){e.setStep("Stopping"),e.setStatus("Locating GAIA repository...");let t=Z();if(!t){e.setError(new Error("Could not find GAIA repository. Run from within a cloned gaia repo."));return}e.updateData("repoPath",t);let r=Se(t);try{await sr(t,o=>{e.setStatus(o)},r),e.setStep("Stopped"),e.setStatus("All services stopped."),e.updateData("stopped",!0)}catch(o){e.setError(new Error(`Failed to stop services: ${o.message}`));return}await e.waitForInput("exit")}async function Rr(){let e=z(),{unmount:t}=qo(Ho.createElement(J,{store:e,command:"stop"})),r=()=>{t(),process.exit(130)};process.once("SIGINT",r),process.once("SIGTERM",r),await new Promise(o=>setTimeout(o,50));try{await wr(e)}catch(o){e.setError(o)}finally{process.off("SIGINT",r),process.off("SIGTERM",r)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}var se=new jo;se.name("gaia").description("CLI tool for setting up and managing GAIA").version("0.1.0");se.command("init").description("Full setup from scratch (clone, configure, start)").option("--branch <branch>","Git branch to clone").action(async e=>{await hr({branch:e.branch})});se.command("setup").description("Configure an existing GAIA repository").action(async()=>{await xr()});se.command("status").description("Check health of all GAIA services").action(async()=>{await Pr()});se.command("start").description("Start GAIA services").option("-b, --build","Rebuild Docker images before starting").option("--pull","Pull latest base images before starting").action(async e=>{await Tr({build:e.build,pull:e.pull})});se.command("stop").description("Stop all GAIA services").action(async()=>{await Rr()});process.argv.slice(2).length||(se.outputHelp(),process.exit(0));se.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heygaia/cli",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "CLI tool for setting up and managing GAIA",
5
5
  "type": "module",
6
6
  "bin": {