import { type ReactNode } from "react";
import { type TimelineSearchTarget } from "./timeline-search.js";
import { type OpenGeniLinkRenderer, type OpenGeniLinkResolver } from "./open-geni-links.js";
/**
* The default renderer for chat message bodies in {@link MessageTimeline}.
*
* Agent (and user) messages arrive as GitHub-flavored markdown. This turns the
* raw text into styled HTML using `react-markdown` + `remark-gfm`, themed to the
* package's `og-*` design tokens so it reads as one cohesive dark surface — no
* stock Tailwind colors leak in.
*
* It re-parses on every render, which is exactly right for streaming: a body
* that is still arriving (an unterminated `**`, a half-open code fence, a table
* mid-row) renders as best-effort markdown and resolves cleanly as the rest of
* the tokens land. Consumers who want a different renderer can still pass
* `renderMessageText` to `MessageTimeline` to override this entirely.
*/
export type MarkdownInteractiveBlock = {
kind: "html" | "site";
content: string;
};
export type MarkdownProps = {
/** Resolve a retained-file reference to the host's authenticated artifact page. */
artifactHref?: ((artifactId: string) => string) | undefined;
/** Reveals a bounded source excerpt; closing Find retains it until explicit restore. */
searchTarget?: TimelineSearchTarget | null | undefined;
renderImage?: ((image: {
src: string;
alt: string;
}) => ReactNode) | undefined;
/** Show alt text without loading image URLs (e.g. in search previews). */
suppressImages?: boolean | undefined;
/** Host opt-in for assistant-authored interactive fences. */
renderInteractiveBlock?: ((block: MarkdownInteractiveBlock) => ReactNode) | undefined;
children: string;
className?: string | undefined;
/**
* Render a single newline inside prose as a line break (`
`), the way chat
* apps show messages; CommonMark otherwise folds it into a space. Chat message
* bodies enable this. Leave it off for documents and other authored Markdown.
* Code (fenced and inline), lists, tables, and blank-line paragraphs are
* unaffected either way.
*/
softLineBreaks?: boolean | undefined;
/**
* While true, newly arrived source fades in through tip ink (`.og-stream-ink`):
* an age window over each append batch — fast streams keep a large soft band,
* slow streams a tight tip. Paint-only: the DOM always holds the full truthful
* text. Once streaming ends and trailing ink settles, the body re-renders as
* plain markdown with a short local settle breath (no page-wide view
* transition — that blinked the whole document).
*/
streaming?: boolean | undefined;
/**
* Open a session-local file link in the host's Files surface. The path is the
* exact decoded `sandbox:` payload; `line`, when present, is 1-based.
*/
onSandboxFile?: ((path: string, line?: number) => void | Promise) | undefined;
/**
* Resolve Opengeni object links (`artifact:`, `sandbox:`, editable
* artifacts, Sites) to a host URL or action. Asked before any
* {@link OpenGeniLinkProvider} above this body; `artifactHref` and
* `onSandboxFile` still win for their own kinds.
*/
resolveLink?: OpenGeniLinkResolver | undefined;
/**
* Draw the host's own links (its scheme, in-app paths, web URLs) instead of
* the default link. Asked before any `renderLink` on an
* {@link OpenGeniLinkProvider} above this body. A link that is the only
* content of its paragraph or list item arrives with `standalone: true`, and
* that paragraph renders as a block so the host may return block content.
*/
renderLink?: OpenGeniLinkRenderer | undefined;
};
/** Exact target path plus optional 1-based line from a markdown href. */
export type SandboxFileLocation = {
path: string;
line: number | null;
};
/**
* Parse an Opengeni `sandbox:` application href (plus the historical bare
* `/workspace/...` form). The decoded path is intentionally opaque here:
* target selection, path policy, and filesystem authority belong to the
* session-aware host and its FileSystem boundary.
*/
export declare function sandboxFileLocationFromHref(href: string | undefined): SandboxFileLocation | null;
/** Return the exact decoded path for a supported sandbox-link href. */
export declare function sandboxFilePathFromHref(href: string | undefined): string | null;
export declare function retainedImageId(src: string): string | null;
/** Memoized so streaming re-renders of the parent don't re-parse settled bodies. */
export declare const Markdown: import("react").MemoExoticComponent<(props: MarkdownProps) => import("react").JSX.Element>;