DartCodeAI Plugin Authoring

This guide covers the backend plugin authoring surface used by Enterprise and Enhanced DartCodeAI teams.

Lifecycle

  1. Choose a template from dartcodeai/backend/suite/plugin_templates.

  2. Run dart pub get in the template repository.

  3. Generate or edit plugin.yaml.

  4. Validate with dartcodeai plugins manifest validate plugin.yaml.

  5. Run locally with dartcodeai plugins dev --watch.

  6. Test with dart test and dartcodeai plugins test-harness run.

  7. Publish with dartcodeai plugins publish --manifest plugin.yaml --bundle ..

SDK

Plugin authors import package:dartcodeai_plugin/dartcodeai_plugin.dart.

The SDK exposes:

  • PluginEntrypoint with Future<void> onEvent(PluginEvent event, PluginContext ctx).

  • PluginContext with workspaceId, repoId, installId, scopes, and a short-lived jwt.

  • PluginLogger for structured runtime logs.

  • PluginMetrics for counters, gauges, and histograms.

  • PluginArtifacts for runtime artifact put() and get().

  • PluginSecrets.getRef() for resolving runtime secret references without persistence.

  • DcaiHttpClient for allowlisted Enterprise egress.

  • ConfigSchema for simple required-field checks.

Scopes

Scopes are declared in plugin.yaml and enforced by the runtime:

  • repo:read

  • runs:read

  • artifacts:read

  • artifacts:write

  • reports:write

  • events:read

  • webhooks:write

  • secrets:read

  • logs:write

  • metrics:write

Use the narrowest scopes possible. Runtime credentials are short-lived and should not be stored by plugins.

Events

Common event names:

  • qa.run.requested

  • qa.run.completed

  • coverage.report.ready

  • release.gate.failed

  • sync.requested

Events contain a type string and an arbitrary JSON payload.

Manifest Init

The CLI module exposes POST /cli/plugins/manifest/init for the manifest wizard backend. The response includes a normalized manifest map and a pluginYaml string that can be written to plugin.yaml.

Required manifest fields:

  • name

  • version

  • type

  • entrypoint

  • visibility

  • scopes

Troubleshooting

  • If plugins manifest validate fails, fix the reported path entries before running or publishing.

  • If plugins dev --watch fails immediately, check the entrypoint command and package dependencies.

  • If publish returns pending_signature, provide a KMS-backed signature or use a public visibility manifest that does not require signing.

  • If a plugin cannot reach an external service, confirm the destination host is allowlisted for the tenant.

Cookbook

Slack Notifier

  1. Start from plugin-notifier-template.

  2. Add webhookUrl to configSchema.required.

  3. Subscribe to qa.run.completed.

  4. In onEvent, format a short message and send it through the runtime HTTP client once the Slack host is allowlisted.

LCOV Reporter

  1. Start from plugin-reporter-template.

  2. Add artifacts:read and reports:write scopes.

  3. Read the LCOV artifact from ctx.artifacts.

  4. Write a summarized JSON report back to ctx.artifacts.

External Issue Datasource

  1. Start from plugin-datasource-template.

  2. Store external credentials as runtime secret references.

  3. Use ctx.secrets.getRef("ISSUE_API_TOKEN") at runtime.

  4. Emit normalized issue data as an artifact for reporting plugins.