/** * In-process forced delivery (#1024). * * What `POST /api/terminal/:s/deliver` with `force: true` does, callable from * backend services without an HTTP hop. The runtime exit monitor and the * Slack bridge's direct-delivery fallback used to make that hop with no * credential; the route now refuses anonymous callers, and a service * presenting a pseudo-agent badge would also make the target "act for" the * owner (issue #968), which a system notice must not do. * * Order: * 0. the session must exist locally (in-process runtime that is ready, or a * PTY) — otherwise `not-found`. Unlike the route there is no remote * routing and no offline-member start: both callers send local system * notices; * 1. restart drain — queued for after the restart (crewly#1015 §6); * 2. daily token cap — queued, no new turn (#937); * 3. in-process Crewly Agent — `handleMessage`; * 4. PTY — the guarded two-step write (`sendMessage`). * * @module services/messaging/forced-delivery */ import { queueIfSpendCapped } from './spend-capped-delivery.js'; import { queueIfRestartDraining } from './drain-queued-delivery.js'; /** Outcome of a forced delivery. */ export type ForcedDeliveryResult = { status: 'delivered'; inProcess: boolean; } | { status: 'queued'; reason: 'restart-drain' | 'spend-cap'; message: string; } | { status: 'not-found'; error: string; } | { status: 'input-not-ours'; error: string; } | { status: 'failed'; error: string; }; /** Minimal in-process runtime surface used here. */ interface InProcessTarget { isReady(): boolean; handleMessage(message: string): Promise; } /** Injectable dependencies (tests). */ export interface ForcedDeliveryDeps { /** In-process Crewly Agent runtime for a session, if any */ getInProcessRuntime?: (sessionName: string) => InProcessTarget | undefined; /** PTY write: resolves when written; throws TuiInputGuardError when the box holds someone else's text */ writeToPty?: (sessionName: string) => ((message: string) => Promise) | null; /** Drain gate */ queueIfRestartDraining?: typeof queueIfRestartDraining; /** Spend-cap gate */ queueIfSpendCapped?: typeof queueIfSpendCapped; } /** * Force-deliver a message into a local agent, in process. * * @param sessionName - Target agent session * @param message - Message text * @param deps - Dependencies (tests) * @returns What happened; never throws * * @example * ```ts * const r = await deliverForcedMessage(ORCHESTRATOR_SESSION_NAME, notice); * if (r.status !== 'delivered' && r.status !== 'queued') logger.debug('not delivered', r); * ``` */ export declare function deliverForcedMessage(sessionName: string, message: string, deps?: ForcedDeliveryDeps): Promise; export {}; //# sourceMappingURL=forced-delivery.d.ts.map