dual-edition-module-migration
The dual-edition-module-migration skill guides developers through migrating modules between open-source and enterprise codebases while maintaining strict boundaries. Apply this skill when a module must exist in both editions, the user references `src/opensource/`, `enterprise/`, or Vite overlays, or when removing legacy `src/variant/` facades. It enforces four core invariants: `src/opensource/` remains the shared source of truth without commercial dependencies, `enterprise/` functions as a thin overlay with mirrored paths, open-source callers use real shared imports, and extension points are chosen by artifact type.
git clone --depth 1 https://github.com/dtyq/magic /tmp/dual-edition-module-migration && cp -r /tmp/dual-edition-module-migration/frontend/magic-web/.agents/skills/dual-edition-module-migration ~/.claude/skills/dual-edition-module-migrationSKILL.md
# Dual Edition Module Migration
## When to apply
- A module must exist in both open-source and enterprise editions
- The user mentions `src/opensource`, `enterprise/`, Vite overlay, or edition-specific behavior
- A shared module needs to stay under `src/opensource/...`, but enterprise behavior must override it
- Old `src/variant/...` or `src/opensource/variant/...` facades need to be removed
- A migration must preserve the `src/opensource` import boundary
## Core invariants
### 1. `src/opensource` is the shared source of truth
- Code under `src/opensource/` is the default implementation
- `src/opensource/` must not import commercial code
- If open-source needs a dependency, migrate that dependency too or degrade the feature
- If a file under `src/opensource/` or `enterprise/src/opensource/` imports a module outside the `opensource` tree, move that dependency into the current `opensource` closure instead of keeping a shim
- Do not pull private infrastructure such as `keewoodClient` or `teamshareClient` into `src/opensource`
### 2. `enterprise/` is an overlay, not a second app
- Keep the same relative path under `enterprise/` as the shared file under `src/`
- Runtime resolution priority is `enterprise/**` first, then `src/**`
- Enterprise files should be as thin as possible
- Prefer a re-export shim in `enterprise/...` when it preserves behavior without duplication
- Do not use re-export shims when the stable caller path is already `@/opensource/...` and the shim would import from outside the `opensource` tree
- If a dependency chain is truly enterprise-only, keep the whole chain in `enterprise/...`
- Do not leave enterprise-only stores or services in `src` just because enterprise files import them
- Do not create an enterprise overlay file that re-imports the same logical `@/opensource/...` path it overrides
- If the stable caller path is `@/opensource/...`, the enterprise implementation must live under `enterprise/src/opensource/...`
- Do not move a dual-edition module into `enterprise/components/...` or another non-mirrored path unless the user explicitly wants a commercial-only module
### 3. Open-source callers should import the real shared path
- Files under `src/opensource/` should import `@/opensource/...` directly
- Do not keep `@/variant/...` in open-source code
- If enterprise needs different behavior for that shared path, add an overlay file under `enterprise/src/opensource/...`
### 4. Choose extension point by artifact type
Use this rule first:
| Artifact | Preferred mechanism |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| React view/component rendered through factory | `ComponentFactory` default in `src/opensource` plus enterprise or premium override where still needed |
| Hook / service / preload helper imported from open-source code | Direct `@/opensource/...` import plus `enterprise/src/opensource/...` overlay when behavior differs |
| Shared implementation used by both editions | Move to `src/opensource/...`; if callers already target `@/opensource/...`, migrate the real code and delete the old file instead of leaving a compatibility shim |
| Legacy `src/components/...` module becoming dual-edition | Migrate to `src/opensource/...` plus mirrored `enterprise/src/opensource/...`; then switch callers to `@/opensource/...` |
| Runtime-only indirection | `src/runtime/<domain>/` only when direct imports and overlay cannot express the binding |
## Architecture patterns
### Pattern A: Shared baseline plus enterprise overlay
Use this for hooks, services, helpers, and other non-visual modules.
1. Keep the default implementation in `src/opensource/...`
2. Update callers to import that `@/opensource/...` path directly
3. If enterprise behavior differs, add the same path under `enterprise/src/opensource/...`
4. Let Vite resolve the enterprise file first at runtime
5. Remove the old `variant` facade after callers are switched
Minimal example:
```ts
// src/opensource/components/business/RecordingSummary/hooks/useCancelRecord.tsx
export default function useCancelRecord() {
// shared implementation
}
```
```ts
// enterprise/src/opensource/components/business/RecordingSummary/hooks/useCancelRecord.tsx
export default function useCancelRecord() {
// enterprise implementation
}
```
```ts
import useCancelRecord from "@/opensource/components/business/RecordingSummary/hooks/useCancelRecord"
```
### Pattern B: Component override
Use this when a UI component needs edition-specific rendering.
1. Keep the default implementation in `src/opensource/...`
2. Register it in `src/opensource/components/ComponentRender/config/defaultComponents.tsx`
3. Keep commercial-only UI in `src/...` only when it owns real delta
4. Register premium overrides only where the factory still needs explicit component replacement
5. For helper imports such as preload code, prefer direct `@/opensource/...` imports plus enterprise overlay
This keeps render-time switching and non-render imports aligned.
### Pattern B.5: Shared facade plus enterprise child override
Use this when the only edition difference is a small injected block inside a much larger shared page or layout.
Rules:
1. Extract the changing block into the smallest possible shared child component or hook under `src/opensource/...`
2. Keep the sharedCore canvas design skill covering project management, multimedia principles, AI image generation, web image search, and design marker processing. Load for any canvas design task. CRITICAL - When user message contains [@design_canvas_project:...] or [@design_marker:...] mentions, or when the user wants to generate video/animation/clip on a canvas project, you MUST load this skill first before any operations.
Summarize and compress the current conversation history into a structured context snapshot, then call compact_chat_history to save it. Read this skill only when the user explicitly asks to compact/summarize — system-triggered compaction injects the instructions directly without requiring a skill read.
Slide/PPT creation skill that provides complete slide creation, editing, and management capabilities. Use when users need to create slides, make presentations, edit slide content, or manage slide projects. CRITICAL - When user message contains [@slide_project:...] mention, you MUST load this skill first before any operations.
|
|
Data analysis dashboard (instrument panel) development skill. Use when users need to develop data dashboards, create/edit Dashboard projects, build large-screen data boards, or perform dashboard data cleaning. Includes dashboard project creation, card plan, data cleaning (data_cleaning.py), card management tools (create_dashboard_cards, update_dashboard_cards, delete_dashboard_cards, query_dashboard_cards), map download tool (download_dashboard_maps), dashboard development, and validation.
Use when the user wants to interact with DingTalk/钉钉 in any way — including but not limited to: reading, querying, searching, sending, replying to, forwarding, or recalling DingTalk/钉钉 chat messages and chat history; managing group chats and conversations; sending DING alerts; querying contacts, org structure, AI search, or coworkers; reading, searching, creating, or editing DingTalk/钉钉 docs, drive files, sheets, AI tables, wiki, mail, calendar events, meeting rooms, AI meeting minutes, attendance, OA approvals, todos, reports/logs, live sessions, AI apps, permissions, or open-platform docs.