/** * Additional channel adapter contracts (optional surfaces). */ import type { Config } from '../../config/schema.js'; import type { BindingRule } from '../../routing/bindings.js'; import type { SessionListReader } from '../../session/store-reader.js'; import type { PairingPendingView } from '../pairing/pairing-types.js'; export interface ChannelPairingAdapter { /** Credential-store channel key (`telegram` | `feishu` | `weixin`). */ pairingChannel: string; listPending(params: { cfg: Config; accountId?: string; }): PairingPendingView[]; approveByCode(params: { cfg: Config; accountId?: string; code: string; }): { ok: true; senderId: string; } | { ok: false; error: string; }; approveBySenderId(params: { cfg: Config; accountId?: string; senderId: string; }): { ok: true; senderId: string; } | { ok: false; error: string; }; revokePaired(params: { cfg: Config; accountId?: string; senderId: string; }): { ok: true; changed: boolean; } | { ok: false; error: string; }; } export interface ChannelAllowlistAdapter { resolveAllowFromIds?(params: { cfg: Config; accountId?: string; }): Array; } export interface ChannelThreadingAdapter { resolveAutoThreadId?(params: { to: string; replyToId?: string; }): string | undefined; topLevelReplyToMode?: string; } export interface ChannelLifecycleAdapter { onBeforeStart?(ctx: { cfg: Config; accountId: string; }): Promise; onAfterStart?(ctx: { cfg: Config; accountId: string; }): Promise; onBeforeStop?(ctx: { cfg: Config; accountId: string; }): Promise; onAfterStop?(ctx: { cfg: Config; accountId: string; }): Promise; } export interface ChannelHeartbeatAdapter { intervalMs: number; check(ctx: { cfg: Config; accountId: string; }): Promise<{ healthy: boolean; details?: string; }>; } export interface ChannelConfiguredBindingProvider { resolveBindings(cfg: Config, accountId?: string): BindingRule[]; } export interface ChannelMessagingAdapter { routeInbound?(params: { cfg: Config; raw: unknown; }): Promise; } export interface ChannelDirectoryAdapter { resolveDisplayName?(params: { cfg: Config; id: string; }): Promise; } export interface ChannelResolverAdapter { resolvePeer?(params: { cfg: Config; handle: string; }): Promise<{ id: string; } | undefined>; } export interface ChannelAuthAdapter { ensureSession?(params: { cfg: Config; accountId: string; }): Promise; } export interface ChannelElevatedAdapter { isElevated?(params: { cfg: Config; senderId: string; }): boolean; } export interface ChannelExecApprovalAdapter { requestApproval?(params: { cfg: Config; payload: unknown; }): Promise; } export interface ChannelAgentPromptAdapter { augmentSystemPrompt?(params: { cfg: Config; accountId?: string; }): string | undefined; } export type ChannelRuntimeActionPayload = { type: 'ok'; message?: string; configChanged?: boolean; [key: string]: unknown; } | { type: 'qr'; sessionKey: string; qrcodeUrl?: string; qrPayload?: string; statusAction?: string; pollIntervalMs?: number; expiresInSec?: number; message?: string; [key: string]: unknown; } | { type: 'poll'; phase: 'pending' | 'done' | 'unknown'; ok?: boolean; message?: string; accountId?: string; qrcodeUrl?: string; qrPayload?: string; qrStatus?: string; configChanged?: boolean; [key: string]: unknown; } | { type: 'diagnostics'; checks: unknown[]; [key: string]: unknown; } | { type: 'form'; schema: Record; values?: Record; submitAction: string; message?: string; [key: string]: unknown; }; export interface ChannelRuntimeActionResult { ok: boolean; payload?: ChannelRuntimeActionPayload; message?: string; /** Internal gateway-side config replacement; never returned to the browser. */ nextConfig?: Config; } /** Gateway/CLI control-plane actions declared by extension manifests. */ export interface ChannelRuntimeActionAdapter { runAction(params: { cfg: Config; locale?: string; actionId: string; accountId?: string; input?: unknown; }): Promise; } /** * Resolves a cron job `delivery.to` string into a normalized chat target for outbound. */ export interface ChannelCronDeliveryAdapter { normalizeDeliveryTarget(to: string, sessionStore?: SessionListReader): Promise<{ chatId: string; accountId?: string; metadata?: Record; }>; } /** Interactive credential login for channels that support terminal setup. */ export interface ChannelCliLoginAdapter { runLogin(params: { configPath: string; verbose?: boolean; timeoutMs?: number; accountId?: string; writeConfig?: boolean; }): Promise<{ ok: boolean; message?: string; accountId?: string; cancelled?: boolean; }>; } /** Snapshot of channel-specific settings for gateway `/api/config` (implementations should redact secrets). */ export interface ChannelConfigSurfaceAdapter { buildConfigSurface(cfg: Config): Record; } /** Interactive onboarding entry for a channel (alternative to declarative {@link ChannelSetupWizard}). */ export interface ChannelOnboardAdapter { isConfigured(config: Config): boolean; configure(config: Config): Promise; } export interface SetupStatus { ok: boolean; detail?: string; } export interface ChannelSetupWizard { channel: string; status?: { check(cfg: Config, accountId?: string): Promise; }; envShortcut?: { envVar: string; configPath: string; }; credentials: Array<{ key: string; label: string; type: 'text' | 'password'; validate?: (value: string) => string | null; hint?: string; }>; dmPolicy?: { options: Array<{ value: string; label: string; description: string; }>; default: string; }; allowFrom?: { hint: string; format: string; }; finalize?: { validate(cfg: Config): Promise<{ ok: boolean; error?: string; }>; message: string; }; }