/**
* Microsoft Teams por Microsoft Graph — la fuente única de sus operaciones
* para el api, hw-nodes, el dashboard y el servidor MCP.
*
* ## Por qué un nodo aparte (2026-10-05)
*
* Ariel pidió las integraciones de Microsoft 365 SEPARADAS, un nodo por
* producto, cada uno con su action, su trigger y su AI toolkit, y una app de
* Entra por servicio («HostWebhook Teams»): Microsoft sólo deja revocar la app
* ENTERA, así que quitarle Teams a HostWebhook no le quita el correo ni los
* ficheros, ni al revés. Éste es el sexto, después de Outlook, Outlook
* Calendar, OneDrive, Excel y Word. Diseño: `plans/microsoft-teams.md`.
*
* ## Sólo cuentas de trabajo o escuela, y la primera vez un admin
*
* Graph no ofrece Teams a cuentas personales: todas las tablas de permisos
* dicen «Delegated (personal Microsoft account): Not supported». Por eso la
* credencial va con la autoridad `organizations` y hw-credentials rechaza un
* `tid` de consumidores.
*
* La credencial pide nueve permisos delegados, y tres de ellos
* (`ChannelMessage.Read.All`, `ChannelMessage.ReadWrite`, `Channel.Create`)
* piden consentimiento de ADMIN: la primera conexión de cada organización la
* aprueba un administrador de Microsoft 365, y después cualquiera de esa
* organización conecta sin pedir nada. Sin `ChannelMessage.Read.All` no hay
* ni leer canales ni trigger de canal, que es lo que se pidió.
*
* Todo va como la PERSONA conectada (permisos delegados): los mensajes salen
* con su nombre. Mandar como app por Graph sólo existe para migraciones.
*
* ## Dieciséis operaciones en cinco familias
*
* - **Teams & channels** — listar equipos y canales, crear un canal.
* - **Channel messages** — publicar, contestar en el hilo, leer los
* últimos de un canal.
* - **Chats** — listar chats, mandar y leer en uno, y el directo a una
* persona por su correo (abre o reutiliza el 1:1).
* - **Any message** — en un canal o en un chat (`where`, sin defecto): leer
* uno, editarlo, borrarlo, poner y quitar una reacción.
* - **People** — buscar personas de la organización.
*
* ## Los tipos de campo
*
* Sólo los que ya existen (`text`, `string`, `number`, `boolean`, `select`),
* para no tocar la clasificación de tipos del dashboard: qué campo pinta un
* selector (equipo, canal, chat, personas) lo decide la página por su NOMBRE
* (`teamId`, `channelId`, `chatId`, `mentions`, `userEmail`), como hace
* Outlook con `folder`. Ningún campo nace elegido: los `select` opcionales
* dicen su defecto en el hueco, sin marcarlo.
*/
export declare const TEAMS_OPERATIONS: readonly ["listTeams", "listChannels", "createChannel", "sendChannelMessage", "replyToChannelMessage", "listChannelMessages", "listChats", "sendChatMessage", "listChatMessages", "sendDirectMessage", "getMessage", "updateMessage", "deleteMessage", "addReaction", "removeReaction", "findUsers"];
export type TeamsOperation = (typeof TEAMS_OPERATIONS)[number];
/** Type guard — for DTOs and AI tool calls, where the input is untrusted. */
export declare function isTeamsOperation(value: unknown): value is TeamsOperation;
/**
* El tipo de credencial: el OAuth de la app «HostWebhook Teams» de Entra, sólo
* cuentas de trabajo o escuela. Un tipo por servicio de Microsoft, porque cada
* uno es su propia app: la credencial de Outlook no sirve aquí ni al revés.
*/
export declare const TEAMS_CREDENTIAL_TYPE = "microsoft_teams_oauth2";
/** Los grupos del desplegable, en su orden. */
export declare const TEAMS_FAMILIAS: readonly ["Teams & channels", "Channel messages", "Chats", "Any message", "People"];
export type TeamsOperationFamily = (typeof TEAMS_FAMILIAS)[number];
/** Un listado: lo más que se puede pedir (el `$top` máximo de Graph en mensajes). */
export declare const TEAMS_LISTADO_MAXIMO = 50;
/** Lo que se pide si no se dice. */
export declare const TEAMS_LISTADO_POR_DEFECTO = 20;
/** «Find people»: lo más que se puede pedir. */
export declare const TEAMS_PERSONAS_MAXIMAS = 25;
/**
* Menciones de personas por mensaje (las de `mentions` más las `correo`
* del contenido). Sin comprobar el tope real de Teams: con 20 no se cruza.
*/
export declare const TEAMS_MENCIONES_MAXIMAS = 20;
/**
* Caracteres de un mensaje. Sin comprobar: el límite que se cita de Teams es
* ~28 KB por mensaje; si Graph contesta 413/400 por tamaño, el error lo dice.
*/
export declare const TEAMS_CONTENIDO_MAXIMO = 28000;
/** El nombre de un canal (documentado por Graph): se comprueba antes de llamar. */
export declare const TEAMS_NOMBRE_DE_CANAL_MAXIMO = 50;
/**
* «Get message» con «Save inline images»: cuántas imágenes y cuántos bytes EN
* TOTAL por llamada. Los metadatos de Graph no traen tamaño ni tipo, así que
* se cuentan los bytes reales al bajar; lo que no entra sale en `skipped`.
*/
export declare const TEAMS_IMAGENES_MAXIMAS = 10;
export declare const TEAMS_IMAGENES_BYTES_MAX: number;
/** `importance` de un mensaje. Vacío = `normal`. `urgent` sigue avisando en los chats. */
export declare const TEAMS_IMPORTANCIAS: readonly ["normal", "high", "urgent"];
/** `body.contentType` de un mensaje. Vacío = `html`. */
export declare const TEAMS_FORMATOS_DE_CONTENIDO: readonly ["html", "text"];
/** `chatType` de un chat («List chats» filtra por él). Vacío = todos. */
export declare const TEAMS_TIPOS_DE_CHAT: readonly ["oneOnOne", "group", "meeting"];
/**
* `membershipType` de un canal nuevo. Vacío = `standard`. Sin `shared`: Graph
* lo crea en una operación asíncrona (202) que el nodo no sigue.
*/
export declare const TEAMS_TIPOS_DE_CANAL: readonly ["standard", "private"];
/**
* Dónde está el mensaje en la familia «Any message». Obligatorio y SIN defecto
* en single operation; en el toolkit, vacío = `chat` si viene `chat_id`, si no
* `channel` (lo infiere hw-nodes).
*/
export declare const TEAMS_DONDE: readonly ["channel", "chat"];
export interface TeamsParamSpec {
/** Field key — also the property name on operationConfig. */
name: string;
label: string;
/**
* Param type, so the dashboard renders the right control. Sólo los tipos
* que ya existen: el selector de equipo, canal, chat o personas lo pone la
* página por el NOMBRE del campo.
*/
type: 'text' | 'string' | 'number' | 'boolean' | 'select';
required?: boolean;
description: string;
/**
* El hueco vacío. En un `select` opcional dice lo que pasará si se deja sin
* elegir («HTML (default)»): lo enseña, no lo marca.
*/
placeholder?: string;
/** For `select`. */
options?: readonly string[];
/** For `number`. */
min?: number;
max?: number;
}
export interface TeamsOperationSpec {
label: string;
description: string;
/** The Graph route this maps to, so the mapping is checkable. */
apiRoute: string;
/** Changes something in Teams (as opposed to only reading it). */
writes?: boolean;
/** El grupo del desplegable. */
family: TeamsOperationFamily;
params: TeamsParamSpec[];
}
export declare const TEAMS_OPERATION_SPECS: Record;