/**
 * `agents feed` -- operator inbox + agent status posts.
 *
 * Default (`agents feed`): list open blocks (decisions agents are waiting on).
 * Aggregates block records from the local feed store and, with --device, from
 * reachable remote hosts via SSH passthrough. Each block carries enough
 * identity for `agents message` to route a reply back to the right agent.
 *
 * Default view groups by **outcome** (ticket / PR / worktree / Unassigned) so
 * an operator sees dozens of deliverables, not ~1,100 agents. Pass `--flat`
 * for the legacy per-agent list.
 *
 * `agents feed post`: agent-callable free-text progress into the activity
 * stream (milestone `status.posted`). Session/agent/host/runtime/pid identity
 * is auto-stamped from env + the pid registry — no domain-specific flags.
 * Humans watch via the feed activity lane.
 */
import type { Command } from 'commander';
import { type OpenBlock } from '../lib/feed/feed.js';
import { type OutcomeGroup, type SessionOutcomeHint } from '../lib/feed-outcome.js';
import { filterBlocksForFeed } from '../lib/ask-classifier.js';
import { type FeedSessionSignal } from '../lib/feed-ranking.js';
export declare const FEED_POST_HELP = "\nExamples:\n  # Title (subject) + body. Phone broadcasts put title first, body after a\n  # blank line, then a \"Sent from agent/session on host\" footer.\n  agents feed post --title \"CHANGELOG pushed\" \"Watching CI and mac-mini E2E\"\n  agents feed post --title \"Cover ready\" \"render at ./out/cover.png\" --attach ./out/cover.png\n  agents feed post --title \"Ready for review\" \"PR opened, waiting on prix-cloud\" --json\n\n  # Worth interrupting someone over - reaches sinks gated on minLevel: important:\n  agents feed post --title \"npm token expired\" \"Cannot publish the release\" --level important\n\n  # Also raise a local desktop banner on THIS machine (same notifier as run\n  # --notify), on top of any configured broadcast - useful when you are at the box:\n  agents feed post --title \"Build green\" \"all checks passed\" --notify\n\n  # Stuck: opens a needs-you block and always broadcasts at important:\n  agents feed post --title \"Force-push denied\" \"git-guard blocked PR #1749\" --blocked\n  agents feed post --title \"Publish or wait?\" \"npm publish now or after review\" --blocked --option publish --option wait\n  agents feed post --title \"Delete preview env?\" \"stale preview still running\" --blocked --default \"leave it\"\n\n  # Exhaust self-serve FIRST. A block is for what you genuinely cannot do:\n  # a credential only the user holds, a decision only they can make, an\n  # approval only they can give. Not \"should I do the obvious next step?\".\n\n  # Outside a run, pass the session explicitly:\n  agents feed post --title \"Manual note\" \"context for the next agent\" --session 00998b0e-2d15-4d2f-a58b-974a886c9b47\n\nIdentity (session, agent, host, runtime, pid, launchId) is stamped automatically\nand rides the phone footer of feed.broadcast {message}. Domain facts (tickets,\nPRs) are not CLI flags - the ticket is joined from the session index at post\ntime. No em-dashes in title/body - they are scrubbed on the way out.\n\nConfigure where a post is mirrored under feed.broadcast in agents.yaml - see\ndocs/observability.md. A channel sink may set message: with placeholders such\nas {message} and {ticket}; a missing placeholder skips that sink. A milestone is always recorded, but it does not text\nthe owner when the sink has minLevel: important. Add --level important for a\nphone-worthy successful update. Use --blocked only when work cannot continue.\nThe owner destination comes from humans.yaml; do not duplicate it in agents.yaml.\n";
export declare const FEED_NO_FANOUT_ENV = "AGENTS_FEED_LOCAL";
/** Right-hand masthead summary: `N blocks · M agents`. */
export declare function formatFeedMastheadRight(blocks: OpenBlock[]): string;
/** Reply hint matching the shared fleet-comms reply line. */
export declare function formatFeedReplyHint(mailboxId: string): string;
export declare function parseRemoteFeed(stdout: string, machine: string): OpenBlock[];
/** Merge local and remote rows, keeping the first copy of a host/session block. */
export declare function mergeFeedBlocks(...groups: OpenBlock[][]): OpenBlock[];
export type FeedControlAction = 'pause' | 'kill';
export declare function controlFeedSession(action: FeedControlAction, target: string, signals: FeedSessionSignal[]): Promise<string>;
export declare function shouldIncludeLocalFeed(hosts: string[] | undefined, self: string): boolean;
export declare function remoteFeedHostsToDial(hosts: string[] | undefined, self: string): string[] | undefined;
export declare function prepareLocalFeedBlocks(localBlocks: OpenBlock[], opts: {
    includeLocal: boolean;
    all?: boolean;
    dispatch?: boolean;
}): {
    visible: OpenBlock[];
    dispatch: OpenBlock[];
    filter: ReturnType<typeof filterBlocksForFeed>;
};
/** Specific host app + routine provenance for one feed row. */
export declare function formatFeedRuntime(block: Pick<OpenBlock, 'runtime' | 'origin' | 'routineName'>): string;
/** Human summary line for one outcome rollup. */
export declare function formatOutcomeHeader(group: OutcomeGroup): string;
/** Map active sessions into the lightweight hints outcome enrichment needs. */
export declare function sessionHintsFromActive(sessions: Array<{
    sessionId?: string;
    agentId?: string;
    cwd?: string;
    ticket?: {
        id?: string;
    };
    pr?: {
        url?: string;
        number?: number;
    };
    worktree?: {
        slug?: string;
    };
    host?: string;
    origin?: 'cli' | 'routine';
    routineName?: string;
}>): SessionOutcomeHint[];
/**
 * True when a SQLite open/query failed because another writer holds the lock.
 * better-sqlite3 surfaces this as message "database is locked" and/or code
 * SQLITE_BUSY (RUSH-2006).
 */
export declare function isSqliteBusyError(err: unknown): boolean;
/**
 * Load session metas for feed outcome enrichment. The sessions index can be
 * locked by a concurrent scanner/daemon — enrichment is best-effort, so a lock
 * degrades to an empty list instead of crashing `agents feed` (RUSH-2006).
 *
 * `load` is injected so tests can throw a real lock-shaped error without
 * mocking the session module.
 */
export declare function loadSessionMetasForFeedEnrichment<T>(load: () => Promise<T[]>): Promise<{
    metas: T[];
    skippedLock: boolean;
}>;
export declare function registerFeedCommand(program: Command): void;
/** Feed view selector (RUSH-2015): decisions, progress, or both. */
export type FeedFilter = 'needs' | 'updates' | 'all';
/** Normalize a raw --filter value; unknown/empty falls back to the default. */
export declare function resolveFeedFilter(raw: string | undefined): FeedFilter;
