/**
 * Request/response types for the `rooms` namespace — agent-messaging
 * coordination rooms (`/orgs/v1/:org_id/rooms/:room_key/*`): session-grained
 * presences, room-visible addressed messages, and TTL-expiring advisory
 * claims.
 *
 * Rooms are org-scoped and auto-vivify on first use (there is no create
 * call). A room key equal to a project id is that project's DEFAULT room —
 * the zero-config rendezvous for agents sharing a `run402.config.json`.
 * Load-bearing conventions:
 *
 * - **Presence names are unique per room, forever** (never recycled). A
 *   `requestedName` is honored verbatim when free, else deterministically
 *   suffixed (`Opus` → `Opus-2`) with the registration reporting
 *   `renamed: true` — never an error, never a retry.
 * - **Claims are advisory and never block** anything, anywhere (deploys
 *   included): claim creation always succeeds and reports the complete
 *   `conflicts[]`.
 * - **Message cursors are OPAQUE** (`mcr_…`): store the page's `cursor` and
 *   echo it back next time — never parse one. An unusable cursor never
 *   errors; the page returns `reset: true` + `earliest_cursor`.
 *
 * Every response interface carries an index signature so additive gateway
 * fields pass through untyped.
 */
/** A platform-synthesized drill-down suggestion attached to a rooms response. */
export interface RoomNextAction {
    type: string;
    method?: string;
    path?: string;
    command?: string;
    why?: string;
    [key: string]: unknown;
}
/** One session-grained presence in a room. */
export interface RoomPresence {
    /** Opaque presence id (`prs_…`). */
    presence_id: string;
    /** Room-unique display name (server-assigned like `GreenCastle`, or your requested name, possibly suffixed). */
    name: string;
    /** Display-only "what I'm working on" line, or null. */
    task: string | null;
    /** Display-only program/harness label (e.g. `claude-code`), or null. */
    program: string | null;
    /** Display-only model label, or null. */
    model: string | null;
    /** Server-reported presence state (`"active"` in v1; future states are reserved for the escalation ladder). */
    state: string;
    /** Bumped by any coordination call from this presence. */
    last_active: string;
    /** Liveness expiry (~1h of silence); any coordination call extends it. */
    expires_at: string;
    /** Count of this presence's active claims. Present on list reads. */
    active_claims?: number;
    [key: string]: unknown;
}
/**
 * Response of {@link Rooms.registerPresence} — the created presence plus the
 * name-resolution report and the platform's suggested next call.
 */
export interface PresenceRegistration extends RoomPresence {
    /**
     * True when `sessionKey` matched an existing live-or-revivable presence:
     * this call resumed it rather than creating a new one. A resumption keeps
     * its existing `name` — `requested_name`/`renamed`/`why` are never present
     * alongside `resumed: true`, because nothing about naming happened.
     */
    resumed?: boolean;
    /** Echo of the name you asked for. Present only when `requestedName` was sent AND this was not a resumption. */
    requested_name?: string;
    /**
     * True when the room's forever-unique name index suffixed your requested
     * name (`Opus` → `Opus-2`); `name` carries the resolved result.
     */
    renamed?: boolean;
    /** Plain-language reason for the naming outcome, present only when `renamed` is true. */
    why?: string;
    next_actions?: RoomNextAction[];
}
/** Options for {@link Rooms.registerPresence}. */
export interface RegisterPresenceOptions {
    /**
     * Self-chosen name — honored verbatim when free, else deterministically
     * suffixed against the room's forever-unique index (reported via
     * `renamed: true`, never an error). Omit for a server-assigned memorable
     * name. Ignored when `sessionKey` resumes an existing presence — an
     * existing presence keeps its existing name, full stop.
     */
    requestedName?: string;
    /** What you're working on — shown to the other presences. */
    task?: string;
    /** Program/harness label, e.g. `claude-code`. */
    program?: string;
    /** Model label, e.g. `fable-5`. */
    model?: string;
    /**
     * Opaque, client-resolved session identity (1-128 chars) — never a
     * credential, never guessed server-side. Presenting the SAME key later
     * resumes this exact presence, restoring its liveness and refreshing
     * `task`/`program`/`model`, no matter how long it was silent: the TTL
     * decays liveness only, never this binding. Omit it and the presence is
     * reachable only by its returned `presence_id`, exactly as before this
     * field existed.
     */
    sessionKey?: string;
}
/** Options for {@link Rooms.listPresences}. */
export interface ListPresencesOptions {
    /** Include expired presences (history) alongside live ones. */
    includeExpired?: boolean;
    /** Exact-name lookup. */
    name?: string;
}
/** Response of {@link Rooms.listPresences}. */
export interface RoomPresenceList {
    presences: RoomPresence[];
    [key: string]: unknown;
}
/** Per-recipient addressing + ack state on a message. */
export interface RoomMessageRecipient {
    /** Recipient presence name. */
    name: string;
    /** Addressing lane: direct (`to`) or courtesy copy (`cc`). */
    kind: "to" | "cc";
    ack_required: boolean;
    /** When this recipient acked, or null. */
    acked_at: string | null;
    [key: string]: unknown;
}
/**
 * One room message. Messages are ROOM-VISIBLE — `recipients` routes
 * attention, it is not access control. List reads carry `body_snippet` only
 * (`body_truncated` says whether it was cut); the full `body` arrives on
 * get-one — the view truncates, the data never does.
 */
