#!/usr/bin/env node /** * cli:efcore-rebase-snapshot — Resync ModelSnapshot after a rebase. * * Called after `git rebase` onto a base branch left ModelSnapshot.cs in a * conflicted state. Resets the snapshot to the base, deletes branch-only * migrations, and regenerates one consolidated migration. * * Usage: * npx --prefer-offline tsx skills/efcore/cli/rebase-snapshot/index.ts --spec '{ * "cwd": "...", * "contextName": "CoreDbContext", * "description": "FeatureXYZOnRebased" * }' */ import { parseArgs } from 'node:util'; import { existsSync, readFileSync } from 'node:fs'; import { validate } from './validate.js'; import { execute } from './execute.js'; async function main(): Promise { const { values } = parseArgs({ options: { spec: { type: 'string' }, help: { type: 'boolean', short: 'h' }, }, }); if (values.help || !values.spec) { console.log(`Usage: npx --prefer-offline tsx skills/efcore/cli/rebase-snapshot/index.ts --spec '{"cwd":"...","contextName":"CoreDbContext","description":"FooOnRebased"}'`); process.exit(values.help ? 0 : 1); } let raw: unknown; try { raw = existsSync(values.spec!) ? JSON.parse(readFileSync(values.spec!, 'utf-8')) : JSON.parse(values.spec!); } catch (err) { console.log(JSON.stringify({ success: false, errors: [`Invalid JSON: ${(err as Error).message}`], warnings: [] }, null, 2)); process.exit(1); } const validation = validate(raw); if (!validation.valid || !validation.data) { console.log(JSON.stringify({ success: false, errors: validation.blockers }, null, 2)); process.exit(1); } const result = await execute(validation.data); console.log(JSON.stringify(result, null, 2)); process.exit(result.success ? 0 : 1); } void main();