@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.
Files changed (76) 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 +1 -1
  9. package/build/desktop/contracts.d.ts.map +1 -1
  10. package/build/desktop/contracts.js +4 -0
  11. package/build/desktop/contracts.js.map +1 -1
  12. package/build/desktop/main.js +41 -9
  13. package/build/desktop/main.js.map +1 -1
  14. package/build/desktop/packaging.d.ts.map +1 -1
  15. package/build/desktop/packaging.js +62 -0
  16. package/build/desktop/packaging.js.map +1 -1
  17. package/build/desktop/setupAssets.d.ts.map +1 -1
  18. package/build/desktop/setupAssets.js +134 -0
  19. package/build/desktop/setupAssets.js.map +1 -1
  20. package/build/desktop/updateInstallHandoff.d.ts +14 -0
  21. package/build/desktop/updateInstallHandoff.d.ts.map +1 -1
  22. package/build/desktop/updateInstallHandoff.js +23 -0
  23. package/build/desktop/updateInstallHandoff.js.map +1 -1
  24. package/build/desktop/updateManager.d.ts.map +1 -1
  25. package/build/desktop/updateManager.js +8 -0
  26. package/build/desktop/updateManager.js.map +1 -1
  27. package/build/desktop/updaterAdapter.d.ts +16 -1
  28. package/build/desktop/updaterAdapter.d.ts.map +1 -1
  29. package/build/desktop/updaterAdapter.js +49 -2
  30. package/build/desktop/updaterAdapter.js.map +1 -1
  31. package/build/renderer/assets/{ActiveSessionPermissionChip-BRMLwkvf.js → ActiveSessionPermissionChip-Dl2UOFgh.js} +1 -1
  32. package/build/renderer/assets/{App-BM2nzo6s.js → App-C57f4p8k.js} +1 -1
  33. package/build/renderer/assets/{App-CVQAwCMi.js → App-CPqGDXVi.js} +1 -1
  34. package/build/renderer/assets/{App-Dl5FLaR_.js → App-ChvP0G9X.js} +1 -1
  35. package/build/renderer/assets/{WorkspaceAppRoutes-C3DUzdbj.js → WorkspaceAppRoutes-DYg2vnjz.js} +1 -1
  36. package/build/renderer/assets/{app-hP5h2jAt.js → app-DVN9Ghrk.js} +3 -3
  37. package/build/renderer/assets/{conversationSidebarRecentEntries-B-mNvfiy.js → conversationSidebarRecentEntries-XZVCnMLw.js} +1 -1
  38. package/build/renderer/assets/{useDraftSessionChips-DuXIoptW.js → useDraftSessionChips-By3XXabI.js} +1 -1
  39. package/build/renderer/index.html +1 -1
  40. package/build/server/shared/providerCatalog.d.ts +2 -2
  41. package/build/server/shared/providerCatalog.d.ts.map +1 -1
  42. package/build/server/shared/providerCatalogData.d.ts +11 -1
  43. package/build/server/shared/providerCatalogData.d.ts.map +1 -1
  44. package/build/server/shared/providerCatalogData.js +8 -0
  45. package/build/server/shared/providerCatalogData.js.map +1 -1
  46. package/build/server/shared/providerCatalogInstances.d.ts.map +1 -1
  47. package/build/server/shared/providerCatalogInstances.js +6 -0
  48. package/build/server/shared/providerCatalogInstances.js.map +1 -1
  49. package/package.json +6 -3
  50. package/scripts/README.md +51 -2
  51. package/scripts/linux/install-aider.sh +8 -0
  52. package/scripts/linux/install-cline.sh +8 -0
  53. package/scripts/linux/install-devin.sh +8 -0
  54. package/scripts/linux/install-grok.sh +8 -0
  55. package/scripts/linux/install-pi.sh +1 -1
  56. package/scripts/linux/node-cli-common.sh +43 -3
  57. package/scripts/linux/provider-cli-common.sh +162 -24
  58. package/scripts/linux/test-linux-package-smoke.sh +16 -0
  59. package/scripts/linux/upgrade-cli-tools.sh +2 -2
  60. package/scripts/macos/install-aider.sh +8 -0
  61. package/scripts/macos/install-cline.sh +8 -0
  62. package/scripts/macos/install-devin.sh +8 -0
  63. package/scripts/macos/install-grok.sh +8 -0
  64. package/scripts/macos/install-pi.sh +1 -1
  65. package/scripts/macos/node-cli-common.sh +43 -3
  66. package/scripts/macos/provider-cli-common.sh +162 -24
  67. package/scripts/macos/test-macos-package-smoke.sh +15 -0
  68. package/scripts/macos/upgrade-cli-tools.sh +2 -2
  69. package/scripts/windows/Check-WindowsSetupReadiness.ps1 +32 -1
  70. package/scripts/windows/Install-Aider.ps1 +368 -0
  71. package/scripts/windows/Install-Cline.ps1 +39 -0
  72. package/scripts/windows/Install-Devin.ps1 +385 -0
  73. package/scripts/windows/Install-Grok.ps1 +355 -0
  74. package/scripts/windows/Install-Pi.ps1 +1 -1
  75. package/scripts/windows/Test-WindowsInstallerSmoke.ps1 +23 -0
  76. package/scripts/windows/_NpmCliInstaller.ps1 +41 -0