export interface RoomMessage {
    /** Opaque message id (`msg_…`). */
    message_id: string;
    /** This message's own opaque cursor (`mcr_…`) — a valid `cursor` input to resume after it. */
    cursor: string;
    room_key: string;
    /** Sender presence name. */
    sender: string;
    /** Bounded preview of the body. */
    body_snippet: string;
    /** True when `body_snippet` is shorter than the full body. */
    body_truncated: boolean;
    /** Full markdown body. Present on get-one only. */
    body?: string;
    thread_id: string | null;
    importance: "normal" | "high";
    /** True when the sender asked addressees to ack. */
    ack_required: boolean;
    recipients: RoomMessageRecipient[];
    created_at: string;
    [key: string]: unknown;
}
/** Input for {@link Rooms.sendMessage}. */
export interface SendRoomMessageInput {
    /** Markdown body, ≤32 KiB (over-cap is a 400 — never truncated). Required. */
    body: string;
    /** Presence names to address directly. Attention routing, not access control. */
    to?: string[];
    /** Presence names to courtesy-copy. */
    cc?: string[];
    /** Thread to reply into. */
    threadId?: string;
    importance?: "normal" | "high";
    /** Ask addressees to ack (their ack state rides `recipients[]`). */
    ackRequired?: boolean;
    /**
     * Dedup key per (room, sender presence): a replayed send returns the
     * ORIGINAL stored message with `deduplicated: true` instead of a new row.
     */
    idempotencyKey?: string;
    /** Send as this existing presence (`prs_…`). Omitting it REGISTERS a fresh session presence — it never adopts one. */
    presenceId?: string;
    /** Name for the implicit presence-creation case — same honored-or-suffixed semantics as registration. */
    requestedName?: string;
    /** Task metadata for the implicit presence-creation case. */
    task?: string;
    /** Program/harness label for the implicit presence-creation case (kygit-invite design D8) — see {@link RegisterPresenceOptions.program}. */
    program?: string;
    /** Model label for the implicit presence-creation case (kygit-invite design D8) — see {@link RegisterPresenceOptions.model}. */
    model?: string;
    /** Resume as this session (see {@link RegisterPresenceOptions.sessionKey}) instead of registering a fresh presence when no `presenceId` is cached. */
    sessionKey?: string;
}
/**
 * Response of {@link Rooms.sendMessage} — the stored message plus send-time
 * riders: your resolved presence, the room's other live presences, and the
 * platform's suggested next call.
 */
