Plugin SDK 1.69.0

What a plugin can reach.

Every part of Whity core, rated by how far a plugin can read it, change it, react to it and extend it through the plugin SDK. Of 51 areas, 11 are full,27 partial and 13 none. The matrix is generated from the repository and updated with every SDK release.

Core 0.2.26 · updated 2026-11-06

Full
A plugin can read, change, react to and extend this area through a published SDK contract.
Partial
Some of it is in the SDK; the rest is missing or reachable only through internal core classes.
None
No SDK contract. A plugin cannot interact with this area in a supported way.
Needs a design
Gaps that could cross workspaces, skip permissions or move money get a reviewed design before any SDK export.

People and access

Users and accounts

Partial
  • user.creating, user.created, user.updated, user.deleted hook events1.0
Missing (6)
  • A user directory and membership reader
  • A supported way to provision or update users
  • user.updating and a user.deleting veto
  • Creation events on self-registration, invitation acceptance and SSO provisioning (only admin create fires them)
  • Custom profile fields
  • A slot on the user record page

Needs a design Hooks on account creation must not expose credentials or let a listener change the role. A read-only notification payload and a narrow, audited mutation contract are needed rather than more filter hooks.

Planned: 0.2.27

People directory

None
Missing (4)
  • A person read and search contract
  • person.* events
  • Custom person fields
  • A person picker block

Needs a design People records are personal data. A reader must be pinned to the current workspace, checked against relations:read for the caller, and able to redact fields.

Planned: 0.2.28

Sign-in, SSO and two-factor

None
  • ExternalAuthProvider and ExternalIdentity types (not yet wired to a registration path)
Missing (4)
  • Registering a plugin identity provider
  • Read-only sign-in, sign-out, two-factor and password-reset events
  • Custom second factors
  • Password policy extension

Needs a design An identity provider decides who an account belongs to. It needs a trust tier, operator-only enablement and binding per workspace. Sign-in events must be observe-only so no plugin can capture credentials or block sign-in.

Planned: later

Workspaces

Partial
  • tenant.creating to tenant.deleted hook events1.0
  • Veto a workspace deletion inside its transaction1.15
  • Owned tables cascade on workspace deletion (PluginTablesInterface)1.20
Missing (3)
  • A workspace read contract (name, plan, locale, enabled plugins)
  • Workspace custom fields
  • A slot on workspace settings

Needs a design Install-wide plugins see every workspace's events. Hook subscriptions scoped to a workspace need a design before more workspace data is exposed.

Planned: 0.2.28

Roles and permissions

Partial
  • Route requiredPermission enforced by the host1.2
  • PermissionResolver: read-only permission checks1.16
  • Permission checks scoped to one record1.17
  • Plugin-declared resource types1.18
  • Role checks scoped to one record1.22
  • Declared permissions and seeded roles (PluginRolesInterface)1.0
Missing (3)
  • Granting and revoking record-level roles through a contract
  • Events when a role's permissions change, and a veto on grants
  • Roles namespaced to the plugin

Needs a design Anything that grants authority can escalate privilege. Role seeding and grants must be limited to the plugin's own roles and permissions, and every check must be bound to the caller's workspace by the host.

Planned: 0.2.27

Delegations

None
Missing (3)
  • Reading active delegations and the acting-for context
  • Delegation events
  • A veto on delegating a plugin-owned permission

Needs a design Delegation transfers authority, so plugins may observe and refuse it but must never create it.

Planned: later

User groups and audiences

Partial
  • Plugin rule kinds in groups and routing (RoutingRuleResolverInterface)1.37
  • Audience rule vocabulary shared with groups1.38
Missing (3)
  • Resolving a group's or audience's members
  • Group events
  • A group picker block

Needs a design A plugin rule resolver returns people for a workspace. The host must drop anyone who is not an active member of that workspace rather than trusting the resolver.

Planned: 0.2.28

Organizational units

Full
  • ou.* hook events, including role assignment and a delete veto1.0
  • Plugin OU types an admin adopts1.30
  • ouScopePicker block1.32
Missing (2)
  • A server-side OU tree reader
  • OU custom fields

Planned: 0.2.28

Invitations and registration

Partial
Missing (4)
  • Published constants for registration.completed, registration.approved and registration.rejected (fired today, not in Events)
  • Invitation events
  • Custom registration fields
  • An accept-or-reject check on registration

