Skip to content

feat(den-api): delete imported plugin components#2606

Draft
reachjalil wants to merge 1 commit into
different-ai:devfrom
reachjalil:feature/delete-plugin-components
Draft

feat(den-api): delete imported plugin components#2606
reachjalil wants to merge 1 commit into
different-ai:devfrom
reachjalil:feature/delete-plugin-components

Conversation

@reachjalil

@reachjalil reachjalil commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Intent

Delete paths deserve a little extra seatbelt, so this PR adds a dedicated plugin remove lifecycle path that cleans up imported plugin components without sweeping up shared resources.

When an imported plugin is removed, we want it gone from active Den plugin surfaces and we also want to clean up the Den-managed skill/MCP rows created by that import. The goal is boring-in-a-good-way cleanup: no orphaned Den skills, skill hubs, external MCP connections, access grants, connected accounts, or OAuth client rows, and no surprise deletion of things another active config object still uses.

What changed

  • Added POST /v1/plugins/:pluginId/remove for plugin removal.
  • Removal archives the plugin, removes active plugin-component memberships, and deletes active imported skill/MCP config objects owned only by that plugin.
  • Added a shared managed cleanup planner for imported skills and MCPs.
  • Reused the managed MCP payload parser for both archive cleanup and remove cleanup, including root and nested mcpServers payload shapes.
  • Added unit coverage for the delete edge cases: duplicate refs, active shared refs, non-owned MCPs, nested MCP payloads, and malformed managed metadata.

Delete Safety

Since this is a delete flow, the PR intentionally keeps the cleanup narrow:

  • Only active config objects with sourceMode: "import" and object type skill/mcp are considered for underlying component cleanup.
  • If the same imported config object is attached to another active plugin, plugin removal does not delete that config object.
  • Underlying Den skills are deleted only when no other active imported skill config object references the same denSkillId.
  • External MCP connections are deleted only when the managed payload explicitly says externalMcpConnectionOwnedByPlugin === true.
  • Shared/non-owned MCP connections, missing ownership markers, and malformed managed IDs are ignored rather than deleted.
  • The plugin remove and config object delete paths run cleanup inside the lifecycle transaction so the state change and managed cleanup stay together.

Reviewer Focus

The most important review target is the planner. This is the small gatekeeper that decides what underlying resources are actually safe to delete:

const activeExternalMcpConnectionIds = new Set(input.active.flatMap((entry) => {
  if (entry.objectType !== "mcp") return []
  return externalMcpConnectionIdsFromConfigObjectVersion(entry.latestVersion)
}))

return {
  externalMcpConnectionIds: uniqueIds(input.deleting.flatMap((entry) => {
    if (entry.objectType !== "mcp") return []
    return externalMcpConnectionIdsFromConfigObjectVersion(entry.latestVersion, { ownedOnly: true })
      .filter((connectionId) => !activeExternalMcpConnectionIds.has(connectionId))
  })),
  skillIds: uniqueIds(input.deleting.flatMap((entry) => {
    if (entry.objectType !== "skill") return []
    const skillId = denSkillIdFromConfigObjectVersion(entry.latestVersion)
    return skillId && !activeSkillIds.has(skillId) ? [skillId] : []
  })),
}

Worth double-checking: the ownedOnly: true MCP branch and the active reference checks. That is where the PR avoids turning a plugin delete into a tiny chaos button.

Validation

  • pnpm --filter @openwork-ee/den-api exec bun test test/plugin-system-lifecycle-cleanup.test.ts - passed, 4 tests
  • pnpm --filter @openwork-ee/den-api build - passed

Fraimz/video not captured: this is a backend lifecycle cleanup path with focused unit coverage plus den-api build validation.

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-landing Ready Ready Preview, Comment, Open in v0 Jul 8, 2026 11:55pm

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

@reachjalil is attempting to deploy a commit to the Different AI Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant