Skip to content

Build, develop, and install a plugin bundle

For a new project, follow your first plugin from installing cargo-dokime through desktop validation and bundle installation. This page describes the build, development, and bundle lifecycle.

A plugin’s normal dependency is dokime. Its Cargo package supplies the bundle name, version, and description; optional files under assets/ are included at the same relative paths. There is no second authored bundle manifest.

From the plugin package directory:

Terminal window
cargo dokime build
cargo dokime inspect target/dokime/my-plugin-0.1.0.dokime

Plain cargo build only compiles. The explicit cargo dokime build command compiles the selected native binaries, reads each static declaration, and invokes each catalog export mode before writing the bundle. The SDK export mode runs registration without initialization, route construction, or the normal service loop. Registration is authored code: it can have effects and need not be deterministic. Building a bundle is therefore an execution step, not a sandbox. Inspection verifies the bundle bytes and prints its manifest plus executable owner identities and served routes; it never invokes the executable.

Use --manifest-path Cargo.toml and --package NAME to select a package in a workspace. The same selection works during development, for example cargo dokime dev -p my-plugin from the workspace root. For a package with several binaries, select one with --bin NAME or Cargo’s default-run. Repeat --bin to include multiple executables in one bundle:

Terminal window
cargo dokime build --bin controller --bin sampler

Each selected binary must declare a distinct executable owner. They share the Cargo package identity and one copy of its assets. An invalid member refuses the whole build and preserves the previous bundle.

--release selects Cargo’s release profile; --profile NAME selects a custom profile. --target-dir DIR selects its build output, and --output FILE chooses the bundle path. A successful build atomically replaces that output; a compilation or export refusal preserves an existing file. The default is <target-dir>/dokime/<package>-<version>.dokime.

Bundle identity follows Cargo. The executable’s owner ID can differ from the package name, allowing packages with multiple executable owners. Its version is derived from Cargo on every build; omit the executable version argument. Description also defaults to Cargo’s nonblank package.description. An explicit description may describe one executable more specifically.

Builds support the current Rust host target and pass it explicitly, including when Cargo configuration selects another target. Cross-target builds are refused.

Each native catalog export has a 10-second deadline, the SDK catalog stdout limit, and a 256 KiB stderr limit. The exporter must exit successfully and produce exactly one complete JSON registration array. Refusal kills and reaps the direct child; this does not isolate descendant processes or filesystem effects. Cargo compilation and metadata have no default deadline. Both build and dev accept --cargo-timeout SECONDS with a positive integer to bound each Cargo invocation separately, including dependency metadata during development. For example, cargo dokime dev --cargo-timeout 1200 allows each Cargo invocation 20 minutes. Cargo build diagnostics appear live on stderr. The build command reserves stdout for its final bundle path, and inspect emits JSON there. Metadata has a 16 MiB stdout limit and a 256 KiB stderr limit. The rustc host probe retains its 30-second deadline, and --cargo-timeout does not change the catalog export deadline. Bundle file, archive, registration, and total-byte limits are also checked. Assets must be regular files with portable paths; links, excessive directory nesting, and oversized trees are rejected.

Terminal window
cargo dokime dev

Run this from your plugin package directory. The command builds the plugin, starts the installed Dokime backend in an isolated child process, and reloads the plugin when source files change. Before compilation, the CLI reports the selected host, where it was found, and the CLI, host, and SDK versions. It checks their supported compatibility series; normal runtime catalog admission still applies after a successful build.

cargo dokime serve runs the same backend directly; cargo dokime version --json reports its SDK and development protocol identity. The backend serves no UI; cargo dokime gui and cargo dokime dev launch the desktop application beside it.

cargo-dokime is a thin tool. It carries no backend and no desktop application of its own: it runs the Dokime that the desktop installer put on this machine, and it looks for that dokime executable in this order.

  1. --dokime PATH, either an executable path or a bare name looked up on PATH.
  2. The DOKIME_HOME directory.
  3. dokime on PATH.
  4. The platform install directory: %LOCALAPPDATA%\Dokime\ then %ProgramFiles%\Dokime\ on Windows, /usr/bin then /usr/local/bin on Linux, and /Applications/Dokime.app/Contents/MacOS on macOS.

The installer ships dokime and dokime-gui side by side, so the desktop application is the dokime-gui executable beside the selected backend. Use --gui PATH to run a different one, or --headless to develop without a GUI. When nothing is found, install Dokime from the desktop installer or name the executable with --dokime PATH.

--color auto, --color always, and --color never control terminal color consistently across the CLI and its Cargo diagnostics. The default is auto.

Development watches the selected package and its reachable local path dependencies from Cargo metadata, plus workspace Cargo configuration and Rust toolchain files. It excludes registry/git dependencies, Cargo’s resolved build output, VCS data, and caches. Repeat --watch PATH for extra inputs and --ignore PATH for generated files. Save bursts are coalesced and an unchanged bundle does not interrupt the current plugin.

Compilation and metadata failures leave dev watching. The old plugin continues running while the replacement builds. A valid replacement blocks new admissions, cancels this plugin’s active and queued executions, waits for terminal evidence and resource cleanup, then replaces its processes and catalogs. The host, native gRPC listener, active RPC streams, and unrelated plugins remain live. Completed execution snapshots remain immutable. If another plugin depends on the changed plugin, reload reports that a full development-host restart is required.

An invalid candidate preserves the current plugin. A replacement initialization failure leaves only that plugin unavailable and the watcher ready to retry. Type r and Enter to retry without a file edit. An unexpected host exit also leaves the watcher running; retry or save to start it again. Ctrl-C or q and Enter stops dev and drains the host. Slow cleanup is reported and awaited.

