Developer Mode
OTools provides a built-in developer center that covers the full workflow from plugin creation to release.
1. Create & Bind
- Create a plugin in the developer center and fill in Pack ID, name, summary, etc.
- Bind the plugin development directory; OTools reads
plugin.jsonand manages runtime info. - Enable debugging to surface the plugin in the home Tabs for quick access.
2. devUrl Debugging
devUrlsupportshttp/https, compatible with Vite, Webpack, and other dev servers.- Local
index.htmlpaths are also supported for static or non-framework plugins.
3. Web SDK & Permissions
Plugin webviews get a Node-style compatibility runtime by default, so plugin code or preload.js can call:
const runtime = require("@otools/runtime");
const fs = require("node:fs");
const path = require("node:path");
const { execSync } = require("node:child_process");Declare elevated capabilities explicitly in plugin.json:
{
"permissions": ["fs", "dialog", "shell", "child_process"]
}Notes:
fs: enablesnode:fs,node:fs/promises,@otools/fsdialog: enables@otools/dialogshell: enables@otools/shellchild_process: enablesnode:child_process,@otools/child_process- If not declared, these privileged capabilities are denied by default;
path,os,process, andhttp/httpsremain available - Built-in tools and non-plugin pages are not restricted by this manifest field
4. Web/Vue Scaffolding
The developer tool can generate a Vue + Vite project scaffold with one click:
package.json,vite.config.ts,tsconfig.jsonsrc/main.ts/src/App.vue- The bound directory is used as the project root
5. Native Capability
OTools supports Rust dynamic libraries for higher performance.
- Initialize native project: creates
native/Rust project under the bound directory. - Build native library: generates dynamic libs under
lib/. - Standalone build: build platform-specific libs on another system.
Repo layout: native vs tauri (optional)
In the main repository, some plugins use plugins/<name>/native (business logic + otools_plugin_invoke) plus an optional plugins/<name>/tauri crate used only when the plugin is bundled inside the OTools desktop app to register #[tauri::command].
Marketplace packages are still plugin.json + frontend assets + lib/ dynamic library — do not ship the tauri sub-crate: after marketplace install, the host loads the dylib via FFI; built-in integration is done by the main app depending on the *-tauri crate.
Push-style events (poll_events)
Third-party native code loaded only as a dylib can expose poll_events; the host polls it and the frontend consumes events via window.otools.listenNative (see the OTools API doc, “Native event subscription”). The polling interval can be set with intervalMs on listenNative (the host clamps roughly 50–10000 ms).
- Web code can still use Tauri
listenfor channels the main appemits; the dynamic library feeds pending items throughpoll_events, and the host performsemitfor the webview.
plugin.json configuration:
{
"native": {
"enabled": true,
"libDir": "lib",
"autoReload": true,
"libName": "macOS.dylib"
}
}Default library names:
- macOS:
macOS.dylib - Windows:
Windows.dll - Linux:
Linux.so
6. Packaging & Release
- Packaging requires
logo.pngandplugin.jsonat the plugin root. - After packaging, a plugin package is generated and written to the local marketplace record.
- Releases require a download URL (only
http/https).
7. Recommended Workflow
- Create and bind a plugin
- Initialize Web/Vue project or use pure HTML
- Set
devUrland enable debugging - Add
nativecapability for performance needs - Package and publish to the marketplace