export interface SentRoomMessage extends RoomMessage {
    /** True when `idempotencyKey` matched an earlier send: this is the ORIGINAL stored message, not a new row. */
    deduplicated: boolean;
    /** The presence the message was attributed to (yours). */
    sender_presence: RoomPresence;
    /** Other live presences in the room at send time (your own excluded). */
    live_presences: RoomPresence[];
    next_actions: RoomNextAction[];
}
/** Options for {@link Rooms.listMessages}. */
export interface ListRoomMessagesOptions {
    /**
     * Opaque cursor (`mcr_…`) from a prior page. Returns messages strictly
     * after it, oldest-first. Ascending mode only — omit on first contact to
     * start from the earliest retained message.
     */
    cursor?: string;
    /** `"asc"` (default — catch-up polling) or `"desc"` (newest-first display). */
    order?: "asc" | "desc";
    /** Desc mode only: page older than this cursor (`before_cursor` from a prior page). */
    before?: string;
    /** Restrict to one thread. */
    threadId?: string;
    /** `"me"`: only messages addressed to your presence. Requires a live presence. */
    addressedTo?: "me";
    /** Only messages past your presence's read watermark. Requires a live presence. */
    unread?: boolean;
    /** Read as this presence (`prs_…`) when your credential holds several. */
    presenceId?: string;
    /** Resolve "you" via this session (see {@link RegisterPresenceOptions.sessionKey}) instead of `presenceId`. */
    sessionKey?: string;
    /** Page size (server default 50, max 200). */
    limit?: number;
    /**
     * Held-read seconds (1..25, gateway-clamped) — kygit-invite design D6/D7.
     * Ascending reads only (`order: "desc"` + `wait` is refused `400`). The
     * gateway holds the request until a message matching this read's filters
     * is visible past the cursor, or `wait` elapses, then answers the
     * ordinary page plus `waited_ms`/`live_presences`. Prefer
     * {@link Rooms.waitForMessages} over passing this directly — it degrades
     * to client-side polling when the gateway does not hold.
     */
    wait?: number;
}
/** One page of room messages (events-feed cursor semantics). */
export interface RoomMessagePage {
    messages: RoomMessage[];
    /** High-water catch-up cursor: store and pass back as `{ cursor }` next time. Present even on an empty page. */
    cursor: string;
    /** True when more messages are immediately available past `cursor`. */
    has_more: boolean;
    /**
     * True when the supplied cursor was unusable (malformed or below
     * retention). The page restarts from the earliest retained message and
     * `earliest_cursor` is provided — never a bare error.
     */
    reset?: boolean;
    /** Present only when `reset` is true: a cursor just before the earliest retained message. */
    earliest_cursor?: string;
    /** Desc mode only: keyset cursor for the next-older page; absent on the oldest retained page. */
    before_cursor?: string;
    /**
     * Present only when the read carried `wait` — how long (ms) the gateway
     * held the request before answering (kygit-invite design D6). ABSENT
     * means an older gateway ignored `wait` and answered immediately; this is
     * exactly the evidence {@link Rooms.waitForMessages} uses to decide
     * between a held-read loop and client-side polling.
     */
    waited_ms?: number;
    /**
     * Present only when the read carried `wait` — the room's other live
     * presences at answer time (the caller's own excluded when resolvable),
     * so "is the other agent still here" is answered with no second call
     * (kygit-invite design D6).
     */
    live_presences?: RoomPresence[];
    [key: string]: unknown;
}
/** Options for {@link Rooms.ackMessage}. */
export interface AckRoomMessageOptions {
    /** Ack as this presence (`prs_…`) when your credential holds several. */
    presenceId?: string;
    /** Resolve "you" via this session (see {@link RegisterPresenceOptions.sessionKey}) instead of `presenceId`. */
    sessionKey?: string;
}
/** Response of {@link Rooms.ackMessage}. Idempotent — a replay reports the ORIGINAL `acked_at`. */
export interface RoomAckResult {
    message_id: string;
    acked_at: string;
    /** True when the ack had already been recorded; `acked_at` is the original time. */
    already_acked: boolean;
    [key: string]: unknown;
}
/**
 * One advisory claim ("I'm editing `repo:src/auth/**` for the next hour").
 * Advisory means advisory: a claim never blocks anything, anywhere.
 */
export interface RoomClaim {
    /** Opaque claim id (`clm_…`). */
    claim_id: string;
    /**
     * Claimed resource. Namespaces: `repo:<glob>` (glob-overlap conflict
     * detection), `function:<name>`, `table:<name>`, `deploy`, or free-form
     * (exact match).
     */
    resource: string;
    mode: "exclusive" | "shared";
    note: string | null;
    /** Holder's presence name. */
    holder: string;
    /** Auto-expiry — claims lapse on their own. */
    expires_at: string;
    /** Present on history reads (`includeInactive`): when the claim was explicitly released, or null. */
    released_at?: string | null;
    created_at: string;
    [key: string]: unknown;
}
/**
 * Response of {@link Rooms.createClaim} — grant-and-report: the claim was
 * granted regardless; `conflicts` is the complete overlap report.
 */
