Files
website/scripts/ai-bots-import.ts

42 lines
1.7 KiB
TypeScript

/**
* Import Grok Bot agent summaries into ai.bot_status (owner-only /trackers/ai/bots tab).
* Idempotent: upserts on name (focus, recent and last_active are overwritten).
* Short neutral summaries only: never raw transcripts, secrets or private details.
*
* bun scripts/ai-bots-import.ts ai-bots.json # upsert
* bun scripts/ai-bots-import.ts --dry-run ai-bots.json # validate only
*
* JSON: an array of
* { "name": "Daisy", "focus": "…", "recent": "…", "last_active": "2026-10-26T00:45:00+01:00" }
* focus (≤300 chars), recent (≤600) and last_active (ISO date or date-time) may be null.
* Uses DB_URL (the app role on prod); see scripts/ai-news-import.ts for how to run it on stan-ovh.
*/
import { readFile } from 'node:fs/promises';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { botsFile, upsertBots } from '../src/lib/server/ai-import';
const args = process.argv.slice(2);
const dryRun = args.includes('--dry-run');
const files = args.filter((a) => !a.startsWith('--'));
if (files.length !== 1) {
console.error('usage: bun scripts/ai-bots-import.ts [--dry-run] <file.json>');
process.exit(2);
}
const parsed = botsFile.safeParse(JSON.parse(await readFile(files[0], 'utf8')));
if (!parsed.success) {
for (const issue of parsed.error.issues.slice(0, 50))
console.error(`${issue.path.join('.')}: ${issue.message}`);
process.exit(1);
}
console.log(`Valid: ${parsed.data.length} bots`);
if (dryRun) process.exit(0);
if (!process.env.DB_URL) throw new Error('DB_URL is required');
const client = postgres(process.env.DB_URL, { max: 1, onnotice: () => {} });
try {
const n = await upsertBots(drizzle({ client }), parsed.data);
console.log(`Upserted ${n} bots`);
} finally {
await client.end();
}