@trops/dash-core 0.1.288 → 0.1.290
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 +1005 -74
- package/dist/electron/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -67574,7 +67574,7 @@ const registeredPrompts = [];
|
|
|
67574
67574
|
* Register a tool to be exposed via the MCP server.
|
|
67575
67575
|
* Call this before starting the server (or restart after registering).
|
|
67576
67576
|
*/
|
|
67577
|
-
function registerTool$
|
|
67577
|
+
function registerTool$6(toolDef) {
|
|
67578
67578
|
registeredTools.push(toolDef);
|
|
67579
67579
|
}
|
|
67580
67580
|
|
|
@@ -67598,7 +67598,14 @@ function registerPrompt$1(promptDef) {
|
|
|
67598
67598
|
*/
|
|
67599
67599
|
function applyRegistrations(server) {
|
|
67600
67600
|
for (const tool of registeredTools) {
|
|
67601
|
-
server.
|
|
67601
|
+
server.registerTool(
|
|
67602
|
+
tool.name,
|
|
67603
|
+
{
|
|
67604
|
+
description: tool.description,
|
|
67605
|
+
inputSchema: tool.inputSchema,
|
|
67606
|
+
},
|
|
67607
|
+
tool.handler,
|
|
67608
|
+
);
|
|
67602
67609
|
}
|
|
67603
67610
|
for (const resource of registeredResources) {
|
|
67604
67611
|
server.resource(
|
|
@@ -67937,7 +67944,7 @@ const mcpDashServerController$4 = {
|
|
|
67937
67944
|
},
|
|
67938
67945
|
|
|
67939
67946
|
// Expose registration functions for other controllers
|
|
67940
|
-
registerTool: registerTool$
|
|
67947
|
+
registerTool: registerTool$6,
|
|
67941
67948
|
registerResource: registerResource$1,
|
|
67942
67949
|
registerPrompt: registerPrompt$1,
|
|
67943
67950
|
getServerContext,
|
|
@@ -70553,7 +70560,7 @@ const dashboardTools$1 = [
|
|
|
70553
70560
|
{
|
|
70554
70561
|
name: "create_dashboard",
|
|
70555
70562
|
description:
|
|
70556
|
-
"Create a new
|
|
70563
|
+
"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.",
|
|
70557
70564
|
inputSchema: {
|
|
70558
70565
|
type: "object",
|
|
70559
70566
|
properties: {
|
|
@@ -70561,6 +70568,32 @@ const dashboardTools$1 = [
|
|
|
70561
70568
|
type: "string",
|
|
70562
70569
|
description: "Display name for the new dashboard",
|
|
70563
70570
|
},
|
|
70571
|
+
layout: {
|
|
70572
|
+
type: "object",
|
|
70573
|
+
description:
|
|
70574
|
+
"Optional grid layout configuration. When provided, creates a grid dashboard instead of a simple container.",
|
|
70575
|
+
properties: {
|
|
70576
|
+
rows: {
|
|
70577
|
+
type: "number",
|
|
70578
|
+
description: "Number of rows (1-10)",
|
|
70579
|
+
},
|
|
70580
|
+
cols: {
|
|
70581
|
+
type: "number",
|
|
70582
|
+
description: "Number of columns (1-10)",
|
|
70583
|
+
},
|
|
70584
|
+
gap: {
|
|
70585
|
+
type: "string",
|
|
70586
|
+
description:
|
|
70587
|
+
"Tailwind gap class (e.g. 'gap-2', 'gap-4'). Defaults to 'gap-2'.",
|
|
70588
|
+
},
|
|
70589
|
+
colModes: {
|
|
70590
|
+
type: "object",
|
|
70591
|
+
description:
|
|
70592
|
+
"Per-row column sizing. Keys are row numbers (as strings), values are mode strings: 'equal', '1/4', '1/3', '1/2', '2/3'.",
|
|
70593
|
+
},
|
|
70594
|
+
},
|
|
70595
|
+
required: ["rows", "cols"],
|
|
70596
|
+
},
|
|
70564
70597
|
},
|
|
70565
70598
|
required: ["name"],
|
|
70566
70599
|
},
|
|
@@ -70596,7 +70629,7 @@ const widgetTools$1 = [
|
|
|
70596
70629
|
{
|
|
70597
70630
|
name: "add_widget",
|
|
70598
70631
|
description:
|
|
70599
|
-
"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.",
|
|
70632
|
+
"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.",
|
|
70600
70633
|
inputSchema: {
|
|
70601
70634
|
type: "object",
|
|
70602
70635
|
properties: {
|
|
@@ -70610,6 +70643,16 @@ const widgetTools$1 = [
|
|
|
70610
70643
|
description:
|
|
70611
70644
|
"Component name of the widget to add (e.g. 'Clock', 'WeatherWidget')",
|
|
70612
70645
|
},
|
|
70646
|
+
row: {
|
|
70647
|
+
type: "number",
|
|
70648
|
+
description:
|
|
70649
|
+
"Grid row to place the widget in (1-indexed). Must be used together with col. Requires a grid layout on the dashboard.",
|
|
70650
|
+
},
|
|
70651
|
+
col: {
|
|
70652
|
+
type: "number",
|
|
70653
|
+
description:
|
|
70654
|
+
"Grid column to place the widget in (1-indexed). Must be used together with row.",
|
|
70655
|
+
},
|
|
70613
70656
|
},
|
|
70614
70657
|
required: ["widgetName"],
|
|
70615
70658
|
},
|
|
@@ -70860,12 +70903,108 @@ const providerTools$1 = [
|
|
|
70860
70903
|
},
|
|
70861
70904
|
];
|
|
70862
70905
|
|
|
70906
|
+
const layoutTools$1 = [
|
|
70907
|
+
{
|
|
70908
|
+
name: "set_layout",
|
|
70909
|
+
description:
|
|
70910
|
+
"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.",
|
|
70911
|
+
inputSchema: {
|
|
70912
|
+
type: "object",
|
|
70913
|
+
properties: {
|
|
70914
|
+
dashboardId: {
|
|
70915
|
+
type: "string",
|
|
70916
|
+
description: "Dashboard ID. Omit to use the active dashboard.",
|
|
70917
|
+
},
|
|
70918
|
+
rows: {
|
|
70919
|
+
type: "number",
|
|
70920
|
+
description: "Number of rows (1-10)",
|
|
70921
|
+
},
|
|
70922
|
+
cols: {
|
|
70923
|
+
type: "number",
|
|
70924
|
+
description: "Number of columns (1-10)",
|
|
70925
|
+
},
|
|
70926
|
+
gap: {
|
|
70927
|
+
type: "string",
|
|
70928
|
+
description:
|
|
70929
|
+
"Tailwind gap class (e.g. 'gap-2', 'gap-4'). Defaults to 'gap-2'.",
|
|
70930
|
+
},
|
|
70931
|
+
colModes: {
|
|
70932
|
+
type: "object",
|
|
70933
|
+
description:
|
|
70934
|
+
"Per-row column sizing. Keys are row numbers (as strings), values are mode strings: 'equal', '1/4', '1/3', '1/2', '2/3'.",
|
|
70935
|
+
},
|
|
70936
|
+
},
|
|
70937
|
+
required: ["rows", "cols"],
|
|
70938
|
+
},
|
|
70939
|
+
},
|
|
70940
|
+
{
|
|
70941
|
+
name: "update_layout",
|
|
70942
|
+
description:
|
|
70943
|
+
"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.",
|
|
70944
|
+
inputSchema: {
|
|
70945
|
+
type: "object",
|
|
70946
|
+
properties: {
|
|
70947
|
+
dashboardId: {
|
|
70948
|
+
type: "string",
|
|
70949
|
+
description: "Dashboard ID. Omit to use the active dashboard.",
|
|
70950
|
+
},
|
|
70951
|
+
rows: {
|
|
70952
|
+
type: "number",
|
|
70953
|
+
description: "New number of rows (1-10). Omit to keep current.",
|
|
70954
|
+
},
|
|
70955
|
+
cols: {
|
|
70956
|
+
type: "number",
|
|
70957
|
+
description: "New number of columns (1-10). Omit to keep current.",
|
|
70958
|
+
},
|
|
70959
|
+
gap: {
|
|
70960
|
+
type: "string",
|
|
70961
|
+
description: "Tailwind gap class. Omit to keep current.",
|
|
70962
|
+
},
|
|
70963
|
+
colModes: {
|
|
70964
|
+
type: "object",
|
|
70965
|
+
description:
|
|
70966
|
+
"Column sizing modes to merge. Set a key to null to reset that row to default.",
|
|
70967
|
+
},
|
|
70968
|
+
},
|
|
70969
|
+
required: [],
|
|
70970
|
+
},
|
|
70971
|
+
},
|
|
70972
|
+
{
|
|
70973
|
+
name: "move_widget",
|
|
70974
|
+
description:
|
|
70975
|
+
"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.",
|
|
70976
|
+
inputSchema: {
|
|
70977
|
+
type: "object",
|
|
70978
|
+
properties: {
|
|
70979
|
+
dashboardId: {
|
|
70980
|
+
type: "string",
|
|
70981
|
+
description: "Dashboard ID. Omit to use the active dashboard.",
|
|
70982
|
+
},
|
|
70983
|
+
widgetId: {
|
|
70984
|
+
type: "string",
|
|
70985
|
+
description: "ID of the widget to move",
|
|
70986
|
+
},
|
|
70987
|
+
row: {
|
|
70988
|
+
type: "number",
|
|
70989
|
+
description: "Target row (1-indexed)",
|
|
70990
|
+
},
|
|
70991
|
+
col: {
|
|
70992
|
+
type: "number",
|
|
70993
|
+
description: "Target column (1-indexed)",
|
|
70994
|
+
},
|
|
70995
|
+
},
|
|
70996
|
+
required: ["widgetId", "row", "col"],
|
|
70997
|
+
},
|
|
70998
|
+
},
|
|
70999
|
+
];
|
|
71000
|
+
|
|
70863
71001
|
var toolDefinitions = {
|
|
70864
71002
|
dashboardTools: dashboardTools$1,
|
|
70865
71003
|
widgetTools: widgetTools$1,
|
|
70866
71004
|
themeTools: themeTools$1,
|
|
70867
71005
|
providerTools: providerTools$1,
|
|
70868
71006
|
guideTools: guideTools$1,
|
|
71007
|
+
layoutTools: layoutTools$1,
|
|
70869
71008
|
};
|
|
70870
71009
|
|
|
70871
71010
|
/**
|
|
@@ -71021,7 +71160,7 @@ async function handleGetDashboard$1({ dashboardId }) {
|
|
|
71021
71160
|
/**
|
|
71022
71161
|
* create_dashboard — Creates a new workspace with the given name.
|
|
71023
71162
|
*/
|
|
71024
|
-
async function handleCreateDashboard$1({ name }) {
|
|
71163
|
+
async function handleCreateDashboard$1({ name, layout }) {
|
|
71025
71164
|
if (!name || typeof name !== "string" || !name.trim()) {
|
|
71026
71165
|
return {
|
|
71027
71166
|
content: [
|
|
@@ -71036,8 +71175,86 @@ async function handleCreateDashboard$1({ name }) {
|
|
|
71036
71175
|
};
|
|
71037
71176
|
}
|
|
71038
71177
|
|
|
71178
|
+
// Validate optional layout parameter
|
|
71179
|
+
if (layout !== undefined && layout !== null) {
|
|
71180
|
+
if (typeof layout !== "object" || Array.isArray(layout)) {
|
|
71181
|
+
return {
|
|
71182
|
+
content: [
|
|
71183
|
+
{
|
|
71184
|
+
type: "text",
|
|
71185
|
+
text: JSON.stringify({
|
|
71186
|
+
error: "layout must be an object with rows and cols",
|
|
71187
|
+
}),
|
|
71188
|
+
},
|
|
71189
|
+
],
|
|
71190
|
+
isError: true,
|
|
71191
|
+
};
|
|
71192
|
+
}
|
|
71193
|
+
const { rows, cols } = layout;
|
|
71194
|
+
if (
|
|
71195
|
+
rows === undefined ||
|
|
71196
|
+
cols === undefined ||
|
|
71197
|
+
typeof rows !== "number" ||
|
|
71198
|
+
typeof cols !== "number"
|
|
71199
|
+
) {
|
|
71200
|
+
return {
|
|
71201
|
+
content: [
|
|
71202
|
+
{
|
|
71203
|
+
type: "text",
|
|
71204
|
+
text: JSON.stringify({
|
|
71205
|
+
error: "layout.rows and layout.cols are required numbers",
|
|
71206
|
+
}),
|
|
71207
|
+
},
|
|
71208
|
+
],
|
|
71209
|
+
isError: true,
|
|
71210
|
+
};
|
|
71211
|
+
}
|
|
71212
|
+
if (rows < 1 || rows > 10 || cols < 1 || cols > 10) {
|
|
71213
|
+
return {
|
|
71214
|
+
content: [
|
|
71215
|
+
{
|
|
71216
|
+
type: "text",
|
|
71217
|
+
text: JSON.stringify({
|
|
71218
|
+
error: "rows and cols must be between 1 and 10",
|
|
71219
|
+
}),
|
|
71220
|
+
},
|
|
71221
|
+
],
|
|
71222
|
+
isError: true,
|
|
71223
|
+
};
|
|
71224
|
+
}
|
|
71225
|
+
}
|
|
71226
|
+
|
|
71039
71227
|
const { win, appId } = requireContext$1();
|
|
71040
71228
|
|
|
71229
|
+
// Build root layout node — grid or plain container
|
|
71230
|
+
const rootNode =
|
|
71231
|
+
layout && layout.rows && layout.cols
|
|
71232
|
+
? {
|
|
71233
|
+
id: 1,
|
|
71234
|
+
order: 1,
|
|
71235
|
+
component: "LayoutGridContainer",
|
|
71236
|
+
type: "grid",
|
|
71237
|
+
parent: 0,
|
|
71238
|
+
hasChildren: 1,
|
|
71239
|
+
scrollable: false,
|
|
71240
|
+
width: "w-full",
|
|
71241
|
+
height: "h-full",
|
|
71242
|
+
workspace: "layout",
|
|
71243
|
+
grid: buildEmptyGrid(
|
|
71244
|
+
layout.rows,
|
|
71245
|
+
layout.cols,
|
|
71246
|
+
layout.gap,
|
|
71247
|
+
layout.colModes,
|
|
71248
|
+
),
|
|
71249
|
+
}
|
|
71250
|
+
: {
|
|
71251
|
+
id: 1,
|
|
71252
|
+
order: 1,
|
|
71253
|
+
component: "Container",
|
|
71254
|
+
parent: 0,
|
|
71255
|
+
items: [],
|
|
71256
|
+
};
|
|
71257
|
+
|
|
71041
71258
|
const newWorkspace = {
|
|
71042
71259
|
id: Date.now(),
|
|
71043
71260
|
name: name.trim(),
|
|
@@ -71045,15 +71262,7 @@ async function handleCreateDashboard$1({ name }) {
|
|
|
71045
71262
|
type: "workspace",
|
|
71046
71263
|
version: 1,
|
|
71047
71264
|
menuId: 1,
|
|
71048
|
-
layout: [
|
|
71049
|
-
{
|
|
71050
|
-
id: 1,
|
|
71051
|
-
order: 1,
|
|
71052
|
-
component: "Container",
|
|
71053
|
-
parentId: 0,
|
|
71054
|
-
items: [],
|
|
71055
|
-
},
|
|
71056
|
-
],
|
|
71265
|
+
layout: [rootNode],
|
|
71057
71266
|
};
|
|
71058
71267
|
|
|
71059
71268
|
const result = workspaceController$2.saveWorkspaceForApplication(
|
|
@@ -71074,15 +71283,16 @@ async function handleCreateDashboard$1({ name }) {
|
|
|
71074
71283
|
};
|
|
71075
71284
|
}
|
|
71076
71285
|
|
|
71286
|
+
const response = { id: String(newWorkspace.id), name: newWorkspace.name };
|
|
71287
|
+
if (layout && layout.rows && layout.cols) {
|
|
71288
|
+
response.layout = { rows: layout.rows, cols: layout.cols };
|
|
71289
|
+
}
|
|
71290
|
+
|
|
71077
71291
|
return {
|
|
71078
71292
|
content: [
|
|
71079
71293
|
{
|
|
71080
71294
|
type: "text",
|
|
71081
|
-
text: JSON.stringify(
|
|
71082
|
-
{ id: String(newWorkspace.id), name: newWorkspace.name },
|
|
71083
|
-
null,
|
|
71084
|
-
2,
|
|
71085
|
-
),
|
|
71295
|
+
text: JSON.stringify(response, null, 2),
|
|
71086
71296
|
},
|
|
71087
71297
|
],
|
|
71088
71298
|
};
|
|
@@ -71273,10 +71483,65 @@ function nextLayoutId(layout) {
|
|
|
71273
71483
|
return maxId + 1;
|
|
71274
71484
|
}
|
|
71275
71485
|
|
|
71486
|
+
/**
|
|
71487
|
+
* Helper: find the LayoutGridContainer node in a layout array.
|
|
71488
|
+
*/
|
|
71489
|
+
function findGridNode(layout) {
|
|
71490
|
+
if (!Array.isArray(layout)) return null;
|
|
71491
|
+
return (
|
|
71492
|
+
layout.find(
|
|
71493
|
+
(item) => item.component === "LayoutGridContainer" && item.grid,
|
|
71494
|
+
) || null
|
|
71495
|
+
);
|
|
71496
|
+
}
|
|
71497
|
+
|
|
71498
|
+
/**
|
|
71499
|
+
* Helper: build an empty grid object with cell slots for all row.col positions.
|
|
71500
|
+
*/
|
|
71501
|
+
function buildEmptyGrid(rows, cols, gap, colModes) {
|
|
71502
|
+
const grid = {
|
|
71503
|
+
rows,
|
|
71504
|
+
cols,
|
|
71505
|
+
gap: gap || "gap-2",
|
|
71506
|
+
};
|
|
71507
|
+
if (colModes && Object.keys(colModes).length > 0) {
|
|
71508
|
+
grid.colModes = colModes;
|
|
71509
|
+
}
|
|
71510
|
+
for (let r = 1; r <= rows; r++) {
|
|
71511
|
+
for (let c = 1; c <= cols; c++) {
|
|
71512
|
+
grid[`${r}.${c}`] = { component: null, hide: false };
|
|
71513
|
+
}
|
|
71514
|
+
}
|
|
71515
|
+
return grid;
|
|
71516
|
+
}
|
|
71517
|
+
|
|
71518
|
+
/**
|
|
71519
|
+
* Helper: find the next empty cell scanning left-to-right, top-to-bottom.
|
|
71520
|
+
*/
|
|
71521
|
+
function findNextEmptyCell(grid) {
|
|
71522
|
+
for (let r = 1; r <= grid.rows; r++) {
|
|
71523
|
+
for (let c = 1; c <= grid.cols; c++) {
|
|
71524
|
+
const key = `${r}.${c}`;
|
|
71525
|
+
const cell = grid[key];
|
|
71526
|
+
if (!cell || (cell.component === null && !cell.hide)) {
|
|
71527
|
+
return { row: r, col: c };
|
|
71528
|
+
}
|
|
71529
|
+
}
|
|
71530
|
+
}
|
|
71531
|
+
return null;
|
|
71532
|
+
}
|
|
71533
|
+
|
|
71534
|
+
/**
|
|
71535
|
+
* Helper: check if a row/col position is within grid bounds.
|
|
71536
|
+
*/
|
|
71537
|
+
function isValidCell(grid, row, col) {
|
|
71538
|
+
return row >= 1 && row <= grid.rows && col >= 1 && col <= grid.cols;
|
|
71539
|
+
}
|
|
71540
|
+
|
|
71276
71541
|
/**
|
|
71277
71542
|
* add_widget — Add a widget to a dashboard by component name.
|
|
71278
71543
|
*/
|
|
71279
|
-
async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
71544
|
+
async function handleAddWidget$1({ dashboardId, widgetName, row, col }) {
|
|
71280
71545
|
if (!widgetName || typeof widgetName !== "string" || !widgetName.trim()) {
|
|
71281
71546
|
return {
|
|
71282
71547
|
content: [
|
|
@@ -71291,6 +71556,25 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71291
71556
|
};
|
|
71292
71557
|
}
|
|
71293
71558
|
|
|
71559
|
+
// Validate row/col pairing
|
|
71560
|
+
if (
|
|
71561
|
+
(row !== undefined && col === undefined) ||
|
|
71562
|
+
(row === undefined && col !== undefined)
|
|
71563
|
+
) {
|
|
71564
|
+
return {
|
|
71565
|
+
content: [
|
|
71566
|
+
{
|
|
71567
|
+
type: "text",
|
|
71568
|
+
text: JSON.stringify({
|
|
71569
|
+
error:
|
|
71570
|
+
"Both row and col must be provided together, or both omitted",
|
|
71571
|
+
}),
|
|
71572
|
+
},
|
|
71573
|
+
],
|
|
71574
|
+
isError: true,
|
|
71575
|
+
};
|
|
71576
|
+
}
|
|
71577
|
+
|
|
71294
71578
|
const { win, appId } = requireContext$1();
|
|
71295
71579
|
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
71296
71580
|
if (result.error) {
|
|
@@ -71315,7 +71599,88 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71315
71599
|
item.component === "LayoutContainer" ||
|
|
71316
71600
|
item.component === "LayoutGridContainer",
|
|
71317
71601
|
);
|
|
71318
|
-
|
|
71602
|
+
|
|
71603
|
+
const gridNode = findGridNode(layout);
|
|
71604
|
+
|
|
71605
|
+
// Determine grid placement
|
|
71606
|
+
let targetRow = null;
|
|
71607
|
+
let targetCol = null;
|
|
71608
|
+
|
|
71609
|
+
if (row !== undefined && col !== undefined) {
|
|
71610
|
+
// Explicit placement requested
|
|
71611
|
+
if (!gridNode) {
|
|
71612
|
+
return {
|
|
71613
|
+
content: [
|
|
71614
|
+
{
|
|
71615
|
+
type: "text",
|
|
71616
|
+
text: JSON.stringify({
|
|
71617
|
+
error:
|
|
71618
|
+
"Cannot specify row/col: dashboard has no grid layout. Use create_dashboard with layout or set_layout first.",
|
|
71619
|
+
}),
|
|
71620
|
+
},
|
|
71621
|
+
],
|
|
71622
|
+
isError: true,
|
|
71623
|
+
};
|
|
71624
|
+
}
|
|
71625
|
+
const r = Number(row);
|
|
71626
|
+
const c = Number(col);
|
|
71627
|
+
if (!isValidCell(gridNode.grid, r, c)) {
|
|
71628
|
+
return {
|
|
71629
|
+
content: [
|
|
71630
|
+
{
|
|
71631
|
+
type: "text",
|
|
71632
|
+
text: JSON.stringify({
|
|
71633
|
+
error: `Cell ${r}.${c} is out of bounds (grid is ${gridNode.grid.rows}x${gridNode.grid.cols})`,
|
|
71634
|
+
}),
|
|
71635
|
+
},
|
|
71636
|
+
],
|
|
71637
|
+
isError: true,
|
|
71638
|
+
};
|
|
71639
|
+
}
|
|
71640
|
+
const cellKey = `${r}.${c}`;
|
|
71641
|
+
const cell = gridNode.grid[cellKey];
|
|
71642
|
+
if (cell && cell.hide) {
|
|
71643
|
+
return {
|
|
71644
|
+
content: [
|
|
71645
|
+
{
|
|
71646
|
+
type: "text",
|
|
71647
|
+
text: JSON.stringify({
|
|
71648
|
+
error: `Cell ${r}.${c} is hidden`,
|
|
71649
|
+
}),
|
|
71650
|
+
},
|
|
71651
|
+
],
|
|
71652
|
+
isError: true,
|
|
71653
|
+
};
|
|
71654
|
+
}
|
|
71655
|
+
if (cell && cell.component !== null) {
|
|
71656
|
+
return {
|
|
71657
|
+
content: [
|
|
71658
|
+
{
|
|
71659
|
+
type: "text",
|
|
71660
|
+
text: JSON.stringify({
|
|
71661
|
+
error: `Cell ${r}.${c} is already occupied by widget ${cell.component}`,
|
|
71662
|
+
}),
|
|
71663
|
+
},
|
|
71664
|
+
],
|
|
71665
|
+
isError: true,
|
|
71666
|
+
};
|
|
71667
|
+
}
|
|
71668
|
+
targetRow = r;
|
|
71669
|
+
targetCol = c;
|
|
71670
|
+
} else if (gridNode) {
|
|
71671
|
+
// No row/col specified but grid exists — auto-place in next empty cell
|
|
71672
|
+
const empty = findNextEmptyCell(gridNode.grid);
|
|
71673
|
+
if (empty) {
|
|
71674
|
+
targetRow = empty.row;
|
|
71675
|
+
targetCol = empty.col;
|
|
71676
|
+
}
|
|
71677
|
+
}
|
|
71678
|
+
|
|
71679
|
+
const parentContainerId = gridNode
|
|
71680
|
+
? gridNode.id
|
|
71681
|
+
: container
|
|
71682
|
+
? container.id
|
|
71683
|
+
: 0;
|
|
71319
71684
|
|
|
71320
71685
|
const newId = nextLayoutId(layout);
|
|
71321
71686
|
const maxOrder = layout.reduce(
|
|
@@ -71327,12 +71692,22 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71327
71692
|
id: newId,
|
|
71328
71693
|
order: maxOrder + 1,
|
|
71329
71694
|
component: widgetName.trim(),
|
|
71330
|
-
|
|
71695
|
+
parent: parentContainerId,
|
|
71331
71696
|
config: {},
|
|
71332
71697
|
};
|
|
71333
71698
|
|
|
71334
71699
|
workspace.layout = [...layout, newItem];
|
|
71335
71700
|
|
|
71701
|
+
// If placing in grid, update the cell assignment
|
|
71702
|
+
if (gridNode && targetRow !== null && targetCol !== null) {
|
|
71703
|
+
const cellKey = `${targetRow}.${targetCol}`;
|
|
71704
|
+
gridNode.grid[cellKey] = {
|
|
71705
|
+
...(gridNode.grid[cellKey] || {}),
|
|
71706
|
+
component: newId,
|
|
71707
|
+
hide: false,
|
|
71708
|
+
};
|
|
71709
|
+
}
|
|
71710
|
+
|
|
71336
71711
|
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
71337
71712
|
win,
|
|
71338
71713
|
appId,
|
|
@@ -71350,19 +71725,20 @@ async function handleAddWidget$1({ dashboardId, widgetName }) {
|
|
|
71350
71725
|
};
|
|
71351
71726
|
}
|
|
71352
71727
|
|
|
71728
|
+
const response = {
|
|
71729
|
+
widgetId: String(newId),
|
|
71730
|
+
name: widgetName.trim(),
|
|
71731
|
+
dashboardId: String(workspace.id),
|
|
71732
|
+
};
|
|
71733
|
+
if (targetRow !== null && targetCol !== null) {
|
|
71734
|
+
response.cell = { row: targetRow, col: targetCol };
|
|
71735
|
+
}
|
|
71736
|
+
|
|
71353
71737
|
return {
|
|
71354
71738
|
content: [
|
|
71355
71739
|
{
|
|
71356
71740
|
type: "text",
|
|
71357
|
-
text: JSON.stringify(
|
|
71358
|
-
{
|
|
71359
|
-
widgetId: String(newId),
|
|
71360
|
-
name: widgetName.trim(),
|
|
71361
|
-
dashboardId: String(workspace.id),
|
|
71362
|
-
},
|
|
71363
|
-
null,
|
|
71364
|
-
2,
|
|
71365
|
-
),
|
|
71741
|
+
text: JSON.stringify(response, null, 2),
|
|
71366
71742
|
},
|
|
71367
71743
|
],
|
|
71368
71744
|
};
|
|
@@ -71418,6 +71794,21 @@ async function handleRemoveWidget$1({ dashboardId, widgetId }) {
|
|
|
71418
71794
|
|
|
71419
71795
|
workspace.layout = layout.filter((item) => String(item.id) !== widgetId);
|
|
71420
71796
|
|
|
71797
|
+
// Clean up grid cell assignments that reference this widget
|
|
71798
|
+
const numericId = Number(widgetId);
|
|
71799
|
+
for (const item of workspace.layout) {
|
|
71800
|
+
if (item.grid) {
|
|
71801
|
+
for (const key of Object.keys(item.grid)) {
|
|
71802
|
+
if (/^\d+\.\d+$/.test(key)) {
|
|
71803
|
+
const cell = item.grid[key];
|
|
71804
|
+
if (cell && cell.component === numericId) {
|
|
71805
|
+
cell.component = null;
|
|
71806
|
+
}
|
|
71807
|
+
}
|
|
71808
|
+
}
|
|
71809
|
+
}
|
|
71810
|
+
}
|
|
71811
|
+
|
|
71421
71812
|
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
71422
71813
|
win,
|
|
71423
71814
|
appId,
|
|
@@ -72579,36 +72970,530 @@ async function handleGetSetupGuide$1({ topic }) {
|
|
|
72579
72970
|
};
|
|
72580
72971
|
}
|
|
72581
72972
|
|
|
72582
|
-
|
|
72583
|
-
handleListDashboards: handleListDashboards$1,
|
|
72584
|
-
handleGetDashboard: handleGetDashboard$1,
|
|
72585
|
-
handleCreateDashboard: handleCreateDashboard$1,
|
|
72586
|
-
handleDeleteDashboard: handleDeleteDashboard$1,
|
|
72587
|
-
handleGetAppStats: handleGetAppStats$1,
|
|
72588
|
-
handleAddWidget: handleAddWidget$1,
|
|
72589
|
-
handleRemoveWidget: handleRemoveWidget$1,
|
|
72590
|
-
handleConfigureWidget: handleConfigureWidget$1,
|
|
72591
|
-
handleListWidgets: handleListWidgets$1,
|
|
72592
|
-
handleSearchWidgets: handleSearchWidgets$1,
|
|
72593
|
-
handleListThemes: handleListThemes$1,
|
|
72594
|
-
handleGetTheme: handleGetTheme$1,
|
|
72595
|
-
handleCreateTheme: handleCreateTheme$1,
|
|
72596
|
-
handleCreateThemeFromUrl: handleCreateThemeFromUrl$1,
|
|
72597
|
-
handleApplyTheme: handleApplyTheme$1,
|
|
72598
|
-
handleListProviders: handleListProviders$1,
|
|
72599
|
-
handleAddProvider: handleAddProvider$1,
|
|
72600
|
-
handleRemoveProvider: handleRemoveProvider$1,
|
|
72601
|
-
handleGetSetupGuide: handleGetSetupGuide$1,
|
|
72602
|
-
};
|
|
72973
|
+
// --- Layout Tool Handlers ---
|
|
72603
72974
|
|
|
72604
72975
|
/**
|
|
72605
|
-
*
|
|
72976
|
+
* set_layout — Set or replace the grid layout on a dashboard.
|
|
72977
|
+
*/
|
|
72978
|
+
async function handleSetLayout$1({ dashboardId, rows, cols, gap, colModes }) {
|
|
72979
|
+
if (
|
|
72980
|
+
rows === undefined ||
|
|
72981
|
+
cols === undefined ||
|
|
72982
|
+
typeof rows !== "number" ||
|
|
72983
|
+
typeof cols !== "number"
|
|
72984
|
+
) {
|
|
72985
|
+
return {
|
|
72986
|
+
content: [
|
|
72987
|
+
{
|
|
72988
|
+
type: "text",
|
|
72989
|
+
text: JSON.stringify({
|
|
72990
|
+
error: "rows and cols are required numbers",
|
|
72991
|
+
}),
|
|
72992
|
+
},
|
|
72993
|
+
],
|
|
72994
|
+
isError: true,
|
|
72995
|
+
};
|
|
72996
|
+
}
|
|
72997
|
+
if (rows < 1 || rows > 10 || cols < 1 || cols > 10) {
|
|
72998
|
+
return {
|
|
72999
|
+
content: [
|
|
73000
|
+
{
|
|
73001
|
+
type: "text",
|
|
73002
|
+
text: JSON.stringify({
|
|
73003
|
+
error: "rows and cols must be between 1 and 10",
|
|
73004
|
+
}),
|
|
73005
|
+
},
|
|
73006
|
+
],
|
|
73007
|
+
isError: true,
|
|
73008
|
+
};
|
|
73009
|
+
}
|
|
73010
|
+
|
|
73011
|
+
const { win, appId } = requireContext$1();
|
|
73012
|
+
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
73013
|
+
if (result.error) {
|
|
73014
|
+
return {
|
|
73015
|
+
content: [
|
|
73016
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
73017
|
+
],
|
|
73018
|
+
isError: true,
|
|
73019
|
+
};
|
|
73020
|
+
}
|
|
73021
|
+
|
|
73022
|
+
const found = findWorkspace(result.workspaces || [], dashboardId);
|
|
73023
|
+
if (found.error) return found.response;
|
|
73024
|
+
|
|
73025
|
+
const workspace = found.workspace;
|
|
73026
|
+
const layout = workspace.layout || [];
|
|
73027
|
+
|
|
73028
|
+
const newGrid = buildEmptyGrid(rows, cols, gap, colModes);
|
|
73029
|
+
const existingGridNode = findGridNode(layout);
|
|
73030
|
+
const orphanedWidgetIds = [];
|
|
73031
|
+
|
|
73032
|
+
if (existingGridNode) {
|
|
73033
|
+
// Preserve cell assignments that still fit in the new dimensions
|
|
73034
|
+
const oldGrid = existingGridNode.grid;
|
|
73035
|
+
for (const key of Object.keys(oldGrid)) {
|
|
73036
|
+
if (
|
|
73037
|
+
/^\d+\.\d+$/.test(key) &&
|
|
73038
|
+
oldGrid[key] &&
|
|
73039
|
+
oldGrid[key].component !== null
|
|
73040
|
+
) {
|
|
73041
|
+
const parts = key.split(".");
|
|
73042
|
+
const r = Number(parts[0]);
|
|
73043
|
+
const c = Number(parts[1]);
|
|
73044
|
+
if (r <= rows && c <= cols) {
|
|
73045
|
+
newGrid[key] = { ...newGrid[key], component: oldGrid[key].component };
|
|
73046
|
+
} else {
|
|
73047
|
+
orphanedWidgetIds.push(oldGrid[key].component);
|
|
73048
|
+
}
|
|
73049
|
+
}
|
|
73050
|
+
}
|
|
73051
|
+
existingGridNode.grid = newGrid;
|
|
73052
|
+
} else {
|
|
73053
|
+
// Replace root Container with a LayoutGridContainer
|
|
73054
|
+
const rootIdx = layout.findIndex(
|
|
73055
|
+
(item) =>
|
|
73056
|
+
item.parent === 0 &&
|
|
73057
|
+
(item.component === "Container" ||
|
|
73058
|
+
item.component === "LayoutContainer"),
|
|
73059
|
+
);
|
|
73060
|
+
|
|
73061
|
+
const newGridNode = {
|
|
73062
|
+
id: rootIdx >= 0 ? layout[rootIdx].id : nextLayoutId(layout),
|
|
73063
|
+
order: 1,
|
|
73064
|
+
component: "LayoutGridContainer",
|
|
73065
|
+
type: "grid",
|
|
73066
|
+
parent: 0,
|
|
73067
|
+
hasChildren: 1,
|
|
73068
|
+
scrollable: false,
|
|
73069
|
+
width: "w-full",
|
|
73070
|
+
height: "h-full",
|
|
73071
|
+
workspace: "layout",
|
|
73072
|
+
grid: newGrid,
|
|
73073
|
+
};
|
|
73074
|
+
|
|
73075
|
+
if (rootIdx >= 0) {
|
|
73076
|
+
// Reparent existing widgets to the new grid node
|
|
73077
|
+
const oldRootId = layout[rootIdx].id;
|
|
73078
|
+
for (const item of layout) {
|
|
73079
|
+
if (item.parent === oldRootId && item.id !== oldRootId) {
|
|
73080
|
+
item.parent = newGridNode.id;
|
|
73081
|
+
}
|
|
73082
|
+
}
|
|
73083
|
+
workspace.layout[rootIdx] = newGridNode;
|
|
73084
|
+
} else {
|
|
73085
|
+
workspace.layout = [newGridNode, ...layout];
|
|
73086
|
+
}
|
|
73087
|
+
}
|
|
73088
|
+
|
|
73089
|
+
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
73090
|
+
win,
|
|
73091
|
+
appId,
|
|
73092
|
+
workspace,
|
|
73093
|
+
);
|
|
73094
|
+
if (saveResult.error) {
|
|
73095
|
+
return {
|
|
73096
|
+
content: [
|
|
73097
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
73098
|
+
],
|
|
73099
|
+
isError: true,
|
|
73100
|
+
};
|
|
73101
|
+
}
|
|
73102
|
+
|
|
73103
|
+
return {
|
|
73104
|
+
content: [
|
|
73105
|
+
{
|
|
73106
|
+
type: "text",
|
|
73107
|
+
text: JSON.stringify(
|
|
73108
|
+
{
|
|
73109
|
+
dashboardId: String(workspace.id),
|
|
73110
|
+
grid: { rows, cols },
|
|
73111
|
+
orphanedWidgets: orphanedWidgetIds.map(String),
|
|
73112
|
+
},
|
|
73113
|
+
null,
|
|
73114
|
+
2,
|
|
73115
|
+
),
|
|
73116
|
+
},
|
|
73117
|
+
],
|
|
73118
|
+
};
|
|
73119
|
+
}
|
|
73120
|
+
|
|
73121
|
+
/**
|
|
73122
|
+
* update_layout — Partially update grid layout properties.
|
|
73123
|
+
*/
|
|
73124
|
+
async function handleUpdateLayout$1({ dashboardId, rows, cols, gap, colModes }) {
|
|
73125
|
+
if (
|
|
73126
|
+
rows === undefined &&
|
|
73127
|
+
cols === undefined &&
|
|
73128
|
+
gap === undefined &&
|
|
73129
|
+
colModes === undefined
|
|
73130
|
+
) {
|
|
73131
|
+
return {
|
|
73132
|
+
content: [
|
|
73133
|
+
{
|
|
73134
|
+
type: "text",
|
|
73135
|
+
text: JSON.stringify({
|
|
73136
|
+
error:
|
|
73137
|
+
"At least one of rows, cols, gap, or colModes must be provided",
|
|
73138
|
+
}),
|
|
73139
|
+
},
|
|
73140
|
+
],
|
|
73141
|
+
isError: true,
|
|
73142
|
+
};
|
|
73143
|
+
}
|
|
73144
|
+
|
|
73145
|
+
const { win, appId } = requireContext$1();
|
|
73146
|
+
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
73147
|
+
if (result.error) {
|
|
73148
|
+
return {
|
|
73149
|
+
content: [
|
|
73150
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
73151
|
+
],
|
|
73152
|
+
isError: true,
|
|
73153
|
+
};
|
|
73154
|
+
}
|
|
73155
|
+
|
|
73156
|
+
const found = findWorkspace(result.workspaces || [], dashboardId);
|
|
73157
|
+
if (found.error) return found.response;
|
|
73158
|
+
|
|
73159
|
+
const workspace = found.workspace;
|
|
73160
|
+
const gridNode = findGridNode(workspace.layout || []);
|
|
73161
|
+
|
|
73162
|
+
if (!gridNode) {
|
|
73163
|
+
return {
|
|
73164
|
+
content: [
|
|
73165
|
+
{
|
|
73166
|
+
type: "text",
|
|
73167
|
+
text: JSON.stringify({
|
|
73168
|
+
error:
|
|
73169
|
+
"Dashboard has no grid layout. Use set_layout or create_dashboard with layout first.",
|
|
73170
|
+
}),
|
|
73171
|
+
},
|
|
73172
|
+
],
|
|
73173
|
+
isError: true,
|
|
73174
|
+
};
|
|
73175
|
+
}
|
|
73176
|
+
|
|
73177
|
+
const grid = gridNode.grid;
|
|
73178
|
+
const oldRows = grid.rows;
|
|
73179
|
+
const oldCols = grid.cols;
|
|
73180
|
+
const newRows = rows !== undefined ? rows : oldRows;
|
|
73181
|
+
const newCols = cols !== undefined ? cols : oldCols;
|
|
73182
|
+
|
|
73183
|
+
if (newRows < 1 || newRows > 10 || newCols < 1 || newCols > 10) {
|
|
73184
|
+
return {
|
|
73185
|
+
content: [
|
|
73186
|
+
{
|
|
73187
|
+
type: "text",
|
|
73188
|
+
text: JSON.stringify({
|
|
73189
|
+
error: "rows and cols must be between 1 and 10",
|
|
73190
|
+
}),
|
|
73191
|
+
},
|
|
73192
|
+
],
|
|
73193
|
+
isError: true,
|
|
73194
|
+
};
|
|
73195
|
+
}
|
|
73196
|
+
|
|
73197
|
+
// Update gap if specified
|
|
73198
|
+
if (gap !== undefined) {
|
|
73199
|
+
grid.gap = gap;
|
|
73200
|
+
}
|
|
73201
|
+
|
|
73202
|
+
// Merge colModes if specified
|
|
73203
|
+
if (colModes !== undefined) {
|
|
73204
|
+
grid.colModes = { ...(grid.colModes || {}), ...colModes };
|
|
73205
|
+
// Remove entries set to null
|
|
73206
|
+
for (const k of Object.keys(grid.colModes)) {
|
|
73207
|
+
if (grid.colModes[k] === null) {
|
|
73208
|
+
delete grid.colModes[k];
|
|
73209
|
+
}
|
|
73210
|
+
}
|
|
73211
|
+
if (Object.keys(grid.colModes).length === 0) {
|
|
73212
|
+
delete grid.colModes;
|
|
73213
|
+
}
|
|
73214
|
+
}
|
|
73215
|
+
|
|
73216
|
+
// Handle dimension changes
|
|
73217
|
+
const orphanedWidgetIds = [];
|
|
73218
|
+
if (newRows !== oldRows || newCols !== oldCols) {
|
|
73219
|
+
// Add new cells
|
|
73220
|
+
for (let r = 1; r <= newRows; r++) {
|
|
73221
|
+
for (let c = 1; c <= newCols; c++) {
|
|
73222
|
+
const key = `${r}.${c}`;
|
|
73223
|
+
if (!grid[key]) {
|
|
73224
|
+
grid[key] = { component: null, hide: false };
|
|
73225
|
+
}
|
|
73226
|
+
}
|
|
73227
|
+
}
|
|
73228
|
+
// Collect orphaned widgets from removed cells
|
|
73229
|
+
for (const key of Object.keys(grid)) {
|
|
73230
|
+
if (/^\d+\.\d+$/.test(key)) {
|
|
73231
|
+
const parts = key.split(".");
|
|
73232
|
+
const r = Number(parts[0]);
|
|
73233
|
+
const c = Number(parts[1]);
|
|
73234
|
+
if (r > newRows || c > newCols) {
|
|
73235
|
+
if (grid[key] && grid[key].component !== null) {
|
|
73236
|
+
orphanedWidgetIds.push(grid[key].component);
|
|
73237
|
+
}
|
|
73238
|
+
delete grid[key];
|
|
73239
|
+
}
|
|
73240
|
+
}
|
|
73241
|
+
}
|
|
73242
|
+
grid.rows = newRows;
|
|
73243
|
+
grid.cols = newCols;
|
|
73244
|
+
}
|
|
73245
|
+
|
|
73246
|
+
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
73247
|
+
win,
|
|
73248
|
+
appId,
|
|
73249
|
+
workspace,
|
|
73250
|
+
);
|
|
73251
|
+
if (saveResult.error) {
|
|
73252
|
+
return {
|
|
73253
|
+
content: [
|
|
73254
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
73255
|
+
],
|
|
73256
|
+
isError: true,
|
|
73257
|
+
};
|
|
73258
|
+
}
|
|
73259
|
+
|
|
73260
|
+
return {
|
|
73261
|
+
content: [
|
|
73262
|
+
{
|
|
73263
|
+
type: "text",
|
|
73264
|
+
text: JSON.stringify(
|
|
73265
|
+
{
|
|
73266
|
+
dashboardId: String(workspace.id),
|
|
73267
|
+
grid: { rows: newRows, cols: newCols, gap: grid.gap },
|
|
73268
|
+
orphanedWidgets: orphanedWidgetIds.map(String),
|
|
73269
|
+
},
|
|
73270
|
+
null,
|
|
73271
|
+
2,
|
|
73272
|
+
),
|
|
73273
|
+
},
|
|
73274
|
+
],
|
|
73275
|
+
};
|
|
73276
|
+
}
|
|
73277
|
+
|
|
73278
|
+
/**
|
|
73279
|
+
* move_widget — Move a widget to a different grid cell (swap if occupied).
|
|
73280
|
+
*/
|
|
73281
|
+
async function handleMoveWidget$1({ dashboardId, widgetId, row, col }) {
|
|
73282
|
+
if (!widgetId || typeof widgetId !== "string") {
|
|
73283
|
+
return {
|
|
73284
|
+
content: [
|
|
73285
|
+
{
|
|
73286
|
+
type: "text",
|
|
73287
|
+
text: JSON.stringify({ error: "widgetId is required" }),
|
|
73288
|
+
},
|
|
73289
|
+
],
|
|
73290
|
+
isError: true,
|
|
73291
|
+
};
|
|
73292
|
+
}
|
|
73293
|
+
if (row === undefined || col === undefined) {
|
|
73294
|
+
return {
|
|
73295
|
+
content: [
|
|
73296
|
+
{
|
|
73297
|
+
type: "text",
|
|
73298
|
+
text: JSON.stringify({ error: "row and col are required" }),
|
|
73299
|
+
},
|
|
73300
|
+
],
|
|
73301
|
+
isError: true,
|
|
73302
|
+
};
|
|
73303
|
+
}
|
|
73304
|
+
|
|
73305
|
+
const { win, appId } = requireContext$1();
|
|
73306
|
+
const result = workspaceController$2.listWorkspacesForApplication(win, appId);
|
|
73307
|
+
if (result.error) {
|
|
73308
|
+
return {
|
|
73309
|
+
content: [
|
|
73310
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
73311
|
+
],
|
|
73312
|
+
isError: true,
|
|
73313
|
+
};
|
|
73314
|
+
}
|
|
73315
|
+
|
|
73316
|
+
const found = findWorkspace(result.workspaces || [], dashboardId);
|
|
73317
|
+
if (found.error) return found.response;
|
|
73318
|
+
|
|
73319
|
+
const workspace = found.workspace;
|
|
73320
|
+
const gridNode = findGridNode(workspace.layout || []);
|
|
73321
|
+
|
|
73322
|
+
if (!gridNode) {
|
|
73323
|
+
return {
|
|
73324
|
+
content: [
|
|
73325
|
+
{
|
|
73326
|
+
type: "text",
|
|
73327
|
+
text: JSON.stringify({
|
|
73328
|
+
error: "Dashboard has no grid layout",
|
|
73329
|
+
}),
|
|
73330
|
+
},
|
|
73331
|
+
],
|
|
73332
|
+
isError: true,
|
|
73333
|
+
};
|
|
73334
|
+
}
|
|
73335
|
+
|
|
73336
|
+
const r = Number(row);
|
|
73337
|
+
const c = Number(col);
|
|
73338
|
+
if (!isValidCell(gridNode.grid, r, c)) {
|
|
73339
|
+
return {
|
|
73340
|
+
content: [
|
|
73341
|
+
{
|
|
73342
|
+
type: "text",
|
|
73343
|
+
text: JSON.stringify({
|
|
73344
|
+
error: `Cell ${r}.${c} is out of bounds (grid is ${gridNode.grid.rows}x${gridNode.grid.cols})`,
|
|
73345
|
+
}),
|
|
73346
|
+
},
|
|
73347
|
+
],
|
|
73348
|
+
isError: true,
|
|
73349
|
+
};
|
|
73350
|
+
}
|
|
73351
|
+
|
|
73352
|
+
const targetKey = `${r}.${c}`;
|
|
73353
|
+
const targetCell = gridNode.grid[targetKey];
|
|
73354
|
+
if (targetCell && targetCell.hide) {
|
|
73355
|
+
return {
|
|
73356
|
+
content: [
|
|
73357
|
+
{
|
|
73358
|
+
type: "text",
|
|
73359
|
+
text: JSON.stringify({
|
|
73360
|
+
error: `Cell ${r}.${c} is hidden`,
|
|
73361
|
+
}),
|
|
73362
|
+
},
|
|
73363
|
+
],
|
|
73364
|
+
isError: true,
|
|
73365
|
+
};
|
|
73366
|
+
}
|
|
73367
|
+
|
|
73368
|
+
// Find the widget's current cell
|
|
73369
|
+
const numericWidgetId = Number(widgetId);
|
|
73370
|
+
let sourceKey = null;
|
|
73371
|
+
for (const key of Object.keys(gridNode.grid)) {
|
|
73372
|
+
if (
|
|
73373
|
+
/^\d+\.\d+$/.test(key) &&
|
|
73374
|
+
gridNode.grid[key] &&
|
|
73375
|
+
gridNode.grid[key].component === numericWidgetId
|
|
73376
|
+
) {
|
|
73377
|
+
sourceKey = key;
|
|
73378
|
+
break;
|
|
73379
|
+
}
|
|
73380
|
+
}
|
|
73381
|
+
|
|
73382
|
+
if (!sourceKey) {
|
|
73383
|
+
return {
|
|
73384
|
+
content: [
|
|
73385
|
+
{
|
|
73386
|
+
type: "text",
|
|
73387
|
+
text: JSON.stringify({
|
|
73388
|
+
error: `Widget ${widgetId} not found in any grid cell`,
|
|
73389
|
+
}),
|
|
73390
|
+
},
|
|
73391
|
+
],
|
|
73392
|
+
isError: true,
|
|
73393
|
+
};
|
|
73394
|
+
}
|
|
73395
|
+
|
|
73396
|
+
if (sourceKey === targetKey) {
|
|
73397
|
+
return {
|
|
73398
|
+
content: [
|
|
73399
|
+
{
|
|
73400
|
+
type: "text",
|
|
73401
|
+
text: JSON.stringify(
|
|
73402
|
+
{
|
|
73403
|
+
widgetId,
|
|
73404
|
+
cell: { row: r, col: c },
|
|
73405
|
+
swapped: false,
|
|
73406
|
+
},
|
|
73407
|
+
null,
|
|
73408
|
+
2,
|
|
73409
|
+
),
|
|
73410
|
+
},
|
|
73411
|
+
],
|
|
73412
|
+
};
|
|
73413
|
+
}
|
|
73414
|
+
|
|
73415
|
+
// Perform the move (swap if target occupied)
|
|
73416
|
+
const targetComponentId = targetCell ? targetCell.component : null;
|
|
73417
|
+
gridNode.grid[targetKey] = {
|
|
73418
|
+
...(gridNode.grid[targetKey] || {}),
|
|
73419
|
+
component: numericWidgetId,
|
|
73420
|
+
};
|
|
73421
|
+
gridNode.grid[sourceKey] = {
|
|
73422
|
+
...(gridNode.grid[sourceKey] || {}),
|
|
73423
|
+
component: targetComponentId,
|
|
73424
|
+
};
|
|
73425
|
+
|
|
73426
|
+
const saveResult = workspaceController$2.saveWorkspaceForApplication(
|
|
73427
|
+
win,
|
|
73428
|
+
appId,
|
|
73429
|
+
workspace,
|
|
73430
|
+
);
|
|
73431
|
+
if (saveResult.error) {
|
|
73432
|
+
return {
|
|
73433
|
+
content: [
|
|
73434
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
73435
|
+
],
|
|
73436
|
+
isError: true,
|
|
73437
|
+
};
|
|
73438
|
+
}
|
|
73439
|
+
|
|
73440
|
+
const response = {
|
|
73441
|
+
widgetId,
|
|
73442
|
+
cell: { row: r, col: c },
|
|
73443
|
+
swapped: targetComponentId !== null,
|
|
73444
|
+
};
|
|
73445
|
+
if (targetComponentId !== null) {
|
|
73446
|
+
response.swappedWidgetId = String(targetComponentId);
|
|
73447
|
+
}
|
|
73448
|
+
|
|
73449
|
+
return {
|
|
73450
|
+
content: [
|
|
73451
|
+
{
|
|
73452
|
+
type: "text",
|
|
73453
|
+
text: JSON.stringify(response, null, 2),
|
|
73454
|
+
},
|
|
73455
|
+
],
|
|
73456
|
+
};
|
|
73457
|
+
}
|
|
73458
|
+
|
|
73459
|
+
var toolHandlers = {
|
|
73460
|
+
handleListDashboards: handleListDashboards$1,
|
|
73461
|
+
handleGetDashboard: handleGetDashboard$1,
|
|
73462
|
+
handleCreateDashboard: handleCreateDashboard$1,
|
|
73463
|
+
handleDeleteDashboard: handleDeleteDashboard$1,
|
|
73464
|
+
handleGetAppStats: handleGetAppStats$1,
|
|
73465
|
+
handleAddWidget: handleAddWidget$1,
|
|
73466
|
+
handleRemoveWidget: handleRemoveWidget$1,
|
|
73467
|
+
handleConfigureWidget: handleConfigureWidget$1,
|
|
73468
|
+
handleListWidgets: handleListWidgets$1,
|
|
73469
|
+
handleSearchWidgets: handleSearchWidgets$1,
|
|
73470
|
+
handleListThemes: handleListThemes$1,
|
|
73471
|
+
handleGetTheme: handleGetTheme$1,
|
|
73472
|
+
handleCreateTheme: handleCreateTheme$1,
|
|
73473
|
+
handleCreateThemeFromUrl: handleCreateThemeFromUrl$1,
|
|
73474
|
+
handleApplyTheme: handleApplyTheme$1,
|
|
73475
|
+
handleListProviders: handleListProviders$1,
|
|
73476
|
+
handleAddProvider: handleAddProvider$1,
|
|
73477
|
+
handleRemoveProvider: handleRemoveProvider$1,
|
|
73478
|
+
handleGetSetupGuide: handleGetSetupGuide$1,
|
|
73479
|
+
handleSetLayout: handleSetLayout$1,
|
|
73480
|
+
handleUpdateLayout: handleUpdateLayout$1,
|
|
73481
|
+
handleMoveWidget: handleMoveWidget$1,
|
|
73482
|
+
// Helpers (exported for testing)
|
|
73483
|
+
findGridNode,
|
|
73484
|
+
buildEmptyGrid,
|
|
73485
|
+
findNextEmptyCell,
|
|
73486
|
+
isValidCell,
|
|
73487
|
+
};
|
|
73488
|
+
|
|
73489
|
+
/**
|
|
73490
|
+
* dashboardTools.js
|
|
72606
73491
|
*
|
|
72607
73492
|
* Registers dashboard/workspace MCP tools with the MCP Dash server.
|
|
72608
73493
|
* Call registerDashboardTools() during app startup (before or after server start).
|
|
72609
73494
|
*/
|
|
72610
73495
|
|
|
72611
|
-
const { registerTool: registerTool$
|
|
73496
|
+
const { registerTool: registerTool$5 } = mcpDashServerController_1;
|
|
72612
73497
|
const { dashboardTools } = toolDefinitions;
|
|
72613
73498
|
const {
|
|
72614
73499
|
handleListDashboards,
|
|
@@ -72619,7 +73504,7 @@ const {
|
|
|
72619
73504
|
} = toolHandlers;
|
|
72620
73505
|
|
|
72621
73506
|
// Map tool names to handler functions
|
|
72622
|
-
const handlerMap$
|
|
73507
|
+
const handlerMap$7 = {
|
|
72623
73508
|
list_dashboards: handleListDashboards,
|
|
72624
73509
|
get_dashboard: handleGetDashboard,
|
|
72625
73510
|
create_dashboard: handleCreateDashboard,
|
|
@@ -72632,12 +73517,12 @@ const handlerMap$6 = {
|
|
|
72632
73517
|
*/
|
|
72633
73518
|
function registerDashboardTools$1() {
|
|
72634
73519
|
for (const tool of dashboardTools) {
|
|
72635
|
-
const handler = handlerMap$
|
|
73520
|
+
const handler = handlerMap$7[tool.name];
|
|
72636
73521
|
if (!handler) {
|
|
72637
73522
|
console.warn(`[dashboardTools] No handler found for tool: ${tool.name}`);
|
|
72638
73523
|
continue;
|
|
72639
73524
|
}
|
|
72640
|
-
registerTool$
|
|
73525
|
+
registerTool$5({
|
|
72641
73526
|
name: tool.name,
|
|
72642
73527
|
description: tool.description,
|
|
72643
73528
|
inputSchema: tool.inputSchema,
|
|
@@ -72658,7 +73543,7 @@ var dashboardTools_1 = { registerDashboardTools: registerDashboardTools$1 };
|
|
|
72658
73543
|
* Call registerWidgetTools() during app startup (before or after server start).
|
|
72659
73544
|
*/
|
|
72660
73545
|
|
|
72661
|
-
const { registerTool: registerTool$
|
|
73546
|
+
const { registerTool: registerTool$4 } = mcpDashServerController_1;
|
|
72662
73547
|
const { widgetTools } = toolDefinitions;
|
|
72663
73548
|
const {
|
|
72664
73549
|
handleAddWidget,
|
|
@@ -72669,7 +73554,7 @@ const {
|
|
|
72669
73554
|
} = toolHandlers;
|
|
72670
73555
|
|
|
72671
73556
|
// Map tool names to handler functions
|
|
72672
|
-
const handlerMap$
|
|
73557
|
+
const handlerMap$6 = {
|
|
72673
73558
|
add_widget: handleAddWidget,
|
|
72674
73559
|
remove_widget: handleRemoveWidget,
|
|
72675
73560
|
configure_widget: handleConfigureWidget,
|
|
@@ -72682,12 +73567,12 @@ const handlerMap$5 = {
|
|
|
72682
73567
|
*/
|
|
72683
73568
|
function registerWidgetTools$1() {
|
|
72684
73569
|
for (const tool of widgetTools) {
|
|
72685
|
-
const handler = handlerMap$
|
|
73570
|
+
const handler = handlerMap$6[tool.name];
|
|
72686
73571
|
if (!handler) {
|
|
72687
73572
|
console.warn(`[widgetTools] No handler found for tool: ${tool.name}`);
|
|
72688
73573
|
continue;
|
|
72689
73574
|
}
|
|
72690
|
-
registerTool$
|
|
73575
|
+
registerTool$4({
|
|
72691
73576
|
name: tool.name,
|
|
72692
73577
|
description: tool.description,
|
|
72693
73578
|
inputSchema: tool.inputSchema,
|
|
@@ -72706,7 +73591,7 @@ var widgetTools_1 = { registerWidgetTools: registerWidgetTools$1 };
|
|
|
72706
73591
|
* Call registerThemeTools() during app startup (before or after server start).
|
|
72707
73592
|
*/
|
|
72708
73593
|
|
|
72709
|
-
const { registerTool: registerTool$
|
|
73594
|
+
const { registerTool: registerTool$3 } = mcpDashServerController_1;
|
|
72710
73595
|
const { themeTools } = toolDefinitions;
|
|
72711
73596
|
const {
|
|
72712
73597
|
handleListThemes,
|
|
@@ -72717,7 +73602,7 @@ const {
|
|
|
72717
73602
|
} = toolHandlers;
|
|
72718
73603
|
|
|
72719
73604
|
// Map tool names to handler functions
|
|
72720
|
-
const handlerMap$
|
|
73605
|
+
const handlerMap$5 = {
|
|
72721
73606
|
list_themes: handleListThemes,
|
|
72722
73607
|
get_theme: handleGetTheme,
|
|
72723
73608
|
create_theme: handleCreateTheme,
|
|
@@ -72730,12 +73615,12 @@ const handlerMap$4 = {
|
|
|
72730
73615
|
*/
|
|
72731
73616
|
function registerThemeTools$1() {
|
|
72732
73617
|
for (const tool of themeTools) {
|
|
72733
|
-
const handler = handlerMap$
|
|
73618
|
+
const handler = handlerMap$5[tool.name];
|
|
72734
73619
|
if (!handler) {
|
|
72735
73620
|
console.warn(`[themeTools] No handler found for tool: ${tool.name}`);
|
|
72736
73621
|
continue;
|
|
72737
73622
|
}
|
|
72738
|
-
registerTool$
|
|
73623
|
+
registerTool$3({
|
|
72739
73624
|
name: tool.name,
|
|
72740
73625
|
description: tool.description,
|
|
72741
73626
|
inputSchema: tool.inputSchema,
|
|
@@ -72754,7 +73639,7 @@ var themeTools_1 = { registerThemeTools: registerThemeTools$1 };
|
|
|
72754
73639
|
* Call registerProviderTools() during app startup (before or after server start).
|
|
72755
73640
|
*/
|
|
72756
73641
|
|
|
72757
|
-
const { registerTool: registerTool$
|
|
73642
|
+
const { registerTool: registerTool$2 } = mcpDashServerController_1;
|
|
72758
73643
|
const { providerTools } = toolDefinitions;
|
|
72759
73644
|
const {
|
|
72760
73645
|
handleListProviders,
|
|
@@ -72763,7 +73648,7 @@ const {
|
|
|
72763
73648
|
} = toolHandlers;
|
|
72764
73649
|
|
|
72765
73650
|
// Map tool names to handler functions
|
|
72766
|
-
const handlerMap$
|
|
73651
|
+
const handlerMap$4 = {
|
|
72767
73652
|
list_providers: handleListProviders,
|
|
72768
73653
|
add_provider: handleAddProvider,
|
|
72769
73654
|
remove_provider: handleRemoveProvider,
|
|
@@ -72774,12 +73659,12 @@ const handlerMap$3 = {
|
|
|
72774
73659
|
*/
|
|
72775
73660
|
function registerProviderTools$1() {
|
|
72776
73661
|
for (const tool of providerTools) {
|
|
72777
|
-
const handler = handlerMap$
|
|
73662
|
+
const handler = handlerMap$4[tool.name];
|
|
72778
73663
|
if (!handler) {
|
|
72779
73664
|
console.warn(`[providerTools] No handler found for tool: ${tool.name}`);
|
|
72780
73665
|
continue;
|
|
72781
73666
|
}
|
|
72782
|
-
registerTool$
|
|
73667
|
+
registerTool$2({
|
|
72783
73668
|
name: tool.name,
|
|
72784
73669
|
description: tool.description,
|
|
72785
73670
|
inputSchema: tool.inputSchema,
|
|
@@ -72800,22 +73685,22 @@ var providerTools_1 = { registerProviderTools: registerProviderTools$1 };
|
|
|
72800
73685
|
* Call registerGuideTools() during app startup.
|
|
72801
73686
|
*/
|
|
72802
73687
|
|
|
72803
|
-
const { registerTool } = mcpDashServerController_1;
|
|
73688
|
+
const { registerTool: registerTool$1 } = mcpDashServerController_1;
|
|
72804
73689
|
const { guideTools } = toolDefinitions;
|
|
72805
73690
|
const { handleGetSetupGuide } = toolHandlers;
|
|
72806
73691
|
|
|
72807
|
-
const handlerMap$
|
|
73692
|
+
const handlerMap$3 = {
|
|
72808
73693
|
get_setup_guide: handleGetSetupGuide,
|
|
72809
73694
|
};
|
|
72810
73695
|
|
|
72811
73696
|
function registerGuideTools$1() {
|
|
72812
73697
|
for (const tool of guideTools) {
|
|
72813
|
-
const handler = handlerMap$
|
|
73698
|
+
const handler = handlerMap$3[tool.name];
|
|
72814
73699
|
if (!handler) {
|
|
72815
73700
|
console.warn(`[guideTools] No handler found for tool: ${tool.name}`);
|
|
72816
73701
|
continue;
|
|
72817
73702
|
}
|
|
72818
|
-
registerTool({
|
|
73703
|
+
registerTool$1({
|
|
72819
73704
|
name: tool.name,
|
|
72820
73705
|
description: tool.description,
|
|
72821
73706
|
inputSchema: tool.inputSchema,
|
|
@@ -72827,6 +73712,49 @@ function registerGuideTools$1() {
|
|
|
72827
73712
|
|
|
72828
73713
|
var guideTools_1 = { registerGuideTools: registerGuideTools$1 };
|
|
72829
73714
|
|
|
73715
|
+
/**
|
|
73716
|
+
* layoutTools.js
|
|
73717
|
+
*
|
|
73718
|
+
* Registers layout/grid MCP tools with the MCP Dash server.
|
|
73719
|
+
* Call registerLayoutTools() during app startup (before or after server start).
|
|
73720
|
+
*/
|
|
73721
|
+
|
|
73722
|
+
const { registerTool } = mcpDashServerController_1;
|
|
73723
|
+
const { layoutTools } = toolDefinitions;
|
|
73724
|
+
const {
|
|
73725
|
+
handleSetLayout,
|
|
73726
|
+
handleUpdateLayout,
|
|
73727
|
+
handleMoveWidget,
|
|
73728
|
+
} = toolHandlers;
|
|
73729
|
+
|
|
73730
|
+
const handlerMap$2 = {
|
|
73731
|
+
set_layout: handleSetLayout,
|
|
73732
|
+
update_layout: handleUpdateLayout,
|
|
73733
|
+
move_widget: handleMoveWidget,
|
|
73734
|
+
};
|
|
73735
|
+
|
|
73736
|
+
/**
|
|
73737
|
+
* Register all layout tools with the MCP server controller.
|
|
73738
|
+
*/
|
|
73739
|
+
function registerLayoutTools$1() {
|
|
73740
|
+
for (const tool of layoutTools) {
|
|
73741
|
+
const handler = handlerMap$2[tool.name];
|
|
73742
|
+
if (!handler) {
|
|
73743
|
+
console.warn(`[layoutTools] No handler found for tool: ${tool.name}`);
|
|
73744
|
+
continue;
|
|
73745
|
+
}
|
|
73746
|
+
registerTool({
|
|
73747
|
+
name: tool.name,
|
|
73748
|
+
description: tool.description,
|
|
73749
|
+
inputSchema: tool.inputSchema,
|
|
73750
|
+
handler,
|
|
73751
|
+
});
|
|
73752
|
+
}
|
|
73753
|
+
console.log(`[layoutTools] Registered ${layoutTools.length} layout tools`);
|
|
73754
|
+
}
|
|
73755
|
+
|
|
73756
|
+
var layoutTools_1 = { registerLayoutTools: registerLayoutTools$1 };
|
|
73757
|
+
|
|
72830
73758
|
/**
|
|
72831
73759
|
* resourceDefinitions.js
|
|
72832
73760
|
*
|
|
@@ -73795,6 +74723,7 @@ const { registerWidgetTools } = widgetTools_1;
|
|
|
73795
74723
|
const { registerThemeTools } = themeTools_1;
|
|
73796
74724
|
const { registerProviderTools } = providerTools_1;
|
|
73797
74725
|
const { registerGuideTools } = guideTools_1;
|
|
74726
|
+
const { registerLayoutTools } = layoutTools_1;
|
|
73798
74727
|
const { registerResources } = resources;
|
|
73799
74728
|
const { registerPrompts } = promptRegistration;
|
|
73800
74729
|
registerDashboardTools();
|
|
@@ -73802,6 +74731,7 @@ registerWidgetTools();
|
|
|
73802
74731
|
registerThemeTools();
|
|
73803
74732
|
registerProviderTools();
|
|
73804
74733
|
registerGuideTools();
|
|
74734
|
+
registerLayoutTools();
|
|
73805
74735
|
registerResources();
|
|
73806
74736
|
registerPrompts();
|
|
73807
74737
|
|
|
@@ -73903,6 +74833,7 @@ var electron = {
|
|
|
73903
74833
|
registerWidgetTools,
|
|
73904
74834
|
registerThemeTools,
|
|
73905
74835
|
registerProviderTools,
|
|
74836
|
+
registerLayoutTools,
|
|
73906
74837
|
registerResources,
|
|
73907
74838
|
};
|
|
73908
74839
|
|