/**
 * WhatsApp MCP server — exposes WhatsApp lifecycle tools to the admin agent.
 *
 * Tools call the platform's Hono API routes (localhost) which manage the
 * Baileys connection lifecycle in the server process.
 */
import { initStderrTee } from "../../../../lib/mcp-stderr-tee/dist/index.js";
initStderrTee("whatsapp");
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { callApi as rawCallApi } from "./call-api.js";
import { requirePortEnv } from "../../../../lib/require-port-env/dist/index.js";
// Task 142 — PLATFORM_PORT is the internal loopback port, stamped on
// the claude-session-manager systemd unit and forwarded by the
// per-spawn mcp.json env block written by pty-spawner.
//
// Task 265 — read deferred to first tool invocation. CC's plugin-system
// enumerates tools/list by spawning this server with empty env; any
// module-init throw empties plugin registry #1. The cache is populated
// on first successful resolve, then reused for every subsequent call.
let cachedBaseUrl = null;
function getBaseUrl(toolName) {
    if (cachedBaseUrl !== null)
        return cachedBaseUrl;
    try {
        const port = requirePortEnv("PLATFORM_PORT", { tag: "whatsapp" });
        cachedBaseUrl = `http://127.0.0.1:${port}`;
        return cachedBaseUrl;
    }
    catch (err) {
        process.stderr.write(`[whatsapp] missing-port-env tool=${toolName} action=tool-result-error\n`);
        throw err;
    }
}
// Maxy account ID — used for file path validation in send-document.
const MAXY_ACCOUNT_ID = process.env.ACCOUNT_ID;
const server = new McpServer({
    name: "maxy-whatsapp",
    version: "0.1.0",
});
function callApi(toolName, path, method = "POST", body) {
    return rawCallApi(getBaseUrl(toolName), path, method, body);
}
function textResult(text, isError = false) {
    return {
        content: [{ type: "text", text }],
        ...(isError ? { isError: true } : {}),
    };
}
// ─── whatsapp-login-start ──────────────────────────────────────────────
server.tool("whatsapp-login-start", "Start WhatsApp QR code pairing. Initiates a Baileys WebSocket and generates a QR code the user scans with their phone. The tool returns the QR as a scannable ASCII block in its result — show that block verbatim to the operator so they can scan it.", {
    accountId: z.string().optional().describe('Account ID (default: "default")'),
    force: z.boolean().optional().describe("Force re-link even if already connected"),
}, async ({ accountId, force }) => {
    try {
        const result = await callApi("whatsapp-login-start", "/api/whatsapp/login/start", "POST", { accountId, force });
        if (result.error)
            return textResult(`Login start failed: ${result.error}`, true);
        let response = result.message;
        if (result.qrTerminal) {
            // PTY stdout is the only surface — print the QR as a scannable ASCII
            // block (fenced so the operator's terminal renders it monospaced).
            // Show this block verbatim to the operator so they can scan it.
            response += `\n\nScan this QR in WhatsApp → Linked Devices:\n\n\`\`\`\n${result.qrTerminal}\`\`\``;
            response += "\n\nThen call whatsapp-login-wait to poll for scan completion.";
        }
        else if (result.qrRaw) {
            response += "\n\nQR generated but could not be rendered for the terminal. Call whatsapp-login-wait to poll for scan completion.";
        }
        if (result.selfPhone) {
            response += `\nLinked phone: ${result.selfPhone}`;
        }
        return textResult(response);
    }
    catch (err) {
        return textResult(`Login start failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-login-wait ───────────────────────────────────────────────
server.tool("whatsapp-login-wait", "Wait for WhatsApp QR code to be scanned and connection to be established. Call after whatsapp-login-start. Polls for up to 60 seconds.", {
    accountId: z.string().optional().describe('Account ID (default: "default")'),
    timeoutMs: z.number().optional().describe("Max wait time in ms (default: 60000)"),
}, async ({ accountId, timeoutMs }) => {
    try {
        const result = await callApi("whatsapp-login-wait", "/api/whatsapp/login/wait", "POST", { accountId, timeoutMs });
        if (result.error)
            return textResult(`Login wait failed: ${result.error}`, true);
        let response = result.message;
        if (result.connected && result.selfPhone) {
            response += `\nLinked phone: ${result.selfPhone}`;
        }
        return textResult(response);
    }
    catch (err) {
        return textResult(`Login wait failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-status ───────────────────────────────────────────────────
server.tool("whatsapp-status", "Get WhatsApp connection status for all linked accounts. Shows connected/disconnected state, linked phone number, and reconnection attempts.", {}, async () => {
    try {
        const result = await callApi("whatsapp-status", "/api/whatsapp/status", "GET");
        if (result.error)
            return textResult(`Status check failed: ${result.error}`, true);
        const accounts = result.accounts ?? [];
        if (accounts.length === 0) {
            return textResult("No WhatsApp accounts configured. Say \"connect WhatsApp\" to get started.");
        }
        const lines = accounts.map((a) => {
            const status = a.connected ? "✓ Connected" : "✗ Disconnected";
            const phone = a.selfPhone ? ` (${a.selfPhone})` : "";
            const name = a.accountName ? ` — ${a.accountName}` : "";
            const error = a.lastError ? ` — ${a.lastError}` : "";
            const retries = a.reconnectAttempts > 0 ? ` [${a.reconnectAttempts} reconnect attempts]` : "";
            return `${a.accountId}${name}: ${status}${phone}${error}${retries}`;
        });
        return textResult(lines.join("\n"));
    }
    catch (err) {
        return textResult(`Status check failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-activity ────────────────────────────────────────────────
server.tool("whatsapp-activity", "Get WhatsApp channel activity — message counts (inbound and outbound) and recent events since last restart. Shows per-account usage metrics so you can report on channel activity when asked. Counters reset on server restart.", {
    accountId: z.string().optional().describe('Filter to a specific account (default: all accounts)'),
}, async ({ accountId }) => {
    try {
        const query = accountId ? `?accountId=${encodeURIComponent(accountId)}` : "";
        const result = await callApi("whatsapp-activity", `/api/whatsapp/activity${query}`, "GET");
        if (result.error)
            return textResult(`Activity check failed: ${result.error}`, true);
        const accounts = result.accounts ?? [];
        if (accounts.length === 0) {
            return textResult("No WhatsApp activity recorded since last restart.");
        }
        const lines = [];
        for (const a of accounts) {
            const lastAt = a.lastEventAt ? new Date(a.lastEventAt).toISOString() : "never";
            lines.push(`${a.accountId}: ${a.total} messages (${a.inbound} inbound, ${a.outbound} outbound) — last activity: ${lastAt}`);
        }
        const events = result.recentEvents ?? [];
        if (events.length > 0) {
            lines.push("");
            lines.push(`Recent events (${events.length}):`);
            // Show last 10 for readability
            const recent = events.slice(-10);
            for (const e of recent) {
                const ts = new Date(e.timestamp).toISOString();
                lines.push(`  ${ts} ${e.direction} account=${e.accountId} jid=${e.jid}${e.messageType ? ` type=${e.messageType}` : ""}`);
            }
            if (events.length > 10) {
                lines.push(`  ... and ${events.length - 10} more events`);
            }
        }
        return textResult(lines.join("\n"));
    }
    catch (err) {
        return textResult(`Activity check failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-disconnect ───────────────────────────────────────────────
server.tool("whatsapp-disconnect", "Disconnect a WhatsApp account. Closes the Baileys WebSocket connection cleanly.", {
    accountId: z.string().optional().describe('Account ID to disconnect (default: "default")'),
}, async ({ accountId }) => {
    try {
        const result = await callApi("whatsapp-disconnect", "/api/whatsapp/disconnect", "POST", { accountId });
        if (result.error)
            return textResult(`Disconnect failed: ${result.error}`, true);
        return textResult(`WhatsApp account "${result.accountId}" disconnected.`);
    }
    catch (err) {
        return textResult(`Disconnect failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-send ─────────────────────────────────────────────────────
server.tool("whatsapp-send", "Send a WhatsApp message to a phone number or group. The target can be an E.164 phone number or a WhatsApp group JID.", {
    to: z.string().describe("Target phone number (E.164) or group JID"),
    text: z.string().describe("Message text to send"),
    accountId: z.string().optional().describe('Account to send from (default: "default")'),
}, async ({ to, text, accountId }) => {
    try {
        const result = await callApi("whatsapp-send", "/api/whatsapp/send", "POST", { to, text, accountId });
        if (result.error)
            return textResult(`Send failed: ${result.error}`, true);
        return textResult(`Message sent via WhatsApp${result.messageId ? ` (ID: ${result.messageId})` : ""}`);
    }
    catch (err) {
        return textResult(`Send failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-config ──────────────────────────────────────────────────
server.tool("whatsapp-config", [
    "Manage WhatsApp configuration. Actions:",
    "  - add-admin-phone (register a phone as admin — messages from it route to admin agent)",
    "  - remove-admin-phone (demote to public routing)",
    "  - list-admin-phones (show current admin phones)",
    "  - set-public-agent (set the top-level public-agent slug for non-admin DMs and groups without an override; requires `slug`)",
    "  - get-public-agent (show the resolved public-agent slug; pass optional `groupJid` to resolve the per-group → per-account → top-level chain)",
    "  - set-group-public-agent (set a per-group public-agent override; requires `groupJid` and `slug`; optional `accountId` defaults to 'default')",
    "  - unset-group-public-agent (remove a per-group override; requires `groupJid`; optional `accountId`)",
    "  - list-public-agents (slug and display name for each available public agent)",
    "  - update-config (change any WhatsApp config field — pass `fields` as a JSON string of field/value pairs)",
    "  - get-config (return the full current WhatsApp config object)",
    "  - schema (return all config field definitions — names, types, defaults, descriptions, constraints)",
    "  - list-groups (return WhatsApp groups the account belongs to — names, JIDs, participant counts)",
    "Per-group config keys (under `accounts.<id>.groups.<jid>`): `activation` ('always' | 'mention' | 'off') and `publicAgent` (slug). No other keys are accepted.",
    "Public-agent precedence at routing time: per-group override → per-account default → top-level default.",
    "Phone numbers must be E.164 format (e.g. +441234567890).",
].join("\n"), {
    action: z.enum([
        "add-admin-phone",
        "remove-admin-phone",
        "list-admin-phones",
        "set-public-agent",
        "get-public-agent",
        "set-group-public-agent",
        "unset-group-public-agent",
        "list-public-agents",
        "update-config",
        "get-config",
        "schema",
        "list-groups",
    ]).describe("The config action to perform"),
    phone: z.string().optional().describe("Phone number in E.164 format (required for add/remove admin phone)"),
    slug: z.string().optional().describe("Agent slug (required for set-public-agent and set-group-public-agent)"),
    groupJid: z.string().optional().describe("Group JID ending in @g.us (required for set-group-public-agent and unset-group-public-agent; optional for get-public-agent to resolve the per-group chain)"),
    fields: z.string().optional().describe('JSON string of config fields to update (required for update-config, e.g. \'{"dmPolicy":"open","allowFrom":["*"]}\')'),
    accountId: z.string().optional().describe('Account ID (default: "default"). Used by list-groups, set-group-public-agent, unset-group-public-agent, get-public-agent (per-group resolution).'),
}, async ({ action, phone, slug, groupJid, fields, accountId }) => {
    try {
        // Parse fields JSON string for update-config
        let parsedFields;
        if (action === "update-config" && fields) {
            try {
                parsedFields = JSON.parse(fields);
            }
            catch {
                return textResult('Invalid JSON in "fields" parameter. Expected a JSON object, e.g. {"dmPolicy":"open","allowFrom":["*"]}', true);
            }
        }
        const result = await callApi("whatsapp-config", "/api/whatsapp/config", "POST", { action, phone, slug, groupJid, fields: parsedFields, accountId });
        if (!result.ok)
            return textResult(result.error ?? "Config operation failed.", true);
        if (action === "list-admin-phones") {
            const phones = result.phones ?? [];
            if (phones.length === 0)
                return textResult("No admin phones configured. Use add-admin-phone to register one.");
            return textResult(`Admin phones:\n${phones.map((p) => `  ${p}`).join("\n")}`);
        }
        if (action === "get-public-agent") {
            const agentSlug = result.slug;
            const source = result.source;
            if (!agentSlug) {
                return textResult(groupJid
                    ? `No public agent resolves for group ${groupJid}. Set one with set-group-public-agent, or set a top-level fallback with set-public-agent.`
                    : "No public agent configured for WhatsApp. Use set-public-agent to assign one.");
            }
            const sourceLabel = source ? ` (source: ${source})` : "";
            return textResult(groupJid
                ? `Resolved public agent for group ${groupJid}: ${agentSlug}${sourceLabel}`
                : `WhatsApp public agent: ${agentSlug}${sourceLabel}`);
        }
        if (action === "list-public-agents") {
            const agents = result.agents ?? [];
            if (agents.length === 0)
                return textResult("No public agents found. Create a public agent first using the public-agent-manager skill.");
            const lines = agents.map((a) => `  ${a.slug} — ${a.displayName}`);
            return textResult(`Public agents (${agents.length}):\n${lines.join("\n")}`);
        }
        if (action === "schema") {
            return textResult(result.text ?? "Schema unavailable.");
        }
        if (action === "get-config") {
            const waConfig = result.config;
            if (!waConfig)
                return textResult("No WhatsApp config found. Connect WhatsApp first.");
            return textResult(JSON.stringify(waConfig, null, 2));
        }
        if (action === "list-groups") {
            const groups = result.groups ?? [];
            if (groups.length === 0)
                return textResult("No WhatsApp groups found for this account. Groups appear once the connected phone joins them.");
            const lines = groups.map((g) => `  ${g.name} (${g.participantCount} members) — ${g.jid}`);
            return textResult(`WhatsApp groups (${groups.length}):\n${lines.join("\n")}`);
        }
        return textResult(result.message ?? "Done.");
    }
    catch (err) {
        return textResult(`Config operation failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-send-document ───────────────────────────────────────────
server.tool("whatsapp-send-document", "Send a file as a WhatsApp document message. The file is read from disk and sent as a downloadable document attachment. The file must be within the account directory tree.", {
    to: z.string().describe("Target phone number (E.164) or group JID"),
    filePath: z.string().describe("Absolute path to the file to send"),
    caption: z.string().optional().describe("Optional caption text to accompany the document"),
    accountId: z.string().optional().describe('Account to send from (default: "default")'),
}, async ({ to, filePath, caption, accountId }) => {
    try {
        const result = await callApi("whatsapp-send-document", "/api/whatsapp/send-document", "POST", {
            to, filePath, caption, accountId, maxyAccountId: MAXY_ACCOUNT_ID,
        });
        if (result.error)
            return textResult(`Send failed: ${result.error}`, true);
        return textResult(`Document sent via WhatsApp${result.messageId ? ` (ID: ${result.messageId})` : ""}`);
    }
    catch (err) {
        return textResult(`Send failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-conversations ──────────────────────────────────────────
server.tool("whatsapp-conversations", "List WhatsApp conversations with recent message activity. Returns each conversation's JID, type (group or DM), last message timestamp, and message count. Messages are from the in-memory store (clears on server restart). Use this to see which conversations have recent activity before retrieving specific messages with whatsapp-messages.", {
    accountId: z.string().optional().describe('Account ID (default: "default")'),
}, async ({ accountId }) => {
    try {
        const id = accountId ?? "default";
        console.error(`[whatsapp-mcp] whatsapp-conversations called for account ${id}`);
        const result = await callApi("whatsapp-conversations", `/api/whatsapp/conversations?accountId=${encodeURIComponent(id)}`, "GET");
        if (result.error)
            return textResult(`Failed to list conversations: ${result.error}`, true);
        const conversations = result.conversations ?? [];
        if (conversations.length === 0) {
            return textResult("No conversations with stored messages. Messages are stored when they arrive while the server is running.");
        }
        const lines = conversations.map((c) => {
            const type = c.type === "group" ? "[group]" : "[DM]";
            const ts = c.lastMessageTimestamp
                ? new Date(c.lastMessageTimestamp * 1000).toISOString()
                : "unknown";
            return `${type} ${c.jid} — ${c.messageCount} messages, last: ${ts}`;
        });
        return textResult(`Conversations (${conversations.length}):\n${lines.join("\n")}`);
    }
    catch (err) {
        console.error(`[whatsapp-mcp] whatsapp-conversations error: ${err instanceof Error ? err.message : String(err)}`);
        return textResult(`Failed to list conversations: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-messages ───────────────────────────────────────────────
server.tool("whatsapp-messages", "Retrieve stored WhatsApp messages for a specific conversation. Returns messages in chronological order (oldest first) with sender, body, timestamp, and reply context. Messages are from the in-memory store (clears on server restart). Use whatsapp-conversations first to see available JIDs.", {
    jid: z.string().describe("Conversation JID (phone@s.whatsapp.net for DMs, id@g.us for groups)"),
    accountId: z.string().optional().describe('Account ID (default: "default")'),
    limit: z.number().optional().describe("Max number of most recent messages to return (default: all)"),
}, async ({ jid, accountId, limit }) => {
    try {
        const id = accountId ?? "default";
        console.error(`[whatsapp-mcp] whatsapp-messages called for account ${id} jid=${jid} limit=${limit ?? "all"}`);
        const params = new URLSearchParams({ accountId: id, jid });
        if (limit !== undefined)
            params.set("limit", String(limit));
        const result = await callApi("whatsapp-messages", `/api/whatsapp/messages?${params}`, "GET");
        if (result.error)
            return textResult(`Failed to get messages: ${result.error}`, true);
        const messages = result.messages ?? [];
        if (messages.length === 0) {
            return textResult(`No stored messages for ${jid}. Messages appear when they arrive while the server is running.`);
        }
        const lines = messages.map((m) => {
            const ts = new Date(m.timestamp * 1000).toISOString();
            const direction = m.fromMe ? "→" : "←";
            const sender = m.senderName ? `${m.senderName} (${m.sender})` : m.sender;
            let line = `[${ts}] ${direction} ${sender}: ${m.body}`;
            if (m.quoted?.body) {
                line += `\n  ↳ replying to: "${m.quoted.body}"`;
            }
            return line;
        });
        return textResult(`Messages for ${jid} (${messages.length}):\n${lines.join("\n")}`);
    }
    catch (err) {
        console.error(`[whatsapp-mcp] whatsapp-messages error: ${err instanceof Error ? err.message : String(err)}`);
        return textResult(`Failed to get messages: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-conversation-graph-state ───────────────────────────────
//
// Sub-fix 2 of the comprehensive stream-log fix. Deterministic graph-read
// for "messages persisted to this conversation". Replaces ad-hoc cypher
// composition by the agent — the cypher lives in the platform route
// (/api/whatsapp/conversation-graph-state) and uses the writer-known
// filter (m:Message:WhatsAppMessage)-[:PART_OF]->(c {sessionKey}).
//
// Pass either `sessionKey` (direct) or `jid` (+ optional `accountId`) to
// derive the public-agent sessionKey. The divergence header surfaces
// graph-row vs in-memory-store count drift as an operator-visible signal.
server.tool("whatsapp-conversation-graph-state", [
    "Read persisted graph state for a WhatsApp conversation deterministically.",
    "Returns the conversation's `sessionId` and every `:Message:WhatsAppMessage` row attached via `(:PART_OF)->`, plus the in-memory store's row count for divergence visibility.",
    "Use this whenever the question is 'what messages got persisted to <jid> / <sessionKey>?'. Do not compose cypher by hand — the cypher in the platform uses the writer-known filter (sessionKey on the Conversation node, not jid match on the Message node).",
    "Input: pass `jid` (e.g. group `120363...@g.us` or DM `44...@s.whatsapp.net`) — the platform derives the public-agent sessionKey. For admin-agent sessionKeys, pass `sessionKey` directly.",
].join("\n"), {
    jid: z.string().optional().describe("Conversation JID (group `…@g.us` or DM `…@s.whatsapp.net`). Mutually exclusive with sessionKey."),
    sessionKey: z.string().optional().describe("Direct sessionKey (e.g. `whatsapp:default:group:<jid>` or `whatsapp:default` for admin). Mutually exclusive with jid."),
    accountId: z.string().optional().describe('Account ID (default: "default") — used only when deriving sessionKey from jid.'),
}, async ({ jid, sessionKey, accountId }) => {
    try {
        if (!jid && !sessionKey) {
            return textResult("Provide either `jid` or `sessionKey`.", true);
        }
        const id = accountId ?? "default";
        const params = new URLSearchParams();
        if (sessionKey)
            params.set("sessionKey", sessionKey);
        if (jid) {
            params.set("jid", jid);
            params.set("accountId", id);
        }
        const result = await callApi("whatsapp-conversation-graph-state", `/api/whatsapp/conversation-graph-state?${params}`, "GET");
        if (result.error)
            return textResult(`Graph state failed: ${result.error}`, true);
        // Side-fetch in-memory store count for divergence visibility.
        let memoryCount = null;
        if (jid) {
            try {
                const mem = await callApi("whatsapp-conversation-graph-state", `/api/whatsapp/messages?accountId=${encodeURIComponent(id)}&jid=${encodeURIComponent(jid)}`, "GET");
                if (Array.isArray(mem.messages))
                    memoryCount = mem.messages.length;
            }
            catch {
                // Best-effort — divergence header omits memory count if the call fails.
            }
        }
        const rows = result.graphRows ?? [];
        const headerParts = [
            `sessionKey=${result.sessionKey}`,
            `sessionId=${result.sessionId ?? "null"}`,
            `graphRows=${rows.length}`,
        ];
        if (memoryCount !== null)
            headerParts.push(`memoryRows=${memoryCount}`);
        headerParts.push(`ms=${result.ms}`);
        const header = `[${headerParts.join(" ")}]`;
        if (rows.length === 0) {
            return textResult([
                header,
                "",
                "No messages persisted on this Conversation node.",
                memoryCount !== null && memoryCount > 0
                    ? `In-memory store has ${memoryCount} message(s) — divergence: writer pipeline may not have flushed to graph yet (or the conversation node is missing).`
                    : "In-memory store also empty (or could not be queried).",
            ].join("\n"));
        }
        const lines = rows.map((r) => {
            const ts = r.dateSent ? r.dateSent : "(no-date)";
            const direction = r.fromMe ? "→" : "←";
            const sender = r.senderTelephone ?? "(unknown)";
            return `[${ts}] ${direction} ${sender}: ${r.body ?? "(no body)"}`;
        });
        return textResult([header, "", ...lines].join("\n"));
    }
    catch (err) {
        return textResult(`Graph state failed: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── whatsapp-group-info ─────────────────────────────────────────────
server.tool("whatsapp-group-info", "Get metadata for a WhatsApp group: subject (name), description, participant list with admin flags, creation date, and owner. Queries WhatsApp servers directly (requires active connection). The JID must be a group JID ending in @g.us — use whatsapp-conversations or whatsapp-config action list-groups to find group JIDs.", {
    jid: z.string().describe("Group JID (must end with @g.us)"),
    accountId: z.string().optional().describe('Account ID (default: "default")'),
}, async ({ jid, accountId }) => {
    try {
        const id = accountId ?? "default";
        console.error(`[whatsapp-mcp] whatsapp-group-info called for account ${id} jid=${jid}`);
        const params = new URLSearchParams({ accountId: id, jid });
        const result = await callApi("whatsapp-group-info", `/api/whatsapp/group-info?${params}`, "GET");
        if (result.error)
            return textResult(`Failed to get group info: ${result.error}`, true);
        const parts = (result.participants ?? []).map((p) => {
            const role = p.admin === "superadmin" ? " (super admin)" : p.admin === "admin" ? " (admin)" : "";
            return `  ${p.jid}${role}`;
        });
        const lines = [
            `Group: ${result.subject}`,
            result.description ? `Description: ${result.description}` : null,
            result.owner ? `Owner: ${result.owner}` : null,
            result.creation ? `Created: ${new Date(result.creation * 1000).toISOString()}` : null,
            `Participants (${result.participantCount}):`,
            ...parts,
        ].filter(Boolean);
        return textResult(lines.join("\n"));
    }
    catch (err) {
        console.error(`[whatsapp-mcp] whatsapp-group-info error: ${err instanceof Error ? err.message : String(err)}`);
        return textResult(`Failed to get group info: ${err instanceof Error ? err.message : String(err)}`, true);
    }
});
// ─── Start server ──────────────────────────────────────────────────────
const transport = new StdioServerTransport();
await server.connect(transport);
//# sourceMappingURL=index.js.map