/** Read-only inventory. Does not load keys, modify configuration or call any model. */ import { readFile, writeFile, mkdir, stat } from 'node:fs/promises' import path from 'node:path' import { requestAiModelCapabilityCatalog } from '../lib/ai-model-http' import { auditAiModelContracts, renderAiModelContractAudit } from '../lib/ai-model-contract-audit' async function main() { const args = process.argv.slice(2) const flag = (name: string) => { const index = args.indexOf(name); return index < 0 ? undefined : args[index + 1] } const output = path.resolve(flag('--output') || 'output/ai-model-contract-audit') const catalogFile = flag('--catalog'), snapshotFile = flag('--admin-state') const catalog = catalogFile ? JSON.parse(await readFile(catalogFile, 'utf8')) : await (async () => { const response = await requestAiModelCapabilityCatalog('https://api.vip98k.com/v1'); if (!response.ok) throw new Error(`公开目录 HTTP ${response.status}`); return response.json() })() const snapshot = snapshotFile ? JSON.parse(await readFile(snapshotFile, 'utf8')) : undefined const report = auditAiModelContracts(catalog, snapshot) const at = new Date().toISOString() const catalogAt = catalogFile ? (await stat(catalogFile)).mtime.toISOString() : at await mkdir(output, { recursive: true }) await writeFile(path.join(output, 'catalog-source.json'), JSON.stringify(catalog, null, 2)) await writeFile(path.join(output, 'model-contracts.json'), JSON.stringify({ inspectedAt: at, catalogCapturedAt: catalogAt, adminSnapshotAt: snapshot?.at || null, ...report }, null, 2)) const displayTime = (iso: string) => new Intl.DateTimeFormat('zh-CN', { timeZone: 'Asia/Singapore', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h23' }).format(new Date(iso)) + '(UTC+8)' const markdown = renderAiModelContractAudit(report, `${displayTime(at)};目录抓取于 ${displayTime(catalogAt)}${snapshot?.at ? `;平台状态读取于 ${displayTime(snapshot.at)}` : ''}`) await writeFile(path.join(output, 'model-contracts.md'), markdown) if (flag('--markdown')) await writeFile(flag('--markdown')!, markdown) console.log(JSON.stringify({ models: report.modelCount, nativeOnly: report.nativeOnly.length, byKind: report.models.reduce>((counts, model) => (counts[model.kind] = (counts[model.kind] || 0) + 1, counts), {}), output, paidCalls: 0, writesToProduction: 0 })) } main().catch(error => { console.error(error instanceof Error ? error.message : '目录核查失败'); process.exitCode = 1 })