import type { RuntimeScopeCarrier } from "@pinet/transport-core"; import { type SlackInteractiveInboxEvent } from "./slack-block-kit.js"; import { type ThreadOwnerHint } from "./broker/router.js"; export { SLACK_SOCKET_DELIVERY_DEDUP_MAX_SIZE, SLACK_SOCKET_DELIVERY_DEDUP_TTL_MS, } from "./slack-socket-dedup.js"; export type SlackCall = (method: string, token: string, body?: Record) => Promise>; export interface SlackAccessCache { get(key: K): V | undefined; set(key: K, value: V): unknown; has?(key: K): boolean; } export interface SlackAccessSet { has(key: K): boolean; add(key: K): unknown; delete?(key: K): unknown; } export interface SlackThreadContext { channelId: string; teamId?: string; scope: RuntimeScopeCarrier; } export declare function buildSlackThreadRuntimeScope(input: { channelId?: string | null; context?: SlackThreadContext | null; }): RuntimeScopeCarrier; export interface ParsedSlashCommand { command: string; text: string; channelId: string; userId: string; responseUrl?: string; triggerId?: string; teamId?: string; } export interface ParsedEnvelope { envelopeId?: string; type: string; dedupKey?: string; event?: Record; interactivePayload?: Record; slashCommand?: ParsedSlashCommand; } export declare function isSlackUserAllowed(allowlist: Set | null, userId: string): boolean; /** * Parse a raw Socket Mode WebSocket frame into a structured envelope. * Returns null if the frame is malformed JSON. */ export declare function parseSocketFrame(raw: string): ParsedEnvelope | null; export interface ParsedThreadStarted { channelId: string; threadTs: string; userId: string; context?: SlackThreadContext; } /** * Extract thread info from an assistant_thread_started event. */ export declare function extractThreadStarted(evt: Record): ParsedThreadStarted | null; export interface ParsedThreadContextChanged { threadTs: string; context?: SlackThreadContext; } export declare function extractThreadContextChanged(evt: Record): ParsedThreadContextChanged | null; export interface ParsedAppHomeOpened { userId: string; tab: string; eventTs: string | null; } export declare function extractAppHomeOpened(evt: Record): ParsedAppHomeOpened | null; /** * Classification result for an incoming message event. * Uses a discriminated union so TypeScript narrows fields when relevant is true. */ export type MessageClassification = { relevant: false; } | { relevant: true; threadTs: string; channel: string; userId: string; text: string; isDM: boolean; isChannelMention: boolean; messageTs: string; metadata?: Record; }; /** * Classify an incoming Slack message event. Determines whether the * message is relevant (DM, known thread, or bot mention) and * extracts the cleaned fields. */ export declare function classifyMessage(evt: Record, botUserId: string | null, trackedThreadIds: Set, isKnownThread?: (threadTs: string) => boolean): MessageClassification; /** * Parse a member_joined_channel event. Returns null if required fields * are missing. */ export declare function parseMemberJoinedChannel(evt: Record, botUserId: string | null): { channel: string; isSelf: boolean; } | null; export interface FetchSlackMessageByTsInput { slack: SlackCall; token: string; channel: string; messageTs: string; } export declare function fetchSlackMessageByTs(input: FetchSlackMessageByTsInput): Promise | null>; export interface SlackReactionInput { slack: SlackCall; token: string; channel: string; timestamp: string; emoji: string; } export declare function addSlackReaction(input: SlackReactionInput): Promise; export declare function removeSlackReaction(input: SlackReactionInput): Promise; export interface ResolveSlackUserNameInput { slack: SlackCall; token: string; userId: string; cache?: SlackAccessCache; shouldUseResult?: () => boolean; } export declare function resolveSlackUserName(input: ResolveSlackUserNameInput): Promise; export interface ResolveSlackChannelIdInput { slack: SlackCall; token: string; nameOrId: string; cache?: SlackAccessCache; } export declare function resolveSlackChannelId(input: ResolveSlackChannelIdInput): Promise; export interface ClearSlackThreadStatusInput { slack: SlackCall; token: string; channelId: string; threadTs: string; } export declare function clearSlackThreadStatus(input: ClearSlackThreadStatusInput): Promise; export interface SlackSuggestedPrompt { title: string; message: string; } export interface SetSlackSuggestedPromptsInput { slack: SlackCall; token: string; channelId: string; threadTs: string; prompts: SlackSuggestedPrompt[]; } export declare function setSlackSuggestedPrompts(input: SetSlackSuggestedPromptsInput): Promise; export interface ResolveSlackThreadOwnerHintInput { slack: SlackCall; token: string; channel: string; threadTs: string; cache?: SlackAccessCache; limit?: number; } export declare function resolveSlackThreadOwnerHint(input: ResolveSlackThreadOwnerHintInput): Promise; export declare const RECONNECT_DELAY_MS = 5000; export interface SlackSocketModeClientConfig { slack: SlackCall; botToken: string; appToken: string; resolveBotUserIdOnConnect?: boolean; reconnectDelayMs?: number; dedup?: SlackAccessSet; abortAndWait?: () => Promise; onOpen?: () => void; onReconnectScheduled?: () => void; onError?: (error: unknown) => void; onThreadStarted?: (event: ParsedThreadStarted) => Promise | void; onThreadContextChanged?: (event: ParsedThreadContextChanged) => Promise | void; onMessage?: (event: Record) => Promise | void; onReactionAdded?: (event: Record) => Promise | void; onMemberJoinedChannel?: (event: { channel: string; isSelf: boolean; }) => Promise | void; onAppHomeOpened?: (event: ParsedAppHomeOpened) => Promise | void; onInteractive?: (event: SlackInteractiveInboxEvent) => Promise | void; onSlashCommand?: (event: ParsedSlashCommand) => Promise | void; } export declare class SlackSocketModeClient { private readonly config; private botUserId; private ws; private reconnectTimer; private shuttingDown; constructor(config: SlackSocketModeClientConfig); getBotUserId(): string | null; isConnected(): boolean; connect(): Promise; disconnect(): Promise; private connectSocketMode; private handleFrame; private scheduleReconnect; }