Files

DBX Hello Workbench plugin

This example exercises the complete manifest v1 path instead of mocking a contribution preview:

  • native Rust sidecar built with dbx-plugin-sdk;
  • protocol handshake and concurrent JSON-RPC requests;
  • saved connection-provider with common/config/secret field bindings;
  • test, connect, and disconnect lifecycle;
  • per-connection backend registry;
  • asynchronous connection/progress events;
  • sandboxed workbench UI using window.dbxPlugin;
  • workbench-to-sidecar RPC plus a read-only filesystem contribution rendered by DBX's host-owned file manager;
  • unsigned .dbxp candidate packaging plus separate repository signing;
  • automated install-to-uninstall smoke runner.

Files

hello-workbench/
├── manifest.json
├── assets/                # plugin and connection-provider icons
├── backend/               # native sidecar
├── ui/index.html          # sandboxed workbench
├── package.mjs            # current-platform unsigned candidate build
├── repository-sign.mjs    # custom repository signing example
├── repository-smoke.mjs   # candidate-to-signed-install end-to-end smoke
└── smoke.mjs              # package + lifecycle smoke test

The reusable smoke executable lives at crates/dbx-core/examples/plugin_package_smoke.rs so it shares DBX's workspace lockfile and dependency patches.

Build an unsigned development package

From the DBX repository root:

node plugins/examples/hello-workbench/package.mjs

The package is written to:

plugins/examples/hello-workbench/dist/
  dbx.example.hello-1.0.0-<target>.dbxp
  dbx.example.hello-1.0.0-<target>.artifact.json

The .artifact.json file contains the target, candidate URL, package SHA-256, and size used by review and multi-platform release aggregation. It intentionally contains no signingKeyId.

In DBX, open Plugin Center, enable Allow unsigned development package, and install the .dbxp.

Use the example

  1. Select DBX Hello Workbench in the plugin center.
  2. Create a Hello connection.
  3. Fill the host, port, greeting, and optional example token.
  4. Click Test.
  5. Click Save & Open.
  6. Invoke the sidecar from the workbench.
  7. Click Open host files to browse and preview the virtual hello:/ filesystem without plugin-owned file-browser UI.

The example token is persisted through connection_secrets; the raw connection config_json contains only an empty placeholder. The iframe receives the saved connection ID, never the token.

Run the real package smoke test

node plugins/examples/hello-workbench/smoke.mjs

The smoke runner performs:

build package
→ install into a temporary plugin store
→ verify manifest compatibility
→ read plugin and connection-provider icon assets
→ start and initialize the native sidecar
→ test the provider connection
→ connect the saved plugin connection
→ invoke hello/greet
→ list and preview files through the typed filesystem host API
→ observe connection and progress events
→ disconnect
→ stop the sidecar
→ uninstall

To reuse an already-built package:

node plugins/examples/hello-workbench/smoke.mjs \
  plugins/examples/hello-workbench/dist/dbx.example.hello-1.0.0-darwin-arm64.dbxp

To verify a repository-signed package with marketplace policy, provide the trusted repository public keys:

DBX_PLUGIN_SMOKE_TRUSTED_KEYS_JSON='{"example-repository":"BASE64_32_BYTE_ED25519_PUBLIC_KEY"}' \
node plugins/examples/hello-workbench/smoke.mjs \
  plugins/examples/hello-workbench/dist/dbx.example.hello-1.0.0-darwin-arm64.signed.dbxp

Sign as a custom repository operator

Official plugin authors skip this section because DBX Store signs approved candidates. To exercise the custom-repository flow, generate or load a repository key and sign the already-built candidate:

dbx-plugin keygen example-repository
source .dbx-repository-signing-key.env
node plugins/examples/hello-workbench/repository-sign.mjs

The script writes a .signed.dbxp, creates final artifact metadata containing signingKeyId, and refreshes the example catalog entry. Add the corresponding Base64 public key under Plugin Center → Custom repository trust before installing from that catalog.

Do not put the private seed in the repository or package. Distribute the repository public key through a channel independent from the .dbxp download.

Run the complete temporary-key flow without modifying the example catalog:

node plugins/examples/hello-workbench/repository-smoke.mjs

This builds an unsigned candidate, generates an ephemeral repository key outside the workspace, signs the reviewed candidate, installs it with strict signature policy, exercises assets/actions/connections/filesystem/events, uninstalls it, and removes temporary keys and Cargo targets.

Set DBX_PLUGIN_OUTPUT_DIR when automation should place candidate outputs outside the example dist/ directory.

Connection request shape

The backend lifecycle receives the hydrated connection and the final DBX transport endpoint:

{
  "provider": {
    "id": "dbx.example.hello.connection",
    "databaseType": "hello"
  },
  "connection": {
    "id": "saved-connection-id",
    "db_type": "plugin",
    "plugin_id": "dbx.example.hello",
    "plugin_connection_provider": "dbx.example.hello.connection",
    "plugin_connection_type": "hello",
    "external_config": {
      "greeting": "Hello"
    },
    "connection_secrets": {
      "api_token": "hydrated only for the backend"
    }
  },
  "runtime": {
    "host": "localhost",
    "port": 22
  }
}

The workbench context is intentionally smaller:

{
  "connectionId": "saved-connection-id",
  "providerId": "dbx.example.hello.connection",
  "connectionType": "hello"
}

Adapt it for a real plugin

  • SSH/SFTP: switch to stdio-framed, keep PTY/SFTP sessions in a backend registry, and use binary channels for terminal/transfer data.
  • OpenDAL: keep credentials in the connection provider, implement filesystem methods in the backend, and let DBX own generic file-manager UI.
  • Other tools: add contributions rather than adding a new DBX database enum variant or importing plugin Vue code into the main window.