@heygaia/cli 0.1.13 → 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 -27
  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,35 +1,34 @@
1
1
  #!/usr/bin/env node
2
- import{Command as Lo}from"commander";import{render as To}from"ink";import bo from"react";import{Box as Le,Text as ue}from"ink";import Qr from"react";import{ProgressBar as Ct,Select as Qe,Spinner as Xe}from"@inkjs/ui";import{Box as f,Text as u,useInput as ie}from"ink";import Ee from"ink-text-input";import{useEffect as Pe,useRef as Br,useState as H}from"react";import{Box as Ie,Text as Be}from"ink";var b="#00bbff";import{Box as br,Text as Ir}from"ink";import{jsx as Tt}from"react/jsx-runtime";var bt=({status:e,step:t})=>t.toLowerCase()==="welcome"?null:Tt(br,{width:"100%",paddingX:1,marginTop:1,children:Tt(Ir,{color:"gray",dimColor:!0,children:e})});import{Box as Cr}from"ink";import Er from"ink-big-text";import Pr from"ink-gradient";import{jsx as Ue}from"react/jsx-runtime";var me=()=>Ue(Cr,{flexDirection:"column",marginTop:1,marginBottom:1,children:Ue(Pr,{colors:[b,"#b0eaff",b],children:Ue(Er,{text:"GAIA",font:"3d"})})});import{jsx as ce,jsxs as Ce}from"react/jsx-runtime";var wr=["Welcome","Prerequisites","Setup Mode","Repository Setup","Environment Setup","Install Tools","Project Setup","Installing CLI","Finished"],It=["Detect Repo","Prerequisites","Environment Setup","Project Setup","Finished"],Rr={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"},Dr=({currentStep:e,steps:t})=>{let o=t.indexOf(e);return ce(Ie,{marginBottom:1,flexWrap:"nowrap",children:t.map((r,n)=>{let s=n<o,l=n===o,a=Rr[r]??r;return Ce(Ie,{flexShrink:0,children:[n>0&&Ce(Be,{color:"gray",dimColor:!0,children:[" ","\xB7"," "]}),s&&Ce(Be,{color:"green",children:["\u2713 ",a]}),l&&ce(Be,{color:b,bold:!0,children:a}),!s&&!l&&ce(Be,{color:"gray",dimColor:!0,children:a})]},r)})})},_e=({children:e,status:t,step:o,steps:r=wr})=>Ce(Ie,{flexDirection:"column",height:"100%",width:"100%",children:[Ce(Ie,{flexGrow:1,flexDirection:"column",children:[ce(me,{}),ce(Dr,{currentStep:o,steps:r}),ce(Ie,{flexDirection:"column",flexGrow:1,children:e})]}),ce(bt,{status:t,step:o})]});import{Spinner as kr}from"@inkjs/ui";import{Box as oe,Text as U,useInput as Ar}from"ink";import{jsx as j,jsxs as le}from"react/jsx-runtime";var ne=({label:e,status:t})=>le(oe,{children:[j(oe,{marginRight:1,children:t==="pending"?j(kr,{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})=>{Ar((n,s)=>{s.return?t():s.escape&&o()});let r=e.filter(n=>!n.available);return le(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=>le(oe,{children:[le(U,{color:n.available?"green":n.alternative?"yellow":"red",children:[n.available?"\u2714":n.alternative?"\u26A0":"\u2716"," "]}),le(U,{children:[n.service," (:",n.port,")"]}),!n.available&&le(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:le(U,{dimColor:!0,children:[j(U,{bold:!0,children:"Enter"})," continue \xB7 ",j(U,{bold:!0,children:"ESC"})," abort"]})})]})};import{Fragment as pn,jsx as i,jsxs as g}from"react/jsx-runtime";var _r=({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(Ee,{value:o,onChange:r,onSubmit:t})]})]})},Lr=({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(Qe,{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)})})]}),Mr=({setupMode:e,portOverrides:t,onConfirm:o})=>{ie((s,l)=>{l.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"]})})]})},Fr=8,Et=({logs:e,height:t=Fr})=>{let[o,r]=H(0),n=Br(e.length);Pe(()=>{e.length!==n.current&&(n.current=e.length,r(0))},[e.length]),ie((v,y)=>{y.upArrow?r(x=>Math.min(x+1,Math.max(0,e.length-t))):y.downArrow&&r(x=>Math.max(0,x-1))});let s=e.length,l=Math.max(0,s-t-o),a=Math.max(0,s-o),c=e.slice(l,a),p=l,S=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:c.map((v,y)=>i(u,{color:"gray",wrap:"truncate",children:v},l+y))}),S>0?g(u,{color:"gray",dimColor:!0,children:["\u2193 ",S," more line",S!==1?"s":""]}):i(u,{color:"gray",dimColor:!0,children:"\u2191\u2193 scroll"})]})},Nr=({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(Xe,{label:e||"Preparing..."})}),!o&&t>0&&i(f,{width:50,children:i(Ct,{value:t})}),!o&&r&&r.length>0&&i(Et,{logs:r}),!o&&i(f,{marginTop:1,children:i(u,{color:"gray",dimColor:!0,children:"This may take a few minutes..."})})]})]});var Ye=({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(Qe,{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)})})]}),Ke=({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(Qe,{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)"})]})]}),Je=({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,l]=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,S)=>{if(S.tab||S.downArrow)n(v=>v<a.length-1?v+1:v);else if(S.upArrow)n(v=>v>0?v-1:v);else if(S.return){if(r<a.length-1){n(y=>y+1);return}let v=a.filter(y=>!t[y.key].trim());if(v.length>0){l(`Required: ${v.map(x=>x.key).join(", ")}`);let y=a.findIndex(x=>!t[x.key].trim());y>=0&&n(y);return}e(t)}});let c=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,S)=>{let v=p.key.includes("SECRET")||p.key.includes("TOKEN");return g(f,{flexDirection:"column",marginBottom:1,children:[i(f,{children:g(u,{color:S===r?b:"white",children:[S===r?"\u25B8 ":" ",p.key,":"]})}),i(f,{marginLeft:2,children:i(u,{color:"gray",dimColor:!0,children:p.description})}),S===r?i(f,{marginLeft:2,children:i(Ee,{value:t[p.key],onChange:y=>{o(x=>({...x,[p.key]:y})),l(null)},placeholder:"Enter value...",mask:v?"*":void 0})}):i(f,{marginLeft:2,children:i(u,{color:t[p.key]?"green":"gray",children:t[p.key]?v?`\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"]})})]})},ze=({category:e,currentIndex:t,totalGroups:o,onSubmit:r})=>{let[n,s]=H(()=>{let y={};for(let x of e.variables)y[x.name]=x.defaultValue||"";return y}),[l,a]=H(0),[c,p]=H(null);Pe(()=>{let y={};for(let x of e.variables)y[x.name]=x.defaultValue||"";s(y),a(0),p(null)},[e.name]),ie((y,x)=>{if(x.tab||x.downArrow)a(m=>m<e.variables.length-1?m+1:m);else if(x.upArrow)a(m=>m>0?m-1:m);else if(x.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 S=()=>{if(l<e.variables.length-1)a(l+1);else{let y=e.variables.filter(x=>x.required&&!n[x.name]?.trim());if(y.length>0){p(`Required fields are missing: ${y.map(x=>x.name).join(", ")}`);return}p(null),r(n)}},v=e.variables.some(y=>y.required);return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:c?"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,x)=>{let m=x===l,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(Ee,{value:n[y.name]||"",onChange:h=>{s(T=>({...T,[y.name]:h})),c&&p(null)},onSubmit:S,placeholder:d?`Default: ${y.defaultValue}`:y.required?"Enter a value (required)":"Press Enter to skip"})})]},y.name)})}),c&&i(f,{marginTop:1,children:g(u,{color:"red",bold:!0,children:["\u26A0 ",c]})}),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",!v&&g(u,{children:[" ","\xB7 ",i(u,{bold:!0,children:"ESC"})," skip"]})]})})]})},Ze=({alternatives:e,onSubmit:t})=>{let[o,r]=H(new Set),[n,s]=H({}),[l,a]=H(0),[c,p]=H(null);Pe(()=>{let h={};for(let T of e)for(let I of T.variables)h[I.name]=I.defaultValue||"";s(h)},[e]);let S=[];for(let h=0;h<e.length;h++)if(S.push({type:"provider",categoryIndex:h}),o.has(h)){let T=e[h];if(T)for(let I=0;I<T.variables.length;I++)S.push({type:"field",categoryIndex:h,fieldIndex:I})}S.push({type:"submit"});let v=S[l],y=v?.type==="field",x=v?.type==="submit";ie((h,T)=>{let I=Math.min(l,S.length-1);if(I!==l){a(I);return}if(y)T.upArrow?a(C=>Math.max(0,C-1)):(T.downArrow||T.tab)&&a(C=>Math.min(S.length-1,C+1));else if(x)T.upArrow?a(C=>Math.max(0,C-1)):(T.return||h===" ")&&d();else if(T.upArrow)a(C=>Math.max(0,C-1));else if(T.downArrow||T.tab)a(C=>Math.min(S.length-1,C+1));else if((T.return||h===" ")&&v?.type==="provider"){let C=v.categoryIndex;r(k=>{let R=new Set(k);return R.has(C)?R.delete(C):R.add(C),R}),c&&p(null)}});let m=()=>{c&&p(null),a(h=>Math.min(S.length-1,h+1))},d=()=>{let h=[],T={};for(let I of o){let C=e[I];if(!C)continue;if(C.variables.some(R=>n[R.name]?.trim())){h.push(C.name);for(let R of C.variables){let pe=n[R.name];pe&&(T[R.name]=pe)}}}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,T)};return g(f,{flexDirection:"column",marginTop:1,paddingX:1,borderStyle:"round",borderColor:c?"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,T)=>{let I=o.has(T),C=S.findIndex(R=>R.type==="provider"&&R.categoryIndex===T),k=l===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((R,pe)=>{let Te=S.findIndex(be=>be.type==="field"&&be.categoryIndex===T&&be.fieldIndex===pe),de=l===Te,vt=!!R.defaultValue,Ve=n[R.name]||"";return g(f,{flexDirection:"column",marginBottom:1,children:[g(f,{children:[g(u,{color:de?b:"gray",bold:de,children:[de?" \u279C ":" ",R.name]}),!de&&Ve&&i(u,{color:"green",children:" \u2713"}),!de&&!Ve&&vt&&g(u,{color:"gray",dimColor:!0,children:[" ","(default: ",R.defaultValue,")"]})]}),de&&i(f,{marginLeft:4,children:i(Ee,{value:Ve,onChange:be=>{s(Tr=>({...Tr,[R.name]:be})),c&&p(null)},onSubmit:m,placeholder:vt?`Default: ${R.defaultValue}`:"Enter value..."})})]},R.name)})})]},h.name)})}),c&&i(f,{marginTop:1,children:g(u,{color:"red",bold:!0,children:["\u26A0 ",c]})}),g(f,{marginTop:1,children:[i(u,{color:x?b:void 0,bold:x,children:x?"\u279C ":" "}),i(f,{borderStyle:"round",borderColor:x?b:"gray",paddingX:2,children:i(u,{color:x?b:"gray",bold:x,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"})})]})},et=({currentVar:e,currentIndex:t,totalCount:o,onSubmit:r,onSkip:n})=>{let[s,l]=H(e.defaultValue||""),[a,c]=H(null);Pe(()=>{l(e.defaultValue||""),c(null)},[e.name]),ie((v,y)=>{if(y.escape){if(e.required&&!s.trim()){c("This field is required and cannot be skipped");return}n()}});let p=v=>{if(e.required&&!v.trim()){c("This field is required");return}c(null),r(v)},S=!!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(Ee,{value:s,onChange:v=>{l(v),a&&c(null)},onSubmit:p,placeholder:S?`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(_e,{status:t.status,step:t.step,children:[t.step==="Welcome"&&t.inputRequest?.id==="welcome"&&i(_r,{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(Lr,{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(Ct,{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(Ye,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&i(Ke,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&i(Je,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&i(et,{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(ze,{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(Ze,{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(Xe,{label:t.status||"Configuring environment..."})})]}),t.step==="Finished"&&i(Mr,{setupMode:t.data.setupMode,portOverrides:t.data.portOverrides,onConfirm:()=>e.submitInput("exit")}),(t.step==="Install Tools"||t.step==="Project Setup")&&i(Nr,{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(Xe,{label:t.status||"Installing gaia CLI globally..."})}),t.data.cliInstallLogs&&t.data.cliInstallLogs.length>0&&i(Et,{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 Gr}from"@inkjs/ui";import{Box as G,Text as w,useInput as wt}from"ink";import{useEffect as Rt,useRef as $r,useState as Dt}from"react";import{jsx as F,jsxs as P}from"react/jsx-runtime";var tt=8,qr=({logs:e})=>{let[t,o]=Dt(0),r=$r(e.length);Rt(()=>{e.length!==r.current&&(r.current=e.length,o(0))},[e.length]),wt((S,v)=>{v.upArrow?o(y=>Math.min(y+1,Math.max(0,e.length-tt))):v.downArrow&&o(y=>Math.max(0,y-1))});let n=e.length,s=Math.max(0,n-tt-t),l=Math.max(0,n-t),a=e.slice(s,l),c=s,p=t;return P(G,{flexDirection:"column",marginTop:1,marginLeft:1,children:[c>0&&P(w,{color:"gray",dimColor:!0,children:["\u2191 ",c," more line",c!==1?"s":""]}),F(G,{flexDirection:"column",height:tt,overflow:"hidden",children:a.map((S,v)=>F(w,{color:"gray",wrap:"truncate",children:S},s+v))}),p>0?P(w,{color:"gray",dimColor:!0,children:["\u2193 ",p," more line",p!==1?"s":""]}):F(w,{color:"gray",dimColor:!0,children:"\u2191\u2193 scroll"})]})},kt=({store:e})=>{let[t,o]=Dt(e.currentState);return Rt(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),wt((r,n)=>{(n.return||n.escape)&&(t.data.started||t.data.stopped||t.error)&&e.submitInput("exit")}),P(G,{flexDirection:"column",width:"100%",children:[F(me,{}),(t.step==="Starting"||t.step==="Stopping")&&P(G,{flexDirection:"column",marginTop:1,paddingX:2,borderStyle:"round",borderColor:b,children:[F(Gr,{label:t.status||"Working..."}),t.data.repoPath&&F(G,{marginTop:1,children:P(w,{color:"gray",children:["Repository: ",t.data.repoPath]})}),t.data.setupMode&&F(G,{children:P(w,{color:"gray",children:["Mode: ",t.data.setupMode]})}),t.data.dockerLogs&&t.data.dockerLogs.length>0&&F(qr,{logs:t.data.dockerLogs})]}),t.step==="Running"&&t.data.started&&P(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:"green",children:[P(w,{color:"green",bold:!0,children:["\u2713"," GAIA is running!"]}),t.data.setupMode!=="developer"&&P(G,{marginTop:1,flexDirection:"column",children:[P(w,{children:["Web:"," ",P(w,{color:"cyan",bold:!0,children:["http://localhost:",t.data.webPort||3e3]})]}),P(w,{children:["API:"," ",P(w,{color:"cyan",bold:!0,children:["http://localhost:",t.data.apiPort||8e3]})]})]}),t.data.setupMode==="developer"&&P(G,{marginTop:1,flexDirection:"column",children:[P(G,{flexDirection:"column",children:[P(w,{children:["Web:"," ",P(w,{color:"cyan",bold:!0,children:["http://localhost:",t.data.webPort||3e3]})]}),P(w,{children:["API:"," ",P(w,{color:"cyan",bold:!0,children:["http://localhost:",t.data.apiPort||8e3]})]})]}),P(G,{marginTop:1,flexDirection:"column",children:[F(w,{color:"gray",children:"Dev servers started in background."}),P(w,{color:"gray",children:["Logs: ",F(w,{color:b,children:"dev-start.log"})," in your repo root."]}),P(w,{color:"gray",children:["Run ",F(w,{color:b,children:"gaia stop"})," to shut down."]})]})]}),F(G,{marginTop:1,children:P(w,{dimColor:!0,children:[F(w,{bold:!0,children:"Enter"})," to exit"]})})]}),t.step==="Stopped"&&t.data.stopped&&P(G,{flexDirection:"column",marginTop:1,paddingX:2,paddingY:1,borderStyle:"round",borderColor:b,children:[P(w,{color:b,bold:!0,children:["\u2713"," All GAIA services stopped."]}),F(G,{marginTop:1,children:P(w,{dimColor:!0,children:[F(w,{bold:!0,children:"Enter"})," to exit"]})})]}),t.error&&P(G,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:[P(w,{color:"red",children:["Error: ",t.error.message]}),F(G,{marginTop:1,children:P(w,{dimColor:!0,children:[F(w,{bold:!0,children:"Enter"})," to exit"]})})]})]})};import{ProgressBar as jr,Spinner as rt}from"@inkjs/ui";import{Box as B,Text as O,useInput as At}from"ink";import{useEffect as Hr,useState as Wr}from"react";import{jsx as E,jsxs as _}from"react/jsx-runtime";var Bt=({store:e})=>{let[t,o]=Wr(e.currentState);return Hr(()=>{let r=()=>o({...e.currentState});return e.on("change",r),()=>{e.off("change",r)}},[e]),At((r,n)=>{(n.return||n.escape)&&t.error&&e.submitInput("exit")}),_(_e,{status:t.status,step:t.step,steps:It,children:[t.step==="Detect Repo"&&_(B,{flexDirection:"column",paddingX:2,borderStyle:"round",borderColor:b,children:[E(O,{bold:!0,children:"Detecting GAIA Repository"}),E(B,{marginTop:1,children:E(rt,{label:"Searching for repository..."})}),t.data.repoPath&&E(B,{marginTop:1,children:_(O,{color:"green",children:["Found: ",t.data.repoPath]})})]}),t.step==="Prerequisites"&&t.data.checks&&_(B,{flexDirection:"column",borderStyle:"round",paddingX:1,borderColor:b,children:[E(O,{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(Ye,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_method"&&E(Ke,{onSelect:r=>e.submitInput(r)}),t.inputRequest?.id==="env_infisical"&&E(Je,{onSubmit:r=>e.submitInput(r)}),t.step==="Environment Setup"&&t.inputRequest?.id==="env_var"&&t.data.currentEnvVar&&E(et,{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(ze,{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(Ze,{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(O,{bold:!0,children:"Environment Setup"}),E(B,{marginTop:1,children:E(rt,{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(O,{bold:!0,color:b,children:"Project Setup"})}),_(B,{flexDirection:"column",gap:1,children:[E(B,{children:t.data.dependencyComplete?_(O,{color:"green",children:["\u2713"," ",t.data.dependencyPhase]}):E(rt,{label:t.data.dependencyPhase||"Preparing..."})}),!t.data.dependencyComplete&&t.data.dependencyProgress>0&&E(B,{width:50,children:E(jr,{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(O,{color:"gray",wrap:"truncate",children:r},n))})]})]}),t.step==="Finished"&&E(Vr,{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:[_(O,{color:"red",children:["Error: ",t.error.message]}),E(B,{marginTop:1,children:_(O,{dimColor:!0,children:[E(O,{bold:!0,children:"Enter"})," to exit"]})})]})]})},Vr=({portOverrides:e,onConfirm:t})=>{At((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(O,{color:b,bold:!0,children:"Setup Complete!"}),_(B,{marginTop:1,children:[E(O,{bold:!0,children:"Run: "}),E(O,{color:"cyan",children:"$ gaia start"})]}),_(B,{marginTop:1,flexDirection:"column",children:[_(O,{children:["Web:"," ",_(O,{color:"cyan",bold:!0,children:["http://localhost:",o]})]}),_(O,{children:["API:"," ",_(O,{color:"cyan",bold:!0,children:["http://localhost:",r]})]})]}),E(B,{marginTop:1,children:E(O,{color:"gray",children:"gaia stop \xB7 gaia status \xB7 gaia setup"})}),E(B,{marginTop:1,children:_(O,{dimColor:!0,children:[E(O,{bold:!0,children:"Enter"})," to exit"]})})]})};import{Spinner as Ur}from"@inkjs/ui";import{Box as L,Text as A,useInput as Xr}from"ink";import{useEffect as _t,useState as ot}from"react";import{jsx as D,jsxs as $}from"react/jsx-runtime";var Ot=({store:e})=>{let[t,o]=ot(e.currentState),[r,n]=ot(!1),[s,l]=ot(null);return _t(()=>{let a=()=>o({...e.currentState});return e.on("change",a),()=>{e.off("change",a)}},[e]),_t(()=>{t.step==="Results"&&(n(!1),l(new Date().toLocaleTimeString()))},[t.step]),Xr((a,c)=>{(c.return||c.escape)&&t.step==="Results"&&e.submitInput("exit"),a==="r"&&t.step==="Results"&&t.data.refreshable&&!r&&(n(!0),e.submitInput("refresh"))}),$(L,{flexDirection:"column",width:"100%",children:[D(me,{}),t.step==="Checking"&&D(L,{marginTop:1,children:D(Ur,{label:t.data.services?"Refreshing service health...":"Checking service health..."})}),t.step==="Results"&&t.data.services&&$(L,{flexDirection:"column",children:[$(L,{flexDirection:"column",borderStyle:"round",borderColor:b,paddingX:2,paddingY:1,children:[$(L,{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"]})]}),$(L,{marginTop:1,flexDirection:"column",children:[$(L,{children:[D(L,{width:22,children:D(A,{bold:!0,children:"Service"})}),D(L,{width:10,children:D(A,{bold:!0,children:"Status"})}),D(L,{width:10,children:D(A,{bold:!0,children:"Latency"})})]}),D(A,{color:"gray",children:"\u2500".repeat(42)}),[...t.data.services].sort((a,c)=>a.status==="down"&&c.status!=="down"?-1:a.status!=="down"&&c.status==="down"?1:a.name.localeCompare(c.name)).map(a=>$(L,{children:[D(L,{width:22,children:$(A,{children:[a.name," (:",a.port,")"]})}),D(L,{width:10,children:D(A,{color:a.status==="up"?"green":"red",bold:!0,children:a.status==="up"?"\u2713 UP":"\u2717 DOWN"})}),D(L,{width:10,children:D(A,{color:"gray",children:a.latency?`${a.latency}ms`:"--"})})]},a.name))]})]}),t.data.docker&&$(L,{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(L,{marginTop:1,flexDirection:"column",children:t.data.docker.containers.map(a=>$(L,{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(L,{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(L,{borderStyle:"single",borderColor:"red",padding:1,marginTop:2,children:$(A,{color:"red",children:["Error: ",t.error.message]})})]})};import{jsx as Y,jsxs as we}from"react/jsx-runtime";var Yr=["init","setup","status","start","stop"],nt=class extends Qr.Component{constructor(t){super(t),this.state={error:null}}static getDerivedStateFromError(t){return{error:t}}render(){return this.state.error?we(Le,{flexDirection:"column",padding:1,children:[Y(ue,{color:"red",bold:!0,children:"An unexpected error occurred:"}),Y(ue,{color:"red",children:this.state.error.message}),this.state.error.stack&&Y(Le,{marginTop:1,children:Y(ue,{color:"gray",dimColor:!0,children:this.state.error.stack})})]}):this.props.children}},Kr=({store:e,command:t})=>{switch(t){case"init":return Y(Pt,{store:e});case"setup":return Y(Bt,{store:e});case"status":return Y(Ot,{store:e});case"start":case"stop":return Y(kt,{store:e,command:t});default:return we(Le,{flexDirection:"column",padding:1,children:[we(ue,{color:"red",children:["Unknown command: ",t]}),we(Le,{marginTop:1,flexDirection:"column",children:[Y(ue,{bold:!0,children:"Available commands:"}),Yr.map(o=>we(ue,{children:[" ",Y(ue,{color:"cyan",children:o})]},o))]})]})}},K=({store:e,command:t})=>Y(nt,{children:Y(Kr,{store:e,command:t})});import{EventEmitter as Jr}from"events";var zr=150,it=class extends Jr{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){return this.state.inputRequest={id:t,meta:o},this.emitNow(),new Promise(r=>{this.inputResolver=r})}submitInput(t){this.inputResolver&&(this.inputResolver(t),this.inputResolver=null,this.state.inputRequest=null,this.emitNow())}},J=()=>new it;import*as re from"fs";import*as ar from"os";import*as ae from"path";import*as ee from"fs";import*as Lt from"os";import*as ct from"path";var at=ct.join(Lt.homedir(),".gaia"),st=ct.join(at,"config.json"),lt="0.1.10";function Zr(){ee.existsSync(at)||ee.mkdirSync(at,{recursive:!0})}function ut(){try{if(!ee.existsSync(st))return null;let e=ee.readFileSync(st,"utf-8");return JSON.parse(e)}catch{return null}}function Me(e){Zr(),ee.writeFileSync(st,`${JSON.stringify(e,null,2)}
3
- `)}function Re(e){let o={...ut()??{version:lt,setupComplete:!1,setupMethod:"manual",repoPath:"",createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()},...e,updatedAt:new Date().toISOString()};Me(o)}import*as Kt from"path";import*as ge from"node:fs";import*as fe from"node:path";import{execa as Mt}from"execa";var pt={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/"}},Ft={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 dt(e,t){return pt[t][e]??Ft[t][e]}async function Nt(e){let t=fe.join(e,"apps/api/scripts/dump_config_schema.py"),o=fe.join(e,"apps/api/app/config/settings_validator.py"),r=fe.join(e,"apps/api/app/config/settings.py");if(!ge.existsSync(t))throw new Error("dump_config_schema.py not found in apps/api/scripts");try{try{let{stdout:n}=await Mt("python3",[t,o,r],{cwd:e});return JSON.parse(n)}catch{let{stdout:n}=await Mt("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 Gt(e){let t=fe.join(e,"apps","web",".env.local"),o=ge.existsSync(t)?t:fe.join(e,"apps","web",".env");if(!ge.existsSync(o))return[];let r=ge.readFileSync(o,"utf-8"),n=[],s="General";for(let l of r.split(`
4
- `)){let a=l.trim();if(a.startsWith("#")&&!a.startsWith("#=")){let v=a.replace(/^#+\s*/,"").trim();v&&!v.startsWith("These are")&&(s=v);continue}if(!a||a.startsWith("#"))continue;let c=a.indexOf("=");if(c===-1)continue;let p=a.substring(0,c).trim(),S=a.substring(c+1).trim();n.push({name:p,value:S,category:s})}return n}function $t(e,t){return{NEXT_PUBLIC_API_BASE_URL:`http://localhost:${t?.[8e3]??8e3}/api/v1/`}}function qt(e,t,o){let r=o==="selfhost"?new Set(Object.keys(pt.selfhost)):new Set;for(let[n,s]of Object.entries(t)){let l=Number(n),a=Number(s);for(let[c,p]of Object.entries(e)){if(r.has(c))continue;if(p===String(l)){e[c]=String(a);continue}let S=new RegExp(`:${l}(?=[/\\s]|$)`,"g");e[c]=p.replaceAll(S,`:${a}`)}}}function jt(e,t){return e.map(o=>({...o,variables:o.variables.map(r=>{let n=dt(r.name,t);return{...r,defaultValue:n||r.defaultValue}})}))}function mt(){return Object.keys(pt.selfhost)}function Ht(e){return{...Ft[e]}}import*as W from"fs";import*as he from"path";function ft(e){W.existsSync(e)&&W.copyFileSync(e,`${e}.bak`)}function Vt(e,t){let o=he.join(e,".env");ft(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 c=a.split("_");return c.length===1?"Core":c[0]||"Core"}let l=new Map;for(let[a,c]of Object.entries(t)){let p=s(a);l.has(p)||l.set(p,[]);let v=/[\s#"'\\]/.test(c)||c===""?`"${c.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:c;l.get(p).push(`${a}=${v}`)}for(let[a,c]of l.entries())r.push(`# ${a} Configuration`),r.push(...c),r.push("");W.writeFileSync(o,r.join(`
5
- `),"utf-8")}function Ut(e,t,o){let r=he.join(e,"apps","web",".env.local");ft(r);let n=Gt(e),s=$t(t,o),l=["# GAIA Web App Environment Configuration","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""],a=new Map;for(let c of n){a.has(c.category)||a.set(c.category,[]);let p=s[c.name]??c.value;a.get(c.category).push({name:c.name,value:p})}if(n.length===0){l.push("# Core URLs");for(let[c,p]of Object.entries(s))l.push(`${c}=${p}`);l.push("")}else for(let[c,p]of a.entries()){l.push(`# ${c}`);for(let{name:S,value:v}of p)l.push(`${S}=${v}`);l.push("")}W.writeFileSync(r,l.join(`
6
- `),"utf-8")}var Xt={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 Qt(e,t,o){let r=he.join(e,"infra","docker",".env");ft(r);let n=["# Docker Compose environment overrides","# Generated by GAIA CLI",`# Created: ${new Date().toISOString()}`,""];for(let[s,l]of Object.entries(t)){let a=Number(s),c=Xt[a];c&&n.push(`${c}=${l}`)}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=Xt[n];s&&(t[s]=String(r))}return t}function Yt(e){let t=he.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:l,containerPort:a}of r){let c=`"${l}:${a}"`,p=`"\${${s}:-${l}}:${a}"`;o.includes(c)&&(o=o.replaceAll(c,p),n=!0)}n&&W.writeFileSync(t,o,"utf-8")}var Wt={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=he.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[l,...a]=s.split("=");if(l&&Wt[l]){let c=a.join("=").trim().replace(/^["']|["']$/g,""),p=Number(c);!Number.isNaN(p)&&p>0&&(o[Wt[l]]=p)}}}return o}var ro=e=>new Promise(t=>setTimeout(t,e));async function Fe(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 Ne(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 l=mt();for(let c of l){let p=dt(c,o);p&&(s[c]=p)}let a=Ht(o);for(let[c,p]of Object.entries(a))s[c]=p;if(n==="infisical")await oo(e,s),e.setStatus("Infisical credentials saved. Ensure your Infisical project contains all required variables.");else try{await no(e,t,s,o)}catch(c){e.setError(c);return}r&&qt(s,r,o);try{await io(e,t,s,o,r)}catch(c){e.setError(c);return}await ro(1e3)}async function oo(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 no(e,t,o,r){e.setStatus("Parsing environment variables...");let n;try{n=await Nt(t),n=jt(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,l=[],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&&(l.push([m,d]),s.add(m.name),s.add(d.name),a.add(m.name),a.add(d.name))}let c=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 l){e.updateData("alternativeGroups",m),e.setStatus("Choose an AI provider...");let d=await e.waitForInput("env_alternatives");for(let[h,T]of Object.entries(d.values))T&&(o[h]=T)}let S=mt(),y=[...c.flatMap(m=>m.variables).filter(m=>!S.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 x=[...p].filter(m=>!m.variables.every(d=>S.includes(d.name))).sort((m,d)=>{let h=m.variables.some(I=>I.required),T=d.variables.some(I=>I.required);return h&&!T?-1:!h&&T?1:0});e.updateData("envGroupTotal",x.length);for(let m=0;m<x.length;m++){let d=x[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[T,I]of Object.entries(h)){let C=d.variables.find(k=>k.name===T);(I||C?.required||C?.defaultValue)&&(o[T]=I||C?.defaultValue||"")}}}async function io(e,t,o,r,n){e.setStatus("Writing API environment file...");try{let l=Kt.join(t,"apps","api");Vt(l,o),e.setStatus("API environment variables configured!")}catch(l){throw new Error(`Failed to write API .env file: ${l.message}`)}e.setStatus("Writing web environment file...");try{Ut(t,r,n),e.setStatus("Web environment variables configured!")}catch(l){throw new Error(`Failed to write web .env file: ${l.message}`)}let s=n&&Object.keys(n).length>0;if(s||r==="selfhost"){e.setStatus("Writing Docker Compose environment...");try{s&&Yt(t),Qt(t,n??{},r),e.setStatus("Docker Compose environment configured!")}catch(l){throw new Error(`Failed to write Docker Compose .env: ${l.message}`)}}}import{execa as ao}from"execa";import Ge from"fs";import so from"simple-git";async function Jt(e,t,o,r){if(Ge.existsSync(e)){let n=`${e}/.git`;if(!Ge.existsSync(n))throw new Error(`Directory ${e} exists but is not a git repository`);await so().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=ao("git",n);s.stderr?.on("data",l=>{let a=l.toString();a.includes("Counting objects")?o(5,"Counting objects"):a.includes("Compressing objects")&&o(10,"Compressing objects");let c=a.match(/Receiving objects:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(c?.[1]){let S=Math.min(100,parseInt(c[1],10)),v=c[2],y=c[3];o(10+Math.floor(S*.5),`Receiving objects: ${v}/${y}`)}let p=a.match(/Resolving deltas:\s+(\d+)%\s+\((\d+)\/(\d+)\)/);if(p?.[1]){let S=Math.min(100,parseInt(p[1],10)),v=p[2],y=p[3];o(60+Math.floor(S*.4),`Resolving deltas: ${v}/${y}`)}}),await s,o(100,"Clone complete")}catch(n){throw Ge.existsSync(e)&&Ge.rmSync(e,{recursive:!0,force:!0}),n}}import{execSync as gt}from"child_process";import*as M from"fs";import*as $e from"os";import*as q from"path";var De=process.platform==="win32";function ke(e){try{return gt(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}catch{return null}}function zt(){let e=ke("npm config get prefix");return e?De?e:q.join(e,"bin"):null}function Zt(){let e=ke("pnpm bin -g");if(e&&M.existsSync(e))return e;let t=ke("pnpm root -g");if(t){let o=q.join(q.dirname(t),"bin");if(M.existsSync(o))return o}return null}function er(){let e=q.join($e.homedir(),".bun","bin");return M.existsSync(e)?e:null}function tr(){let e=ke("yarn global bin");return e&&M.existsSync(e)?e:null}function lo(){let e=De?"gaia.cmd":"gaia";for(let t of[zt,Zt,er,tr]){let o=t();if(o&&M.existsSync(q.join(o,e)))return o}if(De)for(let t of[zt,Zt,er,tr]){let o=t();if(o&&M.existsSync(q.join(o,"gaia")))return o}return null}function uo(){try{return gt(De?"where gaia":"command -v gaia",{stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function po(){let e=process.env.SHELL||"",t=$e.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 mo(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 fo(e){try{let t=ke(`powershell -Command "[Environment]::GetEnvironmentVariable('Path', 'User')"`);if(t&&t.includes(e))return!0;gt(`setx PATH "${e};${t||""}"`,{stdio:["pipe","pipe","pipe"]});let o=q.join($e.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 ht(){if(uo())return{success:!0,message:"gaia command is ready.",inPath:!0,pathAdded:!1};let e=lo();if(!e)return{success:!1,message:"Could not find gaia binary. Run manually: npm install -g @heygaia/cli",inPath:!1,pathAdded:!1};if(De)return fo(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=po();if(!t)return{success:!1,message:`Add to your PATH: export PATH="${e}:$PATH"`,inPath:!1,pathAdded:!1};if(mo(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"},go={8e3:"API Server",5432:"PostgreSQL",6379:"Redis",27017:"MongoDB",5672:"RabbitMQ",3e3:"Web Frontend",8080:"ChromaDB",8083:"Mongo Express"};async function qe(){try{return await te("git",["--version"]),"success"}catch{return"error"}}async function ye(){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 je(){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 He(e){let t=await import("node:net"),o=[],r=n=>new Promise(s=>{let l=t.createServer();l.once("error",()=>s(!1)),l.once("listening",()=>{l.close(()=>s(!0))}),l.listen(n)});for(let n of e){let s=go[n]||`Port ${n}`;if(await r(n))o.push({port:n,service:s,available:!0});else{let a=await ho(n),c=await xo(n+1,n+100,r);o.push({port:n,service:s,available:!1,usedBy:a,alternative:c||void 0})}}return o}async function ho(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 l=s.trim().split(/\s+/),a=l[l.length-1];if(a)try{let{stdout:c}=await te("tasklist",["/FI",`PID eq ${a}`,"/FO","CSV","/NH"]);return c.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 So=e=>new Promise(t=>setTimeout(t,e)),yo="dev-start.log";var or=".gaia-dev.pid";function nr(e){let t=Q.join(e,".env");return N.existsSync(t)?["--env-file",".env"]:[]}async function Ae(e,t,o,r,n,s){if(t==="selfhost"){let l=s?.build??!1,a=s?.pull??!1;o?.(l?"Building and starting all services in Docker...":"Starting all services in Docker (selfhost mode)...");let c=Q.join(e,"infra/docker"),p=nr(c),S=r&&Object.keys(r).length>0?xe(r):void 0,v=["compose","-f","docker-compose.selfhost.yml",...p,"up","-d","--remove-orphans"];l&&v.push("--build"),a&&v.push("--pull","always");let y=l?900*1e3:300*1e3;await V("docker",v,c,void 0,n,S,y),o?.("All services started in Docker!")}else{o?.("Starting development servers...");let{spawn:l}=await import("child_process"),a=Q.join(e,yo),c=Q.join(e,or),p=N.openSync(a,"w"),S;try{S=l("mise",["dev"],{cwd:e,stdio:["ignore",p,p],detached:!0,shell:!0}),S.unref()}finally{N.closeSync(p)}if(S.pid!=null&&N.writeFileSync(c,String(S.pid),"utf-8"),await So(1500),S.pid!=null)try{process.kill(S.pid,0)}catch{throw new Error(`Development servers crashed on startup. Check logs at: ${a}`)}o?.(`Development servers started! Logs: ${a}`)}}async function ir(e,t,o){let r=Q.join(e,"infra/docker"),n=await xt(e);t?.("Stopping Docker services...");try{let s=nr(r),l=n==="selfhost"?["compose","-f","docker-compose.selfhost.yml",...s,"down"]:["compose",...s,"down"];await V("docker",l,r)}catch{}if(n!=="selfhost"){t?.("Stopping local processes...");let s=Q.join(e,or),l=!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"),l=!0}catch{}}catch{}try{N.unlinkSync(s)}catch{}}if(!l)try{let a=o?.[8e3]??8e3,c=o?.[3e3]??3e3;if(process.platform==="win32")for(let p of[a,c])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,c])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,l){let{spawn:a}=await import("child_process");return new Promise((c,p)=>{let S=a(e,t,{cwd:o,stdio:["ignore","pipe","pipe"],shell:!0,env:s?{...process.env,...s}:void 0}),v="",y=0,x=!1,m;l&&(m=setTimeout(()=>{x=!0,S.kill("SIGTERM"),p(new Error(`Command timed out after ${Math.round(l/6e4)}m. Check \`docker compose logs\` to debug.`))},l)),S.stdout?.on("data",d=>{let h=d.toString();v+=h,n?.(h),y=Math.min(y+5,95),r?.(y)}),S.stderr?.on("data",d=>{let h=d.toString();v+=h,n?.(h),y=Math.min(y+5,95),r?.(y)}),S.on("close",d=>{m&&clearTimeout(m),!x&&(d===0?(r?.(100),c()):p(new Error(`Command failed with code ${d}: ${v.slice(-500)}`)))}),S.on("error",d=>{m&&clearTimeout(m),!x&&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=ut();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.`),Re({repoPath:"",setupComplete:!1})}return null}var vo=process.env.GAIA_CLI_DEV==="true",Z=e=>new Promise(t=>setTimeout(t,e));async function sr(e,t){e.setStep("Welcome"),e.setStatus("Waiting for user input..."),await e.waitForInput("welcome");let o=d=>{let h=e.currentState.data.dependencyLogs||[],T=d.split(`
21
- `).filter(C=>C.trim()!==""),I=[...h,...T].slice(-20);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 qe();e.updateData("checks",{...e.currentState.data.checks,git:r}),e.setStatus("Checking Docker...");let n=await ye(),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 l=await ve();e.updateData("checks",{...e.currentState.data.checks,mise:l}),l==="missing"&&(e.setStatus("Installing Mise..."),l=await je()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:l}));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 He([8e3,5432,6379,27017,5672,3e3,8080,8083]),S={},v=p.filter(d=>!d.available);if(v.length>0){let d=v.filter(T=>!T.alternative);if(d.length>0){e.setError(new Error(`Cannot find free alternative ports for: ${d.map(T=>`${T.port} (${T.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 T of p)!T.available&&T.alternative&&(S[T.port]=T.alternative)}e.updateData("portOverrides",S),e.setStatus("Prerequisites check complete!"),await Z(1e3);let y=await Fe(e),x="";if(vo){if(x=z()||"",!x){e.setError(new Error("DEV_MODE: Could not find workspace root. Run from within the gaia repo."));return}e.setStep("Repository Setup"),e.setStatus("[DEV MODE] Using current workspace..."),await Z(500),e.setStatus("Repository ready!")}else{e.setStep("Repository Setup");let d=y==="selfhost"?ae.join(ar.homedir(),"gaia"):ae.resolve("gaia"),h=!0;for(x=d;;){if(x=await e.waitForInput("repo_path",{default:d}),ae.isAbsolute(x)||(x=ae.resolve(x)),re.existsSync(x)){if(!re.statSync(x).isDirectory()){e.setError(new Error(`Path ${x} exists and is not a directory.`)),await Z(2e3),e.setError(null);continue}if(re.existsSync(ae.join(x,"apps/api/app/config/settings_validator.py"))){e.updateData("existingRepoPath",x);let k=await e.waitForInput("existing_repo");if(k==="use_existing"){h=!1;break}else if(k==="delete_reclone"){e.setStatus("Removing existing installation..."),re.rmSync(x,{recursive:!0,force:!0});break}else{if(k==="different_path")continue;e.setError(new Error("Setup cancelled by user."));return}}if(re.readdirSync(x).length>0){e.setError(new Error(`Directory ${x} 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 Jt(x,"https://github.com/theexperiencecompany/gaia.git",(T,I)=>{e.updateData("repoProgress",T),I?(e.updateData("repoPhase",I),e.setStatus(`${I}...`)):e.setStatus(`Cloning repository to ${x}... ${T}%`)},t),e.setStatus("Repository ready!")}catch(T){e.setError(T);return}}else e.setStatus("Using existing repository!")}if(await Z(1e3),await Ne(e,x,y,S),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"],x,void 0,k=>{let R=k.split(`
24
- `).map(Te=>Te.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(Te=>Te.length>0);if(R.length===0)return;let pe=e.currentState.data.cliInstallLogs||[];e.updateData("cliInstallLogs",[...pe,...R].slice(-50))}),e.setStatus("Verifying PATH...");let C=await ht();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(`
25
- `).map(R=>R.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(R=>R.length>0);if(C.length===0)return;let k=e.currentState.data.dependencyLogs||[];e.updateData("dependencyLogs",[...k,...C].slice(-50))},h=!1;try{e.setStatus("Pulling pre-built images from registry..."),await Ae(x,"selfhost",I=>e.setStatus(I),S,d,{pull:!0}),h=!0}catch{e.setStatus("Registry pull failed \u2014 building images locally (this takes a few minutes)...")}if(!h)try{await Ae(x,"selfhost",I=>e.setStatus(I),S,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 T=e.currentState.data.envMethod||"manual";Me({version:lt,setupComplete:!0,setupMethod:T,repoPath:x,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(l==="error"){e.setError(new Error(`Developer mode requires Mise but it failed to install.
26
- \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"],x,void 0,o),e.updateData("dependencyProgress",50),e.updateData("dependencyPhase","Installing tools (node, python, uv, nx)..."),await V("mise",["install"],x,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",x),e.updateData("dependencyLogs",[]);try{e.updateData("dependencyProgress",0),e.updateData("dependencyPhase","Running mise setup (all dependencies)...");let d=Object.keys(S).length>0?xe(S):void 0;await V("mise",["setup"],x,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";Me({version:"0.1.8",setupComplete:!0,setupMethod:m,repoPath:x,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"],x,void 0,T=>{let I=T.split(`
27
- `).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(-50))}),e.setStatus("Verifying PATH...");let h=await ht();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 cr(e={}){let t=J(),{unmount:o}=To(bo.createElement(K,{store:t,command:"init"}));try{await sr(t,e.branch)}catch(r){t.setError(r)}t.currentState.error&&await t.waitForInput("exit"),o(),process.exit(t.currentState.error?1:0)}import{render as Io}from"ink";import Co from"react";var We=e=>new Promise(t=>setTimeout(t,e));async function lr(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 We(1e3),e.setStep("Prerequisites"),e.setStatus("Checking system requirements..."),e.updateData("checks",{git:"pending",docker:"pending",mise:"pending"}),await We(500);let o=await qe();e.updateData("checks",{...e.currentState.data.checks,git:o});let r=await ye(),n=r.working?"success":"error";e.updateData("checks",{...e.currentState.data.checks,docker:n}),r.working||e.updateData("dockerError",r.errorMessage);let s=await ve();e.updateData("checks",{...e.currentState.data.checks,mise:s}),s==="missing"&&(e.setStatus("Installing Mise..."),s=await je()?"success":"error",e.updateData("checks",{...e.currentState.data.checks,mise:s}));let l=[];if(o==="error"&&l.push({name:"Git"}),n==="error"&&l.push({name:"Docker",message:r.errorMessage}),l.length>0){let m=[];m.push("Prerequisites failed:");for(let d of l)m.push(` \u2022 ${d.name}: ${d.message||"Not installed or not working"}`);m.push(`
28
- 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(`
29
- `)));return}e.setStatus("Checking Ports...");let c=await He([8e3,5432,6379,27017,5672,3e3,8080,8083]),p={},S=c.filter(m=>!m.available);if(S.length>0){let m=S.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",c),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 c)!h.available&&h.alternative&&(p[h.port]=h.alternative)}e.updateData("portOverrides",p),e.setStatus("Prerequisites check complete!"),await We(1e3);let v=await Fe(e);if(await Ne(e,t,v,p),e.currentState.error)return;if(v==="selfhost"){let m=e.currentState.data.envMethod||"manual";Re({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.
30
- \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(`
31
- `).filter(I=>I.trim()!==""),T=[...d,...h].slice(-20);e.updateData("dependencyLogs",T)};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 We(1e3);let x=e.currentState.data.envMethod||"manual";Re({setupComplete:!0,setupMethod:x,repoPath:t}),e.setStep("Finished"),e.setStatus("Setup complete!"),await e.waitForInput("exit")}async function ur(){let e=J(),{unmount:t}=Io(Co.createElement(K,{store:e,command:"setup"}));try{await lr(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}import{render as Eo}from"ink";import Po from"react";async function pr(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 c=await ye();if(!c.working){e.setError(new Error(c.errorMessage||`Docker is not running. Please start Docker and try again.
32
- ${X.docker}`));return}}else{e.setStatus("Checking Mise...");let c=await ve();if(c==="missing"||c==="error"){e.setError(new Error(`Developer mode requires Mise but it is not installed.
33
- Install: ${X.mise}`));return}}let n=Se(o),s=n[3e3]??3e3,l=n[8e3]??8e3;e.updateData("setupMode",r),e.updateData("webPort",s),e.updateData("apiPort",l),e.updateData("dockerLogs",[]),e.setStatus(`Starting GAIA in ${r} mode...`);let a=c=>{let p=c.split(`
34
- `).map(v=>v.replace(/\x1b\[[0-9;]*m/g,"").trim()).filter(v=>v.length>0);if(p.length===0)return;let S=e.currentState.data.dockerLogs||[];e.updateData("dockerLogs",[...S,...p].slice(-50))};try{await Ae(o,r,c=>{e.setStatus(c)},n,a,t),e.setStep("Running"),e.setStatus("GAIA is running!"),e.updateData("started",!0)}catch(c){e.setError(new Error(`Failed to start services: ${c.message}`));return}await e.waitForInput("exit")}async function dr(e){let t=J(),{unmount:o}=Eo(Po.createElement(K,{store:t,command:"start"}));await new Promise(r=>setTimeout(r,50));try{await pr(t,e)}catch(r){t.setError(r)}t.currentState.error&&await t.waitForInput("exit"),o(),process.exit(t.currentState.error?1:0)}import{render as Ao}from"ink";import Bo from"react";import{execa as yt}from"execa";var St=["gaia-backend","gaia-web","chromadb","postgres","redis","mongo","rabbitmq","arq_worker"];async function mr(){try{let{stdout:e}=await yt("docker",["inspect","--format","{{.Name}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}",...St]),t=new Map;for(let o of e.trim().split(`
35
- `)){if(!o)continue;let[r,n,s]=o.split("|"),l=r?.replace(/^\//,"")??"";t.set(l,{name:l,status:n==="running"?"running":"stopped",health:s!=="none"?s:void 0})}return St.map(o=>t.get(o)??{name:o,status:"not_found"})}catch{let e=St.map(async t=>{try{let{stdout:o}=await yt("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 fr(){try{return await yt("docker",["info"]),!0}catch{return!1}}var wo=[{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 gr(e){let o=wo.map(r=>({...r,port:e?.[r.port]??r.port})).map(r=>r.type==="http"?Ro(r.name,r.port,r.path):Do(r.name,r.port));return Promise.all(o)}async function Ro(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 Do(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 l=Date.now()-r;s.destroy(),n({name:e,port:t,status:"up",latency:l})}),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 hr(){return await fr()?{running:!0,containers:await mr()}:{running:!1,containers:[]}}async function ko(e){e.setStep("Checking"),e.setStatus("Checking service health..."),e.updateData("refreshable",!1);let t=z(),o=t?Se(t):void 0,[r,n]=await Promise.all([gr(o),hr()]);e.updateData("services",r),e.updateData("docker",n);let s=r.filter(a=>a.status==="up").length,l=r.length;e.setStep("Results"),e.setStatus(`${s}/${l} services running`),e.updateData("refreshable",!0)}async function xr(e){for(;await ko(e),await e.waitForInput("exit_or_refresh")==="refresh";);}async function Sr(){let e=J(),{unmount:t}=Ao(Bo.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 _o}from"ink";import Oo from"react";async function yr(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=Se(t);try{await ir(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}=_o(Oo.createElement(K,{store:e,command:"stop"}));await new Promise(o=>setTimeout(o,50));try{await yr(e)}catch(o){e.setError(o)}e.currentState.error&&await e.waitForInput("exit"),t(),process.exit(e.currentState.error?1:0)}var se=new Lo;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 cr({branch:e.branch})});se.command("setup").description("Configure an existing GAIA repository").action(async()=>{await ur()});se.command("status").description("Check health of all GAIA services").action(async()=>{await Sr()});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 dr({build:e.build,pull:e.pull})});se.command("stop").description("Stop all GAIA services").action(async()=>{await vr()});process.argv.slice(2).length||(se.outputHelp(),process.exit(0));se.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.13",
3
+ "version": "0.1.15",
4
4
  "description": "CLI tool for setting up and managing GAIA",
5
5
  "type": "module",
6
6
  "bin": {