#!/usr/bin/env node /** * sync CLI — Sync branch with remote and optionally rebase on base branch */ import { parseArgs } from 'node:util'; import { validate } from './validate.js'; import { execute } from './execute.js'; import { SyncResultSchema } from './types.js'; async function main() { try { const args = parseArgs({ options: { spec: { type: 'string' }, workdir: { type: 'string' }, json: { type: 'boolean', default: false }, }, allowPositionals: false, }); if (!args.values.spec) { console.error('Error: --spec is required'); process.exit(2); } let specObj: unknown; try { specObj = JSON.parse(args.values.spec); } catch { console.error('Error: --spec must be valid JSON'); process.exit(2); } const validation = validate(specObj); if (!validation.valid) { if (args.values.json) { console.log(JSON.stringify({ success: false, error: validation.blockers.join('; '), }, null, 2)); } else { console.error('Validation failed:'); validation.blockers.forEach(b => console.error(` - ${b}`)); } process.exit(2); } const result = await execute(validation.data!, args.values.workdir); const validated = SyncResultSchema.parse(result); if (args.values.json) { console.log(JSON.stringify(validated, null, 2)); } else { if (validated.success) { console.log(`✓ Sync completed for ${validated.branch}`); if (validated.pushed) console.log(` Pushed to origin`); if (validated.pulled) console.log(` Pulled from origin`); if (validated.rebased) console.log(` Rebased on ${validated.baseBranch}`); } else { console.error(`✗ ${validated.error}`); if (validated.conflictFiles && validated.conflictFiles.length > 0) { console.error(` Conflicts in: ${validated.conflictFiles.join(', ')}`); } } (validated.warnings ?? []).forEach(w => console.warn(`[WARNING] ${w}`)); } process.exit(validated.success ? 0 : 1); } catch (err: unknown) { console.error('Fatal error:', (err as Error).message); process.exit(2); } } main();