Needs a design A registration check may accept or reject, never set the role or unit, or it becomes an escalation path.

Planned: 0.2.27

Relations

None
Missing (3)
  • Plugin relationship types
  • Reading and writing relations
  • Relation events

Needs a design Relations hold family and guardian links. Writes need permission-checked contracts.

Planned: later

Tags and taxonomy

None
Missing (4)
  • Declared taggable types and vocabularies
  • Reading and attaching tags
  • A tag picker block
  • Tag events

Planned: 0.2.28

Documents

Documents

Partial
  • documentViewer block1.36
  • document.issuing (veto and checks), document.issued, document.rendered events1.49
  • Issue documents as the person (Documents::issue)1.56
  • Issue in the background where the workspace allows it1.58
  • PluginDocumentStore, QR verification links and tracking1.63
  • Document numbering rules and document.numbered1.65
  • Preflight an issue without writing1.66
  • document.revised1.68
Missing (6)
  • Reading and listing documents other than the plugin's own
  • Withdraw and revise contracts, and document.withdrawn
  • Issue events for documents raised by form submissions
  • Published constants for document.routed and document.route_acted
  • Embed record providers and chart sources
  • Collections and organizer views

Needs a design Document visibility depends on the caller and the route. A reader must apply the host's visibility policy per caller, and withdraw or revise must keep the audit trail intact.

Planned: 0.2.27

Templates, themes and the editor

Partial
  • Template slots in plugin.json1.55
  • Template slots and merge-field providers for code plugins1.56
Missing (5)
  • Plugin document themes
  • Editor blocks, toolbar items and slash-menu entries
  • Starter templates shipped by a plugin
  • Reading templates
  • Template and theme events

Needs a design Merge fields and editor blocks end up in printed, immutable documents. Providers must be held to the caller's workspace and permissions by the host, and plugin block markup needs a sandbox and server-side schema checks.

Planned: later

Render service

Partial
  • DocumentRenderer, FlowDocument, PageSpec1.41
  • Inline runs in flowing text1.44
Missing (3)
  • Choosing a theme or brand when rendering
  • Rendering from a workspace template outside Documents::issue
  • Rendering from a job (the seam is HTTP-only)

Needs a design HTML or CSS input to the renderer would be an injection and server-side request surface. Keep input structured.

Planned: 0.2.28

Routing and approvals

Partial
  • Plugin routing rules that resolve recipients1.37
Missing (4)
  • Reading a document's route and trail
  • Starting or acting on a route
  • Plugin route effects
  • route.completed, step-due events and a veto before an action

Needs a design Acting on a route is an approval on a person's behalf. It needs the actor bound by the host and the agent proposal policy.

Planned: later

Forms and workflow

Plugin forms and public routes

Full
  • form block and input blocks1.8
  • Form preload from the plugin's own GET (dataSource)1.40
  • Discriminated sub-forms (variant)1.42
  • Anonymous form posts ('public' => 'form', PublicForm)1.67
  • Anonymous link reads ('public' => 'read', PublicRead)1.69
Missing (1)
  • Per-route rate limits beyond the host defaults

Planned: later

Core forms and submissions

None
Missing (5)
  • form.submitted, submission.reviewed and submission.withdrawn events
  • Reading submissions
  • Custom field types, validators and prefill sources
  • Mapping a submission to a plugin record
  • A slot in the form builder and in submission review

Needs a design Submissions hold personal data and anonymous input. Readers must respect member and reviewer scope, events should carry ids only, and a plugin field type on a public form needs the same gate public forms already have.

Planned: 0.2.27

Meetings and decisions

None
Missing (3)
  • meeting.scheduled, meeting.held and decision.recorded events
  • Reading meetings and decisions
  • Agenda-item sources and a minutes slot

Needs a design Attendance, quorum and decisions are legal facts. Writes need a host-bound actor and audit.

Planned: later

Inbox and Waiting for you

Partial
  • inbox and timeline blocks for the plugin's own items1.31
Missing (2)
  • An inbox source contract so plugin tasks reach Waiting for you
  • Acting on an inbox item from a plugin

Needs a design Each source must answer only for the caller in the current workspace. The host has to enforce that rather than trust the source.

Planned: 0.2.28

Time windows

Partial
  • Plugin window types an admin adopts1.39
Missing (4)
  • Resolving a date to its window
  • window.closing veto, window.closed and window.reopened
  • A closed-period guard for plugin records
  • A published close-report contract

