slackmark 0.6.0 → 0.6.2
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.
- package/dist/adapters/block-to-plain-text.d.ts +24 -0
- package/dist/adapters/block-to-plain-text.d.ts.map +1 -0
- package/dist/adapters/blockquote-adapter.d.ts.map +1 -1
- package/dist/adapters/inline.d.ts.map +1 -1
- package/dist/adapters/list-adapter.d.ts.map +1 -1
- package/dist/adapters/phrasing-to-markdown.d.ts +15 -0
- package/dist/adapters/phrasing-to-markdown.d.ts.map +1 -0
- package/dist/adapters/table-adapter.d.ts.map +1 -1
- package/dist/adapters/task-list-adapter.d.ts +6 -1
- package/dist/adapters/task-list-adapter.d.ts.map +1 -1
- package/dist/assemble/text-fallback.d.ts.map +1 -1
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/converter/slackmark-converter.d.ts.map +1 -1
- package/dist/index.js +453 -47
- package/dist/index.js.map +1 -1
- package/dist/renderers.d.ts +1 -0
- package/dist/renderers.d.ts.map +1 -1
- package/dist/renderers.js +61 -50
- package/dist/renderers.js.map +1 -1
- package/dist/slack.d.ts +1 -0
- package/dist/slack.d.ts.map +1 -1
- package/dist/slack.js +32 -22
- package/dist/slack.js.map +1 -1
- package/dist/validate/validate-blocks.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Overflow","COMMENT_RE","code"],"sources":["../src/errors.ts","../src/capabilities/capabilities.ts","../src/constants.ts","../src/budget/standard-budget-ledger.ts","../src/budget/recording-degradation-collector.ts","../src/budget/recording-receipt-collector.ts","../src/budget/conversion-context.ts","../src/registry/adapter-registry.ts","../src/assert-never.ts","../src/utf16.ts","../src/receipts.ts","../src/types.ts","../src/assemble/message-assembler.ts","../src/assemble/text-fallback.ts","../src/parsers/remark-markdown-parser.ts","../src/mermaid/mermaid-pie-parser.ts","../src/mermaid/mermaid-xychart-parser.ts","../src/budget/operation-scope.ts","../src/converter/resolve-config.ts","../src/converter/slackmark-converter.ts","../src/adapters/inline.ts","../src/adapters/blockquote-adapter.ts","../src/slack/slack-upload-error.ts","../src/adapters/try-render-image.ts","../src/adapters/code-fence-adapter.ts","../src/adapters/heading-adapter.ts","../src/adapters/html-block-adapter.ts","../src/adapters/list-adapter.ts","../src/adapters/math-block-adapter.ts","../src/adapters/mermaid-fence-adapter.ts","../src/adapters/paragraph-adapter.ts","../src/adapters/skip-adapter.ts","../src/adapters/table-adapter.ts","../src/adapters/task-list-adapter.ts","../src/adapters/thematic-break-adapter.ts","../src/converter/create-converter.ts","../src/validate/validate-blocks.ts"],"sourcesContent":["import type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Registry-keyed markers, not module-local symbols.\n *\n * Each published entry (`slackmark`, `slackmark/renderers`, `slackmark/slack`) is bundled\n * without code splitting, so every entry carries its own copy of these classes and\n * `instanceof` is false for an error that crosses an entry boundary. `Symbol.for` keys are\n * shared by every copy, which is what makes the exported guards below reliable. Prefer\n * those guards to `instanceof` for any error that can cross an entry.\n */\nconst RECEIPT_SNAPSHOT_LOCK = Symbol.for(\"slackmark.receiptSnapshotLock\");\nconst OPERATION_ERROR_CARRIER = Symbol.for(\"slackmark.operationErrorCarrier\");\nconst CONFIGURATION_ERROR_BRAND = Symbol.for(\"slackmark.error.configuration\");\nconst OPERATION_ERROR_BRAND = Symbol.for(\"slackmark.error.operation\");\n\n/**\n * Marks a class prototype so instances from any bundled copy answer to one identity.\n * Subclasses inherit the brand, and instances carry no extra own property.\n */\nexport function brandErrorPrototype(prototype: object, brand: symbol): void {\n Object.defineProperty(prototype, brand, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n}\n\n/**\n * Reads a brand without trusting the value: a hostile getter must not escape a guard.\n */\nexport function hasErrorBrand(value: unknown, brand: symbol): boolean {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n try {\n return Reflect.get(value, brand) === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Programmer/configuration error thrown only from the composition root.\n */\nexport interface ConfigurationErrorOptions {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\nexport class ConfigurationError extends Error {\n static {\n brandErrorPrototype(this.prototype, CONFIGURATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: string;\n readonly stage: string | undefined;\n readonly retryable: false;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, options: ConfigurationErrorOptions = {}) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"ConfigurationError\";\n this.code = options.code ?? \"invalid_configuration\";\n this.stage = options.stage;\n this.retryable = false;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport const OperationErrorCode = {\n Aborted: \"operation_aborted\",\n DeadlineExceeded: \"operation_deadline_exceeded\",\n Shutdown: \"operation_shutdown\",\n} as const;\n\nexport type OperationErrorCode = (typeof OperationErrorCode)[keyof typeof OperationErrorCode];\n\nexport interface OperationErrorOptions {\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Operational control-flow error. These failures are never degradations.\n */\nexport class OperationError extends Error {\n static {\n brandErrorPrototype(this.prototype, OPERATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: OperationErrorCode;\n readonly stage: string;\n readonly retryable: boolean;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n message: string,\n code: OperationErrorCode,\n stage: string,\n retryable: boolean,\n options: OperationErrorOptions = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"OperationError\";\n this.code = code;\n this.stage = stage;\n this.retryable = retryable;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport class OperationAbortedError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation aborted by caller\", OperationErrorCode.Aborted, stage, false, options);\n this.name = \"OperationAbortedError\";\n }\n}\n\nexport class OperationDeadlineExceededError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation deadline exceeded\", OperationErrorCode.DeadlineExceeded, stage, true, options);\n this.name = \"OperationDeadlineExceededError\";\n }\n}\n\nexport class OperationShutdownError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation interrupted by shutdown\", OperationErrorCode.Shutdown, stage, true, options);\n this.name = \"OperationShutdownError\";\n }\n}\n\n/**\n * Identifies a {@link ConfigurationError} from any entry of this package.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example a `ConfigurationError` from `slackmark/renderers` caught by code\n * that imported the class from `slackmark`.\n */\nexport function isConfigurationError(value: unknown): value is ConfigurationError {\n return hasErrorBrand(value, CONFIGURATION_ERROR_BRAND);\n}\n\n/**\n * Identifies an {@link OperationError} — abort, deadline, or shutdown — from any entry of\n * this package, including its subclasses.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example an abort raised inside `FetchSlackUploader` from `slackmark/slack`\n * caught by code that imported the class from `slackmark`. Narrow further with `code`\n * against {@link OperationErrorCode} rather than testing a subclass with `instanceof`.\n */\nexport function isOperationError(value: unknown): value is OperationError {\n return hasErrorBrand(value, OPERATION_ERROR_BRAND);\n}\n\nexport function cloneOperationError(error: OperationError, fallbackStage: string): OperationError {\n const stage = error.stage.length > 0 ? error.stage : fallbackStage;\n const options: OperationErrorOptions = {\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n };\n let cloned: OperationError;\n switch (error.code) {\n case OperationErrorCode.Aborted:\n cloned = new OperationAbortedError(stage, options);\n break;\n case OperationErrorCode.DeadlineExceeded:\n cloned = new OperationDeadlineExceededError(stage, options);\n break;\n case OperationErrorCode.Shutdown:\n cloned = new OperationShutdownError(stage, options);\n break;\n }\n Reflect.defineProperty(cloned, OPERATION_ERROR_CARRIER, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n return cloned;\n}\n\nexport function isOperationErrorCarrier(error: OperationError): boolean {\n return Reflect.get(error, OPERATION_ERROR_CARRIER) === true;\n}\n\nexport function cloneConfigurationError(error: ConfigurationError): ConfigurationError {\n return new ConfigurationError(error.message, {\n code: error.code,\n stage: error.stage,\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n });\n}\n\nexport function attachReceipts(\n error: unknown,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts?: Promise<ReadonlyArray<UploadReceipt>>,\n): unknown {\n if (!(error instanceof Error)) {\n return error;\n }\n try {\n if (Reflect.get(error, RECEIPT_SNAPSHOT_LOCK) === true) {\n return error;\n }\n } catch {\n return error;\n }\n let existing: ReadonlyArray<UploadReceipt> = [];\n try {\n const candidate = Reflect.get(error, \"receipts\");\n if (Array.isArray(candidate)) {\n existing = candidate.filter(isUploadReceipt);\n }\n } catch {\n existing = [];\n }\n Reflect.defineProperty(error, \"receipts\", {\n configurable: true,\n enumerable: true,\n value: freezeReceipts(mergeReceipts(existing, receipts)),\n writable: false,\n });\n if (settledReceipts !== undefined) {\n const finalReceipts = freezeSettledReceipts(settledReceipts, receipts);\n Reflect.defineProperty(error, \"settledReceipts\", {\n configurable: true,\n enumerable: true,\n value: finalReceipts,\n writable: false,\n });\n }\n return error;\n}\n\nexport function lockReceiptSnapshot(error: unknown): unknown {\n if (error instanceof Error) {\n Reflect.defineProperty(error, RECEIPT_SNAPSHOT_LOCK, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n }\n return error;\n}\n\nasync function freezeSettledReceipts(\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n fallback: ReadonlyArray<UploadReceipt>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n return freezeReceipts(await settledReceipts);\n } catch {\n return freezeReceipts(fallback);\n }\n}\n\nfunction mergeReceipts(\n existing: ReadonlyArray<UploadReceipt>,\n incoming: ReadonlyArray<UploadReceipt>,\n): ReadonlyArray<UploadReceipt> {\n const existingGroups = groupReceipts(existing);\n const incomingGroups = groupReceipts(incoming);\n const merged: UploadReceipt[] = [...incoming];\n for (const [key, values] of existingGroups) {\n const overlap = incomingGroups.get(key)?.length ?? 0;\n if (values.length > overlap) {\n merged.push(...values.slice(overlap));\n }\n }\n return merged;\n}\n\nfunction groupReceipts(\n receipts: ReadonlyArray<UploadReceipt>,\n): ReadonlyMap<string, ReadonlyArray<UploadReceipt>> {\n const grouped = new Map<string, UploadReceipt[]>();\n for (const receipt of receipts) {\n const key = receiptKey(receipt);\n const values = grouped.get(key);\n if (values === undefined) {\n grouped.set(key, [receipt]);\n } else {\n values.push(receipt);\n }\n }\n return grouped;\n}\n\nfunction receiptKey(receipt: UploadReceipt): string {\n return [\n receipt.provider,\n receipt.phase,\n receipt.fileId ?? \"\",\n String(receipt.shared),\n receipt.processing,\n String(receipt.status ?? \"\"),\n String(receipt.retryAfterMs ?? \"\"),\n receipt.providerCode ?? \"\",\n receipt.retrySafety,\n ].join(\"\\u0000\");\n}\n\nfunction freezeReceipts(receipts: ReadonlyArray<UploadReceipt>): ReadonlyArray<UploadReceipt> {\n return Object.freeze(receipts.map((receipt) => Object.freeze({ ...receipt })));\n}\n\nfunction isUploadReceipt(value: unknown): value is UploadReceipt {\n return typeof value === \"object\" && value !== null && Reflect.get(value, \"kind\") === \"upload\";\n}\n","/**\n * Capability profiles keyed to Slack changelog dates.\n * @see design/mapping-matrix.md\n */\nimport { ConfigurationError } from \"../errors.js\";\n\nexport interface CapabilityFlags {\n readonly markdownBlock: boolean;\n readonly tableBlock: boolean;\n readonly preformattedLanguage: boolean;\n readonly headerLevel: boolean;\n readonly dataTable: boolean;\n readonly dataVisualization: boolean;\n readonly containerBlock: boolean;\n}\n\nexport type CapabilityFlag = keyof CapabilityFlags;\nconst CAPABILITY_KEYS: ReadonlyArray<CapabilityFlag> = [\n \"markdownBlock\",\n \"tableBlock\",\n \"preformattedLanguage\",\n \"headerLevel\",\n \"dataTable\",\n \"dataVisualization\",\n \"containerBlock\",\n];\n\nexport const CapabilityPresetName = {\n Latest: \"latest\",\n Conservative: \"conservative\",\n D2025_02: \"2025-02\",\n D2025_08: \"2025-08\",\n D2026_03: \"2026-03\",\n D2026_05: \"2026-05\",\n D2026_06: \"2026-06\",\n} as const;\n\nexport type CapabilityPresetName = (typeof CapabilityPresetName)[keyof typeof CapabilityPresetName];\n\nconst ALL_OFF: CapabilityFlags = {\n markdownBlock: false,\n tableBlock: false,\n preformattedLanguage: false,\n headerLevel: false,\n dataTable: false,\n dataVisualization: false,\n containerBlock: false,\n};\n\n/** Baseline rich_text path only — every optional Slack capability off. */\nconst CONSERVATIVE: CapabilityFlags = { ...ALL_OFF };\n\nconst P_2025_02: CapabilityFlags = {\n ...CONSERVATIVE,\n markdownBlock: true,\n};\n\nconst P_2025_08: CapabilityFlags = {\n ...P_2025_02,\n tableBlock: true,\n};\n\nconst P_2026_03: CapabilityFlags = {\n ...P_2025_08,\n preformattedLanguage: true,\n headerLevel: true,\n};\n\nconst P_2026_05: CapabilityFlags = {\n ...P_2026_03,\n dataTable: true,\n};\n\nconst P_2026_06: CapabilityFlags = {\n ...P_2026_05,\n dataVisualization: true,\n containerBlock: true,\n};\n\nconst LATEST: CapabilityFlags = { ...P_2026_06 };\n\nexport const CAPABILITY_PRESETS: {\n readonly latest: CapabilityFlags;\n readonly conservative: CapabilityFlags;\n readonly \"2025-02\": CapabilityFlags;\n readonly \"2025-08\": CapabilityFlags;\n readonly \"2026-03\": CapabilityFlags;\n readonly \"2026-05\": CapabilityFlags;\n readonly \"2026-06\": CapabilityFlags;\n} = {\n latest: LATEST,\n conservative: CONSERVATIVE,\n \"2025-02\": P_2025_02,\n \"2025-08\": P_2025_08,\n \"2026-03\": P_2026_03,\n \"2026-05\": P_2026_05,\n \"2026-06\": P_2026_06,\n};\n\nexport type CapabilityFlagsPartial = {\n readonly [K in CapabilityFlag]?: boolean;\n};\n\n/**\n * Resolve a preset name, flags object, or preset + overrides into immutable flags.\n * Unknown preset names throw {@link ConfigurationError}: silently substituting\n * `latest` would enable every capability behind a typo.\n */\nexport function resolveCapabilities(\n input: CapabilityPresetName | CapabilityFlags | CapabilityFlagsPartial | undefined,\n overrides?: CapabilityFlagsPartial,\n): CapabilityFlags {\n let base: CapabilityFlags;\n if (input === undefined) {\n base = CAPABILITY_PRESETS.latest;\n } else if (typeof input === \"string\") {\n const preset = isPresetName(input) ? CAPABILITY_PRESETS[input] : undefined;\n if (preset === undefined) {\n throw new ConfigurationError(\n `Unknown capability preset; use one of: ${Object.keys(CAPABILITY_PRESETS).join(\", \")}.`,\n );\n }\n base = preset;\n } else {\n const normalized = normalizeFlags(input, \"capabilities\");\n base = isFullFlags(normalized) ? normalized : { ...CAPABILITY_PRESETS.latest, ...normalized };\n }\n if (overrides === undefined) {\n return Object.freeze({ ...base });\n }\n return Object.freeze({\n ...base,\n ...normalizeFlags(overrides, \"capabilityOverrides\"),\n });\n}\n\nfunction normalizeFlags(value: unknown, label: string): CapabilityFlagsPartial {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n } catch (cause) {\n throw new ConfigurationError(`${label} could not be inspected`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n cause,\n });\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n const normalized: Partial<Record<CapabilityFlag, boolean>> = {};\n for (const key of keys) {\n if (!isCapabilityKey(key)) {\n throw new ConfigurationError(`Unknown ${label} key: ${key}`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n let flag: unknown;\n try {\n flag = Reflect.get(value, key);\n } catch (cause) {\n throw new ConfigurationError(`${label}.${key} could not be read`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n cause,\n });\n }\n if (typeof flag !== \"boolean\") {\n throw new ConfigurationError(`${label}.${key} must be boolean`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n normalized[key] = flag;\n }\n return normalized;\n}\n\nfunction isCapabilityKey(value: string): value is CapabilityFlag {\n return CAPABILITY_KEYS.includes(value as CapabilityFlag);\n}\n\n// TS narrows string inputs to CapabilityPresetName, but JS callers can pass\n// any string; membership must be checked at runtime.\nfunction isPresetName(value: string): value is CapabilityPresetName {\n return Object.hasOwn(CAPABILITY_PRESETS, value);\n}\n\nfunction isFullFlags(value: CapabilityFlags | CapabilityFlagsPartial): value is CapabilityFlags {\n return (\n typeof value.markdownBlock === \"boolean\" &&\n typeof value.tableBlock === \"boolean\" &&\n typeof value.preformattedLanguage === \"boolean\" &&\n typeof value.headerLevel === \"boolean\" &&\n typeof value.dataTable === \"boolean\" &&\n typeof value.dataVisualization === \"boolean\" &&\n typeof value.containerBlock === \"boolean\"\n );\n}\n","/**\n * Named Slack Block Kit limits.\n * Sources: https://docs.slack.dev/block-kit and block reference pages (July 2026 research).\n */\n\n/** https://docs.slack.dev/block-kit */\nexport const MAX_BLOCKS_PER_MESSAGE = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/section-block */\nexport const SECTION_TEXT_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_TEXT_MAX_CHARS = 150;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_LEVEL_MAX = 4;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_URL_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_ALT_MAX_CHARS = 2000;\n\n/** slackmark renderer safety limit for retained/uploaded image bytes. */\nexport const RENDERED_IMAGE_MAX_BYTES: number = 10 * 1024 * 1024;\n\n/** Portable filename component limit used by renderer output validation. */\nexport const RENDERED_IMAGE_FILENAME_MAX_CHARS = 255;\n\n/** Defensive upper bound for Slack file IDs returned by uploaders. */\nexport const SLACK_FILE_ID_MAX_CHARS = 255;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/context-block */\nexport const CONTEXT_ELEMENTS_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/markdown-block */\nexport const MARKDOWN_CUMULATIVE_MAX_CHARS = 12_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_ROWS = 100;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_COLS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_CELL_CHARS_MAX = 10_000;\n\n/** Spec decision: prefer `table` up to this many rows (incl. header). */\nexport const TABLE_PREFERRED_MAX_ROWS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_MAX_DATA_ROWS = 200;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_CELL_CHARS_MAX = 20_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_TITLE_MAX_CHARS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_LABEL_MAX_CHARS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SEGMENTS_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SERIES_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_POINTS_MAX = 20;\n\n/**\n * Community-reported cap (ENG-4936); not in official docs.\n * Enforced defensively with degradation.\n */\nexport const DATA_VISUALIZATION_MAX_PER_MESSAGE = 2;\n\n/** https://docs.slack.dev/reference/methods/chat.postMessage#truncating */\nexport const MESSAGE_TEXT_SAFETY_MAX_CHARS = 40_000;\n\n/** Undocumented; defensive clamp for rich_text_list.indent. */\nexport const RICH_TEXT_LIST_INDENT_MAX = 6;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_CHILDREN_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_TITLE_MAX_CHARS = 150;\n\n/** Cell wrap heuristic for table column_settings.is_wrapped. */\nexport const TABLE_CELL_WRAP_THRESHOLD = 40;\n\nexport const ELLIPSIS = \"…\";\n","import {\n DATA_TABLE_CELL_CHARS_MAX,\n DATA_VISUALIZATION_MAX_PER_MESSAGE,\n MARKDOWN_CUMULATIVE_MAX_CHARS,\n MAX_BLOCKS_PER_MESSAGE,\n MESSAGE_TEXT_SAFETY_MAX_CHARS,\n TABLE_CELL_CHARS_MAX,\n} from \"../constants.js\";\nimport type { BudgetClaim, BudgetLedger, BudgetSnapshot } from \"../types.js\";\n\nexport interface StandardBudgetLedgerOptions {\n /**\n * When false, the per-message chart cap is not enforced (used while emitting\n * a document that will be split; the assembler re-applies the cap per message).\n * Table/markdown/total char caps stay enforced so oversized single blocks cannot slip through.\n */\n readonly enforceChartCap?: boolean;\n}\n\n/**\n * O(1) running-total budget tracker for a single Slack message.\n */\nexport class StandardBudgetLedger implements BudgetLedger {\n readonly maxBlocks: number;\n private readonly enforceChartCap: boolean;\n private blocks: number;\n private tableChars: number;\n private dataTableChars: number;\n private markdownChars: number;\n private charts: number;\n private totalChars: number;\n\n constructor(maxBlocks: number = MAX_BLOCKS_PER_MESSAGE, options?: StandardBudgetLedgerOptions) {\n this.maxBlocks = maxBlocks;\n this.enforceChartCap = options?.enforceChartCap ?? true;\n this.blocks = 0;\n this.tableChars = 0;\n this.dataTableChars = 0;\n this.markdownChars = 0;\n this.charts = 0;\n this.totalChars = 0;\n }\n\n tryReserveClaim(claim: BudgetClaim | undefined): boolean {\n if (claim === undefined) {\n return true;\n }\n const nextBlocks = this.blocks + (claim.blocks ?? 0);\n const nextTable = this.tableChars + (claim.tableChars ?? 0);\n const nextData = this.dataTableChars + (claim.dataTableChars ?? 0);\n const nextMd = this.markdownChars + (claim.markdownChars ?? 0);\n const nextCharts = this.charts + (claim.chart === true ? 1 : 0);\n const nextTotal = this.totalChars + (claim.totalChars ?? 0);\n\n if (nextBlocks > this.maxBlocks) return false;\n if (nextTable > TABLE_CELL_CHARS_MAX) return false;\n if (nextData > DATA_TABLE_CELL_CHARS_MAX) return false;\n if (nextMd > MARKDOWN_CUMULATIVE_MAX_CHARS) return false;\n if (this.enforceChartCap && nextCharts > DATA_VISUALIZATION_MAX_PER_MESSAGE) return false;\n if (nextTotal > MESSAGE_TEXT_SAFETY_MAX_CHARS) return false;\n\n this.blocks = nextBlocks;\n this.tableChars = nextTable;\n this.dataTableChars = nextData;\n this.markdownChars = nextMd;\n this.charts = nextCharts;\n this.totalChars = nextTotal;\n return true;\n }\n\n snapshot(): BudgetSnapshot {\n return {\n blocks: this.blocks,\n tableChars: this.tableChars,\n dataTableChars: this.dataTableChars,\n markdownChars: this.markdownChars,\n charts: this.charts,\n totalChars: this.totalChars,\n };\n }\n\n restore(snapshot: BudgetSnapshot): void {\n this.blocks = snapshot.blocks;\n this.tableChars = snapshot.tableChars;\n this.dataTableChars = snapshot.dataTableChars;\n this.markdownChars = snapshot.markdownChars;\n this.charts = snapshot.charts;\n this.totalChars = snapshot.totalChars;\n }\n\n resetForNewMessage(): void {\n this.blocks = 0;\n this.tableChars = 0;\n this.dataTableChars = 0;\n this.markdownChars = 0;\n this.charts = 0;\n this.totalChars = 0;\n }\n}\n","import type { Degradation, DegradationCollector } from \"../types.js\";\n\n/**\n * In-memory degradation collector for one conversion.\n */\nexport class RecordingDegradationCollector implements DegradationCollector {\n private readonly items: Degradation[];\n\n constructor() {\n this.items = [];\n }\n\n add(d: Degradation): void {\n this.items.push(d);\n }\n\n all(): ReadonlyArray<Degradation> {\n return this.items.slice();\n }\n}\n","import type { ReceiptCollector, UploadReceipt } from \"../types.js\";\n\nexport class RecordingReceiptCollector implements ReceiptCollector {\n private readonly items: UploadReceipt[];\n private readonly settledPromise: Promise<ReadonlyArray<UploadReceipt>>;\n private readonly resolveSettled: (receipts: ReadonlyArray<UploadReceipt>) => void;\n private isSettled: boolean;\n\n constructor() {\n this.items = [];\n let resolvePromise: ((receipts: ReadonlyArray<UploadReceipt>) => void) | undefined;\n this.settledPromise = new Promise((resolve) => {\n resolvePromise = resolve;\n });\n this.resolveSettled = (receipts): void => {\n resolvePromise?.(receipts);\n };\n this.isSettled = false;\n }\n\n add(receipt: UploadReceipt): void {\n this.items.push(Object.freeze({ ...receipt }));\n }\n\n all(): ReadonlyArray<UploadReceipt> {\n return Object.freeze([...this.items]);\n }\n\n settle(): void {\n if (this.isSettled) {\n return;\n }\n this.isSettled = true;\n this.resolveSettled(this.all());\n }\n\n settled(): Promise<ReadonlyArray<UploadReceipt>> {\n return this.settledPromise;\n }\n}\n","import type { Definition, FootnoteDefinition } from \"mdast\";\n\nimport type { CapabilityFlags } from \"../capabilities/capabilities.js\";\nimport type {\n BudgetLedger,\n ConversionStrategy,\n DegradationCollector,\n ImageRenderer,\n MentionResolvers,\n OperationContext,\n OverflowMode,\n ReceiptCollector,\n SlackUploader,\n} from \"../types.js\";\n\n/**\n * Immutable resolved config for one conversion.\n */\nexport interface ResolvedConfig {\n readonly capabilities: CapabilityFlags;\n readonly overflow: OverflowMode;\n readonly strategy: ConversionStrategy;\n readonly renderers: ReadonlyArray<ImageRenderer>;\n readonly uploader: SlackUploader | undefined;\n readonly enableMath: boolean;\n readonly enableInlineMath: boolean;\n readonly enableFrontmatter: boolean;\n readonly mentionResolvers: MentionResolvers | undefined;\n readonly operation: OperationContext;\n}\n\nexport interface ConversionContextDeps {\n readonly config: ResolvedConfig;\n readonly budget: BudgetLedger;\n readonly degradations: DegradationCollector;\n readonly receipts: ReceiptCollector;\n readonly definitions: ReadonlyMap<string, Definition>;\n readonly footnotes: ReadonlyMap<string, FootnoteDefinition>;\n readonly footnoteOrder: ReadonlyArray<string>;\n readonly precedingHeading: string | undefined;\n readonly path: string;\n}\n\n/**\n * Per-call conversion state. Never stored on converter instances.\n */\nexport class ConversionContext {\n readonly config: ResolvedConfig;\n readonly budget: BudgetLedger;\n readonly degradations: DegradationCollector;\n readonly receipts: ReceiptCollector;\n readonly definitions: ReadonlyMap<string, Definition>;\n readonly footnotes: ReadonlyMap<string, FootnoteDefinition>;\n readonly footnoteOrder: ReadonlyArray<string>;\n readonly precedingHeading: string | undefined;\n readonly path: string;\n\n constructor(deps: ConversionContextDeps) {\n this.config = deps.config;\n this.budget = deps.budget;\n this.degradations = deps.degradations;\n this.receipts = deps.receipts;\n this.definitions = deps.definitions;\n this.footnotes = deps.footnotes;\n this.footnoteOrder = deps.footnoteOrder;\n this.precedingHeading = deps.precedingHeading;\n this.path = deps.path;\n }\n\n withDegradations(degradations: DegradationCollector): ConversionContext {\n return new ConversionContext({\n config: this.config,\n budget: this.budget,\n degradations,\n receipts: this.receipts,\n definitions: this.definitions,\n footnotes: this.footnotes,\n footnoteOrder: this.footnoteOrder,\n precedingHeading: this.precedingHeading,\n path: this.path,\n });\n }\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { NodeAdapter } from \"../adapters/node-adapter.js\";\nimport type { Block } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport type { CapabilityFlag } from \"../capabilities/capabilities.js\";\n\n/**\n * First-matching adapter wins; candidates tried in order with capability/budget gates.\n */\nexport class AdapterRegistry {\n private readonly adapters: ReadonlyArray<NodeAdapter>;\n\n constructor(adapters: ReadonlyArray<NodeAdapter>) {\n this.adapters = adapters;\n }\n\n async emit(node: RootContent, ctx: ConversionContext): Promise<ReadonlyArray<Block>> {\n for (const adapter of this.adapters) {\n if (!adapter.match(node, ctx)) {\n continue;\n }\n const candidates = adapter.plan(node, ctx);\n let budgetBlocked = false;\n let emittedEmpty = false;\n for (const candidate of candidates) {\n if (!capabilitiesAllow(candidate.requires, ctx)) {\n continue;\n }\n const beforeClaim = ctx.budget.snapshot();\n if (!ctx.budget.tryReserveClaim(candidate.budget)) {\n budgetBlocked = true;\n continue;\n }\n const blocks = await candidate.emit(ctx);\n if (blocks.length === 0) {\n // Release the reservation and try the next candidate (e.g. mermaid fallback).\n ctx.budget.restore(beforeClaim);\n emittedEmpty = true;\n continue;\n }\n return blocks;\n }\n // Intentional empty emits (SkipAdapter, empty HTML) already recorded their own\n // degradations; do not double-flag when nothing was budget-blocked.\n if (emittedEmpty && !budgetBlocked) {\n return [];\n }\n ctx.degradations.add({\n nodeType: node.type,\n from: \"adapter\",\n to: \"empty\",\n reason: budgetBlocked\n ? \"Message budget exhausted (blocks/chars/charts); content omitted\"\n : \"All candidates failed capability/budget gates\",\n path: ctx.path,\n });\n return [];\n }\n\n ctx.degradations.add({\n nodeType: node.type,\n from: node.type,\n to: \"skip\",\n reason: \"No adapter matched node\",\n path: ctx.path,\n });\n return [];\n }\n}\n\nfunction capabilitiesAllow(\n requires: ReadonlyArray<CapabilityFlag> | undefined,\n ctx: ConversionContext,\n): boolean {\n if (requires === undefined) {\n return true;\n }\n for (const flag of requires) {\n if (!ctx.config.capabilities[flag]) {\n return false;\n }\n }\n return true;\n}\n","/**\n * Exhaustiveness helper for discriminated unions.\n */\nexport function assertNever(value: never, message?: string): never {\n const detail = message ?? \"Unexpected value\";\n throw new Error(`${detail}: ${JSON.stringify(value)}`);\n}\n","/**\n * Surrogate-pair-safe string truncation.\n *\n * `String.prototype.slice` counts UTF-16 code units, so a cut can land between\n * the high and low half of a surrogate pair (astral chars: emoji, some CJK).\n * A lone surrogate is malformed UTF-16 — Slack rejects such payloads with\n * `invalid_blocks` — so every truncation site must back off one unit instead.\n * Unicode ranges: https://unicode.org/faq/utf_bom.html#utf16-2\n */\n\nconst HIGH_SURROGATE_MIN = 0xd800;\nconst HIGH_SURROGATE_MAX = 0xdbff;\nconst LOW_SURROGATE_MIN = 0xdc00;\nconst LOW_SURROGATE_MAX = 0xdfff;\n\n/**\n * Largest cut index ≤ `end` that does not split a surrogate pair in `text`.\n * `end` is clamped into `[0, text.length]`.\n */\nexport function surrogateSafeEnd(text: string, end: number): number {\n if (end <= 0) {\n return 0;\n }\n if (end >= text.length) {\n return text.length;\n }\n const before = text.charCodeAt(end - 1);\n const after = text.charCodeAt(end);\n if (\n before >= HIGH_SURROGATE_MIN &&\n before <= HIGH_SURROGATE_MAX &&\n after >= LOW_SURROGATE_MIN &&\n after <= LOW_SURROGATE_MAX\n ) {\n return end - 1;\n }\n return end;\n}\n\n/**\n * `text.slice(0, max)` that never splits a surrogate pair: when the cut would\n * land mid-pair, the whole pair is dropped (result is `max - 1` units).\n */\nexport function sliceSurrogateSafe(text: string, max: number): string {\n return text.slice(0, surrogateSafeEnd(text, max));\n}\n","export const UploadPhase = {\n Requested: \"requested\",\n Allocated: \"allocated\",\n Uploaded: \"uploaded\",\n Completed: \"completed\",\n Shared: \"shared\",\n Unknown: \"unknown\",\n} as const;\n\nexport type UploadPhase = (typeof UploadPhase)[keyof typeof UploadPhase];\n\nexport const UploadProcessing = {\n NotRequested: \"not-requested\",\n Pending: \"pending\",\n Verified: \"verified\",\n Unverified: \"unverified\",\n} as const;\n\nexport type UploadProcessing = (typeof UploadProcessing)[keyof typeof UploadProcessing];\n\nexport const RetrySafety = {\n Never: \"never\",\n Safe: \"safe\",\n MayDuplicate: \"may-duplicate\",\n} as const;\n\nexport type RetrySafety = (typeof RetrySafety)[keyof typeof RetrySafety];\n\nexport interface UploadReceipt {\n readonly kind: \"upload\";\n readonly provider: string;\n readonly rendererId?: string | undefined;\n readonly filename?: string | undefined;\n readonly phase: UploadPhase;\n readonly fileId?: string | undefined;\n readonly shared: boolean;\n readonly processing: UploadProcessing;\n readonly status?: number | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly providerCode?: string | undefined;\n readonly retrySafety: RetrySafety;\n}\n","import type { Root } from \"mdast\";\n\nimport type { Block } from \"./blocks/types.js\";\nimport type {\n CapabilityFlags,\n CapabilityFlagsPartial,\n CapabilityPresetName,\n} from \"./capabilities/capabilities.js\";\nimport type { UploadReceipt } from \"./receipts.js\";\n\nexport { RetrySafety, UploadPhase, UploadProcessing } from \"./receipts.js\";\nexport type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Structured degradation emitted when content falls back or is truncated.\n */\nexport interface Degradation {\n readonly nodeType: string;\n readonly from: string;\n readonly to: string;\n readonly reason: string;\n readonly path: string;\n readonly details?: DegradationDetails | undefined;\n}\n\n/**\n * Optional machine-readable context for a degradation. The core fields above\n * remain stable and sufficient for human-readable fallback reporting.\n */\nexport interface DegradationDetails {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly retryable?: boolean | undefined;\n readonly rendererId?: string | undefined;\n}\n\n/**\n * Total conversion result — never throws on user markdown.\n */\nexport interface ConversionResult {\n readonly blocks: ReadonlyArray<Block>;\n readonly text: string;\n readonly degradations: ReadonlyArray<Degradation>;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n}\n\n/**\n * One message chunk from multi-message conversion.\n */\nexport interface ConversionMessage {\n readonly blocks: ReadonlyArray<Block>;\n readonly text: string;\n}\n\n/**\n * Multi-message conversion result.\n */\nexport interface ConversionMessagesResult {\n readonly messages: ReadonlyArray<ConversionMessage>;\n readonly degradations: ReadonlyArray<Degradation>;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n}\n\nexport const OverflowMode = {\n Degrade: \"degrade\",\n Split: \"split\",\n} as const;\n\nexport type OverflowMode = (typeof OverflowMode)[keyof typeof OverflowMode];\n\nexport const ConversionStrategy = {\n RichTextFirst: \"rich-text-first\",\n MarkdownBlock: \"markdown-block\",\n} as const;\n\nexport type ConversionStrategy = (typeof ConversionStrategy)[keyof typeof ConversionStrategy];\n\n/**\n * Normalized fenced content passed to {@link ImageRenderer}. Display math uses\n * `lang: \"math\"`; fenced-code languages are lowercase and trimmed.\n */\nexport interface RenderRequest {\n readonly lang: string;\n readonly source: string;\n readonly altText: string;\n}\n\nexport type BytesImage = {\n readonly kind: \"bytes\";\n readonly data: Uint8Array;\n readonly mimeType: \"image/png\" | \"image/jpeg\" | \"image/gif\";\n readonly filename: string;\n readonly altText?: string | undefined;\n};\n\nexport type UrlImage = {\n readonly kind: \"url\";\n readonly imageUrl: string;\n readonly altText?: string | undefined;\n};\n\nexport type RenderedImage = UrlImage | BytesImage;\n\n/**\n * Safe machine-readable renderer failure metadata. Implementations must keep\n * untrusted source and collaborator messages out of these fields.\n */\nexport interface StructuredRendererError {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId?: string | undefined;\n}\n\n/**\n * Pluggable image renderer for Mermaid fences that cannot become native\n * charts, display math, and generic code fences.\n *\n * Renderers are consulted in configuration order. {@link canRender} should be\n * a cheap, synchronous capability check; conversion calls {@link render} only\n * after it returns true. Return `null` to decline a request after inspection.\n * Attempt failures are buffered while conversion tries later renderers. A\n * later success emits no failure degradation; only an all-failed chain records\n * the buffered failures before text fallback. URL output must be an absolute\n * HTTPS URL without credentials and within Slack's image URL limit.\n */\nexport const ImageRendererOutput = {\n Url: \"url\",\n Bytes: \"bytes\",\n Both: \"both\",\n} as const;\n\nexport type ImageRendererOutput = (typeof ImageRendererOutput)[keyof typeof ImageRendererOutput];\n\nexport type RendererImage<TOutput extends ImageRendererOutput> = TOutput extends \"url\"\n ? UrlImage\n : TOutput extends \"bytes\"\n ? BytesImage\n : RenderedImage;\n\nexport interface ImageRenderer<TOutput extends ImageRendererOutput = ImageRendererOutput> {\n /** Stable machine-readable renderer identity. */\n readonly id: string;\n /** Declared output contract, enforced against every non-null result. */\n readonly output: TOutput;\n /** Whether this renderer accepts the normalized language and request. */\n canRender(req: RenderRequest): boolean;\n /** Produce an image or return `null` to let the next renderer try. */\n render(req: RenderRequest, context: OperationContext): Promise<RendererImage<TOutput> | null>;\n}\n\nexport type UrlImageRenderer = ImageRenderer<\"url\">;\nexport type BytesImageRenderer = ImageRenderer<\"bytes\">;\nexport type BothImageRenderer = ImageRenderer<\"both\">;\n\n/**\n * Ergonomic high-level operation bounds.\n */\nexport interface OperationOptions {\n readonly signal?: AbortSignal | undefined;\n /** Relative milliseconds from call start. */\n readonly timeoutMs?: number | undefined;\n}\n\n/**\n * Absolute context passed only to execution collaborators.\n */\nexport interface OperationContext {\n readonly signal: AbortSignal | undefined;\n readonly deadlineMs: number | undefined;\n}\n\n/**\n * Uploads bytes-producing renderer output to Slack files API.\n */\nexport interface SlackUploader {\n upload(\n img: BytesImage,\n context: OperationContext,\n ): Promise<{ readonly fileId: string; readonly receipt: UploadReceipt }>;\n}\n\n/**\n * Optional mention resolvers (off by default).\n */\nexport interface MentionResolvers {\n readonly resolveUser?: ((handle: string) => string | undefined) | undefined;\n readonly resolveChannel?: ((name: string) => string | undefined) | undefined;\n}\n\n/**\n * Public conversion options (per-call).\n * Custom adapters are wired via {@link createConverter}, not per-call options.\n */\nexport interface ConvertOptions {\n readonly capabilities?:\n | CapabilityPresetName\n | CapabilityFlags\n | CapabilityFlagsPartial\n | undefined;\n readonly capabilityOverrides?: CapabilityFlagsPartial | undefined;\n readonly overflow?: OverflowMode | undefined;\n readonly strategy?: ConversionStrategy | undefined;\n readonly renderers?: ReadonlyArray<ImageRenderer> | undefined;\n readonly uploader?: SlackUploader | undefined;\n readonly enableMath?: boolean | undefined;\n /**\n * Treat `$x$` inside a paragraph as inline math. Off by default even when\n * {@link ConversionOptions.enableMath} is on, because agent prose is far more likely to\n * contain currency (`$200/mo versus $350/mo`) than inline LaTeX, and reading the span\n * between two dollar signs as math deletes both signs. `$$…$$` is unaffected.\n */\n readonly enableInlineMath?: boolean | undefined;\n readonly enableFrontmatter?: boolean | undefined;\n readonly mentionResolvers?: MentionResolvers | undefined;\n readonly signal?: AbortSignal | undefined;\n readonly timeoutMs?: number | undefined;\n}\n\n/**\n * Collects degradations during a single conversion.\n */\nexport interface DegradationCollector {\n add(d: Degradation): void;\n all(): ReadonlyArray<Degradation>;\n}\n\nexport interface ReceiptCollector {\n add(receipt: UploadReceipt): void;\n all(): ReadonlyArray<UploadReceipt>;\n settle(): void;\n settled(): Promise<ReadonlyArray<UploadReceipt>>;\n}\n\n/**\n * Budget reservation claimed while planning a candidate.\n */\nexport interface BudgetClaim {\n readonly blocks?: number;\n readonly tableChars?: number;\n readonly dataTableChars?: number;\n readonly markdownChars?: number;\n readonly chart?: boolean;\n readonly totalChars?: number;\n}\n\n/**\n * Message-wide budget ledger.\n */\nexport interface BudgetLedger {\n readonly maxBlocks: number;\n tryReserveClaim(claim: BudgetClaim | undefined): boolean;\n snapshot(): BudgetSnapshot;\n /** Restore counters to a prior {@link snapshot} (e.g. after an empty emit). */\n restore(snapshot: BudgetSnapshot): void;\n resetForNewMessage(): void;\n}\n\nexport interface BudgetSnapshot {\n readonly blocks: number;\n readonly tableChars: number;\n readonly dataTableChars: number;\n readonly markdownChars: number;\n readonly charts: number;\n readonly totalChars: number;\n}\n\n/**\n * Deterministic markdown → plain text for notification fallbacks.\n */\nexport interface PlainTextRenderer {\n render(markdown: string): string;\n renderFromBlocks(blocks: ReadonlyArray<Block>): string;\n}\n\n/**\n * Swappable markdown parser (wraps remark by default).\n */\nexport interface MarkdownParser {\n parse(markdown: string, options: ParserOptions): Promise<Root>;\n}\n\nexport interface ParserOptions {\n readonly enableMath: boolean;\n readonly enableInlineMath: boolean;\n readonly enableFrontmatter: boolean;\n}\n\n/**\n * Mermaid chart grammar parser (pie / xychart).\n */\nexport interface MermaidChartParser {\n parse(source: string): MermaidParseResult;\n}\n\nexport type MermaidParseResult =\n | { readonly ok: true; readonly value: MermaidPieAst | MermaidXyChartAst }\n | { readonly ok: false; readonly reason: string };\n\nexport interface MermaidPieAst {\n readonly kind: \"pie\";\n readonly title: string | undefined;\n readonly segments: ReadonlyArray<{ readonly label: string; readonly value: number }>;\n}\n\nexport interface MermaidXyChartAst {\n readonly kind: \"xychart-beta\";\n readonly title: string | undefined;\n readonly categories: ReadonlyArray<string>;\n readonly xLabel: string | undefined;\n readonly yLabel: string | undefined;\n readonly bars: ReadonlyArray<ReadonlyArray<number>>;\n readonly lines: ReadonlyArray<ReadonlyArray<number>>;\n}\n","import { assertNever } from \"../assert-never.js\";\nimport type {\n Block,\n DataTableBlock,\n RichTextBlock,\n RichTextElement,\n TableBlock,\n TableCell,\n} from \"../blocks/types.js\";\nimport { StandardBudgetLedger } from \"../budget/standard-budget-ledger.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport {\n CONTEXT_ELEMENTS_MAX,\n MAX_BLOCKS_PER_MESSAGE,\n MESSAGE_TEXT_SAFETY_MAX_CHARS,\n SECTION_TEXT_MAX_CHARS,\n} from \"../constants.js\";\nimport type {\n BudgetClaim,\n ConversionMessage,\n DegradationCollector,\n PlainTextRenderer,\n} from \"../types.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\nimport { OverflowMode as Overflow } from \"../types.js\";\n\nexport interface MessageAssemblerDeps {\n readonly plainText: PlainTextRenderer;\n}\n\n/**\n * Packs blocks into messages, coalesces adjacent rich_text, attaches footnotes.\n */\nexport class MessageAssembler {\n private readonly plainText: PlainTextRenderer;\n\n constructor(deps: MessageAssemblerDeps) {\n this.plainText = deps.plainText;\n }\n\n assemble(\n blocks: ReadonlyArray<Block>,\n ctx: ConversionContext,\n footnoteBlocks: ReadonlyArray<Block>,\n ): ReadonlyArray<ConversionMessage> {\n const coalesced = coalesceRichText(blocks);\n\n if (ctx.config.overflow === Overflow.Split) {\n return this.splitMessages([...coalesced, ...footnoteBlocks], ctx);\n }\n\n // Degrade: reserve trailing slots for footnotes so they are not sliced off.\n const noteCount = footnoteBlocks.length;\n const bodyCap = Math.max(0, MAX_BLOCKS_PER_MESSAGE - noteCount);\n const clippedBody = coalesced.slice(0, bodyCap);\n if (coalesced.length > bodyCap) {\n ctx.degradations.add({\n nodeType: \"message\",\n from: `${String(coalesced.length)} body blocks`,\n to: `${String(bodyCap)} body blocks`,\n reason:\n noteCount > 0\n ? `overflow=degrade truncated body to reserve ${String(noteCount)} footnote blocks`\n : \"overflow=degrade truncated to 50 blocks\",\n path: ctx.path,\n });\n }\n\n let notes = footnoteBlocks;\n if (notes.length > MAX_BLOCKS_PER_MESSAGE) {\n notes = footnoteBlocks.slice(0, MAX_BLOCKS_PER_MESSAGE);\n ctx.degradations.add({\n nodeType: \"footnote\",\n from: `${String(footnoteBlocks.length)} footnote blocks`,\n to: `${String(MAX_BLOCKS_PER_MESSAGE)} footnote blocks`,\n reason: \"Footnote blocks alone exceed 50; truncated\",\n path: ctx.path,\n });\n }\n\n const finalBlocks = [...clippedBody, ...notes];\n return [this.toMessage(finalBlocks, ctx)];\n }\n\n private splitMessages(\n blocks: ReadonlyArray<Block>,\n ctx: ConversionContext,\n ): ReadonlyArray<ConversionMessage> {\n const messages: ConversionMessage[] = [];\n let current: Block[] = [];\n let ledger = new StandardBudgetLedger(MAX_BLOCKS_PER_MESSAGE);\n\n const flush = (): void => {\n if (current.length === 0) {\n return;\n }\n messages.push(this.toMessage(current, ctx));\n current = [];\n ledger = new StandardBudgetLedger(MAX_BLOCKS_PER_MESSAGE);\n };\n\n for (const block of blocks) {\n const claim = claimForBlock(block);\n if (!ledger.tryReserveClaim(claim)) {\n flush();\n if (!ledger.tryReserveClaim(claim)) {\n // Single block exceeds an empty message budget (e.g. oversized table) — omit.\n ctx.degradations.add({\n nodeType: \"message\",\n from: block.type,\n to: \"omitted\",\n reason: \"Block exceeds per-message budget; omitted\",\n path: ctx.path,\n });\n continue;\n }\n }\n current.push(block);\n }\n flush();\n\n if (messages.length > 1) {\n ctx.degradations.add({\n nodeType: \"message\",\n from: \"single\",\n to: `${String(messages.length)} messages`,\n reason: \"Split at semantic block boundaries (per-message budgets)\",\n path: ctx.path,\n });\n }\n\n return messages.length > 0 ? messages : [{ blocks: [], text: \" \" }];\n }\n\n private toMessage(blocks: ReadonlyArray<Block>, ctx: ConversionContext): ConversionMessage {\n const raw = this.plainText.renderFromBlocks(blocks);\n if (raw.length <= MESSAGE_TEXT_SAFETY_MAX_CHARS) {\n return { blocks, text: raw };\n }\n ctx.degradations.add({\n nodeType: \"message\",\n from: `${String(raw.length)} text chars`,\n to: `${String(MESSAGE_TEXT_SAFETY_MAX_CHARS)} text chars`,\n reason: \"Notification text truncated to 40k safety limit\",\n path: ctx.path,\n });\n return { blocks, text: sliceSurrogateSafe(raw, MESSAGE_TEXT_SAFETY_MAX_CHARS) };\n }\n}\n\n/**\n * Build trailing divider + context chunks for footnotes.\n */\nexport function buildFootnoteBlocks(\n entries: ReadonlyArray<{ readonly n: number; readonly text: string }>,\n degradations?: DegradationCollector,\n): ReadonlyArray<Block> {\n if (entries.length === 0) {\n return [];\n }\n const blocks: Block[] = [{ type: \"divider\" }];\n const elements: ContextBlockElements = [];\n for (const e of entries) {\n const note = `[${String(e.n)}] ${e.text}`;\n if (note.length > SECTION_TEXT_MAX_CHARS) {\n degradations?.add({\n nodeType: \"footnote\",\n from: `${String(note.length)} chars`,\n to: `${String(SECTION_TEXT_MAX_CHARS)} chars`,\n reason: \"Footnote context text truncated to 3000 chars\",\n path: \"footnote\",\n });\n elements.push({ type: \"mrkdwn\", text: sliceSurrogateSafe(note, SECTION_TEXT_MAX_CHARS) });\n } else {\n elements.push({ type: \"mrkdwn\", text: note });\n }\n }\n for (let i = 0; i < elements.length; i += CONTEXT_ELEMENTS_MAX) {\n const chunk = elements.slice(i, i + CONTEXT_ELEMENTS_MAX);\n blocks.push({ type: \"context\", elements: chunk });\n }\n return blocks;\n}\n\ntype ContextBlockElements = Array<{ type: \"mrkdwn\"; text: string }>;\n\nfunction claimForBlock(block: Block): BudgetClaim {\n switch (block.type) {\n case \"data_visualization\":\n return { blocks: 1, chart: true };\n case \"markdown\":\n return { blocks: 1, markdownChars: block.text.length };\n case \"table\":\n return { blocks: 1, tableChars: countEmittedTableChars(block) };\n case \"data_table\":\n return { blocks: 1, dataTableChars: countEmittedTableChars(block) };\n case \"rich_text\":\n case \"header\":\n case \"divider\":\n case \"section\":\n case \"image\":\n case \"context\":\n case \"container\":\n return { blocks: 1 };\n default:\n return assertNever(block);\n }\n}\n\nfunction countEmittedTableChars(block: TableBlock | DataTableBlock): number {\n let total = 0;\n for (const row of block.rows) {\n for (const cell of row) {\n total += cellTextLength(cell);\n }\n }\n return total;\n}\n\nfunction cellTextLength(cell: TableCell): number {\n if (cell.type === \"raw_text\" || cell.type === \"raw_number\") {\n return cell.text.length;\n }\n // rich_text cell — approximate via JSON length of text nodes\n return JSON.stringify(cell).length;\n}\n\n/**\n * How many blocks `blocks` adds to a message whose last block is `previous`, once\n * {@link MessageAssembler.assemble} has merged adjacent rich_text sections.\n *\n * Emission reserves one block per source node before it knows what the node produces, so\n * without this a run of 60 paragraphs exhausts the 50-block budget even though it\n * coalesces into a single block. The converter reconciles the reservation against this\n * count so the budget tracks what is actually emitted.\n */\nexport function coalescedBlockCount(\n previous: Block | undefined,\n blocks: ReadonlyArray<Block>,\n): number {\n let count = 0;\n let tail = previous;\n for (const block of blocks) {\n if (!mergesIntoTail(tail, block)) {\n count += 1;\n }\n tail = block;\n }\n return count;\n}\n\nfunction mergesIntoTail(tail: Block | undefined, next: Block): boolean {\n return (\n tail?.type === \"rich_text\" &&\n next.type === \"rich_text\" &&\n isCoalescable(tail) &&\n isCoalescable(next)\n );\n}\n\nfunction coalesceRichText(blocks: ReadonlyArray<Block>): Block[] {\n const out: Block[] = [];\n let pending: RichTextElement[] | undefined;\n\n const flushPending = (): void => {\n if (pending === undefined || pending.length === 0) {\n pending = undefined;\n return;\n }\n const block: RichTextBlock = { type: \"rich_text\", elements: pending };\n out.push(block);\n pending = undefined;\n };\n\n for (const block of blocks) {\n if (block.type === \"rich_text\" && isCoalescable(block)) {\n if (pending === undefined) {\n pending = [...block.elements];\n } else {\n pending.push(...block.elements);\n }\n } else {\n flushPending();\n out.push(block);\n }\n }\n flushPending();\n return out;\n}\n\nfunction isCoalescable(block: RichTextBlock): boolean {\n // Only coalesce pure section flow; leave lists/quotes/preformatted alone as unit\n return block.elements.every((e) => e.type === \"rich_text_section\");\n}\n","import type { Block, RichTextElement, RichTextInline } from \"../blocks/types.js\";\nimport type { PlainTextRenderer } from \"../types.js\";\n\n/**\n * Deterministic plain-text renderer for notifications / screen readers.\n */\nexport class DeterministicPlainTextRenderer implements PlainTextRenderer {\n render(markdown: string): string {\n const parts: string[] = [];\n // Lightweight strip — full fidelity comes from renderFromBlocks after convert.\n let i = 0;\n const src = markdown;\n while (i < src.length) {\n if (src.startsWith(\"```\", i)) {\n const end = src.indexOf(\"```\", i + 3);\n if (end === -1) {\n parts.push(src.slice(i + 3));\n break;\n }\n parts.push(src.slice(i + 3, end).trim());\n i = end + 3;\n continue;\n }\n parts.push(src[i] ?? \"\");\n i += 1;\n }\n const raw = parts\n .join(\"\")\n .replace(/!\\[[^\\]]{0,200}\\]\\([^)]{0,3000}\\)/g, \" \")\n .replace(/\\[([^\\]]{0,200})\\]\\([^)]{0,3000}\\)/g, \"$1\")\n .replace(/[#>*_`~]/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n return raw.length > 0 ? raw : \" \";\n }\n\n renderFromBlocks(blocks: ReadonlyArray<Block>): string {\n const parts: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case \"header\":\n parts.push(block.text.text);\n break;\n case \"section\":\n if (block.text !== undefined) {\n parts.push(stripMrkdwn(block.text.text));\n }\n break;\n case \"rich_text\":\n parts.push(richTextToPlain(block.elements));\n break;\n case \"markdown\":\n parts.push(this.render(block.text));\n break;\n case \"divider\":\n parts.push(\"---\");\n break;\n case \"image\":\n parts.push(block.alt_text);\n break;\n case \"context\":\n for (const el of block.elements) {\n if (el.type === \"mrkdwn\" || el.type === \"plain_text\") {\n parts.push(stripMrkdwn(el.text));\n }\n }\n break;\n case \"table\":\n case \"data_table\":\n parts.push(tableToPlain(block.rows));\n break;\n case \"data_visualization\":\n parts.push(block.title);\n break;\n case \"container\":\n if (block.title !== undefined) {\n parts.push(block.title.text);\n }\n parts.push(this.renderFromBlocks(block.child_blocks));\n break;\n default:\n break;\n }\n }\n const text = parts\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .join(\"\\n\")\n .trim();\n return text.length > 0 ? text : \" \";\n }\n}\n\nfunction stripMrkdwn(text: string): string {\n return text\n .replace(/<([^|>]{1,3000})\\|([^>]{0,500})>/g, \"$2\")\n .replace(/<([^>]{1,3000})>/g, \"$1\")\n .replace(/[*_~`]/g, \"\");\n}\n\nfunction richTextToPlain(elements: ReadonlyArray<RichTextElement>): string {\n const parts: string[] = [];\n for (const el of elements) {\n switch (el.type) {\n case \"rich_text_section\":\n case \"rich_text_quote\":\n parts.push(inlinesToPlain(el.elements));\n break;\n case \"rich_text_list\":\n for (const item of el.elements) {\n parts.push(`• ${inlinesToPlain(item.elements)}`);\n }\n break;\n case \"rich_text_preformatted\":\n parts.push(inlinesToPlain(el.elements));\n break;\n default:\n break;\n }\n }\n return parts.join(\"\\n\");\n}\n\nfunction inlinesToPlain(elements: ReadonlyArray<RichTextInline>): string {\n const parts: string[] = [];\n for (const el of elements) {\n switch (el.type) {\n case \"text\":\n parts.push(el.text);\n break;\n case \"link\":\n parts.push(el.text ?? el.url);\n break;\n case \"emoji\":\n parts.push(`:${el.name}:`);\n break;\n case \"user\":\n parts.push(`@${el.user_id}`);\n break;\n case \"channel\":\n parts.push(`#${el.channel_id}`);\n break;\n case \"usergroup\":\n parts.push(`@${el.usergroup_id}`);\n break;\n case \"broadcast\":\n parts.push(`@${el.range}`);\n break;\n case \"date\":\n parts.push(el.fallback ?? formatDateTokensUtc(el.timestamp, el.format));\n break;\n default:\n break;\n }\n }\n return parts.join(\"\");\n}\n\nconst DATE_TOKEN_RE = /\\{([a-z_]+)\\}/g;\n\nconst MONTHS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n] as const;\n\nconst WEEKDAYS = [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n] as const;\n\nfunction pad2(value: number): string {\n return String(value).padStart(2, \"0\");\n}\n\nfunction ordinal(value: number): string {\n const remainder = value % 100;\n if (remainder >= 11 && remainder <= 13) {\n return `${String(value)}th`;\n }\n switch (value % 10) {\n case 1:\n return `${String(value)}st`;\n case 2:\n return `${String(value)}nd`;\n case 3:\n return `${String(value)}rd`;\n default:\n return `${String(value)}th`;\n }\n}\n\n/** One Slack date-format token rendered in UTC, or undefined when unsupported. */\nfunction dateToken(token: string, date: Date): string | undefined {\n const day = date.getUTCDate();\n const month = MONTHS[date.getUTCMonth()] ?? \"\";\n const shortMonth = month.slice(0, 3);\n const weekday = WEEKDAYS[date.getUTCDay()] ?? \"\";\n const year = date.getUTCFullYear();\n\n switch (token) {\n case \"date_num\":\n return `${String(year)}-${pad2(date.getUTCMonth() + 1)}-${pad2(day)}`;\n // Slack renders {date_slash} month-first: 02/18/2014 (docs example for\n // timestamp 1392734382).\n case \"date_slash\":\n return `${pad2(date.getUTCMonth() + 1)}/${pad2(day)}/${String(year)}`;\n case \"date_long\":\n case \"date_long_pretty\":\n return `${weekday}, ${month} ${ordinal(day)}, ${String(year)}`;\n case \"date_long_full\":\n return `${month} ${String(day)}, ${String(year)}`;\n // {date} renders \"February 18th, 2014\" (ordinal + year), not \"February 18\".\n case \"date\":\n case \"date_pretty\":\n return `${month} ${ordinal(day)}, ${String(year)}`;\n case \"date_short\":\n case \"date_short_pretty\":\n return `${shortMonth} ${String(day)}, ${String(year)}`;\n case \"time\":\n return `${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;\n case \"time_secs\":\n return `${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}:${pad2(date.getUTCSeconds())}`;\n default:\n return undefined;\n }\n}\n\n/**\n * Deterministic UTC rendering of Slack date-format tokens for notification\n * text. A date element without a fallback must not dump raw \"{date_short}\"\n * tokens into the message preview. Tokens needing a clock ({ago}, relative\n * \"pretty\" phrasing) render as their absolute equivalents; unknown tokens\n * degrade the whole format to the ISO date.\n * https://docs.slack.dev/messaging/formatting-message-text#date-formatting\n */\nfunction formatDateTokensUtc(timestamp: number, format: string): string {\n const date = new Date(timestamp * 1000);\n if (!Number.isFinite(timestamp) || Number.isNaN(date.getTime())) {\n return String(timestamp);\n }\n let unsupported = false;\n const formatted = format.replace(DATE_TOKEN_RE, (_match, token: string) => {\n const replacement = dateToken(token, date);\n if (replacement === undefined) {\n unsupported = true;\n return \"\";\n }\n return replacement;\n });\n if (format.length === 0 || unsupported) {\n return date.toISOString().slice(0, 10);\n }\n return formatted;\n}\n\nfunction tableToPlain(rows: ReadonlyArray<ReadonlyArray<unknown>>): string {\n const lines: string[] = [];\n for (const row of rows) {\n const cells = row.map((cell) => cellPlain(cell));\n lines.push(cells.join(\" | \"));\n }\n return lines.join(\"\\n\");\n}\n\nfunction cellPlain(cell: unknown): string {\n if (typeof cell !== \"object\" || cell === null) {\n return \"\";\n }\n const c = cell as { type?: string; text?: string; value?: number; elements?: unknown };\n if (c.type === \"raw_text\" && typeof c.text === \"string\") {\n return c.text;\n }\n if (c.type === \"raw_number\") {\n return typeof c.text === \"string\" ? c.text : String(c.value ?? \"\");\n }\n if (c.type === \"rich_text\" && Array.isArray(c.elements)) {\n return richTextToPlain(c.elements as RichTextElement[]);\n }\n return \"\";\n}\n","import type { Root } from \"mdast\";\nimport remarkFrontmatter from \"remark-frontmatter\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkParse from \"remark-parse\";\nimport { unified } from \"unified\";\n\nimport type { MarkdownParser, ParserOptions } from \"../types.js\";\n\n/**\n * Default markdown parser wrapping the unified/remark pipeline.\n */\nexport class RemarkMarkdownParser implements MarkdownParser {\n async parse(markdown: string, options: ParserOptions): Promise<Root> {\n const processor = unified().use(remarkParse).use(remarkGfm);\n if (options.enableFrontmatter) {\n processor.use(remarkFrontmatter, [\"yaml\", \"toml\"]);\n }\n if (options.enableMath) {\n processor.use(remarkMath, { singleDollarTextMath: options.enableInlineMath });\n }\n return processor.parse(markdown) as Root;\n }\n}\n","import type { MermaidChartParser, MermaidParseResult, MermaidPieAst } from \"../types.js\";\n\nconst COMMENT_RE = /%%[^\\n]{0,500}/g;\nconst TITLE_RE = /^\\s*pie\\b(?:\\s+showData)?(?:\\s+title\\s+(.+))?\\s*$/i;\nconst ENTRY_RE = /^\\s*\"([^\"]{1,200})\"\\s*:\\s*(-?\\d+(?:\\.\\d+)?)\\s*$/;\n\n/**\n * Parses mermaid `pie` diagram grammar into a structured AST.\n */\nexport class MermaidPieParser implements MermaidChartParser {\n parse(source: string): MermaidParseResult {\n const cleaned = source.replace(COMMENT_RE, \"\");\n const lines = cleaned.split(/\\r?\\n/);\n let title: string | undefined;\n const segments: Array<{ label: string; value: number }> = [];\n let seenHeader = false;\n\n for (const raw of lines) {\n const line = raw.trim();\n if (line.length === 0) {\n continue;\n }\n if (!seenHeader) {\n if (!/^\\s*pie\\b/i.test(line)) {\n return { ok: false, reason: \"Not a pie diagram\" };\n }\n seenHeader = true;\n const tm = TITLE_RE.exec(line);\n const titlePart = tm?.[1]?.trim();\n if (titlePart !== undefined && titlePart.length > 0) {\n title = titlePart;\n }\n continue;\n }\n\n // Optional standalone title line: title Foo\n const titleLine = /^\\s*title\\s+(.+)\\s*$/i.exec(line);\n if (titleLine !== null && title === undefined) {\n title = (titleLine[1] ?? \"\").trim();\n continue;\n }\n\n const em = ENTRY_RE.exec(line);\n if (em === null) {\n return { ok: false, reason: `Invalid pie entry: ${line}` };\n }\n const label = em[1] ?? \"\";\n const value = Number(em[2]);\n if (!(value > 0)) {\n return { ok: false, reason: `Pie values must be > 0 (got ${String(value)})` };\n }\n segments.push({ label, value });\n }\n\n if (!seenHeader) {\n return { ok: false, reason: \"Missing pie header\" };\n }\n if (segments.length === 0) {\n return { ok: false, reason: \"Pie has no segments\" };\n }\n\n const ast: MermaidPieAst = {\n kind: \"pie\",\n title,\n segments,\n };\n return { ok: true, value: ast };\n }\n}\n","import { CHART_POINTS_MAX } from \"../constants.js\";\nimport type { MermaidChartParser, MermaidParseResult, MermaidXyChartAst } from \"../types.js\";\n\nconst COMMENT_RE = /%%[^\\n]{0,500}/g;\nconst NUM = String.raw`-?\\d+(?:\\.\\d+)?`;\nconst NUM_LIST_RE = new RegExp(String.raw`\\[\\s*((?:${NUM}\\s*,\\s*)*${NUM})\\s*\\]`);\nconst STR_LIST_RE = /\\[\\s*((?:\"[^\"]{0,200}\"\\s*,\\s*)*\"[^\"]{0,200}\")\\s*\\]/;\n\n/**\n * Parses mermaid `xychart-beta` grammar (categories, bar/line series).\n */\nexport class MermaidXyChartParser implements MermaidChartParser {\n parse(source: string): MermaidParseResult {\n const cleaned = source.replace(COMMENT_RE, \"\");\n const lines = cleaned.split(/\\r?\\n/);\n let title: string | undefined;\n let categories: string[] = [];\n let xLabel: string | undefined;\n let yLabel: string | undefined;\n const bars: number[][] = [];\n const linesSeries: number[][] = [];\n let seenHeader = false;\n\n for (const raw of lines) {\n const line = raw.trim();\n if (line.length === 0) {\n continue;\n }\n if (!seenHeader) {\n if (!/^\\s*xychart-beta\\b/i.test(line)) {\n return { ok: false, reason: \"Not an xychart-beta diagram\" };\n }\n seenHeader = true;\n continue;\n }\n\n const titleM =\n /^\\s*title\\s+\"([^\"]{0,200})\"\\s*$/i.exec(line) ?? /^\\s*title\\s+(.+)\\s*$/i.exec(line);\n if (titleM !== null) {\n title = (titleM[1] ?? \"\").trim();\n continue;\n }\n\n if (/^\\s*x-axis\\b/i.test(line)) {\n const strList = STR_LIST_RE.exec(line);\n if (strList !== null) {\n categories = parseStringList(strList[1] ?? \"\");\n const labelM = /^\\s*x-axis\\s+\"([^\"]{0,200})\"\\s+/i.exec(line);\n if (labelM !== null) {\n xLabel = labelM[1];\n }\n continue;\n }\n const rangeM = new RegExp(\n String.raw`x-axis\\s+(?:\"([^\"]{0,200})\"\\s+)?(${NUM})\\s*-->\\s*(${NUM})`,\n \"i\",\n ).exec(line);\n if (rangeM !== null) {\n xLabel = rangeM[1];\n const min = Number(rangeM[2]);\n const max = Number(rangeM[3]);\n if (!Number.isFinite(min) || !Number.isFinite(max) || max < min) {\n return { ok: false, reason: `Invalid x-axis range: ${line}` };\n }\n const span = max - min + 1;\n if (span > CHART_POINTS_MAX) {\n return {\n ok: false,\n reason: `x-axis range has ${String(span)} points (max ${String(CHART_POINTS_MAX)})`,\n };\n }\n categories = [];\n for (let i = min; i <= max; i += 1) {\n categories.push(String(i));\n }\n continue;\n }\n return { ok: false, reason: `Invalid x-axis: ${line}` };\n }\n\n if (/^\\s*y-axis\\b/i.test(line)) {\n const ym = new RegExp(\n String.raw`y-axis\\s+(?:\"([^\"]{0,200})\"\\s+)?(?:(${NUM})\\s*-->\\s*(${NUM}))?`,\n \"i\",\n ).exec(line);\n if (ym !== null) {\n yLabel = ym[1];\n continue;\n }\n return { ok: false, reason: `Invalid y-axis: ${line}` };\n }\n\n if (/^\\s*bar\\b/i.test(line)) {\n const nums = NUM_LIST_RE.exec(line);\n if (nums === null) {\n return { ok: false, reason: `Invalid bar series: ${line}` };\n }\n bars.push(parseNumberList(nums[1] ?? \"\"));\n continue;\n }\n\n if (/^\\s*line\\b/i.test(line)) {\n const nums = NUM_LIST_RE.exec(line);\n if (nums === null) {\n return { ok: false, reason: `Invalid line series: ${line}` };\n }\n linesSeries.push(parseNumberList(nums[1] ?? \"\"));\n continue;\n }\n\n return { ok: false, reason: `Unrecognized xychart line: ${line}` };\n }\n\n if (!seenHeader) {\n return { ok: false, reason: \"Missing xychart-beta header\" };\n }\n if (categories.length === 0) {\n return { ok: false, reason: \"xychart missing categories\" };\n }\n if (bars.length === 0 && linesSeries.length === 0) {\n return { ok: false, reason: \"xychart has no series\" };\n }\n\n const ast: MermaidXyChartAst = {\n kind: \"xychart-beta\",\n title,\n categories,\n xLabel,\n yLabel,\n bars,\n lines: linesSeries,\n };\n return { ok: true, value: ast };\n }\n}\n\nfunction parseStringList(inner: string): string[] {\n const out: string[] = [];\n const re = /\"([^\"]{0,200})\"/g;\n let m: RegExpExecArray | null = re.exec(inner);\n while (m !== null) {\n out.push(m[1] ?? \"\");\n m = re.exec(inner);\n }\n return out;\n}\n\nfunction parseNumberList(inner: string): number[] {\n return inner\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map((s) => Number(s));\n}\n","import {\n ConfigurationError,\n OperationAbortedError,\n OperationDeadlineExceededError,\n cloneOperationError,\n isOperationError,\n} from \"../errors.js\";\nimport type { OperationContext, OperationOptions } from \"../types.js\";\n\nexport interface OperationScope {\n readonly context: OperationContext;\n race<T>(promise: Promise<T>): Promise<T>;\n cleanup(): void;\n}\n\nexport function createOperationScope(options: OperationOptions, stage: string): OperationScope {\n validateOperationOptions(options);\n const controller = new AbortController();\n const abortFromCaller = (): void => {\n const reason = options.signal?.reason;\n controller.abort(\n isOperationError(reason)\n ? cloneOperationError(reason, stage)\n : new OperationAbortedError(stage, { cause: reason }),\n );\n };\n if (options.signal?.aborted === true) {\n abortFromCaller();\n } else {\n options.signal?.addEventListener(\"abort\", abortFromCaller, { once: true });\n }\n const deadlineMs = options.timeoutMs === undefined ? undefined : Date.now() + options.timeoutMs;\n const timeout =\n options.timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n controller.abort(new OperationDeadlineExceededError(stage));\n }, options.timeoutMs);\n const context: OperationContext = Object.freeze({\n signal: controller.signal,\n deadlineMs,\n });\n return {\n context,\n race: <T>(promise: Promise<T>): Promise<T> => raceWithContext(promise, context),\n cleanup: (): void => {\n if (timeout !== undefined) {\n clearTimeout(timeout);\n }\n options.signal?.removeEventListener(\"abort\", abortFromCaller);\n },\n };\n}\n\nexport function throwIfOperationEnded(context: OperationContext, stage: string): void {\n if (context.signal?.aborted === true) {\n const reason = context.signal.reason;\n throw isOperationError(reason) ? reason : new OperationAbortedError(stage, { cause: reason });\n }\n if (context.deadlineMs !== undefined && Date.now() >= context.deadlineMs) {\n throw new OperationDeadlineExceededError(stage);\n }\n}\n\nfunction raceWithContext<T>(promise: Promise<T>, context: OperationContext): Promise<T> {\n const signal = context.signal;\n if (signal?.aborted === true) {\n return Promise.reject(signal.reason);\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(signal?.reason);\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n void promise.then(\n (value) => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(value);\n return undefined;\n },\n (error: unknown) => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nfunction validateOperationOptions(options: OperationOptions): void {\n if (\n options.signal !== undefined &&\n (typeof options.signal !== \"object\" ||\n options.signal === null ||\n typeof options.signal.addEventListener !== \"function\" ||\n typeof options.signal.removeEventListener !== \"function\")\n ) {\n throw new ConfigurationError(\"signal must be an AbortSignal\", {\n code: \"invalid_signal\",\n stage: \"configuration\",\n });\n }\n if (\n options.timeoutMs !== undefined &&\n (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0)\n ) {\n throw new ConfigurationError(\"timeoutMs must be positive\", {\n code: \"invalid_timeout\",\n stage: \"configuration\",\n });\n }\n}\n","import { resolveCapabilities } from \"../capabilities/capabilities.js\";\nimport type { ResolvedConfig } from \"../budget/conversion-context.js\";\nimport { ConfigurationError } from \"../errors.js\";\nimport {\n ConversionStrategy,\n OverflowMode,\n type ConvertOptions,\n type ImageRenderer,\n type MentionResolvers,\n type OperationContext,\n type OperationOptions,\n type RenderRequest,\n type SlackUploader,\n} from \"../types.js\";\n\nconst RENDERER_ID_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/u;\nconst CONVERT_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"capabilities\",\n \"capabilityOverrides\",\n \"overflow\",\n \"strategy\",\n \"renderers\",\n \"uploader\",\n \"enableMath\",\n \"enableInlineMath\",\n \"enableFrontmatter\",\n \"mentionResolvers\",\n \"signal\",\n \"timeoutMs\",\n]);\n\nexport function readOperationOptions(options: ConvertOptions | undefined): OperationOptions {\n if (options === undefined) {\n return {};\n }\n validatePlainOptions(options, CONVERT_OPTION_KEYS, \"conversion options\");\n try {\n return {\n signal: Reflect.get(options, \"signal\") as AbortSignal | undefined,\n timeoutMs: Reflect.get(options, \"timeoutMs\") as number | undefined,\n };\n } catch (cause) {\n throw new ConfigurationError(\"Operation options could not be read\", {\n code: \"invalid_operation_options\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\n/**\n * Merge defaults + per-call options into a frozen ResolvedConfig.\n */\nexport function resolveConfig(\n defaults: ConvertOptions,\n overrides: ConvertOptions | undefined,\n operation: OperationContext,\n): ResolvedConfig {\n validateOwnedOptionValues(defaults);\n if (overrides !== undefined) {\n validatePlainOptions(overrides, CONVERT_OPTION_KEYS, \"conversion options\");\n }\n let overrideSnapshot: ConvertOptions | undefined;\n try {\n overrideSnapshot = overrides === undefined ? undefined : { ...overrides };\n } catch (cause) {\n throw new ConfigurationError(\"Conversion options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n validateOwnedOptionValues(overrideSnapshot);\n let merged: ConvertOptions;\n try {\n merged = {\n ...defaults,\n ...overrideSnapshot,\n capabilityOverrides: {\n ...defaults.capabilityOverrides,\n ...overrideSnapshot?.capabilityOverrides,\n },\n renderers:\n overrideSnapshot !== undefined && Object.hasOwn(overrideSnapshot, \"renderers\")\n ? overrideSnapshot.renderers\n : defaults.renderers,\n uploader:\n overrideSnapshot !== undefined && Object.hasOwn(overrideSnapshot, \"uploader\")\n ? overrideSnapshot.uploader\n : defaults.uploader,\n mentionResolvers:\n overrideSnapshot !== undefined && Object.hasOwn(overrideSnapshot, \"mentionResolvers\")\n ? overrideSnapshot.mentionResolvers\n : defaults.mentionResolvers,\n };\n } catch (cause) {\n throw new ConfigurationError(\"Conversion options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n\n const capabilities = resolveCapabilities(merged.capabilities, merged.capabilityOverrides);\n\n const overflow = merged.overflow ?? OverflowMode.Degrade;\n if (overflow !== OverflowMode.Degrade && overflow !== OverflowMode.Split) {\n throw new ConfigurationError('Invalid overflow mode; use \"degrade\" or \"split\".');\n }\n\n const strategy = merged.strategy ?? ConversionStrategy.RichTextFirst;\n if (\n strategy !== ConversionStrategy.RichTextFirst &&\n strategy !== ConversionStrategy.MarkdownBlock\n ) {\n throw new ConfigurationError('Invalid strategy; use \"rich-text-first\" or \"markdown-block\".');\n }\n\n const renderers = resolveRendererDescriptors(merged.renderers);\n validateUploader(merged.uploader);\n if (merged.enableMath !== undefined && typeof merged.enableMath !== \"boolean\") {\n throw new ConfigurationError(\"enableMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (merged.enableInlineMath !== undefined && typeof merged.enableInlineMath !== \"boolean\") {\n throw new ConfigurationError(\"enableInlineMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (merged.enableFrontmatter !== undefined && typeof merged.enableFrontmatter !== \"boolean\") {\n throw new ConfigurationError(\"enableFrontmatter must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n const mentionResolvers = resolveMentionResolvers(merged.mentionResolvers);\n\n return Object.freeze({\n capabilities,\n overflow,\n strategy,\n renderers,\n uploader: merged.uploader,\n enableMath: merged.enableMath === true,\n enableInlineMath: merged.enableInlineMath === true,\n enableFrontmatter: merged.enableFrontmatter === true,\n mentionResolvers,\n operation,\n });\n}\n\nfunction resolveMentionResolvers(\n value: MentionResolvers | undefined,\n): MentionResolvers | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(\"mentionResolvers must be a plain object\", {\n code: \"invalid_mention_resolvers\",\n stage: \"configuration\",\n });\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n let resolveUser: unknown;\n let resolveChannel: unknown;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n resolveUser = Reflect.get(value, \"resolveUser\");\n resolveChannel = Reflect.get(value, \"resolveChannel\");\n } catch (cause) {\n throw new ConfigurationError(\"mentionResolvers could not be inspected\", {\n code: \"invalid_mention_resolvers\",\n stage: \"configuration\",\n cause,\n });\n }\n if (\n (prototype !== Object.prototype && prototype !== null) ||\n keys.some((key) => key !== \"resolveUser\" && key !== \"resolveChannel\") ||\n (resolveUser !== undefined && typeof resolveUser !== \"function\") ||\n (resolveChannel !== undefined && typeof resolveChannel !== \"function\")\n ) {\n throw new ConfigurationError(\"mentionResolvers is invalid\", {\n code: \"invalid_mention_resolvers\",\n stage: \"configuration\",\n });\n }\n return Object.freeze({\n resolveUser:\n resolveUser === undefined\n ? undefined\n : (handle: string): string | undefined =>\n (resolveUser as (handle: string) => string | undefined).call(value, handle),\n resolveChannel:\n resolveChannel === undefined\n ? undefined\n : (name: string): string | undefined =>\n (resolveChannel as (name: string) => string | undefined).call(value, name),\n });\n}\n\nexport function resolveRendererDescriptors(\n configured: ReadonlyArray<ImageRenderer> | undefined,\n): ReadonlyArray<ImageRenderer> {\n if (configured !== undefined && !Array.isArray(configured)) {\n throw new ConfigurationError(\"renderers must be an array\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n let inputRenderers: ReadonlyArray<ImageRenderer>;\n try {\n inputRenderers = Object.freeze([...(configured ?? [])]);\n } catch (cause) {\n throw new ConfigurationError(\"renderers must be an iterable renderer array\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n cause,\n });\n }\n const rendererIds = new Set<string>();\n const resolvedRenderers: ImageRenderer[] = [];\n for (const renderer of inputRenderers) {\n let id: unknown;\n let output: unknown;\n let canRender: unknown;\n let render: unknown;\n try {\n id = Reflect.get(renderer as object, \"id\");\n output = Reflect.get(renderer as object, \"output\");\n canRender = Reflect.get(renderer as object, \"canRender\");\n render = Reflect.get(renderer as object, \"render\");\n } catch (cause) {\n throw new ConfigurationError(\"Renderer descriptor could not be read\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n cause,\n });\n }\n if (\n typeof id !== \"string\" ||\n !RENDERER_ID_RE.test(id) ||\n (output !== \"url\" && output !== \"bytes\" && output !== \"both\") ||\n typeof canRender !== \"function\" ||\n typeof render !== \"function\"\n ) {\n throw new ConfigurationError(\"Renderer descriptor is invalid\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n if (rendererIds.has(id)) {\n throw new ConfigurationError(`Duplicate renderer id: ${id}`, {\n code: \"duplicate_renderer_id\",\n stage: \"configuration\",\n });\n }\n rendererIds.add(id);\n const canRenderMethod = canRender as ImageRenderer[\"canRender\"];\n const renderMethod = render as ImageRenderer[\"render\"];\n resolvedRenderers.push(\n Object.freeze({\n id,\n output,\n canRender: (request: RenderRequest): boolean => canRenderMethod.call(renderer, request),\n render: (request: RenderRequest, context: OperationContext) =>\n renderMethod.call(renderer, request, context),\n }) as ImageRenderer,\n );\n }\n return Object.freeze(resolvedRenderers);\n}\n\nfunction validateOwnedOptionValues(options: ConvertOptions | undefined): void {\n if (options === undefined) {\n return;\n }\n resolveCapabilities(options.capabilities, options.capabilityOverrides);\n if (\n options.overflow !== undefined &&\n options.overflow !== OverflowMode.Degrade &&\n options.overflow !== OverflowMode.Split\n ) {\n throw new ConfigurationError('Invalid overflow mode; use \"degrade\" or \"split\".');\n }\n if (\n options.strategy !== undefined &&\n options.strategy !== ConversionStrategy.RichTextFirst &&\n options.strategy !== ConversionStrategy.MarkdownBlock\n ) {\n throw new ConfigurationError('Invalid strategy; use \"rich-text-first\" or \"markdown-block\".');\n }\n resolveRendererDescriptors(options.renderers);\n validateUploader(options.uploader);\n if (options.enableMath !== undefined && typeof options.enableMath !== \"boolean\") {\n throw new ConfigurationError(\"enableMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableInlineMath !== undefined && typeof options.enableInlineMath !== \"boolean\") {\n throw new ConfigurationError(\"enableInlineMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableFrontmatter !== undefined && typeof options.enableFrontmatter !== \"boolean\") {\n throw new ConfigurationError(\"enableFrontmatter must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n resolveMentionResolvers(options.mentionResolvers);\n}\n\nfunction validateUploader(uploader: SlackUploader | undefined): void {\n if (uploader === undefined) {\n return;\n }\n try {\n if (\n (typeof uploader !== \"object\" && typeof uploader !== \"function\") ||\n uploader === null ||\n typeof Reflect.get(uploader, \"upload\") !== \"function\"\n ) {\n throw new TypeError(\"upload must be a function\");\n }\n } catch (cause) {\n throw new ConfigurationError(\"uploader is invalid\", {\n code: \"invalid_uploader\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction validatePlainOptions(\n value: object,\n allowedKeys: ReadonlySet<string>,\n label: string,\n): void {\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n } catch (cause) {\n throw new ConfigurationError(`${label} could not be inspected`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw new ConfigurationError(`Unknown ${label} key: ${key}`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n }\n}\n","import type { Definition, FootnoteDefinition, Heading, Root, RootContent } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type { Block } from \"../blocks/types.js\";\nimport { ConversionContext, type ResolvedConfig } from \"../budget/conversion-context.js\";\nimport { RecordingDegradationCollector } from \"../budget/recording-degradation-collector.js\";\nimport { RecordingReceiptCollector } from \"../budget/recording-receipt-collector.js\";\nimport { StandardBudgetLedger } from \"../budget/standard-budget-ledger.js\";\nimport { createOperationScope, throwIfOperationEnded } from \"../budget/operation-scope.js\";\nimport {\n buildFootnoteBlocks,\n coalescedBlockCount,\n type MessageAssembler,\n} from \"../assemble/message-assembler.js\";\nimport type { AdapterRegistry } from \"../registry/adapter-registry.js\";\nimport {\n MAX_BLOCKS_PER_MESSAGE,\n MESSAGE_TEXT_SAFETY_MAX_CHARS,\n SECTION_TEXT_MAX_CHARS,\n} from \"../constants.js\";\nimport {\n ConfigurationError,\n attachReceipts,\n cloneConfigurationError,\n cloneOperationError,\n isConfigurationError,\n isOperationError,\n isOperationErrorCarrier,\n lockReceiptSnapshot,\n} from \"../errors.js\";\nimport { sliceSurrogateSafe, surrogateSafeEnd } from \"../utf16.js\";\nimport type {\n ConversionMessagesResult,\n ConversionResult,\n ConvertOptions,\n DegradationCollector,\n MarkdownParser,\n OperationContext,\n PlainTextRenderer,\n ReceiptCollector,\n} from \"../types.js\";\nimport { ConversionStrategy, OverflowMode } from \"../types.js\";\n\nimport { readOperationOptions, resolveConfig } from \"./resolve-config.js\";\n\nexport interface SlackMarkConverterDeps {\n readonly parser: MarkdownParser;\n readonly registry: AdapterRegistry;\n readonly assembler: MessageAssembler;\n readonly plainText: PlainTextRenderer;\n readonly defaultOptions: ConvertOptions;\n}\n\n/**\n * Primary public API class — stateless across concurrent convert() calls.\n */\nexport class SlackMarkConverter {\n private readonly parser: MarkdownParser;\n private readonly registry: AdapterRegistry;\n private readonly assembler: MessageAssembler;\n private readonly plainText: PlainTextRenderer;\n private readonly defaultOptions: ConvertOptions;\n\n constructor(deps: SlackMarkConverterDeps) {\n this.parser = deps.parser;\n this.registry = deps.registry;\n this.assembler = deps.assembler;\n this.plainText = deps.plainText;\n this.defaultOptions = deps.defaultOptions;\n }\n\n /**\n * Convert markdown to a single message. Always uses overflow=degrade so content\n * is truncated with degradations rather than silently dropping split messages.\n * Callers that need multi-message output should use {@link convertToMessages}.\n */\n async convert(markdown: string, options?: ConvertOptions): Promise<ConversionResult> {\n readOperationOptions(options);\n resolveConfig(this.defaultOptions, options, {\n signal: undefined,\n deadlineMs: undefined,\n });\n let singleOptions: ConvertOptions;\n try {\n singleOptions = { ...options, overflow: OverflowMode.Degrade };\n } catch (cause) {\n throw new ConfigurationError(\"Conversion options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n const multi = await this.convertToMessages(markdown, singleOptions);\n const first = multi.messages[0] ?? { blocks: [], text: \" \" };\n return {\n blocks: first.blocks,\n text: first.text,\n degradations: multi.degradations,\n receipts: multi.receipts,\n };\n }\n\n /**\n * Advanced execution seam for orchestrators that already own an absolute\n * operation context. The returned promise tracks underlying conversion work.\n */\n async convertWithContext(\n markdown: string,\n options: ConvertOptions | undefined,\n operation: OperationContext,\n receipts: ReceiptCollector = new RecordingReceiptCollector(),\n ): Promise<ConversionResult> {\n const multi = await this.convertToMessagesWithContext(\n markdown,\n { ...options, overflow: OverflowMode.Degrade },\n operation,\n receipts,\n );\n const first = multi.messages[0] ?? { blocks: [], text: \" \" };\n return {\n blocks: first.blocks,\n text: first.text,\n degradations: multi.degradations,\n receipts: multi.receipts,\n };\n }\n\n /**\n * Convert markdown into one or more messages at semantic boundaries.\n */\n async convertToMessages(\n markdown: string,\n options?: ConvertOptions,\n ): Promise<ConversionMessagesResult> {\n const receipts = new RecordingReceiptCollector();\n const operation = createOperationScope(readOperationOptions(options), \"conversion\");\n const underlying = this.convertUnderOperation(markdown, options, operation.context, receipts);\n settleReceiptsWith(underlying, receipts);\n try {\n return await operation.race(underlying);\n } catch (error) {\n throw lockReceiptSnapshot(attachReceipts(error, receipts.all(), receipts.settled()));\n } finally {\n operation.cleanup();\n }\n }\n\n /**\n * Advanced multi-message seam paired with {@link convertWithContext}.\n */\n async convertToMessagesWithContext(\n markdown: string,\n options: ConvertOptions | undefined,\n operation: OperationContext,\n receipts: ReceiptCollector = new RecordingReceiptCollector(),\n ): Promise<ConversionMessagesResult> {\n try {\n return await this.convertUnderOperation(markdown, options, operation, receipts);\n } catch (error) {\n throw attachReceipts(error, receipts.all(), receipts.settled());\n } finally {\n receipts.settle();\n }\n }\n\n private async convertUnderOperation(\n markdown: string,\n options: ConvertOptions | undefined,\n operation: OperationContext,\n receipts: ReceiptCollector,\n ): Promise<ConversionMessagesResult> {\n throwIfOperationEnded(operation, \"conversion\");\n const config = resolveConfig(this.defaultOptions, options, operation);\n const degradations = new RecordingDegradationCollector();\n // When splitting, lift the block + chart caps during emission; the assembler\n // re-applies per-message budgets. Table/markdown/total char caps stay on so\n // oversized single blocks cannot be emitted.\n const splitting = config.overflow === OverflowMode.Split;\n const budget = new StandardBudgetLedger(\n splitting ? Number.MAX_SAFE_INTEGER : MAX_BLOCKS_PER_MESSAGE,\n { enforceChartCap: !splitting },\n );\n\n try {\n if (config.strategy === ConversionStrategy.MarkdownBlock) {\n return this.emitAsMarkdownBlocks(markdown, config, degradations, receipts, budget);\n }\n\n const tree = await this.parser.parse(markdown, {\n enableMath: config.enableMath,\n enableInlineMath: config.enableInlineMath,\n enableFrontmatter: config.enableFrontmatter,\n });\n throwIfOperationEnded(operation, \"parse\");\n\n const { definitions, footnotes, footnoteOrder } = collectRefs(tree, degradations);\n let precedingHeading: string | undefined;\n const emitted: Block[] = [];\n\n let index = 0;\n for (const node of tree.children) {\n throwIfOperationEnded(operation, \"conversion\");\n // Message boundaries are chosen after emission. In split mode, validate\n // each semantic unit against an empty message, then let the assembler\n // enforce cumulative limits for the messages it creates.\n if (splitting) {\n budget.resetForNewMessage();\n }\n const ctx = new ConversionContext({\n config,\n budget,\n degradations,\n receipts,\n definitions,\n footnotes,\n footnoteOrder,\n precedingHeading,\n path: `root[${String(index)}]`,\n });\n\n if (node.type === \"heading\") {\n precedingHeading = toString(node as Heading);\n }\n\n const reservedBefore = budget.snapshot().blocks;\n const blocks = await this.registry.emit(node as RootContent, ctx);\n refundCoalescedBlocks(budget, reservedBefore, emitted.at(-1), blocks);\n emitted.push(...blocks);\n index += 1;\n }\n\n const footnoteNumbers = new Map<string, number>();\n footnoteOrder.forEach((id, i) => footnoteNumbers.set(id, i + 1));\n const footnoteEntries = footnoteOrder.map((id, i) => {\n const def = footnotes.get(id);\n return {\n n: i + 1,\n text: def !== undefined ? footnoteBodyText(def, footnoteNumbers).trim() : id,\n };\n });\n const footnoteBlocks = buildFootnoteBlocks(footnoteEntries, degradations);\n\n const assembleCtx = new ConversionContext({\n config,\n budget,\n degradations,\n receipts,\n definitions,\n footnotes,\n footnoteOrder,\n precedingHeading,\n path: \"assemble\",\n });\n const messages = this.assembler.assemble(emitted, assembleCtx, footnoteBlocks);\n\n return {\n messages,\n degradations: degradations.all(),\n receipts: receipts.all(),\n };\n } catch (err) {\n if (isConfigurationError(err)) {\n throw cloneConfigurationError(err);\n }\n if (isOperationError(err)) {\n throw err === operation.signal?.reason || isOperationErrorCarrier(err)\n ? err\n : cloneOperationError(err, \"conversion\");\n }\n // User markdown must never throw — degrade to a single section.\n degradations.add({\n nodeType: \"document\",\n from: \"convert\",\n to: \"section\",\n reason: \"Conversion failed; emitted plain-text fallback\",\n path: \"root\",\n details: {\n code: \"document_conversion_failed\",\n stage: \"conversion\",\n retryable: false,\n },\n });\n const text = safeNotificationText(this.plainText, markdown, degradations);\n return {\n messages: [\n {\n blocks: [\n {\n type: \"section\",\n text: { type: \"mrkdwn\", text: clampSectionFallback(text, degradations) },\n },\n ],\n text,\n },\n ],\n degradations: degradations.all(),\n receipts: receipts.all(),\n };\n }\n }\n\n private emitAsMarkdownBlocks(\n markdown: string,\n config: ResolvedConfig,\n degradations: RecordingDegradationCollector,\n receipts: ReceiptCollector,\n budget: StandardBudgetLedger,\n ): ConversionMessagesResult {\n const chunks = chunkMarkdown(markdown, 12_000);\n let blocks: Block[] = [];\n if (!config.capabilities.markdownBlock) {\n degradations.add({\n nodeType: \"document\",\n from: \"markdown-block\",\n to: \"section\",\n reason: \"markdownBlock capability off; emitting section fallback\",\n path: \"root\",\n });\n const text = safeNotificationText(this.plainText, markdown, degradations);\n blocks = [\n {\n type: \"section\",\n text: { type: \"mrkdwn\", text: clampSectionFallback(text, degradations) },\n },\n ];\n } else {\n for (const chunk of chunks) {\n if (config.overflow === OverflowMode.Split) {\n budget.resetForNewMessage();\n }\n if (!budget.tryReserveClaim({ blocks: 1, markdownChars: chunk.length })) {\n degradations.add({\n nodeType: \"document\",\n from: \"markdown-block\",\n to: \"truncated\",\n reason: \"markdown 12k cumulative budget exhausted\",\n path: \"root\",\n });\n break;\n }\n blocks.push({ type: \"markdown\", text: chunk });\n }\n }\n\n const assembleCtx = new ConversionContext({\n config,\n budget,\n degradations,\n receipts,\n definitions: new Map(),\n footnotes: new Map(),\n footnoteOrder: [],\n precedingHeading: undefined,\n path: \"assemble\",\n });\n // Markdown strategy has no GFM footnote pass; assembler still applies overflow split/degrade.\n const messages = this.assembler.assemble(blocks, assembleCtx, []);\n return {\n messages,\n degradations: degradations.all(),\n receipts: receipts.all(),\n };\n }\n}\n\n/**\n * Reconcile a node's block reservation with the blocks it actually contributes.\n *\n * A node reserves its blocks before it emits, which is the only order that can gate an\n * adapter. Once the node has emitted, adjacent rich_text sections are known to merge\n * during assembly, so the reservation is reduced to the merged count. Character and chart\n * totals are untouched: coalescing does not shrink them.\n */\nfunction refundCoalescedBlocks(\n budget: StandardBudgetLedger,\n reservedBefore: number,\n previous: Block | undefined,\n blocks: ReadonlyArray<Block>,\n): void {\n const snapshot = budget.snapshot();\n const reserved = snapshot.blocks - reservedBefore;\n const actual = coalescedBlockCount(previous, blocks);\n if (reserved <= actual) {\n return;\n }\n budget.restore({ ...snapshot, blocks: snapshot.blocks - (reserved - actual) });\n}\n\nfunction settleReceiptsWith(promise: Promise<unknown>, receipts: ReceiptCollector): void {\n void promise.then(\n () => {\n receipts.settle();\n return undefined;\n },\n () => {\n receipts.settle();\n return undefined;\n },\n );\n}\n\nfunction safeNotificationText(\n plainText: PlainTextRenderer,\n markdown: string,\n degradations: DegradationCollector,\n): string {\n const raw = plainText.render(markdown);\n if (raw.length <= MESSAGE_TEXT_SAFETY_MAX_CHARS) {\n return raw;\n }\n degradations.add({\n nodeType: \"message\",\n from: `${String(raw.length)} text chars`,\n to: `${String(MESSAGE_TEXT_SAFETY_MAX_CHARS)} text chars`,\n reason: \"Notification text truncated to 40k safety limit\",\n path: \"root\",\n });\n return sliceSurrogateSafe(raw, MESSAGE_TEXT_SAFETY_MAX_CHARS);\n}\n\nfunction clampSectionFallback(text: string, degradations: DegradationCollector): string {\n if (text.length <= SECTION_TEXT_MAX_CHARS) {\n return text;\n }\n degradations.add({\n nodeType: \"section\",\n from: `${String(text.length)} chars`,\n to: `${String(SECTION_TEXT_MAX_CHARS)} chars`,\n reason: \"Section text truncated to 3000 chars\",\n path: \"root\",\n });\n return sliceSurrogateSafe(text, SECTION_TEXT_MAX_CHARS);\n}\n\nfunction collectRefs(\n tree: Root,\n degradations: DegradationCollector,\n): {\n definitions: Map<string, Definition>;\n footnotes: Map<string, FootnoteDefinition>;\n footnoteOrder: string[];\n} {\n const definitions = new Map<string, Definition>();\n const footnotes = new Map<string, FootnoteDefinition>();\n // CommonMark: when identifiers collide, the first definition takes\n // precedence (spec §Link reference definitions); mdast-util-to-hast applies\n // the same rule to footnote definitions. Ignored duplicates are flagged.\n for (const node of tree.children) {\n if (node.type === \"definition\") {\n const key = node.identifier.toLowerCase();\n if (definitions.has(key)) {\n degradations.add({\n nodeType: \"definition\",\n from: node.identifier,\n to: \"ignored\",\n reason: \"Duplicate link reference definition; first definition wins\",\n path: \"root\",\n });\n } else {\n definitions.set(key, node);\n }\n }\n if (node.type === \"footnoteDefinition\") {\n if (footnotes.has(node.identifier)) {\n degradations.add({\n nodeType: \"footnoteDefinition\",\n from: node.identifier,\n to: \"ignored\",\n reason: \"Duplicate footnote definition; first definition wins\",\n path: \"root\",\n });\n } else {\n footnotes.set(node.identifier, node);\n }\n }\n }\n // Number footnotes by first reference in document order (not definition order).\n const footnoteOrder: string[] = [];\n const seen = new Set<string>();\n walkFootnoteReferences(tree, (id) => {\n if (!seen.has(id)) {\n seen.add(id);\n footnoteOrder.push(id);\n }\n });\n // Footnotes referenced only from other footnote bodies are rendered too\n // (GitHub lists them after body-referenced ones); breadth-first over the\n // bodies of already-ordered footnotes, cycle-safe via `seen`.\n for (let i = 0; i < footnoteOrder.length; i += 1) {\n const def = footnotes.get(footnoteOrder[i] ?? \"\");\n if (def === undefined) {\n continue;\n }\n for (const child of def.children) {\n walkFootnoteReferences(child, (id) => {\n if (!seen.has(id)) {\n seen.add(id);\n footnoteOrder.push(id);\n }\n });\n }\n }\n return { definitions, footnotes, footnoteOrder };\n}\n\n/**\n * Footnote definition body as plain text with nested footnote references\n * rendered as their `[n]` markers (mdast-util-to-string drops them entirely).\n */\nfunction footnoteBodyText(node: unknown, numbers: ReadonlyMap<string, number>): string {\n if (node === null || typeof node !== \"object\") {\n return \"\";\n }\n const record = node as {\n readonly type?: string;\n readonly identifier?: string;\n readonly value?: string;\n readonly alt?: string;\n readonly children?: ReadonlyArray<unknown>;\n };\n if (record.type === \"footnoteReference\" && typeof record.identifier === \"string\") {\n const n = numbers.get(record.identifier);\n return n !== undefined ? `[${String(n)}]` : `[^${record.identifier}]`;\n }\n if (typeof record.value === \"string\") {\n return record.value;\n }\n if (typeof record.alt === \"string\") {\n return record.alt;\n }\n if (record.children !== undefined) {\n const parts: string[] = [];\n for (const child of record.children) {\n parts.push(footnoteBodyText(child, numbers));\n }\n return parts.join(\"\");\n }\n return \"\";\n}\n\nfunction walkFootnoteReferences(node: unknown, onRef: (id: string) => void): void {\n if (node === null || typeof node !== \"object\") {\n return;\n }\n const record = node as {\n readonly type?: string;\n readonly identifier?: string;\n readonly children?: ReadonlyArray<unknown>;\n };\n // Definitions are not part of reading-order numbering.\n if (record.type === \"footnoteDefinition\") {\n return;\n }\n if (record.type === \"footnoteReference\" && typeof record.identifier === \"string\") {\n onRef(record.identifier);\n return;\n }\n if (record.children !== undefined) {\n for (const child of record.children) {\n walkFootnoteReferences(child, onRef);\n }\n }\n}\n\nfunction chunkMarkdown(text: string, max: number): string[] {\n if (text.length <= max) {\n return [text.length > 0 ? text : \" \"];\n }\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n // Chunk boundaries must not split a surrogate pair (max ≥ 2 guarantees progress).\n const end = surrogateSafeEnd(text, i + max);\n out.push(text.slice(i, end));\n i = end;\n }\n return out;\n}\n","import type { Emphasis, Link, LinkReference, PhrasingContent, Strong, Text } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type {\n ImageBlock,\n RichTextBlock,\n RichTextEmoji,\n RichTextInline,\n RichTextLink,\n RichTextStyle,\n RichTextText,\n} from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport {\n ELLIPSIS,\n IMAGE_ALT_MAX_CHARS,\n IMAGE_URL_MAX_CHARS,\n SECTION_TEXT_MAX_CHARS,\n} from \"../constants.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\n\nconst HTTP_URL_RE = /^(https?:|mailto:)/i;\nconst IMAGE_EXT_RE = /\\.(png|jpe?g|gif)(?:\\?|#|$)/i;\n\nexport type HoistedImage = {\n readonly url: string;\n readonly alt: string;\n readonly title: string | undefined;\n};\n\nexport interface InlineEmitResult {\n readonly elements: ReadonlyArray<RichTextInline>;\n readonly hoistedImages: ReadonlyArray<HoistedImage>;\n}\n\n/**\n * Convert mdast phrasing content into rich_text inline elements.\n */\nexport function emitPhrasing(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n baseStyle: RichTextStyle = {},\n): InlineEmitResult {\n const elements: RichTextInline[] = [];\n const hoistedImages: HoistedImage[] = [];\n // Mutable working copy: Slack labeled links with spaces (<https://u|two words>)\n // parse as text(\"…<\") + autolink + text(\"words>…\") and are reassembled in place.\n const work: PhrasingContent[] = [...nodes];\n // remark splits <a href>label</a> into html/text/html siblings — track across nodes.\n let pendingAnchor: OpenAnchor | undefined;\n // remark also splits <b>bold</b> into html/text/html siblings, so formatting\n // tags must style the text nodes BETWEEN them; a per-call stack tracks the\n // currently open cross-node tags.\n const htmlStyles: RichTextStyle[] = [];\n const activeStyle = (): RichTextStyle => htmlStyles[htmlStyles.length - 1] ?? baseStyle;\n\n const flushPendingAnchor = (): void => {\n if (pendingAnchor === undefined) {\n return;\n }\n elements.push(anchorInline(pendingAnchor, ctx));\n pendingAnchor = undefined;\n };\n\n for (let i = 0; i < work.length; i += 1) {\n const node = work[i] as PhrasingContent;\n if (pendingAnchor === undefined) {\n const reassembled = reassembleSlackLabeledLink(work, i, activeStyle());\n if (reassembled !== undefined) {\n if (reassembled.leadingText.value.length > 0) {\n elements.push(\n ...emitTextWithMentionsAndEmoji(reassembled.leadingText, activeStyle(), ctx),\n );\n }\n elements.push(reassembled.link);\n // Drop the lead+autolink+tail trio so the fractured autolink cannot be\n // emitLink'd again; keep only a non-empty trailing remnant for the next pass.\n if (reassembled.trailingText.value.length > 0) {\n work.splice(i, 3, reassembled.trailingText);\n } else {\n work.splice(i, 3);\n }\n i -= 1;\n continue;\n }\n }\n if (pendingAnchor !== undefined) {\n if (node.type === \"html\" && /^<\\/a\\s*>$/i.test(node.value.trim())) {\n flushPendingAnchor();\n continue;\n }\n if (node.type === \"text\") {\n pendingAnchor.textParts.push(node.value);\n continue;\n }\n if (node.type === \"break\") {\n pendingAnchor.textParts.push(\"\\n\");\n continue;\n }\n pendingAnchor.textParts.push(toString(node));\n continue;\n }\n\n if (node.type === \"html\") {\n const trimmed = node.value.trim();\n // remark parses <!here>, <!date^…>, <!subteam^…> as inline html — convert\n // them to their rich text elements instead of stripping (silent mangling).\n const entityInlines = slackEntityRichTextInlines(trimmed, activeStyle());\n if (entityInlines !== undefined) {\n elements.push(...entityInlines);\n continue;\n }\n const openOnly = /^<a\\b([^>]{0,500})>\\s*$/i.exec(trimmed);\n if (openOnly !== null) {\n const hrefMatch = /href\\s*=\\s*[\"']([^\"']{0,3000})[\"']/i.exec(openOnly[1] ?? \"\");\n const href = hrefMatch?.[1];\n if (href !== undefined) {\n // Invalid hrefs still collect the label so the anchor text is not lost;\n // the flush degrades them to text with the URL as a suffix.\n pendingAnchor = {\n href,\n style: activeStyle(),\n textParts: [],\n valid: isValidLinkUrl(href),\n };\n continue;\n }\n }\n const openTag = HTML_STYLE_OPEN_RE.exec(trimmed);\n if (openTag !== null) {\n htmlStyles.push(htmlTagStyle(activeStyle(), openTag[1] ?? \"\"));\n continue;\n }\n if (HTML_STYLE_CLOSE_RE.test(trimmed)) {\n htmlStyles.pop();\n continue;\n }\n elements.push(...emitInlineHtml(node.value, activeStyle(), ctx));\n continue;\n }\n\n switch (node.type) {\n case \"text\": {\n elements.push(...emitTextWithMentionsAndEmoji(node as Text, activeStyle(), ctx));\n break;\n }\n case \"strong\": {\n const inner = emitPhrasing((node as Strong).children, ctx, {\n ...activeStyle(),\n bold: true,\n });\n elements.push(...inner.elements);\n hoistedImages.push(...inner.hoistedImages);\n break;\n }\n case \"emphasis\": {\n const inner = emitPhrasing((node as Emphasis).children, ctx, {\n ...activeStyle(),\n italic: true,\n });\n elements.push(...inner.elements);\n hoistedImages.push(...inner.hoistedImages);\n break;\n }\n case \"delete\": {\n const inner = emitPhrasing(node.children, ctx, { ...activeStyle(), strike: true });\n elements.push(...inner.elements);\n hoistedImages.push(...inner.hoistedImages);\n break;\n }\n case \"inlineCode\": {\n const el: RichTextText = {\n type: \"text\",\n text: node.value,\n style: styleOrUndefined({ ...activeStyle(), code: true }),\n };\n elements.push(el);\n break;\n }\n case \"break\": {\n elements.push({ type: \"text\", text: \"\\n\", style: styleOrUndefined(activeStyle()) });\n break;\n }\n case \"link\": {\n elements.push(...emitLink(node, ctx, activeStyle()));\n break;\n }\n case \"linkReference\": {\n elements.push(...emitLinkReference(node, ctx, activeStyle()));\n break;\n }\n case \"image\": {\n const url = node.url;\n if (isPublicImageUrl(url)) {\n hoistedImages.push({\n url,\n alt: node.alt ?? \"\",\n title: node.title ?? undefined,\n });\n elements.push({\n type: \"link\",\n url,\n text: node.alt && node.alt.length > 0 ? node.alt : url,\n style: styleOrUndefined(activeStyle()),\n });\n } else {\n // Slack link elements require absolute http(s)/mailto URLs; anything\n // else (relative, ftp:, data:, empty) must degrade to text or the\n // whole message is rejected with invalid_blocks.\n const linkable = isValidLinkUrl(url);\n ctx.degradations.add({\n nodeType: \"image\",\n from: \"image\",\n to: linkable ? \"link\" : \"text\",\n reason: \"Image URL is not a public http(s) png/jpg/gif ≤3000 chars\",\n path: ctx.path,\n });\n const label = node.alt && node.alt.length > 0 ? node.alt : url.length > 0 ? url : \"image\";\n if (linkable) {\n elements.push({\n type: \"link\",\n url,\n text: label,\n style: styleOrUndefined(activeStyle()),\n });\n } else {\n const suffix = url.length > 0 && url !== label ? ` (${url})` : \"\";\n elements.push({\n type: \"text\",\n text: `${label}${suffix}`,\n style: styleOrUndefined(activeStyle()),\n });\n }\n }\n break;\n }\n case \"imageReference\": {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n if (def === undefined) {\n elements.push({\n type: \"text\",\n text: node.alt ?? node.identifier,\n style: styleOrUndefined(activeStyle()),\n });\n break;\n }\n const asImage = emitPhrasing(\n [\n {\n type: \"image\",\n url: def.url,\n alt: node.alt ?? undefined,\n title: def.title ?? undefined,\n },\n ],\n ctx,\n activeStyle(),\n );\n elements.push(...asImage.elements);\n hoistedImages.push(...asImage.hoistedImages);\n break;\n }\n case \"footnoteReference\": {\n const idx = ctx.footnoteOrder.indexOf(node.identifier);\n const n = idx >= 0 ? idx + 1 : 1;\n elements.push({\n type: \"text\",\n text: `[${String(n)}]`,\n style: styleOrUndefined(activeStyle()),\n });\n break;\n }\n case \"inlineMath\": {\n elements.push({\n type: \"text\",\n text: node.value,\n style: styleOrUndefined({ ...activeStyle(), code: true }),\n });\n ctx.degradations.add({\n nodeType: \"inlineMath\",\n from: \"inlineMath\",\n to: \"style.code\",\n reason: \"Math is emitted as preformatted/code text\",\n path: ctx.path,\n });\n break;\n }\n default: {\n const text = toString(node);\n if (text.length > 0) {\n elements.push({ type: \"text\", text, style: styleOrUndefined(activeStyle()) });\n }\n break;\n }\n }\n }\n\n flushPendingAnchor();\n return { elements: coalesceText(elements), hoistedImages };\n}\n\n/**\n * Plain string from phrasing (strips styles) — for headers etc.\n */\nexport function phrasingToPlain(nodes: ReadonlyArray<PhrasingContent>): string {\n return toString({ type: \"paragraph\", children: nodes as PhrasingContent[] });\n}\n\nexport function isPublicImageUrl(url: string): boolean {\n if (url.length === 0 || url.length > IMAGE_URL_MAX_CHARS) {\n return false;\n }\n if (!HTTP_URL_RE.test(url)) {\n return false;\n }\n if (\n /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|10\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[01])\\.)/i.test(\n url,\n )\n ) {\n return false;\n }\n return IMAGE_EXT_RE.test(url);\n}\n\n/**\n * Count images that {@link emitPhrasing} would hoist into separate image blocks.\n */\nexport function countHoistableImages(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n): number {\n let count = 0;\n for (const node of nodes) {\n switch (node.type) {\n case \"image\": {\n if (isPublicImageUrl(node.url)) {\n count += 1;\n }\n break;\n }\n case \"imageReference\": {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n if (def !== undefined && isPublicImageUrl(def.url)) {\n count += 1;\n }\n break;\n }\n case \"strong\":\n case \"emphasis\":\n case \"delete\": {\n count += countHoistableImages(node.children, ctx);\n break;\n }\n case \"text\":\n case \"inlineCode\":\n case \"break\":\n case \"link\":\n case \"linkReference\":\n case \"footnoteReference\":\n case \"html\":\n case \"inlineMath\":\n break;\n default: {\n // Other phrasing (e.g. extensions) cannot hoist images.\n break;\n }\n }\n }\n return count;\n}\n\nexport function truncateLabel(label: string, max: number): { text: string; truncated: boolean } {\n if (label.length <= max) {\n return { text: label, truncated: false };\n }\n return { text: `${sliceSurrogateSafe(label, Math.max(0, max - 1))}${ELLIPSIS}`, truncated: true };\n}\n\n/** Standalone image block for an image hoisted out of phrasing content. */\nexport function hoistedImageBlock(h: HoistedImage, ctx: ConversionContext): ImageBlock {\n return {\n type: \"image\",\n image_url: h.url,\n alt_text: clampImageText(h.alt.length > 0 ? h.alt : \"image\", ctx, \"alt_text\"),\n title:\n h.title !== undefined && h.title.length > 0\n ? { type: \"plain_text\", text: clampImageText(h.title, ctx, \"title\") }\n : undefined,\n };\n}\n\n/** Clamp section mrkdwn to 3000 chars and record a degradation when clipped. */\nexport function clampSectionText(text: string, ctx: ConversionContext, nodeType: string): string {\n if (text.length <= SECTION_TEXT_MAX_CHARS) {\n return text;\n }\n ctx.degradations.add({\n nodeType,\n from: `${String(text.length)} chars`,\n to: `${String(SECTION_TEXT_MAX_CHARS)} chars`,\n reason: \"Section text truncated to 3000 chars\",\n path: ctx.path,\n });\n return sliceSurrogateSafe(text, SECTION_TEXT_MAX_CHARS);\n}\n\n/** rich_text_preformatted block shared by code/math/mermaid/table fallbacks. */\nexport function preformattedRichText(text: string, language: string | undefined): RichTextBlock {\n return {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_preformatted\",\n elements: [{ type: \"text\", text: text.length > 0 ? text : \" \" }],\n border: 0,\n language,\n },\n ],\n };\n}\n\n/** Clamp image alt/title to Slack limits and record a degradation when clipped. */\nexport function clampImageText(\n value: string,\n ctx: ConversionContext,\n field: \"alt_text\" | \"title\",\n): string {\n if (value.length <= IMAGE_ALT_MAX_CHARS) {\n return value;\n }\n ctx.degradations.add({\n nodeType: \"image\",\n from: field,\n to: \"truncated\",\n reason: `Image ${field} truncated to ${String(IMAGE_ALT_MAX_CHARS)} chars`,\n path: ctx.path,\n });\n return sliceSurrogateSafe(value, IMAGE_ALT_MAX_CHARS);\n}\n\nfunction styleOrUndefined(style: RichTextStyle): RichTextStyle | undefined {\n if (\n style.bold === true ||\n style.italic === true ||\n style.strike === true ||\n style.code === true ||\n style.underline === true\n ) {\n return style;\n }\n return undefined;\n}\n\n// Raw Slack mrkdwn entity tokens (<@U…>, <#C…>, <!here>, <!subteam^S…>, <!date^…>).\n// These carry Slack IDs directly, so they convert unconditionally — no resolvers needed.\n// Sticky + ignoreCase (`iy`) candidate form for the single-pass scanner; strict parse follows.\nconst SLACK_ENTITY_AT_RE =\n /<([@#!][^<>]{1,340}|(?:https?:|mailto:)[^<>|]{1,3000}\\|[^<>]{1,300})>/iy;\n// charCodeAt gates so sticky regexes only run at plausible token starts.\nconst CHAR_LT = 60; // <\nconst CHAR_HASH = 35; // #\nconst CHAR_AT = 64; // @\nconst CHAR_COLON = 58; // :\nconst SLACK_USER_RE = /^@([UW][A-Z0-9]{1,60})(?:\\|[^>]{0,300})?$/;\nconst SLACK_CHANNEL_RE = /^#([CDG][A-Z0-9]{1,60})(?:\\|[^>]{0,300})?$/;\nconst SLACK_USERGROUP_RE = /^!subteam\\^(S[A-Z0-9]{1,60})(?:\\|[^>]{0,300})?$/;\nconst SLACK_BROADCAST_RE = /^!(here|channel|everyone)(?:\\|[^>]{0,300})?$/;\nconst SLACK_DATE_RE =\n /^!date\\^(\\d{1,13})\\^([^^|]{1,300})(?:\\^([^^|]{1,3000}))?(?:\\|([^]{0,300}))?$/;\nconst SLACK_LINK_RE = /^((?:https?:|mailto:)[^|]{1,3000})\\|([^]{1,300})$/i;\n\n// Require a non-identifier boundary so emails like user@example.com are not\n// mentions. Handles may contain dots (\"john.doe\") but never start or end with\n// one — a trailing dot is sentence punctuation (\"ping @sarah.\"), and matching\n// it made the handle unresolvable. Shared source keeps the probe and scanner aligned.\nconst MENTION_PATTERN = String.raw`(?<![A-Za-z0-9._-])@([a-zA-Z0-9_-](?:[a-zA-Z0-9._-]{0,62}[a-zA-Z0-9_-])?)|(?<![A-Za-z0-9_-])#([a-zA-Z0-9_-]{1,80})`;\nconst MENTION_RE = new RegExp(MENTION_PATTERN, \"g\");\nconst MENTION_AT_RE = new RegExp(MENTION_PATTERN, \"y\");\n\n// Every well-formed `:name:` becomes an emoji element — Slack accepts arbitrary\n// names and renders a literal `:name:` fallback for unknown ones (verified via\n// Builder probe 2026-07-22), which is also the only way custom workspace emoji\n// (`:party-parrot:`) can work. Word boundaries prevent misparsing times/ratios\n// like `12:30:45` (same rule as react-blockkit's mrkdwn tokenizer).\nconst EMOJI_AT_RE = /(?<![A-Za-z0-9]):([a-z0-9_+-]{1,64}):(?![A-Za-z0-9])/y;\n\n/** Parse the inside of one `<…>` token into a rich text element, or undefined if not Slack syntax. */\nfunction slackEntityElement(inner: string, style: RichTextStyle): RichTextInline | undefined {\n const labeledLink = SLACK_LINK_RE.exec(inner);\n if (labeledLink?.[1] !== undefined && labeledLink[2] !== undefined) {\n if (!isValidLinkUrl(labeledLink[1])) {\n return undefined;\n }\n return {\n type: \"link\",\n url: labeledLink[1],\n text: labeledLink[2],\n style: styleOrUndefined(style),\n };\n }\n const user = SLACK_USER_RE.exec(inner);\n if (user?.[1] !== undefined) {\n return { type: \"user\", user_id: user[1], style: styleOrUndefined(style) };\n }\n const channel = SLACK_CHANNEL_RE.exec(inner);\n if (channel?.[1] !== undefined) {\n return { type: \"channel\", channel_id: channel[1], style: styleOrUndefined(style) };\n }\n const usergroup = SLACK_USERGROUP_RE.exec(inner);\n if (usergroup?.[1] !== undefined) {\n return { type: \"usergroup\", usergroup_id: usergroup[1], style: styleOrUndefined(style) };\n }\n const broadcast = SLACK_BROADCAST_RE.exec(inner);\n if (broadcast !== null) {\n const range = broadcast[1];\n if (range === \"here\" || range === \"channel\" || range === \"everyone\") {\n return { type: \"broadcast\", range, style: styleOrUndefined(style) };\n }\n }\n const date = SLACK_DATE_RE.exec(inner);\n if (date?.[1] !== undefined && date[2] !== undefined) {\n const timestamp = Number(date[1]);\n if (Number.isSafeInteger(timestamp)) {\n return {\n type: \"date\",\n timestamp,\n format: date[2],\n url: date[3],\n fallback: date[4],\n style: styleOrUndefined(style),\n };\n }\n }\n return undefined;\n}\n\n/**\n * Single-pass text-run tokenizer. Walks once against an ordered token table\n * (entity → mention → emoji), preserving the historical three-pass priority.\n * Mentions only attempt when a resolver is configured. `sawEntity` lets HTML\n * callers keep their non-entity path when nothing parsed.\n */\nfunction scanTextRun(\n value: string,\n style: RichTextStyle,\n resolveUser?: (handle: string) => string | undefined,\n resolveChannel?: (name: string) => string | undefined,\n): { elements: RichTextInline[]; sawEntity: boolean } {\n const scanMentions = resolveUser !== undefined || resolveChannel !== undefined;\n const styleOpt = styleOrUndefined(style);\n const out: RichTextInline[] = [];\n let sawEntity = false;\n let i = 0;\n let textStart = 0;\n\n while (i < value.length) {\n const ch = value.charCodeAt(i);\n let element: RichTextInline | undefined;\n let tokenEnd = 0;\n\n // Token table (priority order): entity → mention → emoji.\n if (ch === CHAR_LT) {\n SLACK_ENTITY_AT_RE.lastIndex = i;\n const match = SLACK_ENTITY_AT_RE.exec(value);\n if (match !== null) {\n // Failed strict parse: leave the candidate for later mention/emoji/text.\n element = slackEntityElement(match[1] ?? \"\", style);\n if (element !== undefined) {\n tokenEnd = SLACK_ENTITY_AT_RE.lastIndex;\n sawEntity = true;\n }\n }\n } else if (scanMentions && (ch === CHAR_AT || ch === CHAR_HASH)) {\n MENTION_AT_RE.lastIndex = i;\n const match = MENTION_AT_RE.exec(value);\n if (match !== null) {\n const userHandle = match[1];\n const channelName = match[2];\n if (userHandle !== undefined && resolveUser !== undefined) {\n const userId = resolveUser(userHandle);\n if (userId !== undefined && userId.length > 0) {\n element = { type: \"user\", user_id: userId, style: styleOpt };\n tokenEnd = MENTION_AT_RE.lastIndex;\n }\n } else if (channelName !== undefined && resolveChannel !== undefined) {\n const channelId = resolveChannel(channelName);\n if (channelId !== undefined && channelId.length > 0) {\n element = { type: \"channel\", channel_id: channelId, style: styleOpt };\n tokenEnd = MENTION_AT_RE.lastIndex;\n }\n }\n // Unresolved / wrong-kind: leave for emoji/text (mention charset has no ':').\n }\n } else if (ch === CHAR_COLON) {\n EMOJI_AT_RE.lastIndex = i;\n const match = EMOJI_AT_RE.exec(value);\n if (match !== null) {\n const emoji: RichTextEmoji = { type: \"emoji\", name: match[1] ?? \"\" };\n element = emoji;\n tokenEnd = EMOJI_AT_RE.lastIndex;\n }\n }\n\n if (element !== undefined) {\n if (i > textStart) {\n out.push({ type: \"text\", text: value.slice(textStart, i), style: styleOpt });\n }\n out.push(element);\n i = tokenEnd;\n textStart = i;\n continue;\n }\n i += 1;\n }\n\n if (textStart < value.length) {\n out.push({ type: \"text\", text: value.slice(textStart), style: styleOpt });\n }\n if (out.length === 0) {\n out.push({ type: \"text\", text: value, style: styleOpt });\n }\n return { elements: out, sawEntity };\n}\n\n/**\n * Section inlines for raw HTML values carrying Slack entity tokens (remark parses\n * `<!here>` and friends as html nodes). Undefined when the value has no entities.\n */\nexport function slackEntityRichTextInlines(\n value: string,\n style: RichTextStyle,\n): ReadonlyArray<RichTextInline> | undefined {\n // Mentions stay off — HTML entity nodes historically only split entities + emoji.\n const { elements, sawEntity } = scanTextRun(value, style);\n return sawEntity ? elements : undefined;\n}\n\n/** True when mention resolvers are configured and phrasing contains @user / #channel tokens. */\nexport function phrasingNeedsMentionResolution(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n): boolean {\n const resolvers = ctx.config.mentionResolvers;\n if (resolvers?.resolveUser === undefined && resolvers?.resolveChannel === undefined) {\n return false;\n }\n const plain = phrasingToPlain(nodes);\n MENTION_RE.lastIndex = 0;\n return MENTION_RE.test(plain);\n}\n\nfunction emitTextWithMentionsAndEmoji(\n node: Text,\n style: RichTextStyle,\n ctx: ConversionContext,\n): RichTextInline[] {\n const resolvers = ctx.config.mentionResolvers;\n return scanTextRun(node.value, style, resolvers?.resolveUser, resolvers?.resolveChannel).elements;\n}\n\ninterface ReassembledSlackLink {\n readonly leadingText: Text;\n readonly link: RichTextLink;\n readonly trailingText: Text;\n}\n\n/**\n * Slack labeled links whose label contains spaces (`<https://u|two words>`)\n * parse as text ending in \"<\", an autolink whose url swallowed \"|firstWord\",\n * then text carrying the rest of the label up to \">\". Reassemble the trio.\n */\nfunction reassembleSlackLabeledLink(\n work: ReadonlyArray<PhrasingContent>,\n i: number,\n style: RichTextStyle,\n): ReassembledSlackLink | undefined {\n const lead = work[i];\n const linkNode = work[i + 1];\n const tail = work[i + 2];\n if (lead?.type !== \"text\" || !lead.value.endsWith(\"<\")) {\n return undefined;\n }\n if (linkNode?.type !== \"link\" || tail?.type !== \"text\") {\n return undefined;\n }\n const url = linkNode.url;\n const pipeIndex = url.indexOf(\"|\");\n if (pipeIndex <= 0 || !HTTP_URL_RE.test(url)) {\n return undefined;\n }\n // Only GFM literal autolinks qualify (label text equals the raw url).\n if (phrasingToPlain(linkNode.children) !== url) {\n return undefined;\n }\n const closeIndex = tail.value.indexOf(\">\");\n if (closeIndex === -1) {\n return undefined;\n }\n const realUrl = url.slice(0, pipeIndex);\n if (!isValidLinkUrl(realUrl)) {\n return undefined;\n }\n const label = `${url.slice(pipeIndex + 1)}${tail.value.slice(0, closeIndex)}`;\n if (label.length === 0) {\n return undefined;\n }\n return {\n leadingText: { type: \"text\", value: lead.value.slice(0, -1) },\n link: { type: \"link\", url: realUrl, text: label, style: styleOrUndefined(style) },\n trailingText: { type: \"text\", value: tail.value.slice(closeIndex + 1) },\n };\n}\n\nfunction emitLink(node: Link, ctx: ConversionContext, style: RichTextStyle): RichTextInline[] {\n const url = node.url;\n const text = phrasingToPlain(node.children);\n // Slack-style labeled autolink <https://url|label>: remark folds the pipe and\n // label into the URL of an autolink. Split them back apart.\n const pipeIndex = url.indexOf(\"|\");\n if (pipeIndex > 0 && HTTP_URL_RE.test(url) && text === url) {\n const realUrl = url.slice(0, pipeIndex);\n const label = url.slice(pipeIndex + 1);\n if (label.length > 0 && isValidLinkUrl(realUrl)) {\n return [{ type: \"link\", url: realUrl, text: label, style: styleOrUndefined(style) }];\n }\n }\n if (!isValidLinkUrl(url)) {\n ctx.degradations.add({\n nodeType: \"link\",\n from: \"link\",\n to: \"text\",\n reason: \"Invalid or oversized URL\",\n path: ctx.path,\n });\n const suffix = url.length > 0 && url !== text ? ` (${url})` : \"\";\n return [{ type: \"text\", text: `${text}${suffix}`, style: styleOrUndefined(style) }];\n }\n const link: RichTextLink = {\n type: \"link\",\n url,\n text: text.length > 0 ? text : url,\n style: styleOrUndefined(style),\n };\n return [link];\n}\n\nfunction emitLinkReference(\n node: LinkReference,\n ctx: ConversionContext,\n style: RichTextStyle,\n): RichTextInline[] {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n if (def === undefined) {\n return [\n {\n type: \"text\",\n text: phrasingToPlain(node.children) || node.identifier,\n style: styleOrUndefined(style),\n },\n ];\n }\n return emitLink(\n {\n type: \"link\",\n url: def.url,\n title: def.title ?? undefined,\n children: node.children,\n },\n ctx,\n style,\n );\n}\n\n/**\n * Slack rich text link elements require absolute http(s)/mailto URLs; relative\n * URLs (`/path`, `#fragment`) or other schemes are rejected with invalid_blocks.\n * https://docs.slack.dev/reference/block-kit/block-elements/rich-text-elements\n */\nexport function isValidLinkUrl(url: string): boolean {\n if (url.length === 0 || url.length > IMAGE_URL_MAX_CHARS) {\n return false;\n }\n return HTTP_URL_RE.test(url);\n}\n\n/** Anchor state collected across `<a href>` … `</a>` tags before emission. */\ninterface OpenAnchor {\n readonly href: string;\n readonly style: RichTextStyle;\n readonly textParts: string[];\n readonly valid: boolean;\n}\n\n/** Emit a collected anchor as a link, or degrade to text+suffix when the href is not link-safe. */\nfunction anchorInline(anchor: OpenAnchor, ctx: ConversionContext): RichTextInline {\n const label = anchor.textParts.join(\"\");\n if (anchor.valid) {\n return {\n type: \"link\",\n url: anchor.href,\n text: label.length > 0 ? label : anchor.href,\n style: styleOrUndefined(anchor.style),\n };\n }\n ctx.degradations.add({\n nodeType: \"link\",\n from: \"link\",\n to: \"text\",\n reason: \"Invalid or oversized URL\",\n path: ctx.path,\n });\n const base = label.length > 0 ? label : anchor.href;\n const suffix =\n label.length > 0 && anchor.href.length > 0 && anchor.href !== label ? ` (${anchor.href})` : \"\";\n return { type: \"text\", text: `${base}${suffix}`, style: styleOrUndefined(anchor.style) };\n}\n\n// remark emits formatting tags as standalone html nodes (<b> and </b> are\n// siblings of the text they wrap); these single-tag patterns drive the\n// cross-node style stack in emitPhrasing.\nconst HTML_STYLE_OPEN_RE = /^<(b|strong|i|em|s|del|code)(\\s+[^>]{0,200})?>$/i;\nconst HTML_STYLE_CLOSE_RE = /^<\\/(b|strong|i|em|s|del|code)\\s*>$/i;\n\nfunction htmlTagStyle(base: RichTextStyle, tag: string): RichTextStyle {\n const t = tag.toLowerCase();\n if (t === \"b\" || t === \"strong\") {\n return { ...base, bold: true };\n }\n if (t === \"i\" || t === \"em\") {\n return { ...base, italic: true };\n }\n if (t === \"s\" || t === \"del\") {\n return { ...base, strike: true };\n }\n return { ...base, code: true };\n}\n\n// Alternatives in match order: known tag (optionally self-closing), unknown\n// tag (stripped), a text run, or a stray \"<\" kept literal so unknown tags can\n// never leak fragments like \"ad>\" into the output.\nconst INLINE_TAG_RE =\n /<\\/?(b|strong|i|em|s|del|code|br|a)(\\s+[^>]{0,200})?\\s*\\/?>|<[^>]{0,200}>|[^<]+|</gi;\n\nfunction emitInlineHtml(\n html: string,\n style: RichTextStyle,\n ctx: ConversionContext,\n): RichTextInline[] {\n const out: RichTextInline[] = [];\n const stack: Array<{ tag: string; style: RichTextStyle }> = [];\n let current = style;\n let openAnchor: OpenAnchor | undefined;\n INLINE_TAG_RE.lastIndex = 0;\n let m: RegExpExecArray | null = INLINE_TAG_RE.exec(html);\n let strippedUnknown = false;\n while (m !== null) {\n const token = m[0];\n if (token.startsWith(\"<\") && token.length > 1 && m[1] === undefined) {\n // Unknown <…> tag — strip it (flagged below) instead of leaking fragments.\n strippedUnknown = true;\n m = INLINE_TAG_RE.exec(html);\n continue;\n }\n if (token.startsWith(\"<\") && m[1] !== undefined) {\n const tag = (m[1] ?? \"\").toLowerCase();\n const closing = token.startsWith(\"</\");\n if (tag === \"br\") {\n if (openAnchor !== undefined) {\n openAnchor.textParts.push(\"\\n\");\n } else {\n out.push({ type: \"text\", text: \"\\n\", style: styleOrUndefined(current) });\n }\n } else if (closing) {\n if (tag === \"a\" && openAnchor !== undefined) {\n out.push(anchorInline(openAnchor, ctx));\n openAnchor = undefined;\n }\n stack.pop();\n current = stack.length > 0 ? (stack[stack.length - 1]?.style ?? style) : style;\n } else if (tag === \"a\") {\n const hrefMatch = /href\\s*=\\s*[\"']([^\"']{0,3000})[\"']/i.exec(token);\n const href = hrefMatch?.[1];\n stack.push({ tag, style: current });\n if (href !== undefined) {\n // Collect label text until </a>; do not emit yet. A nested <a> closes\n // the outer anchor first so its collected label is not dropped.\n if (openAnchor !== undefined) {\n out.push(anchorInline(openAnchor, ctx));\n }\n openAnchor = { href, style: current, textParts: [], valid: isValidLinkUrl(href) };\n }\n } else {\n const next = { ...current };\n if (tag === \"b\" || tag === \"strong\") next.bold = true;\n if (tag === \"i\" || tag === \"em\") next.italic = true;\n if (tag === \"s\" || tag === \"del\") next.strike = true;\n if (tag === \"code\") next.code = true;\n stack.push({ tag, style: next });\n current = next;\n }\n } else if (token.length > 0) {\n if (openAnchor !== undefined) {\n openAnchor.textParts.push(token);\n } else {\n out.push({ type: \"text\", text: token, style: styleOrUndefined(current) });\n }\n }\n m = INLINE_TAG_RE.exec(html);\n }\n if (openAnchor !== undefined) {\n out.push(anchorInline(openAnchor, ctx));\n }\n if (strippedUnknown) {\n ctx.degradations.add({\n nodeType: \"html\",\n from: \"html\",\n to: \"text\",\n reason: \"Unrecognized inline HTML stripped to text\",\n path: ctx.path,\n });\n }\n return out;\n}\n\nfunction coalesceText(elements: ReadonlyArray<RichTextInline>): RichTextInline[] {\n const out: RichTextInline[] = [];\n for (const el of elements) {\n const prev = out[out.length - 1];\n if (\n el.type === \"text\" &&\n prev !== undefined &&\n prev.type === \"text\" &&\n JSON.stringify(prev.style) === JSON.stringify(el.style)\n ) {\n out[out.length - 1] = { type: \"text\", text: prev.text + el.text, style: prev.style };\n } else {\n out.push(el);\n }\n }\n return out;\n}\n","import type { Blockquote, RootContent } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type { Block, RichTextBlock, RichTextInline } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport { emitPhrasing } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\nconst ADMONITION_RE = /^\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\]\\s*/i;\n\nconst ADMONITION_META = {\n NOTE: { emoji: \"📝\", title: \"Note\" },\n TIP: { emoji: \"💡\", title: \"Tip\" },\n IMPORTANT: { emoji: \"❗\", title: \"Important\" },\n WARNING: { emoji: \"⚠️\", title: \"Warning\" },\n CAUTION: { emoji: \"🚫\", title: \"Caution\" },\n} as const;\n\n/**\n * Blockquotes → rich_text_quote; GitHub admonitions get styled first line.\n */\nexport class BlockquoteAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"blockquote\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const quote = node as Blockquote;\n return [\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n const elements = flattenQuote(quote, ctx);\n const block: RichTextBlock = {\n type: \"rich_text\",\n elements: [{ type: \"rich_text_quote\", elements, border: 0 }],\n };\n return [block];\n },\n },\n ];\n }\n}\n\nfunction flattenQuote(quote: Blockquote, ctx: ConversionContext): RichTextInline[] {\n const parts: RichTextInline[] = [];\n let first = true;\n\n for (const child of quote.children) {\n if (child.type === \"paragraph\") {\n let children = child.children;\n if (first && children[0]?.type === \"text\") {\n const textNode = children[0];\n const m = ADMONITION_RE.exec(textNode.value);\n if (m !== null) {\n const kind = (m[1] ?? \"NOTE\").toUpperCase() as keyof typeof ADMONITION_META;\n const meta = ADMONITION_META[kind];\n parts.push({\n type: \"text\",\n text: `${meta.emoji}${meta.title}\\n`,\n style: { bold: true },\n });\n const rest = textNode.value.slice(m[0].length);\n children = [\n ...(rest.length > 0 ? [{ ...textNode, value: rest }] : []),\n ...children.slice(1),\n ];\n }\n }\n first = false;\n const inline = emitPhrasing(children, ctx);\n if (parts.length > 0 && inline.elements.length > 0) {\n parts.push({ type: \"text\", text: \"\\n\" });\n }\n parts.push(...inline.elements);\n } else if (child.type === \"list\") {\n ctx.degradations.add({\n nodeType: \"blockquote\",\n from: \"list\",\n to: \"bullet_lines\",\n reason: \"Nested list inside blockquote flattened\",\n path: ctx.path,\n });\n if (parts.length > 0) parts.push({ type: \"text\", text: \"\\n\" });\n for (const item of child.children) {\n parts.push({ type: \"text\", text: `• ${toString(item)}\\n` });\n }\n } else if (child.type === \"code\") {\n ctx.degradations.add({\n nodeType: \"blockquote\",\n from: \"code\",\n to: \"text\",\n reason: \"Nested code inside blockquote flattened to text\",\n path: ctx.path,\n });\n if (parts.length > 0) parts.push({ type: \"text\", text: \"\\n\" });\n parts.push({ type: \"text\", text: child.value, style: { code: true } });\n } else {\n ctx.degradations.add({\n nodeType: \"blockquote\",\n from: child.type,\n to: \"text\",\n reason: \"Nested block inside blockquote flattened\",\n path: ctx.path,\n });\n if (parts.length > 0) parts.push({ type: \"text\", text: \"\\n\" });\n parts.push({ type: \"text\", text: toString(child) });\n }\n }\n\n return parts.length > 0 ? parts : [{ type: \"text\", text: \" \" }];\n}\n","import { brandErrorPrototype, hasErrorBrand } from \"../errors.js\";\nimport { RetrySafety, UploadPhase, UploadProcessing, type UploadReceipt } from \"../types.js\";\n\n/** See the brand rationale in `errors.ts`: this class is bundled into more than one entry. */\nconst SLACK_UPLOAD_ERROR_BRAND = Symbol.for(\"slackmark.error.slackUpload\");\n\nexport const SlackUploadStage = {\n Admission: \"admission\",\n GetUploadUrl: \"get-upload-url\",\n UploadBytes: \"upload-bytes\",\n CompleteUpload: \"complete-upload\",\n FileInfo: \"file-info\",\n ProcessingTimeout: \"processing-timeout\",\n} as const;\n\nexport type SlackUploadStage = (typeof SlackUploadStage)[keyof typeof SlackUploadStage];\n\nexport interface SlackUploadErrorDetails {\n readonly stage: SlackUploadStage;\n readonly status?: number | undefined;\n readonly code?: string | undefined;\n readonly retryable?: boolean | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly receipt?: UploadReceipt | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Integration error from one explicit stage of Slack's external-upload flow.\n */\nexport class SlackUploadError extends Error {\n static {\n brandErrorPrototype(this.prototype, SLACK_UPLOAD_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly stage: SlackUploadStage;\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly retryable: boolean;\n readonly retryAfterMs: number | undefined;\n readonly receipt: UploadReceipt;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, details: SlackUploadErrorDetails) {\n super(message, details.cause !== undefined ? { cause: details.cause } : undefined);\n this.name = \"SlackUploadError\";\n this.stage = details.stage;\n this.status = details.status;\n this.code = details.code;\n this.retryable = details.retryable ?? isRetryable(details.status, details.code);\n this.retryAfterMs = details.retryAfterMs;\n this.receipt = Object.freeze(\n details.receipt ?? {\n kind: \"upload\",\n provider: \"slack\",\n phase: UploadPhase.Requested,\n fileId: undefined,\n shared: false,\n processing: UploadProcessing.NotRequested,\n status: details.status,\n retryAfterMs: details.retryAfterMs,\n providerCode: details.code,\n retrySafety: RetrySafety.Safe,\n },\n );\n this.receipts = Object.freeze([this.receipt]);\n this.settledReceipts = Promise.resolve(this.receipts);\n }\n}\n\n/**\n * Identifies a {@link SlackUploadError} from any entry of this package. `slackmark` and\n * `slackmark/slack` each bundle their own copy, so `instanceof` is unreliable when the\n * error crosses between them.\n */\nexport function isSlackUploadError(value: unknown): value is SlackUploadError {\n return hasErrorBrand(value, SLACK_UPLOAD_ERROR_BRAND);\n}\n\nfunction isRetryable(status: number | undefined, code: string | undefined): boolean {\n return (\n status === 429 ||\n (status !== undefined && status >= 500) ||\n code === \"fetch_failed\" ||\n code === \"request_timeout\" ||\n code === \"processing_timeout\"\n );\n}\n","import type { ImageBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { throwIfOperationEnded } from \"../budget/operation-scope.js\";\nimport {\n IMAGE_URL_MAX_CHARS,\n RENDERED_IMAGE_FILENAME_MAX_CHARS,\n RENDERED_IMAGE_MAX_BYTES,\n SLACK_FILE_ID_MAX_CHARS,\n} from \"../constants.js\";\nimport {\n ConfigurationError,\n attachReceipts,\n cloneConfigurationError,\n cloneOperationError,\n isConfigurationError,\n isOperationError,\n} from \"../errors.js\";\nimport { isSlackUploadError } from \"../slack/slack-upload-error.js\";\nimport {\n RetrySafety,\n UploadPhase,\n UploadProcessing,\n type BytesImage,\n type Degradation,\n type ImageRenderer,\n type RenderRequest,\n type SlackUploader,\n type StructuredRendererError,\n type UploadReceipt,\n} from \"../types.js\";\n\nimport { clampImageText } from \"./inline.js\";\n\nconst SAFE_METADATA_RE = /^[a-z0-9][a-z0-9._-]*$/u;\nconst SAFE_FILENAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/u;\nconst SLACK_FILE_ID_RE = /^[A-Z][A-Z0-9]{1,254}$/u;\nconst PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10] as const;\nconst GIF87A_SIGNATURE = [71, 73, 70, 56, 55, 97] as const;\nconst GIF89A_SIGNATURE = [71, 73, 70, 56, 57, 97] as const;\n\ntype ValidRenderResult =\n | {\n readonly kind: \"url\";\n readonly imageUrl: string;\n readonly altText: string | undefined;\n }\n | {\n readonly kind: \"bytes\";\n readonly image: BytesImage;\n readonly altText: string | undefined;\n };\n\ntype RenderInspection =\n | { readonly kind: \"decline\" }\n | { readonly kind: \"valid\"; readonly result: ValidRenderResult }\n | { readonly kind: \"invalid\"; readonly reason: string; readonly code: string };\n\n/**\n * Try configured renderers in order and turn the first successful result into\n * a Slack image block. Attempt failures are emitted only on terminal fallback.\n */\nexport async function tryRenderImage(\n request: RenderRequest,\n nodeType: string,\n ctx: ConversionContext,\n): Promise<ImageBlock | undefined> {\n const pendingFailures: Degradation[] = [];\n let missingUploaderRendererId: string | undefined;\n\n for (const renderer of ctx.config.renderers) {\n throwIfOperationEnded(ctx.config.operation, \"renderer_admission\");\n let capability: unknown;\n try {\n capability = renderer.canRender(request);\n } catch (error) {\n rethrowNonDegradationError(error, ctx);\n const metadata = rendererFailureMetadata(error, renderer.id, {\n code: \"renderer_capability_failed\",\n stage: \"capability\",\n retryable: false,\n });\n pendingFailures.push(\n createFailure(\n ctx,\n nodeType,\n \"image.canRender\",\n \"Renderer capability check failed\",\n metadata,\n ),\n );\n continue;\n }\n if (typeof capability !== \"boolean\") {\n observeThenableRejection(capability);\n pendingFailures.push(\n createFailure(\n ctx,\n nodeType,\n \"image.canRender\",\n \"Renderer capability check returned a non-boolean result\",\n {\n code: \"invalid_renderer_capability_result\",\n stage: \"capability\",\n retryable: false,\n rendererId: renderer.id,\n },\n ),\n );\n continue;\n }\n if (!capability) {\n continue;\n }\n\n let rawResult: unknown;\n try {\n rawResult = await renderer.render(request, ctx.config.operation);\n } catch (error) {\n rethrowNonDegradationError(error, ctx);\n const metadata = rendererFailureMetadata(error, renderer.id, {\n code: \"renderer_failed\",\n stage: \"render\",\n retryable: true,\n });\n pendingFailures.push(\n createFailure(ctx, nodeType, \"image.render\", \"Renderer failed\", metadata),\n );\n continue;\n }\n throwIfOperationEnded(ctx.config.operation, \"render\");\n\n const inspection = inspectRenderResult(rawResult, renderer.output);\n if (inspection.kind === \"decline\") {\n continue;\n }\n if (inspection.kind === \"invalid\") {\n pendingFailures.push(\n createFailure(ctx, nodeType, \"image.render\", inspection.reason, {\n code: inspection.code,\n stage: \"validation\",\n retryable: false,\n rendererId: renderer.id,\n }),\n );\n continue;\n }\n\n const result = inspection.result;\n if (result.kind === \"url\") {\n const urlError = validateRendererUrl(result.imageUrl);\n if (urlError !== undefined) {\n pendingFailures.push(\n createFailure(ctx, nodeType, \"image.url\", urlError, {\n code: \"invalid_renderer_url\",\n stage: \"validation\",\n retryable: false,\n rendererId: renderer.id,\n }),\n );\n continue;\n }\n return {\n type: \"image\",\n image_url: result.imageUrl,\n alt_text: clampImageText(result.altText ?? request.altText, ctx, \"alt_text\"),\n };\n }\n\n const uploader = ctx.config.uploader;\n if (uploader === undefined) {\n missingUploaderRendererId ??= renderer.id;\n continue;\n }\n\n const upload = await uploadImage(uploader, result.image, renderer, nodeType, ctx);\n if (upload.ok) {\n return {\n type: \"image\",\n alt_text: clampImageText(result.altText ?? request.altText, ctx, \"alt_text\"),\n slack_file: { id: upload.fileId },\n };\n }\n pendingFailures.push(upload.failure);\n }\n\n if (missingUploaderRendererId !== undefined) {\n throw new ConfigurationError(\n `Renderer \"${missingUploaderRendererId}\" returned bytes but no uploader was configured`,\n {\n code: \"bytes_uploader_missing\",\n stage: \"upload\",\n },\n );\n }\n for (const failure of pendingFailures) {\n ctx.degradations.add(failure);\n }\n return undefined;\n}\n\nasync function uploadImage(\n uploader: SlackUploader,\n image: BytesImage,\n renderer: ImageRenderer,\n nodeType: string,\n ctx: ConversionContext,\n): Promise<\n | { readonly ok: true; readonly fileId: string }\n | { readonly ok: false; readonly failure: Degradation }\n> {\n let rawUpload: unknown;\n try {\n rawUpload = await uploader.upload(image, ctx.config.operation);\n } catch (error) {\n const receipt = receiptFromUploadError(error, renderer.id, image.filename);\n ctx.receipts.add(receipt);\n rethrowNonDegradationError(error, ctx);\n const metadata = uploadFailureMetadata(error, renderer.id);\n return {\n ok: false,\n failure: createFailure(ctx, nodeType, \"image.bytes\", \"Image upload failed\", {\n ...metadata,\n }),\n };\n }\n const upload = inspectUploadResult(rawUpload, renderer.id, image.filename);\n ctx.receipts.add(upload.receipt);\n throwIfOperationEnded(ctx.config.operation, \"upload\");\n if (!upload.valid) {\n return {\n ok: false,\n failure: createFailure(ctx, nodeType, \"image.bytes\", \"Uploader returned an invalid result\", {\n code: \"invalid_upload_result\",\n stage: \"validation\",\n retryable: false,\n rendererId: renderer.id,\n }),\n };\n }\n return { ok: true, fileId: upload.fileId };\n}\n\nfunction uploadFailureMetadata(\n error: unknown,\n rendererId: string,\n): {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId: string;\n} {\n if (isSlackUploadError(error)) {\n return {\n code: error.code ?? \"slack_upload_failed\",\n stage: error.stage,\n retryable: error.retryable,\n rendererId,\n };\n }\n if (typeof error === \"object\" && error !== null) {\n try {\n const code = Reflect.get(error, \"code\");\n const stage = Reflect.get(error, \"stage\");\n const retryable = Reflect.get(error, \"retryable\");\n if (\n isSafeMetadataToken(code) &&\n isSafeMetadataToken(stage) &&\n typeof retryable === \"boolean\"\n ) {\n return { code, stage, retryable, rendererId };\n }\n } catch {\n // Unknown errors use conservative upload metadata below.\n }\n }\n return {\n code: \"upload_failed\",\n stage: \"upload\",\n retryable: true,\n rendererId,\n };\n}\n\nfunction inspectRenderResult(\n value: unknown,\n declaredOutput: ImageRenderer[\"output\"],\n): RenderInspection {\n if (value === null) {\n return { kind: \"decline\" };\n }\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return invalidRenderResult(\"Renderer returned a non-object result\");\n }\n try {\n const kind = Reflect.get(value, \"kind\");\n if (kind !== \"url\" && kind !== \"bytes\") {\n return invalidRenderResult(\"Renderer returned an unknown image kind\");\n }\n if (\n (declaredOutput === \"url\" && kind !== \"url\") ||\n (declaredOutput === \"bytes\" && kind !== \"bytes\")\n ) {\n return {\n kind: \"invalid\",\n reason: \"Renderer result does not match its declared output\",\n code: \"renderer_output_mismatch\",\n };\n }\n const altText = Reflect.get(value, \"altText\");\n if (altText !== undefined && typeof altText !== \"string\") {\n return invalidRenderResult(\"Renderer altText override must be a string\");\n }\n if (kind === \"url\") {\n const imageUrl = Reflect.get(value, \"imageUrl\");\n return typeof imageUrl === \"string\"\n ? { kind: \"valid\", result: { kind, imageUrl, altText } }\n : invalidRenderResult(\"Renderer URL result is missing imageUrl\");\n }\n const data = Reflect.get(value, \"data\");\n const mimeType = Reflect.get(value, \"mimeType\");\n const filename = Reflect.get(value, \"filename\");\n if (\n !(data instanceof Uint8Array) ||\n (mimeType !== \"image/png\" && mimeType !== \"image/jpeg\" && mimeType !== \"image/gif\") ||\n typeof filename !== \"string\"\n ) {\n return invalidRenderResult(\"Renderer byte result is malformed\");\n }\n const byteError = validateBytes(data, mimeType, filename);\n if (byteError !== undefined) {\n return invalidRenderResult(byteError);\n }\n return {\n kind: \"valid\",\n result: {\n kind,\n image: { kind, data, mimeType, filename },\n altText,\n },\n };\n } catch {\n return invalidRenderResult(\"Renderer result properties could not be read\");\n }\n}\n\nfunction invalidRenderResult(reason: string): RenderInspection {\n return { kind: \"invalid\", reason, code: \"invalid_renderer_output\" };\n}\n\nfunction observeThenableRejection(value: unknown): void {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return;\n }\n try {\n const then = Reflect.get(value, \"then\");\n if (typeof then === \"function\") {\n void Promise.resolve(value).catch(() => undefined);\n }\n } catch {\n // Reading a hostile thenable is itself the invalid capability result.\n }\n}\n\nfunction validateRendererUrl(imageUrl: string): string | undefined {\n if (imageUrl !== imageUrl.trim() || hasControlCharacter(imageUrl)) {\n return \"Renderer URL must not contain surrounding or control whitespace\";\n }\n if (imageUrl.length === 0 || imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return \"Renderer URL is empty or exceeds Slack's 3000-character limit\";\n }\n try {\n const url = new URL(imageUrl);\n if (url.protocol !== \"https:\") {\n return \"Renderer URL must use HTTPS\";\n }\n if (url.username.length > 0 || url.password.length > 0) {\n return \"Renderer URL must not contain credentials\";\n }\n return undefined;\n } catch {\n return \"Renderer URL must be absolute\";\n }\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const code = character.codePointAt(0) ?? 0;\n if (code <= 31 || code === 127) {\n return true;\n }\n }\n return false;\n}\n\nfunction validateBytes(\n data: Uint8Array,\n mimeType: BytesImage[\"mimeType\"],\n filename: string,\n): string | undefined {\n if (data.byteLength === 0 || data.byteLength > RENDERED_IMAGE_MAX_BYTES) {\n return \"Renderer bytes must be nonempty and at most 10 MiB\";\n }\n if (\n filename.length === 0 ||\n filename.length > RENDERED_IMAGE_FILENAME_MAX_CHARS ||\n filename !== filename.trim() ||\n !SAFE_FILENAME_RE.test(filename) ||\n filename.includes(\"..\")\n ) {\n return \"Renderer filename is unsafe\";\n }\n switch (mimeType) {\n case \"image/png\":\n return hasSignature(data, PNG_SIGNATURE) ? undefined : \"PNG signature does not match MIME\";\n case \"image/jpeg\":\n return data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff\n ? undefined\n : \"JPEG signature does not match MIME\";\n case \"image/gif\":\n return hasSignature(data, GIF87A_SIGNATURE) || hasSignature(data, GIF89A_SIGNATURE)\n ? undefined\n : \"GIF signature does not match MIME\";\n }\n return \"Renderer MIME type is unsupported\";\n}\n\nfunction hasSignature(data: Uint8Array, signature: ReadonlyArray<number>): boolean {\n if (data.byteLength < signature.length) {\n return false;\n }\n return signature.every((byte, index) => data[index] === byte);\n}\n\nfunction inspectUploadResult(\n value: unknown,\n rendererId: string,\n filename: string,\n):\n | {\n readonly valid: true;\n readonly fileId: string;\n readonly receipt: UploadReceipt;\n }\n | { readonly valid: false; readonly receipt: UploadReceipt } {\n try {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return { valid: false, receipt: unknownReceipt(rendererId, filename) };\n }\n const rawFileId = Reflect.get(value, \"fileId\");\n const rawReceipt = Reflect.get(value, \"receipt\");\n const fileId = normalizeFileId(rawFileId);\n const receipt = normalizeReceipt(rawReceipt, rendererId, filename);\n if (fileId === undefined || receipt === undefined) {\n return {\n valid: false,\n receipt: receipt ?? unknownReceipt(rendererId, filename),\n };\n }\n if (receipt.fileId !== undefined && receipt.fileId !== fileId) {\n return {\n valid: false,\n receipt: Object.freeze({\n ...receipt,\n providerCode: \"receipt_file_id_mismatch\",\n retrySafety: RetrySafety.MayDuplicate,\n }),\n };\n }\n return {\n valid: true,\n fileId,\n receipt: receipt.fileId === undefined ? Object.freeze({ ...receipt, fileId }) : receipt,\n };\n } catch {\n return { valid: false, receipt: unknownReceipt(rendererId, filename) };\n }\n}\n\nfunction normalizeFileId(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const normalized = value.trim();\n return normalized.length <= SLACK_FILE_ID_MAX_CHARS && SLACK_FILE_ID_RE.test(normalized)\n ? normalized\n : undefined;\n}\n\nfunction normalizeReceipt(\n value: unknown,\n rendererId: string,\n filename: string,\n): UploadReceipt | undefined {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return undefined;\n }\n try {\n const kind = Reflect.get(value, \"kind\");\n const provider = Reflect.get(value, \"provider\");\n const phase = Reflect.get(value, \"phase\");\n const fileIdValue = Reflect.get(value, \"fileId\");\n const shared = Reflect.get(value, \"shared\");\n const processing = Reflect.get(value, \"processing\");\n const status = Reflect.get(value, \"status\");\n const retryAfterMs = Reflect.get(value, \"retryAfterMs\");\n const providerCode = Reflect.get(value, \"providerCode\");\n const retrySafety = Reflect.get(value, \"retrySafety\");\n const fileId = fileIdValue === undefined ? undefined : normalizeFileId(fileIdValue);\n if (\n kind !== \"upload\" ||\n !isSafeMetadataToken(provider) ||\n !isUploadPhase(phase) ||\n (fileIdValue !== undefined && fileId === undefined) ||\n typeof shared !== \"boolean\" ||\n !isUploadProcessing(processing) ||\n (status !== undefined && (!Number.isInteger(status) || status < 0)) ||\n (retryAfterMs !== undefined && (!Number.isFinite(retryAfterMs) || retryAfterMs < 0)) ||\n (providerCode !== undefined && !isSafeMetadataToken(providerCode)) ||\n !isRetrySafety(retrySafety)\n ) {\n return undefined;\n }\n return Object.freeze({\n kind,\n provider,\n rendererId,\n filename,\n phase,\n fileId,\n shared,\n processing,\n status,\n retryAfterMs,\n providerCode,\n retrySafety,\n });\n } catch {\n return undefined;\n }\n}\n\nfunction receiptFromUploadError(\n error: unknown,\n rendererId: string,\n filename: string,\n): UploadReceipt {\n if (isSlackUploadError(error)) {\n return (\n normalizeReceipt(error.receipt, rendererId, filename) ?? unknownReceipt(rendererId, filename)\n );\n }\n try {\n const receipts = Reflect.get(error as object, \"receipts\");\n if (Array.isArray(receipts)) {\n for (const receipt of receipts) {\n const normalized = normalizeReceipt(receipt, rendererId, filename);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n }\n } catch {\n // Unknown uploader errors receive a conservative receipt below.\n }\n return unknownReceipt(rendererId, filename);\n}\n\nfunction unknownReceipt(rendererId: string, filename: string): UploadReceipt {\n return Object.freeze({\n kind: \"upload\",\n provider: \"unknown\",\n rendererId,\n filename,\n phase: UploadPhase.Unknown,\n fileId: undefined,\n shared: false,\n processing: UploadProcessing.Unverified,\n status: undefined,\n retryAfterMs: undefined,\n providerCode: undefined,\n retrySafety: RetrySafety.MayDuplicate,\n });\n}\n\nfunction createFailure(\n ctx: ConversionContext,\n nodeType: string,\n from: string,\n reason: string,\n metadata: {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId: string;\n },\n): Degradation {\n return {\n nodeType,\n from,\n to: \"skip\",\n reason,\n path: ctx.path,\n details: metadata,\n };\n}\n\nfunction rethrowNonDegradationError(error: unknown, ctx: ConversionContext): void {\n if (isConfigurationError(error)) {\n throw attachReceipts(\n cloneConfigurationError(error),\n ctx.receipts.all(),\n ctx.receipts.settled(),\n );\n }\n if (isOperationError(error)) {\n throw attachReceipts(\n cloneOperationError(error, \"renderer\"),\n ctx.receipts.all(),\n ctx.receipts.settled(),\n );\n }\n}\n\nfunction rendererFailureMetadata(\n error: unknown,\n fallbackRendererId: string,\n fallback: Omit<StructuredRendererError, \"rendererId\">,\n): {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId: string;\n} {\n if (isStructuredRendererError(error)) {\n return {\n code: error.code,\n stage: error.stage,\n retryable: error.retryable,\n rendererId: error.rendererId ?? fallbackRendererId,\n };\n }\n return { ...fallback, rendererId: fallbackRendererId };\n}\n\nfunction isStructuredRendererError(error: unknown): error is StructuredRendererError {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n try {\n const code = Reflect.get(error, \"code\");\n const stage = Reflect.get(error, \"stage\");\n const retryable = Reflect.get(error, \"retryable\");\n const rendererId = Reflect.get(error, \"rendererId\");\n return (\n isSafeMetadataToken(code) &&\n isSafeMetadataToken(stage) &&\n typeof retryable === \"boolean\" &&\n (rendererId === undefined || isSafeMetadataToken(rendererId))\n );\n } catch {\n return false;\n }\n}\n\nfunction isSafeMetadataToken(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n value.length <= 64 &&\n SAFE_METADATA_RE.test(value)\n );\n}\n\nfunction isUploadPhase(value: unknown): value is UploadReceipt[\"phase\"] {\n return (\n value === UploadPhase.Requested ||\n value === UploadPhase.Allocated ||\n value === UploadPhase.Uploaded ||\n value === UploadPhase.Completed ||\n value === UploadPhase.Shared ||\n value === UploadPhase.Unknown\n );\n}\n\nfunction isUploadProcessing(value: unknown): value is UploadReceipt[\"processing\"] {\n return (\n value === UploadProcessing.NotRequested ||\n value === UploadProcessing.Pending ||\n value === UploadProcessing.Verified ||\n value === UploadProcessing.Unverified\n );\n}\n\nfunction isRetrySafety(value: unknown): value is UploadReceipt[\"retrySafety\"] {\n return (\n value === RetrySafety.Never || value === RetrySafety.Safe || value === RetrySafety.MayDuplicate\n );\n}\n","import type { Code, RootContent } from \"mdast\";\n\nimport type { Block, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport { preformattedRichText } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { tryRenderImage } from \"./try-render-image.js\";\n\n/**\n * Code fences → configured image renderer / rich_text_preformatted.\n * Mermaid/math dialects are handled by more specific adapters that match first.\n */\nexport class CodeFenceAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"code\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const code = node as Code;\n const hasLang = code.lang !== null && code.lang !== undefined && code.lang.length > 0;\n const language = hasLang ? (code.lang ?? \"\").trim().toLowerCase() : \"\";\n return [\n {\n budget: { blocks: 1 },\n emit: async (ctx: ConversionContext): Promise<ReadonlyArray<Block>> => {\n const rendered = await tryRenderImage(\n {\n lang: language,\n source: code.value,\n altText: `${language.length > 0 ? language : \"code\"} diagram`,\n },\n \"code\",\n ctx,\n );\n return rendered === undefined ? [] : [rendered];\n },\n },\n {\n requires: [\"preformattedLanguage\"],\n budget: { blocks: 1 },\n emit: (): ReadonlyArray<Block> => [preformatted(code, true)],\n },\n {\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n if (hasLang) {\n emitCtx.degradations.add({\n nodeType: \"code\",\n from: \"preformatted.language\",\n to: \"preformatted\",\n reason: \"preformattedLanguage capability unavailable; omitting language\",\n path: emitCtx.path,\n });\n }\n return [preformatted(code, false)];\n },\n },\n ];\n }\n}\n\nfunction preformatted(code: Code, withLang: boolean): RichTextBlock {\n const language =\n withLang && code.lang !== null && code.lang !== undefined && code.lang.length > 0\n ? code.lang.toLowerCase()\n : undefined;\n return preformattedRichText(code.value, language);\n}\n","import type { Heading, RootContent } from \"mdast\";\n\nimport type { Block, HeaderBlock, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { HEADER_LEVEL_MAX, HEADER_TEXT_MAX_CHARS } from \"../constants.js\";\n\nimport {\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n phrasingNeedsMentionResolution,\n phrasingToPlain,\n} from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Headings 1–4 → header (+level); 5–6 / overflow → bold rich_text.\n */\nexport class HeadingAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"heading\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const heading = node as Heading;\n const hoistCount = countHoistableImages(heading.children, ctx);\n const needsRich = headingNeedsRichText(heading, ctx);\n\n if (!needsRich) {\n return [\n {\n requires: [\"headerLevel\"],\n budget: { blocks: 1 },\n emit: (): ReadonlyArray<Block> => {\n return emitPlainHeader(heading, true);\n },\n },\n {\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"heading\",\n from: \"header.level\",\n to: \"header\",\n reason: \"headerLevel capability unavailable; omitting level\",\n path: emitCtx.path,\n });\n return emitPlainHeader(heading, false);\n },\n },\n ];\n }\n\n const richCandidates: Candidate[] = [\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n return emitRichHeading(heading, emitCtx, true);\n },\n },\n ];\n if (hoistCount > 0) {\n richCandidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"heading\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted heading images; emitting text only\",\n path: emitCtx.path,\n });\n return emitRichHeading(heading, emitCtx, false);\n },\n });\n }\n return richCandidates;\n }\n}\n\nfunction headingNeedsRichText(heading: Heading, ctx: ConversionContext): boolean {\n if (heading.depth > HEADER_LEVEL_MAX) {\n return true;\n }\n const plain = phrasingToPlain(heading.children);\n if (plain.length > HEADER_TEXT_MAX_CHARS) {\n return true;\n }\n if (phrasingNeedsMentionResolution(heading.children, ctx)) {\n return true;\n }\n return heading.children.some(\n (c) =>\n c.type === \"link\" ||\n c.type === \"inlineCode\" ||\n c.type === \"strong\" ||\n c.type === \"emphasis\" ||\n c.type === \"delete\" ||\n c.type === \"image\" ||\n c.type === \"imageReference\" ||\n c.type === \"html\",\n );\n}\n\nfunction emitPlainHeader(heading: Heading, withLevel: boolean): ReadonlyArray<Block> {\n const plain = phrasingToPlain(heading.children);\n const block: HeaderBlock = {\n type: \"header\",\n text: { type: \"plain_text\", text: plain.length > 0 ? plain : \" \" },\n level: withLevel ? headerLevelOf(heading.depth) : undefined,\n };\n return [block];\n}\n\n/**\n * Narrows mdast depth (1–6) to Slack's header domain (1–4, `HEADER_LEVEL_MAX`).\n * Only reachable for depth ≤ 4: deeper headings take the rich_text path.\n */\nfunction headerLevelOf(depth: Heading[\"depth\"]): HeaderBlock[\"level\"] {\n return depth === 1 || depth === 2 || depth === 3 || depth === 4 ? depth : undefined;\n}\n\nfunction emitRichHeading(\n heading: Heading,\n ctx: ConversionContext,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n const plain = phrasingToPlain(heading.children);\n const depth = heading.depth;\n if (depth > HEADER_LEVEL_MAX) {\n ctx.degradations.add({\n nodeType: \"heading\",\n from: `header.h${String(depth)}`,\n to: \"rich_text.bold\",\n reason: `Heading level ${String(depth)} exceeds max ${String(HEADER_LEVEL_MAX)}`,\n path: ctx.path,\n });\n } else if (plain.length > HEADER_TEXT_MAX_CHARS) {\n ctx.degradations.add({\n nodeType: \"heading\",\n from: \"header\",\n to: \"rich_text.bold\",\n reason: \"Heading exceeds 150 plain chars\",\n path: ctx.path,\n });\n } else {\n ctx.degradations.add({\n nodeType: \"heading\",\n from: \"header\",\n to: \"rich_text.bold\",\n reason:\n \"Heading contains inline content unsupported by header (styles, links, images, or mentions)\",\n path: ctx.path,\n });\n }\n\n const inline = emitPhrasing(heading.children, ctx, { bold: true });\n const rich: RichTextBlock = {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements:\n inline.elements.length > 0\n ? inline.elements\n : [{ type: \"text\", text: \" \", style: { bold: true } }],\n },\n ],\n };\n const blocks: Block[] = [rich];\n if (!hoistImages) {\n return blocks;\n }\n for (const h of inline.hoistedImages) {\n blocks.push(hoistedImageBlock(h, ctx));\n }\n return blocks;\n}\n","import type { Html, RootContent } from \"mdast\";\n\nimport type { Block, ContainerBlock, SectionBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { CONTAINER_CHILDREN_MAX, CONTAINER_TITLE_MAX_CHARS } from \"../constants.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\n\nimport { clampSectionText, slackEntityRichTextInlines } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\nconst DETAILS_RE =\n /<details\\b[^>]{0,200}>\\s*<summary\\b[^>]{0,200}>([\\s\\S]{0,500}?)<\\/summary>([\\s\\S]{0,8000}?)<\\/details>/i;\n\n/**\n * Block HTML — details/summary → container; else strip+warn.\n */\nexport class HtmlBlockAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"html\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const html = node as Html;\n // details/summary must win over the Slack-entity path: a collapsible block\n // that also mentions <@U…> should stay a container, not flatten to rich_text.\n const details = DETAILS_RE.exec(html.value);\n if (details !== null) {\n const title = stripTags(details[1] ?? \"Details\").trim();\n const body = stripTags(details[2] ?? \"\").trim();\n return [\n {\n requires: [\"containerBlock\"],\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n const child: SectionBlock = {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: clampSectionText(body.length > 0 ? body : \" \", ctx, \"html.details.body\"),\n },\n };\n const block: ContainerBlock = {\n type: \"container\",\n title: {\n type: \"plain_text\",\n text: clampContainerTitle(title.length > 0 ? title : \"Details\", ctx),\n },\n child_blocks: [child].slice(0, CONTAINER_CHILDREN_MAX),\n is_collapsible: true,\n };\n return [block];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"html.details\",\n from: \"container\",\n to: \"section\",\n reason: \"containerBlock unavailable\",\n path: ctx.path,\n });\n return [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: clampSectionText(`*${title}*\\n${body}`, ctx, \"html.details.section\"),\n },\n },\n ];\n },\n },\n ];\n }\n\n // A line like \"<!here> deploying now\" parses as one block html node; Slack\n // entity tokens must survive as rich text elements, not be stripped as tags.\n const entityInlines = slackEntityRichTextInlines(html.value.trim(), {});\n if (entityInlines !== undefined) {\n return [\n {\n budget: { blocks: 1 },\n emit: (): ReadonlyArray<Block> => [\n {\n type: \"rich_text\",\n elements: [{ type: \"rich_text_section\", elements: entityInlines }],\n },\n ],\n },\n ];\n }\n\n return [\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"html\",\n from: \"html\",\n to: \"section\",\n reason: \"Unsupported block HTML stripped to text\",\n path: ctx.path,\n });\n const text = stripTags(html.value).trim();\n if (text.length === 0) {\n return [];\n }\n return [\n {\n type: \"section\",\n text: { type: \"mrkdwn\", text: clampSectionText(text, ctx, \"html.section\") },\n },\n ];\n },\n },\n ];\n }\n}\n\nfunction stripTags(html: string): string {\n return html.replace(/<[^>]{0,200}>/g, \"\");\n}\n\nfunction clampContainerTitle(text: string, ctx: ConversionContext): string {\n if (text.length <= CONTAINER_TITLE_MAX_CHARS) {\n return text;\n }\n ctx.degradations.add({\n nodeType: \"html.details\",\n from: \"container.title\",\n to: \"truncated\",\n reason: `Container title truncated to ${String(CONTAINER_TITLE_MAX_CHARS)} chars`,\n path: ctx.path,\n });\n return sliceSurrogateSafe(text, CONTAINER_TITLE_MAX_CHARS);\n}\n","import type { List, ListItem, PhrasingContent, RootContent } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type { Block, RichTextBlock, RichTextList, RichTextSection } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RICH_TEXT_LIST_INDENT_MAX } from \"../constants.js\";\n\nimport {\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n type HoistedImage,\n} from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Non-task lists → rich_text_list with sibling-indent nesting.\n */\nexport class ListAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n if (node.type !== \"list\") {\n return false;\n }\n return !isTaskList(node);\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const list = node as List;\n const hoistCount = countHoistableImagesInList(list, ctx);\n const candidates: Candidate[] = [\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n return emitListBlocks(list, emitCtx, true);\n },\n },\n ];\n if (hoistCount > 0) {\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"list\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted list images; emitting text only\",\n path: emitCtx.path,\n });\n return emitListBlocks(list, emitCtx, false);\n },\n });\n }\n return candidates;\n }\n}\n\nfunction emitListBlocks(\n list: List,\n emitCtx: ConversionContext,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n const { elements, hoistedImages } = emitListTree(list, 0, emitCtx);\n const block: RichTextBlock = { type: \"rich_text\", elements };\n const blocks: Block[] = [block];\n if (!hoistImages) {\n return blocks;\n }\n for (const h of hoistedImages) {\n blocks.push(hoistedImageBlock(h, emitCtx));\n }\n return blocks;\n}\n\nexport function isTaskList(list: List): boolean {\n return list.children.some((item) => item.checked === true || item.checked === false);\n}\n\nfunction countHoistableImagesInList(list: List, ctx: ConversionContext): number {\n let count = 0;\n for (const item of list.children) {\n count += countHoistableImages(collectListItemPhrasing(item), ctx);\n for (const child of item.children) {\n if (child.type === \"list\") {\n count += countHoistableImagesInList(child, ctx);\n }\n }\n }\n return count;\n}\n\nfunction emitListTree(\n list: List,\n indent: number,\n ctx: ConversionContext,\n): { elements: Array<RichTextList>; hoistedImages: HoistedImage[] } {\n let effectiveIndent = indent;\n if (effectiveIndent > RICH_TEXT_LIST_INDENT_MAX) {\n ctx.degradations.add({\n nodeType: \"list\",\n from: `indent:${String(effectiveIndent)}`,\n to: `indent:${String(RICH_TEXT_LIST_INDENT_MAX)}`,\n reason: \"List indent clamped at 6\",\n path: ctx.path,\n });\n effectiveIndent = RICH_TEXT_LIST_INDENT_MAX;\n }\n\n const ordered = list.ordered === true;\n const startOffset =\n ordered && list.start !== null && list.start !== undefined && list.start > 1\n ? list.start - 1\n : 0;\n\n // Slack nests a higher-indent rich_text_list under the *last* item of the\n // preceding same-indent chunk (see Block Kit rich_text examples). Keep\n // nest-free siblings in the buffer and flush only when an item has children\n // so that item is last in its chunk; ordered continuation chunks carry an\n // offset so numbering resumes where it left off.\n const out: RichTextList[] = [];\n const hoistedImages: HoistedImage[] = [];\n let pendingSections: RichTextSection[] = [];\n\n const flush = (lastIndex: number): void => {\n if (pendingSections.length === 0) {\n return;\n }\n const chunkStartIndex = lastIndex - pendingSections.length + 1;\n const offset = startOffset + chunkStartIndex;\n out.push({\n type: \"rich_text_list\",\n style: ordered ? \"ordered\" : \"bullet\",\n elements: pendingSections,\n indent: effectiveIndent,\n offset: ordered && offset > 0 ? offset : undefined,\n });\n pendingSections = [];\n };\n\n for (const [index, item] of list.children.entries()) {\n const { section, childLists, hoistedImages: itemImages } = emitListItem(item, ctx);\n pendingSections.push(section);\n hoistedImages.push(...itemImages);\n if (childLists.length === 0) {\n continue;\n }\n flush(index);\n for (const child of childLists) {\n const nestedResult = emitListTree(child, effectiveIndent + 1, ctx);\n out.push(...nestedResult.elements);\n hoistedImages.push(...nestedResult.hoistedImages);\n }\n }\n flush(list.children.length - 1);\n\n if (out.length === 0) {\n out.push({\n type: \"rich_text_list\",\n style: ordered ? \"ordered\" : \"bullet\",\n elements: [{ type: \"rich_text_section\", elements: [{ type: \"text\", text: \" \" }] }],\n indent: effectiveIndent,\n offset: undefined,\n });\n }\n\n return { elements: out, hoistedImages };\n}\n\n/** Phrasing content of a list item for hoist counting — no degradations emitted. */\nfunction collectListItemPhrasing(item: ListItem): PhrasingContent[] {\n const phrasing: PhrasingContent[] = [];\n let sawBlock = false;\n\n for (const child of item.children) {\n if (child.type === \"paragraph\") {\n if (sawBlock) {\n phrasing.push({ type: \"text\", value: \"\\n\" });\n }\n phrasing.push(...child.children);\n sawBlock = true;\n } else if (child.type !== \"list\") {\n sawBlock = true;\n }\n }\n return phrasing;\n}\n\nfunction emitListItem(\n item: ListItem,\n ctx: ConversionContext,\n): { section: RichTextSection; childLists: List[]; hoistedImages: HoistedImage[] } {\n const phrasing: PhrasingContent[] = [];\n const childLists: List[] = [];\n let sawBlock = false;\n\n for (const child of item.children) {\n if (child.type === \"paragraph\") {\n if (sawBlock) {\n phrasing.push({ type: \"text\", value: \"\\n\" });\n }\n phrasing.push(...child.children);\n sawBlock = true;\n } else if (child.type === \"list\") {\n childLists.push(child);\n } else {\n ctx.degradations.add({\n nodeType: \"listItem\",\n from: child.type,\n to: \"text\",\n reason: \"Block child of list item flattened into text\",\n path: ctx.path,\n });\n const text = toString(child);\n if (text.length > 0) {\n phrasing.push({ type: \"text\", value: text });\n }\n sawBlock = true;\n }\n }\n\n const inline = emitPhrasing(phrasing, ctx);\n return {\n section: {\n type: \"rich_text_section\",\n elements: inline.elements.length > 0 ? inline.elements : [{ type: \"text\", text: \" \" }],\n },\n childLists,\n hoistedImages: [...inline.hoistedImages],\n };\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { Block, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport { preformattedRichText } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { tryRenderImage } from \"./try-render-image.js\";\n\n/**\n * Display math → configured image renderer / preformatted TeX.\n */\nexport class MathBlockAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"math\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const value = \"value\" in node && typeof node.value === \"string\" ? node.value : \"\";\n return [\n {\n budget: { blocks: 1 },\n emit: async (ctx: ConversionContext): Promise<ReadonlyArray<Block>> => {\n const rendered = await tryRenderImage(\n {\n lang: \"math\",\n source: value,\n altText: \"display math\",\n },\n \"math\",\n ctx,\n );\n return rendered === undefined ? [] : [rendered];\n },\n },\n {\n requires: [\"preformattedLanguage\"],\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n return [preformattedMath(value, true, ctx)];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"math\",\n from: \"preformatted.language\",\n to: \"preformatted\",\n reason: \"preformattedLanguage capability unavailable; omitting language\",\n path: ctx.path,\n });\n return [preformattedMath(value, false, ctx)];\n },\n },\n ];\n }\n}\n\nfunction preformattedMath(value: string, withLang: boolean, ctx: ConversionContext): RichTextBlock {\n ctx.degradations.add({\n nodeType: \"math\",\n from: \"math\",\n to: \"rich_text_preformatted\",\n reason: \"Math is emitted as preformatted/code text\",\n path: ctx.path,\n });\n return preformattedRichText(value, withLang ? \"latex\" : undefined);\n}\n","import type { Code, RootContent } from \"mdast\";\n\nimport type { Block, DataVisualizationBlock, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RecordingDegradationCollector } from \"../budget/recording-degradation-collector.js\";\nimport {\n CHART_LABEL_MAX_CHARS,\n CHART_POINTS_MAX,\n CHART_SEGMENTS_MAX,\n CHART_SERIES_MAX,\n CHART_TITLE_MAX_CHARS,\n} from \"../constants.js\";\nimport type { MermaidChartParser, MermaidPieAst, MermaidXyChartAst } from \"../types.js\";\n\nimport { preformattedRichText, truncateLabel } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { tryRenderImage } from \"./try-render-image.js\";\n\nexport interface MermaidFenceAdapterDeps {\n readonly pieParser: MermaidChartParser;\n readonly xyParser: MermaidChartParser;\n}\n\n/**\n * Mermaid fences → data_visualization / image renderer / preformatted.\n */\nexport class MermaidFenceAdapter implements NodeAdapter {\n private readonly pieParser: MermaidChartParser;\n private readonly xyParser: MermaidChartParser;\n\n constructor(deps: MermaidFenceAdapterDeps) {\n this.pieParser = deps.pieParser;\n this.xyParser = deps.xyParser;\n }\n\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"code\" && (node.lang ?? \"\").toLowerCase() === \"mermaid\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const code = node as Code;\n const source = code.value;\n const kind = detectMermaidKind(source);\n const candidates: Candidate[] = [];\n let rendererAttempted = false;\n\n // Probe native chart viability with a throwaway collector so plan-time\n // parse/limit failures are not recorded unless the native candidate emits.\n const probeCtx = ctx.withDegradations(new RecordingDegradationCollector());\n\n if (kind === \"pie\") {\n const parsed = this.pieParser.parse(source);\n if (parsed.ok && parsed.value.kind === \"pie\") {\n const probe = tryPieBlock(parsed.value, probeCtx);\n if (probe !== undefined) {\n const ast = parsed.value;\n candidates.push({\n requires: [\"dataVisualization\"],\n budget: { blocks: 1, chart: true },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n const block = tryPieBlock(ast, emitCtx);\n return block !== undefined ? [block] : [];\n },\n });\n }\n }\n } else if (kind === \"xychart-beta\") {\n const parsed = this.xyParser.parse(source);\n if (parsed.ok && parsed.value.kind === \"xychart-beta\") {\n const probe = tryXyBlock(parsed.value, probeCtx);\n if (probe !== undefined) {\n const ast = parsed.value;\n candidates.push({\n requires: [\"dataVisualization\"],\n budget: { blocks: 1, chart: true },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n const block = tryXyBlock(ast, emitCtx);\n return block !== undefined ? [block] : [];\n },\n });\n }\n }\n }\n\n candidates.push({\n budget: { blocks: 1 },\n emit: async (emitCtx: ConversionContext): Promise<ReadonlyArray<Block>> => {\n rendererAttempted = true;\n const rendered = await tryRenderImage(\n {\n lang: \"mermaid\",\n source,\n altText: \"mermaid diagram\",\n },\n \"code.mermaid\",\n emitCtx,\n );\n return rendered === undefined ? [] : [rendered];\n },\n });\n\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"code.mermaid\",\n from: kind,\n to: \"rich_text_preformatted\",\n reason: rendererAttempted\n ? \"No native chart / renderer image; emitting mermaid source\"\n : \"Renderer candidate skipped by message budget; emitting mermaid source\",\n path: emitCtx.path,\n });\n return [preformattedMermaid(source, emitCtx)];\n },\n });\n\n return candidates;\n }\n}\n\nfunction detectMermaidKind(source: string): \"pie\" | \"xychart-beta\" | \"other\" {\n const first = source\n .split(/\\r?\\n/)\n .map((l) => l.replace(/%%[^\\n]{0,500}/, \"\").trim())\n .find((l) => l.length > 0);\n if (first === undefined) {\n return \"other\";\n }\n if (/^pie\\b/i.test(first)) {\n return \"pie\";\n }\n if (/^xychart-beta\\b/i.test(first)) {\n return \"xychart-beta\";\n }\n return \"other\";\n}\n\nfunction tryPieBlock(\n ast: MermaidPieAst,\n ctx: ConversionContext,\n): DataVisualizationBlock | undefined {\n if (ast.segments.length > CHART_SEGMENTS_MAX) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.pie\",\n from: \"data_visualization\",\n to: \"fallback\",\n reason: `Pie has ${String(ast.segments.length)} segments (max ${String(CHART_SEGMENTS_MAX)})`,\n path: ctx.path,\n });\n return undefined;\n }\n const segments = ast.segments.map((s) => {\n const t = truncateLabel(s.label, CHART_LABEL_MAX_CHARS);\n if (t.truncated) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.pie\",\n from: s.label,\n to: t.text,\n reason: \"Pie label truncated to 20 chars\",\n path: ctx.path,\n });\n }\n return { label: t.text, value: s.value };\n });\n const titleRaw =\n ast.title ??\n (ctx.precedingHeading !== undefined && ctx.precedingHeading.length > 0\n ? ctx.precedingHeading\n : \"Chart\");\n return {\n type: \"data_visualization\",\n title: truncateChartTitle(titleRaw, ctx, \"code.mermaid.pie\"),\n chart: { type: \"pie\", segments },\n };\n}\n\nfunction tryXyBlock(\n ast: MermaidXyChartAst,\n ctx: ConversionContext,\n): DataVisualizationBlock | undefined {\n const categories = ast.categories.map((c) => {\n const t = truncateLabel(c, CHART_LABEL_MAX_CHARS);\n if (t.truncated) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: c,\n to: t.text,\n reason: \"Category label truncated to 20 chars\",\n path: ctx.path,\n });\n }\n return t.text;\n });\n\n if (categories.length > CHART_POINTS_MAX) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: \"data_visualization\",\n to: \"fallback\",\n reason: `xychart has ${String(categories.length)} points (max ${String(CHART_POINTS_MAX)})`,\n path: ctx.path,\n });\n return undefined;\n }\n\n let chartType: \"bar\" | \"line\" = \"bar\";\n let seriesValues = ast.bars;\n if (ast.bars.length > 0 && ast.lines.length > 0) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: \"mixed bar+line\",\n to: \"bar\",\n reason: \"Slack charts are single-type; preferring bar\",\n path: ctx.path,\n });\n } else if (ast.bars.length === 0) {\n chartType = \"line\";\n seriesValues = ast.lines;\n }\n\n if (seriesValues.length === 0 || seriesValues.length > CHART_SERIES_MAX) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: \"data_visualization\",\n to: \"fallback\",\n reason: `Invalid series count (${String(seriesValues.length)})`,\n path: ctx.path,\n });\n return undefined;\n }\n\n for (const [i, values] of seriesValues.entries()) {\n if (values.length !== categories.length) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: `series[${String(i)}].length=${String(values.length)}`,\n to: `categories.length=${String(categories.length)}`,\n reason: \"xychart series length mismatched categories; padded/truncated by index\",\n path: ctx.path,\n });\n }\n }\n const series = seriesValues.map((values, i) => ({\n name: truncateLabel(`Series ${String(i + 1)}`, CHART_LABEL_MAX_CHARS).text,\n data: categories.map((label, idx) => ({\n label,\n value: values[idx] ?? 0,\n })),\n }));\n\n const titleRaw =\n ast.title ??\n (ctx.precedingHeading !== undefined && ctx.precedingHeading.length > 0\n ? ctx.precedingHeading\n : \"Chart\");\n\n return {\n type: \"data_visualization\",\n title: truncateChartTitle(titleRaw, ctx, \"code.mermaid.xychart\"),\n chart: {\n type: chartType,\n series,\n axis_config: {\n categories,\n x_label:\n ast.xLabel !== undefined\n ? truncateChartTitle(ast.xLabel, ctx, \"code.mermaid.xychart\")\n : undefined,\n y_label:\n ast.yLabel !== undefined\n ? truncateChartTitle(ast.yLabel, ctx, \"code.mermaid.xychart\")\n : undefined,\n },\n },\n };\n}\n\nfunction truncateChartTitle(raw: string, ctx: ConversionContext, nodeType: string): string {\n const t = truncateLabel(raw, CHART_TITLE_MAX_CHARS);\n if (t.truncated) {\n ctx.degradations.add({\n nodeType,\n from: raw,\n to: t.text,\n reason: `Chart title truncated to ${String(CHART_TITLE_MAX_CHARS)} chars`,\n path: ctx.path,\n });\n }\n return t.text;\n}\n\nfunction preformattedMermaid(source: string, ctx: ConversionContext): RichTextBlock {\n const withLang = ctx.config.capabilities.preformattedLanguage;\n if (!withLang) {\n ctx.degradations.add({\n nodeType: \"code.mermaid\",\n from: \"preformatted.language\",\n to: \"preformatted\",\n reason: \"preformattedLanguage capability unavailable; omitting language\",\n path: ctx.path,\n });\n }\n return preformattedRichText(source, withLang ? \"mermaid\" : undefined);\n}\n","import type { Paragraph, RootContent } from \"mdast\";\n\nimport type { Block, ImageBlock, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport {\n clampImageText,\n clampSectionText,\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n isPublicImageUrl,\n isValidLinkUrl,\n} from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Paragraph → rich_text_section (coalesced later by assembler).\n */\nexport class ParagraphAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"paragraph\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const paragraph = node as Paragraph;\n const loneImage =\n paragraph.children.length === 1 && paragraph.children[0]?.type === \"image\"\n ? paragraph.children[0]\n : undefined;\n const hoistCount = loneImage !== undefined ? 0 : countHoistableImages(paragraph.children, ctx);\n\n const candidates: Candidate[] = [\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n return emitParagraph(paragraph, emitCtx, loneImage, true);\n },\n },\n ];\n if (hoistCount > 0) {\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"paragraph\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted paragraph images; emitting text only\",\n path: emitCtx.path,\n });\n return emitParagraph(paragraph, emitCtx, loneImage, false);\n },\n });\n }\n return candidates;\n }\n}\n\nfunction emitParagraph(\n paragraph: Paragraph,\n emitCtx: ConversionContext,\n loneImage: Paragraph[\"children\"][number] | undefined,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n // Lone image paragraph → image block\n if (loneImage !== undefined && loneImage.type === \"image\") {\n const img = loneImage;\n if (isPublicImageUrl(img.url)) {\n const altRaw = img.alt ?? \"image\";\n const alt = clampImageText(altRaw.length > 0 ? altRaw : \"image\", emitCtx, \"alt_text\");\n const block: ImageBlock = {\n type: \"image\",\n image_url: img.url,\n alt_text: alt,\n title:\n img.title !== null && img.title !== undefined && img.title.length > 0\n ? {\n type: \"plain_text\",\n text: clampImageText(img.title, emitCtx, \"title\"),\n }\n : undefined,\n };\n return [block];\n }\n // mrkdwn <url|label> links share the rich text link URL rules; a relative\n // or non-http(s) URL renders as literal \"<…|…>\" garbage, so degrade those\n // to plain text with the URL preserved as a suffix.\n const linkable = isValidLinkUrl(img.url);\n emitCtx.degradations.add({\n nodeType: \"image\",\n from: \"image\",\n to: linkable ? \"section.link\" : \"section.text\",\n reason: \"Non-public or invalid image URL\",\n path: emitCtx.path,\n });\n const alt = img.alt ?? \"\";\n const label = alt.length > 0 ? alt : img.url.length > 0 ? img.url : \"image\";\n const fallbackText = linkable\n ? `<${img.url}|${label}>`\n : img.url.length > 0 && img.url !== label\n ? `${label} (${img.url})`\n : label;\n return [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: clampSectionText(fallbackText, emitCtx, \"section\"),\n },\n },\n ];\n }\n\n const inline = emitPhrasing(paragraph.children, emitCtx);\n const blocks: Block[] = [];\n const rich: RichTextBlock = {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements: inline.elements.length > 0 ? inline.elements : [{ type: \"text\", text: \" \" }],\n },\n ],\n };\n blocks.push(rich);\n if (!hoistImages) {\n return blocks;\n }\n for (const h of inline.hoistedImages) {\n blocks.push(hoistedImageBlock(h, emitCtx));\n }\n return blocks;\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { Block } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Consumes definition / yaml / toml nodes without emitting blocks.\n */\nexport class SkipAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n const t = node.type as string;\n return t === \"definition\" || t === \"yaml\" || t === \"toml\" || t === \"footnoteDefinition\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n return [\n {\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n const t = node.type as string;\n if (t === \"yaml\" || t === \"toml\") {\n ctx.degradations.add({\n nodeType: t,\n from: \"frontmatter\",\n to: \"skip\",\n reason: \"Frontmatter skipped by default\",\n path: ctx.path,\n });\n }\n return [];\n },\n },\n ];\n }\n}\n","import type { AlignType, RootContent, Table, TableCell as MdastTableCell } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type {\n Block,\n DataTableBlock,\n MarkdownBlock,\n RichTextBlock,\n TableBlock,\n TableCell,\n TableColumnSetting,\n} from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RecordingDegradationCollector } from \"../budget/recording-degradation-collector.js\";\nimport {\n DATA_TABLE_MAX_DATA_ROWS,\n TABLE_CELL_WRAP_THRESHOLD,\n TABLE_MAX_COLS,\n TABLE_PREFERRED_MAX_ROWS,\n} from \"../constants.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\n\nimport { emitPhrasing, preformattedRichText } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * GFM tables → table / data_table / markdown / ASCII fallbacks.\n */\nexport class TableAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"table\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const table = normalizeTableRows(node as Table, ctx);\n const rowCount = table.children.length;\n const colCount = table.children[0]?.children.length ?? 0;\n\n if (colCount > TABLE_MAX_COLS) {\n const cellChars = countEmittedCellChars(table, ctx, \"table\");\n return markdownThenAscii(table, cellChars, \"Table exceeds 20 columns\");\n }\n\n if (rowCount <= TABLE_PREFERRED_MAX_ROWS) {\n // Match validateBlocks measurement (JSON size for rich_text cells).\n const cellChars = countEmittedCellChars(table, ctx, \"table\");\n return [\n {\n requires: [\"tableBlock\"],\n budget: { blocks: 1, tableChars: cellChars },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n return [buildTableBlock(table, ctx)];\n },\n },\n ...markdownThenAscii(table, cellChars, \"tableBlock unavailable or char budget\"),\n ];\n }\n\n // >50 rows → data_table (≤200 data rows)\n const dataRows = Math.max(0, rowCount - 1);\n if (dataRows <= DATA_TABLE_MAX_DATA_ROWS) {\n const preferredTable = truncateRows(table, TABLE_PREFERRED_MAX_ROWS);\n const preferredChars = countEmittedCellChars(preferredTable, ctx, \"table\");\n // data_table headers stay raw_text — count with that mode so budget matches emit.\n const dataTableChars = countEmittedCellChars(table, ctx, \"data_table\");\n return [\n {\n requires: [\"dataTable\"],\n budget: { blocks: 1, dataTableChars },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"table\",\n from: \"table\",\n to: \"data_table\",\n reason: `Table has ${String(rowCount)} rows (>${String(TABLE_PREFERRED_MAX_ROWS)}); using data_table`,\n path: emitCtx.path,\n });\n return [buildDataTable(table, emitCtx)];\n },\n },\n {\n requires: [\"tableBlock\"],\n budget: { blocks: 1, tableChars: preferredChars },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"table\",\n from: \"data_table\",\n to: \"table\",\n reason: \"dataTable unavailable; truncating to table block capacity\",\n path: emitCtx.path,\n });\n return [buildTableBlock(preferredTable, emitCtx)];\n },\n },\n ...markdownThenAscii(table, dataTableChars, \"native table unavailable\"),\n ];\n }\n\n // >200 data rows → split warning + first chunk as data_table / table\n const dataChunk = truncateRows(table, DATA_TABLE_MAX_DATA_ROWS + 1);\n const dataChunkChars = countEmittedCellChars(dataChunk, ctx, \"data_table\");\n return [\n {\n requires: [\"dataTable\"],\n budget: { blocks: 1, dataTableChars: dataChunkChars },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"table\",\n from: \"table\",\n to: \"data_table.split\",\n reason: `Table has ${String(dataRows)} data rows; emitting first ${String(DATA_TABLE_MAX_DATA_ROWS)}`,\n path: emitCtx.path,\n });\n return [buildDataTable(dataChunk, emitCtx)];\n },\n },\n ...markdownThenAscii(table, dataChunkChars, \"oversized table\"),\n ];\n }\n}\n\n/**\n * GFM tables key column count off the header row: shorter rows get empty\n * cells inserted and excess cells are ignored\n * (https://github.github.com/gfm/#tables-extension-). remark preserves rows\n * as authored, so without this step ragged rows reach the Slack table block\n * misaligned against `column_settings`.\n */\nfunction normalizeTableRows(table: Table, ctx: ConversionContext): Table {\n const colCount = table.children[0]?.children.length ?? 0;\n if (colCount === 0 || table.children.every((row) => row.children.length === colCount)) {\n return table;\n }\n const children = table.children.map((row, rowIndex) => {\n if (row.children.length === colCount) {\n return row;\n }\n if (row.children.length > colCount) {\n ctx.degradations.add({\n nodeType: \"table\",\n from: `row[${String(rowIndex)}]: ${String(row.children.length)} cells`,\n to: `${String(colCount)} cells`,\n reason: \"Cells beyond the header column count dropped (GFM ignores the excess)\",\n path: ctx.path,\n });\n return { ...row, children: row.children.slice(0, colCount) };\n }\n const padding = Array.from(\n { length: colCount - row.children.length },\n (): MdastTableCell => ({ type: \"tableCell\", children: [] }),\n );\n return { ...row, children: [...row.children, ...padding] };\n });\n return { ...table, children };\n}\n\nfunction markdownThenAscii(table: Table, cellChars: number, reason: string): Candidate[] {\n const md = toPipeMarkdown(table);\n return [\n {\n requires: [\"markdownBlock\"],\n budget: { blocks: 1, markdownChars: md.length },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"table\",\n from: \"native_table\",\n to: \"markdown\",\n reason,\n path: ctx.path,\n });\n const block: MarkdownBlock = { type: \"markdown\", text: md };\n return [block];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"table\",\n from: \"markdown\",\n to: \"ascii_preformatted\",\n reason: `${reason}; markdown unavailable (chars≈${String(cellChars)})`,\n path: ctx.path,\n });\n return [asciiTableBlock(table)];\n },\n },\n ];\n}\n\nfunction buildTableBlock(table: Table, ctx: ConversionContext): TableBlock {\n const rows = table.children.map((row, rowIndex) =>\n row.children.map((cell) => cellToSlack(cell, ctx, rowIndex === 0)),\n );\n return {\n type: \"table\",\n rows,\n column_settings: columnSettings(table),\n };\n}\n\nfunction buildDataTable(table: Table, ctx: ConversionContext): DataTableBlock {\n const captionRaw =\n ctx.precedingHeading !== undefined && ctx.precedingHeading.length > 0\n ? ctx.precedingHeading\n : \"Table\";\n const caption = sliceSurrogateSafe(captionRaw, 150);\n if (captionRaw.length > 150) {\n ctx.degradations.add({\n nodeType: \"table\",\n from: \"data_table.caption\",\n to: \"truncated\",\n reason: \"data_table caption truncated to 150 chars\",\n path: ctx.path,\n });\n }\n const rows = table.children.map((row, rowIndex) =>\n row.children.map((cell) => cellForDataTable(cell, ctx, rowIndex)),\n );\n return {\n type: \"data_table\",\n caption,\n rows,\n page_size: 5,\n row_header_column_index: 0,\n };\n}\n\n/** Slack forbids rich_text in data_table headers; keep emission and budget counting aligned. */\nfunction cellForDataTable(\n cell: MdastTableCell,\n ctx: ConversionContext,\n rowIndex: number,\n): TableCell {\n if (rowIndex === 0) {\n return { type: \"raw_text\", text: toString(cell) };\n }\n return cellToSlack(cell, ctx, false);\n}\n\nfunction cellToSlack(cell: MdastTableCell, ctx: ConversionContext, header: boolean): TableCell {\n // Emit the cell through the shared inline pipeline so Slack entity tokens\n // (<@U…>, <!here>), emoji shortcodes, mention resolvers, and labeled links\n // are converted instead of landing in raw_text as literal source text. A\n // cell that reduces to one unstyled text element stays raw_text/raw_number.\n const inline = emitPhrasing(cell.children, ctx);\n const single = inline.elements.length === 1 ? inline.elements[0] : undefined;\n const isEmpty = inline.elements.length === 0;\n const isSingleUnstyledText = single?.type === \"text\" && single.style === undefined;\n const plainText = isEmpty ? toString(cell) : isSingleUnstyledText ? single.text : undefined;\n if (plainText !== undefined) {\n // Header row titles must stay text — numeric-looking labels like \"2024\" are not values.\n const trimmed = plainText.trim();\n if (!header && /^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n return { type: \"raw_number\", value: Number(trimmed), text: trimmed };\n }\n return { type: \"raw_text\", text: plainText };\n }\n const rich: RichTextBlock = {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements: inline.elements,\n },\n ],\n };\n return rich;\n}\n\nfunction columnSettings(table: Table): ReadonlyArray<TableColumnSetting | null> {\n const align = table.align ?? [];\n const colCount = table.children[0]?.children.length ?? 0;\n const settings: Array<TableColumnSetting | null> = [];\n for (let i = 0; i < colCount; i += 1) {\n const a = align[i] as AlignType | null | undefined;\n const long = table.children.some(\n (row) =>\n toString(row.children[i] ?? { type: \"text\", value: \"\" }).length > TABLE_CELL_WRAP_THRESHOLD,\n );\n const alignVal = a === \"left\" || a === \"center\" || a === \"right\" ? a : undefined;\n if (alignVal === undefined && !long) {\n settings.push(null);\n } else {\n settings.push({\n align: alignVal,\n is_wrapped: long ? true : undefined,\n });\n }\n }\n return settings;\n}\n\nfunction countEmittedCellChars(\n table: Table,\n ctx: ConversionContext,\n mode: \"table\" | \"data_table\",\n): number {\n const probe = ctx.withDegradations(new RecordingDegradationCollector());\n let n = 0;\n for (const [rowIndex, row] of table.children.entries()) {\n for (const cell of row.children) {\n const emitted =\n mode === \"data_table\"\n ? cellForDataTable(cell, probe, rowIndex)\n : cellToSlack(cell, probe, rowIndex === 0);\n n += slackCellCharCount(emitted);\n }\n }\n return n;\n}\n\nfunction slackCellCharCount(cell: TableCell): number {\n if (cell.type === \"raw_text\" || cell.type === \"raw_number\") {\n return cell.text.length;\n }\n return JSON.stringify(cell).length;\n}\n\nfunction truncateRows(table: Table, maxRows: number): Table {\n return {\n ...table,\n children: table.children.slice(0, maxRows),\n };\n}\n\nfunction toPipeMarkdown(table: Table): string {\n const rows = table.children.map((row) =>\n row.children.map((c) => toString(c).replace(/\\|/g, \"\\\\|\")),\n );\n if (rows.length === 0) {\n return \"\";\n }\n const header = rows[0] ?? [];\n const align = table.align ?? [];\n const sep = header.map((_, i) => {\n const a = align[i];\n if (a === \"center\") return \":---:\";\n if (a === \"right\") return \"---:\";\n if (a === \"left\") return \":---\";\n return \"---\";\n });\n const lines = [\n `| ${header.join(\" | \")} |`,\n `| ${sep.join(\" | \")} |`,\n ...rows.slice(1).map((r) => `| ${r.join(\" | \")} |`),\n ];\n return lines.join(\"\\n\");\n}\n\nfunction asciiTableBlock(table: Table): RichTextBlock {\n return preformattedRichText(toPipeMarkdown(table), undefined);\n}\n","import type { List, ListItem, RootContent } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type {\n Block,\n MarkdownBlock,\n RichTextBlock,\n RichTextList,\n RichTextSection,\n} from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RICH_TEXT_LIST_INDENT_MAX } from \"../constants.js\";\n\nimport { isTaskList } from \"./list-adapter.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Task lists → markdown block (checkboxes); fallback unicode in rich_text_list.\n */\nexport class TaskListAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"list\" && isTaskList(node);\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const list = node as List;\n const md = serializeTaskList(list);\n return [\n {\n requires: [\"markdownBlock\"],\n budget: { blocks: 1, markdownChars: md.length },\n emit: (): ReadonlyArray<Block> => {\n const block: MarkdownBlock = { type: \"markdown\", text: md };\n return [block];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"list\",\n from: \"markdown.task_list\",\n to: \"rich_text_list.unicode_checkbox\",\n reason: \"markdownBlock unavailable or budget exhausted\",\n path: ctx.path,\n });\n return [unicodeTaskList(list, ctx)];\n },\n },\n ];\n }\n}\n\nfunction serializeTaskList(list: List, indent = 0): string {\n const pad = \" \".repeat(indent);\n const lines: string[] = [];\n for (const item of list.children) {\n const checked = item.checked === true;\n const box = checked ? \"[x]\" : \"[ ]\";\n const text = itemText(item);\n lines.push(`${pad}- ${box} ${text}`);\n for (const child of item.children) {\n if (child.type === \"list\") {\n lines.push(serializeTaskList(child, indent + 1));\n }\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction itemText(item: ListItem): string {\n const parts: string[] = [];\n for (const child of item.children) {\n if (child.type === \"paragraph\") {\n parts.push(toString(child));\n } else if (child.type !== \"list\") {\n parts.push(toString(child));\n }\n }\n return parts.join(\" \").trim();\n}\n\nfunction unicodeTaskList(list: List, ctx: ConversionContext): RichTextBlock {\n return {\n type: \"rich_text\",\n elements: emitUnicodeTaskTree(list, 0, ctx),\n };\n}\n\nfunction emitUnicodeTaskTree(\n list: List,\n indent: number,\n ctx: ConversionContext,\n): Array<RichTextList> {\n let effectiveIndent = indent;\n if (effectiveIndent > RICH_TEXT_LIST_INDENT_MAX) {\n ctx.degradations.add({\n nodeType: \"list\",\n from: `indent:${String(effectiveIndent)}`,\n to: `indent:${String(RICH_TEXT_LIST_INDENT_MAX)}`,\n reason: \"Task list indent clamped at 6\",\n path: ctx.path,\n });\n effectiveIndent = RICH_TEXT_LIST_INDENT_MAX;\n }\n\n // Same interleaving as the list adapter: nest under the last item of each\n // same-indent chunk (Slack's flat indent model).\n const out: RichTextList[] = [];\n let pendingSections: RichTextSection[] = [];\n\n const flush = (): void => {\n if (pendingSections.length === 0) {\n return;\n }\n out.push({\n type: \"rich_text_list\",\n style: \"bullet\",\n elements: pendingSections,\n indent: effectiveIndent,\n });\n pendingSections = [];\n };\n\n for (const item of list.children) {\n const prefix = item.checked === true ? \"☑ \" : item.checked === false ? \"☐ \" : \"\";\n pendingSections.push({\n type: \"rich_text_section\",\n elements: [{ type: \"text\", text: `${prefix}${itemText(item)}` }],\n });\n const childLists: List[] = [];\n for (const child of item.children) {\n if (child.type === \"list\") {\n childLists.push(child);\n }\n }\n if (childLists.length === 0) {\n continue;\n }\n flush();\n for (const child of childLists) {\n out.push(...emitUnicodeTaskTree(child, effectiveIndent + 1, ctx));\n }\n }\n flush();\n\n if (out.length === 0) {\n out.push({\n type: \"rich_text_list\",\n style: \"bullet\",\n elements: [{ type: \"rich_text_section\", elements: [{ type: \"text\", text: \" \" }] }],\n indent: effectiveIndent,\n });\n }\n\n return out;\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { Block } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * thematicBreak → divider.\n */\nexport class ThematicBreakAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"thematicBreak\";\n }\n\n plan(_node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n return [\n {\n budget: { blocks: 1 },\n emit: (_ctx: ConversionContext): ReadonlyArray<Block> => [{ type: \"divider\" }],\n },\n ];\n }\n}\n","import { BlockquoteAdapter } from \"../adapters/blockquote-adapter.js\";\nimport { CodeFenceAdapter } from \"../adapters/code-fence-adapter.js\";\nimport { HeadingAdapter } from \"../adapters/heading-adapter.js\";\nimport { HtmlBlockAdapter } from \"../adapters/html-block-adapter.js\";\nimport { ListAdapter } from \"../adapters/list-adapter.js\";\nimport { MathBlockAdapter } from \"../adapters/math-block-adapter.js\";\nimport { MermaidFenceAdapter } from \"../adapters/mermaid-fence-adapter.js\";\nimport type { NodeAdapter } from \"../adapters/node-adapter.js\";\nimport { ParagraphAdapter } from \"../adapters/paragraph-adapter.js\";\nimport { SkipAdapter } from \"../adapters/skip-adapter.js\";\nimport { TableAdapter } from \"../adapters/table-adapter.js\";\nimport { TaskListAdapter } from \"../adapters/task-list-adapter.js\";\nimport { ThematicBreakAdapter } from \"../adapters/thematic-break-adapter.js\";\nimport { MessageAssembler } from \"../assemble/message-assembler.js\";\nimport { DeterministicPlainTextRenderer } from \"../assemble/text-fallback.js\";\nimport { MermaidPieParser } from \"../mermaid/mermaid-pie-parser.js\";\nimport { MermaidXyChartParser } from \"../mermaid/mermaid-xychart-parser.js\";\nimport { RemarkMarkdownParser } from \"../parsers/remark-markdown-parser.js\";\nimport { AdapterRegistry } from \"../registry/adapter-registry.js\";\nimport { ConfigurationError, isConfigurationError, isOperationError } from \"../errors.js\";\nimport type {\n ConversionMessagesResult,\n ConversionResult,\n ConvertOptions,\n MarkdownParser,\n ParserOptions,\n PlainTextRenderer,\n} from \"../types.js\";\nimport { OverflowMode } from \"../types.js\";\n\nimport { SlackMarkConverter } from \"./slackmark-converter.js\";\nimport { resolveConfig, resolveRendererDescriptors } from \"./resolve-config.js\";\n\nconst CREATE_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"capabilities\",\n \"capabilityOverrides\",\n \"overflow\",\n \"strategy\",\n \"renderers\",\n \"uploader\",\n \"enableMath\",\n \"enableInlineMath\",\n \"enableFrontmatter\",\n \"mentionResolvers\",\n \"adapters\",\n \"parser\",\n \"plainText\",\n]);\n\n/**\n * Options for the composition root. Extends per-call {@link ConvertOptions}\n * with injectable collaborators and user adapters (prepended).\n */\nexport interface CreateConverterOptions extends Omit<ConvertOptions, \"signal\" | \"timeoutMs\"> {\n readonly adapters?: ReadonlyArray<NodeAdapter>;\n readonly parser?: MarkdownParser;\n readonly plainText?: PlainTextRenderer;\n}\n\n/**\n * Single composition root — wires default implementations.\n */\nexport function createConverter(options: CreateConverterOptions = {}): SlackMarkConverter {\n validateCreateOptions(options);\n try {\n const parser =\n options.parser === undefined\n ? new RemarkMarkdownParser()\n : new GuardedMarkdownParser(options.parser);\n const plainText =\n options.plainText === undefined\n ? new DeterministicPlainTextRenderer()\n : new GuardedPlainTextRenderer(options.plainText);\n const pieParser = new MermaidPieParser();\n const xyParser = new MermaidXyChartParser();\n\n const builtIns: NodeAdapter[] = [\n new MermaidFenceAdapter({ pieParser, xyParser }),\n new MathBlockAdapter(),\n new TaskListAdapter(),\n new ListAdapter(),\n new TableAdapter(),\n new HeadingAdapter(),\n new ParagraphAdapter(),\n new BlockquoteAdapter(),\n new CodeFenceAdapter(),\n new ThematicBreakAdapter(),\n new HtmlBlockAdapter(),\n new SkipAdapter(),\n ];\n\n const adapters = validateAdapters(options.adapters);\n const registry = new AdapterRegistry([...adapters, ...builtIns]);\n const assembler = new MessageAssembler({ plainText });\n\n const configuredDefaults: ConvertOptions = {\n capabilities: options.capabilities,\n capabilityOverrides: options.capabilityOverrides,\n overflow: options.overflow === undefined ? OverflowMode.Degrade : options.overflow,\n strategy: options.strategy,\n renderers: resolveRendererDescriptors(options.renderers),\n uploader: options.uploader,\n enableMath: options.enableMath,\n enableInlineMath: options.enableInlineMath,\n enableFrontmatter: options.enableFrontmatter,\n mentionResolvers: options.mentionResolvers,\n };\n const resolvedDefaults = resolveConfig(configuredDefaults, undefined, {\n signal: undefined,\n deadlineMs: undefined,\n });\n const defaultOptions: ConvertOptions = {\n capabilities: resolvedDefaults.capabilities,\n overflow: resolvedDefaults.overflow,\n strategy: resolvedDefaults.strategy,\n renderers: resolvedDefaults.renderers,\n uploader: resolvedDefaults.uploader,\n enableMath: resolvedDefaults.enableMath,\n enableInlineMath: resolvedDefaults.enableInlineMath,\n enableFrontmatter: resolvedDefaults.enableFrontmatter,\n mentionResolvers: resolvedDefaults.mentionResolvers,\n };\n\n return new SlackMarkConverter({\n parser,\n registry,\n assembler,\n plainText,\n defaultOptions,\n });\n } catch (cause) {\n if (isConfigurationError(cause)) {\n throw cause;\n }\n throw new ConfigurationError(\"Converter options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nclass GuardedMarkdownParser implements MarkdownParser {\n private readonly parser: MarkdownParser;\n\n constructor(parser: MarkdownParser) {\n this.parser = parser;\n assertMethod(parser, \"parse\", \"parser\");\n }\n\n async parse(markdown: string, options: ParserOptions): ReturnType<MarkdownParser[\"parse\"]> {\n try {\n return await this.parser.parse(markdown, options);\n } catch (cause) {\n if (isConfigurationError(cause) || isOperationError(cause)) {\n throw cause;\n }\n throw new ConfigurationError(\"Injected parser failed\", {\n code: \"parser_failed\",\n stage: \"parse\",\n cause,\n });\n }\n }\n}\n\nclass GuardedPlainTextRenderer implements PlainTextRenderer {\n private readonly renderer: PlainTextRenderer;\n\n constructor(renderer: PlainTextRenderer) {\n this.renderer = renderer;\n assertMethod(renderer, \"render\", \"plainText\");\n assertMethod(renderer, \"renderFromBlocks\", \"plainText\");\n }\n\n render(markdown: string): string {\n try {\n const rendered = this.renderer.render(markdown);\n if (typeof rendered !== \"string\") {\n throw new TypeError(\"render must return string\");\n }\n return rendered;\n } catch (cause) {\n throw new ConfigurationError(\"Injected plain-text renderer failed\", {\n code: \"plain_text_failed\",\n stage: \"fallback\",\n cause,\n });\n }\n }\n\n renderFromBlocks(blocks: Parameters<PlainTextRenderer[\"renderFromBlocks\"]>[0]): string {\n try {\n const rendered = this.renderer.renderFromBlocks(blocks);\n if (typeof rendered !== \"string\") {\n throw new TypeError(\"renderFromBlocks must return string\");\n }\n return rendered;\n } catch (cause) {\n throw new ConfigurationError(\"Injected plain-text renderer failed\", {\n code: \"plain_text_failed\",\n stage: \"fallback\",\n cause,\n });\n }\n }\n}\n\nfunction validateAdapters(\n adapters: ReadonlyArray<NodeAdapter> | undefined,\n): ReadonlyArray<NodeAdapter> {\n if (adapters === undefined) {\n return [];\n }\n if (!Array.isArray(adapters)) {\n throw new ConfigurationError(\"adapters must be an array\", {\n code: \"invalid_adapter\",\n stage: \"configuration\",\n });\n }\n for (const adapter of adapters) {\n assertMethod(adapter, \"match\", \"adapter\");\n assertMethod(adapter, \"plan\", \"adapter\");\n }\n return Object.freeze([...adapters]);\n}\n\nfunction assertMethod(collaborator: unknown, method: string, label: string): void {\n try {\n if (\n (typeof collaborator !== \"object\" && typeof collaborator !== \"function\") ||\n collaborator === null ||\n typeof Reflect.get(collaborator, method) !== \"function\"\n ) {\n throw new TypeError(`${method} must be a function`);\n }\n } catch (cause) {\n throw new ConfigurationError(`${label} collaborator is invalid`, {\n code: `invalid_${label}`,\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction validateCreateOptions(options: CreateConverterOptions): void {\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(options);\n keys = Object.keys(options);\n } catch (cause) {\n throw new ConfigurationError(\"Converter options could not be inspected\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ConfigurationError(\"Converter options must be a plain object\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n for (const key of keys) {\n if (!CREATE_OPTION_KEYS.has(key)) {\n throw new ConfigurationError(`Unknown converter option: ${key}`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n }\n}\n\n/**\n * Convenience API — creates a default converter per call.\n */\nexport function convert(markdown: string, options?: ConvertOptions): Promise<ConversionResult> {\n return createConverter().convert(markdown, options);\n}\n\n/**\n * Convenience multi-message API.\n */\nexport function convertToMessages(\n markdown: string,\n options?: ConvertOptions,\n): Promise<ConversionMessagesResult> {\n return createConverter().convertToMessages(markdown, options);\n}\n","import type { Block, RichTextBlock, RichTextElement, TableCell } from \"../blocks/types.js\";\nimport {\n CHART_LABEL_MAX_CHARS,\n CHART_POINTS_MAX,\n CHART_SEGMENTS_MAX,\n CHART_SERIES_MAX,\n CHART_TITLE_MAX_CHARS,\n CONTAINER_CHILDREN_MAX,\n CONTAINER_TITLE_MAX_CHARS,\n CONTEXT_ELEMENTS_MAX,\n DATA_TABLE_CELL_CHARS_MAX,\n DATA_TABLE_MAX_DATA_ROWS,\n DATA_VISUALIZATION_MAX_PER_MESSAGE,\n HEADER_TEXT_MAX_CHARS,\n IMAGE_ALT_MAX_CHARS,\n IMAGE_URL_MAX_CHARS,\n MARKDOWN_CUMULATIVE_MAX_CHARS,\n MAX_BLOCKS_PER_MESSAGE,\n SECTION_TEXT_MAX_CHARS,\n TABLE_CELL_CHARS_MAX,\n TABLE_MAX_COLS,\n TABLE_MAX_ROWS,\n} from \"../constants.js\";\n\nexport interface ValidationIssue {\n readonly path: string;\n readonly message: string;\n}\n\ndeclare const validatedBlocksBrand: unique symbol;\n\n/**\n * Blocks that have passed {@link validateBlocks}.\n */\nexport type ValidatedBlocks = ReadonlyArray<Block> & {\n readonly [validatedBlocksBrand]: true;\n};\n\ninterface CumulativeCounters {\n markdownChars: number;\n tableChars: number;\n dataTableChars: number;\n charts: number;\n}\n\n/**\n * Assert every documented Block Kit limit from the research doc.\n */\nexport function validateBlocks(blocks: ReadonlyArray<Block>): ValidatedBlocks {\n const issues: ValidationIssue[] = [];\n if (blocks.length > MAX_BLOCKS_PER_MESSAGE) {\n issues.push({\n path: \"$\",\n message: `Too many blocks: ${String(blocks.length)} > ${String(MAX_BLOCKS_PER_MESSAGE)}`,\n });\n }\n\n const counters: CumulativeCounters = {\n markdownChars: 0,\n tableChars: 0,\n dataTableChars: 0,\n charts: 0,\n };\n\n blocks.forEach((block, i) => {\n validateBlock(block, `blocks[${String(i)}]`, issues, counters, 0);\n });\n\n if (counters.markdownChars > MARKDOWN_CUMULATIVE_MAX_CHARS) {\n issues.push({\n path: \"$\",\n message: `markdown cumulative ${String(counters.markdownChars)} > 12000`,\n });\n }\n if (counters.tableChars > TABLE_CELL_CHARS_MAX) {\n issues.push({\n path: \"$\",\n message: `table chars ${String(counters.tableChars)} > 10000`,\n });\n }\n if (counters.dataTableChars > DATA_TABLE_CELL_CHARS_MAX) {\n issues.push({\n path: \"$\",\n message: `data_table chars ${String(counters.dataTableChars)} > 20000`,\n });\n }\n if (counters.charts > DATA_VISUALIZATION_MAX_PER_MESSAGE) {\n issues.push({\n path: \"$\",\n message: `charts ${String(counters.charts)} > ${String(DATA_VISUALIZATION_MAX_PER_MESSAGE)}`,\n });\n }\n\n if (issues.length > 0) {\n const detail = issues.map((x) => `${x.path}: ${x.message}`).join(\"; \");\n throw new Error(`validateBlocks failed: ${detail}`);\n }\n\n return blocks as ValidatedBlocks;\n}\n\nfunction validateBlock(\n block: Block,\n path: string,\n issues: ValidationIssue[],\n counters: CumulativeCounters,\n depth: number,\n): void {\n // Containers can nest in hand-crafted payloads; bound recursion so cycles cannot\n // stack-overflow. Message-depth beyond the block budget is already illegal.\n if (depth > MAX_BLOCKS_PER_MESSAGE) {\n issues.push({ path, message: \"container nesting too deep\" });\n return;\n }\n\n switch (block.type) {\n case \"header\":\n if (block.text.text.length > HEADER_TEXT_MAX_CHARS) {\n issues.push({ path, message: \"header text > 150\" });\n }\n if (block.level !== undefined && (block.level < 1 || block.level > 4)) {\n issues.push({ path, message: \"header level out of 1–4\" });\n }\n break;\n case \"section\":\n if (block.text !== undefined && block.text.text.length > SECTION_TEXT_MAX_CHARS) {\n issues.push({ path, message: \"section text > 3000\" });\n }\n break;\n case \"image\":\n if (block.alt_text.length > IMAGE_ALT_MAX_CHARS) {\n issues.push({ path, message: \"image alt > 2000\" });\n }\n if (\n block.image_url !== undefined &&\n !isAbsoluteHttpUrl(block.image_url, IMAGE_URL_MAX_CHARS)\n ) {\n issues.push({ path, message: \"image_url invalid\" });\n }\n if (\"slack_file\" in block) {\n if (\"id\" in block.slack_file && block.slack_file.id.trim().length === 0) {\n issues.push({ path, message: \"slack_file.id empty\" });\n }\n if (\n \"url\" in block.slack_file &&\n !isAbsoluteHttpUrl(block.slack_file.url, IMAGE_URL_MAX_CHARS)\n ) {\n issues.push({ path, message: \"slack_file.url invalid\" });\n }\n }\n break;\n case \"context\":\n // Slack context blocks require 1–CONTEXT_ELEMENTS_MAX elements\n // (https://docs.slack.dev/reference/block-kit/blocks/context-block).\n if (block.elements.length === 0) {\n issues.push({ path, message: \"context elements empty\" });\n } else if (block.elements.length > CONTEXT_ELEMENTS_MAX) {\n issues.push({ path, message: \"context elements > 10\" });\n }\n break;\n case \"markdown\":\n counters.markdownChars += block.text.length;\n break;\n case \"table\":\n if (block.rows.length > TABLE_MAX_ROWS) {\n issues.push({ path, message: \"table rows > 100\" });\n }\n counters.tableChars += validateTableCells(block.rows, path, \"table cols > 20\", issues);\n break;\n case \"data_table\":\n if (block.rows.length > DATA_TABLE_MAX_DATA_ROWS + 1) {\n issues.push({ path, message: \"data_table rows > 201\" });\n }\n counters.dataTableChars += validateTableCells(\n block.rows,\n path,\n \"data_table cols > 20\",\n issues,\n );\n break;\n case \"data_visualization\":\n counters.charts += 1;\n if (block.title.length > CHART_TITLE_MAX_CHARS) {\n issues.push({ path, message: \"chart title > 50\" });\n }\n validateChart(block, path, issues);\n break;\n case \"container\":\n if (block.child_blocks.length > CONTAINER_CHILDREN_MAX) {\n issues.push({ path, message: \"container children > 10\" });\n }\n if (block.title !== undefined && block.title.text.length > CONTAINER_TITLE_MAX_CHARS) {\n issues.push({ path, message: \"container title > 150\" });\n }\n if (block.rich_text_title !== undefined) {\n validateRichTextBlock(block.rich_text_title, `${path}.rich_text_title`, issues);\n }\n // Typed ContainerChildBlock excludes charts/nested containers; hand-crafted\n // payloads can still smuggle them — recurse so counters and per-block checks apply.\n for (const [i, child] of block.child_blocks.entries()) {\n validateBlock(child, `${path}.child_blocks[${String(i)}]`, issues, counters, depth + 1);\n }\n break;\n case \"divider\":\n break;\n case \"rich_text\":\n validateRichTextBlock(block, path, issues);\n break;\n default: {\n const exhaustive: never = block;\n void exhaustive;\n break;\n }\n }\n}\n\nfunction isAbsoluteHttpUrl(value: string, maxChars: number): boolean {\n if (value.length === 0 || value.length > maxChars) {\n return false;\n }\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nfunction validateRichTextBlock(\n block: RichTextBlock,\n path: string,\n issues: ValidationIssue[],\n): void {\n if (block.elements.length === 0) {\n issues.push({ path, message: \"rich_text elements empty\" });\n return;\n }\n for (const [i, element] of block.elements.entries()) {\n validateRichTextElement(element, `${path}.elements[${String(i)}]`, issues);\n }\n}\n\nfunction validateRichTextElement(\n element: RichTextElement,\n path: string,\n issues: ValidationIssue[],\n): void {\n switch (element.type) {\n case \"rich_text_section\":\n case \"rich_text_quote\":\n case \"rich_text_preformatted\":\n if (element.elements.length === 0) {\n issues.push({ path, message: `${element.type} elements empty` });\n return;\n }\n for (const [i, inline] of element.elements.entries()) {\n if (inline.type === \"link\" && !isValidRichTextLinkUrl(inline.url)) {\n issues.push({\n path: `${path}.elements[${String(i)}]`,\n message: \"invalid rich text link URL\",\n });\n }\n }\n break;\n case \"rich_text_list\":\n if (element.elements.length === 0) {\n issues.push({ path, message: \"rich_text_list elements empty\" });\n return;\n }\n for (const [i, section] of element.elements.entries()) {\n validateRichTextElement(section, `${path}.elements[${String(i)}]`, issues);\n }\n break;\n default: {\n const exhaustive: never = element;\n void exhaustive;\n break;\n }\n }\n}\n\n/** Count cell chars and validate any rich_text cells (links / empty elements). */\nfunction validateTableCells(\n rows: ReadonlyArray<ReadonlyArray<TableCell>>,\n path: string,\n colsMessage: string,\n issues: ValidationIssue[],\n): number {\n let chars = 0;\n for (const [r, row] of rows.entries()) {\n if (row.length > TABLE_MAX_COLS) {\n issues.push({ path, message: colsMessage });\n }\n for (const [c, cell] of row.entries()) {\n chars += cellCharCount(cell);\n if (cell.type === \"rich_text\") {\n validateRichTextBlock(cell, `${path}.rows[${String(r)}][${String(c)}]`, issues);\n }\n }\n }\n return chars;\n}\n\n/**\n * Slack rich text `link` elements require absolute http(s)/mailto URLs; relative\n * URLs (`/path`, `#fragment`) or other schemes are rejected with invalid_blocks.\n * https://docs.slack.dev/reference/block-kit/block-elements/rich-text-elements\n *\n * Honest local duplicate of `isValidLinkUrl` in adapters/inline.ts — validate must\n * not import adapters (layering: adapters → … → validate).\n */\nconst HTTP_OR_MAILTO_URL_RE = /^(https?:|mailto:)/i;\n\nfunction isValidRichTextLinkUrl(url: string): boolean {\n if (url.length === 0 || url.length > IMAGE_URL_MAX_CHARS) {\n return false;\n }\n return HTTP_OR_MAILTO_URL_RE.test(url);\n}\n\nfunction cellCharCount(cell: TableCell): number {\n if (cell.type === \"raw_text\") {\n return cell.text.length;\n }\n if (cell.type === \"raw_number\") {\n return cell.text.length;\n }\n return JSON.stringify(cell).length;\n}\n\nfunction validateChart(\n block: Extract<Block, { type: \"data_visualization\" }>,\n path: string,\n issues: ValidationIssue[],\n): void {\n const chart = block.chart;\n if (chart.type === \"pie\") {\n if (chart.segments.length < 1 || chart.segments.length > CHART_SEGMENTS_MAX) {\n issues.push({ path, message: \"pie segments out of 1–12\" });\n }\n for (const s of chart.segments) {\n if (s.label.length > CHART_LABEL_MAX_CHARS) {\n issues.push({ path, message: \"pie label > 20\" });\n }\n if (!(s.value > 0)) {\n issues.push({ path, message: \"pie value must be > 0\" });\n }\n }\n return;\n }\n if (chart.series.length < 1 || chart.series.length > CHART_SERIES_MAX) {\n issues.push({ path, message: \"series out of 1–12\" });\n }\n if (chart.axis_config.categories.length > CHART_POINTS_MAX) {\n issues.push({ path, message: \"categories > 20\" });\n }\n for (const s of chart.series) {\n if (s.name.length > CHART_LABEL_MAX_CHARS) {\n issues.push({ path, message: \"series name > 20\" });\n }\n if (s.data.length < 1 || s.data.length > CHART_POINTS_MAX) {\n issues.push({ path, message: \"points out of 1–20\" });\n }\n for (const p of s.data) {\n if (p.label.length > CHART_LABEL_MAX_CHARS) {\n issues.push({ path, message: \"point label > 20\" });\n }\n if (!chart.axis_config.categories.includes(p.label)) {\n issues.push({ path, message: `point label ${p.label} missing from categories` });\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Overflow","COMMENT_RE","code"],"sources":["../src/errors.ts","../src/capabilities/capabilities.ts","../src/constants.ts","../src/budget/standard-budget-ledger.ts","../src/budget/recording-degradation-collector.ts","../src/budget/recording-receipt-collector.ts","../src/budget/conversion-context.ts","../src/registry/adapter-registry.ts","../src/assert-never.ts","../src/utf16.ts","../src/receipts.ts","../src/types.ts","../src/assemble/message-assembler.ts","../src/assemble/text-fallback.ts","../src/parsers/remark-markdown-parser.ts","../src/mermaid/mermaid-pie-parser.ts","../src/mermaid/mermaid-xychart-parser.ts","../src/adapters/block-to-plain-text.ts","../src/budget/operation-scope.ts","../src/converter/resolve-config.ts","../src/converter/slackmark-converter.ts","../src/adapters/inline.ts","../src/adapters/blockquote-adapter.ts","../src/slack/slack-upload-error.ts","../src/adapters/try-render-image.ts","../src/adapters/code-fence-adapter.ts","../src/adapters/heading-adapter.ts","../src/adapters/html-block-adapter.ts","../src/adapters/list-adapter.ts","../src/adapters/math-block-adapter.ts","../src/adapters/mermaid-fence-adapter.ts","../src/adapters/paragraph-adapter.ts","../src/adapters/skip-adapter.ts","../src/adapters/table-adapter.ts","../src/adapters/phrasing-to-markdown.ts","../src/adapters/task-list-adapter.ts","../src/adapters/thematic-break-adapter.ts","../src/converter/create-converter.ts","../src/validate/validate-blocks.ts"],"sourcesContent":["import type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Registry-keyed markers, not module-local symbols.\n *\n * Each published entry (`slackmark`, `slackmark/renderers`, `slackmark/slack`) is bundled\n * without code splitting, so every entry carries its own copy of these classes and\n * `instanceof` is false for an error that crosses an entry boundary. `Symbol.for` keys are\n * shared by every copy, which is what makes the exported guards below reliable. Prefer\n * those guards to `instanceof` for any error that can cross an entry.\n */\nconst RECEIPT_SNAPSHOT_LOCK = Symbol.for(\"slackmark.receiptSnapshotLock\");\nconst OPERATION_ERROR_CARRIER = Symbol.for(\"slackmark.operationErrorCarrier\");\nconst CONFIGURATION_ERROR_BRAND = Symbol.for(\"slackmark.error.configuration\");\nconst OPERATION_ERROR_BRAND = Symbol.for(\"slackmark.error.operation\");\n\n/**\n * Marks a class prototype so instances from any bundled copy answer to one identity.\n * Subclasses inherit the brand, and instances carry no extra own property.\n */\nexport function brandErrorPrototype(prototype: object, brand: symbol): void {\n Object.defineProperty(prototype, brand, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n}\n\n/**\n * Reads a brand without trusting the value: a hostile getter must not escape a guard.\n */\nexport function hasErrorBrand(value: unknown, brand: symbol): boolean {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n try {\n return Reflect.get(value, brand) === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Programmer/configuration error thrown only from the composition root.\n */\nexport interface ConfigurationErrorOptions {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\nexport class ConfigurationError extends Error {\n static {\n brandErrorPrototype(this.prototype, CONFIGURATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: string;\n readonly stage: string | undefined;\n readonly retryable: false;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, options: ConfigurationErrorOptions = {}) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"ConfigurationError\";\n this.code = options.code ?? \"invalid_configuration\";\n this.stage = options.stage;\n this.retryable = false;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport const OperationErrorCode = {\n Aborted: \"operation_aborted\",\n DeadlineExceeded: \"operation_deadline_exceeded\",\n Shutdown: \"operation_shutdown\",\n} as const;\n\nexport type OperationErrorCode = (typeof OperationErrorCode)[keyof typeof OperationErrorCode];\n\nexport interface OperationErrorOptions {\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Operational control-flow error. These failures are never degradations.\n */\nexport class OperationError extends Error {\n static {\n brandErrorPrototype(this.prototype, OPERATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: OperationErrorCode;\n readonly stage: string;\n readonly retryable: boolean;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n message: string,\n code: OperationErrorCode,\n stage: string,\n retryable: boolean,\n options: OperationErrorOptions = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"OperationError\";\n this.code = code;\n this.stage = stage;\n this.retryable = retryable;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport class OperationAbortedError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation aborted by caller\", OperationErrorCode.Aborted, stage, false, options);\n this.name = \"OperationAbortedError\";\n }\n}\n\nexport class OperationDeadlineExceededError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation deadline exceeded\", OperationErrorCode.DeadlineExceeded, stage, true, options);\n this.name = \"OperationDeadlineExceededError\";\n }\n}\n\nexport class OperationShutdownError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation interrupted by shutdown\", OperationErrorCode.Shutdown, stage, true, options);\n this.name = \"OperationShutdownError\";\n }\n}\n\n/**\n * Identifies a {@link ConfigurationError} from any entry of this package.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example a `ConfigurationError` from `slackmark/renderers` caught by code\n * that imported the class from `slackmark`.\n */\nexport function isConfigurationError(value: unknown): value is ConfigurationError {\n return hasErrorBrand(value, CONFIGURATION_ERROR_BRAND);\n}\n\n/**\n * Identifies an {@link OperationError} — abort, deadline, or shutdown — from any entry of\n * this package, including its subclasses.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example an abort raised inside `FetchSlackUploader` from `slackmark/slack`\n * caught by code that imported the class from `slackmark`. Narrow further with `code`\n * against {@link OperationErrorCode} rather than testing a subclass with `instanceof`.\n */\nexport function isOperationError(value: unknown): value is OperationError {\n return hasErrorBrand(value, OPERATION_ERROR_BRAND);\n}\n\nexport function cloneOperationError(error: OperationError, fallbackStage: string): OperationError {\n const stage = error.stage.length > 0 ? error.stage : fallbackStage;\n const options: OperationErrorOptions = {\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n };\n let cloned: OperationError;\n switch (error.code) {\n case OperationErrorCode.Aborted:\n cloned = new OperationAbortedError(stage, options);\n break;\n case OperationErrorCode.DeadlineExceeded:\n cloned = new OperationDeadlineExceededError(stage, options);\n break;\n case OperationErrorCode.Shutdown:\n cloned = new OperationShutdownError(stage, options);\n break;\n }\n Reflect.defineProperty(cloned, OPERATION_ERROR_CARRIER, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n return cloned;\n}\n\nexport function isOperationErrorCarrier(error: OperationError): boolean {\n return Reflect.get(error, OPERATION_ERROR_CARRIER) === true;\n}\n\nexport function cloneConfigurationError(error: ConfigurationError): ConfigurationError {\n return new ConfigurationError(error.message, {\n code: error.code,\n stage: error.stage,\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n });\n}\n\nexport function attachReceipts(\n error: unknown,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts?: Promise<ReadonlyArray<UploadReceipt>>,\n): unknown {\n if (!(error instanceof Error)) {\n return error;\n }\n try {\n if (Reflect.get(error, RECEIPT_SNAPSHOT_LOCK) === true) {\n return error;\n }\n } catch {\n return error;\n }\n let existing: ReadonlyArray<UploadReceipt> = [];\n try {\n const candidate = Reflect.get(error, \"receipts\");\n if (Array.isArray(candidate)) {\n existing = candidate.filter(isUploadReceipt);\n }\n } catch {\n existing = [];\n }\n Reflect.defineProperty(error, \"receipts\", {\n configurable: true,\n enumerable: true,\n value: freezeReceipts(mergeReceipts(existing, receipts)),\n writable: false,\n });\n if (settledReceipts !== undefined) {\n const finalReceipts = freezeSettledReceipts(settledReceipts, receipts);\n Reflect.defineProperty(error, \"settledReceipts\", {\n configurable: true,\n enumerable: true,\n value: finalReceipts,\n writable: false,\n });\n }\n return error;\n}\n\nexport function lockReceiptSnapshot(error: unknown): unknown {\n if (error instanceof Error) {\n Reflect.defineProperty(error, RECEIPT_SNAPSHOT_LOCK, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n }\n return error;\n}\n\nasync function freezeSettledReceipts(\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n fallback: ReadonlyArray<UploadReceipt>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n return freezeReceipts(await settledReceipts);\n } catch {\n return freezeReceipts(fallback);\n }\n}\n\nfunction mergeReceipts(\n existing: ReadonlyArray<UploadReceipt>,\n incoming: ReadonlyArray<UploadReceipt>,\n): ReadonlyArray<UploadReceipt> {\n const existingGroups = groupReceipts(existing);\n const incomingGroups = groupReceipts(incoming);\n const merged: UploadReceipt[] = [...incoming];\n for (const [key, values] of existingGroups) {\n const overlap = incomingGroups.get(key)?.length ?? 0;\n if (values.length > overlap) {\n merged.push(...values.slice(overlap));\n }\n }\n return merged;\n}\n\nfunction groupReceipts(\n receipts: ReadonlyArray<UploadReceipt>,\n): ReadonlyMap<string, ReadonlyArray<UploadReceipt>> {\n const grouped = new Map<string, UploadReceipt[]>();\n for (const receipt of receipts) {\n const key = receiptKey(receipt);\n const values = grouped.get(key);\n if (values === undefined) {\n grouped.set(key, [receipt]);\n } else {\n values.push(receipt);\n }\n }\n return grouped;\n}\n\nfunction receiptKey(receipt: UploadReceipt): string {\n return [\n receipt.provider,\n receipt.phase,\n receipt.fileId ?? \"\",\n String(receipt.shared),\n receipt.processing,\n String(receipt.status ?? \"\"),\n String(receipt.retryAfterMs ?? \"\"),\n receipt.providerCode ?? \"\",\n receipt.retrySafety,\n ].join(\"\\u0000\");\n}\n\nfunction freezeReceipts(receipts: ReadonlyArray<UploadReceipt>): ReadonlyArray<UploadReceipt> {\n return Object.freeze(receipts.map((receipt) => Object.freeze({ ...receipt })));\n}\n\nfunction isUploadReceipt(value: unknown): value is UploadReceipt {\n return typeof value === \"object\" && value !== null && Reflect.get(value, \"kind\") === \"upload\";\n}\n","/**\n * Capability profiles keyed to Slack changelog dates.\n * @see design/mapping-matrix.md\n */\nimport { ConfigurationError } from \"../errors.js\";\n\nexport interface CapabilityFlags {\n readonly markdownBlock: boolean;\n readonly tableBlock: boolean;\n readonly preformattedLanguage: boolean;\n readonly headerLevel: boolean;\n readonly dataTable: boolean;\n readonly dataVisualization: boolean;\n readonly containerBlock: boolean;\n}\n\nexport type CapabilityFlag = keyof CapabilityFlags;\nconst CAPABILITY_KEYS: ReadonlyArray<CapabilityFlag> = [\n \"markdownBlock\",\n \"tableBlock\",\n \"preformattedLanguage\",\n \"headerLevel\",\n \"dataTable\",\n \"dataVisualization\",\n \"containerBlock\",\n];\n\nexport const CapabilityPresetName = {\n Latest: \"latest\",\n Conservative: \"conservative\",\n D2025_02: \"2025-02\",\n D2025_08: \"2025-08\",\n D2026_03: \"2026-03\",\n D2026_05: \"2026-05\",\n D2026_06: \"2026-06\",\n} as const;\n\nexport type CapabilityPresetName = (typeof CapabilityPresetName)[keyof typeof CapabilityPresetName];\n\nconst ALL_OFF: CapabilityFlags = {\n markdownBlock: false,\n tableBlock: false,\n preformattedLanguage: false,\n headerLevel: false,\n dataTable: false,\n dataVisualization: false,\n containerBlock: false,\n};\n\n/** Baseline rich_text path only — every optional Slack capability off. */\nconst CONSERVATIVE: CapabilityFlags = { ...ALL_OFF };\n\nconst P_2025_02: CapabilityFlags = {\n ...CONSERVATIVE,\n markdownBlock: true,\n};\n\nconst P_2025_08: CapabilityFlags = {\n ...P_2025_02,\n tableBlock: true,\n};\n\nconst P_2026_03: CapabilityFlags = {\n ...P_2025_08,\n preformattedLanguage: true,\n headerLevel: true,\n};\n\nconst P_2026_05: CapabilityFlags = {\n ...P_2026_03,\n dataTable: true,\n};\n\nconst P_2026_06: CapabilityFlags = {\n ...P_2026_05,\n dataVisualization: true,\n containerBlock: true,\n};\n\nconst LATEST: CapabilityFlags = { ...P_2026_06 };\n\nexport const CAPABILITY_PRESETS: {\n readonly latest: CapabilityFlags;\n readonly conservative: CapabilityFlags;\n readonly \"2025-02\": CapabilityFlags;\n readonly \"2025-08\": CapabilityFlags;\n readonly \"2026-03\": CapabilityFlags;\n readonly \"2026-05\": CapabilityFlags;\n readonly \"2026-06\": CapabilityFlags;\n} = {\n latest: LATEST,\n conservative: CONSERVATIVE,\n \"2025-02\": P_2025_02,\n \"2025-08\": P_2025_08,\n \"2026-03\": P_2026_03,\n \"2026-05\": P_2026_05,\n \"2026-06\": P_2026_06,\n};\n\nexport type CapabilityFlagsPartial = {\n readonly [K in CapabilityFlag]?: boolean;\n};\n\n/**\n * Resolve a preset name, flags object, or preset + overrides into immutable flags.\n * Unknown preset names throw {@link ConfigurationError}: silently substituting\n * `latest` would enable every capability behind a typo.\n */\nexport function resolveCapabilities(\n input: CapabilityPresetName | CapabilityFlags | CapabilityFlagsPartial | undefined,\n overrides?: CapabilityFlagsPartial,\n): CapabilityFlags {\n let base: CapabilityFlags;\n if (input === undefined) {\n base = CAPABILITY_PRESETS.latest;\n } else if (typeof input === \"string\") {\n const preset = isPresetName(input) ? CAPABILITY_PRESETS[input] : undefined;\n if (preset === undefined) {\n throw new ConfigurationError(\n `Unknown capability preset; use one of: ${Object.keys(CAPABILITY_PRESETS).join(\", \")}.`,\n );\n }\n base = preset;\n } else {\n const normalized = normalizeFlags(input, \"capabilities\");\n base = isFullFlags(normalized) ? normalized : { ...CAPABILITY_PRESETS.latest, ...normalized };\n }\n if (overrides === undefined) {\n return Object.freeze({ ...base });\n }\n return Object.freeze({\n ...base,\n ...normalizeFlags(overrides, \"capabilityOverrides\"),\n });\n}\n\nfunction normalizeFlags(value: unknown, label: string): CapabilityFlagsPartial {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n } catch (cause) {\n throw new ConfigurationError(`${label} could not be inspected`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n cause,\n });\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n const normalized: Partial<Record<CapabilityFlag, boolean>> = {};\n for (const key of keys) {\n if (!isCapabilityKey(key)) {\n throw new ConfigurationError(`Unknown ${label} key: ${key}`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n let flag: unknown;\n try {\n flag = Reflect.get(value, key);\n } catch (cause) {\n throw new ConfigurationError(`${label}.${key} could not be read`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n cause,\n });\n }\n if (typeof flag !== \"boolean\") {\n throw new ConfigurationError(`${label}.${key} must be boolean`, {\n code: \"invalid_capabilities\",\n stage: \"configuration\",\n });\n }\n normalized[key] = flag;\n }\n return normalized;\n}\n\nfunction isCapabilityKey(value: string): value is CapabilityFlag {\n return CAPABILITY_KEYS.includes(value as CapabilityFlag);\n}\n\n// TS narrows string inputs to CapabilityPresetName, but JS callers can pass\n// any string; membership must be checked at runtime.\nfunction isPresetName(value: string): value is CapabilityPresetName {\n return Object.hasOwn(CAPABILITY_PRESETS, value);\n}\n\nfunction isFullFlags(value: CapabilityFlags | CapabilityFlagsPartial): value is CapabilityFlags {\n return (\n typeof value.markdownBlock === \"boolean\" &&\n typeof value.tableBlock === \"boolean\" &&\n typeof value.preformattedLanguage === \"boolean\" &&\n typeof value.headerLevel === \"boolean\" &&\n typeof value.dataTable === \"boolean\" &&\n typeof value.dataVisualization === \"boolean\" &&\n typeof value.containerBlock === \"boolean\"\n );\n}\n","/**\n * Named Slack Block Kit limits.\n * Sources: https://docs.slack.dev/block-kit and block reference pages (July 2026 research).\n */\n\n/** https://docs.slack.dev/block-kit */\nexport const MAX_BLOCKS_PER_MESSAGE = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/section-block */\nexport const SECTION_TEXT_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_TEXT_MAX_CHARS = 150;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_LEVEL_MAX = 4;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_URL_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_ALT_MAX_CHARS = 2000;\n\n/** slackmark renderer safety limit for retained/uploaded image bytes. */\nexport const RENDERED_IMAGE_MAX_BYTES: number = 10 * 1024 * 1024;\n\n/** Portable filename component limit used by renderer output validation. */\nexport const RENDERED_IMAGE_FILENAME_MAX_CHARS = 255;\n\n/** Defensive upper bound for Slack file IDs returned by uploaders. */\nexport const SLACK_FILE_ID_MAX_CHARS = 255;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/context-block */\nexport const CONTEXT_ELEMENTS_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/markdown-block */\nexport const MARKDOWN_CUMULATIVE_MAX_CHARS = 12_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_ROWS = 100;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_COLS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_CELL_CHARS_MAX = 10_000;\n\n/**\n * `raw_text.text` / `raw_number.text` declare `minLength: 1`; a blank markdown\n * cell must be padded or Slack rejects the payload with `invalid_blocks`.\n * https://docs.slack.dev/reference/block-kit/blocks/data-table-block\n */\nexport const TABLE_CELL_MIN_CHARS = 1;\n\n/** Spec decision: prefer `table` up to this many rows (incl. header). */\nexport const TABLE_PREFERRED_MAX_ROWS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_MAX_DATA_ROWS = 200;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_CELL_CHARS_MAX = 20_000;\n\n/** Spec decision: caption is required but unbounded in Slack's docs; match header. */\nexport const DATA_TABLE_CAPTION_MAX_CHARS = 150;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_TITLE_MAX_CHARS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_LABEL_MAX_CHARS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SEGMENTS_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SERIES_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_POINTS_MAX = 20;\n\n/**\n * Community-reported cap (ENG-4936); not in official docs.\n * Enforced defensively with degradation.\n */\nexport const DATA_VISUALIZATION_MAX_PER_MESSAGE = 2;\n\n/** https://docs.slack.dev/reference/methods/chat.postMessage#truncating */\nexport const MESSAGE_TEXT_SAFETY_MAX_CHARS = 40_000;\n\n/** Undocumented; defensive clamp for rich_text_list.indent. */\nexport const RICH_TEXT_LIST_INDENT_MAX = 6;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_CHILDREN_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_TITLE_MAX_CHARS = 150;\n\n/** Cell wrap heuristic for table column_settings.is_wrapped. */\nexport const TABLE_CELL_WRAP_THRESHOLD = 40;\n\nexport const ELLIPSIS = \"…\";\n","import {\n DATA_TABLE_CELL_CHARS_MAX,\n DATA_VISUALIZATION_MAX_PER_MESSAGE,\n MARKDOWN_CUMULATIVE_MAX_CHARS,\n MAX_BLOCKS_PER_MESSAGE,\n MESSAGE_TEXT_SAFETY_MAX_CHARS,\n TABLE_CELL_CHARS_MAX,\n} from \"../constants.js\";\nimport type { BudgetClaim, BudgetLedger, BudgetSnapshot } from \"../types.js\";\n\nexport interface StandardBudgetLedgerOptions {\n /**\n * When false, the per-message chart cap is not enforced (used while emitting\n * a document that will be split; the assembler re-applies the cap per message).\n * Table/markdown/total char caps stay enforced so oversized single blocks cannot slip through.\n */\n readonly enforceChartCap?: boolean;\n}\n\n/**\n * O(1) running-total budget tracker for a single Slack message.\n */\nexport class StandardBudgetLedger implements BudgetLedger {\n readonly maxBlocks: number;\n private readonly enforceChartCap: boolean;\n private blocks: number;\n private tableChars: number;\n private dataTableChars: number;\n private markdownChars: number;\n private charts: number;\n private totalChars: number;\n\n constructor(maxBlocks: number = MAX_BLOCKS_PER_MESSAGE, options?: StandardBudgetLedgerOptions) {\n this.maxBlocks = maxBlocks;\n this.enforceChartCap = options?.enforceChartCap ?? true;\n this.blocks = 0;\n this.tableChars = 0;\n this.dataTableChars = 0;\n this.markdownChars = 0;\n this.charts = 0;\n this.totalChars = 0;\n }\n\n tryReserveClaim(claim: BudgetClaim | undefined): boolean {\n if (claim === undefined) {\n return true;\n }\n const nextBlocks = this.blocks + (claim.blocks ?? 0);\n const nextTable = this.tableChars + (claim.tableChars ?? 0);\n const nextData = this.dataTableChars + (claim.dataTableChars ?? 0);\n const nextMd = this.markdownChars + (claim.markdownChars ?? 0);\n const nextCharts = this.charts + (claim.chart === true ? 1 : 0);\n const nextTotal = this.totalChars + (claim.totalChars ?? 0);\n\n if (nextBlocks > this.maxBlocks) return false;\n if (nextTable > TABLE_CELL_CHARS_MAX) return false;\n if (nextData > DATA_TABLE_CELL_CHARS_MAX) return false;\n if (nextMd > MARKDOWN_CUMULATIVE_MAX_CHARS) return false;\n if (this.enforceChartCap && nextCharts > DATA_VISUALIZATION_MAX_PER_MESSAGE) return false;\n if (nextTotal > MESSAGE_TEXT_SAFETY_MAX_CHARS) return false;\n\n this.blocks = nextBlocks;\n this.tableChars = nextTable;\n this.dataTableChars = nextData;\n this.markdownChars = nextMd;\n this.charts = nextCharts;\n this.totalChars = nextTotal;\n return true;\n }\n\n snapshot(): BudgetSnapshot {\n return {\n blocks: this.blocks,\n tableChars: this.tableChars,\n dataTableChars: this.dataTableChars,\n markdownChars: this.markdownChars,\n charts: this.charts,\n totalChars: this.totalChars,\n };\n }\n\n restore(snapshot: BudgetSnapshot): void {\n this.blocks = snapshot.blocks;\n this.tableChars = snapshot.tableChars;\n this.dataTableChars = snapshot.dataTableChars;\n this.markdownChars = snapshot.markdownChars;\n this.charts = snapshot.charts;\n this.totalChars = snapshot.totalChars;\n }\n\n resetForNewMessage(): void {\n this.blocks = 0;\n this.tableChars = 0;\n this.dataTableChars = 0;\n this.markdownChars = 0;\n this.charts = 0;\n this.totalChars = 0;\n }\n}\n","import type { Degradation, DegradationCollector } from \"../types.js\";\n\n/**\n * In-memory degradation collector for one conversion.\n */\nexport class RecordingDegradationCollector implements DegradationCollector {\n private readonly items: Degradation[];\n\n constructor() {\n this.items = [];\n }\n\n add(d: Degradation): void {\n this.items.push(d);\n }\n\n all(): ReadonlyArray<Degradation> {\n return this.items.slice();\n }\n}\n","import type { ReceiptCollector, UploadReceipt } from \"../types.js\";\n\nexport class RecordingReceiptCollector implements ReceiptCollector {\n private readonly items: UploadReceipt[];\n private readonly settledPromise: Promise<ReadonlyArray<UploadReceipt>>;\n private readonly resolveSettled: (receipts: ReadonlyArray<UploadReceipt>) => void;\n private isSettled: boolean;\n\n constructor() {\n this.items = [];\n let resolvePromise: ((receipts: ReadonlyArray<UploadReceipt>) => void) | undefined;\n this.settledPromise = new Promise((resolve) => {\n resolvePromise = resolve;\n });\n this.resolveSettled = (receipts): void => {\n resolvePromise?.(receipts);\n };\n this.isSettled = false;\n }\n\n add(receipt: UploadReceipt): void {\n this.items.push(Object.freeze({ ...receipt }));\n }\n\n all(): ReadonlyArray<UploadReceipt> {\n return Object.freeze([...this.items]);\n }\n\n settle(): void {\n if (this.isSettled) {\n return;\n }\n this.isSettled = true;\n this.resolveSettled(this.all());\n }\n\n settled(): Promise<ReadonlyArray<UploadReceipt>> {\n return this.settledPromise;\n }\n}\n","import type { Definition, FootnoteDefinition } from \"mdast\";\n\nimport type { CapabilityFlags } from \"../capabilities/capabilities.js\";\nimport type {\n BudgetLedger,\n ConversionStrategy,\n DegradationCollector,\n ImageRenderer,\n MentionResolvers,\n OperationContext,\n OverflowMode,\n ReceiptCollector,\n SlackUploader,\n} from \"../types.js\";\n\n/**\n * Immutable resolved config for one conversion.\n */\nexport interface ResolvedConfig {\n readonly capabilities: CapabilityFlags;\n readonly overflow: OverflowMode;\n readonly strategy: ConversionStrategy;\n readonly renderers: ReadonlyArray<ImageRenderer>;\n readonly uploader: SlackUploader | undefined;\n readonly enableMath: boolean;\n readonly enableInlineMath: boolean;\n readonly enableFrontmatter: boolean;\n readonly mentionResolvers: MentionResolvers | undefined;\n readonly operation: OperationContext;\n}\n\nexport interface ConversionContextDeps {\n readonly config: ResolvedConfig;\n readonly budget: BudgetLedger;\n readonly degradations: DegradationCollector;\n readonly receipts: ReceiptCollector;\n readonly definitions: ReadonlyMap<string, Definition>;\n readonly footnotes: ReadonlyMap<string, FootnoteDefinition>;\n readonly footnoteOrder: ReadonlyArray<string>;\n readonly precedingHeading: string | undefined;\n readonly path: string;\n}\n\n/**\n * Per-call conversion state. Never stored on converter instances.\n */\nexport class ConversionContext {\n readonly config: ResolvedConfig;\n readonly budget: BudgetLedger;\n readonly degradations: DegradationCollector;\n readonly receipts: ReceiptCollector;\n readonly definitions: ReadonlyMap<string, Definition>;\n readonly footnotes: ReadonlyMap<string, FootnoteDefinition>;\n readonly footnoteOrder: ReadonlyArray<string>;\n readonly precedingHeading: string | undefined;\n readonly path: string;\n\n constructor(deps: ConversionContextDeps) {\n this.config = deps.config;\n this.budget = deps.budget;\n this.degradations = deps.degradations;\n this.receipts = deps.receipts;\n this.definitions = deps.definitions;\n this.footnotes = deps.footnotes;\n this.footnoteOrder = deps.footnoteOrder;\n this.precedingHeading = deps.precedingHeading;\n this.path = deps.path;\n }\n\n withDegradations(degradations: DegradationCollector): ConversionContext {\n return new ConversionContext({\n config: this.config,\n budget: this.budget,\n degradations,\n receipts: this.receipts,\n definitions: this.definitions,\n footnotes: this.footnotes,\n footnoteOrder: this.footnoteOrder,\n precedingHeading: this.precedingHeading,\n path: this.path,\n });\n }\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { NodeAdapter } from \"../adapters/node-adapter.js\";\nimport type { Block } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport type { CapabilityFlag } from \"../capabilities/capabilities.js\";\n\n/**\n * First-matching adapter wins; candidates tried in order with capability/budget gates.\n */\nexport class AdapterRegistry {\n private readonly adapters: ReadonlyArray<NodeAdapter>;\n\n constructor(adapters: ReadonlyArray<NodeAdapter>) {\n this.adapters = adapters;\n }\n\n async emit(node: RootContent, ctx: ConversionContext): Promise<ReadonlyArray<Block>> {\n for (const adapter of this.adapters) {\n if (!adapter.match(node, ctx)) {\n continue;\n }\n const candidates = adapter.plan(node, ctx);\n let budgetBlocked = false;\n let emittedEmpty = false;\n for (const candidate of candidates) {\n if (!capabilitiesAllow(candidate.requires, ctx)) {\n continue;\n }\n const beforeClaim = ctx.budget.snapshot();\n if (!ctx.budget.tryReserveClaim(candidate.budget)) {\n budgetBlocked = true;\n continue;\n }\n const blocks = await candidate.emit(ctx);\n if (blocks.length === 0) {\n // Release the reservation and try the next candidate (e.g. mermaid fallback).\n ctx.budget.restore(beforeClaim);\n emittedEmpty = true;\n continue;\n }\n return blocks;\n }\n // Intentional empty emits (SkipAdapter, empty HTML) already recorded their own\n // degradations; do not double-flag when nothing was budget-blocked.\n if (emittedEmpty && !budgetBlocked) {\n return [];\n }\n ctx.degradations.add({\n nodeType: node.type,\n from: \"adapter\",\n to: \"empty\",\n reason: budgetBlocked\n ? \"Message budget exhausted (blocks/chars/charts); content omitted\"\n : \"All candidates failed capability/budget gates\",\n path: ctx.path,\n });\n return [];\n }\n\n ctx.degradations.add({\n nodeType: node.type,\n from: node.type,\n to: \"skip\",\n reason: \"No adapter matched node\",\n path: ctx.path,\n });\n return [];\n }\n}\n\nfunction capabilitiesAllow(\n requires: ReadonlyArray<CapabilityFlag> | undefined,\n ctx: ConversionContext,\n): boolean {\n if (requires === undefined) {\n return true;\n }\n for (const flag of requires) {\n if (!ctx.config.capabilities[flag]) {\n return false;\n }\n }\n return true;\n}\n","/**\n * Exhaustiveness helper for discriminated unions.\n */\nexport function assertNever(value: never, message?: string): never {\n const detail = message ?? \"Unexpected value\";\n throw new Error(`${detail}: ${JSON.stringify(value)}`);\n}\n","/**\n * Surrogate-pair-safe string truncation.\n *\n * `String.prototype.slice` counts UTF-16 code units, so a cut can land between\n * the high and low half of a surrogate pair (astral chars: emoji, some CJK).\n * A lone surrogate is malformed UTF-16 — Slack rejects such payloads with\n * `invalid_blocks` — so every truncation site must back off one unit instead.\n * Unicode ranges: https://unicode.org/faq/utf_bom.html#utf16-2\n */\n\nconst HIGH_SURROGATE_MIN = 0xd800;\nconst HIGH_SURROGATE_MAX = 0xdbff;\nconst LOW_SURROGATE_MIN = 0xdc00;\nconst LOW_SURROGATE_MAX = 0xdfff;\n\n/**\n * Largest cut index ≤ `end` that does not split a surrogate pair in `text`.\n * `end` is clamped into `[0, text.length]`.\n */\nexport function surrogateSafeEnd(text: string, end: number): number {\n if (end <= 0) {\n return 0;\n }\n if (end >= text.length) {\n return text.length;\n }\n const before = text.charCodeAt(end - 1);\n const after = text.charCodeAt(end);\n if (\n before >= HIGH_SURROGATE_MIN &&\n before <= HIGH_SURROGATE_MAX &&\n after >= LOW_SURROGATE_MIN &&\n after <= LOW_SURROGATE_MAX\n ) {\n return end - 1;\n }\n return end;\n}\n\n/**\n * `text.slice(0, max)` that never splits a surrogate pair: when the cut would\n * land mid-pair, the whole pair is dropped (result is `max - 1` units).\n */\nexport function sliceSurrogateSafe(text: string, max: number): string {\n return text.slice(0, surrogateSafeEnd(text, max));\n}\n","export const UploadPhase = {\n Requested: \"requested\",\n Allocated: \"allocated\",\n Uploaded: \"uploaded\",\n Completed: \"completed\",\n Shared: \"shared\",\n Unknown: \"unknown\",\n} as const;\n\nexport type UploadPhase = (typeof UploadPhase)[keyof typeof UploadPhase];\n\nexport const UploadProcessing = {\n NotRequested: \"not-requested\",\n Pending: \"pending\",\n Verified: \"verified\",\n Unverified: \"unverified\",\n} as const;\n\nexport type UploadProcessing = (typeof UploadProcessing)[keyof typeof UploadProcessing];\n\nexport const RetrySafety = {\n Never: \"never\",\n Safe: \"safe\",\n MayDuplicate: \"may-duplicate\",\n} as const;\n\nexport type RetrySafety = (typeof RetrySafety)[keyof typeof RetrySafety];\n\nexport interface UploadReceipt {\n readonly kind: \"upload\";\n readonly provider: string;\n readonly rendererId?: string | undefined;\n readonly filename?: string | undefined;\n readonly phase: UploadPhase;\n readonly fileId?: string | undefined;\n readonly shared: boolean;\n readonly processing: UploadProcessing;\n readonly status?: number | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly providerCode?: string | undefined;\n readonly retrySafety: RetrySafety;\n}\n","import type { Root } from \"mdast\";\n\nimport type { Block } from \"./blocks/types.js\";\nimport type {\n CapabilityFlags,\n CapabilityFlagsPartial,\n CapabilityPresetName,\n} from \"./capabilities/capabilities.js\";\nimport type { UploadReceipt } from \"./receipts.js\";\n\nexport { RetrySafety, UploadPhase, UploadProcessing } from \"./receipts.js\";\nexport type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Structured degradation emitted when content falls back or is truncated.\n */\nexport interface Degradation {\n readonly nodeType: string;\n readonly from: string;\n readonly to: string;\n readonly reason: string;\n readonly path: string;\n readonly details?: DegradationDetails | undefined;\n}\n\n/**\n * Optional machine-readable context for a degradation. The core fields above\n * remain stable and sufficient for human-readable fallback reporting.\n */\nexport interface DegradationDetails {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly retryable?: boolean | undefined;\n readonly rendererId?: string | undefined;\n}\n\n/**\n * Total conversion result — never throws on user markdown.\n */\nexport interface ConversionResult {\n readonly blocks: ReadonlyArray<Block>;\n readonly text: string;\n readonly degradations: ReadonlyArray<Degradation>;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n}\n\n/**\n * One message chunk from multi-message conversion.\n */\nexport interface ConversionMessage {\n readonly blocks: ReadonlyArray<Block>;\n readonly text: string;\n}\n\n/**\n * Multi-message conversion result.\n */\nexport interface ConversionMessagesResult {\n readonly messages: ReadonlyArray<ConversionMessage>;\n readonly degradations: ReadonlyArray<Degradation>;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n}\n\nexport const OverflowMode = {\n Degrade: \"degrade\",\n Split: \"split\",\n} as const;\n\nexport type OverflowMode = (typeof OverflowMode)[keyof typeof OverflowMode];\n\nexport const ConversionStrategy = {\n RichTextFirst: \"rich-text-first\",\n MarkdownBlock: \"markdown-block\",\n} as const;\n\nexport type ConversionStrategy = (typeof ConversionStrategy)[keyof typeof ConversionStrategy];\n\n/**\n * Normalized fenced content passed to {@link ImageRenderer}. Display math uses\n * `lang: \"math\"`; fenced-code languages are lowercase and trimmed.\n */\nexport interface RenderRequest {\n readonly lang: string;\n readonly source: string;\n readonly altText: string;\n}\n\nexport type BytesImage = {\n readonly kind: \"bytes\";\n readonly data: Uint8Array;\n readonly mimeType: \"image/png\" | \"image/jpeg\" | \"image/gif\";\n readonly filename: string;\n readonly altText?: string | undefined;\n};\n\nexport type UrlImage = {\n readonly kind: \"url\";\n readonly imageUrl: string;\n readonly altText?: string | undefined;\n};\n\nexport type RenderedImage = UrlImage | BytesImage;\n\n/**\n * Safe machine-readable renderer failure metadata. Implementations must keep\n * untrusted source and collaborator messages out of these fields.\n */\nexport interface StructuredRendererError {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId?: string | undefined;\n}\n\n/**\n * Pluggable image renderer for Mermaid fences that cannot become native\n * charts, display math, and generic code fences.\n *\n * Renderers are consulted in configuration order. {@link canRender} should be\n * a cheap, synchronous capability check; conversion calls {@link render} only\n * after it returns true. Return `null` to decline a request after inspection.\n * Attempt failures are buffered while conversion tries later renderers. A\n * later success emits no failure degradation; only an all-failed chain records\n * the buffered failures before text fallback. URL output must be an absolute\n * HTTPS URL without credentials and within Slack's image URL limit.\n */\nexport const ImageRendererOutput = {\n Url: \"url\",\n Bytes: \"bytes\",\n Both: \"both\",\n} as const;\n\nexport type ImageRendererOutput = (typeof ImageRendererOutput)[keyof typeof ImageRendererOutput];\n\nexport type RendererImage<TOutput extends ImageRendererOutput> = TOutput extends \"url\"\n ? UrlImage\n : TOutput extends \"bytes\"\n ? BytesImage\n : RenderedImage;\n\nexport interface ImageRenderer<TOutput extends ImageRendererOutput = ImageRendererOutput> {\n /** Stable machine-readable renderer identity. */\n readonly id: string;\n /** Declared output contract, enforced against every non-null result. */\n readonly output: TOutput;\n /** Whether this renderer accepts the normalized language and request. */\n canRender(req: RenderRequest): boolean;\n /** Produce an image or return `null` to let the next renderer try. */\n render(req: RenderRequest, context: OperationContext): Promise<RendererImage<TOutput> | null>;\n}\n\nexport type UrlImageRenderer = ImageRenderer<\"url\">;\nexport type BytesImageRenderer = ImageRenderer<\"bytes\">;\nexport type BothImageRenderer = ImageRenderer<\"both\">;\n\n/**\n * Ergonomic high-level operation bounds.\n */\nexport interface OperationOptions {\n readonly signal?: AbortSignal | undefined;\n /** Relative milliseconds from call start. */\n readonly timeoutMs?: number | undefined;\n}\n\n/**\n * Absolute context passed only to execution collaborators.\n */\nexport interface OperationContext {\n readonly signal: AbortSignal | undefined;\n readonly deadlineMs: number | undefined;\n}\n\n/**\n * Uploads bytes-producing renderer output to Slack files API.\n */\nexport interface SlackUploader {\n upload(\n img: BytesImage,\n context: OperationContext,\n ): Promise<{ readonly fileId: string; readonly receipt: UploadReceipt }>;\n}\n\n/**\n * Optional mention resolvers (off by default).\n */\nexport interface MentionResolvers {\n readonly resolveUser?: ((handle: string) => string | undefined) | undefined;\n readonly resolveChannel?: ((name: string) => string | undefined) | undefined;\n}\n\n/**\n * Public conversion options (per-call).\n * Custom adapters are wired via {@link createConverter}, not per-call options.\n */\nexport interface ConvertOptions {\n readonly capabilities?:\n | CapabilityPresetName\n | CapabilityFlags\n | CapabilityFlagsPartial\n | undefined;\n readonly capabilityOverrides?: CapabilityFlagsPartial | undefined;\n readonly overflow?: OverflowMode | undefined;\n readonly strategy?: ConversionStrategy | undefined;\n readonly renderers?: ReadonlyArray<ImageRenderer> | undefined;\n readonly uploader?: SlackUploader | undefined;\n readonly enableMath?: boolean | undefined;\n /**\n * Treat `$x$` inside a paragraph as inline math. Off by default even when\n * {@link ConversionOptions.enableMath} is on, because agent prose is far more likely to\n * contain currency (`$200/mo versus $350/mo`) than inline LaTeX, and reading the span\n * between two dollar signs as math deletes both signs. `$$…$$` is unaffected.\n */\n readonly enableInlineMath?: boolean | undefined;\n readonly enableFrontmatter?: boolean | undefined;\n readonly mentionResolvers?: MentionResolvers | undefined;\n readonly signal?: AbortSignal | undefined;\n readonly timeoutMs?: number | undefined;\n}\n\n/**\n * Collects degradations during a single conversion.\n */\nexport interface DegradationCollector {\n add(d: Degradation): void;\n all(): ReadonlyArray<Degradation>;\n}\n\nexport interface ReceiptCollector {\n add(receipt: UploadReceipt): void;\n all(): ReadonlyArray<UploadReceipt>;\n settle(): void;\n settled(): Promise<ReadonlyArray<UploadReceipt>>;\n}\n\n/**\n * Budget reservation claimed while planning a candidate.\n */\nexport interface BudgetClaim {\n readonly blocks?: number;\n readonly tableChars?: number;\n readonly dataTableChars?: number;\n readonly markdownChars?: number;\n readonly chart?: boolean;\n readonly totalChars?: number;\n}\n\n/**\n * Message-wide budget ledger.\n */\nexport interface BudgetLedger {\n readonly maxBlocks: number;\n tryReserveClaim(claim: BudgetClaim | undefined): boolean;\n snapshot(): BudgetSnapshot;\n /** Restore counters to a prior {@link snapshot} (e.g. after an empty emit). */\n restore(snapshot: BudgetSnapshot): void;\n resetForNewMessage(): void;\n}\n\nexport interface BudgetSnapshot {\n readonly blocks: number;\n readonly tableChars: number;\n readonly dataTableChars: number;\n readonly markdownChars: number;\n readonly charts: number;\n readonly totalChars: number;\n}\n\n/**\n * Deterministic markdown → plain text for notification fallbacks.\n */\nexport interface PlainTextRenderer {\n render(markdown: string): string;\n renderFromBlocks(blocks: ReadonlyArray<Block>): string;\n}\n\n/**\n * Swappable markdown parser (wraps remark by default).\n */\nexport interface MarkdownParser {\n parse(markdown: string, options: ParserOptions): Promise<Root>;\n}\n\nexport interface ParserOptions {\n readonly enableMath: boolean;\n readonly enableInlineMath: boolean;\n readonly enableFrontmatter: boolean;\n}\n\n/**\n * Mermaid chart grammar parser (pie / xychart).\n */\nexport interface MermaidChartParser {\n parse(source: string): MermaidParseResult;\n}\n\nexport type MermaidParseResult =\n | { readonly ok: true; readonly value: MermaidPieAst | MermaidXyChartAst }\n | { readonly ok: false; readonly reason: string };\n\nexport interface MermaidPieAst {\n readonly kind: \"pie\";\n readonly title: string | undefined;\n readonly segments: ReadonlyArray<{ readonly label: string; readonly value: number }>;\n}\n\nexport interface MermaidXyChartAst {\n readonly kind: \"xychart-beta\";\n readonly title: string | undefined;\n readonly categories: ReadonlyArray<string>;\n readonly xLabel: string | undefined;\n readonly yLabel: string | undefined;\n readonly bars: ReadonlyArray<ReadonlyArray<number>>;\n readonly lines: ReadonlyArray<ReadonlyArray<number>>;\n}\n","import { assertNever } from \"../assert-never.js\";\nimport type {\n Block,\n DataTableBlock,\n RichTextBlock,\n RichTextElement,\n TableBlock,\n TableCell,\n} from \"../blocks/types.js\";\nimport { StandardBudgetLedger } from \"../budget/standard-budget-ledger.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport {\n CONTEXT_ELEMENTS_MAX,\n MAX_BLOCKS_PER_MESSAGE,\n MESSAGE_TEXT_SAFETY_MAX_CHARS,\n SECTION_TEXT_MAX_CHARS,\n} from \"../constants.js\";\nimport type {\n BudgetClaim,\n ConversionMessage,\n DegradationCollector,\n PlainTextRenderer,\n} from \"../types.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\nimport { OverflowMode as Overflow } from \"../types.js\";\n\nexport interface MessageAssemblerDeps {\n readonly plainText: PlainTextRenderer;\n}\n\n/**\n * Packs blocks into messages, coalesces adjacent rich_text, attaches footnotes.\n */\nexport class MessageAssembler {\n private readonly plainText: PlainTextRenderer;\n\n constructor(deps: MessageAssemblerDeps) {\n this.plainText = deps.plainText;\n }\n\n assemble(\n blocks: ReadonlyArray<Block>,\n ctx: ConversionContext,\n footnoteBlocks: ReadonlyArray<Block>,\n ): ReadonlyArray<ConversionMessage> {\n const coalesced = coalesceRichText(blocks);\n\n if (ctx.config.overflow === Overflow.Split) {\n return this.splitMessages([...coalesced, ...footnoteBlocks], ctx);\n }\n\n // Degrade: reserve trailing slots for footnotes so they are not sliced off.\n const noteCount = footnoteBlocks.length;\n const bodyCap = Math.max(0, MAX_BLOCKS_PER_MESSAGE - noteCount);\n const clippedBody = coalesced.slice(0, bodyCap);\n if (coalesced.length > bodyCap) {\n ctx.degradations.add({\n nodeType: \"message\",\n from: `${String(coalesced.length)} body blocks`,\n to: `${String(bodyCap)} body blocks`,\n reason:\n noteCount > 0\n ? `overflow=degrade truncated body to reserve ${String(noteCount)} footnote blocks`\n : \"overflow=degrade truncated to 50 blocks\",\n path: ctx.path,\n });\n }\n\n let notes = footnoteBlocks;\n if (notes.length > MAX_BLOCKS_PER_MESSAGE) {\n notes = footnoteBlocks.slice(0, MAX_BLOCKS_PER_MESSAGE);\n ctx.degradations.add({\n nodeType: \"footnote\",\n from: `${String(footnoteBlocks.length)} footnote blocks`,\n to: `${String(MAX_BLOCKS_PER_MESSAGE)} footnote blocks`,\n reason: \"Footnote blocks alone exceed 50; truncated\",\n path: ctx.path,\n });\n }\n\n const finalBlocks = [...clippedBody, ...notes];\n return [this.toMessage(finalBlocks, ctx)];\n }\n\n private splitMessages(\n blocks: ReadonlyArray<Block>,\n ctx: ConversionContext,\n ): ReadonlyArray<ConversionMessage> {\n const messages: ConversionMessage[] = [];\n let current: Block[] = [];\n let ledger = new StandardBudgetLedger(MAX_BLOCKS_PER_MESSAGE);\n\n const flush = (): void => {\n if (current.length === 0) {\n return;\n }\n messages.push(this.toMessage(current, ctx));\n current = [];\n ledger = new StandardBudgetLedger(MAX_BLOCKS_PER_MESSAGE);\n };\n\n for (const block of blocks) {\n const claim = claimForBlock(block);\n if (!ledger.tryReserveClaim(claim)) {\n flush();\n if (!ledger.tryReserveClaim(claim)) {\n // Single block exceeds an empty message budget (e.g. oversized table) — omit.\n ctx.degradations.add({\n nodeType: \"message\",\n from: block.type,\n to: \"omitted\",\n reason: \"Block exceeds per-message budget; omitted\",\n path: ctx.path,\n });\n continue;\n }\n }\n current.push(block);\n }\n flush();\n\n if (messages.length > 1) {\n ctx.degradations.add({\n nodeType: \"message\",\n from: \"single\",\n to: `${String(messages.length)} messages`,\n reason: \"Split at semantic block boundaries (per-message budgets)\",\n path: ctx.path,\n });\n }\n\n return messages.length > 0 ? messages : [{ blocks: [], text: \" \" }];\n }\n\n private toMessage(blocks: ReadonlyArray<Block>, ctx: ConversionContext): ConversionMessage {\n const raw = this.plainText.renderFromBlocks(blocks);\n if (raw.length <= MESSAGE_TEXT_SAFETY_MAX_CHARS) {\n return { blocks, text: raw };\n }\n ctx.degradations.add({\n nodeType: \"message\",\n from: `${String(raw.length)} text chars`,\n to: `${String(MESSAGE_TEXT_SAFETY_MAX_CHARS)} text chars`,\n reason: \"Notification text truncated to 40k safety limit\",\n path: ctx.path,\n });\n return { blocks, text: sliceSurrogateSafe(raw, MESSAGE_TEXT_SAFETY_MAX_CHARS) };\n }\n}\n\n/**\n * Build trailing divider + context chunks for footnotes.\n */\nexport function buildFootnoteBlocks(\n entries: ReadonlyArray<{ readonly n: number; readonly text: string }>,\n degradations?: DegradationCollector,\n): ReadonlyArray<Block> {\n if (entries.length === 0) {\n return [];\n }\n const blocks: Block[] = [{ type: \"divider\" }];\n const elements: ContextBlockElements = [];\n for (const e of entries) {\n const note = `[${String(e.n)}] ${e.text}`;\n if (note.length > SECTION_TEXT_MAX_CHARS) {\n degradations?.add({\n nodeType: \"footnote\",\n from: `${String(note.length)} chars`,\n to: `${String(SECTION_TEXT_MAX_CHARS)} chars`,\n reason: \"Footnote context text truncated to 3000 chars\",\n path: \"footnote\",\n });\n elements.push({ type: \"mrkdwn\", text: sliceSurrogateSafe(note, SECTION_TEXT_MAX_CHARS) });\n } else {\n elements.push({ type: \"mrkdwn\", text: note });\n }\n }\n for (let i = 0; i < elements.length; i += CONTEXT_ELEMENTS_MAX) {\n const chunk = elements.slice(i, i + CONTEXT_ELEMENTS_MAX);\n blocks.push({ type: \"context\", elements: chunk });\n }\n return blocks;\n}\n\ntype ContextBlockElements = Array<{ type: \"mrkdwn\"; text: string }>;\n\nfunction claimForBlock(block: Block): BudgetClaim {\n switch (block.type) {\n case \"data_visualization\":\n return { blocks: 1, chart: true };\n case \"markdown\":\n return { blocks: 1, markdownChars: block.text.length };\n case \"table\":\n return { blocks: 1, tableChars: countEmittedTableChars(block) };\n case \"data_table\":\n return { blocks: 1, dataTableChars: countEmittedTableChars(block) };\n case \"rich_text\":\n case \"header\":\n case \"divider\":\n case \"section\":\n case \"image\":\n case \"context\":\n case \"container\":\n return { blocks: 1 };\n default:\n return assertNever(block);\n }\n}\n\nfunction countEmittedTableChars(block: TableBlock | DataTableBlock): number {\n let total = 0;\n for (const row of block.rows) {\n for (const cell of row) {\n total += cellTextLength(cell);\n }\n }\n return total;\n}\n\nfunction cellTextLength(cell: TableCell): number {\n if (cell.type === \"raw_text\" || cell.type === \"raw_number\") {\n return cell.text.length;\n }\n // rich_text cell — approximate via JSON length of text nodes\n return JSON.stringify(cell).length;\n}\n\n/**\n * How many blocks `blocks` adds to a message whose last block is `previous`, once\n * {@link MessageAssembler.assemble} has merged adjacent rich_text sections.\n *\n * Emission reserves one block per source node before it knows what the node produces, so\n * without this a run of 60 paragraphs exhausts the 50-block budget even though it\n * coalesces into a single block. The converter reconciles the reservation against this\n * count so the budget tracks what is actually emitted.\n */\nexport function coalescedBlockCount(\n previous: Block | undefined,\n blocks: ReadonlyArray<Block>,\n): number {\n let count = 0;\n let tail = previous;\n for (const block of blocks) {\n if (!mergesIntoTail(tail, block)) {\n count += 1;\n }\n tail = block;\n }\n return count;\n}\n\nfunction mergesIntoTail(tail: Block | undefined, next: Block): boolean {\n return (\n tail?.type === \"rich_text\" &&\n next.type === \"rich_text\" &&\n isCoalescable(tail) &&\n isCoalescable(next)\n );\n}\n\nfunction coalesceRichText(blocks: ReadonlyArray<Block>): Block[] {\n const out: Block[] = [];\n let pending: RichTextElement[] | undefined;\n\n const flushPending = (): void => {\n if (pending === undefined || pending.length === 0) {\n pending = undefined;\n return;\n }\n const block: RichTextBlock = { type: \"rich_text\", elements: pending };\n out.push(block);\n pending = undefined;\n };\n\n for (const block of blocks) {\n if (block.type === \"rich_text\" && isCoalescable(block)) {\n if (pending === undefined) {\n pending = [...block.elements];\n } else {\n pending.push(...block.elements);\n }\n } else {\n flushPending();\n out.push(block);\n }\n }\n flushPending();\n return out;\n}\n\nfunction isCoalescable(block: RichTextBlock): boolean {\n // Only coalesce pure section flow; leave lists/quotes/preformatted alone as unit\n return block.elements.every((e) => e.type === \"rich_text_section\");\n}\n","import type { Block, RichTextElement, RichTextInline } from \"../blocks/types.js\";\nimport type { PlainTextRenderer } from \"../types.js\";\n\n/**\n * Deterministic plain-text renderer for notifications / screen readers.\n */\nexport class DeterministicPlainTextRenderer implements PlainTextRenderer {\n render(markdown: string): string {\n const parts: string[] = [];\n // Lightweight strip — full fidelity comes from renderFromBlocks after convert.\n let i = 0;\n const src = markdown;\n while (i < src.length) {\n if (src.startsWith(\"```\", i)) {\n const end = src.indexOf(\"```\", i + 3);\n if (end === -1) {\n parts.push(src.slice(i + 3));\n break;\n }\n parts.push(src.slice(i + 3, end).trim());\n i = end + 3;\n continue;\n }\n parts.push(src[i] ?? \"\");\n i += 1;\n }\n const raw = slackEntitiesToPlain(parts.join(\"\"))\n .replace(/!\\[[^\\]]{0,200}\\]\\([^)]{0,3000}\\)/g, \" \")\n .replace(/\\[([^\\]]{0,200})\\]\\([^)]{0,3000}\\)/g, \"$1\")\n // `#` and `>` are markup only at the start of a line. Stripping them\n // everywhere also ate the `#` of a channel reference and the `>` closing\n // every Slack entity.\n .replace(/^[ \\t]*#{1,6}[ \\t]*/gm, \"\")\n .replace(/^[ \\t]*>[ \\t]?/gm, \"\")\n .replace(/[*_`~]/g, \"\")\n // A backslash escape is markup: the reader should see the character, not\n // the backslash that stopped markdown from acting on it.\n .replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!>~|])/g, \"$1\")\n .replace(/\\s+/g, \" \")\n .trim();\n return raw.length > 0 ? raw : \" \";\n }\n\n renderFromBlocks(blocks: ReadonlyArray<Block>): string {\n const parts: string[] = [];\n for (const block of blocks) {\n switch (block.type) {\n case \"header\":\n parts.push(block.text.text);\n break;\n case \"section\":\n if (block.text !== undefined) {\n parts.push(stripMrkdwn(block.text.text));\n }\n break;\n case \"rich_text\":\n parts.push(richTextToPlain(block.elements));\n break;\n case \"markdown\":\n parts.push(this.render(block.text));\n break;\n case \"divider\":\n parts.push(\"---\");\n break;\n case \"image\":\n parts.push(block.alt_text);\n break;\n case \"context\":\n for (const el of block.elements) {\n if (el.type === \"mrkdwn\" || el.type === \"plain_text\") {\n parts.push(stripMrkdwn(el.text));\n }\n }\n break;\n case \"table\":\n case \"data_table\":\n parts.push(tableToPlain(block.rows));\n break;\n case \"data_visualization\":\n parts.push(block.title);\n break;\n case \"container\":\n if (block.title !== undefined) {\n parts.push(block.title.text);\n }\n parts.push(this.renderFromBlocks(block.child_blocks));\n break;\n default:\n break;\n }\n }\n const text = parts\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n .join(\"\\n\")\n .trim();\n return text.length > 0 ? text : \" \";\n }\n}\n\nfunction stripMrkdwn(text: string): string {\n return slackEntitiesToPlain(text).replace(/[*_~`]/g, \"\");\n}\n\n/**\n * Slack entity syntax rendered the way {@link inlinesToPlain} renders the\n * equivalent structured element, so a mention reads the same whether it reached\n * the output as a `rich_text` element or as literal text in a `markdown` block.\n *\n * This has to run before markdown punctuation is stripped. `>` closes every one\n * of these forms and also marks a blockquote, and `#` opens a channel reference\n * and also a heading, so stripping those characters first leaves `<@U123` behind.\n */\nfunction slackEntitiesToPlain(text: string): string {\n return text.replace(/<([^<>]{1,3000})>/g, (_match, body: string) => {\n const [target, label] = splitOnce(body, \"|\");\n if (target.startsWith(\"@\")) {\n return `@${target.slice(1)}`;\n }\n if (target.startsWith(\"#\")) {\n return `#${target.slice(1)}`;\n }\n if (target.startsWith(\"!\")) {\n return specialToPlain(target.slice(1), label);\n }\n // A link: Slack shows the label when there is one, else the bare URL.\n return label ?? target;\n });\n}\n\n/** `<!here>`, `<!subteam^S1|@x>`, `<!date^…|fallback>` and friends. */\nfunction specialToPlain(command: string, label: string | undefined): string {\n const [name, argument] = splitOnce(command, \"^\");\n if (name === \"subteam\") {\n return `@${argument ?? \"\"}`;\n }\n if (name === \"date\") {\n return label ?? command;\n }\n return `@${name}`;\n}\n\nfunction splitOnce(value: string, separator: string): [string, string | undefined] {\n const index = value.indexOf(separator);\n if (index === -1) {\n return [value, undefined];\n }\n return [value.slice(0, index), value.slice(index + separator.length)];\n}\n\nfunction richTextToPlain(elements: ReadonlyArray<RichTextElement>): string {\n const parts: string[] = [];\n for (const el of elements) {\n switch (el.type) {\n case \"rich_text_section\":\n case \"rich_text_quote\":\n parts.push(inlinesToPlain(el.elements));\n break;\n case \"rich_text_list\":\n for (const item of el.elements) {\n parts.push(`• ${inlinesToPlain(item.elements)}`);\n }\n break;\n case \"rich_text_preformatted\":\n parts.push(inlinesToPlain(el.elements));\n break;\n default:\n break;\n }\n }\n return parts.join(\"\\n\");\n}\n\nfunction inlinesToPlain(elements: ReadonlyArray<RichTextInline>): string {\n const parts: string[] = [];\n for (const el of elements) {\n switch (el.type) {\n case \"text\":\n parts.push(el.text);\n break;\n case \"link\":\n parts.push(el.text ?? el.url);\n break;\n case \"emoji\":\n parts.push(`:${el.name}:`);\n break;\n case \"user\":\n parts.push(`@${el.user_id}`);\n break;\n case \"channel\":\n parts.push(`#${el.channel_id}`);\n break;\n case \"usergroup\":\n parts.push(`@${el.usergroup_id}`);\n break;\n case \"broadcast\":\n parts.push(`@${el.range}`);\n break;\n case \"date\":\n parts.push(el.fallback ?? formatDateTokensUtc(el.timestamp, el.format));\n break;\n default:\n break;\n }\n }\n return parts.join(\"\");\n}\n\nconst DATE_TOKEN_RE = /\\{([a-z_]+)\\}/g;\n\nconst MONTHS = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n] as const;\n\nconst WEEKDAYS = [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n] as const;\n\nfunction pad2(value: number): string {\n return String(value).padStart(2, \"0\");\n}\n\nfunction ordinal(value: number): string {\n const remainder = value % 100;\n if (remainder >= 11 && remainder <= 13) {\n return `${String(value)}th`;\n }\n switch (value % 10) {\n case 1:\n return `${String(value)}st`;\n case 2:\n return `${String(value)}nd`;\n case 3:\n return `${String(value)}rd`;\n default:\n return `${String(value)}th`;\n }\n}\n\n/** One Slack date-format token rendered in UTC, or undefined when unsupported. */\nfunction dateToken(token: string, date: Date): string | undefined {\n const day = date.getUTCDate();\n const month = MONTHS[date.getUTCMonth()] ?? \"\";\n const shortMonth = month.slice(0, 3);\n const weekday = WEEKDAYS[date.getUTCDay()] ?? \"\";\n const year = date.getUTCFullYear();\n\n switch (token) {\n case \"date_num\":\n return `${String(year)}-${pad2(date.getUTCMonth() + 1)}-${pad2(day)}`;\n // Slack renders {date_slash} month-first: 02/18/2014 (docs example for\n // timestamp 1392734382).\n case \"date_slash\":\n return `${pad2(date.getUTCMonth() + 1)}/${pad2(day)}/${String(year)}`;\n case \"date_long\":\n case \"date_long_pretty\":\n return `${weekday}, ${month} ${ordinal(day)}, ${String(year)}`;\n case \"date_long_full\":\n return `${month} ${String(day)}, ${String(year)}`;\n // {date} renders \"February 18th, 2014\" (ordinal + year), not \"February 18\".\n case \"date\":\n case \"date_pretty\":\n return `${month} ${ordinal(day)}, ${String(year)}`;\n case \"date_short\":\n case \"date_short_pretty\":\n return `${shortMonth} ${String(day)}, ${String(year)}`;\n case \"time\":\n return `${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}`;\n case \"time_secs\":\n return `${pad2(date.getUTCHours())}:${pad2(date.getUTCMinutes())}:${pad2(date.getUTCSeconds())}`;\n default:\n return undefined;\n }\n}\n\n/**\n * Deterministic UTC rendering of Slack date-format tokens for notification\n * text. A date element without a fallback must not dump raw \"{date_short}\"\n * tokens into the message preview. Tokens needing a clock ({ago}, relative\n * \"pretty\" phrasing) render as their absolute equivalents; unknown tokens\n * degrade the whole format to the ISO date.\n * https://docs.slack.dev/messaging/formatting-message-text#date-formatting\n */\nfunction formatDateTokensUtc(timestamp: number, format: string): string {\n const date = new Date(timestamp * 1000);\n if (!Number.isFinite(timestamp) || Number.isNaN(date.getTime())) {\n return String(timestamp);\n }\n let unsupported = false;\n const formatted = format.replace(DATE_TOKEN_RE, (_match, token: string) => {\n const replacement = dateToken(token, date);\n if (replacement === undefined) {\n unsupported = true;\n return \"\";\n }\n return replacement;\n });\n if (format.length === 0 || unsupported) {\n return date.toISOString().slice(0, 10);\n }\n return formatted;\n}\n\nfunction tableToPlain(rows: ReadonlyArray<ReadonlyArray<unknown>>): string {\n const lines: string[] = [];\n for (const row of rows) {\n const cells = row.map((cell) => cellPlain(cell));\n lines.push(cells.join(\" | \"));\n }\n return lines.join(\"\\n\");\n}\n\nfunction cellPlain(cell: unknown): string {\n if (typeof cell !== \"object\" || cell === null) {\n return \"\";\n }\n const c = cell as { type?: string; text?: string; value?: number; elements?: unknown };\n if (c.type === \"raw_text\" && typeof c.text === \"string\") {\n return c.text;\n }\n if (c.type === \"raw_number\") {\n return typeof c.text === \"string\" ? c.text : String(c.value ?? \"\");\n }\n if (c.type === \"rich_text\" && Array.isArray(c.elements)) {\n return richTextToPlain(c.elements as RichTextElement[]);\n }\n return \"\";\n}\n","import type { Root } from \"mdast\";\nimport remarkFrontmatter from \"remark-frontmatter\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkParse from \"remark-parse\";\nimport { unified } from \"unified\";\n\nimport type { MarkdownParser, ParserOptions } from \"../types.js\";\n\n/**\n * Default markdown parser wrapping the unified/remark pipeline.\n */\nexport class RemarkMarkdownParser implements MarkdownParser {\n async parse(markdown: string, options: ParserOptions): Promise<Root> {\n const processor = unified().use(remarkParse).use(remarkGfm);\n if (options.enableFrontmatter) {\n processor.use(remarkFrontmatter, [\"yaml\", \"toml\"]);\n }\n if (options.enableMath) {\n processor.use(remarkMath, { singleDollarTextMath: options.enableInlineMath });\n }\n return processor.parse(markdown) as Root;\n }\n}\n","import type { MermaidChartParser, MermaidParseResult, MermaidPieAst } from \"../types.js\";\n\nconst COMMENT_RE = /%%[^\\n]{0,500}/g;\nconst TITLE_RE = /^\\s*pie\\b(?:\\s+showData)?(?:\\s+title\\s+(.+))?\\s*$/i;\nconst ENTRY_RE = /^\\s*\"([^\"]{1,200})\"\\s*:\\s*(-?\\d+(?:\\.\\d+)?)\\s*$/;\n\n/**\n * Parses mermaid `pie` diagram grammar into a structured AST.\n */\nexport class MermaidPieParser implements MermaidChartParser {\n parse(source: string): MermaidParseResult {\n const cleaned = source.replace(COMMENT_RE, \"\");\n const lines = cleaned.split(/\\r?\\n/);\n let title: string | undefined;\n const segments: Array<{ label: string; value: number }> = [];\n let seenHeader = false;\n\n for (const raw of lines) {\n const line = raw.trim();\n if (line.length === 0) {\n continue;\n }\n if (!seenHeader) {\n if (!/^\\s*pie\\b/i.test(line)) {\n return { ok: false, reason: \"Not a pie diagram\" };\n }\n seenHeader = true;\n const tm = TITLE_RE.exec(line);\n const titlePart = tm?.[1]?.trim();\n if (titlePart !== undefined && titlePart.length > 0) {\n title = titlePart;\n }\n continue;\n }\n\n // Optional standalone title line: title Foo\n const titleLine = /^\\s*title\\s+(.+)\\s*$/i.exec(line);\n if (titleLine !== null && title === undefined) {\n title = (titleLine[1] ?? \"\").trim();\n continue;\n }\n\n const em = ENTRY_RE.exec(line);\n if (em === null) {\n return { ok: false, reason: `Invalid pie entry: ${line}` };\n }\n const label = em[1] ?? \"\";\n const value = Number(em[2]);\n if (!(value > 0)) {\n return { ok: false, reason: `Pie values must be > 0 (got ${String(value)})` };\n }\n segments.push({ label, value });\n }\n\n if (!seenHeader) {\n return { ok: false, reason: \"Missing pie header\" };\n }\n if (segments.length === 0) {\n return { ok: false, reason: \"Pie has no segments\" };\n }\n\n const ast: MermaidPieAst = {\n kind: \"pie\",\n title,\n segments,\n };\n return { ok: true, value: ast };\n }\n}\n","import { CHART_POINTS_MAX } from \"../constants.js\";\nimport type { MermaidChartParser, MermaidParseResult, MermaidXyChartAst } from \"../types.js\";\n\nconst COMMENT_RE = /%%[^\\n]{0,500}/g;\nconst NUM = String.raw`-?\\d+(?:\\.\\d+)?`;\nconst NUM_LIST_RE = new RegExp(String.raw`\\[\\s*((?:${NUM}\\s*,\\s*)*${NUM})\\s*\\]`);\nconst STR_LIST_RE = /\\[\\s*((?:\"[^\"]{0,200}\"\\s*,\\s*)*\"[^\"]{0,200}\")\\s*\\]/;\n\n/**\n * Parses mermaid `xychart-beta` grammar (categories, bar/line series).\n */\nexport class MermaidXyChartParser implements MermaidChartParser {\n parse(source: string): MermaidParseResult {\n const cleaned = source.replace(COMMENT_RE, \"\");\n const lines = cleaned.split(/\\r?\\n/);\n let title: string | undefined;\n let categories: string[] = [];\n let xLabel: string | undefined;\n let yLabel: string | undefined;\n const bars: number[][] = [];\n const linesSeries: number[][] = [];\n let seenHeader = false;\n\n for (const raw of lines) {\n const line = raw.trim();\n if (line.length === 0) {\n continue;\n }\n if (!seenHeader) {\n if (!/^\\s*xychart-beta\\b/i.test(line)) {\n return { ok: false, reason: \"Not an xychart-beta diagram\" };\n }\n seenHeader = true;\n continue;\n }\n\n const titleM =\n /^\\s*title\\s+\"([^\"]{0,200})\"\\s*$/i.exec(line) ?? /^\\s*title\\s+(.+)\\s*$/i.exec(line);\n if (titleM !== null) {\n title = (titleM[1] ?? \"\").trim();\n continue;\n }\n\n if (/^\\s*x-axis\\b/i.test(line)) {\n const strList = STR_LIST_RE.exec(line);\n if (strList !== null) {\n categories = parseStringList(strList[1] ?? \"\");\n const labelM = /^\\s*x-axis\\s+\"([^\"]{0,200})\"\\s+/i.exec(line);\n if (labelM !== null) {\n xLabel = labelM[1];\n }\n continue;\n }\n const rangeM = new RegExp(\n String.raw`x-axis\\s+(?:\"([^\"]{0,200})\"\\s+)?(${NUM})\\s*-->\\s*(${NUM})`,\n \"i\",\n ).exec(line);\n if (rangeM !== null) {\n xLabel = rangeM[1];\n const min = Number(rangeM[2]);\n const max = Number(rangeM[3]);\n if (!Number.isFinite(min) || !Number.isFinite(max) || max < min) {\n return { ok: false, reason: `Invalid x-axis range: ${line}` };\n }\n const span = max - min + 1;\n if (span > CHART_POINTS_MAX) {\n return {\n ok: false,\n reason: `x-axis range has ${String(span)} points (max ${String(CHART_POINTS_MAX)})`,\n };\n }\n categories = [];\n for (let i = min; i <= max; i += 1) {\n categories.push(String(i));\n }\n continue;\n }\n return { ok: false, reason: `Invalid x-axis: ${line}` };\n }\n\n if (/^\\s*y-axis\\b/i.test(line)) {\n const ym = new RegExp(\n String.raw`y-axis\\s+(?:\"([^\"]{0,200})\"\\s+)?(?:(${NUM})\\s*-->\\s*(${NUM}))?`,\n \"i\",\n ).exec(line);\n if (ym !== null) {\n yLabel = ym[1];\n continue;\n }\n return { ok: false, reason: `Invalid y-axis: ${line}` };\n }\n\n if (/^\\s*bar\\b/i.test(line)) {\n const nums = NUM_LIST_RE.exec(line);\n if (nums === null) {\n return { ok: false, reason: `Invalid bar series: ${line}` };\n }\n bars.push(parseNumberList(nums[1] ?? \"\"));\n continue;\n }\n\n if (/^\\s*line\\b/i.test(line)) {\n const nums = NUM_LIST_RE.exec(line);\n if (nums === null) {\n return { ok: false, reason: `Invalid line series: ${line}` };\n }\n linesSeries.push(parseNumberList(nums[1] ?? \"\"));\n continue;\n }\n\n return { ok: false, reason: `Unrecognized xychart line: ${line}` };\n }\n\n if (!seenHeader) {\n return { ok: false, reason: \"Missing xychart-beta header\" };\n }\n if (categories.length === 0) {\n return { ok: false, reason: \"xychart missing categories\" };\n }\n if (bars.length === 0 && linesSeries.length === 0) {\n return { ok: false, reason: \"xychart has no series\" };\n }\n\n const ast: MermaidXyChartAst = {\n kind: \"xychart-beta\",\n title,\n categories,\n xLabel,\n yLabel,\n bars,\n lines: linesSeries,\n };\n return { ok: true, value: ast };\n }\n}\n\nfunction parseStringList(inner: string): string[] {\n const out: string[] = [];\n const re = /\"([^\"]{0,200})\"/g;\n let m: RegExpExecArray | null = re.exec(inner);\n while (m !== null) {\n out.push(m[1] ?? \"\");\n m = re.exec(inner);\n }\n return out;\n}\n\nfunction parseNumberList(inner: string): number[] {\n return inner\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map((s) => Number(s));\n}\n","import type { Nodes } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\n/**\n * Plain text for a block that had to be flattened into a single text run.\n *\n * `mdast-util-to-string` concatenates every descendant with no separator, so a\n * table collapses to \"ab12\" and sibling paragraphs run together as\n * \"para onepara two\". Flattening is already flagged as a degradation; the text\n * it leaves behind still has to be readable, so re-insert the separators the\n * structure carried.\n */\nexport function blockToPlainText(node: Nodes): string {\n // Deliberately not an exhaustive switch: every node type not named here is\n // already a single text run, and `toString` is the right answer for all of them.\n if (node.type === \"table\") {\n return node.children\n .map((row) => row.children.map((cell) => toString(cell)).join(\" | \"))\n .join(\"\\n\");\n }\n if (node.type === \"list\") {\n return node.children.map((item) => `• ${blockToPlainText(item)}`).join(\"\\n\");\n }\n if (\n node.type === \"blockquote\" ||\n node.type === \"listItem\" ||\n node.type === \"footnoteDefinition\"\n ) {\n return node.children.map((child) => blockToPlainText(child)).join(\"\\n\");\n }\n return toString(node);\n}\n\n/** A link or image URL that flattening is about to discard. */\nexport interface FlattenedUrl {\n readonly nodeType: \"link\" | \"image\";\n readonly url: string;\n}\n\n/**\n * Link and image URLs carried by a block that is about to be flattened.\n * {@link blockToPlainText} keeps only labels and alt text, so callers must\n * flag these before they disappear — silent omission is a bug even when the\n * surrounding flattening is itself already flagged.\n */\nexport function collectFlattenedUrls(node: unknown, into: FlattenedUrl[]): void {\n if (node === null || typeof node !== \"object\") {\n return;\n }\n const record = node as {\n readonly type?: string;\n readonly url?: string;\n readonly children?: ReadonlyArray<unknown>;\n };\n if ((record.type === \"link\" || record.type === \"image\") && typeof record.url === \"string\") {\n into.push({ nodeType: record.type, url: record.url });\n }\n if (record.children !== undefined) {\n for (const child of record.children) {\n collectFlattenedUrls(child, into);\n }\n }\n}\n","import {\n ConfigurationError,\n OperationAbortedError,\n OperationDeadlineExceededError,\n cloneOperationError,\n isOperationError,\n} from \"../errors.js\";\nimport type { OperationContext, OperationOptions } from \"../types.js\";\n\nexport interface OperationScope {\n readonly context: OperationContext;\n race<T>(promise: Promise<T>): Promise<T>;\n cleanup(): void;\n}\n\nexport function createOperationScope(options: OperationOptions, stage: string): OperationScope {\n validateOperationOptions(options);\n const controller = new AbortController();\n const abortFromCaller = (): void => {\n const reason = options.signal?.reason;\n controller.abort(\n isOperationError(reason)\n ? cloneOperationError(reason, stage)\n : new OperationAbortedError(stage, { cause: reason }),\n );\n };\n if (options.signal?.aborted === true) {\n abortFromCaller();\n } else {\n options.signal?.addEventListener(\"abort\", abortFromCaller, { once: true });\n }\n const deadlineMs = options.timeoutMs === undefined ? undefined : Date.now() + options.timeoutMs;\n const timeout =\n options.timeoutMs === undefined\n ? undefined\n : setTimeout(() => {\n controller.abort(new OperationDeadlineExceededError(stage));\n }, options.timeoutMs);\n const context: OperationContext = Object.freeze({\n signal: controller.signal,\n deadlineMs,\n });\n return {\n context,\n race: <T>(promise: Promise<T>): Promise<T> => raceWithContext(promise, context),\n cleanup: (): void => {\n if (timeout !== undefined) {\n clearTimeout(timeout);\n }\n options.signal?.removeEventListener(\"abort\", abortFromCaller);\n },\n };\n}\n\nexport function throwIfOperationEnded(context: OperationContext, stage: string): void {\n if (context.signal?.aborted === true) {\n const reason = context.signal.reason;\n throw isOperationError(reason) ? reason : new OperationAbortedError(stage, { cause: reason });\n }\n if (context.deadlineMs !== undefined && Date.now() >= context.deadlineMs) {\n throw new OperationDeadlineExceededError(stage);\n }\n}\n\nfunction raceWithContext<T>(promise: Promise<T>, context: OperationContext): Promise<T> {\n const signal = context.signal;\n if (signal?.aborted === true) {\n return Promise.reject(signal.reason);\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(signal?.reason);\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n void promise.then(\n (value) => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(value);\n return undefined;\n },\n (error: unknown) => {\n signal?.removeEventListener(\"abort\", onAbort);\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nfunction validateOperationOptions(options: OperationOptions): void {\n if (\n options.signal !== undefined &&\n (typeof options.signal !== \"object\" ||\n options.signal === null ||\n typeof options.signal.addEventListener !== \"function\" ||\n typeof options.signal.removeEventListener !== \"function\")\n ) {\n throw new ConfigurationError(\"signal must be an AbortSignal\", {\n code: \"invalid_signal\",\n stage: \"configuration\",\n });\n }\n if (\n options.timeoutMs !== undefined &&\n (!Number.isFinite(options.timeoutMs) || options.timeoutMs <= 0)\n ) {\n throw new ConfigurationError(\"timeoutMs must be positive\", {\n code: \"invalid_timeout\",\n stage: \"configuration\",\n });\n }\n}\n","import { resolveCapabilities } from \"../capabilities/capabilities.js\";\nimport type { ResolvedConfig } from \"../budget/conversion-context.js\";\nimport { ConfigurationError } from \"../errors.js\";\nimport {\n ConversionStrategy,\n OverflowMode,\n type ConvertOptions,\n type ImageRenderer,\n type MentionResolvers,\n type OperationContext,\n type OperationOptions,\n type RenderRequest,\n type SlackUploader,\n} from \"../types.js\";\n\nconst RENDERER_ID_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/u;\nconst CONVERT_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"capabilities\",\n \"capabilityOverrides\",\n \"overflow\",\n \"strategy\",\n \"renderers\",\n \"uploader\",\n \"enableMath\",\n \"enableInlineMath\",\n \"enableFrontmatter\",\n \"mentionResolvers\",\n \"signal\",\n \"timeoutMs\",\n]);\n\nexport function readOperationOptions(options: ConvertOptions | undefined): OperationOptions {\n if (options === undefined) {\n return {};\n }\n validatePlainOptions(options, CONVERT_OPTION_KEYS, \"conversion options\");\n try {\n return {\n signal: Reflect.get(options, \"signal\") as AbortSignal | undefined,\n timeoutMs: Reflect.get(options, \"timeoutMs\") as number | undefined,\n };\n } catch (cause) {\n throw new ConfigurationError(\"Operation options could not be read\", {\n code: \"invalid_operation_options\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\n/**\n * Merge defaults + per-call options into a frozen ResolvedConfig.\n */\nexport function resolveConfig(\n defaults: ConvertOptions,\n overrides: ConvertOptions | undefined,\n operation: OperationContext,\n): ResolvedConfig {\n validateOwnedOptionValues(defaults);\n if (overrides !== undefined) {\n validatePlainOptions(overrides, CONVERT_OPTION_KEYS, \"conversion options\");\n }\n let overrideSnapshot: ConvertOptions | undefined;\n try {\n overrideSnapshot = overrides === undefined ? undefined : { ...overrides };\n } catch (cause) {\n throw new ConfigurationError(\"Conversion options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n validateOwnedOptionValues(overrideSnapshot);\n let merged: ConvertOptions;\n try {\n merged = {\n ...defaults,\n ...overrideSnapshot,\n capabilityOverrides: {\n ...defaults.capabilityOverrides,\n ...overrideSnapshot?.capabilityOverrides,\n },\n renderers:\n overrideSnapshot !== undefined && Object.hasOwn(overrideSnapshot, \"renderers\")\n ? overrideSnapshot.renderers\n : defaults.renderers,\n uploader:\n overrideSnapshot !== undefined && Object.hasOwn(overrideSnapshot, \"uploader\")\n ? overrideSnapshot.uploader\n : defaults.uploader,\n mentionResolvers:\n overrideSnapshot !== undefined && Object.hasOwn(overrideSnapshot, \"mentionResolvers\")\n ? overrideSnapshot.mentionResolvers\n : defaults.mentionResolvers,\n };\n } catch (cause) {\n throw new ConfigurationError(\"Conversion options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n\n const capabilities = resolveCapabilities(merged.capabilities, merged.capabilityOverrides);\n\n const overflow = merged.overflow ?? OverflowMode.Degrade;\n if (overflow !== OverflowMode.Degrade && overflow !== OverflowMode.Split) {\n throw new ConfigurationError('Invalid overflow mode; use \"degrade\" or \"split\".');\n }\n\n const strategy = merged.strategy ?? ConversionStrategy.RichTextFirst;\n if (\n strategy !== ConversionStrategy.RichTextFirst &&\n strategy !== ConversionStrategy.MarkdownBlock\n ) {\n throw new ConfigurationError('Invalid strategy; use \"rich-text-first\" or \"markdown-block\".');\n }\n\n const renderers = resolveRendererDescriptors(merged.renderers);\n validateUploader(merged.uploader);\n if (merged.enableMath !== undefined && typeof merged.enableMath !== \"boolean\") {\n throw new ConfigurationError(\"enableMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (merged.enableInlineMath !== undefined && typeof merged.enableInlineMath !== \"boolean\") {\n throw new ConfigurationError(\"enableInlineMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (merged.enableFrontmatter !== undefined && typeof merged.enableFrontmatter !== \"boolean\") {\n throw new ConfigurationError(\"enableFrontmatter must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n const mentionResolvers = resolveMentionResolvers(merged.mentionResolvers);\n\n return Object.freeze({\n capabilities,\n overflow,\n strategy,\n renderers,\n uploader: merged.uploader,\n enableMath: merged.enableMath === true,\n enableInlineMath: merged.enableInlineMath === true,\n enableFrontmatter: merged.enableFrontmatter === true,\n mentionResolvers,\n operation,\n });\n}\n\nfunction resolveMentionResolvers(\n value: MentionResolvers | undefined,\n): MentionResolvers | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new ConfigurationError(\"mentionResolvers must be a plain object\", {\n code: \"invalid_mention_resolvers\",\n stage: \"configuration\",\n });\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n let resolveUser: unknown;\n let resolveChannel: unknown;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n resolveUser = Reflect.get(value, \"resolveUser\");\n resolveChannel = Reflect.get(value, \"resolveChannel\");\n } catch (cause) {\n throw new ConfigurationError(\"mentionResolvers could not be inspected\", {\n code: \"invalid_mention_resolvers\",\n stage: \"configuration\",\n cause,\n });\n }\n if (\n (prototype !== Object.prototype && prototype !== null) ||\n keys.some((key) => key !== \"resolveUser\" && key !== \"resolveChannel\") ||\n (resolveUser !== undefined && typeof resolveUser !== \"function\") ||\n (resolveChannel !== undefined && typeof resolveChannel !== \"function\")\n ) {\n throw new ConfigurationError(\"mentionResolvers is invalid\", {\n code: \"invalid_mention_resolvers\",\n stage: \"configuration\",\n });\n }\n return Object.freeze({\n resolveUser:\n resolveUser === undefined\n ? undefined\n : (handle: string): string | undefined =>\n (resolveUser as (handle: string) => string | undefined).call(value, handle),\n resolveChannel:\n resolveChannel === undefined\n ? undefined\n : (name: string): string | undefined =>\n (resolveChannel as (name: string) => string | undefined).call(value, name),\n });\n}\n\nexport function resolveRendererDescriptors(\n configured: ReadonlyArray<ImageRenderer> | undefined,\n): ReadonlyArray<ImageRenderer> {\n if (configured !== undefined && !Array.isArray(configured)) {\n throw new ConfigurationError(\"renderers must be an array\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n let inputRenderers: ReadonlyArray<ImageRenderer>;\n try {\n inputRenderers = Object.freeze([...(configured ?? [])]);\n } catch (cause) {\n throw new ConfigurationError(\"renderers must be an iterable renderer array\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n cause,\n });\n }\n const rendererIds = new Set<string>();\n const resolvedRenderers: ImageRenderer[] = [];\n for (const renderer of inputRenderers) {\n let id: unknown;\n let output: unknown;\n let canRender: unknown;\n let render: unknown;\n try {\n id = Reflect.get(renderer as object, \"id\");\n output = Reflect.get(renderer as object, \"output\");\n canRender = Reflect.get(renderer as object, \"canRender\");\n render = Reflect.get(renderer as object, \"render\");\n } catch (cause) {\n throw new ConfigurationError(\"Renderer descriptor could not be read\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n cause,\n });\n }\n if (\n typeof id !== \"string\" ||\n !RENDERER_ID_RE.test(id) ||\n (output !== \"url\" && output !== \"bytes\" && output !== \"both\") ||\n typeof canRender !== \"function\" ||\n typeof render !== \"function\"\n ) {\n throw new ConfigurationError(\"Renderer descriptor is invalid\", {\n code: \"invalid_renderer\",\n stage: \"configuration\",\n });\n }\n if (rendererIds.has(id)) {\n throw new ConfigurationError(`Duplicate renderer id: ${id}`, {\n code: \"duplicate_renderer_id\",\n stage: \"configuration\",\n });\n }\n rendererIds.add(id);\n const canRenderMethod = canRender as ImageRenderer[\"canRender\"];\n const renderMethod = render as ImageRenderer[\"render\"];\n resolvedRenderers.push(\n Object.freeze({\n id,\n output,\n canRender: (request: RenderRequest): boolean => canRenderMethod.call(renderer, request),\n render: (request: RenderRequest, context: OperationContext) =>\n renderMethod.call(renderer, request, context),\n }) as ImageRenderer,\n );\n }\n return Object.freeze(resolvedRenderers);\n}\n\nfunction validateOwnedOptionValues(options: ConvertOptions | undefined): void {\n if (options === undefined) {\n return;\n }\n resolveCapabilities(options.capabilities, options.capabilityOverrides);\n if (\n options.overflow !== undefined &&\n options.overflow !== OverflowMode.Degrade &&\n options.overflow !== OverflowMode.Split\n ) {\n throw new ConfigurationError('Invalid overflow mode; use \"degrade\" or \"split\".');\n }\n if (\n options.strategy !== undefined &&\n options.strategy !== ConversionStrategy.RichTextFirst &&\n options.strategy !== ConversionStrategy.MarkdownBlock\n ) {\n throw new ConfigurationError('Invalid strategy; use \"rich-text-first\" or \"markdown-block\".');\n }\n resolveRendererDescriptors(options.renderers);\n validateUploader(options.uploader);\n if (options.enableMath !== undefined && typeof options.enableMath !== \"boolean\") {\n throw new ConfigurationError(\"enableMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableInlineMath !== undefined && typeof options.enableInlineMath !== \"boolean\") {\n throw new ConfigurationError(\"enableInlineMath must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n if (options.enableFrontmatter !== undefined && typeof options.enableFrontmatter !== \"boolean\") {\n throw new ConfigurationError(\"enableFrontmatter must be boolean\", {\n code: \"invalid_option\",\n stage: \"configuration\",\n });\n }\n resolveMentionResolvers(options.mentionResolvers);\n}\n\nfunction validateUploader(uploader: SlackUploader | undefined): void {\n if (uploader === undefined) {\n return;\n }\n try {\n if (\n (typeof uploader !== \"object\" && typeof uploader !== \"function\") ||\n uploader === null ||\n typeof Reflect.get(uploader, \"upload\") !== \"function\"\n ) {\n throw new TypeError(\"upload must be a function\");\n }\n } catch (cause) {\n throw new ConfigurationError(\"uploader is invalid\", {\n code: \"invalid_uploader\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction validatePlainOptions(\n value: object,\n allowedKeys: ReadonlySet<string>,\n label: string,\n): void {\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n } catch (cause) {\n throw new ConfigurationError(`${label} could not be inspected`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ConfigurationError(`${label} must be a plain object`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw new ConfigurationError(`Unknown ${label} key: ${key}`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n }\n}\n","import type { Definition, FootnoteDefinition, Heading, Root, RootContent } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport { collectFlattenedUrls, type FlattenedUrl } from \"../adapters/block-to-plain-text.js\";\nimport type { Block } from \"../blocks/types.js\";\nimport { ConversionContext, type ResolvedConfig } from \"../budget/conversion-context.js\";\nimport { RecordingDegradationCollector } from \"../budget/recording-degradation-collector.js\";\nimport { RecordingReceiptCollector } from \"../budget/recording-receipt-collector.js\";\nimport { StandardBudgetLedger } from \"../budget/standard-budget-ledger.js\";\nimport { createOperationScope, throwIfOperationEnded } from \"../budget/operation-scope.js\";\nimport {\n buildFootnoteBlocks,\n coalescedBlockCount,\n type MessageAssembler,\n} from \"../assemble/message-assembler.js\";\nimport type { AdapterRegistry } from \"../registry/adapter-registry.js\";\nimport {\n MAX_BLOCKS_PER_MESSAGE,\n MESSAGE_TEXT_SAFETY_MAX_CHARS,\n SECTION_TEXT_MAX_CHARS,\n} from \"../constants.js\";\nimport {\n ConfigurationError,\n attachReceipts,\n cloneConfigurationError,\n cloneOperationError,\n isConfigurationError,\n isOperationError,\n isOperationErrorCarrier,\n lockReceiptSnapshot,\n} from \"../errors.js\";\nimport { sliceSurrogateSafe, surrogateSafeEnd } from \"../utf16.js\";\nimport type {\n ConversionMessagesResult,\n ConversionResult,\n ConvertOptions,\n DegradationCollector,\n MarkdownParser,\n OperationContext,\n PlainTextRenderer,\n ReceiptCollector,\n} from \"../types.js\";\nimport { ConversionStrategy, OverflowMode } from \"../types.js\";\n\nimport { readOperationOptions, resolveConfig } from \"./resolve-config.js\";\n\nexport interface SlackMarkConverterDeps {\n readonly parser: MarkdownParser;\n readonly registry: AdapterRegistry;\n readonly assembler: MessageAssembler;\n readonly plainText: PlainTextRenderer;\n readonly defaultOptions: ConvertOptions;\n}\n\n/**\n * Primary public API class — stateless across concurrent convert() calls.\n */\nexport class SlackMarkConverter {\n private readonly parser: MarkdownParser;\n private readonly registry: AdapterRegistry;\n private readonly assembler: MessageAssembler;\n private readonly plainText: PlainTextRenderer;\n private readonly defaultOptions: ConvertOptions;\n\n constructor(deps: SlackMarkConverterDeps) {\n this.parser = deps.parser;\n this.registry = deps.registry;\n this.assembler = deps.assembler;\n this.plainText = deps.plainText;\n this.defaultOptions = deps.defaultOptions;\n }\n\n /**\n * Convert markdown to a single message. Always uses overflow=degrade so content\n * is truncated with degradations rather than silently dropping split messages.\n * Callers that need multi-message output should use {@link convertToMessages}.\n */\n async convert(markdown: string, options?: ConvertOptions): Promise<ConversionResult> {\n readOperationOptions(options);\n resolveConfig(this.defaultOptions, options, {\n signal: undefined,\n deadlineMs: undefined,\n });\n let singleOptions: ConvertOptions;\n try {\n singleOptions = { ...options, overflow: OverflowMode.Degrade };\n } catch (cause) {\n throw new ConfigurationError(\"Conversion options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n const multi = await this.convertToMessages(markdown, singleOptions);\n const first = multi.messages[0] ?? { blocks: [], text: \" \" };\n return {\n blocks: first.blocks,\n text: first.text,\n degradations: multi.degradations,\n receipts: multi.receipts,\n };\n }\n\n /**\n * Advanced execution seam for orchestrators that already own an absolute\n * operation context. The returned promise tracks underlying conversion work.\n */\n async convertWithContext(\n markdown: string,\n options: ConvertOptions | undefined,\n operation: OperationContext,\n receipts: ReceiptCollector = new RecordingReceiptCollector(),\n ): Promise<ConversionResult> {\n // Overriding `overflow` below hides an invalid caller value from `resolveConfig`,\n // so validate the caller's options first — as `convert()` does.\n resolveConfig(this.defaultOptions, options, operation);\n const multi = await this.convertToMessagesWithContext(\n markdown,\n { ...options, overflow: OverflowMode.Degrade },\n operation,\n receipts,\n );\n const first = multi.messages[0] ?? { blocks: [], text: \" \" };\n return {\n blocks: first.blocks,\n text: first.text,\n degradations: multi.degradations,\n receipts: multi.receipts,\n };\n }\n\n /**\n * Convert markdown into one or more messages at semantic boundaries.\n */\n async convertToMessages(\n markdown: string,\n options?: ConvertOptions,\n ): Promise<ConversionMessagesResult> {\n const receipts = new RecordingReceiptCollector();\n const operation = createOperationScope(readOperationOptions(options), \"conversion\");\n const underlying = this.convertUnderOperation(markdown, options, operation.context, receipts);\n settleReceiptsWith(underlying, receipts);\n try {\n return await operation.race(underlying);\n } catch (error) {\n throw lockReceiptSnapshot(attachReceipts(error, receipts.all(), receipts.settled()));\n } finally {\n operation.cleanup();\n }\n }\n\n /**\n * Advanced multi-message seam paired with {@link convertWithContext}.\n */\n async convertToMessagesWithContext(\n markdown: string,\n options: ConvertOptions | undefined,\n operation: OperationContext,\n receipts: ReceiptCollector = new RecordingReceiptCollector(),\n ): Promise<ConversionMessagesResult> {\n try {\n return await this.convertUnderOperation(markdown, options, operation, receipts);\n } catch (error) {\n throw attachReceipts(error, receipts.all(), receipts.settled());\n } finally {\n receipts.settle();\n }\n }\n\n private async convertUnderOperation(\n markdown: string,\n options: ConvertOptions | undefined,\n operation: OperationContext,\n receipts: ReceiptCollector,\n ): Promise<ConversionMessagesResult> {\n throwIfOperationEnded(operation, \"conversion\");\n const config = resolveConfig(this.defaultOptions, options, operation);\n const degradations = new RecordingDegradationCollector();\n // When splitting, lift the block + chart caps during emission; the assembler\n // re-applies per-message budgets. Table/markdown/total char caps stay on so\n // oversized single blocks cannot be emitted.\n const splitting = config.overflow === OverflowMode.Split;\n const budget = new StandardBudgetLedger(\n splitting ? Number.MAX_SAFE_INTEGER : MAX_BLOCKS_PER_MESSAGE,\n { enforceChartCap: !splitting },\n );\n\n try {\n if (config.strategy === ConversionStrategy.MarkdownBlock) {\n return this.emitAsMarkdownBlocks(markdown, config, degradations, receipts, budget);\n }\n\n const tree = await this.parser.parse(markdown, {\n enableMath: config.enableMath,\n enableInlineMath: config.enableInlineMath,\n enableFrontmatter: config.enableFrontmatter,\n });\n throwIfOperationEnded(operation, \"parse\");\n\n const { definitions, footnotes, footnoteOrder } = collectRefs(tree, degradations);\n let precedingHeading: string | undefined;\n const emitted: Block[] = [];\n\n let index = 0;\n for (const node of tree.children) {\n throwIfOperationEnded(operation, \"conversion\");\n // Message boundaries are chosen after emission. In split mode, validate\n // each semantic unit against an empty message, then let the assembler\n // enforce cumulative limits for the messages it creates.\n if (splitting) {\n budget.resetForNewMessage();\n }\n const ctx = new ConversionContext({\n config,\n budget,\n degradations,\n receipts,\n definitions,\n footnotes,\n footnoteOrder,\n precedingHeading,\n path: `root[${String(index)}]`,\n });\n\n if (node.type === \"heading\") {\n precedingHeading = toString(node as Heading);\n }\n\n const reservedBefore = budget.snapshot().blocks;\n const blocks = await this.registry.emit(node as RootContent, ctx);\n refundCoalescedBlocks(budget, reservedBefore, emitted.at(-1), blocks);\n emitted.push(...blocks);\n index += 1;\n }\n\n const footnoteNumbers = new Map<string, number>();\n footnoteOrder.forEach((id, i) => footnoteNumbers.set(id, i + 1));\n const footnoteEntries = footnoteOrder.map((id, i) => {\n const def = footnotes.get(id);\n if (def !== undefined) {\n const dropped: FlattenedUrl[] = [];\n collectFlattenedUrls(def, dropped);\n for (const { nodeType, url } of dropped) {\n degradations.add({\n nodeType,\n from: url,\n to: \"label_only\",\n reason: \"Footnote body renders as plain context text; URL dropped\",\n path: `footnote[${String(i + 1)}]`,\n });\n }\n }\n return {\n n: i + 1,\n text: def !== undefined ? footnoteBodyText(def, footnoteNumbers).trim() : id,\n };\n });\n const footnoteBlocks = buildFootnoteBlocks(footnoteEntries, degradations);\n\n const assembleCtx = new ConversionContext({\n config,\n budget,\n degradations,\n receipts,\n definitions,\n footnotes,\n footnoteOrder,\n precedingHeading,\n path: \"assemble\",\n });\n const messages = this.assembler.assemble(emitted, assembleCtx, footnoteBlocks);\n\n return {\n messages,\n degradations: degradations.all(),\n receipts: receipts.all(),\n };\n } catch (err) {\n if (isConfigurationError(err)) {\n throw cloneConfigurationError(err);\n }\n if (isOperationError(err)) {\n throw err === operation.signal?.reason || isOperationErrorCarrier(err)\n ? err\n : cloneOperationError(err, \"conversion\");\n }\n // User markdown must never throw — degrade to a single section.\n degradations.add({\n nodeType: \"document\",\n from: \"convert\",\n to: \"section\",\n reason: \"Conversion failed; emitted plain-text fallback\",\n path: \"root\",\n details: {\n code: \"document_conversion_failed\",\n stage: \"conversion\",\n retryable: false,\n },\n });\n const text = safeNotificationText(this.plainText, markdown, degradations);\n return {\n messages: [\n {\n blocks: [\n {\n type: \"section\",\n text: { type: \"mrkdwn\", text: clampSectionFallback(text, degradations) },\n },\n ],\n text,\n },\n ],\n degradations: degradations.all(),\n receipts: receipts.all(),\n };\n }\n }\n\n private emitAsMarkdownBlocks(\n markdown: string,\n config: ResolvedConfig,\n degradations: RecordingDegradationCollector,\n receipts: ReceiptCollector,\n budget: StandardBudgetLedger,\n ): ConversionMessagesResult {\n const chunks = chunkMarkdown(markdown, 12_000);\n let blocks: Block[] = [];\n if (!config.capabilities.markdownBlock) {\n degradations.add({\n nodeType: \"document\",\n from: \"markdown-block\",\n to: \"section\",\n reason: \"markdownBlock capability off; emitting section fallback\",\n path: \"root\",\n });\n const text = safeNotificationText(this.plainText, markdown, degradations);\n blocks = [\n {\n type: \"section\",\n text: { type: \"mrkdwn\", text: clampSectionFallback(text, degradations) },\n },\n ];\n } else {\n for (const chunk of chunks) {\n if (config.overflow === OverflowMode.Split) {\n budget.resetForNewMessage();\n }\n if (!budget.tryReserveClaim({ blocks: 1, markdownChars: chunk.length })) {\n degradations.add({\n nodeType: \"document\",\n from: \"markdown-block\",\n to: \"truncated\",\n reason: \"markdown 12k cumulative budget exhausted\",\n path: \"root\",\n });\n break;\n }\n blocks.push({ type: \"markdown\", text: chunk });\n }\n }\n\n const assembleCtx = new ConversionContext({\n config,\n budget,\n degradations,\n receipts,\n definitions: new Map(),\n footnotes: new Map(),\n footnoteOrder: [],\n precedingHeading: undefined,\n path: \"assemble\",\n });\n // Markdown strategy has no GFM footnote pass; assembler still applies overflow split/degrade.\n const messages = this.assembler.assemble(blocks, assembleCtx, []);\n return {\n messages,\n degradations: degradations.all(),\n receipts: receipts.all(),\n };\n }\n}\n\n/**\n * Reconcile a node's block reservation with the blocks it actually contributes.\n *\n * A node reserves its blocks before it emits, which is the only order that can gate an\n * adapter. Once the node has emitted, adjacent rich_text sections are known to merge\n * during assembly, so the reservation is reduced to the merged count. Character and chart\n * totals are untouched: coalescing does not shrink them.\n */\nfunction refundCoalescedBlocks(\n budget: StandardBudgetLedger,\n reservedBefore: number,\n previous: Block | undefined,\n blocks: ReadonlyArray<Block>,\n): void {\n const snapshot = budget.snapshot();\n const reserved = snapshot.blocks - reservedBefore;\n const actual = coalescedBlockCount(previous, blocks);\n if (reserved <= actual) {\n return;\n }\n budget.restore({ ...snapshot, blocks: snapshot.blocks - (reserved - actual) });\n}\n\nfunction settleReceiptsWith(promise: Promise<unknown>, receipts: ReceiptCollector): void {\n void promise.then(\n () => {\n receipts.settle();\n return undefined;\n },\n () => {\n receipts.settle();\n return undefined;\n },\n );\n}\n\nfunction safeNotificationText(\n plainText: PlainTextRenderer,\n markdown: string,\n degradations: DegradationCollector,\n): string {\n const raw = plainText.render(markdown);\n if (raw.length <= MESSAGE_TEXT_SAFETY_MAX_CHARS) {\n return raw;\n }\n degradations.add({\n nodeType: \"message\",\n from: `${String(raw.length)} text chars`,\n to: `${String(MESSAGE_TEXT_SAFETY_MAX_CHARS)} text chars`,\n reason: \"Notification text truncated to 40k safety limit\",\n path: \"root\",\n });\n return sliceSurrogateSafe(raw, MESSAGE_TEXT_SAFETY_MAX_CHARS);\n}\n\nfunction clampSectionFallback(text: string, degradations: DegradationCollector): string {\n if (text.length <= SECTION_TEXT_MAX_CHARS) {\n return text;\n }\n degradations.add({\n nodeType: \"section\",\n from: `${String(text.length)} chars`,\n to: `${String(SECTION_TEXT_MAX_CHARS)} chars`,\n reason: \"Section text truncated to 3000 chars\",\n path: \"root\",\n });\n return sliceSurrogateSafe(text, SECTION_TEXT_MAX_CHARS);\n}\n\nfunction collectRefs(\n tree: Root,\n degradations: DegradationCollector,\n): {\n definitions: Map<string, Definition>;\n footnotes: Map<string, FootnoteDefinition>;\n footnoteOrder: string[];\n} {\n const definitions = new Map<string, Definition>();\n const footnotes = new Map<string, FootnoteDefinition>();\n // CommonMark: when identifiers collide, the first definition takes\n // precedence (spec §Link reference definitions); mdast-util-to-hast applies\n // the same rule to footnote definitions. Ignored duplicates are flagged.\n for (const node of tree.children) {\n if (node.type === \"definition\") {\n const key = node.identifier.toLowerCase();\n if (definitions.has(key)) {\n degradations.add({\n nodeType: \"definition\",\n from: node.identifier,\n to: \"ignored\",\n reason: \"Duplicate link reference definition; first definition wins\",\n path: \"root\",\n });\n } else {\n definitions.set(key, node);\n }\n }\n if (node.type === \"footnoteDefinition\") {\n if (footnotes.has(node.identifier)) {\n degradations.add({\n nodeType: \"footnoteDefinition\",\n from: node.identifier,\n to: \"ignored\",\n reason: \"Duplicate footnote definition; first definition wins\",\n path: \"root\",\n });\n } else {\n footnotes.set(node.identifier, node);\n }\n }\n }\n // Number footnotes by first reference in document order (not definition order).\n const footnoteOrder: string[] = [];\n const seen = new Set<string>();\n walkFootnoteReferences(tree, (id) => {\n if (!seen.has(id)) {\n seen.add(id);\n footnoteOrder.push(id);\n }\n });\n // Footnotes referenced only from other footnote bodies are rendered too\n // (GitHub lists them after body-referenced ones); breadth-first over the\n // bodies of already-ordered footnotes, cycle-safe via `seen`.\n for (let i = 0; i < footnoteOrder.length; i += 1) {\n const def = footnotes.get(footnoteOrder[i] ?? \"\");\n if (def === undefined) {\n continue;\n }\n for (const child of def.children) {\n walkFootnoteReferences(child, (id) => {\n if (!seen.has(id)) {\n seen.add(id);\n footnoteOrder.push(id);\n }\n });\n }\n }\n return { definitions, footnotes, footnoteOrder };\n}\n\n/**\n * Separator inserted between the children of a flattened footnote body node.\n * Without these, sibling paragraphs and table cells run together as\n * \"para onepara two\" / \"ab12\".\n */\nconst FOOTNOTE_CHILD_SEPARATORS: ReadonlyMap<string, string> = new Map([\n [\"footnoteDefinition\", \"\\n\"],\n [\"blockquote\", \"\\n\"],\n [\"list\", \"\\n\"],\n [\"listItem\", \"\\n\"],\n [\"table\", \"\\n\"],\n [\"tableRow\", \" | \"],\n]);\n\n/**\n * Footnote definition body as plain text with nested footnote references\n * rendered as their `[n]` markers (mdast-util-to-string drops them entirely).\n */\nfunction footnoteBodyText(node: unknown, numbers: ReadonlyMap<string, number>): string {\n if (node === null || typeof node !== \"object\") {\n return \"\";\n }\n const record = node as {\n readonly type?: string;\n readonly identifier?: string;\n readonly value?: string;\n readonly alt?: string;\n readonly children?: ReadonlyArray<unknown>;\n };\n if (record.type === \"footnoteReference\" && typeof record.identifier === \"string\") {\n const n = numbers.get(record.identifier);\n return n !== undefined ? `[${String(n)}]` : `[^${record.identifier}]`;\n }\n if (typeof record.value === \"string\") {\n return record.value;\n }\n if (typeof record.alt === \"string\") {\n return record.alt;\n }\n if (record.children !== undefined) {\n const parts: string[] = [];\n for (const child of record.children) {\n parts.push(footnoteBodyText(child, numbers));\n }\n const separator =\n record.type !== undefined ? (FOOTNOTE_CHILD_SEPARATORS.get(record.type) ?? \"\") : \"\";\n return parts.join(separator);\n }\n return \"\";\n}\n\nfunction walkFootnoteReferences(node: unknown, onRef: (id: string) => void): void {\n if (node === null || typeof node !== \"object\") {\n return;\n }\n const record = node as {\n readonly type?: string;\n readonly identifier?: string;\n readonly children?: ReadonlyArray<unknown>;\n };\n // Definitions are not part of reading-order numbering.\n if (record.type === \"footnoteDefinition\") {\n return;\n }\n if (record.type === \"footnoteReference\" && typeof record.identifier === \"string\") {\n onRef(record.identifier);\n return;\n }\n if (record.children !== undefined) {\n for (const child of record.children) {\n walkFootnoteReferences(child, onRef);\n }\n }\n}\n\nfunction chunkMarkdown(text: string, max: number): string[] {\n if (text.length <= max) {\n return [text.length > 0 ? text : \" \"];\n }\n const out: string[] = [];\n let i = 0;\n while (i < text.length) {\n // Chunk boundaries must not split a surrogate pair (max ≥ 2 guarantees progress).\n const end = surrogateSafeEnd(text, i + max);\n out.push(text.slice(i, end));\n i = end;\n }\n return out;\n}\n","import type { Emphasis, Link, LinkReference, PhrasingContent, Strong, Text } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type {\n ImageBlock,\n RichTextBlock,\n RichTextEmoji,\n RichTextInline,\n RichTextLink,\n RichTextStyle,\n RichTextText,\n} from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport {\n ELLIPSIS,\n IMAGE_ALT_MAX_CHARS,\n IMAGE_URL_MAX_CHARS,\n SECTION_TEXT_MAX_CHARS,\n} from \"../constants.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\n\nconst HTTP_URL_RE = /^(https?:|mailto:)/i;\nconst IMAGE_EXT_RE = /\\.(png|jpe?g|gif)(?:\\?|#|$)/i;\n\nexport type HoistedImage = {\n readonly url: string;\n readonly alt: string;\n readonly title: string | undefined;\n};\n\nexport interface InlineEmitResult {\n readonly elements: ReadonlyArray<RichTextInline>;\n readonly hoistedImages: ReadonlyArray<HoistedImage>;\n}\n\n/**\n * Convert mdast phrasing content into rich_text inline elements.\n */\nexport function emitPhrasing(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n baseStyle: RichTextStyle = {},\n): InlineEmitResult {\n const elements: RichTextInline[] = [];\n const hoistedImages: HoistedImage[] = [];\n // Mutable working copy: Slack labeled links with spaces (<https://u|two words>)\n // parse as text(\"…<\") + autolink + text(\"words>…\") and are reassembled in place.\n const work: PhrasingContent[] = [...nodes];\n // remark splits <a href>label</a> into html/text/html siblings — track across nodes.\n let pendingAnchor: OpenAnchor | undefined;\n // remark also splits <b>bold</b> into html/text/html siblings, so formatting\n // tags must style the text nodes BETWEEN them; a per-call stack tracks the\n // currently open cross-node tags.\n const htmlStyles: RichTextStyle[] = [];\n const activeStyle = (): RichTextStyle => htmlStyles[htmlStyles.length - 1] ?? baseStyle;\n\n const flushPendingAnchor = (): void => {\n if (pendingAnchor === undefined) {\n return;\n }\n elements.push(anchorInline(pendingAnchor, ctx));\n pendingAnchor = undefined;\n };\n\n for (let i = 0; i < work.length; i += 1) {\n const node = work[i] as PhrasingContent;\n if (pendingAnchor === undefined) {\n const reassembled = reassembleSlackLabeledLink(work, i, activeStyle());\n if (reassembled !== undefined) {\n if (reassembled.leadingText.value.length > 0) {\n elements.push(\n ...emitTextWithMentionsAndEmoji(reassembled.leadingText, activeStyle(), ctx),\n );\n }\n elements.push(reassembled.link);\n // Drop the lead+autolink+tail trio so the fractured autolink cannot be\n // emitLink'd again; keep only a non-empty trailing remnant for the next pass.\n if (reassembled.trailingText.value.length > 0) {\n work.splice(i, 3, reassembled.trailingText);\n } else {\n work.splice(i, 3);\n }\n i -= 1;\n continue;\n }\n }\n if (pendingAnchor !== undefined) {\n if (node.type === \"html\" && /^<\\/a\\s*>$/i.test(node.value.trim())) {\n flushPendingAnchor();\n continue;\n }\n if (node.type === \"text\") {\n pendingAnchor.textParts.push(node.value);\n continue;\n }\n if (node.type === \"break\") {\n pendingAnchor.textParts.push(\"\\n\");\n continue;\n }\n pendingAnchor.textParts.push(toString(node));\n continue;\n }\n\n if (node.type === \"html\") {\n const trimmed = node.value.trim();\n // remark parses <!here>, <!date^…>, <!subteam^…> as inline html — convert\n // them to their rich text elements instead of stripping (silent mangling).\n const entityInlines = slackEntityRichTextInlines(trimmed, activeStyle());\n if (entityInlines !== undefined) {\n elements.push(...entityInlines);\n continue;\n }\n const openOnly = /^<a\\b([^>]{0,500})>\\s*$/i.exec(trimmed);\n if (openOnly !== null) {\n const hrefMatch = /href\\s*=\\s*[\"']([^\"']{0,3000})[\"']/i.exec(openOnly[1] ?? \"\");\n const href = hrefMatch?.[1];\n if (href !== undefined) {\n // Invalid hrefs still collect the label so the anchor text is not lost;\n // the flush degrades them to text with the URL as a suffix.\n pendingAnchor = {\n href,\n style: activeStyle(),\n textParts: [],\n valid: isValidLinkUrl(href),\n };\n continue;\n }\n }\n const openTag = HTML_STYLE_OPEN_RE.exec(trimmed);\n if (openTag !== null) {\n htmlStyles.push(htmlTagStyle(activeStyle(), openTag[1] ?? \"\"));\n continue;\n }\n if (HTML_STYLE_CLOSE_RE.test(trimmed)) {\n htmlStyles.pop();\n continue;\n }\n elements.push(...emitInlineHtml(node.value, activeStyle(), ctx));\n continue;\n }\n\n switch (node.type) {\n case \"text\": {\n elements.push(...emitTextWithMentionsAndEmoji(node as Text, activeStyle(), ctx));\n break;\n }\n case \"strong\": {\n const inner = emitPhrasing((node as Strong).children, ctx, {\n ...activeStyle(),\n bold: true,\n });\n elements.push(...inner.elements);\n hoistedImages.push(...inner.hoistedImages);\n break;\n }\n case \"emphasis\": {\n const inner = emitPhrasing((node as Emphasis).children, ctx, {\n ...activeStyle(),\n italic: true,\n });\n elements.push(...inner.elements);\n hoistedImages.push(...inner.hoistedImages);\n break;\n }\n case \"delete\": {\n const inner = emitPhrasing(node.children, ctx, { ...activeStyle(), strike: true });\n elements.push(...inner.elements);\n hoistedImages.push(...inner.hoistedImages);\n break;\n }\n case \"inlineCode\": {\n const el: RichTextText = {\n type: \"text\",\n text: node.value,\n style: styleOrUndefined({ ...activeStyle(), code: true }),\n };\n elements.push(el);\n break;\n }\n case \"break\": {\n elements.push({ type: \"text\", text: \"\\n\", style: styleOrUndefined(activeStyle()) });\n break;\n }\n case \"link\": {\n elements.push(...emitLink(node, ctx, activeStyle()));\n break;\n }\n case \"linkReference\": {\n elements.push(...emitLinkReference(node, ctx, activeStyle()));\n break;\n }\n case \"image\": {\n const url = node.url;\n if (isPublicImageUrl(url)) {\n hoistedImages.push({\n url,\n alt: node.alt ?? \"\",\n title: node.title ?? undefined,\n });\n elements.push({\n type: \"link\",\n url,\n text: node.alt && node.alt.length > 0 ? node.alt : url,\n style: styleOrUndefined(activeStyle()),\n });\n } else {\n // Slack link elements require absolute http(s)/mailto URLs; anything\n // else (relative, ftp:, data:, empty) must degrade to text or the\n // whole message is rejected with invalid_blocks.\n const linkable = isValidLinkUrl(url);\n ctx.degradations.add({\n nodeType: \"image\",\n from: \"image\",\n to: linkable ? \"link\" : \"text\",\n reason: \"Image URL is not a public http(s) png/jpg/gif ≤3000 chars\",\n path: ctx.path,\n });\n const label = node.alt && node.alt.length > 0 ? node.alt : url.length > 0 ? url : \"image\";\n if (linkable) {\n elements.push({\n type: \"link\",\n url,\n text: label,\n style: styleOrUndefined(activeStyle()),\n });\n } else {\n const suffix = url.length > 0 && url !== label ? ` (${url})` : \"\";\n elements.push({\n type: \"text\",\n text: `${label}${suffix}`,\n style: styleOrUndefined(activeStyle()),\n });\n }\n }\n break;\n }\n case \"imageReference\": {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n if (def === undefined) {\n elements.push({\n type: \"text\",\n text: node.alt ?? node.identifier,\n style: styleOrUndefined(activeStyle()),\n });\n break;\n }\n const asImage = emitPhrasing(\n [\n {\n type: \"image\",\n url: def.url,\n alt: node.alt ?? undefined,\n title: def.title ?? undefined,\n },\n ],\n ctx,\n activeStyle(),\n );\n elements.push(...asImage.elements);\n hoistedImages.push(...asImage.hoistedImages);\n break;\n }\n case \"footnoteReference\": {\n const idx = ctx.footnoteOrder.indexOf(node.identifier);\n const n = idx >= 0 ? idx + 1 : 1;\n elements.push({\n type: \"text\",\n text: `[${String(n)}]`,\n style: styleOrUndefined(activeStyle()),\n });\n break;\n }\n case \"inlineMath\": {\n elements.push({\n type: \"text\",\n text: node.value,\n style: styleOrUndefined({ ...activeStyle(), code: true }),\n });\n ctx.degradations.add({\n nodeType: \"inlineMath\",\n from: \"inlineMath\",\n to: \"style.code\",\n reason: \"Math is emitted as preformatted/code text\",\n path: ctx.path,\n });\n break;\n }\n default: {\n const text = toString(node);\n if (text.length > 0) {\n elements.push({ type: \"text\", text, style: styleOrUndefined(activeStyle()) });\n }\n break;\n }\n }\n }\n\n flushPendingAnchor();\n return { elements: coalesceText(elements), hoistedImages };\n}\n\n/**\n * Plain string from phrasing (strips styles) — for headers etc.\n */\nexport function phrasingToPlain(nodes: ReadonlyArray<PhrasingContent>): string {\n return toString({ type: \"paragraph\", children: nodes as PhrasingContent[] });\n}\n\nexport function isPublicImageUrl(url: string): boolean {\n if (url.length === 0 || url.length > IMAGE_URL_MAX_CHARS) {\n return false;\n }\n if (!HTTP_URL_RE.test(url)) {\n return false;\n }\n if (\n /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0|10\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[01])\\.)/i.test(\n url,\n )\n ) {\n return false;\n }\n return IMAGE_EXT_RE.test(url);\n}\n\n/**\n * Count images that {@link emitPhrasing} would hoist into separate image blocks.\n */\nexport function countHoistableImages(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n): number {\n let count = 0;\n for (const node of nodes) {\n switch (node.type) {\n case \"image\": {\n if (isPublicImageUrl(node.url)) {\n count += 1;\n }\n break;\n }\n case \"imageReference\": {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n if (def !== undefined && isPublicImageUrl(def.url)) {\n count += 1;\n }\n break;\n }\n case \"strong\":\n case \"emphasis\":\n case \"delete\": {\n count += countHoistableImages(node.children, ctx);\n break;\n }\n case \"text\":\n case \"inlineCode\":\n case \"break\":\n case \"link\":\n case \"linkReference\":\n case \"footnoteReference\":\n case \"html\":\n case \"inlineMath\":\n break;\n default: {\n // Other phrasing (e.g. extensions) cannot hoist images.\n break;\n }\n }\n }\n return count;\n}\n\n/**\n * Record images a link label swallows. Slack link elements carry plain text, and hoisting\n * would detach the image from its link, so only the alt text survives.\n */\nfunction flagImagesLostInLabel(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n): void {\n for (const node of nodes) {\n switch (node.type) {\n case \"image\": {\n addImageLostInLabel(node.url, ctx);\n break;\n }\n case \"imageReference\": {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n addImageLostInLabel(def?.url ?? node.identifier, ctx);\n break;\n }\n case \"strong\":\n case \"emphasis\":\n case \"delete\": {\n flagImagesLostInLabel(node.children, ctx);\n break;\n }\n case \"text\":\n case \"inlineCode\":\n case \"break\":\n case \"link\":\n case \"linkReference\":\n case \"footnoteReference\":\n case \"html\":\n case \"inlineMath\":\n break;\n default: {\n // Other phrasing (e.g. extensions) cannot carry images.\n break;\n }\n }\n }\n}\n\nfunction addImageLostInLabel(url: string, ctx: ConversionContext): void {\n ctx.degradations.add({\n nodeType: \"image\",\n from: \"image\",\n to: \"text\",\n reason: `Image nested in a link is dropped; only its alt text survives (${url})`,\n path: ctx.path,\n });\n}\n\nexport function truncateLabel(label: string, max: number): { text: string; truncated: boolean } {\n if (label.length <= max) {\n return { text: label, truncated: false };\n }\n return { text: `${sliceSurrogateSafe(label, Math.max(0, max - 1))}${ELLIPSIS}`, truncated: true };\n}\n\n/** Standalone image block for an image hoisted out of phrasing content. */\nexport function hoistedImageBlock(h: HoistedImage, ctx: ConversionContext): ImageBlock {\n return {\n type: \"image\",\n image_url: h.url,\n alt_text: clampImageText(h.alt.length > 0 ? h.alt : \"image\", ctx, \"alt_text\"),\n title:\n h.title !== undefined && h.title.length > 0\n ? { type: \"plain_text\", text: clampImageText(h.title, ctx, \"title\") }\n : undefined,\n };\n}\n\n/** Clamp section mrkdwn to 3000 chars and record a degradation when clipped. */\nexport function clampSectionText(text: string, ctx: ConversionContext, nodeType: string): string {\n if (text.length <= SECTION_TEXT_MAX_CHARS) {\n return text;\n }\n ctx.degradations.add({\n nodeType,\n from: `${String(text.length)} chars`,\n to: `${String(SECTION_TEXT_MAX_CHARS)} chars`,\n reason: \"Section text truncated to 3000 chars\",\n path: ctx.path,\n });\n return sliceSurrogateSafe(text, SECTION_TEXT_MAX_CHARS);\n}\n\n/** rich_text_preformatted block shared by code/math/mermaid/table fallbacks. */\nexport function preformattedRichText(text: string, language: string | undefined): RichTextBlock {\n return {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_preformatted\",\n elements: [{ type: \"text\", text: text.length > 0 ? text : \" \" }],\n border: 0,\n language,\n },\n ],\n };\n}\n\n/** Clamp image alt/title to Slack limits and record a degradation when clipped. */\nexport function clampImageText(\n value: string,\n ctx: ConversionContext,\n field: \"alt_text\" | \"title\",\n): string {\n if (value.length <= IMAGE_ALT_MAX_CHARS) {\n return value;\n }\n ctx.degradations.add({\n nodeType: \"image\",\n from: field,\n to: \"truncated\",\n reason: `Image ${field} truncated to ${String(IMAGE_ALT_MAX_CHARS)} chars`,\n path: ctx.path,\n });\n return sliceSurrogateSafe(value, IMAGE_ALT_MAX_CHARS);\n}\n\nfunction styleOrUndefined(style: RichTextStyle): RichTextStyle | undefined {\n if (\n style.bold === true ||\n style.italic === true ||\n style.strike === true ||\n style.code === true ||\n style.underline === true\n ) {\n return style;\n }\n return undefined;\n}\n\n// Raw Slack mrkdwn entity tokens (<@U…>, <#C…>, <!here>, <!subteam^S…>, <!date^…>).\n// These carry Slack IDs directly, so they convert unconditionally — no resolvers needed.\n// Sticky + ignoreCase (`iy`) candidate form for the single-pass scanner; strict parse follows.\nconst SLACK_ENTITY_AT_RE =\n /<([@#!][^<>]{1,340}|(?:https?:|mailto:)[^<>|]{1,3000}\\|[^<>]{1,300})>/iy;\n// charCodeAt gates so sticky regexes only run at plausible token starts.\nconst CHAR_LT = 60; // <\nconst CHAR_HASH = 35; // #\nconst CHAR_AT = 64; // @\nconst CHAR_COLON = 58; // :\nconst SLACK_USER_RE = /^@([UW][A-Z0-9]{1,60})(?:\\|[^>]{0,300})?$/;\nconst SLACK_CHANNEL_RE = /^#([CDG][A-Z0-9]{1,60})(?:\\|[^>]{0,300})?$/;\nconst SLACK_USERGROUP_RE = /^!subteam\\^(S[A-Z0-9]{1,60})(?:\\|[^>]{0,300})?$/;\nconst SLACK_BROADCAST_RE = /^!(here|channel|everyone)(?:\\|[^>]{0,300})?$/;\nconst SLACK_DATE_RE =\n /^!date\\^(\\d{1,13})\\^([^^|]{1,300})(?:\\^([^^|]{1,3000}))?(?:\\|([^]{0,300}))?$/;\nconst SLACK_LINK_RE = /^((?:https?:|mailto:)[^|]{1,3000})\\|([^]{1,300})$/i;\n\n// Require a non-identifier boundary so emails like user@example.com are not\n// mentions. Handles may contain dots (\"john.doe\") but never start or end with\n// one — a trailing dot is sentence punctuation (\"ping @sarah.\"), and matching\n// it made the handle unresolvable. Shared source keeps the probe and scanner aligned.\nconst MENTION_PATTERN = String.raw`(?<![A-Za-z0-9._-])@([a-zA-Z0-9_-](?:[a-zA-Z0-9._-]{0,62}[a-zA-Z0-9_-])?)|(?<![A-Za-z0-9_-])#([a-zA-Z0-9_-]{1,80})`;\nconst MENTION_RE = new RegExp(MENTION_PATTERN, \"g\");\nconst MENTION_AT_RE = new RegExp(MENTION_PATTERN, \"y\");\n\n// Every well-formed `:name:` becomes an emoji element — Slack accepts arbitrary\n// names and renders a literal `:name:` fallback for unknown ones (verified via\n// Builder probe 2026-07-22), which is also the only way custom workspace emoji\n// (`:party-parrot:`) can work. Word boundaries prevent misparsing times/ratios\n// like `12:30:45` (same rule as react-blockkit's mrkdwn tokenizer).\nconst EMOJI_AT_RE = /(?<![A-Za-z0-9]):([a-z0-9_+-]{1,64}):(?![A-Za-z0-9])/y;\n\n/** Parse the inside of one `<…>` token into a rich text element, or undefined if not Slack syntax. */\nfunction slackEntityElement(inner: string, style: RichTextStyle): RichTextInline | undefined {\n const labeledLink = SLACK_LINK_RE.exec(inner);\n if (labeledLink?.[1] !== undefined && labeledLink[2] !== undefined) {\n if (!isValidLinkUrl(labeledLink[1])) {\n return undefined;\n }\n return {\n type: \"link\",\n url: labeledLink[1],\n text: labeledLink[2],\n style: styleOrUndefined(style),\n };\n }\n const user = SLACK_USER_RE.exec(inner);\n if (user?.[1] !== undefined) {\n return { type: \"user\", user_id: user[1], style: styleOrUndefined(style) };\n }\n const channel = SLACK_CHANNEL_RE.exec(inner);\n if (channel?.[1] !== undefined) {\n return { type: \"channel\", channel_id: channel[1], style: styleOrUndefined(style) };\n }\n const usergroup = SLACK_USERGROUP_RE.exec(inner);\n if (usergroup?.[1] !== undefined) {\n return { type: \"usergroup\", usergroup_id: usergroup[1], style: styleOrUndefined(style) };\n }\n const broadcast = SLACK_BROADCAST_RE.exec(inner);\n if (broadcast !== null) {\n const range = broadcast[1];\n if (range === \"here\" || range === \"channel\" || range === \"everyone\") {\n return { type: \"broadcast\", range, style: styleOrUndefined(style) };\n }\n }\n const date = SLACK_DATE_RE.exec(inner);\n if (date?.[1] !== undefined && date[2] !== undefined) {\n const timestamp = Number(date[1]);\n if (Number.isSafeInteger(timestamp)) {\n return {\n type: \"date\",\n timestamp,\n format: date[2],\n url: date[3],\n fallback: date[4],\n style: styleOrUndefined(style),\n };\n }\n }\n return undefined;\n}\n\n/**\n * Single-pass text-run tokenizer. Walks once against an ordered token table\n * (entity → mention → emoji), preserving the historical three-pass priority.\n * Mentions only attempt when a resolver is configured. `sawEntity` lets HTML\n * callers keep their non-entity path when nothing parsed.\n */\nfunction scanTextRun(\n value: string,\n style: RichTextStyle,\n resolveUser?: (handle: string) => string | undefined,\n resolveChannel?: (name: string) => string | undefined,\n): { elements: RichTextInline[]; sawEntity: boolean } {\n const scanMentions = resolveUser !== undefined || resolveChannel !== undefined;\n const styleOpt = styleOrUndefined(style);\n const out: RichTextInline[] = [];\n let sawEntity = false;\n let i = 0;\n let textStart = 0;\n\n while (i < value.length) {\n const ch = value.charCodeAt(i);\n let element: RichTextInline | undefined;\n let tokenEnd = 0;\n\n // Token table (priority order): entity → mention → emoji.\n if (ch === CHAR_LT) {\n SLACK_ENTITY_AT_RE.lastIndex = i;\n const match = SLACK_ENTITY_AT_RE.exec(value);\n if (match !== null) {\n // Failed strict parse: leave the candidate for later mention/emoji/text.\n element = slackEntityElement(match[1] ?? \"\", style);\n if (element !== undefined) {\n tokenEnd = SLACK_ENTITY_AT_RE.lastIndex;\n sawEntity = true;\n }\n }\n } else if (scanMentions && (ch === CHAR_AT || ch === CHAR_HASH)) {\n MENTION_AT_RE.lastIndex = i;\n const match = MENTION_AT_RE.exec(value);\n if (match !== null) {\n const userHandle = match[1];\n const channelName = match[2];\n if (userHandle !== undefined && resolveUser !== undefined) {\n const userId = resolveUser(userHandle);\n if (userId !== undefined && userId.length > 0) {\n element = { type: \"user\", user_id: userId, style: styleOpt };\n tokenEnd = MENTION_AT_RE.lastIndex;\n }\n } else if (channelName !== undefined && resolveChannel !== undefined) {\n const channelId = resolveChannel(channelName);\n if (channelId !== undefined && channelId.length > 0) {\n element = { type: \"channel\", channel_id: channelId, style: styleOpt };\n tokenEnd = MENTION_AT_RE.lastIndex;\n }\n }\n // Unresolved / wrong-kind: leave for emoji/text (mention charset has no ':').\n }\n } else if (ch === CHAR_COLON) {\n EMOJI_AT_RE.lastIndex = i;\n const match = EMOJI_AT_RE.exec(value);\n if (match !== null) {\n const emoji: RichTextEmoji = { type: \"emoji\", name: match[1] ?? \"\" };\n element = emoji;\n tokenEnd = EMOJI_AT_RE.lastIndex;\n }\n }\n\n if (element !== undefined) {\n if (i > textStart) {\n out.push({ type: \"text\", text: value.slice(textStart, i), style: styleOpt });\n }\n out.push(element);\n i = tokenEnd;\n textStart = i;\n continue;\n }\n i += 1;\n }\n\n if (textStart < value.length) {\n out.push({ type: \"text\", text: value.slice(textStart), style: styleOpt });\n }\n if (out.length === 0) {\n out.push({ type: \"text\", text: value, style: styleOpt });\n }\n return { elements: out, sawEntity };\n}\n\n/**\n * Section inlines for raw HTML values carrying Slack entity tokens (remark parses\n * `<!here>` and friends as html nodes). Undefined when the value has no entities.\n */\nexport function slackEntityRichTextInlines(\n value: string,\n style: RichTextStyle,\n): ReadonlyArray<RichTextInline> | undefined {\n // Mentions stay off — HTML entity nodes historically only split entities + emoji.\n const { elements, sawEntity } = scanTextRun(value, style);\n return sawEntity ? elements : undefined;\n}\n\n/** True when mention resolvers are configured and phrasing contains @user / #channel tokens. */\nexport function phrasingNeedsMentionResolution(\n nodes: ReadonlyArray<PhrasingContent>,\n ctx: ConversionContext,\n): boolean {\n const resolvers = ctx.config.mentionResolvers;\n if (resolvers?.resolveUser === undefined && resolvers?.resolveChannel === undefined) {\n return false;\n }\n const plain = phrasingToPlain(nodes);\n MENTION_RE.lastIndex = 0;\n return MENTION_RE.test(plain);\n}\n\nfunction emitTextWithMentionsAndEmoji(\n node: Text,\n style: RichTextStyle,\n ctx: ConversionContext,\n): RichTextInline[] {\n const resolvers = ctx.config.mentionResolvers;\n return scanTextRun(node.value, style, resolvers?.resolveUser, resolvers?.resolveChannel).elements;\n}\n\ninterface ReassembledSlackLink {\n readonly leadingText: Text;\n readonly link: RichTextLink;\n readonly trailingText: Text;\n}\n\n/**\n * Slack labeled links whose label contains spaces (`<https://u|two words>`)\n * parse as text ending in \"<\", an autolink whose url swallowed \"|firstWord\",\n * then text carrying the rest of the label up to \">\". Reassemble the trio.\n */\nfunction reassembleSlackLabeledLink(\n work: ReadonlyArray<PhrasingContent>,\n i: number,\n style: RichTextStyle,\n): ReassembledSlackLink | undefined {\n const lead = work[i];\n const linkNode = work[i + 1];\n const tail = work[i + 2];\n if (lead?.type !== \"text\" || !lead.value.endsWith(\"<\")) {\n return undefined;\n }\n if (linkNode?.type !== \"link\" || tail?.type !== \"text\") {\n return undefined;\n }\n const url = linkNode.url;\n const pipeIndex = url.indexOf(\"|\");\n if (pipeIndex <= 0 || !HTTP_URL_RE.test(url)) {\n return undefined;\n }\n // Only GFM literal autolinks qualify (label text equals the raw url).\n if (phrasingToPlain(linkNode.children) !== url) {\n return undefined;\n }\n const closeIndex = tail.value.indexOf(\">\");\n if (closeIndex === -1) {\n return undefined;\n }\n const realUrl = url.slice(0, pipeIndex);\n if (!isValidLinkUrl(realUrl)) {\n return undefined;\n }\n const label = `${url.slice(pipeIndex + 1)}${tail.value.slice(0, closeIndex)}`;\n if (label.length === 0) {\n return undefined;\n }\n return {\n leadingText: { type: \"text\", value: lead.value.slice(0, -1) },\n link: { type: \"link\", url: realUrl, text: label, style: styleOrUndefined(style) },\n trailingText: { type: \"text\", value: tail.value.slice(closeIndex + 1) },\n };\n}\n\nfunction emitLink(node: Link, ctx: ConversionContext, style: RichTextStyle): RichTextInline[] {\n const url = node.url;\n const text = phrasingToPlain(node.children);\n flagImagesLostInLabel(node.children, ctx);\n // Slack-style labeled autolink <https://url|label>: remark folds the pipe and\n // label into the URL of an autolink. Split them back apart.\n const pipeIndex = url.indexOf(\"|\");\n if (pipeIndex > 0 && HTTP_URL_RE.test(url) && text === url) {\n const realUrl = url.slice(0, pipeIndex);\n const label = url.slice(pipeIndex + 1);\n if (label.length > 0 && isValidLinkUrl(realUrl)) {\n return [{ type: \"link\", url: realUrl, text: label, style: styleOrUndefined(style) }];\n }\n }\n if (!isValidLinkUrl(url)) {\n ctx.degradations.add({\n nodeType: \"link\",\n from: \"link\",\n to: \"text\",\n reason: \"Invalid or oversized URL\",\n path: ctx.path,\n });\n const suffix = url.length > 0 && url !== text ? ` (${url})` : \"\";\n return [{ type: \"text\", text: `${text}${suffix}`, style: styleOrUndefined(style) }];\n }\n const link: RichTextLink = {\n type: \"link\",\n url,\n text: text.length > 0 ? text : url,\n style: styleOrUndefined(style),\n };\n return [link];\n}\n\nfunction emitLinkReference(\n node: LinkReference,\n ctx: ConversionContext,\n style: RichTextStyle,\n): RichTextInline[] {\n const def = ctx.definitions.get(node.identifier.toLowerCase());\n if (def === undefined) {\n flagImagesLostInLabel(node.children, ctx);\n return [\n {\n type: \"text\",\n text: phrasingToPlain(node.children) || node.identifier,\n style: styleOrUndefined(style),\n },\n ];\n }\n return emitLink(\n {\n type: \"link\",\n url: def.url,\n title: def.title ?? undefined,\n children: node.children,\n },\n ctx,\n style,\n );\n}\n\n/**\n * Slack rich text link elements require absolute http(s)/mailto URLs; relative\n * URLs (`/path`, `#fragment`) or other schemes are rejected with invalid_blocks.\n * https://docs.slack.dev/reference/block-kit/block-elements/rich-text-elements\n */\nexport function isValidLinkUrl(url: string): boolean {\n if (url.length === 0 || url.length > IMAGE_URL_MAX_CHARS) {\n return false;\n }\n return HTTP_URL_RE.test(url);\n}\n\n/** Anchor state collected across `<a href>` … `</a>` tags before emission. */\ninterface OpenAnchor {\n readonly href: string;\n readonly style: RichTextStyle;\n readonly textParts: string[];\n readonly valid: boolean;\n}\n\n/** Emit a collected anchor as a link, or degrade to text+suffix when the href is not link-safe. */\nfunction anchorInline(anchor: OpenAnchor, ctx: ConversionContext): RichTextInline {\n const label = anchor.textParts.join(\"\");\n if (anchor.valid) {\n return {\n type: \"link\",\n url: anchor.href,\n text: label.length > 0 ? label : anchor.href,\n style: styleOrUndefined(anchor.style),\n };\n }\n ctx.degradations.add({\n nodeType: \"link\",\n from: \"link\",\n to: \"text\",\n reason: \"Invalid or oversized URL\",\n path: ctx.path,\n });\n const base = label.length > 0 ? label : anchor.href;\n const suffix =\n label.length > 0 && anchor.href.length > 0 && anchor.href !== label ? ` (${anchor.href})` : \"\";\n return { type: \"text\", text: `${base}${suffix}`, style: styleOrUndefined(anchor.style) };\n}\n\n// remark emits formatting tags as standalone html nodes (<b> and </b> are\n// siblings of the text they wrap); these single-tag patterns drive the\n// cross-node style stack in emitPhrasing.\nconst HTML_STYLE_OPEN_RE = /^<(b|strong|i|em|s|del|code)(\\s+[^>]{0,200})?>$/i;\nconst HTML_STYLE_CLOSE_RE = /^<\\/(b|strong|i|em|s|del|code)\\s*>$/i;\n\nfunction htmlTagStyle(base: RichTextStyle, tag: string): RichTextStyle {\n const t = tag.toLowerCase();\n if (t === \"b\" || t === \"strong\") {\n return { ...base, bold: true };\n }\n if (t === \"i\" || t === \"em\") {\n return { ...base, italic: true };\n }\n if (t === \"s\" || t === \"del\") {\n return { ...base, strike: true };\n }\n return { ...base, code: true };\n}\n\n// Alternatives in match order: known tag (optionally self-closing), unknown\n// tag (stripped), a text run, or a stray \"<\" kept literal so unknown tags can\n// never leak fragments like \"ad>\" into the output.\nconst INLINE_TAG_RE =\n /<\\/?(b|strong|i|em|s|del|code|br|a)(\\s+[^>]{0,200})?\\s*\\/?>|<[^>]{0,200}>|[^<]+|</gi;\n\nfunction emitInlineHtml(\n html: string,\n style: RichTextStyle,\n ctx: ConversionContext,\n): RichTextInline[] {\n const out: RichTextInline[] = [];\n const stack: Array<{ tag: string; style: RichTextStyle }> = [];\n let current = style;\n let openAnchor: OpenAnchor | undefined;\n INLINE_TAG_RE.lastIndex = 0;\n let m: RegExpExecArray | null = INLINE_TAG_RE.exec(html);\n let strippedUnknown = false;\n while (m !== null) {\n const token = m[0];\n if (token.startsWith(\"<\") && token.length > 1 && m[1] === undefined) {\n // Unknown <…> tag — strip it (flagged below) instead of leaking fragments.\n strippedUnknown = true;\n m = INLINE_TAG_RE.exec(html);\n continue;\n }\n if (token.startsWith(\"<\") && m[1] !== undefined) {\n const tag = (m[1] ?? \"\").toLowerCase();\n const closing = token.startsWith(\"</\");\n if (tag === \"br\") {\n if (openAnchor !== undefined) {\n openAnchor.textParts.push(\"\\n\");\n } else {\n out.push({ type: \"text\", text: \"\\n\", style: styleOrUndefined(current) });\n }\n } else if (closing) {\n if (tag === \"a\" && openAnchor !== undefined) {\n out.push(anchorInline(openAnchor, ctx));\n openAnchor = undefined;\n }\n stack.pop();\n current = stack.length > 0 ? (stack[stack.length - 1]?.style ?? style) : style;\n } else if (tag === \"a\") {\n const hrefMatch = /href\\s*=\\s*[\"']([^\"']{0,3000})[\"']/i.exec(token);\n const href = hrefMatch?.[1];\n stack.push({ tag, style: current });\n if (href !== undefined) {\n // Collect label text until </a>; do not emit yet. A nested <a> closes\n // the outer anchor first so its collected label is not dropped.\n if (openAnchor !== undefined) {\n out.push(anchorInline(openAnchor, ctx));\n }\n openAnchor = { href, style: current, textParts: [], valid: isValidLinkUrl(href) };\n }\n } else {\n const next = { ...current };\n if (tag === \"b\" || tag === \"strong\") next.bold = true;\n if (tag === \"i\" || tag === \"em\") next.italic = true;\n if (tag === \"s\" || tag === \"del\") next.strike = true;\n if (tag === \"code\") next.code = true;\n stack.push({ tag, style: next });\n current = next;\n }\n } else if (token.length > 0) {\n if (openAnchor !== undefined) {\n openAnchor.textParts.push(token);\n } else {\n out.push({ type: \"text\", text: token, style: styleOrUndefined(current) });\n }\n }\n m = INLINE_TAG_RE.exec(html);\n }\n if (openAnchor !== undefined) {\n out.push(anchorInline(openAnchor, ctx));\n }\n if (strippedUnknown) {\n ctx.degradations.add({\n nodeType: \"html\",\n from: \"html\",\n to: \"text\",\n reason: \"Unrecognized inline HTML stripped to text\",\n path: ctx.path,\n });\n }\n return out;\n}\n\nfunction coalesceText(elements: ReadonlyArray<RichTextInline>): RichTextInline[] {\n const out: RichTextInline[] = [];\n for (const el of elements) {\n const prev = out[out.length - 1];\n if (\n el.type === \"text\" &&\n prev !== undefined &&\n prev.type === \"text\" &&\n JSON.stringify(prev.style) === JSON.stringify(el.style)\n ) {\n out[out.length - 1] = { type: \"text\", text: prev.text + el.text, style: prev.style };\n } else {\n out.push(el);\n }\n }\n return out;\n}\n","import type { Blockquote, RootContent } from \"mdast\";\n\nimport type { Block, RichTextBlock, RichTextInline } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport {\n blockToPlainText,\n collectFlattenedUrls,\n type FlattenedUrl,\n} from \"./block-to-plain-text.js\";\nimport { emitPhrasing } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\nconst ADMONITION_RE = /^\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\]\\s*/i;\n\nconst ADMONITION_META = {\n NOTE: { emoji: \"📝\", title: \"Note\" },\n TIP: { emoji: \"💡\", title: \"Tip\" },\n IMPORTANT: { emoji: \"❗\", title: \"Important\" },\n WARNING: { emoji: \"⚠️\", title: \"Warning\" },\n CAUTION: { emoji: \"🚫\", title: \"Caution\" },\n} as const;\n\n/**\n * Blockquotes → rich_text_quote; GitHub admonitions get styled first line.\n */\nexport class BlockquoteAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"blockquote\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const quote = node as Blockquote;\n return [\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n const elements = flattenQuote(quote, ctx);\n const block: RichTextBlock = {\n type: \"rich_text\",\n elements: [{ type: \"rich_text_quote\", elements, border: 0 }],\n };\n return [block];\n },\n },\n ];\n }\n}\n\nfunction flattenQuote(quote: Blockquote, ctx: ConversionContext): RichTextInline[] {\n const parts: RichTextInline[] = [];\n let first = true;\n\n for (const child of quote.children) {\n if (child.type === \"paragraph\") {\n let children = child.children;\n if (first && children[0]?.type === \"text\") {\n const textNode = children[0];\n const m = ADMONITION_RE.exec(textNode.value);\n if (m !== null) {\n const kind = (m[1] ?? \"NOTE\").toUpperCase() as keyof typeof ADMONITION_META;\n const meta = ADMONITION_META[kind];\n parts.push({\n type: \"text\",\n text: `${meta.emoji}${meta.title}\\n`,\n style: { bold: true },\n });\n const rest = textNode.value.slice(m[0].length);\n children = [\n ...(rest.length > 0 ? [{ ...textNode, value: rest }] : []),\n ...children.slice(1),\n ];\n }\n }\n first = false;\n const inline = emitPhrasing(children, ctx);\n if (parts.length > 0 && inline.elements.length > 0) {\n parts.push({ type: \"text\", text: \"\\n\" });\n }\n parts.push(...inline.elements);\n } else if (child.type === \"list\") {\n ctx.degradations.add({\n nodeType: \"blockquote\",\n from: \"list\",\n to: \"bullet_lines\",\n reason: \"Nested list inside blockquote flattened\",\n path: ctx.path,\n });\n flagFlattenedUrls(child, ctx);\n if (parts.length > 0) parts.push({ type: \"text\", text: \"\\n\" });\n for (const item of child.children) {\n parts.push({ type: \"text\", text: `• ${blockToPlainText(item)}\\n` });\n }\n } else if (child.type === \"code\") {\n ctx.degradations.add({\n nodeType: \"blockquote\",\n from: \"code\",\n to: \"text\",\n reason: \"Nested code inside blockquote flattened to text\",\n path: ctx.path,\n });\n if (parts.length > 0) parts.push({ type: \"text\", text: \"\\n\" });\n parts.push({ type: \"text\", text: child.value, style: { code: true } });\n } else {\n ctx.degradations.add({\n nodeType: \"blockquote\",\n from: child.type,\n to: \"text\",\n reason: \"Nested block inside blockquote flattened\",\n path: ctx.path,\n });\n flagFlattenedUrls(child, ctx);\n if (parts.length > 0) parts.push({ type: \"text\", text: \"\\n\" });\n parts.push({ type: \"text\", text: blockToPlainText(child) });\n }\n }\n\n return parts.length > 0 ? parts : [{ type: \"text\", text: \" \" }];\n}\n\n/** Flattening keeps labels and alt text only; every dropped URL gets a record. */\nfunction flagFlattenedUrls(node: RootContent, ctx: ConversionContext): void {\n const dropped: FlattenedUrl[] = [];\n collectFlattenedUrls(node, dropped);\n for (const { nodeType, url } of dropped) {\n ctx.degradations.add({\n nodeType,\n from: url,\n to: \"label_only\",\n reason: \"Block flattened into quote text; URL dropped\",\n path: ctx.path,\n });\n }\n}\n","import { brandErrorPrototype, hasErrorBrand } from \"../errors.js\";\nimport { RetrySafety, UploadPhase, UploadProcessing, type UploadReceipt } from \"../types.js\";\n\n/** See the brand rationale in `errors.ts`: this class is bundled into more than one entry. */\nconst SLACK_UPLOAD_ERROR_BRAND = Symbol.for(\"slackmark.error.slackUpload\");\n\nexport const SlackUploadStage = {\n Admission: \"admission\",\n GetUploadUrl: \"get-upload-url\",\n UploadBytes: \"upload-bytes\",\n CompleteUpload: \"complete-upload\",\n FileInfo: \"file-info\",\n ProcessingTimeout: \"processing-timeout\",\n} as const;\n\nexport type SlackUploadStage = (typeof SlackUploadStage)[keyof typeof SlackUploadStage];\n\nexport interface SlackUploadErrorDetails {\n readonly stage: SlackUploadStage;\n readonly status?: number | undefined;\n readonly code?: string | undefined;\n readonly retryable?: boolean | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly receipt?: UploadReceipt | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Integration error from one explicit stage of Slack's external-upload flow.\n */\nexport class SlackUploadError extends Error {\n static {\n brandErrorPrototype(this.prototype, SLACK_UPLOAD_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly stage: SlackUploadStage;\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly retryable: boolean;\n readonly retryAfterMs: number | undefined;\n readonly receipt: UploadReceipt;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, details: SlackUploadErrorDetails) {\n super(message, details.cause !== undefined ? { cause: details.cause } : undefined);\n this.name = \"SlackUploadError\";\n this.stage = details.stage;\n this.status = details.status;\n this.code = details.code;\n this.retryable = details.retryable ?? isRetryable(details.status, details.code);\n this.retryAfterMs = details.retryAfterMs;\n this.receipt = Object.freeze(\n details.receipt ?? {\n kind: \"upload\",\n provider: \"slack\",\n phase: UploadPhase.Requested,\n fileId: undefined,\n shared: false,\n processing: UploadProcessing.NotRequested,\n status: details.status,\n retryAfterMs: details.retryAfterMs,\n providerCode: details.code,\n retrySafety: RetrySafety.Safe,\n },\n );\n this.receipts = Object.freeze([this.receipt]);\n this.settledReceipts = Promise.resolve(this.receipts);\n }\n}\n\n/**\n * Identifies a {@link SlackUploadError} from any entry of this package. `slackmark` and\n * `slackmark/slack` each bundle their own copy, so `instanceof` is unreliable when the\n * error crosses between them.\n */\nexport function isSlackUploadError(value: unknown): value is SlackUploadError {\n return hasErrorBrand(value, SLACK_UPLOAD_ERROR_BRAND);\n}\n\nfunction isRetryable(status: number | undefined, code: string | undefined): boolean {\n return (\n status === 429 ||\n (status !== undefined && status >= 500) ||\n code === \"fetch_failed\" ||\n code === \"request_timeout\" ||\n code === \"processing_timeout\"\n );\n}\n","import type { ImageBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { throwIfOperationEnded } from \"../budget/operation-scope.js\";\nimport {\n IMAGE_URL_MAX_CHARS,\n RENDERED_IMAGE_FILENAME_MAX_CHARS,\n RENDERED_IMAGE_MAX_BYTES,\n SLACK_FILE_ID_MAX_CHARS,\n} from \"../constants.js\";\nimport {\n ConfigurationError,\n attachReceipts,\n cloneConfigurationError,\n cloneOperationError,\n isConfigurationError,\n isOperationError,\n} from \"../errors.js\";\nimport { isSlackUploadError } from \"../slack/slack-upload-error.js\";\nimport {\n RetrySafety,\n UploadPhase,\n UploadProcessing,\n type BytesImage,\n type Degradation,\n type ImageRenderer,\n type RenderRequest,\n type SlackUploader,\n type StructuredRendererError,\n type UploadReceipt,\n} from \"../types.js\";\n\nimport { clampImageText } from \"./inline.js\";\n\nconst SAFE_METADATA_RE = /^[a-z0-9][a-z0-9._-]*$/u;\nconst SAFE_FILENAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/u;\nconst SLACK_FILE_ID_RE = /^[A-Z][A-Z0-9]{1,254}$/u;\nconst PNG_SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10] as const;\nconst GIF87A_SIGNATURE = [71, 73, 70, 56, 55, 97] as const;\nconst GIF89A_SIGNATURE = [71, 73, 70, 56, 57, 97] as const;\n\ntype ValidRenderResult =\n | {\n readonly kind: \"url\";\n readonly imageUrl: string;\n readonly altText: string | undefined;\n }\n | {\n readonly kind: \"bytes\";\n readonly image: BytesImage;\n readonly altText: string | undefined;\n };\n\ntype RenderInspection =\n | { readonly kind: \"decline\" }\n | { readonly kind: \"valid\"; readonly result: ValidRenderResult }\n | { readonly kind: \"invalid\"; readonly reason: string; readonly code: string };\n\n/**\n * Try configured renderers in order and turn the first successful result into\n * a Slack image block. Attempt failures are emitted only on terminal fallback.\n */\nexport async function tryRenderImage(\n request: RenderRequest,\n nodeType: string,\n ctx: ConversionContext,\n): Promise<ImageBlock | undefined> {\n const pendingFailures: Degradation[] = [];\n let missingUploaderRendererId: string | undefined;\n\n for (const renderer of ctx.config.renderers) {\n throwIfOperationEnded(ctx.config.operation, \"renderer_admission\");\n let capability: unknown;\n try {\n capability = renderer.canRender(request);\n } catch (error) {\n rethrowNonDegradationError(error, ctx);\n const metadata = rendererFailureMetadata(error, renderer.id, {\n code: \"renderer_capability_failed\",\n stage: \"capability\",\n retryable: false,\n });\n pendingFailures.push(\n createFailure(\n ctx,\n nodeType,\n \"image.canRender\",\n \"Renderer capability check failed\",\n metadata,\n ),\n );\n continue;\n }\n if (typeof capability !== \"boolean\") {\n observeThenableRejection(capability);\n pendingFailures.push(\n createFailure(\n ctx,\n nodeType,\n \"image.canRender\",\n \"Renderer capability check returned a non-boolean result\",\n {\n code: \"invalid_renderer_capability_result\",\n stage: \"capability\",\n retryable: false,\n rendererId: renderer.id,\n },\n ),\n );\n continue;\n }\n if (!capability) {\n continue;\n }\n\n let rawResult: unknown;\n try {\n rawResult = await renderer.render(request, ctx.config.operation);\n } catch (error) {\n rethrowNonDegradationError(error, ctx);\n const metadata = rendererFailureMetadata(error, renderer.id, {\n code: \"renderer_failed\",\n stage: \"render\",\n retryable: true,\n });\n pendingFailures.push(\n createFailure(ctx, nodeType, \"image.render\", \"Renderer failed\", metadata),\n );\n continue;\n }\n throwIfOperationEnded(ctx.config.operation, \"render\");\n\n const inspection = inspectRenderResult(rawResult, renderer.output);\n if (inspection.kind === \"decline\") {\n continue;\n }\n if (inspection.kind === \"invalid\") {\n pendingFailures.push(\n createFailure(ctx, nodeType, \"image.render\", inspection.reason, {\n code: inspection.code,\n stage: \"validation\",\n retryable: false,\n rendererId: renderer.id,\n }),\n );\n continue;\n }\n\n const result = inspection.result;\n if (result.kind === \"url\") {\n const urlError = validateRendererUrl(result.imageUrl);\n if (urlError !== undefined) {\n pendingFailures.push(\n createFailure(ctx, nodeType, \"image.url\", urlError, {\n code: \"invalid_renderer_url\",\n stage: \"validation\",\n retryable: false,\n rendererId: renderer.id,\n }),\n );\n continue;\n }\n return {\n type: \"image\",\n image_url: result.imageUrl,\n alt_text: clampImageText(result.altText ?? request.altText, ctx, \"alt_text\"),\n };\n }\n\n const uploader = ctx.config.uploader;\n if (uploader === undefined) {\n missingUploaderRendererId ??= renderer.id;\n continue;\n }\n\n const upload = await uploadImage(uploader, result.image, renderer, nodeType, ctx);\n if (upload.ok) {\n return {\n type: \"image\",\n alt_text: clampImageText(result.altText ?? request.altText, ctx, \"alt_text\"),\n slack_file: { id: upload.fileId },\n };\n }\n pendingFailures.push(upload.failure);\n }\n\n if (missingUploaderRendererId !== undefined) {\n throw new ConfigurationError(\n `Renderer \"${missingUploaderRendererId}\" returned bytes but no uploader was configured`,\n {\n code: \"bytes_uploader_missing\",\n stage: \"upload\",\n },\n );\n }\n for (const failure of pendingFailures) {\n ctx.degradations.add(failure);\n }\n return undefined;\n}\n\nasync function uploadImage(\n uploader: SlackUploader,\n image: BytesImage,\n renderer: ImageRenderer,\n nodeType: string,\n ctx: ConversionContext,\n): Promise<\n | { readonly ok: true; readonly fileId: string }\n | { readonly ok: false; readonly failure: Degradation }\n> {\n let rawUpload: unknown;\n try {\n rawUpload = await uploader.upload(image, ctx.config.operation);\n } catch (error) {\n const receipt = receiptFromUploadError(error, renderer.id, image.filename);\n ctx.receipts.add(receipt);\n rethrowNonDegradationError(error, ctx);\n const metadata = uploadFailureMetadata(error, renderer.id);\n return {\n ok: false,\n failure: createFailure(ctx, nodeType, \"image.bytes\", \"Image upload failed\", {\n ...metadata,\n }),\n };\n }\n const upload = inspectUploadResult(rawUpload, renderer.id, image.filename);\n ctx.receipts.add(upload.receipt);\n throwIfOperationEnded(ctx.config.operation, \"upload\");\n if (!upload.valid) {\n return {\n ok: false,\n failure: createFailure(ctx, nodeType, \"image.bytes\", \"Uploader returned an invalid result\", {\n code: \"invalid_upload_result\",\n stage: \"validation\",\n retryable: false,\n rendererId: renderer.id,\n }),\n };\n }\n return { ok: true, fileId: upload.fileId };\n}\n\nfunction uploadFailureMetadata(\n error: unknown,\n rendererId: string,\n): {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId: string;\n} {\n if (isSlackUploadError(error)) {\n return {\n code: error.code ?? \"slack_upload_failed\",\n stage: error.stage,\n retryable: error.retryable,\n rendererId,\n };\n }\n if (typeof error === \"object\" && error !== null) {\n try {\n const code = Reflect.get(error, \"code\");\n const stage = Reflect.get(error, \"stage\");\n const retryable = Reflect.get(error, \"retryable\");\n if (\n isSafeMetadataToken(code) &&\n isSafeMetadataToken(stage) &&\n typeof retryable === \"boolean\"\n ) {\n return { code, stage, retryable, rendererId };\n }\n } catch {\n // Unknown errors use conservative upload metadata below.\n }\n }\n return {\n code: \"upload_failed\",\n stage: \"upload\",\n retryable: true,\n rendererId,\n };\n}\n\nfunction inspectRenderResult(\n value: unknown,\n declaredOutput: ImageRenderer[\"output\"],\n): RenderInspection {\n if (value === null) {\n return { kind: \"decline\" };\n }\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return invalidRenderResult(\"Renderer returned a non-object result\");\n }\n try {\n const kind = Reflect.get(value, \"kind\");\n if (kind !== \"url\" && kind !== \"bytes\") {\n return invalidRenderResult(\"Renderer returned an unknown image kind\");\n }\n if (\n (declaredOutput === \"url\" && kind !== \"url\") ||\n (declaredOutput === \"bytes\" && kind !== \"bytes\")\n ) {\n return {\n kind: \"invalid\",\n reason: \"Renderer result does not match its declared output\",\n code: \"renderer_output_mismatch\",\n };\n }\n const altText = Reflect.get(value, \"altText\");\n if (altText !== undefined && typeof altText !== \"string\") {\n return invalidRenderResult(\"Renderer altText override must be a string\");\n }\n if (kind === \"url\") {\n const imageUrl = Reflect.get(value, \"imageUrl\");\n return typeof imageUrl === \"string\"\n ? { kind: \"valid\", result: { kind, imageUrl, altText } }\n : invalidRenderResult(\"Renderer URL result is missing imageUrl\");\n }\n const data = Reflect.get(value, \"data\");\n const mimeType = Reflect.get(value, \"mimeType\");\n const filename = Reflect.get(value, \"filename\");\n if (\n !(data instanceof Uint8Array) ||\n (mimeType !== \"image/png\" && mimeType !== \"image/jpeg\" && mimeType !== \"image/gif\") ||\n typeof filename !== \"string\"\n ) {\n return invalidRenderResult(\"Renderer byte result is malformed\");\n }\n const byteError = validateBytes(data, mimeType, filename);\n if (byteError !== undefined) {\n return invalidRenderResult(byteError);\n }\n return {\n kind: \"valid\",\n result: {\n kind,\n image: { kind, data, mimeType, filename },\n altText,\n },\n };\n } catch {\n return invalidRenderResult(\"Renderer result properties could not be read\");\n }\n}\n\nfunction invalidRenderResult(reason: string): RenderInspection {\n return { kind: \"invalid\", reason, code: \"invalid_renderer_output\" };\n}\n\nfunction observeThenableRejection(value: unknown): void {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return;\n }\n try {\n const then = Reflect.get(value, \"then\");\n if (typeof then === \"function\") {\n void Promise.resolve(value).catch(() => undefined);\n }\n } catch {\n // Reading a hostile thenable is itself the invalid capability result.\n }\n}\n\nfunction validateRendererUrl(imageUrl: string): string | undefined {\n if (imageUrl !== imageUrl.trim() || hasControlCharacter(imageUrl)) {\n return \"Renderer URL must not contain surrounding or control whitespace\";\n }\n if (imageUrl.length === 0 || imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return \"Renderer URL is empty or exceeds Slack's 3000-character limit\";\n }\n try {\n const url = new URL(imageUrl);\n if (url.protocol !== \"https:\") {\n return \"Renderer URL must use HTTPS\";\n }\n if (url.username.length > 0 || url.password.length > 0) {\n return \"Renderer URL must not contain credentials\";\n }\n return undefined;\n } catch {\n return \"Renderer URL must be absolute\";\n }\n}\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n const code = character.codePointAt(0) ?? 0;\n if (code <= 31 || code === 127) {\n return true;\n }\n }\n return false;\n}\n\nfunction validateBytes(\n data: Uint8Array,\n mimeType: BytesImage[\"mimeType\"],\n filename: string,\n): string | undefined {\n if (data.byteLength === 0 || data.byteLength > RENDERED_IMAGE_MAX_BYTES) {\n return \"Renderer bytes must be nonempty and at most 10 MiB\";\n }\n if (\n filename.length === 0 ||\n filename.length > RENDERED_IMAGE_FILENAME_MAX_CHARS ||\n filename !== filename.trim() ||\n !SAFE_FILENAME_RE.test(filename) ||\n filename.includes(\"..\")\n ) {\n return \"Renderer filename is unsafe\";\n }\n switch (mimeType) {\n case \"image/png\":\n return hasSignature(data, PNG_SIGNATURE) ? undefined : \"PNG signature does not match MIME\";\n case \"image/jpeg\":\n return data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff\n ? undefined\n : \"JPEG signature does not match MIME\";\n case \"image/gif\":\n return hasSignature(data, GIF87A_SIGNATURE) || hasSignature(data, GIF89A_SIGNATURE)\n ? undefined\n : \"GIF signature does not match MIME\";\n }\n return \"Renderer MIME type is unsupported\";\n}\n\nfunction hasSignature(data: Uint8Array, signature: ReadonlyArray<number>): boolean {\n if (data.byteLength < signature.length) {\n return false;\n }\n return signature.every((byte, index) => data[index] === byte);\n}\n\nfunction inspectUploadResult(\n value: unknown,\n rendererId: string,\n filename: string,\n):\n | {\n readonly valid: true;\n readonly fileId: string;\n readonly receipt: UploadReceipt;\n }\n | { readonly valid: false; readonly receipt: UploadReceipt } {\n try {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return { valid: false, receipt: unknownReceipt(rendererId, filename) };\n }\n const rawFileId = Reflect.get(value, \"fileId\");\n const rawReceipt = Reflect.get(value, \"receipt\");\n const fileId = normalizeFileId(rawFileId);\n const receipt = normalizeReceipt(rawReceipt, rendererId, filename);\n if (fileId === undefined || receipt === undefined) {\n return {\n valid: false,\n receipt: receipt ?? unknownReceipt(rendererId, filename),\n };\n }\n if (receipt.fileId !== undefined && receipt.fileId !== fileId) {\n return {\n valid: false,\n receipt: Object.freeze({\n ...receipt,\n providerCode: \"receipt_file_id_mismatch\",\n retrySafety: RetrySafety.MayDuplicate,\n }),\n };\n }\n return {\n valid: true,\n fileId,\n receipt: receipt.fileId === undefined ? Object.freeze({ ...receipt, fileId }) : receipt,\n };\n } catch {\n return { valid: false, receipt: unknownReceipt(rendererId, filename) };\n }\n}\n\nfunction normalizeFileId(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const normalized = value.trim();\n return normalized.length <= SLACK_FILE_ID_MAX_CHARS && SLACK_FILE_ID_RE.test(normalized)\n ? normalized\n : undefined;\n}\n\nfunction normalizeReceipt(\n value: unknown,\n rendererId: string,\n filename: string,\n): UploadReceipt | undefined {\n if ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) {\n return undefined;\n }\n try {\n const kind = Reflect.get(value, \"kind\");\n const provider = Reflect.get(value, \"provider\");\n const phase = Reflect.get(value, \"phase\");\n const fileIdValue = Reflect.get(value, \"fileId\");\n const shared = Reflect.get(value, \"shared\");\n const processing = Reflect.get(value, \"processing\");\n const status = Reflect.get(value, \"status\");\n const retryAfterMs = Reflect.get(value, \"retryAfterMs\");\n const providerCode = Reflect.get(value, \"providerCode\");\n const retrySafety = Reflect.get(value, \"retrySafety\");\n const fileId = fileIdValue === undefined ? undefined : normalizeFileId(fileIdValue);\n if (\n kind !== \"upload\" ||\n !isSafeMetadataToken(provider) ||\n !isUploadPhase(phase) ||\n (fileIdValue !== undefined && fileId === undefined) ||\n typeof shared !== \"boolean\" ||\n !isUploadProcessing(processing) ||\n (status !== undefined && (!Number.isInteger(status) || status < 0)) ||\n (retryAfterMs !== undefined && (!Number.isFinite(retryAfterMs) || retryAfterMs < 0)) ||\n (providerCode !== undefined && !isSafeMetadataToken(providerCode)) ||\n !isRetrySafety(retrySafety)\n ) {\n return undefined;\n }\n return Object.freeze({\n kind,\n provider,\n rendererId,\n filename,\n phase,\n fileId,\n shared,\n processing,\n status,\n retryAfterMs,\n providerCode,\n retrySafety,\n });\n } catch {\n return undefined;\n }\n}\n\nfunction receiptFromUploadError(\n error: unknown,\n rendererId: string,\n filename: string,\n): UploadReceipt {\n if (isSlackUploadError(error)) {\n return (\n normalizeReceipt(error.receipt, rendererId, filename) ?? unknownReceipt(rendererId, filename)\n );\n }\n try {\n const receipts = Reflect.get(error as object, \"receipts\");\n if (Array.isArray(receipts)) {\n for (const receipt of receipts) {\n const normalized = normalizeReceipt(receipt, rendererId, filename);\n if (normalized !== undefined) {\n return normalized;\n }\n }\n }\n } catch {\n // Unknown uploader errors receive a conservative receipt below.\n }\n return unknownReceipt(rendererId, filename);\n}\n\nfunction unknownReceipt(rendererId: string, filename: string): UploadReceipt {\n return Object.freeze({\n kind: \"upload\",\n provider: \"unknown\",\n rendererId,\n filename,\n phase: UploadPhase.Unknown,\n fileId: undefined,\n shared: false,\n processing: UploadProcessing.Unverified,\n status: undefined,\n retryAfterMs: undefined,\n providerCode: undefined,\n retrySafety: RetrySafety.MayDuplicate,\n });\n}\n\nfunction createFailure(\n ctx: ConversionContext,\n nodeType: string,\n from: string,\n reason: string,\n metadata: {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId: string;\n },\n): Degradation {\n return {\n nodeType,\n from,\n to: \"skip\",\n reason,\n path: ctx.path,\n details: metadata,\n };\n}\n\nfunction rethrowNonDegradationError(error: unknown, ctx: ConversionContext): void {\n if (isConfigurationError(error)) {\n throw attachReceipts(\n cloneConfigurationError(error),\n ctx.receipts.all(),\n ctx.receipts.settled(),\n );\n }\n if (isOperationError(error)) {\n throw attachReceipts(\n cloneOperationError(error, \"renderer\"),\n ctx.receipts.all(),\n ctx.receipts.settled(),\n );\n }\n}\n\nfunction rendererFailureMetadata(\n error: unknown,\n fallbackRendererId: string,\n fallback: Omit<StructuredRendererError, \"rendererId\">,\n): {\n readonly code: string;\n readonly stage: string;\n readonly retryable: boolean;\n readonly rendererId: string;\n} {\n if (isStructuredRendererError(error)) {\n return {\n code: error.code,\n stage: error.stage,\n retryable: error.retryable,\n rendererId: error.rendererId ?? fallbackRendererId,\n };\n }\n return { ...fallback, rendererId: fallbackRendererId };\n}\n\nfunction isStructuredRendererError(error: unknown): error is StructuredRendererError {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n try {\n const code = Reflect.get(error, \"code\");\n const stage = Reflect.get(error, \"stage\");\n const retryable = Reflect.get(error, \"retryable\");\n const rendererId = Reflect.get(error, \"rendererId\");\n return (\n isSafeMetadataToken(code) &&\n isSafeMetadataToken(stage) &&\n typeof retryable === \"boolean\" &&\n (rendererId === undefined || isSafeMetadataToken(rendererId))\n );\n } catch {\n return false;\n }\n}\n\nfunction isSafeMetadataToken(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n value.length <= 64 &&\n SAFE_METADATA_RE.test(value)\n );\n}\n\nfunction isUploadPhase(value: unknown): value is UploadReceipt[\"phase\"] {\n return (\n value === UploadPhase.Requested ||\n value === UploadPhase.Allocated ||\n value === UploadPhase.Uploaded ||\n value === UploadPhase.Completed ||\n value === UploadPhase.Shared ||\n value === UploadPhase.Unknown\n );\n}\n\nfunction isUploadProcessing(value: unknown): value is UploadReceipt[\"processing\"] {\n return (\n value === UploadProcessing.NotRequested ||\n value === UploadProcessing.Pending ||\n value === UploadProcessing.Verified ||\n value === UploadProcessing.Unverified\n );\n}\n\nfunction isRetrySafety(value: unknown): value is UploadReceipt[\"retrySafety\"] {\n return (\n value === RetrySafety.Never || value === RetrySafety.Safe || value === RetrySafety.MayDuplicate\n );\n}\n","import type { Code, RootContent } from \"mdast\";\n\nimport type { Block, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport { preformattedRichText } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { tryRenderImage } from \"./try-render-image.js\";\n\n/**\n * Code fences → configured image renderer / rich_text_preformatted.\n * Mermaid/math dialects are handled by more specific adapters that match first.\n */\nexport class CodeFenceAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"code\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const code = node as Code;\n const hasLang = code.lang !== null && code.lang !== undefined && code.lang.length > 0;\n const language = hasLang ? (code.lang ?? \"\").trim().toLowerCase() : \"\";\n return [\n {\n budget: { blocks: 1 },\n emit: async (ctx: ConversionContext): Promise<ReadonlyArray<Block>> => {\n const rendered = await tryRenderImage(\n {\n lang: language,\n source: code.value,\n altText: `${language.length > 0 ? language : \"code\"} diagram`,\n },\n \"code\",\n ctx,\n );\n return rendered === undefined ? [] : [rendered];\n },\n },\n {\n requires: [\"preformattedLanguage\"],\n budget: { blocks: 1 },\n emit: (): ReadonlyArray<Block> => [preformatted(code, true)],\n },\n {\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n if (hasLang) {\n emitCtx.degradations.add({\n nodeType: \"code\",\n from: \"preformatted.language\",\n to: \"preformatted\",\n reason: \"preformattedLanguage capability unavailable; omitting language\",\n path: emitCtx.path,\n });\n }\n return [preformatted(code, false)];\n },\n },\n ];\n }\n}\n\nfunction preformatted(code: Code, withLang: boolean): RichTextBlock {\n const language =\n withLang && code.lang !== null && code.lang !== undefined && code.lang.length > 0\n ? code.lang.toLowerCase()\n : undefined;\n return preformattedRichText(code.value, language);\n}\n","import type { Heading, RootContent } from \"mdast\";\n\nimport type { Block, HeaderBlock, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { HEADER_LEVEL_MAX, HEADER_TEXT_MAX_CHARS } from \"../constants.js\";\n\nimport {\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n phrasingNeedsMentionResolution,\n phrasingToPlain,\n} from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Headings 1–4 → header (+level); 5–6 / overflow → bold rich_text.\n */\nexport class HeadingAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"heading\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const heading = node as Heading;\n const hoistCount = countHoistableImages(heading.children, ctx);\n const needsRich = headingNeedsRichText(heading, ctx);\n\n if (!needsRich) {\n return [\n {\n requires: [\"headerLevel\"],\n budget: { blocks: 1 },\n emit: (): ReadonlyArray<Block> => {\n return emitPlainHeader(heading, true);\n },\n },\n {\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"heading\",\n from: \"header.level\",\n to: \"header\",\n reason: \"headerLevel capability unavailable; omitting level\",\n path: emitCtx.path,\n });\n return emitPlainHeader(heading, false);\n },\n },\n ];\n }\n\n const richCandidates: Candidate[] = [\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n return emitRichHeading(heading, emitCtx, true);\n },\n },\n ];\n if (hoistCount > 0) {\n richCandidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"heading\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted heading images; emitting text only\",\n path: emitCtx.path,\n });\n return emitRichHeading(heading, emitCtx, false);\n },\n });\n }\n return richCandidates;\n }\n}\n\nfunction headingNeedsRichText(heading: Heading, ctx: ConversionContext): boolean {\n if (heading.depth > HEADER_LEVEL_MAX) {\n return true;\n }\n const plain = phrasingToPlain(heading.children);\n if (plain.length > HEADER_TEXT_MAX_CHARS) {\n return true;\n }\n if (phrasingNeedsMentionResolution(heading.children, ctx)) {\n return true;\n }\n return heading.children.some(\n (c) =>\n c.type === \"link\" ||\n c.type === \"inlineCode\" ||\n c.type === \"strong\" ||\n c.type === \"emphasis\" ||\n c.type === \"delete\" ||\n c.type === \"image\" ||\n c.type === \"imageReference\" ||\n c.type === \"html\",\n );\n}\n\nfunction emitPlainHeader(heading: Heading, withLevel: boolean): ReadonlyArray<Block> {\n const plain = phrasingToPlain(heading.children);\n const block: HeaderBlock = {\n type: \"header\",\n text: { type: \"plain_text\", text: plain.length > 0 ? plain : \" \" },\n level: withLevel ? headerLevelOf(heading.depth) : undefined,\n };\n return [block];\n}\n\n/**\n * Narrows mdast depth (1–6) to Slack's header domain (1–4, `HEADER_LEVEL_MAX`).\n * Only reachable for depth ≤ 4: deeper headings take the rich_text path.\n */\nfunction headerLevelOf(depth: Heading[\"depth\"]): HeaderBlock[\"level\"] {\n return depth === 1 || depth === 2 || depth === 3 || depth === 4 ? depth : undefined;\n}\n\nfunction emitRichHeading(\n heading: Heading,\n ctx: ConversionContext,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n const plain = phrasingToPlain(heading.children);\n const depth = heading.depth;\n if (depth > HEADER_LEVEL_MAX) {\n ctx.degradations.add({\n nodeType: \"heading\",\n from: `header.h${String(depth)}`,\n to: \"rich_text.bold\",\n reason: `Heading level ${String(depth)} exceeds max ${String(HEADER_LEVEL_MAX)}`,\n path: ctx.path,\n });\n } else if (plain.length > HEADER_TEXT_MAX_CHARS) {\n ctx.degradations.add({\n nodeType: \"heading\",\n from: \"header\",\n to: \"rich_text.bold\",\n reason: \"Heading exceeds 150 plain chars\",\n path: ctx.path,\n });\n } else {\n ctx.degradations.add({\n nodeType: \"heading\",\n from: \"header\",\n to: \"rich_text.bold\",\n reason:\n \"Heading contains inline content unsupported by header (styles, links, images, or mentions)\",\n path: ctx.path,\n });\n }\n\n const inline = emitPhrasing(heading.children, ctx, { bold: true });\n const rich: RichTextBlock = {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements:\n inline.elements.length > 0\n ? inline.elements\n : [{ type: \"text\", text: \" \", style: { bold: true } }],\n },\n ],\n };\n const blocks: Block[] = [rich];\n if (!hoistImages) {\n return blocks;\n }\n for (const h of inline.hoistedImages) {\n blocks.push(hoistedImageBlock(h, ctx));\n }\n return blocks;\n}\n","import type { Html, RootContent } from \"mdast\";\n\nimport type { Block, ContainerBlock, SectionBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { CONTAINER_CHILDREN_MAX, CONTAINER_TITLE_MAX_CHARS } from \"../constants.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\n\nimport { clampSectionText, slackEntityRichTextInlines } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\nconst DETAILS_RE =\n /<details\\b[^>]{0,200}>\\s*<summary\\b[^>]{0,200}>([\\s\\S]{0,500}?)<\\/summary>([\\s\\S]{0,8000}?)<\\/details>/i;\n\n/**\n * Block HTML — details/summary → container; else strip+warn.\n */\nexport class HtmlBlockAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"html\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const html = node as Html;\n // details/summary must win over the Slack-entity path: a collapsible block\n // that also mentions <@U…> should stay a container, not flatten to rich_text.\n const details = DETAILS_RE.exec(html.value);\n if (details !== null) {\n const title = stripTags(details[1] ?? \"Details\").trim();\n const body = stripTags(details[2] ?? \"\").trim();\n return [\n {\n requires: [\"containerBlock\"],\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n const child: SectionBlock = {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: clampSectionText(body.length > 0 ? body : \" \", ctx, \"html.details.body\"),\n },\n };\n const block: ContainerBlock = {\n type: \"container\",\n title: {\n type: \"plain_text\",\n text: clampContainerTitle(title.length > 0 ? title : \"Details\", ctx),\n },\n child_blocks: [child].slice(0, CONTAINER_CHILDREN_MAX),\n is_collapsible: true,\n };\n return [block];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"html.details\",\n from: \"container\",\n to: \"section\",\n reason: \"containerBlock unavailable\",\n path: ctx.path,\n });\n return [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: clampSectionText(`*${title}*\\n${body}`, ctx, \"html.details.section\"),\n },\n },\n ];\n },\n },\n ];\n }\n\n // A line like \"<!here> deploying now\" parses as one block html node; Slack\n // entity tokens must survive as rich text elements, not be stripped as tags.\n const entityInlines = slackEntityRichTextInlines(html.value.trim(), {});\n if (entityInlines !== undefined) {\n return [\n {\n budget: { blocks: 1 },\n emit: (): ReadonlyArray<Block> => [\n {\n type: \"rich_text\",\n elements: [{ type: \"rich_text_section\", elements: entityInlines }],\n },\n ],\n },\n ];\n }\n\n return [\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"html\",\n from: \"html\",\n to: \"section\",\n reason: \"Unsupported block HTML stripped to text\",\n path: ctx.path,\n });\n const text = stripTags(html.value).trim();\n if (text.length === 0) {\n return [];\n }\n return [\n {\n type: \"section\",\n text: { type: \"mrkdwn\", text: clampSectionText(text, ctx, \"html.section\") },\n },\n ];\n },\n },\n ];\n }\n}\n\nfunction stripTags(html: string): string {\n return html.replace(/<[^>]{0,200}>/g, \"\");\n}\n\nfunction clampContainerTitle(text: string, ctx: ConversionContext): string {\n if (text.length <= CONTAINER_TITLE_MAX_CHARS) {\n return text;\n }\n ctx.degradations.add({\n nodeType: \"html.details\",\n from: \"container.title\",\n to: \"truncated\",\n reason: `Container title truncated to ${String(CONTAINER_TITLE_MAX_CHARS)} chars`,\n path: ctx.path,\n });\n return sliceSurrogateSafe(text, CONTAINER_TITLE_MAX_CHARS);\n}\n","import type { List, ListItem, PhrasingContent, RootContent } from \"mdast\";\n\nimport type { Block, RichTextBlock, RichTextList, RichTextSection } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RICH_TEXT_LIST_INDENT_MAX } from \"../constants.js\";\n\nimport {\n blockToPlainText,\n collectFlattenedUrls,\n type FlattenedUrl,\n} from \"./block-to-plain-text.js\";\nimport {\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n type HoistedImage,\n} from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Non-task lists → rich_text_list with sibling-indent nesting.\n */\nexport class ListAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n if (node.type !== \"list\") {\n return false;\n }\n return !isTaskList(node);\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const list = node as List;\n const hoistCount = countHoistableImagesInList(list, ctx);\n const candidates: Candidate[] = [\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n return emitListBlocks(list, emitCtx, true);\n },\n },\n ];\n if (hoistCount > 0) {\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"list\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted list images; emitting text only\",\n path: emitCtx.path,\n });\n return emitListBlocks(list, emitCtx, false);\n },\n });\n }\n return candidates;\n }\n}\n\nfunction emitListBlocks(\n list: List,\n emitCtx: ConversionContext,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n const { elements, hoistedImages } = emitListTree(list, 0, emitCtx);\n const block: RichTextBlock = { type: \"rich_text\", elements };\n const blocks: Block[] = [block];\n if (!hoistImages) {\n return blocks;\n }\n for (const h of hoistedImages) {\n blocks.push(hoistedImageBlock(h, emitCtx));\n }\n return blocks;\n}\n\nexport function isTaskList(list: List): boolean {\n return list.children.some((item) => item.checked === true || item.checked === false);\n}\n\nfunction countHoistableImagesInList(list: List, ctx: ConversionContext): number {\n let count = 0;\n for (const item of list.children) {\n count += countHoistableImages(collectListItemPhrasing(item), ctx);\n for (const child of item.children) {\n if (child.type === \"list\") {\n count += countHoistableImagesInList(child, ctx);\n }\n }\n }\n return count;\n}\n\nfunction emitListTree(\n list: List,\n indent: number,\n ctx: ConversionContext,\n): { elements: Array<RichTextList>; hoistedImages: HoistedImage[] } {\n let effectiveIndent = indent;\n if (effectiveIndent > RICH_TEXT_LIST_INDENT_MAX) {\n ctx.degradations.add({\n nodeType: \"list\",\n from: `indent:${String(effectiveIndent)}`,\n to: `indent:${String(RICH_TEXT_LIST_INDENT_MAX)}`,\n reason: \"List indent clamped at 6\",\n path: ctx.path,\n });\n effectiveIndent = RICH_TEXT_LIST_INDENT_MAX;\n }\n\n const ordered = list.ordered === true;\n const startOffset =\n ordered && list.start !== null && list.start !== undefined && list.start > 1\n ? list.start - 1\n : 0;\n\n // Slack nests a higher-indent rich_text_list under the *last* item of the\n // preceding same-indent chunk (see Block Kit rich_text examples). Keep\n // nest-free siblings in the buffer and flush only when an item has children\n // so that item is last in its chunk; ordered continuation chunks carry an\n // offset so numbering resumes where it left off.\n const out: RichTextList[] = [];\n const hoistedImages: HoistedImage[] = [];\n let pendingSections: RichTextSection[] = [];\n\n const flush = (lastIndex: number): void => {\n if (pendingSections.length === 0) {\n return;\n }\n const chunkStartIndex = lastIndex - pendingSections.length + 1;\n const offset = startOffset + chunkStartIndex;\n out.push({\n type: \"rich_text_list\",\n style: ordered ? \"ordered\" : \"bullet\",\n elements: pendingSections,\n indent: effectiveIndent,\n offset: ordered && offset > 0 ? offset : undefined,\n });\n pendingSections = [];\n };\n\n for (const [index, item] of list.children.entries()) {\n const { section, childLists, hoistedImages: itemImages } = emitListItem(item, ctx);\n pendingSections.push(section);\n hoistedImages.push(...itemImages);\n if (childLists.length === 0) {\n continue;\n }\n flush(index);\n for (const child of childLists) {\n const nestedResult = emitListTree(child, effectiveIndent + 1, ctx);\n out.push(...nestedResult.elements);\n hoistedImages.push(...nestedResult.hoistedImages);\n }\n }\n flush(list.children.length - 1);\n\n if (out.length === 0) {\n out.push({\n type: \"rich_text_list\",\n style: ordered ? \"ordered\" : \"bullet\",\n elements: [{ type: \"rich_text_section\", elements: [{ type: \"text\", text: \" \" }] }],\n indent: effectiveIndent,\n offset: undefined,\n });\n }\n\n return { elements: out, hoistedImages };\n}\n\n/** Phrasing content of a list item for hoist counting — no degradations emitted. */\nfunction collectListItemPhrasing(item: ListItem): PhrasingContent[] {\n const phrasing: PhrasingContent[] = [];\n let sawBlock = false;\n\n for (const child of item.children) {\n if (child.type === \"paragraph\") {\n if (sawBlock) {\n phrasing.push({ type: \"text\", value: \"\\n\" });\n }\n phrasing.push(...child.children);\n sawBlock = true;\n } else if (child.type !== \"list\") {\n sawBlock = true;\n }\n }\n return phrasing;\n}\n\nfunction emitListItem(\n item: ListItem,\n ctx: ConversionContext,\n): { section: RichTextSection; childLists: List[]; hoistedImages: HoistedImage[] } {\n const phrasing: PhrasingContent[] = [];\n const childLists: List[] = [];\n let sawBlock = false;\n\n for (const child of item.children) {\n if (child.type === \"paragraph\") {\n if (sawBlock) {\n phrasing.push({ type: \"text\", value: \"\\n\" });\n }\n phrasing.push(...child.children);\n sawBlock = true;\n } else if (child.type === \"list\") {\n childLists.push(child);\n } else {\n ctx.degradations.add({\n nodeType: \"listItem\",\n from: child.type,\n to: \"text\",\n reason: \"Block child of list item flattened into text\",\n path: ctx.path,\n });\n const dropped: FlattenedUrl[] = [];\n collectFlattenedUrls(child, dropped);\n for (const { nodeType, url } of dropped) {\n ctx.degradations.add({\n nodeType,\n from: url,\n to: \"label_only\",\n reason: \"Block flattened into list item text; URL dropped\",\n path: ctx.path,\n });\n }\n const text = blockToPlainText(child);\n if (text.length > 0) {\n if (sawBlock) {\n phrasing.push({ type: \"text\", value: \"\\n\" });\n }\n phrasing.push({ type: \"text\", value: text });\n }\n sawBlock = true;\n }\n }\n\n const inline = emitPhrasing(phrasing, ctx);\n return {\n section: {\n type: \"rich_text_section\",\n elements: inline.elements.length > 0 ? inline.elements : [{ type: \"text\", text: \" \" }],\n },\n childLists,\n hoistedImages: [...inline.hoistedImages],\n };\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { Block, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport { preformattedRichText } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { tryRenderImage } from \"./try-render-image.js\";\n\n/**\n * Display math → configured image renderer / preformatted TeX.\n */\nexport class MathBlockAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"math\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n const value = \"value\" in node && typeof node.value === \"string\" ? node.value : \"\";\n return [\n {\n budget: { blocks: 1 },\n emit: async (ctx: ConversionContext): Promise<ReadonlyArray<Block>> => {\n const rendered = await tryRenderImage(\n {\n lang: \"math\",\n source: value,\n altText: \"display math\",\n },\n \"math\",\n ctx,\n );\n return rendered === undefined ? [] : [rendered];\n },\n },\n {\n requires: [\"preformattedLanguage\"],\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n return [preformattedMath(value, true, ctx)];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"math\",\n from: \"preformatted.language\",\n to: \"preformatted\",\n reason: \"preformattedLanguage capability unavailable; omitting language\",\n path: ctx.path,\n });\n return [preformattedMath(value, false, ctx)];\n },\n },\n ];\n }\n}\n\nfunction preformattedMath(value: string, withLang: boolean, ctx: ConversionContext): RichTextBlock {\n ctx.degradations.add({\n nodeType: \"math\",\n from: \"math\",\n to: \"rich_text_preformatted\",\n reason: \"Math is emitted as preformatted/code text\",\n path: ctx.path,\n });\n return preformattedRichText(value, withLang ? \"latex\" : undefined);\n}\n","import type { Code, RootContent } from \"mdast\";\n\nimport type { Block, DataVisualizationBlock, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RecordingDegradationCollector } from \"../budget/recording-degradation-collector.js\";\nimport {\n CHART_LABEL_MAX_CHARS,\n CHART_POINTS_MAX,\n CHART_SEGMENTS_MAX,\n CHART_SERIES_MAX,\n CHART_TITLE_MAX_CHARS,\n} from \"../constants.js\";\nimport type { MermaidChartParser, MermaidPieAst, MermaidXyChartAst } from \"../types.js\";\n\nimport { preformattedRichText, truncateLabel } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { tryRenderImage } from \"./try-render-image.js\";\n\nexport interface MermaidFenceAdapterDeps {\n readonly pieParser: MermaidChartParser;\n readonly xyParser: MermaidChartParser;\n}\n\n/**\n * Mermaid fences → data_visualization / image renderer / preformatted.\n */\nexport class MermaidFenceAdapter implements NodeAdapter {\n private readonly pieParser: MermaidChartParser;\n private readonly xyParser: MermaidChartParser;\n\n constructor(deps: MermaidFenceAdapterDeps) {\n this.pieParser = deps.pieParser;\n this.xyParser = deps.xyParser;\n }\n\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"code\" && (node.lang ?? \"\").toLowerCase() === \"mermaid\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const code = node as Code;\n const source = code.value;\n const kind = detectMermaidKind(source);\n const candidates: Candidate[] = [];\n let rendererAttempted = false;\n\n // Probe native chart viability with a throwaway collector so plan-time\n // parse/limit failures are not recorded unless the native candidate emits.\n const probeCtx = ctx.withDegradations(new RecordingDegradationCollector());\n\n if (kind === \"pie\") {\n const parsed = this.pieParser.parse(source);\n if (parsed.ok && parsed.value.kind === \"pie\") {\n const probe = tryPieBlock(parsed.value, probeCtx);\n if (probe !== undefined) {\n const ast = parsed.value;\n candidates.push({\n requires: [\"dataVisualization\"],\n budget: { blocks: 1, chart: true },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n const block = tryPieBlock(ast, emitCtx);\n return block !== undefined ? [block] : [];\n },\n });\n }\n }\n } else if (kind === \"xychart-beta\") {\n const parsed = this.xyParser.parse(source);\n if (parsed.ok && parsed.value.kind === \"xychart-beta\") {\n const probe = tryXyBlock(parsed.value, probeCtx);\n if (probe !== undefined) {\n const ast = parsed.value;\n candidates.push({\n requires: [\"dataVisualization\"],\n budget: { blocks: 1, chart: true },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n const block = tryXyBlock(ast, emitCtx);\n return block !== undefined ? [block] : [];\n },\n });\n }\n }\n }\n\n candidates.push({\n budget: { blocks: 1 },\n emit: async (emitCtx: ConversionContext): Promise<ReadonlyArray<Block>> => {\n rendererAttempted = true;\n const rendered = await tryRenderImage(\n {\n lang: \"mermaid\",\n source,\n altText: \"mermaid diagram\",\n },\n \"code.mermaid\",\n emitCtx,\n );\n return rendered === undefined ? [] : [rendered];\n },\n });\n\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"code.mermaid\",\n from: kind,\n to: \"rich_text_preformatted\",\n reason: rendererAttempted\n ? \"No native chart / renderer image; emitting mermaid source\"\n : \"Renderer candidate skipped by message budget; emitting mermaid source\",\n path: emitCtx.path,\n });\n return [preformattedMermaid(source, emitCtx)];\n },\n });\n\n return candidates;\n }\n}\n\nfunction detectMermaidKind(source: string): \"pie\" | \"xychart-beta\" | \"other\" {\n const first = source\n .split(/\\r?\\n/)\n .map((l) => l.replace(/%%[^\\n]{0,500}/, \"\").trim())\n .find((l) => l.length > 0);\n if (first === undefined) {\n return \"other\";\n }\n if (/^pie\\b/i.test(first)) {\n return \"pie\";\n }\n if (/^xychart-beta\\b/i.test(first)) {\n return \"xychart-beta\";\n }\n return \"other\";\n}\n\nfunction tryPieBlock(\n ast: MermaidPieAst,\n ctx: ConversionContext,\n): DataVisualizationBlock | undefined {\n if (ast.segments.length > CHART_SEGMENTS_MAX) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.pie\",\n from: \"data_visualization\",\n to: \"fallback\",\n reason: `Pie has ${String(ast.segments.length)} segments (max ${String(CHART_SEGMENTS_MAX)})`,\n path: ctx.path,\n });\n return undefined;\n }\n const segments = ast.segments.map((s) => {\n const t = truncateLabel(s.label, CHART_LABEL_MAX_CHARS);\n if (t.truncated) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.pie\",\n from: s.label,\n to: t.text,\n reason: \"Pie label truncated to 20 chars\",\n path: ctx.path,\n });\n }\n return { label: t.text, value: s.value };\n });\n const titleRaw =\n ast.title ??\n (ctx.precedingHeading !== undefined && ctx.precedingHeading.length > 0\n ? ctx.precedingHeading\n : \"Chart\");\n return {\n type: \"data_visualization\",\n title: truncateChartTitle(titleRaw, ctx, \"code.mermaid.pie\"),\n chart: { type: \"pie\", segments },\n };\n}\n\nfunction tryXyBlock(\n ast: MermaidXyChartAst,\n ctx: ConversionContext,\n): DataVisualizationBlock | undefined {\n const categories = ast.categories.map((c) => {\n const t = truncateLabel(c, CHART_LABEL_MAX_CHARS);\n if (t.truncated) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: c,\n to: t.text,\n reason: \"Category label truncated to 20 chars\",\n path: ctx.path,\n });\n }\n return t.text;\n });\n\n if (categories.length > CHART_POINTS_MAX) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: \"data_visualization\",\n to: \"fallback\",\n reason: `xychart has ${String(categories.length)} points (max ${String(CHART_POINTS_MAX)})`,\n path: ctx.path,\n });\n return undefined;\n }\n\n let chartType: \"bar\" | \"line\" = \"bar\";\n let seriesValues = ast.bars;\n if (ast.bars.length > 0 && ast.lines.length > 0) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: \"mixed bar+line\",\n to: \"bar\",\n reason: \"Slack charts are single-type; preferring bar\",\n path: ctx.path,\n });\n } else if (ast.bars.length === 0) {\n chartType = \"line\";\n seriesValues = ast.lines;\n }\n\n if (seriesValues.length === 0 || seriesValues.length > CHART_SERIES_MAX) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: \"data_visualization\",\n to: \"fallback\",\n reason: `Invalid series count (${String(seriesValues.length)})`,\n path: ctx.path,\n });\n return undefined;\n }\n\n for (const [i, values] of seriesValues.entries()) {\n if (values.length !== categories.length) {\n ctx.degradations.add({\n nodeType: \"code.mermaid.xychart\",\n from: `series[${String(i)}].length=${String(values.length)}`,\n to: `categories.length=${String(categories.length)}`,\n reason: \"xychart series length mismatched categories; padded/truncated by index\",\n path: ctx.path,\n });\n }\n }\n const series = seriesValues.map((values, i) => ({\n name: truncateLabel(`Series ${String(i + 1)}`, CHART_LABEL_MAX_CHARS).text,\n data: categories.map((label, idx) => ({\n label,\n value: values[idx] ?? 0,\n })),\n }));\n\n const titleRaw =\n ast.title ??\n (ctx.precedingHeading !== undefined && ctx.precedingHeading.length > 0\n ? ctx.precedingHeading\n : \"Chart\");\n\n return {\n type: \"data_visualization\",\n title: truncateChartTitle(titleRaw, ctx, \"code.mermaid.xychart\"),\n chart: {\n type: chartType,\n series,\n axis_config: {\n categories,\n x_label:\n ast.xLabel !== undefined\n ? truncateChartTitle(ast.xLabel, ctx, \"code.mermaid.xychart\")\n : undefined,\n y_label:\n ast.yLabel !== undefined\n ? truncateChartTitle(ast.yLabel, ctx, \"code.mermaid.xychart\")\n : undefined,\n },\n },\n };\n}\n\nfunction truncateChartTitle(raw: string, ctx: ConversionContext, nodeType: string): string {\n const t = truncateLabel(raw, CHART_TITLE_MAX_CHARS);\n if (t.truncated) {\n ctx.degradations.add({\n nodeType,\n from: raw,\n to: t.text,\n reason: `Chart title truncated to ${String(CHART_TITLE_MAX_CHARS)} chars`,\n path: ctx.path,\n });\n }\n return t.text;\n}\n\nfunction preformattedMermaid(source: string, ctx: ConversionContext): RichTextBlock {\n const withLang = ctx.config.capabilities.preformattedLanguage;\n if (!withLang) {\n ctx.degradations.add({\n nodeType: \"code.mermaid\",\n from: \"preformatted.language\",\n to: \"preformatted\",\n reason: \"preformattedLanguage capability unavailable; omitting language\",\n path: ctx.path,\n });\n }\n return preformattedRichText(source, withLang ? \"mermaid\" : undefined);\n}\n","import type { Paragraph, RootContent } from \"mdast\";\n\nimport type { Block, ImageBlock, RichTextBlock } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport {\n clampImageText,\n clampSectionText,\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n isPublicImageUrl,\n isValidLinkUrl,\n} from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Paragraph → rich_text_section (coalesced later by assembler).\n */\nexport class ParagraphAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"paragraph\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const paragraph = node as Paragraph;\n const loneImage =\n paragraph.children.length === 1 && paragraph.children[0]?.type === \"image\"\n ? paragraph.children[0]\n : undefined;\n const hoistCount = loneImage !== undefined ? 0 : countHoistableImages(paragraph.children, ctx);\n\n const candidates: Candidate[] = [\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n return emitParagraph(paragraph, emitCtx, loneImage, true);\n },\n },\n ];\n if (hoistCount > 0) {\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"paragraph\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted paragraph images; emitting text only\",\n path: emitCtx.path,\n });\n return emitParagraph(paragraph, emitCtx, loneImage, false);\n },\n });\n }\n return candidates;\n }\n}\n\nfunction emitParagraph(\n paragraph: Paragraph,\n emitCtx: ConversionContext,\n loneImage: Paragraph[\"children\"][number] | undefined,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n // Lone image paragraph → image block\n if (loneImage !== undefined && loneImage.type === \"image\") {\n const img = loneImage;\n if (isPublicImageUrl(img.url)) {\n const altRaw = img.alt ?? \"image\";\n const alt = clampImageText(altRaw.length > 0 ? altRaw : \"image\", emitCtx, \"alt_text\");\n const block: ImageBlock = {\n type: \"image\",\n image_url: img.url,\n alt_text: alt,\n title:\n img.title !== null && img.title !== undefined && img.title.length > 0\n ? {\n type: \"plain_text\",\n text: clampImageText(img.title, emitCtx, \"title\"),\n }\n : undefined,\n };\n return [block];\n }\n // mrkdwn <url|label> links share the rich text link URL rules; a relative\n // or non-http(s) URL renders as literal \"<…|…>\" garbage, so degrade those\n // to plain text with the URL preserved as a suffix.\n const linkable = isValidLinkUrl(img.url);\n emitCtx.degradations.add({\n nodeType: \"image\",\n from: \"image\",\n to: linkable ? \"section.link\" : \"section.text\",\n reason: \"Non-public or invalid image URL\",\n path: emitCtx.path,\n });\n const alt = img.alt ?? \"\";\n const label = alt.length > 0 ? alt : img.url.length > 0 ? img.url : \"image\";\n const fallbackText = linkable\n ? `<${img.url}|${label}>`\n : img.url.length > 0 && img.url !== label\n ? `${label} (${img.url})`\n : label;\n return [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: clampSectionText(fallbackText, emitCtx, \"section\"),\n },\n },\n ];\n }\n\n const inline = emitPhrasing(paragraph.children, emitCtx);\n const blocks: Block[] = [];\n const rich: RichTextBlock = {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements: inline.elements.length > 0 ? inline.elements : [{ type: \"text\", text: \" \" }],\n },\n ],\n };\n blocks.push(rich);\n if (!hoistImages) {\n return blocks;\n }\n for (const h of inline.hoistedImages) {\n blocks.push(hoistedImageBlock(h, emitCtx));\n }\n return blocks;\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { Block } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * Consumes definition / yaml / toml nodes without emitting blocks.\n */\nexport class SkipAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n const t = node.type as string;\n return t === \"definition\" || t === \"yaml\" || t === \"toml\" || t === \"footnoteDefinition\";\n }\n\n plan(node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n return [\n {\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n const t = node.type as string;\n if (t === \"yaml\" || t === \"toml\") {\n ctx.degradations.add({\n nodeType: t,\n from: \"frontmatter\",\n to: \"skip\",\n reason: \"Frontmatter skipped by default\",\n path: ctx.path,\n });\n }\n return [];\n },\n },\n ];\n }\n}\n","import type { AlignType, RootContent, Table, TableCell as MdastTableCell } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\nimport type {\n Block,\n DataTableBlock,\n MarkdownBlock,\n RichTextBlock,\n TableBlock,\n TableCell,\n TableColumnSetting,\n} from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RecordingDegradationCollector } from \"../budget/recording-degradation-collector.js\";\nimport {\n DATA_TABLE_CAPTION_MAX_CHARS,\n DATA_TABLE_MAX_DATA_ROWS,\n TABLE_CELL_MIN_CHARS,\n TABLE_CELL_WRAP_THRESHOLD,\n TABLE_MAX_COLS,\n TABLE_PREFERRED_MAX_ROWS,\n} from \"../constants.js\";\nimport { sliceSurrogateSafe } from \"../utf16.js\";\n\nimport { emitPhrasing, preformattedRichText } from \"./inline.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * GFM tables → table / data_table / markdown / ASCII fallbacks.\n */\nexport class TableAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"table\";\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const table = normalizeTableRows(node as Table, ctx);\n const rowCount = table.children.length;\n const colCount = table.children[0]?.children.length ?? 0;\n\n if (colCount > TABLE_MAX_COLS) {\n const cellChars = countEmittedCellChars(table, ctx, \"table\");\n return markdownThenAscii(table, cellChars, \"Table exceeds 20 columns\");\n }\n\n if (rowCount <= TABLE_PREFERRED_MAX_ROWS) {\n // Match validateBlocks measurement (JSON size for rich_text cells).\n const cellChars = countEmittedCellChars(table, ctx, \"table\");\n return [\n {\n requires: [\"tableBlock\"],\n budget: { blocks: 1, tableChars: cellChars },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n return [buildTableBlock(table, ctx)];\n },\n },\n ...markdownThenAscii(table, cellChars, \"tableBlock unavailable or char budget\"),\n ];\n }\n\n // >50 rows → data_table (≤200 data rows)\n const dataRows = Math.max(0, rowCount - 1);\n if (dataRows <= DATA_TABLE_MAX_DATA_ROWS) {\n const preferredTable = truncateRows(table, TABLE_PREFERRED_MAX_ROWS);\n const preferredChars = countEmittedCellChars(preferredTable, ctx, \"table\");\n // data_table headers stay raw_text — count with that mode so budget matches emit.\n const dataTableChars = countEmittedCellChars(table, ctx, \"data_table\");\n return [\n {\n requires: [\"dataTable\"],\n budget: { blocks: 1, dataTableChars },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"table\",\n from: \"table\",\n to: \"data_table\",\n reason: `Table has ${String(rowCount)} rows (>${String(TABLE_PREFERRED_MAX_ROWS)}); using data_table`,\n path: emitCtx.path,\n });\n return [buildDataTable(table, emitCtx)];\n },\n },\n {\n requires: [\"tableBlock\"],\n budget: { blocks: 1, tableChars: preferredChars },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"table\",\n from: \"data_table\",\n to: \"table\",\n reason: \"dataTable unavailable; truncating to table block capacity\",\n path: emitCtx.path,\n });\n return [buildTableBlock(preferredTable, emitCtx)];\n },\n },\n ...markdownThenAscii(table, dataTableChars, \"native table unavailable\"),\n ];\n }\n\n // >200 data rows → split warning + first chunk as data_table / table\n const dataChunk = truncateRows(table, DATA_TABLE_MAX_DATA_ROWS + 1);\n const dataChunkChars = countEmittedCellChars(dataChunk, ctx, \"data_table\");\n return [\n {\n requires: [\"dataTable\"],\n budget: { blocks: 1, dataTableChars: dataChunkChars },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n emitCtx.degradations.add({\n nodeType: \"table\",\n from: \"table\",\n to: \"data_table.split\",\n reason: `Table has ${String(dataRows)} data rows; emitting first ${String(DATA_TABLE_MAX_DATA_ROWS)}`,\n path: emitCtx.path,\n });\n return [buildDataTable(dataChunk, emitCtx)];\n },\n },\n ...markdownThenAscii(table, dataChunkChars, \"oversized table\"),\n ];\n }\n}\n\n/**\n * GFM tables key column count off the header row: shorter rows get empty\n * cells inserted and excess cells are ignored\n * (https://github.github.com/gfm/#tables-extension-). remark preserves rows\n * as authored, so without this step ragged rows reach the Slack table block\n * misaligned against `column_settings`.\n */\nfunction normalizeTableRows(table: Table, ctx: ConversionContext): Table {\n const colCount = table.children[0]?.children.length ?? 0;\n if (colCount === 0 || table.children.every((row) => row.children.length === colCount)) {\n return table;\n }\n const children = table.children.map((row, rowIndex) => {\n if (row.children.length === colCount) {\n return row;\n }\n if (row.children.length > colCount) {\n ctx.degradations.add({\n nodeType: \"table\",\n from: `row[${String(rowIndex)}]: ${String(row.children.length)} cells`,\n to: `${String(colCount)} cells`,\n reason: \"Cells beyond the header column count dropped (GFM ignores the excess)\",\n path: ctx.path,\n });\n return { ...row, children: row.children.slice(0, colCount) };\n }\n const padding = Array.from(\n { length: colCount - row.children.length },\n (): MdastTableCell => ({ type: \"tableCell\", children: [] }),\n );\n return { ...row, children: [...row.children, ...padding] };\n });\n return { ...table, children };\n}\n\nfunction markdownThenAscii(table: Table, cellChars: number, reason: string): Candidate[] {\n const md = toPipeMarkdown(table);\n return [\n {\n requires: [\"markdownBlock\"],\n budget: { blocks: 1, markdownChars: md.length },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"table\",\n from: \"native_table\",\n to: \"markdown\",\n reason,\n path: ctx.path,\n });\n const block: MarkdownBlock = { type: \"markdown\", text: md };\n return [block];\n },\n },\n {\n budget: { blocks: 1 },\n emit: (ctx: ConversionContext): ReadonlyArray<Block> => {\n ctx.degradations.add({\n nodeType: \"table\",\n from: \"markdown\",\n to: \"ascii_preformatted\",\n reason: `${reason}; markdown unavailable (chars≈${String(cellChars)})`,\n path: ctx.path,\n });\n return [asciiTableBlock(table)];\n },\n },\n ];\n}\n\nfunction buildTableBlock(table: Table, ctx: ConversionContext): TableBlock {\n return {\n type: \"table\",\n rows: buildRows(table, ctx, \"table\"),\n column_settings: columnSettings(table),\n };\n}\n\n/**\n * Emit every cell and flag the blanks that had to be padded to satisfy Slack's\n * `minLength: 1` on `raw_text`/`raw_number` text.\n */\nfunction buildRows(\n table: Table,\n ctx: ConversionContext,\n mode: \"table\" | \"data_table\",\n): ReadonlyArray<ReadonlyArray<TableCell>> {\n let padded = 0;\n const rows = table.children.map((row, rowIndex) =>\n row.children.map((cell) => {\n const emitted =\n mode === \"data_table\"\n ? cellForDataTable(cell, ctx, rowIndex)\n : cellToSlack(cell, ctx, rowIndex === 0);\n if (emitted.type === \"raw_text\" && emitted.text === EMPTY_CELL_TEXT) {\n padded += 1;\n }\n return emitted;\n }),\n );\n if (padded > 0) {\n ctx.degradations.add({\n nodeType: \"table\",\n from: `${String(padded)} empty cells`,\n to: \"single-space cells\",\n reason: \"Slack rejects empty table cell text; padded to one space\",\n path: ctx.path,\n });\n }\n return rows;\n}\n\nfunction buildDataTable(table: Table, ctx: ConversionContext): DataTableBlock {\n const captionRaw =\n ctx.precedingHeading !== undefined && ctx.precedingHeading.length > 0\n ? ctx.precedingHeading\n : \"Table\";\n const caption = sliceSurrogateSafe(captionRaw, DATA_TABLE_CAPTION_MAX_CHARS);\n if (captionRaw.length > DATA_TABLE_CAPTION_MAX_CHARS) {\n ctx.degradations.add({\n nodeType: \"table\",\n from: \"data_table.caption\",\n to: \"truncated\",\n reason: \"data_table caption truncated to 150 chars\",\n path: ctx.path,\n });\n }\n return {\n type: \"data_table\",\n caption,\n rows: buildRows(table, ctx, \"data_table\"),\n page_size: 5,\n row_header_column_index: 0,\n };\n}\n\n/**\n * Slack requires at least one character in every `raw_text`/`raw_number` cell\n * (`minLength: 1`), so a blank markdown cell renders as a single space.\n * https://docs.slack.dev/reference/block-kit/blocks/data-table-block\n */\nconst EMPTY_CELL_TEXT = \" \";\n\nfunction cellText(text: string): string {\n return text.length >= TABLE_CELL_MIN_CHARS ? text : EMPTY_CELL_TEXT;\n}\n\n/** Slack forbids rich_text in data_table headers; keep emission and budget counting aligned. */\nfunction cellForDataTable(\n cell: MdastTableCell,\n ctx: ConversionContext,\n rowIndex: number,\n): TableCell {\n if (rowIndex === 0) {\n return { type: \"raw_text\", text: cellText(toString(cell)) };\n }\n return cellToSlack(cell, ctx, false);\n}\n\nfunction cellToSlack(cell: MdastTableCell, ctx: ConversionContext, header: boolean): TableCell {\n // Emit the cell through the shared inline pipeline so Slack entity tokens\n // (<@U…>, <!here>), emoji shortcodes, mention resolvers, and labeled links\n // are converted instead of landing in raw_text as literal source text. A\n // cell that reduces to one unstyled text element stays raw_text/raw_number.\n const inline = emitPhrasing(cell.children, ctx);\n const single = inline.elements.length === 1 ? inline.elements[0] : undefined;\n const isEmpty = inline.elements.length === 0;\n const isSingleUnstyledText = single?.type === \"text\" && single.style === undefined;\n const plainText = isEmpty ? toString(cell) : isSingleUnstyledText ? single.text : undefined;\n if (plainText !== undefined) {\n // Header row titles must stay text — numeric-looking labels like \"2024\" are not values.\n const trimmed = plainText.trim();\n if (!header && /^-?\\d+(\\.\\d+)?$/.test(trimmed)) {\n return { type: \"raw_number\", value: Number(trimmed), text: trimmed };\n }\n return { type: \"raw_text\", text: cellText(plainText) };\n }\n const rich: RichTextBlock = {\n type: \"rich_text\",\n elements: [\n {\n type: \"rich_text_section\",\n elements: inline.elements,\n },\n ],\n };\n return rich;\n}\n\nfunction columnSettings(table: Table): ReadonlyArray<TableColumnSetting | null> {\n const align = table.align ?? [];\n const colCount = table.children[0]?.children.length ?? 0;\n const settings: Array<TableColumnSetting | null> = [];\n for (let i = 0; i < colCount; i += 1) {\n const a = align[i] as AlignType | null | undefined;\n const long = table.children.some(\n (row) =>\n toString(row.children[i] ?? { type: \"text\", value: \"\" }).length > TABLE_CELL_WRAP_THRESHOLD,\n );\n const alignVal = a === \"left\" || a === \"center\" || a === \"right\" ? a : undefined;\n if (alignVal === undefined && !long) {\n settings.push(null);\n } else {\n settings.push({\n align: alignVal,\n is_wrapped: long ? true : undefined,\n });\n }\n }\n return settings;\n}\n\nfunction countEmittedCellChars(\n table: Table,\n ctx: ConversionContext,\n mode: \"table\" | \"data_table\",\n): number {\n const probe = ctx.withDegradations(new RecordingDegradationCollector());\n let n = 0;\n for (const [rowIndex, row] of table.children.entries()) {\n for (const cell of row.children) {\n const emitted =\n mode === \"data_table\"\n ? cellForDataTable(cell, probe, rowIndex)\n : cellToSlack(cell, probe, rowIndex === 0);\n n += slackCellCharCount(emitted);\n }\n }\n return n;\n}\n\nfunction slackCellCharCount(cell: TableCell): number {\n if (cell.type === \"raw_text\" || cell.type === \"raw_number\") {\n return cell.text.length;\n }\n return JSON.stringify(cell).length;\n}\n\nfunction truncateRows(table: Table, maxRows: number): Table {\n return {\n ...table,\n children: table.children.slice(0, maxRows),\n };\n}\n\nfunction toPipeMarkdown(table: Table): string {\n const rows = table.children.map((row) =>\n row.children.map((c) => toString(c).replace(/\\|/g, \"\\\\|\")),\n );\n if (rows.length === 0) {\n return \"\";\n }\n const header = rows[0] ?? [];\n const align = table.align ?? [];\n const sep = header.map((_, i) => {\n const a = align[i];\n if (a === \"center\") return \":---:\";\n if (a === \"right\") return \"---:\";\n if (a === \"left\") return \":---\";\n return \"---\";\n });\n const lines = [\n `| ${header.join(\" | \")} |`,\n `| ${sep.join(\" | \")} |`,\n ...rows.slice(1).map((r) => `| ${r.join(\" | \")} |`),\n ];\n return lines.join(\"\\n\");\n}\n\nfunction asciiTableBlock(table: Table): RichTextBlock {\n return preformattedRichText(toPipeMarkdown(table), undefined);\n}\n","import type { Definition, PhrasingContent } from \"mdast\";\nimport { toString } from \"mdast-util-to-string\";\n\n/**\n * Inline markdown for content bound for a Slack `markdown` block.\n *\n * Slack renders standard markdown in that block — links, bold, italic,\n * strikethrough, inline code, and images (as link text) — so flattening inlines\n * to bare text discards fidelity the destination would have carried.\n *\n * Text nodes pass through unescaped, exactly as they did when this content was\n * flattened wholesale. This only re-adds syntax around nodes that already\n * carried that meaning in the source, so a document with no links converts\n * byte-identically to before.\n */\nexport function phrasingToMarkdown(\n nodes: ReadonlyArray<PhrasingContent>,\n definitions: ReadonlyMap<string, Definition>,\n): string {\n let out = \"\";\n for (const node of nodes) {\n out += nodeToMarkdown(node, definitions);\n }\n return out;\n}\n\n// Deliberately not an exhaustive switch: anything not named here is a single\n// text run for which `toString` is already the right answer.\nfunction nodeToMarkdown(\n node: PhrasingContent,\n definitions: ReadonlyMap<string, Definition>,\n): string {\n if (node.type === \"text\") {\n return node.value;\n }\n if (node.type === \"inlineCode\") {\n return `\\`${node.value}\\``;\n }\n if (node.type === \"strong\") {\n return `**${phrasingToMarkdown(node.children, definitions)}**`;\n }\n if (node.type === \"emphasis\") {\n return `_${phrasingToMarkdown(node.children, definitions)}_`;\n }\n if (node.type === \"delete\") {\n return `~~${phrasingToMarkdown(node.children, definitions)}~~`;\n }\n if (node.type === \"link\") {\n return labelledLink(phrasingToMarkdown(node.children, definitions), node.url);\n }\n if (node.type === \"image\") {\n return ``;\n }\n if (node.type === \"linkReference\") {\n const url = definitions.get(node.identifier)?.url;\n const label = phrasingToMarkdown(node.children, definitions);\n return url === undefined ? label : labelledLink(label, url);\n }\n if (node.type === \"imageReference\") {\n const url = definitions.get(node.identifier)?.url;\n const alt = node.alt ?? \"\";\n return url === undefined ? alt : ``;\n }\n // A hard break inside a list item would end the item, so keep the run on one line.\n if (node.type === \"break\") {\n return \" \";\n }\n return toString(node);\n}\n\n/**\n * An autolink already reads as its own URL; wrapping it as `[url](url)` would be\n * noise, and bare URLs are what this path emitted before.\n */\nfunction labelledLink(label: string, url: string): string {\n return label === url ? url : `[${label}](${url})`;\n}\n","import type { Definition, List, ListItem, PhrasingContent, RootContent } from \"mdast\";\n\nimport type {\n Block,\n MarkdownBlock,\n RichTextBlock,\n RichTextList,\n RichTextSection,\n} from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\nimport { RICH_TEXT_LIST_INDENT_MAX } from \"../constants.js\";\n\nimport {\n blockToPlainText,\n collectFlattenedUrls,\n type FlattenedUrl,\n} from \"./block-to-plain-text.js\";\nimport {\n countHoistableImages,\n emitPhrasing,\n hoistedImageBlock,\n type HoistedImage,\n} from \"./inline.js\";\nimport { isTaskList } from \"./list-adapter.js\";\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\nimport { phrasingToMarkdown } from \"./phrasing-to-markdown.js\";\n\n/**\n * Task lists → markdown block (checkboxes); fallback unicode in rich_text_list.\n *\n * Both rungs carry inline links: Slack renders `[label](url)` in a `markdown`\n * block, and a rich_text section holds real `link` elements next to the unicode\n * checkbox. Only a block child of an item (a table, a code fence) still has to\n * be flattened, and only that flattening drops URLs.\n */\nexport class TaskListAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"list\" && isTaskList(node);\n }\n\n plan(node: RootContent, ctx: ConversionContext): ReadonlyArray<Candidate> {\n const list = node as List;\n const md = serializeTaskList(list, ctx.definitions);\n const hoistCount = countHoistableImagesInTaskList(list, ctx);\n const candidates: Candidate[] = [\n {\n requires: [\"markdownBlock\"],\n budget: { blocks: 1, markdownChars: md.length },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n flagBlockChildUrlLoss(list, emitCtx);\n flagImagesRenderedAsLinks(list, emitCtx);\n const block: MarkdownBlock = { type: \"markdown\", text: md };\n return [block];\n },\n },\n {\n budget: { blocks: 1 + hoistCount },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n flagUnicodeCheckboxes(list, emitCtx);\n return emitUnicodeTaskBlocks(list, emitCtx, HOIST_IMAGES);\n },\n },\n ];\n if (hoistCount > 0) {\n candidates.push({\n budget: { blocks: 1 },\n emit: (emitCtx: ConversionContext): ReadonlyArray<Block> => {\n flagUnicodeCheckboxes(list, emitCtx);\n emitCtx.degradations.add({\n nodeType: \"list\",\n from: \"rich_text+images\",\n to: \"rich_text\",\n reason: \"Budget exhausted for hoisted task list images; emitting text only\",\n path: emitCtx.path,\n });\n return emitUnicodeTaskBlocks(list, emitCtx, TEXT_ONLY);\n },\n });\n }\n return candidates;\n }\n}\n\nfunction flagUnicodeCheckboxes(list: List, ctx: ConversionContext): void {\n flagBlockChildUrlLoss(list, ctx);\n ctx.degradations.add({\n nodeType: \"list\",\n from: \"markdown.task_list\",\n to: \"rich_text_list.unicode_checkbox\",\n reason: \"markdownBlock unavailable or budget exhausted\",\n path: ctx.path,\n });\n}\n\n/**\n * URLs inside a block child of an item. Both rungs flatten a table or code fence\n * to plain text, which keeps labels only, so this loss is real on either path.\n * Inline links in a paragraph are not flagged: both rungs now carry them.\n */\nfunction flagBlockChildUrlLoss(list: List, ctx: ConversionContext): void {\n for (const item of list.children) {\n for (const child of item.children) {\n if (child.type === \"list\") {\n flagBlockChildUrlLoss(child, ctx);\n continue;\n }\n if (child.type === \"paragraph\") {\n continue;\n }\n const urls: FlattenedUrl[] = [];\n collectFlattenedUrls(child, urls);\n for (const { nodeType, url } of urls) {\n ctx.degradations.add({\n nodeType,\n from: url,\n to: \"label_only\",\n reason: \"Block child of task list item flattened into text; URL dropped\",\n path: ctx.path,\n });\n }\n }\n }\n}\n\n/**\n * Slack renders `` in a `markdown` block as link text, so on that rung\n * the URL survives but the image does not. A fidelity note, not a dropped URL.\n * The rich_text rung hoists images into real image blocks instead.\n */\nfunction flagImagesRenderedAsLinks(list: List, ctx: ConversionContext): void {\n for (const item of list.children) {\n for (const child of item.children) {\n if (child.type === \"list\") {\n flagImagesRenderedAsLinks(child, ctx);\n continue;\n }\n if (child.type !== \"paragraph\") {\n continue;\n }\n const urls: string[] = [];\n collectRenderedImageUrls(child, ctx.definitions, urls);\n for (const url of urls) {\n ctx.degradations.add({\n nodeType: \"image\",\n from: url,\n to: \"link\",\n reason: \"Slack renders images in a markdown block as link text\",\n path: ctx.path,\n });\n }\n }\n }\n}\n\n/**\n * Image URLs this rung will render as link text, reference images included.\n * {@link collectFlattenedUrls} cannot see those: a reference carries an identifier,\n * not a url. But {@link phrasingToMarkdown} resolves it and emits the same\n * ``, so it loses the same fidelity and owes the same note. An\n * unresolvable reference emits no image, and so is correctly skipped here.\n */\nfunction collectRenderedImageUrls(\n node: unknown,\n definitions: ReadonlyMap<string, Definition>,\n into: string[],\n): void {\n if (node === null || typeof node !== \"object\") {\n return;\n }\n const record = node as {\n readonly type?: string;\n readonly url?: string;\n readonly identifier?: string;\n readonly children?: ReadonlyArray<unknown>;\n };\n if (record.type === \"image\" && typeof record.url === \"string\") {\n into.push(record.url);\n }\n if (record.type === \"imageReference\" && typeof record.identifier === \"string\") {\n const resolved = definitions.get(record.identifier)?.url;\n if (resolved !== undefined) {\n into.push(resolved);\n }\n }\n for (const child of record.children ?? []) {\n collectRenderedImageUrls(child, definitions, into);\n }\n}\n\nfunction serializeTaskList(\n list: List,\n definitions: ReadonlyMap<string, Definition>,\n indent = 0,\n): string {\n const pad = \" \".repeat(indent);\n const lines: string[] = [];\n for (const item of list.children) {\n const text = itemMarkdown(item, definitions);\n lines.push(`${pad}${taskMarker(item.checked)}${escapeLeadingCheckbox(item.checked, text)}`);\n for (const child of item.children) {\n if (child.type === \"list\") {\n lines.push(serializeTaskList(child, definitions, indent + 1));\n }\n }\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * `checked` has three states, and a plain bullet is not an unchecked task. A\n * mixed list holds both, so collapsing `undefined` into `false` renders work the\n * author never wrote as unfinished. The rich_text rung already omits the prefix\n * for these items; this keeps the two rungs saying the same thing.\n */\nfunction taskMarker(checked: boolean | null | undefined): string {\n if (checked === true) {\n return \"- [x] \";\n }\n if (checked === false) {\n return \"- [ ] \";\n }\n return \"- \";\n}\n\n/**\n * A plain item whose text happens to start with `[x]` would be re-parsed as a\n * checked task once the marker in front of it is a bare bullet, which is the same\n * meaning change {@link taskMarker} exists to avoid. `- [x] ` with a trailing\n * space is exactly this: GFM reads it as a plain item whose literal text is\n * `[x]`. Escaping the bracket keeps it literal.\n */\nfunction escapeLeadingCheckbox(checked: boolean | null | undefined, text: string): string {\n if (checked !== undefined && checked !== null) {\n return text;\n }\n return /^\\[[ xX]\\]/.test(text) ? `\\\\${text}` : text;\n}\n\n/**\n * Item content as inline markdown. Slack renders links, emphasis and code in a\n * `markdown` block, so flattening those to bare text would discard fidelity the\n * destination carries natively.\n */\nfunction itemMarkdown(item: ListItem, definitions: ReadonlyMap<string, Definition>): string {\n const parts: string[] = [];\n for (const child of item.children) {\n if (child.type === \"paragraph\") {\n parts.push(phrasingToMarkdown(child.children, definitions));\n } else if (child.type !== \"list\") {\n // A table or code fence has no inline markdown form that survives inside a\n // single list item; `flagMarkdownRungLosses` accounts for what this drops.\n parts.push(blockToPlainText(child));\n }\n }\n return parts.join(\" \").trim();\n}\n\n/** Phrasing content of a task item, for hoist counting and for emission. */\nfunction taskItemPhrasing(item: ListItem): PhrasingContent[] {\n const phrasing: PhrasingContent[] = [];\n for (const child of item.children) {\n let segment: ReadonlyArray<PhrasingContent> = [];\n if (child.type === \"paragraph\") {\n segment = child.children;\n } else if (child.type !== \"list\") {\n const text = blockToPlainText(child);\n segment = text.length > 0 ? [{ type: \"text\", value: text }] : [];\n }\n if (segment.length === 0) {\n continue;\n }\n // An item can hold several blocks, and they were separate lines in the source.\n // `emitPhrasing` coalesces adjacent text runs, so without this the last word of\n // one and the first word of the next arrive glued together. `itemMarkdown` joins\n // the same segments with a space; the two rungs have to agree.\n if (phrasing.length > 0) {\n phrasing.push({ type: \"text\", value: \" \" });\n }\n phrasing.push(...segment);\n }\n return phrasing;\n}\n\nfunction countHoistableImagesInTaskList(list: List, ctx: ConversionContext): number {\n let count = 0;\n for (const item of list.children) {\n count += countHoistableImages(taskItemPhrasing(item), ctx);\n for (const child of item.children) {\n if (child.type === \"list\") {\n count += countHoistableImagesInTaskList(child, ctx);\n }\n }\n }\n return count;\n}\n\n/** Named at the call site, because `emitUnicodeTaskBlocks(list, ctx, true)` says nothing. */\nconst HOIST_IMAGES = true;\nconst TEXT_ONLY = false;\n\nfunction emitUnicodeTaskBlocks(\n list: List,\n ctx: ConversionContext,\n hoistImages: boolean,\n): ReadonlyArray<Block> {\n const { elements, hoistedImages } = emitUnicodeTaskTree(list, 0, ctx);\n const block: RichTextBlock = { type: \"rich_text\", elements };\n const blocks: Block[] = [block];\n if (!hoistImages) {\n return blocks;\n }\n for (const image of hoistedImages) {\n blocks.push(hoistedImageBlock(image, ctx));\n }\n return blocks;\n}\n\nfunction emitUnicodeTaskTree(\n list: List,\n indent: number,\n ctx: ConversionContext,\n): { elements: Array<RichTextList>; hoistedImages: HoistedImage[] } {\n let effectiveIndent = indent;\n if (effectiveIndent > RICH_TEXT_LIST_INDENT_MAX) {\n ctx.degradations.add({\n nodeType: \"list\",\n from: `indent:${String(effectiveIndent)}`,\n to: `indent:${String(RICH_TEXT_LIST_INDENT_MAX)}`,\n reason: \"Task list indent clamped at 6\",\n path: ctx.path,\n });\n effectiveIndent = RICH_TEXT_LIST_INDENT_MAX;\n }\n\n // Same interleaving as the list adapter: nest under the last item of each\n // same-indent chunk (Slack's flat indent model).\n const out: RichTextList[] = [];\n const hoistedImages: HoistedImage[] = [];\n let pendingSections: RichTextSection[] = [];\n\n const flush = (): void => {\n if (pendingSections.length === 0) {\n return;\n }\n out.push({\n type: \"rich_text_list\",\n style: \"bullet\",\n elements: pendingSections,\n indent: effectiveIndent,\n });\n pendingSections = [];\n };\n\n for (const item of list.children) {\n const prefix = item.checked === true ? \"☑ \" : item.checked === false ? \"☐ \" : \"\";\n // The checkbox is a character, not a Slack element, so it is simply the\n // first text run — leaving the rest of the item free to hold real links.\n const inline = emitPhrasing(taskItemPhrasing(item), ctx);\n hoistedImages.push(...inline.hoistedImages);\n // An empty text run is not valid Slack, so the prefix is only its own\n // element when there is one, and an empty item still needs something.\n const elements =\n prefix === \"\"\n ? [...inline.elements]\n : [{ type: \"text\" as const, text: prefix }, ...inline.elements];\n pendingSections.push({\n type: \"rich_text_section\",\n elements: elements.length > 0 ? elements : [{ type: \"text\", text: \" \" }],\n });\n const childLists: List[] = [];\n for (const child of item.children) {\n if (child.type === \"list\") {\n childLists.push(child);\n }\n }\n if (childLists.length === 0) {\n continue;\n }\n flush();\n for (const child of childLists) {\n const nested = emitUnicodeTaskTree(child, effectiveIndent + 1, ctx);\n out.push(...nested.elements);\n hoistedImages.push(...nested.hoistedImages);\n }\n }\n flush();\n\n if (out.length === 0) {\n out.push({\n type: \"rich_text_list\",\n style: \"bullet\",\n elements: [{ type: \"rich_text_section\", elements: [{ type: \"text\", text: \" \" }] }],\n indent: effectiveIndent,\n });\n }\n\n return { elements: out, hoistedImages };\n}\n","import type { RootContent } from \"mdast\";\n\nimport type { Block } from \"../blocks/types.js\";\nimport type { ConversionContext } from \"../budget/conversion-context.js\";\n\nimport type { Candidate, NodeAdapter } from \"./node-adapter.js\";\n\n/**\n * thematicBreak → divider.\n */\nexport class ThematicBreakAdapter implements NodeAdapter {\n match(node: RootContent, _ctx: ConversionContext): boolean {\n return node.type === \"thematicBreak\";\n }\n\n plan(_node: RootContent, _ctx: ConversionContext): ReadonlyArray<Candidate> {\n return [\n {\n budget: { blocks: 1 },\n emit: (_ctx: ConversionContext): ReadonlyArray<Block> => [{ type: \"divider\" }],\n },\n ];\n }\n}\n","import { BlockquoteAdapter } from \"../adapters/blockquote-adapter.js\";\nimport { CodeFenceAdapter } from \"../adapters/code-fence-adapter.js\";\nimport { HeadingAdapter } from \"../adapters/heading-adapter.js\";\nimport { HtmlBlockAdapter } from \"../adapters/html-block-adapter.js\";\nimport { ListAdapter } from \"../adapters/list-adapter.js\";\nimport { MathBlockAdapter } from \"../adapters/math-block-adapter.js\";\nimport { MermaidFenceAdapter } from \"../adapters/mermaid-fence-adapter.js\";\nimport type { NodeAdapter } from \"../adapters/node-adapter.js\";\nimport { ParagraphAdapter } from \"../adapters/paragraph-adapter.js\";\nimport { SkipAdapter } from \"../adapters/skip-adapter.js\";\nimport { TableAdapter } from \"../adapters/table-adapter.js\";\nimport { TaskListAdapter } from \"../adapters/task-list-adapter.js\";\nimport { ThematicBreakAdapter } from \"../adapters/thematic-break-adapter.js\";\nimport { MessageAssembler } from \"../assemble/message-assembler.js\";\nimport { DeterministicPlainTextRenderer } from \"../assemble/text-fallback.js\";\nimport { MermaidPieParser } from \"../mermaid/mermaid-pie-parser.js\";\nimport { MermaidXyChartParser } from \"../mermaid/mermaid-xychart-parser.js\";\nimport { RemarkMarkdownParser } from \"../parsers/remark-markdown-parser.js\";\nimport { AdapterRegistry } from \"../registry/adapter-registry.js\";\nimport { ConfigurationError, isConfigurationError, isOperationError } from \"../errors.js\";\nimport type {\n ConversionMessagesResult,\n ConversionResult,\n ConvertOptions,\n MarkdownParser,\n ParserOptions,\n PlainTextRenderer,\n} from \"../types.js\";\nimport { OverflowMode } from \"../types.js\";\n\nimport { SlackMarkConverter } from \"./slackmark-converter.js\";\nimport { resolveConfig, resolveRendererDescriptors } from \"./resolve-config.js\";\n\nconst CREATE_OPTION_KEYS: ReadonlySet<string> = new Set([\n \"capabilities\",\n \"capabilityOverrides\",\n \"overflow\",\n \"strategy\",\n \"renderers\",\n \"uploader\",\n \"enableMath\",\n \"enableInlineMath\",\n \"enableFrontmatter\",\n \"mentionResolvers\",\n \"adapters\",\n \"parser\",\n \"plainText\",\n]);\n\n/**\n * Options for the composition root. Extends per-call {@link ConvertOptions}\n * with injectable collaborators and user adapters (prepended).\n */\nexport interface CreateConverterOptions extends Omit<ConvertOptions, \"signal\" | \"timeoutMs\"> {\n readonly adapters?: ReadonlyArray<NodeAdapter>;\n readonly parser?: MarkdownParser;\n readonly plainText?: PlainTextRenderer;\n}\n\n/**\n * Single composition root — wires default implementations.\n */\nexport function createConverter(options: CreateConverterOptions = {}): SlackMarkConverter {\n validateCreateOptions(options);\n try {\n const parser =\n options.parser === undefined\n ? new RemarkMarkdownParser()\n : new GuardedMarkdownParser(options.parser);\n const plainText =\n options.plainText === undefined\n ? new DeterministicPlainTextRenderer()\n : new GuardedPlainTextRenderer(options.plainText);\n const pieParser = new MermaidPieParser();\n const xyParser = new MermaidXyChartParser();\n\n const builtIns: NodeAdapter[] = [\n new MermaidFenceAdapter({ pieParser, xyParser }),\n new MathBlockAdapter(),\n new TaskListAdapter(),\n new ListAdapter(),\n new TableAdapter(),\n new HeadingAdapter(),\n new ParagraphAdapter(),\n new BlockquoteAdapter(),\n new CodeFenceAdapter(),\n new ThematicBreakAdapter(),\n new HtmlBlockAdapter(),\n new SkipAdapter(),\n ];\n\n const adapters = validateAdapters(options.adapters);\n const registry = new AdapterRegistry([...adapters, ...builtIns]);\n const assembler = new MessageAssembler({ plainText });\n\n const configuredDefaults: ConvertOptions = {\n capabilities: options.capabilities,\n capabilityOverrides: options.capabilityOverrides,\n overflow: options.overflow === undefined ? OverflowMode.Degrade : options.overflow,\n strategy: options.strategy,\n renderers: resolveRendererDescriptors(options.renderers),\n uploader: options.uploader,\n enableMath: options.enableMath,\n enableInlineMath: options.enableInlineMath,\n enableFrontmatter: options.enableFrontmatter,\n mentionResolvers: options.mentionResolvers,\n };\n const resolvedDefaults = resolveConfig(configuredDefaults, undefined, {\n signal: undefined,\n deadlineMs: undefined,\n });\n const defaultOptions: ConvertOptions = {\n capabilities: resolvedDefaults.capabilities,\n overflow: resolvedDefaults.overflow,\n strategy: resolvedDefaults.strategy,\n renderers: resolvedDefaults.renderers,\n uploader: resolvedDefaults.uploader,\n enableMath: resolvedDefaults.enableMath,\n enableInlineMath: resolvedDefaults.enableInlineMath,\n enableFrontmatter: resolvedDefaults.enableFrontmatter,\n mentionResolvers: resolvedDefaults.mentionResolvers,\n };\n\n return new SlackMarkConverter({\n parser,\n registry,\n assembler,\n plainText,\n defaultOptions,\n });\n } catch (cause) {\n if (isConfigurationError(cause)) {\n throw cause;\n }\n throw new ConfigurationError(\"Converter options could not be read\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nclass GuardedMarkdownParser implements MarkdownParser {\n private readonly parser: MarkdownParser;\n\n constructor(parser: MarkdownParser) {\n this.parser = parser;\n assertMethod(parser, \"parse\", \"parser\");\n }\n\n async parse(markdown: string, options: ParserOptions): ReturnType<MarkdownParser[\"parse\"]> {\n try {\n return await this.parser.parse(markdown, options);\n } catch (cause) {\n if (isConfigurationError(cause) || isOperationError(cause)) {\n throw cause;\n }\n throw new ConfigurationError(\"Injected parser failed\", {\n code: \"parser_failed\",\n stage: \"parse\",\n cause,\n });\n }\n }\n}\n\nclass GuardedPlainTextRenderer implements PlainTextRenderer {\n private readonly renderer: PlainTextRenderer;\n\n constructor(renderer: PlainTextRenderer) {\n this.renderer = renderer;\n assertMethod(renderer, \"render\", \"plainText\");\n assertMethod(renderer, \"renderFromBlocks\", \"plainText\");\n }\n\n render(markdown: string): string {\n try {\n const rendered = this.renderer.render(markdown);\n if (typeof rendered !== \"string\") {\n throw new TypeError(\"render must return string\");\n }\n return rendered;\n } catch (cause) {\n throw new ConfigurationError(\"Injected plain-text renderer failed\", {\n code: \"plain_text_failed\",\n stage: \"fallback\",\n cause,\n });\n }\n }\n\n renderFromBlocks(blocks: Parameters<PlainTextRenderer[\"renderFromBlocks\"]>[0]): string {\n try {\n const rendered = this.renderer.renderFromBlocks(blocks);\n if (typeof rendered !== \"string\") {\n throw new TypeError(\"renderFromBlocks must return string\");\n }\n return rendered;\n } catch (cause) {\n throw new ConfigurationError(\"Injected plain-text renderer failed\", {\n code: \"plain_text_failed\",\n stage: \"fallback\",\n cause,\n });\n }\n }\n}\n\nfunction validateAdapters(\n adapters: ReadonlyArray<NodeAdapter> | undefined,\n): ReadonlyArray<NodeAdapter> {\n if (adapters === undefined) {\n return [];\n }\n if (!Array.isArray(adapters)) {\n throw new ConfigurationError(\"adapters must be an array\", {\n code: \"invalid_adapter\",\n stage: \"configuration\",\n });\n }\n for (const adapter of adapters) {\n assertMethod(adapter, \"match\", \"adapter\");\n assertMethod(adapter, \"plan\", \"adapter\");\n }\n return Object.freeze([...adapters]);\n}\n\nfunction assertMethod(collaborator: unknown, method: string, label: string): void {\n try {\n if (\n (typeof collaborator !== \"object\" && typeof collaborator !== \"function\") ||\n collaborator === null ||\n typeof Reflect.get(collaborator, method) !== \"function\"\n ) {\n throw new TypeError(`${method} must be a function`);\n }\n } catch (cause) {\n throw new ConfigurationError(`${label} collaborator is invalid`, {\n code: `invalid_${label}`,\n stage: \"configuration\",\n cause,\n });\n }\n}\n\nfunction validateCreateOptions(options: CreateConverterOptions): void {\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(options);\n keys = Object.keys(options);\n } catch (cause) {\n throw new ConfigurationError(\"Converter options could not be inspected\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n cause,\n });\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw new ConfigurationError(\"Converter options must be a plain object\", {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n for (const key of keys) {\n if (!CREATE_OPTION_KEYS.has(key)) {\n throw new ConfigurationError(`Unknown converter option: ${key}`, {\n code: \"invalid_options\",\n stage: \"configuration\",\n });\n }\n }\n}\n\n/**\n * Convenience API — creates a default converter per call.\n */\nexport function convert(markdown: string, options?: ConvertOptions): Promise<ConversionResult> {\n return createConverter().convert(markdown, options);\n}\n\n/**\n * Convenience multi-message API.\n */\nexport function convertToMessages(\n markdown: string,\n options?: ConvertOptions,\n): Promise<ConversionMessagesResult> {\n return createConverter().convertToMessages(markdown, options);\n}\n","import type { Block, RichTextBlock, RichTextElement, TableCell } from \"../blocks/types.js\";\nimport {\n CHART_LABEL_MAX_CHARS,\n CHART_POINTS_MAX,\n CHART_SEGMENTS_MAX,\n CHART_SERIES_MAX,\n CHART_TITLE_MAX_CHARS,\n CONTAINER_CHILDREN_MAX,\n CONTAINER_TITLE_MAX_CHARS,\n CONTEXT_ELEMENTS_MAX,\n DATA_TABLE_CELL_CHARS_MAX,\n DATA_TABLE_MAX_DATA_ROWS,\n DATA_VISUALIZATION_MAX_PER_MESSAGE,\n HEADER_TEXT_MAX_CHARS,\n IMAGE_ALT_MAX_CHARS,\n IMAGE_URL_MAX_CHARS,\n MARKDOWN_CUMULATIVE_MAX_CHARS,\n MAX_BLOCKS_PER_MESSAGE,\n SECTION_TEXT_MAX_CHARS,\n TABLE_CELL_CHARS_MAX,\n TABLE_CELL_MIN_CHARS,\n TABLE_MAX_COLS,\n TABLE_MAX_ROWS,\n} from \"../constants.js\";\n\nexport interface ValidationIssue {\n readonly path: string;\n readonly message: string;\n}\n\ndeclare const validatedBlocksBrand: unique symbol;\n\n/**\n * Blocks that have passed {@link validateBlocks}.\n */\nexport type ValidatedBlocks = ReadonlyArray<Block> & {\n readonly [validatedBlocksBrand]: true;\n};\n\ninterface CumulativeCounters {\n markdownChars: number;\n tableChars: number;\n dataTableChars: number;\n charts: number;\n}\n\n/**\n * Assert every documented Block Kit limit from the research doc.\n */\nexport function validateBlocks(blocks: ReadonlyArray<Block>): ValidatedBlocks {\n const issues: ValidationIssue[] = [];\n if (blocks.length > MAX_BLOCKS_PER_MESSAGE) {\n issues.push({\n path: \"$\",\n message: `Too many blocks: ${String(blocks.length)} > ${String(MAX_BLOCKS_PER_MESSAGE)}`,\n });\n }\n\n const counters: CumulativeCounters = {\n markdownChars: 0,\n tableChars: 0,\n dataTableChars: 0,\n charts: 0,\n };\n\n blocks.forEach((block, i) => {\n validateBlock(block, `blocks[${String(i)}]`, issues, counters, 0);\n });\n\n if (counters.markdownChars > MARKDOWN_CUMULATIVE_MAX_CHARS) {\n issues.push({\n path: \"$\",\n message: `markdown cumulative ${String(counters.markdownChars)} > 12000`,\n });\n }\n if (counters.tableChars > TABLE_CELL_CHARS_MAX) {\n issues.push({\n path: \"$\",\n message: `table chars ${String(counters.tableChars)} > 10000`,\n });\n }\n if (counters.dataTableChars > DATA_TABLE_CELL_CHARS_MAX) {\n issues.push({\n path: \"$\",\n message: `data_table chars ${String(counters.dataTableChars)} > 20000`,\n });\n }\n if (counters.charts > DATA_VISUALIZATION_MAX_PER_MESSAGE) {\n issues.push({\n path: \"$\",\n message: `charts ${String(counters.charts)} > ${String(DATA_VISUALIZATION_MAX_PER_MESSAGE)}`,\n });\n }\n\n if (issues.length > 0) {\n const detail = issues.map((x) => `${x.path}: ${x.message}`).join(\"; \");\n throw new Error(`validateBlocks failed: ${detail}`);\n }\n\n return blocks as ValidatedBlocks;\n}\n\nfunction validateBlock(\n block: Block,\n path: string,\n issues: ValidationIssue[],\n counters: CumulativeCounters,\n depth: number,\n): void {\n // Containers can nest in hand-crafted payloads; bound recursion so cycles cannot\n // stack-overflow. Message-depth beyond the block budget is already illegal.\n if (depth > MAX_BLOCKS_PER_MESSAGE) {\n issues.push({ path, message: \"container nesting too deep\" });\n return;\n }\n\n switch (block.type) {\n case \"header\":\n if (block.text.text.length > HEADER_TEXT_MAX_CHARS) {\n issues.push({ path, message: \"header text > 150\" });\n }\n if (block.level !== undefined && (block.level < 1 || block.level > 4)) {\n issues.push({ path, message: \"header level out of 1–4\" });\n }\n break;\n case \"section\":\n if (block.text !== undefined && block.text.text.length > SECTION_TEXT_MAX_CHARS) {\n issues.push({ path, message: \"section text > 3000\" });\n }\n break;\n case \"image\":\n if (block.alt_text.length > IMAGE_ALT_MAX_CHARS) {\n issues.push({ path, message: \"image alt > 2000\" });\n }\n if (\n block.image_url !== undefined &&\n !isAbsoluteHttpUrl(block.image_url, IMAGE_URL_MAX_CHARS)\n ) {\n issues.push({ path, message: \"image_url invalid\" });\n }\n if (\"slack_file\" in block) {\n if (\"id\" in block.slack_file && block.slack_file.id.trim().length === 0) {\n issues.push({ path, message: \"slack_file.id empty\" });\n }\n if (\n \"url\" in block.slack_file &&\n !isAbsoluteHttpUrl(block.slack_file.url, IMAGE_URL_MAX_CHARS)\n ) {\n issues.push({ path, message: \"slack_file.url invalid\" });\n }\n }\n break;\n case \"context\":\n // Slack context blocks require 1–CONTEXT_ELEMENTS_MAX elements\n // (https://docs.slack.dev/reference/block-kit/blocks/context-block).\n if (block.elements.length === 0) {\n issues.push({ path, message: \"context elements empty\" });\n } else if (block.elements.length > CONTEXT_ELEMENTS_MAX) {\n issues.push({ path, message: \"context elements > 10\" });\n }\n break;\n case \"markdown\":\n counters.markdownChars += block.text.length;\n break;\n case \"table\":\n if (block.rows.length > TABLE_MAX_ROWS) {\n issues.push({ path, message: \"table rows > 100\" });\n }\n counters.tableChars += validateTableCells(block.rows, path, \"table cols > 20\", issues);\n break;\n case \"data_table\":\n if (block.rows.length > DATA_TABLE_MAX_DATA_ROWS + 1) {\n issues.push({ path, message: \"data_table rows > 201\" });\n }\n counters.dataTableChars += validateTableCells(\n block.rows,\n path,\n \"data_table cols > 20\",\n issues,\n );\n break;\n case \"data_visualization\":\n counters.charts += 1;\n if (block.title.length > CHART_TITLE_MAX_CHARS) {\n issues.push({ path, message: \"chart title > 50\" });\n }\n validateChart(block, path, issues);\n break;\n case \"container\":\n if (block.child_blocks.length > CONTAINER_CHILDREN_MAX) {\n issues.push({ path, message: \"container children > 10\" });\n }\n if (block.title !== undefined && block.title.text.length > CONTAINER_TITLE_MAX_CHARS) {\n issues.push({ path, message: \"container title > 150\" });\n }\n if (block.rich_text_title !== undefined) {\n validateRichTextBlock(block.rich_text_title, `${path}.rich_text_title`, issues);\n }\n // Typed ContainerChildBlock excludes charts/nested containers; hand-crafted\n // payloads can still smuggle them — recurse so counters and per-block checks apply.\n for (const [i, child] of block.child_blocks.entries()) {\n validateBlock(child, `${path}.child_blocks[${String(i)}]`, issues, counters, depth + 1);\n }\n break;\n case \"divider\":\n break;\n case \"rich_text\":\n validateRichTextBlock(block, path, issues);\n break;\n default: {\n const exhaustive: never = block;\n void exhaustive;\n break;\n }\n }\n}\n\nfunction isAbsoluteHttpUrl(value: string, maxChars: number): boolean {\n if (value.length === 0 || value.length > maxChars) {\n return false;\n }\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nfunction validateRichTextBlock(\n block: RichTextBlock,\n path: string,\n issues: ValidationIssue[],\n): void {\n if (block.elements.length === 0) {\n issues.push({ path, message: \"rich_text elements empty\" });\n return;\n }\n for (const [i, element] of block.elements.entries()) {\n validateRichTextElement(element, `${path}.elements[${String(i)}]`, issues);\n }\n}\n\nfunction validateRichTextElement(\n element: RichTextElement,\n path: string,\n issues: ValidationIssue[],\n): void {\n switch (element.type) {\n case \"rich_text_section\":\n case \"rich_text_quote\":\n case \"rich_text_preformatted\":\n if (element.elements.length === 0) {\n issues.push({ path, message: `${element.type} elements empty` });\n return;\n }\n for (const [i, inline] of element.elements.entries()) {\n if (inline.type === \"link\" && !isValidRichTextLinkUrl(inline.url)) {\n issues.push({\n path: `${path}.elements[${String(i)}]`,\n message: \"invalid rich text link URL\",\n });\n }\n }\n break;\n case \"rich_text_list\":\n if (element.elements.length === 0) {\n issues.push({ path, message: \"rich_text_list elements empty\" });\n return;\n }\n for (const [i, section] of element.elements.entries()) {\n validateRichTextElement(section, `${path}.elements[${String(i)}]`, issues);\n }\n break;\n default: {\n const exhaustive: never = element;\n void exhaustive;\n break;\n }\n }\n}\n\n/** Count cell chars and validate any rich_text cells (links / empty elements). */\nfunction validateTableCells(\n rows: ReadonlyArray<ReadonlyArray<TableCell>>,\n path: string,\n colsMessage: string,\n issues: ValidationIssue[],\n): number {\n let chars = 0;\n for (const [r, row] of rows.entries()) {\n if (row.length > TABLE_MAX_COLS) {\n issues.push({ path, message: colsMessage });\n }\n for (const [c, cell] of row.entries()) {\n chars += cellCharCount(cell);\n const cellPath = `${path}.rows[${String(r)}][${String(c)}]`;\n if (cell.type === \"rich_text\") {\n validateRichTextBlock(cell, cellPath, issues);\n } else if (cell.text.length < TABLE_CELL_MIN_CHARS) {\n issues.push({ path: cellPath, message: \"table cell text is empty\" });\n }\n }\n }\n return chars;\n}\n\n/**\n * Slack rich text `link` elements require absolute http(s)/mailto URLs; relative\n * URLs (`/path`, `#fragment`) or other schemes are rejected with invalid_blocks.\n * https://docs.slack.dev/reference/block-kit/block-elements/rich-text-elements\n *\n * Honest local duplicate of `isValidLinkUrl` in adapters/inline.ts — validate must\n * not import adapters (layering: adapters → … → validate).\n */\nconst HTTP_OR_MAILTO_URL_RE = /^(https?:|mailto:)/i;\n\nfunction isValidRichTextLinkUrl(url: string): boolean {\n if (url.length === 0 || url.length > IMAGE_URL_MAX_CHARS) {\n return false;\n }\n return HTTP_OR_MAILTO_URL_RE.test(url);\n}\n\nfunction cellCharCount(cell: TableCell): number {\n if (cell.type === \"raw_text\") {\n return cell.text.length;\n }\n if (cell.type === \"raw_number\") {\n return cell.text.length;\n }\n return JSON.stringify(cell).length;\n}\n\nfunction validateChart(\n block: Extract<Block, { type: \"data_visualization\" }>,\n path: string,\n issues: ValidationIssue[],\n): void {\n const chart = block.chart;\n if (chart.type === \"pie\") {\n if (chart.segments.length < 1 || chart.segments.length > CHART_SEGMENTS_MAX) {\n issues.push({ path, message: \"pie segments out of 1–12\" });\n }\n for (const s of chart.segments) {\n if (s.label.length > CHART_LABEL_MAX_CHARS) {\n issues.push({ path, message: \"pie label > 20\" });\n }\n if (!(s.value > 0)) {\n issues.push({ path, message: \"pie value must be > 0\" });\n }\n }\n return;\n }\n if (chart.series.length < 1 || chart.series.length > CHART_SERIES_MAX) {\n issues.push({ path, message: \"series out of 1–12\" });\n }\n if (chart.axis_config.categories.length > CHART_POINTS_MAX) {\n issues.push({ path, message: \"categories > 20\" });\n }\n for (const s of chart.series) {\n if (s.name.length > CHART_LABEL_MAX_CHARS) {\n issues.push({ path, message: \"series name > 20\" });\n }\n if (s.data.length < 1 || s.data.length > CHART_POINTS_MAX) {\n issues.push({ path, message: \"points out of 1–20\" });\n }\n for (const p of s.data) {\n if (p.label.length > CHART_LABEL_MAX_CHARS) {\n issues.push({ path, message: \"point label > 20\" });\n }\n if (!chart.axis_config.categories.includes(p.label)) {\n issues.push({ path, message: `point label ${p.label} missing from categories` });\n }\n }\n }\n}\n"],"mappings":"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"}
|