@@ -0,0 +1,385 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Install or verify the native Windows Devin CLI for Cats.
4
+
5
+ .DESCRIPTION
6
+ Cats-owned packaged setup wrapper for Cognition's Devin CLI. The official
7
+ installer places devin.exe in %LOCALAPPDATA%\devin\cli\bin and keeps
8
+ versions under %LOCALAPPDATA%\devin\cli, both of which uninstall removes.
9
+
10
+ The installer's final line launches the interactive devin setup wizard,
11
+ which packaged setup strips because it runs with no console a prompt can
12
+ reach. Authentication is therefore still owed after a successful install:
13
+ run devin auth login once and check with devin auth status.
14
+ #>
15
+ param(
16
+ [switch]$CheckOnly,
17
+ [switch]$Apply,
18
+ [switch]$Upgrade,
19
+ [switch]$Force,
20
+ [switch]$Uninstall,
21
+ [switch]$DryRun,
22
+ [switch]$Json,
23
+ [switch]$AllowAdmin,
24
+ [ValidateSet('auto', 'installed', 'missing')]
25
+ [string]$InstallState = 'auto',
26
+ [string]$DetectedVersion = '',
27
+ [switch]$SkipInstaller
28
+ )
29
+
30
+ Set-StrictMode -Version Latest
31
+ $ErrorActionPreference = 'Stop'
32
+
33
+ . (Join-Path $PSScriptRoot '_HiddenProcess.ps1')
34
+ . (Join-Path $PSScriptRoot '_PackagedUninstall.ps1')
35
+
36
+ function Write-StructuredResult {
37
+ param(
38
+ [pscustomobject]$Result,
39
+ [int]$ExitCode
40
+ )
41
+
42
+ if ($Json) {
43
+ $Result | ConvertTo-Json -Depth 10
44
+ } else {
45
+ Write-Host "Mode: $($Result.mode)"
46
+ Write-Host "Status: $($Result.status)"
47
+ Write-Host "Installed: $($Result.installed)"
48
+ if ($Result.detectedVersion) { Write-Host "Version: $($Result.detectedVersion)" }
49
+ foreach ($action in $Result.plannedActions) { Write-Host "Planned action: $action" }
50
+ foreach ($warning in $Result.warnings) { Write-Host "Warning: $warning" }
51
+ foreach ($step in $Result.manualSteps) { Write-Host "Manual step: $step" }
52
+ }
53
+
54
+ exit $ExitCode
55
+ }
56
+
57
+ function Resolve-DevinInstallDir {
58
+ return Join-Path $env:LOCALAPPDATA 'devin\cli\bin'
59
+ }
60
+
61
+ function Resolve-DevinExecutablePath {
62
+ return Join-Path (Resolve-DevinInstallDir) 'devin.exe'
63
+ }
64
+
65
+ function Refresh-UserPath {
66
+ $env:Path = [System.Environment]::GetEnvironmentVariable('Path', 'User') + ';' +
67
+ [System.Environment]::GetEnvironmentVariable('Path', 'Machine')
68
+ }
69
+
70
+ function Detect-DevinInstall {
71
+ $exePath = Resolve-DevinExecutablePath
72
+
73
+ if ($InstallState -eq 'installed') {
74
+ return [pscustomobject]@{
75
+ installed = $true
76
+ commandPath = $exePath
77
+ detectedVersion = $DetectedVersion
78
+ }
79
+ }
80
+ if ($InstallState -eq 'missing') {
81
+ return [pscustomobject]@{
82
+ installed = $false
83
+ commandPath = $exePath
84
+ detectedVersion = $DetectedVersion
85
+ }
86
+ }
87
+
88
+ Refresh-UserPath
89
+ $command = Get-Command devin -ErrorAction SilentlyContinue
90
+ $installed = $null -ne $command -or (Test-Path -LiteralPath $exePath -PathType Leaf)
91
+ $commandPath = if ($null -ne $command) { $command.Source } else { $exePath }
92
+ $commandSource = if ($null -ne $command) { $command.Source } else { '' }
93
+ $version = $DetectedVersion
94
+ $versionProbePath = Resolve-HiddenVersionProbePath `
95
+ -PreferredPath $commandSource `
96
+ -FallbackPath $exePath
97
+
98
+ if ($installed -and [string]::IsNullOrWhiteSpace($version) -and $versionProbePath) {
99
+ try {
100
+ $version = Get-HiddenCommandText -FileName $versionProbePath -ArgumentList @('--version')
101
+ } catch {
102
+ $version = ''
103
+ }
104
+ }
105
+
106
+ return [pscustomobject]@{
107
+ installed = $installed
108
+ commandPath = $commandPath
109
+ detectedVersion = $version
110
+ }
111
+ }
112
+
113
+ function Add-DevinToUserPath {
114
+ $installDir = Resolve-DevinInstallDir
115
+ $userPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
116
+ if ([string]::IsNullOrWhiteSpace($userPath)) {
117
+ [System.Environment]::SetEnvironmentVariable('Path', $installDir, 'User')
118
+ } elseif ($userPath -notlike "*$installDir*") {
119
+ [System.Environment]::SetEnvironmentVariable('Path', "$installDir;$userPath", 'User')
120
+ }
121
+ Refresh-UserPath
122
+ }
123
+
124
+ function Invoke-DevinInstaller {
125
+ if ($SkipInstaller) {
126
+ return [pscustomobject]@{ skipped = $true; success = $true; exitCode = 0; stderr = '' }
127
+ }
128
+
129
+ $tempScript = [System.IO.Path]::Combine(
130
+ [System.IO.Path]::GetTempPath(),
131
+ "cats-devin-install-$([System.Guid]::NewGuid().ToString('N')).ps1"
132
+ )
133
+ $stdoutPath = "$tempScript.stdout"
134
+ $stderrPath = "$tempScript.stderr"
135
+ # Devin's setup.ps1 ends by launching the interactive `devin setup` wizard.
136
+ # Packaged setup runs with no console a prompt can reach, so an unstripped
137
+ # installer would stall the step rather than fail.
138
+ #
139
+ # Verified against https://static.devin.ai/cli/setup.ps1 on 2026-08-09: the
140
+ # file is 234 lines and its final line is `& $EntryExe setup`, which is also
141
+ # the only line in the file that invokes setup. The helper refuses to run the
142
+ # script when that shape does not hold rather than executing an unrecognised
143
+ # installer on a guess.
144
+ $installerSource = ''
145
+ try {
146
+ $installerSource = Invoke-RestMethod 'https://static.devin.ai/cli/setup.ps1'
147
+ } catch {
148
+ return [pscustomobject]@{
149
+ skipped = $false
150
+ success = $false
151
+ exitCode = -1
152
+ stderr = "Failed to download the Devin installer: $($_.Exception.Message)"
153
+ }
154
+ }
155
+
156
+ $installerLines = [regex]::Split([string]$installerSource, '\r?\n')
157
+ $setupMatches = @($installerLines | Where-Object { $_ -match '^\s*&\s+\$EntryExe\s+setup\s*$' })
158
+ if ($setupMatches.Count -ne 1) {
159
+ return [pscustomobject]@{
160
+ skipped = $false
161
+ success = $false
162
+ exitCode = -1
163
+ stderr = ("Refusing to run the Devin installer: expected exactly one interactive setup " +
164
+ "invocation, found $($setupMatches.Count). Install Devin with the upstream installer and report this.")
165
+ }
166
+ }
167
+
168
+ $patchedLines = $installerLines | ForEach-Object {
169
+ if ($_ -match '^\s*&\s+\$EntryExe\s+setup\s*$') {
170
+ '# skipped interactive devin setup (packaged setup runs non-interactively)'
171
+ } else {
172
+ $_
173
+ }
174
+ }
175
+ $bootstrap = ($patchedLines -join [Environment]::NewLine)
176
+
177
+ try {
178
+ [System.IO.File]::WriteAllText(
179
+ $tempScript,
180
+ $bootstrap,
181
+ [System.Text.UTF8Encoding]::new($false)
182
+ )
183
+ $powerShellExe = if (Get-Command pwsh.exe -ErrorAction SilentlyContinue) {
184
+ 'pwsh.exe'
185
+ } else {
186
+ 'powershell.exe'
187
+ }
188
+ $process = Start-Process -FilePath $powerShellExe `
189
+ -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $tempScript) `
190
+ -Wait -PassThru -NoNewWindow `
191
+ -RedirectStandardOutput $stdoutPath `
192
+ -RedirectStandardError $stderrPath
193
+ $stderrRaw = if (Test-Path -LiteralPath $stderrPath -PathType Leaf) {
194
+ Get-Content -LiteralPath $stderrPath -Raw -ErrorAction SilentlyContinue
195
+ } else { $null }
196
+
197
+ return [pscustomobject]@{
198
+ skipped = $false
199
+ success = ($process.ExitCode -eq 0)
200
+ exitCode = $process.ExitCode
201
+ stderr = if ($null -eq $stderrRaw) { '' } else { [string]$stderrRaw }
202
+ }
203
+ } catch {
204
+ return [pscustomobject]@{
205
+ skipped = $false
206
+ success = $false
207
+ exitCode = -1
208
+ stderr = "Failed to invoke Devin installer: $($_.Exception.Message)"
209
+ }
210
+ } finally {
211
+ foreach ($path in @($tempScript, $stdoutPath, $stderrPath)) {
212
+ if (Test-Path -LiteralPath $path -PathType Leaf) {
213
+ Remove-Item -LiteralPath $path -Force -ErrorAction SilentlyContinue
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+ if (-not $CheckOnly -and -not $Apply -and -not $Upgrade -and -not $Force -and -not $Uninstall) {
220
+ $CheckOnly = $true
221
+ }
222
+
223
+ $mutationCount = @($Apply, $Upgrade, $Force | Where-Object { $_ }).Count
224
+ if ($Uninstall -and ($CheckOnly -or $mutationCount -gt 0)) {
225
+ throw 'Install-Devin.ps1 -Uninstall is mutually exclusive with other modes.'
226
+ }
227
+ if ($CheckOnly -and $mutationCount -gt 0) {
228
+ throw 'Install-Devin.ps1 accepts either -CheckOnly or one mutation mode.'
229
+ }
230
+ if ($mutationCount -gt 1) {
231
+ throw 'Install-Devin.ps1 accepts at most one of -Apply / -Upgrade / -Force.'
232
+ }
233
+
234
+ $executionMode = if ($Uninstall) {
235
+ 'uninstall'
236
+ } elseif ($CheckOnly) {
237
+ 'check'
238
+ } elseif ($Force) {
239
+ 'force'
240
+ } elseif ($Upgrade) {
241
+ 'upgrade'
242
+ } else {
243
+ 'apply'
244
+ }
245
+
246
+ if ($Uninstall) {
247
+ Invoke-PackagedProviderUninstall `
248
+ -HelperId 'windows-devin-native-installer' `
249
+ -UserBinaryPath (Resolve-DevinExecutablePath) `
250
+ -ExtraUserOwnedPaths @((Join-Path $env:LOCALAPPDATA 'devin\cli')) `
251
+ -RedetectCommand { Detect-DevinInstall } `
252
+ -EmitJson:$Json `
253
+ -DryRun:$DryRun
254
+ }
255
+
256
+ $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).
257
+ IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
258
+ if ($isAdmin -and -not $AllowAdmin) {
259
+ Write-StructuredResult -Result ([pscustomobject]@{
260
+ helper = 'windows-devin-native-installer'
261
+ mode = $executionMode
262
+ status = 'failed'
263
+ installed = $false
264
+ detectedVersion = $null
265
+ commandPath = Resolve-DevinExecutablePath
266
+ restartRequired = $false
267
+ plannedActions = @()
268
+ warnings = @('Refusing to run under an elevated shell without -AllowAdmin because Devin CLI is intended for user-scoped installation.')
269
+ appliedChanges = @()
270
+ manualSteps = @()
271
+ interruptions = @()
272
+ }) -ExitCode 1
273
+ }
274
+
275
+ $detected = Detect-DevinInstall
276
+ $plannedActions = [System.Collections.Generic.List[string]]::new()
277
+ $appliedChanges = [System.Collections.Generic.List[string]]::new()
278
+ $warnings = [System.Collections.Generic.List[string]]::new()
279
+ $manualSteps = [System.Collections.Generic.List[string]]::new()
280
+
281
+ if ($Force) {
282
+ $plannedActions.Add('reinstall_devin_native')
283
+ } elseif ($Upgrade -and $detected.installed) {
284
+ $plannedActions.Add('upgrade_devin_native')
285
+ } elseif (-not $detected.installed) {
286
+ $plannedActions.Add('install_devin_native')
287
+ }
288
+
289
+ if ($CheckOnly) {
290
+ Write-StructuredResult -Result ([pscustomobject]@{
291
+ helper = 'windows-devin-native-installer'
292
+ mode = 'check'
293
+ status = if ($detected.installed) { 'ready' } else { 'not_installed' }
294
+ installed = [bool]$detected.installed
295
+ detectedVersion = if ($detected.detectedVersion) { $detected.detectedVersion } else { $null }
296
+ commandPath = $detected.commandPath
297
+ restartRequired = $false
298
+ plannedActions = $plannedActions.ToArray()
299
+ warnings = @()
300
+ appliedChanges = @()
301
+ manualSteps = @()
302
+ interruptions = @()
303
+ }) -ExitCode 0
304
+ }
305
+
306
+ $shouldInstall = $Force -or $Upgrade -or -not $detected.installed
307
+ $installFailed = $false
308
+ $installSkipped = $false
309
+ if ($shouldInstall) {
310
+ if ($DryRun) {
311
+ $warnings.Add('Dry-run requested; Devin installer invocation was skipped.')
312
+ $installSkipped = $true
313
+ } else {
314
+ $installResult = Invoke-DevinInstaller
315
+ $installSkipped = [bool]$installResult.skipped
316
+ $installFailed = (-not $installSkipped) -and (-not $installResult.success)
317
+ if ($installSkipped) {
318
+ $warnings.Add('Installer invocation was skipped by request.')
319
+ } elseif ($installFailed) {
320
+ $stderrSnippet = if ([string]::IsNullOrWhiteSpace($installResult.stderr)) {
321
+ 'no stderr captured'
322
+ } else {
323
+ ($installResult.stderr.Trim() -split "`r?`n" |
324
+ Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
325
+ Select-Object -Last 8) -join ' | '
326
+ }
327
+ $warnings.Add("Devin installer exited $($installResult.exitCode): $stderrSnippet")
328
+ }
329
+
330
+ Start-Sleep -Seconds 2
331
+ Add-DevinToUserPath
332
+ $detected = Detect-DevinInstall
333
+ if (-not $detected.installed -and -not $installSkipped -and -not $installFailed) {
334
+ $warnings.Add('Devin installation completed but devin.exe was not detected at the expected path.')
335
+ $installFailed = $true
336
+ }
337
+ }
338
+
339
+ if (-not $installFailed -and -not ($DryRun -and $shouldInstall)) {
340
+ if ($Force) {
341
+ $appliedChanges.Add('reinstall_devin_native')
342
+ } elseif ($Upgrade) {
343
+ $appliedChanges.Add('upgrade_devin_native')
344
+ } else {
345
+ $appliedChanges.Add('install_devin_native')
346
+ }
347
+ }
348
+ }
349
+
350
+ $manualSteps.Add('Run `devin login` or set XAI_API_KEY before first use.')
351
+ $interruptions = [System.Collections.Generic.List[object]]::new()
352
+ if ($shouldInstall -and -not $installFailed -and -not $DryRun) {
353
+ $interruptions.Add([pscustomobject]@{
354
+ kind = 'relaunch_required'
355
+ summary = 'Relaunch Cats Desktop Host after the Devin install step, then rerun the packaged setup check.'
356
+ resumable = $true
357
+ requiresRestart = $false
358
+ requiresElevation = $false
359
+ })
360
+ }
361
+
362
+ $status = if ($installFailed) {
363
+ 'failed'
364
+ } elseif ($DryRun -and $shouldInstall) {
365
+ 'preview'
366
+ } elseif ($interruptions.Count -gt 0) {
367
+ [string]$interruptions[0].kind
368
+ } else {
369
+ 'ready'
370
+ }
371
+
372
+ Write-StructuredResult -Result ([pscustomobject]@{
373
+ helper = 'windows-devin-native-installer'
374
+ mode = $executionMode
375
+ status = $status
376
+ installed = [bool]$detected.installed
377
+ detectedVersion = if ($detected.detectedVersion) { $detected.detectedVersion } else { $null }
378
+ commandPath = $detected.commandPath
379
+ restartRequired = $false
380
+ plannedActions = $plannedActions.ToArray()
381
+ warnings = $warnings.ToArray()
382
+ appliedChanges = $appliedChanges.ToArray()
383
+ manualSteps = $manualSteps.ToArray()
384
+ interruptions = $interruptions.ToArray()
385
+ }) -ExitCode $(if ($installFailed) { 1 } else { 0 })