(opts: {
name: string;
status: 'success' | 'error' | 'skipped';
exitCode: number;
durationSec: number;
tail: string;
recipe?: string | null;
})
| 33 | /** Build the chat summary for a finished run. PURE. Pulls out a recipe's final status line |
| 34 | * (e.g. `VERIFIED-PR: opened …`) and leads with it, since that's the headline a user wants. */ |
| 35 | export function formatRunSummary(opts: { |
| 36 | name: string; |
| 37 | status: 'success' | 'error' | 'skipped'; |
| 38 | exitCode: number; |
| 39 | durationSec: number; |
| 40 | tail: string; |
| 41 | recipe?: string | null; |
| 42 | }): string { |
| 43 | const icon = opts.status === 'success' ? '✅' : opts.status === 'skipped' ? '⏭️' : '❌'; |
| 44 | const head = `${icon} QodeX schedule: ${opts.name}`; |
| 45 | const meta = opts.status === 'success' |
| 46 | ? `done in ${opts.durationSec}s` |
| 47 | : `${opts.status} (exit ${opts.exitCode}) after ${opts.durationSec}s`; |
| 48 | const lines = [head, meta]; |
| 49 | // Surface a recipe verdict line if present (VERIFIED-PR: …). |
| 50 | const verdict = /^VERIFIED-PR:.*$/im.exec(opts.tail)?.[0]; |
| 51 | if (verdict) lines.push('', verdict.trim()); |
| 52 | else if (opts.tail.trim()) lines.push('', opts.tail.trim()); |
| 53 | return lines.join('\n'); |
| 54 | } |
| 55 | |
| 56 | /** Hard-truncate to a platform's message limit, keeping the head (the verdict lives there). PURE. */ |
| 57 | export function clampForPlatform(text: string, platform: DeliveryTarget['platform']): string { |
no test coverage detected