From opensaas-migration
Migrate Keystone document fields (@keystone-6/fields-document) to OpenSaaS Stack tiptap rich text fields. Invoke as a forked subagent, passing the config file path and document field details.
How this skill is triggered — by the user, by Claude, or both
Slash command
/opensaas-migration:migrate-document-fieldsgeneral-purposeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Migrate the Keystone document fields described below to OpenSaaS Stack's Tiptap rich text fields. This involves config changes, package updates, and a data format note for existing content.
Migrate the Keystone document fields described below to OpenSaaS Stack's Tiptap rich text fields. This involves config changes, package updates, and a data format note for existing content.
$ARGUMENTS
Keystone uses a proprietary document editor from @keystone-6/fields-document:
import { document } from '@keystone-6/fields-document'
content: document({
formatting: true,
links: true,
dividers: true,
layouts: [
[1, 1],
[1, 1, 1],
],
})
OpenSaaS Stack uses Tiptap (ProseMirror-based) from @opensaas/stack-tiptap:
import { richText } from '@opensaas/stack-tiptap/fields'
content: richText()
Both store JSON in the database, but the JSON formats are different (see data migration note below).
- import { document } from '@keystone-6/fields-document'
+ import { richText } from '@opensaas/stack-tiptap/fields'
content: document({
- formatting: true,
- links: true,
- dividers: true,
- layouts: [[1, 1]],
- })
+ content: richText()
All document field options (formatting, links, dividers, layouts) are dropped — Tiptap's toolbar is configured at the UI level, not the field level.
The user needs to install @opensaas/stack-tiptap and its peer dependencies:
pnpm add @opensaas/stack-tiptap
pnpm remove @keystone-6/fields-document
In the admin page (app/admin/[[...admin]]/page.tsx or similar):
// lib/register-fields.ts
'use client'
import { registerFieldComponent } from '@opensaas/stack-ui'
import { TiptapField } from '@opensaas/stack-tiptap'
registerFieldComponent('richText', TiptapField)
Then import it in the admin page as a side effect:
import '../../../lib/register-fields'
The Keystone document format and Tiptap's ProseMirror JSON format are different. Existing content stored in the database will not automatically render correctly in the Tiptap editor.
If the project has existing document content that must be preserved:
[{ "type": "paragraph", "children": [{ "text": "..." }] }] (Slate-based){ "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "..." }] }] }Options:
Write a comment in the code for any document fields that had existing content so the user knows to address it:
// NOTE: This field was migrated from Keystone document format.
// Existing content may not render correctly until re-saved in the Tiptap editor.
// See specs/keystone-document-migration.md for data migration guidance.
content: richText()
document() fieldsrichText(), update importspnpm add @opensaas/stack-tiptap, pnpm remove @keystone-6/fields-document)// NOTE: comment above each migrated fieldGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Resolves in-progress git merge or rebase conflicts by analyzing history, understanding intent, and preserving both changes where possible. Runs automated checks after resolution.
npx claudepluginhub opensaasau/stack --plugin opensaas-migration