schemeog-mcp 2.9.3 → 2.10.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/index.js +175 -23
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -756,7 +756,8 @@ Claude обрезает большие параметры, но file_path чит
|
|
|
756
756
|
name: "delete_schema",
|
|
757
757
|
description: `Удалить схему по ID.
|
|
758
758
|
|
|
759
|
-
|
|
759
|
+
Схема перемещается в корзину (soft delete). Можно восстановить через restore_schema.
|
|
760
|
+
Для полного удаления используй permanent_delete_schema.`,
|
|
760
761
|
inputSchema: {
|
|
761
762
|
type: "object",
|
|
762
763
|
properties: {
|
|
@@ -768,6 +769,52 @@ Claude обрезает большие параметры, но file_path чит
|
|
|
768
769
|
required: ["schema_id"],
|
|
769
770
|
},
|
|
770
771
|
},
|
|
772
|
+
{
|
|
773
|
+
name: "list_deleted_schemas",
|
|
774
|
+
description: `Получить список удалённых схем (корзина).
|
|
775
|
+
|
|
776
|
+
Возвращает схемы, которые были удалены но ещё не удалены навсегда.
|
|
777
|
+
Можно восстановить через restore_schema или удалить навсегда через permanent_delete_schema.`,
|
|
778
|
+
inputSchema: {
|
|
779
|
+
type: "object",
|
|
780
|
+
properties: {},
|
|
781
|
+
required: [],
|
|
782
|
+
},
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
name: "restore_schema",
|
|
786
|
+
description: `Восстановить схему из корзины.
|
|
787
|
+
|
|
788
|
+
Параметры:
|
|
789
|
+
- schema_id: ID схемы из корзины (можно получить через list_deleted_schemas)`,
|
|
790
|
+
inputSchema: {
|
|
791
|
+
type: "object",
|
|
792
|
+
properties: {
|
|
793
|
+
schema_id: {
|
|
794
|
+
type: "string",
|
|
795
|
+
description: "ID схемы для восстановления",
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
required: ["schema_id"],
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
name: "permanent_delete_schema",
|
|
803
|
+
description: `Удалить схему НАВСЕГДА.
|
|
804
|
+
|
|
805
|
+
ВНИМАНИЕ: Это действие необратимо! Схема будет удалена из базы данных навсегда.
|
|
806
|
+
Работает только со схемами в корзине (сначала нужен обычный delete_schema).`,
|
|
807
|
+
inputSchema: {
|
|
808
|
+
type: "object",
|
|
809
|
+
properties: {
|
|
810
|
+
schema_id: {
|
|
811
|
+
type: "string",
|
|
812
|
+
description: "ID схемы для полного удаления",
|
|
813
|
+
},
|
|
814
|
+
},
|
|
815
|
+
required: ["schema_id"],
|
|
816
|
+
},
|
|
817
|
+
},
|
|
771
818
|
|
|
772
819
|
// ========== ПРОЕКТЫ ==========
|
|
773
820
|
{
|
|
@@ -1438,9 +1485,12 @@ URL: ${API_BASE_URL}/canvas?schema=${result.schema.id}
|
|
|
1438
1485
|
const updateBody = {};
|
|
1439
1486
|
let warnings = [];
|
|
1440
1487
|
let finalElements = elements;
|
|
1488
|
+
let finalConnections = null; // Связи из файла (cloud формат)
|
|
1489
|
+
let finalTagsDictionary = null; // Теги из файла
|
|
1441
1490
|
let fileSize = null;
|
|
1442
1491
|
let fileNameFromJson = null;
|
|
1443
1492
|
let fileDescFromJson = null;
|
|
1493
|
+
let preservePositionsFromFile = false; // Флаг: сохранять координаты из файла
|
|
1444
1494
|
|
|
1445
1495
|
// Если указан file_path — читаем элементы из файла (обходит лимит Claude)
|
|
1446
1496
|
if (file_path) {
|
|
@@ -1457,22 +1507,26 @@ URL: ${API_BASE_URL}/canvas?schema=${result.schema.id}
|
|
|
1457
1507
|
schemaData = parsedContent.schema;
|
|
1458
1508
|
fileNameFromJson = schemaData.name;
|
|
1459
1509
|
fileDescFromJson = schemaData.description;
|
|
1510
|
+
preservePositionsFromFile = true; // Экспорт содержит точные координаты
|
|
1460
1511
|
}
|
|
1461
|
-
// Формат 2: Вложенный формат { name, data: { elements: [...] } }
|
|
1512
|
+
// Формат 2: Вложенный формат { name, data: { elements: [...], connections: [...] } }
|
|
1462
1513
|
else if (parsedContent.data && parsedContent.data.elements) {
|
|
1463
1514
|
schemaData = parsedContent.data;
|
|
1464
1515
|
fileNameFromJson = parsedContent.name;
|
|
1465
1516
|
fileDescFromJson = parsedContent.description;
|
|
1517
|
+
preservePositionsFromFile = true; // Полный формат с координатами
|
|
1466
1518
|
}
|
|
1467
1519
|
// Формат 3: Простой { name, elements, connections }
|
|
1468
1520
|
else if (parsedContent.elements || parsedContent.name) {
|
|
1469
1521
|
schemaData = parsedContent;
|
|
1470
1522
|
fileNameFromJson = parsedContent.name;
|
|
1471
1523
|
fileDescFromJson = parsedContent.description;
|
|
1524
|
+
preservePositionsFromFile = true;
|
|
1472
1525
|
}
|
|
1473
1526
|
// Формат 4: Только массив элементов
|
|
1474
1527
|
else if (Array.isArray(parsedContent)) {
|
|
1475
1528
|
schemaData = { elements: parsedContent };
|
|
1529
|
+
preservePositionsFromFile = false; // Простой массив — без координат
|
|
1476
1530
|
}
|
|
1477
1531
|
else {
|
|
1478
1532
|
return {
|
|
@@ -1485,6 +1539,10 @@ URL: ${API_BASE_URL}/canvas?schema=${result.schema.id}
|
|
|
1485
1539
|
}
|
|
1486
1540
|
|
|
1487
1541
|
finalElements = schemaData.elements || [];
|
|
1542
|
+
// КРИТИЧНО: Берём connections из файла если есть (cloud формат)
|
|
1543
|
+
finalConnections = schemaData.connections || null;
|
|
1544
|
+
// Берём tagsDictionary из файла если есть
|
|
1545
|
+
finalTagsDictionary = schemaData.tagsDictionary || null;
|
|
1488
1546
|
} catch (readError) {
|
|
1489
1547
|
return {
|
|
1490
1548
|
content: [{
|
|
@@ -1526,27 +1584,57 @@ URL: ${API_BASE_URL}/canvas?schema=${result.schema.id}
|
|
|
1526
1584
|
};
|
|
1527
1585
|
}
|
|
1528
1586
|
|
|
1529
|
-
//
|
|
1530
|
-
//
|
|
1531
|
-
|
|
1532
|
-
(
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1587
|
+
// Сохраняем координаты:
|
|
1588
|
+
// - Если file_path с preservePositionsFromFile — берём x/y из файла
|
|
1589
|
+
// - Иначе — из текущих данных схемы на сервере
|
|
1590
|
+
if (preservePositionsFromFile) {
|
|
1591
|
+
// Координаты из ФАЙЛА — восстанавливаем из исходных элементов
|
|
1592
|
+
const filePositions = {};
|
|
1593
|
+
finalElements.forEach(el => {
|
|
1594
|
+
if (el.id && (typeof el.x === 'number' || typeof el.y === 'number')) {
|
|
1595
|
+
filePositions[el.id] = { x: el.x, y: el.y };
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
normalized.elements.forEach(el => {
|
|
1599
|
+
if (filePositions[el.id]) {
|
|
1600
|
+
el.x = filePositions[el.id].x;
|
|
1601
|
+
el.y = filePositions[el.id].y;
|
|
1602
|
+
}
|
|
1603
|
+
});
|
|
1604
|
+
} else {
|
|
1605
|
+
// Координаты из СЕРВЕРА (для MCP-созданных элементов без координат)
|
|
1606
|
+
const existingPositions = {};
|
|
1607
|
+
(currentData.elements || []).forEach(el => {
|
|
1608
|
+
if (el.id && (typeof el.x === 'number' || typeof el.y === 'number')) {
|
|
1609
|
+
existingPositions[el.id] = { x: el.x, y: el.y };
|
|
1610
|
+
}
|
|
1611
|
+
});
|
|
1612
|
+
normalized.elements.forEach(el => {
|
|
1613
|
+
if (existingPositions[el.id]) {
|
|
1614
|
+
el.x = existingPositions[el.id].x;
|
|
1615
|
+
el.y = existingPositions[el.id].y;
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1546
1619
|
|
|
1547
1620
|
newData.elements = normalized.elements;
|
|
1548
|
-
|
|
1549
|
-
|
|
1621
|
+
|
|
1622
|
+
// КРИТИЧНО: Выбор источника связей
|
|
1623
|
+
// 1. Если есть finalConnections (из файла в cloud формате) — используем их
|
|
1624
|
+
// 2. Иначе — связи из inline формата внутри элементов
|
|
1625
|
+
if (finalConnections && Array.isArray(finalConnections) && finalConnections.length > 0) {
|
|
1626
|
+
// Cloud формат: connections как отдельный массив
|
|
1627
|
+
newData.connections = prepareConnections(finalConnections);
|
|
1628
|
+
} else {
|
|
1629
|
+
// Inline формат: connections внутри элементов
|
|
1630
|
+
newData.connections = normalized.extractedConnections;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
// Обновляем tagsDictionary если есть в файле
|
|
1634
|
+
if (finalTagsDictionary && Array.isArray(finalTagsDictionary)) {
|
|
1635
|
+
newData.tagsDictionary = finalTagsDictionary;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1550
1638
|
warnings = normalized.warnings;
|
|
1551
1639
|
}
|
|
1552
1640
|
updateBody.data = newData;
|
|
@@ -1590,14 +1678,78 @@ URL: ${API_BASE_URL}/canvas?schema=${schema_id}${warningsText}`,
|
|
|
1590
1678
|
case "delete_schema": {
|
|
1591
1679
|
const { schema_id } = args;
|
|
1592
1680
|
|
|
1593
|
-
await apiRequest(`/schemas/${schema_id}`, {
|
|
1681
|
+
const result = await apiRequest(`/schemas/${schema_id}`, {
|
|
1682
|
+
method: "DELETE",
|
|
1683
|
+
});
|
|
1684
|
+
|
|
1685
|
+
return {
|
|
1686
|
+
content: [{
|
|
1687
|
+
type: "text",
|
|
1688
|
+
text: `🗑️ Схема перемещена в корзину.
|
|
1689
|
+
|
|
1690
|
+
Восстановить можно через restore_schema или в профиле на сайте.
|
|
1691
|
+
Для полного удаления используй permanent_delete_schema.`,
|
|
1692
|
+
}],
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
case "list_deleted_schemas": {
|
|
1697
|
+
const result = await apiRequest("/schemas/deleted/list");
|
|
1698
|
+
|
|
1699
|
+
if (!result.schemas || result.schemas.length === 0) {
|
|
1700
|
+
return {
|
|
1701
|
+
content: [{
|
|
1702
|
+
type: "text",
|
|
1703
|
+
text: `Корзина пуста. Удалённых схем нет.`,
|
|
1704
|
+
}],
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
const schemasList = result.schemas.map(s => ({
|
|
1709
|
+
id: s.id,
|
|
1710
|
+
name: s.name,
|
|
1711
|
+
description: s.description || "",
|
|
1712
|
+
deletedAt: s.deletedAt,
|
|
1713
|
+
}));
|
|
1714
|
+
|
|
1715
|
+
return {
|
|
1716
|
+
content: [{
|
|
1717
|
+
type: "text",
|
|
1718
|
+
text: `🗑️ В корзине ${result.count} схем:\n\n${JSON.stringify(schemasList, null, 2)}`,
|
|
1719
|
+
}],
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
case "restore_schema": {
|
|
1724
|
+
const { schema_id } = args;
|
|
1725
|
+
|
|
1726
|
+
const result = await apiRequest(`/schemas/${schema_id}/restore`, {
|
|
1727
|
+
method: "POST",
|
|
1728
|
+
});
|
|
1729
|
+
|
|
1730
|
+
return {
|
|
1731
|
+
content: [{
|
|
1732
|
+
type: "text",
|
|
1733
|
+
text: `✅ ${result.message}
|
|
1734
|
+
|
|
1735
|
+
URL: ${API_BASE_URL}/canvas?schema=${schema_id}`,
|
|
1736
|
+
}],
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
case "permanent_delete_schema": {
|
|
1741
|
+
const { schema_id } = args;
|
|
1742
|
+
|
|
1743
|
+
const result = await apiRequest(`/schemas/${schema_id}/permanent`, {
|
|
1594
1744
|
method: "DELETE",
|
|
1595
1745
|
});
|
|
1596
1746
|
|
|
1597
1747
|
return {
|
|
1598
1748
|
content: [{
|
|
1599
1749
|
type: "text",
|
|
1600
|
-
text:
|
|
1750
|
+
text: `🔥 ${result.message}
|
|
1751
|
+
|
|
1752
|
+
Это действие необратимо.`,
|
|
1601
1753
|
}],
|
|
1602
1754
|
};
|
|
1603
1755
|
}
|