import { Client } from "discord.js"; import { type MessengerAdapter, type CommandHandler, type TurnControls, type ApprovalRequest, type ApprovalVerdict } from "./base.js"; export declare class DiscordAdapter implements MessengerAdapter { readonly platform = "discord"; readonly channelNames: string[]; private client; /** v0.8 §3.5 — resolved bot user's handle. Null until `clientReady` fires. */ private ownHandle; private ownOrgSlug; /** v1.3.0 Part B — turn-control hook (🛑 button → cancelTurn). */ private turnControls; startBot(onCommand: CommandHandler, controls?: TurnControls): Promise; startNotifier(): Promise; sendToChannel(productConfig: Record, channelName: string, text: string, title?: string, threadName?: string): Promise; setupChannels(productConfig: Record): Promise; getClient(): Client | null; /** v1.3.0 Part A/B — the handle this bot is bound to (command-). */ getOwnHandle(): string | null; /** * v1.3.0 Part A — post a dev-confirm approval card to `command-` and * resolve with the user's verdict. Called out-of-turn by the dev-confirm * bridge (not tied to an inbound message). Returns "n" when the channel can't * be resolved (fail-safe: no approval surface ⇒ block). */ postApprovalToCommandChannel(handle: string, req: ApprovalRequest, timeoutMs: number): Promise; private findCommandChannel; /** * v0.8 §3.5 — the per-user channel pair this bot owns once bound to a * handle: `command-` / `works-`. Empty when unbound (legacy * path falls back to DEFAULT_CHANNELS). Single source of truth for both * channel creation (`ensureChannels`) and config persistence * (`syncGuildProductMapping`). * * v1.2.10 — the `git-` feed (v1.2.9 Part B) was dropped; SoloSquad * does not create or notify a git channel. Push approval lives in the * dev-confirm gate (v1.3.0); push notifications are the user's own * GitHub→messenger webhook. */ private boundChannelNames; private ensureChannels; private ensureSystemThreads; private ensureThread; /** * v1.0.4 — bind the current Discord guild to the bot's own org, creating * `/discord/config.yaml` on first run if missing. * * Pre-v1.0.4 silently early-returned when `discord/config.yaml` did not * exist. The file was never scaffolded at org creation (`scaffoldOrg` * makes the empty `discord/` directory but no yaml inside), so for any * user who completed `solosquad init` without manually authoring this * file, binding never happened — `getProductByGuild` then returned null * and every Discord message produced "No product linked to this server". * v1.0.3 fixed the name-match heuristic but not this file-existence bail. * * v1.0.4: load-or-empty pattern + auto-write. The bot already knows * (a) its own org from `ownOrgSlug`, (b) the guild it's connected to, * and (c) the channels it just created via `ensureChannels` — all the * info needed to write the config. No reason to require a pre-existing * file. */ private syncGuildProductMapping; /** * v1.0.4 — diagnose *which hop* of the 5-stage Discord ↔ org binding * chain failed. Called from the messageCreate handler when * `getProductByGuild` returns null. Output is a single-line human- * readable reason that goes into both console logs and the user-facing * channel reply. * * Per the 9-reference research (Best Practice 5): silent / generic * failure messages are the primary cause of repeated regression. Each * SoloSquad release v1.0.2-v1.0.4 fixed one hop's silent fail; this * helper makes future regressions immediately attributable. */ private diagnoseProductByGuildFailure; /** * v1.0.4 — resolve which org owns a given Discord guild. Trusts the bot's * own org (`ownOrgSlug`) when set; relies on `syncGuildProductMapping` * having written `config.guild_id` (which v1.0.4 always does on startup * since the auto-write happens unconditionally now). */ private getProductByGuild; }