Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
wshobson avatar

Database Migration

  • 14.5k installs
  • 38.3k repo stars
  • Updated July 22, 2026
  • wshobson/agents

wshobson/agents is a multi-harness plugin marketplace that ships 92 production-ready agent plugins, 199 domain-expert agents, 162 skills, and 106 commands compiled to five AI coding harnesses (Claude Code, Codex, Cursor,

About

A production-grade agentic plugin marketplace with 92 composable plugins, 199 domain-expert agents, and 162 skills that compile to five AI coding harnesses (Claude Code, Codex, Cursor, OpenCode, Gemini, Copilot). Each plugin isolates its own agents, commands, and skills - install only what you need. Includes orchestrators for multi-agent coordination (full-stack builds, security, ML, incident response) and tiered model selection (Fable 5 for long-horizon work down to Haiku for fast ops).

  • 92 production-ready plugins spanning architecture, languages, infra, security, data, ML, docs, and business
  • Single Markdown source compiles to five harnesses: Claude Code, Codex, Cursor, OpenCode, Gemini, Copilot
  • 199 domain-expert agents + 162 skills + 106 slash commands for autonomous workflow orchestration

Database Migration by the numbers

  • 14,536 all-time installs (skills.sh)
  • +240 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #60 of 16,659 AI & Agent Building skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

database-migration capabilities & compatibility

Capabilities
multi agent orchestration · plugin composition · harness abstraction · tiered model selection
Platforms
macOS · Linux · Windows
IDEs
vscode · cursor ide · jetbrains · neovim
Runs
Runs locally
Pricing
Free
npx skills add https://github.com/wshobson/agents --skill database-migration

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs14.5k
repo stars38.3k
Security audit3 / 3 scanners passed
Last updatedJuly 22, 2026
Repositorywshobson/agents

What it does

Build production agentic workflows with composable plugins across architecture, security, data, and DevOps domains - one source compiles idiomatic code for five harnesses.

Who is it for?

Teams building autonomous agentic systems with multi-language, multi-domain coverage; single Markdown source requirement across five harnesses

Skip if: Greenfield prototypes with disposable databases where destructive migrations are acceptable.

When should I use this skill?

Need composable agent plugins for full-stack builds, security reviews, ML workflows, or incident response

What you get

Install a plugin, get idiomatic agents/skills/commands for all five harnesses; multi-agent orchestrators coordinate complex workflows

  • Phased migration module files
  • Backfill SQL scripts
  • Rollout phase checklist

By the numbers

  • 92 production-ready plugins with 88 local + 4 external via git-subdir
  • 199 domain-expert agents spanning architecture, languages, infra, security, data, ML, docs, business
  • 5 harnesses supported (Claude Code, Codex, Cursor, OpenCode, Gemini, Copilot)

Files

SKILL.mdMarkdownGitHub ↗

Database Migration

Master database schema and data migrations across ORMs (Sequelize, TypeORM, Prisma), including rollback strategies and zero-downtime deployments.

When to Use This Skill

  • Migrating between different ORMs
  • Performing schema transformations
  • Moving data between databases
  • Implementing rollback procedures
  • Zero-downtime deployments
  • Database version upgrades
  • Data model refactoring

ORM Migrations

Sequelize Migrations

// migrations/20231201-create-users.js
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable("users", {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true,
      },
      email: {
        type: Sequelize.STRING,
        unique: true,
        allowNull: false,
      },
      createdAt: Sequelize.DATE,
      updatedAt: Sequelize.DATE,
    });
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable("users");
  },
};

// Run: npx sequelize-cli db:migrate
// Rollback: npx sequelize-cli db:migrate:undo

TypeORM Migrations

// migrations/1701234567-CreateUsers.ts
import { MigrationInterface, QueryRunner, Table } from "typeorm";

export class CreateUsers1701234567 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.createTable(
      new Table({
        name: "users",
        columns: [
          {
            name: "id",
            type: "int",
            isPrimary: true,
            isGenerated: true,
            generationStrategy: "increment",
          },
          {
            name: "email",
            type: "varchar",
            isUnique: true,
          },
          {
            name: "created_at",
            type: "timestamp",
            default: "CURRENT_TIMESTAMP",
          },
        ],
      }),
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.dropTable("users");
  }
}

// Run: npm run typeorm migration:run
// Rollback: npm run typeorm migration:revert

Prisma Migrations

// schema.prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  createdAt DateTime @default(now())
}

// Generate migration: npx prisma migrate dev --name create_users
// Apply: npx prisma migrate deploy

Schema Transformations

Adding Columns with Defaults

// Safe migration: add column with default
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.addColumn("users", "status", {
      type: Sequelize.STRING,
      defaultValue: "active",
      allowNull: false,
    });
  },

  down: async (queryInterface) => {
    await queryInterface.removeColumn("users", "status");
  },
};

Renaming Columns (Zero Downtime)