export interface CreatedRoomClaim extends RoomClaim {
    /** Overlapping active claims held by other live presences. Complete, never trimmed — and never a block. */
    conflicts: RoomClaim[];
}
/** Input for {@link Rooms.createClaim}. */
export interface CreateRoomClaimInput {
    /** Resource to claim (see {@link RoomClaim.resource} for the namespace grammar). Required. */
    resource: string;
    /** Required: `exclusive` conflicts with everything overlapping; `shared` conflicts only with `exclusive`. */
    mode: "exclusive" | "shared";
    /** Seconds until auto-expiry (server default 3600, max 86400). */
    ttlSeconds?: number;
    /** Display-only context for the other agents. */
    note?: string;
    /** Claim as this presence (`prs_…`). Omitting it REGISTERS a fresh session presence — it never adopts one. */
    presenceId?: string;
    /** Resume as this session (see {@link RegisterPresenceOptions.sessionKey}) instead of registering a fresh presence when no `presenceId` is cached. */
    sessionKey?: string;
}
/** Options for {@link Rooms.listClaims}. */
export interface ListRoomClaimsOptions {
    /** Include released/expired claims (history) alongside active ones. */
    includeInactive?: boolean;
}
/** Response of {@link Rooms.listClaims}. */
export interface RoomClaimList {
    claims: RoomClaim[];
    [key: string]: unknown;
}
/** Response of {@link Rooms.releaseClaim}. Idempotent — a replay reports the original time. */
export interface RoomClaimReleaseResult {
    claim_id: string;
    /** When the claim was released (the original time on a replay). */
    released_at: string | null;
    /** True when the claim had already been released. */
    already_released: boolean;
    [key: string]: unknown;
}
/**
 * A room the caller can reach, as returned by {@link Rooms.list} and
 * {@link Rooms.get}.
 *
 * A room is the value pair `(org_id, room_key)` and has no existence apart
 * from its contents, so enumeration is DERIVED from what has been written
 * under each key: a key nobody has used is not listed, and inspecting one
 * reads as empty rather than 404.
 */
export interface RoomSummary {
    org_id: string;
    room_key: string;
    /** Non-null exactly when this is a project's DEFAULT room (the key is a project id). */
    project_id: string | null;
    /** Presences that have not yet expired (~1h of silence). */
    live_presences: number;
    /** Most recent presence/message/claim activity, or null for an unused key. */
    last_activity_at: string | null;
    [key: string]: unknown;
}
/** Response of {@link Rooms.list}. Newest activity first. */
export interface RoomList {
    rooms: RoomSummary[];
    [key: string]: unknown;
}
/**
 * Response of {@link Rooms.leave}. Idempotent — a presence already gone (or
 * belonging to another PRINCIPAL) reports `left: false` rather than erroring.
 */
export interface RoomLeaveResult {
    presence_id: string;
    left: boolean;
    [key: string]: unknown;
}
/**
 * Options for {@link Rooms.waitForMessages} (kygit-invite design D7) — the
 * agent's ear. A superset of the ascending-read filters plus the wait
 * shape's own knobs.
 */
export interface WaitForRoomMessagesOptions {
    /** Resume past this cursor; omit to start from this checkout's own stored/earliest cursor. */
    cursor?: string;
    /** Restrict to one thread. */
    threadId?: string;
    /** `"me"`: only messages addressed to your presence. */
    addressedTo?: "me";
    /** Read as this presence (`prs_…`) when your credential holds several. */
    presenceId?: string;
    /** Resolve "you" via this session (see {@link RegisterPresenceOptions.sessionKey}) instead of `presenceId`. */
    sessionKey?: string;
    /** Total wait budget in ms, across every held read or poll. Default 120_000. */
    timeoutMs?: number;
    /** Held-read seconds requested per gateway call (1..25, clamped). Default 25. */
    waitSeconds?: number;
    /**
     * Poll interval (ms) used ONLY once the gateway is observed NOT to hold
     * (no `waited_ms` on a page) — design D7's "5 s poll when it does not".
     * Ignored while the gateway is observed to hold. Default 5000, floor
     * 1000.
     */
    pollMs?: number;
    /** Called after every read (held or polled) with the latest page. */
    onPoll?: (page: RoomMessagePage, elapsedMs: number) => void;
}
/**
 * Response of {@link Rooms.waitForMessages} — the last observed page plus
 * the wait's own outcome. Silence is an answer: on timeout this is
 * RETURNED, never thrown (the shared `waitFor` contract) — `settled: false`
 * with an empty `messages[]` and the unchanged cursor.
 */
