Principle:Openclaw Openclaw Plugin Installation
Plugin Installation
Plugin Installation is the principle governing how OpenClaw acquires plugin packages from multiple sources -- the npm registry, local filesystem paths, compressed archives, or single files -- validates their manifests, scans them for security concerns, resolves their dependencies, and copies them into the extensions directory.
Overview
OpenClaw plugins are TypeScript packages that declare their entry points via an openclaw.extensions array in package.json. Before a plugin can be loaded and registered, it must be installed: its source must be fetched, its manifest validated, its code security-scanned, and its runtime dependencies resolved.
The installation system is designed around three principles:
- Source flexibility. Plugins can be installed from the npm registry (by package spec), from a local directory, from an archive file (
.tar.gz,.tgz,.zip), or from a single TypeScript/JavaScript file. - Safety first. Every plugin goes through manifest validation (the
openclaw.extensionsfield must exist and be non-empty) and a code security scan before installation proceeds. Path traversal is prevented at every stage. - Idempotent semantics. The install operation supports both
"install"(fails if the target already exists) and"update"(backs up the existing install, replaces it, and rolls back on failure) modes.
Installation Sources
| Source | Entry Point | Behavior |
|---|---|---|
| npm registry | installPluginFromNpmSpec() |
Runs npm pack <spec> in a temp directory to download the tarball, then delegates to the archive installer.
|
| Local path | installPluginFromPath() |
Auto-detects whether the path points to a directory, an archive, or a single file and delegates to the appropriate installer. |
| Archive | installPluginFromArchive() |
Extracts the archive to a temp directory, locates the package root, then delegates to the package-directory installer. |
| Directory | installPluginFromDir() |
Validates the directory contains a package.json, then delegates to the package-directory installer.
|
| Single file | installPluginFromFile() |
Copies a single .ts or .js file directly into the extensions directory.
|
Installation Pipeline
For package-based installations (npm, archive, directory), the common pipeline is:
- Manifest read. Read
package.jsonfrom the package directory. - Extensions validation. Verify that
openclaw.extensionsis a non-empty array of strings. - Plugin ID derivation. The unscoped package name becomes the plugin ID (e.g.,
@openclaw/voice-callbecomesvoice-call). - Path safety check. Every extension entry path is verified to stay within the package directory. Entries that escape the directory are logged and skipped.
- Security scan. The package directory is scanned for dangerous code patterns. Critical findings produce warnings but do not block installation.
- Target resolution. The target directory is computed inside
~/.openclaw/extensions/(or a custom extensions directory), with path traversal prevention. - Collision check. In install mode, the target must not already exist. In update mode, the existing directory is backed up.
- Copy. The package directory is recursively copied to the target.
- Dependency installation. If the package has
dependencies,npm install --omit=devis run inside the target directory. - Cleanup. Backup directories are removed on success; restored on failure.
Result Type
All install functions return InstallPluginResult:
export type InstallPluginResult =
| {
ok: true;
pluginId: string;
targetDir: string;
manifestName?: string;
version?: string;
extensions: string[];
}
| { ok: false; error: string };
A successful result carries the derived plugin ID, the installation path, the package name, the version, and the list of extension entry points. A failure carries an error message.
Dry Run Support
All install functions accept a dryRun parameter. When set to true, the function performs validation and returns the would-be result without copying files or running npm install. This is used by the CLI to preview installation effects.
Related Concepts
- Extension Type Identification -- how plugins differ from skills.
- Extension Configuration -- how installed plugins are enabled and configured.
- Extension Verification -- how installed plugins are discovered and loaded into the registry.
Implementation
Implementation:Openclaw_Openclaw_InstallPluginFromNpmSpec