@trops/dash-core 0.1.172 → 0.1.173
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 +668 -27
- package/dist/electron/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -169,7 +169,7 @@ const THEME_LIST_COMPLETE = "theme-list-complete";
|
|
|
169
169
|
const THEME_LIST_ERROR = "theme-list-error";
|
|
170
170
|
|
|
171
171
|
const THEME_SAVE$1 = "theme-save";
|
|
172
|
-
const THEME_SAVE_COMPLETE = "theme-save-complete";
|
|
172
|
+
const THEME_SAVE_COMPLETE$1 = "theme-save-complete";
|
|
173
173
|
const THEME_SAVE_ERROR = "theme-save-error";
|
|
174
174
|
|
|
175
175
|
const THEME_DELETE$1 = "theme-delete";
|
|
@@ -185,7 +185,7 @@ var themeEvents$1 = {
|
|
|
185
185
|
THEME_LIST_COMPLETE,
|
|
186
186
|
THEME_LIST_ERROR,
|
|
187
187
|
THEME_SAVE: THEME_SAVE$1,
|
|
188
|
-
THEME_SAVE_COMPLETE,
|
|
188
|
+
THEME_SAVE_COMPLETE: THEME_SAVE_COMPLETE$1,
|
|
189
189
|
THEME_SAVE_ERROR,
|
|
190
190
|
THEME_DELETE: THEME_DELETE$1,
|
|
191
191
|
THEME_DELETE_COMPLETE,
|
|
@@ -304,7 +304,7 @@ const SETTINGS_GET_COMPLETE = "settings-get-complete";
|
|
|
304
304
|
const SETTINGS_GET_ERROR = "settings-get-error";
|
|
305
305
|
|
|
306
306
|
const SETTINGS_SAVE$1 = "settings-save";
|
|
307
|
-
const SETTINGS_SAVE_COMPLETE = "settings-save-complete";
|
|
307
|
+
const SETTINGS_SAVE_COMPLETE$1 = "settings-save-complete";
|
|
308
308
|
const SETTINGS_SAVE_ERROR = "settings-save-error";
|
|
309
309
|
|
|
310
310
|
const SETTINGS_GET_DATA_DIR$1 = "settings-get-data-dir";
|
|
@@ -324,7 +324,7 @@ var settingsEvents$1 = {
|
|
|
324
324
|
SETTINGS_GET_COMPLETE,
|
|
325
325
|
SETTINGS_GET_ERROR,
|
|
326
326
|
SETTINGS_SAVE: SETTINGS_SAVE$1,
|
|
327
|
-
SETTINGS_SAVE_COMPLETE,
|
|
327
|
+
SETTINGS_SAVE_COMPLETE: SETTINGS_SAVE_COMPLETE$1,
|
|
328
328
|
SETTINGS_SAVE_ERROR,
|
|
329
329
|
SETTINGS_GET_DATA_DIR: SETTINGS_GET_DATA_DIR$1,
|
|
330
330
|
SETTINGS_GET_DATA_DIR_COMPLETE,
|
|
@@ -4294,7 +4294,7 @@ function copyDirectory(source, destination) {
|
|
|
4294
4294
|
}
|
|
4295
4295
|
}
|
|
4296
4296
|
|
|
4297
|
-
const settingsController$
|
|
4297
|
+
const settingsController$3 = {
|
|
4298
4298
|
/**
|
|
4299
4299
|
* saveSettingsForApplication
|
|
4300
4300
|
* Save the settings object to a file (settings.json)
|
|
@@ -4526,7 +4526,7 @@ const settingsController$2 = {
|
|
|
4526
4526
|
},
|
|
4527
4527
|
};
|
|
4528
4528
|
|
|
4529
|
-
var settingsController_1 = settingsController$
|
|
4529
|
+
var settingsController_1 = settingsController$3;
|
|
4530
4530
|
|
|
4531
4531
|
/**
|
|
4532
4532
|
* responseCache.js
|
|
@@ -39626,13 +39626,13 @@ async function extractColorsFromUrl({
|
|
|
39626
39626
|
};
|
|
39627
39627
|
}
|
|
39628
39628
|
|
|
39629
|
-
const themeFromUrlController$
|
|
39629
|
+
const themeFromUrlController$2 = {
|
|
39630
39630
|
extractColorsFromUrl,
|
|
39631
39631
|
extractFaviconUrls,
|
|
39632
39632
|
extractFaviconColors,
|
|
39633
39633
|
};
|
|
39634
39634
|
|
|
39635
|
-
var themeFromUrlController_1 = themeFromUrlController$
|
|
39635
|
+
var themeFromUrlController_1 = themeFromUrlController$2;
|
|
39636
39636
|
|
|
39637
39637
|
/**
|
|
39638
39638
|
* themeGenerator.js
|
|
@@ -40289,13 +40289,13 @@ function generateThemeFromPalette$1(palette, overrides = {}) {
|
|
|
40289
40289
|
};
|
|
40290
40290
|
}
|
|
40291
40291
|
|
|
40292
|
-
const paletteToThemeMapper$
|
|
40292
|
+
const paletteToThemeMapper$2 = {
|
|
40293
40293
|
assignRoles: assignRoles$1,
|
|
40294
40294
|
matchTailwindFamily: matchTailwindFamily$1,
|
|
40295
40295
|
generateThemeFromPalette: generateThemeFromPalette$1,
|
|
40296
40296
|
};
|
|
40297
40297
|
|
|
40298
|
-
var paletteToThemeMapper_1 = paletteToThemeMapper$
|
|
40298
|
+
var paletteToThemeMapper_1 = paletteToThemeMapper$2;
|
|
40299
40299
|
|
|
40300
40300
|
var bufferUtil$1 = {exports: {}};
|
|
40301
40301
|
|
|
@@ -46080,9 +46080,9 @@ function stats() {
|
|
|
46080
46080
|
};
|
|
46081
46081
|
}
|
|
46082
46082
|
|
|
46083
|
-
const extractionCacheController$
|
|
46083
|
+
const extractionCacheController$2 = { get, has, clear, invalidate, stats };
|
|
46084
46084
|
|
|
46085
|
-
var extractionCacheController_1 = extractionCacheController$
|
|
46085
|
+
var extractionCacheController_1 = extractionCacheController$2;
|
|
46086
46086
|
|
|
46087
46087
|
var mcp = {};
|
|
46088
46088
|
|
|
@@ -66056,7 +66056,7 @@ const {
|
|
|
66056
66056
|
StreamableHTTPServerTransport,
|
|
66057
66057
|
} = streamableHttp;
|
|
66058
66058
|
|
|
66059
|
-
const settingsController$
|
|
66059
|
+
const settingsController$2 = settingsController_1;
|
|
66060
66060
|
|
|
66061
66061
|
// --- State ---
|
|
66062
66062
|
let mcpServer = null;
|
|
@@ -66111,7 +66111,7 @@ const registeredResources = [];
|
|
|
66111
66111
|
* Register a tool to be exposed via the MCP server.
|
|
66112
66112
|
* Call this before starting the server (or restart after registering).
|
|
66113
66113
|
*/
|
|
66114
|
-
function registerTool$
|
|
66114
|
+
function registerTool$3(toolDef) {
|
|
66115
66115
|
registeredTools.push(toolDef);
|
|
66116
66116
|
}
|
|
66117
66117
|
|
|
@@ -66141,16 +66141,16 @@ function applyRegistrations(server) {
|
|
|
66141
66141
|
|
|
66142
66142
|
// --- Settings Helpers ---
|
|
66143
66143
|
function getMcpServerSettings(win) {
|
|
66144
|
-
const result = settingsController$
|
|
66144
|
+
const result = settingsController$2.getSettingsForApplication(win);
|
|
66145
66145
|
const settings = result?.settings || {};
|
|
66146
66146
|
return settings.mcpDashServer || {};
|
|
66147
66147
|
}
|
|
66148
66148
|
|
|
66149
66149
|
function saveMcpServerSettings(win, mcpSettings) {
|
|
66150
|
-
const result = settingsController$
|
|
66150
|
+
const result = settingsController$2.getSettingsForApplication(win);
|
|
66151
66151
|
const settings = result?.settings || {};
|
|
66152
66152
|
settings.mcpDashServer = mcpSettings;
|
|
66153
|
-
settingsController$
|
|
66153
|
+
settingsController$2.saveSettingsForApplication(win, settings);
|
|
66154
66154
|
}
|
|
66155
66155
|
|
|
66156
66156
|
// --- App ID Resolution ---
|
|
@@ -66434,7 +66434,7 @@ const mcpDashServerController$3 = {
|
|
|
66434
66434
|
},
|
|
66435
66435
|
|
|
66436
66436
|
// Expose registration functions for other controllers
|
|
66437
|
-
registerTool: registerTool$
|
|
66437
|
+
registerTool: registerTool$3,
|
|
66438
66438
|
registerResource,
|
|
66439
66439
|
getServerContext,
|
|
66440
66440
|
};
|
|
@@ -69134,7 +69134,91 @@ const widgetTools$1 = [
|
|
|
69134
69134
|
},
|
|
69135
69135
|
];
|
|
69136
69136
|
|
|
69137
|
-
|
|
69137
|
+
const themeTools$1 = [
|
|
69138
|
+
{
|
|
69139
|
+
name: "list_themes",
|
|
69140
|
+
description:
|
|
69141
|
+
"List all saved themes with their names and whether they are currently active",
|
|
69142
|
+
inputSchema: {
|
|
69143
|
+
type: "object",
|
|
69144
|
+
properties: {},
|
|
69145
|
+
required: [],
|
|
69146
|
+
},
|
|
69147
|
+
},
|
|
69148
|
+
{
|
|
69149
|
+
name: "get_theme",
|
|
69150
|
+
description:
|
|
69151
|
+
"Get full details of a theme by name, including all color values",
|
|
69152
|
+
inputSchema: {
|
|
69153
|
+
type: "object",
|
|
69154
|
+
properties: {
|
|
69155
|
+
name: {
|
|
69156
|
+
type: "string",
|
|
69157
|
+
description: "Name of the theme to retrieve",
|
|
69158
|
+
},
|
|
69159
|
+
},
|
|
69160
|
+
required: ["name"],
|
|
69161
|
+
},
|
|
69162
|
+
},
|
|
69163
|
+
{
|
|
69164
|
+
name: "create_theme",
|
|
69165
|
+
description:
|
|
69166
|
+
"Create a new theme from a colors object. The colors object should contain color role keys (e.g. primary, secondary, surface, background) mapped to hex values or shade objects.",
|
|
69167
|
+
inputSchema: {
|
|
69168
|
+
type: "object",
|
|
69169
|
+
properties: {
|
|
69170
|
+
name: {
|
|
69171
|
+
type: "string",
|
|
69172
|
+
description: "Display name for the new theme",
|
|
69173
|
+
},
|
|
69174
|
+
colors: {
|
|
69175
|
+
type: "object",
|
|
69176
|
+
description:
|
|
69177
|
+
"Theme colors object with role keys mapped to hex values or shade objects",
|
|
69178
|
+
},
|
|
69179
|
+
},
|
|
69180
|
+
required: ["name", "colors"],
|
|
69181
|
+
},
|
|
69182
|
+
},
|
|
69183
|
+
{
|
|
69184
|
+
name: "create_theme_from_url",
|
|
69185
|
+
description:
|
|
69186
|
+
"Extract brand colors from a website URL and generate a theme. Loads the page, extracts colors from meta tags, CSS variables, computed styles, and favicons, then maps them to theme roles.",
|
|
69187
|
+
inputSchema: {
|
|
69188
|
+
type: "object",
|
|
69189
|
+
properties: {
|
|
69190
|
+
url: {
|
|
69191
|
+
type: "string",
|
|
69192
|
+
description:
|
|
69193
|
+
"Website URL to extract colors from (must start with http:// or https://)",
|
|
69194
|
+
},
|
|
69195
|
+
name: {
|
|
69196
|
+
type: "string",
|
|
69197
|
+
description:
|
|
69198
|
+
"Optional name for the theme. If omitted, a name is derived from the URL hostname.",
|
|
69199
|
+
},
|
|
69200
|
+
},
|
|
69201
|
+
required: ["url"],
|
|
69202
|
+
},
|
|
69203
|
+
},
|
|
69204
|
+
{
|
|
69205
|
+
name: "apply_theme",
|
|
69206
|
+
description:
|
|
69207
|
+
"Apply a saved theme to the active dashboard. The theme must already exist (use list_themes to see available themes).",
|
|
69208
|
+
inputSchema: {
|
|
69209
|
+
type: "object",
|
|
69210
|
+
properties: {
|
|
69211
|
+
name: {
|
|
69212
|
+
type: "string",
|
|
69213
|
+
description: "Name of the theme to apply",
|
|
69214
|
+
},
|
|
69215
|
+
},
|
|
69216
|
+
required: ["name"],
|
|
69217
|
+
},
|
|
69218
|
+
},
|
|
69219
|
+
];
|
|
69220
|
+
|
|
69221
|
+
var toolDefinitions = { dashboardTools: dashboardTools$1, widgetTools: widgetTools$1, themeTools: themeTools$1 };
|
|
69138
69222
|
|
|
69139
69223
|
/**
|
|
69140
69224
|
* toolHandlers.js
|
|
@@ -69969,6 +70053,507 @@ async function handleSearchWidgets$1({ query }) {
|
|
|
69969
70053
|
}
|
|
69970
70054
|
}
|
|
69971
70055
|
|
|
70056
|
+
// --- Theme Tool Handlers ---
|
|
70057
|
+
|
|
70058
|
+
const settingsController$1 = settingsController_1;
|
|
70059
|
+
const themeFromUrlController$1 = themeFromUrlController_1;
|
|
70060
|
+
const paletteToThemeMapper$1 = paletteToThemeMapper_1;
|
|
70061
|
+
const extractionCacheController$1 = extractionCacheController_1;
|
|
70062
|
+
const { THEME_SAVE_COMPLETE, SETTINGS_SAVE_COMPLETE } = events$8;
|
|
70063
|
+
|
|
70064
|
+
/**
|
|
70065
|
+
* list_themes — Returns all saved themes with name, active state, and color summary.
|
|
70066
|
+
*/
|
|
70067
|
+
async function handleListThemes$1() {
|
|
70068
|
+
const { win, appId } = requireContext();
|
|
70069
|
+
const result = themeController$1.listThemesForApplication(win, appId);
|
|
70070
|
+
|
|
70071
|
+
if (result.error) {
|
|
70072
|
+
return {
|
|
70073
|
+
content: [
|
|
70074
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
70075
|
+
],
|
|
70076
|
+
isError: true,
|
|
70077
|
+
};
|
|
70078
|
+
}
|
|
70079
|
+
|
|
70080
|
+
const themes = result.themes || {};
|
|
70081
|
+
const settingsResult = settingsController$1.getSettingsForApplication(win);
|
|
70082
|
+
const activeThemeKey = settingsResult?.settings?.theme || null;
|
|
70083
|
+
|
|
70084
|
+
const themeList = Object.keys(themes).map((name) => ({
|
|
70085
|
+
name,
|
|
70086
|
+
isActive: name === activeThemeKey,
|
|
70087
|
+
colors: themes[name],
|
|
70088
|
+
}));
|
|
70089
|
+
|
|
70090
|
+
return {
|
|
70091
|
+
content: [
|
|
70092
|
+
{
|
|
70093
|
+
type: "text",
|
|
70094
|
+
text: JSON.stringify(
|
|
70095
|
+
{ themes: themeList, count: themeList.length },
|
|
70096
|
+
null,
|
|
70097
|
+
2,
|
|
70098
|
+
),
|
|
70099
|
+
},
|
|
70100
|
+
],
|
|
70101
|
+
};
|
|
70102
|
+
}
|
|
70103
|
+
|
|
70104
|
+
/**
|
|
70105
|
+
* get_theme — Returns full details of a theme by name.
|
|
70106
|
+
*/
|
|
70107
|
+
async function handleGetTheme$1({ name }) {
|
|
70108
|
+
if (!name || typeof name !== "string" || !name.trim()) {
|
|
70109
|
+
return {
|
|
70110
|
+
content: [
|
|
70111
|
+
{
|
|
70112
|
+
type: "text",
|
|
70113
|
+
text: JSON.stringify({
|
|
70114
|
+
error: "name is required and must be a non-empty string",
|
|
70115
|
+
}),
|
|
70116
|
+
},
|
|
70117
|
+
],
|
|
70118
|
+
isError: true,
|
|
70119
|
+
};
|
|
70120
|
+
}
|
|
70121
|
+
|
|
70122
|
+
const { win, appId } = requireContext();
|
|
70123
|
+
const result = themeController$1.listThemesForApplication(win, appId);
|
|
70124
|
+
|
|
70125
|
+
if (result.error) {
|
|
70126
|
+
return {
|
|
70127
|
+
content: [
|
|
70128
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
70129
|
+
],
|
|
70130
|
+
isError: true,
|
|
70131
|
+
};
|
|
70132
|
+
}
|
|
70133
|
+
|
|
70134
|
+
const themes = result.themes || {};
|
|
70135
|
+
const themeName = name.trim();
|
|
70136
|
+
|
|
70137
|
+
if (!(themeName in themes)) {
|
|
70138
|
+
return {
|
|
70139
|
+
content: [
|
|
70140
|
+
{
|
|
70141
|
+
type: "text",
|
|
70142
|
+
text: JSON.stringify({ error: `Theme not found: ${themeName}` }),
|
|
70143
|
+
},
|
|
70144
|
+
],
|
|
70145
|
+
isError: true,
|
|
70146
|
+
};
|
|
70147
|
+
}
|
|
70148
|
+
|
|
70149
|
+
const settingsResult = settingsController$1.getSettingsForApplication(win);
|
|
70150
|
+
const activeThemeKey = settingsResult?.settings?.theme || null;
|
|
70151
|
+
|
|
70152
|
+
return {
|
|
70153
|
+
content: [
|
|
70154
|
+
{
|
|
70155
|
+
type: "text",
|
|
70156
|
+
text: JSON.stringify(
|
|
70157
|
+
{
|
|
70158
|
+
name: themeName,
|
|
70159
|
+
isActive: themeName === activeThemeKey,
|
|
70160
|
+
colors: themes[themeName],
|
|
70161
|
+
},
|
|
70162
|
+
null,
|
|
70163
|
+
2,
|
|
70164
|
+
),
|
|
70165
|
+
},
|
|
70166
|
+
],
|
|
70167
|
+
};
|
|
70168
|
+
}
|
|
70169
|
+
|
|
70170
|
+
/**
|
|
70171
|
+
* create_theme — Creates a new theme from a colors object.
|
|
70172
|
+
*/
|
|
70173
|
+
async function handleCreateTheme$1({ name, colors }) {
|
|
70174
|
+
if (!name || typeof name !== "string" || !name.trim()) {
|
|
70175
|
+
return {
|
|
70176
|
+
content: [
|
|
70177
|
+
{
|
|
70178
|
+
type: "text",
|
|
70179
|
+
text: JSON.stringify({
|
|
70180
|
+
error: "name is required and must be a non-empty string",
|
|
70181
|
+
}),
|
|
70182
|
+
},
|
|
70183
|
+
],
|
|
70184
|
+
isError: true,
|
|
70185
|
+
};
|
|
70186
|
+
}
|
|
70187
|
+
|
|
70188
|
+
if (!colors || typeof colors !== "object" || Array.isArray(colors)) {
|
|
70189
|
+
return {
|
|
70190
|
+
content: [
|
|
70191
|
+
{
|
|
70192
|
+
type: "text",
|
|
70193
|
+
text: JSON.stringify({
|
|
70194
|
+
error: "colors is required and must be an object",
|
|
70195
|
+
}),
|
|
70196
|
+
},
|
|
70197
|
+
],
|
|
70198
|
+
isError: true,
|
|
70199
|
+
};
|
|
70200
|
+
}
|
|
70201
|
+
|
|
70202
|
+
const { win, appId } = requireContext();
|
|
70203
|
+
const themeName = name.trim();
|
|
70204
|
+
|
|
70205
|
+
const result = themeController$1.saveThemeForApplication(
|
|
70206
|
+
win,
|
|
70207
|
+
appId,
|
|
70208
|
+
themeName,
|
|
70209
|
+
colors,
|
|
70210
|
+
);
|
|
70211
|
+
|
|
70212
|
+
if (result.error) {
|
|
70213
|
+
return {
|
|
70214
|
+
content: [
|
|
70215
|
+
{ type: "text", text: JSON.stringify({ error: result.message }) },
|
|
70216
|
+
],
|
|
70217
|
+
isError: true,
|
|
70218
|
+
};
|
|
70219
|
+
}
|
|
70220
|
+
|
|
70221
|
+
// Notify the renderer so the UI updates
|
|
70222
|
+
win.webContents.send(THEME_SAVE_COMPLETE, result);
|
|
70223
|
+
|
|
70224
|
+
return {
|
|
70225
|
+
content: [
|
|
70226
|
+
{
|
|
70227
|
+
type: "text",
|
|
70228
|
+
text: JSON.stringify({ name: themeName, created: true }, null, 2),
|
|
70229
|
+
},
|
|
70230
|
+
],
|
|
70231
|
+
};
|
|
70232
|
+
}
|
|
70233
|
+
|
|
70234
|
+
/**
|
|
70235
|
+
* create_theme_from_url — Extracts colors from a URL and generates a theme.
|
|
70236
|
+
* Uses a hidden BrowserWindow to load the page and extract styles.
|
|
70237
|
+
*/
|
|
70238
|
+
async function handleCreateThemeFromUrl$1({ url, name }) {
|
|
70239
|
+
if (!url || typeof url !== "string" || !url.trim()) {
|
|
70240
|
+
return {
|
|
70241
|
+
content: [
|
|
70242
|
+
{
|
|
70243
|
+
type: "text",
|
|
70244
|
+
text: JSON.stringify({
|
|
70245
|
+
error: "url is required and must be a non-empty string",
|
|
70246
|
+
}),
|
|
70247
|
+
},
|
|
70248
|
+
],
|
|
70249
|
+
isError: true,
|
|
70250
|
+
};
|
|
70251
|
+
}
|
|
70252
|
+
|
|
70253
|
+
const trimmedUrl = url.trim();
|
|
70254
|
+
|
|
70255
|
+
// Validate URL format
|
|
70256
|
+
if (!trimmedUrl.startsWith("http://") && !trimmedUrl.startsWith("https://")) {
|
|
70257
|
+
return {
|
|
70258
|
+
content: [
|
|
70259
|
+
{
|
|
70260
|
+
type: "text",
|
|
70261
|
+
text: JSON.stringify({
|
|
70262
|
+
error: "url must start with http:// or https://",
|
|
70263
|
+
}),
|
|
70264
|
+
},
|
|
70265
|
+
],
|
|
70266
|
+
isError: true,
|
|
70267
|
+
};
|
|
70268
|
+
}
|
|
70269
|
+
|
|
70270
|
+
const { win, appId } = requireContext();
|
|
70271
|
+
const { BrowserWindow } = require$$0$2;
|
|
70272
|
+
|
|
70273
|
+
const LOAD_TIMEOUT_MS = 15000;
|
|
70274
|
+
|
|
70275
|
+
try {
|
|
70276
|
+
// Extract colors using a hidden BrowserWindow (same approach as dash-electron IPC handler)
|
|
70277
|
+
const extractionData = await extractionCacheController$1.get(
|
|
70278
|
+
trimmedUrl,
|
|
70279
|
+
async () => {
|
|
70280
|
+
const scanWindow = new BrowserWindow({
|
|
70281
|
+
width: 1280,
|
|
70282
|
+
height: 900,
|
|
70283
|
+
show: false,
|
|
70284
|
+
webPreferences: {
|
|
70285
|
+
nodeIntegration: false,
|
|
70286
|
+
contextIsolation: true,
|
|
70287
|
+
},
|
|
70288
|
+
});
|
|
70289
|
+
|
|
70290
|
+
let destroyed = false;
|
|
70291
|
+
const destroyScanWindow = () => {
|
|
70292
|
+
if (!destroyed) {
|
|
70293
|
+
destroyed = true;
|
|
70294
|
+
scanWindow.destroy();
|
|
70295
|
+
}
|
|
70296
|
+
};
|
|
70297
|
+
|
|
70298
|
+
try {
|
|
70299
|
+
scanWindow.webContents.on("will-navigate", (event) => {
|
|
70300
|
+
event.preventDefault();
|
|
70301
|
+
});
|
|
70302
|
+
|
|
70303
|
+
await new Promise((resolve, reject) => {
|
|
70304
|
+
const timeout = setTimeout(() => {
|
|
70305
|
+
reject(
|
|
70306
|
+
new Error(
|
|
70307
|
+
`Page load timed out after ${LOAD_TIMEOUT_MS}ms for ${trimmedUrl}`,
|
|
70308
|
+
),
|
|
70309
|
+
);
|
|
70310
|
+
}, LOAD_TIMEOUT_MS);
|
|
70311
|
+
|
|
70312
|
+
scanWindow.webContents.on(
|
|
70313
|
+
"did-fail-load",
|
|
70314
|
+
(event, errorCode, errorDescription) => {
|
|
70315
|
+
clearTimeout(timeout);
|
|
70316
|
+
const desc = errorDescription || `Error code ${errorCode}`;
|
|
70317
|
+
reject(new Error(`Page load failed: ${desc}`));
|
|
70318
|
+
},
|
|
70319
|
+
);
|
|
70320
|
+
|
|
70321
|
+
scanWindow
|
|
70322
|
+
.loadURL(trimmedUrl)
|
|
70323
|
+
.then(() => {
|
|
70324
|
+
clearTimeout(timeout);
|
|
70325
|
+
resolve();
|
|
70326
|
+
})
|
|
70327
|
+
.catch((err) => {
|
|
70328
|
+
clearTimeout(timeout);
|
|
70329
|
+
reject(
|
|
70330
|
+
new Error(`Failed to load ${trimmedUrl}: ${err.message}`),
|
|
70331
|
+
);
|
|
70332
|
+
});
|
|
70333
|
+
});
|
|
70334
|
+
|
|
70335
|
+
const extracted = await scanWindow.webContents.executeJavaScript(`
|
|
70336
|
+
(function() {
|
|
70337
|
+
try {
|
|
70338
|
+
const htmlContent = document.documentElement.outerHTML;
|
|
70339
|
+
let cssContent = '';
|
|
70340
|
+
try {
|
|
70341
|
+
for (const sheet of document.styleSheets) {
|
|
70342
|
+
try {
|
|
70343
|
+
for (const rule of sheet.cssRules) {
|
|
70344
|
+
cssContent += rule.cssText + '\\n';
|
|
70345
|
+
}
|
|
70346
|
+
} catch (e) { /* cross-origin stylesheet */ }
|
|
70347
|
+
}
|
|
70348
|
+
} catch (e) {}
|
|
70349
|
+
const selectors = ['body', 'header', 'nav', 'main', 'footer', 'a', 'button', 'h1', 'h2'];
|
|
70350
|
+
const computedStyles = {};
|
|
70351
|
+
for (const sel of selectors) {
|
|
70352
|
+
const el = document.querySelector(sel);
|
|
70353
|
+
if (!el) continue;
|
|
70354
|
+
const cs = window.getComputedStyle(el);
|
|
70355
|
+
computedStyles[sel] = {
|
|
70356
|
+
color: cs.color,
|
|
70357
|
+
backgroundColor: cs.backgroundColor,
|
|
70358
|
+
borderColor: cs.borderColor,
|
|
70359
|
+
};
|
|
70360
|
+
}
|
|
70361
|
+
return { success: true, htmlContent, cssContent, computedStyles };
|
|
70362
|
+
} catch (e) {
|
|
70363
|
+
return { success: false, error: { type: 'EXTRACTION_FAILED', message: e.message } };
|
|
70364
|
+
}
|
|
70365
|
+
})();
|
|
70366
|
+
`);
|
|
70367
|
+
|
|
70368
|
+
if (!extracted || !extracted.success) {
|
|
70369
|
+
const errMsg =
|
|
70370
|
+
extracted?.error?.message || "Script execution failed";
|
|
70371
|
+
throw new Error(`Color extraction failed: ${errMsg}`);
|
|
70372
|
+
}
|
|
70373
|
+
|
|
70374
|
+
return themeFromUrlController$1.extractColorsFromUrl({
|
|
70375
|
+
htmlContent: extracted.htmlContent,
|
|
70376
|
+
cssContent: extracted.cssContent,
|
|
70377
|
+
computedStyles: extracted.computedStyles,
|
|
70378
|
+
baseUrl: trimmedUrl,
|
|
70379
|
+
});
|
|
70380
|
+
} finally {
|
|
70381
|
+
destroyScanWindow();
|
|
70382
|
+
}
|
|
70383
|
+
},
|
|
70384
|
+
);
|
|
70385
|
+
|
|
70386
|
+
// Map palette to theme
|
|
70387
|
+
const palette = extractionData?.palette || [];
|
|
70388
|
+
if (palette.length === 0) {
|
|
70389
|
+
return {
|
|
70390
|
+
content: [
|
|
70391
|
+
{
|
|
70392
|
+
type: "text",
|
|
70393
|
+
text: JSON.stringify({
|
|
70394
|
+
error: "No colors could be extracted from the URL",
|
|
70395
|
+
}),
|
|
70396
|
+
},
|
|
70397
|
+
],
|
|
70398
|
+
isError: true,
|
|
70399
|
+
};
|
|
70400
|
+
}
|
|
70401
|
+
|
|
70402
|
+
const { theme: generatedTheme } =
|
|
70403
|
+
paletteToThemeMapper$1.generateThemeFromPalette(palette);
|
|
70404
|
+
|
|
70405
|
+
// Derive theme name from URL hostname if not provided
|
|
70406
|
+
let themeName;
|
|
70407
|
+
if (name && typeof name === "string" && name.trim()) {
|
|
70408
|
+
themeName = name.trim();
|
|
70409
|
+
} else {
|
|
70410
|
+
try {
|
|
70411
|
+
const { URL } = require("url");
|
|
70412
|
+
const parsed = new URL(trimmedUrl);
|
|
70413
|
+
themeName = parsed.hostname.replace(/^www\./, "");
|
|
70414
|
+
} catch {
|
|
70415
|
+
themeName = "url-theme";
|
|
70416
|
+
}
|
|
70417
|
+
}
|
|
70418
|
+
|
|
70419
|
+
// Save the generated theme
|
|
70420
|
+
const saveResult = themeController$1.saveThemeForApplication(
|
|
70421
|
+
win,
|
|
70422
|
+
appId,
|
|
70423
|
+
themeName,
|
|
70424
|
+
generatedTheme,
|
|
70425
|
+
);
|
|
70426
|
+
|
|
70427
|
+
if (saveResult.error) {
|
|
70428
|
+
return {
|
|
70429
|
+
content: [
|
|
70430
|
+
{ type: "text", text: JSON.stringify({ error: saveResult.message }) },
|
|
70431
|
+
],
|
|
70432
|
+
isError: true,
|
|
70433
|
+
};
|
|
70434
|
+
}
|
|
70435
|
+
|
|
70436
|
+
// Notify the renderer
|
|
70437
|
+
win.webContents.send(THEME_SAVE_COMPLETE, saveResult);
|
|
70438
|
+
|
|
70439
|
+
return {
|
|
70440
|
+
content: [
|
|
70441
|
+
{
|
|
70442
|
+
type: "text",
|
|
70443
|
+
text: JSON.stringify(
|
|
70444
|
+
{
|
|
70445
|
+
name: themeName,
|
|
70446
|
+
created: true,
|
|
70447
|
+
colorsExtracted: palette.length,
|
|
70448
|
+
source: trimmedUrl,
|
|
70449
|
+
},
|
|
70450
|
+
null,
|
|
70451
|
+
2,
|
|
70452
|
+
),
|
|
70453
|
+
},
|
|
70454
|
+
],
|
|
70455
|
+
};
|
|
70456
|
+
} catch (err) {
|
|
70457
|
+
return {
|
|
70458
|
+
content: [
|
|
70459
|
+
{
|
|
70460
|
+
type: "text",
|
|
70461
|
+
text: JSON.stringify({
|
|
70462
|
+
error: `Failed to create theme from URL: ${err.message}`,
|
|
70463
|
+
}),
|
|
70464
|
+
},
|
|
70465
|
+
],
|
|
70466
|
+
isError: true,
|
|
70467
|
+
};
|
|
70468
|
+
}
|
|
70469
|
+
}
|
|
70470
|
+
|
|
70471
|
+
/**
|
|
70472
|
+
* apply_theme — Applies a saved theme to the active dashboard.
|
|
70473
|
+
* Updates settings to set the active theme key and notifies the renderer.
|
|
70474
|
+
*/
|
|
70475
|
+
async function handleApplyTheme$1({ name }) {
|
|
70476
|
+
if (!name || typeof name !== "string" || !name.trim()) {
|
|
70477
|
+
return {
|
|
70478
|
+
content: [
|
|
70479
|
+
{
|
|
70480
|
+
type: "text",
|
|
70481
|
+
text: JSON.stringify({
|
|
70482
|
+
error: "name is required and must be a non-empty string",
|
|
70483
|
+
}),
|
|
70484
|
+
},
|
|
70485
|
+
],
|
|
70486
|
+
isError: true,
|
|
70487
|
+
};
|
|
70488
|
+
}
|
|
70489
|
+
|
|
70490
|
+
const { win, appId } = requireContext();
|
|
70491
|
+
const themeName = name.trim();
|
|
70492
|
+
|
|
70493
|
+
// Verify the theme exists
|
|
70494
|
+
const themeResult = themeController$1.listThemesForApplication(win, appId);
|
|
70495
|
+
if (themeResult.error) {
|
|
70496
|
+
return {
|
|
70497
|
+
content: [
|
|
70498
|
+
{
|
|
70499
|
+
type: "text",
|
|
70500
|
+
text: JSON.stringify({ error: themeResult.message }),
|
|
70501
|
+
},
|
|
70502
|
+
],
|
|
70503
|
+
isError: true,
|
|
70504
|
+
};
|
|
70505
|
+
}
|
|
70506
|
+
|
|
70507
|
+
const themes = themeResult.themes || {};
|
|
70508
|
+
if (!(themeName in themes)) {
|
|
70509
|
+
return {
|
|
70510
|
+
content: [
|
|
70511
|
+
{
|
|
70512
|
+
type: "text",
|
|
70513
|
+
text: JSON.stringify({
|
|
70514
|
+
error: `Theme not found: ${themeName}. Use list_themes to see available themes.`,
|
|
70515
|
+
}),
|
|
70516
|
+
},
|
|
70517
|
+
],
|
|
70518
|
+
isError: true,
|
|
70519
|
+
};
|
|
70520
|
+
}
|
|
70521
|
+
|
|
70522
|
+
// Update settings to set the active theme
|
|
70523
|
+
const settingsResult = settingsController$1.getSettingsForApplication(win);
|
|
70524
|
+
const settings = settingsResult?.settings || {};
|
|
70525
|
+
settings.theme = themeName;
|
|
70526
|
+
|
|
70527
|
+
const saveResult = settingsController$1.saveSettingsForApplication(
|
|
70528
|
+
win,
|
|
70529
|
+
settings,
|
|
70530
|
+
);
|
|
70531
|
+
|
|
70532
|
+
if (saveResult.error) {
|
|
70533
|
+
return {
|
|
70534
|
+
content: [
|
|
70535
|
+
{
|
|
70536
|
+
type: "text",
|
|
70537
|
+
text: JSON.stringify({ error: saveResult.message }),
|
|
70538
|
+
},
|
|
70539
|
+
],
|
|
70540
|
+
isError: true,
|
|
70541
|
+
};
|
|
70542
|
+
}
|
|
70543
|
+
|
|
70544
|
+
// Notify the renderer to update the theme
|
|
70545
|
+
win.webContents.send(SETTINGS_SAVE_COMPLETE, { settings });
|
|
70546
|
+
|
|
70547
|
+
return {
|
|
70548
|
+
content: [
|
|
70549
|
+
{
|
|
70550
|
+
type: "text",
|
|
70551
|
+
text: JSON.stringify({ name: themeName, applied: true }, null, 2),
|
|
70552
|
+
},
|
|
70553
|
+
],
|
|
70554
|
+
};
|
|
70555
|
+
}
|
|
70556
|
+
|
|
69972
70557
|
var toolHandlers = {
|
|
69973
70558
|
handleListDashboards: handleListDashboards$1,
|
|
69974
70559
|
handleGetDashboard: handleGetDashboard$1,
|
|
@@ -69980,6 +70565,11 @@ var toolHandlers = {
|
|
|
69980
70565
|
handleConfigureWidget: handleConfigureWidget$1,
|
|
69981
70566
|
handleListWidgets: handleListWidgets$1,
|
|
69982
70567
|
handleSearchWidgets: handleSearchWidgets$1,
|
|
70568
|
+
handleListThemes: handleListThemes$1,
|
|
70569
|
+
handleGetTheme: handleGetTheme$1,
|
|
70570
|
+
handleCreateTheme: handleCreateTheme$1,
|
|
70571
|
+
handleCreateThemeFromUrl: handleCreateThemeFromUrl$1,
|
|
70572
|
+
handleApplyTheme: handleApplyTheme$1,
|
|
69983
70573
|
};
|
|
69984
70574
|
|
|
69985
70575
|
/**
|
|
@@ -69989,7 +70579,7 @@ var toolHandlers = {
|
|
|
69989
70579
|
* Call registerDashboardTools() during app startup (before or after server start).
|
|
69990
70580
|
*/
|
|
69991
70581
|
|
|
69992
|
-
const { registerTool: registerTool$
|
|
70582
|
+
const { registerTool: registerTool$2 } = mcpDashServerController_1;
|
|
69993
70583
|
const { dashboardTools } = toolDefinitions;
|
|
69994
70584
|
const {
|
|
69995
70585
|
handleListDashboards,
|
|
@@ -70000,7 +70590,7 @@ const {
|
|
|
70000
70590
|
} = toolHandlers;
|
|
70001
70591
|
|
|
70002
70592
|
// Map tool names to handler functions
|
|
70003
|
-
const handlerMap$
|
|
70593
|
+
const handlerMap$2 = {
|
|
70004
70594
|
list_dashboards: handleListDashboards,
|
|
70005
70595
|
get_dashboard: handleGetDashboard,
|
|
70006
70596
|
create_dashboard: handleCreateDashboard,
|
|
@@ -70013,12 +70603,12 @@ const handlerMap$1 = {
|
|
|
70013
70603
|
*/
|
|
70014
70604
|
function registerDashboardTools$1() {
|
|
70015
70605
|
for (const tool of dashboardTools) {
|
|
70016
|
-
const handler = handlerMap$
|
|
70606
|
+
const handler = handlerMap$2[tool.name];
|
|
70017
70607
|
if (!handler) {
|
|
70018
70608
|
console.warn(`[dashboardTools] No handler found for tool: ${tool.name}`);
|
|
70019
70609
|
continue;
|
|
70020
70610
|
}
|
|
70021
|
-
registerTool$
|
|
70611
|
+
registerTool$2({
|
|
70022
70612
|
name: tool.name,
|
|
70023
70613
|
description: tool.description,
|
|
70024
70614
|
inputSchema: tool.inputSchema,
|
|
@@ -70039,7 +70629,7 @@ var dashboardTools_1 = { registerDashboardTools: registerDashboardTools$1 };
|
|
|
70039
70629
|
* Call registerWidgetTools() during app startup (before or after server start).
|
|
70040
70630
|
*/
|
|
70041
70631
|
|
|
70042
|
-
const { registerTool } = mcpDashServerController_1;
|
|
70632
|
+
const { registerTool: registerTool$1 } = mcpDashServerController_1;
|
|
70043
70633
|
const { widgetTools } = toolDefinitions;
|
|
70044
70634
|
const {
|
|
70045
70635
|
handleAddWidget,
|
|
@@ -70050,7 +70640,7 @@ const {
|
|
|
70050
70640
|
} = toolHandlers;
|
|
70051
70641
|
|
|
70052
70642
|
// Map tool names to handler functions
|
|
70053
|
-
const handlerMap = {
|
|
70643
|
+
const handlerMap$1 = {
|
|
70054
70644
|
add_widget: handleAddWidget,
|
|
70055
70645
|
remove_widget: handleRemoveWidget,
|
|
70056
70646
|
configure_widget: handleConfigureWidget,
|
|
@@ -70063,12 +70653,12 @@ const handlerMap = {
|
|
|
70063
70653
|
*/
|
|
70064
70654
|
function registerWidgetTools$1() {
|
|
70065
70655
|
for (const tool of widgetTools) {
|
|
70066
|
-
const handler = handlerMap[tool.name];
|
|
70656
|
+
const handler = handlerMap$1[tool.name];
|
|
70067
70657
|
if (!handler) {
|
|
70068
70658
|
console.warn(`[widgetTools] No handler found for tool: ${tool.name}`);
|
|
70069
70659
|
continue;
|
|
70070
70660
|
}
|
|
70071
|
-
registerTool({
|
|
70661
|
+
registerTool$1({
|
|
70072
70662
|
name: tool.name,
|
|
70073
70663
|
description: tool.description,
|
|
70074
70664
|
inputSchema: tool.inputSchema,
|
|
@@ -70080,6 +70670,54 @@ function registerWidgetTools$1() {
|
|
|
70080
70670
|
|
|
70081
70671
|
var widgetTools_1 = { registerWidgetTools: registerWidgetTools$1 };
|
|
70082
70672
|
|
|
70673
|
+
/**
|
|
70674
|
+
* themeTools.js
|
|
70675
|
+
*
|
|
70676
|
+
* Registers theme MCP tools with the MCP Dash server.
|
|
70677
|
+
* Call registerThemeTools() during app startup (before or after server start).
|
|
70678
|
+
*/
|
|
70679
|
+
|
|
70680
|
+
const { registerTool } = mcpDashServerController_1;
|
|
70681
|
+
const { themeTools } = toolDefinitions;
|
|
70682
|
+
const {
|
|
70683
|
+
handleListThemes,
|
|
70684
|
+
handleGetTheme,
|
|
70685
|
+
handleCreateTheme,
|
|
70686
|
+
handleCreateThemeFromUrl,
|
|
70687
|
+
handleApplyTheme,
|
|
70688
|
+
} = toolHandlers;
|
|
70689
|
+
|
|
70690
|
+
// Map tool names to handler functions
|
|
70691
|
+
const handlerMap = {
|
|
70692
|
+
list_themes: handleListThemes,
|
|
70693
|
+
get_theme: handleGetTheme,
|
|
70694
|
+
create_theme: handleCreateTheme,
|
|
70695
|
+
create_theme_from_url: handleCreateThemeFromUrl,
|
|
70696
|
+
apply_theme: handleApplyTheme,
|
|
70697
|
+
};
|
|
70698
|
+
|
|
70699
|
+
/**
|
|
70700
|
+
* Register all theme tools with the MCP server controller.
|
|
70701
|
+
*/
|
|
70702
|
+
function registerThemeTools$1() {
|
|
70703
|
+
for (const tool of themeTools) {
|
|
70704
|
+
const handler = handlerMap[tool.name];
|
|
70705
|
+
if (!handler) {
|
|
70706
|
+
console.warn(`[themeTools] No handler found for tool: ${tool.name}`);
|
|
70707
|
+
continue;
|
|
70708
|
+
}
|
|
70709
|
+
registerTool({
|
|
70710
|
+
name: tool.name,
|
|
70711
|
+
description: tool.description,
|
|
70712
|
+
inputSchema: tool.inputSchema,
|
|
70713
|
+
handler,
|
|
70714
|
+
});
|
|
70715
|
+
}
|
|
70716
|
+
console.log(`[themeTools] Registered ${themeTools.length} theme tools`);
|
|
70717
|
+
}
|
|
70718
|
+
|
|
70719
|
+
var themeTools_1 = { registerThemeTools: registerThemeTools$1 };
|
|
70720
|
+
|
|
70083
70721
|
/**
|
|
70084
70722
|
* dashboardRatingsApi.js
|
|
70085
70723
|
*
|
|
@@ -70403,8 +71041,10 @@ const dynamicWidgetLoader = dynamicWidgetLoaderExports;
|
|
|
70403
71041
|
// --- MCP Dash Server Tools ---
|
|
70404
71042
|
const { registerDashboardTools } = dashboardTools_1;
|
|
70405
71043
|
const { registerWidgetTools } = widgetTools_1;
|
|
71044
|
+
const { registerThemeTools } = themeTools_1;
|
|
70406
71045
|
registerDashboardTools();
|
|
70407
71046
|
registerWidgetTools();
|
|
71047
|
+
registerThemeTools();
|
|
70408
71048
|
|
|
70409
71049
|
// --- Schema ---
|
|
70410
71050
|
const dashboardConfigValidator = dashboardConfigValidator$1;
|
|
@@ -70501,6 +71141,7 @@ var electron = {
|
|
|
70501
71141
|
// MCP Dash Server Tools
|
|
70502
71142
|
registerDashboardTools,
|
|
70503
71143
|
registerWidgetTools,
|
|
71144
|
+
registerThemeTools,
|
|
70504
71145
|
};
|
|
70505
71146
|
|
|
70506
71147
|
var index = /*@__PURE__*/getDefaultExportFromCjs(electron);
|