/**
 * Forward an owner notification to a capable fleet peer over SSH (PHNX-3303).
 *
 * The owner's delivery provider for the rush-backed channels (imessage /
 * telegram / slack / discord via the `rush` CLI) is macOS-only and
 * keychain-bound, so a headless Linux worker structurally CANNOT ring the
 * owner's phone: `agents feed post --level important` records the post but the
 * owner sink fails with `rush CLI not found on PATH`, and the important post
 * reaches nobody. `probeOwnerSink` (owner-sink.ts) already reports this as the
 * `owner-sink-unreachable` doctor finding; this module is the runtime answer to
 * it — instead of stranding the failure, hand the delivery to a reachable macOS
 * peer that DOES have the provider.
 *
 * This mirrors the SSH reroute `agents message` (decideHostTaskRoute →
 * runOnPeer) and the sessions fan-out already use for work that lives on another
 * box: pick a reachable peer from the device registry and run the same `agents`
 * verb there. Here the verb is `agents send --channel <channel> --to <target>`.
 * Keeping the destination explicit and delivering through the peer's local rush
 * destination explicit prevents a multi-channel owner policy from expanding a
 * second time on the peer and duplicating already-successful channels.
 *
 * Best-effort seam: it never throws and never blocks the post. When no capable
 * peer is reachable it resolves `undefined` and the caller keeps its original
 * clean local error, exactly as before.
 */
import type { Meta } from '../types.js';
import type { SendResult } from './registry.js';
import type { DeviceProfile } from '../devices/registry.js';
/**
 * Env marker set on the forwarded `agents send` so a box that received a
 * forwarded owner notify never forwards it onward. `agents send` does not route
 * through this module today, so this is defense-in-depth against a future
 * consumer wiring forwarding into the send path and creating a fan-out loop.
 */
export declare const OWNER_FORWARD_GUARD_ENV = "AGENTS_OWNER_NO_FORWARD";
/** Why forwarding did not run, so a caller/test can assert the decision. */
export type OwnerForwardSkip = 'guarded' | 'not-rush-backed' | 'no-capable-peer';
export interface OwnerForwardPlan {
    /** Ordered machine ids to try — capable (macOS), reachable, self excluded. */
    candidates: string[];
    /** Set when forwarding does not apply; the caller keeps its local error. */
    skip?: OwnerForwardSkip;
}
/**
 * True when the resolved owner transport is the macOS-only rush family — the
 * one case a Linux/headless box structurally cannot deliver and a peer can.
 * `openclaw-telegram` and the local `desktop`/`mailbox` providers are NOT
 * rush-backed, so a failure there is not a wrong-OS problem and is left as-is.
 * Mirrors the same `RUSH_CHANNELS.includes(transport)` gate in owner-sink.ts.
 */
export declare function isRushBackedTransport(channel: string, meta: Meta): boolean;
/**
 * Decide which peers can deliver the owner notification, in try order. Pure —
 * no I/O — so the channel gate, the recursion guard, self-exclusion, and the
 * capability/ordering rules are unit-testable without a live tailnet.
 *
 * Only macOS peers are candidates: the rush owner transport is macOS-only, so a
 * Linux/Windows peer could not deliver it either. The configured
 * `interactive.host` (the box the operator sits at, where rush is signed in) is
 * tried first when it is among the candidates.
 */
export declare function planOwnerForward(channel: string, meta: Meta, devices: DeviceProfile[], self: string, opts?: {
    guarded?: boolean;
}): OwnerForwardPlan;
/**
 * Deliver `text` to the owner FROM one peer over SSH. Runs the peer's own
 * `agents send --channel <channel> --to <target> --text <text> --json`, which
 * delivers the already-resolved destination through its local provider.
 * Resolves the parsed `SendResult`, or `undefined` when the peer is
 * unreachable / not a dialable device / answered with unparseable output —
 * every one of which means "try the next peer".
 */
export interface PeerOwnerEnvelope {
    thread?: string;
    from?: string;
}
export type PeerOwnerSender = (machine: string, text: string, channel: string, target: string, envelope?: PeerOwnerEnvelope) => Promise<SendResult | undefined>;
/**
 * Try each capable peer in order and return the first successful delivery. A
 * peer that is unreachable or reports its own delivery failure is skipped and
 * the next is tried; the first `ok:true` wins and stops the sweep so the owner's
 * phone rings once. Resolves `undefined` when forwarding does not apply or no
 * peer delivered — the caller then keeps its original local error.
 *
 * The transport (`send`) is injectable so the try-order / first-success / stop
 * orchestration is testable without a live SSH host; the default runs the real
 * explicit-destination `agents send` over SSH.
 */
export declare function forwardOwnerNotifyToPeer(text: string, channel: string, target: string, meta: Meta, opts?: {
    self?: string;
    devices?: DeviceProfile[];
    send?: PeerOwnerSender;
    envelope?: PeerOwnerEnvelope;
}): Promise<SendResult | undefined>;
