> ## Documentation Index
> Fetch the complete documentation index at: https://openidea.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Install the plugin tool, scaffold a Rust plugin, build it, link it into OpenIDEA and run its commands.

This walkthrough creates a code plugin with two commands, tests it, builds it to WebAssembly and loads it into the IDE without installing it.

## Prerequisites

* OpenIDEA installed.
* Rust through [rustup](https://rustup.rs). `openidea-plugin build` adds the `wasm32-wasip2` target through rustup if it is missing; you can also add it yourself with `rustup target add wasm32-wasip2`.

**1. Install the openidea-plugin tool**

```sh theme={null}
cargo install --locked --git https://github.com/l0ng-ai/openidea ide-host --bin openidea-plugin
```

This builds the tool from the `main` branch. To match a released IDE, add `--tag v<version>` (for example `--tag v0.1.40`). Each release also attaches a Linux x64 binary, `openidea-plugin-linux-x86_64.gz`.

`openidea-plugin --version` prints the tool version and the plugin API it checks against.

**2. Scaffold a plugin**

```sh theme={null}
openidea-plugin new hello --id acme.hello
cd hello
```

The `command` template (the default) writes:

| File | What it is |
| - | - |
| `plugin.toml` | The manifest: id `acme.hello`, name `Hello`, two commands, the `editor.read` capability |
| `Cargo.toml` | A `cdylib` crate that depends on the SDK |
| `src/lib.rs` | The commands, plus unit tests against the SDK's mock host |
| `README.md`, `.gitignore` | |

The id is `<publisher>.<name>`. The publisher part (`acme`) is what you sign with when you publish; without `--id` the id is derived from the folder name. `--name` sets the display name.

The SDK dependency points at this repository at the tool's release tag (`{ git = "https://github.com/l0ng-ai/openidea", tag = "v…" }`). Pass `--sdk <path to sdk/rust/openidea-plugin>` to use a local checkout instead.

Other templates: `--template theme`, `--template icon-theme`, `--template language`. They need no code.

**3. Run the unit tests**

```sh theme={null}
cargo test
```

On your machine the SDK talks to a mock host, so the command logic is tested without the IDE. See [Testing and debugging](https://openidea.sh/en/plugins/testing.md).

**4. Build the component**

```sh theme={null}
openidea-plugin build
```

This runs `cargo build --release --target wasm32-wasip2`, copies the result to `dist/plugin.wasm` (the manifest's `wasm` path) and then runs `openidea-plugin check`, which validates the package exactly as installing would and prints what the user will be asked to grant:

```text theme={null}
acme.hello 0.1.0 — Hello
  code: dist/plugin.wasm (…, plugin API 1.4)
  categories: tools
  contributes 2 × commands
  capability editor.read (required, Low risk): Read the focused editor's file and selection
ok
```

Use `openidea-plugin build --debug` for a debug build.

**5. Link the folder into the IDE**

```sh theme={null}
openidea-plugin link
```

`link` adds the folder to `links.json` in the IDE's plugins directory. Linked plugins are read from the folder itself, so you never reinstall while developing. `openidea-plugin links` lists linked folders and `openidea-plugin unlink` removes one.

> [!NOTE]
>
> The plugins directory is `$OPENIDEA_PLUGINS_DIR`, or `ai.l0ng.openidea/plugins` in your system's app data directory. A development build of OpenIDEA from source uses its own data directory: point `OPENIDEA_PLUGINS_DIR` at its `plugins` folder when you link. See [Data directories](https://openidea.sh/en/reference/data-directories.md).

**6. Allow it and run a command**

1. Open **Settings › Plugins** (`⌘,` on macOS, `Ctrl+Alt+S` on Windows/Linux). The plugin is listed under **Linked for development** with the status **Needs permission**.
2. Select it and click **Review Permissions…**, then **Allow** in the *Allow Hello to run?* dialog.
3. Open Find Action (`⌘⇧A` / `Ctrl+Shift+A`) and run **Hello: Say Hello**. A notification says *Hello #1 from Hello!*.
4. Open any file and run **Hello: Line Count of Active File**. The command returns text, which the IDE shows to you.

## The edit loop

1. Change `src/lib.rs` (or `plugin.toml`).
2. Run `openidea-plugin build`.
3. In **Settings › Plugins**, select the plugin and click the **Reload from disk** button in its details, or run the **Reload Plugins** action from Find Action.

If something goes wrong, the plugin's details in **Settings › Plugins** show its status and why it failed. See [Testing and debugging](https://openidea.sh/en/plugins/testing.md) for logs.

## What is in the code

```rust theme={null}
use openidea_plugin::{Error, Invocation, NotificationLevel, Plugin, host, register_plugin};

#[derive(Default)]
pub struct Main {
    greetings: u32,
}

impl Plugin for Main {
    fn run_command(&mut self, id: &str, ctx: &Invocation, _arg: Option<&str>) -> Result<Option<String>, Error> {
        match id {
            "say-hello" => {
                self.greetings += 1;
                let body = format!("Hello #{} from Hello!", self.greetings);
                host::notify(NotificationLevel::Info, "Hello", &body);
                Ok(None)
            }
            "line-count" => {
                let editor = ctx.editor().ok_or("no file is open")?;
                let text = editor.document()?.text;
                Ok(Some(format!("{} lines in {}", text.lines().count(), editor.path())))
            }
            _ => Err(format!("unknown command {id}").into()),
        }
    }
}

register_plugin!(Main);
```

* `plugin.toml` declares the commands (`[[contributes.commands]]`), so they appear in Find Action before the code is loaded.
* `run_command` receives the command id and the invocation context (the window's project and focused editor).
* `greetings` lives in the instance and resets when the plugin is unloaded after being idle. Keep what must survive in `host::storage` (see [Lifecycle and events](https://openidea.sh/en/plugins/lifecycle.md)).
* Reading the editor needs the `editor.read` capability. Without it, `editor.document()` returns `Error::Denied`.

## Next steps

* [Manifest](https://openidea.sh/en/plugins/manifest.md): every field of `plugin.toml`.
* [Commands and actions](https://openidea.sh/en/plugins/guides/commands.md): menus, shortcuts, `when` clauses and command arguments.
* [Example plugins](https://openidea.sh/en/plugins/examples.md): working plugins to copy from.
* [Packaging and signing](https://openidea.sh/en/plugins/publishing/packaging.md): turn the folder into an `.oiplugin`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.