Remote plugin download & installation system
This document describes the design and implementation plan for the remote plugin download and installation system, which allows users to install, update, and uninstall plugins from a central registry hosted at cli.datarobot.com/plugins/index.json.
Overview
The system enables:
- Downloading and installing versioned plugins from a remote registry
- Semver-based version constraints (exact, caret, tilde, range)
- Platform-agnostic plugin packages containing both Posix and Windows scripts
- Python-based plugins wrapped in shell scripts using uv run
Architecture
Plugin Registry (index.json)
A minimal JSON schema pointing to plugin archives:
{
"version": "1",
"plugins": {
"assist": {
"name": "assist",
"description": "AI agent design, coding, and deployment assistant",
"versions": [
{
"version": "0.1.6",
"url": "assist/assist-0.1.6.tar.xz",
"sha256": "...",
"releaseDate": "2026-02-11"
}
]
}
}
}
Note: URLs can be relative (e.g., assist/assist-0.1.6.tar.xz) or absolute (e.g., https://example.com/plugins/assist-0.1.6.tar.xz). Relative URLs are resolved against the base URL of the registry. This enables the same registry to work with both local development servers and production CDNs.
Plugin package structure
Each .tar.xz archive contains:
manifest.json # Plugin metadata and platform script mappings
scripts/
dr-<name>.sh # Posix wrapper script
dr-<name>.ps1 # Windows PowerShell script
Manifest schema
The manifest.json inside each package defines platform-specific executables:
{
"name": "assist",
"version": "0.1.6",
"description": "AI agent design, coding, and deployment assistant",
"minCLIVersion": "0.2.0",
"scripts": {
"posix": "scripts/dr-assist.sh",
"windows": "scripts/dr-assist.ps1"
}
}
Implementation steps
1. Create plugin registry schema
- Add
docs/plugins/index.jsonwith minimal schema - Support plugin names, semver versions, descriptions, and download URLs
- Include SHA256 checksums per artifact for verification
2. Build plugin package
- Create wrapper scripts:
dr-<name>.sh(Posix): Executesuv run --with <package> <command> "$@"dr-<name>.ps1(Windows): PowerShell equivalent- Package with
manifest.jsondefining platform script mappings - Create
.tar.xzarchive and publish todocs/plugins/<plugin>/
3. Implement plugin install command
- Create
cmd/plugin/install/cmd.go - Fetch registry (
index.json) from remote URL - Parse semver constraints using version comparison logic
- Select appropriate platform (windows vs posix)
- Download and verify SHA256 checksums
- Extract to
~/.config/datarobot/plugins/<name>/ - Make scripts executable
- Persist installation metadata in
.installed.json
4. Update plugin discovery
- Modify
internal/plugin/discover.go - Search
~/.config/datarobot/plugins/first (higher priority than PATH) - Scan subdirectories for
manifest.json - Resolve platform-specific executable from manifest's
scriptsfield - Maintain backward compatibility with PATH-based plugins
5. Add update/uninstall commands
- Create
cmd/plugin/update/cmd.go: - Compare installed vs available versions
- Re-download and reinstall if newer version exists
- Support
--allflag for bulk updates - Create
cmd/plugin/uninstall/cmd.go: - Remove plugin directory from managed plugins
- Clean up installation metadata
Semver support
Version constraints supported:
- Exact: 1.2.3 - Match exactly this version
- Caret: ^1.2.3 - Any version compatible with major (1.x.x >= 1.2.3)
- Tilde: ~1.2.3 - Any version compatible with minor (1.2.x >= 1.2.3)
- Range: >=1.0.0 - Any version at or above
- Latest: latest or empty - Most recent version
Directory structure
~/.config/datarobot/
plugins/
assist/ # Managed plugin directory
manifest.json # Plugin manifest
.installed.json # Installation metadata
scripts/
dr-assist.sh
dr-assist.ps1
Plugin execution
When a managed plugin is invoked:
1. Discovery finds the plugin in ~/.config/datarobot/plugins/
2. Platform-specific script is resolved from manifest.json
3. On Posix: Execute .sh script with bash
4. On Windows: Execute .ps1 script with PowerShell
Python plugin pattern
For Python-based plugins, wrapper scripts use uv for dependency management:
This pattern:
- Eliminates bundling Python dependencies
- Leverages uv's fast package resolution
- Works in air-gapped environments when pre-cached
Files created
| File | Purpose |
|---|---|
docs/plugins/index.json |
Remote plugin registry |
cmd/plugin/install/cmd.go |
Install command |
cmd/plugin/uninstall/cmd.go |
Uninstall command |
cmd/plugin/update/cmd.go |
Update command |
internal/plugin/remote.go |
Remote fetch & install logic |
internal/plugin/types.go |
Extended type definitions |
cmd/self/plugin/package/cmd.go |
Package command |
cmd/self/plugin/add/cmd.go |
Add to registry command |
cmd/self/plugin/publish/cmd.go |
Publish command (all-in-one) |
Files modified
| File | Changes |
|---|---|
cmd/plugin/cmd.go |
Register new subcommands |
internal/plugin/discover.go |
Scan managed plugins directory |
internal/repo/paths.go |
Added ManagedPluginsDir() |
Usage examples
# List available plugins from registry
dr plugin install --list
dr plugin install --list --registry-url http://127.0.0.1:8000/cli/dev-docs/plugins
# Install a plugin
dr plugin install assist
dr plugin install assist --version 0.1.6
dr plugin install assist --version "^0.1.0"
dr plugin install assist --registry-url http://127.0.0.1:8000/cli/dev-docs/plugins
# Update plugins
dr plugin update assist
dr plugin update --all
# Uninstall a plugin
dr plugin uninstall assist
# List installed plugins
dr plugin list
Future considerations
- UV prerequisite checking: Add
uvto prerequisites validation - Plugin update notifications: Show "(update available)" in
dr plugin list - GitHub Actions automation: Automate plugin publishing workflow
- Code signing: Add verification for macOS/Windows binaries