diff --git a/scripts/lib/plugins.ps1 b/scripts/lib/plugins.ps1 index ac93c84..d4161c9 100644 --- a/scripts/lib/plugins.ps1 +++ b/scripts/lib/plugins.ps1 @@ -9,14 +9,14 @@ function Invoke-PluginCommand { if ($DryRun) { if (-not $Summary) { Write-Output "DRYRUN $display" }; return } $resolvedCommand = Get-Command $Command -ErrorAction Stop if (-not $Summary) { - & $resolvedCommand @Arguments + if ($script:PluginNonInteractive) { $null | & $resolvedCommand @Arguments } else { & $resolvedCommand @Arguments } if ($LASTEXITCODE -ne 0) { throw "Plugin command failed: $display" } return } $previousPreference = $ErrorActionPreference try { $ErrorActionPreference = 'Continue' - $output = @(& $resolvedCommand @Arguments 2>&1) + $output = if ($script:PluginNonInteractive) { @($null | & $resolvedCommand @Arguments 2>&1) } else { @(& $resolvedCommand @Arguments 2>&1) } $exitCode = $LASTEXITCODE } finally { $ErrorActionPreference = $previousPreference } if (-not $Summary -or $env:AI_CONFIG_VERBOSE -eq '1') { $output | Write-Output } elseif ($exitCode -eq 0) { $output | Where-Object { "$_" -match '(?i)warn|error|fail|deprecat' } } @@ -60,7 +60,7 @@ function Ensure-CodexMarketplace { $previousErrorActionPreference = $ErrorActionPreference try { $ErrorActionPreference = 'Continue' - $output = @(& codex plugin marketplace add $Source 2>&1) + $output = if ($script:PluginNonInteractive) { @($null | & codex plugin marketplace add $Source 2>&1) } else { @(& codex plugin marketplace add $Source 2>&1) } $exitCode = $LASTEXITCODE } catch { $output = @($_) diff --git a/scripts/update.ps1 b/scripts/update.ps1 index 61a8f22..498fcc4 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -1,6 +1,7 @@ [CmdletBinding()] param( [switch]$DryRun, + [switch]$Quick, [ValidateSet('Codex','Claude','Both')][string]$Client, [ValidateSet('Windows','Linux')][string]$Platform, [switch]$Summary @@ -10,12 +11,19 @@ $root = Split-Path $PSScriptRoot -Parent . (Join-Path $PSScriptRoot 'lib/plugins.ps1') . (Join-Path $PSScriptRoot 'lib/manifest.ps1') . (Join-Path $PSScriptRoot 'lib/install-targets.ps1') +. (Join-Path $PSScriptRoot 'lib/selection-state.ps1') + +$homePath = [Environment]::GetFolderPath('UserProfile') +if ($Quick) { + $saved = Read-UpdateSelection -HomePath $homePath -RepositoryRoot $root + if (-not $Platform) { $Platform = $saved.platform } + if (-not $Client) { $Client = $saved.client } +} $Platform = Read-InstallPlatform -Platform $Platform $platform = $Platform.ToLowerInvariant() $Client = Read-InstallClient -Client $Client -$homePath = [Environment]::GetFolderPath('UserProfile') if (-not $DryRun -and -not (Test-AllManifestsPresent (Get-InstallDestinations -HomePath $homePath -Client $Client))) { throw 'Not installed, use the install script.' } @@ -31,13 +39,29 @@ $shellCommand = 'pwsh -NoProfile -ExecutionPolicy Bypass -File' $windowsShellCommand = 'powershell -NoProfile -ExecutionPolicy Bypass -File' if ([Environment]::OSVersion.Platform -eq [PlatformID]::Win32NT) { $shellCommand = $windowsShellCommand } +$plugins = if ($Quick) { + $entries = @(Get-ConfiguredPluginEntries -RepositoryRoot $root) + @{ Selected = @($entries | Where-Object { $saved.selected -contains $_.name }); Deselected = @($entries | Where-Object { $saved.deselected -contains $_.name }) } +} else { + Select-ConfiguredPlugins -RepositoryRoot $root -Client $Client -Mode 'Update' -DryRun:$DryRun +} + foreach ($item in (Get-InstallTargets -Generated $generated -HomePath $homePath -Platform $platform -Client $Client)) { Sync-ManagedDestination -Source $item.Source -Destination $item.Destination -Stamp $stamp ` -AiConfigRoot $item.Destination.Replace('\','/') -ShellCommand $shellCommand -WindowsShellCommand $windowsShellCommand -DryRun:$DryRun -Summary:$Summary } -$plugins = Select-ConfiguredPlugins -RepositoryRoot $root -Client $Client -Mode 'Update' -DryRun:$DryRun -Install-ConfiguredPlugins -RepositoryRoot $root -Client $Client -DryRun:$DryRun -Update -Summary:$Summary -Entries $plugins.Selected -Uninstall-DeselectedPlugins -Entries $plugins.Deselected -Client $Client -DryRun:$DryRun -Summary:$Summary +$previousPluginNonInteractive = $script:PluginNonInteractive +$previousCI = $env:CI +try { + $script:PluginNonInteractive = [bool]$Quick + if ($Quick) { $env:CI = 'true' } + Install-ConfiguredPlugins -RepositoryRoot $root -Client $Client -DryRun:$DryRun -Update -Summary:$Summary -Entries $plugins.Selected + Uninstall-DeselectedPlugins -Entries $plugins.Deselected -Client $Client -DryRun:$DryRun -Summary:$Summary +} finally { + $script:PluginNonInteractive = $previousPluginNonInteractive + $env:CI = $previousCI +} +if (-not $DryRun) { Save-UpdateSelection -HomePath $homePath -RepositoryRoot $root -Platform $Platform -Client $Client -Plugins $plugins } if ($Summary) { Write-Output "Update: PASS | $Client, $Platform$(if ($DryRun) { ', dry-run' })" } else { Write-Output ($(if ($DryRun) { 'PASS update dry-run' } else { 'PASS update' })) } exit 0 diff --git a/scripts/update.sh b/scripts/update.sh index 18f4d41..d75df03 100644 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -2,12 +2,14 @@ set -euo pipefail dry_run=false +quick=false client="" platform="" summary=false while [ $# -gt 0 ]; do case "$1" in --dry-run) dry_run=true; shift ;; + --quick) quick=true; shift ;; --summary) summary=true; shift ;; --client) client=${2:?--client requires a value}; shift 2 ;; --platform) platform=${2:?--platform requires a value}; shift 2 ;; @@ -19,11 +21,16 @@ root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) . "$root/scripts/lib/plugins.sh" . "$root/scripts/lib/manifest.sh" . "$root/scripts/lib/install-targets.sh" +. "$root/scripts/lib/selection-state.sh" + +home_path=${HOME:?HOME is required} +selected_plugins=() +deselected_plugins=() +if [ "$quick" = true ]; then read_update_selection; fi platform=$(read_install_platform "$platform") client=$(read_install_client "$client") -home_path=${HOME:?HOME is required} if [ "$dry_run" = false ]; then mapfile -t destinations < <(get_install_destinations "$home_path" "$client") if ! all_manifests_present "${destinations[@]}"; then @@ -42,17 +49,24 @@ stamp=$(date +%Y%m%d-%H%M%S) shell_command=bash windows_shell_command='powershell -NoProfile -ExecutionPolicy Bypass -File' +if [ "$quick" = false ]; then + select_configured_plugins "$root" "$client" Update "$dry_run" selected_plugins deselected_plugins +fi + while IFS='|' read -r source destination; do ai_config_root=$destination command -v cygpath >/dev/null && ai_config_root=$(cygpath -m "$destination") sync_managed_destination "$source" "$destination" "$stamp" "$ai_config_root" "$shell_command" "$windows_shell_command" "$dry_run" "$summary" done < <(get_install_targets "$generated" "$home_path" "$platform" "$client") -selected_plugins=() -deselected_plugins=() -select_configured_plugins "$root" "$client" Update "$dry_run" selected_plugins deselected_plugins -install_configured_plugins "$root" "$client" "$dry_run" true selected_plugins "$summary" -uninstall_deselected_plugins "$root" "$client" "$dry_run" deselected_plugins "$summary" +if [ "$quick" = true ]; then + CI=true install_configured_plugins "$root" "$client" "$dry_run" true selected_plugins "$summary"