Execute major Obsidian plugin rewrites and migration strategies. Use when migrating to or from Obsidian, performing major plugin rewrites, or re-platforming existing note systems to Obsidian. Trigger with phrases like "migrate to obsidian", "obsidian migration", "convert notes to obsidian", "obsidian replatform".
Comprehensive guide for migrating to Obsidian from other note-taking apps, or performing major plugin architecture rewrites.
| Type | Complexity | Duration | Risk |
|---|---|---|---|
| Single app import | Low | Hours | Low |
| Multi-source merge | Medium | Days | Medium |
| Plugin major rewrite | Medium | Weeks | Medium |
| Enterprise migration | High | Months | High |
// scripts/migration-assessment.ts
interface MigrationAssessment {
sourceSystem: string;
noteCount: number;
attachmentCount: number;
totalSize: number;
linkCount: number;
tagCount: number;
uniqueTags: string[];
folderStructure: string[];
issues: MigrationIssue[];
}
interface MigrationIssue {
type: 'encoding' | 'format' | 'link' | 'attachment' | 'metadata';
severity: 'warning' | 'error';
description: string;
affectedFiles: string[];
}
async function assessMigration(sourcePath: string): Promise<MigrationAssessment> {
const assessment: MigrationAssessment = {
sourceSystem: 'unknown',
noteCount: 0,
attachmentCount: 0,
totalSize: 0,
linkCount: 0,
tagCount: 0,
uniqueTags: [],
folderStructure: [],
issues: [],
};
// Scan source directory
// Count files, measure sizes
// Identify formats and potential issues
return assessment;
}
// Generate report
function generateAssessmentReport(assessment: MigrationAssessment): string {
return `
# Migration Assessment Report
## Source System: ${assessment.sourceSystem}
### Content Summary
- Notes: ${assessment.noteCount}
- Attachments: ${assessment.attachmentCount}
- Total Size: ${(assessment.totalSize / 1024 / 1024).toFixed(2)} MB
- Links: ${assessment.linkCount}
- Tags: ${assessment.tagCount} (${assessment.uniqueTags.length} unique)
### Folder Structure
${assessment.folderStructure.map(f => `- ${f}`).join('\n')}
### Issues Found
${assessment.issues.map(i => `- [${i.severity.toUpperCase()}] ${i.type}: ${i.description}`).join('\n')}
### Recommendations
${assessment.issues.length === 0 ? '- No issues found, proceed with migration' : '- Address issues before migration'}
`;
}
// scripts/converters/evernote.ts
import * as fs from 'fs';
import * as path from 'path';
import { parseStringPromise } from 'xml2js';
interface EvernoteNote {
title: string;
content: string;
created: string;
updated: string;
tags: string[];
attachments: EvernoteAttachment[];
}
interface EvernoteAttachment {
filename: string;
mime: string;
data: string; // base64
}
export async function convertEvernoteExport(
enexPath: string,
outputPath: string
): Promise<{ notes: number; attachments: number }> {
const content = fs.readFileSync(enexPath, 'utf-8');
const parsed = await parseStringPromise(content);
const notes = parsed['en-export']?.note || [];
let noteCount = 0;
let attachmentCount = 0;
for (const note of notes) {
const converted = convertEvernoteNote(note);
const fileName = sanitizeFileName(converted.title) + '.md';
const filePath = path.join(outputPath, fileName);
// Convert HTML content to Markdown
const markdown = convertHtmlToMarkdown(converted.content);
// Add frontmatter
const frontmatter = `---