Needs a design A closed period is a bookkeeping rule. Writes into it need a host-enforced guard.

Planned: later

Workspace records and automations

Full
  • plugin.json manifest1.47
  • Manifest expressions1.48
  • Record types1.50
  • Record rules, defaults, computed and locked fields1.51
  • Automations1.53
  • Manifest tests1.54
  • issue_document automation step1.57
Missing (3)
  • send_webhook, ask_approval, wait and call_action steps
  • Triggers from core events (form submitted, document issued)
  • Record types for code plugins

Needs a design Triggers from another area's events must carry ids and re-read under the run's permissions. send_webhook needs an egress allowlist.

Planned: later

Data types

Full
  • Plugin-owned data types with generic admin screens1.20
  • Lifecycle writes and guards1.24
Missing (2)
  • Lifecycle events (trashed, restored, deleted)
  • Data types as document merge fields

Planned: later

Reports

None
Missing (3)
  • A report source contract
  • Custom columns and filters
  • Scheduled reports

Needs a design A report aggregates across records, so row visibility per caller must be enforced by the host or totals leak across units.

Planned: 0.2.28

Platform services

Settings

Partial
  • Declared, typed, namespaced settings keys1.21
Missing (3)
  • An SDK reader and writer for the plugin's own keys
  • A settings-changed event
  • A settings page per plugin and per workspace

Needs a design The internal settings service also covers core and install-wide keys. The SDK reader must be limited to the plugin's own keys in the current workspace.

Planned: 0.2.27

Secrets

Partial
  • PluginSecrets: encrypted per plugin and workspace1.60
Missing (2)
  • A host-rendered secret entry field
  • Listing and rotation

Needs a design The host, not the caller, must decide which plugin and workspace a store belongs to.

Planned: 0.2.27

File storage

Partial
  • Multipart uploads1.5
  • PluginFiles and ready-made file routes1.63
Missing (3)
  • Signed temporary links
  • Quotas and a scan hook
  • file.uploaded event

Needs a design The host must decide which plugin and workspace a store belongs to.

Planned: 0.2.28

Notifications and mail

Partial
  • NotificationTransport contract (not yet discovered from plugins)1.14
Missing (4)
  • A Notifier service: send to a person, role or unit
  • Declared notification types with English and Arabic labels
  • Registering plugin transports
  • Sent and failed events

Needs a design Sending must be bound to the current workspace, reach only its members, and respect opt-outs; a plugin must not be able to pose as a security or billing notice.

Planned: 0.2.27

Languages and translations

Partial
  • English and Arabic labels on settings, data types, manifest screens and agents1.21
Missing (3)
  • Shipping a translation catalogue
  • Arabic labels on frontend features, navigation and block text
  • The request's language in the SDK Request

Planned: 0.2.27

Branding and themes

Partial
  • Theme token override from a plugin route1.12
Missing (3)
  • Reading workspace branding
  • Choosing which plugin's override applies per workspace
  • Fonts, logos and radii

Needs a design The theme route is public and runs on every page. Per-workspace overrides need a design.

Planned: later

Home page

Partial
  • One home card per plugin1.62
Missing (2)
  • More than one card, and actions on cards
  • Contributing to Waiting for you

Planned: 0.2.28

Audit log

Partial
  • Declared audited plugin events1.29
  • timeline block1.31
Missing (2)
  • Reading the plugin's own audit entries
  • Recording an entry with a target and actor directly

Needs a design Audit rows must be attributed by the host to the plugin that wrote them, so one plugin cannot write rows under another's or core's name.

Planned: 0.2.27

Jobs and scheduling

Partial
  • Plugin job handlers1.28
Missing (3)
  • Enqueueing through the SDK
  • Scheduled (cron) jobs
  • Job status for the UI

Needs a design Enqueueing must accept only the plugin's own job names in the current workspace.

Planned: 0.2.27

Health and status

Full
  • Plugin health probes on the status page1.19
Missing (2)
  • Probes per workspace
  • Alerting hook

Planned: later

Plans, entitlements and payments

Partial
  • Declared sellable limits in the plan catalogue (PluginEntitlementsInterface)
Missing (4)
  • Reading entitlements and consuming meters through the SDK
  • requiredEntitlement on routes
  • Plan, subscription and seat events
  • Charging through Whity Pay

