chat 4.16.0 → 4.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -159,6 +159,34 @@ function root(children) {
159
159
  return { type: "root", children };
160
160
  }
161
161
  var BaseFormatConverter = class {
162
+ renderList(node, depth, nodeConverter, unorderedBullet = "-") {
163
+ const indent = " ".repeat(depth);
164
+ const start = node.start ?? 1;
165
+ const lines = [];
166
+ for (const [i, item] of getNodeChildren(node).entries()) {
167
+ const prefix = node.ordered ? `${start + i}.` : unorderedBullet;
168
+ let isFirstContent = true;
169
+ for (const child of getNodeChildren(item)) {
170
+ if (isListNode(child)) {
171
+ lines.push(
172
+ this.renderList(child, depth + 1, nodeConverter, unorderedBullet)
173
+ );
174
+ continue;
175
+ }
176
+ const text2 = nodeConverter(child);
177
+ if (!text2.trim()) {
178
+ continue;
179
+ }
180
+ if (isFirstContent) {
181
+ lines.push(`${indent}${prefix} ${text2}`);
182
+ isFirstContent = false;
183
+ } else {
184
+ lines.push(`${indent} ${text2}`);
185
+ }
186
+ }
187
+ }
188
+ return lines.join("\n");
189
+ }
162
190
  /**
163
191
  * Default fallback for converting an unknown mdast node to text.
164
192
  * Recursively converts children if present, otherwise extracts the node value.
@@ -1068,4 +1096,4 @@ export {
1068
1096
  toModalElement,
1069
1097
  isJSX
1070
1098
  };
1071
- //# sourceMappingURL=chunk-7S5DLTN2.js.map
1099
+ //# sourceMappingURL=chunk-Q32GJ2PR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/markdown.ts","../src/cards.ts","../src/modals.ts","../src/jsx-runtime.ts"],"sourcesContent":["/**\n * Markdown parsing and conversion utilities using unified/remark.\n */\n\nimport type {\n Blockquote,\n Code,\n Content,\n Delete,\n Emphasis,\n InlineCode,\n Link,\n List,\n ListItem,\n Paragraph,\n Root,\n Strong,\n Table,\n TableCell,\n TableRow,\n Text,\n} from \"mdast\";\n\nimport { toString as mdastToString } from \"mdast-util-to-string\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkParse from \"remark-parse\";\nimport remarkStringify from \"remark-stringify\";\nimport { unified } from \"unified\";\nimport type { CardChild, CardElement } from \"./cards\";\nimport type { AdapterPostableMessage } from \"./types\";\n\n// Alias for use within this file\ntype PostableMessageInput = AdapterPostableMessage;\n\n// Re-export types for adapters\nexport type {\n Blockquote,\n Code,\n Content,\n Delete,\n Emphasis,\n InlineCode,\n Link,\n List,\n ListItem,\n Paragraph,\n Root,\n Strong,\n Table,\n TableCell,\n TableRow,\n Text,\n} from \"mdast\";\n\n// ============================================================================\n// Type Guards for mdast nodes\n// ============================================================================\n\n/**\n * Type guard for text nodes.\n */\nexport function isTextNode(node: Content): node is Text {\n return node.type === \"text\";\n}\n\n/**\n * Type guard for paragraph nodes.\n */\nexport function isParagraphNode(node: Content): node is Paragraph {\n return node.type === \"paragraph\";\n}\n\n/**\n * Type guard for strong (bold) nodes.\n */\nexport function isStrongNode(node: Content): node is Strong {\n return node.type === \"strong\";\n}\n\n/**\n * Type guard for emphasis (italic) nodes.\n */\nexport function isEmphasisNode(node: Content): node is Emphasis {\n return node.type === \"emphasis\";\n}\n\n/**\n * Type guard for delete (strikethrough) nodes.\n */\nexport function isDeleteNode(node: Content): node is Delete {\n return node.type === \"delete\";\n}\n\n/**\n * Type guard for inline code nodes.\n */\nexport function isInlineCodeNode(node: Content): node is InlineCode {\n return node.type === \"inlineCode\";\n}\n\n/**\n * Type guard for code block nodes.\n */\nexport function isCodeNode(node: Content): node is Code {\n return node.type === \"code\";\n}\n\n/**\n * Type guard for link nodes.\n */\nexport function isLinkNode(node: Content): node is Link {\n return node.type === \"link\";\n}\n\n/**\n * Type guard for blockquote nodes.\n */\nexport function isBlockquoteNode(node: Content): node is Blockquote {\n return node.type === \"blockquote\";\n}\n\n/**\n * Type guard for list nodes.\n */\nexport function isListNode(node: Content): node is List {\n return node.type === \"list\";\n}\n\n/**\n * Type guard for list item nodes.\n */\nexport function isListItemNode(node: Content): node is ListItem {\n return node.type === \"listItem\";\n}\n\n/**\n * Type guard for table nodes.\n */\nexport function isTableNode(node: Content): node is Table {\n return node.type === \"table\";\n}\n\n/**\n * Type guard for table row nodes.\n */\nexport function isTableRowNode(node: Content): node is TableRow {\n return node.type === \"tableRow\";\n}\n\n/**\n * Type guard for table cell nodes.\n */\nexport function isTableCellNode(node: Content): node is TableCell {\n return node.type === \"tableCell\";\n}\n\n/**\n * Render an mdast table node as a padded ASCII table string.\n *\n * Produces output like:\n * ```\n * Name | Age | Role\n * ------|-----|--------\n * Alice | 30 | Engineer\n * Bob | 25 | Designer\n * ```\n *\n * Shared by adapters that lack native table support (Slack, GChat, Discord, Telegram).\n */\nexport function tableToAscii(node: Table): string {\n const rows: string[][] = [];\n\n for (const row of node.children) {\n const cells: string[] = [];\n for (const cell of row.children) {\n cells.push(mdastToString(cell));\n }\n rows.push(cells);\n }\n\n if (rows.length === 0) {\n return \"\";\n }\n\n const headers = rows[0];\n const dataRows = rows.slice(1);\n return tableElementToAscii(headers, dataRows);\n}\n\n/**\n * Render a table from headers and string rows as a padded ASCII table.\n * Used for card TableElement fallback rendering.\n */\nexport function tableElementToAscii(\n headers: string[],\n rows: string[][]\n): string {\n const allRows = [headers, ...rows];\n const colCount = Math.max(...allRows.map((r) => r.length));\n if (colCount === 0) {\n return \"\";\n }\n const colWidths: number[] = Array.from({ length: colCount }, () => 0);\n\n for (const row of allRows) {\n for (let i = 0; i < colCount; i++) {\n const cellLen = (row[i] || \"\").length;\n if (cellLen > colWidths[i]) {\n colWidths[i] = cellLen;\n }\n }\n }\n\n const formatRow = (cells: string[]): string =>\n Array.from({ length: colCount }, (_, i) =>\n (cells[i] || \"\").padEnd(colWidths[i])\n )\n .join(\" | \")\n .trimEnd();\n\n const lines: string[] = [];\n lines.push(formatRow(headers));\n lines.push(colWidths.map((w) => \"-\".repeat(w)).join(\"-|-\"));\n for (const row of rows) {\n lines.push(formatRow(row));\n }\n return lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Helper functions for accessing node properties type-safely\n// ============================================================================\n\n/**\n * Get children from a content node that has children.\n * Returns empty array for nodes without children.\n * This eliminates the need for `as Content` casts in adapter converters.\n */\nexport function getNodeChildren(node: Content): Content[] {\n if (\"children\" in node && Array.isArray(node.children)) {\n return node.children as Content[];\n }\n return [];\n}\n\n/**\n * Get value from a content node that has a value property.\n * Returns empty string for nodes without value.\n */\nexport function getNodeValue(node: Content): string {\n if (\"value\" in node && typeof node.value === \"string\") {\n return node.value;\n }\n return \"\";\n}\n\n/**\n * Parse markdown string into an AST.\n * Supports GFM (GitHub Flavored Markdown) for strikethrough, tables, etc.\n */\nexport function parseMarkdown(markdown: string): Root {\n const processor = unified().use(remarkParse).use(remarkGfm);\n return processor.parse(markdown);\n}\n\n/**\n * Stringify an AST back to markdown.\n */\nexport function stringifyMarkdown(ast: Root): string {\n const processor = unified().use(remarkStringify).use(remarkGfm);\n return processor.stringify(ast);\n}\n\n/**\n * Extract plain text from an AST (strips all formatting).\n */\nexport function toPlainText(ast: Root): string {\n return mdastToString(ast);\n}\n\n/**\n * Extract plain text from a markdown string.\n */\nexport function markdownToPlainText(markdown: string): string {\n const ast = parseMarkdown(markdown);\n return mdastToString(ast);\n}\n\n/**\n * Walk the AST and transform nodes.\n */\nexport function walkAst<T extends Content | Root>(\n node: T,\n visitor: (node: Content) => Content | null\n): T {\n if (\"children\" in node && Array.isArray(node.children)) {\n node.children = node.children\n .map((child) => {\n const result = visitor(child as Content);\n if (result === null) {\n return null;\n }\n return walkAst(result, visitor);\n })\n .filter((n): n is Content => n !== null);\n }\n return node;\n}\n\n/**\n * Create a text node.\n */\nexport function text(value: string): Text {\n return { type: \"text\", value };\n}\n\n/**\n * Create a strong (bold) node.\n */\nexport function strong(children: Content[]): Strong {\n return { type: \"strong\", children: children as Strong[\"children\"] };\n}\n\n/**\n * Create an emphasis (italic) node.\n */\nexport function emphasis(children: Content[]): Emphasis {\n return { type: \"emphasis\", children: children as Emphasis[\"children\"] };\n}\n\n/**\n * Create a delete (strikethrough) node.\n */\nexport function strikethrough(children: Content[]): Delete {\n return { type: \"delete\", children: children as Delete[\"children\"] };\n}\n\n/**\n * Create an inline code node.\n */\nexport function inlineCode(value: string): InlineCode {\n return { type: \"inlineCode\", value };\n}\n\n/**\n * Create a code block node.\n */\nexport function codeBlock(value: string, lang?: string): Code {\n return { type: \"code\", value, lang };\n}\n\n/**\n * Create a link node.\n */\nexport function link(url: string, children: Content[], title?: string): Link {\n return { type: \"link\", url, children: children as Link[\"children\"], title };\n}\n\n/**\n * Create a blockquote node.\n */\nexport function blockquote(children: Content[]): Blockquote {\n return { type: \"blockquote\", children: children as Blockquote[\"children\"] };\n}\n\n/**\n * Create a paragraph node.\n */\nexport function paragraph(children: Content[]): Paragraph {\n return { type: \"paragraph\", children: children as Paragraph[\"children\"] };\n}\n\n/**\n * Create a root node (top-level AST container).\n */\nexport function root(children: Content[]): Root {\n return { type: \"root\", children: children as Root[\"children\"] };\n}\n\n/**\n * Interface for platform-specific format converters.\n *\n * The AST (mdast Root) is the canonical representation.\n * All conversions go through the AST:\n *\n * Platform Format <-> AST <-> Markdown String\n *\n * Adapters implement this interface to convert between\n * their platform-specific format and the standard AST.\n */\nexport interface FormatConverter {\n /**\n * Extract plain text from platform format.\n * Convenience method - default implementation uses toAst + toPlainText.\n */\n extractPlainText(platformText: string): string;\n /**\n * Render an AST to the platform's native format.\n * This is the primary method used when sending messages.\n */\n fromAst(ast: Root): string;\n\n /**\n * Parse platform's native format into an AST.\n * This is the primary method used when receiving messages.\n */\n toAst(platformText: string): Root;\n}\n\n/**\n * @deprecated Use FormatConverter instead\n */\nexport interface MarkdownConverter extends FormatConverter {\n // Convenience methods for markdown string I/O\n fromMarkdown(markdown: string): string;\n toMarkdown(platformText: string): string;\n toPlainText(platformText: string): string;\n}\n\n/**\n * Base class for format converters with default implementations.\n */\nexport abstract class BaseFormatConverter implements FormatConverter {\n abstract fromAst(ast: Root): string;\n abstract toAst(platformText: string): Root;\n\n protected renderList(\n node: List,\n depth: number,\n nodeConverter: (node: Content) => string,\n unorderedBullet = \"-\"\n ): string {\n const indent = \" \".repeat(depth);\n const start = node.start ?? 1;\n const lines: string[] = [];\n for (const [i, item] of getNodeChildren(node).entries()) {\n const prefix = node.ordered ? `${start + i}.` : unorderedBullet;\n let isFirstContent = true;\n for (const child of getNodeChildren(item)) {\n if (isListNode(child)) {\n lines.push(\n this.renderList(child, depth + 1, nodeConverter, unorderedBullet)\n );\n continue;\n }\n const text = nodeConverter(child);\n if (!text.trim()) {\n continue;\n }\n if (isFirstContent) {\n lines.push(`${indent}${prefix} ${text}`);\n isFirstContent = false;\n } else {\n lines.push(`${indent} ${text}`);\n }\n }\n }\n return lines.join(\"\\n\");\n }\n\n /**\n * Default fallback for converting an unknown mdast node to text.\n * Recursively converts children if present, otherwise extracts the node value.\n * Adapters should call this in their nodeToX() default case.\n */\n protected defaultNodeToText(\n node: Content,\n nodeConverter: (node: Content) => string\n ): string {\n const children = getNodeChildren(node);\n if (children.length > 0) {\n return children.map(nodeConverter).join(\"\");\n }\n return getNodeValue(node);\n }\n\n /**\n * Template method for implementing fromAst with a node converter.\n * Iterates through AST children and converts each using the provided function.\n * Joins results with double newlines (standard paragraph separation).\n *\n * @param ast - The AST to convert\n * @param nodeConverter - Function to convert each Content node to string\n * @returns Platform-formatted string\n */\n protected fromAstWithNodeConverter(\n ast: Root,\n nodeConverter: (node: Content) => string\n ): string {\n const parts: string[] = [];\n for (const node of ast.children) {\n parts.push(nodeConverter(node as Content));\n }\n return parts.join(\"\\n\\n\");\n }\n\n extractPlainText(platformText: string): string {\n return toPlainText(this.toAst(platformText));\n }\n\n // Convenience methods for markdown string I/O\n fromMarkdown(markdown: string): string {\n return this.fromAst(parseMarkdown(markdown));\n }\n\n toMarkdown(platformText: string): string {\n return stringifyMarkdown(this.toAst(platformText));\n }\n\n /** @deprecated Use extractPlainText instead */\n toPlainText(platformText: string): string {\n return this.extractPlainText(platformText);\n }\n\n /**\n * Convert a PostableMessage to platform format (text only).\n * - string: passed through as raw text (no conversion)\n * - { raw: string }: passed through as raw text (no conversion)\n * - { markdown: string }: converted from markdown to platform format\n * - { ast: Root }: converted from AST to platform format\n * - { card: CardElement }: returns fallback text (cards should be handled by adapter)\n * - CardElement: returns fallback text (cards should be handled by adapter)\n *\n * Note: For cards, adapters should check for card content first and render\n * them using platform-specific card APIs, using this method only for fallback.\n */\n renderPostable(message: PostableMessageInput): string {\n if (typeof message === \"string\") {\n return message;\n }\n if (\"raw\" in message) {\n return message.raw;\n }\n if (\"markdown\" in message) {\n return this.fromMarkdown(message.markdown);\n }\n if (\"ast\" in message) {\n return this.fromAst(message.ast);\n }\n if (\"card\" in message) {\n // Card with fallback text or generate from card content\n return message.fallbackText || this.cardToFallbackText(message.card);\n }\n if (\"type\" in message && message.type === \"card\") {\n // Direct CardElement\n return this.cardToFallbackText(message);\n }\n // Should never reach here with proper typing\n throw new Error(\"Invalid PostableMessage format\");\n }\n\n /**\n * Generate fallback text from a card element.\n * Override in subclasses for platform-specific formatting.\n */\n protected cardToFallbackText(card: CardElement): string {\n const parts: string[] = [];\n\n if (card.title) {\n parts.push(`**${card.title}**`);\n }\n\n if (card.subtitle) {\n parts.push(card.subtitle);\n }\n\n for (const child of card.children) {\n const text = this.cardChildToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n }\n\n /**\n * Convert card child element to fallback text.\n */\n protected cardChildToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"fields\":\n return child.children\n .map((f) => `**${f.label}**: ${f.value}`)\n .join(\"\\n\");\n case \"actions\":\n // Actions are interactive-only — exclude from fallback text.\n // See: https://docs.slack.dev/reference/methods/chat.postMessage\n return null;\n case \"table\":\n return tableElementToAscii(child.headers, child.rows);\n case \"section\":\n return child.children\n .map((c) => this.cardChildToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n }\n}\n","/**\n * Card elements for cross-platform rich messaging.\n *\n * Provides a builder API for creating rich cards that automatically\n * convert to platform-specific formats:\n * - Slack: Block Kit\n * - Teams: Adaptive Cards\n * - Google Chat: Card v2\n *\n * Supports both function-call and JSX syntax:\n *\n * @example Function API\n * ```ts\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * Card({\n * title: \"Order #1234\",\n * children: [\n * Text(\"Total: $50.00\"),\n * Actions([\n * Button({ id: \"approve\", label: \"Approve\", style: \"primary\" }),\n * Button({ id: \"reject\", label: \"Reject\", style: \"danger\" }),\n * ]),\n * ],\n * })\n * );\n * ```\n *\n * @example JSX API (requires jsxImportSource: \"chat\" in tsconfig)\n * ```tsx\n * /** @jsxImportSource chat *\\/\n * import { Card, Text, Actions, Button } from \"chat\";\n *\n * await thread.post(\n * <Card title=\"Order #1234\">\n * <Text>Total: $50.00</Text>\n * <Actions>\n * <Button id=\"approve\" style=\"primary\">Approve</Button>\n * <Button id=\"reject\" style=\"danger\">Reject</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport { tableElementToAscii } from \"./markdown\";\nimport type { RadioSelectElement, SelectElement } from \"./modals\";\n\n// ============================================================================\n// Card Element Types\n// ============================================================================\n\n/** Button style options */\nexport type ButtonStyle = \"primary\" | \"danger\" | \"default\";\n\n/** Text style options */\nexport type TextStyle = \"plain\" | \"bold\" | \"muted\";\n\n/** Button element for interactive actions */\nexport interface ButtonElement {\n /** If true, the button is displayed in an inactive state and doesn't respond to user actions */\n disabled?: boolean;\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n type: \"button\";\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/** Link button element that opens a URL */\nexport interface LinkButtonElement {\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n type: \"link-button\";\n /** URL to open when clicked */\n url: string;\n}\n\n/** Text content element */\nexport interface TextElement {\n /** Text content (supports markdown in some platforms) */\n content: string;\n /** Text style */\n style?: TextStyle;\n type: \"text\";\n}\n\n/** Image element */\nexport interface ImageElement {\n /** Alt text for accessibility */\n alt?: string;\n type: \"image\";\n /** Image URL */\n url: string;\n}\n\n/** Visual divider/separator */\nexport interface DividerElement {\n type: \"divider\";\n}\n\n/** Container for action buttons and selects */\nexport interface ActionsElement {\n /** Button, link button, select, and radio select elements */\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[];\n type: \"actions\";\n}\n\n/** Section container for grouping elements */\nexport interface SectionElement {\n /** Section children */\n children: CardChild[];\n type: \"section\";\n}\n\n/** Inline hyperlink element */\nexport interface LinkElement {\n /** Link label text */\n label: string;\n type: \"link\";\n /** URL to link to */\n url: string;\n}\n\n/** Field for key-value display */\nexport interface FieldElement {\n /** Field label */\n label: string;\n type: \"field\";\n /** Field value */\n value: string;\n}\n\n/** Fields container for multi-column layout */\nexport interface FieldsElement {\n /** Field elements */\n children: FieldElement[];\n type: \"fields\";\n}\n\n/** Column alignment for table elements */\nexport type TableAlignment = \"left\" | \"center\" | \"right\";\n\n/** Table element for structured data display */\nexport interface TableElement {\n /** Column alignment */\n align?: TableAlignment[];\n /** Column header labels */\n headers: string[];\n /** Data rows (each row is an array of cell strings) */\n rows: string[][];\n type: \"table\";\n}\n\n/** Union of all card child element types */\nexport type CardChild =\n | TextElement\n | ImageElement\n | DividerElement\n | ActionsElement\n | SectionElement\n | FieldsElement\n | LinkElement\n | TableElement;\n\n/** Union of all element types (including nested children) */\ntype AnyCardElement =\n | CardChild\n | CardElement\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | FieldElement\n | SelectElement\n | RadioSelectElement;\n\n/** Root card element */\nexport interface CardElement {\n /** Card content */\n children: CardChild[];\n /** Header image URL */\n imageUrl?: string;\n /** Card subtitle */\n subtitle?: string;\n /** Card title */\n title?: string;\n type: \"card\";\n}\n\n/** Type guard for CardElement */\nexport function isCardElement(value: unknown): value is CardElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as CardElement).type === \"card\"\n );\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\n/** Options for Card */\nexport interface CardOptions {\n children?: CardChild[];\n imageUrl?: string;\n subtitle?: string;\n title?: string;\n}\n\n/**\n * Create a Card element.\n *\n * @example\n * ```ts\n * Card({\n * title: \"Welcome\",\n * children: [Text(\"Hello!\")],\n * })\n * ```\n */\nexport function Card(options: CardOptions = {}): CardElement {\n return {\n type: \"card\",\n title: options.title,\n subtitle: options.subtitle,\n imageUrl: options.imageUrl,\n children: options.children ?? [],\n };\n}\n\n/**\n * Create a Text element.\n *\n * @example\n * ```ts\n * Text(\"Hello, world!\")\n * Text(\"Important\", { style: \"bold\" })\n * ```\n */\nexport function Text(\n content: string,\n options: { style?: TextStyle } = {}\n): TextElement {\n return {\n type: \"text\",\n content,\n style: options.style,\n };\n}\n\n/**\n * Alias for Text that avoids conflicts with DOM's global Text constructor.\n * Use this when importing in environments where `Text` would conflict.\n *\n * @example\n * ```ts\n * import { CardText } from \"chat\";\n * CardText(\"Hello, world!\")\n * ```\n */\nexport const CardText = Text;\n\n/**\n * Create an Image element.\n *\n * @example\n * ```ts\n * Image({ url: \"https://example.com/image.png\", alt: \"Description\" })\n * ```\n */\nexport function Image(options: { url: string; alt?: string }): ImageElement {\n return {\n type: \"image\",\n url: options.url,\n alt: options.alt,\n };\n}\n\n/**\n * Create a Divider element.\n *\n * @example\n * ```ts\n * Divider()\n * ```\n */\nexport function Divider(): DividerElement {\n return { type: \"divider\" };\n}\n\n/**\n * Create a Section container.\n *\n * @example\n * ```ts\n * Section([\n * Text(\"Grouped content\"),\n * Image({ url: \"...\" }),\n * ])\n * ```\n */\nexport function Section(children: CardChild[]): SectionElement {\n return {\n type: \"section\",\n children,\n };\n}\n\n/**\n * Create an Actions container for buttons and selects.\n *\n * @example\n * ```ts\n * Actions([\n * Button({ id: \"ok\", label: \"OK\" }),\n * Button({ id: \"cancel\", label: \"Cancel\" }),\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\" }),\n * Select({ id: \"priority\", label: \"Priority\", options: [...] }),\n * RadioSelect({ id: \"status\", label: \"Status\", options: [...] }),\n * ])\n * ```\n */\nexport function Actions(\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n): ActionsElement {\n return {\n type: \"actions\",\n children,\n };\n}\n\n/** Options for Button */\nexport interface ButtonOptions {\n /** If true, the button is displayed in an inactive state and doesn't respond to user actions */\n disabled?: boolean;\n /** Unique action ID for callback routing */\n id: string;\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** Optional payload value sent with action callback */\n value?: string;\n}\n\n/**\n * Create a Button element.\n *\n * @example\n * ```ts\n * Button({ id: \"submit\", label: \"Submit\", style: \"primary\" })\n * Button({ id: \"delete\", label: \"Delete\", style: \"danger\", value: \"item-123\" })\n * ```\n */\nexport function Button(options: ButtonOptions): ButtonElement {\n return {\n type: \"button\",\n id: options.id,\n label: options.label,\n style: options.style,\n value: options.value,\n disabled: options.disabled,\n };\n}\n\n/** Options for LinkButton */\nexport interface LinkButtonOptions {\n /** Button label text */\n label: string;\n /** Visual style */\n style?: ButtonStyle;\n /** URL to open when clicked */\n url: string;\n}\n\n/**\n * Create a LinkButton element that opens a URL when clicked.\n *\n * @example\n * ```ts\n * LinkButton({ url: \"https://example.com\", label: \"View Docs\" })\n * LinkButton({ url: \"https://example.com\", label: \"Learn More\", style: \"primary\" })\n * ```\n */\nexport function LinkButton(options: LinkButtonOptions): LinkButtonElement {\n return {\n type: \"link-button\",\n url: options.url,\n label: options.label,\n style: options.style,\n };\n}\n\n/**\n * Create a Field element for key-value display.\n *\n * @example\n * ```ts\n * Field({ label: \"Status\", value: \"Active\" })\n * ```\n */\nexport function Field(options: { label: string; value: string }): FieldElement {\n return {\n type: \"field\",\n label: options.label,\n value: options.value,\n };\n}\n\n/**\n * Create a Fields container for multi-column layout.\n *\n * @example\n * ```ts\n * Fields([\n * Field({ label: \"Name\", value: \"John\" }),\n * Field({ label: \"Email\", value: \"john@example.com\" }),\n * ])\n * ```\n */\nexport function Fields(children: FieldElement[]): FieldsElement {\n return {\n type: \"fields\",\n children,\n };\n}\n\n/** Options for Table */\nexport interface TableOptions {\n /** Column alignment */\n align?: TableAlignment[];\n /** Column header labels */\n headers: string[];\n /** Data rows */\n rows: string[][];\n}\n\n/**\n * Create a Table element for structured data display.\n *\n * @example\n * ```ts\n * Table({\n * headers: [\"Name\", \"Age\", \"Role\"],\n * rows: [\n * [\"Alice\", \"30\", \"Engineer\"],\n * [\"Bob\", \"25\", \"Designer\"],\n * ],\n * })\n * ```\n */\nexport function Table(options: TableOptions): TableElement {\n return {\n type: \"table\",\n headers: options.headers,\n rows: options.rows,\n align: options.align,\n };\n}\n\n/**\n * Create a CardLink element for inline hyperlinks.\n *\n * @example\n * ```ts\n * CardLink({ url: \"https://example.com\", label: \"Visit Site\" })\n * ```\n */\nexport function CardLink(options: { url: string; label: string }): LinkElement {\n return {\n type: \"link\",\n url: options.url,\n label: options.label,\n };\n}\n\n// ============================================================================\n// React Element Support\n// ============================================================================\n\n/** React element shape (minimal typing to avoid React dependency) */\ninterface ReactElement {\n $$typeof: symbol;\n props: Record<string, unknown>;\n type: unknown;\n}\n\n/**\n * Check if a value is a React element.\n */\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\n/**\n * Map of component functions to their names for React element conversion.\n */\nconst componentMap = new Map<unknown, string>([\n [Card, \"Card\"],\n [Text, \"Text\"],\n [Image, \"Image\"],\n [Divider, \"Divider\"],\n [Section, \"Section\"],\n [Actions, \"Actions\"],\n [Button, \"Button\"],\n [LinkButton, \"LinkButton\"],\n [CardLink, \"CardLink\"],\n [Field, \"Field\"],\n [Fields, \"Fields\"],\n [Table, \"Table\"],\n]);\n\n/**\n * Convert a React element tree to a CardElement tree.\n * This allows using React's JSX with our card components.\n *\n * @example\n * ```tsx\n * import React from \"react\";\n * import { Card, Text, fromReactElement } from \"chat\";\n *\n * const element = (\n * <Card title=\"Hello\">\n * <Text>World</Text>\n * </Card>\n * );\n *\n * const card = fromReactElement(element);\n * await thread.post(card);\n * ```\n */\nexport function fromReactElement(element: unknown): AnyCardElement | null {\n if (!isReactElement(element)) {\n // Already a card element or primitive\n if (isCardElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as CardChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = componentMap.get(type);\n\n if (!componentName) {\n // Check if it's an HTML element (string type like \"div\", \"a\", \"span\")\n if (typeof type === \"string\") {\n throw new Error(\n `HTML element <${type}> is not supported in card elements. ` +\n \"Use Card, Text, Section, Actions, Button, Fields, Field, Image, or Divider components instead.\"\n );\n }\n\n // Unknown custom component - try to extract children\n if (props.children) {\n return convertChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n // Convert children recursively\n const convertedChildren = props.children\n ? convertChildren(props.children)\n : [];\n\n // Helper to filter for CardChild elements\n const isCardChild = (el: AnyCardElement): el is CardChild =>\n el.type !== \"card\" &&\n el.type !== \"button\" &&\n el.type !== \"link-button\" &&\n el.type !== \"field\" &&\n el.type !== \"select\" &&\n el.type !== \"radio_select\";\n\n // Call the appropriate builder function based on component type\n switch (componentName) {\n case \"Card\":\n return Card({\n title: props.title as string | undefined,\n subtitle: props.subtitle as string | undefined,\n imageUrl: props.imageUrl as string | undefined,\n children: convertedChildren.filter(isCardChild),\n });\n\n case \"Text\": {\n // JSX: <Text style=\"bold\">content</Text>\n const content = extractTextContent(props.children);\n return Text(content, { style: props.style as TextStyle | undefined });\n }\n\n case \"Image\":\n return Image({\n url: props.url as string,\n alt: props.alt as string | undefined,\n });\n\n case \"Divider\":\n return Divider();\n\n case \"Section\":\n return Section(convertedChildren.filter(isCardChild));\n\n case \"Actions\":\n return Actions(\n convertedChildren.filter(\n (\n c\n ): c is\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement =>\n c.type === \"button\" ||\n c.type === \"link-button\" ||\n c.type === \"select\" ||\n c.type === \"radio_select\"\n )\n );\n\n case \"Button\": {\n // JSX: <Button id=\"x\" style=\"primary\">Label</Button>\n const label = extractTextContent(props.children);\n return Button({\n id: props.id as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n value: props.value as string | undefined,\n });\n }\n\n case \"LinkButton\": {\n // JSX: <LinkButton url=\"https://...\" style=\"primary\">Label</LinkButton>\n const label = extractTextContent(props.children);\n return LinkButton({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n style: props.style as ButtonStyle | undefined,\n });\n }\n\n case \"CardLink\": {\n const label = extractTextContent(props.children);\n return CardLink({\n url: props.url as string,\n label: (props.label as string | undefined) ?? label,\n });\n }\n\n case \"Field\":\n return Field({\n label: props.label as string,\n value: props.value as string,\n });\n\n case \"Fields\":\n return Fields(\n convertedChildren.filter((c): c is FieldElement => c.type === \"field\")\n );\n\n case \"Table\":\n return Table({\n headers: props.headers as string[],\n rows: props.rows as string[][],\n align: props.align as TableAlignment[] | undefined,\n });\n\n default:\n return null;\n }\n}\n\n/**\n * Convert React children to card elements.\n */\nfunction convertChildren(children: unknown): AnyCardElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertChildren);\n }\n\n const converted = fromReactElement(children);\n if (converted && typeof converted === \"object\" && \"type\" in converted) {\n // If it's a card, extract its children\n if (converted.type === \"card\") {\n return (converted as CardElement).children;\n }\n return [converted];\n }\n\n return [];\n}\n\n/**\n * Extract text content from React children.\n */\nfunction extractTextContent(children: unknown): string {\n if (typeof children === \"string\") {\n return children;\n }\n if (typeof children === \"number\") {\n return String(children);\n }\n if (Array.isArray(children)) {\n return children.map(extractTextContent).join(\"\");\n }\n return \"\";\n}\n\n// ============================================================================\n// Fallback Text Generation\n// ============================================================================\n\n/**\n * Generate plain text fallback from a CardElement.\n * Used for platforms/clients that can't render rich cards,\n * and for the SentMessage.text property.\n */\nexport function cardToFallbackText(card: CardElement): string {\n const parts: string[] = [];\n\n if (card.title) {\n parts.push(`**${card.title}**`);\n }\n\n if (card.subtitle) {\n parts.push(card.subtitle);\n }\n\n for (const child of card.children) {\n const text = cardChildToFallbackText(child);\n if (text) {\n parts.push(text);\n }\n }\n\n return parts.join(\"\\n\");\n}\n\n/**\n * Generate fallback text from a card child element.\n * Exported so adapter card converters can call it for unknown types.\n */\nexport function cardChildToFallbackText(child: CardChild): string | null {\n switch (child.type) {\n case \"text\":\n return child.content;\n case \"link\":\n return `${child.label} (${child.url})`;\n case \"fields\":\n return child.children.map((f) => `${f.label}: ${f.value}`).join(\"\\n\");\n case \"actions\":\n // Actions are interactive-only — exclude from fallback text.\n // See: https://docs.slack.dev/reference/methods/chat.postMessage\n return null;\n case \"table\":\n return tableElementToAscii(child.headers, child.rows);\n case \"section\":\n return child.children\n .map((c) => cardChildToFallbackText(c))\n .filter(Boolean)\n .join(\"\\n\");\n default:\n return null;\n }\n}\n","/**\n * Modal elements for form dialogs.\n */\n\nimport type { FieldsElement, TextElement } from \"./cards\";\n\n// ============================================================================\n// Modal Element Types\n// ============================================================================\n\nexport const VALID_MODAL_CHILD_TYPES = [\n \"text_input\",\n \"select\",\n \"radio_select\",\n \"text\",\n \"fields\",\n] as const;\n\nexport type ModalChild =\n | TextInputElement\n | SelectElement\n | RadioSelectElement\n | TextElement\n | FieldsElement;\n\nexport interface ModalElement {\n callbackId: string;\n children: ModalChild[];\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n type: \"modal\";\n}\n\nexport interface TextInputElement {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n type: \"text_input\";\n}\n\nexport interface SelectElement {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n placeholder?: string;\n type: \"select\";\n}\n\nexport interface SelectOptionElement {\n description?: string;\n label: string;\n value: string;\n}\n\nexport interface RadioSelectElement {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n type: \"radio_select\";\n}\n\nexport function isModalElement(value: unknown): value is ModalElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"type\" in value &&\n (value as ModalElement).type === \"modal\"\n );\n}\n\nexport function filterModalChildren(children: unknown[]): ModalChild[] {\n const validChildren = children.filter(\n (c): c is ModalChild =>\n typeof c === \"object\" &&\n c !== null &&\n \"type\" in c &&\n VALID_MODAL_CHILD_TYPES.includes(\n (c as { type: string }).type as (typeof VALID_MODAL_CHILD_TYPES)[number]\n )\n );\n if (validChildren.length < children.length) {\n console.warn(\n \"[chat] Modal contains unsupported child elements that were ignored\"\n );\n }\n return validChildren;\n}\n\n// ============================================================================\n// Builder Functions\n// ============================================================================\n\nexport interface ModalOptions {\n callbackId: string;\n children?: ModalChild[];\n closeLabel?: string;\n notifyOnClose?: boolean;\n /** Arbitrary string passed through the modal lifecycle (e.g., JSON context). */\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n}\n\nexport function Modal(options: ModalOptions): ModalElement {\n return {\n type: \"modal\",\n callbackId: options.callbackId,\n title: options.title,\n submitLabel: options.submitLabel,\n closeLabel: options.closeLabel,\n notifyOnClose: options.notifyOnClose,\n privateMetadata: options.privateMetadata,\n children: options.children ?? [],\n };\n}\n\nexport interface TextInputOptions {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n}\n\nexport function TextInput(options: TextInputOptions): TextInputElement {\n return {\n type: \"text_input\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n initialValue: options.initialValue,\n multiline: options.multiline,\n optional: options.optional,\n maxLength: options.maxLength,\n };\n}\n\nexport interface SelectOptions {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n placeholder?: string;\n}\n\nexport function Select(options: SelectOptions): SelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"Select requires at least one option\");\n }\n return {\n type: \"select\",\n id: options.id,\n label: options.label,\n placeholder: options.placeholder,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\nexport function SelectOption(options: {\n label: string;\n value: string;\n description?: string;\n}): SelectOptionElement {\n return {\n label: options.label,\n value: options.value,\n description: options.description,\n };\n}\n\nexport interface RadioSelectOptions {\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n options: SelectOptionElement[];\n}\n\nexport function RadioSelect(options: RadioSelectOptions): RadioSelectElement {\n if (!options.options || options.options.length === 0) {\n throw new Error(\"RadioSelect requires at least one option\");\n }\n return {\n type: \"radio_select\",\n id: options.id,\n label: options.label,\n options: options.options,\n initialOption: options.initialOption,\n optional: options.optional,\n };\n}\n\n// ============================================================================\n// JSX Support\n// ============================================================================\n\ninterface ReactElement {\n $$typeof: symbol;\n props: Record<string, unknown>;\n type: unknown;\n}\n\nfunction isReactElement(value: unknown): value is ReactElement {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const maybeElement = value as { $$typeof?: unknown };\n if (typeof maybeElement.$$typeof !== \"symbol\") {\n return false;\n }\n const symbolStr = maybeElement.$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n}\n\ntype AnyModalElement = ModalElement | ModalChild | SelectOptionElement;\n\nconst modalComponentMap = new Map<unknown, string>([\n [Modal, \"Modal\"],\n [TextInput, \"TextInput\"],\n [Select, \"Select\"],\n [RadioSelect, \"RadioSelect\"],\n [SelectOption, \"SelectOption\"],\n]);\n\nexport function fromReactModalElement(\n element: unknown\n): AnyModalElement | null {\n if (!isReactElement(element)) {\n if (isModalElement(element)) {\n return element;\n }\n if (typeof element === \"object\" && element !== null && \"type\" in element) {\n return element as ModalChild;\n }\n return null;\n }\n\n const { type, props } = element;\n const componentName = modalComponentMap.get(type);\n\n if (!componentName) {\n if (props.children) {\n return convertModalChildren(props.children)[0] ?? null;\n }\n return null;\n }\n\n const convertedChildren = props.children\n ? convertModalChildren(props.children)\n : [];\n\n switch (componentName) {\n case \"Modal\":\n return Modal({\n callbackId: props.callbackId as string,\n title: props.title as string,\n submitLabel: props.submitLabel as string | undefined,\n closeLabel: props.closeLabel as string | undefined,\n notifyOnClose: props.notifyOnClose as boolean | undefined,\n privateMetadata: props.privateMetadata as string | undefined,\n children: filterModalChildren(convertedChildren),\n });\n\n case \"TextInput\":\n return TextInput({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n initialValue: props.initialValue as string | undefined,\n multiline: props.multiline as boolean | undefined,\n optional: props.optional as boolean | undefined,\n maxLength: props.maxLength as number | undefined,\n });\n\n case \"Select\":\n return Select({\n id: props.id as string,\n label: props.label as string,\n placeholder: props.placeholder as string | undefined,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c)\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"RadioSelect\":\n return RadioSelect({\n id: props.id as string,\n label: props.label as string,\n options: convertedChildren.filter(\n (c): c is SelectOptionElement =>\n c !== null && \"label\" in c && \"value\" in c && !(\"type\" in c)\n ),\n initialOption: props.initialOption as string | undefined,\n optional: props.optional as boolean | undefined,\n });\n\n case \"SelectOption\":\n return SelectOption({\n label: props.label as string,\n value: props.value as string,\n description: props.description as string | undefined,\n });\n\n default:\n return null;\n }\n}\n\nfunction convertModalChildren(children: unknown): AnyModalElement[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(convertModalChildren);\n }\n\n const converted = fromReactModalElement(children);\n if (converted) {\n if (isModalElement(converted)) {\n return converted.children;\n }\n return [converted];\n }\n\n return [];\n}\n","/**\n * Custom JSX runtime for chat cards.\n *\n * This allows using JSX syntax without React. Configure your bundler:\n *\n * tsconfig.json:\n * {\n * \"compilerOptions\": {\n * \"jsx\": \"react-jsx\",\n * \"jsxImportSource\": \"chat\"\n * }\n * }\n *\n * Or per-file:\n * /** @jsxImportSource chat *\\/\n *\n * Usage:\n * ```tsx\n * import { Card, Text, Button, Actions } from \"chat\";\n *\n * const card = (\n * <Card title=\"Order #1234\">\n * <Text>Your order is ready!</Text>\n * <Actions>\n * <Button id=\"pickup\" style=\"primary\">Schedule Pickup</Button>\n * </Actions>\n * </Card>\n * );\n * ```\n */\n\nimport {\n Actions,\n type ActionsElement,\n Button,\n type ButtonElement,\n type ButtonOptions,\n type ButtonStyle,\n Card,\n type CardChild,\n type CardElement,\n CardLink,\n type CardOptions,\n Divider,\n type DividerElement,\n Field,\n type FieldElement,\n Fields,\n type FieldsElement,\n Image,\n type ImageElement,\n LinkButton,\n type LinkButtonElement,\n type LinkButtonOptions,\n type LinkElement,\n Section,\n type SectionElement,\n Text,\n type TextElement,\n type TextStyle,\n} from \"./cards\";\n\nimport {\n filterModalChildren,\n isModalElement,\n Modal,\n type ModalChild,\n type ModalElement,\n type ModalOptions,\n RadioSelect,\n type RadioSelectElement,\n type RadioSelectOptions,\n Select,\n type SelectElement,\n SelectOption,\n type SelectOptionElement,\n type SelectOptions,\n TextInput,\n type TextInputElement,\n type TextInputOptions,\n} from \"./modals\";\n\n// Symbol to identify our JSX elements before they're processed\nconst JSX_ELEMENT = Symbol.for(\"chat.jsx.element\");\n\n// ============================================================================\n// JSX Props Types - Strongly typed props for each component\n// ============================================================================\n\n/** Props for Card component in JSX */\nexport interface CardProps {\n children?: unknown;\n imageUrl?: string;\n subtitle?: string;\n title?: string;\n}\n\n/** Props for Text component in JSX */\nexport interface TextProps {\n children?: string | number | (string | number | undefined)[];\n style?: TextStyle;\n}\n\n/** Props for Button component in JSX */\nexport interface ButtonProps {\n children?: string | number | (string | number | undefined)[];\n id: string;\n label?: string;\n style?: ButtonStyle;\n value?: string;\n}\n\n/** Props for LinkButton component in JSX */\nexport interface LinkButtonProps {\n children?: string | number | (string | number | undefined)[];\n label?: string;\n style?: ButtonStyle;\n url: string;\n}\n\n/** Props for CardLink component in JSX */\nexport interface CardLinkProps {\n children?: string | number | (string | number | undefined)[];\n label?: string;\n url: string;\n}\n\n/** Props for Image component in JSX */\nexport interface ImageProps {\n alt?: string;\n url: string;\n}\n\n/** Props for Field component in JSX */\nexport interface FieldProps {\n label: string;\n value: string;\n}\n\n/** Props for container components (Section, Actions, Fields) */\nexport interface ContainerProps {\n children?: unknown;\n}\n\n/** Props for Divider component (no props) */\nexport type DividerProps = Record<string, never>;\n\n/** Props for Modal component in JSX */\nexport interface ModalProps {\n callbackId: string;\n children?: unknown;\n closeLabel?: string;\n notifyOnClose?: boolean;\n privateMetadata?: string;\n submitLabel?: string;\n title: string;\n}\n\n/** Props for TextInput component in JSX */\nexport interface TextInputProps {\n id: string;\n initialValue?: string;\n label: string;\n maxLength?: number;\n multiline?: boolean;\n optional?: boolean;\n placeholder?: string;\n}\n\n/** Props for Select component in JSX */\nexport interface SelectProps {\n children?: unknown;\n id: string;\n initialOption?: string;\n label: string;\n optional?: boolean;\n placeholder?: string;\n}\n\n/** Props for SelectOption component in JSX */\nexport interface SelectOptionProps {\n description?: string;\n label: string;\n value: string;\n}\n\n/** Union of all valid JSX props */\nexport type CardJSXProps =\n | CardProps\n | TextProps\n | ButtonProps\n | LinkButtonProps\n | CardLinkProps\n | ImageProps\n | FieldProps\n | ContainerProps\n | DividerProps\n | ModalProps\n | TextInputProps\n | SelectProps\n | SelectOptionProps;\n\n/** Component function type with proper overloads */\ntype CardComponentFunction =\n | typeof Card\n | typeof Text\n | typeof Button\n | typeof LinkButton\n | typeof CardLink\n | typeof Image\n | typeof Field\n | typeof Divider\n | typeof Section\n | typeof Actions\n | typeof Fields\n | typeof Modal\n | typeof TextInput\n | typeof Select\n | typeof RadioSelect\n | typeof SelectOption;\n\n/**\n * Represents a JSX element from the chat JSX runtime.\n * This is the type returned when using JSX syntax with chat components.\n */\nexport interface CardJSXElement<P extends CardJSXProps = CardJSXProps> {\n $$typeof: typeof JSX_ELEMENT;\n children: unknown[];\n props: P;\n type: CardComponentFunction;\n}\n\n/** Union of all element types that can be produced by chat components */\nexport type ChatElement =\n | CardJSXElement\n | CardElement\n | TextElement\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | ImageElement\n | DividerElement\n | ActionsElement\n | SectionElement\n | FieldsElement\n | FieldElement\n | ModalElement\n | TextInputElement\n | SelectElement\n | SelectOptionElement\n | RadioSelectElement;\n\n// ============================================================================\n// JSX Component Function Types\n// ============================================================================\n\nexport interface CardComponent {\n (options?: CardOptions): CardElement;\n (props: CardProps): ChatElement;\n}\n\nexport interface TextComponent {\n (content: string, options?: { style?: TextStyle }): TextElement;\n (props: TextProps): ChatElement;\n}\n\nexport interface ButtonComponent {\n (options: ButtonOptions): ButtonElement;\n (props: ButtonProps): ChatElement;\n}\n\nexport interface LinkButtonComponent {\n (options: LinkButtonOptions): LinkButtonElement;\n (props: LinkButtonProps): ChatElement;\n}\n\nexport interface CardLinkComponent {\n (options: { url: string; label: string }): LinkElement;\n (props: CardLinkProps): ChatElement;\n}\n\nexport interface ImageComponent {\n (options: { url: string; alt?: string }): ImageElement;\n (props: ImageProps): ChatElement;\n}\n\nexport interface FieldComponent {\n (options: { label: string; value: string }): FieldElement;\n (props: FieldProps): ChatElement;\n}\n\nexport interface DividerComponent {\n (): DividerElement;\n (props: DividerProps): ChatElement;\n}\n\nexport interface SectionComponent {\n (children: CardChild[]): SectionElement;\n (props: ContainerProps): ChatElement;\n}\n\nexport interface ActionsComponent {\n (\n children: (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n ): ActionsElement;\n (props: ContainerProps): ChatElement;\n}\n\nexport interface FieldsComponent {\n (children: FieldElement[]): FieldsElement;\n (props: ContainerProps): ChatElement;\n}\n\nexport interface ModalComponent {\n (options: ModalOptions): ModalElement;\n (props: ModalProps): ChatElement;\n}\n\nexport interface TextInputComponent {\n (options: TextInputOptions): TextInputElement;\n (props: TextInputProps): ChatElement;\n}\n\nexport interface SelectComponent {\n (options: SelectOptions): SelectElement;\n (props: SelectProps): ChatElement;\n}\n\nexport interface SelectOptionComponent {\n (options: {\n label: string;\n value: string;\n description?: string;\n }): SelectOptionElement;\n (props: SelectOptionProps): ChatElement;\n}\n\nexport interface RadioSelectComponent {\n (options: RadioSelectOptions): RadioSelectElement;\n (props: SelectProps): ChatElement;\n}\n\n// Internal alias for backwards compatibility\ntype JSXElement = CardJSXElement;\n\n/**\n * Check if a value is a JSX element from our runtime.\n */\nfunction isJSXElement(value: unknown): value is JSXElement {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as JSXElement).$$typeof === JSX_ELEMENT\n );\n}\n\n/** Non-null card element for children arrays */\ntype CardChildOrNested =\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | LinkElement\n | FieldElement\n | SelectElement\n | SelectOptionElement\n | RadioSelectElement;\n\n/**\n * Process children, converting JSX elements to card elements.\n */\nfunction processChildren(children: unknown): CardChildOrNested[] {\n if (children == null) {\n return [];\n }\n\n if (Array.isArray(children)) {\n return children.flatMap(processChildren);\n }\n\n // If it's a JSX element, resolve it\n if (isJSXElement(children)) {\n const resolved = resolveJSXElement(children);\n if (resolved) {\n return [resolved as CardChildOrNested];\n }\n return [];\n }\n\n // If it's already a card element, return it\n if (typeof children === \"object\" && \"type\" in children) {\n return [children as CardChildOrNested];\n }\n\n // If it's a string or number, it might be text content for a Button or Text\n if (typeof children === \"string\" || typeof children === \"number\") {\n // Return as string, the component will handle it\n return [String(children) as unknown as CardChildOrNested];\n }\n\n return [];\n}\n\n/** Any card element type that can be created */\ntype AnyCardElement =\n | CardElement\n | CardChild\n | ButtonElement\n | LinkButtonElement\n | FieldElement\n | ModalElement\n | ModalChild\n | SelectOptionElement\n | null;\n\n/**\n * Type guard to check if props match TextProps\n */\nfunction isTextProps(props: CardJSXProps): props is TextProps {\n return !(\"id\" in props || \"url\" in props || \"label\" in props);\n}\n\n/**\n * Type guard to check if props match ButtonProps\n */\nfunction isButtonProps(props: CardJSXProps): props is ButtonProps {\n return \"id\" in props && typeof props.id === \"string\" && !(\"url\" in props);\n}\n\n/**\n * Type guard to check if props match LinkButtonProps\n */\nfunction isLinkButtonProps(props: CardJSXProps): props is LinkButtonProps {\n return \"url\" in props && typeof props.url === \"string\" && !(\"id\" in props);\n}\n\n/**\n * Type guard to check if props match CardLinkProps\n */\nexport function isCardLinkProps(props: CardJSXProps): props is CardLinkProps {\n return (\n \"url\" in props &&\n typeof props.url === \"string\" &&\n !(\"id\" in props) &&\n !(\"alt\" in props) &&\n !(\"style\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ImageProps\n */\nfunction isImageProps(props: CardJSXProps): props is ImageProps {\n return \"url\" in props && typeof props.url === \"string\";\n}\n\n/**\n * Type guard to check if props match FieldProps\n */\nfunction isFieldProps(props: CardJSXProps): props is FieldProps {\n return (\n \"label\" in props &&\n \"value\" in props &&\n typeof props.label === \"string\" &&\n typeof props.value === \"string\"\n );\n}\n\n/**\n * Type guard to check if props match CardProps\n */\nfunction isCardProps(props: CardJSXProps): props is CardProps {\n return (\n !(\"id\" in props || \"url\" in props || \"callbackId\" in props) &&\n (\"title\" in props || \"subtitle\" in props || \"imageUrl\" in props)\n );\n}\n\n/**\n * Type guard to check if props match ModalProps\n */\nfunction isModalProps(props: CardJSXProps): props is ModalProps {\n return \"callbackId\" in props && \"title\" in props;\n}\n\n/**\n * Type guard to check if props match TextInputProps\n */\nfunction isTextInputProps(props: CardJSXProps): props is TextInputProps {\n return (\n \"id\" in props &&\n \"label\" in props &&\n !(\"options\" in props) &&\n !(\"value\" in props)\n );\n}\n\n/**\n * Type guard to check if props match SelectProps\n */\nfunction isSelectProps(props: CardJSXProps): props is SelectProps {\n return \"id\" in props && \"label\" in props && !(\"value\" in props);\n}\n\n/**\n * Type guard to check if props match SelectOptionProps\n */\nfunction isSelectOptionProps(props: CardJSXProps): props is SelectOptionProps {\n return \"label\" in props && \"value\" in props && !(\"id\" in props);\n}\n\n/**\n * Resolve a JSX element by calling its component function.\n * Transforms JSX props into the format each builder function expects.\n */\nfunction resolveJSXElement(element: JSXElement): AnyCardElement {\n const { type, props, children } = element;\n\n // Process children first\n const processedChildren = processChildren(children);\n\n // Use identity comparison to determine which builder function this is\n // This is necessary because function names get minified in production builds\n if (type === Text) {\n // Text(content: string, options?: { style })\n // JSX children become the content string\n const textProps = isTextProps(props) ? props : { style: undefined };\n const content =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : String(textProps.children ?? \"\");\n return Text(content, { style: textProps.style });\n }\n\n if (type === Section) {\n // Section takes array as first argument\n return Section(processedChildren as CardChild[]);\n }\n\n if (type === Actions) {\n // Actions takes array of ButtonElements, LinkButtonElements, SelectElements, and RadioSelectElements\n return Actions(\n processedChildren as (\n | ButtonElement\n | LinkButtonElement\n | SelectElement\n | RadioSelectElement\n )[]\n );\n }\n\n if (type === Fields) {\n // Fields takes array of FieldElements\n return Fields(processedChildren as FieldElement[]);\n }\n\n if (type === Button) {\n // Button({ id, label, style, value })\n // JSX children become the label\n if (!isButtonProps(props)) {\n throw new Error(\"Button requires an 'id' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return Button({\n id: props.id,\n label,\n style: props.style,\n value: props.value,\n });\n }\n\n if (type === LinkButton) {\n // LinkButton({ url, label, style })\n // JSX children become the label\n if (!isLinkButtonProps(props)) {\n throw new Error(\"LinkButton requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return LinkButton({\n url: props.url,\n label,\n style: props.style,\n });\n }\n\n if (type === CardLink) {\n // CardLink({ url, label })\n // JSX children become the label\n if (!isCardLinkProps(props)) {\n throw new Error(\"CardLink requires a 'url' prop\");\n }\n const label =\n processedChildren.length > 0\n ? processedChildren.map(String).join(\"\")\n : (props.label ?? \"\");\n return CardLink({\n url: props.url,\n label,\n });\n }\n\n if (type === Image) {\n // Image({ url, alt })\n if (!isImageProps(props)) {\n throw new Error(\"Image requires a 'url' prop\");\n }\n return Image({ url: props.url, alt: props.alt });\n }\n\n if (type === Field) {\n // Field({ label, value })\n if (!isFieldProps(props)) {\n throw new Error(\"Field requires 'label' and 'value' props\");\n }\n return Field({\n label: props.label,\n value: props.value,\n });\n }\n\n if (type === Divider) {\n // Divider() - no args\n return Divider();\n }\n\n // Modal components\n if (type === Modal) {\n if (!isModalProps(props)) {\n throw new Error(\"Modal requires 'callbackId' and 'title' props\");\n }\n return Modal({\n callbackId: props.callbackId,\n title: props.title,\n submitLabel: props.submitLabel,\n closeLabel: props.closeLabel,\n notifyOnClose: props.notifyOnClose,\n privateMetadata: props.privateMetadata,\n children: filterModalChildren(processedChildren),\n });\n }\n\n if (type === TextInput) {\n if (!isTextInputProps(props)) {\n throw new Error(\"TextInput requires 'id' and 'label' props\");\n }\n return TextInput({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialValue: props.initialValue,\n multiline: props.multiline,\n optional: props.optional,\n maxLength: props.maxLength,\n });\n }\n\n if (type === Select) {\n if (!isSelectProps(props)) {\n throw new Error(\"Select requires 'id' and 'label' props\");\n }\n return Select({\n id: props.id,\n label: props.label,\n placeholder: props.placeholder,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === RadioSelect) {\n if (!isSelectProps(props)) {\n throw new Error(\"RadioSelect requires 'id' and 'label' props\");\n }\n return RadioSelect({\n id: props.id,\n label: props.label,\n initialOption: props.initialOption,\n optional: props.optional,\n options: processedChildren as SelectOptionElement[],\n });\n }\n\n if (type === SelectOption) {\n if (!isSelectOptionProps(props)) {\n throw new Error(\"SelectOption requires 'label' and 'value' props\");\n }\n return SelectOption({\n label: props.label,\n value: props.value,\n description: props.description,\n });\n }\n\n // Default: Card({ title, subtitle, imageUrl, children })\n const cardProps = isCardProps(props) ? props : {};\n return Card({\n title: cardProps.title,\n subtitle: cardProps.subtitle,\n imageUrl: cardProps.imageUrl,\n children: processedChildren as CardChild[],\n });\n}\n\n/**\n * JSX factory function (used by the JSX transform).\n * Creates a lazy JSX element that will be resolved when needed.\n */\nexport function jsx<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: children != null ? [children] : [],\n };\n}\n\n/**\n * JSX factory for elements with multiple children.\n */\nexport function jsxs<P extends CardJSXProps>(\n type: CardComponentFunction,\n props: P & { children?: unknown },\n _key?: string\n): CardJSXElement<P> {\n const { children, ...restProps } = props;\n let resolvedChildren: unknown[];\n if (Array.isArray(children)) {\n resolvedChildren = children;\n } else if (children != null) {\n resolvedChildren = [children];\n } else {\n resolvedChildren = [];\n }\n return {\n $$typeof: JSX_ELEMENT,\n type,\n props: restProps as P,\n children: resolvedChildren,\n };\n}\n\n/**\n * Development JSX factory (same as jsx, but called in dev mode).\n */\nexport const jsxDEV = jsx;\n\n/**\n * Fragment support (flattens children).\n */\nexport function Fragment(props: { children?: unknown }): CardChild[] {\n return processChildren(props.children) as CardChild[];\n}\n\n/**\n * Convert a JSX element tree to a CardElement.\n * Call this on the root JSX element to get a usable CardElement.\n */\nexport function toCardElement(jsxElement: unknown): CardElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"card\"\n ) {\n return resolved as CardElement;\n }\n }\n\n // Already a CardElement\n if (\n typeof jsxElement === \"object\" &&\n jsxElement !== null &&\n \"type\" in jsxElement &&\n (jsxElement as CardElement).type === \"card\"\n ) {\n return jsxElement as CardElement;\n }\n\n return null;\n}\n\nexport function toModalElement(jsxElement: unknown): ModalElement | null {\n if (isJSXElement(jsxElement)) {\n const resolved = resolveJSXElement(jsxElement);\n if (\n resolved &&\n typeof resolved === \"object\" &&\n \"type\" in resolved &&\n resolved.type === \"modal\"\n ) {\n return resolved as ModalElement;\n }\n }\n if (isModalElement(jsxElement)) {\n return jsxElement;\n }\n return null;\n}\n\n/**\n * Check if a value is a JSX element (from our runtime or React).\n */\nexport function isJSX(value: unknown): boolean {\n if (isJSXElement(value)) {\n return true;\n }\n // Check for React elements\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"$$typeof\" in value &&\n typeof (value as { $$typeof: unknown }).$$typeof === \"symbol\"\n ) {\n const symbolStr = (value as { $$typeof: symbol }).$$typeof.toString();\n return (\n symbolStr.includes(\"react.element\") ||\n symbolStr.includes(\"react.transitional.element\")\n );\n }\n return false;\n}\n\n// biome-ignore lint/style/noNamespace: JSX namespace required by TypeScript JSX transform\nexport namespace JSX {\n export type Element = ChatElement;\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX namespace\n export type IntrinsicElements = {};\n export interface IntrinsicAttributes {\n key?: string | number;\n }\n export interface ElementChildrenAttribute {\n // biome-ignore lint/complexity/noBannedTypes: Required for JSX children attribute\n children: {};\n }\n}\n"],"mappings":"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","names":["text","text","isReactElement"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { C as CardElement, M as ModalElement, a as CardJSXElement, b as CardChild, A as Actions$1, B as Button$1, c as Card$1, d as cardChildToFallbackText$1, e as CardLink$1, T as Text$1, D as Divider$1, F as Field$1, f as Fields$1, g as fromReactElement$1, I as Image$1, i as isCardElement$1, h as isJSX$1, L as LinkButton$1, S as Section$1, j as Table$2, t as toCardElement$1, k as toModalElement$1, l as fromReactModalElement$1, m as isModalElement$1, n as Modal$1, R as RadioSelect$1, o as Select$1, p as SelectOption$1, q as TextInput$1 } from './jsx-runtime-Bokk9xw5.js';
2
- export { r as ActionsElement, s as ButtonElement, u as ButtonOptions, V as ButtonProps, v as ButtonStyle, W as CardJSXProps, X as CardLinkProps, w as CardOptions, Y as CardProps, Z as ContainerProps, x as DividerElement, _ as DividerProps, y as FieldElement, $ as FieldProps, z as FieldsElement, E as ImageElement, a0 as ImageProps, G as LinkButtonElement, H as LinkButtonOptions, a1 as LinkButtonProps, J as LinkElement, a3 as ModalChild, a4 as ModalOptions, a5 as RadioSelectElement, a6 as RadioSelectOptions, K as SectionElement, a7 as SelectElement, a8 as SelectOptionElement, a9 as SelectOptions, N as TableAlignment, O as TableElement, P as TableOptions, Q as TextElement, aa as TextInputElement, ab as TextInputOptions, a2 as TextProps, U as TextStyle } from './jsx-runtime-Bokk9xw5.js';
3
1
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
4
- import { Root, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, List, Paragraph, Strong, TableCell, Table as Table$1, TableRow, Text } from 'mdast';
2
+ import { C as CardElement, M as ModalElement, a as ChatElement, b as CardChild, A as ActionsComponent, B as ButtonComponent, c as CardComponent, d as cardChildToFallbackText$1, e as CardLinkComponent, T as TextComponent, D as DividerComponent, F as FieldComponent, f as FieldsComponent, g as fromReactElement$1, I as ImageComponent, i as isCardElement$1, h as isJSX$1, L as LinkButtonComponent, S as SectionComponent, j as Table$2, t as toCardElement$1, k as toModalElement$1, l as fromReactModalElement$1, m as isModalElement$1, n as ModalComponent, R as RadioSelectComponent, o as SelectComponent, p as SelectOptionComponent, q as TextInputComponent } from './jsx-runtime-BJENDuXl.js';
3
+ export { r as ActionsElement, s as ButtonElement, u as ButtonOptions, V as ButtonProps, v as ButtonStyle, W as CardJSXElement, X as CardJSXProps, Y as CardLinkProps, w as CardOptions, Z as CardProps, _ as ContainerProps, x as DividerElement, $ as DividerProps, y as FieldElement, a0 as FieldProps, z as FieldsElement, E as ImageElement, a1 as ImageProps, G as LinkButtonElement, H as LinkButtonOptions, a2 as LinkButtonProps, J as LinkElement, a8 as ModalChild, a9 as ModalOptions, a3 as ModalProps, aa as RadioSelectElement, ab as RadioSelectOptions, K as SectionElement, ac as SelectElement, ad as SelectOptionElement, a4 as SelectOptionProps, ae as SelectOptions, a5 as SelectProps, N as TableAlignment, O as TableElement, P as TableOptions, Q as TextElement, af as TextInputElement, ag as TextInputOptions, a6 as TextInputProps, a7 as TextProps, U as TextStyle } from './jsx-runtime-BJENDuXl.js';
4
+ import { Root, List, Content, Blockquote, Code, Emphasis, InlineCode, Delete, Link, ListItem, Paragraph, Strong, TableCell, Table as Table$1, TableRow, Text } from 'mdast';
5
5
  export { Blockquote, Code, Content, Delete, Emphasis, InlineCode, Link, List, ListItem, Table as MdastTable, Paragraph, Root, Strong, TableCell, TableRow, Text } from 'mdast';
6
6
 
7
7
  /**
@@ -263,15 +263,46 @@ interface Adapter<TThreadId = unknown, TRawMessage = unknown> {
263
263
  * The adapter consumes the async iterable and handles the entire streaming lifecycle.
264
264
  * Only available on platforms with native streaming support (e.g., Slack).
265
265
  *
266
+ * The stream can yield plain strings (text chunks) or {@link StreamChunk} objects
267
+ * for rich content like task progress cards. Adapters that don't support structured
268
+ * chunks will extract text from `markdown_text` chunks and ignore other types.
269
+ *
266
270
  * @param threadId - The thread to stream to
267
- * @param textStream - Async iterable of text chunks (e.g., from AI SDK)
271
+ * @param textStream - Async iterable of text chunks or structured StreamChunk objects
268
272
  * @param options - Platform-specific streaming options
269
273
  * @returns The raw message after streaming completes
270
274
  */
271
- stream?(threadId: string, textStream: AsyncIterable<string>, options?: StreamOptions): Promise<RawMessage<TRawMessage>>;
275
+ stream?(threadId: string, textStream: AsyncIterable<string | StreamChunk>, options?: StreamOptions): Promise<RawMessage<TRawMessage>>;
272
276
  /** Bot username (can override global userName) */
273
277
  readonly userName: string;
274
278
  }