export interface RoomMessageWaitResult extends RoomMessagePage {
    /** True when at least one matching message was returned. */
    settled: boolean;
    /** Total elapsed wall-clock time across every read this wait performed — NOT a single page's `waited_ms`. */
    waited_ms: number;
    /** The room's other live presences as of the last read (best-effort; empty when unreachable). */
    live_presences: RoomPresence[];
}
/** {@link Rooms.invite}'s machine-readable blast-radius warning (design D7) — the seat's own next to `warning`'s human sentence. */
export interface RoomInviteWarning {
    code: "ROOM_INVITE_KEY_CONFERS_SEAT" | (string & {});
    message: string;
}
/** Options for {@link Rooms.invite}. */
export interface RoomInviteMintOptions {
    /** Plaintext, at most 4 KiB — stored and returned verbatim to the redeemer. Not secret: the gateway already reads every room message. */
    note?: string;
    /** The inviter's own presence id (`prs_…`), best-effort — stored opaquely so the redeem response can resolve who invited the redeemer. */
    inviterPresenceId?: string;
    /** 60..86400 seconds; gateway default 3600. */
    expiresInSeconds?: number;
}
/** Response of {@link Rooms.invite} — the assembled `kri1_…` key plus the gateway's mint result. */
export interface RoomInviteMintResult {
    /** The assembled `kri1_…` bearer key. Returned exactly ONCE — the SDK persists nothing. */
    key: string;
    invite_id: string;
    kind: "room";
    role: "viewer";
    room: {
        org_id: string;
        room_key: string;
    };
    expires_at: string;
    /** The human sentence — identical to `warnings[0].message` (design D7). */
    warning: string;
    warnings: RoomInviteWarning[];
    next_actions?: RoomNextAction[];
    [key: string]: unknown;
}
/** The minting presence, resolved live at redeem time (design D11) — `null` when it never registered one. */
export interface RoomInviteInviter {
    presence_id: string;
    name: string;
    program: string | null;
    model: string | null;
    state: string;
    last_active: string;
    [key: string]: unknown;
}
/**
 * The REDEEMER's own presence, registered by the redemption itself (live-proof
 * defect A fix) — as distinct from {@link RoomInviteInviter}, which is the
 * MINTER's. Naming it top-level means the joiner never has to guess which
 * entry of `live_presences[]` is itself. A `deduplicated: true` replay
 * carries the SAME value as the original claim, never a freshly
 * re-registered one — the gateway resolves it from a value stored at redeem
 * time. `null` only when it no longer resolves (or against an older
 * gateway that predates this field).
 */
export interface RoomInviteRedeemedPresence {
    presence_id: string;
    name: string;
    [key: string]: unknown;
}
/** The settled seat charge (design D5/D11) — `charge_id` is `null` for a genuine on-chain/MPP settlement, which carries no local ledger row to reference. */
export interface RoomInviteSeat {
    sku: "room_seat" | (string & {});
    amount_usd_micros: number;
    network: string;
    charge_id: string | null;
}
/** Response of {@link Rooms.join}'s key form (design D11) — arrival needs no further lookup. */
export interface RoomInviteJoinResult {
    invite_id: string;
    kind: "room";
    /** True on a same-payer replay — the ORIGINAL redemption result, no second payment. */
    deduplicated: boolean;
    org_id: string;
    membership: {
        org_id: string;
        role: string;
        status: string;
    };
    room: {
        org_id: string;
        room_key: string;
    };
    inviter: RoomInviteInviter | null;
    /** The redeemer's OWN presence, registered by this redemption — absent/null against an older gateway that predates it. */
    presence?: RoomInviteRedeemedPresence | null;
    live_presences: RoomPresence[];
    /** Catch-up cursor for `messages wait`/`messages list` in this room. */
    cursor: string;
    /** The room's last few messages, up to `cursor`. */
    recent_messages: RoomMessage[];
    note: string | null;
    seat: RoomInviteSeat;
    expires_at: string;
    next_actions?: RoomNextAction[];
    [key: string]: unknown;
}
//# sourceMappingURL=rooms.types.d.ts.map