@darkrei08/setup-ai 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/setup-ai.ps1 ADDED
@@ -0,0 +1,418 @@
1
+ #Requires -Version 7.0
2
+ <#
3
+ ==============================================================================
4
+ AI Dev Suite — Engineering Excellence Edition (Windows)
5
+ Version: 3.0.0
6
+
7
+ Windows-native installer, sibling of setup-ai.sh. Uses each tool's official
8
+ Windows method: winget for language runtimes, the vendor install.ps1 scripts
9
+ for the AI CLIs, `go install` for gentle-ai, npm for opencode, and
10
+ `npx skills` / `pi install` for skills and pi packages.
11
+
12
+ The Node launcher bin/setup-ai.mjs dispatches here on win32 and can pass a
13
+ module selection via -Only (from its interactive menu).
14
+
15
+ Usage:
16
+ pwsh -File setup-ai.ps1 # core module set
17
+ pwsh -File setup-ai.ps1 -All # every module (incl. GUI apps)
18
+ pwsh -File setup-ai.ps1 -Only pi,codex,opencode
19
+ pwsh -File setup-ai.ps1 -List
20
+ pwsh -File setup-ai.ps1 -Help
21
+ ==============================================================================
22
+ #>
23
+
24
+ [CmdletBinding()]
25
+ param(
26
+ [string]$Only = "",
27
+ [switch]$All,
28
+ [switch]$List,
29
+ [switch]$Yes,
30
+ [switch]$Help
31
+ )
32
+
33
+ $ErrorActionPreference = 'Stop'
34
+ Set-StrictMode -Version Latest
35
+
36
+ $ScriptVersion = "3.0.0"
37
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
38
+ $LogDir = Join-Path $ScriptDir "logs"
39
+ New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
40
+
41
+ $RunId = (Get-Date -AsUTC -Format "yyyyMMddTHHmmssZ")
42
+ $HumanLog = Join-Path $LogDir "setup_$RunId.log"
43
+ $JsonlLog = Join-Path $LogDir "setup_$RunId.jsonl"
44
+ $ReportFile = Join-Path $LogDir "engineering-report_$RunId.md"
45
+
46
+ $EE_Slug = "micio86dev/Engineering-Excellence"
47
+ $EE_Skill = "engineering-excellence"
48
+ $PiSkillDir = Join-Path $HOME ".pi\agent\skills\$EE_Skill"
49
+ $PiExtDir = Join-Path $HOME ".pi\agent\extensions"
50
+
51
+ # ------------------------------------------------------------------------------
52
+ # Logging (human + JSONL)
53
+ # ------------------------------------------------------------------------------
54
+
55
+ function Write-Log {
56
+ param(
57
+ [ValidateSet('INFO','WARN','ERROR','DEBUG')] [string]$Level,
58
+ [string]$Phase, [string]$Event, [string]$Message, [int]$ReturnCode = 0, [string]$Meta = ""
59
+ )
60
+ $ts = (Get-Date -AsUTC -Format "yyyy-MM-ddTHH:mm:ssZ")
61
+ $obj = [ordered]@{
62
+ timestamp = $ts; level = $Level; phase = $Phase; event = $Event
63
+ message = $Message; return_code = $ReturnCode; run_id = $RunId; pid = $PID
64
+ }
65
+ if ($Meta) { $obj.meta = $Meta }
66
+ ($obj | ConvertTo-Json -Compress) | Add-Content -Path $JsonlLog
67
+
68
+ $line = "$ts [$Level] $Phase $Event`: $Message"
69
+ $line | Add-Content -Path $HumanLog
70
+ switch ($Level) {
71
+ 'INFO' { Write-Host $line -ForegroundColor Blue }
72
+ 'WARN' { Write-Host $line -ForegroundColor Yellow }
73
+ 'ERROR' { Write-Host $line -ForegroundColor Red }
74
+ 'DEBUG' { if ($env:DEBUG -eq '1') { Write-Host $line -ForegroundColor DarkGray } }
75
+ default { Write-Host $line }
76
+ }
77
+ }
78
+
79
+ function Test-Cmd { param([string]$Name) [bool](Get-Command $Name -ErrorAction SilentlyContinue) }
80
+
81
+ # Run a step; $Optional means failures are logged as WARN and swallowed.
82
+ function Invoke-Step {
83
+ param([string]$Phase, [scriptblock]$Action, [switch]$Optional)
84
+ Write-Log INFO $Phase "step_start" "Running step"
85
+ try {
86
+ & $Action 2>&1 | Tee-Object -FilePath $HumanLog -Append | Out-Host
87
+ Write-Log INFO $Phase "step_ok" "Step completed"
88
+ return $true
89
+ } catch {
90
+ if ($Optional) {
91
+ Write-Log WARN $Phase "step_failed_optional" "$($_.Exception.Message); continuing" 1
92
+ return $false
93
+ }
94
+ Write-Log ERROR $Phase "step_failed" "$($_.Exception.Message)" 1
95
+ throw
96
+ }
97
+ }
98
+
99
+ function Install-Winget {
100
+ param([string]$Id, [string]$Phase)
101
+ if (-not (Test-Cmd winget)) {
102
+ Write-Log WARN $Phase "winget_missing" "winget not available; install '$Id' manually"
103
+ return
104
+ }
105
+ # Skip if already installed.
106
+ $installed = winget list --id $Id -e 2>$null | Select-String -SimpleMatch $Id
107
+ if ($installed) {
108
+ Write-Log INFO $Phase "already_present" "$Id already installed"
109
+ return
110
+ }
111
+ Invoke-Step -Phase $Phase -Optional -Action {
112
+ winget install -e --id $Id --accept-package-agreements --accept-source-agreements --silent
113
+ }
114
+ }
115
+
116
+ function Invoke-RemoteScript {
117
+ param([string]$Url, [string]$Phase)
118
+ # Mirrors the vendor's documented `irm <url> | iex`, but logged.
119
+ Invoke-Step -Phase $Phase -Optional -Action {
120
+ $script = Invoke-RestMethod -Uri $Url -UseBasicParsing
121
+ Invoke-Expression $script
122
+ }
123
+ }
124
+
125
+ # ==============================================================================
126
+ # Module registry
127
+ # ==============================================================================
128
+
129
+ $ModuleOrder = @('base','node','bun','pi','go','ee','pi-workflows','herdr','gentle-ai','engram','codex','antigravity','opencode','cockpit')
130
+
131
+ $ModuleDesc = [ordered]@{
132
+ 'base' = 'Core dev tools via winget (git, gh, python, neovim)'
133
+ 'node' = 'Node.js LTS (winget OpenJS.NodeJS.LTS) + npm@latest'
134
+ 'bun' = 'Bun runtime (bun.sh install.ps1)'
135
+ 'pi' = 'pi.dev coding agent CLI (pi.dev install.ps1)'
136
+ 'go' = 'Go toolchain (winget GoLang.Go)'
137
+ 'ee' = 'Engineering Excellence skill (npx skills add, detected agents)'
138
+ 'pi-workflows' = 'pi-extensible-workflows (module resolution fix for pi extensions)'
139
+ 'herdr' = 'herdr terminal multiplexer (herdr.dev install.ps1)'
140
+ 'gentle-ai' = 'gentle-ai (go install) + gentle-pi package'
141
+ 'engram' = 'Engram persistent memory for pi (gentle-engram: /remember /recall)'
142
+ 'codex' = 'OpenAI Codex CLI (chatgpt.com install.ps1)'
143
+ 'antigravity' = 'Google Antigravity CLI (antigravity.google install.ps1)'
144
+ 'opencode' = 'opencode agent CLI (npm opencode-ai)'
145
+ 'cockpit' = 'cockpit-tools desktop GUI (optional, .msi, CC BY-NC-SA)'
146
+ }
147
+ $ModuleOptional = @{ 'cockpit' = $true }
148
+
149
+ # ==============================================================================
150
+ # Modules
151
+ # ==============================================================================
152
+
153
+ function Mod-Base {
154
+ Write-Log INFO "base" "start" "Core dev tools (winget)"
155
+ Install-Winget -Id "Git.Git" -Phase "base"
156
+ Install-Winget -Id "GitHub.cli" -Phase "base"
157
+ Install-Winget -Id "Python.Python.3.12" -Phase "base"
158
+ Install-Winget -Id "Neovim.Neovim" -Phase "base"
159
+ }
160
+
161
+ function Mod-Node {
162
+ Write-Log INFO "node" "start" "Node.js"
163
+ if (-not (Test-Cmd node)) { Install-Winget -Id "OpenJS.NodeJS.LTS" -Phase "node" }
164
+ if (Test-Cmd npm) { Invoke-Step -Phase "node" -Optional -Action { npm install -g npm@latest } }
165
+ }
166
+
167
+ function Mod-Bun {
168
+ Write-Log INFO "bun" "start" "Bun"
169
+ if (Test-Cmd bun) { Write-Log INFO "bun" "already_present" "bun already installed"; return }
170
+ Invoke-RemoteScript -Url "https://bun.sh/install.ps1" -Phase "bun"
171
+ }
172
+
173
+ function Mod-Pi {
174
+ Write-Log INFO "pi" "start" "pi.dev CLI"
175
+ if (Test-Cmd pi) { Write-Log INFO "pi" "already_present" "pi already installed"; return }
176
+ Invoke-RemoteScript -Url "https://pi.dev/install.ps1" -Phase "pi"
177
+ New-Item -ItemType Directory -Force -Path $PiExtDir | Out-Null
178
+ New-Item -ItemType Directory -Force -Path (Join-Path $HOME ".pi\agent\skills") | Out-Null
179
+ }
180
+
181
+ function Mod-Go {
182
+ Write-Log INFO "go" "start" "Go toolchain"
183
+ if (Test-Cmd go) { Write-Log INFO "go" "already_present" "Go already installed"; return }
184
+ Install-Winget -Id "GoLang.Go" -Phase "go"
185
+ }
186
+
187
+ function Mod-Ee {
188
+ Write-Log INFO "ee" "start" "Engineering Excellence"
189
+ if (-not (Test-Cmd npx)) { Write-Log WARN "ee" "npx_missing" "npx not found; install node first"; return }
190
+ $agents = @{ pi = ".pi"; claude = ".claude"; gemini = ".gemini"; cursor = ".cursor"; antigravity = ".antigravity" }
191
+ $any = $false
192
+ foreach ($a in @('pi','claude','gemini','cursor','antigravity')) {
193
+ if (Test-Path (Join-Path $HOME $agents[$a])) {
194
+ Invoke-Step -Phase "ee" -Optional -Action {
195
+ npx --yes skills@latest add $EE_Slug --skill $EE_Skill --global --agent $a --copy --yes
196
+ }
197
+ $any = $true
198
+ }
199
+ }
200
+ if (-not $any) {
201
+ Invoke-Step -Phase "ee" -Optional -Action {
202
+ npx --yes skills@latest add $EE_Slug --skill $EE_Skill --global --agent pi --copy --yes
203
+ }
204
+ }
205
+ if (Test-Path (Join-Path $PiSkillDir "SKILL.md")) {
206
+ Write-Log INFO "ee" "skill_installed" "EE skill present for pi"
207
+ }
208
+ }
209
+
210
+ function Mod-PiWorkflows {
211
+ Write-Log INFO "pi-workflows" "start" "pi-extensible-workflows"
212
+ if (-not (Test-Cmd pi)) { Write-Log WARN "pi-workflows" "pi_missing" "pi not found; skipped"; return }
213
+ $ver = ""
214
+ try { $ver = (npm view pi-extensible-workflows version).Trim() } catch {}
215
+ if (-not $ver) { Write-Log WARN "pi-workflows" "version_unresolved" "Could not resolve version; skipped"; return }
216
+ Write-Log INFO "pi-workflows" "version" "Version $ver"
217
+ Invoke-Step -Phase "pi-workflows" -Optional -Action { pi install "npm:pi-extensible-workflows@$ver" }
218
+ New-Item -ItemType Directory -Force -Path $PiExtDir | Out-Null
219
+ Set-Content -Path (Join-Path $PiExtDir ".npmrc") -Value "ignore-scripts=false"
220
+ Push-Location $PiExtDir
221
+ try {
222
+ Invoke-Step -Phase "pi-workflows" -Optional -Action {
223
+ npm install --save-exact --no-audit --no-fund "pi-extensible-workflows@$ver"
224
+ }
225
+ Invoke-Step -Phase "pi-workflows" -Optional -Action {
226
+ node -e "console.log(require.resolve('pi-extensible-workflows',{paths:[process.cwd()]}))"
227
+ }
228
+ } finally { Pop-Location }
229
+ }
230
+
231
+ function Mod-Herdr {
232
+ Write-Log INFO "herdr" "start" "herdr"
233
+ if (Test-Cmd herdr) { Write-Log INFO "herdr" "already_present" "herdr already installed"; return }
234
+ Invoke-RemoteScript -Url "https://herdr.dev/install.ps1" -Phase "herdr"
235
+ }
236
+
237
+ function Mod-GentleAi {
238
+ Write-Log INFO "gentle-ai" "start" "gentle-ai"
239
+ if (-not (Test-Cmd gentle-ai) -and -not (Test-Cmd gga)) {
240
+ if (Test-Cmd go) {
241
+ Invoke-Step -Phase "gentle-ai" -Optional -Action {
242
+ go install github.com/gentleman-programming/gentle-ai/v2/cmd/gentle-ai@latest
243
+ }
244
+ } else {
245
+ Write-Log WARN "gentle-ai" "go_missing" "Go not found; cannot 'go install' gentle-ai on Windows"
246
+ }
247
+ }
248
+ if (Test-Cmd pi) {
249
+ Invoke-Step -Phase "gentle-ai" -Optional -Action { pi install npm:gentle-pi }
250
+ Invoke-Step -Phase "gentle-ai" -Optional -Action { pi install npm:pi-mcp-adapter }
251
+ Write-Log INFO "gentle-ai" "pi_enabled" "gentle-pi registered in pi (verify: /gentle-ai:status)"
252
+ }
253
+ @"
254
+ gentle-ai next steps (run yourself, per project):
255
+ 1) Set your API keys
256
+ 2) Run your selected agent
257
+ 3) Try: /sdd-new my-feature (in pi: /gentle-ai:status, /gentleman:models)
258
+ GGA (per project): gga init then gga install
259
+ "@ | Tee-Object -FilePath $HumanLog -Append | Out-Host
260
+ }
261
+
262
+ function Mod-Engram {
263
+ Write-Log INFO "engram" "start" "Engram memory (pi)"
264
+ # The gentle-engram pi extension auto-starts `engram serve`; the Engram Go
265
+ # binary must be on PATH first, or the extension loads but silently fails.
266
+ if (-not (Test-Cmd engram)) {
267
+ if (Test-Cmd go) {
268
+ Invoke-Step -Phase "engram" -Optional -Action {
269
+ go install github.com/Gentleman-Programming/engram/cmd/engram@latest
270
+ }
271
+ $goBin = Join-Path $HOME "go\bin"
272
+ if ((Test-Path (Join-Path $goBin "engram.exe")) -and ($env:Path -notlike "*$goBin*")) {
273
+ $env:Path = "$goBin;$env:Path"
274
+ }
275
+ } else {
276
+ Write-Log WARN "engram" "go_missing" "Go not found; cannot install engram binary (needed on PATH)"
277
+ }
278
+ }
279
+ if (-not (Test-Cmd pi)) { Write-Log WARN "engram" "pi_missing" "pi not found; skipped"; return }
280
+ Invoke-Step -Phase "engram" -Optional -Action { pi install npm:gentle-engram }
281
+ Invoke-Step -Phase "engram" -Optional -Action { pi install npm:pi-mcp-adapter }
282
+ Invoke-Step -Phase "engram" -Optional -Action { npm exec --yes --package gentle-engram@latest -- pi-engram init }
283
+ Write-Log INFO "engram" "enabled" "Engram enabled — RESTART pi, verify: mem_current_project / mem_doctor / 'engram tui'"
284
+ }
285
+
286
+ function Mod-Codex {
287
+ Write-Log INFO "codex" "start" "Codex CLI"
288
+ if (Test-Cmd codex) { Write-Log INFO "codex" "already_present" "codex already installed"; return }
289
+ Invoke-RemoteScript -Url "https://chatgpt.com/codex/install.ps1" -Phase "codex"
290
+ }
291
+
292
+ function Mod-Antigravity {
293
+ Write-Log INFO "antigravity" "start" "Antigravity CLI"
294
+ if (Test-Cmd agy) { Write-Log INFO "antigravity" "already_present" "agy already installed"; return }
295
+ Invoke-RemoteScript -Url "https://antigravity.google/cli/install.ps1" -Phase "antigravity"
296
+ }
297
+
298
+ function Mod-Opencode {
299
+ Write-Log INFO "opencode" "start" "opencode"
300
+ if (Test-Cmd opencode) { Write-Log INFO "opencode" "already_present" "opencode already installed"; return }
301
+ if (Test-Cmd npm) {
302
+ Invoke-Step -Phase "opencode" -Optional -Action { npm install -g opencode-ai }
303
+ } else {
304
+ Write-Log WARN "opencode" "npm_missing" "npm not found; install node first"
305
+ }
306
+ @"
307
+ OpenCode Go (paid) is hosted-model access; after install run: opencode auth login
308
+ The SAME key works in pi.dev — add a custom provider (baseUrl https://opencode.ai/zen/v1,
309
+ api openai-completions) or run /provider add. Docs: https://pi.dev/docs/latest/custom-provider
310
+ "@ | Tee-Object -FilePath $HumanLog -Append | Out-Host
311
+ }
312
+
313
+ function Mod-Cockpit {
314
+ Write-Log INFO "cockpit" "start" "cockpit-tools (GUI)"
315
+ Write-Log INFO "cockpit" "license_notice" "cockpit-tools is a desktop GUI app under CC BY-NC-SA 4.0"
316
+ try {
317
+ $rel = Invoke-RestMethod -Uri "https://api.github.com/repos/jlcodes99/cockpit-tools/releases/latest" -Headers @{ 'User-Agent' = 'setup-ai' }
318
+ $asset = $rel.assets | Where-Object { $_.name -match '\.msi$' } | Select-Object -First 1
319
+ if (-not $asset) { Write-Log WARN "cockpit" "no_msi" "No .msi asset in latest release; download manually"; return }
320
+ $msi = Join-Path $env:TEMP $asset.name
321
+ Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $msi
322
+ Invoke-Step -Phase "cockpit" -Optional -Action { Start-Process msiexec.exe -ArgumentList "/i `"$msi`" /qb" -Wait }
323
+ } catch {
324
+ Write-Log WARN "cockpit" "failed" "$($_.Exception.Message)"
325
+ }
326
+ }
327
+
328
+ $ModuleFn = @{
329
+ 'base' = ${function:Mod-Base}; 'node' = ${function:Mod-Node}; 'bun' = ${function:Mod-Bun}
330
+ 'pi' = ${function:Mod-Pi}; 'go' = ${function:Mod-Go}; 'ee' = ${function:Mod-Ee}
331
+ 'pi-workflows' = ${function:Mod-PiWorkflows}; 'herdr' = ${function:Mod-Herdr}
332
+ 'gentle-ai' = ${function:Mod-GentleAi}; 'engram' = ${function:Mod-Engram}
333
+ 'codex' = ${function:Mod-Codex}; 'antigravity' = ${function:Mod-Antigravity}
334
+ 'opencode' = ${function:Mod-Opencode}; 'cockpit' = ${function:Mod-Cockpit}
335
+ }
336
+
337
+ # ==============================================================================
338
+ # CLI / selection
339
+ # ==============================================================================
340
+
341
+ function Show-List {
342
+ Write-Host "AI Dev Suite $ScriptVersion — modules (core = installed by default):`n"
343
+ foreach ($m in $ModuleOrder) {
344
+ $tag = if ($ModuleOptional.ContainsKey($m)) { "optional" } else { "core " }
345
+ "{0,-10} {1,-14} {2}" -f "[$tag]", $m, $ModuleDesc[$m] | Write-Host
346
+ }
347
+ Write-Host "`nUse: -Only <csv> | -All | (default = core)"
348
+ }
349
+
350
+ function Show-Help {
351
+ Get-Content $MyInvocation.MyCommand.Path | Select-Object -First 30 | ForEach-Object { $_ }
352
+ Show-List
353
+ }
354
+
355
+ function Resolve-Selection {
356
+ $requested = @()
357
+ if ($All) {
358
+ $requested = $ModuleOrder
359
+ } elseif ($Only) {
360
+ foreach ($r in ($Only -split ',')) {
361
+ $r = $r.Trim()
362
+ if (-not $r) { continue }
363
+ if (-not $ModuleDesc.Contains($r)) { Write-Error "Unknown module: $r"; exit 2 }
364
+ $requested += $r
365
+ }
366
+ } else {
367
+ $requested = $ModuleOrder | Where-Object { -not $ModuleOptional.ContainsKey($_) }
368
+ }
369
+ # Order by ModuleOrder so dependencies run first.
370
+ return $ModuleOrder | Where-Object { $requested -contains $_ }
371
+ }
372
+
373
+ # ==============================================================================
374
+ # Main
375
+ # ==============================================================================
376
+
377
+ New-Item -ItemType File -Force -Path $HumanLog | Out-Null
378
+ New-Item -ItemType File -Force -Path $JsonlLog | Out-Null
379
+
380
+ if ($Help) { Show-Help; exit 0 }
381
+ if ($List) { Show-List; exit 0 }
382
+
383
+ Write-Log INFO "bootstrap" "start" "AI Dev Suite (Windows) started" 0 "script_version=$ScriptVersion"
384
+
385
+ $selected = Resolve-Selection
386
+ Write-Log INFO "bootstrap" "modules_selected" "Modules queued" 0 ("modules=" + ($selected -join ' '))
387
+
388
+ $failed = @()
389
+ foreach ($m in $selected) {
390
+ try { & $ModuleFn[$m] }
391
+ catch { $failed += $m; Write-Log ERROR "modules" "module_failed" "Module $m failed: $($_.Exception.Message)" 1 }
392
+ }
393
+
394
+ # Report
395
+ @"
396
+ # AI Dev Suite — Engineering Report (Windows)
397
+
398
+ **Script version:** $ScriptVersion
399
+ **Run ID:** $RunId
400
+ **Selected modules:** $($selected -join ' ')
401
+ **Failed modules:** $(if ($failed) { $failed -join ' ' } else { 'none' })
402
+
403
+ ## Versions
404
+ - Node: $(if (Test-Cmd node) { node --version } else { 'n/a' })
405
+ - npm: $(if (Test-Cmd npm) { npm --version } else { 'n/a' })
406
+ - Go: $(if (Test-Cmd go) { (go version) } else { 'n/a' })
407
+ - pi: $(if (Test-Cmd pi) { 'installed' } else { 'n/a' })
408
+
409
+ Logs: $HumanLog ; $JsonlLog
410
+ "@ | Set-Content -Path $ReportFile
411
+
412
+ Write-Host "`n============================================================" -ForegroundColor Green
413
+ Write-Host " AI Dev Suite (Windows) setup finished" -ForegroundColor Green
414
+ Write-Host "============================================================" -ForegroundColor Green
415
+ Write-Host "Modules : $($selected -join ' ')"
416
+ if ($failed) { Write-Host "Failed : $($failed -join ' ')" -ForegroundColor Yellow }
417
+ Write-Host "Report : $ReportFile"
418
+ Write-Host "`nNext: open a new terminal so PATH updates apply."