fix(menu): parse Bash plugin inventory safely
This commit is contained in:
1 parent
ac861c047d
commit
0fc5725ec4
2 files changed
+23
-7
No files matched your search
@@ -21,7 +21,7 @@
|
||||
- [ ] Reconcile resources whose ownership record remains but whose installation was removed manually. `ensure_cli()` and `ensure_mcporter()` return early from a ledger record without checking the actual CLI or server; normal sync cannot restore the missing resource. (`scripts/lib/managed-extensions.py:342`, `scripts/lib/managed-extensions.py:395`)
|
||||
- [ ] Update owned MCPorter itself on `--update`. `ensure_cli()` returns whenever its ledger record exists, so a selected MCPorter package never receives the requested update. (`scripts/lib/managed-extensions.py:342`)
|
||||
- [x] Keep terminal newlines in Bash-managed files that need substitution. Command substitution strips trailing newlines before Bash hashes and writes the content, while PowerShell retains them; switching installers causes needless file changes and backups. (`scripts/lib/manifest.sh:70`, `scripts/lib/manifest.ps1:75`)
|
||||
- [ ] Parse the Bash plugin inventory as JSON and stop when listing fails. `plugin_installed()` searches for one exact spacing pattern and suppresses CLI errors; a minified response or listing failure marks installed plugins unchecked, allowing an update to remove owned plugins. PowerShell parses JSON and fails on a CLI error. (`scripts/lib/plugins.sh:4`, `scripts/lib/plugins.ps1:36`)
|
||||
- [x] Parse the Bash plugin inventory as JSON and stop when listing fails. `plugin_installed()` searches for one exact spacing pattern and suppresses CLI errors; a minified response or listing failure marks installed plugins unchecked, allowing an update to remove owned plugins. PowerShell parses JSON and fails on a CLI error. (`scripts/lib/plugins.sh:4`, `scripts/lib/plugins.ps1:36`)
|
||||
- [x] Serialize Bash manifest entries without shell word splitting. `write_managed_manifest()` loops over command substitution; a managed filename containing spaces becomes multiple invalid entries and can no longer be reconciled correctly. (`scripts/lib/manifest.sh:47`)
|
||||
- [ ] Allow uninstall to reconcile owned extensions when file manifests are missing. Both uninstall commands stop with “Not installed” based only on destination manifests, even if `extensions.json` still owns plugins, skills, or MCP servers. (`scripts/commands/uninstall.ps1:21`, `scripts/commands/uninstall.sh:34`)
|
||||
|
||||
|
||||
+22
-6
@@ -3,11 +3,22 @@ set -euo pipefail
|
||||
|
||||
plugin_installed() {
|
||||
local client=$1 plugin=$2
|
||||
if [ "$client" = claude ]; then
|
||||
claude plugin list --json 2>/dev/null | grep -Fq "\"id\": \"$plugin\""
|
||||
else
|
||||
codex plugin list --json 2>/dev/null | grep -Fq "\"pluginId\": \"$plugin\""
|
||||
fi
|
||||
local inventory
|
||||
inventory=$("$client" plugin list --json) || return 2
|
||||
printf '%s' "$inventory" | python3 -c '
|
||||
import json, sys
|
||||
try:
|
||||
client, plugin = sys.argv[1:]
|
||||
data = json.load(sys.stdin)
|
||||
if client == "codex":
|
||||
data = data["installed"]
|
||||
if not isinstance(data, list) or any(not isinstance(item, dict) for item in data):
|
||||
raise ValueError("Invalid plugin inventory")
|
||||
sys.exit(0 if any(item.get("id" if client == "claude" else "pluginId") == plugin for item in data) else 1)
|
||||
except (ValueError, KeyError, TypeError) as error:
|
||||
print("Invalid plugin inventory: " + str(error), file=sys.stderr)
|
||||
sys.exit(2)
|
||||
' "$client" "$plugin"
|
||||
}
|
||||
|
||||
run_plugin_command() {
|
||||
@@ -121,7 +132,12 @@ select_configured_plugins() {
|
||||
local skill_name
|
||||
skill_name=$(plugin_field "$root" "$name" codex_skill)
|
||||
if [ -d "$HOME/.agents/skills/$skill_name" ] || [ -d "$HOME/.codex/skills/$skill_name" ]; then checked+=(true); else checked+=(false); fi
|
||||
elif plugin_installed "$reference_client" "$selector"; then checked+=(true); else checked+=(false); fi
|
||||
elif plugin_installed "$reference_client" "$selector"; then checked+=(true)
|
||||
else
|
||||
local status=$?
|
||||
[ "$status" -eq 1 ] || return "$status"
|
||||
checked+=(false)
|
||||
fi
|
||||
done
|
||||
|
||||
read_plugin_toggle_selection toggle_names checked
|
||||
|
||||
Reference in new issue
Block a user