@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.
@@ -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$5(toolDef) {
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.tool(tool.name, tool.description, tool.inputSchema, tool.handler);
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$5,
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 empty dashboard with the given name. Returns the dashboard ID. After creating, use search_widgets or list_widgets to find widgets, then add_widget to populate the dashboard.",
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
- const parentId = container ? container.id : 0;
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
- parentId,
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
- var toolHandlers = {
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
- * dashboardTools.js
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$4 } = mcpDashServerController_1;
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$6 = {
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$6[tool.name];
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$4({
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$3 } = mcpDashServerController_1;
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$5 = {
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$5[tool.name];
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$3({
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$2 } = mcpDashServerController_1;
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$4 = {
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$4[tool.name];
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$2({
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$1 } = mcpDashServerController_1;
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$3 = {
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$3[tool.name];
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$1({
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$2 = {
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$2[tool.name];
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