@ai-matrx/rich-content 0.2.18 → 0.2.20
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 +8 -1
- package/dist/copy/markdown-readable-text.js +18 -10
- package/dist/host/app-bindings.d.ts +18 -11
- package/dist/host/app-bindings.js +32 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.20
|
|
4
|
+
|
|
5
|
+
- Readable Markdown copy now uses Content IR's canonical fence opener and closer. Inline code made from four or more backticks remains prose, while closed, unclosed, and nested fenced-code bodies are copied without their outer fence.
|
|
6
|
+
|
|
7
|
+
### Consumer action
|
|
8
|
+
|
|
9
|
+
- None required. Public imports and host setup are unchanged.
|
|
10
|
+
|
|
3
11
|
## 0.2.10
|
|
4
12
|
|
|
5
13
|
- Markdown copy goes through the host's `app.CopyButtons` (the copy menu; matrx-frontend ALC-19).
|
|
@@ -133,4 +141,3 @@ held-back streaming text; the heal tests encode 1.3.1's behavior).
|
|
|
133
141
|
|
|
134
142
|
- matrx-frontend: call `configureRichContent` at the root (see README) and import from
|
|
135
143
|
`@ai-matrx/rich-content/<domain>/<module>`.
|
|
136
|
-
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
closeFence,
|
|
3
|
+
fenceOpenerOf,
|
|
4
|
+
fenceParts,
|
|
5
|
+
unwrapKindEnvelopes
|
|
6
|
+
} from "@ai-matrx/content-ir/source";
|
|
2
7
|
import {
|
|
3
8
|
findTableEnd,
|
|
4
9
|
rowCells,
|
|
5
10
|
tableStartsAt,
|
|
6
11
|
unescapeCellPipes
|
|
7
12
|
} from "../display/markdown-classification/processors/utils/gfm-table-lines.js";
|
|
8
|
-
const FENCE = /^( {0,3})(`{3,}|~{3,})/;
|
|
9
13
|
function readableInline(line) {
|
|
10
14
|
const codes = [];
|
|
11
15
|
let out = line.replace(/(`+)([\s\S]*?[^`])\1(?!`)/g, (_m, _ticks, body) => {
|
|
@@ -20,18 +24,22 @@ function readableInline(line) {
|
|
|
20
24
|
}
|
|
21
25
|
function markdownToReadableText(markdown) {
|
|
22
26
|
const lines = unwrapKindEnvelopes(markdown).replace(/\r\n?/g, "\n").split("\n");
|
|
27
|
+
const fenceLines = {
|
|
28
|
+
count: lines.length,
|
|
29
|
+
line: (line) => lines[line] ?? null
|
|
30
|
+
};
|
|
23
31
|
const out = [];
|
|
24
32
|
for (let i = 0; i < lines.length; i += 1) {
|
|
25
33
|
const line = lines[i];
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
const opener = fenceOpenerOf(line);
|
|
35
|
+
if (opener) {
|
|
36
|
+
const end = closeFence(fenceLines, i, opener);
|
|
37
|
+
const parts = fenceParts(lines.slice(i, end.line + 1).join("\n"));
|
|
38
|
+
if (parts) {
|
|
39
|
+
const bodyLineCount = end.line - i - (end.closed ? 1 : 0);
|
|
40
|
+
if (parts.body || bodyLineCount > 0) out.push(...parts.body.split("\n"));
|
|
33
41
|
}
|
|
34
|
-
i =
|
|
42
|
+
i = end.line;
|
|
35
43
|
continue;
|
|
36
44
|
}
|
|
37
45
|
if (tableStartsAt(lines, i)) {
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* APP BINDINGS — the host's own windows, records, canvas, menus and kind views that the engine's
|
|
3
|
-
* blocks offer when a host has them. Each export keeps the name the engine code used when it
|
|
4
|
-
* lived in matrx-frontend, so call sites read the same; each one delegates to
|
|
5
|
-
* `configureRichContent({ app: { … } })` and falls back to an honest default (absent control,
|
|
6
|
-
* plain rendering, announced once) on a bare host.
|
|
7
|
-
*
|
|
8
|
-
* Typing debt (recorded in FEATURE.md): these host callables are typed loosely (`HostFn`,
|
|
9
|
-
* `HostComponent`) because their real signatures live in the host app. Tighten each one when it
|
|
10
|
-
* gets a package-owned contract.
|
|
11
|
-
*/
|
|
12
1
|
import { type ComponentType } from "react";
|
|
13
2
|
export type HostFn = (...args: any[]) => any;
|
|
14
3
|
export type HostComponent = ComponentType<any>;
|
|
@@ -45,6 +34,15 @@ export interface RichContentAppBindings {
|
|
|
45
34
|
convertOriginForSource: HostFn;
|
|
46
35
|
useDocumentDialogsHost: HostFn;
|
|
47
36
|
RecordAnnotations: HostComponent;
|
|
37
|
+
ConfirmDialog: HostComponent;
|
|
38
|
+
TextInputDialog: HostComponent;
|
|
39
|
+
EditableContextMenu: HostComponent;
|
|
40
|
+
buildApplicationScopeFromMenuContext: HostFn;
|
|
41
|
+
useMicField: HostFn;
|
|
42
|
+
useFileUpload: HostFn;
|
|
43
|
+
fileUrls: HostFn;
|
|
44
|
+
searchKindDefinitions: HostFn;
|
|
45
|
+
kindCanonicalExample: HostFn;
|
|
48
46
|
annotationRecordOf: HostFn;
|
|
49
47
|
recordKeyOf: HostFn;
|
|
50
48
|
useMermaidPreferences: HostFn;
|
|
@@ -157,6 +155,15 @@ export declare const useDocumentDialogsHost: HostFn;
|
|
|
157
155
|
export declare const RecordAnnotations: HostComponent;
|
|
158
156
|
export declare const annotationRecordOf: HostFn;
|
|
159
157
|
export declare const recordKeyOf: HostFn;
|
|
158
|
+
export declare const ConfirmDialog: HostComponent;
|
|
159
|
+
export declare const TextInputDialog: HostComponent;
|
|
160
|
+
export declare const EditableContextMenu: HostComponent;
|
|
161
|
+
export declare const buildApplicationScopeFromMenuContext: HostFn;
|
|
162
|
+
export declare const useMicField: HostFn;
|
|
163
|
+
export declare const useFileUpload: HostFn;
|
|
164
|
+
export declare const fileUrls: HostFn;
|
|
165
|
+
export declare const searchKindDefinitions: HostFn;
|
|
166
|
+
export declare const kindCanonicalExample: HostFn;
|
|
160
167
|
export declare const MarkdownStream: HostComponent;
|
|
161
168
|
export declare const CitationMarkerInline: HostComponent;
|
|
162
169
|
export declare const CopyButtons: HostComponent;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { ConfirmDialog as DesignSystemConfirmDialog } from "@ai-matrx/design-system";
|
|
2
3
|
import { createElement } from "react";
|
|
3
4
|
import { GenericStructuredView } from "@ai-matrx/content-ir-react";
|
|
4
5
|
import { announceBareHost, BARE_HOST_ATTR, hostCapability } from "./registry.js";
|
|
@@ -86,6 +87,28 @@ const useDocumentDialogsHost = fn("useDocumentDialogsHost", () => ({ callbacks:
|
|
|
86
87
|
const RecordAnnotations = component("RecordAnnotations", Passthrough, "no reading set on saved records");
|
|
87
88
|
const annotationRecordOf = fn("annotationRecordOf", () => null, "no saved record is known");
|
|
88
89
|
const recordKeyOf = fn("recordKeyOf", (r) => `${r.token}:${r.id}`, "records key as token:id");
|
|
90
|
+
const ConfirmDialog = component("ConfirmDialog", DesignSystemConfirmDialog, "confirm dialogs open in the page, not the popout");
|
|
91
|
+
const TextInputDialog = component("TextInputDialog", null, "no text prompt dialog (link insertion is absent)");
|
|
92
|
+
const EditableContextMenu = component("EditableContextMenu", Passthrough, "no editor context menu");
|
|
93
|
+
const buildApplicationScopeFromMenuContext = fn("buildApplicationScopeFromMenuContext", () => ({}), "agents see no application scope");
|
|
94
|
+
const useMicField = fn(
|
|
95
|
+
"useMicField",
|
|
96
|
+
() => ({ available: false, isRecording: false, isTranscribing: false, handleVoiceClick: async () => {
|
|
97
|
+
} }),
|
|
98
|
+
"no dictation"
|
|
99
|
+
);
|
|
100
|
+
const useFileUpload = fn(
|
|
101
|
+
"useFileUpload",
|
|
102
|
+
() => ({
|
|
103
|
+
upload: async () => {
|
|
104
|
+
throw new Error("This app cannot upload files.");
|
|
105
|
+
}
|
|
106
|
+
}),
|
|
107
|
+
"images cannot be uploaded"
|
|
108
|
+
);
|
|
109
|
+
const fileUrls = fn("fileUrls", (id) => ({ inline: id }), "file links are the file id");
|
|
110
|
+
const searchKindDefinitions = fn("searchKindDefinitions", async () => [], "no kinds can be inserted");
|
|
111
|
+
const kindCanonicalExample = fn("kindCanonicalExample", async () => ({}), "an inserted kind starts empty");
|
|
89
112
|
const MarkdownStream = component("MarkdownStream", null, "the full renderer is not registered");
|
|
90
113
|
const CitationMarkerInline = component("CitationMarkerInline", TextOnly, "citation markers show as text");
|
|
91
114
|
const CopyButtons = component("CopyButtons", null, "no copy menu on rendered content");
|
|
@@ -129,7 +152,9 @@ export {
|
|
|
129
152
|
ArtifactRender,
|
|
130
153
|
CitationMarkerInline,
|
|
131
154
|
CodeBlockWithContextAttach,
|
|
155
|
+
ConfirmDialog,
|
|
132
156
|
CopyButtons,
|
|
157
|
+
EditableContextMenu,
|
|
133
158
|
EntityRef,
|
|
134
159
|
IconInputWithValidation,
|
|
135
160
|
InlineCopyButton,
|
|
@@ -146,12 +171,15 @@ export {
|
|
|
146
171
|
RawJsonExplorer,
|
|
147
172
|
RecordAnnotations,
|
|
148
173
|
StructuredValueView,
|
|
174
|
+
TextInputDialog,
|
|
149
175
|
annotationRecordOf,
|
|
150
176
|
announceProposedGoogleWrite,
|
|
177
|
+
buildApplicationScopeFromMenuContext,
|
|
151
178
|
contentSourceKey,
|
|
152
179
|
convertOriginForSource,
|
|
153
180
|
createMermaidEditorScope,
|
|
154
181
|
ensureOrganizationContext,
|
|
182
|
+
fileUrls,
|
|
155
183
|
getArtifactDef,
|
|
156
184
|
hasArtifactRenderer,
|
|
157
185
|
holdDeliberateIntent,
|
|
@@ -161,6 +189,7 @@ export {
|
|
|
161
189
|
imageKnobPrincipals,
|
|
162
190
|
isOrganizationSelectionCancelled,
|
|
163
191
|
isProposedGoogleWrite,
|
|
192
|
+
kindCanonicalExample,
|
|
164
193
|
kindHasRecordChrome,
|
|
165
194
|
loadExportTargets,
|
|
166
195
|
loadSendToGoogle,
|
|
@@ -169,6 +198,7 @@ export {
|
|
|
169
198
|
reportCanvasOpenDrop,
|
|
170
199
|
resolveArtifactDef,
|
|
171
200
|
sameContentSource,
|
|
201
|
+
searchKindDefinitions,
|
|
172
202
|
setImageKnobMapEntry,
|
|
173
203
|
useActiveOrganizationId,
|
|
174
204
|
useAdvancedMenu,
|
|
@@ -177,6 +207,7 @@ export {
|
|
|
177
207
|
useCanvasOpenGuard,
|
|
178
208
|
useDiagramAgents,
|
|
179
209
|
useDocumentDialogsHost,
|
|
210
|
+
useFileUpload,
|
|
180
211
|
useHideReasoning,
|
|
181
212
|
useHideToolResults,
|
|
182
213
|
useHostDispatch,
|
|
@@ -188,6 +219,7 @@ export {
|
|
|
188
219
|
useIsSuperAdmin,
|
|
189
220
|
useMachineFramesVisible,
|
|
190
221
|
useMermaidPreferences,
|
|
222
|
+
useMicField,
|
|
191
223
|
useOpenArtifactInCanvas,
|
|
192
224
|
useOpenConvertToShapeWindow,
|
|
193
225
|
useOpenOverlay,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/rich-content",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.20",
|
|
4
4
|
"description": "The AI Matrx formatted-text engine: the one markdown renderer, streaming markdown, the block splitter and renderer, the generic blocks, <RichContent> levels, the rich-document action registry and menus, copy, and the selection toolbar — as portable React.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -130,9 +130,9 @@
|
|
|
130
130
|
"unist-util-visit": "^5.1.0",
|
|
131
131
|
"unist-util-visit-parents": "^6.0.2",
|
|
132
132
|
"yaml": "^2.9.1",
|
|
133
|
-
"@ai-matrx/canvas": "latest",
|
|
134
133
|
"@ai-matrx/agents": "latest",
|
|
135
134
|
"@ai-matrx/alchemy": "latest",
|
|
135
|
+
"@ai-matrx/canvas": "latest",
|
|
136
136
|
"@ai-matrx/content-ir": "latest",
|
|
137
137
|
"@ai-matrx/content-ir-react": "latest",
|
|
138
138
|
"@ai-matrx/data": "latest",
|
|
@@ -140,9 +140,9 @@
|
|
|
140
140
|
"@ai-matrx/diff": "latest",
|
|
141
141
|
"@ai-matrx/icons": "latest",
|
|
142
142
|
"@ai-matrx/kit": "latest",
|
|
143
|
+
"@ai-matrx/media": "latest",
|
|
143
144
|
"@ai-matrx/print": "latest",
|
|
144
145
|
"@ai-matrx/records": "latest",
|
|
145
|
-
"@ai-matrx/media": "latest",
|
|
146
146
|
"@ai-matrx/records-ui": "latest",
|
|
147
147
|
"@ai-matrx/tap-target": "latest"
|
|
148
148
|
},
|