Files
kandev/docs/specs/plugins/requirements/authoring-experience.md
T
2026-08-24 11:09:03 +00:00

9.9 KiB

status, system, created, owners
status system created owners
draft plugins 2026-08-02
kandev

Plugin Authoring Experience Requirements

Overview

Plugin authors and coding agents cannot currently move from discovery to a tested package without reconciling public tutorials, frozen contract notes, frontend types, the Go SDK, the manifest implementation, packaging code, and ADRs. Some of those references have drifted behind the shipped contract, which makes otherwise copy-pasteable guidance unsafe.

Requirements

REQ-PLUGINS-AUTHORING-EXPERIENCE-001: Plugin Authoring Experience

Intent: Plugin authors and coding agents cannot currently move from discovery to a tested package without reconciling public tutorials, frozen contract notes, frontend types, the Go SDK, the manifest implementation, packaging code, and ADRs. Some of those references have drifted behind the shipped contract, which makes otherwise copy-pasteable guidance unsafe.

Acceptance criteria

  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.1: docs/public/plugins-authoring.md is the canonical developer entry point and is linked directly from the root, backend, and web AGENTS.md files.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.2: The entry point teaches one workflow: choose a supported recipe, edit manifest.yaml, implement against the authoritative contract, run the available validation, package, install, and smoke test.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.3: It explains the install-to-load lifecycle, package and per-plugin data layout, backend/UI-focused/combined plugin shapes, capability boundary, and the rule that plugins use Host APIs rather than Kandev databases or internal packages.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.4: A storage decision table distinguishes plugin-scoped Host state, the absence of per-user host.storage in this branch, operator config and vault-backed secrets, and files rooted under KANDEV_PLUGIN_DATA_DIR.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.5: A frontend matrix covers every registration and Host value currently exposed by apps/web/lib/plugins/types.ts and apps/web/lib/plugins/host-api.ts. It names every mounted component slot and records input, manifest requirement, lifecycle/cleanup, and an example or authoritative source link.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.6: A backend matrix covers Plugin.OnEvent, Plugin.HandleWebhook, every pluginsdk.Host method/resource accessor, the required capability, and the relevant SDK/proto source.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.7: The guide explicitly says that registerTaskPanel, registerTaskMenuAction, per-user host.storage, RichTextEditor, RichTextReadOnly, and direct Kanban-card injection are not part of the current branch. It does not invent future signatures.
  • AC-PLUGINS-AUTHORING-EXPERIENCE-001.8: At least six current-contract recipes are runnable or link to maintained source: a UI-focused plugin with the required no-op managed binary; a Go backend using Host state; a task-sidebar contribution backed by task-scoped Host state; a webhook receiver; an event subscriber; and a Kanban-aware route that reads host.store without injecting into first-party cards.

Migrated source detail

Why

Plugin authors and coding agents cannot currently move from discovery to a tested package without reconciling public tutorials, frozen contract notes, frontend types, the Go SDK, the manifest implementation, packaging code, and ADRs. Some of those references have drifted behind the shipped contract, which makes otherwise copy-pasteable guidance unsafe.

What

  • docs/public/plugins-authoring.md is the canonical developer entry point and is linked directly from the root, backend, and web AGENTS.md files.
  • The entry point teaches one workflow: choose a supported recipe, edit manifest.yaml, implement against the authoritative contract, run the available validation, package, install, and smoke test.
  • It explains the install-to-load lifecycle, package and per-plugin data layout, backend/UI-focused/combined plugin shapes, capability boundary, and the rule that plugins use Host APIs rather than Kandev databases or internal packages.
  • A storage decision table distinguishes plugin-scoped Host state, the absence of per-user host.storage in this branch, operator config and vault-backed secrets, and files rooted under KANDEV_PLUGIN_DATA_DIR.
  • A frontend matrix covers every registration and Host value currently exposed by apps/web/lib/plugins/types.ts and apps/web/lib/plugins/host-api.ts. It names every mounted component slot and records input, manifest requirement, lifecycle/cleanup, and an example or authoritative source link.
  • A backend matrix covers Plugin.OnEvent, Plugin.HandleWebhook, every pluginsdk.Host method/resource accessor, the required capability, and the relevant SDK/proto source.
  • The guide explicitly says that registerTaskPanel, registerTaskMenuAction, per-user host.storage, RichTextEditor, RichTextReadOnly, and direct Kanban-card injection are not part of the current branch. It does not invent future signatures.
  • At least six current-contract recipes are runnable or link to maintained source: a UI-focused plugin with the required no-op managed binary; a Go backend using Host state; a task-sidebar contribution backed by task-scoped Host state; a webhook receiver; an event subscriber; and a Kanban-aware route that reads host.store without injecting into first-party cards.
  • The reproducible workflow documents the exact checks already available in the plugin template and monorepo, including their limits. Package creation generates checksums; the install path performs manifest, checksum, archive, extraction, and host-binary checks; the in-tree fixture package tests provide the closest no-production-instance validation. This change does not add a second validator or new runtime behavior.
  • Existing plugin pages, contract notes, relevant README-style example docs, and the create-kandev-plugin skill link back to the canonical entry point instead of duplicating or contradicting the API.
  • The plugin system remains marked experimental unless a separate product stability decision changes the public status evidence.

