@trops/dash-core 0.1.287 → 0.1.289
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/electron/index.js +1095 -55
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +54 -16
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +54 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -31578,6 +31578,77 @@ var schedulerController_1 = schedulerController$2;
|
|
|
31578
31578
|
} catch (error) {
|
|
31579
31579
|
console.error("[WidgetRegistry] Error loading registry:", error);
|
|
31580
31580
|
}
|
|
31581
|
+
|
|
31582
|
+
// Reconcile: re-register orphaned widget packages found on disk
|
|
31583
|
+
this.reconcileWithDisk();
|
|
31584
|
+
}
|
|
31585
|
+
|
|
31586
|
+
/**
|
|
31587
|
+
* Scan the widgets directory for packages that exist on disk but are
|
|
31588
|
+
* missing from the registry (e.g. because registry.json was manually edited).
|
|
31589
|
+
* Re-registers them so they can be properly managed (listed, uninstalled).
|
|
31590
|
+
*/
|
|
31591
|
+
reconcileWithDisk() {
|
|
31592
|
+
try {
|
|
31593
|
+
if (!WIDGETS_CACHE_DIR || !fs.existsSync(WIDGETS_CACHE_DIR)) return;
|
|
31594
|
+
|
|
31595
|
+
const registeredPaths = new Set(
|
|
31596
|
+
Array.from(this.widgets.values()).map((w) => w.path),
|
|
31597
|
+
);
|
|
31598
|
+
let reconciled = false;
|
|
31599
|
+
|
|
31600
|
+
const entries = fs.readdirSync(WIDGETS_CACHE_DIR, {
|
|
31601
|
+
withFileTypes: true,
|
|
31602
|
+
});
|
|
31603
|
+
for (const entry of entries) {
|
|
31604
|
+
if (!entry.isDirectory()) continue;
|
|
31605
|
+
|
|
31606
|
+
if (entry.name.startsWith("@")) {
|
|
31607
|
+
// Scoped packages: @scope/name
|
|
31608
|
+
const scopeDir = path.join(WIDGETS_CACHE_DIR, entry.name);
|
|
31609
|
+
const pkgs = fs.readdirSync(scopeDir, { withFileTypes: true });
|
|
31610
|
+
for (const pkg of pkgs) {
|
|
31611
|
+
if (!pkg.isDirectory()) continue;
|
|
31612
|
+
const pkgPath = path.join(scopeDir, pkg.name);
|
|
31613
|
+
const pkgId = `${entry.name}/${pkg.name}`;
|
|
31614
|
+
if (!registeredPaths.has(pkgPath) && !this.widgets.has(pkgId)) {
|
|
31615
|
+
this._reregisterOrphan(pkgId, pkgPath);
|
|
31616
|
+
reconciled = true;
|
|
31617
|
+
}
|
|
31618
|
+
}
|
|
31619
|
+
} else if (entry.name !== "registry.json") {
|
|
31620
|
+
// Bare-name packages
|
|
31621
|
+
const pkgPath = path.join(WIDGETS_CACHE_DIR, entry.name);
|
|
31622
|
+
if (!registeredPaths.has(pkgPath) && !this.widgets.has(entry.name)) {
|
|
31623
|
+
this._reregisterOrphan(entry.name, pkgPath);
|
|
31624
|
+
reconciled = true;
|
|
31625
|
+
}
|
|
31626
|
+
}
|
|
31627
|
+
}
|
|
31628
|
+
|
|
31629
|
+
if (reconciled) {
|
|
31630
|
+
this.saveRegistry();
|
|
31631
|
+
console.log("[WidgetRegistry] Disk reconciliation complete");
|
|
31632
|
+
}
|
|
31633
|
+
} catch (err) {
|
|
31634
|
+
console.warn("[WidgetRegistry] Reconciliation error:", err.message);
|
|
31635
|
+
}
|
|
31636
|
+
}
|
|
31637
|
+
|
|
31638
|
+
/**
|
|
31639
|
+
* Re-register an orphaned widget package found on disk.
|
|
31640
|
+
*/
|
|
31641
|
+
_reregisterOrphan(pkgId, pkgPath) {
|
|
31642
|
+
console.log(`[WidgetRegistry] Re-registering orphaned widget: ${pkgId}`);
|
|
31643
|
+
const { scope } = parsePackageId(pkgId);
|
|
31644
|
+
this.widgets.set(pkgId, {
|
|
31645
|
+
name: pkgId,
|
|
31646
|
+
packageId: pkgId,
|
|
31647
|
+
scope: scope || null,
|
|
31648
|
+
path: pkgPath,
|
|
31649
|
+
version: null,
|
|
31650
|
+
orphaned: true,
|
|
31651
|
+
});
|
|
31581
31652
|
}
|
|
31582
31653
|
|
|
31583
31654
|
/**
|
|
@@ -32171,10 +32242,23 @@ var schedulerController_1 = schedulerController$2;
|
|
|
32171
32242
|
* @param {string} widgetName - Name of the widget to remove
|
|
32172
32243
|
*/
|
|
32173
32244
|
uninstallWidget(widgetName) {
|
|
32174
|
-
|
|
32245
|
+
let widget = this.widgets.get(widgetName);
|
|
32246
|
+
|
|
32247
|
+
// Fallback: widget not in registry but might exist on disk
|
|
32175
32248
|
if (!widget) {
|
|
32176
|
-
|
|
32177
|
-
|
|
32249
|
+
const candidatePath = path.join(
|
|
32250
|
+
WIDGETS_CACHE_DIR,
|
|
32251
|
+
...widgetName.split("/"),
|
|
32252
|
+
);
|
|
32253
|
+
if (fs.existsSync(candidatePath)) {
|
|
32254
|
+
widget = { path: candidatePath };
|
|
32255
|
+
console.log(
|
|
32256
|
+
`[WidgetRegistry] Widget ${widgetName} not in registry, removing from disk`,
|
|
32257
|
+
);
|
|
32258
|
+
} else {
|
|
32259
|
+
console.warn(`[WidgetRegistry] Widget not found: ${widgetName}`);
|
|
32260
|
+
return false;
|
|
32261
|
+
}
|
|
32178
32262
|
}
|
|
32179
32263
|
|
|
32180
32264
|
try {
|
|
@@ -32347,7 +32431,13 @@ var schedulerController_1 = schedulerController$2;
|
|
|
32347
32431
|
ipcMain.handle("widget:uninstall", (event, widgetName) => {
|
|
32348
32432
|
const schedulerController = schedulerController_1;
|
|
32349
32433
|
schedulerController.cleanupWidget(widgetName);
|
|
32350
|
-
|
|
32434
|
+
const success = getWidgetRegistry().uninstallWidget(widgetName);
|
|
32435
|
+
if (success) {
|
|
32436
|
+
BrowserWindow.getAllWindows().forEach((win) => {
|
|
32437
|
+
win.webContents.send("widget:uninstalled", { widgetName });
|
|
32438
|
+
});
|
|
32439
|
+
}
|
|
32440
|
+
return success;
|
|
32351
32441
|
});
|
|
32352
32442
|
|
|
32353
32443
|
ipcMain.handle("widget:cache-path", () => getWidgetRegistry().getCachePath());
|
|
@@ -67484,7 +67574,7 @@ const registeredPrompts = [];
|
|
|
67484
67574
|
* Register a tool to be exposed via the MCP server.
|
|
67485
67575
|
* Call this before starting the server (or restart after registering).
|
|
67486
67576
|
*/
|
|
67487
|
-
function registerTool$
|
|
67577
|
+
function registerTool$6(toolDef) {
|
|
67488
67578
|
registeredTools.push(toolDef);
|
|
67489
67579
|
}
|
|
67490
67580
|
|
|
@@ -67847,7 +67937,7 @@ const mcpDashServerController$4 = {
|
|
|
67847
67937
|
},
|
|
67848
67938
|
|
|
67849
67939
|
// Expose registration functions for other controllers
|
|
67850
|
-
registerTool: registerTool$
|
|
67940
|
+
registerTool: registerTool$6,
|
|
67851
67941
|
registerResource: registerResource$1,
|
|
67852
67942
|
registerPrompt: registerPrompt$1,
|
|
67853
67943
|
getServerContext,
|
|
@@ -68929,6 +69019,23 @@ const widgetApi$2 = {
|
|
|
68929
69019
|
});
|
|
68930
69020
|
},
|
|
68931
69021
|
|
|
69022
|
+
/**
|
|
69023
|
+
* Listen for widget uninstallation events
|
|
69024
|
+
* Useful for cleaning up ComponentManager entries and refreshing UI
|
|
69025
|
+
*
|
|
69026
|
+
* @param {Function} callback - Function called when a widget is uninstalled
|
|
69027
|
+
*
|
|
69028
|
+
* @example
|
|
69029
|
+
* mainApi.widgets.onUninstalled(({ widgetName }) => {
|
|
69030
|
+
* console.log(`Widget ${widgetName} was uninstalled!`);
|
|
69031
|
+
* });
|
|
69032
|
+
*/
|
|
69033
|
+
onUninstalled: (callback) => {
|
|
69034
|
+
ipcRenderer$k.on("widget:uninstalled", (event, data) => {
|
|
69035
|
+
callback(data);
|
|
69036
|
+
});
|
|
69037
|
+
},
|
|
69038
|
+
|
|
68932
69039
|
/**
|
|
68933
69040
|
* Listen for batch widget loading events
|
|
68934
69041
|
* Useful for updating UI when multiple widgets are loaded at once
|
|
@@ -68956,6 +69063,15 @@ const widgetApi$2 = {
|
|
|
68956
69063
|
ipcRenderer$k.removeListener("widget:installed", callback);
|
|
68957
69064
|
},
|
|
68958
69065
|
|
|
69066
|
+
/**
|
|
69067
|
+
* Remove listener for widget uninstallation events
|
|
69068
|
+
*
|
|
69069
|
+
* @param {Function} callback - The callback to remove
|
|
69070
|
+
*/
|
|
69071
|
+
removeUninstalledListener: (callback) => {
|
|
69072
|
+
ipcRenderer$k.removeListener("widget:uninstalled", callback);
|
|
69073
|
+
},
|
|
69074
|
+
|
|
68959
69075
|
/**
|
|
68960
69076
|
* Remove listener for batch widget loading events
|
|
68961
69077
|
*
|
|
@@ -70437,7 +70553,7 @@ const dashboardTools$1 = [
|
|
|
70437
70553
|
{
|
|
70438
70554
|
name: "create_dashboard",
|
|
70439
70555
|
description:
|
|
70440
|
-
"Create a new
|
|
70556
|
+
"Create a new dashboard with the given name. Optionally provide a layout to create a grid dashboard. Returns the dashboard ID. After creating, use search_widgets or list_widgets to find widgets, then add_widget to populate the dashboard.",
|
|
70441
70557
|
inputSchema: {
|
|
70442
70558
|
type: "object",
|
|
70443
70559
|
properties: {
|
|
@@ -70445,6 +70561,32 @@ const dashboardTools$1 = [
|
|
|
70445
70561
|
type: "string",
|
|
70446
70562
|
description: "Display name for the new dashboard",
|
|
70447
70563
|
},
|
|
70564
|
+
layout: {
|
|
70565
|
+
type: "object",
|
|
70566
|
+
description:
|
|
70567
|
+
"Optional grid layout configuration. When provided, creates a grid dashboard instead of a simple container.",
|
|
70568
|
+
properties: {
|
|
70569
|
+
rows: {
|
|
70570
|
+
type: "number",
|
|
70571
|
+
description: "Number of rows (1-10)",
|
|
70572
|
+
},
|
|
70573
|
+
cols: {
|
|
70574
|
+
type: "number",
|
|
70575
|
+
description: "Number of columns (1-10)",
|
|
70576
|
+
},
|
|
70577
|
+
gap: {
|
|
70578
|
+
type: "string",
|
|
70579
|
+
description:
|
|
70580
|
+
"Tailwind gap class (e.g. 'gap-2', 'gap-4'). Defaults to 'gap-2'.",
|
|
70581
|
+
},
|
|
70582
|
+
colModes: {
|
|
70583
|
+
type: "object",
|
|
70584
|
+
description:
|
|
70585
|
+
"Per-row column sizing. Keys are row numbers (as strings), values are mode strings: 'equal', '1/4', '1/3', '1/2', '2/3'.",
|
|
70586
|
+
},
|
|
70587
|
+
},
|
|
70588
|
+
required: ["rows", "cols"],
|
|
70589
|
+
},
|
|
70448
70590
|
},
|
|
70449
70591
|
required: ["name"],
|
|
70450
70592
|
},
|
|
@@ -70480,7 +70622,7 @@ const widgetTools$1 = [
|
|
|
70480
70622
|
{
|
|
70481
70623
|
name: "add_widget",
|
|
70482
70624
|
description:
|
|
70483
|
-
"Add a widget to a dashboard by component name. Call list_widgets or search_widgets first to discover available widget names. Can be called multiple times to add multiple widgets. Returns the widget instance ID for use with configure_widget.",
|
|
70625
|
+
"Add a widget to a dashboard by component name. Call list_widgets or search_widgets first to discover available widget names. Can be called multiple times to add multiple widgets. Returns the widget instance ID for use with configure_widget. If the dashboard has a grid layout, you can specify row/col for explicit placement, or omit them to auto-place in the next empty cell.",
|
|
70484
70626
|
inputSchema: {
|
|
70485
70627
|
type: "object",
|
|
70486
70628
|
properties: {
|
|
@@ -70494,6 +70636,16 @@ const widgetTools$1 = [
|
|
|
70494
70636
|
description:
|
|
70495
70637
|
"Component name of the widget to add (e.g. 'Clock', 'WeatherWidget')",
|
|
70496
70638
|
},
|
|
70639
|
+
row: {
|
|
70640
|
+
type: "number",
|
|
70641
|
+
description:
|
|
70642
|
+
"Grid row to place the widget in (1-indexed). Must be used together with col. Requires a grid layout on the dashboard.",
|
|
70643
|
+
},
|
|
70644
|
+
col: {
|
|
70645
|
+
type: "number",
|
|
70646
|
+
description:
|
|
70647
|
+
"Grid column to place the widget in (1-indexed). Must be used together with row.",
|
|
70648
|
+
},
|
|
70497
70649
|
},
|
|
70498
70650
|
required: ["widgetName"],
|
|
70499
70651
|
},
|
|
@@ -70744,12 +70896,108 @@ const providerTools$1 = [
|
|
|
70744
70896
|
},
|
|
70745
70897
|
];
|
|
70746
70898
|
|
|
70899
|
+
const layoutTools$1 = [
|
|
70900
|
+
{
|
|
70901
|
+
name: "set_layout",
|
|
70902
|
+
description:
|
|
70903
|
+
"Set or replace the grid layout on a dashboard. Creates a LayoutGridContainer with the specified dimensions. Existing widgets in cells that fit the new grid are preserved; widgets outside the new bounds are orphaned (kept but unassigned). Use this to add a grid to an existing dashboard or to resize the grid.",
|
|
70904
|
+
inputSchema: {
|
|
70905
|
+
type: "object",
|
|
70906
|
+
properties: {
|
|
70907
|
+
dashboardId: {
|
|
70908
|
+
type: "string",
|
|
70909
|
+
description: "Dashboard ID. Omit to use the active dashboard.",
|
|
70910
|
+
},
|
|
70911
|
+
rows: {
|
|
70912
|
+
type: "number",
|
|
70913
|
+
description: "Number of rows (1-10)",
|
|
70914
|
+
},
|
|
70915
|
+
cols: {
|
|
70916
|
+
type: "number",
|
|
70917
|
+
description: "Number of columns (1-10)",
|
|
70918
|
+
},
|
|
70919
|
+
gap: {
|
|
70920
|
+
type: "string",
|
|
70921
|
+
description:
|
|
70922
|
+
"Tailwind gap class (e.g. 'gap-2', 'gap-4'). Defaults to 'gap-2'.",
|
|
70923
|
+
},
|
|
70924
|
+
colModes: {
|
|
70925
|
+
type: "object",
|
|
70926
|
+
description:
|
|
70927
|
+
"Per-row column sizing. Keys are row numbers (as strings), values are mode strings: 'equal', '1/4', '1/3', '1/2', '2/3'.",
|
|
70928
|
+
},
|
|
70929
|
+
},
|
|
70930
|
+
required: ["rows", "cols"],
|
|
70931
|
+
},
|
|
70932
|
+
},
|
|
70933
|
+
{
|
|
70934
|
+
name: "update_layout",
|
|
70935
|
+
description:
|
|
70936
|
+
"Partially update the grid layout. Only specified properties change — omitted properties keep their current values. colModes is merged (not replaced). Widgets in removed rows/columns are orphaned. Dashboard must already have a grid layout.",
|
|
70937
|
+
inputSchema: {
|
|
70938
|
+
type: "object",
|
|
70939
|
+
properties: {
|
|
70940
|
+
dashboardId: {
|
|
70941
|
+
type: "string",
|
|
70942
|
+
description: "Dashboard ID. Omit to use the active dashboard.",
|
|
70943
|
+
},
|
|
70944
|
+
rows: {
|
|
70945
|
+
type: "number",
|
|
70946
|
+
description: "New number of rows (1-10). Omit to keep current.",
|
|
70947
|
+
},
|
|
70948
|
+
cols: {
|
|
70949
|
+
type: "number",
|
|
70950
|
+
description: "New number of columns (1-10). Omit to keep current.",
|
|
70951
|
+
},
|
|
70952
|
+
gap: {
|
|
70953
|
+
type: "string",
|
|
70954
|
+
description: "Tailwind gap class. Omit to keep current.",
|
|
70955
|
+
},
|
|
70956
|
+
colModes: {
|
|
70957
|
+
type: "object",
|
|
70958
|
+
description:
|
|
70959
|
+
"Column sizing modes to merge. Set a key to null to reset that row to default.",
|
|
70960
|
+
},
|
|
70961
|
+
},
|
|
70962
|
+
required: [],
|
|
70963
|
+
},
|
|
70964
|
+
},
|
|
70965
|
+
{
|
|
70966
|
+
name: "move_widget",
|
|
70967
|
+
description:
|
|
70968
|
+
"Move a widget to a different grid cell. If the target cell is occupied, the two widgets are swapped. The widget must already be placed in a grid cell. Use get_dashboard to find widget IDs and current positions.",
|
|
70969
|
+
inputSchema: {
|
|
70970
|
+
type: "object",
|
|
70971
|
+
properties: {
|
|
70972
|
+
dashboardId: {
|
|
70973
|
+
type: "string",
|
|
70974
|
+
description: "Dashboard ID. Omit to use the active dashboard.",
|
|
70975
|
+
},
|
|
70976
|
+
widgetId: {
|
|
70977
|
+
type: "string",
|
|
70978
|
+
description: "ID of the widget to move",
|
|
70979
|
+
},
|
|
70980
|
+
row: {
|
|
70981
|
+
type: "number",
|
|
70982
|
+
description: "Target row (1-indexed)",
|
|
70983
|
+
},
|
|
70984
|
+
col: {
|
|
70985
|
+
type: "number",
|
|
70986
|
+
description: "Target column (1-indexed)",
|
|
70987
|
+
},
|
|
70988
|
+
},
|
|
70989
|
+
required: ["widgetId", "row", "col"],
|
|
70990
|
+
},
|
|
70991
|
+
},
|
|
70992
|
+
];
|
|
70993
|
+
|
|
70747
70994
|
var toolDefinitions = {
|
|
70748
70995
|
dashboardTools: dashboardTools$1,
|
|
70749
70996
|
widgetTools: widgetTools$1,
|
|
70750
70997
|
themeTools: themeTools$1,
|
|
70751
70998
|
providerTools: providerTools$1,
|
|
70752
70999
|
guideTools: guideTools$1,
|
|
71000
|
+
layoutTools: layoutTools$1,
|
|
70753
71001
|
};
|
|
70754
71002
|
|
|
70755
71003
|
/**
|
|
@@ -70905,7 +71153,7 @@ async function handleGetDashboard$1({ dashboardId }) {
|
|
|
70905
71153
|
/**
|
|
70906
71154
|
* create_dashboard — Creates a new workspace with the given name.
|
|
70907
71155
|
*/
|
|
70908
|
-
async function handleCreateDashboard$1({ name }) {
|
|
71156
|
+
async function handleCreateDashboard$1({ name, layout }) {
|
|
70909
71157
|
if (!name || typeof name !== "string" || !name.trim()) {
|
|
70910
71158
|
return {
|
|
70911
71159
|
content: [
|
|
@@ -70920,8 +71168,86 @@ async function handleCreateDashboard$1({ name }) {
|
|
|
70920
71168
|
};
|
|
70921
71169
|
}
|
|
70922
71170
|
|
|
71171
|
+
// Validate optional layout parameter
|
|
71172
|
+
if (layout !== undefined && layout !== null) {
|
|
71173
|
+
if (typeof layout !== "object" || Array.isArray(layout)) {
|
|
71174
|
+
return {
|
|
71175
|
+
content: [
|
|
71176
|
+
{
|
|
71177
|
+
type: "text",
|
|
71178
|
+
text: JSON.stringify({
|
|
71179
|
+
error: "layout must be an object with rows and cols",
|
|
71180
|
+
}),
|
|
71181
|
+
},
|
|
71182
|
+
],
|
|
71183
|
+
isError: true,
|
|
71184
|
+
};
|
|
71185
|
+
}
|
|
71186
|
+
const { rows, cols } = layout;
|
|
71187
|
+
if (
|
|
71188
|
+
rows === undefined ||
|
|
71189
|
+
cols === undefined ||
|
|
71190
|
+
typeof rows !== "number" ||
|
|
71191
|
+
typeof cols !== "number"
|
|
71192
|
+
) {
|
|
71193
|
+
return {
|
|
71194
|
+
content: [
|
|
71195
|
+
{
|
|
71196
|
+
type: "text",
|
|
71197
|
+
text: JSON.stringify({
|
|
71198
|
+
error: "layout.rows and layout.cols are required numbers",
|
|
71199
|
+
}),
|
|
71200
|
+
},
|
|
71201
|
+
],
|
|
71202
|
+
isError: true,
|
|
71203
|
+
};
|
|
71204
|
+
}
|
|
71205
|
+
if (rows < 1 || rows > 10 || cols < 1 || cols > 10) {
|
|
71206
|
+
return {
|
|
71207
|
+
content: [
|
|
71208
|
+
{
|
|
71209
|
+
type: "text",
|
|
71210
|
+
text: JSON.stringify({
|
|
71211
|
+
error: "rows and cols must be between 1 and 10",
|
|
71212
|
+
}),
|
|
71213
|
+
},
|
|
71214
|
+
],
|
|
71215
|
+
isError: true,
|
|
71216
|
+
};
|
|
71217
|
+
}
|
|
71218
|
+
}
|
|
71219
|
+
|
|
70923
71220
|
const { win, appId } = requireContext$1();
|
|
70924
71221
|
|
|
71222
|
+
// Build root layout node — grid or plain container
|
|
71223
|
+
const rootNode =
|
|
71224
|
+
layout && layout.rows && layout.cols
|
|
71225
|
+
? {
|
|
71226
|
+
id: 1,
|
|
71227
|
+
order: 1,
|
|
71228
|
+
component: "LayoutGridContainer",
|
|
71229
|
+
type: "grid",
|
|
71230
|
+
parent: 0,
|
|
71231
|
+
hasChildren: 1,
|
|
71232
|
+
scrollable: false,
|
|
71233
|
+
width: "w-full",
|
|
71234
|
+
height: "h-full",
|
|
71235
|
+
workspace: "layout",
|
|
71236
|
+
grid: buildEmptyGrid(
|
|
71237
|
+
layout.rows,
|
|
71238
|
+
layout.cols,
|
|
71239
|
+
layout.gap,
|
|
71240
|
+
layout.colModes,
|
|
71241
|
+
),
|
|
71242
|
+
}
|
|
71243
|
+
: {
|
|
71244
|
+
id: 1,
|
|
71245
|
+
order: 1,
|
|
71246
|
+
component: "Container",
|
|
71247
|
+
parent: 0,
|
|
71248
|
+
items: [],
|
|
71249
|
+
};
|
|
71250
|
+
|
|
70925
71251
|
const newWorkspace = {
|
|
70926
71252
|
id: Date.now(),
|
|
70927
71253
|
name: name.trim(),
|
|
@@ -70929,15 +71255,7 @@ async function handleCreateDashboard$1({ name }) {
|
|
|
70929
71255
|
type: "workspace",
|
|
70930
71256
|
version: 1,
|
|
70931
71257
|
menuId: 1,
|
|
70932
|
-
layout: [
|
|
70933
|
-
{
|
|
70934
|
-
id: 1,
|
|
70935
|
-
order: 1,
|
|
70936
|
-
component: "Container",
|
|
70937
|
-
parentId: 0,
|
|
70938
|
-
items: [],
|
|
70939
|
-
},
|
|
70940
|
-
],
|
|
71258
|
+
layout: [rootNode],
|
|
70941
71259
|
};
|
|
70942
71260
|
|
|
70943
71261
|
const result = workspaceController$2.saveWorkspaceForApplication(
|
|
@@ -70958,15 +71276,16 @@ async function handleCreateDashboard$1({ name }) {
|
|
|
70958
71276
|
};
|
|
70959
71277
|
}
|
|
70960
71278
|
|
|
71279
|
+
const response = { id: String(newWorkspace.id), name: newWorkspace.name };
|
|
71280
|
+
if (layout && layout.rows && layout.cols) {
|
|
71281
|
+
response.layout = { rows: layout.rows, cols: layout.cols };
|
|
71282
|
+
}
|
|
71283
|
+
|
|
70961
71284
|
return {
|
|
70962
71285
|
content: [
|
|
70963
71286
|
{
|
|
70964
71287
|
type: "text",
|
|
70965
|
-
text: JSON.stringify(
|
|
70966
|
-
{ id: String(newWorkspace.id), name: newWorkspace.name },
|
|
70967
|
-
null,
|
|
70968
|
-
2,
|
|
70969
|
-
),
|
|
71288
|
+
text: JSON.stringify(response, null, 2),
|
|
70970
71289
|
},
|
|
70971
71290
|
],
|
|
70972
71291
|
};
|
|
@@ -71157,10 +71476,65 @@ function nextLayoutId(layout) {
|
|
|
71157
71476
|
return maxId + 1;
|
|
71158
71477
|
}
|
|
71159
71478
|
|
|
71479
|
+
/**
|
|
71480
|
+
* Helper: find the LayoutGridContainer node in a layout array.
|
|
71481
|
+
*/
|
|
71482
|
+
function findGridNode(layout) {
|
|
71483
|
+
if (!Array.isArray(layout)) return null;
|
|
71484
|
+
return (
|
|
71485
|
+
layout.find(
|
|
71486
|
+
(item) => item.component === "LayoutGridContainer" && item.grid,
|
|
71487
|
+
) || null
|
|
71488
|
+
);
|
|
71489
|
+
}
|
|
71490
|
+
|
|
71491
|
+
/**
|
|
71492
|
+
* Helper: build an empty grid object with cell slots for all row.col positions.
|
|
71493
|
+
*/
|
|
71494
|
+
function buildEmptyGrid(rows, cols, gap, colModes) {
|
|
71495
|
+
const grid = {
|
|
71496
|
+
rows,
|
|
71497
|
+
cols,
|
|
71498
|
+
gap: gap || "gap-2",
|
|
71499
|
+
};
|
|
71500
|
+
if (colModes && Object.keys(colModes).length > 0) {
|
|
71501
|
+
grid.colModes = colModes;
|
|
71502
|
+
}
|
|
71503
|
+
for (let r = 1; r <= rows; r++) {
|
|
71504
|
+
for (let c = 1; c <= cols; c++) {
|
|
71505
|
+
grid[`${r}.${c}`] = { component: null, hide: false };
|
|
71506
|
+
}
|
|
71507
|
+
}
|
|
71508
|
+
return grid;
|
|
71509
|
+
}
|
|
71510
|
+
|
|
71511
|
+
/**
|
|
71512
|
+
* Helper: find the next empty cell scanning left-to-right, top-to-bottom.
|
|
71513
|
+
*/
|
|
71514
|
+
function findNextEmptyCell(grid) {
|
|
71515
|
+
for (let r = 1; r <= grid.rows; r++) {
|
|
71516
|
+
for (let c = 1; c <= grid.cols; c++) {
|
|
71517
|
+
const key = `${r}.${c}`;
|
|
71518
|
+
const cell = grid[key];
|
|
71519
|
+
if (!cell || (cell.component === null && !cell.hide)) {
|
|
71520
|
+
return { row: r, col: c };
|
|
71521
|
+
}
|
|
71522
|
+
}
|
|
71523
|
+
}
|
|
71524
|
+
return null;
|
|
71525
|
+
}
|
|
71526
|
+
|
|
71527
|
+
/**
|
|
71528
|
+
* Helper: check if a row/col position is within grid bounds.
|
|
71529
|
+
*/
|
|
71530
|
+
function isValidCell(grid, row, col) {
|
|
71531
|
+
return row >= 1 && row <= grid.rows && col >= 1 && col <= grid.cols;
|
|
71532
|
+
}
|
|
71533
|
+
|
|
71160
71534
|
/**
|
|
71161
71535
|
* add_widget — Add a widget to a dashboard by component name.
|
|
71162
71536
|
*/
|
|
71163
|
-
async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
71537
|
+
async function handleAddWidget$1({ dashboardId, widgetName, row, col }) {
|
|
71164
71538
|
if (!widgetName || typeof widgetName !== "string" || !widgetName.trim()) {
|
|
71165
71539
|
return {
|
|
71166
71540
|
content: [
|
|
@@ -71175,6 +71549,25 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71175
71549
|
};
|
|
71176
71550
|
}
|
|
71177
71551
|
|
|
71552
|
+
// Validate row/col pairing
|
|
71553
|
+
if (
|
|
71554
|
+
(row !== undefined && col === undefined) ||
|
|
71555
|
+
(row === undefined && col !== undefined)
|
|
71556
|
+
) {
|
|
71557
|
+
return {
|
|
71558
|
+
content: [
|
|
71559
|
+
{
|
|
71560
|
+
type: "text",
|
|
71561
|
+
text: JSON.stringify({
|
|
71562
|
+
error:
|
|
71563
|
+
"Both row and col must be provided together, or both omitted",
|
|
71564
|
+
}),
|
|
71565
|
+
},
|
|
71566
|
+
],
|
|
71567
|
+
isError: true,
|
|
71568
|
+
};
|
|
71569
|
+
}
|
|
71570
|
+
|
|
71178
71571
|
const { win, appId } = requireContext$1();
|
|
71179
71572
|
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
71180
71573
|
if (result.error) {
|
|
@@ -71199,7 +71592,88 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71199
71592
|
item.component === "LayoutContainer" ||
|
|
71200
71593
|
item.component === "LayoutGridContainer",
|
|
71201
71594
|
);
|
|
71202
|
-
|
|
71595
|
+
|
|
71596
|
+
const gridNode = findGridNode(layout);
|
|
71597
|
+
|
|
71598
|
+
// Determine grid placement
|
|
71599
|
+
let targetRow = null;
|
|
71600
|
+
let targetCol = null;
|
|
71601
|
+
|
|
71602
|
+
if (row !== undefined && col !== undefined) {
|
|
71603
|
+
// Explicit placement requested
|
|
71604
|
+
if (!gridNode) {
|
|
71605
|
+
return {
|
|
71606
|
+
content: [
|
|
71607
|
+
{
|
|
71608
|
+
type: "text",
|
|
71609
|
+
text: JSON.stringify({
|
|
71610
|
+
error:
|
|
71611
|
+
"Cannot specify row/col: dashboard has no grid layout. Use create_dashboard with layout or set_layout first.",
|
|
71612
|
+
}),
|
|
71613
|
+
},
|
|
71614
|
+
],
|
|
71615
|
+
isError: true,
|
|
71616
|
+
};
|
|
71617
|
+
}
|
|
71618
|
+
const r = Number(row);
|
|
71619
|
+
const c = Number(col);
|
|
71620
|
+
if (!isValidCell(gridNode.grid, r, c)) {
|
|
71621
|
+
return {
|
|
71622
|
+
content: [
|
|
71623
|
+
{
|
|
71624
|
+
type: "text",
|
|
71625
|
+
text: JSON.stringify({
|
|
71626
|
+
error: `Cell ${r}.${c} is out of bounds (grid is ${gridNode.grid.rows}x${gridNode.grid.cols})`,
|
|
71627
|
+
}),
|
|
71628
|
+
},
|
|
71629
|
+
],
|
|
71630
|
+
isError: true,
|
|
71631
|
+
};
|
|
71632
|
+
}
|
|
71633
|
+
const cellKey = `${r}.${c}`;
|
|
71634
|
+
const cell = gridNode.grid[cellKey];
|
|
71635
|
+
if (cell && cell.hide) {
|
|
71636
|
+
return {
|
|
71637
|
+
content: [
|
|
71638
|
+
{
|
|
71639
|
+
type: "text",
|
|
71640
|
+
text: JSON.stringify({
|
|
71641
|
+
error: `Cell ${r}.${c} is hidden`,
|
|
71642
|
+
}),
|
|
71643
|
+
},
|
|
71644
|
+
],
|
|
71645
|
+
isError: true,
|
|
71646
|
+
};
|
|
71647
|
+
}
|
|
71648
|
+
if (cell && cell.component !== null) {
|
|
71649
|
+
return {
|
|
71650
|
+
content: [
|
|
71651
|
+
{
|
|
71652
|
+
type: "text",
|
|
71653
|
+
text: JSON.stringify({
|
|
71654
|
+
error: `Cell ${r}.${c} is already occupied by widget ${cell.component}`,
|
|
71655
|
+
}),
|
|
71656
|
+
},
|
|
71657
|
+
],
|
|
71658
|
+
isError: true,
|
|
71659
|
+
};
|
|
71660
|
+
}
|
|
71661
|
+
targetRow = r;
|
|
71662
|
+
targetCol = c;
|
|
71663
|
+
} else if (gridNode) {
|
|
71664
|
+
// No row/col specified but grid exists — auto-place in next empty cell
|
|
71665
|
+
const empty = findNextEmptyCell(gridNode.grid);
|
|
71666
|
+
if (empty) {
|
|
71667
|
+
targetRow = empty.row;
|
|
71668
|
+
targetCol = empty.col;
|
|
71669
|
+
}
|
|
71670
|
+
}
|
|
71671
|
+
|
|
71672
|
+
const parentContainerId = gridNode
|
|
71673
|
+
? gridNode.id
|
|
71674
|
+
: container
|
|
71675
|
+
? container.id
|
|
71676
|
+
: 0;
|
|
71203
71677
|
|
|
71204
71678
|
const newId = nextLayoutId(layout);
|
|
71205
71679
|
const maxOrder = layout.reduce(
|
|
@@ -71211,12 +71685,22 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71211
71685
|
id: newId,
|
|
71212
71686
|
order: maxOrder + 1,
|
|
71213
71687
|
component: widgetName.trim(),
|
|
71214
|
-
|
|
71688
|
+
parent: parentContainerId,
|
|
71215
71689
|
config: {},
|
|
71216
71690
|
};
|
|
71217
71691
|
|
|
71218
71692
|
workspace.layout = [...layout, newItem];
|
|
71219
71693
|
|
|
71694
|
+
// If placing in grid, update the cell assignment
|
|
71695
|
+
if (gridNode && targetRow !== null && targetCol !== null) {
|
|
71696
|
+
const cellKey = `${targetRow}.${targetCol}`;
|
|
71697
|
+
gridNode.grid[cellKey] = {
|
|
71698
|
+
...(gridNode.grid[cellKey] || {}),
|
|
71699
|
+
component: newId,
|
|
71700
|
+
hide: false,
|
|
71701
|
+
};
|
|
71702
|
+
}
|
|
71703
|
+
|
|
71220
71704
|
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
71221
71705
|
win,
|
|
71222
71706
|
appId,
|
|
@@ -71234,19 +71718,20 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71234
71718
|
};
|
|
71235
71719
|
}
|
|
71236
71720
|
|
|
71721
|
+
const response = {
|
|
71722
|
+
widgetId: String(newId),
|
|
71723
|
+
name: widgetName.trim(),
|
|
71724
|
+
dashboardId: String(workspace.id),
|
|
71725
|
+
};
|
|
71726
|
+
if (targetRow !== null && targetCol !== null) {
|
|
71727
|
+
response.cell = { row: targetRow, col: targetCol };
|
|
71728
|
+
}
|
|
71729
|
+
|
|
71237
71730
|
return {
|
|
71238
71731
|
content: [
|
|
71239
71732
|
{
|
|
71240
71733
|
type: "text",
|
|
71241
|
-
text: JSON.stringify(
|
|
71242
|
-
{
|
|
71243
|
-
widgetId: String(newId),
|
|
71244
|
-
name: widgetName.trim(),
|
|
71245
|
-
dashboardId: String(workspace.id),
|
|
71246
|
-
},
|
|
71247
|
-
null,
|
|
71248
|
-
2,
|
|
71249
|
-
),
|
|
71734
|
+
text: JSON.stringify(response, null, 2),
|
|
71250
71735
|
},
|
|
71251
71736
|
],
|
|
71252
71737
|
};
|
|
@@ -71302,6 +71787,21 @@ async function handleRemoveWidget$1({ dashboardId, widgetId }) {
|
|
|
71302
71787
|
|
|
71303
71788
|
workspace.layout = layout.filter((item) => String(item.id) !== widgetId);
|
|
71304
71789
|
|
|
71790
|
+
// Clean up grid cell assignments that reference this widget
|
|
71791
|
+
const numericId = Number(widgetId);
|
|
71792
|
+
for (const item of workspace.layout) {
|
|
71793
|
+
if (item.grid) {
|
|
71794
|
+
for (const key of Object.keys(item.grid)) {
|
|
71795
|
+
if (/^\d+\.\d+$/.test(key)) {
|
|
71796
|
+
const cell = item.grid[key];
|
|
71797
|
+
if (cell && cell.component === numericId) {
|
|
71798
|
+
cell.component = null;
|
|
71799
|
+
}
|
|
71800
|
+
}
|
|
71801
|
+
}
|
|
71802
|
+
}
|
|
71803
|
+
}
|
|
71804
|
+
|
|
71305
71805
|
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
71306
71806
|
win,
|
|
71307
71807
|
appId,
|
|
@@ -72463,6 +72963,492 @@ async function handleGetSetupGuide$1({ topic }) {
|
|
|
72463
72963
|
};
|
|
72464
72964
|
}
|
|
72465
72965
|
|
|
72966
|
+
// --- Layout Tool Handlers ---
|
|
72967
|
+
|
|
72968
|
+
/**
|
|
72969
|
+
* set_layout — Set or replace the grid layout on a dashboard.
|
|
72970
|
+
*/
|
|
72971
|
+
async function handleSetLayout$1({ dashboardId, rows, cols, gap, colModes }) {
|
|
72972
|
+
if (
|
|
72973
|
+
rows === undefined ||
|
|
72974
|
+
cols === undefined ||
|
|
72975
|
+
typeof rows !== "number" ||
|
|
72976
|
+
typeof cols !== "number"
|
|
72977
|
+
) {
|
|
72978
|
+
return {
|
|
72979
|
+
content: [
|
|
72980
|
+
{
|
|
72981
|
+
type: "text",
|
|
72982
|
+
text: JSON.stringify({
|
|
72983
|
+
error: "rows and cols are required numbers",
|
|
72984
|
+
}),
|
|
72985
|
+
},
|
|
72986
|
+
],
|
|
72987
|
+
isError: true,
|
|
72988
|
+
};
|
|
72989
|
+
}
|
|
72990
|
+
if (rows < 1 || rows > 10 || cols < 1 || cols > 10) {
|
|
72991
|
+
return {
|
|
72992
|
+
content: [
|
|
72993
|
+
{
|
|
72994
|
+
type: "text",
|
|
72995
|
+
text: JSON.stringify({
|
|
72996
|
+
error: "rows and cols must be between 1 and 10",
|
|
72997
|
+
}),
|
|
72998
|
+
},
|
|
72999
|
+
],
|
|
73000
|
+
isError: true,
|
|
73001
|
+
};
|
|
73002
|
+
}
|
|
73003
|
+
|
|
73004
|
+
const { win, appId } = requireContext$1();
|
|
73005
|
+
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
73006
|
+
if (result.error) {
|
|
73007
|
+
return {
|
|
73008
|
+
content: [
|
|
73009
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
73010
|
+
],
|
|
73011
|
+
isError: true,
|
|
73012
|
+
};
|
|
73013
|
+
}
|
|
73014
|
+
|
|
73015
|
+
const found = findWorkspace(result.workspaces || [], dashboardId);
|
|
73016
|
+
if (found.error) return found.response;
|
|
73017
|
+
|
|
73018
|
+
const workspace = found.workspace;
|
|
73019
|
+
const layout = workspace.layout || [];
|
|
73020
|
+
|
|
73021
|
+
const newGrid = buildEmptyGrid(rows, cols, gap, colModes);
|
|
73022
|
+
const existingGridNode = findGridNode(layout);
|
|
73023
|
+
const orphanedWidgetIds = [];
|
|
73024
|
+
|
|
73025
|
+
if (existingGridNode) {
|
|
73026
|
+
// Preserve cell assignments that still fit in the new dimensions
|
|
73027
|
+
const oldGrid = existingGridNode.grid;
|
|
73028
|
+
for (const key of Object.keys(oldGrid)) {
|
|
73029
|
+
if (
|
|
73030
|
+
/^\d+\.\d+$/.test(key) &&
|
|
73031
|
+
oldGrid[key] &&
|
|
73032
|
+
oldGrid[key].component !== null
|
|
73033
|
+
) {
|
|
73034
|
+
const parts = key.split(".");
|
|
73035
|
+
const r = Number(parts[0]);
|
|
73036
|
+
const c = Number(parts[1]);
|
|
73037
|
+
if (r <= rows && c <= cols) {
|
|
73038
|
+
newGrid[key] = { ...newGrid[key], component: oldGrid[key].component };
|
|
73039
|
+
} else {
|
|
73040
|
+
orphanedWidgetIds.push(oldGrid[key].component);
|
|
73041
|
+
}
|
|
73042
|
+
}
|
|
73043
|
+
}
|
|
73044
|
+
existingGridNode.grid = newGrid;
|
|
73045
|
+
} else {
|
|
73046
|
+
// Replace root Container with a LayoutGridContainer
|
|
73047
|
+
const rootIdx = layout.findIndex(
|
|
73048
|
+
(item) =>
|
|
73049
|
+
item.parent === 0 &&
|
|
73050
|
+
(item.component === "Container" ||
|
|
73051
|
+
item.component === "LayoutContainer"),
|
|
73052
|
+
);
|
|
73053
|
+
|
|
73054
|
+
const newGridNode = {
|
|
73055
|
+
id: rootIdx >= 0 ? layout[rootIdx].id : nextLayoutId(layout),
|
|
73056
|
+
order: 1,
|
|
73057
|
+
component: "LayoutGridContainer",
|
|
73058
|
+
type: "grid",
|
|
73059
|
+
parent: 0,
|
|
73060
|
+
hasChildren: 1,
|
|
73061
|
+
scrollable: false,
|
|
73062
|
+
width: "w-full",
|
|
73063
|
+
height: "h-full",
|
|
73064
|
+
workspace: "layout",
|
|
73065
|
+
grid: newGrid,
|
|
73066
|
+
};
|
|
73067
|
+
|
|
73068
|
+
if (rootIdx >= 0) {
|
|
73069
|
+
// Reparent existing widgets to the new grid node
|
|
73070
|
+
const oldRootId = layout[rootIdx].id;
|
|
73071
|
+
for (const item of layout) {
|
|
73072
|
+
if (item.parent === oldRootId && item.id !== oldRootId) {
|
|
73073
|
+
item.parent = newGridNode.id;
|
|
73074
|
+
}
|
|
73075
|
+
}
|
|
73076
|
+
workspace.layout[rootIdx] = newGridNode;
|
|
73077
|
+
} else {
|
|
73078
|
+
workspace.layout = [newGridNode, ...layout];
|
|
73079
|
+
}
|
|
73080
|
+
}
|
|
73081
|
+
|
|
73082
|
+
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
73083
|
+
win,
|
|
73084
|
+
appId,
|
|
73085
|
+
workspace,
|
|
73086
|
+
);
|
|
73087
|
+
if (saveResult.error) {
|
|
73088
|
+
return {
|
|
73089
|
+
content: [
|
|
73090
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
73091
|
+
],
|
|
73092
|
+
isError: true,
|
|
73093
|
+
};
|
|
73094
|
+
}
|
|
73095
|
+
|
|
73096
|
+
return {
|
|
73097
|
+
content: [
|
|
73098
|
+
{
|
|
73099
|
+
type: "text",
|
|
73100
|
+
text: JSON.stringify(
|
|
73101
|
+
{
|
|
73102
|
+
dashboardId: String(workspace.id),
|
|
73103
|
+
grid: { rows, cols },
|
|
73104
|
+
orphanedWidgets: orphanedWidgetIds.map(String),
|
|
73105
|
+
},
|
|
73106
|
+
null,
|
|
73107
|
+
2,
|
|
73108
|
+
),
|
|
73109
|
+
},
|
|
73110
|
+
],
|
|
73111
|
+
};
|
|
73112
|
+
}
|
|
73113
|
+
|
|
73114
|
+
/**
|
|
73115
|
+
* update_layout — Partially update grid layout properties.
|
|
73116
|
+
*/
|
|
73117
|
+
async function handleUpdateLayout$1({ dashboardId, rows, cols, gap, colModes }) {
|
|
73118
|
+
if (
|
|
73119
|
+
rows === undefined &&
|
|
73120
|
+
cols === undefined &&
|
|
73121
|
+
gap === undefined &&
|
|
73122
|
+
colModes === undefined
|
|
73123
|
+
) {
|
|
73124
|
+
return {
|
|
73125
|
+
content: [
|
|
73126
|
+
{
|
|
73127
|
+
type: "text",
|
|
73128
|
+
text: JSON.stringify({
|
|
73129
|
+
error:
|
|
73130
|
+
"At least one of rows, cols, gap, or colModes must be provided",
|
|
73131
|
+
}),
|
|
73132
|
+
},
|
|
73133
|
+
],
|
|
73134
|
+
isError: true,
|
|
73135
|
+
};
|
|
73136
|
+
}
|
|
73137
|
+
|
|
73138
|
+
const { win, appId } = requireContext$1();
|
|
73139
|
+
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
73140
|
+
if (result.error) {
|
|
73141
|
+
return {
|
|
73142
|
+
content: [
|
|
73143
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
73144
|
+
],
|
|
73145
|
+
isError: true,
|
|
73146
|
+
};
|
|
73147
|
+
}
|
|
73148
|
+
|
|
73149
|
+
const found = findWorkspace(result.workspaces || [], dashboardId);
|
|
73150
|
+
if (found.error) return found.response;
|
|
73151
|
+
|
|
73152
|
+
const workspace = found.workspace;
|
|
73153
|
+
const gridNode = findGridNode(workspace.layout || []);
|
|
73154
|
+
|
|
73155
|
+
if (!gridNode) {
|
|
73156
|
+
return {
|
|
73157
|
+
content: [
|
|
73158
|
+
{
|
|
73159
|
+
type: "text",
|
|
73160
|
+
text: JSON.stringify({
|
|
73161
|
+
error:
|
|
73162
|
+
"Dashboard has no grid layout. Use set_layout or create_dashboard with layout first.",
|
|
73163
|
+
}),
|
|
73164
|
+
},
|
|
73165
|
+
],
|
|
73166
|
+
isError: true,
|
|
73167
|
+
};
|
|
73168
|
+
}
|
|
73169
|
+
|
|
73170
|
+
const grid = gridNode.grid;
|
|
73171
|
+
const oldRows = grid.rows;
|
|
73172
|
+
const oldCols = grid.cols;
|
|
73173
|
+
const newRows = rows !== undefined ? rows : oldRows;
|
|
73174
|
+
const newCols = cols !== undefined ? cols : oldCols;
|
|
73175
|
+
|
|
73176
|
+
if (newRows < 1 || newRows > 10 || newCols < 1 || newCols > 10) {
|
|
73177
|
+
return {
|
|
73178
|
+
content: [
|
|
73179
|
+
{
|
|
73180
|
+
type: "text",
|
|
73181
|
+
text: JSON.stringify({
|
|
73182
|
+
error: "rows and cols must be between 1 and 10",
|
|
73183
|
+
}),
|
|
73184
|
+
},
|
|
73185
|
+
],
|
|
73186
|
+
isError: true,
|
|
73187
|
+
};
|
|
73188
|
+
}
|
|
73189
|
+
|
|
73190
|
+
// Update gap if specified
|
|
73191
|
+
if (gap !== undefined) {
|
|
73192
|
+
grid.gap = gap;
|
|
73193
|
+
}
|
|
73194
|
+
|
|
73195
|
+
// Merge colModes if specified
|
|
73196
|
+
if (colModes !== undefined) {
|
|
73197
|
+
grid.colModes = { ...(grid.colModes || {}), ...colModes };
|
|
73198
|
+
// Remove entries set to null
|
|
73199
|
+
for (const k of Object.keys(grid.colModes)) {
|
|
73200
|
+
if (grid.colModes[k] === null) {
|
|
73201
|
+
delete grid.colModes[k];
|
|
73202
|
+
}
|
|
73203
|
+
}
|
|
73204
|
+
if (Object.keys(grid.colModes).length === 0) {
|
|
73205
|
+
delete grid.colModes;
|
|
73206
|
+
}
|
|
73207
|
+
}
|
|
73208
|
+
|
|
73209
|
+
// Handle dimension changes
|
|
73210
|
+
const orphanedWidgetIds = [];
|
|
73211
|
+
if (newRows !== oldRows || newCols !== oldCols) {
|
|
73212
|
+
// Add new cells
|
|
73213
|
+
for (let r = 1; r <= newRows; r++) {
|
|
73214
|
+
for (let c = 1; c <= newCols; c++) {
|
|
73215
|
+
const key = `${r}.${c}`;
|
|
73216
|
+
if (!grid[key]) {
|
|
73217
|
+
grid[key] = { component: null, hide: false };
|
|
73218
|
+
}
|
|
73219
|
+
}
|
|
73220
|
+
}
|
|
73221
|
+
// Collect orphaned widgets from removed cells
|
|
73222
|
+
for (const key of Object.keys(grid)) {
|
|
73223
|
+
if (/^\d+\.\d+$/.test(key)) {
|
|
73224
|
+
const parts = key.split(".");
|
|
73225
|
+
const r = Number(parts[0]);
|
|
73226
|
+
const c = Number(parts[1]);
|
|
73227
|
+
if (r > newRows || c > newCols) {
|
|
73228
|
+
if (grid[key] && grid[key].component !== null) {
|
|
73229
|
+
orphanedWidgetIds.push(grid[key].component);
|
|
73230
|
+
}
|
|
73231
|
+
delete grid[key];
|
|
73232
|
+
}
|
|
73233
|
+
}
|
|
73234
|
+
}
|
|
73235
|
+
grid.rows = newRows;
|
|
73236
|
+
grid.cols = newCols;
|
|
73237
|
+
}
|
|
73238
|
+
|
|
73239
|
+
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
73240
|
+
win,
|
|
73241
|
+
appId,
|
|
73242
|
+
workspace,
|
|
73243
|
+
);
|
|
73244
|
+
if (saveResult.error) {
|
|
73245
|
+
return {
|
|
73246
|
+
content: [
|
|
73247
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
73248
|
+
],
|
|
73249
|
+
isError: true,
|
|
73250
|
+
};
|
|
73251
|
+
}
|
|
73252
|
+
|
|
73253
|
+
return {
|
|
73254
|
+
content: [
|
|
73255
|
+
{
|
|
73256
|
+
type: "text",
|
|
73257
|
+
text: JSON.stringify(
|
|
73258
|
+
{
|
|
73259
|
+
dashboardId: String(workspace.id),
|
|
73260
|
+
grid: { rows: newRows, cols: newCols, gap: grid.gap },
|
|
73261
|
+
orphanedWidgets: orphanedWidgetIds.map(String),
|
|
73262
|
+
},
|
|
73263
|
+
null,
|
|
73264
|
+
2,
|
|
73265
|
+
),
|
|
73266
|
+
},
|
|
73267
|
+
],
|
|
73268
|
+
};
|
|
73269
|
+
}
|
|
73270
|
+
|
|
73271
|
+
/**
|
|
73272
|
+
* move_widget — Move a widget to a different grid cell (swap if occupied).
|
|
73273
|
+
*/
|
|
73274
|
+
async function handleMoveWidget$1({ dashboardId, widgetId, row, col }) {
|
|
73275
|
+
if (!widgetId || typeof widgetId !== "string") {
|
|
73276
|
+
return {
|
|
73277
|
+
content: [
|
|
73278
|
+
{
|
|
73279
|
+
type: "text",
|
|
73280
|
+
text: JSON.stringify({ error: "widgetId is required" }),
|
|
73281
|
+
},
|
|
73282
|
+
],
|
|
73283
|
+
isError: true,
|
|
73284
|
+
};
|
|
73285
|
+
}
|
|
73286
|
+
if (row === undefined || col === undefined) {
|
|
73287
|
+
return {
|
|
73288
|
+
content: [
|
|
73289
|
+
{
|
|
73290
|
+
type: "text",
|
|
73291
|
+
text: JSON.stringify({ error: "row and col are required" }),
|
|
73292
|
+
},
|
|
73293
|
+
],
|
|
73294
|
+
isError: true,
|
|
73295
|
+
};
|
|
73296
|
+
}
|
|
73297
|
+
|
|
73298
|
+
const { win, appId } = requireContext$1();
|
|
73299
|
+
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
73300
|
+
if (result.error) {
|
|
73301
|
+
return {
|
|
73302
|
+
content: [
|
|
73303
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
73304
|
+
],
|
|
73305
|
+
isError: true,
|
|
73306
|
+
};
|
|
73307
|
+
}
|
|
73308
|
+
|
|
73309
|
+
const found = findWorkspace(result.workspaces || [], dashboardId);
|
|
73310
|
+
if (found.error) return found.response;
|
|
73311
|
+
|
|
73312
|
+
const workspace = found.workspace;
|
|
73313
|
+
const gridNode = findGridNode(workspace.layout || []);
|
|
73314
|
+
|
|
73315
|
+
if (!gridNode) {
|
|
73316
|
+
return {
|
|
73317
|
+
content: [
|
|
73318
|
+
{
|
|
73319
|
+
type: "text",
|
|
73320
|
+
text: JSON.stringify({
|
|
73321
|
+
error: "Dashboard has no grid layout",
|
|
73322
|
+
}),
|
|
73323
|
+
},
|
|
73324
|
+
],
|
|
73325
|
+
isError: true,
|
|
73326
|
+
};
|
|
73327
|
+
}
|
|
73328
|
+
|
|
73329
|
+
const r = Number(row);
|
|
73330
|
+
const c = Number(col);
|
|
73331
|
+
if (!isValidCell(gridNode.grid, r, c)) {
|
|
73332
|
+
return {
|
|
73333
|
+
content: [
|
|
73334
|
+
{
|
|
73335
|
+
type: "text",
|
|
73336
|
+
text: JSON.stringify({
|
|
73337
|
+
error: `Cell ${r}.${c} is out of bounds (grid is ${gridNode.grid.rows}x${gridNode.grid.cols})`,
|
|
73338
|
+
}),
|
|
73339
|
+
},
|
|
73340
|
+
],
|
|
73341
|
+
isError: true,
|
|
73342
|
+
};
|
|
73343
|
+
}
|
|
73344
|
+
|
|
73345
|
+
const targetKey = `${r}.${c}`;
|
|
73346
|
+
const targetCell = gridNode.grid[targetKey];
|
|
73347
|
+
if (targetCell && targetCell.hide) {
|
|
73348
|
+
return {
|
|
73349
|
+
content: [
|
|
73350
|
+
{
|
|
73351
|
+
type: "text",
|
|
73352
|
+
text: JSON.stringify({
|
|
73353
|
+
error: `Cell ${r}.${c} is hidden`,
|
|
73354
|
+
}),
|
|
73355
|
+
},
|
|
73356
|
+
],
|
|
73357
|
+
isError: true,
|
|
73358
|
+
};
|
|
73359
|
+
}
|
|
73360
|
+
|
|
73361
|
+
// Find the widget's current cell
|
|
73362
|
+
const numericWidgetId = Number(widgetId);
|
|
73363
|
+
let sourceKey = null;
|
|
73364
|
+
for (const key of Object.keys(gridNode.grid)) {
|
|
73365
|
+
if (
|
|
73366
|
+
/^\d+\.\d+$/.test(key) &&
|
|
73367
|
+
gridNode.grid[key] &&
|
|
73368
|
+
gridNode.grid[key].component === numericWidgetId
|
|
73369
|
+
) {
|
|
73370
|
+
sourceKey = key;
|
|
73371
|
+
break;
|
|
73372
|
+
}
|
|
73373
|
+
}
|
|
73374
|
+
|
|
73375
|
+
if (!sourceKey) {
|
|
73376
|
+
return {
|
|
73377
|
+
content: [
|
|
73378
|
+
{
|
|
73379
|
+
type: "text",
|
|
73380
|
+
text: JSON.stringify({
|
|
73381
|
+
error: `Widget ${widgetId} not found in any grid cell`,
|
|
73382
|
+
}),
|
|
73383
|
+
},
|
|
73384
|
+
],
|
|
73385
|
+
isError: true,
|
|
73386
|
+
};
|
|
73387
|
+
}
|
|
73388
|
+
|
|
73389
|
+
if (sourceKey === targetKey) {
|
|
73390
|
+
return {
|
|
73391
|
+
content: [
|
|
73392
|
+
{
|
|
73393
|
+
type: "text",
|
|
73394
|
+
text: JSON.stringify(
|
|
73395
|
+
{
|
|
73396
|
+
widgetId,
|
|
73397
|
+
cell: { row: r, col: c },
|
|
73398
|
+
swapped: false,
|
|
73399
|
+
},
|
|
73400
|
+
null,
|
|
73401
|
+
2,
|
|
73402
|
+
),
|
|
73403
|
+
},
|
|
73404
|
+
],
|
|
73405
|
+
};
|
|
73406
|
+
}
|
|
73407
|
+
|
|
73408
|
+
// Perform the move (swap if target occupied)
|
|
73409
|
+
const targetComponentId = targetCell ? targetCell.component : null;
|
|
73410
|
+
gridNode.grid[targetKey] = {
|
|
73411
|
+
...(gridNode.grid[targetKey] || {}),
|
|
73412
|
+
component: numericWidgetId,
|
|
73413
|
+
};
|
|
73414
|
+
gridNode.grid[sourceKey] = {
|
|
73415
|
+
...(gridNode.grid[sourceKey] || {}),
|
|
73416
|
+
component: targetComponentId,
|
|
73417
|
+
};
|
|
73418
|
+
|
|
73419
|
+
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
73420
|
+
win,
|
|
73421
|
+
appId,
|
|
73422
|
+
workspace,
|
|
73423
|
+
);
|
|
73424
|
+
if (saveResult.error) {
|
|
73425
|
+
return {
|
|
73426
|
+
content: [
|
|
73427
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
73428
|
+
],
|
|
73429
|
+
isError: true,
|
|
73430
|
+
};
|
|
73431
|
+
}
|
|
73432
|
+
|
|
73433
|
+
const response = {
|
|
73434
|
+
widgetId,
|
|
73435
|
+
cell: { row: r, col: c },
|
|
73436
|
+
swapped: targetComponentId !== null,
|
|
73437
|
+
};
|
|
73438
|
+
if (targetComponentId !== null) {
|
|
73439
|
+
response.swappedWidgetId = String(targetComponentId);
|
|
73440
|
+
}
|
|
73441
|
+
|
|
73442
|
+
return {
|
|
73443
|
+
content: [
|
|
73444
|
+
{
|
|
73445
|
+
type: "text",
|
|
73446
|
+
text: JSON.stringify(response, null, 2),
|
|
73447
|
+
},
|
|
73448
|
+
],
|
|
73449
|
+
};
|
|
73450
|
+
}
|
|
73451
|
+
|
|
72466
73452
|
var toolHandlers = {
|
|
72467
73453
|
handleListDashboards: handleListDashboards$1,
|
|
72468
73454
|
handleGetDashboard: handleGetDashboard$1,
|
|
@@ -72483,6 +73469,14 @@ var toolHandlers = {
|
|
|
72483
73469
|
handleAddProvider: handleAddProvider$1,
|
|
72484
73470
|
handleRemoveProvider: handleRemoveProvider$1,
|
|
72485
73471
|
handleGetSetupGuide: handleGetSetupGuide$1,
|
|
73472
|
+
handleSetLayout: handleSetLayout$1,
|
|
73473
|
+
handleUpdateLayout: handleUpdateLayout$1,
|
|
73474
|
+
handleMoveWidget: handleMoveWidget$1,
|
|
73475
|
+
// Helpers (exported for testing)
|
|
73476
|
+
findGridNode,
|
|
73477
|
+
buildEmptyGrid,
|
|
73478
|
+
findNextEmptyCell,
|
|
73479
|
+
isValidCell,
|
|
72486
73480
|
};
|
|
72487
73481
|
|
|
72488
73482
|
/**
|
|
@@ -72492,7 +73486,7 @@ var toolHandlers = {
|
|
|
72492
73486
|
* Call registerDashboardTools() during app startup (before or after server start).
|
|
72493
73487
|
*/
|
|
72494
73488
|
|
|
72495
|
-
const { registerTool: registerTool$
|
|
73489
|
+
const { registerTool: registerTool$5 } = mcpDashServerController_1;
|
|
72496
73490
|
const { dashboardTools } = toolDefinitions;
|
|
72497
73491
|
const {
|
|
72498
73492
|
handleListDashboards,
|
|
@@ -72503,7 +73497,7 @@ const {
|
|
|
72503
73497
|
} = toolHandlers;
|
|
72504
73498
|
|
|
72505
73499
|
// Map tool names to handler functions
|
|
72506
|
-
const handlerMap$
|
|
73500
|
+
const handlerMap$7 = {
|
|
72507
73501
|
list_dashboards: handleListDashboards,
|
|
72508
73502
|
get_dashboard: handleGetDashboard,
|
|
72509
73503
|
create_dashboard: handleCreateDashboard,
|
|
@@ -72516,12 +73510,12 @@ const handlerMap$6 = {
|
|
|
72516
73510
|
*/
|
|
72517
73511
|
function registerDashboardTools$1() {
|
|
72518
73512
|
for (const tool of dashboardTools) {
|
|
72519
|
-
const handler = handlerMap$
|
|
73513
|
+
const handler = handlerMap$7[tool.name];
|
|
72520
73514
|
if (!handler) {
|
|
72521
73515
|
console.warn(`[dashboardTools] No handler found for tool: ${tool.name}`);
|
|
72522
73516
|
continue;
|
|
72523
73517
|
}
|
|
72524
|
-
registerTool$
|
|
73518
|
+
registerTool$5({
|
|
72525
73519
|
name: tool.name,
|
|
72526
73520
|
description: tool.description,
|
|
72527
73521
|
inputSchema: tool.inputSchema,
|
|
@@ -72542,7 +73536,7 @@ var dashboardTools_1 = { registerDashboardTools: registerDashboardTools$1 };
|
|
|
72542
73536
|
* Call registerWidgetTools() during app startup (before or after server start).
|
|
72543
73537
|
*/
|
|
72544
73538
|
|
|
72545
|
-
const { registerTool: registerTool$
|
|
73539
|
+
const { registerTool: registerTool$4 } = mcpDashServerController_1;
|
|
72546
73540
|
const { widgetTools } = toolDefinitions;
|
|
72547
73541
|
const {
|
|
72548
73542
|
handleAddWidget,
|
|
@@ -72553,7 +73547,7 @@ const {
|
|
|
72553
73547
|
} = toolHandlers;
|
|
72554
73548
|
|
|
72555
73549
|
// Map tool names to handler functions
|
|
72556
|
-
const handlerMap$
|
|
73550
|
+
const handlerMap$6 = {
|
|
72557
73551
|
add_widget: handleAddWidget,
|
|
72558
73552
|
remove_widget: handleRemoveWidget,
|
|
72559
73553
|
configure_widget: handleConfigureWidget,
|
|
@@ -72566,12 +73560,12 @@ const handlerMap$5 = {
|
|
|
72566
73560
|
*/
|
|
72567
73561
|
function registerWidgetTools$1() {
|
|
72568
73562
|
for (const tool of widgetTools) {
|
|
72569
|
-
const handler = handlerMap$
|
|
73563
|
+
const handler = handlerMap$6[tool.name];
|
|
72570
73564
|
if (!handler) {
|
|
72571
73565
|
console.warn(`[widgetTools] No handler found for tool: ${tool.name}`);
|
|
72572
73566
|
continue;
|
|
72573
73567
|
}
|
|
72574
|
-
registerTool$
|
|
73568
|
+
registerTool$4({
|
|
72575
73569
|
name: tool.name,
|
|
72576
73570
|
description: tool.description,
|
|
72577
73571
|
inputSchema: tool.inputSchema,
|
|
@@ -72590,7 +73584,7 @@ var widgetTools_1 = { registerWidgetTools: registerWidgetTools$1 };
|
|
|
72590
73584
|
* Call registerThemeTools() during app startup (before or after server start).
|
|
72591
73585
|
*/
|
|
72592
73586
|
|
|
72593
|
-
const { registerTool: registerTool$
|
|
73587
|
+
const { registerTool: registerTool$3 } = mcpDashServerController_1;
|
|
72594
73588
|
const { themeTools } = toolDefinitions;
|
|
72595
73589
|
const {
|
|
72596
73590
|
handleListThemes,
|
|
@@ -72601,7 +73595,7 @@ const {
|
|
|
72601
73595
|
} = toolHandlers;
|
|
72602
73596
|
|
|
72603
73597
|
// Map tool names to handler functions
|
|
72604
|
-
const handlerMap$
|
|
73598
|
+
const handlerMap$5 = {
|
|
72605
73599
|
list_themes: handleListThemes,
|
|
72606
73600
|
get_theme: handleGetTheme,
|
|
72607
73601
|
create_theme: handleCreateTheme,
|
|
@@ -72614,12 +73608,12 @@ const handlerMap$4 = {
|
|
|
72614
73608
|
*/
|
|
72615
73609
|
function registerThemeTools$1() {
|
|
72616
73610
|
for (const tool of themeTools) {
|
|
72617
|
-
const handler = handlerMap$
|
|
73611
|
+
const handler = handlerMap$5[tool.name];
|
|
72618
73612
|
if (!handler) {
|
|
72619
73613
|
console.warn(`[themeTools] No handler found for tool: ${tool.name}`);
|
|
72620
73614
|
continue;
|
|
72621
73615
|
}
|
|
72622
|
-
registerTool$
|
|
73616
|
+
registerTool$3({
|
|
72623
73617
|
name: tool.name,
|
|
72624
73618
|
description: tool.description,
|
|
72625
73619
|
inputSchema: tool.inputSchema,
|
|
@@ -72638,7 +73632,7 @@ var themeTools_1 = { registerThemeTools: registerThemeTools$1 };
|
|
|
72638
73632
|
* Call registerProviderTools() during app startup (before or after server start).
|
|
72639
73633
|
*/
|
|
72640
73634
|
|
|
72641
|
-
const { registerTool: registerTool$
|
|
73635
|
+
const { registerTool: registerTool$2 } = mcpDashServerController_1;
|
|
72642
73636
|
const { providerTools } = toolDefinitions;
|
|
72643
73637
|
const {
|
|
72644
73638
|
handleListProviders,
|
|
@@ -72647,7 +73641,7 @@ const {
|
|
|
72647
73641
|
} = toolHandlers;
|
|
72648
73642
|
|
|
72649
73643
|
// Map tool names to handler functions
|
|
72650
|
-
const handlerMap$
|
|
73644
|
+
const handlerMap$4 = {
|
|
72651
73645
|
list_providers: handleListProviders,
|
|
72652
73646
|
add_provider: handleAddProvider,
|
|
72653
73647
|
remove_provider: handleRemoveProvider,
|
|
@@ -72658,12 +73652,12 @@ const handlerMap$3 = {
|
|
|
72658
73652
|
*/
|
|
72659
73653
|
function registerProviderTools$1() {
|
|
72660
73654
|
for (const tool of providerTools) {
|
|
72661
|
-
const handler = handlerMap$
|
|
73655
|
+
const handler = handlerMap$4[tool.name];
|
|
72662
73656
|
if (!handler) {
|
|
72663
73657
|
console.warn(`[providerTools] No handler found for tool: ${tool.name}`);
|
|
72664
73658
|
continue;
|
|
72665
73659
|
}
|
|
72666
|
-
registerTool$
|
|
73660
|
+
registerTool$2({
|
|
72667
73661
|
name: tool.name,
|
|
72668
73662
|
description: tool.description,
|
|
72669
73663
|
inputSchema: tool.inputSchema,
|
|
@@ -72684,22 +73678,22 @@ var providerTools_1 = { registerProviderTools: registerProviderTools$1 };
|
|
|
72684
73678
|
* Call registerGuideTools() during app startup.
|
|
72685
73679
|
*/
|
|
72686
73680
|
|
|
72687
|
-
const { registerTool } = mcpDashServerController_1;
|
|
73681
|
+
const { registerTool: registerTool$1 } = mcpDashServerController_1;
|
|
72688
73682
|
const { guideTools } = toolDefinitions;
|
|
72689
73683
|
const { handleGetSetupGuide } = toolHandlers;
|
|
72690
73684
|
|
|
72691
|
-
const handlerMap$
|
|
73685
|
+
const handlerMap$3 = {
|
|
72692
73686
|
get_setup_guide: handleGetSetupGuide,
|
|
72693
73687
|
};
|
|
72694
73688
|
|
|
72695
73689
|
function registerGuideTools$1() {
|
|
72696
73690
|
for (const tool of guideTools) {
|
|
72697
|
-
const handler = handlerMap$
|
|
73691
|
+
const handler = handlerMap$3[tool.name];
|
|
72698
73692
|
if (!handler) {
|
|
72699
73693
|
console.warn(`[guideTools] No handler found for tool: ${tool.name}`);
|
|
72700
73694
|
continue;
|
|
72701
73695
|
}
|
|
72702
|
-
registerTool({
|
|
73696
|
+
registerTool$1({
|
|
72703
73697
|
name: tool.name,
|
|
72704
73698
|
description: tool.description,
|
|
72705
73699
|
inputSchema: tool.inputSchema,
|
|
@@ -72711,6 +73705,49 @@ function registerGuideTools$1() {
|
|
|
72711
73705
|
|
|
72712
73706
|
var guideTools_1 = { registerGuideTools: registerGuideTools$1 };
|
|
72713
73707
|
|
|
73708
|
+
/**
|
|
73709
|
+
* layoutTools.js
|
|
73710
|
+
*
|
|
73711
|
+
* Registers layout/grid MCP tools with the MCP Dash server.
|
|
73712
|
+
* Call registerLayoutTools() during app startup (before or after server start).
|
|
73713
|
+
*/
|
|
73714
|
+
|
|
73715
|
+
const { registerTool } = mcpDashServerController_1;
|
|
73716
|
+
const { layoutTools } = toolDefinitions;
|
|
73717
|
+
const {
|
|
73718
|
+
handleSetLayout,
|
|
73719
|
+
handleUpdateLayout,
|
|
73720
|
+
handleMoveWidget,
|
|
73721
|
+
} = toolHandlers;
|
|
73722
|
+
|
|
73723
|
+
const handlerMap$2 = {
|
|
73724
|
+
set_layout: handleSetLayout,
|
|
73725
|
+
update_layout: handleUpdateLayout,
|
|
73726
|
+
move_widget: handleMoveWidget,
|
|
73727
|
+
};
|
|
73728
|
+
|
|
73729
|
+
/**
|
|
73730
|
+
* Register all layout tools with the MCP server controller.
|
|
73731
|
+
*/
|
|
73732
|
+
function registerLayoutTools$1() {
|
|
73733
|
+
for (const tool of layoutTools) {
|
|
73734
|
+
const handler = handlerMap$2[tool.name];
|
|
73735
|
+
if (!handler) {
|
|
73736
|
+
console.warn(`[layoutTools] No handler found for tool: ${tool.name}`);
|
|
73737
|
+
continue;
|
|
73738
|
+
}
|
|
73739
|
+
registerTool({
|
|
73740
|
+
name: tool.name,
|
|
73741
|
+
description: tool.description,
|
|
73742
|
+
inputSchema: tool.inputSchema,
|
|
73743
|
+
handler,
|
|
73744
|
+
});
|
|
73745
|
+
}
|
|
73746
|
+
console.log(`[layoutTools] Registered ${layoutTools.length} layout tools`);
|
|
73747
|
+
}
|
|
73748
|
+
|
|
73749
|
+
var layoutTools_1 = { registerLayoutTools: registerLayoutTools$1 };
|
|
73750
|
+
|
|
72714
73751
|
/**
|
|
72715
73752
|
* resourceDefinitions.js
|
|
72716
73753
|
*
|
|
@@ -73679,6 +74716,7 @@ const { registerWidgetTools } = widgetTools_1;
|
|
|
73679
74716
|
const { registerThemeTools } = themeTools_1;
|
|
73680
74717
|
const { registerProviderTools } = providerTools_1;
|
|
73681
74718
|
const { registerGuideTools } = guideTools_1;
|
|
74719
|
+
const { registerLayoutTools } = layoutTools_1;
|
|
73682
74720
|
const { registerResources } = resources;
|
|
73683
74721
|
const { registerPrompts } = promptRegistration;
|
|
73684
74722
|
registerDashboardTools();
|
|
@@ -73686,6 +74724,7 @@ registerWidgetTools();
|
|
|
73686
74724
|
registerThemeTools();
|
|
73687
74725
|
registerProviderTools();
|
|
73688
74726
|
registerGuideTools();
|
|
74727
|
+
registerLayoutTools();
|
|
73689
74728
|
registerResources();
|
|
73690
74729
|
registerPrompts();
|
|
73691
74730
|
|
|
@@ -73787,6 +74826,7 @@ var electron = {
|
|
|
73787
74826
|
registerWidgetTools,
|
|
73788
74827
|
registerThemeTools,
|
|
73789
74828
|
registerProviderTools,
|
|
74829
|
+
registerLayoutTools,
|
|
73790
74830
|
registerResources,
|
|
73791
74831
|
};
|
|
73792
74832
|
|