feat(scripts): add summary mode to plugin install/uninstall

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Julian lechnerandClaude Haiku 4.5 committed 2026-09-16 14:32:17 +02:00
1 parent 18b6a7e390
commit 0cc6909057
2 files changed
+252 -17

No files matched your search

+101 -5
View File
@@ -67,18 +67,109 @@ function Ensure-CodexMarketplace {
throw "Plugin command failed: codex plugin marketplace add $Source"
}
function Read-PluginToggleSelection {
param(
[Parameter(Mandatory=$true)][string[]]$Names,
[Parameter(Mandatory=$true)][bool[]]$Checked
)
$state = @($Checked)
while ($true) {
Write-Host 'Select plugins (enter a number to toggle, "done" to confirm):'
for ($i = 0; $i -lt $Names.Count; $i++) {
$mark = if ($state[$i]) { 'x' } else { ' ' }
Write-Host (" {0}) [{1}] {2}" -f ($i + 1), $mark, $Names[$i])
}
$answer = Read-Host 'Toggle number or "done"'
if ($answer -eq 'done') { return $state }
$index = 0
if ([int]::TryParse($answer, [ref]$index) -and $index -ge 1 -and $index -le $Names.Count) {
$state[$index - 1] = -not $state[$index - 1]
}
}
}
function Select-ConfiguredPlugins {
<#
.SYNOPSIS
Lets the user toggle each configured plugin on or off. Install mode starts
with everything checked; update mode starts checked to match what the
reference client (Claude, or Codex when only Codex is targeted) already
has installed, so unchecking a currently installed plugin uninstalls it.
#>
param(
[Parameter(Mandatory=$true)][string]$RepositoryRoot,
[ValidateSet('Codex','Claude','Both')][Parameter(Mandatory=$true)][string]$Client,
[ValidateSet('Install','Update')][Parameter(Mandatory=$true)][string]$Mode,
[switch]$DryRun
)
$entries = @(Get-ConfiguredPluginEntries -RepositoryRoot $RepositoryRoot)
$toggleable = @($entries | Where-Object { $Client -in @('Claude','Both') -or $_.codex_method -eq 'plugin' })
$fixed = @($entries | Where-Object { $toggleable -notcontains $_ })
if ($DryRun -or $toggleable.Count -eq 0) { return @{ Selected = $entries; Deselected = @() } }
$referenceClient = if ($Client -eq 'Codex') { 'Codex' } else { 'Claude' }
$installed = @(Get-InstalledPlugins -Client $referenceClient)
$idField = if ($referenceClient -eq 'Claude') { 'id' } else { 'pluginId' }
$checked = @($toggleable | ForEach-Object {
if ($Mode -eq 'Install') { $true; return }
$selector = if ($referenceClient -eq 'Claude') { $_.claude_plugin } else { $_.codex_plugin }
[bool](@($installed | Where-Object { $_.$idField -eq $selector }).Count)
})
$names = @($toggleable | ForEach-Object { $_.name })
$checked = Read-PluginToggleSelection -Names $names -Checked $checked
$selected = @()
$deselected = @()
for ($i = 0; $i -lt $toggleable.Count; $i++) {
if ($checked[$i]) { $selected += $toggleable[$i] } else { $deselected += $toggleable[$i] }
}
return @{ Selected = ($selected + $fixed); Deselected = $deselected }
}
function Uninstall-DeselectedPlugins {
param(
[Parameter(Mandatory=$true)][object[]]$Entries,
[ValidateSet('Codex','Claude','Both')][Parameter(Mandatory=$true)][string]$Client,
[switch]$DryRun,
[switch]$Summary
)
$clients = if ($Client -eq 'Both') { @('Claude','Codex') } else { @($Client) }
foreach ($selectedClient in $clients) {
$installed = if ($DryRun) { @() } else { @(Get-InstalledPlugins -Client $selectedClient) }
$idField = if ($selectedClient -eq 'Claude') { 'id' } else { 'pluginId' }
$removedCount = 0
foreach ($entry in $Entries) {
$plugin = if ($selectedClient -eq 'Claude') { $entry.claude_plugin } else { $entry.codex_plugin }
if ([string]::IsNullOrWhiteSpace($plugin)) { continue }
$isInstalled = [bool](@($installed | Where-Object { $_.$idField -eq $plugin }).Count)
if (-not $isInstalled) { continue }
if ($selectedClient -eq 'Claude') {
Invoke-PluginCommand -Command 'claude' -Arguments @('plugin','uninstall',$plugin,'--scope','user') -DryRun:$DryRun
} else {
Invoke-PluginCommand -Command 'codex' -Arguments @('plugin','remove',$plugin) -DryRun:$DryRun
}
if (-not $Summary) { Write-Output "PASS $selectedClient plugin removed: $plugin" }
$removedCount++
}
if ($Summary -and $removedCount -gt 0) { Write-Output "PLUGINS ${selectedClient}: $removedCount removed" }
}
}
function Install-ConfiguredPlugins {
param(
[Parameter(Mandatory=$true)][string]$RepositoryRoot,
[ValidateSet('Codex','Claude','Both')][Parameter(Mandatory=$true)][string]$Client,
[switch]$DryRun,
[switch]$Update
[switch]$Update,
[switch]$Summary,
[object[]]$Entries
)
$entries = @(Get-ConfiguredPluginEntries -RepositoryRoot $RepositoryRoot)
$entries = if ($Entries) { $Entries } else { @(Get-ConfiguredPluginEntries -RepositoryRoot $RepositoryRoot) }
$clients = if ($Client -eq 'Both') { @('Claude','Codex') } else { @($Client) }
foreach ($selectedClient in $clients) {
$installed = if ($DryRun) { @() } else { @(Get-InstalledPlugins -Client $selectedClient) }
$tally = @{ Ensured = 0; AlreadyInstalled = 0; Updated = 0 }
foreach ($entry in $entries) {
$marketplace = if ($selectedClient -eq 'Claude') { $entry.claude_marketplace.Trim() } else { $entry.codex_marketplace.Trim() }
if ($marketplace -eq '-') { $marketplace = '' }
@@ -95,7 +186,8 @@ function Install-ConfiguredPlugins {
throw "Unknown Codex install method '$($entry.codex_method)' for $($entry.name)."
}
Invoke-PluginCommand -Command 'npx' -Arguments $arguments -DryRun:$DryRun
Write-Output "PASS Codex skill ensured: $($entry.name)"
if (-not $Summary) { Write-Output "PASS Codex skill ensured: $($entry.name)" }
$tally.Ensured++
continue
}
@@ -105,13 +197,15 @@ function Install-ConfiguredPlugins {
if (-not $installedItem.enabled) {
Invoke-PluginCommand -Command 'claude' -Arguments @('plugin','enable',$plugin) -DryRun:$DryRun
}
$tally.Updated++
continue
}
if (-not $Update -and $null -ne $installedItem) {
if ($selectedClient -eq 'Claude' -and -not $installedItem.enabled) {
Invoke-PluginCommand -Command 'claude' -Arguments @('plugin','enable',$plugin) -DryRun:$DryRun
}
Write-Output "PASS $selectedClient plugin already installed: $plugin"
if (-not $Summary) { Write-Output "PASS $selectedClient plugin already installed: $plugin" }
$tally.AlreadyInstalled++
continue
}
@@ -127,7 +221,9 @@ function Install-ConfiguredPlugins {
}
Invoke-PluginCommand -Command 'codex' -Arguments @('plugin','add',$plugin) -DryRun:$DryRun
}
Write-Output "PASS $selectedClient plugin ensured: $plugin"
if (-not $Summary) { Write-Output "PASS $selectedClient plugin ensured: $plugin" }
$tally.Ensured++
}
if ($Summary) { Write-Output ("PLUGINS {0}: {1} ensured, {2} already installed, {3} updated" -f $selectedClient, $tally.Ensured, $tally.AlreadyInstalled, $tally.Updated) }
}
}