import { v } from 'convex/values'; import { internalMutation } from './_generated/server.js'; // One-shot backfill: preserve existing automatic fast-forward behavior for // GitHub spoons now that refreshes honor autoSyncEnabled. Idempotent. export const backfillAutoSyncDefaults = internalMutation({ args: {}, returns: v.object({ updated: v.number() }), handler: async (ctx) => { const settings = await ctx.db.query('spoonSettings').collect(); let updated = 0; for (const row of settings) { if (row.autoSyncEnabled) continue; const spoon = await ctx.db.get(row.spoonId); if (spoon?.provider !== 'github') continue; await ctx.db.patch(row._id, { autoSyncEnabled: true, updatedAt: Date.now(), }); updated += 1; } return { updated }; }, }); // One-shot migration retiring the legacy `openai_direct` runtime literal: // rewrites any surviving `agentJobs`/`spoonAgentSettings` rows to `opencode`. // `openai_direct` stays in the schema unions as a legacy-read literal; nothing // writes it anymore. Run once post-deploy via // `npx convex run migrations:migrateOpenAiDirectRuntime`. Idempotent. export const migrateOpenAiDirectRuntime = internalMutation({ args: {}, returns: v.object({ patched: v.number() }), handler: async (ctx) => { let patched = 0; for (const job of await ctx.db.query('agentJobs').collect()) { if (job.runtime === 'openai_direct') { await ctx.db.patch(job._id, { runtime: 'opencode', updatedAt: Date.now(), }); patched += 1; } } for (const settings of await ctx.db.query('spoonAgentSettings').collect()) { if (settings.runtime === 'openai_direct') { await ctx.db.patch(settings._id, { runtime: 'opencode', updatedAt: Date.now(), }); patched += 1; } } return { patched }; }, });