Needs a design Charging moves money. It needs consent, the ledger, idempotency and webhook trust; meters must stay bound to the workspace.

Planned: 0.2.28

Interface

Plugin screens and blocks

Full
  • Frontend features (crud, action, custom)1.2
  • Server-driven blocks1.6
  • Data blocks1.7
  • chart block1.10
  • Sort, filter and paging1.11
  • Embedded screens1.13
  • dataRecord and recordFields blocks1.33
  • visibleWhen and accessGate1.34
  • flow block1.35
Missing (2)
  • Native screens for store plugins (custom screens need a change in this repository)
  • Blocks outside /admin/x pages

Needs a design Embedded screens are not isolated from the app. Third-party UI needs a separate origin, a message bridge and a scoped token first.

Planned: later

Slots in core screens

None
Missing (3)
  • Tabs, sections and actions on person, user, role, unit, workspace and document record pages
  • Slots in admin screens, settings and the person's own settings
  • Top bar and user menu entries

Needs a design A slot receives the record it sits on. It needs per-record permission checks and the same own-routes rule blocks have.

Planned: 0.2.28

Desktop app

Partial
  • Plugins run under the offline desktop PHP host1.27
Missing (2)
  • Rendering plugin blocks in the desktop or Flutter apps
  • Desktop plugin releases per workspace

Planned: later

Agents and integrations

MCP tools

Full
  • Plugin routes become MCP tools
  • Hand-authored tools1.43
  • Tool annotations1.45
  • Tool context1.46
  • Toolsets, visibility, agent policy and undo windows1.52
  • Caller identity: person, agent or system1.59
Missing (1)
  • Previews of what a proposed tool call would change

Needs a design Whether an agent must ask first has to come from the host's view of the operation, never from a hint the plugin declares.

Planned: 0.2.27

MCP prompts and resources

Partial
  • Plugin prompts1.9
Missing (2)
  • Authored resources and subscriptions
  • Workspace-specific prompts

Needs a design Prompt text goes straight into an agent's context. Third-party prompts should be limited to verified plugins and gated by permission.

Planned: later

Agents and presets

Full
  • Agent presets1.61
  • Plugin agents1.64
Missing (1)
  • Agent and token lifecycle events

Planned: later

Agent proposals

Partial
  • agentPolicy propose and suggest-only on plugin tools1.52
Missing (2)
  • Proposal created, decided and undone events
  • Plugin-provided previews of a proposal

Needs a design Only the granting person decides a proposal. Any plugin view must be read-only.

Planned: 0.2.28

Outbound webhooks and connectors

None
Missing (3)
  • Subscribing external URLs to events, with signing, retries and a delivery log
  • An outbound HTTP client
  • Admin-registered connectors

Needs a design Outbound calls need a guard against private addresses, signing secrets kept in PluginSecrets, a workspace check per event and id-only payloads.

Planned: later

Plugin runtime

Install, versions and lifecycle

Partial
  • SDK version constraint1.1
  • Core version constraint1.4
Missing (3)
  • Enabled, installed and upgraded callbacks
  • Knowing whether the plugin is on for the current workspace
  • The running core version

Needs a design Installing and enabling stay operator-only. A lifecycle callback must not let a plugin enable others.

Planned: 0.2.28

Logging, errors and rate limits

None
Missing (4)
  • A scrubbed logger
  • Reporting errors to the error tracker
  • Rate limits declared per route
  • Metrics

Needs a design Plugin payloads must pass through the same scrubber before they reach logs or the error tracker.

Planned: 0.2.28

Database and migrations

Full
  • Migrations1.0
  • Tenant-isolation conformance kit1.3
  • SchemaInspector1.23
  • Upsert and SequenceAllocator1.25
  • Undeclared-reference linter1.26
  • Offline-host conformance kit1.27
Missing (2)
  • A runtime connection handle from the SDK
  • Read-only views of core tables

Needs a design Workspace isolation is checked by lint and tests, not enforced. A connection bound to the workspace is a design question.

Planned: later

HTTP routes

Full
  • Request and Response1.0
  • Multipart requests1.5
  • Route schemas in the OpenAPI document
Missing (2)
  • Workspace, language and actor kind on Request
  • Per-route rate limits and entitlements

Needs a design Routes cannot tell an agent from a person today, so they cannot apply stricter rules to agents.

Planned: 0.2.27

Hook events

Partial
  • Events catalogue1.0
  • Veto exception1.15