279
+ /**
280
+ * A structured streaming chunk for platform-native rich content.
281
+ *
282
+ * On Slack, these map directly to streaming chunk types:
283
+ * - `markdown_text`: Streamed text content
284
+ * - `task_update`: Tool/step progress cards (pending → in_progress → complete → error)
285
+ * - `plan_update`: Plan title updates
286
+ *
287
+ * Adapters that don't support structured chunks will extract `text` from
288
+ * `markdown_text` chunks and ignore other types gracefully.
289
+ */
290
+ type StreamChunk = MarkdownTextChunk | TaskUpdateChunk | PlanUpdateChunk;
291
+ interface MarkdownTextChunk {
292
+ text: string;
293
+ type: "markdown_text";
294
+ }
295
+ interface TaskUpdateChunk {
296
+ id: string;
297
+ output?: string;
298
+ status: "pending" | "in_progress" | "complete" | "error";
299
+ title: string;
300
+ type: "task_update";
301
+ }
302
+ interface PlanUpdateChunk {
303
+ title: string;
304
+ type: "plan_update";
305
+ }
275
306
  /**
276
307
  * Options for streaming messages.
277
308
  * Platform-specific options are passed through to the adapter.
@@ -283,6 +314,12 @@ interface StreamOptions {
283
314
  recipientUserId?: string;
284
315
  /** Block Kit elements to attach when stopping the stream (Slack only, via chat.stopStream) */
