editor.apply-edits-at applies edits that may come from another machine (a collaboration session), so it no longer uses the ordinary read resolver. The path must be project-relative, every component is checked with symlink_metadata from the canonical root, and symbolic links, junctions and other reparse points are refused, as are VCS and IDE control directories (.git, .hg, .svn, .idea, .openidea, .vscode, including Windows alternate spellings). The WIT docs describe the rule in both wit/ and the SDK copy.
Co-authored-by: SorPuti <56741582+SorPuti@users.noreply.github.com>
Plugins read problems from a host-owned snapshot that records every Diagnostics event per file and producer, instead of the UI-reported Problems reports, so what a plugin sees no longer depends on window lifetime or the invoking window. Adds the problems-changed workbench event (plugin API 1.8.0, gated at needs_api 8), editor focus events for files of other windows, severity style previews in plugin settings, and lays plugin annotations on the line-end chain before code-vision hints and inline blame. Components and fixtures are rebuilt for API 1.8.0.
Co-authored-by: muutot <92625353+muutot@users.noreply.github.com>
Plugins could show their own content in an editor tab (open-content-tab) but
could open the diff viewer only as the reply to one of that tab's actions. A
review plugin (a merge request's files, say) had no way to show a file's
before and after.
views.open-diff opens two texts in the invoking window's diff viewer, with
optional labels and title and a file name that picks the syntax highlighting;
web views send { op: "open-diff", ... }. The SDK wraps it as host::open_diff
with a mock. The plugin API moves to 1.7.0 (1.6.0 is released) and the checked-in
components are rebuilt.
Plugins can subscribe to committed local edits of open project documents with subscribe-paths("document-changed", globs) and receive versioned UTF-16 replacements. editor.document-at and editor.apply-edits-at read and edit an explicitly named open project document from background events; stale versions are rejected without changing the editor, and these edits are non-undoable and not re-emitted as local changes.
document-changed is delivered only for named paths and only to plugins granted project.read and editor.read. Also delivers websocket-ready events to plugins from the frontend runtime. API 1.6.
Co-authored-by: SorPuti <56741582+SorPuti@users.noreply.github.com>
Plugins get a host-owned WebSocket resource (net.websocket-connect → websocket with id/send/drain/close; dropping it closes the transport). The connection is bound to the project it was opened for, needs the endpoint's net:<host> grant, uses WSS outside loopback with the shared rustls config, and is capped at eight per plugin. Request headers (secret placeholders expanded) go with the handshake, except the ones the handshake owns; an empty subprotocol requests none; the handshake is bounded by the call's I/O budget. Incoming frames queue in a bounded FIFO, signalled by the websocket-ready event. Checked-in components are rebuilt for API 1.6.
Co-authored-by: SorPuti <56741582+SorPuti@users.noreply.github.com>
`read-file` returns UTF-8 text only, so a plugin could not read a PDF, image, archive or font inside the open project, and `fs.read-bytes` needs a per-path grant. `workspace.project` gains `read-bytes(path)` with `read-file`'s rules (`project.read`, `resolve_in_root` confinement, `not-found` for missing paths, 16 MiB cap; always the file on disk). The Rust SDK exposes `Project::read_bytes` and the mock host `add_file_bytes`. Web custom editors get `document.bytes()` (at most 64 MiB, read-only).
Fixes#2347
Co-authored-by: Inf1mum <8135225+Inf1mum@users.noreply.github.com>
- Add ui.notify-project: it shows only in that project's window (the most recently focused one if there are several) and works without a calling window
- Button commands run in the window showing the notification; a closed project returns not-found, with nothing shown and no fallback to another window
- Bump the plugin API to 1.5.0 (wit/, SDK copy, ENGINE_VERSION, API_VERSION) and rebuild all components
- Add Project::notify and its mock to the SDK; update plugins/README.md
Co-authored-by: LU XIANGRUI <26499420+wildcatDownstairs@users.noreply.github.com>
Plugin API 1.4: grants for unencrypted HTTP, local sockets, IDE commands and owned database sources; window status items, output channels, content tabs, editor selections, decorations, search, Problems and VCS reads; runs, keyed terminals with exit events, plugin run targets, dynamic run configurations and test parsers; language features, injections, snippets and menu locations; plugin MCP tools on the built-in server; four official API examples. Released 1.3 plugins keep working.
- workspace.symbols becomes the project method project.symbols(query, limit), like find-files; the Rust SDK's Project::symbols is unchanged, components built against the previous main need a rebuild.
- The open-log-tab web message names its arguments args, as pty-spawn and the services process-log do; baseArgs is refused with log-error rather than ignored.
- Document the hover, semantic-tokens and diagnostics provider exports and their worlds.
Closes#1944
API 1.3 lets a plugin search the IDE's workspace symbol index. Results are limited to paths the plugin may read under its `project.read` grant (external content roots and symlink aliases excluded), the search honours the call's cancellation and deadline including lock waits, and ranges use UTF-16. Incremental index updates no longer publish symlink-ancestor aliases. Verified on macOS with the test fixture.
Co-authored-by: arnaud-ritti <77437157+arnaud-ritti@users.noreply.github.com>
Adds fs.write-file / fs.write-bytes behind a new fs.write:<path> capability (high risk; resolved to the real path, a missing file through its real directory, so a link cannot reach outside the grant; writing doesn't imply reading), and workspace.project.write-file(path, text) behind project.write (medium risk; stays inside the root and creates missing directories).
Writes go through the editor's save path: atomic, keeping the file's encoding and BOM (new files are UTF-8), capped at 16 MiB, and refused while an editor holds unsaved changes for the file. Both capabilities need engines.openidea ^1.3. Tested through the real component (misbehave fixture) and the SDK mock.
Closes#1823Closes#1824
Co-authored-by: chaoes <26876656+chaoes@users.noreply.github.com>
Adds API 1.3 `events.subscribe-paths(kind, globs)` for `file-opened` and `file-saved`: project-relative globs checked before an event is queued or wakes an idle plugin, and again before a queued event is delivered. A new filter replaces the old one atomically; `subscribe` restores unfiltered delivery; filters survive idle reclamation. Also `workspace.project-of(path)`, the most specific open project containing a document (reading it still needs `project.read`). Closes#1958.
Co-authored-by: arnaud-ritti <77437157+arnaud-ritti@users.noreply.github.com>
Adds API 1.3 `ui.pick-directory` (native folder chooser, same window/budget rules as `pick`) and `workspace.open-project(path, new-window)`, which goes through the normal File › Open flow with its trust prompt, window reuse and unsaved-change handling. Paths are absolute on the UI machine and validated by the host whatever its OS. Closes#1959.
Co-authored-by: arnaud-ritti <77437157+arnaud-ritti@users.noreply.github.com>
* fix(plugin): report missing files as not-found and add project exists/stat
read-file of a missing path now returns error::not-found in the host,
matching the SDK mock, instead of error::invalid. project gains
exists(path) for a cheap existence check (files and directories, hidden
and ignored included) and stat(path) for kind/size/modified, both
gated by project.read and refusing paths outside the root.
Fixes#1957
* chore: silence clippy in sandbox test and rebuild plugin components
- drop an unnecessary to_path_buf clippy flags on unix
- rebuild every checked-in plugin.wasm: the SDK and wit/ changed, so
their source fingerprints moved
* test(plugin): cover missing-file not-found and fix CRLF-only Windows failure
Plugin API 1.3 adds an optional semantic-tokens-provider export (world plugin-semantic-tokens). A plugin declares the semantic-tokens kind under [[contributes.providers]] for any language, including ones it does not contribute, and returns single-line tokens with LSP token kinds and modifiers. The host asks it with the other editor providers (50 ms / 500 ms) when the editor requests semantic tokens and joins the result with the language server's: plugin tokens replace the server tokens they overlap, so the colour scheme styles them like any semantic token. Declaring the kind needs engines.openidea ^1.3.
API 1.2 shipped with 0.1.38, so wit/ and the SDK's copy, ENGINE_VERSION and both API_VERSION constants move to 1.3 and every shipped component is rebuilt. The SDK gains openidea_plugin::semantic_tokens, and register_plugin! accepts any combination of optional exports (providers, views, indexing, syntax, semantic_tokens) instead of a fixed list of pairs.
Plugin API 1.2 adds `invocation.selected-paths`: the files and folders a Project view or editor tab menu ran the command on, as absolute paths (the command's argument stays the first of them, so existing plugins see no change). The frontend passes the menu's selection to `plugin_run_command` on the desktop and through the remote dispatcher; the Rust SDK and its mock gain `Invocation::selected_paths`. All components are rebuilt for the WIT change.
Closes#1621
Co-authored-by: arnaud-ritti <77437157+arnaud-ritti@users.noreply.github.com>
API 1.1.0 shipped with 0.1.37 and wit/ matched the released snapshot, so additions start with a bump: the package in wit/ and the SDK's copy, ENGINE_VERSION and both API_VERSION constants move to 1.2, and the official plugins and fixtures are rebuilt against it. No interface changes; 1.0 and 1.1 components keep linking. The release that ships 1.2 copies wit/ over the released snapshot.
Plugins get three host calls in API 1.1: vcs.remotes (under vcs.read) lists the
repository's remotes, ui.copy-to-clipboard and ui.open-url act on the window that
invoked the plugin's command.
Remote URLs are returned without the user:password part they may carry, and the
two UI calls fail when there is no invoking window instead of reaching every window.
Co-authored-by: dengliu <5108773+dengliu@users.noreply.github.com>
A plugin system built on WebAssembly components (wasmtime, WASI p2), with a
typed WIT API (`openidea:plugin@1.0.0`) and a Rust SDK, shipped as a preview.
- Extension points declared in `plugin.toml` (commands, languages, themes,
icon themes, menus, key bindings, status items, settings, views, custom
editors, file icons and templates, run detectors, editor providers),
validated before anything takes effect and projected onto the workbench's
own registries: plugin themes and file icon themes are chosen in
Settings › Appearance and Quick Switch, plugin shortcuts are edited in
Settings › Keymap, plugin problems are grouped in Settings › Inspections.
- Capabilities with risk levels and consent at install, pinned `process:`
programs, secrets in the OS keychain.
- Runtime: one thread per active plugin, fuel/time/memory budgets, soft and
hard deadlines on the editing path, cancellation, crash backoff, idle
reclaim, a precompiled-component cache; remote projects run code plugins on
`openidea-server`.
- Web views and custom editors with a sandboxed page, a document bridge
joined to the text editor's undo history, and split or preview layouts.
- Distribution: signed `.oiplugin` packages, a static marketplace index with
revocation, versioned installs with rollback, install from a `.zip` or a
folder. The release workflow signs and publishes the official plugins and
their index, which released builds use as the default marketplace.
- Official plugins: String Tools, Key Promoter, Git Toolbox, AI Completion,
Checkstyle, MyBatis Navigator, CSV Editor, Solidity, Material Icons, Harbor
Night, Excalidraw, Graphviz, Regex Tester, License Header.
Closes#732
Co-authored-by: Deng Liu <5108773+dengliu@users.noreply.github.com>
Co-authored-by: florentvdry <16673235+florentvdry@users.noreply.github.com>