// Step 1: Add new column
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.addColumn("users", "full_name", {
      type: Sequelize.STRING,
    });

    // Copy data from old column
    await queryInterface.sequelize.query("UPDATE users SET full_name = name");
  },

  down: async (queryInterface) => {
    await queryInterface.removeColumn("users", "full_name");
  },
};

// Step 2: Update application to use new column

// Step 3: Remove old column
module.exports = {
  up: async (queryInterface) => {
    await queryInterface.removeColumn("users", "name");
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.addColumn("users", "name", {
      type: Sequelize.STRING,
    });
  },
};

Changing Column Types

module.exports = {
  up: async (queryInterface, Sequelize) => {
    // For large tables, use multi-step approach

    // 1. Add new column
    await queryInterface.addColumn("users", "age_new", {
      type: Sequelize.INTEGER,
    });

    // 2. Copy and transform data
    await queryInterface.sequelize.query(`
      UPDATE users
      SET age_new = CAST(age AS INTEGER)
      WHERE age IS NOT NULL
    `);

    // 3. Drop old column
    await queryInterface.removeColumn("users", "age");

    // 4. Rename new column
    await queryInterface.renameColumn("users", "age_new", "age");
  },

  down: async (queryInterface, Sequelize) => {
    await queryInterface.changeColumn("users", "age", {
      type: Sequelize.STRING,
    });
  },
};

Data Transformations

Complex Data Migration

module.exports = {
  up: async (queryInterface, Sequelize) => {
    // Get all records
    const [users] = await queryInterface.sequelize.query(
      "SELECT id, address_string FROM users",
    );

    // Transform each record
    for (const user of users) {
      const addressParts = user.address_string.split(",");

      await queryInterface.sequelize.query(
        `UPDATE users
         SET street = :street,
             city = :city,
             state = :state
         WHERE id = :id`,
        {
          replacements: {
            id: user.id,
            street: addressParts[0]?.trim(),
            city: addressParts[1]?.trim(),
            state: addressParts[2]?.trim(),
          },
        },
      );
    }

    // Drop old column
    await queryInterface.removeColumn("users", "address_string");
  },

  down: async (queryInterface, Sequelize) => {
    // Reconstruct original column
    await queryInterface.addColumn("users", "address_string", {
      type: Sequelize.STRING,
    });

    await queryInterface.sequelize.query(`
      UPDATE users
      SET address_string = CONCAT(street, ', ', city, ', ', state)
    `);

    await queryInterface.removeColumn("users", "street");
    await queryInterface.removeColumn("users", "city");
    await queryInterface.removeColumn("users", "state");
  },
};

Rollback Strategies

Transaction-Based Migrations

module.exports = {
  up: async (queryInterface, Sequelize) => {
    const transaction = await queryInterface.sequelize.transaction();

    try {
      await queryInterface.addColumn(
        "users",
        "verified",
        { type: Sequelize.BOOLEAN, defaultValue: false },
        { transaction },
      );

      await queryInterface.sequelize.query(
        "UPDATE users SET verified = true WHERE email_verified_at IS NOT NULL",
        { transaction },
      );

      await transaction.commit();
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  },

  down: async (queryInterface) => {
    await queryInterface.removeColumn("users", "verified");
  },
};

Checkpoint-Based Rollback

module.exports = {
  up: async (queryInterface, Sequelize) => {
    // Create backup table
    await queryInterface.sequelize.query(
      "CREATE TABLE users_backup AS SELECT * FROM users",
    );

    try {
      // Perform migration
      await queryInterface.addColumn("users", "new_field", {
        type: Sequelize.STRING,
      });

      // Verify migration
      const [result] = await queryInterface.sequelize.query(
        "SELECT COUNT(*) as count FROM users WHERE new_field IS NULL",
      );

      if (result[0].count > 0) {
        throw new Error("Migration verification failed");
      }

      // Drop backup
      await queryInterface.dropTable("users_backup");
    } catch (error) {
      // Restore from backup
      await queryInterface.sequelize.query("DROP TABLE users");
      await queryInterface.sequelize.query(
        "CREATE TABLE users AS SELECT * FROM users_backup",
      );
      await queryInterface.dropTable("users_backup");
      throw error;
    }
  },
};

Additional patterns and templates

More detailed templates and worked examples live in references/details.md. Read that file for the full pattern library.

Related skills

How it compares

Use database-migration when you need phased, production-safe patterns rather than single-step dev-only ALTER examples.

FAQ

Do I install wshobson/agents into all five harnesses, or once?

Install once into your harness of choice; it ships idiomatic registries/artifacts for that harness (e.g., marketplace.json for Claude Code, .codex-plugin/ for Codex).

Can I use a single plugin across harnesses?

Yes - the Markdown plugin is source-of-truth; the make build process emits harness-native code. Codex and Cursor auto-read the committed registries; Gemini/OpenCode require clone + make generate.

Is Database Migration safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

AI & Agent Buildingagentsautomation

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.