Development workflow
Recommended order: locate the local contract, pick a template, declare integrations, implement Worker or App, wire the stdio entry, validate and test, link a running Host, pack.
Locate the contract
From the VibeX repository root, list the contract files that must be read:
python3 .agents/skills/vibex-plugin-development/scripts/locate_toolchain.pyThe script prints JSON. The required array contains:
packages/plugin-sdk/src/manifest.tspackages/plugin-sdk/src/protocol.tspackages/plugin-sdk/src/worker.tspackages/plugin-sdk/src/app.tspackages/plugin-sdk/src/testing.tspackages/plugin-cli/src/validation.tsdocs/plugins/package-v4.mddocs/plugins/sdk-and-cli.md
Read every path in required. When missing is non-empty, restore those files first.
Print the built CLI and language SDK paths:
node packages/plugin-cli/dist/cli.js toolchaintoolchain prints hostVersion, cli, contract, js, python, rust, and templates. The Python SDK lives at sdk/python. The Rust SDK lives at crates/plugin-sdk. The checkout is authoritative.
Templates
node packages/plugin-cli/dist/cli.js init my-notes --publisher you --template fullinit writes the manifest, README, config.json, content index, tests, and matching source, then builds immediately. Default template: full. --template agent has been removed.
| Template | Output |
|---|---|
skill |
Skill projection |
mcp |
Managed MCP descriptor and placeholder process |
hooks |
Hook resource |
file-tab |
Node Worker, read-only .txt preview (artifact.preview), and a detail panel (slot: plugin.detail.panel) |
full |
Node Worker, App detail panel, Workflow |
ts-worker |
TypeScript Worker definition (runtime/main.ts) |
node-worker |
JavaScript Worker definition (runtime/main.mjs) |
python-worker |
CPython Worker (runtime/worker.py includes the stdio entry) |
rust-worker |
native Worker source (runtime/src/main.rs includes the stdio entry) |
host-service |
Periodic handler, default intervalSeconds 30 |
python-worker and rust-worker source already call run_stdio_plugin_worker / run_stdio_plugin_worker_blocking. Node templates write the handler definition to runtime/main.mjs (or runtime/main.ts). The Host starts node dist/worker.mjs; that file must call runStdioPluginWorker at top level. See “Node Worker entry” below.
Declare an editable file tab with file.opener.editorSurface plus an app.surface whose slot is artifact.editor. Steps: Contribution model.
Node Worker entry
The Host starts a Node Worker:
node --max-old-space-size=128 <entrypoints.worker.path>The process must speak protocol 1.1 on stdin/stdout. Recommended split:
runtime/worker.mjs # definePluginWorker(...)
runtime/main.mjs # runStdioPluginWorker(definition)runtime/main.mjs:
import { runStdioPluginWorker } from '@vibex/plugin-sdk/stdio';
import definition from './worker.mjs';
await runStdioPluginWorker(definition);vibex-plugin build bundles runtime/main.mjs to dist/worker.mjs. Manifest:
"entrypoints": {
"worker": {
"path": "dist/worker.mjs",
"runtime": "node",
"protocol": "1.1"
}
}Official Office uses this split. init --template node-worker writes the definition in runtime/main.mjs; add runStdioPluginWorker there, or split into two modules as above. Tests import the definition from runtime/worker.mjs.
CLI
Run from the plugin root. Connect with --host or VIBEX_PLUGIN_DEV_HOST. Authorization reads VIBEX_PLUGIN_DEV_GRANT. Passing --token or setting VIBEX_PLUGIN_DEV_TOKEN throws dev_link_host_only. The URL must be a loopback HTTP origin: http://localhost, http://127.0.0.1, http://[::1], pathname /. HTTPS, a path, a query, or userinfo yields plugin_dev_host_must_be_loopback_http_origin. Settings → Plugins developer tools emit the loopback connection. Grant file mode is 0600.
| Command | Role |
|---|---|
validate [--json] |
Validate manifest, index, references |
build |
Validate the package; compile runtime/main.mjs to dist/worker.mjs; compile App and managed MCP sources |
test |
build, then run test/*.{test,spec}.{mjs,js,mts,ts} from a temp directory |
install --link . |
Link the development directory and write the lock; published .vxp installs by drag-and-drop |
dev |
build, link, watch; reload a candidate generation when the digest changes |
doctor |
Install, activation, Runtime, surfaces, bindings, recent crashes |
pack [--output file.vxp] |
Write package.lock.json, emit a deterministic .vxp, print sha256: |
uninstall [--delete-data] |
Unlink; user data kept by default |
A failed candidate leaves the previous complete activation generation visible.
Host acceptance
- Edit README
summaryand body. - Declare only integrations you implement.
- Keep handler ids aligned with declarations and the handler regex.
- For a Node package, confirm
runtime/main.mjscallsrunStdioPluginWorker. build,validate,test.- Open VibeX and copy the developer connection (grant + loopback origin).
install --link .ordev.- Enable under
/plugins. Exercise the integrations this package actually declares: Skill projection, MCP injection, read-only preview, revision conflict on an editable file, detail panel, slash command, disappearance after disable. doctorfor crash rings andmcpRebindingRequired.packand drag the.vxpinto the desktop to distribute.
The harness covers in-process contracts. File tabs, preview processes, Runtimes, and workstation observation complete on a running Host.

