import type { ExtensionContext } from "@earendil-works/pi-coding-agent"; import { type InboxMessage } from "./helpers.js"; import { type ReactionCommandTemplate } from "./reaction-triggers.js"; import type { SlackToolsThreadContextPort } from "./slack-tools.js"; import { type ParsedThreadStarted, type SlackAccessSet, type SlackCall } from "./slack-access.js"; export interface SinglePlayerThreadState { channelId: string; threadTs: string; userId: string; source?: string; context?: ParsedThreadStarted["context"]; owner?: string; } export interface SinglePlayerPendingAttention { channel: string; messageTs: string; } export type SinglePlayerThreadInfo = SinglePlayerThreadState; export type SinglePlayerPendingAttentionEntry = SinglePlayerPendingAttention; export interface SinglePlayerUnclaimedThreads { has: (threadTs: string) => boolean; add: (threadTs: string) => void; delete: (threadTs: string) => void; } export interface SinglePlayerRuntimeDeps { slack: SlackCall; getBotToken: () => string; getAppToken: () => string; dedup: SlackAccessSet; abortSlackRequests: () => Promise; isSingleRuntimeActive: () => boolean; setExtStatus: (ctx: ExtensionContext, state: "ok" | "reconnecting" | "error" | "off") => void; formatError: (error: unknown) => string; getAgentName: () => string; getAgentAliases: () => Iterable; getAgentOwnerToken: () => string; getBotUserId: () => string | null; getThreads: () => Map; getPendingEyes: () => Map; getUnclaimedThreads: () => SinglePlayerUnclaimedThreads; pushInboxMessage: (message: InboxMessage) => void; setLastDmChannel: (channelId: string | null) => void; persistState: () => void; updateBadge: () => void; maybeDrainInboxIfIdle: (ctx: ExtensionContext) => boolean; resolveThreadChannel: (threadTs: string | undefined) => Promise; setSuggestedPrompts: (channelId: string, threadTs: string) => Promise; publishCurrentPinetHomeTab: (userId: string, ctx: ExtensionContext) => Promise; fetchSlackMessageByTs: (channel: string, messageTs: string) => Promise | null>; addReaction: (channel: string, ts: string, emoji: string) => Promise; removeReaction: (channel: string, ts: string, emoji: string) => Promise; resolveUser: (userId: string) => Promise; isUserAllowed: (userId: string) => boolean; getReactionCommand: (reactionName: string) => ReactionCommandTemplate | undefined; consumeConfirmationReply: (threadTs: string, text: string) => { approved: boolean; } | null; claimOwnedThread: (threadTs: string, channelId: string, source?: string) => void; beginThreadStatus?: (channelId: string, threadTs: string, status: string) => Promise; } export interface SinglePlayerRuntime { connect: (ctx: ExtensionContext) => Promise; disconnect: () => Promise; getBotUserId: () => string | null; isConnected: () => boolean; isShuttingDown: () => boolean; resetShutdownState: () => void; trackOwnedThread: (threadTs: string, channelId: string, source?: string) => void; getThreadContextPort: () => SlackToolsThreadContextPort; } export declare function createSinglePlayerRuntime(deps: SinglePlayerRuntimeDeps): SinglePlayerRuntime;