Help us improve
Share bugs, ideas, or general feedback.
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.
npx claudepluginhub opensaasau/stack --plugin opensaas-migrationHow this skill is triggered — by the user, by Claude, or both
Slash command
/opensaas-migration:migrate-document-fieldsThe 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.
Write and run Contentful content model migration scripts using the contentful-migration library and Contentful CLI. Covers content types, fields, validations, editor interfaces, layouts, sidebar widgets, entry transformations, tags, and annotations.
Plans and implements content migrations from AEM, Contentful, Strapi, Webflow, WordPress, Drupal, Payload, Markdown/MDX, and other sources into Sanity CMS with Portable Text conversion, asset migration, redirects, and validation.
Guides Documenso API v1 to v2 upgrades and TypeScript/Python SDK migrations with code examples and bash commands.
Share bugs, ideas, or general feedback.
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 { RichTextFieldComponent } from '@opensaas/stack-tiptap'
registerFieldComponent('richText', RichTextFieldComponent)
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 field