@xnetjs/plugins 1.0.0 → 2.0.0
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/dist/index.d.ts +126 -47
- package/dist/index.js +541 -14
- package/dist/services/node.d.ts +80 -3
- package/dist/services/node.js +529 -14
- package/package.json +6 -7
package/dist/index.js
CHANGED
|
@@ -1978,25 +1978,37 @@ async function resolveMentionProviders(providers, trigger, query, options = {})
|
|
|
1978
1978
|
}
|
|
1979
1979
|
|
|
1980
1980
|
// src/editor-schema-safety.ts
|
|
1981
|
-
function
|
|
1982
|
-
return
|
|
1981
|
+
function collectSpecNames(contribution) {
|
|
1982
|
+
return [
|
|
1983
|
+
...Object.keys(contribution.blockSpecs ?? {}).map((name) => ({ kind: "block", name })),
|
|
1984
|
+
...Object.keys(contribution.inlineContentSpecs ?? {}).map((name) => ({
|
|
1985
|
+
kind: "inlineContent",
|
|
1986
|
+
name
|
|
1987
|
+
})),
|
|
1988
|
+
...Object.keys(contribution.styleSpecs ?? {}).map((name) => ({ kind: "style", name }))
|
|
1989
|
+
];
|
|
1990
|
+
}
|
|
1991
|
+
function isSchemaDefiningContribution(contribution) {
|
|
1992
|
+
return collectSpecNames(contribution).length > 0;
|
|
1983
1993
|
}
|
|
1984
|
-
function findEditorSchemaRisks(contributions) {
|
|
1994
|
+
function findEditorSchemaRisks(contributions, bundledSpecNames = []) {
|
|
1995
|
+
const bundled = new Set(bundledSpecNames);
|
|
1985
1996
|
const risks = [];
|
|
1986
1997
|
for (const c of contributions) {
|
|
1987
|
-
const
|
|
1988
|
-
|
|
1989
|
-
|
|
1998
|
+
for (const spec of collectSpecNames(c)) {
|
|
1999
|
+
if (!bundled.has(spec.name)) {
|
|
2000
|
+
risks.push({ id: c.id, kind: spec.kind, name: spec.name });
|
|
2001
|
+
}
|
|
1990
2002
|
}
|
|
1991
2003
|
}
|
|
1992
2004
|
return risks;
|
|
1993
2005
|
}
|
|
1994
|
-
function warnOnEditorSchemaRisks(pluginId, contributions) {
|
|
1995
|
-
const risks = findEditorSchemaRisks(contributions);
|
|
2006
|
+
function warnOnEditorSchemaRisks(pluginId, contributions, bundledSpecNames = []) {
|
|
2007
|
+
const risks = findEditorSchemaRisks(contributions, bundledSpecNames);
|
|
1996
2008
|
if (risks.length > 0 && process.env.NODE_ENV !== "production") {
|
|
1997
2009
|
for (const r of risks) {
|
|
1998
2010
|
console.warn(
|
|
1999
|
-
`[plugins] '${pluginId}' editor contribution '${r.id}' adds a schema ${r.kind} ('${r.name}'). Schema-defining
|
|
2011
|
+
`[plugins] '${pluginId}' editor contribution '${r.id}' adds a schema ${r.kind} spec ('${r.name}') that is not statically bundled. Schema-defining specs must be present for ALL collaborators or Yjs will silently drop content across version skew. Ship schema specs in the bundled core and contribute only the UI affordance (slash menu items).`
|
|
2000
2012
|
);
|
|
2001
2013
|
}
|
|
2002
2014
|
}
|
|
@@ -6291,7 +6303,7 @@ var applyPageMarkdownTool = {
|
|
|
6291
6303
|
definition: {
|
|
6292
6304
|
name: "xnet_apply_page_markdown",
|
|
6293
6305
|
title: "Apply page Markdown plan",
|
|
6294
|
-
description: "Apply a validated page Markdown mutation plan through the configured
|
|
6306
|
+
description: "Apply a validated page Markdown mutation plan through the configured BlockNote/Yjs document adapter, with a node-property fallback.",
|
|
6295
6307
|
risk: "high",
|
|
6296
6308
|
requiredScopes: ["page.read", "page.write"],
|
|
6297
6309
|
inputSchema: {
|
|
@@ -9007,6 +9019,514 @@ function quoteYaml(value) {
|
|
|
9007
9019
|
return JSON.stringify(value);
|
|
9008
9020
|
}
|
|
9009
9021
|
|
|
9022
|
+
// src/ai-surface/page-fragment.ts
|
|
9023
|
+
import * as Y from "yjs";
|
|
9024
|
+
var XNET_PAGE_FRAGMENT_FIELD = "content-v4";
|
|
9025
|
+
var XNET_PAGE_LEGACY_FRAGMENT_FIELD = "content";
|
|
9026
|
+
function isRecord5(value) {
|
|
9027
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9028
|
+
}
|
|
9029
|
+
function attrString(attrs, ...keys) {
|
|
9030
|
+
for (const key of keys) {
|
|
9031
|
+
const value = attrs[key];
|
|
9032
|
+
if (value !== void 0 && value !== null && value !== "") return String(value);
|
|
9033
|
+
}
|
|
9034
|
+
return "";
|
|
9035
|
+
}
|
|
9036
|
+
function markWrap(text3, attributes) {
|
|
9037
|
+
if (!attributes || text3 === "") return text3;
|
|
9038
|
+
let out = text3;
|
|
9039
|
+
if (attributes.code) out = `\`${out}\``;
|
|
9040
|
+
if (attributes.bold) out = `**${out}**`;
|
|
9041
|
+
if (attributes.italic) out = `*${out}*`;
|
|
9042
|
+
const link = attributes.link;
|
|
9043
|
+
const href = isRecord5(link) ? link.href : link;
|
|
9044
|
+
if (typeof href === "string" && href) out = `[${out}](${href})`;
|
|
9045
|
+
return out;
|
|
9046
|
+
}
|
|
9047
|
+
function textToMarkdown(node) {
|
|
9048
|
+
let out = "";
|
|
9049
|
+
const delta = node.toDelta();
|
|
9050
|
+
for (const op of delta) {
|
|
9051
|
+
if (typeof op.insert === "string") {
|
|
9052
|
+
out += markWrap(op.insert, op.attributes);
|
|
9053
|
+
} else if (isRecord5(op.insert)) {
|
|
9054
|
+
out += embeddedAtomToMarkdown(op.insert);
|
|
9055
|
+
}
|
|
9056
|
+
}
|
|
9057
|
+
return out;
|
|
9058
|
+
}
|
|
9059
|
+
function embeddedAtomToMarkdown(embed) {
|
|
9060
|
+
const type = typeof embed.type === "string" ? embed.type : "";
|
|
9061
|
+
const attrs = isRecord5(embed.attrs) ? embed.attrs : embed;
|
|
9062
|
+
return atomToMarkdown(type, attrs) ?? "";
|
|
9063
|
+
}
|
|
9064
|
+
function atomToMarkdown(name, attrs) {
|
|
9065
|
+
switch (name) {
|
|
9066
|
+
case "mention":
|
|
9067
|
+
case "personMention":
|
|
9068
|
+
case "taskMention":
|
|
9069
|
+
return `@${attrString(attrs, "label", "id")}`;
|
|
9070
|
+
case "hashtag":
|
|
9071
|
+
return `#${attrString(attrs, "name")}`;
|
|
9072
|
+
case "wikilink":
|
|
9073
|
+
return `[[${attrString(attrs, "title", "href")}]]`;
|
|
9074
|
+
case "inlineMath":
|
|
9075
|
+
return `$${attrString(attrs, "latex")}$`;
|
|
9076
|
+
case "smartReference":
|
|
9077
|
+
case "databaseReference":
|
|
9078
|
+
return attrString(attrs, "title", "url", "databaseId");
|
|
9079
|
+
case "emoji": {
|
|
9080
|
+
const emoji = attrString(attrs, "name");
|
|
9081
|
+
return emoji ? `:${emoji}:` : "";
|
|
9082
|
+
}
|
|
9083
|
+
default:
|
|
9084
|
+
return null;
|
|
9085
|
+
}
|
|
9086
|
+
}
|
|
9087
|
+
function inlineToMarkdown(element) {
|
|
9088
|
+
let out = "";
|
|
9089
|
+
for (let i = 0; i < element.length; i++) {
|
|
9090
|
+
const child = element.get(i);
|
|
9091
|
+
if (child instanceof Y.XmlText) {
|
|
9092
|
+
out += textToMarkdown(child);
|
|
9093
|
+
} else if (child instanceof Y.XmlElement) {
|
|
9094
|
+
const atom = atomToMarkdown(child.nodeName, child.getAttributes());
|
|
9095
|
+
out += atom ?? inlineToMarkdown(child);
|
|
9096
|
+
}
|
|
9097
|
+
}
|
|
9098
|
+
return out;
|
|
9099
|
+
}
|
|
9100
|
+
var LIST_ITEM_TYPES = /* @__PURE__ */ new Set(["bulletListItem", "numberedListItem", "checkListItem"]);
|
|
9101
|
+
function elementChildren(element) {
|
|
9102
|
+
const children = [];
|
|
9103
|
+
for (let i = 0; i < element.length; i++) {
|
|
9104
|
+
const child = element.get(i);
|
|
9105
|
+
if (child instanceof Y.XmlElement) children.push(child);
|
|
9106
|
+
}
|
|
9107
|
+
return children;
|
|
9108
|
+
}
|
|
9109
|
+
function joinChunks(chunks) {
|
|
9110
|
+
let out = "";
|
|
9111
|
+
chunks.forEach((chunk, index) => {
|
|
9112
|
+
if (index > 0) {
|
|
9113
|
+
const previous = chunks[index - 1];
|
|
9114
|
+
out += previous.kind === "list" && chunk.kind === "list" ? "\n" : "\n\n";
|
|
9115
|
+
}
|
|
9116
|
+
out += chunk.text;
|
|
9117
|
+
});
|
|
9118
|
+
return out;
|
|
9119
|
+
}
|
|
9120
|
+
function indentLines(text3, indent) {
|
|
9121
|
+
return text3.split("\n").map((line) => line ? indent + line : line).join("\n");
|
|
9122
|
+
}
|
|
9123
|
+
function tableToMarkdown(table) {
|
|
9124
|
+
const rows = [];
|
|
9125
|
+
const visit = (element) => {
|
|
9126
|
+
for (const child of elementChildren(element)) {
|
|
9127
|
+
if (child.nodeName === "tableRow") {
|
|
9128
|
+
const cells = [];
|
|
9129
|
+
for (const cell of elementChildren(child)) {
|
|
9130
|
+
if (cell.nodeName === "tableCell" || cell.nodeName === "tableHeader") {
|
|
9131
|
+
cells.push(inlineToMarkdown(cell).replace(/\n/g, " ").trim());
|
|
9132
|
+
}
|
|
9133
|
+
}
|
|
9134
|
+
rows.push(cells);
|
|
9135
|
+
} else {
|
|
9136
|
+
visit(child);
|
|
9137
|
+
}
|
|
9138
|
+
}
|
|
9139
|
+
};
|
|
9140
|
+
visit(table);
|
|
9141
|
+
if (rows.length === 0) return "";
|
|
9142
|
+
const lines = [`| ${rows[0].join(" | ")} |`, `| ${rows[0].map(() => "---").join(" | ")} |`];
|
|
9143
|
+
for (const row of rows.slice(1)) lines.push(`| ${row.join(" | ")} |`);
|
|
9144
|
+
return lines.join("\n");
|
|
9145
|
+
}
|
|
9146
|
+
function blockContentToMarkdown(content, orderedIndex) {
|
|
9147
|
+
const attrs = content.getAttributes();
|
|
9148
|
+
switch (content.nodeName) {
|
|
9149
|
+
case "paragraph":
|
|
9150
|
+
return inlineToMarkdown(content);
|
|
9151
|
+
case "heading": {
|
|
9152
|
+
const level = Math.min(Math.max(Number(attrs.level ?? 1) || 1, 1), 6);
|
|
9153
|
+
return `${"#".repeat(level)} ${inlineToMarkdown(content)}`;
|
|
9154
|
+
}
|
|
9155
|
+
case "bulletListItem":
|
|
9156
|
+
return `- ${inlineToMarkdown(content)}`;
|
|
9157
|
+
case "numberedListItem":
|
|
9158
|
+
return `${orderedIndex}. ${inlineToMarkdown(content)}`;
|
|
9159
|
+
case "checkListItem": {
|
|
9160
|
+
const checked = attrs.checked === true || attrs.checked === "true";
|
|
9161
|
+
return `- [${checked ? "x" : " "}] ${inlineToMarkdown(content)}`;
|
|
9162
|
+
}
|
|
9163
|
+
case "codeBlock": {
|
|
9164
|
+
const language = typeof attrs.language === "string" ? attrs.language : "";
|
|
9165
|
+
return `\`\`\`${language}
|
|
9166
|
+
${inlineToMarkdown(content)}
|
|
9167
|
+
\`\`\``;
|
|
9168
|
+
}
|
|
9169
|
+
case "quote":
|
|
9170
|
+
return inlineToMarkdown(content).split("\n").map((line) => `> ${line}`).join("\n");
|
|
9171
|
+
case "callout": {
|
|
9172
|
+
const kind = attrString(attrs, "kind") || "info";
|
|
9173
|
+
return `> [!${kind}] ${inlineToMarkdown(content)}`;
|
|
9174
|
+
}
|
|
9175
|
+
case "table":
|
|
9176
|
+
return tableToMarkdown(content);
|
|
9177
|
+
case "mermaid":
|
|
9178
|
+
return `\`\`\`mermaid
|
|
9179
|
+
${attrString(attrs, "code") || inlineToMarkdown(content)}
|
|
9180
|
+
\`\`\``;
|
|
9181
|
+
case "embed":
|
|
9182
|
+
case "richLink":
|
|
9183
|
+
return attrString(attrs, "url");
|
|
9184
|
+
case "pageEmbed":
|
|
9185
|
+
return `[[${attrString(attrs, "title", "nodeId")}]]`;
|
|
9186
|
+
case "image":
|
|
9187
|
+
return `})`;
|
|
9188
|
+
case "divider":
|
|
9189
|
+
case "horizontalRule":
|
|
9190
|
+
return "---";
|
|
9191
|
+
default:
|
|
9192
|
+
return inlineToMarkdown(content);
|
|
9193
|
+
}
|
|
9194
|
+
}
|
|
9195
|
+
function blockGroupToChunks(group) {
|
|
9196
|
+
const chunks = [];
|
|
9197
|
+
let orderedIndex = 0;
|
|
9198
|
+
for (const container of elementChildren(group)) {
|
|
9199
|
+
if (container.nodeName !== "blockContainer") {
|
|
9200
|
+
chunks.push(...blockGroupToChunks(container));
|
|
9201
|
+
continue;
|
|
9202
|
+
}
|
|
9203
|
+
const children = elementChildren(container);
|
|
9204
|
+
const content = children.find((child) => child.nodeName !== "blockGroup") ?? null;
|
|
9205
|
+
const childGroup = children.find((child) => child.nodeName === "blockGroup") ?? null;
|
|
9206
|
+
const type = content?.nodeName ?? "";
|
|
9207
|
+
orderedIndex = type === "numberedListItem" ? orderedIndex + 1 : 0;
|
|
9208
|
+
const kind = LIST_ITEM_TYPES.has(type) ? "list" : "block";
|
|
9209
|
+
let text3 = content ? blockContentToMarkdown(content, orderedIndex) : "";
|
|
9210
|
+
if (childGroup) {
|
|
9211
|
+
const nested = joinChunks(blockGroupToChunks(childGroup));
|
|
9212
|
+
if (nested) {
|
|
9213
|
+
const separator = kind === "list" ? "\n" : "\n\n";
|
|
9214
|
+
text3 = text3 ? `${text3}${separator}${indentLines(nested, " ")}` : indentLines(nested, " ");
|
|
9215
|
+
}
|
|
9216
|
+
}
|
|
9217
|
+
if (text3.trim()) chunks.push({ text: text3, kind });
|
|
9218
|
+
}
|
|
9219
|
+
return chunks;
|
|
9220
|
+
}
|
|
9221
|
+
function blockNoteFragmentToMarkdown(fragment) {
|
|
9222
|
+
return joinChunks(blockGroupToChunks(fragment));
|
|
9223
|
+
}
|
|
9224
|
+
function legacyBlockToLines(element, lines) {
|
|
9225
|
+
const attrs = element.getAttributes();
|
|
9226
|
+
switch (element.nodeName) {
|
|
9227
|
+
case "paragraph": {
|
|
9228
|
+
const text3 = inlineToMarkdown(element);
|
|
9229
|
+
if (text3.trim()) lines.push(text3);
|
|
9230
|
+
break;
|
|
9231
|
+
}
|
|
9232
|
+
case "heading": {
|
|
9233
|
+
const level = Math.min(Math.max(Number(attrs.level ?? 1) || 1, 1), 6);
|
|
9234
|
+
lines.push(`${"#".repeat(level)} ${inlineToMarkdown(element)}`);
|
|
9235
|
+
break;
|
|
9236
|
+
}
|
|
9237
|
+
case "codeBlock": {
|
|
9238
|
+
const language = typeof attrs.language === "string" ? attrs.language : "";
|
|
9239
|
+
lines.push(`\`\`\`${language}
|
|
9240
|
+
${inlineToMarkdown(element)}
|
|
9241
|
+
\`\`\``);
|
|
9242
|
+
break;
|
|
9243
|
+
}
|
|
9244
|
+
case "blockquote":
|
|
9245
|
+
case "callout": {
|
|
9246
|
+
const inner = [];
|
|
9247
|
+
legacyChildrenToLines(element, inner);
|
|
9248
|
+
lines.push(inner.map((line) => indentLines(line, "> ").replace(/^> $/gm, ">")).join("\n>\n"));
|
|
9249
|
+
break;
|
|
9250
|
+
}
|
|
9251
|
+
case "bulletList":
|
|
9252
|
+
legacyListToLines(element, false, lines);
|
|
9253
|
+
break;
|
|
9254
|
+
case "orderedList":
|
|
9255
|
+
legacyListToLines(element, true, lines);
|
|
9256
|
+
break;
|
|
9257
|
+
case "taskList":
|
|
9258
|
+
legacyTaskListToLines(element, lines);
|
|
9259
|
+
break;
|
|
9260
|
+
case "horizontalRule":
|
|
9261
|
+
lines.push("---");
|
|
9262
|
+
break;
|
|
9263
|
+
case "image":
|
|
9264
|
+
lines.push(`})`);
|
|
9265
|
+
break;
|
|
9266
|
+
case "embed":
|
|
9267
|
+
case "richLink":
|
|
9268
|
+
lines.push(attrString(attrs, "url"));
|
|
9269
|
+
break;
|
|
9270
|
+
case "pageEmbed":
|
|
9271
|
+
lines.push(`[[${attrString(attrs, "title", "nodeId")}]]`);
|
|
9272
|
+
break;
|
|
9273
|
+
case "mermaid":
|
|
9274
|
+
lines.push(`\`\`\`mermaid
|
|
9275
|
+
${attrString(attrs, "code") || inlineToMarkdown(element)}
|
|
9276
|
+
\`\`\``);
|
|
9277
|
+
break;
|
|
9278
|
+
default:
|
|
9279
|
+
if (element.length > 0 && elementChildren(element).length > 0) {
|
|
9280
|
+
legacyChildrenToLines(element, lines);
|
|
9281
|
+
} else {
|
|
9282
|
+
const text3 = inlineToMarkdown(element);
|
|
9283
|
+
if (text3.trim()) lines.push(text3);
|
|
9284
|
+
}
|
|
9285
|
+
}
|
|
9286
|
+
}
|
|
9287
|
+
function legacyListToLines(element, ordered, lines) {
|
|
9288
|
+
const items = [];
|
|
9289
|
+
let index = 1;
|
|
9290
|
+
for (const child of elementChildren(element)) {
|
|
9291
|
+
if (child.nodeName !== "listItem") continue;
|
|
9292
|
+
const inner = [];
|
|
9293
|
+
legacyChildrenToLines(child, inner);
|
|
9294
|
+
const marker = ordered ? `${index}.` : "-";
|
|
9295
|
+
items.push(`${marker} ${indentLines(inner.join("\n"), " ").trimStart()}`);
|
|
9296
|
+
index += 1;
|
|
9297
|
+
}
|
|
9298
|
+
if (items.length > 0) lines.push(items.join("\n"));
|
|
9299
|
+
}
|
|
9300
|
+
function legacyTaskListToLines(element, lines) {
|
|
9301
|
+
const items = [];
|
|
9302
|
+
for (const child of elementChildren(element)) {
|
|
9303
|
+
if (child.nodeName !== "taskItem") continue;
|
|
9304
|
+
const checkedAttr = child.getAttribute("checked");
|
|
9305
|
+
const checked = checkedAttr === true || checkedAttr === "true";
|
|
9306
|
+
const inner = [];
|
|
9307
|
+
legacyChildrenToLines(child, inner);
|
|
9308
|
+
items.push(`- [${checked ? "x" : " "}] ${indentLines(inner.join("\n"), " ").trimStart()}`);
|
|
9309
|
+
}
|
|
9310
|
+
if (items.length > 0) lines.push(items.join("\n"));
|
|
9311
|
+
}
|
|
9312
|
+
function legacyChildrenToLines(element, lines) {
|
|
9313
|
+
for (let i = 0; i < element.length; i++) {
|
|
9314
|
+
const child = element.get(i);
|
|
9315
|
+
if (child instanceof Y.XmlElement) {
|
|
9316
|
+
legacyBlockToLines(child, lines);
|
|
9317
|
+
} else if (child instanceof Y.XmlText) {
|
|
9318
|
+
const text3 = textToMarkdown(child);
|
|
9319
|
+
if (text3.trim()) lines.push(text3);
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9322
|
+
}
|
|
9323
|
+
function legacyFragmentToMarkdown(fragment) {
|
|
9324
|
+
const lines = [];
|
|
9325
|
+
legacyChildrenToLines(fragment, lines);
|
|
9326
|
+
return lines.join("\n\n");
|
|
9327
|
+
}
|
|
9328
|
+
function xnetPageFragmentToMarkdown(doc, options = {}) {
|
|
9329
|
+
const fragment = doc.getXmlFragment(options.field ?? XNET_PAGE_FRAGMENT_FIELD);
|
|
9330
|
+
if (fragment.length > 0) return blockNoteFragmentToMarkdown(fragment);
|
|
9331
|
+
const legacy = doc.getXmlFragment(options.legacyField ?? XNET_PAGE_LEGACY_FRAGMENT_FIELD);
|
|
9332
|
+
if (legacy.length > 0) return legacyFragmentToMarkdown(legacy);
|
|
9333
|
+
return "";
|
|
9334
|
+
}
|
|
9335
|
+
var HEADING_PATTERN = /^(#{1,6})\s+(.*)$/;
|
|
9336
|
+
var FENCE_PATTERN = /^```([A-Za-z0-9_-]*)\s*$/;
|
|
9337
|
+
var LIST_ITEM_PATTERN = /^(\s*)(?:([-*+])|(\d+)[.)])\s+(.*)$/;
|
|
9338
|
+
var CHECK_PATTERN = /^\[([ xX])\]\s+(.*)$/;
|
|
9339
|
+
var CALLOUT_PATTERN = /^\[!([a-z][a-z0-9-]*)\]\s?(.*)$/i;
|
|
9340
|
+
function parseMarkdownBlocks(markdown) {
|
|
9341
|
+
const lines = markdown.replace(/\r\n/g, "\n").split("\n");
|
|
9342
|
+
const blocks = [];
|
|
9343
|
+
let listStack = [];
|
|
9344
|
+
let index = 0;
|
|
9345
|
+
const pushTop = (block) => {
|
|
9346
|
+
blocks.push(block);
|
|
9347
|
+
listStack = [];
|
|
9348
|
+
};
|
|
9349
|
+
while (index < lines.length) {
|
|
9350
|
+
const line = lines[index];
|
|
9351
|
+
if (!line.trim()) {
|
|
9352
|
+
index += 1;
|
|
9353
|
+
listStack = [];
|
|
9354
|
+
continue;
|
|
9355
|
+
}
|
|
9356
|
+
const fence = FENCE_PATTERN.exec(line.trim());
|
|
9357
|
+
if (fence) {
|
|
9358
|
+
const code = [];
|
|
9359
|
+
index += 1;
|
|
9360
|
+
while (index < lines.length && !/^```\s*$/.test(lines[index].trim())) {
|
|
9361
|
+
code.push(lines[index]);
|
|
9362
|
+
index += 1;
|
|
9363
|
+
}
|
|
9364
|
+
index += 1;
|
|
9365
|
+
pushTop({
|
|
9366
|
+
type: "codeBlock",
|
|
9367
|
+
props: fence[1] ? { language: fence[1] } : {},
|
|
9368
|
+
text: code.join("\n"),
|
|
9369
|
+
children: []
|
|
9370
|
+
});
|
|
9371
|
+
continue;
|
|
9372
|
+
}
|
|
9373
|
+
const heading = HEADING_PATTERN.exec(line);
|
|
9374
|
+
if (heading) {
|
|
9375
|
+
pushTop({
|
|
9376
|
+
type: "heading",
|
|
9377
|
+
props: { level: heading[1].length },
|
|
9378
|
+
text: heading[2],
|
|
9379
|
+
children: []
|
|
9380
|
+
});
|
|
9381
|
+
index += 1;
|
|
9382
|
+
continue;
|
|
9383
|
+
}
|
|
9384
|
+
const listItem = LIST_ITEM_PATTERN.exec(line);
|
|
9385
|
+
if (listItem) {
|
|
9386
|
+
const indent = Math.floor(listItem[1].replace(/\t/g, " ").length / 2);
|
|
9387
|
+
const rest = listItem[4];
|
|
9388
|
+
const check = listItem[2] ? CHECK_PATTERN.exec(rest) : null;
|
|
9389
|
+
const block = check ? {
|
|
9390
|
+
type: "checkListItem",
|
|
9391
|
+
props: { checked: check[1] !== " " },
|
|
9392
|
+
text: check[2],
|
|
9393
|
+
children: []
|
|
9394
|
+
} : {
|
|
9395
|
+
type: listItem[3] ? "numberedListItem" : "bulletListItem",
|
|
9396
|
+
props: {},
|
|
9397
|
+
text: rest,
|
|
9398
|
+
children: []
|
|
9399
|
+
};
|
|
9400
|
+
while (listStack.length > 0 && listStack[listStack.length - 1].indent >= indent) {
|
|
9401
|
+
listStack.pop();
|
|
9402
|
+
}
|
|
9403
|
+
const parent = listStack[listStack.length - 1];
|
|
9404
|
+
if (parent) {
|
|
9405
|
+
parent.block.children.push(block);
|
|
9406
|
+
} else {
|
|
9407
|
+
blocks.push(block);
|
|
9408
|
+
}
|
|
9409
|
+
listStack.push({ indent, block });
|
|
9410
|
+
index += 1;
|
|
9411
|
+
continue;
|
|
9412
|
+
}
|
|
9413
|
+
if (line.startsWith(">")) {
|
|
9414
|
+
const quoted = [];
|
|
9415
|
+
while (index < lines.length && lines[index].startsWith(">")) {
|
|
9416
|
+
quoted.push(lines[index].replace(/^>\s?/, ""));
|
|
9417
|
+
index += 1;
|
|
9418
|
+
}
|
|
9419
|
+
const callout = CALLOUT_PATTERN.exec(quoted[0] ?? "");
|
|
9420
|
+
if (callout) {
|
|
9421
|
+
pushTop({
|
|
9422
|
+
type: "callout",
|
|
9423
|
+
props: { kind: callout[1].toLowerCase() },
|
|
9424
|
+
text: [callout[2], ...quoted.slice(1)].filter((part) => part !== "").join("\n"),
|
|
9425
|
+
children: []
|
|
9426
|
+
});
|
|
9427
|
+
} else {
|
|
9428
|
+
pushTop({ type: "quote", props: {}, text: quoted.join("\n"), children: [] });
|
|
9429
|
+
}
|
|
9430
|
+
continue;
|
|
9431
|
+
}
|
|
9432
|
+
const paragraph = [line];
|
|
9433
|
+
index += 1;
|
|
9434
|
+
while (index < lines.length) {
|
|
9435
|
+
const next = lines[index];
|
|
9436
|
+
if (!next.trim() || HEADING_PATTERN.test(next) || FENCE_PATTERN.test(next.trim()) || LIST_ITEM_PATTERN.test(next) || next.startsWith(">")) {
|
|
9437
|
+
break;
|
|
9438
|
+
}
|
|
9439
|
+
paragraph.push(next);
|
|
9440
|
+
index += 1;
|
|
9441
|
+
}
|
|
9442
|
+
pushTop({ type: "paragraph", props: {}, text: paragraph.join("\n"), children: [] });
|
|
9443
|
+
}
|
|
9444
|
+
return blocks;
|
|
9445
|
+
}
|
|
9446
|
+
var blockIdCounter = 0;
|
|
9447
|
+
function defaultBlockId() {
|
|
9448
|
+
const cryptoApi = globalThis.crypto;
|
|
9449
|
+
if (cryptoApi?.randomUUID) return cryptoApi.randomUUID();
|
|
9450
|
+
blockIdCounter += 1;
|
|
9451
|
+
return `ai-block-${Date.now().toString(36)}-${blockIdCounter}`;
|
|
9452
|
+
}
|
|
9453
|
+
function setAttr(element, name, value) {
|
|
9454
|
+
element.setAttribute(name, value);
|
|
9455
|
+
}
|
|
9456
|
+
var WIKILINK_SPLIT = /(\[\[[^\]\n]+\]\])/;
|
|
9457
|
+
function inlineNodesForText(text3) {
|
|
9458
|
+
const nodes = [];
|
|
9459
|
+
for (const part of text3.split(WIKILINK_SPLIT)) {
|
|
9460
|
+
if (!part) continue;
|
|
9461
|
+
const wikilink = /^\[\[([^\]\n]+)\]\]$/.exec(part);
|
|
9462
|
+
if (wikilink) {
|
|
9463
|
+
const atom = new Y.XmlElement("wikilink");
|
|
9464
|
+
setAttr(atom, "title", wikilink[1]);
|
|
9465
|
+
setAttr(atom, "href", "");
|
|
9466
|
+
nodes.push(atom);
|
|
9467
|
+
} else {
|
|
9468
|
+
nodes.push(new Y.XmlText(part));
|
|
9469
|
+
}
|
|
9470
|
+
}
|
|
9471
|
+
return nodes;
|
|
9472
|
+
}
|
|
9473
|
+
function blockToYElement(block, generateBlockId) {
|
|
9474
|
+
const container = new Y.XmlElement("blockContainer");
|
|
9475
|
+
setAttr(container, "id", generateBlockId());
|
|
9476
|
+
const content = new Y.XmlElement(block.type);
|
|
9477
|
+
for (const [key, value] of Object.entries(block.props)) setAttr(content, key, value);
|
|
9478
|
+
if (block.type === "codeBlock") {
|
|
9479
|
+
if (block.text) content.insert(0, [new Y.XmlText(block.text)]);
|
|
9480
|
+
} else if (block.text) {
|
|
9481
|
+
content.insert(0, inlineNodesForText(block.text));
|
|
9482
|
+
}
|
|
9483
|
+
container.insert(0, [content]);
|
|
9484
|
+
if (block.children.length > 0) {
|
|
9485
|
+
const group = new Y.XmlElement("blockGroup");
|
|
9486
|
+
group.insert(
|
|
9487
|
+
0,
|
|
9488
|
+
block.children.map((child) => blockToYElement(child, generateBlockId))
|
|
9489
|
+
);
|
|
9490
|
+
container.insert(1, [group]);
|
|
9491
|
+
}
|
|
9492
|
+
return container;
|
|
9493
|
+
}
|
|
9494
|
+
function replaceXNetPageFragmentWithMarkdown(doc, markdown, options = {}) {
|
|
9495
|
+
const fragment = doc.getXmlFragment(options.field ?? XNET_PAGE_FRAGMENT_FIELD);
|
|
9496
|
+
const generateBlockId = options.generateBlockId ?? defaultBlockId;
|
|
9497
|
+
const blocks = parseMarkdownBlocks(markdown);
|
|
9498
|
+
doc.transact(() => {
|
|
9499
|
+
if (fragment.length > 0) fragment.delete(0, fragment.length);
|
|
9500
|
+
if (blocks.length === 0) return;
|
|
9501
|
+
const group = new Y.XmlElement("blockGroup");
|
|
9502
|
+
fragment.insert(0, [group]);
|
|
9503
|
+
group.insert(
|
|
9504
|
+
0,
|
|
9505
|
+
blocks.map((block) => blockToYElement(block, generateBlockId))
|
|
9506
|
+
);
|
|
9507
|
+
});
|
|
9508
|
+
}
|
|
9509
|
+
function createBlockNotePageMarkdownAdapter(options) {
|
|
9510
|
+
const field = options.field ?? XNET_PAGE_FRAGMENT_FIELD;
|
|
9511
|
+
return {
|
|
9512
|
+
applyMarkdown: async ({ pageId, bodyMarkdown }) => {
|
|
9513
|
+
const doc = await options.resolveDoc(pageId);
|
|
9514
|
+
if (!doc) {
|
|
9515
|
+
throw new Error(`No document available for page ${pageId}`);
|
|
9516
|
+
}
|
|
9517
|
+
replaceXNetPageFragmentWithMarkdown(doc, bodyMarkdown, {
|
|
9518
|
+
field,
|
|
9519
|
+
...options.generateBlockId ? { generateBlockId: options.generateBlockId } : {}
|
|
9520
|
+
});
|
|
9521
|
+
return { mode: "blocknote-yjs", yjsField: field };
|
|
9522
|
+
},
|
|
9523
|
+
readMarkdown: async (pageId) => {
|
|
9524
|
+
const doc = await options.resolveDoc(pageId);
|
|
9525
|
+
return doc ? xnetPageFragmentToMarkdown(doc, { field }) : null;
|
|
9526
|
+
}
|
|
9527
|
+
};
|
|
9528
|
+
}
|
|
9529
|
+
|
|
9010
9530
|
// src/sandbox/ast-validator.ts
|
|
9011
9531
|
import * as acorn from "acorn";
|
|
9012
9532
|
var FORBIDDEN_GLOBALS = /* @__PURE__ */ new Set([
|
|
@@ -10128,12 +10648,12 @@ var createCapabilities = (overrides = {}) => ({
|
|
|
10128
10648
|
...overrides
|
|
10129
10649
|
});
|
|
10130
10650
|
var normalizeBaseUrl = (baseUrl) => baseUrl.replace(/\/+$/, "");
|
|
10131
|
-
var
|
|
10651
|
+
var isRecord6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10132
10652
|
var parseToolArguments = (value) => {
|
|
10133
10653
|
if (!value) return {};
|
|
10134
10654
|
try {
|
|
10135
10655
|
const parsed = JSON.parse(value);
|
|
10136
|
-
return
|
|
10656
|
+
return isRecord6(parsed) ? parsed : { value: parsed };
|
|
10137
10657
|
} catch {
|
|
10138
10658
|
return { raw: value };
|
|
10139
10659
|
}
|
|
@@ -12434,6 +12954,8 @@ export {
|
|
|
12434
12954
|
WebLLMProvider,
|
|
12435
12955
|
WebhookEmitter,
|
|
12436
12956
|
XNET_MARKDOWN_DIRECTIVE_SPECS,
|
|
12957
|
+
XNET_PAGE_FRAGMENT_FIELD,
|
|
12958
|
+
XNET_PAGE_LEGACY_FRAGMENT_FIELD,
|
|
12437
12959
|
agentToolToExtraTool,
|
|
12438
12960
|
agentToolsAsExtraTools,
|
|
12439
12961
|
aggregateRatings,
|
|
@@ -12443,6 +12965,7 @@ export {
|
|
|
12443
12965
|
assertSystemAudio,
|
|
12444
12966
|
assistTurnProvenance,
|
|
12445
12967
|
attachAiPlanValidation,
|
|
12968
|
+
blockNoteFragmentToMarkdown,
|
|
12446
12969
|
buildAirtableConnector,
|
|
12447
12970
|
buildDiscordAction,
|
|
12448
12971
|
buildEmailAction,
|
|
@@ -12470,6 +12993,7 @@ export {
|
|
|
12470
12993
|
createAiOperation,
|
|
12471
12994
|
createAiSurfaceService,
|
|
12472
12995
|
createAiValidationResult,
|
|
12996
|
+
createBlockNotePageMarkdownAdapter,
|
|
12473
12997
|
createCanvasErpPrototypeRiskSummary,
|
|
12474
12998
|
createCanvasErpPrototypeScenario,
|
|
12475
12999
|
createCanvasPluginFixtureCards,
|
|
@@ -12537,7 +13061,7 @@ export {
|
|
|
12537
13061
|
isOllamaAvailable,
|
|
12538
13062
|
isPaidPricing,
|
|
12539
13063
|
isPresetWorkspaceId,
|
|
12540
|
-
|
|
13064
|
+
isSchemaDefiningContribution,
|
|
12541
13065
|
isSchemaReadAllowed,
|
|
12542
13066
|
isSchemaWriteAllowed,
|
|
12543
13067
|
isScriptNode,
|
|
@@ -12545,6 +13069,7 @@ export {
|
|
|
12545
13069
|
isSystemAudioAllowed,
|
|
12546
13070
|
ladderTierForTrust,
|
|
12547
13071
|
leaveWithEverything,
|
|
13072
|
+
legacyFragmentToMarkdown,
|
|
12548
13073
|
listOllamaModels,
|
|
12549
13074
|
matchSchemaIri,
|
|
12550
13075
|
moveSlot,
|
|
@@ -12570,6 +13095,7 @@ export {
|
|
|
12570
13095
|
renderMarkdownLineDiff,
|
|
12571
13096
|
renderMarkdownReviewDiff,
|
|
12572
13097
|
renderSelectionPrompt,
|
|
13098
|
+
replaceXNetPageFragmentWithMarkdown,
|
|
12573
13099
|
requiresCapabilityReprompt,
|
|
12574
13100
|
resolveImporters,
|
|
12575
13101
|
resolveInstallOrder,
|
|
@@ -12601,5 +13127,6 @@ export {
|
|
|
12601
13127
|
verifyProvenance,
|
|
12602
13128
|
warnOnEditorSchemaRisks,
|
|
12603
13129
|
wrapCliConnector,
|
|
12604
|
-
writeModeFor
|
|
13130
|
+
writeModeFor,
|
|
13131
|
+
xnetPageFragmentToMarkdown
|
|
12605
13132
|
};
|