export type QueueLane = "steer" | "followUp"; /** A queued row that executes a Pi command instead of becoming an LLM message. */ export type QueuedCommand = { kind: "compact"; instructions?: string; } | { kind: "reload"; } | { kind: "new"; } | { kind: "model"; target?: string; } | { kind: "thinking"; level?: string; } | { kind: "fabric-prewalk"; } | { kind: "fabric-await"; peer?: string; }; /** * Parse row text as a queueable command. Commands are recognised at dispatch * and render time, so editing a row into or out of command form just works. */ export declare function parseQueuedCommand(text: string): QueuedCommand | undefined; /** * True when plain submission content should become a queue row instead of * passing to Pi directly: real text or images, and not Pi's own "/" command * or "!" bash dispatch. Command rows are recognised via parseQueuedCommand. */ export declare function isQueueableSubmission(text: string, images?: readonly unknown[]): boolean; export interface QueuedMessage { id: string; lane: QueueLane; text: string; images: TImage[]; sequence: number; /** Row-level dispatch hold: a paused row stops the global timeline at its * position until resumed; rows behind it never jump ahead of it. */ paused?: boolean; } /** * One FIFO timeline whose rows retain their steering or follow-up delivery lane. * * Delivery-depth changes preserve global row positions, and sequence remains a * separate enqueue-recency clock so editing can enter at the newest row after * explicit reorders. */ export declare class DeliveryQueue { private items; private nextIdNumber; private nextSequence; enqueue(lane: QueueLane, text: string, images?: readonly TImage[]): QueuedMessage; /** Insert interactive steering into the current run, before future run roots. */ enqueueSteer(text: string, images?: readonly TImage[]): QueuedMessage; prepend(item: QueuedMessage): void; prependMany(items: readonly QueuedMessage[]): void; update(id: string, text: string, images?: readonly TImage[]): boolean; /** Set a row's dispatch hold. Returns false when the row is missing or already in that state. */ setPaused(id: string, paused: boolean): boolean; /** Swap a row with its lane neighbour in delivery order. Returns false at lane ends. */ moveInLane(id: string, direction: -1 | 1): boolean; /** Swap exact row identities; also used to undo moves despite lane changes. */ swapRows(id: string, neighbourId: string): boolean; /** Move one visible row up or down without changing its delivery depth. */ moveInTimeline(id: string, direction: -1 | 1): boolean; /** Change a row's delivery depth without changing its timeline position. */ setLane(id: string, lane: QueueLane): boolean; remove(id: string): QueuedMessage | undefined; peek(): QueuedMessage | undefined; shift(): QueuedMessage | undefined; shiftAll(lane: QueueLane): QueuedMessage[]; /** * Shift an adjacent run from the timeline head while the lane and predicate * match. A lane switch, command, or paused row ends an `all`-mode batch so * later rows can never jump across an interleaved delivery boundary. */ shiftWhile(lane: QueueLane, accept: (item: QueuedMessage) => boolean): QueuedMessage[]; get(id: string): QueuedMessage | undefined; previousId(currentId?: string): string | undefined; nextId(currentId?: string): string | undefined; mostRecentId(): string | undefined; laneSnapshot(lane: QueueLane): QueuedMessage[]; snapshot(): QueuedMessage[]; laneLength(lane: QueueLane): number; get length(): number; /** Restore an in-memory queue snapshot without changing row identity or recency. */ restore(items: readonly QueuedMessage[]): void; /** Persist high-water marks even when every row has been consumed. */ identity(): { nextIdNumber: number; nextSequence: number; }; restoreIdentity(identity: { nextIdNumber: number; nextSequence: number; }): void; clear(): void; private copy; } export interface EditCommitResult { updated: number; removed: number; moved: number; /** Rows whose dispatch hold was engaged by this save. */ held: number; /** Rows whose dispatch hold was lifted by this save. */ released: number; } /** Rollback-safe drafts spanning rows from either delivery lane. */ export declare class QueueEditSession { private readonly drafts; private readonly positionMoves; private currentId; readonly composerDraft: string; constructor(item: QueuedMessage, composerDraft: string); private newDraft; get selectedId(): string; get selectedText(): string; capture(text: string, images?: readonly TImage[]): void; select(item: QueuedMessage, currentText: string, images?: readonly TImage[]): string; /** * Move a row in the visible timeline immediately, recording the inverse so cancel * restores positions. Position changes apply to dispatch order at once; * Escape replays the inverses newest-first. */ moveRow(queue: DeliveryQueue, id: string, direction: -1 | 1): boolean; /** Committed position projection for persistence, without consuming the rollback log. */ committedPositions(queue: DeliveryQueue): QueuedMessage[]; /** Undo in-session reorders, newest first. Best-effort if rows left mid-session. */ rollbackPositions(queue: DeliveryQueue): void; /** Toggle whether the row is deleted on save. Returns the new mark. */ toggleRemoved(id: string): boolean | undefined; /** Set the row's draft delivery depth. Returns the effective lane. */ setLane(id: string, lane: QueueLane): QueueLane | undefined; /** Legacy toggle for terminals where Option+Arrow cannot be distinguished. */ toggleLane(id: string): QueueLane | undefined; /** Toggle the row's draft dispatch hold. Returns the new paused state. */ togglePaused(id: string): boolean | undefined; /** The row's drafted dispatch hold, or undefined when the session never touched it. */ pausedFor(id: string): boolean | undefined; laneFor(id: string): QueueLane | undefined; isRemoved(id: string): boolean; touches(id: string): boolean; touchesLane(queue: DeliveryQueue, lane: QueueLane): boolean; textFor(id: string): string | undefined; imagesFor(id: string): TImage[] | undefined; commit(queue: DeliveryQueue, currentText: string, images?: readonly TImage[]): EditCommitResult; }