SuperAPI AI Directory

plugin-core-builtin-migration

General & other

View repository

Updated 10-16 05:48

About this skill

Plugin Core Built-in Migration

Transform a single plugin into a "stable, default, indispensable" product capability, and distill reusable migration steps.

Applicable scenarios:

  • A certain plugin has become part of the core experience (e.g., TODO, CSV, configuration, change center)
  • The old plugin entry point is to be retired, but historical data must be migratable
  • Need to avoid registration drift such as "a page missing an import causing an empty plugin list"

Goal definition (align first)

In this project, "fully built-in" is recommended to simultaneously satisfy:

  1. Stable registration: There is exactly one renderer registrationClient root entry(recommended SidebarLayout / ShellLayout)
  2. Available by default:manifest.builtin = true
  3. Not disableable(if true core is needed):manifest.core = true(registry will force enable)
  4. Observable and maintainable: Plugin page, settings page, documentation, and tests are consistent
  5. Historical compatibility: Old entry point data has a migration plan, no content is lost
  6. Clear surface semantics: Distinguish between "plugins (manageable)" and "in-app built-in capabilities (not shown in the plugin panel)"

Quality gates (mandatory)

Each time this Skill is executed, the following quality perspectives are applied by default (in order):

  1. Product design perspective(product-designer)

    • Check information hierarchy, task paths, primary/secondary actions, feedback timing
    • Ensure "the main path can be completed within 3 steps," avoiding longer flows after migration
  2. UI/UX perspective(ui-design-patterns)

    • Check button hierarchy, interaction consistency, empty states/error states/loading states
    • Prohibit meaningless underlined-link overuse; the visual hierarchy of primary CTA and secondary CTA must be clear
    • Dark mode readability must pass (button text contrast, tag contrast, focus visibility)
  3. Implementation quality perspective

  • Migration logic is idempotent (repeated execution does not duplicate imports)
  • Registration mechanism is single-sourced (prohibit multiple scattered imports causing drift)
  • Avoid server-side-only registration causing client-side 0/0 empty list
    • Compatibility code failure does not block the main flow (best-effort + observable)
  1. Verification perspective
    • Minimum pass: core/API regression tests + lint
    • UI changes require at least one manual check (light/dark)

If any step is not satisfied, the migration must not be judged complete.


Execution flow (general)

Step 1) Inventory the current state and boundaries

First confirm the four types of fact sources for the plugin:

  • Code entry:packages/web/components/renderers/<plugin>/manifest.ts
  • Registration entry:packages/web/lib/renderers/index.ts(auto-generated)
  • Usage entry:resolveRenderer() call chain (e.g., ViewPageClient)
  • Display entry: plugin panel/settings page (prefer using getPluginRenderers())

And answer:

  • Should this plugin be core(not disableable)?
  • Is there an old file protocol/old entry point (e.g., Agent-Diff.md) that needs migration?

Step 2) Upgrade the plugin declaration

Set in the manifest:

  • builtin: true(built-in)
  • core: true(if it should be fully built-in and cannot be disabled)
  • appBuiltinFeature: true(if it is an “in-app built-in capability” and should not appear in the plugin management panel)
  • match Keep it explicit to avoid mismatches

If the plugin is to be replaced/retired:

  • Delete the old renderer files
  • Regenerate packages/web/lib/renderers/index.ts

Step 3) Unify the registration mechanism (prevent drift)

It must converge to a single-point initialization (client):

  • In the client root component (recommended SidebarLayout) import @/lib/renderers/index
  • Remove scattered imports in other pages/components (to avoid duplication and omission coexisting)

Acceptance criteria:

  • When entering the plugin page from any route, the plugin list should not show 0/0 false empty state
  • In “in-app built-in capability” mode, the marked capability should disappear from the plugin panel but still render normally

Step 4) Historical compatibility migration (critical)

If the old plugin depends on the old file format:

  1. Implement “lazy migration” in the core data layer:
    • Automatically import the old format on first read
    • Write the new format (structured JSON)
  2. After migration, clean up the old entry files (to prevent dual writes and duplicate imports)
  3. Provide a one-time script (offline/manual repair):
    • scripts/migrate-*.js

Step 5) UI/UX alignment

  • Plugin page: status and toggleable policies are consistent with core semantics
  • Settings page: display builtin/core label logic consistently
  • If set to appBuiltinFeature: consistently hide on the plugin page/settings page/home page Extensions
  • Complete basic interactions such as filtering, empty state, loading, and read status on the new main process pages

Step 6) Documentation and knowledge synchronization

At minimum synchronize:

  • wiki/plugins/README.md
  • wiki/60-stage-plugins.md
  • Related specs / pitfalls / refs (if the behavior model changes)

And record the migration decision:

  • Why move from a plugin entry to a main program capability
  • How the old entry remains compatible and when to clean it up

Step 7) Testing and regression

Minimum test set:

  • Core layer migration test (old format -> new format)
  • API layer filtering/query tests (if there are changes/feed-type interfaces)
  • UI basic smoke (plugin list is non-empty, core buttons are usable)
  • Category test (appBuiltinFeature whether it can be correctly hidden from the plugin surface)

Recommended command:

npm --prefix app run test -- __tests__/core/content-changes.test.ts __tests__/api/changes.test.ts

AgentDiff -> Built-in reference mapping

This migration can serve as a template:

  • Old:Agent-Diff.md + agent-diff renderer
  • New:.mindos/change-log.json + /api/changes + /changes main page + global reminder
  • Compatibility: read the old block and automatically import it; after import, delete Agent-Diff.md
  • Governance: delete diff-viewer renderer and the old documentation entry, keep the structured audit trail

Common pitfalls checklist

  1. Only deleting the plugin without migrating old data -> user history is lost
  2. Registration entries are scattered/registered only on the server side -> the client plugin panel shows 0/0
  3. Documentation not synchronized -> users see outdated entries
  4. core/builtin/appBuiltinFeature semantics are confused -> capabilities that should be “in-app built-in” still appear in the plugin panel
  5. Migration is not idempotent -> Repeatedly importing the same batch of old data on each read

Delivery Checklist (Copyable)

  • The manifest layer completes the builtin/core definitions
  • If "non-plug-in" is required, add to the manifest appBuiltinFeature: true
  • Unify global registration to a single point (imported uniformly at the client root entry)
  • The old entry migration logic is implemented and idempotent
  • Old files can be cleaned up after migration
  • Provide a one-time migration script
  • Plugin page/settings page status is correct (including the appBuiltinFeature hiding strategy)
  • Documentation has been updated in sync
  • Tests pass