@athenaintel/react 0.26.3 → 0.26.6
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/README.md +22 -0
- package/dist/auth/AthenaAuthProvider.d.ts +1 -1
- package/dist/auth/AthenaSSOProvider.d.ts +1 -1
- package/dist/chat/AthenaChat.cjs +1 -1
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.js +1 -1
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/StatewireApprovalCard.cjs +68 -9
- package/dist/chat/StatewireApprovalCard.cjs.map +1 -1
- package/dist/chat/StatewireApprovalCard.d.ts +0 -31
- package/dist/chat/StatewireApprovalCard.js +70 -11
- package/dist/chat/StatewireApprovalCard.js.map +1 -1
- package/dist/chat/StatewireQueuedMessages.cjs +44 -1
- package/dist/chat/StatewireQueuedMessages.cjs.map +1 -1
- package/dist/chat/StatewireQueuedMessages.js +45 -2
- package/dist/chat/StatewireQueuedMessages.js.map +1 -1
- package/dist/chat/super-grouping/CollapsibleGroup.d.ts +1 -1
- package/dist/chat/super-grouping/SuperGroupingCard.d.ts +2 -2
- package/dist/chat/super-grouping/ToolTimeline.d.ts +1 -1
- package/dist/chat/use-statewire-approval-request.cjs +6 -1
- package/dist/chat/use-statewire-approval-request.cjs.map +1 -1
- package/dist/chat/use-statewire-approval-request.d.ts +20 -0
- package/dist/chat/use-statewire-approval-request.js +6 -1
- package/dist/chat/use-statewire-approval-request.js.map +1 -1
- package/dist/chat-ui/header/chat-header.cjs +4 -4
- package/dist/chat-ui/header/chat-header.cjs.map +1 -1
- package/dist/chat-ui/header/chat-header.d.ts +3 -3
- package/dist/chat-ui/header/chat-header.js +1 -1
- package/dist/chat-ui/header/chat-header.js.map +1 -1
- package/dist/chat-ui/header/conversation-history-panel.d.ts +1 -1
- package/dist/chat-ui/index.cjs +8 -7
- package/dist/chat-ui/index.cjs.map +1 -1
- package/dist/chat-ui/index.d.ts +2 -1
- package/dist/chat-ui/index.js +2 -1
- package/dist/chat-ui/index.js.map +1 -1
- package/dist/chat-ui/markdown-storage.cjs +2 -1
- package/dist/chat-ui/markdown-storage.cjs.map +1 -1
- package/dist/chat-ui/markdown-storage.d.ts +3 -0
- package/dist/chat-ui/markdown-storage.js +2 -1
- package/dist/chat-ui/markdown-storage.js.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs +6 -0
- package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.d.ts +2 -0
- package/dist/chat-ui/mentions/mention-chip.js +6 -0
- package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/components/mention-icon.d.ts +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-breadcrumbs.d.ts +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-item.d.ts +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-list.d.ts +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-skeleton.d.ts +1 -1
- package/dist/chat-ui/mentions/suggestions/components/menu-summary.d.ts +1 -1
- package/dist/chat-ui/mentions/suggestions/shims.d.ts +1 -1
- package/dist/chat-ui/messages/message-components.cjs +13 -59
- package/dist/chat-ui/messages/message-components.cjs.map +1 -1
- package/dist/chat-ui/messages/message-components.d.ts +2 -14
- package/dist/chat-ui/messages/message-components.js +2 -47
- package/dist/chat-ui/messages/message-components.js.map +1 -1
- package/dist/chat-ui/messages/runtime-message.cjs +1 -1
- package/dist/chat-ui/messages/runtime-message.cjs.map +1 -1
- package/dist/chat-ui/messages/runtime-message.js +1 -1
- package/dist/chat-ui/messages/runtime-message.js.map +1 -1
- package/dist/chat-ui/messages/thread-chrome.cjs +59 -0
- package/dist/chat-ui/messages/thread-chrome.cjs.map +1 -0
- package/dist/chat-ui/messages/thread-chrome.d.ts +14 -0
- package/dist/chat-ui/messages/thread-chrome.js +59 -0
- package/dist/chat-ui/messages/thread-chrome.js.map +1 -0
- package/dist/chat-ui/messages/wake-marker.cjs +1 -1
- package/dist/chat-ui/messages/wake-marker.cjs.map +1 -1
- package/dist/chat-ui/messages/wake-marker.js +1 -1
- package/dist/chat-ui/messages/wake-marker.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-link.d.ts +2 -2
- package/dist/chat-ui/rich-text/chat-message-body.d.ts +1 -1
- package/dist/chat-ui/rich-text/chat-node-views.d.ts +5 -5
- package/dist/chat-ui/rich-text/chat-text-schema.cjs +9 -1
- package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-text-schema.d.ts +7 -0
- package/dist/chat-ui/rich-text/chat-text-schema.js +9 -1
- package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
- package/dist/chat-ui/thread/chat-composer-dock.d.ts +1 -1
- package/dist/chat-ui/thread/chat-thread-shell.cjs +4 -3
- package/dist/chat-ui/thread/chat-thread-shell.cjs.map +1 -1
- package/dist/chat-ui/thread/chat-thread-shell.d.ts +1 -1
- package/dist/chat-ui/thread/chat-thread-shell.js +2 -1
- package/dist/chat-ui/thread/chat-thread-shell.js.map +1 -1
- package/dist/composer/AttachmentContext.d.ts +1 -1
- package/dist/composer/QuoteContext.d.ts +1 -1
- package/dist/lib/posthog/before-send.cjs +12 -0
- package/dist/lib/posthog/before-send.cjs.map +1 -1
- package/dist/lib/posthog/before-send.js +12 -0
- package/dist/lib/posthog/before-send.js.map +1 -1
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -0
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -0
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/packages/agent-runtime/src/messages.cjs +15 -1
- package/dist/packages/agent-runtime/src/messages.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/messages.js +15 -1
- package/dist/packages/agent-runtime/src/messages.js.map +1 -1
- package/dist/packages/agent-runtime/src/tool-metadata.cjs +15 -0
- package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/tool-metadata.js +15 -0
- package/dist/packages/agent-runtime/src/tool-metadata.js.map +1 -1
- package/dist/packages/react/package.json.cjs +1 -1
- package/dist/packages/react/package.json.js +1 -1
- package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.cjs +114 -0
- package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.cjs.map +1 -0
- package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.js +114 -0
- package/dist/packages/tiptap-markdown-table/src/markdown-table-serializer.js.map +1 -0
- package/dist/provider/AthenaProvider.d.ts +1 -1
- package/dist/provider/PostHogProvider.d.ts +1 -1
- package/dist/threads/SessionList.d.ts +1 -1
- package/dist/threads/ThreadList.d.ts +1 -1
- package/dist/threads/statewire-thread-list.d.ts +1 -1
- package/dist/tools/primitives.d.ts +3 -3
- package/dist/tools/tool-fallback.d.ts +8 -8
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/collapsible.d.ts +3 -3
- package/dist/ui/popover.d.ts +3 -3
- package/dist/ui/tooltip.d.ts +4 -4
- package/dist/voice/use-athena-voice-session.cjs.map +1 -1
- package/dist/voice/use-athena-voice-session.d.ts +5 -0
- package/dist/voice/use-athena-voice-session.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
2
|
+
export declare function IconButton({ children, tooltip, className, ...props }: ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
3
|
+
tooltip: string;
|
|
4
|
+
}): import("react").JSX.Element;
|
|
5
|
+
export declare function SmallIconButton({ children, tooltip, className, ...props }: ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
6
|
+
tooltip: string;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
/** Panel chrome: the thread card and the header row that sits inside it. */
|
|
9
|
+
export declare const THREAD_PANEL_CLASS = "m-1 flex min-h-0 flex-1 flex-col overflow-hidden rounded-[18px] border border-dashed border-amber-500 bg-background shadow-[0_1px_10px_rgba(54,45,33,0.08)]";
|
|
10
|
+
export declare const THREAD_HEADER_CLASS = "flex items-center justify-between gap-2 px-3 py-2";
|
|
11
|
+
export declare const THREAD_HEADER_ACTIONS_CLASS = "flex min-w-0 items-center justify-end gap-1.5";
|
|
12
|
+
/** Pill used for the header's leading control (agent picker, host label). */
|
|
13
|
+
export declare const THREAD_HEADER_PILL_CLASS = "inline-flex h-7 max-w-[170px] items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-2 text-xs font-medium text-neutral-800 shadow-sm";
|
|
14
|
+
export declare const THREAD_HEADER_ICON_CLASS = "size-[18px]";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "cnfast";
|
|
3
|
+
function IconButton({
|
|
4
|
+
children,
|
|
5
|
+
tooltip,
|
|
6
|
+
className,
|
|
7
|
+
...props
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsx(
|
|
10
|
+
"button",
|
|
11
|
+
{
|
|
12
|
+
type: "button",
|
|
13
|
+
title: tooltip,
|
|
14
|
+
"aria-label": tooltip,
|
|
15
|
+
className: cn(
|
|
16
|
+
"inline-flex size-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
17
|
+
className
|
|
18
|
+
),
|
|
19
|
+
...props,
|
|
20
|
+
children
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
function SmallIconButton({
|
|
25
|
+
children,
|
|
26
|
+
tooltip,
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}) {
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
"button",
|
|
32
|
+
{
|
|
33
|
+
type: "button",
|
|
34
|
+
title: tooltip,
|
|
35
|
+
"aria-label": tooltip,
|
|
36
|
+
className: cn(
|
|
37
|
+
"inline-flex size-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
38
|
+
className
|
|
39
|
+
),
|
|
40
|
+
...props,
|
|
41
|
+
children
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
const THREAD_PANEL_CLASS = "m-1 flex min-h-0 flex-1 flex-col overflow-hidden rounded-[18px] border border-dashed border-amber-500 bg-background shadow-[0_1px_10px_rgba(54,45,33,0.08)]";
|
|
46
|
+
const THREAD_HEADER_CLASS = "flex items-center justify-between gap-2 px-3 py-2";
|
|
47
|
+
const THREAD_HEADER_ACTIONS_CLASS = "flex min-w-0 items-center justify-end gap-1.5";
|
|
48
|
+
const THREAD_HEADER_PILL_CLASS = "inline-flex h-7 max-w-[170px] items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-2 text-xs font-medium text-neutral-800 shadow-sm";
|
|
49
|
+
const THREAD_HEADER_ICON_CLASS = "size-[18px]";
|
|
50
|
+
export {
|
|
51
|
+
IconButton,
|
|
52
|
+
SmallIconButton,
|
|
53
|
+
THREAD_HEADER_ACTIONS_CLASS,
|
|
54
|
+
THREAD_HEADER_CLASS,
|
|
55
|
+
THREAD_HEADER_ICON_CLASS,
|
|
56
|
+
THREAD_HEADER_PILL_CLASS,
|
|
57
|
+
THREAD_PANEL_CLASS
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=thread-chrome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-chrome.js","sources":["../../../src/chat-ui/messages/thread-chrome.tsx"],"sourcesContent":["import type { ButtonHTMLAttributes } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\n/*\n * The thread panel's chrome: its icon buttons, card and header row. A leaf module on\n * purpose: a host that renders only a header (the Office add-in's pane) must not load\n * the message renderers, which pull in the rich-text editor.\n */\n\nexport function IconButton({\n children,\n tooltip,\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { tooltip: string }) {\n return (\n <button\n type=\"button\"\n title={tooltip}\n aria-label={tooltip}\n className={cn(\n \"inline-flex size-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport function SmallIconButton({\n children,\n tooltip,\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { tooltip: string }) {\n return (\n <button\n type=\"button\"\n title={tooltip}\n aria-label={tooltip}\n className={cn(\n \"inline-flex size-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\n/** Panel chrome: the thread card and the header row that sits inside it. */\nexport const THREAD_PANEL_CLASS =\n \"m-1 flex min-h-0 flex-1 flex-col overflow-hidden rounded-[18px] border border-dashed border-amber-500 bg-background shadow-[0_1px_10px_rgba(54,45,33,0.08)]\";\nexport const THREAD_HEADER_CLASS =\n \"flex items-center justify-between gap-2 px-3 py-2\";\nexport const THREAD_HEADER_ACTIONS_CLASS =\n \"flex min-w-0 items-center justify-end gap-1.5\";\n/** Pill used for the header's leading control (agent picker, host label). */\nexport const THREAD_HEADER_PILL_CLASS =\n \"inline-flex h-7 max-w-[170px] items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-2 text-xs font-medium text-neutral-800 shadow-sm\";\nexport const THREAD_HEADER_ICON_CLASS = \"size-[18px]\";\n"],"names":[],"mappings":";;AASO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkE;AAChE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAO;AAAA,MACP,cAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EAAA;AAGP;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkE;AAChE,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAO;AAAA,MACP,cAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EAAA;AAGP;AAGO,MAAM,qBACX;AACK,MAAM,sBACX;AACK,MAAM,8BACX;AAEK,MAAM,2BACX;AACK,MAAM,2BAA2B;"}
|
|
@@ -22,7 +22,7 @@ const WakeMarkerCard = ({ event, className, ...rest }) => {
|
|
|
22
22
|
),
|
|
23
23
|
children: [
|
|
24
24
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.GitPullRequestIcon, { className: "mt-0.5 size-4 shrink-0", "aria-hidden": "true" }),
|
|
25
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 [overflow-wrap:anywhere]", children: [
|
|
26
26
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
|
|
27
27
|
"Woke: ",
|
|
28
28
|
githubWakeEvent.githubWakeEventLabel(event),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wake-marker.cjs","sources":["../../../src/chat-ui/messages/wake-marker.tsx"],"sourcesContent":["/**\n * The runtime marker for a wake turn: a GitHub webhook woke the session and\n * injected a user message (see `@athenaintel/agent-runtime`'s\n * `github-wake-event.ts`). It renders in the same visual language as the\n * runtime-ending card (`RuntimeMessageCard`) — a compact status row, not a\n * user bubble quoting the whole wake text.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n type GithubWakeEvent,\n githubWakeEventLabel,\n githubWakeReference,\n readGithubWakeEvent,\n} from \"@athenaintel/agent-runtime\";\nimport { GitPullRequestIcon } from \"lucide-react\";\nimport { type ComponentPropsWithoutRef, type FC, useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface WakeMarkerCardProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"role\"> {\n event: GithubWakeEvent;\n}\n\n/** The \"Woke: review comment on #36337\" row; pure presenter. */\nexport const WakeMarkerCard: FC<WakeMarkerCardProps> = ({ event, className, ...rest }) => {\n const target = event.number !== null ? `#${event.number}` : event.repo;\n const reference = githubWakeReference(event);\n return (\n <div\n {...rest}\n role=\"status\"\n data-runtime-message-kind=\"wake\"\n data-testid=\"wake-marker\"\n className={cn(\n \"my-2 flex w-full items-start gap-2 rounded-lg border border-border bg-muted/40 px-3 py-2 text-muted-foreground text-sm\",\n className,\n )}\n >\n <GitPullRequestIcon className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5
|
|
1
|
+
{"version":3,"file":"wake-marker.cjs","sources":["../../../src/chat-ui/messages/wake-marker.tsx"],"sourcesContent":["/**\n * The runtime marker for a wake turn: a GitHub webhook woke the session and\n * injected a user message (see `@athenaintel/agent-runtime`'s\n * `github-wake-event.ts`). It renders in the same visual language as the\n * runtime-ending card (`RuntimeMessageCard`) — a compact status row, not a\n * user bubble quoting the whole wake text.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n type GithubWakeEvent,\n githubWakeEventLabel,\n githubWakeReference,\n readGithubWakeEvent,\n} from \"@athenaintel/agent-runtime\";\nimport { GitPullRequestIcon } from \"lucide-react\";\nimport { type ComponentPropsWithoutRef, type FC, useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface WakeMarkerCardProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"role\"> {\n event: GithubWakeEvent;\n}\n\n/** The \"Woke: review comment on #36337\" row; pure presenter. */\nexport const WakeMarkerCard: FC<WakeMarkerCardProps> = ({ event, className, ...rest }) => {\n const target = event.number !== null ? `#${event.number}` : event.repo;\n const reference = githubWakeReference(event);\n return (\n <div\n {...rest}\n role=\"status\"\n data-runtime-message-kind=\"wake\"\n data-testid=\"wake-marker\"\n className={cn(\n \"my-2 flex w-full items-start gap-2 rounded-lg border border-border bg-muted/40 px-3 py-2 text-muted-foreground text-sm\",\n className,\n )}\n >\n <GitPullRequestIcon className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5 [overflow-wrap:anywhere]\">\n <span className=\"font-medium\">\n Woke: {githubWakeEventLabel(event)} on{\" \"}\n {event.url ? (\n <a\n href={event.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={event.title ?? reference}\n className=\"underline-offset-2 hover:underline\"\n >\n {target}\n </a>\n ) : (\n <span title={event.title ?? reference}>{target}</span>\n )}\n </span>\n {event.sender || event.title ? (\n <span className=\"text-xs opacity-90\">\n {event.sender ? `by ${event.sender}` : null}\n {event.sender && event.title ? \" · \" : null}\n {event.title}\n </span>\n ) : null}\n {event.bodyExcerpt ? (\n <span className=\"truncate text-xs italic opacity-90\" title={event.bodyExcerpt}>\n “{event.bodyExcerpt}”\n </span>\n ) : null}\n </div>\n </div>\n );\n};\n\n/**\n * {@link WakeMarkerCard} bound to the assistant-ui message in scope. Selects\n * the message's `metadata.custom` (a stable store reference) and derives the\n * envelope from it: the reader allocates a fresh object per call, so selecting\n * its result directly would re-render on every store update.\n */\nexport const WakeMarkerMessage: FC<{ className?: string }> = ({ className }) => {\n const custom = useAuiState((s) => s.message.metadata?.custom);\n const event = useMemo(() => readGithubWakeEvent(custom), [custom]);\n if (!event) return null;\n return <WakeMarkerCard event={event} className={className} />;\n};\n"],"names":["githubWakeReference","jsxs","cn","jsx","GitPullRequestIcon","githubWakeEventLabel","useAuiState","useMemo","readGithubWakeEvent"],"mappings":";;;;;;;;AAwBO,MAAM,iBAA0C,CAAC,EAAE,OAAO,WAAW,GAAG,WAAW;AACxF,QAAM,SAAS,MAAM,WAAW,OAAO,IAAI,MAAM,MAAM,KAAK,MAAM;AAClE,QAAM,YAAYA,gBAAAA,oBAAoB,KAAK;AAC3C,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACJ,MAAK;AAAA,MACL,6BAA0B;AAAA,MAC1B,eAAY;AAAA,MACZ,WAAWC,OAAAA;AAAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAAC,2BAAAA,IAACC,YAAAA,oBAAA,EAAmB,WAAU,0BAAyB,eAAY,QAAO;AAAA,QAC1EH,2BAAAA,KAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,UAAAA,2BAAAA,KAAC,QAAA,EAAK,WAAU,eAAc,UAAA;AAAA,YAAA;AAAA,YACrBI,gBAAAA,qBAAqB,KAAK;AAAA,YAAE;AAAA,YAAI;AAAA,YACtC,MAAM,MACLF,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAM,MAAM;AAAA,gBACZ,QAAO;AAAA,gBACP,KAAI;AAAA,gBACJ,OAAO,MAAM,SAAS;AAAA,gBACtB,WAAU;AAAA,gBAET,UAAA;AAAA,cAAA;AAAA,YAAA,IAGHA,2BAAAA,IAAC,QAAA,EAAK,OAAO,MAAM,SAAS,WAAY,UAAA,OAAA,CAAO;AAAA,UAAA,GAEnD;AAAA,UACC,MAAM,UAAU,MAAM,QACrBF,2BAAAA,KAAC,QAAA,EAAK,WAAU,sBACb,UAAA;AAAA,YAAA,MAAM,SAAS,MAAM,MAAM,MAAM,KAAK;AAAA,YACtC,MAAM,UAAU,MAAM,QAAQ,QAAQ;AAAA,YACtC,MAAM;AAAA,UAAA,EAAA,CACT,IACE;AAAA,UACH,MAAM,cACLA,gCAAC,QAAA,EAAK,WAAU,sCAAqC,OAAO,MAAM,aAAa,UAAA;AAAA,YAAA;AAAA,YAC3E,MAAM;AAAA,YAAY;AAAA,UAAA,EAAA,CACtB,IACE;AAAA,QAAA,EAAA,CACN;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAQO,MAAM,oBAAgD,CAAC,EAAE,gBAAgB;AAC9E,QAAM,SAASK,MAAAA,YAAY,CAAC;;AAAM,mBAAE,QAAQ,aAAV,mBAAoB;AAAA,GAAM;AAC5D,QAAM,QAAQC,QAAAA,QAAQ,MAAMC,gBAAAA,oBAAoB,MAAM,GAAG,CAAC,MAAM,CAAC;AACjE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAOL,2BAAAA,IAAC,gBAAA,EAAe,OAAc,UAAA,CAAsB;AAC7D;;;"}
|
|
@@ -20,7 +20,7 @@ const WakeMarkerCard = ({ event, className, ...rest }) => {
|
|
|
20
20
|
),
|
|
21
21
|
children: [
|
|
22
22
|
/* @__PURE__ */ jsx(GitPullRequestIcon, { className: "mt-0.5 size-4 shrink-0", "aria-hidden": "true" }),
|
|
23
|
-
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5
|
|
23
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-0.5 [overflow-wrap:anywhere]", children: [
|
|
24
24
|
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
25
25
|
"Woke: ",
|
|
26
26
|
githubWakeEventLabel(event),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wake-marker.js","sources":["../../../src/chat-ui/messages/wake-marker.tsx"],"sourcesContent":["/**\n * The runtime marker for a wake turn: a GitHub webhook woke the session and\n * injected a user message (see `@athenaintel/agent-runtime`'s\n * `github-wake-event.ts`). It renders in the same visual language as the\n * runtime-ending card (`RuntimeMessageCard`) — a compact status row, not a\n * user bubble quoting the whole wake text.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n type GithubWakeEvent,\n githubWakeEventLabel,\n githubWakeReference,\n readGithubWakeEvent,\n} from \"@athenaintel/agent-runtime\";\nimport { GitPullRequestIcon } from \"lucide-react\";\nimport { type ComponentPropsWithoutRef, type FC, useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface WakeMarkerCardProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"role\"> {\n event: GithubWakeEvent;\n}\n\n/** The \"Woke: review comment on #36337\" row; pure presenter. */\nexport const WakeMarkerCard: FC<WakeMarkerCardProps> = ({ event, className, ...rest }) => {\n const target = event.number !== null ? `#${event.number}` : event.repo;\n const reference = githubWakeReference(event);\n return (\n <div\n {...rest}\n role=\"status\"\n data-runtime-message-kind=\"wake\"\n data-testid=\"wake-marker\"\n className={cn(\n \"my-2 flex w-full items-start gap-2 rounded-lg border border-border bg-muted/40 px-3 py-2 text-muted-foreground text-sm\",\n className,\n )}\n >\n <GitPullRequestIcon className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5
|
|
1
|
+
{"version":3,"file":"wake-marker.js","sources":["../../../src/chat-ui/messages/wake-marker.tsx"],"sourcesContent":["/**\n * The runtime marker for a wake turn: a GitHub webhook woke the session and\n * injected a user message (see `@athenaintel/agent-runtime`'s\n * `github-wake-event.ts`). It renders in the same visual language as the\n * runtime-ending card (`RuntimeMessageCard`) — a compact status row, not a\n * user bubble quoting the whole wake text.\n */\nimport { useAuiState } from \"@assistant-ui/react\";\nimport {\n type GithubWakeEvent,\n githubWakeEventLabel,\n githubWakeReference,\n readGithubWakeEvent,\n} from \"@athenaintel/agent-runtime\";\nimport { GitPullRequestIcon } from \"lucide-react\";\nimport { type ComponentPropsWithoutRef, type FC, useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface WakeMarkerCardProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"role\"> {\n event: GithubWakeEvent;\n}\n\n/** The \"Woke: review comment on #36337\" row; pure presenter. */\nexport const WakeMarkerCard: FC<WakeMarkerCardProps> = ({ event, className, ...rest }) => {\n const target = event.number !== null ? `#${event.number}` : event.repo;\n const reference = githubWakeReference(event);\n return (\n <div\n {...rest}\n role=\"status\"\n data-runtime-message-kind=\"wake\"\n data-testid=\"wake-marker\"\n className={cn(\n \"my-2 flex w-full items-start gap-2 rounded-lg border border-border bg-muted/40 px-3 py-2 text-muted-foreground text-sm\",\n className,\n )}\n >\n <GitPullRequestIcon className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-0.5 [overflow-wrap:anywhere]\">\n <span className=\"font-medium\">\n Woke: {githubWakeEventLabel(event)} on{\" \"}\n {event.url ? (\n <a\n href={event.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={event.title ?? reference}\n className=\"underline-offset-2 hover:underline\"\n >\n {target}\n </a>\n ) : (\n <span title={event.title ?? reference}>{target}</span>\n )}\n </span>\n {event.sender || event.title ? (\n <span className=\"text-xs opacity-90\">\n {event.sender ? `by ${event.sender}` : null}\n {event.sender && event.title ? \" · \" : null}\n {event.title}\n </span>\n ) : null}\n {event.bodyExcerpt ? (\n <span className=\"truncate text-xs italic opacity-90\" title={event.bodyExcerpt}>\n “{event.bodyExcerpt}”\n </span>\n ) : null}\n </div>\n </div>\n );\n};\n\n/**\n * {@link WakeMarkerCard} bound to the assistant-ui message in scope. Selects\n * the message's `metadata.custom` (a stable store reference) and derives the\n * envelope from it: the reader allocates a fresh object per call, so selecting\n * its result directly would re-render on every store update.\n */\nexport const WakeMarkerMessage: FC<{ className?: string }> = ({ className }) => {\n const custom = useAuiState((s) => s.message.metadata?.custom);\n const event = useMemo(() => readGithubWakeEvent(custom), [custom]);\n if (!event) return null;\n return <WakeMarkerCard event={event} className={className} />;\n};\n"],"names":[],"mappings":";;;;;;AAwBO,MAAM,iBAA0C,CAAC,EAAE,OAAO,WAAW,GAAG,WAAW;AACxF,QAAM,SAAS,MAAM,WAAW,OAAO,IAAI,MAAM,MAAM,KAAK,MAAM;AAClE,QAAM,YAAY,oBAAoB,KAAK;AAC3C,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAG;AAAA,MACJ,MAAK;AAAA,MACL,6BAA0B;AAAA,MAC1B,eAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,oBAAC,oBAAA,EAAmB,WAAU,0BAAyB,eAAY,QAAO;AAAA,QAC1E,qBAAC,OAAA,EAAI,WAAU,iEACb,UAAA;AAAA,UAAA,qBAAC,QAAA,EAAK,WAAU,eAAc,UAAA;AAAA,YAAA;AAAA,YACrB,qBAAqB,KAAK;AAAA,YAAE;AAAA,YAAI;AAAA,YACtC,MAAM,MACL;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAM,MAAM;AAAA,gBACZ,QAAO;AAAA,gBACP,KAAI;AAAA,gBACJ,OAAO,MAAM,SAAS;AAAA,gBACtB,WAAU;AAAA,gBAET,UAAA;AAAA,cAAA;AAAA,YAAA,IAGH,oBAAC,QAAA,EAAK,OAAO,MAAM,SAAS,WAAY,UAAA,OAAA,CAAO;AAAA,UAAA,GAEnD;AAAA,UACC,MAAM,UAAU,MAAM,QACrB,qBAAC,QAAA,EAAK,WAAU,sBACb,UAAA;AAAA,YAAA,MAAM,SAAS,MAAM,MAAM,MAAM,KAAK;AAAA,YACtC,MAAM,UAAU,MAAM,QAAQ,QAAQ;AAAA,YACtC,MAAM;AAAA,UAAA,EAAA,CACT,IACE;AAAA,UACH,MAAM,cACL,qBAAC,QAAA,EAAK,WAAU,sCAAqC,OAAO,MAAM,aAAa,UAAA;AAAA,YAAA;AAAA,YAC3E,MAAM;AAAA,YAAY;AAAA,UAAA,EAAA,CACtB,IACE;AAAA,QAAA,EAAA,CACN;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAQO,MAAM,oBAAgD,CAAC,EAAE,gBAAgB;AAC9E,QAAM,SAAS,YAAY,CAAC;;AAAM,mBAAE,QAAQ,aAAV,mBAAoB;AAAA,GAAM;AAC5D,QAAM,QAAQ,QAAQ,MAAM,oBAAoB,MAAM,GAAG,CAAC,MAAM,CAAC;AACjE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,oBAAC,gBAAA,EAAe,OAAc,UAAA,CAAsB;AAC7D;"}
|
|
@@ -9,7 +9,7 @@ export declare function ChatLink({ href, excerpt, children, }: {
|
|
|
9
9
|
href: string | null | undefined;
|
|
10
10
|
excerpt?: string | null;
|
|
11
11
|
children: ReactNode;
|
|
12
|
-
}): import("react
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
13
|
/**
|
|
14
14
|
* A cited web page: the site's favicon, the model's label, the excerpt as
|
|
15
15
|
* the tooltip, opening the page at the excerpt (scroll-to-text) in a new tab.
|
|
@@ -21,4 +21,4 @@ export declare function SourceChip({ href, excerpt, children, }: {
|
|
|
21
21
|
href: string;
|
|
22
22
|
excerpt: string;
|
|
23
23
|
children: ReactNode;
|
|
24
|
-
}): import("react
|
|
24
|
+
}): import("react").JSX.Element;
|
|
@@ -4,12 +4,12 @@ import { type ReactNode } from "react";
|
|
|
4
4
|
export declare function ChatMention({ node, interactive, }: {
|
|
5
5
|
node: ProseMirrorNode;
|
|
6
6
|
interactive?: boolean;
|
|
7
|
-
}): import("react
|
|
8
|
-
export declare function ChatMentionNodeView({ node, editor }: NodeViewProps): import("react
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
export declare function ChatMentionNodeView({ node, editor }: NodeViewProps): import("react").JSX.Element;
|
|
9
9
|
export declare function ChatCodeBlock({ node, children, }: {
|
|
10
10
|
node: ProseMirrorNode;
|
|
11
11
|
children: ReactNode;
|
|
12
|
-
}): import("react
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
13
|
/**
|
|
14
14
|
* A fenced block whose closing fence has not arrived: the same frame with the
|
|
15
15
|
* code as plain text and no copy action (there is no settled source to copy
|
|
@@ -20,5 +20,5 @@ export declare function StreamingCodeBlock({ language, code, caret, }: {
|
|
|
20
20
|
language: string;
|
|
21
21
|
code: string;
|
|
22
22
|
caret?: ReactNode;
|
|
23
|
-
}): import("react
|
|
24
|
-
export declare function ChatCodeBlockNodeView({ node }: NodeViewProps): import("react
|
|
23
|
+
}): import("react").JSX.Element;
|
|
24
|
+
export declare function ChatCodeBlockNodeView({ node }: NodeViewProps): import("react").JSX.Element;
|
|
@@ -10,6 +10,7 @@ const Image = require("@tiptap/extension-image");
|
|
|
10
10
|
const extensionTable = require("@tiptap/extension-table");
|
|
11
11
|
const TaskList = require("@tiptap/extension-task-list");
|
|
12
12
|
const TaskItem = require("@tiptap/extension-task-item");
|
|
13
|
+
const markdownTableSerializer = require("../../packages/tiptap-markdown-table/src/markdown-table-serializer.cjs");
|
|
13
14
|
const tiptapMarkdown = require("tiptap-markdown");
|
|
14
15
|
const markdownStorage = require("../markdown-storage.cjs");
|
|
15
16
|
const mentionExtension = require("../mentions/mention-extension.cjs");
|
|
@@ -21,6 +22,12 @@ const ChatMentionExtension = mentionExtension.MentionExtension.extend({
|
|
|
21
22
|
const ChatCodeBlockExtension = CodeBlock.extend({
|
|
22
23
|
addNodeView: () => react.ReactNodeViewRenderer(chatNodeViews.ChatCodeBlockNodeView)
|
|
23
24
|
});
|
|
25
|
+
const ChatTableExtension = extensionTable.Table.extend({
|
|
26
|
+
addStorage() {
|
|
27
|
+
var _a;
|
|
28
|
+
return { ...(_a = this.parent) == null ? void 0 : _a.call(this), ...markdownTableSerializer.markdownTableStorage() };
|
|
29
|
+
}
|
|
30
|
+
});
|
|
24
31
|
const ChatLinkExtension = Link.extend({
|
|
25
32
|
addAttributes() {
|
|
26
33
|
var _a;
|
|
@@ -53,7 +60,7 @@ function createChatTextExtensions() {
|
|
|
53
60
|
isAllowedUri: (url) => citationAnchors.isAllowedChatHref(url)
|
|
54
61
|
}),
|
|
55
62
|
Image.configure({ inline: true }),
|
|
56
|
-
|
|
63
|
+
ChatTableExtension.configure({ resizable: false }),
|
|
57
64
|
extensionTable.TableRow,
|
|
58
65
|
extensionTable.TableCell,
|
|
59
66
|
extensionTable.TableHeader,
|
|
@@ -88,6 +95,7 @@ const CHAT_TEXT_CLASS = "aui-md prose prose-sm max-w-none min-w-0 break-words te
|
|
|
88
95
|
exports.CHAT_TEXT_CLASS = CHAT_TEXT_CLASS;
|
|
89
96
|
exports.ChatCodeBlockExtension = ChatCodeBlockExtension;
|
|
90
97
|
exports.ChatLinkExtension = ChatLinkExtension;
|
|
98
|
+
exports.ChatTableExtension = ChatTableExtension;
|
|
91
99
|
exports.createChatTextExtensions = createChatTextExtensions;
|
|
92
100
|
exports.parseChatText = parseChatText;
|
|
93
101
|
//# sourceMappingURL=chat-text-schema.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-text-schema.cjs","sources":["../../../src/chat-ui/rich-text/chat-text-schema.tsx"],"sourcesContent":["import { Editor, type Extensions } from \"@tiptap/core\";\nimport { DOMParser as ProseMirrorDOMParser } from \"@tiptap/pm/model\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport CodeBlock from \"@tiptap/extension-code-block\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport Link from \"@tiptap/extension-link\";\nimport Image from \"@tiptap/extension-image\";\nimport { Table, TableCell, TableHeader, TableRow } from \"@tiptap/extension-table\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport { Markdown } from \"tiptap-markdown\";\nimport { getMarkdownStorage } from \"../markdown-storage\";\nimport { MentionExtension } from \"../mentions/mention-extension\";\nimport { ChatCodeBlockNodeView, ChatMentionNodeView } from \"./chat-node-views\";\nimport { isAllowedChatHref, normalizeCitationAnchors } from \"./citation-anchors\";\n\nconst ChatMentionExtension = MentionExtension.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatMentionNodeView, { as: \"span\" }),\n});\n/** Fenced code rendered through `ChatCodeBlock` (language label + copy button). */\nexport const ChatCodeBlockExtension = CodeBlock.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatCodeBlockNodeView),\n});\n\n/**\n * The Link mark with the excerpt a citation carries (`data-excerpt`, the\n * source chip's tooltip and scroll-to-text target) and an href allow-list\n * narrower than tiptap's default: `http(s):`, `mailto:`, the screen-point\n * protocol and app-relative Spaces paths pass; every other scheme\n * (`javascript:`, `ftp:`, `data:`, protocol-relative `//host`) is dropped and\n * its label kept as text. The same rule governs the composer's autolink.\n */\nexport const ChatLinkExtension = Link.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n excerpt: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-excerpt\"),\n renderHTML: (attributes: Record<string, unknown>) =>\n typeof attributes.excerpt === \"string\" && attributes.excerpt\n ? { \"data-excerpt\": attributes.excerpt }\n : {},\n },\n };\n },\n});\n\n/** Both the editable draft and the static message body use this schema and parser. */\nexport function createChatTextExtensions(): Extensions {\n return [\n StarterKit.configure({\n codeBlock: false,\n // Tiptap 3 StarterKit also bundles these; chat text registers its own link and never had the rest.\n link: false,\n underline: false,\n listKeymap: false,\n trailingNode: false,\n }),\n ChatCodeBlockExtension,\n ChatLinkExtension.configure({\n openOnClick: false,\n autolink: true,\n linkOnPaste: true,\n protocols: [\"athena-point\"],\n isAllowedUri: (url) => isAllowedChatHref(url),\n }),\n Image.configure({ inline: true }),\n
|
|
1
|
+
{"version":3,"file":"chat-text-schema.cjs","sources":["../../../src/chat-ui/rich-text/chat-text-schema.tsx"],"sourcesContent":["import { Editor, type Extensions } from \"@tiptap/core\";\nimport { DOMParser as ProseMirrorDOMParser } from \"@tiptap/pm/model\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport CodeBlock from \"@tiptap/extension-code-block\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport Link from \"@tiptap/extension-link\";\nimport Image from \"@tiptap/extension-image\";\nimport { Table, TableCell, TableHeader, TableRow } from \"@tiptap/extension-table\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport { markdownTableStorage } from \"@athenaintel/tiptap-markdown-table\";\nimport { Markdown } from \"tiptap-markdown\";\nimport { getMarkdownStorage } from \"../markdown-storage\";\nimport { MentionExtension } from \"../mentions/mention-extension\";\nimport { ChatCodeBlockNodeView, ChatMentionNodeView } from \"./chat-node-views\";\nimport { isAllowedChatHref, normalizeCitationAnchors } from \"./citation-anchors\";\n\nconst ChatMentionExtension = MentionExtension.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatMentionNodeView, { as: \"span\" }),\n});\n/** Fenced code rendered through `ChatCodeBlock` (language label + copy button). */\nexport const ChatCodeBlockExtension = CodeBlock.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatCodeBlockNodeView),\n});\n\n/**\n * The table node, written to Markdown through the table writer Olympus's\n * editors share (`@athenaintel/tiptap-markdown-table`), which escapes a `|`\n * inside a cell as `\\|`, so a draft's table reaches the message with the cells\n * it was typed with.\n */\nexport const ChatTableExtension = Table.extend({\n addStorage() {\n return { ...this.parent?.(), ...markdownTableStorage() };\n },\n});\n\n/**\n * The Link mark with the excerpt a citation carries (`data-excerpt`, the\n * source chip's tooltip and scroll-to-text target) and an href allow-list\n * narrower than tiptap's default: `http(s):`, `mailto:`, the screen-point\n * protocol and app-relative Spaces paths pass; every other scheme\n * (`javascript:`, `ftp:`, `data:`, protocol-relative `//host`) is dropped and\n * its label kept as text. The same rule governs the composer's autolink.\n */\nexport const ChatLinkExtension = Link.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n excerpt: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-excerpt\"),\n renderHTML: (attributes: Record<string, unknown>) =>\n typeof attributes.excerpt === \"string\" && attributes.excerpt\n ? { \"data-excerpt\": attributes.excerpt }\n : {},\n },\n };\n },\n});\n\n/** Both the editable draft and the static message body use this schema and parser. */\nexport function createChatTextExtensions(): Extensions {\n return [\n StarterKit.configure({\n codeBlock: false,\n // Tiptap 3 StarterKit also bundles these; chat text registers its own link and never had the rest.\n link: false,\n underline: false,\n listKeymap: false,\n trailingNode: false,\n }),\n ChatCodeBlockExtension,\n ChatLinkExtension.configure({\n openOnClick: false,\n autolink: true,\n linkOnPaste: true,\n protocols: [\"athena-point\"],\n isAllowedUri: (url) => isAllowedChatHref(url),\n }),\n Image.configure({ inline: true }),\n ChatTableExtension.configure({ resizable: false }),\n TableRow,\n TableCell,\n TableHeader,\n TaskList,\n TaskItem.configure({ nested: true }),\n Markdown.configure({\n html: true,\n tightLists: true,\n tightListClass: \"tight\",\n bulletListMarker: \"-\",\n linkify: true,\n breaks: true,\n transformPastedText: true,\n transformCopiedText: false,\n }),\n ChatMentionExtension,\n ];\n}\n\nlet parserEditor: Editor | undefined;\n\n/**\n * A single detached parser per browser tab, never an editor per message.\n * Markdown → HTML (markdown-it, with bare URLs linkified and inline HTML kept)\n * → agora's citation anchors given their hrefs → the schema's document.\n */\nexport function parseChatText(markdown: string) {\n parserEditor ??= new Editor({\n extensions: createChatTextExtensions(),\n content: \"\",\n editable: false,\n });\n const html: string = getMarkdownStorage(parserEditor).parser.parse(markdown);\n const body = new window.DOMParser().parseFromString(html, \"text/html\").body;\n normalizeCitationAnchors(body);\n return ProseMirrorDOMParser.fromSchema(parserEditor.schema).parse(body);\n}\n\n/** Typography is shared; the composer supplies only its padding and scroll boundary. */\nexport const CHAT_TEXT_CLASS =\n \"aui-md prose prose-sm max-w-none min-w-0 break-words text-sm leading-snug text-foreground prose-p:my-1.5 prose-p:leading-snug prose-headings:mt-3 prose-headings:mb-1.5 prose-headings:font-semibold prose-h1:text-sm prose-h2:text-sm prose-h3:text-xs prose-ul:my-1.5 prose-ol:my-1.5 prose-li:my-0.5 prose-blockquote:border-l-2 prose-blockquote:border-border prose-blockquote:text-muted-foreground prose-code:rounded prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:text-xs prose-code:font-mono prose-code:before:content-none prose-code:after:content-none prose-pre:my-2 prose-pre:overflow-x-auto prose-pre:rounded-lg prose-pre:border prose-pre:border-border prose-pre:bg-muted/30 prose-pre:p-3 prose-a:text-primary prose-a:underline prose-a:decoration-primary/40 prose-a:underline-offset-2 hover:prose-a:decoration-primary prose-strong:font-semibold prose-hr:border-border [&>:first-child]:mt-0 [&>:last-child]:mb-0 [&_table]:block [&_table]:overflow-x-auto [&_td]:border [&_td]:border-border [&_td]:px-2 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_ul[data-type=taskList]]:list-none [&_ul[data-type=taskList]]:pl-0 [&_li[data-type=taskItem]]:flex [&_li[data-type=taskItem]]:gap-2\";\n"],"names":["MentionExtension","ReactNodeViewRenderer","ChatMentionNodeView","ChatCodeBlockNodeView","Table","markdownTableStorage","isAllowedChatHref","TableRow","TableCell","TableHeader","Markdown","Editor","getMarkdownStorage","normalizeCitationAnchors","ProseMirrorDOMParser"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,MAAM,uBAAuBA,iBAAAA,iBAAiB,OAAO;AAAA,EACnD,aAAa,MAAMC,MAAAA,sBAAsBC,cAAAA,qBAAqB,EAAE,IAAI,QAAQ;AAC9E,CAAC;AAEM,MAAM,yBAAyB,UAAU,OAAO;AAAA,EACrD,aAAa,MAAMD,MAAAA,sBAAsBE,cAAAA,qBAAqB;AAChE,CAAC;AAQM,MAAM,qBAAqBC,eAAAA,MAAM,OAAO;AAAA,EAC7C,aAAa;;AACX,WAAO,EAAE,IAAG,UAAK,WAAL,+BAAiB,GAAGC,wBAAAA,uBAAqB;AAAA,EACvD;AACF,CAAC;AAUM,MAAM,oBAAoB,KAAK,OAAO;AAAA,EAC3C,gBAAgB;;AACd,WAAO;AAAA,MACL,IAAG,UAAK,WAAL;AAAA,MACH,SAAS;AAAA,QACP,SAAS;AAAA,QACT,WAAW,CAAC,YAAyB,QAAQ,aAAa,cAAc;AAAA,QACxE,YAAY,CAAC,eACX,OAAO,WAAW,YAAY,YAAY,WAAW,UACjD,EAAE,gBAAgB,WAAW,QAAA,IAC7B,CAAA;AAAA,MAAC;AAAA,IACT;AAAA,EAEJ;AACF,CAAC;AAGM,SAAS,2BAAuC;AACrD,SAAO;AAAA,IACL,WAAW,UAAU;AAAA,MACnB,WAAW;AAAA;AAAA,MAEX,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc;AAAA,IAAA,CACf;AAAA,IACD;AAAA,IACA,kBAAkB,UAAU;AAAA,MAC1B,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa;AAAA,MACb,WAAW,CAAC,cAAc;AAAA,MAC1B,cAAc,CAAC,QAAQC,gBAAAA,kBAAkB,GAAG;AAAA,IAAA,CAC7C;AAAA,IACD,MAAM,UAAU,EAAE,QAAQ,MAAM;AAAA,IAChC,mBAAmB,UAAU,EAAE,WAAW,OAAO;AAAA,IACjDC,eAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACA;AAAA,IACA,SAAS,UAAU,EAAE,QAAQ,MAAM;AAAA,IACnCC,eAAAA,SAAS,UAAU;AAAA,MACjB,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,IAAA,CACtB;AAAA,IACD;AAAA,EAAA;AAEJ;AAEA,IAAI;AAOG,SAAS,cAAc,UAAkB;AAC9C,kCAAiB,IAAIC,KAAAA,OAAO;AAAA,IAC1B,YAAY,yBAAA;AAAA,IACZ,SAAS;AAAA,IACT,UAAU;AAAA,EAAA,CACX;AACD,QAAM,OAAeC,gBAAAA,mBAAmB,YAAY,EAAE,OAAO,MAAM,QAAQ;AAC3E,QAAM,OAAO,IAAI,OAAO,UAAA,EAAY,gBAAgB,MAAM,WAAW,EAAE;AACvEC,kBAAAA,yBAAyB,IAAI;AAC7B,SAAOC,MAAAA,UAAqB,WAAW,aAAa,MAAM,EAAE,MAAM,IAAI;AACxE;AAGO,MAAM,kBACX;;;;;;;"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { type Extensions } from "@tiptap/core";
|
|
2
2
|
/** Fenced code rendered through `ChatCodeBlock` (language label + copy button). */
|
|
3
3
|
export declare const ChatCodeBlockExtension: import("@tiptap/core").Node<import("@tiptap/extension-code-block").CodeBlockOptions, any>;
|
|
4
|
+
/**
|
|
5
|
+
* The table node, written to Markdown through the table writer Olympus's
|
|
6
|
+
* editors share (`@athenaintel/tiptap-markdown-table`), which escapes a `|`
|
|
7
|
+
* inside a cell as `\|`, so a draft's table reaches the message with the cells
|
|
8
|
+
* it was typed with.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ChatTableExtension: import("@tiptap/core").Node<import("@tiptap/extension-table").TableOptions, any>;
|
|
4
11
|
/**
|
|
5
12
|
* The Link mark with the excerpt a citation carries (`data-excerpt`, the
|
|
6
13
|
* source chip's tooltip and scroll-to-text target) and an href allow-list
|
|
@@ -8,6 +8,7 @@ import Image from "@tiptap/extension-image";
|
|
|
8
8
|
import { TableRow, TableCell, TableHeader, Table } from "@tiptap/extension-table";
|
|
9
9
|
import TaskList from "@tiptap/extension-task-list";
|
|
10
10
|
import TaskItem from "@tiptap/extension-task-item";
|
|
11
|
+
import { markdownTableStorage } from "../../packages/tiptap-markdown-table/src/markdown-table-serializer.js";
|
|
11
12
|
import { Markdown } from "tiptap-markdown";
|
|
12
13
|
import { getMarkdownStorage } from "../markdown-storage.js";
|
|
13
14
|
import { MentionExtension } from "../mentions/mention-extension.js";
|
|
@@ -19,6 +20,12 @@ const ChatMentionExtension = MentionExtension.extend({
|
|
|
19
20
|
const ChatCodeBlockExtension = CodeBlock.extend({
|
|
20
21
|
addNodeView: () => ReactNodeViewRenderer(ChatCodeBlockNodeView)
|
|
21
22
|
});
|
|
23
|
+
const ChatTableExtension = Table.extend({
|
|
24
|
+
addStorage() {
|
|
25
|
+
var _a;
|
|
26
|
+
return { ...(_a = this.parent) == null ? void 0 : _a.call(this), ...markdownTableStorage() };
|
|
27
|
+
}
|
|
28
|
+
});
|
|
22
29
|
const ChatLinkExtension = Link.extend({
|
|
23
30
|
addAttributes() {
|
|
24
31
|
var _a;
|
|
@@ -51,7 +58,7 @@ function createChatTextExtensions() {
|
|
|
51
58
|
isAllowedUri: (url) => isAllowedChatHref(url)
|
|
52
59
|
}),
|
|
53
60
|
Image.configure({ inline: true }),
|
|
54
|
-
|
|
61
|
+
ChatTableExtension.configure({ resizable: false }),
|
|
55
62
|
TableRow,
|
|
56
63
|
TableCell,
|
|
57
64
|
TableHeader,
|
|
@@ -87,6 +94,7 @@ export {
|
|
|
87
94
|
CHAT_TEXT_CLASS,
|
|
88
95
|
ChatCodeBlockExtension,
|
|
89
96
|
ChatLinkExtension,
|
|
97
|
+
ChatTableExtension,
|
|
90
98
|
createChatTextExtensions,
|
|
91
99
|
parseChatText
|
|
92
100
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-text-schema.js","sources":["../../../src/chat-ui/rich-text/chat-text-schema.tsx"],"sourcesContent":["import { Editor, type Extensions } from \"@tiptap/core\";\nimport { DOMParser as ProseMirrorDOMParser } from \"@tiptap/pm/model\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport CodeBlock from \"@tiptap/extension-code-block\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport Link from \"@tiptap/extension-link\";\nimport Image from \"@tiptap/extension-image\";\nimport { Table, TableCell, TableHeader, TableRow } from \"@tiptap/extension-table\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport { Markdown } from \"tiptap-markdown\";\nimport { getMarkdownStorage } from \"../markdown-storage\";\nimport { MentionExtension } from \"../mentions/mention-extension\";\nimport { ChatCodeBlockNodeView, ChatMentionNodeView } from \"./chat-node-views\";\nimport { isAllowedChatHref, normalizeCitationAnchors } from \"./citation-anchors\";\n\nconst ChatMentionExtension = MentionExtension.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatMentionNodeView, { as: \"span\" }),\n});\n/** Fenced code rendered through `ChatCodeBlock` (language label + copy button). */\nexport const ChatCodeBlockExtension = CodeBlock.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatCodeBlockNodeView),\n});\n\n/**\n * The Link mark with the excerpt a citation carries (`data-excerpt`, the\n * source chip's tooltip and scroll-to-text target) and an href allow-list\n * narrower than tiptap's default: `http(s):`, `mailto:`, the screen-point\n * protocol and app-relative Spaces paths pass; every other scheme\n * (`javascript:`, `ftp:`, `data:`, protocol-relative `//host`) is dropped and\n * its label kept as text. The same rule governs the composer's autolink.\n */\nexport const ChatLinkExtension = Link.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n excerpt: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-excerpt\"),\n renderHTML: (attributes: Record<string, unknown>) =>\n typeof attributes.excerpt === \"string\" && attributes.excerpt\n ? { \"data-excerpt\": attributes.excerpt }\n : {},\n },\n };\n },\n});\n\n/** Both the editable draft and the static message body use this schema and parser. */\nexport function createChatTextExtensions(): Extensions {\n return [\n StarterKit.configure({\n codeBlock: false,\n // Tiptap 3 StarterKit also bundles these; chat text registers its own link and never had the rest.\n link: false,\n underline: false,\n listKeymap: false,\n trailingNode: false,\n }),\n ChatCodeBlockExtension,\n ChatLinkExtension.configure({\n openOnClick: false,\n autolink: true,\n linkOnPaste: true,\n protocols: [\"athena-point\"],\n isAllowedUri: (url) => isAllowedChatHref(url),\n }),\n Image.configure({ inline: true }),\n
|
|
1
|
+
{"version":3,"file":"chat-text-schema.js","sources":["../../../src/chat-ui/rich-text/chat-text-schema.tsx"],"sourcesContent":["import { Editor, type Extensions } from \"@tiptap/core\";\nimport { DOMParser as ProseMirrorDOMParser } from \"@tiptap/pm/model\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport CodeBlock from \"@tiptap/extension-code-block\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport Link from \"@tiptap/extension-link\";\nimport Image from \"@tiptap/extension-image\";\nimport { Table, TableCell, TableHeader, TableRow } from \"@tiptap/extension-table\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport { markdownTableStorage } from \"@athenaintel/tiptap-markdown-table\";\nimport { Markdown } from \"tiptap-markdown\";\nimport { getMarkdownStorage } from \"../markdown-storage\";\nimport { MentionExtension } from \"../mentions/mention-extension\";\nimport { ChatCodeBlockNodeView, ChatMentionNodeView } from \"./chat-node-views\";\nimport { isAllowedChatHref, normalizeCitationAnchors } from \"./citation-anchors\";\n\nconst ChatMentionExtension = MentionExtension.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatMentionNodeView, { as: \"span\" }),\n});\n/** Fenced code rendered through `ChatCodeBlock` (language label + copy button). */\nexport const ChatCodeBlockExtension = CodeBlock.extend({\n addNodeView: () => ReactNodeViewRenderer(ChatCodeBlockNodeView),\n});\n\n/**\n * The table node, written to Markdown through the table writer Olympus's\n * editors share (`@athenaintel/tiptap-markdown-table`), which escapes a `|`\n * inside a cell as `\\|`, so a draft's table reaches the message with the cells\n * it was typed with.\n */\nexport const ChatTableExtension = Table.extend({\n addStorage() {\n return { ...this.parent?.(), ...markdownTableStorage() };\n },\n});\n\n/**\n * The Link mark with the excerpt a citation carries (`data-excerpt`, the\n * source chip's tooltip and scroll-to-text target) and an href allow-list\n * narrower than tiptap's default: `http(s):`, `mailto:`, the screen-point\n * protocol and app-relative Spaces paths pass; every other scheme\n * (`javascript:`, `ftp:`, `data:`, protocol-relative `//host`) is dropped and\n * its label kept as text. The same rule governs the composer's autolink.\n */\nexport const ChatLinkExtension = Link.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n excerpt: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-excerpt\"),\n renderHTML: (attributes: Record<string, unknown>) =>\n typeof attributes.excerpt === \"string\" && attributes.excerpt\n ? { \"data-excerpt\": attributes.excerpt }\n : {},\n },\n };\n },\n});\n\n/** Both the editable draft and the static message body use this schema and parser. */\nexport function createChatTextExtensions(): Extensions {\n return [\n StarterKit.configure({\n codeBlock: false,\n // Tiptap 3 StarterKit also bundles these; chat text registers its own link and never had the rest.\n link: false,\n underline: false,\n listKeymap: false,\n trailingNode: false,\n }),\n ChatCodeBlockExtension,\n ChatLinkExtension.configure({\n openOnClick: false,\n autolink: true,\n linkOnPaste: true,\n protocols: [\"athena-point\"],\n isAllowedUri: (url) => isAllowedChatHref(url),\n }),\n Image.configure({ inline: true }),\n ChatTableExtension.configure({ resizable: false }),\n TableRow,\n TableCell,\n TableHeader,\n TaskList,\n TaskItem.configure({ nested: true }),\n Markdown.configure({\n html: true,\n tightLists: true,\n tightListClass: \"tight\",\n bulletListMarker: \"-\",\n linkify: true,\n breaks: true,\n transformPastedText: true,\n transformCopiedText: false,\n }),\n ChatMentionExtension,\n ];\n}\n\nlet parserEditor: Editor | undefined;\n\n/**\n * A single detached parser per browser tab, never an editor per message.\n * Markdown → HTML (markdown-it, with bare URLs linkified and inline HTML kept)\n * → agora's citation anchors given their hrefs → the schema's document.\n */\nexport function parseChatText(markdown: string) {\n parserEditor ??= new Editor({\n extensions: createChatTextExtensions(),\n content: \"\",\n editable: false,\n });\n const html: string = getMarkdownStorage(parserEditor).parser.parse(markdown);\n const body = new window.DOMParser().parseFromString(html, \"text/html\").body;\n normalizeCitationAnchors(body);\n return ProseMirrorDOMParser.fromSchema(parserEditor.schema).parse(body);\n}\n\n/** Typography is shared; the composer supplies only its padding and scroll boundary. */\nexport const CHAT_TEXT_CLASS =\n \"aui-md prose prose-sm max-w-none min-w-0 break-words text-sm leading-snug text-foreground prose-p:my-1.5 prose-p:leading-snug prose-headings:mt-3 prose-headings:mb-1.5 prose-headings:font-semibold prose-h1:text-sm prose-h2:text-sm prose-h3:text-xs prose-ul:my-1.5 prose-ol:my-1.5 prose-li:my-0.5 prose-blockquote:border-l-2 prose-blockquote:border-border prose-blockquote:text-muted-foreground prose-code:rounded prose-code:bg-muted prose-code:px-1 prose-code:py-0.5 prose-code:text-xs prose-code:font-mono prose-code:before:content-none prose-code:after:content-none prose-pre:my-2 prose-pre:overflow-x-auto prose-pre:rounded-lg prose-pre:border prose-pre:border-border prose-pre:bg-muted/30 prose-pre:p-3 prose-a:text-primary prose-a:underline prose-a:decoration-primary/40 prose-a:underline-offset-2 hover:prose-a:decoration-primary prose-strong:font-semibold prose-hr:border-border [&>:first-child]:mt-0 [&>:last-child]:mb-0 [&_table]:block [&_table]:overflow-x-auto [&_td]:border [&_td]:border-border [&_td]:px-2 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_ul[data-type=taskList]]:list-none [&_ul[data-type=taskList]]:pl-0 [&_li[data-type=taskItem]]:flex [&_li[data-type=taskItem]]:gap-2\";\n"],"names":["ProseMirrorDOMParser"],"mappings":";;;;;;;;;;;;;;;;AAiBA,MAAM,uBAAuB,iBAAiB,OAAO;AAAA,EACnD,aAAa,MAAM,sBAAsB,qBAAqB,EAAE,IAAI,QAAQ;AAC9E,CAAC;AAEM,MAAM,yBAAyB,UAAU,OAAO;AAAA,EACrD,aAAa,MAAM,sBAAsB,qBAAqB;AAChE,CAAC;AAQM,MAAM,qBAAqB,MAAM,OAAO;AAAA,EAC7C,aAAa;;AACX,WAAO,EAAE,IAAG,UAAK,WAAL,+BAAiB,GAAG,uBAAqB;AAAA,EACvD;AACF,CAAC;AAUM,MAAM,oBAAoB,KAAK,OAAO;AAAA,EAC3C,gBAAgB;;AACd,WAAO;AAAA,MACL,IAAG,UAAK,WAAL;AAAA,MACH,SAAS;AAAA,QACP,SAAS;AAAA,QACT,WAAW,CAAC,YAAyB,QAAQ,aAAa,cAAc;AAAA,QACxE,YAAY,CAAC,eACX,OAAO,WAAW,YAAY,YAAY,WAAW,UACjD,EAAE,gBAAgB,WAAW,QAAA,IAC7B,CAAA;AAAA,MAAC;AAAA,IACT;AAAA,EAEJ;AACF,CAAC;AAGM,SAAS,2BAAuC;AACrD,SAAO;AAAA,IACL,WAAW,UAAU;AAAA,MACnB,WAAW;AAAA;AAAA,MAEX,MAAM;AAAA,MACN,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc;AAAA,IAAA,CACf;AAAA,IACD;AAAA,IACA,kBAAkB,UAAU;AAAA,MAC1B,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa;AAAA,MACb,WAAW,CAAC,cAAc;AAAA,MAC1B,cAAc,CAAC,QAAQ,kBAAkB,GAAG;AAAA,IAAA,CAC7C;AAAA,IACD,MAAM,UAAU,EAAE,QAAQ,MAAM;AAAA,IAChC,mBAAmB,UAAU,EAAE,WAAW,OAAO;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,UAAU,EAAE,QAAQ,MAAM;AAAA,IACnC,SAAS,UAAU;AAAA,MACjB,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,IAAA,CACtB;AAAA,IACD;AAAA,EAAA;AAEJ;AAEA,IAAI;AAOG,SAAS,cAAc,UAAkB;AAC9C,kCAAiB,IAAI,OAAO;AAAA,IAC1B,YAAY,yBAAA;AAAA,IACZ,SAAS;AAAA,IACT,UAAU;AAAA,EAAA,CACX;AACD,QAAM,OAAe,mBAAmB,YAAY,EAAE,OAAO,MAAM,QAAQ;AAC3E,QAAM,OAAO,IAAI,OAAO,UAAA,EAAY,gBAAgB,MAAM,WAAW,EAAE;AACvE,2BAAyB,IAAI;AAC7B,SAAOA,UAAqB,WAAW,aAAa,MAAM,EAAE,MAAM,IAAI;AACxE;AAGO,MAAM,kBACX;"}
|
|
@@ -51,4 +51,4 @@ export interface ChatComposerDockProps {
|
|
|
51
51
|
* editor row, and the toolbar with its start/end slots around a flexible
|
|
52
52
|
* spacer. Hosts supply the editor element and toolbar controls.
|
|
53
53
|
*/
|
|
54
|
-
export declare function ChatComposerDock({ appearance, className, surfaceClassName, editorRowClassName, toolbarClassName, dragActive, aboveSurface, beforeEditor, editor, toolbarStart, toolbarEnd, belowSurface, }: ChatComposerDockProps): import("react
|
|
54
|
+
export declare function ChatComposerDock({ appearance, className, surfaceClassName, editorRowClassName, toolbarClassName, dragActive, aboveSurface, beforeEditor, editor, toolbarStart, toolbarEnd, belowSurface, }: ChatComposerDockProps): import("react").JSX.Element;
|
|
@@ -8,6 +8,7 @@ const messageComponents = require("../messages/message-components.cjs");
|
|
|
8
8
|
const messageActionsConfig = require("../messages/message-actions-config.cjs");
|
|
9
9
|
const userEditComposer = require("../messages/user-edit-composer.cjs");
|
|
10
10
|
const runningIndicator = require("../messages/running-indicator.cjs");
|
|
11
|
+
const threadChrome = require("../messages/thread-chrome.cjs");
|
|
11
12
|
const DEFAULT_VIEWPORT_CLASS = "relative flex flex-1 flex-col overflow-y-auto scroll-smooth";
|
|
12
13
|
const DEFAULT_CONTENT_CLASS = "w-full flex-1 px-3 pt-3";
|
|
13
14
|
const DEFAULT_VIEWPORT_FOOTER_CLASS = "sticky bottom-0";
|
|
@@ -47,7 +48,7 @@ function ChatThreadShell({
|
|
|
47
48
|
AssistantMessage,
|
|
48
49
|
UserEditComposer: UserEditComposerComponent = userEditComposer.UserEditComposer
|
|
49
50
|
} = components;
|
|
50
|
-
const
|
|
51
|
+
const messageComponents2 = react.useMemo(
|
|
51
52
|
() => ({
|
|
52
53
|
UserMessage,
|
|
53
54
|
AssistantMessage,
|
|
@@ -55,11 +56,11 @@ function ChatThreadShell({
|
|
|
55
56
|
}),
|
|
56
57
|
[UserMessage, AssistantMessage, UserEditComposerComponent]
|
|
57
58
|
);
|
|
58
|
-
const messages = /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Messages, { components:
|
|
59
|
+
const messages = /* @__PURE__ */ jsxRuntime.jsx(react$1.ThreadPrimitive.Messages, { components: messageComponents2 });
|
|
59
60
|
return /* @__PURE__ */ jsxRuntime.jsx(messageActionsConfig.MessageActionsReadOnlyProvider, { readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
60
61
|
react$1.ThreadPrimitive.Root,
|
|
61
62
|
{
|
|
62
|
-
className: panelClassName ??
|
|
63
|
+
className: panelClassName ?? threadChrome.THREAD_PANEL_CLASS,
|
|
63
64
|
style: { "--thread-max-width": maxWidth },
|
|
64
65
|
children: [
|
|
65
66
|
overlay,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-thread-shell.cjs","sources":["../../../src/chat-ui/thread/chat-thread-shell.tsx"],"sourcesContent":["import { AuiIf, ThreadPrimitive } from \"@assistant-ui/react\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport {\n THREAD_PANEL_CLASS,\n THREAD_SCROLL_TO_BOTTOM_CLASS,\n} from \"../messages/message-components\";\nimport { MessageActionsReadOnlyProvider } from \"../messages/message-actions-config\";\nimport { UserEditComposer } from \"../messages/user-edit-composer\";\nimport { ThreadRunningIndicator } from \"../messages/running-indicator\";\n\nexport interface ChatThreadMessageComponents {\n UserMessage: FC;\n AssistantMessage: FC;\n /**\n * Rendered in place of a user message while it is being edited (the action\n * bar's Edit control). Defaults to the shared UserEditComposer.\n */\n UserEditComposer?: FC;\n}\n\nconst DEFAULT_VIEWPORT_CLASS =\n \"relative flex flex-1 flex-col overflow-y-auto scroll-smooth\";\nconst DEFAULT_CONTENT_CLASS = \"w-full flex-1 px-3 pt-3\";\nconst DEFAULT_VIEWPORT_FOOTER_CLASS = \"sticky bottom-0\";\n\nconst DefaultScrollToBottom: FC = () => (\n <AuiIf condition={(state) => !state.thread.isEmpty}>\n <div className=\"flex justify-center pb-0.5\">\n <ThreadPrimitive.ScrollToBottom\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className={THREAD_SCROLL_TO_BOTTOM_CLASS}\n >\n <ChevronDownIcon className=\"size-3.5\" />\n </ThreadPrimitive.ScrollToBottom>\n </div>\n </AuiIf>\n);\n\nexport interface ChatThreadShellProps {\n /**\n * Rendered as the first child of the panel — for absolutely-positioned\n * scrims that must cover the whole panel (AthenaChat's thread-loading\n * overlay). The shell does not force a positioning context; hosts include\n * `relative` in `panelClassName` when the scrim anchors to the panel.\n */\n overlay?: ReactNode;\n /**\n * Rendered above the viewport, inside the panel: header rows, slide-over\n * panels, and anything else the host docks at the top.\n */\n header?: ReactNode;\n /** Status/approval banners rendered between the header and the viewport. */\n banners?: ReactNode;\n /**\n * Nodes rendered inside the scroll viewport before the message column —\n * absolutely/sticky-positioned overlays (thread-switch skeletons,\n * scroll-to-top controls) and invisible observers (read receipts).\n */\n viewportOverlay?: ReactNode;\n /** Empty-thread state, rendered via ThreadPrimitive.Empty when provided. */\n welcome?: ReactNode;\n /**\n * Rendered inside the message column right above the messages — the\n * windowed wire's history edge (`StatewireHistoryEdge`): the \"N earlier\n * messages\" row that pages older history in and fetches cut tool outputs.\n */\n beforeMessages?: ReactNode;\n /** Message renderers for ThreadPrimitive.Messages. */\n components: ChatThreadMessageComponents;\n /**\n * Wraps the messages element — for hosts that provide message-scoped\n * context (e.g. activity-grouping providers). Must render its argument.\n */\n renderMessages?: (messages: ReactNode) => ReactNode;\n /**\n * Rendered between the viewport and the composer: connection banners,\n * queued-message trays.\n */\n belowViewport?: ReactNode;\n /** The composer dock (or a read-only notice replacing it). */\n composer?: ReactNode;\n /**\n * Replaces the docked-panel card chrome — for hosts that render a\n * full-page column (AthenaChat's `aui-*` surface) instead of the\n * side-panel/task-pane card.\n */\n panelClassName?: string;\n /**\n * Value of the `--thread-max-width` variable read by width-capped\n * message/welcome/footer columns. Panels fill their width (the default,\n * \"100%\"); full-page hosts cap the column (AthenaChat defaults to 44rem).\n */\n maxWidth?: string;\n /**\n * Anchors the latest turn to the top of the viewport instead of pinning\n * scroll to the bottom (AthenaChat). Omitted = the primitive's default.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Replaces the scroll-viewport chrome (padding, overflow tuning). */\n viewportClassName?: string;\n /**\n * Replaces the message-column chrome. Hosts whose welcome screen centers\n * vertically make this a flex column so the welcome node can grow.\n */\n contentClassName?: string;\n /**\n * Thread-level \"Thinking...\" indicator rendered after the messages. Hosts\n * whose message components render their own per-message indicators pass\n * null so the two never double up.\n */\n runningIndicator?: ReactNode;\n /**\n * Replaces the default centered scroll-to-bottom pill inside the sticky\n * viewport footer (AthenaChat floats a circular button above its composer).\n */\n scrollToBottom?: ReactNode;\n /**\n * Content docked inside the sticky viewport footer, after the\n * scroll-to-bottom control — for hosts whose banners + composer float over\n * the scrolling messages (AthenaChat) instead of sitting below the\n * viewport via `belowViewport`/`composer`.\n */\n viewportFooter?: ReactNode;\n /** Replaces the sticky viewport-footer chrome. */\n viewportFooterClassName?: string;\n /**\n * Marks the transcript read-only: mutating message actions (Edit,\n * Regenerate) hide while Copy stays available. For threads whose server\n * rejects dispatch (e.g. legacy pre-cutover conversations) — the runtime's\n * static capability flags cannot express a per-thread fence.\n */\n readOnly?: boolean;\n}\n\n/**\n * The shared thread layout: panel chrome, scroll viewport with welcome +\n * messages + running indicator, the sticky scroll-to-bottom control, and the\n * host-supplied composer dock.\n *\n * Hosts express their genuine divergences through the slots above; the\n * layout, scroll behaviour, and empty/running states stay identical across\n * surfaces so fixes land once.\n */\nexport function ChatThreadShell({\n overlay,\n header,\n banners,\n viewportOverlay,\n welcome,\n beforeMessages,\n components,\n renderMessages,\n belowViewport,\n composer,\n panelClassName,\n maxWidth = \"100%\",\n turnAnchor,\n viewportClassName,\n contentClassName,\n runningIndicator = <ThreadRunningIndicator />,\n scrollToBottom = <DefaultScrollToBottom />,\n viewportFooter,\n viewportFooterClassName,\n readOnly = false,\n}: ChatThreadShellProps) {\n const {\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent = UserEditComposer,\n } = components;\n // ThreadPrimitive.Messages resolves per-message renderers by component\n // identity, so keep the merged map referentially stable across renders.\n const messageComponents = useMemo(\n () => ({\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent,\n }),\n [UserMessage, AssistantMessage, UserEditComposerComponent],\n );\n const messages = <ThreadPrimitive.Messages components={messageComponents} />;\n return (\n <MessageActionsReadOnlyProvider readOnly={readOnly}>\n <ThreadPrimitive.Root\n className={panelClassName ?? THREAD_PANEL_CLASS}\n style={{ \"--thread-max-width\": maxWidth } as CSSProperties}\n >\n {overlay}\n {header}\n {banners}\n <ThreadPrimitive.Viewport\n turnAnchor={turnAnchor}\n className={viewportClassName ?? DEFAULT_VIEWPORT_CLASS}\n data-aui-thread-viewport=\"\"\n >\n {viewportOverlay}\n {/* No min-h-0 here: the column's automatic minimum height is what\n lets it extend past one screen, keeping the sticky footer's flow\n position after the full message list. Capping it detaches the\n footer (scroll pill, docked composers) as soon as the thread\n scrolls — proven in a live-browser probe of both structures. */}\n <div className=\"flex flex-1 flex-col items-center\">\n <div className={contentClassName ?? DEFAULT_CONTENT_CLASS}>\n {welcome != null ? (\n <ThreadPrimitive.Empty>{welcome}</ThreadPrimitive.Empty>\n ) : null}\n {beforeMessages}\n {renderMessages ? renderMessages(messages) : messages}\n {runningIndicator}\n </div>\n </div>\n <ThreadPrimitive.ViewportFooter\n className={viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS}\n >\n {scrollToBottom}\n {viewportFooter}\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n {belowViewport}\n {composer}\n </ThreadPrimitive.Root>\n </MessageActionsReadOnlyProvider>\n );\n}\n"],"names":["jsx","AuiIf","ThreadPrimitive","THREAD_SCROLL_TO_BOTTOM_CLASS","ChevronDownIcon","runningIndicator","ThreadRunningIndicator","UserEditComposer","messageComponents","useMemo","MessageActionsReadOnlyProvider","jsxs","THREAD_PANEL_CLASS"],"mappings":";;;;;;;;;;AAsBA,MAAM,yBACJ;AACF,MAAM,wBAAwB;AAC9B,MAAM,gCAAgC;AAEtC,MAAM,wBAA4B,MAChCA,2BAAAA,IAACC,QAAAA,OAAA,EAAM,WAAW,CAAC,UAAU,CAAC,MAAM,OAAO,SACzC,UAAAD,+BAAC,OAAA,EAAI,WAAU,8BACb,UAAAA,2BAAAA;AAAAA,EAACE,QAAAA,gBAAgB;AAAA,EAAhB;AAAA,IACC,cAAW;AAAA,IACX,OAAM;AAAA,IACN,WAAWC,kBAAAA;AAAAA,IAEX,UAAAH,2BAAAA,IAACI,YAAAA,iBAAA,EAAgB,WAAU,WAAA,CAAW;AAAA,EAAA;AACxC,EAAA,CACF,EAAA,CACF;AA4GK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EAAA,kBACAC,oDAAoBC,iBAAAA,wBAAA,EAAuB;AAAA,EAC3C,gDAAkB,uBAAA,EAAsB;AAAA,EACxC;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAyB;AACvB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,kBAAkB,4BAA4BC,iBAAAA;AAAAA,EAAA,IAC5C;AAGJ,QAAMC,sBAAoBC,MAAAA;AAAAA,IACxB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IAAA;AAAA,IAEpB,CAAC,aAAa,kBAAkB,yBAAyB;AAAA,EAAA;AAE3D,QAAM,WAAWT,2BAAAA,IAACE,QAAAA,gBAAgB,UAAhB,EAAyB,YAAYM,qBAAmB;AAC1E,SACER,2BAAAA,IAACU,qBAAAA,kCAA+B,UAC9B,UAAAC,2BAAAA;AAAAA,IAACT,QAAAA,gBAAgB;AAAA,IAAhB;AAAA,MACC,WAAW,kBAAkBU,kBAAAA;AAAAA,MAC7B,OAAO,EAAE,sBAAsB,SAAA;AAAA,MAE9B,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,QACA;AAAA,QACDD,2BAAAA;AAAAA,UAACT,QAAAA,gBAAgB;AAAA,UAAhB;AAAA,YACC;AAAA,YACA,WAAW,qBAAqB;AAAA,YAChC,4BAAyB;AAAA,YAExB,UAAA;AAAA,cAAA;AAAA,cAMDF,2BAAAA,IAAC,SAAI,WAAU,qCACb,0CAAC,OAAA,EAAI,WAAW,oBAAoB,uBACjC,UAAA;AAAA,gBAAA,WAAW,OACVA,2BAAAA,IAACE,QAAAA,gBAAgB,OAAhB,EAAuB,mBAAQ,IAC9B;AAAA,gBACH;AAAA,gBACA,iBAAiB,eAAe,QAAQ,IAAI;AAAA,gBAC5CG;AAAAA,cAAA,EAAA,CACH,EAAA,CACF;AAAA,cACAM,2BAAAA;AAAAA,gBAACT,QAAAA,gBAAgB;AAAA,gBAAhB;AAAA,kBACC,WAAW,2BAA2B;AAAA,kBAErC,UAAA;AAAA,oBAAA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH;AAAA,UAAA;AAAA,QAAA;AAAA,QAED;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;;"}
|
|
1
|
+
{"version":3,"file":"chat-thread-shell.cjs","sources":["../../../src/chat-ui/thread/chat-thread-shell.tsx"],"sourcesContent":["import { AuiIf, ThreadPrimitive } from \"@assistant-ui/react\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport {\n THREAD_PANEL_CLASS,\n THREAD_SCROLL_TO_BOTTOM_CLASS,\n} from \"../messages/message-components\";\nimport { MessageActionsReadOnlyProvider } from \"../messages/message-actions-config\";\nimport { UserEditComposer } from \"../messages/user-edit-composer\";\nimport { ThreadRunningIndicator } from \"../messages/running-indicator\";\n\nexport interface ChatThreadMessageComponents {\n UserMessage: FC;\n AssistantMessage: FC;\n /**\n * Rendered in place of a user message while it is being edited (the action\n * bar's Edit control). Defaults to the shared UserEditComposer.\n */\n UserEditComposer?: FC;\n}\n\nconst DEFAULT_VIEWPORT_CLASS =\n \"relative flex flex-1 flex-col overflow-y-auto scroll-smooth\";\nconst DEFAULT_CONTENT_CLASS = \"w-full flex-1 px-3 pt-3\";\nconst DEFAULT_VIEWPORT_FOOTER_CLASS = \"sticky bottom-0\";\n\nconst DefaultScrollToBottom: FC = () => (\n <AuiIf condition={(state) => !state.thread.isEmpty}>\n <div className=\"flex justify-center pb-0.5\">\n <ThreadPrimitive.ScrollToBottom\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className={THREAD_SCROLL_TO_BOTTOM_CLASS}\n >\n <ChevronDownIcon className=\"size-3.5\" />\n </ThreadPrimitive.ScrollToBottom>\n </div>\n </AuiIf>\n);\n\nexport interface ChatThreadShellProps {\n /**\n * Rendered as the first child of the panel — for absolutely-positioned\n * scrims that must cover the whole panel (AthenaChat's thread-loading\n * overlay). The shell does not force a positioning context; hosts include\n * `relative` in `panelClassName` when the scrim anchors to the panel.\n */\n overlay?: ReactNode;\n /**\n * Rendered above the viewport, inside the panel: header rows, slide-over\n * panels, and anything else the host docks at the top.\n */\n header?: ReactNode;\n /** Status/approval banners rendered between the header and the viewport. */\n banners?: ReactNode;\n /**\n * Nodes rendered inside the scroll viewport before the message column —\n * absolutely/sticky-positioned overlays (thread-switch skeletons,\n * scroll-to-top controls) and invisible observers (read receipts).\n */\n viewportOverlay?: ReactNode;\n /** Empty-thread state, rendered via ThreadPrimitive.Empty when provided. */\n welcome?: ReactNode;\n /**\n * Rendered inside the message column right above the messages — the\n * windowed wire's history edge (`StatewireHistoryEdge`): the \"N earlier\n * messages\" row that pages older history in and fetches cut tool outputs.\n */\n beforeMessages?: ReactNode;\n /** Message renderers for ThreadPrimitive.Messages. */\n components: ChatThreadMessageComponents;\n /**\n * Wraps the messages element — for hosts that provide message-scoped\n * context (e.g. activity-grouping providers). Must render its argument.\n */\n renderMessages?: (messages: ReactNode) => ReactNode;\n /**\n * Rendered between the viewport and the composer: connection banners,\n * queued-message trays.\n */\n belowViewport?: ReactNode;\n /** The composer dock (or a read-only notice replacing it). */\n composer?: ReactNode;\n /**\n * Replaces the docked-panel card chrome — for hosts that render a\n * full-page column (AthenaChat's `aui-*` surface) instead of the\n * side-panel/task-pane card.\n */\n panelClassName?: string;\n /**\n * Value of the `--thread-max-width` variable read by width-capped\n * message/welcome/footer columns. Panels fill their width (the default,\n * \"100%\"); full-page hosts cap the column (AthenaChat defaults to 44rem).\n */\n maxWidth?: string;\n /**\n * Anchors the latest turn to the top of the viewport instead of pinning\n * scroll to the bottom (AthenaChat). Omitted = the primitive's default.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Replaces the scroll-viewport chrome (padding, overflow tuning). */\n viewportClassName?: string;\n /**\n * Replaces the message-column chrome. Hosts whose welcome screen centers\n * vertically make this a flex column so the welcome node can grow.\n */\n contentClassName?: string;\n /**\n * Thread-level \"Thinking...\" indicator rendered after the messages. Hosts\n * whose message components render their own per-message indicators pass\n * null so the two never double up.\n */\n runningIndicator?: ReactNode;\n /**\n * Replaces the default centered scroll-to-bottom pill inside the sticky\n * viewport footer (AthenaChat floats a circular button above its composer).\n */\n scrollToBottom?: ReactNode;\n /**\n * Content docked inside the sticky viewport footer, after the\n * scroll-to-bottom control — for hosts whose banners + composer float over\n * the scrolling messages (AthenaChat) instead of sitting below the\n * viewport via `belowViewport`/`composer`.\n */\n viewportFooter?: ReactNode;\n /** Replaces the sticky viewport-footer chrome. */\n viewportFooterClassName?: string;\n /**\n * Marks the transcript read-only: mutating message actions (Edit,\n * Regenerate) hide while Copy stays available. For threads whose server\n * rejects dispatch (e.g. legacy pre-cutover conversations) — the runtime's\n * static capability flags cannot express a per-thread fence.\n */\n readOnly?: boolean;\n}\n\n/**\n * The shared thread layout: panel chrome, scroll viewport with welcome +\n * messages + running indicator, the sticky scroll-to-bottom control, and the\n * host-supplied composer dock.\n *\n * Hosts express their genuine divergences through the slots above; the\n * layout, scroll behaviour, and empty/running states stay identical across\n * surfaces so fixes land once.\n */\nexport function ChatThreadShell({\n overlay,\n header,\n banners,\n viewportOverlay,\n welcome,\n beforeMessages,\n components,\n renderMessages,\n belowViewport,\n composer,\n panelClassName,\n maxWidth = \"100%\",\n turnAnchor,\n viewportClassName,\n contentClassName,\n runningIndicator = <ThreadRunningIndicator />,\n scrollToBottom = <DefaultScrollToBottom />,\n viewportFooter,\n viewportFooterClassName,\n readOnly = false,\n}: ChatThreadShellProps) {\n const {\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent = UserEditComposer,\n } = components;\n // ThreadPrimitive.Messages resolves per-message renderers by component\n // identity, so keep the merged map referentially stable across renders.\n const messageComponents = useMemo(\n () => ({\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent,\n }),\n [UserMessage, AssistantMessage, UserEditComposerComponent],\n );\n const messages = <ThreadPrimitive.Messages components={messageComponents} />;\n return (\n <MessageActionsReadOnlyProvider readOnly={readOnly}>\n <ThreadPrimitive.Root\n className={panelClassName ?? THREAD_PANEL_CLASS}\n style={{ \"--thread-max-width\": maxWidth } as CSSProperties}\n >\n {overlay}\n {header}\n {banners}\n <ThreadPrimitive.Viewport\n turnAnchor={turnAnchor}\n className={viewportClassName ?? DEFAULT_VIEWPORT_CLASS}\n data-aui-thread-viewport=\"\"\n >\n {viewportOverlay}\n {/* No min-h-0 here: the column's automatic minimum height is what\n lets it extend past one screen, keeping the sticky footer's flow\n position after the full message list. Capping it detaches the\n footer (scroll pill, docked composers) as soon as the thread\n scrolls — proven in a live-browser probe of both structures. */}\n <div className=\"flex flex-1 flex-col items-center\">\n <div className={contentClassName ?? DEFAULT_CONTENT_CLASS}>\n {welcome != null ? (\n <ThreadPrimitive.Empty>{welcome}</ThreadPrimitive.Empty>\n ) : null}\n {beforeMessages}\n {renderMessages ? renderMessages(messages) : messages}\n {runningIndicator}\n </div>\n </div>\n <ThreadPrimitive.ViewportFooter\n className={viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS}\n >\n {scrollToBottom}\n {viewportFooter}\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n {belowViewport}\n {composer}\n </ThreadPrimitive.Root>\n </MessageActionsReadOnlyProvider>\n );\n}\n"],"names":["jsx","AuiIf","ThreadPrimitive","THREAD_SCROLL_TO_BOTTOM_CLASS","ChevronDownIcon","runningIndicator","ThreadRunningIndicator","UserEditComposer","messageComponents","useMemo","MessageActionsReadOnlyProvider","jsxs","THREAD_PANEL_CLASS"],"mappings":";;;;;;;;;;;AAsBA,MAAM,yBACJ;AACF,MAAM,wBAAwB;AAC9B,MAAM,gCAAgC;AAEtC,MAAM,wBAA4B,MAChCA,2BAAAA,IAACC,QAAAA,OAAA,EAAM,WAAW,CAAC,UAAU,CAAC,MAAM,OAAO,SACzC,UAAAD,+BAAC,OAAA,EAAI,WAAU,8BACb,UAAAA,2BAAAA;AAAAA,EAACE,QAAAA,gBAAgB;AAAA,EAAhB;AAAA,IACC,cAAW;AAAA,IACX,OAAM;AAAA,IACN,WAAWC,kBAAAA;AAAAA,IAEX,UAAAH,2BAAAA,IAACI,YAAAA,iBAAA,EAAgB,WAAU,WAAA,CAAW;AAAA,EAAA;AACxC,EAAA,CACF,EAAA,CACF;AA4GK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EAAA,kBACAC,oDAAoBC,iBAAAA,wBAAA,EAAuB;AAAA,EAC3C,gDAAkB,uBAAA,EAAsB;AAAA,EACxC;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAyB;AACvB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,kBAAkB,4BAA4BC,iBAAAA;AAAAA,EAAA,IAC5C;AAGJ,QAAMC,qBAAoBC,MAAAA;AAAAA,IACxB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IAAA;AAAA,IAEpB,CAAC,aAAa,kBAAkB,yBAAyB;AAAA,EAAA;AAE3D,QAAM,WAAWT,2BAAAA,IAACE,QAAAA,gBAAgB,UAAhB,EAAyB,YAAYM,oBAAmB;AAC1E,SACER,2BAAAA,IAACU,qBAAAA,kCAA+B,UAC9B,UAAAC,2BAAAA;AAAAA,IAACT,QAAAA,gBAAgB;AAAA,IAAhB;AAAA,MACC,WAAW,kBAAkBU,aAAAA;AAAAA,MAC7B,OAAO,EAAE,sBAAsB,SAAA;AAAA,MAE9B,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,QACA;AAAA,QACDD,2BAAAA;AAAAA,UAACT,QAAAA,gBAAgB;AAAA,UAAhB;AAAA,YACC;AAAA,YACA,WAAW,qBAAqB;AAAA,YAChC,4BAAyB;AAAA,YAExB,UAAA;AAAA,cAAA;AAAA,cAMDF,2BAAAA,IAAC,SAAI,WAAU,qCACb,0CAAC,OAAA,EAAI,WAAW,oBAAoB,uBACjC,UAAA;AAAA,gBAAA,WAAW,OACVA,2BAAAA,IAACE,QAAAA,gBAAgB,OAAhB,EAAuB,mBAAQ,IAC9B;AAAA,gBACH;AAAA,gBACA,iBAAiB,eAAe,QAAQ,IAAI;AAAA,gBAC5CG;AAAAA,cAAA,EAAA,CACH,EAAA,CACF;AAAA,cACAM,2BAAAA;AAAAA,gBAACT,QAAAA,gBAAgB;AAAA,gBAAhB;AAAA,kBACC,WAAW,2BAA2B;AAAA,kBAErC,UAAA;AAAA,oBAAA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH;AAAA,UAAA;AAAA,QAAA;AAAA,QAED;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;;"}
|
|
@@ -112,4 +112,4 @@ export interface ChatThreadShellProps {
|
|
|
112
112
|
* layout, scroll behaviour, and empty/running states stay identical across
|
|
113
113
|
* surfaces so fixes land once.
|
|
114
114
|
*/
|
|
115
|
-
export declare function ChatThreadShell({ overlay, header, banners, viewportOverlay, welcome, beforeMessages, components, renderMessages, belowViewport, composer, panelClassName, maxWidth, turnAnchor, viewportClassName, contentClassName, runningIndicator, scrollToBottom, viewportFooter, viewportFooterClassName, readOnly, }: ChatThreadShellProps): import("react
|
|
115
|
+
export declare function ChatThreadShell({ overlay, header, banners, viewportOverlay, welcome, beforeMessages, components, renderMessages, belowViewport, composer, panelClassName, maxWidth, turnAnchor, viewportClassName, contentClassName, runningIndicator, scrollToBottom, viewportFooter, viewportFooterClassName, readOnly, }: ChatThreadShellProps): import("react").JSX.Element;
|
|
@@ -2,10 +2,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { ThreadPrimitive, AuiIf } from "@assistant-ui/react";
|
|
3
3
|
import { ChevronDownIcon } from "lucide-react";
|
|
4
4
|
import { useMemo } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { THREAD_SCROLL_TO_BOTTOM_CLASS } from "../messages/message-components.js";
|
|
6
6
|
import { MessageActionsReadOnlyProvider } from "../messages/message-actions-config.js";
|
|
7
7
|
import { UserEditComposer } from "../messages/user-edit-composer.js";
|
|
8
8
|
import { ThreadRunningIndicator } from "../messages/running-indicator.js";
|
|
9
|
+
import { THREAD_PANEL_CLASS } from "../messages/thread-chrome.js";
|
|
9
10
|
const DEFAULT_VIEWPORT_CLASS = "relative flex flex-1 flex-col overflow-y-auto scroll-smooth";
|
|
10
11
|
const DEFAULT_CONTENT_CLASS = "w-full flex-1 px-3 pt-3";
|
|
11
12
|
const DEFAULT_VIEWPORT_FOOTER_CLASS = "sticky bottom-0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-thread-shell.js","sources":["../../../src/chat-ui/thread/chat-thread-shell.tsx"],"sourcesContent":["import { AuiIf, ThreadPrimitive } from \"@assistant-ui/react\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport {\n THREAD_PANEL_CLASS,\n THREAD_SCROLL_TO_BOTTOM_CLASS,\n} from \"../messages/message-components\";\nimport { MessageActionsReadOnlyProvider } from \"../messages/message-actions-config\";\nimport { UserEditComposer } from \"../messages/user-edit-composer\";\nimport { ThreadRunningIndicator } from \"../messages/running-indicator\";\n\nexport interface ChatThreadMessageComponents {\n UserMessage: FC;\n AssistantMessage: FC;\n /**\n * Rendered in place of a user message while it is being edited (the action\n * bar's Edit control). Defaults to the shared UserEditComposer.\n */\n UserEditComposer?: FC;\n}\n\nconst DEFAULT_VIEWPORT_CLASS =\n \"relative flex flex-1 flex-col overflow-y-auto scroll-smooth\";\nconst DEFAULT_CONTENT_CLASS = \"w-full flex-1 px-3 pt-3\";\nconst DEFAULT_VIEWPORT_FOOTER_CLASS = \"sticky bottom-0\";\n\nconst DefaultScrollToBottom: FC = () => (\n <AuiIf condition={(state) => !state.thread.isEmpty}>\n <div className=\"flex justify-center pb-0.5\">\n <ThreadPrimitive.ScrollToBottom\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className={THREAD_SCROLL_TO_BOTTOM_CLASS}\n >\n <ChevronDownIcon className=\"size-3.5\" />\n </ThreadPrimitive.ScrollToBottom>\n </div>\n </AuiIf>\n);\n\nexport interface ChatThreadShellProps {\n /**\n * Rendered as the first child of the panel — for absolutely-positioned\n * scrims that must cover the whole panel (AthenaChat's thread-loading\n * overlay). The shell does not force a positioning context; hosts include\n * `relative` in `panelClassName` when the scrim anchors to the panel.\n */\n overlay?: ReactNode;\n /**\n * Rendered above the viewport, inside the panel: header rows, slide-over\n * panels, and anything else the host docks at the top.\n */\n header?: ReactNode;\n /** Status/approval banners rendered between the header and the viewport. */\n banners?: ReactNode;\n /**\n * Nodes rendered inside the scroll viewport before the message column —\n * absolutely/sticky-positioned overlays (thread-switch skeletons,\n * scroll-to-top controls) and invisible observers (read receipts).\n */\n viewportOverlay?: ReactNode;\n /** Empty-thread state, rendered via ThreadPrimitive.Empty when provided. */\n welcome?: ReactNode;\n /**\n * Rendered inside the message column right above the messages — the\n * windowed wire's history edge (`StatewireHistoryEdge`): the \"N earlier\n * messages\" row that pages older history in and fetches cut tool outputs.\n */\n beforeMessages?: ReactNode;\n /** Message renderers for ThreadPrimitive.Messages. */\n components: ChatThreadMessageComponents;\n /**\n * Wraps the messages element — for hosts that provide message-scoped\n * context (e.g. activity-grouping providers). Must render its argument.\n */\n renderMessages?: (messages: ReactNode) => ReactNode;\n /**\n * Rendered between the viewport and the composer: connection banners,\n * queued-message trays.\n */\n belowViewport?: ReactNode;\n /** The composer dock (or a read-only notice replacing it). */\n composer?: ReactNode;\n /**\n * Replaces the docked-panel card chrome — for hosts that render a\n * full-page column (AthenaChat's `aui-*` surface) instead of the\n * side-panel/task-pane card.\n */\n panelClassName?: string;\n /**\n * Value of the `--thread-max-width` variable read by width-capped\n * message/welcome/footer columns. Panels fill their width (the default,\n * \"100%\"); full-page hosts cap the column (AthenaChat defaults to 44rem).\n */\n maxWidth?: string;\n /**\n * Anchors the latest turn to the top of the viewport instead of pinning\n * scroll to the bottom (AthenaChat). Omitted = the primitive's default.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Replaces the scroll-viewport chrome (padding, overflow tuning). */\n viewportClassName?: string;\n /**\n * Replaces the message-column chrome. Hosts whose welcome screen centers\n * vertically make this a flex column so the welcome node can grow.\n */\n contentClassName?: string;\n /**\n * Thread-level \"Thinking...\" indicator rendered after the messages. Hosts\n * whose message components render their own per-message indicators pass\n * null so the two never double up.\n */\n runningIndicator?: ReactNode;\n /**\n * Replaces the default centered scroll-to-bottom pill inside the sticky\n * viewport footer (AthenaChat floats a circular button above its composer).\n */\n scrollToBottom?: ReactNode;\n /**\n * Content docked inside the sticky viewport footer, after the\n * scroll-to-bottom control — for hosts whose banners + composer float over\n * the scrolling messages (AthenaChat) instead of sitting below the\n * viewport via `belowViewport`/`composer`.\n */\n viewportFooter?: ReactNode;\n /** Replaces the sticky viewport-footer chrome. */\n viewportFooterClassName?: string;\n /**\n * Marks the transcript read-only: mutating message actions (Edit,\n * Regenerate) hide while Copy stays available. For threads whose server\n * rejects dispatch (e.g. legacy pre-cutover conversations) — the runtime's\n * static capability flags cannot express a per-thread fence.\n */\n readOnly?: boolean;\n}\n\n/**\n * The shared thread layout: panel chrome, scroll viewport with welcome +\n * messages + running indicator, the sticky scroll-to-bottom control, and the\n * host-supplied composer dock.\n *\n * Hosts express their genuine divergences through the slots above; the\n * layout, scroll behaviour, and empty/running states stay identical across\n * surfaces so fixes land once.\n */\nexport function ChatThreadShell({\n overlay,\n header,\n banners,\n viewportOverlay,\n welcome,\n beforeMessages,\n components,\n renderMessages,\n belowViewport,\n composer,\n panelClassName,\n maxWidth = \"100%\",\n turnAnchor,\n viewportClassName,\n contentClassName,\n runningIndicator = <ThreadRunningIndicator />,\n scrollToBottom = <DefaultScrollToBottom />,\n viewportFooter,\n viewportFooterClassName,\n readOnly = false,\n}: ChatThreadShellProps) {\n const {\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent = UserEditComposer,\n } = components;\n // ThreadPrimitive.Messages resolves per-message renderers by component\n // identity, so keep the merged map referentially stable across renders.\n const messageComponents = useMemo(\n () => ({\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent,\n }),\n [UserMessage, AssistantMessage, UserEditComposerComponent],\n );\n const messages = <ThreadPrimitive.Messages components={messageComponents} />;\n return (\n <MessageActionsReadOnlyProvider readOnly={readOnly}>\n <ThreadPrimitive.Root\n className={panelClassName ?? THREAD_PANEL_CLASS}\n style={{ \"--thread-max-width\": maxWidth } as CSSProperties}\n >\n {overlay}\n {header}\n {banners}\n <ThreadPrimitive.Viewport\n turnAnchor={turnAnchor}\n className={viewportClassName ?? DEFAULT_VIEWPORT_CLASS}\n data-aui-thread-viewport=\"\"\n >\n {viewportOverlay}\n {/* No min-h-0 here: the column's automatic minimum height is what\n lets it extend past one screen, keeping the sticky footer's flow\n position after the full message list. Capping it detaches the\n footer (scroll pill, docked composers) as soon as the thread\n scrolls — proven in a live-browser probe of both structures. */}\n <div className=\"flex flex-1 flex-col items-center\">\n <div className={contentClassName ?? DEFAULT_CONTENT_CLASS}>\n {welcome != null ? (\n <ThreadPrimitive.Empty>{welcome}</ThreadPrimitive.Empty>\n ) : null}\n {beforeMessages}\n {renderMessages ? renderMessages(messages) : messages}\n {runningIndicator}\n </div>\n </div>\n <ThreadPrimitive.ViewportFooter\n className={viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS}\n >\n {scrollToBottom}\n {viewportFooter}\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n {belowViewport}\n {composer}\n </ThreadPrimitive.Root>\n </MessageActionsReadOnlyProvider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAsBA,MAAM,yBACJ;AACF,MAAM,wBAAwB;AAC9B,MAAM,gCAAgC;AAEtC,MAAM,wBAA4B,MAChC,oBAAC,OAAA,EAAM,WAAW,CAAC,UAAU,CAAC,MAAM,OAAO,SACzC,UAAA,oBAAC,OAAA,EAAI,WAAU,8BACb,UAAA;AAAA,EAAC,gBAAgB;AAAA,EAAhB;AAAA,IACC,cAAW;AAAA,IACX,OAAM;AAAA,IACN,WAAW;AAAA,IAEX,UAAA,oBAAC,iBAAA,EAAgB,WAAU,WAAA,CAAW;AAAA,EAAA;AACxC,EAAA,CACF,EAAA,CACF;AA4GK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,uCAAoB,wBAAA,EAAuB;AAAA,EAC3C,qCAAkB,uBAAA,EAAsB;AAAA,EACxC;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAyB;AACvB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,kBAAkB,4BAA4B;AAAA,EAAA,IAC5C;AAGJ,QAAM,oBAAoB;AAAA,IACxB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IAAA;AAAA,IAEpB,CAAC,aAAa,kBAAkB,yBAAyB;AAAA,EAAA;AAE3D,QAAM,WAAW,oBAAC,gBAAgB,UAAhB,EAAyB,YAAY,mBAAmB;AAC1E,SACE,oBAAC,kCAA+B,UAC9B,UAAA;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,WAAW,kBAAkB;AAAA,MAC7B,OAAO,EAAE,sBAAsB,SAAA;AAAA,MAE9B,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,QACA;AAAA,QACD;AAAA,UAAC,gBAAgB;AAAA,UAAhB;AAAA,YACC;AAAA,YACA,WAAW,qBAAqB;AAAA,YAChC,4BAAyB;AAAA,YAExB,UAAA;AAAA,cAAA;AAAA,cAMD,oBAAC,SAAI,WAAU,qCACb,+BAAC,OAAA,EAAI,WAAW,oBAAoB,uBACjC,UAAA;AAAA,gBAAA,WAAW,OACV,oBAAC,gBAAgB,OAAhB,EAAuB,mBAAQ,IAC9B;AAAA,gBACH;AAAA,gBACA,iBAAiB,eAAe,QAAQ,IAAI;AAAA,gBAC5C;AAAA,cAAA,EAAA,CACH,EAAA,CACF;AAAA,cACA;AAAA,gBAAC,gBAAgB;AAAA,gBAAhB;AAAA,kBACC,WAAW,2BAA2B;AAAA,kBAErC,UAAA;AAAA,oBAAA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH;AAAA,UAAA;AAAA,QAAA;AAAA,QAED;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"chat-thread-shell.js","sources":["../../../src/chat-ui/thread/chat-thread-shell.tsx"],"sourcesContent":["import { AuiIf, ThreadPrimitive } from \"@assistant-ui/react\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type { CSSProperties, FC, ReactNode } from \"react\";\nimport { useMemo } from \"react\";\nimport {\n THREAD_PANEL_CLASS,\n THREAD_SCROLL_TO_BOTTOM_CLASS,\n} from \"../messages/message-components\";\nimport { MessageActionsReadOnlyProvider } from \"../messages/message-actions-config\";\nimport { UserEditComposer } from \"../messages/user-edit-composer\";\nimport { ThreadRunningIndicator } from \"../messages/running-indicator\";\n\nexport interface ChatThreadMessageComponents {\n UserMessage: FC;\n AssistantMessage: FC;\n /**\n * Rendered in place of a user message while it is being edited (the action\n * bar's Edit control). Defaults to the shared UserEditComposer.\n */\n UserEditComposer?: FC;\n}\n\nconst DEFAULT_VIEWPORT_CLASS =\n \"relative flex flex-1 flex-col overflow-y-auto scroll-smooth\";\nconst DEFAULT_CONTENT_CLASS = \"w-full flex-1 px-3 pt-3\";\nconst DEFAULT_VIEWPORT_FOOTER_CLASS = \"sticky bottom-0\";\n\nconst DefaultScrollToBottom: FC = () => (\n <AuiIf condition={(state) => !state.thread.isEmpty}>\n <div className=\"flex justify-center pb-0.5\">\n <ThreadPrimitive.ScrollToBottom\n aria-label=\"Scroll to bottom\"\n title=\"Scroll to bottom\"\n className={THREAD_SCROLL_TO_BOTTOM_CLASS}\n >\n <ChevronDownIcon className=\"size-3.5\" />\n </ThreadPrimitive.ScrollToBottom>\n </div>\n </AuiIf>\n);\n\nexport interface ChatThreadShellProps {\n /**\n * Rendered as the first child of the panel — for absolutely-positioned\n * scrims that must cover the whole panel (AthenaChat's thread-loading\n * overlay). The shell does not force a positioning context; hosts include\n * `relative` in `panelClassName` when the scrim anchors to the panel.\n */\n overlay?: ReactNode;\n /**\n * Rendered above the viewport, inside the panel: header rows, slide-over\n * panels, and anything else the host docks at the top.\n */\n header?: ReactNode;\n /** Status/approval banners rendered between the header and the viewport. */\n banners?: ReactNode;\n /**\n * Nodes rendered inside the scroll viewport before the message column —\n * absolutely/sticky-positioned overlays (thread-switch skeletons,\n * scroll-to-top controls) and invisible observers (read receipts).\n */\n viewportOverlay?: ReactNode;\n /** Empty-thread state, rendered via ThreadPrimitive.Empty when provided. */\n welcome?: ReactNode;\n /**\n * Rendered inside the message column right above the messages — the\n * windowed wire's history edge (`StatewireHistoryEdge`): the \"N earlier\n * messages\" row that pages older history in and fetches cut tool outputs.\n */\n beforeMessages?: ReactNode;\n /** Message renderers for ThreadPrimitive.Messages. */\n components: ChatThreadMessageComponents;\n /**\n * Wraps the messages element — for hosts that provide message-scoped\n * context (e.g. activity-grouping providers). Must render its argument.\n */\n renderMessages?: (messages: ReactNode) => ReactNode;\n /**\n * Rendered between the viewport and the composer: connection banners,\n * queued-message trays.\n */\n belowViewport?: ReactNode;\n /** The composer dock (or a read-only notice replacing it). */\n composer?: ReactNode;\n /**\n * Replaces the docked-panel card chrome — for hosts that render a\n * full-page column (AthenaChat's `aui-*` surface) instead of the\n * side-panel/task-pane card.\n */\n panelClassName?: string;\n /**\n * Value of the `--thread-max-width` variable read by width-capped\n * message/welcome/footer columns. Panels fill their width (the default,\n * \"100%\"); full-page hosts cap the column (AthenaChat defaults to 44rem).\n */\n maxWidth?: string;\n /**\n * Anchors the latest turn to the top of the viewport instead of pinning\n * scroll to the bottom (AthenaChat). Omitted = the primitive's default.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Replaces the scroll-viewport chrome (padding, overflow tuning). */\n viewportClassName?: string;\n /**\n * Replaces the message-column chrome. Hosts whose welcome screen centers\n * vertically make this a flex column so the welcome node can grow.\n */\n contentClassName?: string;\n /**\n * Thread-level \"Thinking...\" indicator rendered after the messages. Hosts\n * whose message components render their own per-message indicators pass\n * null so the two never double up.\n */\n runningIndicator?: ReactNode;\n /**\n * Replaces the default centered scroll-to-bottom pill inside the sticky\n * viewport footer (AthenaChat floats a circular button above its composer).\n */\n scrollToBottom?: ReactNode;\n /**\n * Content docked inside the sticky viewport footer, after the\n * scroll-to-bottom control — for hosts whose banners + composer float over\n * the scrolling messages (AthenaChat) instead of sitting below the\n * viewport via `belowViewport`/`composer`.\n */\n viewportFooter?: ReactNode;\n /** Replaces the sticky viewport-footer chrome. */\n viewportFooterClassName?: string;\n /**\n * Marks the transcript read-only: mutating message actions (Edit,\n * Regenerate) hide while Copy stays available. For threads whose server\n * rejects dispatch (e.g. legacy pre-cutover conversations) — the runtime's\n * static capability flags cannot express a per-thread fence.\n */\n readOnly?: boolean;\n}\n\n/**\n * The shared thread layout: panel chrome, scroll viewport with welcome +\n * messages + running indicator, the sticky scroll-to-bottom control, and the\n * host-supplied composer dock.\n *\n * Hosts express their genuine divergences through the slots above; the\n * layout, scroll behaviour, and empty/running states stay identical across\n * surfaces so fixes land once.\n */\nexport function ChatThreadShell({\n overlay,\n header,\n banners,\n viewportOverlay,\n welcome,\n beforeMessages,\n components,\n renderMessages,\n belowViewport,\n composer,\n panelClassName,\n maxWidth = \"100%\",\n turnAnchor,\n viewportClassName,\n contentClassName,\n runningIndicator = <ThreadRunningIndicator />,\n scrollToBottom = <DefaultScrollToBottom />,\n viewportFooter,\n viewportFooterClassName,\n readOnly = false,\n}: ChatThreadShellProps) {\n const {\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent = UserEditComposer,\n } = components;\n // ThreadPrimitive.Messages resolves per-message renderers by component\n // identity, so keep the merged map referentially stable across renders.\n const messageComponents = useMemo(\n () => ({\n UserMessage,\n AssistantMessage,\n UserEditComposer: UserEditComposerComponent,\n }),\n [UserMessage, AssistantMessage, UserEditComposerComponent],\n );\n const messages = <ThreadPrimitive.Messages components={messageComponents} />;\n return (\n <MessageActionsReadOnlyProvider readOnly={readOnly}>\n <ThreadPrimitive.Root\n className={panelClassName ?? THREAD_PANEL_CLASS}\n style={{ \"--thread-max-width\": maxWidth } as CSSProperties}\n >\n {overlay}\n {header}\n {banners}\n <ThreadPrimitive.Viewport\n turnAnchor={turnAnchor}\n className={viewportClassName ?? DEFAULT_VIEWPORT_CLASS}\n data-aui-thread-viewport=\"\"\n >\n {viewportOverlay}\n {/* No min-h-0 here: the column's automatic minimum height is what\n lets it extend past one screen, keeping the sticky footer's flow\n position after the full message list. Capping it detaches the\n footer (scroll pill, docked composers) as soon as the thread\n scrolls — proven in a live-browser probe of both structures. */}\n <div className=\"flex flex-1 flex-col items-center\">\n <div className={contentClassName ?? DEFAULT_CONTENT_CLASS}>\n {welcome != null ? (\n <ThreadPrimitive.Empty>{welcome}</ThreadPrimitive.Empty>\n ) : null}\n {beforeMessages}\n {renderMessages ? renderMessages(messages) : messages}\n {runningIndicator}\n </div>\n </div>\n <ThreadPrimitive.ViewportFooter\n className={viewportFooterClassName ?? DEFAULT_VIEWPORT_FOOTER_CLASS}\n >\n {scrollToBottom}\n {viewportFooter}\n </ThreadPrimitive.ViewportFooter>\n </ThreadPrimitive.Viewport>\n {belowViewport}\n {composer}\n </ThreadPrimitive.Root>\n </MessageActionsReadOnlyProvider>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAsBA,MAAM,yBACJ;AACF,MAAM,wBAAwB;AAC9B,MAAM,gCAAgC;AAEtC,MAAM,wBAA4B,MAChC,oBAAC,OAAA,EAAM,WAAW,CAAC,UAAU,CAAC,MAAM,OAAO,SACzC,UAAA,oBAAC,OAAA,EAAI,WAAU,8BACb,UAAA;AAAA,EAAC,gBAAgB;AAAA,EAAhB;AAAA,IACC,cAAW;AAAA,IACX,OAAM;AAAA,IACN,WAAW;AAAA,IAEX,UAAA,oBAAC,iBAAA,EAAgB,WAAU,WAAA,CAAW;AAAA,EAAA;AACxC,EAAA,CACF,EAAA,CACF;AA4GK,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,uCAAoB,wBAAA,EAAuB;AAAA,EAC3C,qCAAkB,uBAAA,EAAsB;AAAA,EACxC;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAyB;AACvB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,kBAAkB,4BAA4B;AAAA,EAAA,IAC5C;AAGJ,QAAM,oBAAoB;AAAA,IACxB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,kBAAkB;AAAA,IAAA;AAAA,IAEpB,CAAC,aAAa,kBAAkB,yBAAyB;AAAA,EAAA;AAE3D,QAAM,WAAW,oBAAC,gBAAgB,UAAhB,EAAyB,YAAY,mBAAmB;AAC1E,SACE,oBAAC,kCAA+B,UAC9B,UAAA;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,WAAW,kBAAkB;AAAA,MAC7B,OAAO,EAAE,sBAAsB,SAAA;AAAA,MAE9B,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,QACA;AAAA,QACD;AAAA,UAAC,gBAAgB;AAAA,UAAhB;AAAA,YACC;AAAA,YACA,WAAW,qBAAqB;AAAA,YAChC,4BAAyB;AAAA,YAExB,UAAA;AAAA,cAAA;AAAA,cAMD,oBAAC,SAAI,WAAU,qCACb,+BAAC,OAAA,EAAI,WAAW,oBAAoB,uBACjC,UAAA;AAAA,gBAAA,WAAW,OACV,oBAAC,gBAAgB,OAAhB,EAAuB,mBAAQ,IAC9B;AAAA,gBACH;AAAA,gBACA,iBAAiB,eAAe,QAAQ,IAAI;AAAA,gBAC5C;AAAA,cAAA,EAAA,CACH,EAAA,CACF;AAAA,cACA;AAAA,gBAAC,gBAAgB;AAAA,gBAAhB;AAAA,kBACC,WAAW,2BAA2B;AAAA,kBAErC,UAAA;AAAA,oBAAA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH;AAAA,UAAA;AAAA,QAAA;AAAA,QAED;AAAA,QACA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ;"}
|
|
@@ -11,7 +11,7 @@ interface AttachmentContextValue {
|
|
|
11
11
|
}
|
|
12
12
|
export declare function AttachmentProvider({ children }: {
|
|
13
13
|
children: ReactNode;
|
|
14
|
-
}): import("react
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
15
|
export declare function useAttachments(): AttachmentContextValue;
|
|
16
16
|
/**
|
|
17
17
|
* Build the markdown references for the current attachments.
|
|
@@ -18,7 +18,7 @@ interface QuoteContextValue {
|
|
|
18
18
|
}
|
|
19
19
|
export declare function QuoteProvider({ children }: {
|
|
20
20
|
children: ReactNode;
|
|
21
|
-
}): import("react
|
|
21
|
+
}): import("react").JSX.Element;
|
|
22
22
|
export declare function useQuote(): QuoteContextValue;
|
|
23
23
|
/**
|
|
24
24
|
* Listens for:
|
|
@@ -24,6 +24,13 @@ const BENIGN_MESSAGE_PATTERNS = [
|
|
|
24
24
|
// Drift-proof ResizeObserver loop diagnostics across engines.
|
|
25
25
|
/^ResizeObserver loop /
|
|
26
26
|
];
|
|
27
|
+
const BENIGN_TYPED_MESSAGE_PATTERNS = [
|
|
28
|
+
// CefSharp host-bridge rejection from Outlook Safe Links / Defender link scanners.
|
|
29
|
+
{
|
|
30
|
+
type: "UnhandledRejection",
|
|
31
|
+
pattern: /^Non-Error promise rejection captured with value: Object Not Found Matching Id:\d+, MethodName:update, ParamCount:4$/
|
|
32
|
+
}
|
|
33
|
+
];
|
|
27
34
|
const FORMULA_ERROR_CODE_TYPE_PATTERN = /^#[A-Z0-9/_]{1,14}[!?]?$/;
|
|
28
35
|
function isBenignBrowserExceptionEntry(exception) {
|
|
29
36
|
var _a, _b;
|
|
@@ -33,6 +40,11 @@ function isBenignBrowserExceptionEntry(exception) {
|
|
|
33
40
|
if (type !== void 0 && FORMULA_ERROR_CODE_TYPE_PATTERN.test(type)) return true;
|
|
34
41
|
if (type === void 0 || value === void 0) return false;
|
|
35
42
|
if (BENIGN_BROWSER_EXCEPTION_SIGNATURES.has(`${type}: ${value}`)) return true;
|
|
43
|
+
if (BENIGN_TYPED_MESSAGE_PATTERNS.some(
|
|
44
|
+
(entry) => entry.type === type && entry.pattern.test(value)
|
|
45
|
+
)) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
36
48
|
return BENIGN_MESSAGE_PATTERNS.some((pattern) => pattern.test(value));
|
|
37
49
|
}
|
|
38
50
|
function isBenignBrowserException(captureResult) {
|