|
2 | 2 | # Usage: irm https://raw.githubusercontent.com/OpenAnalystInc/cli/main/install.ps1 | iex |
3 | 3 |
|
4 | 4 | $ErrorActionPreference = "Continue" |
5 | | -$ProgressPreference = "SilentlyContinue" |
6 | 5 | try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 } catch {} |
7 | 6 |
|
8 | | -$Repo = "OpenAnalystInc/cli" |
9 | | -$BinaryName = "openanalyst.exe" |
10 | | -$InstallDir = "$env:USERPROFILE\.openanalyst\bin" |
11 | | -$ConfigDir = "$env:USERPROFILE\.openanalyst" |
| 7 | +Write-Host "" |
| 8 | +Write-Host " OpenAnalyst CLI" -ForegroundColor DarkCyan |
| 9 | +Write-Host " The Universal AI Agent for Your Terminal" -ForegroundColor DarkGray |
| 10 | +Write-Host "" |
12 | 11 |
|
13 | | -# ── Helpers ── |
14 | | -function Repeat([string]$c, [int]$n) { if ($n -le 0) { return "" }; return ($c * $n) } |
15 | | -function Pad([int]$n) { if ($n -le 0) { return "" }; return (" " * $n) } |
16 | | -function W([string]$t) { Write-Host $t -NoNewline -ForegroundColor White } |
17 | | -function Dim([string]$t) { Write-Host $t -NoNewline -ForegroundColor DarkGray } |
18 | | -function Br([string]$t) { Write-Host $t -NoNewline -ForegroundColor DarkCyan } |
19 | | -function Grn([string]$t) { Write-Host $t -NoNewline -ForegroundColor Green } |
20 | | -function Yl([string]$t) { Write-Host $t -NoNewline -ForegroundColor Yellow } |
21 | | -function Acc([string]$t) { Write-Host $t -NoNewline -ForegroundColor Cyan } |
22 | | -function Nl { Write-Host "" } |
23 | | -$H = [string][char]0x2500 # ─ |
24 | | -$TL = [string][char]0x250C # ┌ |
25 | | -$TR = [string][char]0x2510 # ┐ |
26 | | -$BL = [string][char]0x2514 # └ |
27 | | -$BR = [string][char]0x2518 # ┘ |
28 | | -$VL = [string][char]0x2502 # │ |
| 12 | +# Check for Node.js |
| 13 | +$NodeVersion = $null |
| 14 | +try { $NodeVersion = (node --version 2>$null) } catch {} |
29 | 15 |
|
30 | | -# ── Fetch version ── |
31 | | -$GhHeaders = @{ "User-Agent" = "openanalyst-cli" } |
32 | | -if ($env:GITHUB_TOKEN) { $GhHeaders["Authorization"] = "Bearer $env:GITHUB_TOKEN" } |
33 | | -elseif ($env:GH_TOKEN) { $GhHeaders["Authorization"] = "Bearer $env:GH_TOKEN" } |
34 | | -else { try { $t = (gh auth token 2>$null); if ($t) { $GhHeaders["Authorization"] = "Bearer $t" } } catch {} } |
35 | | - |
36 | | -$Version = "latest" |
37 | | -$Release = $null |
38 | | -try { |
39 | | - $Release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest" -Headers $GhHeaders -ErrorAction Stop |
40 | | - $Version = $Release.tag_name -replace "^v", "" |
41 | | -} catch {} |
42 | | - |
43 | | -# ── Header ── |
44 | | -Nl; Nl |
45 | | -Dim " "; Br "######## "; Acc " #### "; Nl |
46 | | -Dim " "; Br "## ## "; Acc " ## ## "; Nl |
47 | | -Dim " "; Br "## ## "; Acc "## ## "; Nl |
48 | | -Dim " "; Br "## ## "; Acc "######## "; Nl |
49 | | -Dim " "; Br "## ## "; Acc "## ## "; Nl |
50 | | -Dim " "; Br "######## "; Acc "## ## "; Nl |
51 | | -Nl |
52 | | -Write-Host " " -NoNewline |
53 | | -Write-Host "OpenAnalyst CLI" -NoNewline -ForegroundColor White |
54 | | -Dim " v$Version" |
55 | | -Nl |
56 | | -Dim " The Universal AI Agent for Your Terminal" |
57 | | -Nl; Nl |
58 | | -Dim " $(Repeat $H 44)"; Nl; Nl |
59 | | - |
60 | | -# ── System info ── |
61 | | -$OsLabel = "Windows" |
62 | | -$ArchLabel = if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" } |
63 | | -$BoxW = 42 |
64 | | - |
65 | | -Dim " $TL$(Repeat $H $BoxW)$TR"; Nl |
66 | | -Dim " $VL"; W " System "; Dim "$OsLabel $ArchLabel"; Dim (Pad ($BoxW - 15 - "$OsLabel $ArchLabel".Length)); Dim $VL; Nl |
67 | | -Dim " $VL"; W " Install to "; Dim "~\.openanalyst\bin"; Dim (Pad ($BoxW - 15 - 18)); Dim $VL; Nl |
68 | | -Dim " $VL"; W " Config at "; Dim "~\.openanalyst"; Dim (Pad ($BoxW - 15 - 14)); Dim $VL; Nl |
69 | | -Dim " $BL$(Repeat $H $BoxW)$BR"; Nl |
70 | | -Nl |
71 | | - |
72 | | -# ── Setup ── |
73 | | -New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null |
74 | | -New-Item -ItemType Directory -Force -Path $ConfigDir | Out-Null |
75 | | - |
76 | | -# ── Step 1: Download ── |
77 | | -$Downloaded = $false |
78 | | -Get-Process -Name "openanalyst" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue |
79 | | -Start-Sleep -Milliseconds 300 |
80 | | - |
81 | | -Dim " "; Acc "$([char]0x203A)"; Dim " Downloading binary..." |
82 | | -if ($Release) { |
83 | | - $Asset = $Release.assets | Where-Object { $_.name -eq "openanalyst.exe" } | Select-Object -First 1 |
84 | | - if (-not $Asset) { $Asset = $Release.assets | Where-Object { $_.name -like "*.exe" } | Select-Object -First 1 } |
85 | | - if ($Asset -and $Asset.browser_download_url) { $AssetUrl = $Asset.browser_download_url } |
86 | | - else { $AssetUrl = "https://github.com/$Repo/releases/download/$($Release.tag_name)/openanalyst.exe" } |
87 | | - try { |
88 | | - Invoke-WebRequest -Uri $AssetUrl -OutFile "$InstallDir\$BinaryName" -UseBasicParsing -ErrorAction Stop |
89 | | - $Downloaded = $true |
90 | | - Write-Host " " -NoNewline; Grn "$([char]0x2713)"; Dim " done"; Nl |
91 | | - } catch { |
92 | | - Write-Host " " -NoNewline; Yl "failed"; Nl |
93 | | - } |
94 | | -} else { |
95 | | - Write-Host " " -NoNewline; Yl "no release found"; Nl |
96 | | -} |
97 | | - |
98 | | -if (-not $Downloaded) { |
99 | | - Nl |
100 | | - Yl " Download failed. Visit:" |
101 | | - Nl |
102 | | - Acc " github.com/$Repo/releases" |
103 | | - Nl; Nl |
| 16 | +if (-not $NodeVersion) { |
| 17 | + Write-Host " Node.js is required but not found." -ForegroundColor Red |
| 18 | + Write-Host " Install from: https://nodejs.org/" -ForegroundColor DarkGray |
| 19 | + Write-Host "" |
104 | 20 | exit 1 |
105 | 21 | } |
106 | 22 |
|
107 | | -# ── Step 2: Install npm package (TUI + proper entry point) ── |
108 | | -Dim " "; Acc "$([char]0x203A)"; Dim " Installing TUI package..." |
| 23 | +Write-Host " Node.js $NodeVersion detected" -ForegroundColor DarkGray |
| 24 | + |
| 25 | +# Install via npm |
| 26 | +Write-Host "" |
| 27 | +Write-Host " Installing..." -ForegroundColor White -NoNewline |
| 28 | + |
109 | 29 | try { |
110 | | - $npmOutput = npm install -g @openanalystinc/openanalyst-cli@$Version 2>&1 |
111 | | - Write-Host " " -NoNewline; Grn "$([char]0x2713)"; Dim " npm package installed"; Nl |
| 30 | + npm install -g @openanalystinc/openanalyst-cli@latest 2>&1 | Out-Null |
| 31 | + Write-Host " done" -ForegroundColor Green |
112 | 32 | } catch { |
113 | | - Write-Host " " -NoNewline; Yl "npm install skipped"; Nl |
| 33 | + Write-Host " failed" -ForegroundColor Red |
| 34 | + Write-Host " Try manually: npm install -g @openanalystinc/openanalyst-cli" -ForegroundColor DarkGray |
| 35 | + exit 1 |
114 | 36 | } |
115 | 37 |
|
116 | | -# ── Step 3: PATH ── |
117 | | -Dim " "; Acc "$([char]0x203A)"; Dim " Configuring PATH..." |
118 | | -$CurrentPath = [Environment]::GetEnvironmentVariable("Path", "User") |
119 | | -if ($CurrentPath -notlike "*$InstallDir*") { |
120 | | - [Environment]::SetEnvironmentVariable("Path", "$InstallDir;$CurrentPath", "User") |
121 | | - $env:Path = "$InstallDir;$env:Path" |
122 | | - Write-Host " " -NoNewline; Grn "$([char]0x2713)"; Dim " added"; Nl |
123 | | -} else { |
124 | | - Write-Host " " -NoNewline; Grn "$([char]0x2713)"; Dim " already configured"; Nl |
125 | | -} |
| 38 | +# Verify |
| 39 | +$Version = $null |
| 40 | +try { $Version = (openanalyst --version 2>$null) } catch {} |
126 | 41 |
|
127 | | -# ── Step 3: Config ── |
128 | | -Dim " "; Acc "$([char]0x203A)"; Dim " Creating config..." |
129 | | -$EnvFile = "$ConfigDir\.env" |
130 | | -if (-not (Test-Path $EnvFile)) { |
131 | | - @" |
132 | | -# OpenAnalyst CLI — Environment Configuration |
133 | | -# OPENANALYST_API_KEY= |
134 | | -# ANTHROPIC_API_KEY=sk-ant-... |
135 | | -# OPENAI_API_KEY=sk-... |
136 | | -# GEMINI_API_KEY=AIza... |
137 | | -"@ | Out-File -FilePath $EnvFile -Encoding utf8 |
138 | | - Write-Host " " -NoNewline; Grn "$([char]0x2713)"; Dim " ~\.openanalyst\.env"; Nl |
| 42 | +Write-Host "" |
| 43 | +if ($Version) { |
| 44 | + Write-Host " $([char]0x2713) $Version" -ForegroundColor Green |
139 | 45 | } else { |
140 | | - Write-Host " " -NoNewline; Grn "$([char]0x2713)"; Dim " already exists"; Nl |
141 | | -} |
142 | | - |
143 | | -# ── Summary ── |
144 | | -Nl; Nl |
145 | | -Dim " $(Repeat $H 44)"; Nl; Nl |
146 | | -Write-Host " $([char]0x2713) Installation complete" -ForegroundColor Green |
147 | | -Nl; Nl |
148 | | - |
149 | | -$BinPath = "~\.openanalyst\bin\openanalyst" |
150 | | -$CfgPath = "~\.openanalyst\.env" |
151 | | -$VerStr = "v$Version" |
152 | | - |
153 | | -Dim " $TL$(Repeat $H $BoxW)$TR"; Nl |
154 | | -Dim " $VL$(Pad $BoxW)$VL"; Nl |
155 | | -Dim " $VL"; W " Binary "; Dim $BinPath; Dim (Pad ($BoxW - 13 - $BinPath.Length)); Dim $VL; Nl |
156 | | -Dim " $VL"; W " Config "; Dim $CfgPath; Dim (Pad ($BoxW - 13 - $CfgPath.Length)); Dim $VL; Nl |
157 | | -Dim " $VL"; W " Version "; Dim $VerStr; Dim (Pad ($BoxW - 13 - $VerStr.Length)); Dim $VL; Nl |
158 | | -Dim " $VL$(Pad $BoxW)$VL"; Nl |
159 | | -Dim " $BL$(Repeat $H $BoxW)$BR"; Nl |
160 | | -Nl |
161 | | - |
162 | | -# ── Next steps ── |
163 | | -Write-Host " Next steps" -ForegroundColor White |
164 | | -Nl |
165 | | -Acc " 1."; W " Login to your LLM provider"; Nl |
166 | | -Nl |
167 | | -Acc " `$ openanalyst login"; Nl |
168 | | -Nl |
169 | | -Dim " Select a provider, use the free model" |
170 | | -Nl |
171 | | -Dim " or paste your API key." |
172 | | -Nl; Nl |
173 | | -Acc " 2."; W " Start coding"; Nl |
174 | | -Nl |
175 | | -Acc " `$ openanalyst"; Nl |
176 | | -Nl; Nl |
177 | | - |
178 | | -# ── Provider list ── |
179 | | -Dim " $TL$(Repeat $H $BoxW)$TR"; Nl |
180 | | -Dim " $VL$(Pad $BoxW)$VL"; Nl |
181 | | -Dim " $VL"; W " 7 LLM Providers. One Interface."; Dim (Pad ($BoxW - 34)); Dim $VL; Nl |
182 | | -Dim " $VL$(Pad $BoxW)$VL"; Nl |
183 | | - |
184 | | -$providers = @( |
185 | | - @{ n="OpenAnalyst"; d="(default)" }, |
186 | | - @{ n="Anthropic / Claude"; d="direct API" }, |
187 | | - @{ n="OpenAI / Codex"; d="direct API" }, |
188 | | - @{ n="Google Gemini"; d="direct API" }, |
189 | | - @{ n="xAI / Grok"; d="" }, |
190 | | - @{ n="OpenRouter"; d="350+ models" }, |
191 | | - @{ n="Amazon Bedrock"; d="" } |
192 | | -) |
193 | | -foreach ($p in $providers) { |
194 | | - $name = $p.n |
195 | | - $desc = $p.d |
196 | | - Dim " $VL" |
197 | | - Acc " $([char]0x25A0)" |
198 | | - W " $name" |
199 | | - if ($desc) { |
200 | | - $used = 4 + $name.Length + 3 + $desc.Length |
201 | | - Dim (Pad ($BoxW - $used)) |
202 | | - Dim $desc |
203 | | - } else { |
204 | | - Dim (Pad ($BoxW - 4 - $name.Length)) |
205 | | - } |
206 | | - Dim $VL; Nl |
| 46 | + Write-Host " $([char]0x2713) Installed" -ForegroundColor Green |
207 | 47 | } |
208 | | -Dim " $VL$(Pad $BoxW)$VL"; Nl |
209 | | -Dim " $BL$(Repeat $H $BoxW)$BR"; Nl |
210 | | -Nl |
211 | 48 |
|
212 | | -Dim " Documentation: " |
213 | | -Acc "github.com/OpenAnalystInc/cli" |
214 | | -Nl |
215 | | -Dim " Support: " |
216 | | -Acc "support@openanalyst.com" |
217 | | -Nl; Nl |
| 49 | +Write-Host "" |
| 50 | +Write-Host " To get started:" -ForegroundColor White |
| 51 | +Write-Host "" |
| 52 | +Write-Host " openanalyst" -ForegroundColor Cyan |
| 53 | +Write-Host "" |
0 commit comments