Authoritative contracts

This feature does not add plugin runtime hooks or Host RPCs. It documents the current contract and points readers to:

  • Frontend pair: docs/plans/plugins/PLUGIN-API.md and apps/web/lib/plugins/types.ts.
  • Concrete frontend Host exports: apps/web/lib/plugins/host-api.ts.
  • Backend author API: apps/backend/pkg/pluginsdk.
  • Wire API: apps/backend/proto/kandev/plugin/v1/plugin.proto.
  • Manifest model and semantics: apps/backend/internal/plugins/manifest.
  • Package integrity and install semantics: apps/backend/internal/plugins/pkgtar.

The canonical guide summarizes those sources for discovery, but does not become another type, proto, or schema definition.

Permissions and storage

  • Frontend bundles run in the Kandev origin and receive the current shared React instance and curated host/store surface. Frontend registrations are not individually capability-gated; ui.bundle and ui.keybindings declare the relevant UI entry points.
  • Host state requires state; secrets require secrets; reads require the matching api_read resource; task/message writes require the matching api_write resource; utility-agent invocation requires agent_invoke; and event delivery requires a matching event subscription.
  • Host.GetConfig and Host.EmitEvent are ungated. Webhook keys must be declared. The external-auth response directive additionally requires auth.
  • Plugins do not receive sanctioned direct database access. Domain reads and writes go through typed Host RPCs and Kandev's service layer.
  • Host state is plugin-scoped structured data and is not per-user browser storage. Arbitrary plugin files belong below KANDEV_PLUGIN_DATA_DIR.

Scenarios

  • GIVEN an agent starts at a relevant AGENTS.md, WHEN it follows the plugin-authoring link, THEN it reaches the canonical guide in one step and sees the contract map and supported workflow.
  • GIVEN a UI-focused plugin author, WHEN they follow the recipe, THEN they include the no-op managed executable required by the current installer and a native UI bundle without inventing unsupported backend behavior.
  • GIVEN an author needs durable task-related state, WHEN they consult the storage table and sidebar recipe, THEN they use task-scoped Host state and do not mistake it for unavailable per-user host.storage.
  • GIVEN a manifest declares api_write: ["tasks"], WHEN an author reads the capability matrix, THEN it documents Tasks().Create/Update as implemented and links to the SDK/proto.
  • GIVEN a package whose ui.bundle omits the leading slash, WHEN an author follows the workflow, THEN the guide identifies that error before install and explains which remaining checks happen during packaging and install.
  • GIVEN a disabled or uninstalled UI plugin, WHEN an author consults the lifecycle matrix, THEN it explains destroy, bulk unregistration, modal closure, stylesheet removal, and plugin-owned side-effect cleanup.
  • GIVEN a request for a future task-panel, task-menu, per-user storage, rich-text, or Kanban-card hook, WHEN an author checks the canonical page, THEN it says the API is unavailable in this branch and points to the closest supported recipe.

Out of scope

  • Adding a package checker or changing manifest, packaging, installation, runtime supervision, capability enforcement, signing, or database behavior.
  • Adding frontend hooks, per-user plugin storage, rich-text components, or Kanban-card injection.
  • Publishing or modifying external plugin repositories.
  • Creating a second manifest, proto, TypeScript, or Go SDK definition in docs.
  • Promoting the plugin system from experimental to stable.