@ai-matrx/rich-content 0.2.9 → 0.2.15
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/CHANGELOG.md +9 -0
- package/dist/copy/copy-commands.d.ts +42 -0
- package/dist/copy/copy-commands.js +119 -0
- package/dist/copy/markdown-copy-html.d.ts +3 -0
- package/dist/copy/markdown-copy-html.js +8 -0
- package/dist/copy/markdown-readable-text.d.ts +4 -0
- package/dist/copy/markdown-readable-text.js +62 -0
- package/dist/display/blocks/json/json-tabular-utils.d.ts +7 -5
- package/dist/display/blocks/json/json-tabular-utils.js +26 -17
- package/dist/display/blocks/table/StreamingTableRenderer.js +11 -16
- package/dist/display/chat-markdown/BasicMarkdownContent.js +8 -6
- package/dist/display/chat-markdown/ConfigurableMarkdownContent.js +8 -6
- package/dist/display/chat-markdown/block-registry/BlockComponentRegistry.js +2 -0
- package/dist/display/chat-markdown/block-registry/block-dispatch.js +2 -0
- package/dist/display/tables/MarkdownTable.js +11 -16
- package/dist/display/tables/TableWithSeparatedControls.js +11 -16
- package/dist/display/tables/table-csv.d.ts +7 -0
- package/dist/display/tables/table-csv.js +19 -0
- package/dist/host/app-bindings.d.ts +32 -0
- package/dist/host/app-bindings.js +40 -0
- package/dist/host/feedback-subject.d.ts +16 -0
- package/dist/host/feedback-subject.js +0 -0
- package/dist/host/manual-copy.d.ts +7 -0
- package/dist/host/manual-copy.js +11 -0
- package/dist/host/registry.d.ts +2 -0
- package/dist/host/registry.js +10 -0
- package/dist/host/session-knob.d.ts +5 -0
- package/dist/host/session-knob.js +7 -0
- package/dist/host/types.d.ts +24 -0
- package/dist/rich-document/RegistryContextMenu.d.ts +29 -0
- package/dist/rich-document/RegistryContextMenu.js +40 -0
- package/dist/rich-document/RichDocument.d.ts +78 -0
- package/dist/rich-document/RichDocument.js +218 -0
- package/dist/rich-document/RichDocumentActionProvider.d.ts +18 -0
- package/dist/rich-document/RichDocumentActionProvider.js +18 -0
- package/dist/rich-document/RichDocumentActionSurface.d.ts +11 -0
- package/dist/rich-document/RichDocumentActionSurface.js +59 -0
- package/dist/rich-document/RichDocumentActions.d.ts +12 -0
- package/dist/rich-document/RichDocumentActions.js +29 -0
- package/dist/rich-document/actions/hostActions.d.ts +5 -0
- package/dist/rich-document/actions/hostActions.js +31 -0
- package/dist/rich-document/actions/labels.d.ts +9 -0
- package/dist/rich-document/actions/labels.js +8 -0
- package/dist/rich-document/actions/markdownTable.d.ts +9 -0
- package/dist/rich-document/actions/markdownTable.js +39 -0
- package/dist/rich-document/actions/provider.d.ts +58 -0
- package/dist/rich-document/actions/provider.js +245 -0
- package/dist/rich-document/actions/resumePendingAuthAction.d.ts +3 -0
- package/dist/rich-document/actions/resumePendingAuthAction.js +31 -0
- package/dist/rich-document/actions/sources/index.d.ts +9 -0
- package/dist/rich-document/actions/sources/index.js +22 -0
- package/dist/rich-document/actions/sources/raw.d.ts +4 -0
- package/dist/rich-document/actions/sources/raw.js +35 -0
- package/dist/rich-document/actions/useRichDocumentProvider.d.ts +1 -0
- package/dist/rich-document/actions/useRichDocumentProvider.js +13 -0
- package/dist/rich-document/host-types.d.ts +51 -0
- package/dist/rich-document/host-types.js +0 -0
- package/dist/rich-document/registrations.d.ts +1 -0
- package/dist/rich-document/registrations.js +13 -0
- package/dist/rich-document/review/applyTargets.d.ts +16 -0
- package/dist/rich-document/review/applyTargets.js +32 -0
- package/dist/rich-document/review/proposedEdit.d.ts +22 -0
- package/dist/rich-document/review/proposedEdit.js +48 -0
- package/dist/rich-document/review/protectedSpans.d.ts +14 -0
- package/dist/rich-document/review/protectedSpans.js +61 -0
- package/dist/rich-document/runtime/actionSurfacesStore.d.ts +30 -0
- package/dist/rich-document/runtime/actionSurfacesStore.js +79 -0
- package/dist/rich-document/runtime/contextMenuFor.d.ts +6 -0
- package/dist/rich-document/runtime/contextMenuFor.js +7 -0
- package/dist/rich-document/runtime/providerBridge.d.ts +20 -0
- package/dist/rich-document/runtime/providerBridge.js +23 -0
- package/dist/rich-document/runtime/useActionSurfaceProvider.d.ts +33 -0
- package/dist/rich-document/runtime/useActionSurfaceProvider.js +214 -0
- package/dist/rich-document/search/ContentFindControl.d.ts +8 -0
- package/dist/rich-document/search/ContentFindControl.js +46 -0
- package/dist/rich-document/search/RenderedFindBar.d.ts +8 -0
- package/dist/rich-document/search/RenderedFindBar.js +110 -0
- package/dist/rich-document/search/renderedFind.d.ts +1 -0
- package/dist/rich-document/search/renderedFind.js +1 -0
- package/dist/rich-document/types.d.ts +384 -0
- package/dist/rich-document/types.js +0 -0
- package/dist/rich-document/variants/ActionBar.d.ts +17 -0
- package/dist/rich-document/variants/ActionBar.js +48 -0
- package/dist/rich-document/variants/MenuVariant.d.ts +15 -0
- package/dist/rich-document/variants/MenuVariant.js +17 -0
- package/dist/rich-document/variants/MiniActionBar.d.ts +5 -0
- package/dist/rich-document/variants/MiniActionBar.js +11 -0
- package/dist/rich-document/variants/RegistryActionList.d.ts +17 -0
- package/dist/rich-document/variants/RegistryActionList.js +94 -0
- package/dist/rich-document/variants/RegistryActionMenu.d.ts +24 -0
- package/dist/rich-document/variants/RegistryActionMenu.js +74 -0
- package/dist/rich-document/variants/shared/AlchemyDocumentMenu.d.ts +7 -0
- package/dist/rich-document/variants/shared/AlchemyDocumentMenu.js +83 -0
- package/dist/rich-document/variants/shared/OpenOneMenuButton.d.ts +9 -0
- package/dist/rich-document/variants/shared/OpenOneMenuButton.js +70 -0
- package/dist/rich-document/variants/shared/StandaloneOneMenu.d.ts +8 -0
- package/dist/rich-document/variants/shared/StandaloneOneMenu.js +32 -0
- package/dist/rich-document/variants/shared/categories.d.ts +4 -0
- package/dist/rich-document/variants/shared/categories.js +31 -0
- package/dist/rich-document/variants/shared/iconMap.d.ts +2 -0
- package/dist/rich-document/variants/shared/iconMap.js +73 -0
- package/dist/rich-document/variants/shared/menuStructure.d.ts +81 -0
- package/dist/rich-document/variants/shared/menuStructure.js +268 -0
- package/dist/rich-document/variants/shared/runAction.d.ts +17 -0
- package/dist/rich-document/variants/shared/runAction.js +24 -0
- package/dist/selection-toolbar/SelectionToolbarFrame.d.ts +64 -0
- package/dist/selection-toolbar/SelectionToolbarFrame.js +191 -0
- package/dist/selection-toolbar/common-actions.d.ts +2 -0
- package/dist/selection-toolbar/common-actions.js +103 -0
- package/dist/selection-toolbar/selection-actions.d.ts +126 -0
- package/dist/selection-toolbar/selection-actions.js +240 -0
- package/dist/selection-toolbar/selection-copy.d.ts +19 -0
- package/dist/selection-toolbar/selection-copy.js +98 -0
- package/dist/selection-toolbar/selection-shape.d.ts +1 -0
- package/dist/selection-toolbar/selection-shape.js +15 -0
- package/dist/selection-toolbar/selection-zones.d.ts +90 -0
- package/dist/selection-toolbar/selection-zones.js +85 -0
- package/dist/selection-toolbar/textarea-caret.d.ts +8 -0
- package/dist/selection-toolbar/textarea-caret.js +69 -0
- package/dist/utils/alchemy-icon-keys.d.ts +18 -0
- package/dist/utils/alchemy-icon-keys.js +29 -0
- package/dist/utils/rendered-find.d.ts +9 -0
- package/dist/utils/rendered-find.js +68 -0
- package/package.json +21 -5
|
@@ -32,6 +32,21 @@ export interface RichContentAppBindings {
|
|
|
32
32
|
useHostUser: HostFn;
|
|
33
33
|
useIsAdminDebugger: HostFn;
|
|
34
34
|
useIsAuthenticated: HostFn;
|
|
35
|
+
useHostDispatch: HostFn;
|
|
36
|
+
useHostGetState: HostFn;
|
|
37
|
+
useIsSuperAdmin: HostFn;
|
|
38
|
+
useActiveOrganizationId: HostFn;
|
|
39
|
+
holdDeliberateIntent: HostFn;
|
|
40
|
+
useAlchemyDisclosure: HostFn;
|
|
41
|
+
useRegistryMenuSource: HostFn;
|
|
42
|
+
sameContentSource: HostFn;
|
|
43
|
+
contentSourceKey: HostFn;
|
|
44
|
+
openContextMenuForElement: HostFn;
|
|
45
|
+
convertOriginForSource: HostFn;
|
|
46
|
+
useDocumentDialogsHost: HostFn;
|
|
47
|
+
RecordAnnotations: HostComponent;
|
|
48
|
+
annotationRecordOf: HostFn;
|
|
49
|
+
recordKeyOf: HostFn;
|
|
35
50
|
useMermaidPreferences: HostFn;
|
|
36
51
|
useSetMermaidPreferences: HostFn;
|
|
37
52
|
useImageKnob: HostFn;
|
|
@@ -47,6 +62,7 @@ export interface RichContentAppBindings {
|
|
|
47
62
|
MarkdownStream: HostComponent;
|
|
48
63
|
CitationMarkerInline: HostComponent;
|
|
49
64
|
InlineCopyButton: HostComponent;
|
|
65
|
+
CopyButtons: HostComponent;
|
|
50
66
|
AdvancedMenu: HostComponent;
|
|
51
67
|
useAdvancedMenu: HostFn;
|
|
52
68
|
EntityRef: HostComponent;
|
|
@@ -127,8 +143,23 @@ export declare const KindInstanceRender: HostComponent;
|
|
|
127
143
|
export declare const KindRecordChrome: HostComponent;
|
|
128
144
|
export declare const kindHasRecordChrome: HostFn;
|
|
129
145
|
export declare const KindFixItBar: HostComponent;
|
|
146
|
+
export declare const useHostDispatch: HostFn;
|
|
147
|
+
export declare const useHostGetState: HostFn;
|
|
148
|
+
export declare const useIsSuperAdmin: HostFn;
|
|
149
|
+
export declare const useActiveOrganizationId: HostFn;
|
|
150
|
+
export declare const useAlchemyDisclosure: HostFn;
|
|
151
|
+
export declare const useRegistryMenuSource: HostFn;
|
|
152
|
+
export declare const sameContentSource: HostFn;
|
|
153
|
+
export declare const contentSourceKey: HostFn;
|
|
154
|
+
export declare const openContextMenuForElement: HostFn;
|
|
155
|
+
export declare const convertOriginForSource: HostFn;
|
|
156
|
+
export declare const useDocumentDialogsHost: HostFn;
|
|
157
|
+
export declare const RecordAnnotations: HostComponent;
|
|
158
|
+
export declare const annotationRecordOf: HostFn;
|
|
159
|
+
export declare const recordKeyOf: HostFn;
|
|
130
160
|
export declare const MarkdownStream: HostComponent;
|
|
131
161
|
export declare const CitationMarkerInline: HostComponent;
|
|
162
|
+
export declare const CopyButtons: HostComponent;
|
|
132
163
|
export declare const InlineCopyButton: HostComponent;
|
|
133
164
|
export declare const AdvancedMenu: HostComponent;
|
|
134
165
|
export declare const useAdvancedMenu: HostFn;
|
|
@@ -140,6 +171,7 @@ export declare const IconInputWithValidation: HostComponent;
|
|
|
140
171
|
export declare const LocatedTableViewer: HostComponent;
|
|
141
172
|
export declare const OpenDestinationDialog: HostComponent;
|
|
142
173
|
export declare function hostHtmlPageService(): unknown;
|
|
174
|
+
export declare const holdDeliberateIntent: <T>(work: () => T | Promise<T>) => Promise<T>;
|
|
143
175
|
export declare const ensureOrganizationContext: HostFn;
|
|
144
176
|
export declare const isOrganizationSelectionCancelled: HostFn;
|
|
145
177
|
export declare const loadExportTargets: HostFn;
|
|
@@ -68,8 +68,27 @@ const KindInstanceRender = component("KindInstanceRender", ValueFloor, "kind ins
|
|
|
68
68
|
const KindRecordChrome = component("KindRecordChrome", Passthrough, "kind records show without record chrome");
|
|
69
69
|
const kindHasRecordChrome = fn("kindHasRecordChrome", () => false, "kind records show without record chrome");
|
|
70
70
|
const KindFixItBar = component("KindFixItBar", null, "no fix-it bar on broken kinds");
|
|
71
|
+
const useHostDispatch = fn("useHostDispatch", () => (action) => action, "actions dispatch nowhere");
|
|
72
|
+
const useHostGetState = fn("useHostGetState", () => () => ({}), "actions read an empty host state");
|
|
73
|
+
const useIsSuperAdmin = fn("useIsSuperAdmin", () => false, "admin-only actions are absent");
|
|
74
|
+
const useActiveOrganizationId = fn("useActiveOrganizationId", () => null, "no organization is active");
|
|
75
|
+
const useAlchemyDisclosure = fn("useAlchemyDisclosure", noop, "no Alchemy disclosure");
|
|
76
|
+
const useRegistryMenuSource = fn("useRegistryMenuSource", () => null, "no menu carries a content source");
|
|
77
|
+
const sameContentSource = fn(
|
|
78
|
+
"sameContentSource",
|
|
79
|
+
(a, b) => Boolean(a && b && JSON.stringify(a) === JSON.stringify(b)),
|
|
80
|
+
"content sources compare by value"
|
|
81
|
+
);
|
|
82
|
+
const contentSourceKey = fn("contentSourceKey", (s) => JSON.stringify(s), "content sources key by value");
|
|
83
|
+
const openContextMenuForElement = fn("openContextMenuForElement", noop, "no context menu opens");
|
|
84
|
+
const convertOriginForSource = fn("convertOriginForSource", () => null, "convert is absent");
|
|
85
|
+
const useDocumentDialogsHost = fn("useDocumentDialogsHost", () => ({ callbacks: {} }), "document dialogs are absent");
|
|
86
|
+
const RecordAnnotations = component("RecordAnnotations", Passthrough, "no reading set on saved records");
|
|
87
|
+
const annotationRecordOf = fn("annotationRecordOf", () => null, "no saved record is known");
|
|
88
|
+
const recordKeyOf = fn("recordKeyOf", (r) => `${r.token}:${r.id}`, "records key as token:id");
|
|
71
89
|
const MarkdownStream = component("MarkdownStream", null, "the full renderer is not registered");
|
|
72
90
|
const CitationMarkerInline = component("CitationMarkerInline", TextOnly, "citation markers show as text");
|
|
91
|
+
const CopyButtons = component("CopyButtons", null, "no copy menu on rendered content");
|
|
73
92
|
const InlineCopyButton = component("InlineCopyButton", null, "no inline copy button");
|
|
74
93
|
const AdvancedMenu = component("AdvancedMenu", null, "no block menus");
|
|
75
94
|
const useAdvancedMenu = fn("useAdvancedMenu", () => ({ isOpen: false, open: noop, close: noop, toggle: noop, menuProps: {} }), "no block menus");
|
|
@@ -83,6 +102,11 @@ const OpenDestinationDialog = component("OpenDestinationDialog", null, "no desti
|
|
|
83
102
|
function hostHtmlPageService() {
|
|
84
103
|
return binding("HTMLPageService") ?? null;
|
|
85
104
|
}
|
|
105
|
+
const holdDeliberateIntent = fn(
|
|
106
|
+
"holdDeliberateIntent",
|
|
107
|
+
(work) => Promise.resolve().then(work),
|
|
108
|
+
"actions run without an intent hold"
|
|
109
|
+
);
|
|
86
110
|
const ensureOrganizationContext = fn("ensureOrganizationContext", async () => null, "no organization can be chosen");
|
|
87
111
|
const isOrganizationSelectionCancelled = fn("isOrganizationSelectionCancelled", () => false, "no organization can be chosen");
|
|
88
112
|
const loadExportTargets = fn("loadExportTargets", async () => null, "no workbook export");
|
|
@@ -105,6 +129,7 @@ export {
|
|
|
105
129
|
ArtifactRender,
|
|
106
130
|
CitationMarkerInline,
|
|
107
131
|
CodeBlockWithContextAttach,
|
|
132
|
+
CopyButtons,
|
|
108
133
|
EntityRef,
|
|
109
134
|
IconInputWithValidation,
|
|
110
135
|
InlineCopyButton,
|
|
@@ -119,12 +144,17 @@ export {
|
|
|
119
144
|
NonEditableContextMenu,
|
|
120
145
|
OpenDestinationDialog,
|
|
121
146
|
RawJsonExplorer,
|
|
147
|
+
RecordAnnotations,
|
|
122
148
|
StructuredValueView,
|
|
149
|
+
annotationRecordOf,
|
|
123
150
|
announceProposedGoogleWrite,
|
|
151
|
+
contentSourceKey,
|
|
152
|
+
convertOriginForSource,
|
|
124
153
|
createMermaidEditorScope,
|
|
125
154
|
ensureOrganizationContext,
|
|
126
155
|
getArtifactDef,
|
|
127
156
|
hasArtifactRenderer,
|
|
157
|
+
holdDeliberateIntent,
|
|
128
158
|
hostCodeEditorAgents,
|
|
129
159
|
hostHtmlPageService,
|
|
130
160
|
hostMermaidEditorManifest,
|
|
@@ -134,19 +164,28 @@ export {
|
|
|
134
164
|
kindHasRecordChrome,
|
|
135
165
|
loadExportTargets,
|
|
136
166
|
loadSendToGoogle,
|
|
167
|
+
openContextMenuForElement,
|
|
168
|
+
recordKeyOf,
|
|
137
169
|
reportCanvasOpenDrop,
|
|
138
170
|
resolveArtifactDef,
|
|
171
|
+
sameContentSource,
|
|
139
172
|
setImageKnobMapEntry,
|
|
173
|
+
useActiveOrganizationId,
|
|
140
174
|
useAdvancedMenu,
|
|
175
|
+
useAlchemyDisclosure,
|
|
141
176
|
useCanvas,
|
|
142
177
|
useCanvasOpenGuard,
|
|
143
178
|
useDiagramAgents,
|
|
179
|
+
useDocumentDialogsHost,
|
|
144
180
|
useHideReasoning,
|
|
145
181
|
useHideToolResults,
|
|
182
|
+
useHostDispatch,
|
|
183
|
+
useHostGetState,
|
|
146
184
|
useHostUser,
|
|
147
185
|
useImageKnob,
|
|
148
186
|
useIsAdminDebugger,
|
|
149
187
|
useIsAuthenticated,
|
|
188
|
+
useIsSuperAdmin,
|
|
150
189
|
useMachineFramesVisible,
|
|
151
190
|
useMermaidPreferences,
|
|
152
191
|
useOpenArtifactInCanvas,
|
|
@@ -154,6 +193,7 @@ export {
|
|
|
154
193
|
useOpenOverlay,
|
|
155
194
|
useOpenSmartCodeEditorWindow,
|
|
156
195
|
useOpenTableViewerWindow,
|
|
196
|
+
useRegistryMenuSource,
|
|
157
197
|
useSaveAndOpenInCodeEditor,
|
|
158
198
|
useSetMermaidPreferences,
|
|
159
199
|
useThemeMode
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a feedback report points at (matrx-frontend: features/overlays/openers/feedbackDialog
|
|
3
|
+
* `FeedbackSubject`). The engine only builds the text-passage subject; the host owns the rest.
|
|
4
|
+
*/
|
|
5
|
+
export interface TextPassageFeedbackSubject {
|
|
6
|
+
kind: "text_passage";
|
|
7
|
+
sourceToken: string;
|
|
8
|
+
sourceId: string;
|
|
9
|
+
sourceTitle: string;
|
|
10
|
+
quote: string;
|
|
11
|
+
anchor?: unknown;
|
|
12
|
+
[extra: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export type FeedbackSubject = TextPassageFeedbackSubject | ({
|
|
15
|
+
kind: string;
|
|
16
|
+
} & Record<string, unknown>);
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { announceBareHost, hostCapability } from "./registry.js";
|
|
2
|
+
function showManualCopy(opts) {
|
|
3
|
+
if (!opts.text) return;
|
|
4
|
+
const show = hostCapability("showManualCopy");
|
|
5
|
+
if (show) return show(opts);
|
|
6
|
+
announceBareHost("showManualCopy", "a refused copy is written to the console");
|
|
7
|
+
console.warn("[rich-content] the clipboard refused this copy; the text follows:\n" + opts.text);
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
showManualCopy
|
|
11
|
+
};
|
package/dist/host/registry.d.ts
CHANGED
|
@@ -25,3 +25,5 @@ export declare function announceBareHost(capability: string, degraded: string):
|
|
|
25
25
|
export declare const BARE_HOST_ATTR: {
|
|
26
26
|
readonly "data-rich-content-host": "bare";
|
|
27
27
|
};
|
|
28
|
+
/** Run the host's `ensureBlockRegistrations` once (see RichContentHost). */
|
|
29
|
+
export declare function ensureHostBlockRegistrations(): void;
|
package/dist/host/registry.js
CHANGED
|
@@ -44,10 +44,20 @@ function announceBareHost(capability, degraded) {
|
|
|
44
44
|
console.warn(`[@ai-matrx/rich-content] The host registered no "${capability}", so ${degraded}.`);
|
|
45
45
|
}
|
|
46
46
|
const BARE_HOST_ATTR = { "data-rich-content-host": "bare" };
|
|
47
|
+
const ENSURED_KEY = /* @__PURE__ */ Symbol.for("ai-matrx.rich-content.block-registrations-ensured");
|
|
48
|
+
function ensureHostBlockRegistrations() {
|
|
49
|
+
const g = globalThis;
|
|
50
|
+
if (g[ENSURED_KEY]) return;
|
|
51
|
+
const ensure = hostCapability("ensureBlockRegistrations");
|
|
52
|
+
if (!ensure) return;
|
|
53
|
+
g[ENSURED_KEY] = true;
|
|
54
|
+
ensure();
|
|
55
|
+
}
|
|
47
56
|
export {
|
|
48
57
|
BARE_HOST_ATTR,
|
|
49
58
|
announceBareHost,
|
|
50
59
|
configureRichContent,
|
|
60
|
+
ensureHostBlockRegistrations,
|
|
51
61
|
hostCapability,
|
|
52
62
|
resetRichContentHost,
|
|
53
63
|
richContentHostVersion,
|
package/dist/host/types.d.ts
CHANGED
|
@@ -149,6 +149,30 @@ export interface RichContentHost {
|
|
|
149
149
|
splitterEnvelopes: RichContentSplitterEnvelopes;
|
|
150
150
|
/** A hook returning the host's "save these rows as a table" opener, or null. Default: no opener (the button is absent). */
|
|
151
151
|
useOpenSaveToTable: () => ((options: Record<string, unknown>) => unknown) | null;
|
|
152
|
+
/**
|
|
153
|
+
* Loads the host's own block registrations on first use (matrx-frontend's Jest setup requires its
|
|
154
|
+
* registration module here, so suites that mock a block still see the mock). Called once, on the
|
|
155
|
+
* first block-registry or dispatch lookup. Default: none (registrations arrive by import).
|
|
156
|
+
*/
|
|
157
|
+
ensureBlockRegistrations: () => void;
|
|
158
|
+
/** Loads the host's rich-document registrations (handlers, source adapters) on first registry read. */
|
|
159
|
+
ensureRichDocumentRegistrations: () => void;
|
|
160
|
+
/** The manual-copy dialog for a copy the clipboard refused. Default: the console. */
|
|
161
|
+
showManualCopy: (opts: {
|
|
162
|
+
text: string;
|
|
163
|
+
title?: string;
|
|
164
|
+
description?: string;
|
|
165
|
+
}) => void;
|
|
166
|
+
/** A knob's effective value for the signed-in person, synchronously. Default: undefined. */
|
|
167
|
+
readSessionKnob: (knob: {
|
|
168
|
+
feature: string;
|
|
169
|
+
key: string;
|
|
170
|
+
}) => unknown;
|
|
171
|
+
/**
|
|
172
|
+
* The editor's HTML → markdown converter (matrx-frontend: @ai-matrx/rich-editor core), loaded at
|
|
173
|
+
* copy time. Default: none — a copied selection keeps its shape text (tables and lists).
|
|
174
|
+
*/
|
|
175
|
+
loadHtmlToMarkdown: () => Promise<(html: string) => string>;
|
|
152
176
|
/** Loads mermaid (`() => import("mermaid").then((m) => m.default)`). Default: none — diagrams show their source. */
|
|
153
177
|
loadMermaid: () => Promise<unknown>;
|
|
154
178
|
/** Loads the ELK layout loaders (`() => import("@mermaid-js/layout-elk").then((m) => m.default)`). Default: dagre only. */
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { NonEditableContextMenu } from "../host/app-bindings.js";
|
|
3
|
+
import type { ContentSource, RichDocumentAction, RichDocumentActionId, RichDocumentActionsProp } from "./types.js";
|
|
4
|
+
export interface RegistryContextMenuProps {
|
|
5
|
+
content: string;
|
|
6
|
+
source: ContentSource;
|
|
7
|
+
actions?: RichDocumentActionsProp;
|
|
8
|
+
/** Context-menu-only additions / removals. */
|
|
9
|
+
extra?: RichDocumentAction[];
|
|
10
|
+
exclude?: (RichDocumentActionId | string)[];
|
|
11
|
+
/** Yield to the native menu (e.g. while the content streams). */
|
|
12
|
+
suppressed?: boolean;
|
|
13
|
+
sourceFeature?: React.ComponentProps<typeof NonEditableContextMenu>["sourceFeature"];
|
|
14
|
+
surfaceName?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The surface's declared values (e.g. `conversation_id` for the assistant
|
|
17
|
+
* message surface) — merged into the menu scope so bound agents and
|
|
18
|
+
* shortcuts receive them.
|
|
19
|
+
*/
|
|
20
|
+
contextData?: Record<string, unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Which agent-menu placements show (e.g. `{ "content-block": "hide" }` over
|
|
23
|
+
* a rendered answer, where a block could only be copied, never inserted).
|
|
24
|
+
*/
|
|
25
|
+
placementMode?: React.ComponentProps<typeof NonEditableContextMenu>["placementMode"];
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
}
|
|
28
|
+
export declare function RegistryContextMenu(props: RegistryContextMenuProps): React.ReactElement;
|
|
29
|
+
export default RegistryContextMenu;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { NonEditableContextMenu } from "../host/app-bindings.js";
|
|
4
|
+
import { useActionSurfaceProvider } from "./runtime/useActionSurfaceProvider.js";
|
|
5
|
+
function RegistryContextMenu(props) {
|
|
6
|
+
const { content, source, actions, extra, exclude, suppressed, children } = props;
|
|
7
|
+
const { ctx } = useActionSurfaceProvider({
|
|
8
|
+
content,
|
|
9
|
+
source,
|
|
10
|
+
actions,
|
|
11
|
+
actionsVariant: "none"
|
|
12
|
+
});
|
|
13
|
+
const excludes = [...actions?.exclude ?? [], ...exclude ?? []];
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
NonEditableContextMenu,
|
|
16
|
+
{
|
|
17
|
+
sourceFeature: props.sourceFeature ?? "documents",
|
|
18
|
+
surfaceName: props.surfaceName,
|
|
19
|
+
suppressed,
|
|
20
|
+
contentSource: source,
|
|
21
|
+
contextData: { ...props.contextData, content: ctx.content },
|
|
22
|
+
placementMode: props.placementMode,
|
|
23
|
+
excludedRichActions: excludes,
|
|
24
|
+
richDocCtxExtras: {
|
|
25
|
+
callbacks: actions?.callbacks,
|
|
26
|
+
extensions: actions?.extensions,
|
|
27
|
+
metadata: actions?.metadata ?? null,
|
|
28
|
+
isCreator: actions?.isCreator ?? false,
|
|
29
|
+
surfaceKey: actions?.surfaceKey ?? null
|
|
30
|
+
},
|
|
31
|
+
extraRichActions: [...actions?.extra ?? [], ...extra ?? []],
|
|
32
|
+
children
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
var RegistryContextMenu_default = RegistryContextMenu;
|
|
37
|
+
export {
|
|
38
|
+
RegistryContextMenu,
|
|
39
|
+
RegistryContextMenu_default as default
|
|
40
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type SpecimenMode } from "../display/specimen/SpecimenContext.js";
|
|
3
|
+
import type { ContentSource, RichDocumentAction, RichDocumentActionId, RichDocumentActionsProp, RichDocumentActionsVariant, RichDocumentActionsPosition, RichDocumentActionsBehavior } from "./types.js";
|
|
4
|
+
import type { AnnotationRecord, ServerProcessedBlock } from "./host-types.js";
|
|
5
|
+
import type { TypedStreamEvent } from "../display/chat-markdown/types.js";
|
|
6
|
+
export interface RichDocumentProps {
|
|
7
|
+
content?: string;
|
|
8
|
+
events?: TypedStreamEvent[];
|
|
9
|
+
serverProcessedBlocks?: ServerProcessedBlock[];
|
|
10
|
+
taskId?: string;
|
|
11
|
+
requestId?: string;
|
|
12
|
+
turnId?: string;
|
|
13
|
+
conversationId?: string;
|
|
14
|
+
isStreamActive?: boolean;
|
|
15
|
+
/** Required. Use { type: "raw" } when the source is genuinely unknown. */
|
|
16
|
+
source: ContentSource;
|
|
17
|
+
renderer?: "basic" | "configurable" | "stream";
|
|
18
|
+
actions?: RichDocumentActionsProp;
|
|
19
|
+
actionsVariant?: RichDocumentActionsVariant;
|
|
20
|
+
/** Where the action surface sits. Default "below". */
|
|
21
|
+
actionsPosition?: RichDocumentActionsPosition;
|
|
22
|
+
/** Visibility. Default "always". */
|
|
23
|
+
actionsBehavior?: RichDocumentActionsBehavior;
|
|
24
|
+
/** Required when actionsVariant === "remote". */
|
|
25
|
+
actionsSurfaceId?: string;
|
|
26
|
+
/**
|
|
27
|
+
* DECLARE that this content is a specimen — generated work that is meant to
|
|
28
|
+
* look right and be wrong (the Bad Example probe, a wrong explanation, a
|
|
29
|
+
* decoy option). Suppresses every action surface, the right-click menu, and
|
|
30
|
+
* the actions inside the content itself (table export / workbook / Google
|
|
31
|
+
* Sheet / edit / open-in-window), and prints the specimen banner in their
|
|
32
|
+
* place. Pass `true` for the default wording, or override the two lines.
|
|
33
|
+
* See @ai-matrx/rich-content/display/specimen/SpecimenContext.tsx.
|
|
34
|
+
*/
|
|
35
|
+
specimen?: boolean | Partial<SpecimenMode>;
|
|
36
|
+
/**
|
|
37
|
+
* Enable a right-click context menu over the content. Lazy-loaded (the
|
|
38
|
+
* menu chunk only ships after the first right-click) and streaming-safe
|
|
39
|
+
* (yields to the native browser menu while isStreamActive). Pass an object
|
|
40
|
+
* to add context-menu-only `extra` actions or `exclude` specific ones.
|
|
41
|
+
* This is the extension point for future per-surface right-click actions.
|
|
42
|
+
*/
|
|
43
|
+
enableContextMenu?: boolean | {
|
|
44
|
+
extra?: RichDocumentAction[];
|
|
45
|
+
exclude?: (RichDocumentActionId | string)[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* The SAVED RECORD this content is, for the reading set (highlight, comment,
|
|
49
|
+
* suggest, link) and its Notes & comments dock. Derived from `source` for a
|
|
50
|
+
* note, a chat answer and a saved working document; pass it when the source
|
|
51
|
+
* does not say (the studio previewing a loaded document), or `null` to turn
|
|
52
|
+
* the reading set off. A read-only copy, a stream in flight and a specimen
|
|
53
|
+
* never get one.
|
|
54
|
+
*/
|
|
55
|
+
annotationRecord?: AnnotationRecord | null;
|
|
56
|
+
className?: string;
|
|
57
|
+
contentClassName?: string;
|
|
58
|
+
actionsClassName?: string;
|
|
59
|
+
onContentChange?: (newContent: string) => void;
|
|
60
|
+
applyLocalEdits?: boolean;
|
|
61
|
+
analysisData?: unknown;
|
|
62
|
+
messageId?: string;
|
|
63
|
+
allowFullScreenEditor?: boolean;
|
|
64
|
+
hideCopyButton?: boolean;
|
|
65
|
+
onError?: (error: string) => void;
|
|
66
|
+
onPhaseUpdate?: (phase: string) => void;
|
|
67
|
+
strictServerData?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* WHO WROTE this content — "ai" (a model), "other" (someone else) or "self"
|
|
70
|
+
* (the viewer). Decides whether remote images load by themselves
|
|
71
|
+
* (components/rich-content/prose/remote-image-policy.tsx, chair ruling
|
|
72
|
+
* 2026-09-25). Declare it at every call site — guard:
|
|
73
|
+
* components/rich-content/__tests__/image-policy-declared.test.ts.
|
|
74
|
+
*/
|
|
75
|
+
imagePolicy?: "self" | "other" | "ai" | "inherit";
|
|
76
|
+
}
|
|
77
|
+
export declare function RichDocument(props: RichDocumentProps): React.ReactElement;
|
|
78
|
+
export default RichDocument;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from "@ai-matrx/design-system";
|
|
4
|
+
import { useActionSurfaceProvider } from "./runtime/useActionSurfaceProvider.js";
|
|
5
|
+
import { RegistryContextMenu } from "./RegistryContextMenu.js";
|
|
6
|
+
import { getSourceAdapter } from "./actions/sources/index.js";
|
|
7
|
+
import {
|
|
8
|
+
convertOriginForSource,
|
|
9
|
+
useDocumentDialogsHost,
|
|
10
|
+
RecordAnnotations,
|
|
11
|
+
annotationRecordOf,
|
|
12
|
+
recordKeyOf,
|
|
13
|
+
MarkdownStream
|
|
14
|
+
} from "../host/app-bindings.js";
|
|
15
|
+
import { ActionBar } from "./variants/ActionBar.js";
|
|
16
|
+
import { MiniActionBar } from "./variants/MiniActionBar.js";
|
|
17
|
+
import { MenuVariant } from "./variants/MenuVariant.js";
|
|
18
|
+
import { contextMenuFor } from "./runtime/contextMenuFor.js";
|
|
19
|
+
import {
|
|
20
|
+
SpecimenProvider,
|
|
21
|
+
SpecimenBanner,
|
|
22
|
+
resolveSpecimenMode
|
|
23
|
+
} from "../display/specimen/SpecimenContext.js";
|
|
24
|
+
function RichDocument(props) {
|
|
25
|
+
const {
|
|
26
|
+
source,
|
|
27
|
+
actions: actionsProp,
|
|
28
|
+
actionsVariant = "none",
|
|
29
|
+
actionsPosition = "below",
|
|
30
|
+
actionsBehavior = "always",
|
|
31
|
+
actionsSurfaceId,
|
|
32
|
+
specimen,
|
|
33
|
+
enableContextMenu,
|
|
34
|
+
className,
|
|
35
|
+
contentClassName,
|
|
36
|
+
actionsClassName,
|
|
37
|
+
content,
|
|
38
|
+
events,
|
|
39
|
+
serverProcessedBlocks,
|
|
40
|
+
taskId,
|
|
41
|
+
requestId,
|
|
42
|
+
turnId,
|
|
43
|
+
conversationId,
|
|
44
|
+
isStreamActive,
|
|
45
|
+
onContentChange,
|
|
46
|
+
applyLocalEdits,
|
|
47
|
+
analysisData,
|
|
48
|
+
messageId,
|
|
49
|
+
allowFullScreenEditor,
|
|
50
|
+
hideCopyButton,
|
|
51
|
+
onError,
|
|
52
|
+
onPhaseUpdate,
|
|
53
|
+
strictServerData,
|
|
54
|
+
imagePolicy,
|
|
55
|
+
annotationRecord
|
|
56
|
+
} = props;
|
|
57
|
+
const specimenMode = resolveSpecimenMode(specimen);
|
|
58
|
+
const effectiveActionsVariant = specimenMode ? "none" : actionsVariant;
|
|
59
|
+
const dialogsHost = useDocumentDialogsHost({
|
|
60
|
+
convertOrigin: convertOriginForSource(
|
|
61
|
+
source,
|
|
62
|
+
source.type === "note" ? "Note" : "Chat response"
|
|
63
|
+
),
|
|
64
|
+
text: content ?? "",
|
|
65
|
+
// Clean up / Help / Custom agent need somewhere to APPLY the result.
|
|
66
|
+
writable: !source.readOnly && Boolean(getSourceAdapter(source.type).edit) && !(actionsProp?.extensions?.type === "chat-message" && (actionsProp.extensions.contentIsStructuredRaw || actionsProp.extensions.role === "user")),
|
|
67
|
+
chatMessage: source.type === "chat-message" && !source.readOnly ? {
|
|
68
|
+
conversationId: source.conversationId,
|
|
69
|
+
messageId: source.messageId,
|
|
70
|
+
surfaceKey: actionsProp?.surfaceKey ?? null
|
|
71
|
+
} : null
|
|
72
|
+
});
|
|
73
|
+
const record = annotationRecord !== void 0 ? annotationRecord : source.readOnly ? null : annotationRecordOf(source);
|
|
74
|
+
const hostedActions = {
|
|
75
|
+
...actionsProp,
|
|
76
|
+
callbacks: {
|
|
77
|
+
...dialogsHost.callbacks,
|
|
78
|
+
// A host that names its record explicitly (the studio's loaded document
|
|
79
|
+
// rides a raw source) tells the ⋯ "Notes & comments" row which dock it is.
|
|
80
|
+
...record && annotationRecord !== void 0 ? { annotationRecordKey: () => recordKeyOf(record) } : {},
|
|
81
|
+
...actionsProp?.callbacks
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const { ctx, getCtx, resolvedActions, target } = useActionSurfaceProvider({
|
|
85
|
+
content,
|
|
86
|
+
source,
|
|
87
|
+
actions: hostedActions,
|
|
88
|
+
actionsVariant: effectiveActionsVariant,
|
|
89
|
+
actionsSurfaceId
|
|
90
|
+
});
|
|
91
|
+
let variantNode = null;
|
|
92
|
+
switch (effectiveActionsVariant) {
|
|
93
|
+
case "bar":
|
|
94
|
+
variantNode = /* @__PURE__ */ jsx(
|
|
95
|
+
ActionBar,
|
|
96
|
+
{
|
|
97
|
+
actions: resolvedActions,
|
|
98
|
+
getCtx,
|
|
99
|
+
target,
|
|
100
|
+
sourceId: ctx.instanceKey("alchemy")
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
break;
|
|
104
|
+
case "mini-bar":
|
|
105
|
+
variantNode = /* @__PURE__ */ jsx(
|
|
106
|
+
MiniActionBar,
|
|
107
|
+
{
|
|
108
|
+
actions: resolvedActions,
|
|
109
|
+
getCtx,
|
|
110
|
+
target,
|
|
111
|
+
sourceId: ctx.instanceKey("alchemy")
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
break;
|
|
115
|
+
case "menu":
|
|
116
|
+
case "icon-only":
|
|
117
|
+
variantNode = /* @__PURE__ */ jsx(MenuVariant, { getCtx, target });
|
|
118
|
+
break;
|
|
119
|
+
case "remote":
|
|
120
|
+
case "none":
|
|
121
|
+
default:
|
|
122
|
+
variantNode = null;
|
|
123
|
+
}
|
|
124
|
+
const isAbsolute = actionsPosition === "top-right" || actionsPosition === "top-left" || actionsPosition === "middle-right" || actionsPosition === "middle-left";
|
|
125
|
+
const absolutePositionClass = isAbsolute ? cn(
|
|
126
|
+
"absolute z-10",
|
|
127
|
+
actionsPosition === "top-right" && "right-1 top-1",
|
|
128
|
+
actionsPosition === "top-left" && "left-1 top-1",
|
|
129
|
+
actionsPosition === "middle-right" && "right-1 top-1/2 -translate-y-1/2",
|
|
130
|
+
actionsPosition === "middle-left" && "left-1 top-1/2 -translate-y-1/2"
|
|
131
|
+
) : null;
|
|
132
|
+
const hoverClass = actionsBehavior === "hover-only" ? "opacity-0 transition-opacity group-hover:opacity-100 focus-within:opacity-100" : null;
|
|
133
|
+
const inFlowClass = !isAbsolute ? actionsPosition === "above" ? "mb-1" : "mt-1" : null;
|
|
134
|
+
const actionsNode = variantNode ? /* @__PURE__ */ jsx(
|
|
135
|
+
"div",
|
|
136
|
+
{
|
|
137
|
+
className: cn(
|
|
138
|
+
absolutePositionClass,
|
|
139
|
+
hoverClass,
|
|
140
|
+
inFlowClass,
|
|
141
|
+
actionsClassName
|
|
142
|
+
),
|
|
143
|
+
children: variantNode
|
|
144
|
+
}
|
|
145
|
+
) : null;
|
|
146
|
+
const rootClassName = cn(
|
|
147
|
+
"rich-document",
|
|
148
|
+
(isAbsolute || actionsBehavior === "hover-only") && "relative group",
|
|
149
|
+
className
|
|
150
|
+
);
|
|
151
|
+
const annotationSource = record && !specimenMode && !isStreamActive && typeof content === "string" && content.trim() ? {
|
|
152
|
+
token: record.token,
|
|
153
|
+
id: record.id,
|
|
154
|
+
title: record.title ?? "",
|
|
155
|
+
body: content,
|
|
156
|
+
contentVersion: Math.max(1, record.contentVersion ?? 1),
|
|
157
|
+
...record.href ? { href: record.href } : {},
|
|
158
|
+
...record.conversationId ? { conversationId: record.conversationId } : {}
|
|
159
|
+
} : null;
|
|
160
|
+
const engineInner = /* @__PURE__ */ jsx(RecordAnnotations, { record: annotationSource, children: /* @__PURE__ */ jsx("div", { className: cn("rich-document__content", contentClassName), children: /* @__PURE__ */ jsx(
|
|
161
|
+
MarkdownStream,
|
|
162
|
+
{
|
|
163
|
+
imagePolicy,
|
|
164
|
+
content,
|
|
165
|
+
events,
|
|
166
|
+
serverProcessedBlocks,
|
|
167
|
+
taskId,
|
|
168
|
+
requestId,
|
|
169
|
+
turnId,
|
|
170
|
+
conversationId,
|
|
171
|
+
isStreamActive,
|
|
172
|
+
onContentChange,
|
|
173
|
+
applyLocalEdits,
|
|
174
|
+
analysisData,
|
|
175
|
+
messageId,
|
|
176
|
+
allowFullScreenEditor,
|
|
177
|
+
hideCopyButton,
|
|
178
|
+
onError,
|
|
179
|
+
onPhaseUpdate,
|
|
180
|
+
strictServerData
|
|
181
|
+
}
|
|
182
|
+
) }) });
|
|
183
|
+
let engine = engineInner;
|
|
184
|
+
const contextMenu = contextMenuFor(enableContextMenu, effectiveActionsVariant);
|
|
185
|
+
if (contextMenu && !specimenMode) {
|
|
186
|
+
const cmOptions = typeof contextMenu === "object" ? contextMenu : {};
|
|
187
|
+
engine = /* @__PURE__ */ jsx(
|
|
188
|
+
RegistryContextMenu,
|
|
189
|
+
{
|
|
190
|
+
content: content ?? "",
|
|
191
|
+
source,
|
|
192
|
+
actions: hostedActions,
|
|
193
|
+
extra: cmOptions.extra,
|
|
194
|
+
exclude: cmOptions.exclude,
|
|
195
|
+
suppressed: isStreamActive,
|
|
196
|
+
children: engineInner
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
if (specimenMode) {
|
|
201
|
+
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
202
|
+
/* @__PURE__ */ jsx(SpecimenBanner, { mode: specimenMode }),
|
|
203
|
+
/* @__PURE__ */ jsx(SpecimenProvider, { value: specimenMode, children: engine })
|
|
204
|
+
] });
|
|
205
|
+
}
|
|
206
|
+
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
207
|
+
isAbsolute ? actionsNode : null,
|
|
208
|
+
!isAbsolute && actionsPosition === "above" ? actionsNode : null,
|
|
209
|
+
engine,
|
|
210
|
+
!isAbsolute && actionsPosition !== "above" ? actionsNode : null,
|
|
211
|
+
dialogsHost.dialogs
|
|
212
|
+
] });
|
|
213
|
+
}
|
|
214
|
+
var RichDocument_default = RichDocument;
|
|
215
|
+
export {
|
|
216
|
+
RichDocument,
|
|
217
|
+
RichDocument_default as default
|
|
218
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ContentSource, RichDocumentActionsProp } from "./types.js";
|
|
3
|
+
export interface RichDocumentActionProviderProps {
|
|
4
|
+
/** Live content the actions operate on (re-read at click time via the bridge). */
|
|
5
|
+
content: string;
|
|
6
|
+
/** Source identity — drives which actions show + save-to-task parent linking. */
|
|
7
|
+
source: ContentSource;
|
|
8
|
+
/** The surface a <RichDocumentActionSurface/> consumes. Required. */
|
|
9
|
+
surfaceId: string;
|
|
10
|
+
/** Trim/extend the action set + supply host callbacks (same shape as RichDocument). */
|
|
11
|
+
actions?: RichDocumentActionsProp;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Registers a remote RichDocument action provider for `surfaceId`. Renders
|
|
15
|
+
* nothing. See the file header for when to reach for this over RichDocument.
|
|
16
|
+
*/
|
|
17
|
+
export declare function RichDocumentActionProvider(props: RichDocumentActionProviderProps): React.ReactElement | null;
|
|
18
|
+
export default RichDocumentActionProvider;
|