/**
 * Routine lifecycle desktop notifications (RUSH-2030).
 *
 * The daemon fires a branded notification when a scheduled routine starts and
 * when it finishes (success or failure), routed through the MenubarHelper
 * companion (notify-desktop.ts) so it carries the agents-cli mark.
 *
 * Anti-spam threshold (Acceptance Criteria #4 — "define a sensible threshold so
 * users are not spammed"):
 *   - Agent / workflow routines: notify on BOTH start and finish. These are the
 *     runs whose output a user actually wants surfaced.
 *   - Command routines (deterministic housekeeping — version checks, `git pull`,
 *     notify shims that can fire every minute): notify only on FAILURE. A green
 *     housekeeping run is noise; a broken one is worth a ping. No start ping.
 *   - "Notable output" is folded into the single finish notification rather than
 *     sent as a third message: on failure the error reason, on success the first
 *     line of the run's report (the user-facing result) when the routine produced
 *     one. One start + one finish per run — never a stream.
 *
 * The pure builders (`routineStartNotification` / `routineFinishNotification`)
 * return `null` when the threshold says "don't notify", and are unit-tested; the
 * `notifyRoutine*` wrappers do the filesystem read + dispatch for the daemon.
 */
import type { JobConfig, RunMeta } from './scheduling/routines.js';
import { type DesktopNotification } from './menubar/notify-desktop.js';
type RoutineKind = 'agent' | 'workflow' | 'command';
/** Which flavor of routine a config/meta describes — drives the notify threshold. */
export declare function routineKind(r: Pick<JobConfig, 'agent' | 'workflow' | 'command'>): RoutineKind;
/**
 * The harness a routine runs on, for the notification's right-hand avatar, or
 * undefined when none owns it. A command routine is deterministic housekeeping
 * with no agent, so it gets no avatar. An agent routine names its own harness.
 * A workflow routine has no `agent` field (the schema omits it — routines.ts
 * `JobConfig.agent` and the validation that rejects setting both), and it runs
 * via `agents run <workflow>`, which delegates to claude under the hood — so its
 * avatar is the Claude mark, matching `effectiveAgent` on the finish path
 * (runner.ts). Start and finish banners therefore show the same avatar.
 */
export declare function routineAgent(r: Pick<JobConfig, 'agent' | 'workflow' | 'command'>): string | undefined;
/** "1m 20s" / "45s" / "2h 3m" from a millisecond duration, or null when unknown. */
export declare function formatDuration(ms: number | undefined): string | null;
/**
 * First non-empty line of a run report, trimmed to a notification-sized snippet.
 * This is the "notable output" surfaced on a successful finish — the routine's
 * own user-facing result. Returns null for an empty/whitespace report so the
 * caller falls back to a plain "Completed" body.
 */
export declare function notableSnippet(report: string | null | undefined, maxLen?: number): string | null;
/**
 * Notification for a routine START, or null when the threshold suppresses it
 * (command-mode housekeeping). Clicking opens the runs folder
 * (~/.agents/.history/runs).
 */
export declare function routineStartNotification(config: Pick<JobConfig, 'name' | 'agent' | 'workflow' | 'command'>): DesktopNotification | null;
/**
 * Notification for a routine that failed to even START — `executeJobDetached`
 * threw before the child was spawned, so no run record and no finish will ever
 * exist. The daemon fires the START notification unconditionally, so this closes
 * the "exactly one start + one finish" invariant: the orphaned start gets its
 * matching failure banner (RUSH-2030). Unlike a green finish this is never
 * suppressed — a broken start is worth a ping for every routine kind, including
 * command housekeeping. Clicking opens the runs folder (~/.agents/.history/runs)
 * since there is no run report to open.
 */
export declare function routineStartFailedNotification(config: Pick<JobConfig, 'name' | 'agent' | 'workflow' | 'command'>, error: string): DesktopNotification;
/**
 * Notification for a routine FINISH, or null when the threshold suppresses it
 * (a successful command-mode housekeeping run). Success carries the report's
 * first line when present (the notable output); failure carries the reason.
 * Clicking opens the run report/log when one is available, else the runs folder
 * (~/.agents/.history/runs).
 */
export declare function routineFinishNotification(meta: Pick<RunMeta, 'jobName' | 'status' | 'exitCode' | 'errorMessage' | 'duration' | 'agent' | 'workflow' | 'command'>, opts?: {
    report?: string | null;
    artifactPath?: string | null;
}): DesktopNotification | null;
/** Daemon glue: fire the START notification for a triggered routine. Best-effort. */
export declare function notifyRoutineStart(config: JobConfig): void;
/**
 * Daemon glue: fire the "failed to start" notification when a routine trigger
 * threw before spawning a child. Pairs with the unconditional START ping so a
 * pre-spawn failure never leaves an orphaned "Routine started". Best-effort.
 */
export declare function notifyRoutineStartFailed(config: JobConfig, error: string): void;
/** Daemon glue: fire the FINISH notification for a completed run. Best-effort. */
export declare function notifyRoutineFinish(meta: RunMeta): void;
export {};
