Soubi

CLI

init, build, check, install, uninstall, tools, port, add-harness, and dev.

Run the published CLI with npx soubi@latest <command>. Inside a project created by soubi init, use the local binary with npx soubi <command> or the generated npm scripts.

Repository contributors can run the same CLI with pnpm soubi <command>.

init

Creates a new portable plugin, installs its dependencies, and initializes Git when the destination is not already in a repository.

npx soubi@latest init my-plugin

Run it inside an existing project to preserve existing files, scripts, and dependencies:

npx soubi@latest init .

Soubi always adds soubi:build, soubi:check, and soubi:dev scripts. In a new plugin, the shorter build, check, and dev aliases point to the same commands. Existing scripts with those names are preserved.

FlagDescription
--package-manager <name>Use npm, pnpm, yarn, or bun.
--no-installWrite the scaffold without installing dependencies.
--no-gitSkip Git initialization.
--forceReplace existing template files.

Sources

build, check, install, uninstall, and tools accept a positional source (or the --cwd flag). A source is one of:

FormResolves to
. / ./path / /absa local directory (default)
owner/repoa GitHub repo (shorthand)
github:owner/repo#refa GitHub repo at an optional ref
npm:pkg@versionan npm package

Remote sources are fetched into a temp dir with the system git / npm and cleaned up afterward. An existing local path always wins over the owner/repo shorthand.

Common flags

FlagApplies toDescription
--cwd <dir>build/check/install/uninstall/tools/devThe plugin root (always local). Defaults to ..
--harness <a,b>build/check/install/devRestrict to specific harnesses.
--out <dir>build, devOutput root, relative to the plugin dir. Defaults to .soubi-out.

build

Compiles the plugin and writes .soubi-out/<harness>/ for every non-excluded target.

pnpm soubi build ./my-plugin --harness claude,opencode

Add --strict to exit non-zero when any target is excluded.

check

Validates and reports every problem across every target at once without writing files. Exits non-zero only when there are real failures (unsupported-hard exclusions).

pnpm soubi check ./my-plugin

install

Merges compiled artifacts beneath the selected repository/install base and records hashes and provenance, never values, in its ownership manifest. Each adapter supplies its complete native path relative to that base: some use a harness directory (for example .claude or .opencode), while root-oriented adapters can span several top-level directories. Id-keyed JSON config (.mcp.json, opencode.json, kilo.json, MastraCode/Amp/Kiro settings, and Droid mcp.json) is merged by key: identical plugin entries are shared, while differing entries stop the whole install before anything is written. Existing user content is never silently replaced.

Root AGENTS.md instructions use Soubi-managed blocks, so blocks from multiple plugins and arbitrary surrounding text can coexist. A changed managed block, ordinary file, or JSON key is treated as a conflict on reinstall. Malformed manifest/config/markers also abort without rewrite. Older installs must be reinstalled for the same harnesses before they can be safely uninstalled.

Only one Soubi install, uninstall, or installed-plugin listing can run for a selected base at a time. Install and uninstall changes are staged in a private journal under .soubi/transactions/, then destination files are replaced atomically and .soubi/manifest.json is committed last. A failure before that commit rolls the destination changes back. If a process is interrupted, the next manifest-facing command claims a dead local lock and either completes cleanup or restores the before state. Recovery stops and reports the affected path instead of overwriting a destination edited after the interruption.

For diagnosis, inspect .soubi/install.lock and .soubi/transactions/ beneath the selected base. This local protocol does not coordinate distributed filesystems or protect against unrelated programs directly editing destinations while Soubi is running.

pnpm soubi install ./my-plugin            # into ./
pnpm soubi install ./my-plugin --global   # into ~/
pnpm soubi install ./my-plugin --dry-run  # preview only

# Final paths are relative to the selected base:
pnpm soubi install ./my-plugin --dest ./repo --harness cursor    # .cursor-plugin/, rules/, skills/, commands/, agents/, hooks/, mcp.json
pnpm soubi install ./my-plugin --dest ./repo --harness copilot   # .github/..., .vscode/mcp.json
pnpm soubi install ./my-plugin --dest ./repo --harness windsurf  # AGENTS.md, .windsurf/..., mcp_config.json
FlagDescription
--dest <dir>Selected repository/install base (default .).
--globalInstall into the home directory.
--dry-runPrint what would be written without writing.

uninstall

Removes only unchanged, plugin-origin content whose last Soubi owner is being uninstalled, including the plugin's own keys in shared JSON config. Pre-existing, shared, or user-modified content remains in place; the summary reports it as preserved. Before uninstalling, Soubi revalidates manifest targets against the selected destination or global base; an invalid path aborts without deletion. Reinstall legacy v1 state for the same harnesses first.

pnpm soubi uninstall --id my-plugin          # by id
pnpm soubi uninstall ./my-plugin             # infer id by scanning the source
pnpm soubi uninstall --id my-plugin --global

tools

List the plugin's custom tools, or run one locally for testing (invokes the real execute function).

pnpm soubi tools ./my-plugin
pnpm soubi tools ./my-plugin --call diff-stats --args '{"base":"main"}'

port

Reverse-generate a portable Soubi plugin from an existing native plugin (currently Claude Code layout).

pnpm soubi port ./some-claude-plugin --out ./ported

add-harness

Scaffold a new adapter source folder under packages/soubi/src/adapters/<id> and print the remaining wiring steps.

pnpm soubi add-harness windsurf --name "Windsurf"

dev

Watches the plugin folder and rebuilds on save for immediate feedback while authoring.

pnpm soubi dev ./my-plugin --install
FlagDescription
--installAlso live-install (non-destructively) into local harness dirs on each rebuild.

On this page