285
316
  stopBlocks?: unknown[];
317
+ /**
318
+ * Slack: Controls how task_update chunks are displayed.
319
+ * - `"timeline"` — individual task cards shown inline with text (default)
320
+ * - `"plan"` — all tasks grouped into a single plan block
321
+ */
322
+ taskDisplayMode?: "timeline" | "plan";
286
323
  /** Minimum interval between updates in ms (default: 1000). Used for fallback mode (GChat/Teams). */
287
324
  updateIntervalMs?: number;
288
325
  }
@@ -377,6 +414,8 @@ interface StateAdapter {
377
414
  releaseLock(lock: Lock): Promise<void>;
378
415
  /** Set a cached value with optional TTL in milliseconds */
379
416
  set<T = unknown>(key: string, value: T, ttlMs?: number): Promise<void>;
417
+ /** Atomically set a value only if the key does not already exist. Returns true if set, false if key existed. */
418
+ setIfNotExists(key: string, value: unknown, ttlMs?: number): Promise<boolean>;
380
419
  /** Subscribe to a thread (persists across restarts) */
381
420
  subscribe(threadId: string): Promise<void>;
382
421
  /** Unsubscribe from a thread */
@@ -413,11 +452,11 @@ interface Postable<TState = Record<string, unknown>, TRawMessage = unknown> {
413
452
  /**
414
453
  * Post a message.
415
454
  */
416
- post(message: string | PostableMessage | CardJSXElement): Promise<SentMessage<TRawMessage>>;
455
+ post(message: string | PostableMessage | ChatElement): Promise<SentMessage<TRawMessage>>;
417
456
  /**
418
457
  * Post an ephemeral message visible only to a specific user.
419
458
  */
420
- postEphemeral(user: string | Author, message: AdapterPostableMessage | CardJSXElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
459
+ postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
421
460
  /**
422
461
  * Set the state. Merges with existing state by default.
423
462
  */
@@ -562,7 +601,7 @@ interface Thread<TState = Record<string, unknown>, TRawMessage = unknown> extend
562
601
  * await thread.post(result.textStream);
563
602
  * ```
564
603
  */
565
- post(message: string | PostableMessage | CardJSXElement): Promise<SentMessage<TRawMessage>>;
604
+ post(message: string | PostableMessage | ChatElement): Promise<SentMessage<TRawMessage>>;
566
605
  /**
567
606
  * Post an ephemeral message visible only to a specific user.
568
607
  *
@@ -591,7 +630,7 @@ interface Thread<TState = Record<string, unknown>, TRawMessage = unknown> extend
591
630
  * }
592
631
  * ```
593
632
  */
594
- postEphemeral(user: string | Author, message: AdapterPostableMessage | CardJSXElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
633
+ postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
595
634
  /** Recently fetched messages (cached) */
596
635
  recentMessages: Message<TRawMessage>[];
597
636
  /**
@@ -747,7 +786,7 @@ interface SentMessage<TRawMessage = unknown> extends Message<TRawMessage> {
747
786
  /** Delete this message */
748
787
  delete(): Promise<void>;
749
788
  /** Edit this message with text, a PostableMessage, or a JSX Card element */
750
- edit(newContent: string | PostableMessage | CardJSXElement): Promise<SentMessage<TRawMessage>>;
789
+ edit(newContent: string | PostableMessage | ChatElement): Promise<SentMessage<TRawMessage>>;
751
790
  /** Remove a reaction from this message */
752
791
  removeReaction(emoji: EmojiValue | string): Promise<void>;
753
792
  }
@@ -794,8 +833,23 @@ type AdapterPostableMessage = string | PostableRaw | PostableMarkdown | Postable
794
833
  * - `{ card: CardElement }` - Rich card with buttons (Block Kit / Adaptive Cards / GChat Cards)
795
834
  * - `CardElement` - Direct card element
796
835
  * - `AsyncIterable<string>` - Streaming text (e.g., from AI SDK's textStream)
797
- */
798
- type PostableMessage = AdapterPostableMessage | AsyncIterable<string>;
836
+ * - `AsyncIterable<string | StreamEvent>` - AI SDK fullStream (auto-detected, extracts text with step separators)
837
+ */
838
+ type PostableMessage = AdapterPostableMessage | AsyncIterable<string | StreamChunk | StreamEvent>;
839
+ /**
840
+ * Duck-typed stream event compatible with AI SDK's `fullStream`.
841
+ * - `text-delta` events are extracted as text output.
842
+ * - `step-finish` events trigger paragraph separators between steps.
843
+ * - All other event types (tool-call, tool-result, etc.) are silently skipped.
844
+ */
845
+ type StreamEvent = {
846
+ textDelta: string;
847
+ type: "text-delta";
848
+ } | {
849
+ type: "step-finish";
850
+ } | {
851
+ type: string;
852
+ };
799
853
  interface PostableRaw {
800
854
  /** File/image attachments */
801
855
  attachments?: Attachment[];
@@ -1062,13 +1116,13 @@ interface ActionEvent<TRawMessage = unknown> {
1062
1116
  * @param modal - The modal element to display (JSX or ModalElement)
1063
1117
  * @returns The view/dialog ID, or undefined if modals are not supported
1064
1118
  */
1065
- openModal(modal: ModalElement | CardJSXElement): Promise<{
1119
+ openModal(modal: ModalElement | ChatElement): Promise<{
1066
1120
  viewId: string;
1067
1121
  } | undefined>;
1068
1122
  /** Platform-specific raw event data */
1069
1123
  raw: unknown;
1070
- /** The thread where the action occurred */
1071
- thread: Thread<TRawMessage>;
1124
+ /** The thread where the action occurred (null for view-based actions like home tab buttons) */
1125
+ thread: Thread<TRawMessage> | null;
1072
1126
  /** The thread ID */
1073
1127
  threadId: string;
1074
1128
  /** Trigger ID for opening modals (required by some platforms, may expire quickly) */
@@ -1241,7 +1295,7 @@ interface SlashCommandEvent<TState = Record<string, unknown>> {
1241
1295
  * @param modal - The modal element to display (JSX or ModalElement)
1242
1296
  * @returns The view/dialog ID, or undefined if modals are not supported
1243
1297
  */
1244
- openModal(modal: ModalElement | CardJSXElement): Promise<{
1298
+ openModal(modal: ModalElement | ChatElement): Promise<{
1245
1299
  viewId: string;
1246
1300
  } | undefined>;
1247
1301
  /** Platform-specific raw payload */
@@ -1519,9 +1573,9 @@ declare class ChannelImpl<TState = Record<string, unknown>> implements Channel<T
1519
1573
  */
1520
1574
  threads(): AsyncIterable<ThreadSummary>;
1521
1575
  fetchMetadata(): Promise<ChannelInfo>;
1522
- post(message: string | PostableMessage | CardJSXElement): Promise<SentMessage>;
1576
+ post(message: string | PostableMessage | ChatElement): Promise<SentMessage>;
1523
1577
  private postSingleMessage;
1524
- postEphemeral(user: string | Author, message: AdapterPostableMessage | CardJSXElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
1578
+ postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
1525
1579
  startTyping(status?: string): Promise<void>;
1526
1580
  mentionUser(userId: string): string;
1527
1581
  toJSON(): SerializedChannel;
@@ -1979,6 +2033,27 @@ declare class Chat<TAdapters extends Record<string, Adapter> = Record<string, Ad
1979
2033
  private runHandlers;
1980
2034
  }
1981
2035
 
2036
+ /**
2037
+ * Normalizes an async iterable stream for use with `thread.post()`.
2038
+ *
2039
+ * Handles three stream types automatically:
2040
+ * - **Text streams** (`AsyncIterable<string>`, e.g. AI SDK `textStream`) —
2041
+ * passed through as-is.
2042
+ * - **Full streams** (`AsyncIterable<object>`, e.g. AI SDK `fullStream`) —
2043
+ * extracts `text-delta` events and injects `"\n\n"` separators between
2044
+ * steps so that multi-step agent output reads naturally.
2045
+ * - **StreamChunk objects** (`task_update`, `plan_update`, `markdown_text`) —
2046
+ * passed through as-is for adapters with native structured chunk support.
2047
+ *
2048
+ * This is used internally by `thread.post()`, so you can pass either stream
2049
+ * directly:
2050
+ * ```ts
2051
+ * await thread.post(result.fullStream); // auto-detected
2052
+ * await thread.post(result.textStream); // still works
2053
+ * ```
2054
+ */
2055
+ declare function fromFullStream(stream: AsyncIterable<unknown>): AsyncIterable<string | StreamChunk>;
2056
+
1982
2057
  /**
1983
2058
  * A streaming markdown renderer that buffers potential table headers
1984
2059
  * until confirmed by a separator line, preventing tables from flashing
@@ -2126,11 +2201,12 @@ declare class ThreadImpl<TState = Record<string, unknown>> implements Thread<TSt
2126
2201
  isSubscribed(): Promise<boolean>;
2127
2202
  subscribe(): Promise<void>;
2128
2203
  unsubscribe(): Promise<void>;
2129
- post(message: string | PostableMessage | CardJSXElement): Promise<SentMessage>;
2130
- postEphemeral(user: string | Author, message: AdapterPostableMessage | CardJSXElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
2204
+ post(message: string | PostableMessage | ChatElement): Promise<SentMessage>;
2205
+ postEphemeral(user: string | Author, message: AdapterPostableMessage | ChatElement, options: PostEphemeralOptions): Promise<EphemeralMessage | null>;
2131
2206
  /**
2132
2207
  * Handle streaming from an AsyncIterable.
2133
- * Uses adapter's native streaming if available, otherwise falls back to post+edit.
2208
+ * Normalizes the stream (supports both textStream and fullStream from AI SDK),
2209
+ * then uses adapter's native streaming if available, otherwise falls back to post+edit.
2134
2210
  */
2135
2211
  private handleStream;
2136
2212
  startTyping(status?: string): Promise<void>;
@@ -2548,6 +2624,7 @@ interface MarkdownConverter extends FormatConverter {
2548
2624
  declare abstract class BaseFormatConverter implements FormatConverter {
2549
2625
  abstract fromAst(ast: Root): string;
2550
2626
  abstract toAst(platformText: string): Root;
2627
+ protected renderList(node: List, depth: number, nodeConverter: (node: Content) => string, unorderedBullet?: string): string;
2551
2628
  /**
2552
2629
  * Default fallback for converting an unknown mdast node to text.
2553
2630
  * Recursively converts children if present, otherwise extracts the node value.
@@ -2593,31 +2670,31 @@ declare abstract class BaseFormatConverter implements FormatConverter {
2593
2670
  protected cardChildToFallbackText(child: CardChild): string | null;
2594
2671
  }
2595
2672
 
2596
- declare const Actions: typeof Actions$1;
2597
- declare const Button: typeof Button$1;
2598
- declare const Card: typeof Card$1;
2673
+ declare const Actions: ActionsComponent;
2674
+ declare const Button: ButtonComponent;
2675
+ declare const Card: CardComponent;
2599
2676
  declare const cardChildToFallbackText: typeof cardChildToFallbackText$1;
2600
- declare const CardLink: typeof CardLink$1;
2601
- declare const CardText: typeof Text$1;
2602
- declare const Divider: typeof Divider$1;
2603
- declare const Field: typeof Field$1;
2604
- declare const Fields: typeof Fields$1;
2677
+ declare const CardLink: CardLinkComponent;
2678
+ declare const CardText: TextComponent;
2679
+ declare const Divider: DividerComponent;
2680
+ declare const Field: FieldComponent;
2681
+ declare const Fields: FieldsComponent;
2605
2682
  declare const fromReactElement: typeof fromReactElement$1;
2606
- declare const Image: typeof Image$1;
2683
+ declare const Image: ImageComponent;
2607
2684
  declare const isCardElement: typeof isCardElement$1;
2608
2685
  declare const isJSX: typeof isJSX$1;
2609
- declare const LinkButton: typeof LinkButton$1;
2610
- declare const Section: typeof Section$1;
2686
+ declare const LinkButton: LinkButtonComponent;
2687
+ declare const Section: SectionComponent;
2611
2688
  declare const Table: typeof Table$2;
2612
2689
  declare const toCardElement: typeof toCardElement$1;
2613
2690
  declare const toModalElement: typeof toModalElement$1;
2614
2691
 
2615
2692
  declare const fromReactModalElement: typeof fromReactModalElement$1;
2616
2693
  declare const isModalElement: typeof isModalElement$1;
2617
- declare const Modal: typeof Modal$1;
2618
- declare const RadioSelect: typeof RadioSelect$1;
2619
- declare const Select: typeof Select$1;
2620
- declare const SelectOption: typeof SelectOption$1;
2621
- declare const TextInput: typeof TextInput$1;
2694
+ declare const Modal: ModalComponent;
2695
+ declare const RadioSelect: RadioSelectComponent;
2696
+ declare const Select: SelectComponent;
2697
+ declare const SelectOption: SelectOptionComponent;
2698
+ declare const TextInput: TextInputComponent;
2622
2699
 
2623
- export { type ActionEvent, type ActionHandler, Actions, type Adapter, type AdapterPostableMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, Card, CardChild, CardElement, CardJSXElement, CardLink, CardText, type Channel, ChannelImpl, type ChannelInfo, Chat, type ChatConfig, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, Fields, type FileUpload, type FormatConverter, type FormattedContent, Image, LinkButton, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MemberJoinedChannelEvent, type MemberJoinedChannelHandler, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, Select, SelectOption, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StateAdapter, type StreamOptions, StreamingMarkdownRenderer, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, Table, TextInput, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type WebhookOptions, type WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toCardElement, toModalElement, toPlainText, walkAst };
2700
+ export { type ActionEvent, type ActionHandler, Actions, ActionsComponent, type Adapter, type AdapterPostableMessage, type AppHomeOpenedEvent, type AppHomeOpenedHandler, type AssistantContextChangedEvent, type AssistantContextChangedHandler, type AssistantThreadStartedEvent, type AssistantThreadStartedHandler, type Attachment, type Author, BaseFormatConverter, Button, ButtonComponent, Card, CardChild, CardComponent, CardElement, CardLink, CardLinkComponent, CardText, type Channel, ChannelImpl, type ChannelInfo, Chat, type ChatConfig, ChatElement, ChatError, type ChatInstance, ConsoleLogger, type CustomEmojiMap, DEFAULT_EMOJI_MAP, Divider, DividerComponent, type Emoji, type EmojiFormats, type EmojiMapConfig, EmojiResolver, type EmojiValue, type EphemeralMessage, type FetchDirection, type FetchOptions, type FetchResult, Field, FieldComponent, Fields, FieldsComponent, type FileUpload, type FormatConverter, type FormattedContent, Image, ImageComponent, LinkButton, LinkButtonComponent, type ListThreadsOptions, type ListThreadsResult, type Lock, LockError, type LogLevel, type Logger, type MarkdownConverter, type MarkdownTextChunk, type MemberJoinedChannelEvent, type MemberJoinedChannelHandler, type MentionHandler, Message, type MessageData, type MessageHandler, type MessageMetadata, Modal, type ModalCloseEvent, type ModalCloseHandler, type ModalCloseResponse, ModalComponent, ModalElement, type ModalErrorsResponse, type ModalPushResponse, type ModalResponse, type ModalSubmitEvent, type ModalSubmitHandler, type ModalUpdateResponse, NotImplementedError, type PlanUpdateChunk, type PostEphemeralOptions, type Postable, type PostableAst, type PostableCard, type PostableMarkdown, type PostableMessage, type PostableRaw, RadioSelect, RadioSelectComponent, RateLimitError, type RawMessage, type ReactionEvent, type ReactionHandler, Section, SectionComponent, Select, SelectComponent, SelectOption, SelectOptionComponent, type SentMessage, type SerializedChannel, type SerializedMessage, type SerializedThread, type SlashCommandEvent, type SlashCommandHandler, type StateAdapter, type StreamChunk, type StreamEvent, type StreamOptions, StreamingMarkdownRenderer, type SubscribedMessageHandler, THREAD_STATE_TTL_MS, Table, type TaskUpdateChunk, TextComponent, TextInput, TextInputComponent, type Thread, ThreadImpl, type ThreadInfo, type ThreadSummary, type WebhookOptions, type WellKnownEmoji, blockquote, cardChildToFallbackText, codeBlock, convertEmojiPlaceholders, createEmoji, defaultEmojiResolver, deriveChannelId, emoji, emphasis, fromFullStream, fromReactElement, fromReactModalElement, getEmoji, getNodeChildren, getNodeValue, inlineCode, isBlockquoteNode, isCardElement, isCodeNode, isDeleteNode, isEmphasisNode, isInlineCodeNode, isJSX, isLinkNode, isListItemNode, isListNode, isModalElement, isParagraphNode, isStrongNode, isTableCellNode, isTableNode, isTableRowNode, isTextNode, link, markdownToPlainText, paragraph, parseMarkdown, root, strikethrough, stringifyMarkdown, strong, tableElementToAscii, tableToAscii, text, toCardElement, toModalElement, toPlainText, walkAst };