/**
 * Desktop notification when a headless `agents run` finishes (`--notify`).
 *
 * The notifying process is the one that OWNS the run. That is the whole point:
 * the menu bar's quick dispatch used to post its completion notice from the
 * dispatching MenubarHelper's process-termination callback, so a helper that
 * restarted (an upgrade, a crash) took the callback with it — the run kept
 * going, reparented to launchd, and no notification could ever fire. Posting
 * from the run process instead means the notice survives anything that happens
 * to the menu bar, and `notifyDesktop` spawns a FRESH one-shot notifier, so it
 * does not need a helper to have been running at dispatch time either.
 *
 * Armed once via `process.on('exit')` so it covers every way the run command
 * terminates — local spawn, `--device` dispatch, `--lease` box, the error path —
 * rather than being sprinkled over ~50 `process.exit` call sites where the next
 * new exit path would silently miss it.
 */
import * as path from 'path';
import { notifyDesktop } from './menubar/notify-desktop.js';
/** Notification body cap: a banner truncates anyway, and a wall of text is noise. */
const BODY_MAX = 120;
function shorten(text, max = BODY_MAX) {
    const flat = text.replace(/\s+/g, ' ').trim();
    return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
}
/**
 * The finish notification for one run. Pure — the exit handler and the tests
 * both build through here, so what ships is what is asserted.
 */
export function buildRunFinishNotification(ctx, exitCode) {
    const label = ctx.name?.trim() || ctx.agent;
    const project = ctx.cwd ? path.basename(ctx.cwd) : undefined;
    const where = [project, ctx.host].filter(Boolean).join(' · ');
    const n = {
        title: exitCode === 0 ? `${label} finished` : `${label} failed`,
        body: shorten(ctx.prompt?.trim() || `${ctx.agent} run`),
        // The harness that ran becomes the banner's right-hand avatar, so a finished
        // run is identifiable at a glance even when `--name` renamed the title.
        agent: ctx.agent,
    };
    if (where)
        n.subtitle = where;
    if (ctx.url)
        n.action = `url:${ctx.url}`;
    return n;
}
/**
 * Post the finish notification when this process exits. Best-effort by
 * construction: `notifyDesktop` swallows its own failures, and a run killed
 * outright (SIGKILL) never reaches an exit handler — that is the documented
 * limit, not a case to paper over.
 */
export function armRunFinishNotification(ctx) {
    process.on('exit', (code) => {
        notifyDesktop(buildRunFinishNotification(ctx, code));
    });
}