Missing (3)
  • Constants for events core already fires (membership, registration, federated sign-in, resource grants, routing, close report)
  • Observe-only listeners that cannot change the payload
  • Events for settings, plugins, plans, notifications, files and jobs

Needs a design Every listener can rewrite the payload today. Observe-only listeners, and a per-event list of what may change, are needed before more events are published.

Planned: 0.2.27

Command line

None
Missing (1)
  • Plugin commands

Needs a design Commands run with full database rights outside RBAC. A plugin command must be operator-only and name its workspace explicitly.

Planned: later

Personal preferences

None
Missing (2)
  • Reading the person's language, calendar and density
  • Plugin preference keys

Planned: 0.2.27

Roadmap

Ordered by value to plugin authors, then by risk.

Hardening (0.2.27). Before new surface: tighten the existing extension points the sweep found too permissive. Tracked privately under SECURITY.md and fixed in 0.2.27; each fix is listed here once it ships.

0.2.27: Events, context and the basics every plugin rebuilds

ItemAreasValueRiskDesign first
Publish constants for every event core already fires, and add observe-only listeners #1673Hook events, Invitations and registration, Users and accounts, Documentshighlow
form.submitted, submission.reviewed and submission.withdrawn, and issue events for submission documents #1674Core forms and submissions, Documentshighmedium
Workspace, language and actor kind (person, agent, system) on the SDK Request #1675HTTP routes, Languages and translations, Personal preferenceshighlow
Read and write the plugin's own settings for the current workspace, a settings-changed event, and a host-rendered secret field #1676Settings, Secretshighmedium
Notifier: declared notification types, sent to a person, role or unit in the current workspace #1677Notifications and mailhighmedium
Ship English and Arabic catalogues, and Arabic labels on features, navigation and blocks #521Languages and translations, Navigationmediumlow
Enqueue the plugin's own jobs, and declare scheduled jobs #1678Jobs and schedulingmediummedium
Record and read the plugin's own audit entries, attributed by the host #1679Audit logmediumlow

0.2.28: Reading core data safely, and appearing inside core screens

ItemAreasValueRiskDesign first
People, user, group and unit readers pinned to the workspace and checked per caller, with picker blocks #1680People directory, Users and accounts, User groups and audiences, Organizational units, WorkspaceshighhighYes
Inbox source contract: plugin tasks in Waiting for you #881Inbox and Waiting for you, Home pagehighmediumYes
Tabs, sections and actions on core record pages, rendered with blocks #1681Slots in core screenshighhighYes
Search and report source contracts, filtered per caller by the host; workspace records in search #1682Search and the command palette, ReportsmediummediumYes
Read entitlements and consume meters, and requiredEntitlement on routes #1683Plans, entitlements and paymentsmediummedium
Read and list documents under the host's visibility policy; withdraw and revise contracts #1684DocumentsmediumhighYes
Plugin previews for proposals, and proposal events #1685Agent proposals, MCP toolsmediumlow
Plugin tag vocabularies and taggable types #714Tags and taxonomymediumlow
Lifecycle callbacks, a scrubbed logger, error reporting and per-route rate limits #1686Install, versions and lifecycle, Logging, errors and rate limitsmediumlow
Render and issue from a job, and render with a workspace theme #1151Render service, File storagemediummedium

later: High-risk surface, each behind its own design

ItemAreasValueRiskDesign first
Outbound webhooks and connectors, and the send_webhook automation step #342Outbound webhooks and connectors, Workspace records and automationshighhighYes
Charging through Whity Pay #1687Plans, entitlements and paymentshighhighYes
Isolated origin for embedded and store-plugin UI, then native screens for store plugins #1688Plugin screens and blockshighhighYes
Editor blocks and document themes from plugins #1689Templates, themes and the editormediumhighYes
Plugin identity providers and sign-in events #1690Sign-in, SSO and two-factormediumhighYes
Custom form field types, validators and prefill sources #1691Core forms and submissionsmediummediumYes
Routing, meeting and time-window events, and a closed-period guard #1692Routing and approvals, Meetings and decisions, Time windowsmediummedium
Least-privilege plugin capabilities: plugins reach only the services they declare #1693Database and migrations, Hook eventsmediumhighYes
Relations, delegations and plugin CLI commands #1694Relations, Delegations, Command linelowhighYes

Source: docs/sdk-coverage/coverage.json· Documentation version