Mastermind plugin-manager — install plugins from npm, uninstall with two-step confirmation, enable/disable installed plugins. Extends mastermind:plugins (listing) and mastermind:plugin-settings (per-plugin config) with the install/uninstall lifecycle. Mirrors PluginManager.tsx.
Scanned 9/10/2026
Install to Claude Code
npx -y skills add monoes/monomind --skill mastermind-plugin-manager --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mastermind Plugin Manager?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/monoes-mastermind-plugin-manager)More formats (shields.io, HTML) on the badges page.
---
name: mastermind-plugin-manager
description: Mastermind plugin-manager — install plugins from npm, uninstall with two-step confirmation, enable/disable installed plugins. Extends mastermind:plugins (listing) and mastermind:plugin-settings (per-plugin config) with the install/uninstall lifecycle. Mirrors PluginManager.tsx.
type: domain-skill
default_mode: confirm
---
# Mastermind Plugin Manager
This skill is invoked by `mastermind:plugin-manager` or directly via `/mastermind:plugin-manager`.
---
## Inputs
- `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
- `action`: list | install | uninstall | enable | disable | check-updates
- `package_name`: npm package name to install (for install; e.g. `@monomind/plugin-github`)
- `plugin_id`: plugin id slug (required for uninstall/enable/disable)
- `confirm`: yes (required second step for uninstall — prevents accidental removal)
- `caller`: command | master
---
## Plugin Record Schema
```json
{
"id": "plugin-slug",
"packageName": "@monomind/plugin-name",
"status": "installed",
"version": "1.2.0",
"category": "monitoring",
"description": "One-line plugin description",
"installedAt": "2026-01-01T00:00:00Z",
"config": {},
"grants": [],
"health": {"status": "ok", "lastCheck": null}
}
```
---
## Step 0 — Brain Load (standalone only)
If `caller` is not "command", load brain context following mastermind-protocol/SKILL.md Brain Load Procedure with namespace: `ops`.
---
## Step 1 — Load Plugin Registry
```bash
registryFile=".monomind/plugins/registry.json"
mkdir -p ".monomind/plugins"
[ ! -f "$registryFile" ] && echo '{"plugins":[]}' > "$registryFile"
```
---
## Step 2 — Execute Action
### list (default)
```bash
echo "INSTALLED PLUGINS"
echo "────────────────────────────────────────────────────────"
printf "%-24s %-10s %-10s %-14s %s\n" "ID" "STATUS" "VERSION" "CATEGORY" "PACKAGE"
echo "────────────────────────────────────────────────────────"
count=$(jq '.plugins | length' "$registryFile")
if [ "$count" -eq 0 ]; then
echo " No plugins installed."
echo " Install one: --action install --package-name @monomind/plugin-github"
else
jq -r '(.plugins // [])[] |
[.id, (.status // "installed"), (.version // "-"), (.category // "general"),
(.packageName // "-")] | @tsv' \
"$registryFile" | while IFS=$'\t' read -r id st ver cat pkg; do
printf "%-24s %-10s %-10s %-14s %s\n" "$id" "$st" "$ver" "$cat" "$pkg"
done
errCount=$(jq '[(.plugins // [])[] | select(.status == "error")] | length' "$registryFile")
[ "$errCount" -gt 0 ] && echo "" && echo " WARNING: $errCount plugin(s) in error state. Run: --action list to inspect."
fi
echo ""
echo " Install: --action install --package-name <npm-package>"
echo " Uninstall: --action uninstall --plugin-id <id>"
echo " Settings: /mastermind:plugin-settings --plugin-id <id>"
```
### install
```bash
[ -z "$package_name" ] && { echo "ERROR: --package-name required (e.g. @monomind/plugin-github)."; exit 1; }
echo "INSTALLING PLUGIN — $package_name"
echo "────────────────────────────────────────────────────────"
echo " Running: npm install $package_name"
# Check if already installed
alreadyId=$(jq -r --arg pkg "$package_name" '(.plugins // [])[] | select(.packageName == $pkg) | .id' "$registryFile" | head -1)
[ -n "$alreadyId" ] && {
echo " Plugin already installed as '$alreadyId'. Use --action enable/disable or reinstall via npm."
exit 0
}
if npm install "$package_name" 2>&1 | tail -5; then
# Derive plugin metadata from npm package
pkgVer=$(node -e "try{console.log(require('${package_name}/package.json').version)}catch(e){console.log('0.0.0')}" 2>/dev/null || echo "0.0.0")
pkgDesc=$(node -e "try{console.log(require('${package_name}/package.json').description||'')}catch(e){console.log('')}" 2>/dev/null || echo "")
pluginId=$(echo "$package_name" | sed 's|@[^/]*/||' | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-//;s/-$//')
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${registryFile}.tmp"
jq --arg id "$pluginId" \
--arg pkg "$package_name" \
--arg ver "$pkgVer" \
--arg desc "$pkgDesc" \
--arg ts "$ts" \
'.plugins += [{"id":$id,"packageName":$pkg,"status":"installed","version":$ver,
"description":$desc,"category":"general","config":{},"grants":[],
"health":{"status":"ok","lastCheck":null},"installedAt":$ts}]' \
"$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
echo ""
echo "Plugin installed: $pluginId @ $pkgVer"
echo " Configure: /mastermind:plugin-settings --plugin-id $pluginId"
else
echo " ERROR: npm install failed. Check the package name and network connectivity."
exit 1
fi
```
### uninstall
```bash
[ -z "$plugin_id" ] && { echo "ERROR: --plugin-id required."; exit 1; }
exists=$(jq -r --arg id "$plugin_id" '[(.plugins // [])[] | select(.id == $id)] | length' "$registryFile")
[ "$exists" -eq 0 ] && { echo "ERROR: Plugin '$plugin_id' not found."; exit 1; }
# Two-step confirmation
if [ "${confirm:-}" != "yes" ]; then
pkg=$(jq -r --arg id "$plugin_id" '(.plugins // [])[] | select(.id == $id) | .packageName // $id' "$registryFile")
echo "UNINSTALL CONFIRMATION REQUIRED"
echo "────────────────────────────────────────────────────────"
echo " Plugin: $plugin_id ($pkg)"
echo " This will remove the plugin and all its configuration."
echo ""
echo " To confirm: --action uninstall --plugin-id $plugin_id --confirm yes"
exit 0
fi
pkg=$(jq -r --arg id "$plugin_id" '(.plugins // [])[] | select(.id == $id) | .packageName // ""' "$registryFile")
# Remove from registry
tmp="${registryFile}.tmp"
jq --arg id "$plugin_id" \
'.plugins = [(.plugins // [])[] | select(.id != $id)]' \
"$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
echo "Plugin '$plugin_id' removed from registry."
# Attempt npm uninstall if packageName known
if [ -n "$pkg" ]; then
echo " Running: npm uninstall $pkg"
npm uninstall "$pkg" 2>&1 | tail -3 || echo " WARNING: npm uninstall had errors — registry entry removed anyway."
fi
```
### enable
```bash
[ -z "$plugin_id" ] && { echo "ERROR: --plugin-id required."; exit 1; }
exists=$(jq -r --arg id "$plugin_id" '[(.plugins // [])[] | select(.id == $id)] | length' "$registryFile")
[ "$exists" -eq 0 ] && { echo "ERROR: Plugin '$plugin_id' not found."; exit 1; }
tmp="${registryFile}.tmp"
jq --arg id "$plugin_id" \
'.plugins = [(.plugins // [])[] | if .id == $id then .status = "installed" | .disabledAt = null else . end]' \
"$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
echo "Plugin '$plugin_id' ENABLED."
```
### disable
```bash
[ -z "$plugin_id" ] && { echo "ERROR: --plugin-id required."; exit 1; }
exists=$(jq -r --arg id "$plugin_id" '[(.plugins // [])[] | select(.id == $id)] | length' "$registryFile")
[ "$exists" -eq 0 ] && { echo "ERROR: Plugin '$plugin_id' not found."; exit 1; }
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${registryFile}.tmp"
jq --arg id "$plugin_id" --arg ts "$ts" \
'.plugins = [(.plugins // [])[] | if .id == $id then .status = "disabled" | .disabledAt = $ts else . end]' \
"$registryFile" > "$tmp" && mv "$tmp" "$registryFile"
echo "Plugin '$plugin_id' DISABLED — will not load on next startup."
```
### check-updates
```bash
echo "CHECKING PLUGIN UPDATES"
echo "────────────────────────────────────────────────────────"
count=$(jq '.plugins | length' "$registryFile")
[ "$count" -eq 0 ] && { echo " No plugins installed."; exit 0; }
jq -r '(.plugins // [])[] | select(.packageName != null) |
[.id, .packageName, (.version // "unknown")] | @tsv' \
"$registryFile" | while IFS=$'\t' read -r id pkg ver; do
latest=$(curl -sf "https://registry.npmjs.org/${pkg}/latest" 2>/dev/null | jq -r '.version // "?"' 2>/dev/null || echo "?")
if [ "$latest" != "?" ] && [ "$latest" != "$ver" ]; then
echo " [$id] $ver → $latest — run: npm install $pkg"
else
echo " [$id] $ver (up to date)"
fi
done
```
---
## Step 3 — Return Output
```yaml
domain: ops
status: complete
action: <action>
plugin_id: <plugin_id>
```
---
## Step 4 — Brain Write (standalone only)
If `caller` is not "command", follow mastermind-protocol/SKILL.md Brain Write Procedure for domain `ops`.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!