/** Discord interaction types (subset used here) */ export declare const DiscordInteractionType: { readonly Ping: 1; readonly ApplicationCommand: 2; readonly MessageComponent: 3; readonly ApplicationCommandAutocomplete: 4; readonly ModalSubmit: 5; }; /** Discord interaction response types */ export declare const DiscordInteractionResponseType: { readonly Pong: 1; readonly ChannelMessageWithSource: 4; readonly DeferredChannelMessageWithSource: 5; readonly DeferredUpdateMessage: 6; }; export interface DiscordInteraction { id: string; type: number; applicationId: string; token: string; guildId?: string | undefined; channelId?: string | undefined; userId: string; commandName?: string | undefined; commandOptions?: Array<{ name: string; value: unknown; }> | undefined; raw: Record; } export interface DiscordOAuthAuthorizeOptions { readonly clientId: string; readonly redirectUri?: string | undefined; readonly scopes?: readonly string[] | undefined; readonly permissions?: string | undefined; readonly guildId?: string | undefined; readonly disableGuildSelect?: boolean | undefined; readonly state?: string | undefined; } export interface DiscordApplicationCommandOption { readonly type: number; readonly name: string; readonly description: string; readonly required?: boolean | undefined; } export interface DiscordApplicationCommand { readonly id?: string | undefined; readonly application_id?: string | undefined; readonly guild_id?: string | undefined; readonly name: string; readonly description: string; readonly type?: number | undefined; readonly options?: readonly DiscordApplicationCommandOption[] | undefined; readonly default_member_permissions?: string | null | undefined; readonly dm_permission?: boolean | undefined; } export interface DiscordGatewayBotResponse { readonly url: string; readonly shards: number; readonly session_start_limit?: Record | undefined; } export interface DiscordGatewayDispatch { readonly op: number; readonly t?: string | undefined; readonly s?: number | undefined; readonly d?: Record | null | undefined; } export interface DiscordGatewayClientOptions { readonly token: string; readonly integration: DiscordIntegration; readonly intents?: number | undefined; readonly gatewayUrl?: string | undefined; readonly onDispatch: (dispatch: DiscordGatewayDispatch, client: DiscordGatewayClient) => void | Promise; readonly WebSocketImpl?: typeof WebSocket | undefined; /** * The gateway closed on its own, not because `stop()` was called. * * A node under LAN leadership holds the Discord surface on the strength of * being able to read it, and a dropped gateway means it cannot. Staying * nominally responsible while reading nothing is the starvation this design * exists to avoid, so the holder stands down and another machine takes it. */ readonly onClosed?: ((reason: string) => void) | undefined; } export declare const DiscordGatewayOpcode: { readonly Dispatch: 0; readonly Heartbeat: 1; readonly Identify: 2; readonly Hello: 10; readonly HeartbeatAck: 11; }; export declare const DiscordGatewayIntent: { readonly Guilds: number; readonly GuildMessages: number; readonly DirectMessages: number; readonly MessageContent: number; }; /** * DiscordIntegration, handles inbound interaction verification/parsing and * outbound message posting for Discord slash commands and webhooks. * * Env vars: * DISCORD_WEBHOOK_URL , webhook URL for outbound posting * DISCORD_BOT_TOKEN , bot token for Discord API calls * DISCORD_PUBLIC_KEY , Ed25519 public key for interaction verification */ export declare class DiscordIntegration { private webhookUrl?; private botToken?; constructor(webhookUrl?: string | undefined, botToken?: string | undefined); static buildOAuthAuthorizeUrl(options: DiscordOAuthAuthorizeOptions): string; static buildGoodVibesCommand(): DiscordApplicationCommand; getGatewayBot(token?: string | undefined): Promise; getCurrentBotUser(token?: string | undefined): Promise>; listGuildChannels(guildId: string, token?: string | undefined): Promise>>; listGuildMembers(guildId: string, options?: { readonly token?: string; readonly limit?: number; readonly after?: string; }): Promise>>; registerGlobalCommand(applicationId: string, command: DiscordApplicationCommand, token?: string | undefined): Promise; registerGuildCommand(applicationId: string, guildId: string, command: DiscordApplicationCommand, token?: string | undefined): Promise; bulkOverwriteGuildCommands(applicationId: string, guildId: string, commands: readonly DiscordApplicationCommand[], token?: string | undefined): Promise; /** * Verify an inbound Discord interaction using Ed25519. * Discord signs: timestamp + body with the application's public key. */ verifySignature(body: string, signature: string, timestamp: string, publicKey: string): Promise; /** * Parse an inbound Discord interaction payload into a typed DiscordInteraction. */ parseInteraction(body: Record): DiscordInteraction; /** * Post a message via Discord webhook URL. */ postWebhook(content: string, embeds?: unknown[], url?: string): Promise; /** * Post a message to a channel via the Discord Bot API. * Requires DISCORD_BOT_TOKEN. */ postMessage(channelId: string, content: string, embeds?: unknown[]): Promise; /** * Respond to an interaction via the Discord interactions endpoint. * Use this to send the deferred acknowledgment or a follow-up. */ respondToInteraction(interactionId: string, interactionToken: string, type: number, data?: Record): Promise; /** * Edit the original deferred interaction response (follow-up). */ editOriginalResponse(applicationId: string, interactionToken: string, content: string, embeds?: unknown[]): Promise; private apiFetch; /** * Format an agent result as a Discord embed object. */ formatAgentResult(agentId: string, task: string, result: string): unknown; /** * Format a session summary as a Discord embed object. */ formatSessionSummary(sessionId: string, messageCount: number, tokensUsed: number): unknown; private hexToBytes; private validateSnowflake; } export declare class DiscordGatewayClient { private readonly options; private socket; private heartbeat; private sequence; private started; /** True while `stop()` is closing the socket, so its close is not a loss. */ private stopping; private readonly WebSocketImpl; constructor(options: DiscordGatewayClientOptions); start(): Promise; stop(): void; send(op: number, d: unknown): void; get isStarted(): boolean; private handleMessage; private identify; private startHeartbeat; private cleanup; } //# sourceMappingURL=discord.d.ts.map