The terminal reports development phases and full iteration/reload timings. Default runtime diagnostics focus on warnings and failures; --verbose enables detailed tracing (an explicit RUST_LOG remains authoritative). Cargo’s color setting is preserved in auto mode; explicit CLI always/never settings take precedence.

Dev loads only the selected bundle and built-in host features; no other plugin loads automatically. Runtime data and the authorization store are isolated in a temporary directory; --state-dir DIR preserves development history between sessions. The browser retains its selected case and inputs because the host stays alive. Use Re-run for a fresh attempt, or opt into --rerun to repeat this plugin’s most recently executed case after each successful reload. Run one case manually to select the scenario; old attempts retain their evidence. Changed parameter contracts can refuse the new attempt and require updating the case inputs.

--port selects the initial host port. Normal Cargo selection flags apply, including --features, --all-features, --no-default-features, --locked, and --offline. Dependency metadata refreshes on every build. The private bundle output belongs to dev; use cargo dokime build --output for distribution files. Run cargo dokime doctor -p NAME to check tools, the host and where it was found, the desktop application beside it, SDK dependency access, and watch roots without compiling.

For local development, the host CLI can load a bundle directly for one process:

Terminal window
dokime serve --plugin target/dokime/my-plugin-0.1.0.dokime \
--output-root target/dokime/session --plugins-root target/dokime/store \
--no-seed-validation-artifact

Repeat --plugin for additional bundles. Explicit paths authorize execution for this launch and still pass normal bundle validation and catalog admission. They do not create persistent installations. The separate store keeps this session away from your normal installed plugins; omitting --plugins-root uses the normal store. Omit --no-seed-validation-artifact to also load the shipped composition.

serve resolves environment-backed secrets once, at startup: an already exported variable always wins, and otherwise it searches upward from its working directory for .env, continuing without one if none exists. Pass --env-file PATH to load exactly that file instead of searching; a missing file is refused rather than silently skipped. Editing the file or exporting a variable afterward has no effect until you restart serve.

The CLI uses the same native gRPC staging and consent API as Settings. Its --endpoint value is the host’s native gRPC endpoint; a loopback endpoint uses the http:// URI scheme for this transport:

Terminal window
cargo dokime install target/dokime/my-plugin-0.1.0.dokime --endpoint http://127.0.0.1:8765
# Explicit automation consent:
cargo dokime install target/dokime/my-plugin-0.1.0.dokime --yes

It checks the staged identity, executable owners and digest against the local verified bundle, displays the destination and plugin, and asks for consent. Declining discards the inert stage. Consent authorizes next-start activation; it does not restart a running host. If a consent response is lost or refused, the command reports the installation UUID and leaves it for review in Plugins; it never automatically deletes or retries an uncertain authorization.

Open Settings → Plugins, upload the .dokime bundle, review its verified package identity and digest, and consent to installation. The plugin activates at the next restart. Staging reads frozen catalogs without executing export, initialization, or any other authored code. Cancel discards the unconsented stage immediately; it does not require a restart or replace an installed plugin.

The same Plugins page lists each active bundle’s programs. Expand a program to edit its configuration, manage credentials, and read its declared settings cards. Programs loaded through the launch configuration appear here too; their bundle files remain managed by that configuration. Host features have their own group. Pending replacement installations stay separate from the currently running programs until the next restart.

The authorization store keeps immutable <UUID>.dokime files and a minimal manifest. DOKIME_PLUGINS_DIR selects the store directory. Copying files there manually does not authorize them. Missing or changed bytes remain visible by installation UUID with an error and no unverified author metadata. A malformed manifest is an error, never an empty registry. Unconsented staged uploads expire after seven days. Expiry revokes their authorization before deleting bytes; failed cleanup remains visible and retryable. Consented installations do not expire.

Consent rechecks executable owner collisions against configured and installed packages. A new version of the same installed package replaces the previous installation at the next restart; different packages cannot claim the same owner. Configured bundles and explicit host sources are protected.

Boot prefers one native file for each executable owner on the current platform, resolves executable-level dependencies, and compares every frozen registration with the live catalog before initialization. Catalog entry order is irrelevant; namespace, schema and payload must match, including unknown namespaces. Declaration IDs must therefore be deterministic. The SDK derives template-local IDs from stable template and authored identifiers; runtime execution IDs remain fresh.

Catalog admission is atomic across the surviving packages. A failed executable removes its package and transitive dependent packages from admission; started siblings stop before their private extraction directories are released. Those directories otherwise remain alive through runtime shutdown.

New catalogs record host or bundle ownership. Removing a package removes only its tracked catalogs. Unclassified historical catalogs remain readable and never authorize executable discovery; an admitted bundle may replace a matching legacy owner. Plugins invoke their admitted typed action, options, and status routes through the host dispatcher. The host supplies credential posture and the request idempotency key; payload strings do not establish trust.

The committed tools/rust/dokime-xtask/plugins.txt lists the first-party Cargo packages that plugins build (mise run build:plugins:dev) builds through cargo-dokime to keep the plugin build system exercised, alongside every fixture bundle the test suites need. Each package has one native binary. Package names determine the .dokime filenames, while executable owner IDs remain inside each verified bundle.

The installer ships the desktop application, its embedded frontend, branding, and the companion dokime CLI only; it does not ship any plugin. Install a plugin into a running Dokime through the plugin store, or pass its bundle path explicitly with --plugin.

Dokime markDokime · Stokker Technologies