import { Type } from "typebox";
import type { TaskAccess } from "../core/task-registry.js";
import { type RosterEntry } from "./roster-store.js";
import { type PeerDirectory, type PeerPresence, type PeerSessionRecord } from "./peer-directory.js";
import type { SubagentTranscriptTier } from "../core/wiring-manifest.js";
import { formatAgo, type AgentState, type AgentStateSource } from "../core/agent-state.js";
import type { CheckpointSeat } from "../core/checkpoint-seat.js";
export declare const LIST_AGENTS_TOOL_NAME = "ListAgents";
export declare const LIST_AGENTS_TOOL_ALIAS = "ListPeers";
/** CC `maxResultSizeChars` for this tool. */
export declare const LIST_AGENTS_MAX_RESULT_CHARS = 10000;
/** The default freshness window (24 h) — one source, the peer lane's knob table. */
export declare const PEER_LISTING_FRESH_WINDOW_MS: number;
/**
 * THE freshness predicate: a peer row is listed by default iff it is live AND (its host says it is
 * working — `tempo` active/blocked — OR it changed within the window). One rule over rendering
 * visibility only: refs are minted and names resolve over the FULL set, so a row hidden here is still
 * addressable by name. Dead and stale rows are what `includeAll` adds.
 */
export declare function isFreshPeerRow(r: Pick<PeerSessionRecord, "liveness" | "tempo" | "updatedAt">, now: number, windowMs?: number): boolean;
/** `Ns` / `Nm` / `Nh` / `Nd` — a bounded age word for a listing row (one definition, shared with the agent-state clauses). */
export { formatAgo };
/** The last two path segments of a working directory (what a person recognizes a project by). */
export declare function cwdTail(cwd: string): string;
export interface ListAgentsToolOptions {
    /** The peer-session directory. Absent ⇒ no peer rows (the two agent lanes still list). */
    peerDirectory?: PeerDirectory;
    /** This session's own identity — excluded from the peer listing, included in ref disambiguation. */
    self: {
        sessionId: string;
        scope: string;
    };
    /** The live registry + this caller's access axes (same axes the SendMessage mount reads). */
    registry?: {
        list(access: TaskAccess, opts?: {
            limit?: number;
        }): Array<{
            task_id: string;
            type: string;
            status: string;
            description?: string;
        }>;
        getAccessibleTask(id: string, access: TaskAccess): {
            name?: string;
            status: string;
        } | undefined;
        /** The live background-agent row's state facts ({@link import("../core/task-registry.js").TaskRegistry.agentStateSource}).
         *  Absent on a registry that does not offer it ⇒ agent rows carry no `agentState` and no state columns. */
        agentStateSource?(id: string, access: TaskAccess): AgentStateSource | undefined;
    };
    access?: TaskAccess;
    /** design/147 S3a parity — a delegated child's TRUSTED parent view (owner = the parent's task id,
     *  sessionId = the parent's session), so the siblings SendMessage can reach by name are listed too.
     *  Unioned with {@link access}, de-duplicated by id; the scope axis is never widened. */
    parentAccess?: TaskAccess;
    /** The durable roster (names recorded by earlier processes). Rows are filtered by the caller's
     *  {@link access} with the store's own predicate (`entryAccessible`) BEFORE anything is listed — a
     *  shared roster holds other owners'/scopes' names, and a listing is a disclosure face. */
    roster?: {
        list(): RosterEntry[] | Promise<RosterEntry[]>;
    };
    /** The resolved freshness window ({@link isFreshPeerRow}); absent ⇒ {@link PEER_LISTING_FRESH_WINDOW_MS}. */
    freshWindowMs?: number;
    /** The continuation reach of the SendMessage mounted beside this tool (`sendMessageContinuationTier` —
     *  the same answer from the same seats, so the two faces cannot disagree): what a recorded agent's label
     *  may promise. `full` = the record and the conversation survive a restart; `rows` = the record survives,
     *  the conversation does not; `none` = only the recorded name. Absent (a direct mount that did not say) ⇒
     *  the `none` wording — a label never promises more than the mount can show. */
    continuationTier?: SubagentTranscriptTier;
    /** The run's checkpoint seat — where a PARKED agent row's approval card is read from (the same seat the
     *  Agent tool parks children into). Absent ⇒ the card reads `unreadable`. */
    checkpointSeat?: CheckpointSeat;
    /** The clock (tests). */
    now?: () => number;
}
/** The store seats the listing reads agent rows' facts through, as one bundle a mount helper passes on unchanged. */
export type ListAgentsReadSeats = Pick<ListAgentsToolOptions, "checkpointSeat">;
/** One rendered row. `kind` names the lane; `address` is what SendMessage accepts. */
export interface ListAgentsRow {
    kind: "peer_session" | "background_agent" | "roster";
    name: string;
    /** Peer rows only: the listing-minted ref. */
    ref?: string;
    /** Peer rows, live: when the row last changed (rendered `active <N> ago`). */
    lastActiveAt?: number;
    /** Peer rows, dead: when the host marked it (rendered `offline <N> ago`); a dead row with no stamp renders `offline`. */
    offlineAt?: number;
    /** Peer rows: the last two segments of the session's working directory, when the row carries one. */
    cwd?: string;
    /** Peer rows: the session's self-reported presence, when it reported any. */
    presence?: PeerPresence;
    /** What SendMessage accepts: on both AGENT lanes the registry `task_id` VERBATIM (no prefixing or
     *  re-minting), never the child's session id — a different domain, tabled in INTEGRATION-CORE §1.6a.
     *  Peer rows carry the `session.<id>` box handle instead. */
    address: string;
    /** What the row IS, right now. Both lanes are a table lookup over the word the row carries
     *  ({@link PEER_ROW_STATE} / {@link AGENT_ROW_STATE}), and `unknown` answers whatever the table cannot
     *  — on the peer lane the common case, since no host writes the activity word. `finished` means
     *  COMPLETED and nothing else: a model applies the continuable rule to that word. */
    state: "busy" | "idle" | "offline" | "running" | "parked" | "finished" | "failed" | "killed" | "cancelled" | "unknown";
    /** Agent lanes with a live registry row: the agent's current state
     *  ({@link import("../core/agent-state.js").readAgentState}, the one reading AgentTranscript and TaskOutput
     *  render too); {@link state} is this status word through the lane table. Absent on peer rows and on a
     *  roster row with no live row. */
    agentState?: AgentState;
}
export declare function createListAgentsTool(opts: ListAgentsToolOptions): import("../core/types.js").AgentTool<Type.TObject<{
    includeAll: Type.TOptional<Type.TBoolean>;
}>, unknown>;
