Skip to content

Latest commit

 

History

History
242 lines (182 loc) · 8.46 KB

plugins.md

File metadata and controls

242 lines (182 loc) · 8.46 KB

Plugins

OpenCLI supports community-contributed plugins. Install third-party adapters from GitHub, and they're automatically discovered alongside built-in commands.

Quick Start

# Install a plugin
opencli plugin install github:ByteYue/opencli-plugin-github-trending

# List installed plugins
opencli plugin list

# Update one plugin
opencli plugin update github-trending

# Update all installed plugins
opencli plugin update --all

# Use the plugin (it's just a regular command)
opencli github-trending repos --limit 10

# Remove a plugin
opencli plugin uninstall github-trending

How Plugins Work

Plugins live in ~/.opencli/plugins/<name>/. Each subdirectory is scanned at startup for .ts or .js command files — the same formats used by built-in adapters.

Supported Source Formats

# GitHub shorthand
opencli plugin install github:user/repo
opencli plugin install github:user/repo/subplugin   # install specific sub-plugin from monorepo
opencli plugin install https://github.com/user/repo

# Any git-cloneable URL
opencli plugin install https://gitlab.example.com/team/repo.git
opencli plugin install ssh://git@gitlab.example.com/team/repo.git
opencli plugin install git@gitlab.example.com:team/repo.git

# Local plugin (for development)
opencli plugin install file:///path/to/plugin
opencli plugin install /path/to/plugin

The repo name prefix opencli-plugin- is automatically stripped for the local directory name. For example, opencli-plugin-hot-digest becomes hot-digest.

Plugin Manifest (opencli-plugin.json)

Plugins can include an opencli-plugin.json manifest file at the repo root to declare metadata:

{
  "name": "my-plugin",
  "version": "1.0.0",
  "opencli": ">=1.0.0",
  "description": "My awesome plugin"
}
Field Description
name Plugin name (overrides repo-derived name)
version Semantic version
opencli Required opencli version range (e.g. >=1.0.0, ^1.2.0)
description Human-readable description
plugins Monorepo sub-plugin declarations (see below)

The manifest is optional — plugins without one continue to work exactly as before.

Monorepo Plugins

A single repository can contain multiple plugins by declaring a plugins field in opencli-plugin.json:

{
  "version": "1.0.0",
  "opencli": ">=1.0.0",
  "description": "My plugin collection",
  "plugins": {
    "polymarket": {
      "path": "packages/polymarket",
      "description": "Prediction market analysis",
      "version": "1.2.0"
    },
    "defi": {
      "path": "packages/defi",
      "description": "DeFi protocol data",
      "version": "0.8.0",
      "opencli": ">=1.2.0"
    },
    "experimental": {
      "path": "packages/experimental",
      "disabled": true
    }
  }
}

Installing

# Install ALL enabled sub-plugins from a monorepo
opencli plugin install github:user/opencli-plugins

# Install a SPECIFIC sub-plugin
opencli plugin install github:user/opencli-plugins/polymarket

How It Works

  • The monorepo is cloned once to ~/.opencli/monorepos/<repo>/
  • Each sub-plugin gets a symlink in ~/.opencli/plugins/<name>/ pointing to its subdirectory
  • Command discovery works transparently — symlinks are scanned just like regular directories
  • Disabled sub-plugins (with "disabled": true) are skipped during install
  • Sub-plugins can specify their own opencli compatibility range

Updating

Updating any sub-plugin from a monorepo pulls the entire repo and refreshes all sub-plugins:

opencli plugin update polymarket   # updates the monorepo, refreshes all

Uninstalling

opencli plugin uninstall polymarket   # removes just this sub-plugin's symlink

When the last sub-plugin from a monorepo is uninstalled, the monorepo clone is automatically cleaned up.

Version Tracking

OpenCLI records installed plugin versions in ~/.opencli/plugins.lock.json. Each entry stores the plugin source, current git commit hash, install time, and last update time. opencli plugin list shows the short commit hash when version metadata is available.

Creating a Plugin

Creating a TypeScript Plugin

my-plugin/
├── package.json
├── my-command.ts
└── README.md

package.json:

{
  "name": "opencli-plugin-my-plugin",
  "version": "0.1.0",
  "type": "module",
  "peerDependencies": {
    "@jackwener/opencli": ">=1.0.0"
  }
}

my-command.ts:

import { cli, Strategy } from '@jackwener/opencli/registry';

cli({
  site: 'my-plugin',
  name: 'my-command',
  description: 'My custom command',
  access: 'read', // 'read' | 'write'
  example: 'opencli my-plugin my-command -f yaml',
  strategy: Strategy.PUBLIC,
  browser: false,
  args: [
    { name: 'limit', type: 'int', default: 10, help: 'Number of items' },
  ],
  columns: ['title', 'score'],
  func: async (kwargs) => {
    const res = await fetch('https://api.example.com/data');
    const data = await res.json();
    return data.items.slice(0, kwargs.limit).map((item: any, i: number) => ({
      title: item.title,
      score: item.score,
    }));
  },
});

TS Plugin Install Lifecycle

When you run opencli plugin install, TS plugins are automatically set up:

  1. Clone — git clone --depth 1 from GitHub
  2. npm install — Resolves regular dependencies
  3. Host symlink — Links the running @jackwener/opencli into the plugin's node_modules/ so import from '@jackwener/opencli/registry' always resolves against the host
  4. Transpile — Compiles .ts → .js via esbuild (production node cannot load .ts directly)

On startup, if both my-command.ts and my-command.js exist, the .js version is loaded to avoid duplicate registration.

Example Plugins

Repo Type Description
opencli-plugin-albato JS Albato automation workflow management: scenario inspection, start/pause, failure diagnosis, and retry
opencli-plugin-amap JS AutoNavi / 高德地图 spot & route extraction, coordinate decoders (GCJ-02 & WGS-84), and SSR search
opencli-plugin-github-trending TS GitHub Trending repositories
opencli-plugin-goofish JS Goofish / 闲鱼 buyer orders, favorites, IM chat, profile, item search, and fulfillment stats
opencli-plugin-hot-digest TS Multi-platform trending aggregator (zhihu, weibo, bilibili, v2ex, stackoverflow, reddit, linux-do)
opencli-plugin-juejin TS 稀土掘金 (Juejin) hot articles, categories, and article feed
opencli-plugin-rubysec TS RubySec advisory archive and advisory article reader
opencli-plugin-taobao JS Taobao buyer chat history, order history, bought shops, favorites, and keyword-based chat summaries
opencli-plugin-x-article-publisher JS Publish Markdown with local images as X long-form Articles via OpenCLI and xPoster

Community adapter bundles

Albato, Goofish and Taobao currently keep their command files under clis/<site> without a monorepo manifest. Installing the repository root with github:vecyang1/opencli-plugin-<site> fails structure validation. Clone the repository and install its command directory instead; keep the clone because local installs link to it:

git clone https://github.com/vecyang1/opencli-plugin-taobao.git
opencli plugin install ./opencli-plugin-taobao/clis/taobao

For Albato or Goofish, substitute albato or goofish in both paths. Those two repositories require Node.js 22.5 or later. Follow each repository's README for its additional tools and setup. These are community-maintained adapters; the listing describes their commands, not a guarantee of historical-data completeness.

Troubleshooting

Command not found after install

Restart opencli (or open a new terminal) — plugins are discovered at startup.

TS plugin import errors

If you see Cannot find module '@jackwener/opencli/registry', the host symlink may be broken. Reinstall the plugin:

opencli plugin uninstall my-plugin
opencli plugin install github:user/opencli-plugin-my-plugin