feat(plugins): add shared client tools

This commit is contained in:
2026-09-14 01:07:28 +02:00
parent e88d27ac43
commit 5b0c623a8d
5 changed files with 47 additions and 9 deletions
+2 -1
View File
@@ -25,7 +25,8 @@ into platform-specific packages that can be inspected before they are installed.
or deleting them. or deleting them.
- Dry-run support (no writes, no backups, no plugin changes) and timestamped, per-run backup directories. - Dry-run support (no writes, no backups, no plugin changes) and timestamped, per-run backup directories.
- Shared safety, notification, validation, and status-line hooks. - Shared safety, notification, validation, and status-line hooks.
- User-level plugin installation for Ponytail, i-have-adhd, Superpowers, and Context7; updates only with - User-level plugin installation for Ponytail, i-have-adhd, Superpowers, Context7, Caveman, Humanizer, Impeccable,
and Anthropic Frontend Design; updates only with
`-UpdatePlugins`/`--update-plugins`. `-UpdatePlugins`/`--update-plugins`.
## Architecture ## Architecture
+9 -5
View File
@@ -1,5 +1,9 @@
name claude_marketplace claude_plugin codex_marketplace codex_plugin name claude_marketplace claude_plugin codex_marketplace codex_plugin codex_method codex_source codex_skill
Ponytail DietrichGebert/ponytail ponytail@ponytail DietrichGebert/ponytail ponytail@ponytail Ponytail DietrichGebert/ponytail ponytail@ponytail DietrichGebert/ponytail ponytail@ponytail plugin - -
i-have-adhd ayghri/i-have-adhd i-have-adhd@i-have-adhd ayghri/i-have-adhd i-have-adhd@i-have-adhd i-have-adhd ayghri/i-have-adhd i-have-adhd@i-have-adhd ayghri/i-have-adhd i-have-adhd@i-have-adhd plugin - -
Superpowers - superpowers@claude-plugins-official openai-curated-remote superpowers@openai-curated-remote Superpowers - superpowers@claude-plugins-official openai-curated-remote superpowers@openai-curated-remote plugin - -
Context7 upstash/context7 context7@context7-marketplace upstash/context7 context7@context7-marketplace Context7 upstash/context7 context7@context7-marketplace upstash/context7 context7@context7-marketplace plugin - -
Caveman JuliusBrussee/caveman caveman@caveman thinkhome-org/caveman-codex caveman@thinkhome-caveman plugin - -
Humanizer blader/humanizer humanizer@humanizer - - skill blader/humanizer -
Impeccable pbakaus/impeccable impeccable@impeccable - - impeccable - -
Anthropic Frontend Design anthropics/claude-plugins-official frontend-design@claude-plugins-official - - skill anthropics/skills frontend-design
1 name claude_marketplace claude_plugin codex_marketplace codex_plugin codex_method codex_source codex_skill
2 Ponytail DietrichGebert/ponytail ponytail@ponytail DietrichGebert/ponytail ponytail@ponytail plugin - -
3 i-have-adhd ayghri/i-have-adhd i-have-adhd@i-have-adhd ayghri/i-have-adhd i-have-adhd@i-have-adhd plugin - -
4 Superpowers - superpowers@claude-plugins-official openai-curated-remote superpowers@openai-curated-remote plugin - -
5 Context7 upstash/context7 context7@context7-marketplace upstash/context7 context7@context7-marketplace plugin - -
6 Caveman JuliusBrussee/caveman caveman@caveman thinkhome-org/caveman-codex caveman@thinkhome-caveman plugin - -
7 Humanizer blader/humanizer humanizer@humanizer - - skill blader/humanizer -
8 Impeccable pbakaus/impeccable impeccable@impeccable - - impeccable - -
9 Anthropic Frontend Design anthropics/claude-plugins-official frontend-design@claude-plugins-official - - skill anthropics/skills frontend-design
+3 -1
View File
@@ -2,7 +2,9 @@
The user-level plugin manifest is `adapters/plugins.tsv`. It maps each logical plugin to the marketplace selector understood by Claude Code and Codex. The user-level plugin manifest is `adapters/plugins.tsv`. It maps each logical plugin to the marketplace selector understood by Claude Code and Codex.
The current baseline includes Ponytail, i-have-adhd, Superpowers, and Context7. The install script operates at user scope and is idempotent: a normal run only installs missing plugins (a disabled but already-installed Claude plugin is re-enabled). Pass `-UpdatePlugins`/`--update-plugins` to also update plugins that are already installed, so a configuration update never silently updates third-party plugin code. The current baseline includes Ponytail, i-have-adhd, Superpowers, Context7, Caveman, Humanizer, Impeccable, and Anthropic Frontend Design. The install script operates at user scope and is idempotent: a normal run only installs missing plugins (a disabled but already-installed Claude plugin is re-enabled). Pass `-UpdatePlugins`/`--update-plugins` to also update plugins that are already installed, so a configuration update never silently updates third-party plugin code.
Codex receives Caveman through its native plugin adapter. Humanizer and Anthropic Frontend Design are installed through the cross-agent Skills CLI; Impeccable uses its provider-aware Codex installer. All four are therefore available to both clients, although Codex does not expose all four as marketplace plugins.
Plugin installation requires the corresponding client CLI, network access, and any authentication required by the plugin. Context7 may open an OAuth flow. Codex or plugin hooks may require a trust review in `/hooks`. The scripts never install plugins during a build or doctor run and never install them when `--dry-run` or `-DryRun` is used. Plugin installation requires the corresponding client CLI, network access, and any authentication required by the plugin. Context7 may open an OAuth flow. Codex or plugin hooks may require a trust review in `/hooks`. The scripts never install plugins during a build or doctor run and never install them when `--dry-run` or `-DryRun` is used.
+14
View File
@@ -85,6 +85,20 @@ function Install-ConfiguredPlugins {
$plugin = if ($selectedClient -eq 'Claude') { $entry.claude_plugin } else { $entry.codex_plugin } $plugin = if ($selectedClient -eq 'Claude') { $entry.claude_plugin } else { $entry.codex_plugin }
if ([string]::IsNullOrWhiteSpace($plugin)) { throw ('Plugin selector missing for {0}: {1}' -f $selectedClient, $entry.name) } if ([string]::IsNullOrWhiteSpace($plugin)) { throw ('Plugin selector missing for {0}: {1}' -f $selectedClient, $entry.name) }
if ($selectedClient -eq 'Codex' -and $entry.codex_method -ne 'plugin') {
if ($entry.codex_method -eq 'skill') {
$arguments = @('-y','skills','add',$entry.codex_source,'--global','--agent','codex')
if ($entry.codex_skill -ne '-') { $arguments = @('-y','skills','add',$entry.codex_source,'--skill',$entry.codex_skill,'--global','--agent','codex') }
} elseif ($entry.codex_method -eq 'impeccable') {
$arguments = @('-y','impeccable','install','-y','--providers=codex','--scope=global')
} else {
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)"
continue
}
$installedItem = if ($selectedClient -eq 'Claude') { $installed | Where-Object { $_.id -eq $plugin } | Select-Object -First 1 } else { $installed | Where-Object { $_.pluginId -eq $plugin } | Select-Object -First 1 } $installedItem = if ($selectedClient -eq 'Claude') { $installed | Where-Object { $_.id -eq $plugin } | Select-Object -First 1 } else { $installed | Where-Object { $_.pluginId -eq $plugin } | Select-Object -First 1 }
if ($Update -and $selectedClient -eq 'Claude' -and $null -ne $installedItem) { if ($Update -and $selectedClient -eq 'Claude' -and $null -ne $installedItem) {
Invoke-PluginCommand -Command 'claude' -Arguments @('plugin','update',$plugin) -DryRun:$DryRun Invoke-PluginCommand -Command 'claude' -Arguments @('plugin','update',$plugin) -DryRun:$DryRun
+19 -2
View File
@@ -53,8 +53,8 @@ install_configured_plugins() {
*) printf 'Unknown plugin client selection: %s\n' "$client_selection" >&2; return 1;; *) printf 'Unknown plugin client selection: %s\n' "$client_selection" >&2; return 1;;
esac esac
local client name claude_marketplace claude_plugin codex_marketplace codex_plugin marketplace plugin local client name claude_marketplace claude_plugin codex_marketplace codex_plugin codex_method codex_source codex_skill marketplace plugin
while IFS=$'\t' read -r name claude_marketplace claude_plugin codex_marketplace codex_plugin; do while IFS=$'\t' read -r name claude_marketplace claude_plugin codex_marketplace codex_plugin codex_method codex_source codex_skill; do
[ "$name" = name ] && continue [ "$name" = name ] && continue
[ -n "$name" ] || continue [ -n "$name" ] || continue
[ "$claude_marketplace" = - ] && claude_marketplace= [ "$claude_marketplace" = - ] && claude_marketplace=
@@ -62,6 +62,23 @@ install_configured_plugins() {
for client in "${clients[@]}"; do for client in "${clients[@]}"; do
if [ "$client" = claude ]; then marketplace=$claude_marketplace; plugin=$claude_plugin; else marketplace=$codex_marketplace; plugin=$codex_plugin; fi if [ "$client" = claude ]; then marketplace=$claude_marketplace; plugin=$claude_plugin; else marketplace=$codex_marketplace; plugin=$codex_plugin; fi
[ -n "$plugin" ] || { printf 'Plugin selector missing for %s: %s\n' "$client" "$name" >&2; return 1; } [ -n "$plugin" ] || { printf 'Plugin selector missing for %s: %s\n' "$client" "$name" >&2; return 1; }
if [ "$client" = codex ] && [ "$codex_method" != plugin ]; then
case "$codex_method" in
skill)
if [ "$codex_skill" = - ]; then
run_plugin_command "$dry_run" npx -y skills add "$codex_source" --global --agent codex
else
run_plugin_command "$dry_run" npx -y skills add "$codex_source" --skill "$codex_skill" --global --agent codex
fi
;;
impeccable)
run_plugin_command "$dry_run" npx -y impeccable install -y --providers=codex --scope=global
;;
*) printf 'Unknown Codex install method for %s: %s\n' "$client" "$name" >&2; return 1;;
esac
printf 'PASS Codex skill ensured: %s\n' "$name"
continue
fi
if [ "$dry_run" = false ] && plugin_installed "$client" "$plugin"; then if [ "$dry_run" = false ] && plugin_installed "$client" "$plugin"; then
if [ "$update" = true ] && [ "$client" = claude ]; then if [ "$update" = true ] && [ "$client" = claude ]; then
run_plugin_command "$dry_run" claude plugin update "$plugin" run_plugin_command "$dry_run" claude plugin update "$plugin"