@cats-inc/cats-platform 0.1.5 → 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.
Files changed (148) hide show
  1. package/README.md +8 -8
  2. package/build/desktop/bootstrapPage.d.ts.map +1 -1
  3. package/build/desktop/bootstrapPage.js +5 -1
  4. package/build/desktop/bootstrapPage.js.map +1 -1
  5. package/build/desktop/cliInventoryProbe.d.ts.map +1 -1
  6. package/build/desktop/cliInventoryProbe.js +12 -0
  7. package/build/desktop/cliInventoryProbe.js.map +1 -1
  8. package/build/desktop/contracts.d.ts +3 -1
  9. package/build/desktop/contracts.d.ts.map +1 -1
  10. package/build/desktop/contracts.js +6 -0
  11. package/build/desktop/contracts.js.map +1 -1
  12. package/build/desktop/ipcSecurity.d.ts +6 -0
  13. package/build/desktop/ipcSecurity.d.ts.map +1 -0
  14. package/build/desktop/ipcSecurity.js +10 -0
  15. package/build/desktop/ipcSecurity.js.map +1 -0
  16. package/build/desktop/main.js +79 -31
  17. package/build/desktop/main.js.map +1 -1
  18. package/build/desktop/packaging.d.ts.map +1 -1
  19. package/build/desktop/packaging.js +62 -0
  20. package/build/desktop/packaging.js.map +1 -1
  21. package/build/desktop/preload.cjs +10 -0
  22. package/build/desktop/preload.cjs.map +1 -1
  23. package/build/desktop/screenshotCapture.d.ts.map +1 -1
  24. package/build/desktop/screenshotCapture.js +3 -7
  25. package/build/desktop/screenshotCapture.js.map +1 -1
  26. package/build/desktop/security.d.ts +8 -0
  27. package/build/desktop/security.d.ts.map +1 -1
  28. package/build/desktop/security.js +54 -1
  29. package/build/desktop/security.js.map +1 -1
  30. package/build/desktop/setupAssets.d.ts.map +1 -1
  31. package/build/desktop/setupAssets.js +134 -0
  32. package/build/desktop/setupAssets.js.map +1 -1
  33. package/build/desktop/updateInstallHandoff.d.ts +14 -0
  34. package/build/desktop/updateInstallHandoff.d.ts.map +1 -1
  35. package/build/desktop/updateInstallHandoff.js +23 -0
  36. package/build/desktop/updateInstallHandoff.js.map +1 -1
  37. package/build/desktop/updateManager.d.ts.map +1 -1
  38. package/build/desktop/updateManager.js +8 -0
  39. package/build/desktop/updateManager.js.map +1 -1
  40. package/build/desktop/updaterAdapter.d.ts +16 -1
  41. package/build/desktop/updaterAdapter.d.ts.map +1 -1
  42. package/build/desktop/updaterAdapter.js +49 -2
  43. package/build/desktop/updaterAdapter.js.map +1 -1
  44. package/build/desktop/voiceCapture.d.ts.map +1 -1
  45. package/build/desktop/voiceCapture.js +3 -7
  46. package/build/desktop/voiceCapture.js.map +1 -1
  47. package/build/renderer/assets/ActiveSessionPermissionChip-Dl2UOFgh.js +1 -0
  48. package/build/renderer/assets/{App-Bs1eRarv.js → App-C57f4p8k.js} +1 -1
  49. package/build/renderer/assets/{App-CNJj5gi9.js → App-CPqGDXVi.js} +1 -1
  50. package/build/renderer/assets/{App-C4S1Wa9f.js → App-ChvP0G9X.js} +1 -1
  51. package/build/renderer/assets/{WorkspaceAppRoutes-CFAuhWGF.js → WorkspaceAppRoutes-DYg2vnjz.js} +1 -1
  52. package/build/renderer/assets/app-DVN9Ghrk.js +43 -0
  53. package/build/renderer/assets/{client-DREGSZqQ.js → client-BdGHAUoK.js} +1 -1
  54. package/build/renderer/assets/{conversationSidebarRecentEntries-CPGopayy.js → conversationSidebarRecentEntries-XZVCnMLw.js} +1 -1
  55. package/build/renderer/assets/{screenshotOverlay-EF07cXvw.js → screenshotOverlay-DfBcolX-.js} +1 -1
  56. package/build/renderer/assets/{useDraftSessionChips-BsOdYfWw.js → useDraftSessionChips-By3XXabI.js} +1 -1
  57. package/build/renderer/desktop/overlay/index.html +2 -2
  58. package/build/renderer/index.html +2 -2
  59. package/build/server/app/server/authGatePolicy.js +14 -2
  60. package/build/server/app/server/authGatePolicy.js.map +1 -1
  61. package/build/server/app/server/authRoutes.d.ts +2 -1
  62. package/build/server/app/server/authRoutes.d.ts.map +1 -1
  63. package/build/server/app/server/authRoutes.js +260 -4
  64. package/build/server/app/server/authRoutes.js.map +1 -1
  65. package/build/server/app/server/contracts.d.ts +3 -1
  66. package/build/server/app/server/contracts.d.ts.map +1 -1
  67. package/build/server/app/server/dependencies.d.ts.map +1 -1
  68. package/build/server/app/server/dependencies.js +4 -1
  69. package/build/server/app/server/dependencies.js.map +1 -1
  70. package/build/server/app/server/requestRouter.d.ts.map +1 -1
  71. package/build/server/app/server/requestRouter.js +1 -0
  72. package/build/server/app/server/requestRouter.js.map +1 -1
  73. package/build/server/platform/auth/browserHandoff.d.ts +50 -0
  74. package/build/server/platform/auth/browserHandoff.d.ts.map +1 -0
  75. package/build/server/platform/auth/browserHandoff.js +94 -0
  76. package/build/server/platform/auth/browserHandoff.js.map +1 -0
  77. package/build/server/platform/auth/index.d.ts +1 -0
  78. package/build/server/platform/auth/index.d.ts.map +1 -1
  79. package/build/server/platform/auth/index.js +1 -0
  80. package/build/server/platform/auth/index.js.map +1 -1
  81. package/build/server/platform/auth/principal.js +2 -2
  82. package/build/server/platform/auth/principal.js.map +1 -1
  83. package/build/server/platform/auth/session.d.ts +3 -0
  84. package/build/server/platform/auth/session.d.ts.map +1 -1
  85. package/build/server/platform/auth/session.js +41 -0
  86. package/build/server/platform/auth/session.js.map +1 -1
  87. package/build/server/platform/auth/state.js +4 -0
  88. package/build/server/platform/auth/state.js.map +1 -1
  89. package/build/server/platform/auth/types.d.ts +1 -0
  90. package/build/server/platform/auth/types.d.ts.map +1 -1
  91. package/build/server/shared/browserHandoff.d.ts +11 -0
  92. package/build/server/shared/browserHandoff.d.ts.map +1 -0
  93. package/build/server/shared/browserHandoff.js +2 -0
  94. package/build/server/shared/browserHandoff.js.map +1 -0
  95. package/build/server/shared/desktopRecoveryBridge.d.ts +1 -0
  96. package/build/server/shared/desktopRecoveryBridge.d.ts.map +1 -1
  97. package/build/server/shared/desktopRecoveryBridge.js.map +1 -1
  98. package/build/server/shared/i18n/catalogs/en.d.ts.map +1 -1
  99. package/build/server/shared/i18n/catalogs/en.js +1 -0
  100. package/build/server/shared/i18n/catalogs/en.js.map +1 -1
  101. package/build/server/shared/i18n/catalogs/zh-TW.d.ts.map +1 -1
  102. package/build/server/shared/i18n/catalogs/zh-TW.js +1 -0
  103. package/build/server/shared/i18n/catalogs/zh-TW.js.map +1 -1
  104. package/build/server/shared/i18n/index.d.ts +1 -0
  105. package/build/server/shared/i18n/index.d.ts.map +1 -1
  106. package/build/server/shared/i18n/messageKeys.d.ts +1 -0
  107. package/build/server/shared/i18n/messageKeys.d.ts.map +1 -1
  108. package/build/server/shared/i18n/messageKeys.js +1 -0
  109. package/build/server/shared/i18n/messageKeys.js.map +1 -1
  110. package/build/server/shared/providerCatalog.d.ts +2 -2
  111. package/build/server/shared/providerCatalog.d.ts.map +1 -1
  112. package/build/server/shared/providerCatalogData.d.ts +11 -1
  113. package/build/server/shared/providerCatalogData.d.ts.map +1 -1
  114. package/build/server/shared/providerCatalogData.js +8 -0
  115. package/build/server/shared/providerCatalogData.js.map +1 -1
  116. package/build/server/shared/providerCatalogInstances.d.ts.map +1 -1
  117. package/build/server/shared/providerCatalogInstances.js +6 -0
  118. package/build/server/shared/providerCatalogInstances.js.map +1 -1
  119. package/package.json +6 -3
  120. package/scripts/README.md +51 -2
  121. package/scripts/linux/install-aider.sh +8 -0
  122. package/scripts/linux/install-cline.sh +8 -0
  123. package/scripts/linux/install-devin.sh +8 -0
  124. package/scripts/linux/install-grok.sh +8 -0
  125. package/scripts/linux/install-pi.sh +1 -1
  126. package/scripts/linux/node-cli-common.sh +43 -3
  127. package/scripts/linux/provider-cli-common.sh +162 -24
  128. package/scripts/linux/test-linux-package-smoke.sh +16 -0
  129. package/scripts/linux/upgrade-cli-tools.sh +2 -2
  130. package/scripts/macos/install-aider.sh +8 -0
  131. package/scripts/macos/install-cline.sh +8 -0
  132. package/scripts/macos/install-devin.sh +8 -0
  133. package/scripts/macos/install-grok.sh +8 -0
  134. package/scripts/macos/install-pi.sh +1 -1
  135. package/scripts/macos/node-cli-common.sh +43 -3
  136. package/scripts/macos/provider-cli-common.sh +162 -24
  137. package/scripts/macos/test-macos-package-smoke.sh +15 -0
  138. package/scripts/macos/upgrade-cli-tools.sh +2 -2
  139. package/scripts/windows/Check-WindowsSetupReadiness.ps1 +32 -1
  140. package/scripts/windows/Install-Aider.ps1 +368 -0
  141. package/scripts/windows/Install-Cline.ps1 +39 -0
  142. package/scripts/windows/Install-Devin.ps1 +385 -0
  143. package/scripts/windows/Install-Grok.ps1 +355 -0
  144. package/scripts/windows/Install-Pi.ps1 +1 -1
  145. package/scripts/windows/Test-WindowsInstallerSmoke.ps1 +23 -0
  146. package/scripts/windows/_NpmCliInstaller.ps1 +41 -0
  147. package/build/renderer/assets/ActiveSessionPermissionChip-BoDkKkmi.js +0 -1
  148. package/build/renderer/assets/app-uJJx-k1S.js +0 -43
@@ -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 '@mariozechner/pi-coding-agent' `
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
@@ -1 +0,0 @@
1
- import{j as o}from"./client-DREGSZqQ.js";import{b as r}from"./app-uJJx-k1S.js";import{D as i,P as t}from"./conversationSidebarRecentEntries-CPGopayy.js";function u({channel:s}){if(!(s.repoPath??s.chatCwd??null))return null;const e=s.runtimeWorkspaceAccess?r(s.runtimeWorkspaceAccess):i;return o.jsx(t,{value:e,onChange:()=>{},disabled:!0})}export{u as A};