DDS Plugin SDK#

Install the DDS Plugin SDK, write a diagnostics plugin, and run it with the local test host.

1. Install the SDK#

DDS Plugin SDK 0.1.0 provides JavaScript APIs, TypeScript declarations, contract validators and a local test host for diagnostics plugins. Use Node.js 22 or 24. Install the versioned package from the official GitHub release:

Bash
mkdir hello-dds-plugin
cd hello-dds-plugin
npm init -y
npm install --save-exact "https://github.com/Altifigence/dds-plugin-sdk/releases/download/v0.1.0/altifigence-dds-plugin-sdk-0.1.0.tgz"

This guide runs trusted plugin code in the local test host process. Current DDS desktop and browser Cloud releases do not load third-party SDK plugins. For existing tool integrations, see Plugins and Third-Party Tools.

2. Write Your First Plugin#

Create plugin.mjs in the new project. This plugin checks plaintext documents and reports an informational diagnostic on each line containing TODO.

plugin.mjs
import { createDiagnosticsResult, definePlugin } from '@altifigence/dds-plugin-sdk';

export default definePlugin({
  manifestVersion: 1,
  id: 'hello-diagnostics',
  name: 'Hello Diagnostics',
  publisher: 'example',
  version: '0.1.0',
  protocolVersion: 1,
  entry: './plugin.mjs',
  capabilities: ['diagnostics'],
  permissions: ['document.read', 'diagnostics.publish'],
  supportedHosts: ['test-host'],
  license: 'Apache-2.0',
}, context => context.registerDiagnosticsProvider({languages: ['plaintext']}, {
  provideDiagnostics(request, {signal}) {
    signal.throwIfAborted();
    const diagnostics = [];
    const lines = request.snapshot.text.split(/\r\n|\n|\r/);
    for (let line = 0; line < lines.length; line++) {
      const character = lines[line].indexOf('TODO');
      if (character !== -1) diagnostics.push({
        range: {start: {line, character}, end: {line, character: character + 4}},
        severity: 'info',
        code: 'todo',
        source: 'hello-diagnostics',
        message: 'Resolve this TODO before sharing the document.',
      });
    }
    return createDiagnosticsResult(request, diagnostics);
  },
}));

The manifest declares protocol version 1, the diagnostics capability, the test-host host, and the document.read and diagnostics.publish permissions. The provider receives a document snapshot and an AbortSignal. Diagnostic ranges use zero-based lines and UTF-16 character offsets.

3. Run It Locally#

Create run.mjs beside plugin.mjs. Activate the plugin, provide a document and request diagnostics. Always dispose the host when finished.

run.mjs
import { createTestHost } from '@altifigence/dds-plugin-sdk/testing';
import plugin from './plugin.mjs';

const host = createTestHost();
try {
  await host.activate(plugin);
  host.setDocument({
    uri: 'memory:///hello.txt',
    languageId: 'plaintext',
    modelVersion: 1,
    workspaceRevision: 'example-1',
    text: 'Hello, DDS!\nTODO: write a plugin.\n',
  });
  const result = await host.requestDiagnostics();
  console.log(`${plugin.manifest.name}: ${result.diagnostics.length} diagnostic`);
  for (const diagnostic of result.diagnostics) {
    console.log(`${diagnostic.severity} ${diagnostic.range.start.line + 1}:${diagnostic.range.start.character + 1} ${diagnostic.message}`);
  }
} finally {
  host.dispose();
}
Bash
node run.mjs

Expected output (the printed line and column are one-based):

Text
Hello Diagnostics: 1 diagnostic
info 2:1 Resolve this TODO before sharing the document.

4. Test Your Plugin#

Save this test as plugin.test.mjs. It checks the diagnostic range and confirms that editing the document clears the diagnostic.

plugin.test.mjs
import assert from 'node:assert/strict';
import test from 'node:test';
import { createTestHost } from '@altifigence/dds-plugin-sdk/testing';
import plugin from './plugin.mjs';

test('reports a TODO and clears it after editing', async () => {
  const host = createTestHost();
  try {
    await host.activate(plugin);
    const document = {
      uri: 'memory:///hello.txt',
      languageId: 'plaintext',
      modelVersion: 1,
      workspaceRevision: 'test-1',
      text: 'TODO: write a plugin.\n',
    };
    host.setDocument(document);
    const result = await host.requestDiagnostics();
    assert.equal(result.diagnostics.length, 1);
    assert.equal(result.diagnostics[0].code, 'todo');
    assert.deepEqual(result.diagnostics[0].range, {
      start: {line: 0, character: 0},
      end: {line: 0, character: 4},
    });
    host.setDocument({...document, modelVersion: 2, text: 'Done.\n'});
    assert.equal((await host.requestDiagnostics()).diagnostics.length, 0);
  } finally {
    host.dispose();
  }
});
Bash
node --test plugin.test.mjs

The test should pass. Add fixtures for your own language, cancellation, invalid results and large documents. Keep the document version current so results from an earlier snapshot are rejected.

API Reference#

Import plugin APIs from @altifigence/dds-plugin-sdk. The package includes TypeScript declarations for the same exports.

API

Use

definePlugin(manifest, activate)

Validate the manifest and declare the activation function.

context.registerDiagnosticsProvider(selector, provider)

Register provideDiagnostics(request, {signal}) for selected language IDs; return a disposable registration.

createDiagnosticsResult(request, diagnostics)

Build a validated result using the request identity.

parseManifest(value)

Validate manifest version, identity, permissions, supported hosts and entry module.

parseDocumentSnapshot(value)

Validate URI, language, model version, workspace revision and text.

parseDiagnosticsRequest(value) / parseDiagnosticsResult(value)

Validate protocol, request, scope, document identity and diagnostic fields.

PluginSdkError / ErrorCode / LIMITS / PROTOCOL_VERSION

Read typed errors, resource limits and protocol version.

Import the developer host from @altifigence/dds-plugin-sdk/testing:

Test host API

Use

createTestHost({scope, grants})

Create a local host. Both options are optional; default grants allow document reading and diagnostics.

await host.activate(plugin)

Activate the plugin and return a disposable activation.

host.setDocument(snapshot)

Set the current document. Increase modelVersion or change workspaceRevision when changing its text.

await host.requestDiagnostics({signal, timeoutMs})

Request diagnostics from a matching provider; both options are optional.

host.deactivate(pluginId) / host.dispose()

Remove registrations and cancel pending work; dispose the host when the test ends.

Requests include requestId, project/session scope and a snapshot with uri, languageId, modelVersion, workspaceRevision and text. Use createDiagnosticsResult to preserve this identity. Results contain a diagnostics array and omit source text.

Errors expose a code, including invalid_contract, permission_denied, cancelled, stale_snapshot, provider_unavailable and budget_exceeded. The default request timeout is 5 seconds; accepted timeouts are 1–30,000 ms. A document is limited to 262,144 UTF-8 bytes and a result to 500 diagnostics. Read LIMITS for the complete limits.

Source, Releases and Contributions#

The official SDK repository contains the source, schemas, examples and contract tests. To run the released example and SDK tests from source:

Bash
git clone --branch v0.1.0 --depth 1 https://github.com/Altifigence/dds-plugin-sdk.git
cd dds-plugin-sdk
npm ci
npm test
npm run example

Report SDK bugs through GitHub Issues, with the SDK version and a minimal reproduction. The SDK is licensed under Apache-2.0; see the repository license and notices. Use the release page for versioned archives and release notes.