Skip to main content

Implementing the Four Extension Points

The four extension points are the heart of the plugin contract: they're the functions the core calls, at defined moments, to hand domain-specific work back to you. Your manifest declares all four; the core invokes them. This is the overview — the most complex one, the result handler, gets its own deep dive.

The four, at a glance

Extension pointThe core calls it when…It returns…
resultHandlera workflow execution completes successfullyvoid — you persist domain artifacts
workspaceSnapshotProviderit's assembling the webhook payload at workflow launchthe domain JSON for workspace_snapshot
dashboardStatsProviderit's rendering the dashboard{ total, completed, label? }
workspaceDisplayResolverit's rendering dashboard tables that show entity identity[{ workspaceId, entityDisplayName, manageRoute }]

resultHandler

Called at completion, inside the core's transaction (you receive a client — use it for all writes; never BEGIN/COMMIT/ROLLBACK). You validate and persist the workflow's result payload, and — when the workflow creates a new workspace — create that workspace via coreWorkspaceService.create and link it. You do not update workspace status; the core does that after you return. If you throw, the core rolls everything back and marks the execution failed_permanent. This one is important enough to have its own article.

workspaceSnapshotProvider

Called at launch. You inspect the workspace's current state and return the domain context for the run — the plugin's slice of the webhook payload (for the default plugin: the thing's title, description, current text, input, and status). This is how the operator's specific request reaches the workflow. If it throws, the launch fails cleanly (no execution created).

dashboardStatsProvider

Called when the dashboard renders. You return your completion KPI{ total, completed, label } — because only your plugin knows what "completed" means for your entity. The core can't compute it; it just renders the card you return.

workspaceDisplayResolver

Called when the core renders shared tables (in-progress executions, recent errors) that need to show which entity a workspace belongs to. Given a list of workspace IDs your plugin owns, you return a display name and manage-route for each (a null route for a deleted/unresolvable one). The core only ever passes you workspace IDs your plugin owns, so you don't filter others.

The shape of the deal

Notice the pattern: the core handles everything domain-agnostic (dispatch, logging, cost, status transitions, table rendering) and calls you for the four things only your domain can answer — persist a result, build domain context, define completion, name an entity. Implement these four faithfully and your plugin is fully wired into the platform.