@cats-inc/cats-platform 0.1.7 → 0.1.9
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/README.md +8 -8
- package/build/desktop/bootstrapPage.d.ts.map +1 -1
- package/build/desktop/bootstrapPage.js +5 -1
- package/build/desktop/bootstrapPage.js.map +1 -1
- package/build/desktop/cliInventoryProbe.d.ts.map +1 -1
- package/build/desktop/cliInventoryProbe.js +12 -0
- package/build/desktop/cliInventoryProbe.js.map +1 -1
- package/build/desktop/contracts.d.ts +1 -1
- package/build/desktop/contracts.d.ts.map +1 -1
- package/build/desktop/contracts.js +4 -0
- package/build/desktop/contracts.js.map +1 -1
- package/build/desktop/main.js +41 -9
- package/build/desktop/main.js.map +1 -1
- package/build/desktop/packaging.d.ts.map +1 -1
- package/build/desktop/packaging.js +62 -0
- package/build/desktop/packaging.js.map +1 -1
- package/build/desktop/setupAssets.d.ts.map +1 -1
- package/build/desktop/setupAssets.js +134 -0
- package/build/desktop/setupAssets.js.map +1 -1
- package/build/desktop/updateInstallHandoff.d.ts +14 -0
- package/build/desktop/updateInstallHandoff.d.ts.map +1 -1
- package/build/desktop/updateInstallHandoff.js +23 -0
- package/build/desktop/updateInstallHandoff.js.map +1 -1
- package/build/desktop/updateManager.d.ts.map +1 -1
- package/build/desktop/updateManager.js +8 -0
- package/build/desktop/updateManager.js.map +1 -1
- package/build/desktop/updaterAdapter.d.ts +16 -1
- package/build/desktop/updaterAdapter.d.ts.map +1 -1
- package/build/desktop/updaterAdapter.js +49 -2
- package/build/desktop/updaterAdapter.js.map +1 -1
- package/build/renderer/assets/{ActiveSessionPermissionChip-BRMLwkvf.js → ActiveSessionPermissionChip-Dl2UOFgh.js} +1 -1
- package/build/renderer/assets/{App-BM2nzo6s.js → App-C57f4p8k.js} +1 -1
- package/build/renderer/assets/{App-CVQAwCMi.js → App-CPqGDXVi.js} +1 -1
- package/build/renderer/assets/{App-Dl5FLaR_.js → App-ChvP0G9X.js} +1 -1
- package/build/renderer/assets/{WorkspaceAppRoutes-C3DUzdbj.js → WorkspaceAppRoutes-DYg2vnjz.js} +1 -1
- package/build/renderer/assets/{app-hP5h2jAt.js → app-DVN9Ghrk.js} +3 -3
- package/build/renderer/assets/{conversationSidebarRecentEntries-B-mNvfiy.js → conversationSidebarRecentEntries-XZVCnMLw.js} +1 -1
- package/build/renderer/assets/{useDraftSessionChips-DuXIoptW.js → useDraftSessionChips-By3XXabI.js} +1 -1
- package/build/renderer/index.html +1 -1
- package/build/server/shared/providerCatalog.d.ts +2 -2
- package/build/server/shared/providerCatalog.d.ts.map +1 -1
- package/build/server/shared/providerCatalogData.d.ts +11 -1
- package/build/server/shared/providerCatalogData.d.ts.map +1 -1
- package/build/server/shared/providerCatalogData.js +8 -0
- package/build/server/shared/providerCatalogData.js.map +1 -1
- package/build/server/shared/providerCatalogInstances.d.ts.map +1 -1
- package/build/server/shared/providerCatalogInstances.js +6 -0
- package/build/server/shared/providerCatalogInstances.js.map +1 -1
- package/package.json +6 -3
- package/scripts/README.md +51 -2
- package/scripts/linux/install-aider.sh +8 -0
- package/scripts/linux/install-cline.sh +8 -0
- package/scripts/linux/install-devin.sh +8 -0
- package/scripts/linux/install-grok.sh +8 -0
- package/scripts/linux/install-pi.sh +1 -1
- package/scripts/linux/node-cli-common.sh +43 -3
- package/scripts/linux/provider-cli-common.sh +162 -24
- package/scripts/linux/test-linux-package-smoke.sh +16 -0
- package/scripts/linux/upgrade-cli-tools.sh +2 -2
- package/scripts/macos/install-aider.sh +8 -0
- package/scripts/macos/install-cline.sh +8 -0
- package/scripts/macos/install-devin.sh +8 -0
- package/scripts/macos/install-grok.sh +8 -0
- package/scripts/macos/install-pi.sh +1 -1
- package/scripts/macos/node-cli-common.sh +43 -3
- package/scripts/macos/provider-cli-common.sh +162 -24
- package/scripts/macos/test-macos-package-smoke.sh +15 -0
- package/scripts/macos/upgrade-cli-tools.sh +2 -2
- package/scripts/windows/Check-WindowsSetupReadiness.ps1 +32 -1
- package/scripts/windows/Install-Aider.ps1 +368 -0
- package/scripts/windows/Install-Cline.ps1 +39 -0
- package/scripts/windows/Install-Devin.ps1 +385 -0
- package/scripts/windows/Install-Grok.ps1 +355 -0
- package/scripts/windows/Install-Pi.ps1 +1 -1
- package/scripts/windows/Test-WindowsInstallerSmoke.ps1 +23 -0
- package/scripts/windows/_NpmCliInstaller.ps1 +41 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Install or verify the native Windows Grok CLI for Cats.
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Cats-owned packaged setup wrapper for xAI's Grok CLI. The official
|
|
7
|
+
installer places grok.exe and an agent.exe alias in
|
|
8
|
+
%USERPROFILE%\.grok\bin. Detection intentionally uses only grok; uninstall
|
|
9
|
+
removes only those two fixed installer-owned paths and never resolves a
|
|
10
|
+
generic agent command from PATH.
|
|
11
|
+
#>
|
|
12
|
+
param(
|
|
13
|
+
[switch]$CheckOnly,
|
|
14
|
+
[switch]$Apply,
|
|
15
|
+
[switch]$Upgrade,
|
|
16
|
+
[switch]$Force,
|
|
17
|
+
[switch]$Uninstall,
|
|
18
|
+
[switch]$DryRun,
|
|
19
|
+
[switch]$Json,
|
|
20
|
+
[switch]$AllowAdmin,
|
|
21
|
+
[ValidateSet('auto', 'installed', 'missing')]
|
|
22
|
+
[string]$InstallState = 'auto',
|
|
23
|
+
[string]$DetectedVersion = '',
|
|
24
|
+
[switch]$SkipInstaller
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
Set-StrictMode -Version Latest
|
|
28
|
+
$ErrorActionPreference = 'Stop'
|
|
29
|
+
|
|
30
|
+
. (Join-Path $PSScriptRoot '_HiddenProcess.ps1')
|
|
31
|
+
. (Join-Path $PSScriptRoot '_PackagedUninstall.ps1')
|
|
32
|
+
|
|
33
|
+
function Write-StructuredResult {
|
|
34
|
+
param(
|
|
35
|
+
[pscustomobject]$Result,
|
|
36
|
+
[int]$ExitCode
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
if ($Json) {
|
|
40
|
+
$Result | ConvertTo-Json -Depth 10
|
|
41
|
+
} else {
|
|
42
|
+
Write-Host "Mode: $($Result.mode)"
|
|
43
|
+
Write-Host "Status: $($Result.status)"
|
|
44
|
+
Write-Host "Installed: $($Result.installed)"
|
|
45
|
+
if ($Result.detectedVersion) { Write-Host "Version: $($Result.detectedVersion)" }
|
|
46
|
+
foreach ($action in $Result.plannedActions) { Write-Host "Planned action: $action" }
|
|
47
|
+
foreach ($warning in $Result.warnings) { Write-Host "Warning: $warning" }
|
|
48
|
+
foreach ($step in $Result.manualSteps) { Write-Host "Manual step: $step" }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
exit $ExitCode
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function Resolve-GrokInstallDir {
|
|
55
|
+
return Join-Path $env:USERPROFILE '.grok\bin'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function Resolve-GrokExecutablePath {
|
|
59
|
+
return Join-Path (Resolve-GrokInstallDir) 'grok.exe'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function Resolve-GrokInstallerAliasPath {
|
|
63
|
+
return Join-Path (Resolve-GrokInstallDir) 'agent.exe'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function Refresh-UserPath {
|
|
67
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'User') + ';' +
|
|
68
|
+
[System.Environment]::GetEnvironmentVariable('Path', 'Machine')
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function Detect-GrokInstall {
|
|
72
|
+
$exePath = Resolve-GrokExecutablePath
|
|
73
|
+
|
|
74
|
+
if ($InstallState -eq 'installed') {
|
|
75
|
+
return [pscustomobject]@{
|
|
76
|
+
installed = $true
|
|
77
|
+
commandPath = $exePath
|
|
78
|
+
detectedVersion = $DetectedVersion
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if ($InstallState -eq 'missing') {
|
|
82
|
+
return [pscustomobject]@{
|
|
83
|
+
installed = $false
|
|
84
|
+
commandPath = $exePath
|
|
85
|
+
detectedVersion = $DetectedVersion
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Refresh-UserPath
|
|
90
|
+
$command = Get-Command grok -ErrorAction SilentlyContinue
|
|
91
|
+
$installed = $null -ne $command -or (Test-Path -LiteralPath $exePath -PathType Leaf)
|
|
92
|
+
$commandPath = if ($null -ne $command) { $command.Source } else { $exePath }
|
|
93
|
+
$commandSource = if ($null -ne $command) { $command.Source } else { '' }
|
|
94
|
+
$version = $DetectedVersion
|
|
95
|
+
$versionProbePath = Resolve-HiddenVersionProbePath `
|
|
96
|
+
-PreferredPath $commandSource `
|
|
97
|
+
-FallbackPath $exePath
|
|
98
|
+
|
|
99
|
+
if ($installed -and [string]::IsNullOrWhiteSpace($version) -and $versionProbePath) {
|
|
100
|
+
try {
|
|
101
|
+
$version = Get-HiddenCommandText -FileName $versionProbePath -ArgumentList @('--version')
|
|
102
|
+
} catch {
|
|
103
|
+
$version = ''
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return [pscustomobject]@{
|
|
108
|
+
installed = $installed
|
|
109
|
+
commandPath = $commandPath
|
|
110
|
+
detectedVersion = $version
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function Add-GrokToUserPath {
|
|
115
|
+
$installDir = Resolve-GrokInstallDir
|
|
116
|
+
$userPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
|
|
117
|
+
if ([string]::IsNullOrWhiteSpace($userPath)) {
|
|
118
|
+
[System.Environment]::SetEnvironmentVariable('Path', $installDir, 'User')
|
|
119
|
+
} elseif ($userPath -notlike "*$installDir*") {
|
|
120
|
+
[System.Environment]::SetEnvironmentVariable('Path', "$installDir;$userPath", 'User')
|
|
121
|
+
}
|
|
122
|
+
Refresh-UserPath
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function Invoke-GrokInstaller {
|
|
126
|
+
if ($SkipInstaller) {
|
|
127
|
+
return [pscustomobject]@{ skipped = $true; success = $true; exitCode = 0; stderr = '' }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
$tempScript = [System.IO.Path]::Combine(
|
|
131
|
+
[System.IO.Path]::GetTempPath(),
|
|
132
|
+
"cats-grok-install-$([System.Guid]::NewGuid().ToString('N')).ps1"
|
|
133
|
+
)
|
|
134
|
+
$stdoutPath = "$tempScript.stdout"
|
|
135
|
+
$stderrPath = "$tempScript.stderr"
|
|
136
|
+
$bootstrap = @'
|
|
137
|
+
& {
|
|
138
|
+
$previousErrorActionPreference = $ErrorActionPreference
|
|
139
|
+
try {
|
|
140
|
+
Invoke-RestMethod 'https://x.ai/cli/install.ps1' | Invoke-Expression
|
|
141
|
+
} finally {
|
|
142
|
+
$ErrorActionPreference = $previousErrorActionPreference
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
'@
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
[System.IO.File]::WriteAllText(
|
|
149
|
+
$tempScript,
|
|
150
|
+
$bootstrap,
|
|
151
|
+
[System.Text.UTF8Encoding]::new($false)
|
|
152
|
+
)
|
|
153
|
+
$powerShellExe = if (Get-Command pwsh.exe -ErrorAction SilentlyContinue) {
|
|
154
|
+
'pwsh.exe'
|
|
155
|
+
} else {
|
|
156
|
+
'powershell.exe'
|
|
157
|
+
}
|
|
158
|
+
$process = Start-Process -FilePath $powerShellExe `
|
|
159
|
+
-ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $tempScript) `
|
|
160
|
+
-Wait -PassThru -NoNewWindow `
|
|
161
|
+
-RedirectStandardOutput $stdoutPath `
|
|
162
|
+
-RedirectStandardError $stderrPath
|
|
163
|
+
$stderrRaw = if (Test-Path -LiteralPath $stderrPath -PathType Leaf) {
|
|
164
|
+
Get-Content -LiteralPath $stderrPath -Raw -ErrorAction SilentlyContinue
|
|
165
|
+
} else { $null }
|
|
166
|
+
|
|
167
|
+
return [pscustomobject]@{
|
|
168
|
+
skipped = $false
|
|
169
|
+
success = ($process.ExitCode -eq 0)
|
|
170
|
+
exitCode = $process.ExitCode
|
|
171
|
+
stderr = if ($null -eq $stderrRaw) { '' } else { [string]$stderrRaw }
|
|
172
|
+
}
|
|
173
|
+
} catch {
|
|
174
|
+
return [pscustomobject]@{
|
|
175
|
+
skipped = $false
|
|
176
|
+
success = $false
|
|
177
|
+
exitCode = -1
|
|
178
|
+
stderr = "Failed to invoke Grok installer: $($_.Exception.Message)"
|
|
179
|
+
}
|
|
180
|
+
} finally {
|
|
181
|
+
foreach ($path in @($tempScript, $stdoutPath, $stderrPath)) {
|
|
182
|
+
if (Test-Path -LiteralPath $path -PathType Leaf) {
|
|
183
|
+
Remove-Item -LiteralPath $path -Force -ErrorAction SilentlyContinue
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (-not $CheckOnly -and -not $Apply -and -not $Upgrade -and -not $Force -and -not $Uninstall) {
|
|
190
|
+
$CheckOnly = $true
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
$mutationCount = @($Apply, $Upgrade, $Force | Where-Object { $_ }).Count
|
|
194
|
+
if ($Uninstall -and ($CheckOnly -or $mutationCount -gt 0)) {
|
|
195
|
+
throw 'Install-Grok.ps1 -Uninstall is mutually exclusive with other modes.'
|
|
196
|
+
}
|
|
197
|
+
if ($CheckOnly -and $mutationCount -gt 0) {
|
|
198
|
+
throw 'Install-Grok.ps1 accepts either -CheckOnly or one mutation mode.'
|
|
199
|
+
}
|
|
200
|
+
if ($mutationCount -gt 1) {
|
|
201
|
+
throw 'Install-Grok.ps1 accepts at most one of -Apply / -Upgrade / -Force.'
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
$executionMode = if ($Uninstall) {
|
|
205
|
+
'uninstall'
|
|
206
|
+
} elseif ($CheckOnly) {
|
|
207
|
+
'check'
|
|
208
|
+
} elseif ($Force) {
|
|
209
|
+
'force'
|
|
210
|
+
} elseif ($Upgrade) {
|
|
211
|
+
'upgrade'
|
|
212
|
+
} else {
|
|
213
|
+
'apply'
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if ($Uninstall) {
|
|
217
|
+
Invoke-PackagedProviderUninstall `
|
|
218
|
+
-HelperId 'windows-grok-native-installer' `
|
|
219
|
+
-UserBinaryPath (Resolve-GrokExecutablePath) `
|
|
220
|
+
-ExtraUserOwnedPaths @((Resolve-GrokInstallerAliasPath)) `
|
|
221
|
+
-RedetectCommand { Detect-GrokInstall } `
|
|
222
|
+
-EmitJson:$Json `
|
|
223
|
+
-DryRun:$DryRun
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).
|
|
227
|
+
IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
228
|
+
if ($isAdmin -and -not $AllowAdmin) {
|
|
229
|
+
Write-StructuredResult -Result ([pscustomobject]@{
|
|
230
|
+
helper = 'windows-grok-native-installer'
|
|
231
|
+
mode = $executionMode
|
|
232
|
+
status = 'failed'
|
|
233
|
+
installed = $false
|
|
234
|
+
detectedVersion = $null
|
|
235
|
+
commandPath = Resolve-GrokExecutablePath
|
|
236
|
+
restartRequired = $false
|
|
237
|
+
plannedActions = @()
|
|
238
|
+
warnings = @('Refusing to run under an elevated shell without -AllowAdmin because Grok CLI is intended for user-scoped installation.')
|
|
239
|
+
appliedChanges = @()
|
|
240
|
+
manualSteps = @()
|
|
241
|
+
interruptions = @()
|
|
242
|
+
}) -ExitCode 1
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
$detected = Detect-GrokInstall
|
|
246
|
+
$plannedActions = [System.Collections.Generic.List[string]]::new()
|
|
247
|
+
$appliedChanges = [System.Collections.Generic.List[string]]::new()
|
|
248
|
+
$warnings = [System.Collections.Generic.List[string]]::new()
|
|
249
|
+
$manualSteps = [System.Collections.Generic.List[string]]::new()
|
|
250
|
+
|
|
251
|
+
if ($Force) {
|
|
252
|
+
$plannedActions.Add('reinstall_grok_native')
|
|
253
|
+
} elseif ($Upgrade -and $detected.installed) {
|
|
254
|
+
$plannedActions.Add('upgrade_grok_native')
|
|
255
|
+
} elseif (-not $detected.installed) {
|
|
256
|
+
$plannedActions.Add('install_grok_native')
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if ($CheckOnly) {
|
|
260
|
+
Write-StructuredResult -Result ([pscustomobject]@{
|
|
261
|
+
helper = 'windows-grok-native-installer'
|
|
262
|
+
mode = 'check'
|
|
263
|
+
status = if ($detected.installed) { 'ready' } else { 'not_installed' }
|
|
264
|
+
installed = [bool]$detected.installed
|
|
265
|
+
detectedVersion = if ($detected.detectedVersion) { $detected.detectedVersion } else { $null }
|
|
266
|
+
commandPath = $detected.commandPath
|
|
267
|
+
restartRequired = $false
|
|
268
|
+
plannedActions = $plannedActions.ToArray()
|
|
269
|
+
warnings = @()
|
|
270
|
+
appliedChanges = @()
|
|
271
|
+
manualSteps = @()
|
|
272
|
+
interruptions = @()
|
|
273
|
+
}) -ExitCode 0
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
$shouldInstall = $Force -or $Upgrade -or -not $detected.installed
|
|
277
|
+
$installFailed = $false
|
|
278
|
+
$installSkipped = $false
|
|
279
|
+
if ($shouldInstall) {
|
|
280
|
+
if ($DryRun) {
|
|
281
|
+
$warnings.Add('Dry-run requested; Grok installer invocation was skipped.')
|
|
282
|
+
$installSkipped = $true
|
|
283
|
+
} else {
|
|
284
|
+
$installResult = Invoke-GrokInstaller
|
|
285
|
+
$installSkipped = [bool]$installResult.skipped
|
|
286
|
+
$installFailed = (-not $installSkipped) -and (-not $installResult.success)
|
|
287
|
+
if ($installSkipped) {
|
|
288
|
+
$warnings.Add('Installer invocation was skipped by request.')
|
|
289
|
+
} elseif ($installFailed) {
|
|
290
|
+
$stderrSnippet = if ([string]::IsNullOrWhiteSpace($installResult.stderr)) {
|
|
291
|
+
'no stderr captured'
|
|
292
|
+
} else {
|
|
293
|
+
($installResult.stderr.Trim() -split "`r?`n" |
|
|
294
|
+
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
|
|
295
|
+
Select-Object -Last 8) -join ' | '
|
|
296
|
+
}
|
|
297
|
+
$warnings.Add("Grok installer exited $($installResult.exitCode): $stderrSnippet")
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
Start-Sleep -Seconds 2
|
|
301
|
+
Add-GrokToUserPath
|
|
302
|
+
$detected = Detect-GrokInstall
|
|
303
|
+
if (-not $detected.installed -and -not $installSkipped -and -not $installFailed) {
|
|
304
|
+
$warnings.Add('Grok installation completed but grok.exe was not detected at the expected path.')
|
|
305
|
+
$installFailed = $true
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (-not $installFailed -and -not ($DryRun -and $shouldInstall)) {
|
|
310
|
+
if ($Force) {
|
|
311
|
+
$appliedChanges.Add('reinstall_grok_native')
|
|
312
|
+
} elseif ($Upgrade) {
|
|
313
|
+
$appliedChanges.Add('upgrade_grok_native')
|
|
314
|
+
} else {
|
|
315
|
+
$appliedChanges.Add('install_grok_native')
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
$manualSteps.Add('Run `grok login` or set XAI_API_KEY before first use.')
|
|
321
|
+
$interruptions = [System.Collections.Generic.List[object]]::new()
|
|
322
|
+
if ($shouldInstall -and -not $installFailed -and -not $DryRun) {
|
|
323
|
+
$interruptions.Add([pscustomobject]@{
|
|
324
|
+
kind = 'relaunch_required'
|
|
325
|
+
summary = 'Relaunch Cats Desktop Host after the Grok install step, then rerun the packaged setup check.'
|
|
326
|
+
resumable = $true
|
|
327
|
+
requiresRestart = $false
|
|
328
|
+
requiresElevation = $false
|
|
329
|
+
})
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
$status = if ($installFailed) {
|
|
333
|
+
'failed'
|
|
334
|
+
} elseif ($DryRun -and $shouldInstall) {
|
|
335
|
+
'preview'
|
|
336
|
+
} elseif ($interruptions.Count -gt 0) {
|
|
337
|
+
[string]$interruptions[0].kind
|
|
338
|
+
} else {
|
|
339
|
+
'ready'
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
Write-StructuredResult -Result ([pscustomobject]@{
|
|
343
|
+
helper = 'windows-grok-native-installer'
|
|
344
|
+
mode = $executionMode
|
|
345
|
+
status = $status
|
|
346
|
+
installed = [bool]$detected.installed
|
|
347
|
+
detectedVersion = if ($detected.detectedVersion) { $detected.detectedVersion } else { $null }
|
|
348
|
+
commandPath = $detected.commandPath
|
|
349
|
+
restartRequired = $false
|
|
350
|
+
plannedActions = $plannedActions.ToArray()
|
|
351
|
+
warnings = $warnings.ToArray()
|
|
352
|
+
appliedChanges = $appliedChanges.ToArray()
|
|
353
|
+
manualSteps = $manualSteps.ToArray()
|
|
354
|
+
interruptions = $interruptions.ToArray()
|
|
355
|
+
}) -ExitCode $(if ($installFailed) { 1 } else { 0 })
|
|
@@ -22,7 +22,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
22
22
|
|
|
23
23
|
Invoke-PackagedNpmCliInstall `
|
|
24
24
|
-HelperId 'windows-pi-native-installer' `
|
|
25
|
-
-PackageName '@
|
|
25
|
+
-PackageName '@earendil-works/pi-coding-agent' `
|
|
26
26
|
-CommandName 'pi' `
|
|
27
27
|
-DisplayName 'Pi Coding Agent' `
|
|
28
28
|
-CheckOnly:$CheckOnly `
|
|
@@ -195,6 +195,7 @@ $requiredFiles = @(
|
|
|
195
195
|
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\_NpmCliInstaller.ps1'); Label = 'bundled Windows shared npm CLI installer helper' },
|
|
196
196
|
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-Codex.ps1'); Label = 'bundled Windows native OpenAI Codex installer helper' },
|
|
197
197
|
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-Antigravity.ps1'); Label = 'bundled Windows native Antigravity installer helper' },
|
|
198
|
+
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-Grok.ps1'); Label = 'bundled Windows native Grok installer helper' },
|
|
198
199
|
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-Copilot.ps1'); Label = 'bundled Windows native GitHub Copilot installer helper' },
|
|
199
200
|
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-OpenCode.ps1'); Label = 'bundled Windows native OpenCode installer helper' },
|
|
200
201
|
@{ Path = (Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-KiloCli.ps1'); Label = 'bundled Windows native Kilo Code installer helper' },
|
|
@@ -216,6 +217,26 @@ foreach ($requiredFile in $requiredFiles) {
|
|
|
216
217
|
Assert-FileExists -Path $requiredFile.Path -Label $requiredFile.Label
|
|
217
218
|
}
|
|
218
219
|
|
|
220
|
+
$grokHelperPath = Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-Grok.ps1'
|
|
221
|
+
$grokCheck = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $grokHelperPath `
|
|
222
|
+
-CheckOnly -Json -AllowAdmin | ConvertFrom-Json
|
|
223
|
+
Assert-True ($grokCheck.helper -eq 'windows-grok-native-installer') `
|
|
224
|
+
'bundled Windows Grok helper check mode completed'
|
|
225
|
+
$grokPreview = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $grokHelperPath `
|
|
226
|
+
-Force -DryRun -Json -AllowAdmin | ConvertFrom-Json
|
|
227
|
+
Assert-True ($grokPreview.status -eq 'preview') `
|
|
228
|
+
'bundled Windows Grok helper dry-run mode completed'
|
|
229
|
+
|
|
230
|
+
$clineHelperPath = Join-Path $resourcesRoot 'desktop\setup-assets\windows\Install-Cline.ps1'
|
|
231
|
+
$clineCheck = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $clineHelperPath `
|
|
232
|
+
-CheckOnly -Json -AllowAdmin | ConvertFrom-Json
|
|
233
|
+
Assert-True ($clineCheck.helper -eq 'windows-cline-native-installer') `
|
|
234
|
+
'bundled Windows Cline helper check mode completed'
|
|
235
|
+
$clinePreview = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $clineHelperPath `
|
|
236
|
+
-Force -DryRun -Json -AllowAdmin -SkipNpmInvocation | ConvertFrom-Json
|
|
237
|
+
Assert-True ($clinePreview.status -eq 'preview') `
|
|
238
|
+
'bundled Windows Cline helper dry-run mode completed'
|
|
239
|
+
|
|
219
240
|
$packagingPlan = Read-JsonFile -Path $packagingPlanPath
|
|
220
241
|
Assert-True ($packagingPlan.strategy -eq 'electron-sidecar-bundle') 'installer packaging strategy is electron-sidecar-bundle'
|
|
221
242
|
Assert-True ($packagingPlan.selfHostedNpmCompatible -eq $true) 'installer keeps self-hosted npm compatibility'
|
|
@@ -232,6 +253,7 @@ Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-githu
|
|
|
232
253
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-npm-prefix-helper-script' }).Count -ge 1) 'Windows target includes the bundled npm prefix setup asset'
|
|
233
254
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-codex-native-installer-script' }).Count -ge 1) 'Windows target includes the bundled native OpenAI Codex installer asset'
|
|
234
255
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-antigravity-native-installer-script' }).Count -ge 1) 'Windows target includes the bundled native Antigravity installer asset'
|
|
256
|
+
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-grok-native-installer-script' }).Count -ge 1) 'Windows target includes the bundled native Grok installer asset'
|
|
235
257
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-copilot-native-installer-script' }).Count -ge 1) 'Windows target includes the bundled native GitHub Copilot installer asset'
|
|
236
258
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-opencode-native-installer-script' }).Count -ge 1) 'Windows target includes the bundled native OpenCode installer asset'
|
|
237
259
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-kilo-native-installer-script' }).Count -ge 1) 'Windows target includes the bundled native Kilo installer asset'
|
|
@@ -246,6 +268,7 @@ Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-ollam
|
|
|
246
268
|
Assert-True (($windowsTarget.artifacts | Where-Object { $_.id -eq 'windows-setup-readiness-audit-script' }).Count -ge 1) 'Windows target includes the bundled setup readiness audit asset'
|
|
247
269
|
Assert-True (($packagingPlan.installer.providerSetup.localProviders | Where-Object { $_.id -eq 'opencode' -and $_.bundledInCurrentInstaller -eq $true }).Count -ge 1) 'installer contract keeps OpenCode in the bundled local-provider rollout'
|
|
248
270
|
Assert-True (($packagingPlan.installer.providerSetup.localProviders | Where-Object { $_.id -eq 'kilo' -and $_.bundledInCurrentInstaller -eq $true }).Count -ge 1) 'installer contract keeps Kilo in the bundled local-provider rollout'
|
|
271
|
+
Assert-True (($packagingPlan.installer.providerSetup.localProviders | Where-Object { $_.id -eq 'grok' -and $_.bundledInCurrentInstaller -eq $true }).Count -ge 1) 'installer contract keeps Grok in the bundled local-provider rollout'
|
|
249
272
|
Assert-True (($packagingPlan.installer.providerSetup.localProviders | Where-Object { $_.id -eq 'ollama' -and $_.bundledInCurrentInstaller -eq $true }).Count -ge 1) 'installer contract keeps Ollama in the bundled local-provider rollout'
|
|
250
273
|
Assert-True (($packagingPlan.installer.providerSetup.helperCatalog | Where-Object { $_.id -eq 'windows-ollama-local-model-installer' }).Count -ge 1) 'installer contract includes the bundled Ollama helper metadata'
|
|
251
274
|
|
|
@@ -183,6 +183,45 @@ function Resolve-NpmCliCommandPath {
|
|
|
183
183
|
return $null
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
function Get-SupersededNpmPackages {
|
|
187
|
+
<#
|
|
188
|
+
Packages whose npm name changed upstream. npm resolves an abandoned name to
|
|
189
|
+
its final published version and reports it as current forever, so
|
|
190
|
+
`npm outdated -g` never flags it and every upgrade path silently skips it.
|
|
191
|
+
Two packages shipping the same bin also fight over the shim, which resolves
|
|
192
|
+
to whichever installed last. The superseded package is therefore removed
|
|
193
|
+
before its replacement is installed, matching environment-bootstrap cfe7785.
|
|
194
|
+
#>
|
|
195
|
+
param(
|
|
196
|
+
[Parameter(Mandatory = $true)]
|
|
197
|
+
[string]$PackageName
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
switch ($PackageName) {
|
|
201
|
+
'@earendil-works/pi-coding-agent' { @('@mariozechner/pi-coding-agent') }
|
|
202
|
+
default { @() }
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function Remove-SupersededNpmPackages {
|
|
207
|
+
param(
|
|
208
|
+
[Parameter(Mandatory = $true)]
|
|
209
|
+
[string]$PackageName,
|
|
210
|
+
[System.Collections.ArrayList]$AppliedChanges
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
foreach ($legacy in (Get-SupersededNpmPackages -PackageName $PackageName)) {
|
|
214
|
+
& npm list -g --depth=0 $legacy 2>$null | Out-Null
|
|
215
|
+
if ($LASTEXITCODE -ne 0) { continue }
|
|
216
|
+
|
|
217
|
+
Write-Host "Removing superseded package $legacy (replaced by $PackageName)."
|
|
218
|
+
& npm uninstall -g $legacy 2>$null | Out-Null
|
|
219
|
+
if ($AppliedChanges) {
|
|
220
|
+
$AppliedChanges.Add("${legacy}:removed-superseded") | Out-Null
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
186
225
|
function Invoke-PackagedNpmCliInstall {
|
|
187
226
|
param(
|
|
188
227
|
[Parameter(Mandatory = $true)]
|
|
@@ -520,6 +559,8 @@ function Invoke-PackagedNpmCliInstall {
|
|
|
520
559
|
exit 0
|
|
521
560
|
}
|
|
522
561
|
|
|
562
|
+
Remove-SupersededNpmPackages -PackageName $PackageName -AppliedChanges $appliedChanges
|
|
563
|
+
|
|
523
564
|
# --include=optional defends against user-level `omit=optional` in npmrc.
|
|
524
565
|
# Without it, packages like @openai/codex skip their platform-specific
|
|
525
566
|
# binaries (codex-win32-x64, codex-darwin-arm64, ...), leaving a shim that
|