@imenam/mcp-documentor 1.0.91 → 1.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +343 -327
- package/dist/src/core/git-sync.js +1 -0
- package/dist/src/core/publication-store.d.ts +76 -0
- package/dist/src/core/publication-store.js +180 -0
- package/dist/src/gui-worker.js +183 -67
- package/dist/src/index.js +118 -4
- package/gui/dist/assets/DocContent-BxncLHIS.css +1 -0
- package/gui/dist/assets/DocContent-qNz5QMPa.js +346 -0
- package/gui/dist/assets/arc-DvP0UOkD.js +1 -0
- package/gui/dist/assets/architectureDiagram-3BPJPVTR-3wEHUA1o.js +36 -0
- package/gui/dist/assets/{blockDiagram-GPEHLZMM-G4A-rV4c.js → blockDiagram-GPEHLZMM-C01nZdXH.js} +1 -1
- package/gui/dist/assets/{c4Diagram-AAUBKEIU-Dq3aMw8v.js → c4Diagram-AAUBKEIU-C995ER45.js} +1 -1
- package/gui/dist/assets/channel-Cjefy81D.js +1 -0
- package/gui/dist/assets/chunk-2J33WTMH-B7Z-cZqf.js +1 -0
- package/gui/dist/assets/chunk-4BX2VUAB-BRtaRRAZ.js +1 -0
- package/gui/dist/assets/chunk-55IACEB6-CZbPaYTs.js +1 -0
- package/gui/dist/assets/{chunk-727SXJPM-Dv3Ay2KV.js → chunk-727SXJPM-BMKPsW_V.js} +1 -1
- package/gui/dist/assets/{chunk-AQP2D5EJ-BycHHbwh.js → chunk-AQP2D5EJ-BQJRaqJz.js} +1 -1
- package/gui/dist/assets/{chunk-FMBD7UC4-DBoCiqpY.js → chunk-FMBD7UC4-BiKjOUxU.js} +1 -1
- package/gui/dist/assets/chunk-ND2GUHAM-BQYUzZi5.js +1 -0
- package/gui/dist/assets/chunk-QZHKN3VN-C0mI_9k0.js +1 -0
- package/gui/dist/assets/classDiagram-4FO5ZUOK-U-TA2l-f.js +1 -0
- package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-U-TA2l-f.js +1 -0
- package/gui/dist/assets/cose-bilkent-S5V4N54A-9QkakK6h.js +1 -0
- package/gui/dist/assets/dagre-BM42HDAG-p_TitJwo.js +4 -0
- package/gui/dist/assets/diagram-2AECGRRQ-T3ul_-C1.js +43 -0
- package/gui/dist/assets/diagram-5GNKFQAL-Cv4-mYjj.js +10 -0
- package/gui/dist/assets/{diagram-KO2AKTUF-CZAde8Sg.js → diagram-KO2AKTUF-GEuY7REm.js} +1 -1
- package/gui/dist/assets/diagram-LMA3HP47-BlZVA1ZL.js +24 -0
- package/gui/dist/assets/diagram-OG6HWLK6-DZ9muekA.js +24 -0
- package/gui/dist/assets/{erDiagram-TEJ5UH35-DPUEmQfe.js → erDiagram-TEJ5UH35-BQ_TWeSA.js} +1 -1
- package/gui/dist/assets/{flowDiagram-I6XJVG4X-p2HfkBjW.js → flowDiagram-I6XJVG4X-BVxlCJhG.js} +1 -1
- package/gui/dist/assets/ganttDiagram-6RSMTGT7-DlHxknKg.js +292 -0
- package/gui/dist/assets/gitGraphDiagram-PVQCEYII-DYHNhcQ1.js +106 -0
- package/gui/dist/assets/infoDiagram-5YYISTIA-usWWgsgX.js +2 -0
- package/gui/dist/assets/{ishikawaDiagram-YF4QCWOH-DZ61Cc8a.js → ishikawaDiagram-YF4QCWOH-GXA4mXdI.js} +1 -1
- package/gui/dist/assets/{journeyDiagram-JHISSGLW-qYtEmFuB.js → journeyDiagram-JHISSGLW-DuiQ_voI.js} +1 -1
- package/gui/dist/assets/{kanban-definition-UN3LZRKU-Bs-W313s.js → kanban-definition-UN3LZRKU-Cf5Zx4Ai.js} +1 -1
- package/gui/dist/assets/linear-Dxg5B9lZ.js +1 -0
- package/gui/dist/assets/main-BoIDzkiC.js +10 -0
- package/gui/dist/assets/main-DDy8gF40.css +1 -0
- package/gui/dist/assets/{mindmap-definition-RKZ34NQL-CvBqAH4c.js → mindmap-definition-RKZ34NQL-BI-GTubt.js} +1 -1
- package/gui/dist/assets/{pieDiagram-4H26LBE5-BD2UcQce.js → pieDiagram-4H26LBE5-jm6JjM7-.js} +1 -1
- package/gui/dist/assets/public-5AzxUEZY.css +1 -0
- package/gui/dist/assets/public-BbfNIL4J.js +1 -0
- package/gui/dist/assets/{quadrantDiagram-W4KKPZXB-DEuynlP9.js → quadrantDiagram-W4KKPZXB-D_FMBvP7.js} +1 -1
- package/gui/dist/assets/{requirementDiagram-4Y6WPE33-DPxfzOF3.js → requirementDiagram-4Y6WPE33-DrAnq7B5.js} +1 -1
- package/gui/dist/assets/{sankeyDiagram-5OEKKPKP-C70_cePR.js → sankeyDiagram-5OEKKPKP-BBxMYinl.js} +1 -1
- package/gui/dist/assets/{sequenceDiagram-3UESZ5HK-FDb_1B1W.js → sequenceDiagram-3UESZ5HK-CzlReNxZ.js} +1 -1
- package/gui/dist/assets/stateDiagram-AJRCARHV-CAj_FaGh.js +1 -0
- package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-DL8IxfA-.js +1 -0
- package/gui/dist/assets/{timeline-definition-PNZ67QCA-DNUx0JIp.js → timeline-definition-PNZ67QCA-CHzi4ypa.js} +1 -1
- package/gui/dist/assets/{vennDiagram-CIIHVFJN-DEAfzbjb.js → vennDiagram-CIIHVFJN-DT2hW75o.js} +1 -1
- package/gui/dist/assets/{wardley-L42UT6IY-_REPWPb-.js → wardley-L42UT6IY-BBPqyjj6.js} +1 -1
- package/gui/dist/assets/{wardleyDiagram-YWT4CUSO-CZFLXFE3.js → wardleyDiagram-YWT4CUSO-CoB6ihhL.js} +1 -1
- package/gui/dist/assets/{xychartDiagram-2RQKCTM6-P2Nhif6M.js → xychartDiagram-2RQKCTM6-FgTwWkea.js} +1 -1
- package/gui/dist/index.html +4 -2
- package/gui/dist/public.html +17 -0
- package/package.json +1 -1
- package/gui/dist/assets/arc-VljQAUvA.js +0 -1
- package/gui/dist/assets/architectureDiagram-3BPJPVTR-lbkjtvmN.js +0 -36
- package/gui/dist/assets/channel-DFvG2cZZ.js +0 -1
- package/gui/dist/assets/chunk-2J33WTMH-VSzyIJHo.js +0 -1
- package/gui/dist/assets/chunk-4BX2VUAB-DER41q8w.js +0 -1
- package/gui/dist/assets/chunk-55IACEB6-BlOGGRk4.js +0 -1
- package/gui/dist/assets/chunk-ND2GUHAM-DGKypjhb.js +0 -1
- package/gui/dist/assets/chunk-QZHKN3VN-B8Gn_mBo.js +0 -1
- package/gui/dist/assets/classDiagram-4FO5ZUOK-B8xEoAMI.js +0 -1
- package/gui/dist/assets/classDiagram-v2-Q7XG4LA2-B8xEoAMI.js +0 -1
- package/gui/dist/assets/cose-bilkent-S5V4N54A-DyamTuYj.js +0 -1
- package/gui/dist/assets/dagre-BM42HDAG-BKC5D2WN.js +0 -4
- package/gui/dist/assets/diagram-2AECGRRQ-BV2lBpwH.js +0 -43
- package/gui/dist/assets/diagram-5GNKFQAL-DGwbAj4W.js +0 -10
- package/gui/dist/assets/diagram-LMA3HP47-fQfo0z7i.js +0 -24
- package/gui/dist/assets/diagram-OG6HWLK6-BlD3VAFM.js +0 -24
- package/gui/dist/assets/ganttDiagram-6RSMTGT7-CWfFoy4g.js +0 -292
- package/gui/dist/assets/gitGraphDiagram-PVQCEYII-DkTKzmes.js +0 -106
- package/gui/dist/assets/index-BJ4WCWig.css +0 -1
- package/gui/dist/assets/index-C8LVeAsA.js +0 -358
- package/gui/dist/assets/infoDiagram-5YYISTIA-CXHTqZoU.js +0 -2
- package/gui/dist/assets/linear-CU6J91M5.js +0 -1
- package/gui/dist/assets/stateDiagram-AJRCARHV-BH1bq2it.js +0 -1
- package/gui/dist/assets/stateDiagram-v2-BHNVJYJU-BfpDu1Qi.js +0 -1
package/dist/src/index.js
CHANGED
|
@@ -54,7 +54,8 @@ import { getImage } from "./tools/get-image.js";
|
|
|
54
54
|
import { SyncEngine } from "./core/git-sync.js";
|
|
55
55
|
import { syncStatus, pullDocs, pushDocs, syncDocs, resolveSyncConflict } from "./tools/sync.js";
|
|
56
56
|
import { listConflicts, getConflictHunks, resolveConflictHunks } from "./tools/conflicts.js";
|
|
57
|
-
import {
|
|
57
|
+
import { hashDocContent, PublicationStore } from "./core/publication-store.js";
|
|
58
|
+
import { MoveDocArgsSchema, textSourceDescriptions, } from "../shared/schemas/doc.schema.js";
|
|
58
59
|
import { isReadOnly, WRITE_TOOLS } from "../shared/read-only.js";
|
|
59
60
|
const __filename = fileURLToPath(import.meta.url);
|
|
60
61
|
const __dirname = path.dirname(__filename);
|
|
@@ -109,6 +110,7 @@ historyStore.init(storageEngine.getDataDir());
|
|
|
109
110
|
storageEngine.setHistoryStore(historyStore);
|
|
110
111
|
const syncEngine = new SyncEngine(storageEngine);
|
|
111
112
|
const localState = new LocalState(storageEngine.getDataDir());
|
|
113
|
+
const publicationStore = new PublicationStore(storageEngine.getDataDir());
|
|
112
114
|
setBlobStoreDir(path.join(storageEngine.getDataDir(), "blob-cache"));
|
|
113
115
|
setCodeRootProvider((project) => localState.getCodeRoot(project));
|
|
114
116
|
setCodeSourceProvider({
|
|
@@ -120,7 +122,6 @@ let guiLauncher;
|
|
|
120
122
|
let guiStatus = "disabled";
|
|
121
123
|
let guiUrl = null;
|
|
122
124
|
let guiStartWaiter = null;
|
|
123
|
-
const sseControllers = new Set();
|
|
124
125
|
function broadcastToGUI(message) {
|
|
125
126
|
const child = guiLauncher.getProcess();
|
|
126
127
|
if (child?.connected) {
|
|
@@ -248,6 +249,18 @@ function dispatchIPCMessage(msg) {
|
|
|
248
249
|
return { success: true };
|
|
249
250
|
});
|
|
250
251
|
}
|
|
252
|
+
else if (msg.type === "LIST_PUBLICATIONS") {
|
|
253
|
+
replyToGUI(msg, "LIST_PUBLICATIONS_RESPONSE", () => listPublications(msg.data?.project || undefined));
|
|
254
|
+
}
|
|
255
|
+
else if (msg.type === "PUBLISH_DOC") {
|
|
256
|
+
replyToGUI(msg, "PUBLISH_DOC_RESPONSE", () => publishDoc(msg.data ?? {}));
|
|
257
|
+
}
|
|
258
|
+
else if (msg.type === "UPDATE_PUBLICATION") {
|
|
259
|
+
replyToGUI(msg, "UPDATE_PUBLICATION_RESPONSE", () => updatePublication(msg.data ?? {}));
|
|
260
|
+
}
|
|
261
|
+
else if (msg.type === "UNPUBLISH_DOC") {
|
|
262
|
+
replyToGUI(msg, "UNPUBLISH_DOC_RESPONSE", () => unpublishDoc(msg.data ?? {}));
|
|
263
|
+
}
|
|
251
264
|
else {
|
|
252
265
|
logger.debug(`Unhandled message from GUI: ${msg.type}`);
|
|
253
266
|
}
|
|
@@ -359,6 +372,14 @@ async function handleGetInitialState(msg) {
|
|
|
359
372
|
}
|
|
360
373
|
catch (err) {
|
|
361
374
|
logger.error(`Failed to get initial state: ${err.message}`);
|
|
375
|
+
if (msg.correlationId) {
|
|
376
|
+
broadcastToGUI({
|
|
377
|
+
type: "INITIAL_STATE",
|
|
378
|
+
correlationId: msg.correlationId,
|
|
379
|
+
error: err.message,
|
|
380
|
+
timestamp: new Date().toISOString(),
|
|
381
|
+
});
|
|
382
|
+
}
|
|
362
383
|
}
|
|
363
384
|
}
|
|
364
385
|
async function handleGetConfig(msg) {
|
|
@@ -909,6 +930,95 @@ async function handleGetDocVersionIPC(msg) {
|
|
|
909
930
|
});
|
|
910
931
|
}
|
|
911
932
|
}
|
|
933
|
+
/** A publication as the GUI lists it: the stored record plus the state of the document it froze. */
|
|
934
|
+
async function describePublication(publication) {
|
|
935
|
+
const doc = await storageEngine.getDoc(publication.docId, publication.project);
|
|
936
|
+
const status = !doc
|
|
937
|
+
? "missing"
|
|
938
|
+
: hashDocContent(doc.title, doc.content) === publication.contentHash
|
|
939
|
+
? "current"
|
|
940
|
+
: "modified";
|
|
941
|
+
return {
|
|
942
|
+
id: publication.id,
|
|
943
|
+
token: publication.token,
|
|
944
|
+
project: publication.project,
|
|
945
|
+
docId: publication.docId,
|
|
946
|
+
title: publication.title,
|
|
947
|
+
version: publication.version,
|
|
948
|
+
note: publication.note,
|
|
949
|
+
createdAt: publication.createdAt,
|
|
950
|
+
publishedAt: publication.publishedAt,
|
|
951
|
+
status,
|
|
952
|
+
currentVersion: doc ? latestVersion(publication.project, publication.docId) : null,
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
function latestVersion(project, docId) {
|
|
956
|
+
return historyStore.listVersions(project, docId)[0]?.version ?? null;
|
|
957
|
+
}
|
|
958
|
+
function assertWritable() {
|
|
959
|
+
if (isReadOnly())
|
|
960
|
+
throw new Error("READ_ONLY mode: publishing is disabled");
|
|
961
|
+
}
|
|
962
|
+
function broadcastPublicationsChanged(project) {
|
|
963
|
+
broadcastToGUI({ type: "PUBLICATIONS_CHANGED", data: { project }, timestamp: new Date().toISOString() });
|
|
964
|
+
}
|
|
965
|
+
async function listPublications(project) {
|
|
966
|
+
const publications = publicationStore.list().filter((p) => !project || p.project === project);
|
|
967
|
+
return { publications: await Promise.all(publications.map(describePublication)) };
|
|
968
|
+
}
|
|
969
|
+
/** The document as it is now, frozen with the version note. */
|
|
970
|
+
async function freezeInput(project, docId, note) {
|
|
971
|
+
const doc = await storageEngine.getDoc(docId, project);
|
|
972
|
+
if (!doc)
|
|
973
|
+
throw new Error(`Doc "${docId}" not found in project "${project}"`);
|
|
974
|
+
return {
|
|
975
|
+
project,
|
|
976
|
+
docId,
|
|
977
|
+
title: doc.title,
|
|
978
|
+
content: doc.content,
|
|
979
|
+
version: latestVersion(project, docId),
|
|
980
|
+
note: note,
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
async function publishDoc(data) {
|
|
984
|
+
assertWritable();
|
|
985
|
+
if (!data.project || !data.id)
|
|
986
|
+
throw new Error("project and id are required");
|
|
987
|
+
const publication = publicationStore.publish(await freezeInput(data.project, data.id, data.note));
|
|
988
|
+
logger.info(`Published [${publication.project}] ${publication.docId}`);
|
|
989
|
+
broadcastPublicationsChanged(publication.project);
|
|
990
|
+
return { publication: await describePublication(publication) };
|
|
991
|
+
}
|
|
992
|
+
async function updatePublication(data) {
|
|
993
|
+
assertWritable();
|
|
994
|
+
const existing = data.publicationId ? publicationStore.get(data.publicationId) : undefined;
|
|
995
|
+
if (!existing)
|
|
996
|
+
throw new Error(`Publication "${data.publicationId}" does not exist`);
|
|
997
|
+
const publication = publicationStore.update(existing.id, await freezeInput(existing.project, existing.docId, data.note));
|
|
998
|
+
logger.info(`Publication of [${publication.project}] ${publication.docId} updated`);
|
|
999
|
+
broadcastPublicationsChanged(publication.project);
|
|
1000
|
+
return { publication: await describePublication(publication) };
|
|
1001
|
+
}
|
|
1002
|
+
async function unpublishDoc(data) {
|
|
1003
|
+
assertWritable();
|
|
1004
|
+
if (!data.publicationId)
|
|
1005
|
+
throw new Error("publicationId is required");
|
|
1006
|
+
const publication = publicationStore.unpublish(data.publicationId);
|
|
1007
|
+
logger.info(`Unpublished [${publication.project}] ${publication.docId}`);
|
|
1008
|
+
broadcastPublicationsChanged(publication.project);
|
|
1009
|
+
return { success: true };
|
|
1010
|
+
}
|
|
1011
|
+
/** A moved document keeps its publication: the link stays valid and its state follows the new path. */
|
|
1012
|
+
function movePublication(args) {
|
|
1013
|
+
const parsed = MoveDocArgsSchema.parse(args);
|
|
1014
|
+
const newProject = parsed.new_project ?? parsed.project;
|
|
1015
|
+
const moved = publicationStore.moveDoc(parsed.project, parsed.path, newProject, parsed.new_path ?? parsed.path);
|
|
1016
|
+
if (!moved)
|
|
1017
|
+
return;
|
|
1018
|
+
broadcastPublicationsChanged(parsed.project);
|
|
1019
|
+
if (newProject !== parsed.project)
|
|
1020
|
+
broadcastPublicationsChanged(newProject);
|
|
1021
|
+
}
|
|
912
1022
|
guiLauncher = new GuiLauncher({
|
|
913
1023
|
guiPath: path.join(__dirname, "gui-worker.js"),
|
|
914
1024
|
env: { ...process.env },
|
|
@@ -1640,8 +1750,12 @@ async function handleToolCall(request) {
|
|
|
1640
1750
|
return await checkLinks(storageEngine, args);
|
|
1641
1751
|
case "delete_doc":
|
|
1642
1752
|
return await deleteDoc(storageEngine, embeddingEngine, args);
|
|
1643
|
-
case "move_doc":
|
|
1644
|
-
|
|
1753
|
+
case "move_doc": {
|
|
1754
|
+
const result = await moveDoc(storageEngine, embeddingEngine, args);
|
|
1755
|
+
if (!result.isError)
|
|
1756
|
+
movePublication(args);
|
|
1757
|
+
return result;
|
|
1758
|
+
}
|
|
1645
1759
|
case "get_doc_tree":
|
|
1646
1760
|
return await getDocTree(storageEngine, args);
|
|
1647
1761
|
case "list_doc_versions":
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;background:#090b0f;color:#e1e4e8;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#root{width:100%;height:100vh}.doc-inline-link{display:inline;padding:0;border:none;background:none;color:#58a6ff;cursor:pointer;font-size:inherit;font-family:inherit;text-decoration:underline;text-underline-offset:2px}.doc-inline-link:hover{color:#79c0ff}.doc-inline-link--broken{color:#f85149;cursor:not-allowed;text-decoration:underline wavy}.doc-inline-link--cross-project{color:#d2a8ff}.doc-inline-link--cross-project:hover{color:#e2c0ff}.doc-content h1{font-size:2em;margin:.67em 0;border-bottom:1px solid #21262d;padding-bottom:.3em}.doc-content h2{font-size:1.5em;margin:.83em 0;border-bottom:1px solid #21262d;padding-bottom:.3em}.doc-content h3{font-size:1.25em;margin:1em 0}.doc-content h4{font-size:1em;margin:1.33em 0}.doc-content p{margin:1em 0;line-height:1.6}.doc-content code{background:#161b22;padding:2px 6px;border-radius:4px;font-family:Fira Code,Cascadia Code,monospace;font-size:.9em;font-variant-ligatures:none}.doc-content pre{background:#161b22;padding:16px;border-radius:8px;overflow-x:auto;border:1px solid #30363d}.doc-content pre code{background:none;padding:0}.doc-content ul,.doc-content ol{padding-left:2em;margin:1em 0}.doc-content li{margin:.25em 0;line-height:1.6}.doc-content table{border-collapse:collapse;width:100%;margin:1em 0}.doc-content th,.doc-content td{border:1px solid #30363d;padding:8px 12px;text-align:left}.doc-content th{background:#161b22;font-weight:600}.doc-content a{color:#58a6ff;text-decoration:none}.doc-content a:hover{text-decoration:underline}.doc-content blockquote{border-left:3px solid #30363d;padding-left:16px;margin:1em 0;color:#8b949e}.code-block-wrapper{border:1px solid #30363d;border-radius:6px;margin:12px 0;overflow:hidden}.code-block-header{display:flex;align-items:center;justify-content:space-between;padding:4px 12px;background:#21262d;border-bottom:1px solid #30363d}.code-block-lang-select{background:transparent;border:none;color:#8b949e;font-size:11px;font-family:Fira Code,Cascadia Code,Consolas,monospace;cursor:pointer;outline:none;padding:2px 0}.code-block-lang-select:hover{color:#c9d1d9}.code-block-lang{color:#8b949e;font-size:11px;font-family:Fira Code,Cascadia Code,Consolas,monospace;padding:2px 0}.code-block-lang-select option{background:#21262d;color:#c9d1d9}.code-block-copy-btn{background:none;border:1px solid #30363d;color:#8b949e;font-size:11px;cursor:pointer;padding:2px 8px;border-radius:4px;transition:all .15s}.code-block-copy-btn:hover{background:#30363d;color:#c9d1d9}.mermaid-block-wrapper{border:1px solid #30363d;border-radius:6px;margin:12px 0;overflow:hidden;background:#161b22}.mermaid-block-header{display:flex;align-items:center;justify-content:space-between;padding:4px 12px;background:#21262d;border-bottom:1px solid #30363d}.mermaid-block-title{color:#8b949e;font-family:Fira Code,Cascadia Code,Consolas,monospace;font-size:11px}.mermaid-block-actions{display:flex;align-items:center;gap:8px}.mermaid-zoom-controls{display:flex;align-items:center;gap:2px}.mermaid-zoom-btn{background:#30363d;border:1px solid #484f58;color:#c9d1d9;border-radius:4px;width:22px;height:22px;font-size:14px;line-height:1;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;transition:background .15s}.mermaid-zoom-btn:hover:not(:disabled){background:#484f58}.mermaid-zoom-btn:disabled{opacity:.35;cursor:not-allowed}.mermaid-zoom-reset{background:transparent;border:1px solid #484f58;color:#8b949e;border-radius:4px;height:22px;min-width:40px;font-size:11px;font-family:Fira Code,Cascadia Code,Consolas,monospace;cursor:pointer;padding:0 4px;transition:background .15s,color .15s}.mermaid-zoom-reset:hover{background:#30363d;color:#c9d1d9}.mermaid-block-content{padding:16px;overflow:auto}.mermaid-block-zoom-container{display:block;transform-origin:top center;transition:transform .15s ease}.mermaid-block-zoom-container svg{display:block;max-width:100%;height:auto;margin:0 auto}.mermaid-block-error{margin:0;color:#f85149;font-family:Fira Code,Cascadia Code,Consolas,monospace;font-size:13px;line-height:1.5;white-space:pre-wrap}.doc-content img.doc-image{max-width:100%;height:auto;border-radius:6px;margin:8px 0;display:block}
|