New plugins: use the isolated method. Create files only inside
plugins/<name>/. Never editplugins/plugins.jsonorcli/plugin-install-guidance.jsfor new bundled plugins. See the "Isolated Plugin Structure" section below.
A bundled plugin is fully self-contained in its own directory. The system auto-discovers
plugins by scanning plugins/ for directories containing plugin.json.
plugins/my-plugin/
├── plugin.json # Required: manifest (commands, checks, adapters)
├── meta.json # Required: registry metadata (description, tags, has_learn)
├── install-guidance.json # Optional: install steps (can also go in meta.json)
├── skills/quickstart/SKILL.md # Optional: agent learning content
├── README.md # Optional: human documentation
└── examples/ # Optional: example usage
The meta.json file provides registry-level metadata that would previously have required
editing the shared plugins/plugins.json file:
{
"description": "My CLI tool integration for supercli",
"tags": ["mytool", "category", "keyword"],
"has_learn": true,
"install_guidance": {
"plugin": "my-plugin",
"binary": "mytool",
"check": "mytool --version",
"install_steps": [
"npm install -g mytool",
"mytool --version"
],
"note": "Optional installation note"
}
}| Field | Type | Required | Description |
|---|---|---|---|
description |
string | Yes | Short description shown in plugins explore |
tags |
string[] | Yes | Discovery tags for filtering |
has_learn |
boolean | No | Set to true if plugin has a skills/quickstart/SKILL.md |
install_guidance |
object | No | Install steps (alternative: use install-guidance.json) |
If you prefer to keep install guidance separate from metadata, use install-guidance.json:
{
"plugin": "my-plugin",
"binary": "mytool",
"check": "mytool --version",
"install_steps": [
"npm install -g mytool",
"mytool --version"
],
"note": "Optional note"
}When the system looks for plugin metadata and install guidance, it checks in this order:
meta.json(description, tags, has_learn, install_guidance)install-guidance.json(install guidance only)plugin.jsonfields (fallback for description, install_guidance)- Legacy:
plugins/plugins.jsonregistry entries - Legacy:
cli/plugin-install-guidance.jshardcoded map
# Install from local directory
supercli plugins install ./plugins/my-plugin
# Verify discovery
supercli plugins explore --name my-plugin
# Check health
supercli plugins doctor my-pluginLearn how to create plugin harnesses that turn any CLI into a supercli harness.
A plugin harness bridges supercli to an external CLI tool. It allows supercli to:
- Discover and route commands to the external CLI
- Expose the CLI's functionality through supercli's unified interface
- Provide consistent output formatting and error handling
- Integrate AI-driven capability discovery across all harnesses
Every plugin harness consists of:
- plugin.json — Manifest defining metadata and commands
- Optional: Custom adapter code (for complex logic)
- Optional: Documentation and examples
my-plugin/
├── plugin.json # Required: manifest
├── README.md # Optional: plugin documentation
└── examples/ # Optional: example usage
└── example.sh
The plugin.json file is the core of your harness. It describes:
- Plugin metadata (name, version, description)
- External CLI requirements (binary checks)
- Available commands and their routing
{
"name": "my-cli-harness",
"version": "0.1.0",
"description": "Wrap my-cli with supercli integration",
"source": "https://github.com/user/my-cli",
"checks": [
{ "type": "binary", "name": "my-cli" }
],
"commands": [
{
"namespace": "my-cli",
"resource": "resource-name",
"action": "action-name",
"description": "What this command does",
"adapter": "process",
"adapterConfig": { ... },
"args": [ ... ]
}
]
}{
"name": "beads", // Unique plugin identifier
"version": "0.1.0", // Semantic versioning
"description": "...", // Short description
"source": "https://...", // Link to upstream CLI
"tags": ["task", "automation"], // Optional: discovery tags
"author": "Your Name" // Optional: plugin author
}"checks": [
{
"type": "binary",
"name": "br", // Binary name to check
"version": ">=1.0.0" // Optional: minimum version
}
]Each command maps supercli routing to CLI execution.
Use for CLIs where you want to expose specific commands:
{
"namespace": "beads",
"resource": "issue",
"action": "create",
"description": "Create a beads issue",
"adapter": "process",
"adapterConfig": {
"command": "br", // Binary to execute
"baseArgs": ["create"], // Base command arguments
"positionalArgs": ["title"],// Map supercli args to CLI positional args
"jsonFlag": "--json", // Flag for JSON output
"parseJson": true, // Parse CLI output as JSON
"timeout_ms": 5000, // Execution timeout
"missingDependencyHelp": "Run: supercli beads install steps"
},
"args": [
{
"name": "title",
"type": "string",
"required": true,
"description": "Issue title"
},
{
"name": "priority",
"type": "integer",
"required": false,
"description": "Priority level (0-4)"
}
]
}Use for CLIs where you want full access to all functionality:
{
"namespace": "gwc",
"resource": "_", // Wildcard namespace/resource
"action": "_", // Wildcard action
"description": "Passthrough to gws CLI",
"adapter": "process",
"adapterConfig": {
"command": "gws", // Binary to execute
"passthrough": true, // Enable full passthrough mode
"parseJson": true, // Parse CLI output
"timeout_ms": 15000, // Longer timeout for complex operations
"missingDependencyHelp": "Run: supercli gwc install steps"
},
"args": [] // No mapped args (passthrough)
}The most common adapter. Executes an external CLI binary.
Configuration Options:
| Key | Type | Description |
|---|---|---|
command |
string | Binary name to execute (must be in PATH) |
baseArgs |
string[] | Default arguments (e.g., ["create"]) |
positionalArgs |
string[] | Map supercli args to CLI positional args |
optionalArgs |
object | Map supercli flag args to CLI flags |
jsonFlag |
string | Flag for JSON output (e.g., --json) |
parseJson |
boolean | Parse CLI output as JSON (default: false) |
passthrough |
boolean | Pass all args directly to CLI (default: false) |
timeout_ms |
number | Execution timeout in milliseconds |
missingDependencyHelp |
string | Message if binary not found |
"adapterConfig": {
"command": "my-cli",
"baseArgs": ["cmd"],
"positionalArgs": ["name", "email"] // First arg -> name, second -> email
}Usage:
supercli my-cli resource action myname myemail@example.comMaps to: my-cli cmd myname myemail@example.com
"adapterConfig": {
"command": "my-cli",
"baseArgs": ["cmd"],
"optionalArgs": {
"priority": "--priority", // supercli --priority maps to --priority
"json": "--json" // supercli --json maps to --json
}
}Usage:
supercli my-cli resource action --priority high --jsonMaps to: my-cli cmd --priority high --json
{
"name": "beads",
"version": "0.1.0",
"description": "Wrap beads_rust (br) issue tracking commands",
"source": "https://github.com/Dicklesworthstone/beads_rust",
"checks": [
{ "type": "binary", "name": "br" }
],
"commands": [
{
"namespace": "beads",
"resource": "issue",
"action": "create",
"description": "Create a beads issue",
"adapter": "process",
"adapterConfig": {
"command": "br",
"baseArgs": ["create"],
"positionalArgs": ["title"],
"jsonFlag": "--json",
"parseJson": true,
"missingDependencyHelp": "Run: supercli beads install steps"
},
"args": [
{ "name": "title", "type": "string", "required": true },
{ "name": "priority", "type": "integer", "required": false }
]
},
{
"namespace": "beads",
"resource": "issue",
"action": "list",
"description": "List beads issues",
"adapter": "process",
"adapterConfig": {
"command": "br",
"baseArgs": ["list"],
"jsonFlag": "--json",
"parseJson": true,
"missingDependencyHelp": "Run: supercli beads install steps"
},
"args": [
{ "name": "status", "type": "string", "required": false },
{ "name": "priority", "type": "string", "required": false }
]
}
]
}{
"name": "gwc",
"version": "0.1.0",
"description": "Wrap Google Workspace CLI (gws) with passthrough support",
"source": "https://github.com/googleworkspace/cli",
"checks": [
{ "type": "binary", "name": "gws" }
],
"commands": [
{
"namespace": "gwc",
"resource": "_",
"action": "_",
"description": "Passthrough to gws CLI",
"adapter": "process",
"adapterConfig": {
"command": "gws",
"passthrough": true,
"parseJson": true,
"timeout_ms": 15000,
"missingDependencyHelp": "Run: supercli gwc install steps"
},
"args": []
}
]
}# Install from local directory
supercli plugins install ./path/to/my-plugin
# Test a command
supercli my-plugin resource action --arg value
# Show plugin info
supercli plugins show my-plugin
# Check plugin health
supercli plugins doctor my-plugin# Check syntax of plugin.json
cat plugins/my-plugin/plugin.json | jq .
# Verify binary detection
which my-cli# Verbose output
supercli my-plugin resource action --verbose
# See command details
supercli inspect my-plugin resource action
# Show generated command before execution
supercli plan my-plugin resource action --argsOnce your plugin is tested and working:
-
Create a GitHub repository with your plugin code
-
Structure it properly:
my-plugin-harness/ ├── plugin.json ├── meta.json ├── README.md ├── LICENSE └── examples/ -
Publish to registry:
supercli plugins publish ./my-plugin-harness
-
Community members can install:
supercli plugins install --git https://github.com/user/my-plugin-harness.git # Or once in registry: supercli plugins install my-plugin-harness
- Be selective with wrapped commands: Only expose stable, frequently-used commands
- Use passthrough for flexibility: If the CLI is stable, passthrough is often better
- Provide clear descriptions: Help users understand what each command does
- Include dependency checks: Always verify the external CLI is installed
- Set appropriate timeouts: Long-running operations may need extended timeouts
- Prefer JSON output: Use
jsonFlagandparseJson: truefor structured data - Document output schema: Help users understand the response format
- Handle errors gracefully: Map CLI exit codes to supercli exit codes
- Provide helpful error messages: Use
missingDependencyHelpto guide installation
- Keep argument names simple: Use lowercase, hyphenated names
- Document constraints: Specify required vs. optional arguments
- Type arguments correctly: Use string, integer, boolean, etc.
- Provide examples: Show common usage patterns in docs
- Write a clear README: Explain what the plugin does and how to use it
- Include examples: Show real-world usage patterns
- Link to upstream CLI: Help users learn more about the tool
- Add install instructions: Make it easy to get started
# Check syntax
jq . plugin.json
# Verify binary is installed
which my-cli
# Check plugin directory
supercli plugins show my-plugin# Test the binary directly
my-cli cmd arg
# Run with verbose output
supercli my-plugin resource action --verbose
# Check timeout isn't too short
# Increase timeout_ms in adapterConfig# See generated command plan
supercli plan my-plugin resource action --arg value
# Test arg parsing
supercli inspect my-plugin resource actionNote: This section describes the previous method of registering plugins. It remains functional for existing plugins but should NOT be used for new bundled plugins.
Previously, adding a bundled plugin required editing two shared files:
plugins/plugins.json— Add a registry entry with description, tags, and sourcecli/plugin-install-guidance.js— Add an entry toPLUGIN_INSTALL_GUIDANCEmap
This approach caused merge conflicts when multiple plugins were added in parallel. The new
isolated meta.json convention eliminates this problem entirely.
If you are maintaining an existing plugin that uses the old method, it will continue to work. Consider migrating to the isolated method by:
- Creating
plugins/<name>/meta.jsonwith description, tags, and has_learn - Optionally creating
plugins/<name>/install-guidance.jsonwith install steps - Removing the plugin's entry from
plugins/plugins.json - Removing the plugin's entry from
cli/plugin-install-guidance.js
Have a plugin you'd like to share? Consider:
- Creating a quality, well-documented plugin
- Opening a discussion in the supercli community
- Submitting your plugin for inclusion in the built-in registry
See CONTRIBUTING.md for details.