Plugins
Plugins are tenant-installable application capabilities published from the
first-party plugins/* packages. Settings -> Plugins is the operator surface
for catalog browse, install, upgrade, uninstall, source freshness, and plugin
activation repair. Members can use installed plugin detail pages for their own
connections; install and refresh controls are operator-only.
Surface: Settings -> Plugins
Primary files: apps/web/src/components/settings/plugins/PluginsPage.tsx,
packages/api/src/graphql/resolvers/plugins, packages/api/src/lib/plugins
Catalog Freshness
Section titled “Catalog Freshness”The authored source of truth is plugins/<plugin-key>/. GitHub Actions turns
that source into a signed catalog artifact, and the GraphQL API verifies and
caches that artifact before it becomes a trusted runtime catalog.
| Layer | What it represents | How it changes |
|---|---|---|
plugins/* source | Package-owned manifest, skills, adapters, runtime, docs, and tests | Normal pull requests |
| Signed GitHub artifact | Machine-readable catalog generated from plugins/* | Plugin Catalog workflow on main or manual dispatch |
| API verified cache | Last trusted catalog snapshot served by GraphQL | TTL refresh, conditional GitHub revalidation, or operator refresh |
| Tenant install pin | Version a tenant installed or upgraded to | installPlugin / upgradePlugin through ThinkWork |
The stable GitHub channel is release tag plugin-catalog-main with asset
thinkwork-plugin-catalog-main.json. The artifact carries source provenance,
generated time, catalog digest, per-version payload digests, and an ed25519
signature. The private signing key stays in GitHub Actions; deployed stages
trust only the public key.
What Operators See
Section titled “What Operators See”The catalog list overlays each signed catalog entry with the tenant’s installed state. Operator rows show:
- installed pinned version versus latest verified catalog version;
- update availability when the latest version is newer than the install pin;
- install state and component health;
- launch link when an installed plugin owns a deployed application runtime.
The catalog source strip shows the API’s current trust posture:
- source mode (
github-release,github-release-stale,bundled-signed, orbundled-unsigned); - GitHub repository, release tag, source commit, and ref when available;
- generated and fetched timestamps;
- verified catalog digest;
- stale fallback message and GitHub rate-limit metadata when applicable.
Refresh catalog is visible only to operators. It calls
refreshPluginCatalog, bypasses the API freshness TTL, and returns the same
trusted metadata surface. It does not install, upgrade, or mutate plugin state.
Failure Behavior
Section titled “Failure Behavior”The API verifies every GitHub artifact before caching or serving it. Bad signature, digest mismatch, malformed JSON, missing assets, GitHub outage, and rate limits must not become a trusted catalog.
If a previous snapshot was verified, the API may serve it as stale fallback and
surface the failure in pluginCatalogMetadata. If no verified snapshot exists
and signed mode is active, catalog reads fail closed. Installed plugin records
remain in Aurora either way, so already-installed plugins are not deleted by a
catalog freshness problem.
Verification Flow
Section titled “Verification Flow”To prove a plugin version bump is visible without a full app deploy:
- Merge the plugin source change under
plugins/*tomain. - Confirm the
Plugin Catalogworkflow published the stable release asset. - Confirm the artifact contains the expected plugin version, source commit SHA, generated timestamp, digest, and signature.
- In a GitHub-backed stage, click
Refresh catalogor wait for the API cache TTL, then query or view Settings -> Plugins. - Confirm latest version, installed pinned version, update availability, source metadata, and stale/fallback state are correct.
- Install or upgrade the plugin through ThinkWork.
- Run the package-owned smoke through ThinkWork’s installed path.
For LastMile, the final smoke must prove the package-owned contract through the
ThinkWork app and MCP proxy: lastmile--crm, lastmile--tasks, and
lastmile--routing are visible for the activated user and absent for a
non-activated user.
For n8n, the final smoke must prove the Settings -> Plugins install path, the
managed n8n deployment evidence, native n8n instance-level MCP readiness, and
the ThinkWork /api/mcp proxy path for the n8n--workflow-management server.
It must not substitute a local n8n run, direct Terraform-only apply, or n8n
Cloud login for the application-plugin install flow.
Related
Section titled “Related”- Managed Applications - optional app runtime lifecycle for plugins that deploy infrastructure
- Tenant MCP Servers - tenant-level MCP registrations and user connection split
- Mobile Integrations & MCP Connect - end-user connection flow