@ai-matrx/rich-content 0.2.10 → 0.2.16

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.
Files changed (114) hide show
  1. package/dist/copy/copy-commands.d.ts +42 -0
  2. package/dist/copy/copy-commands.js +119 -0
  3. package/dist/copy/markdown-copy-html.d.ts +3 -0
  4. package/dist/copy/markdown-copy-html.js +8 -0
  5. package/dist/copy/markdown-readable-text.d.ts +4 -0
  6. package/dist/copy/markdown-readable-text.js +62 -0
  7. package/dist/display/chat-markdown/block-registry/BlockComponentRegistry.js +2 -0
  8. package/dist/display/chat-markdown/block-registry/block-dispatch.js +2 -0
  9. package/dist/host/app-bindings.d.ts +30 -0
  10. package/dist/host/app-bindings.js +38 -0
  11. package/dist/host/feedback-subject.d.ts +16 -0
  12. package/dist/host/feedback-subject.js +0 -0
  13. package/dist/host/manual-copy.d.ts +7 -0
  14. package/dist/host/manual-copy.js +11 -0
  15. package/dist/host/registry.d.ts +2 -0
  16. package/dist/host/registry.js +10 -0
  17. package/dist/host/session-knob.d.ts +5 -0
  18. package/dist/host/session-knob.js +7 -0
  19. package/dist/host/types.d.ts +24 -0
  20. package/dist/rich-document/RegistryContextMenu.d.ts +29 -0
  21. package/dist/rich-document/RegistryContextMenu.js +40 -0
  22. package/dist/rich-document/RichDocument.d.ts +78 -0
  23. package/dist/rich-document/RichDocument.js +218 -0
  24. package/dist/rich-document/RichDocumentActionProvider.d.ts +18 -0
  25. package/dist/rich-document/RichDocumentActionProvider.js +18 -0
  26. package/dist/rich-document/RichDocumentActionSurface.d.ts +11 -0
  27. package/dist/rich-document/RichDocumentActionSurface.js +59 -0
  28. package/dist/rich-document/RichDocumentActions.d.ts +12 -0
  29. package/dist/rich-document/RichDocumentActions.js +29 -0
  30. package/dist/rich-document/actions/hostActions.d.ts +5 -0
  31. package/dist/rich-document/actions/hostActions.js +31 -0
  32. package/dist/rich-document/actions/labels.d.ts +9 -0
  33. package/dist/rich-document/actions/labels.js +8 -0
  34. package/dist/rich-document/actions/markdownTable.d.ts +9 -0
  35. package/dist/rich-document/actions/markdownTable.js +39 -0
  36. package/dist/rich-document/actions/provider.d.ts +58 -0
  37. package/dist/rich-document/actions/provider.js +245 -0
  38. package/dist/rich-document/actions/resumePendingAuthAction.d.ts +3 -0
  39. package/dist/rich-document/actions/resumePendingAuthAction.js +31 -0
  40. package/dist/rich-document/actions/sources/index.d.ts +9 -0
  41. package/dist/rich-document/actions/sources/index.js +22 -0
  42. package/dist/rich-document/actions/sources/raw.d.ts +4 -0
  43. package/dist/rich-document/actions/sources/raw.js +35 -0
  44. package/dist/rich-document/actions/useRichDocumentProvider.d.ts +1 -0
  45. package/dist/rich-document/actions/useRichDocumentProvider.js +13 -0
  46. package/dist/rich-document/host-types.d.ts +51 -0
  47. package/dist/rich-document/host-types.js +0 -0
  48. package/dist/rich-document/registrations.d.ts +1 -0
  49. package/dist/rich-document/registrations.js +13 -0
  50. package/dist/rich-document/review/applyTargets.d.ts +16 -0
  51. package/dist/rich-document/review/applyTargets.js +32 -0
  52. package/dist/rich-document/review/proposedEdit.d.ts +22 -0
  53. package/dist/rich-document/review/proposedEdit.js +48 -0
  54. package/dist/rich-document/review/protectedSpans.d.ts +14 -0
  55. package/dist/rich-document/review/protectedSpans.js +61 -0
  56. package/dist/rich-document/runtime/actionSurfacesStore.d.ts +30 -0
  57. package/dist/rich-document/runtime/actionSurfacesStore.js +79 -0
  58. package/dist/rich-document/runtime/contextMenuFor.d.ts +6 -0
  59. package/dist/rich-document/runtime/contextMenuFor.js +7 -0
  60. package/dist/rich-document/runtime/providerBridge.d.ts +20 -0
  61. package/dist/rich-document/runtime/providerBridge.js +23 -0
  62. package/dist/rich-document/runtime/useActionSurfaceProvider.d.ts +33 -0
  63. package/dist/rich-document/runtime/useActionSurfaceProvider.js +214 -0
  64. package/dist/rich-document/search/ContentFindControl.d.ts +8 -0
  65. package/dist/rich-document/search/ContentFindControl.js +46 -0
  66. package/dist/rich-document/search/RenderedFindBar.d.ts +8 -0
  67. package/dist/rich-document/search/RenderedFindBar.js +110 -0
  68. package/dist/rich-document/search/renderedFind.d.ts +1 -0
  69. package/dist/rich-document/search/renderedFind.js +1 -0
  70. package/dist/rich-document/types.d.ts +384 -0
  71. package/dist/rich-document/types.js +0 -0
  72. package/dist/rich-document/variants/ActionBar.d.ts +17 -0
  73. package/dist/rich-document/variants/ActionBar.js +48 -0
  74. package/dist/rich-document/variants/MenuVariant.d.ts +15 -0
  75. package/dist/rich-document/variants/MenuVariant.js +17 -0
  76. package/dist/rich-document/variants/MiniActionBar.d.ts +5 -0
  77. package/dist/rich-document/variants/MiniActionBar.js +11 -0
  78. package/dist/rich-document/variants/RegistryActionList.d.ts +17 -0
  79. package/dist/rich-document/variants/RegistryActionList.js +94 -0
  80. package/dist/rich-document/variants/RegistryActionMenu.d.ts +24 -0
  81. package/dist/rich-document/variants/RegistryActionMenu.js +74 -0
  82. package/dist/rich-document/variants/shared/AlchemyDocumentMenu.d.ts +7 -0
  83. package/dist/rich-document/variants/shared/AlchemyDocumentMenu.js +83 -0
  84. package/dist/rich-document/variants/shared/OpenOneMenuButton.d.ts +9 -0
  85. package/dist/rich-document/variants/shared/OpenOneMenuButton.js +70 -0
  86. package/dist/rich-document/variants/shared/StandaloneOneMenu.d.ts +8 -0
  87. package/dist/rich-document/variants/shared/StandaloneOneMenu.js +32 -0
  88. package/dist/rich-document/variants/shared/categories.d.ts +4 -0
  89. package/dist/rich-document/variants/shared/categories.js +31 -0
  90. package/dist/rich-document/variants/shared/iconMap.d.ts +2 -0
  91. package/dist/rich-document/variants/shared/iconMap.js +73 -0
  92. package/dist/rich-document/variants/shared/menuStructure.d.ts +81 -0
  93. package/dist/rich-document/variants/shared/menuStructure.js +271 -0
  94. package/dist/rich-document/variants/shared/runAction.d.ts +17 -0
  95. package/dist/rich-document/variants/shared/runAction.js +24 -0
  96. package/dist/selection-toolbar/SelectionToolbarFrame.d.ts +64 -0
  97. package/dist/selection-toolbar/SelectionToolbarFrame.js +191 -0
  98. package/dist/selection-toolbar/common-actions.d.ts +2 -0
  99. package/dist/selection-toolbar/common-actions.js +103 -0
  100. package/dist/selection-toolbar/selection-actions.d.ts +126 -0
  101. package/dist/selection-toolbar/selection-actions.js +240 -0
  102. package/dist/selection-toolbar/selection-copy.d.ts +19 -0
  103. package/dist/selection-toolbar/selection-copy.js +98 -0
  104. package/dist/selection-toolbar/selection-shape.d.ts +1 -0
  105. package/dist/selection-toolbar/selection-shape.js +15 -0
  106. package/dist/selection-toolbar/selection-zones.d.ts +90 -0
  107. package/dist/selection-toolbar/selection-zones.js +85 -0
  108. package/dist/selection-toolbar/textarea-caret.d.ts +8 -0
  109. package/dist/selection-toolbar/textarea-caret.js +69 -0
  110. package/dist/utils/alchemy-icon-keys.d.ts +18 -0
  111. package/dist/utils/alchemy-icon-keys.js +29 -0
  112. package/dist/utils/rendered-find.d.ts +9 -0
  113. package/dist/utils/rendered-find.js +68 -0
  114. package/package.json +23 -7
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { AdvancedMenu } from "../../host/app-bindings.js";
5
+ import { useActionSurfaceProvider } from "../runtime/useActionSurfaceProvider.js";
6
+ import { resumePendingAuthAction } from "../actions/resumePendingAuthAction.js";
7
+ import { buildMenuTree, registryMenuActions } from "./shared/menuStructure.js";
8
+ import { resolveActionDisplay, runAction } from "./shared/runAction.js";
9
+ const menuActions = registryMenuActions;
10
+ function toAdvancedMenuItems(actions, ctx, getCtx) {
11
+ const toItem = (action) => {
12
+ const display = resolveActionDisplay(action, ctx);
13
+ return {
14
+ key: action.id,
15
+ icon: display.Icon,
16
+ iconColor: display.iconColor,
17
+ label: display.label,
18
+ description: display.disabledReason,
19
+ disabled: display.isDisabled,
20
+ // Handlers own their toasts (success, failure, loading) — the menu adds
21
+ // none of its own, so a toast never doubles.
22
+ showToast: false,
23
+ action: () => runAction(action, getCtx)
24
+ };
25
+ };
26
+ const tree = buildMenuTree(menuActions(actions));
27
+ return [
28
+ ...tree.topLevel.map(toItem),
29
+ ...tree.submenus.map((submenu) => ({
30
+ key: `submenu-${submenu.label}`,
31
+ icon: submenu.icon ?? submenu.actions[0].icon,
32
+ label: submenu.label,
33
+ action: () => {
34
+ },
35
+ showToast: false,
36
+ children: submenu.actions.map(toItem)
37
+ })),
38
+ ...tree.extras.map(toItem)
39
+ ];
40
+ }
41
+ function RegistryActionMenu(props) {
42
+ const { isOpen, onClose, content, source, actions, anchorElement, title } = props;
43
+ const { ctx, getCtx, resolvedActions } = useActionSurfaceProvider({
44
+ content,
45
+ source,
46
+ actions,
47
+ actionsVariant: "none"
48
+ });
49
+ const getMenuCtx = () => ({
50
+ ...getCtx(),
51
+ onClose
52
+ });
53
+ React.useEffect(() => {
54
+ resumePendingAuthAction(getMenuCtx());
55
+ });
56
+ return /* @__PURE__ */ jsx(
57
+ AdvancedMenu,
58
+ {
59
+ isOpen,
60
+ onClose,
61
+ items: toAdvancedMenuItems(resolvedActions, ctx, getMenuCtx),
62
+ title,
63
+ position: "bottom-left",
64
+ anchorElement
65
+ }
66
+ );
67
+ }
68
+ var RegistryActionMenu_default = RegistryActionMenu;
69
+ export {
70
+ RegistryActionMenu,
71
+ RegistryActionMenu_default as default,
72
+ menuActions,
73
+ toAdvancedMenuItems
74
+ };
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ import type { RichDocumentActionContext } from "../../types.js";
3
+ export declare function AlchemyDocumentMenu({ getCtx, sourceId, size, }: {
4
+ getCtx: () => RichDocumentActionContext;
5
+ sourceId: string;
6
+ size?: "sm" | "xs";
7
+ }): React.JSX.Element;
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useAlchemyDisclosure } from "../../../host/app-bindings.js";
4
+ import * as React from "react";
5
+ import { ContentTransferMenu } from "@ai-matrx/alchemy/react/workspace";
6
+ import { directSource } from "@ai-matrx/alchemy/operate";
7
+ import { removeThinkingContent } from "@ai-matrx/print/markdown";
8
+ function AlchemyDocumentMenu({
9
+ getCtx,
10
+ sourceId,
11
+ size = "sm"
12
+ }) {
13
+ useAlchemyDisclosure();
14
+ const [hasThinking, setHasThinking] = React.useState(false);
15
+ const source = {
16
+ id: sourceId,
17
+ label: "Document",
18
+ // getCtx reads refs and is legal only when Alchemy starts capture.
19
+ capture: async ({ signal }) => {
20
+ signal.throwIfAborted();
21
+ const ctx = getCtx();
22
+ const capturedSourceId = ctx.instanceKey("alchemy");
23
+ if (capturedSourceId !== sourceId)
24
+ throw new Error(
25
+ "The document changed. Reopen Alchemy Menu for the current document."
26
+ );
27
+ const text = removeThinkingContent(ctx.content);
28
+ setHasThinking(text !== ctx.content);
29
+ return directSource(
30
+ { kind: "markdown", text },
31
+ {
32
+ id: capturedSourceId,
33
+ sourceId: capturedSourceId,
34
+ revision: ctx.content,
35
+ label: "Document"
36
+ }
37
+ );
38
+ }
39
+ };
40
+ const includingThinkingSource = {
41
+ id: `${sourceId}:including-thinking`,
42
+ label: "Document",
43
+ capture: async ({ signal }) => {
44
+ signal.throwIfAborted();
45
+ const ctx = getCtx();
46
+ const capturedSourceId = ctx.instanceKey("alchemy");
47
+ if (capturedSourceId !== sourceId)
48
+ throw new Error(
49
+ "The document changed. Reopen Alchemy Menu for the current document."
50
+ );
51
+ return directSource(
52
+ { kind: "markdown", text: ctx.content },
53
+ {
54
+ id: `${capturedSourceId}:including-thinking`,
55
+ sourceId: capturedSourceId,
56
+ revision: ctx.content,
57
+ label: "Document"
58
+ }
59
+ );
60
+ }
61
+ };
62
+ return /* @__PURE__ */ jsx(
63
+ ContentTransferMenu,
64
+ {
65
+ source,
66
+ label: "Document",
67
+ className: size === "xs" ? "matrx-alchemy-xs" : void 0,
68
+ variants: hasThinking ? [
69
+ {
70
+ id: "include-thinking",
71
+ label: "Including thinking",
72
+ copyLabel: "Copy including thinking",
73
+ hint: "Includes the original reasoning content",
74
+ source: includingThinkingSource
75
+ }
76
+ ] : []
77
+ },
78
+ sourceId
79
+ );
80
+ }
81
+ export {
82
+ AlchemyDocumentMenu
83
+ };
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ import type { ContentSource } from "../../types.js";
3
+ /** True when an ancestor right-click menu already carries this content. */
4
+ export declare function useOneMenuFor(source: ContentSource): boolean;
5
+ export declare function OpenOneMenuButton({ source, className, ariaLabel, }: {
6
+ source: ContentSource;
7
+ className?: string;
8
+ ariaLabel?: string;
9
+ }): React.ReactElement;
@@ -0,0 +1,70 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { MoreHorizontal } from "lucide-react";
5
+ import { Button } from "@ai-matrx/design-system";
6
+ import { cn } from "@ai-matrx/design-system";
7
+ import {
8
+ contentSourceKey,
9
+ sameContentSource,
10
+ useRegistryMenuSource
11
+ } from "../../../host/app-bindings.js";
12
+ import { openContextMenuForElement } from "../../../host/app-bindings.js";
13
+ function contentTriggerFor(button, source) {
14
+ const key = contentSourceKey(source);
15
+ const carries = (el) => el.getAttribute("data-content-source") === key;
16
+ const selector = '[data-alchemy-trigger="context"][data-content-source]';
17
+ for (let node = button; node; node = node.parentElement) {
18
+ if (node.matches(selector) && carries(node)) return node;
19
+ const hit = [...node.querySelectorAll(selector)].find(carries);
20
+ if (hit) return hit;
21
+ }
22
+ return button;
23
+ }
24
+ function useOneMenuFor(source) {
25
+ return sameContentSource(useRegistryMenuSource(), source);
26
+ }
27
+ function OpenOneMenuButton({
28
+ source,
29
+ className,
30
+ ariaLabel = "More actions"
31
+ }) {
32
+ const buttonRef = React.useRef(null);
33
+ return /* @__PURE__ */ jsx(
34
+ Button,
35
+ {
36
+ ref: buttonRef,
37
+ variant: "ghost",
38
+ size: "icon",
39
+ className: cn("h-8 w-8 p-0 pointer-coarse:h-11 pointer-coarse:w-11", className),
40
+ "aria-label": ariaLabel,
41
+ "aria-haspopup": "menu",
42
+ onClick: () => {
43
+ const button = buttonRef.current;
44
+ if (!button) return;
45
+ const trigger = contentTriggerFor(button, source);
46
+ if (trigger === button) {
47
+ openContextMenuForElement(button);
48
+ return;
49
+ }
50
+ const rect = button.getBoundingClientRect();
51
+ trigger.dispatchEvent(
52
+ new MouseEvent("contextmenu", {
53
+ bubbles: true,
54
+ cancelable: true,
55
+ view: window,
56
+ button: 2,
57
+ buttons: 2,
58
+ clientX: rect.left + rect.width / 2,
59
+ clientY: rect.bottom
60
+ })
61
+ );
62
+ },
63
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" })
64
+ }
65
+ );
66
+ }
67
+ export {
68
+ OpenOneMenuButton,
69
+ useOneMenuFor
70
+ };
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ import type { ClickTarget } from "@ai-matrx/alchemy/actions";
3
+ import type { RichDocumentActionContext } from "../../types.js";
4
+ export declare function StandaloneOneMenu({ getCtx, target, className, }: {
5
+ getCtx: () => RichDocumentActionContext;
6
+ target: ClickTarget;
7
+ className?: string;
8
+ }): React.ReactElement;
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { RegistryContextMenu } from "../../RegistryContextMenu.js";
4
+ import { OpenOneMenuButton } from "./OpenOneMenuButton.js";
5
+ function StandaloneOneMenu({
6
+ getCtx,
7
+ target,
8
+ className
9
+ }) {
10
+ const ctx = getCtx();
11
+ const host = target.host;
12
+ return /* @__PURE__ */ jsx(
13
+ RegistryContextMenu,
14
+ {
15
+ content: ctx.content,
16
+ source: ctx.source,
17
+ actions: {
18
+ exclude: [...target.excludedActionIds],
19
+ extra: [...host?.extra ?? []],
20
+ ...ctx.callbacks ? { callbacks: ctx.callbacks } : {},
21
+ ...ctx.extensions ? { extensions: ctx.extensions } : {},
22
+ metadata: ctx.metadata,
23
+ isCreator: ctx.isCreator,
24
+ surfaceKey: ctx.surfaceKey
25
+ },
26
+ children: /* @__PURE__ */ jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsx(OpenOneMenuButton, { source: ctx.source, className }) })
27
+ }
28
+ );
29
+ }
30
+ export {
31
+ StandaloneOneMenu
32
+ };
@@ -0,0 +1,4 @@
1
+ import type { ActionCategory } from "../../types.js";
2
+ export declare function getCategoryLabel(category: ActionCategory): string;
3
+ export declare function getCategoryWeight(category: ActionCategory): number;
4
+ export declare function sortCategoriesInDisplayOrder(categories: ActionCategory[]): ActionCategory[];
@@ -0,0 +1,31 @@
1
+ const CATEGORY_META = {
2
+ edit: { label: "Edit", weight: 0 },
3
+ creator: { label: "Creator", weight: 1 },
4
+ copy: { label: "Copy", weight: 2 },
5
+ export: { label: "Export", weight: 3 },
6
+ save: { label: "Actions", weight: 4 },
7
+ share: { label: "Share", weight: 5 },
8
+ feedback: { label: "Feedback", weight: 6 },
9
+ listen: { label: "Listen", weight: 6.2 },
10
+ study: { label: "Study", weight: 6.4 },
11
+ ask: { label: "Ask in chat", weight: 6.6 },
12
+ ai: { label: "AI", weight: -1 },
13
+ admin: { label: "Server API (test)", weight: 7 },
14
+ app: { label: "App", weight: 8 }
15
+ };
16
+ function getCategoryLabel(category) {
17
+ return CATEGORY_META[category]?.label ?? category;
18
+ }
19
+ function getCategoryWeight(category) {
20
+ return CATEGORY_META[category]?.weight ?? 99;
21
+ }
22
+ function sortCategoriesInDisplayOrder(categories) {
23
+ return [...categories].sort(
24
+ (a, b) => getCategoryWeight(a) - getCategoryWeight(b)
25
+ );
26
+ }
27
+ export {
28
+ getCategoryLabel,
29
+ getCategoryWeight,
30
+ sortCategoriesInDisplayOrder
31
+ };
@@ -0,0 +1,2 @@
1
+ import { type LucideIcon } from "lucide-react";
2
+ export declare function resolveIcon(iconName: string): LucideIcon;
@@ -0,0 +1,73 @@
1
+ import {
2
+ Copy,
3
+ FileText,
4
+ FileType,
5
+ Brain,
6
+ Save,
7
+ FileCode,
8
+ CheckSquare,
9
+ Eye,
10
+ Globe,
11
+ Mail,
12
+ Printer,
13
+ ScanLine,
14
+ Edit,
15
+ History,
16
+ GitBranch,
17
+ Trash2,
18
+ BarChart3,
19
+ Activity,
20
+ ThumbsUp,
21
+ ThumbsDown,
22
+ Maximize2,
23
+ Briefcase,
24
+ BookText,
25
+ Bug,
26
+ Megaphone,
27
+ Settings,
28
+ GitFork,
29
+ EyeOff,
30
+ ListFilter,
31
+ Scissors,
32
+ Undo2,
33
+ Circle
34
+ } from "lucide-react";
35
+ const ICON_MAP = {
36
+ Copy,
37
+ FileText,
38
+ FileType,
39
+ Brain,
40
+ Save,
41
+ FileCode,
42
+ CheckSquare,
43
+ Eye,
44
+ Globe,
45
+ Mail,
46
+ Printer,
47
+ ScanLine,
48
+ Edit,
49
+ History,
50
+ GitBranch,
51
+ Trash2,
52
+ BarChart3,
53
+ Activity,
54
+ ThumbsUp,
55
+ ThumbsDown,
56
+ Maximize2,
57
+ Briefcase,
58
+ BookText,
59
+ Bug,
60
+ Megaphone,
61
+ Settings,
62
+ GitFork,
63
+ EyeOff,
64
+ ListFilter,
65
+ Scissors,
66
+ Undo2
67
+ };
68
+ function resolveIcon(iconName) {
69
+ return ICON_MAP[iconName] ?? Circle;
70
+ }
71
+ export {
72
+ resolveIcon
73
+ };
@@ -0,0 +1,81 @@
1
+ import { type LucideIcon } from "lucide-react";
2
+ import type { RichDocumentAction } from "../../types.js";
3
+ export interface MenuSection {
4
+ /** Submenu label, or null for the promoted top-level group. */
5
+ submenu: string | null;
6
+ /** Icon for the submenu trigger (ignored for the top-level group). */
7
+ icon?: LucideIcon;
8
+ /** Action IDs in this section, in intended display order. */
9
+ actionIds: string[];
10
+ /**
11
+ * The category every row of this section takes in the Alchemy layout, which
12
+ * places a section in a group by its rows' category. Set it on a section
13
+ * whose rows mix categories, so the section sits in ONE predictable place.
14
+ */
15
+ layoutCategory?: RichDocumentAction["category"];
16
+ /**
17
+ * In the one menu engine (⋯, right-click, sheet, palette) this section's rows
18
+ * show INLINE, under no heading — the group has no approved name (ALC-15 chair
19
+ * ruling: a heading is a name the classic menus used; otherwise inline). The
20
+ * tree hosts (ProTextarea's "…", the user bubble) still group them under
21
+ * `submenu`.
22
+ */
23
+ inline?: boolean;
24
+ /**
25
+ * The heading names the THING these rows act on ("Conversation": the whole
26
+ * conversation, not the clicked message) — declared to the engine as a target
27
+ * label (`section.kind: "target"`), never a group heading.
28
+ */
29
+ target?: boolean;
30
+ }
31
+ /**
32
+ * The canonical menu layout. Order here = render order. Action IDs not
33
+ * listed in any section are treated as `extra` (consumer-supplied) and
34
+ * rendered in a trailing group.
35
+ */
36
+ /**
37
+ * The AI section's label in the tree hosts — the classic context-menu name
38
+ * "AI Actions" (agent-shortcuts placement label), restored 2026-09-26 over the
39
+ * coined "Improve with AI" (ALC-15 round 3). Hosts that carry the agent-shortcut
40
+ * libraries and ProTextarea's bound agents fold them INTO this group, so there
41
+ * is one AI family in every menu, never a parallel one. In the one menu engine
42
+ * the group is `inline` (no heading), so it never reads "AI Actions › AI Actions".
43
+ */
44
+ export declare const AI_SUBMENU_LABEL = "AI Actions";
45
+ /** The whole-conversation section's label (answer menus of chat messages). */
46
+ export declare const CONVERSATION_SUBMENU_LABEL = "Conversation";
47
+ export declare const MENU_STRUCTURE: MenuSection[];
48
+ export interface MenuSubmenuNode {
49
+ label: string;
50
+ icon?: LucideIcon;
51
+ actions: RichDocumentAction[];
52
+ }
53
+ export interface MenuTree {
54
+ /** Promoted, always-visible top-level items. */
55
+ topLevel: RichDocumentAction[];
56
+ /** Named submenus, each with ≥1 visible action. */
57
+ submenus: MenuSubmenuNode[];
58
+ /** Consumer-supplied actions not present in MENU_STRUCTURE. */
59
+ extras: RichDocumentAction[];
60
+ }
61
+ export declare function buildMenuTree(input: RichDocumentAction[], options?: {
62
+ aiSlot?: boolean;
63
+ }): MenuTree;
64
+ /**
65
+ * THE ONE selector of which registry actions a MENU shows (every host: ⋯,
66
+ * right-click, ProTextarea "…", the mobile sheet). A bar's primary buttons
67
+ * stay on the bar; a menu carries the overflow set. One selector is what
68
+ * keeps every host's tree identical (guard: __tests__/oneMenuTree.test.ts).
69
+ */
70
+ export declare function registryMenuActions(actions: RichDocumentAction[]): RichDocumentAction[];
71
+ /**
72
+ * The AI submenu, guaranteed present when a host has its own AI rows to fold
73
+ * in (a ProTextarea's bound agents, the v3 agent-shortcut libraries), at the
74
+ * position MENU_STRUCTURE gives it — so no host ever grows a second AI family.
75
+ */
76
+ export declare function withAiSlot(submenus: MenuSubmenuNode[], hasSlot: boolean): MenuSubmenuNode[];
77
+ /** The tree as an ordered id list — what the one-tree guard compares. */
78
+ export declare function flattenMenuTreeIds(tree: MenuTree): string[];
79
+ /** Bumps on every extension, so cached placements rebuild. */
80
+ export declare function menuStructureVersion(): number;
81
+ export declare function extendMenuSection(submenu: string, actionIds: readonly string[]): void;