II.
Page JSON
Structured · livepage:docs-plugins-migration-guide
Migration System Documentation json
Inspect the normalized record payload exactly as the atlas UI reads it.
{
"id": "page:docs-plugins-migration-guide",
"_kind": "Page",
"_file": "wiki/docs/plugins/migration-guide.md",
"_cluster": "wiki",
"attributes": {
"nodeKind": "Page",
"sourcePath": "docs/plugins/migration-guide.md",
"sourceKind": "repo-docs",
"title": "Migration System Documentation",
"displayName": "Migration System Documentation",
"slug": "docs/plugins/migration-guide",
"articlePath": "wiki/docs/plugins/migration-guide.md",
"article": "\n# Migration System Documentation\n\nThe babysitter SDK includes a migration resolution system that finds the shortest path between two plugin versions using migration files in the plugin package directory. This guide covers the naming convention, resolution algorithm, and how to write migration instructions.\n\n## Migration File Naming Convention\n\nMigration files are stored in the `migrations/` subdirectory of a plugin package. Each file describes how to move from one version to another.\n\n### Format\n\n```\n<fromVersion>_to_<toVersion>.<ext>\n```\n\n### Rules\n\n- **fromVersion** and **toVersion** can contain digits, dots, dashes, and alphanumeric pre-release identifiers (e.g., `1.0.0`, `2.0.0-beta.1`, `3.0.0-rc1`).\n- **ext** must be either `md` (markdown instructions) or `js` (babysitter process file).\n- The `_to_` separator is literal and required.\n- Files that do not match the pattern `^([a-zA-Z0-9._-]+)_to_([a-zA-Z0-9._-]+)\\.(md|js)$` are ignored.\n\n### Examples\n\n```\n1.0.0_to_1.1.0.md # Markdown instructions from 1.0.0 to 1.1.0\n1.1.0_to_1.2.0.md # Markdown instructions from 1.1.0 to 1.2.0\n1.2.0_to_2.0.0.js # Process file from 1.2.0 to 2.0.0\n2.0.0-beta_to_2.0.0.md # Pre-release to release\n```\n\n## Migration Chain Resolution\n\nWhen `plugin:update` is called, the SDK resolves the shortest migration path from the installed version to the target version.\n\n### Algorithm\n\n1. **List migrations** -- The SDK reads all files in the `migrations/` directory and parses their filenames into `MigrationDescriptor` objects (containing `from`, `to`, `file`, `type`).\n\n2. **Build graph** -- A directed adjacency list is built with version strings as nodes and migrations as edges. Each edge goes from `fromVersion` to `toVersion`.\n\n3. **BFS shortest path** -- Breadth-first search finds the shortest chain of migrations from the installed version to the target version. This ensures the minimum number of migration steps are applied.\n\n4. **Load content** -- For each migration in the resolved path, the file content is loaded and returned alongside the descriptor.\n\n### Example\n\nGiven these migration files:\n\n```\n1.0.0_to_1.1.0.md\n1.1.0_to_1.2.0.md\n1.0.0_to_1.2.0.md # Direct jump\n1.2.0_to_2.0.0.md\n```\n\nUpdating from `1.0.0` to `2.0.0`:\n\n- Path found by BFS: `1.0.0 -> 1.2.0 -> 2.0.0` (2 steps, using the direct jump)\n- Alternative path: `1.0.0 -> 1.1.0 -> 1.2.0 -> 2.0.0` (3 steps, not chosen because BFS finds the shorter path first)\n\nIf no path exists between the two versions, the SDK returns an error.\n\n### Edge Cases\n\n- **Same version** -- If `fromVersion === toVersion`, the SDK returns an empty migration list with a message `\"Already at target version\"`.\n- **No migrations directory** -- If the `migrations/` directory does not exist, the SDK returns an empty list of descriptors, and BFS will fail to find a path (resulting in an error).\n- **No path found** -- The command returns an error: `No migration path found from version \"<from>\" to \"<to>\" for plugin \"<name>\"`.\n\n## Writing Markdown Migration Instructions\n\nMarkdown migration files (`.md`) contain agent-readable instructions. Structure them clearly:\n\n```markdown\n# Migration from 1.0.0 to 1.1.0\n\n## Summary\nBrief description of what changed.\n\n## Breaking Changes\n- List any breaking changes the agent must handle.\n\n## Steps\n\n1. Step-by-step instructions the agent follows.\n2. Be explicit about file paths and expected values.\n3. Include verification steps where possible.\n\n## Rollback\nIf the migration fails, reverse the steps by:\n1. Rollback instructions.\n```\n\n## Writing JavaScript Migration Process Files\n\nJavaScript migration files (`.js`) are babysitter process definitions. They export a standard `process` function and use `defineTask` for multi-step automated operations.\n\nWhen the SDK finds a `.js` migration file in the resolved chain, it sets the `processFile` field to the absolute path of the file. The agent can then execute it as a babysitter process.\n\n```javascript\nconst { defineTask } = require(\"@a5c-ai/babysitter-sdk\");\n\nconst migrateConfig = defineTask(\"migrate-config\", async (args, ctx) => {\n // Read the old config, transform it, write the new config\n return { success: true };\n});\n\nasync function process(inputs, ctx) {\n const result = await ctx.task(migrateConfig, {\n pluginDir: inputs.pluginDir,\n });\n return result;\n}\n\nmodule.exports = { process };\n```\n\n## Example Migration Workflow\n\n### Scenario\n\nPlugin `my-plugin` is installed at version `1.0.0`. A new version `1.2.0` is available.\n\n### Agent Steps\n\n1. Agent runs:\n ```bash\n babysitter plugin:update my-plugin --marketplace-name my-marketplace --global --json\n ```\n\n2. SDK updates the marketplace (git pull), reads the registry to find installed version `1.0.0`, determines target version `1.2.0`, and resolves the migration chain.\n\n3. SDK returns:\n ```json\n {\n \"plugin\": \"my-plugin\",\n \"fromVersion\": \"1.0.0\",\n \"toVersion\": \"1.2.0\",\n \"marketplace\": \"my-marketplace\",\n \"scope\": \"global\",\n \"migrations\": [\n {\n \"from\": \"1.0.0\",\n \"to\": \"1.1.0\",\n \"file\": \"1.0.0_to_1.1.0.md\",\n \"type\": \"md\",\n \"instructions\": \"# Migration from 1.0.0 to 1.1.0\\n\\n1. Update config...\",\n \"processFile\": null\n },\n {\n \"from\": \"1.1.0\",\n \"to\": \"1.2.0\",\n \"file\": \"1.1.0_to_1.2.0.js\",\n \"type\": \"js\",\n \"instructions\": \"// Process file content...\",\n \"processFile\": \"/home/user/.babysitter/marketplaces/my-marketplace/plugins/my-plugin/migrations/1.1.0_to_1.2.0.js\"\n }\n ]\n }\n ```\n\n4. Agent executes each migration step in order:\n - For the `.md` step: reads and follows the instructions\n - For the `.js` step: runs the babysitter process file\n\n5. Agent updates the registry:\n ```bash\n babysitter plugin:update-registry my-plugin --plugin-version 1.2.0 --marketplace-name my-marketplace --global\n ```\n\n## MigrationDescriptor Type\n\nDefined in `packages/sdk/src/plugins/types.ts`:\n\n```typescript\ninterface MigrationDescriptor {\n /** Source version (semver) */\n from: string;\n /** Target version (semver) */\n to: string;\n /** Filename of the migration file */\n file: string;\n /** Type of migration instructions */\n type: \"md\" | \"js\";\n}\n```\n\n## SDK Functions\n\nThe migration system is implemented in `packages/sdk/src/plugins/migrations.ts` and exports:\n\n| Function | Description |\n|----------|-------------|\n| `parseMigrationFilename(filename)` | Parses a filename into a `MigrationDescriptor` or `undefined` |\n| `listMigrations(migrationsDir)` | Lists all valid migration descriptors in a directory |\n| `buildMigrationGraph(migrations)` | Builds a directed adjacency list from descriptors |\n| `findMigrationPath(migrations, from, to)` | BFS shortest path between two versions |\n| `resolveMigrationChain(packageDir, from, to)` | Full resolution: list, find path, load content |\n",
"documents": []
},
"outgoingEdges": [],
"incomingEdges": [
{
"from": "page:docs-plugins",
"to": "page:docs-plugins-migration-guide",
"kind": "contains_page"
}
]
}