Claude-skill-registry gamma-migration-deep-dive
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/gamma-migration-deep-dive" ~/.claude/skills/majiayu000-claude-skill-registry-gamma-migration-deep-dive && rm -rf "$T"
manifest:
skills/data/gamma-migration-deep-dive/SKILL.mdsource content
Gamma Migration Deep Dive
Overview
Comprehensive guide for migrating presentations and workflows from other platforms to Gamma.
Prerequisites
- Gamma API access
- Source platform export capabilities
- Node.js 18+ for migration scripts
- Sufficient Gamma storage quota
Supported Migration Paths
| Source | Format | Fidelity | Notes |
|---|---|---|---|
| PowerPoint | .pptx | High | Native import |
| Google Slides | .pptx export | High | Export first |
| Canva | .pdf/.pptx | Medium | Limited animations |
| Keynote | .pptx export | High | Export first |
| Medium | Static only | ||
| Markdown | .md | High | Structure preserved |
Instructions
Step 1: Inventory Source Presentations
// scripts/migration-inventory.ts interface SourcePresentation { id: string; title: string; source: 'powerpoint' | 'google' | 'canva' | 'other'; path: string; size: number; lastModified: Date; slideCount?: number; } async function inventoryPresentations(sourceDir: string): Promise<SourcePresentation[]> { const files = await glob('**/*.{pptx,pdf,key}', { cwd: sourceDir }); const inventory: SourcePresentation[] = []; for (const file of files) { const stats = await fs.stat(path.join(sourceDir, file)); const ext = path.extname(file).toLowerCase(); inventory.push({ id: crypto.randomUUID(), title: path.basename(file, ext), source: detectSource(file), path: file, size: stats.size, lastModified: stats.mtime, }); } // Save inventory await fs.writeFile( 'migration-inventory.json', JSON.stringify(inventory, null, 2) ); console.log(`Found ${inventory.length} presentations to migrate`); return inventory; }
Step 2: Migration Engine
// lib/migration-engine.ts import { GammaClient } from '@gamma/sdk'; interface MigrationResult { sourceId: string; gammaId?: string; success: boolean; error?: string; duration: number; } class MigrationEngine { private gamma: GammaClient; private results: MigrationResult[] = []; constructor() { this.gamma = new GammaClient({ apiKey: process.env.GAMMA_API_KEY, timeout: 120000, // Long timeout for imports }); } async migrateFile(source: SourcePresentation): Promise<MigrationResult> { const start = Date.now(); try { // Read file const fileBuffer = await fs.readFile(source.path); // Upload to Gamma const presentation = await this.gamma.presentations.import({ file: fileBuffer, filename: path.basename(source.path), title: source.title, preserveFormatting: true, convertToGammaStyle: false, }); const result: MigrationResult = { sourceId: source.id, gammaId: presentation.id, success: true, duration: Date.now() - start, }; this.results.push(result); return result; } catch (error) { const result: MigrationResult = { sourceId: source.id, success: false, error: error.message, duration: Date.now() - start, }; this.results.push(result); return result; } } async migrateAll( sources: SourcePresentation[], options = { concurrency: 3, retries: 2 } ) { const queue = new PQueue({ concurrency: options.concurrency }); const tasks = sources.map(source => queue.add(async () => { for (let attempt = 0; attempt < options.retries; attempt++) { const result = await this.migrateFile(source); if (result.success) return result; console.log(`Retry ${attempt + 1} for ${source.title}`); await delay(5000 * (attempt + 1)); } }) ); await Promise.all(tasks); return this.getReport(); } getReport() { const successful = this.results.filter(r => r.success); const failed = this.results.filter(r => !r.success); return { total: this.results.length, successful: successful.length, failed: failed.length, successRate: (successful.length / this.results.length * 100).toFixed(1), averageDuration: successful.reduce((a, b) => a + b.duration, 0) / successful.length, failures: failed.map(f => ({ id: f.sourceId, error: f.error })), }; } }
Step 3: Platform-Specific Handlers
Google Slides Migration
// lib/google-slides-migrator.ts import { google } from 'googleapis'; async function migrateFromGoogleSlides( driveFileId: string, gamma: GammaClient ) { const drive = google.drive('v3'); // Export as PowerPoint const exportResponse = await drive.files.export({ fileId: driveFileId, mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', }, { responseType: 'arraybuffer' }); // Import to Gamma const presentation = await gamma.presentations.import({ file: Buffer.from(exportResponse.data as ArrayBuffer), filename: 'exported.pptx', source: 'google_slides', }); return presentation; }
PowerPoint Migration with Metadata
// lib/powerpoint-migrator.ts import JSZip from 'jszip'; import { parseStringPromise } from 'xml2js'; async function extractPowerPointMetadata(filePath: string) { const fileBuffer = await fs.readFile(filePath); const zip = await JSZip.loadAsync(fileBuffer); // Extract core properties const coreXml = await zip.file('docProps/core.xml')?.async('string'); if (!coreXml) return {}; const core = await parseStringPromise(coreXml); return { title: core['cp:coreProperties']?.['dc:title']?.[0], creator: core['cp:coreProperties']?.['dc:creator']?.[0], created: core['cp:coreProperties']?.['dcterms:created']?.[0], modified: core['cp:coreProperties']?.['dcterms:modified']?.[0], }; } async function migrateWithMetadata(source: SourcePresentation, gamma: GammaClient) { const metadata = await extractPowerPointMetadata(source.path); const fileBuffer = await fs.readFile(source.path); const presentation = await gamma.presentations.import({ file: fileBuffer, filename: path.basename(source.path), title: metadata.title || source.title, metadata: { originalCreator: metadata.creator, originalCreated: metadata.created, migratedAt: new Date().toISOString(), }, }); return presentation; }
Step 4: Post-Migration Validation
// scripts/validate-migration.ts async function validateMigration(sourceId: string, gammaId: string) { const gamma = new GammaClient({ apiKey: process.env.GAMMA_API_KEY }); const presentation = await gamma.presentations.get(gammaId, { include: ['slides', 'assets'], }); const validations = { exists: !!presentation, hasSlides: presentation.slides?.length > 0, allAssetsLoaded: presentation.assets?.every(a => a.status === 'loaded'), canExport: false, }; // Test export capability try { const exportTest = await gamma.exports.create(gammaId, { format: 'pdf', dryRun: true, }); validations.canExport = exportTest.valid; } catch { validations.canExport = false; } return { sourceId, gammaId, validations, passed: Object.values(validations).every(v => v), }; }
Step 5: Rollback Plan
// lib/rollback.ts interface MigrationSnapshot { timestamp: Date; mappings: Array<{ sourceId: string; gammaId: string }>; } async function createSnapshot(results: MigrationResult[]): Promise<string> { const snapshot: MigrationSnapshot = { timestamp: new Date(), mappings: results .filter(r => r.success && r.gammaId) .map(r => ({ sourceId: r.sourceId, gammaId: r.gammaId! })), }; const snapshotPath = `migration-snapshot-${Date.now()}.json`; await fs.writeFile(snapshotPath, JSON.stringify(snapshot, null, 2)); return snapshotPath; } async function rollbackMigration(snapshotPath: string) { const snapshot: MigrationSnapshot = JSON.parse( await fs.readFile(snapshotPath, 'utf-8') ); const gamma = new GammaClient({ apiKey: process.env.GAMMA_API_KEY }); console.log(`Rolling back ${snapshot.mappings.length} presentations...`); for (const mapping of snapshot.mappings) { try { await gamma.presentations.delete(mapping.gammaId); console.log(`Deleted: ${mapping.gammaId}`); } catch (error) { console.error(`Failed to delete ${mapping.gammaId}: ${error.message}`); } } console.log('Rollback complete'); }
Migration Checklist
Pre-Migration
- Inventory all source presentations
- Verify Gamma storage quota
- Test import with sample files
- Set up monitoring for migration
- Create rollback plan
- Notify stakeholders
During Migration
- Run migration in batches
- Monitor error rates
- Validate each batch
- Take snapshots for rollback
Post-Migration
- Validate all presentations
- Update links and references
- Train users on Gamma
- Archive source files
- Document lessons learned
Resources
Summary
This skill pack provides comprehensive coverage for Gamma integration from initial setup through enterprise deployment and migration. Start with
gamma-install-auth and progress through the skills as needed for your integration complexity.