@trops/dash-core 0.1.46 → 0.1.48

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.
@@ -22,6 +22,7 @@ var require$$2$4 = require('algoliasearch');
22
22
  var require$$3$2 = require('node:path');
23
23
  var require$$0$3 = require('openai');
24
24
  require('live-plugin-manager');
25
+ var require$$0$4 = require('@anthropic-ai/sdk');
25
26
  var require$$2$6 = require('os');
26
27
  var require$$3$3 = require('adm-zip');
27
28
  var require$$4$1 = require('url');
@@ -513,6 +514,36 @@ var openaiEvents$1 = {
513
514
  OPENAI_DESCRIBE_IMAGE_ERROR,
514
515
  };
515
516
 
517
+ /**
518
+ * Event Constants File - LLM Events
519
+ *
520
+ * This file contains event constants for LLM (Large Language Model)
521
+ * chat IPC communication — streaming, tool-use, and lifecycle.
522
+ */
523
+
524
+ // --- Renderer → Main (invoke) ---
525
+ const LLM_SEND_MESSAGE$1 = "llm-send-message";
526
+ const LLM_ABORT_REQUEST$1 = "llm-abort-request";
527
+ const LLM_LIST_CONNECTED_TOOLS$1 = "llm-list-connected-tools";
528
+
529
+ // --- Main → Renderer (send) ---
530
+ const LLM_STREAM_DELTA$2 = "llm-stream-delta";
531
+ const LLM_STREAM_TOOL_CALL$2 = "llm-stream-tool-call";
532
+ const LLM_STREAM_TOOL_RESULT$2 = "llm-stream-tool-result";
533
+ const LLM_STREAM_COMPLETE$2 = "llm-stream-complete";
534
+ const LLM_STREAM_ERROR$2 = "llm-stream-error";
535
+
536
+ var llmEvents$1 = {
537
+ LLM_SEND_MESSAGE: LLM_SEND_MESSAGE$1,
538
+ LLM_ABORT_REQUEST: LLM_ABORT_REQUEST$1,
539
+ LLM_LIST_CONNECTED_TOOLS: LLM_LIST_CONNECTED_TOOLS$1,
540
+ LLM_STREAM_DELTA: LLM_STREAM_DELTA$2,
541
+ LLM_STREAM_TOOL_CALL: LLM_STREAM_TOOL_CALL$2,
542
+ LLM_STREAM_TOOL_RESULT: LLM_STREAM_TOOL_RESULT$2,
543
+ LLM_STREAM_COMPLETE: LLM_STREAM_COMPLETE$2,
544
+ LLM_STREAM_ERROR: LLM_STREAM_ERROR$2,
545
+ };
546
+
516
547
  /**
517
548
  * Event Constants File - Client Cache Events
518
549
  *
@@ -550,6 +581,7 @@ const registryEvents = registryEvents$1;
550
581
  const algoliaEvents = algoliaEvents$1;
551
582
  const menuItemEvents = menuItemEvents$1;
552
583
  const openaiEvents = openaiEvents$1;
584
+ const llmEvents = llmEvents$1;
553
585
  const clientCacheEvents = clientCacheEvents$1;
554
586
 
555
587
  const publicEvents = {
@@ -571,6 +603,7 @@ var events$8 = {
571
603
  ...algoliaEvents,
572
604
  ...menuItemEvents,
573
605
  ...openaiEvents,
606
+ ...llmEvents,
574
607
  ...clientCacheEvents,
575
608
  };
576
609
 
@@ -4773,6 +4806,33 @@ const {
4773
4806
  const path$6 = require$$1$1;
4774
4807
  const fs$5 = require$$2;
4775
4808
 
4809
+ /**
4810
+ * Cached shell PATH result (resolved once, reused for all spawns).
4811
+ */
4812
+ let _shellPath = null;
4813
+
4814
+ /**
4815
+ * Get the user's full shell PATH (including nvm, homebrew, volta, etc.).
4816
+ * Electron GUI apps on macOS don't inherit the shell PATH, so we
4817
+ * resolve it once by invoking a login shell.
4818
+ */
4819
+ function getShellPath() {
4820
+ if (_shellPath !== null) return _shellPath;
4821
+
4822
+ try {
4823
+ const { execSync } = require("child_process");
4824
+ const shell = process.env.SHELL || "/bin/bash";
4825
+ _shellPath = execSync(`${shell} -ilc 'echo -n "$PATH"'`, {
4826
+ encoding: "utf8",
4827
+ timeout: 5000,
4828
+ });
4829
+ } catch {
4830
+ _shellPath = process.env.PATH || "";
4831
+ }
4832
+
4833
+ return _shellPath;
4834
+ }
4835
+
4776
4836
  /**
4777
4837
  * Active MCP server connections
4778
4838
  * Map<string, { client: Client, transport: Transport, tools: Array, status: string }>
@@ -4812,7 +4872,7 @@ function interpolate(template, credentials) {
4812
4872
  });
4813
4873
  }
4814
4874
 
4815
- const mcpController$1 = {
4875
+ const mcpController$2 = {
4816
4876
  /**
4817
4877
  * startServer
4818
4878
  * Start an MCP server with the given config and credentials
@@ -4850,7 +4910,7 @@ const mcpController$1 = {
4850
4910
  try {
4851
4911
  // Stop if in stale/error state
4852
4912
  if (activeServers.has(serverName)) {
4853
- await mcpController$1.stopServer(win, serverName);
4913
+ await mcpController$2.stopServer(win, serverName);
4854
4914
  }
4855
4915
 
4856
4916
  console.log(
@@ -4886,6 +4946,9 @@ const mcpController$1 = {
4886
4946
  } else {
4887
4947
  // stdio transport (default) - spawn a local child process
4888
4948
  const env = { ...process.env };
4949
+ // Ensure full shell PATH is available (Electron GUI apps
4950
+ // on macOS don't inherit nvm/homebrew paths)
4951
+ env.PATH = getShellPath();
4889
4952
  if (mcpConfig.envMapping && credentials) {
4890
4953
  Object.entries(mcpConfig.envMapping).forEach(
4891
4954
  ([envVar, credentialKey]) => {
@@ -5283,6 +5346,28 @@ const mcpController$1 = {
5283
5346
  }
5284
5347
  },
5285
5348
 
5349
+ /**
5350
+ * listConnectedServers
5351
+ * Returns all connected servers with their cached tool lists.
5352
+ * Used by llmController to discover available MCP tools.
5353
+ *
5354
+ * @returns {Array<{ serverName, tools, resources, status }>}
5355
+ */
5356
+ listConnectedServers: () => {
5357
+ const servers = [];
5358
+ for (const [serverName, server] of activeServers) {
5359
+ if (server.status === STATUS.CONNECTED) {
5360
+ servers.push({
5361
+ serverName,
5362
+ tools: server.tools || [],
5363
+ resources: server.resources || [],
5364
+ status: server.status,
5365
+ });
5366
+ }
5367
+ }
5368
+ return servers;
5369
+ },
5370
+
5286
5371
  /**
5287
5372
  * stopAllServers
5288
5373
  * Stop all running MCP servers (called on app quit)
@@ -5298,14 +5383,14 @@ const mcpController$1 = {
5298
5383
  );
5299
5384
  const promises = [];
5300
5385
  for (const [serverName] of activeServers) {
5301
- promises.push(mcpController$1.stopServer(null, serverName));
5386
+ promises.push(mcpController$2.stopServer(null, serverName));
5302
5387
  }
5303
5388
  await Promise.allSettled(promises);
5304
5389
  console.log("[mcpController] All servers stopped");
5305
5390
  },
5306
5391
  };
5307
5392
 
5308
- var mcpController_1 = mcpController$1;
5393
+ var mcpController_1 = mcpController$2;
5309
5394
 
5310
5395
  /**
5311
5396
  * registryController.js
@@ -6232,6 +6317,316 @@ const pluginController$1 = {
6232
6317
 
6233
6318
  var pluginController_1 = pluginController$1;
6234
6319
 
6320
+ /**
6321
+ * llmController.js
6322
+ *
6323
+ * Manages LLM chat interactions in the main process.
6324
+ * Streams responses from Anthropic's Messages API, handles tool-use loops
6325
+ * by calling MCP tools via mcpController, and supports request cancellation.
6326
+ *
6327
+ * Conversation state lives in the renderer — this controller is stateless
6328
+ * per-request, receiving the full messages array each time.
6329
+ */
6330
+
6331
+ const Anthropic = require$$0$4;
6332
+ const mcpController$1 = mcpController_1;
6333
+ const {
6334
+ LLM_STREAM_DELTA: LLM_STREAM_DELTA$1,
6335
+ LLM_STREAM_TOOL_CALL: LLM_STREAM_TOOL_CALL$1,
6336
+ LLM_STREAM_TOOL_RESULT: LLM_STREAM_TOOL_RESULT$1,
6337
+ LLM_STREAM_COMPLETE: LLM_STREAM_COMPLETE$1,
6338
+ LLM_STREAM_ERROR: LLM_STREAM_ERROR$1,
6339
+ } = llmEvents$1;
6340
+
6341
+ /**
6342
+ * In-flight requests for cancellation support.
6343
+ * Map<requestId, AbortController>
6344
+ */
6345
+ const activeRequests = new Map();
6346
+
6347
+ /**
6348
+ * Default maximum tool-use rounds to prevent infinite loops.
6349
+ */
6350
+ const DEFAULT_MAX_TOOL_ROUNDS = 10;
6351
+
6352
+ /**
6353
+ * Convert MCP tool format to Anthropic tool format.
6354
+ * MCP: { name, description, inputSchema }
6355
+ * Anthropic: { name, description, input_schema }
6356
+ */
6357
+ function mcpToolToAnthropic(tool) {
6358
+ return {
6359
+ name: tool.name,
6360
+ description: tool.description || "",
6361
+ input_schema: tool.inputSchema || { type: "object", properties: {} },
6362
+ };
6363
+ }
6364
+
6365
+ /**
6366
+ * Extract text content from an MCP tool result.
6367
+ * MCP results can be { content: [{ type: "text", text: "..." }] } or plain strings.
6368
+ */
6369
+ function extractToolResultText(mcpResult) {
6370
+ if (!mcpResult) return "No result returned.";
6371
+ if (mcpResult.error) return `Error: ${mcpResult.message}`;
6372
+
6373
+ const result = mcpResult.result;
6374
+ if (!result) return "No result returned.";
6375
+
6376
+ // MCP standard: { content: [{ type, text }] }
6377
+ if (result.content && Array.isArray(result.content)) {
6378
+ return result.content
6379
+ .filter((c) => c.type === "text")
6380
+ .map((c) => c.text)
6381
+ .join("\n");
6382
+ }
6383
+
6384
+ // Plain string
6385
+ if (typeof result === "string") return result;
6386
+
6387
+ // Fallback: JSON stringify
6388
+ return JSON.stringify(result);
6389
+ }
6390
+
6391
+ const llmController$1 = {
6392
+ /**
6393
+ * sendMessage
6394
+ * Stream a response from the Anthropic Messages API with tool-use support.
6395
+ *
6396
+ * @param {BrowserWindow} win - the window to send stream events to
6397
+ * @param {string} requestId - unique ID for this request (for filtering + cancellation)
6398
+ * @param {object} params - { apiKey, model, messages, tools, toolServerMap, systemPrompt, maxToolRounds }
6399
+ */
6400
+ sendMessage: async (win, requestId, params) => {
6401
+ const {
6402
+ apiKey,
6403
+ model = "claude-sonnet-4-20250514",
6404
+ messages,
6405
+ tools = [],
6406
+ toolServerMap = {},
6407
+ systemPrompt,
6408
+ maxToolRounds = DEFAULT_MAX_TOOL_ROUNDS,
6409
+ } = params;
6410
+
6411
+ // Set up abort controller
6412
+ const abortController = new AbortController();
6413
+ activeRequests.set(requestId, abortController);
6414
+
6415
+ try {
6416
+ if (!apiKey) {
6417
+ throw new Error(
6418
+ "API key is required. Add an Anthropic provider in your dashboard settings.",
6419
+ );
6420
+ }
6421
+
6422
+ const client = new Anthropic({ apiKey });
6423
+
6424
+ // Convert MCP tools to Anthropic format
6425
+ const anthropicTools = tools.map(mcpToolToAnthropic);
6426
+
6427
+ // Build the conversation — mutable copy for tool-use loop
6428
+ let currentMessages = [...messages];
6429
+ let toolRound = 0;
6430
+
6431
+ while (toolRound <= maxToolRounds) {
6432
+ // Check for abort before each API call
6433
+ if (abortController.signal.aborted) {
6434
+ return;
6435
+ }
6436
+
6437
+ // Build request params
6438
+ const requestParams = {
6439
+ model,
6440
+ max_tokens: 8192,
6441
+ messages: currentMessages,
6442
+ stream: true,
6443
+ };
6444
+ if (systemPrompt) {
6445
+ requestParams.system = systemPrompt;
6446
+ }
6447
+ if (anthropicTools.length > 0) {
6448
+ requestParams.tools = anthropicTools;
6449
+ }
6450
+
6451
+ // Stream the response
6452
+ const stream = client.messages.stream(requestParams, {
6453
+ signal: abortController.signal,
6454
+ });
6455
+
6456
+ let responseContentBlocks = [];
6457
+ let stopReason = null;
6458
+
6459
+ // Collect text deltas and content blocks
6460
+ stream.on("text", (text) => {
6461
+ if (win && !win.isDestroyed()) {
6462
+ win.webContents.send(LLM_STREAM_DELTA$1, { requestId, text });
6463
+ }
6464
+ });
6465
+
6466
+ // Wait for the full message
6467
+ const finalMessage = await stream.finalMessage();
6468
+ responseContentBlocks = finalMessage.content;
6469
+ stopReason = finalMessage.stop_reason;
6470
+
6471
+ // Check for tool use
6472
+ const toolUseBlocks = responseContentBlocks.filter(
6473
+ (block) => block.type === "tool_use",
6474
+ );
6475
+
6476
+ if (stopReason === "end_turn" || toolUseBlocks.length === 0) {
6477
+ // Done — send complete event
6478
+ if (win && !win.isDestroyed()) {
6479
+ win.webContents.send(LLM_STREAM_COMPLETE$1, {
6480
+ requestId,
6481
+ content: responseContentBlocks,
6482
+ stopReason,
6483
+ usage: finalMessage.usage,
6484
+ });
6485
+ }
6486
+ return;
6487
+ }
6488
+
6489
+ // Tool use round
6490
+ toolRound++;
6491
+
6492
+ // Append assistant message with tool_use blocks
6493
+ currentMessages.push({
6494
+ role: "assistant",
6495
+ content: responseContentBlocks,
6496
+ });
6497
+
6498
+ // Execute each tool call
6499
+ const toolResults = [];
6500
+ for (const toolBlock of toolUseBlocks) {
6501
+ if (abortController.signal.aborted) return;
6502
+
6503
+ const serverName = toolServerMap[toolBlock.name];
6504
+
6505
+ // Notify renderer of tool call
6506
+ if (win && !win.isDestroyed()) {
6507
+ win.webContents.send(LLM_STREAM_TOOL_CALL$1, {
6508
+ requestId,
6509
+ toolUseId: toolBlock.id,
6510
+ toolName: toolBlock.name,
6511
+ serverName,
6512
+ input: toolBlock.input,
6513
+ });
6514
+ }
6515
+
6516
+ let resultText;
6517
+ let isError = false;
6518
+
6519
+ if (!serverName) {
6520
+ resultText = `Error: No MCP server found for tool "${toolBlock.name}". The server may have disconnected.`;
6521
+ isError = true;
6522
+ } else {
6523
+ try {
6524
+ const mcpResult = await mcpController$1.callTool(
6525
+ win,
6526
+ serverName,
6527
+ toolBlock.name,
6528
+ toolBlock.input,
6529
+ );
6530
+ if (mcpResult.error) {
6531
+ resultText = `Error: ${mcpResult.message}`;
6532
+ isError = true;
6533
+ } else {
6534
+ resultText = extractToolResultText(mcpResult);
6535
+ }
6536
+ } catch (err) {
6537
+ resultText = `Error calling tool: ${err.message}`;
6538
+ isError = true;
6539
+ }
6540
+ }
6541
+
6542
+ // Notify renderer of tool result
6543
+ if (win && !win.isDestroyed()) {
6544
+ win.webContents.send(LLM_STREAM_TOOL_RESULT$1, {
6545
+ requestId,
6546
+ toolUseId: toolBlock.id,
6547
+ toolName: toolBlock.name,
6548
+ result: resultText,
6549
+ isError,
6550
+ });
6551
+ }
6552
+
6553
+ toolResults.push({
6554
+ type: "tool_result",
6555
+ tool_use_id: toolBlock.id,
6556
+ content: resultText,
6557
+ is_error: isError,
6558
+ });
6559
+ }
6560
+
6561
+ // Append tool results as user message
6562
+ currentMessages.push({
6563
+ role: "user",
6564
+ content: toolResults,
6565
+ });
6566
+
6567
+ // Loop continues — next API call with tool results
6568
+ }
6569
+
6570
+ // Exceeded max tool rounds
6571
+ if (win && !win.isDestroyed()) {
6572
+ win.webContents.send(LLM_STREAM_ERROR$1, {
6573
+ requestId,
6574
+ error: `Exceeded maximum tool-use rounds (${maxToolRounds}). The assistant may be stuck in a loop.`,
6575
+ code: "MAX_TOOL_ROUNDS",
6576
+ });
6577
+ }
6578
+ } catch (error) {
6579
+ if (abortController.signal.aborted) {
6580
+ // Request was cancelled — not an error
6581
+ return;
6582
+ }
6583
+
6584
+ console.error(`[llmController] Error in sendMessage:`, error);
6585
+
6586
+ const errorPayload = {
6587
+ requestId,
6588
+ error: error.message || "Unknown error",
6589
+ code: error.status || error.code || "UNKNOWN",
6590
+ };
6591
+
6592
+ // Handle rate limiting
6593
+ if (error.status === 429) {
6594
+ errorPayload.code = "RATE_LIMITED";
6595
+ const retryAfter = error.headers?.["retry-after"];
6596
+ if (retryAfter) {
6597
+ errorPayload.retryAfter = parseInt(retryAfter, 10);
6598
+ }
6599
+ }
6600
+
6601
+ if (win && !win.isDestroyed()) {
6602
+ win.webContents.send(LLM_STREAM_ERROR$1, errorPayload);
6603
+ }
6604
+ } finally {
6605
+ activeRequests.delete(requestId);
6606
+ }
6607
+ },
6608
+
6609
+ /**
6610
+ * abortRequest
6611
+ * Cancel an in-flight LLM request.
6612
+ *
6613
+ * @param {BrowserWindow} win - the window (unused but kept for API consistency)
6614
+ * @param {string} requestId - the request to cancel
6615
+ * @returns {{ success: boolean }}
6616
+ */
6617
+ abortRequest: (win, requestId) => {
6618
+ const controller = activeRequests.get(requestId);
6619
+ if (controller) {
6620
+ controller.abort();
6621
+ activeRequests.delete(requestId);
6622
+ return { success: true };
6623
+ }
6624
+ return { success: false, message: "Request not found" };
6625
+ },
6626
+ };
6627
+
6628
+ var llmController_1 = llmController$1;
6629
+
6235
6630
  /**
6236
6631
  * clientFactories.js
6237
6632
  *
@@ -6362,7 +6757,7 @@ var controller = {
6362
6757
  searchIndex,
6363
6758
  };
6364
6759
 
6365
- const { ipcRenderer: ipcRenderer$g } = require$$0;
6760
+ const { ipcRenderer: ipcRenderer$h } = require$$0;
6366
6761
  const {
6367
6762
  SECURE_STORE_ENCRYPTION_CHECK,
6368
6763
  SECURE_STORE_SET_DATA,
@@ -6374,10 +6769,10 @@ const {
6374
6769
  */
6375
6770
  const secureStoreApi$2 = {
6376
6771
  isEncryptionAvailable: () =>
6377
- ipcRenderer$g.invoke(SECURE_STORE_ENCRYPTION_CHECK, {}),
6772
+ ipcRenderer$h.invoke(SECURE_STORE_ENCRYPTION_CHECK, {}),
6378
6773
  saveData: (key, value) =>
6379
- ipcRenderer$g.invoke(SECURE_STORE_SET_DATA, { key, value }),
6380
- getData: (key) => ipcRenderer$g.invoke(SECURE_STORE_GET_DATA, { key }),
6774
+ ipcRenderer$h.invoke(SECURE_STORE_SET_DATA, { key, value }),
6775
+ getData: (key) => ipcRenderer$h.invoke(SECURE_STORE_GET_DATA, { key }),
6381
6776
  };
6382
6777
 
6383
6778
  var secureStoreApi_1 = secureStoreApi$2;
@@ -6388,7 +6783,7 @@ var secureStoreApi_1 = secureStoreApi$2;
6388
6783
  * Handle the workspace configuration file
6389
6784
  */
6390
6785
 
6391
- const { ipcRenderer: ipcRenderer$f } = require$$0;
6786
+ const { ipcRenderer: ipcRenderer$g } = require$$0;
6392
6787
  const {
6393
6788
  WORKSPACE_LIST,
6394
6789
  WORKSPACE_SAVE,
@@ -6405,7 +6800,7 @@ const workspaceApi$2 = {
6405
6800
  */
6406
6801
  listWorkspacesForApplication: (appId) => {
6407
6802
  console.log("listWorkspacesForApplication called with appId:", appId);
6408
- return ipcRenderer$f.invoke(WORKSPACE_LIST, { appId });
6803
+ return ipcRenderer$g.invoke(WORKSPACE_LIST, { appId });
6409
6804
  },
6410
6805
 
6411
6806
  /**
@@ -6416,7 +6811,7 @@ const workspaceApi$2 = {
6416
6811
  * @returns
6417
6812
  */
6418
6813
  saveWorkspaceForApplication: (appId, data) =>
6419
- ipcRenderer$f.invoke(WORKSPACE_SAVE, { appId, data }),
6814
+ ipcRenderer$g.invoke(WORKSPACE_SAVE, { appId, data }),
6420
6815
 
6421
6816
  /**
6422
6817
  * deleteWorkspaceForApplication
@@ -6426,7 +6821,7 @@ const workspaceApi$2 = {
6426
6821
  * @returns
6427
6822
  */
6428
6823
  deleteWorkspaceForApplication: (appId, workspaceId) =>
6429
- ipcRenderer$f.invoke(WORKSPACE_DELETE, { appId, workspaceId }),
6824
+ ipcRenderer$g.invoke(WORKSPACE_DELETE, { appId, workspaceId }),
6430
6825
  };
6431
6826
 
6432
6827
  var workspaceApi_1 = workspaceApi$2;
@@ -6438,15 +6833,15 @@ var workspaceApi_1 = workspaceApi$2;
6438
6833
  */
6439
6834
 
6440
6835
  // ipcRenderer that must be used to invoke the events
6441
- const { ipcRenderer: ipcRenderer$e } = require$$0;
6836
+ const { ipcRenderer: ipcRenderer$f } = require$$0;
6442
6837
 
6443
6838
  const { LAYOUT_LIST, LAYOUT_SAVE } = events$8;
6444
6839
 
6445
6840
  const layoutApi$2 = {
6446
6841
  listLayoutsForApplication: (appId) =>
6447
- ipcRenderer$e.invoke(LAYOUT_LIST, { appId }),
6842
+ ipcRenderer$f.invoke(LAYOUT_LIST, { appId }),
6448
6843
  saveLayoutForApplication: (appId, data) =>
6449
- ipcRenderer$e.invoke(LAYOUT_SAVE, { appId, data }),
6844
+ ipcRenderer$f.invoke(LAYOUT_SAVE, { appId, data }),
6450
6845
  };
6451
6846
 
6452
6847
  var layoutApi_1 = layoutApi$2;
@@ -6458,7 +6853,7 @@ var layoutApi_1 = layoutApi$2;
6458
6853
  */
6459
6854
 
6460
6855
  // ipcRenderer that must be used to invoke the events
6461
- const { ipcRenderer: ipcRenderer$d } = require$$0;
6856
+ const { ipcRenderer: ipcRenderer$e } = require$$0;
6462
6857
 
6463
6858
  const {
6464
6859
  DATA_JSON_TO_CSV_FILE,
@@ -6477,7 +6872,7 @@ const {
6477
6872
  const dataApi$2 = {
6478
6873
  // convert a json array of objects to a csv string and save to file
6479
6874
  convertJsonToCsvFile: (appId, jsonObject, filename) =>
6480
- ipcRenderer$d.invoke(DATA_JSON_TO_CSV_FILE, {
6875
+ ipcRenderer$e.invoke(DATA_JSON_TO_CSV_FILE, {
6481
6876
  appId,
6482
6877
  jsonObject,
6483
6878
  filename,
@@ -6485,10 +6880,10 @@ const dataApi$2 = {
6485
6880
 
6486
6881
  // convert a json array of objects to a csv string and return a string
6487
6882
  convertJsonToCsvString: (appId, jsonObject) =>
6488
- ipcRenderer$d.invoke(DATA_JSON_TO_CSV_STRING, { appId, jsonObject }),
6883
+ ipcRenderer$e.invoke(DATA_JSON_TO_CSV_STRING, { appId, jsonObject }),
6489
6884
 
6490
6885
  parseXMLStream: (filepath, outpath, start) =>
6491
- ipcRenderer$d.invoke(PARSE_XML_STREAM, {
6886
+ ipcRenderer$e.invoke(PARSE_XML_STREAM, {
6492
6887
  filepath,
6493
6888
  outpath,
6494
6889
  start,
@@ -6502,7 +6897,7 @@ const dataApi$2 = {
6502
6897
  headers = null,
6503
6898
  limit = null,
6504
6899
  ) => {
6505
- ipcRenderer$d.invoke(PARSE_CSV_STREAM, {
6900
+ ipcRenderer$e.invoke(PARSE_CSV_STREAM, {
6506
6901
  filepath,
6507
6902
  outpath,
6508
6903
  delimiter,
@@ -6513,15 +6908,15 @@ const dataApi$2 = {
6513
6908
  },
6514
6909
 
6515
6910
  readLinesFromFile: (filepath, lineCount) => {
6516
- ipcRenderer$d.invoke(READ_LINES, { filepath, lineCount });
6911
+ ipcRenderer$e.invoke(READ_LINES, { filepath, lineCount });
6517
6912
  },
6518
6913
 
6519
6914
  readJSONFromFile: (filepath, objectCount = null) => {
6520
- ipcRenderer$d.invoke(READ_JSON, { filepath, objectCount });
6915
+ ipcRenderer$e.invoke(READ_JSON, { filepath, objectCount });
6521
6916
  },
6522
6917
 
6523
6918
  readDataFromURL: (url, toFilepath) => {
6524
- ipcRenderer$d.invoke(READ_DATA_URL, { url, toFilepath });
6919
+ ipcRenderer$e.invoke(READ_DATA_URL, { url, toFilepath });
6525
6920
  },
6526
6921
 
6527
6922
  /*
@@ -6530,7 +6925,7 @@ const dataApi$2 = {
6530
6925
  * @param {object} returnEmpty the return empty object
6531
6926
  */
6532
6927
  saveData: (data, filename, append, returnEmpty, uuid) =>
6533
- ipcRenderer$d.invoke(DATA_SAVE_TO_FILE, {
6928
+ ipcRenderer$e.invoke(DATA_SAVE_TO_FILE, {
6534
6929
  data,
6535
6930
  filename,
6536
6931
  append,
@@ -6542,14 +6937,14 @@ const dataApi$2 = {
6542
6937
  * @param {string} filename the filename to read (not path)
6543
6938
  */
6544
6939
  readData: (filename, returnEmpty = []) =>
6545
- ipcRenderer$d.invoke(DATA_READ_FROM_FILE, { filename, returnEmpty }),
6940
+ ipcRenderer$e.invoke(DATA_READ_FROM_FILE, { filename, returnEmpty }),
6546
6941
 
6547
6942
  /**
6548
6943
  * transformFile
6549
6944
  * @returns
6550
6945
  */
6551
6946
  transformFile: (filepath, outFilepath, mappingFunctionBody, args) => {
6552
- ipcRenderer$d.invoke(TRANSFORM_FILE, {
6947
+ ipcRenderer$e.invoke(TRANSFORM_FILE, {
6553
6948
  filepath,
6554
6949
  outFilepath,
6555
6950
  mappingFunctionBody,
@@ -6558,7 +6953,7 @@ const dataApi$2 = {
6558
6953
  },
6559
6954
 
6560
6955
  extractColorsFromImageURL: (url) => {
6561
- ipcRenderer$d.invoke(EXTRACT_COLORS_FROM_IMAGE, {
6956
+ ipcRenderer$e.invoke(EXTRACT_COLORS_FROM_IMAGE, {
6562
6957
  url,
6563
6958
  });
6564
6959
  },
@@ -6573,7 +6968,7 @@ var dataApi_1 = dataApi$2;
6573
6968
  */
6574
6969
 
6575
6970
  // ipcRenderer that must be used to invoke the events
6576
- const { ipcRenderer: ipcRenderer$c } = require$$0;
6971
+ const { ipcRenderer: ipcRenderer$d } = require$$0;
6577
6972
 
6578
6973
  const {
6579
6974
  SETTINGS_GET,
@@ -6584,14 +6979,14 @@ const {
6584
6979
  } = events$8;
6585
6980
 
6586
6981
  const settingsApi$2 = {
6587
- getSettingsForApplication: () => ipcRenderer$c.invoke(SETTINGS_GET, {}),
6982
+ getSettingsForApplication: () => ipcRenderer$d.invoke(SETTINGS_GET, {}),
6588
6983
  saveSettingsForApplication: (data) =>
6589
- ipcRenderer$c.invoke(SETTINGS_SAVE, { data }),
6590
- getDataDirectory: () => ipcRenderer$c.invoke(SETTINGS_GET_DATA_DIR, {}),
6984
+ ipcRenderer$d.invoke(SETTINGS_SAVE, { data }),
6985
+ getDataDirectory: () => ipcRenderer$d.invoke(SETTINGS_GET_DATA_DIR, {}),
6591
6986
  setDataDirectory: (dataDirectory) =>
6592
- ipcRenderer$c.invoke(SETTINGS_SET_DATA_DIR, { dataDirectory }),
6987
+ ipcRenderer$d.invoke(SETTINGS_SET_DATA_DIR, { dataDirectory }),
6593
6988
  migrateDataDirectory: (oldDirectory, newDirectory) =>
6594
- ipcRenderer$c.invoke(SETTINGS_MIGRATE_DATA_DIR, {
6989
+ ipcRenderer$d.invoke(SETTINGS_MIGRATE_DATA_DIR, {
6595
6990
  oldDirectory,
6596
6991
  newDirectory,
6597
6992
  }),
@@ -6606,7 +7001,7 @@ var settingsApi_1 = settingsApi$2;
6606
7001
  */
6607
7002
 
6608
7003
  // ipcRenderer that must be used to invoke the events
6609
- const { ipcRenderer: ipcRenderer$b } = require$$0;
7004
+ const { ipcRenderer: ipcRenderer$c } = require$$0;
6610
7005
 
6611
7006
  const { CHOOSE_FILE } = events$8;
6612
7007
 
@@ -6618,7 +7013,7 @@ const dialogApi$2 = {
6618
7013
  */
6619
7014
  chooseFile: (allowFile = true, extensions = ["*"]) => {
6620
7015
  console.log("dialog api choose file");
6621
- return ipcRenderer$b.invoke(CHOOSE_FILE, { allowFile, extensions });
7016
+ return ipcRenderer$c.invoke(CHOOSE_FILE, { allowFile, extensions });
6622
7017
  },
6623
7018
  };
6624
7019
 
@@ -6637,7 +7032,7 @@ var dialogApi_1 = dialogApi$2;
6637
7032
  * mainApi.widgets.uninstall('Weather')
6638
7033
  */
6639
7034
 
6640
- const { ipcRenderer: ipcRenderer$a } = require$$0;
7035
+ const { ipcRenderer: ipcRenderer$b } = require$$0;
6641
7036
 
6642
7037
  const widgetApi$2 = {
6643
7038
  /**
@@ -6646,7 +7041,7 @@ const widgetApi$2 = {
6646
7041
  */
6647
7042
  list: async () => {
6648
7043
  try {
6649
- return await ipcRenderer$a.invoke("widget:list");
7044
+ return await ipcRenderer$b.invoke("widget:list");
6650
7045
  } catch (error) {
6651
7046
  console.error("[WidgetApi] Error listing widgets:", error);
6652
7047
  throw error;
@@ -6660,7 +7055,7 @@ const widgetApi$2 = {
6660
7055
  */
6661
7056
  get: async (widgetName) => {
6662
7057
  try {
6663
- return await ipcRenderer$a.invoke("widget:get", widgetName);
7058
+ return await ipcRenderer$b.invoke("widget:get", widgetName);
6664
7059
  } catch (error) {
6665
7060
  console.error(`[WidgetApi] Error getting widget ${widgetName}:`, error);
6666
7061
  throw error;
@@ -6691,7 +7086,7 @@ const widgetApi$2 = {
6691
7086
  console.log(
6692
7087
  `[WidgetApi] Installing widget: ${widgetName} from ${downloadUrl}`,
6693
7088
  );
6694
- const config = await ipcRenderer$a.invoke(
7089
+ const config = await ipcRenderer$b.invoke(
6695
7090
  "widget:install",
6696
7091
  widgetName,
6697
7092
  downloadUrl,
@@ -6731,7 +7126,7 @@ const widgetApi$2 = {
6731
7126
  console.log(
6732
7127
  `[WidgetApi] Installing local widget: ${widgetName} from ${localPath}`,
6733
7128
  );
6734
- const config = await ipcRenderer$a.invoke(
7129
+ const config = await ipcRenderer$b.invoke(
6735
7130
  "widget:install-local",
6736
7131
  widgetName,
6737
7132
  localPath,
@@ -6762,7 +7157,7 @@ const widgetApi$2 = {
6762
7157
  loadFolder: async (folderPath) => {
6763
7158
  try {
6764
7159
  console.log(`[WidgetApi] Loading widgets from folder: ${folderPath}`);
6765
- const results = await ipcRenderer$a.invoke(
7160
+ const results = await ipcRenderer$b.invoke(
6766
7161
  "widget:load-folder",
6767
7162
  folderPath,
6768
7163
  );
@@ -6786,7 +7181,7 @@ const widgetApi$2 = {
6786
7181
  uninstall: async (widgetName) => {
6787
7182
  try {
6788
7183
  console.log(`[WidgetApi] Uninstalling widget: ${widgetName}`);
6789
- const success = await ipcRenderer$a.invoke("widget:uninstall", widgetName);
7184
+ const success = await ipcRenderer$b.invoke("widget:uninstall", widgetName);
6790
7185
  if (success) {
6791
7186
  console.log(`[WidgetApi] ✓ Widget ${widgetName} uninstalled`);
6792
7187
  } else {
@@ -6809,7 +7204,7 @@ const widgetApi$2 = {
6809
7204
  */
6810
7205
  getCachePath: async () => {
6811
7206
  try {
6812
- return await ipcRenderer$a.invoke("widget:cache-path");
7207
+ return await ipcRenderer$b.invoke("widget:cache-path");
6813
7208
  } catch (error) {
6814
7209
  console.error("[WidgetApi] Error getting cache path:", error);
6815
7210
  throw error;
@@ -6823,7 +7218,7 @@ const widgetApi$2 = {
6823
7218
  */
6824
7219
  getStoragePath: async () => {
6825
7220
  try {
6826
- return await ipcRenderer$a.invoke("widget:storage-path");
7221
+ return await ipcRenderer$b.invoke("widget:storage-path");
6827
7222
  } catch (error) {
6828
7223
  console.error("[WidgetApi] Error getting storage path:", error);
6829
7224
  throw error;
@@ -6840,7 +7235,7 @@ const widgetApi$2 = {
6840
7235
  setStoragePath: async (customPath) => {
6841
7236
  try {
6842
7237
  console.log(`[WidgetApi] Setting storage path to: ${customPath}`);
6843
- const result = await ipcRenderer$a.invoke(
7238
+ const result = await ipcRenderer$b.invoke(
6844
7239
  "widget:set-storage-path",
6845
7240
  customPath,
6846
7241
  );
@@ -6862,7 +7257,7 @@ const widgetApi$2 = {
6862
7257
  */
6863
7258
  getComponentConfigs: async () => {
6864
7259
  try {
6865
- return await ipcRenderer$a.invoke("widget:get-component-configs");
7260
+ return await ipcRenderer$b.invoke("widget:get-component-configs");
6866
7261
  } catch (error) {
6867
7262
  console.error("[WidgetApi] Error getting component configs:", error);
6868
7263
  return [];
@@ -6877,7 +7272,7 @@ const widgetApi$2 = {
6877
7272
  */
6878
7273
  readBundle: async (widgetName) => {
6879
7274
  try {
6880
- return await ipcRenderer$a.invoke("widget:read-bundle", widgetName);
7275
+ return await ipcRenderer$b.invoke("widget:read-bundle", widgetName);
6881
7276
  } catch (error) {
6882
7277
  console.error(
6883
7278
  `[WidgetApi] Error reading bundle for ${widgetName}:`,
@@ -6894,7 +7289,7 @@ const widgetApi$2 = {
6894
7289
  */
6895
7290
  readAllBundles: async () => {
6896
7291
  try {
6897
- return await ipcRenderer$a.invoke("widget:read-all-bundles");
7292
+ return await ipcRenderer$b.invoke("widget:read-all-bundles");
6898
7293
  } catch (error) {
6899
7294
  console.error("[WidgetApi] Error reading all bundles:", error);
6900
7295
  return [];
@@ -6914,7 +7309,7 @@ const widgetApi$2 = {
6914
7309
  * });
6915
7310
  */
6916
7311
  onInstalled: (callback) => {
6917
- ipcRenderer$a.on("widget:installed", (event, data) => {
7312
+ ipcRenderer$b.on("widget:installed", (event, data) => {
6918
7313
  callback(data);
6919
7314
  });
6920
7315
  },
@@ -6932,7 +7327,7 @@ const widgetApi$2 = {
6932
7327
  * });
6933
7328
  */
6934
7329
  onLoaded: (callback) => {
6935
- ipcRenderer$a.on("widgets:loaded", (event, data) => {
7330
+ ipcRenderer$b.on("widgets:loaded", (event, data) => {
6936
7331
  callback(data);
6937
7332
  });
6938
7333
  },
@@ -6943,7 +7338,7 @@ const widgetApi$2 = {
6943
7338
  * @param {Function} callback - The callback to remove
6944
7339
  */
6945
7340
  removeInstalledListener: (callback) => {
6946
- ipcRenderer$a.removeListener("widget:installed", callback);
7341
+ ipcRenderer$b.removeListener("widget:installed", callback);
6947
7342
  },
6948
7343
 
6949
7344
  /**
@@ -6952,7 +7347,7 @@ const widgetApi$2 = {
6952
7347
  * @param {Function} callback - The callback to remove
6953
7348
  */
6954
7349
  removeLoadedListener: (callback) => {
6955
- ipcRenderer$a.removeListener("widgets:loaded", callback);
7350
+ ipcRenderer$b.removeListener("widgets:loaded", callback);
6956
7351
  },
6957
7352
  };
6958
7353
 
@@ -6965,7 +7360,7 @@ var widgetApi_1 = widgetApi$2;
6965
7360
  * Communicates with main process via IPC to handle encryption and file storage
6966
7361
  */
6967
7362
 
6968
- const { ipcRenderer: ipcRenderer$9 } = require$$0;
7363
+ const { ipcRenderer: ipcRenderer$a } = require$$0;
6969
7364
  const {
6970
7365
  PROVIDER_SAVE,
6971
7366
  PROVIDER_LIST,
@@ -6995,7 +7390,7 @@ const providerApi$2 = {
6995
7390
  providerClass = "credential",
6996
7391
  mcpConfig = null,
6997
7392
  ) =>
6998
- ipcRenderer$9.invoke(PROVIDER_SAVE, {
7393
+ ipcRenderer$a.invoke(PROVIDER_SAVE, {
6999
7394
  appId,
7000
7395
  providerName,
7001
7396
  providerType,
@@ -7012,7 +7407,7 @@ const providerApi$2 = {
7012
7407
  * @param {String} appId - the appId specified in the dash initialization
7013
7408
  * @returns {Promise<Array>} Array of provider objects with name, type, credentials
7014
7409
  */
7015
- listProviders: (appId) => ipcRenderer$9.invoke(PROVIDER_LIST, { appId }),
7410
+ listProviders: (appId) => ipcRenderer$a.invoke(PROVIDER_LIST, { appId }),
7016
7411
 
7017
7412
  /**
7018
7413
  * getProvider
@@ -7024,7 +7419,7 @@ const providerApi$2 = {
7024
7419
  * @returns {Promise<Object>} Provider object with name, type, credentials
7025
7420
  */
7026
7421
  getProvider: (appId, providerName) =>
7027
- ipcRenderer$9.invoke(PROVIDER_GET, { appId, providerName }),
7422
+ ipcRenderer$a.invoke(PROVIDER_GET, { appId, providerName }),
7028
7423
 
7029
7424
  /**
7030
7425
  * deleteProvider
@@ -7036,7 +7431,7 @@ const providerApi$2 = {
7036
7431
  * @returns {Promise}
7037
7432
  */
7038
7433
  deleteProvider: (appId, providerName) =>
7039
- ipcRenderer$9.invoke(PROVIDER_DELETE, { appId, providerName }),
7434
+ ipcRenderer$a.invoke(PROVIDER_DELETE, { appId, providerName }),
7040
7435
 
7041
7436
  /**
7042
7437
  * listProvidersForApplication
@@ -7046,14 +7441,14 @@ const providerApi$2 = {
7046
7441
  * @param {String} appId - the appId specified in the dash initialization
7047
7442
  */
7048
7443
  listProvidersForApplication: (appId) => {
7049
- ipcRenderer$9
7444
+ ipcRenderer$a
7050
7445
  .invoke(PROVIDER_LIST, { appId })
7051
7446
  .then((result) => {
7052
7447
  // Emit the event for ElectronDashboardApi to listen to
7053
- ipcRenderer$9.send("PROVIDER_LIST_COMPLETE", result);
7448
+ ipcRenderer$a.send("PROVIDER_LIST_COMPLETE", result);
7054
7449
  })
7055
7450
  .catch((error) => {
7056
- ipcRenderer$9.send("PROVIDER_LIST_ERROR", {
7451
+ ipcRenderer$a.send("PROVIDER_LIST_ERROR", {
7057
7452
  error: error.message,
7058
7453
  });
7059
7454
  });
@@ -7070,7 +7465,7 @@ const providerApi$2 = {
7070
7465
  providerType,
7071
7466
  credentials,
7072
7467
  ) => {
7073
- ipcRenderer$9
7468
+ ipcRenderer$a
7074
7469
  .invoke(PROVIDER_SAVE, {
7075
7470
  appId,
7076
7471
  providerName,
@@ -7078,10 +7473,10 @@ const providerApi$2 = {
7078
7473
  credentials,
7079
7474
  })
7080
7475
  .then((result) => {
7081
- ipcRenderer$9.send("PROVIDER_SAVE_COMPLETE", result);
7476
+ ipcRenderer$a.send("PROVIDER_SAVE_COMPLETE", result);
7082
7477
  })
7083
7478
  .catch((error) => {
7084
- ipcRenderer$9.send("PROVIDER_SAVE_ERROR", {
7479
+ ipcRenderer$a.send("PROVIDER_SAVE_ERROR", {
7085
7480
  error: error.message,
7086
7481
  });
7087
7482
  });
@@ -7093,13 +7488,13 @@ const providerApi$2 = {
7093
7488
  * Event-listener-based version for use with ElectronDashboardApi
7094
7489
  */
7095
7490
  getProviderForApplication: (appId, providerName) => {
7096
- ipcRenderer$9
7491
+ ipcRenderer$a
7097
7492
  .invoke(PROVIDER_GET, { appId, providerName })
7098
7493
  .then((result) => {
7099
- ipcRenderer$9.send("PROVIDER_GET_COMPLETE", result);
7494
+ ipcRenderer$a.send("PROVIDER_GET_COMPLETE", result);
7100
7495
  })
7101
7496
  .catch((error) => {
7102
- ipcRenderer$9.send("PROVIDER_GET_ERROR", {
7497
+ ipcRenderer$a.send("PROVIDER_GET_ERROR", {
7103
7498
  error: error.message,
7104
7499
  });
7105
7500
  });
@@ -7111,13 +7506,13 @@ const providerApi$2 = {
7111
7506
  * Event-listener-based version for use with ElectronDashboardApi
7112
7507
  */
7113
7508
  deleteProviderForApplication: (appId, providerName) => {
7114
- ipcRenderer$9
7509
+ ipcRenderer$a
7115
7510
  .invoke(PROVIDER_DELETE, { appId, providerName })
7116
7511
  .then((result) => {
7117
- ipcRenderer$9.send("PROVIDER_DELETE_COMPLETE", result);
7512
+ ipcRenderer$a.send("PROVIDER_DELETE_COMPLETE", result);
7118
7513
  })
7119
7514
  .catch((error) => {
7120
- ipcRenderer$9.send("PROVIDER_DELETE_ERROR", {
7515
+ ipcRenderer$a.send("PROVIDER_DELETE_ERROR", {
7121
7516
  error: error.message,
7122
7517
  });
7123
7518
  });
@@ -7133,7 +7528,7 @@ var providerApi_1 = providerApi$2;
7133
7528
  * Communicates with main process via IPC to manage MCP server lifecycle.
7134
7529
  */
7135
7530
 
7136
- const { ipcRenderer: ipcRenderer$8 } = require$$0;
7531
+ const { ipcRenderer: ipcRenderer$9 } = require$$0;
7137
7532
  const {
7138
7533
  MCP_START_SERVER,
7139
7534
  MCP_STOP_SERVER,
@@ -7156,7 +7551,7 @@ const mcpApi$2 = {
7156
7551
  * @returns {Promise<{ success, serverName, tools, status } | { error, message }>}
7157
7552
  */
7158
7553
  startServer: (serverName, mcpConfig, credentials) =>
7159
- ipcRenderer$8.invoke(MCP_START_SERVER, {
7554
+ ipcRenderer$9.invoke(MCP_START_SERVER, {
7160
7555
  serverName,
7161
7556
  mcpConfig,
7162
7557
  credentials,
@@ -7170,7 +7565,7 @@ const mcpApi$2 = {
7170
7565
  * @returns {Promise<{ success, serverName } | { error, message }>}
7171
7566
  */
7172
7567
  stopServer: (serverName) =>
7173
- ipcRenderer$8.invoke(MCP_STOP_SERVER, { serverName }),
7568
+ ipcRenderer$9.invoke(MCP_STOP_SERVER, { serverName }),
7174
7569
 
7175
7570
  /**
7176
7571
  * listTools
@@ -7179,7 +7574,7 @@ const mcpApi$2 = {
7179
7574
  * @param {string} serverName the server name
7180
7575
  * @returns {Promise<{ tools } | { error, message }>}
7181
7576
  */
7182
- listTools: (serverName) => ipcRenderer$8.invoke(MCP_LIST_TOOLS, { serverName }),
7577
+ listTools: (serverName) => ipcRenderer$9.invoke(MCP_LIST_TOOLS, { serverName }),
7183
7578
 
7184
7579
  /**
7185
7580
  * callTool
@@ -7192,7 +7587,7 @@ const mcpApi$2 = {
7192
7587
  * @returns {Promise<{ result } | { error, message }>}
7193
7588
  */
7194
7589
  callTool: (serverName, toolName, args, allowedTools = null) =>
7195
- ipcRenderer$8.invoke(MCP_CALL_TOOL, {
7590
+ ipcRenderer$9.invoke(MCP_CALL_TOOL, {
7196
7591
  serverName,
7197
7592
  toolName,
7198
7593
  args,
@@ -7207,7 +7602,7 @@ const mcpApi$2 = {
7207
7602
  * @returns {Promise<{ resources } | { error, message }>}
7208
7603
  */
7209
7604
  listResources: (serverName) =>
7210
- ipcRenderer$8.invoke(MCP_LIST_RESOURCES, { serverName }),
7605
+ ipcRenderer$9.invoke(MCP_LIST_RESOURCES, { serverName }),
7211
7606
 
7212
7607
  /**
7213
7608
  * readResource
@@ -7218,7 +7613,7 @@ const mcpApi$2 = {
7218
7613
  * @returns {Promise<{ resource } | { error, message }>}
7219
7614
  */
7220
7615
  readResource: (serverName, uri) =>
7221
- ipcRenderer$8.invoke(MCP_READ_RESOURCE, { serverName, uri }),
7616
+ ipcRenderer$9.invoke(MCP_READ_RESOURCE, { serverName, uri }),
7222
7617
 
7223
7618
  /**
7224
7619
  * getServerStatus
@@ -7228,7 +7623,7 @@ const mcpApi$2 = {
7228
7623
  * @returns {Promise<{ status, tools, error }>}
7229
7624
  */
7230
7625
  getServerStatus: (serverName) =>
7231
- ipcRenderer$8.invoke(MCP_SERVER_STATUS, { serverName }),
7626
+ ipcRenderer$9.invoke(MCP_SERVER_STATUS, { serverName }),
7232
7627
 
7233
7628
  /**
7234
7629
  * getCatalog
@@ -7236,7 +7631,7 @@ const mcpApi$2 = {
7236
7631
  *
7237
7632
  * @returns {Promise<{ catalog } | { error, message }>}
7238
7633
  */
7239
- getCatalog: () => ipcRenderer$8.invoke(MCP_GET_CATALOG),
7634
+ getCatalog: () => ipcRenderer$9.invoke(MCP_GET_CATALOG),
7240
7635
  };
7241
7636
 
7242
7637
  var mcpApi_1 = mcpApi$2;
@@ -7254,7 +7649,7 @@ var mcpApi_1 = mcpApi$2;
7254
7649
  * mainApi.registry.checkUpdates([{ name: "weather-widgets", version: "1.0.0" }])
7255
7650
  */
7256
7651
 
7257
- const { ipcRenderer: ipcRenderer$7 } = require$$0;
7652
+ const { ipcRenderer: ipcRenderer$8 } = require$$0;
7258
7653
 
7259
7654
  const registryApi$2 = {
7260
7655
  /**
@@ -7264,7 +7659,7 @@ const registryApi$2 = {
7264
7659
  */
7265
7660
  fetchIndex: async (forceRefresh = false) => {
7266
7661
  try {
7267
- return await ipcRenderer$7.invoke("registry:fetch-index", forceRefresh);
7662
+ return await ipcRenderer$8.invoke("registry:fetch-index", forceRefresh);
7268
7663
  } catch (error) {
7269
7664
  console.error("[RegistryApi] Error fetching index:", error);
7270
7665
  throw error;
@@ -7279,7 +7674,7 @@ const registryApi$2 = {
7279
7674
  */
7280
7675
  search: async (query = "", filters = {}) => {
7281
7676
  try {
7282
- return await ipcRenderer$7.invoke("registry:search", query, filters);
7677
+ return await ipcRenderer$8.invoke("registry:search", query, filters);
7283
7678
  } catch (error) {
7284
7679
  console.error("[RegistryApi] Error searching registry:", error);
7285
7680
  throw error;
@@ -7293,7 +7688,7 @@ const registryApi$2 = {
7293
7688
  */
7294
7689
  getPackage: async (packageName) => {
7295
7690
  try {
7296
- return await ipcRenderer$7.invoke("registry:get-package", packageName);
7691
+ return await ipcRenderer$8.invoke("registry:get-package", packageName);
7297
7692
  } catch (error) {
7298
7693
  console.error(
7299
7694
  `[RegistryApi] Error getting package ${packageName}:`,
@@ -7310,7 +7705,7 @@ const registryApi$2 = {
7310
7705
  */
7311
7706
  checkUpdates: async (installedWidgets = []) => {
7312
7707
  try {
7313
- return await ipcRenderer$7.invoke(
7708
+ return await ipcRenderer$8.invoke(
7314
7709
  "registry:check-updates",
7315
7710
  installedWidgets,
7316
7711
  );
@@ -7329,17 +7724,17 @@ var registryApi_1 = registryApi$2;
7329
7724
  * Handle the theme configuration file
7330
7725
  */
7331
7726
 
7332
- const { ipcRenderer: ipcRenderer$6 } = require$$0;
7727
+ const { ipcRenderer: ipcRenderer$7 } = require$$0;
7333
7728
 
7334
7729
  const { THEME_LIST, THEME_SAVE, THEME_DELETE } = events$8;
7335
7730
 
7336
7731
  const themeApi$2 = {
7337
7732
  listThemesForApplication: (appId) =>
7338
- ipcRenderer$6.invoke(THEME_LIST, { appId }),
7733
+ ipcRenderer$7.invoke(THEME_LIST, { appId }),
7339
7734
  saveThemeForApplication: (appId, themeName, themeObject) =>
7340
- ipcRenderer$6.invoke(THEME_SAVE, { appId, themeName, themeObject }),
7735
+ ipcRenderer$7.invoke(THEME_SAVE, { appId, themeName, themeObject }),
7341
7736
  deleteThemeForApplication: (appId, themeKey) =>
7342
- ipcRenderer$6.invoke(THEME_DELETE, { appId, themeKey }),
7737
+ ipcRenderer$7.invoke(THEME_DELETE, { appId, themeKey }),
7343
7738
  };
7344
7739
 
7345
7740
  var themeApi_1 = themeApi$2;
@@ -7351,7 +7746,7 @@ var themeApi_1 = themeApi$2;
7351
7746
  */
7352
7747
 
7353
7748
  // ipcRenderer that must be used to invoke the events
7354
- const { ipcRenderer: ipcRenderer$5 } = require$$0;
7749
+ const { ipcRenderer: ipcRenderer$6 } = require$$0;
7355
7750
 
7356
7751
  const {
7357
7752
  ALGOLIA_LIST_INDICES,
@@ -7365,10 +7760,10 @@ const {
7365
7760
 
7366
7761
  const algoliaApi$2 = {
7367
7762
  listIndices: (application) =>
7368
- ipcRenderer$5.invoke(ALGOLIA_LIST_INDICES, application),
7763
+ ipcRenderer$6.invoke(ALGOLIA_LIST_INDICES, application),
7369
7764
 
7370
7765
  browseObjects: (appId, apiKey, indexName) => {
7371
- ipcRenderer$5.invoke(ALGOLIA_BROWSE_OBJECTS, {
7766
+ ipcRenderer$6.invoke(ALGOLIA_BROWSE_OBJECTS, {
7372
7767
  appId,
7373
7768
  apiKey,
7374
7769
  indexName,
@@ -7376,10 +7771,10 @@ const algoliaApi$2 = {
7376
7771
  });
7377
7772
  },
7378
7773
 
7379
- saveSynonyms: () => ipcRenderer$5.invoke(ALGOLIA_SAVE_SYNONYMS, {}),
7774
+ saveSynonyms: () => ipcRenderer$6.invoke(ALGOLIA_SAVE_SYNONYMS, {}),
7380
7775
 
7381
7776
  getAnalyticsForQuery: (application, indexName, query) =>
7382
- ipcRenderer$5.invoke(ALGOLIA_ANALYTICS_FOR_QUERY, {
7777
+ ipcRenderer$6.invoke(ALGOLIA_ANALYTICS_FOR_QUERY, {
7383
7778
  application,
7384
7779
  indexName,
7385
7780
  query,
@@ -7392,7 +7787,7 @@ const algoliaApi$2 = {
7392
7787
  dir,
7393
7788
  createIfNotExists = false,
7394
7789
  ) =>
7395
- ipcRenderer$5.invoke(ALGOLIA_PARTIAL_UPDATE_OBJECTS, {
7790
+ ipcRenderer$6.invoke(ALGOLIA_PARTIAL_UPDATE_OBJECTS, {
7396
7791
  appId,
7397
7792
  apiKey,
7398
7793
  indexName,
@@ -7401,7 +7796,7 @@ const algoliaApi$2 = {
7401
7796
  }),
7402
7797
 
7403
7798
  createBatchesFromFile: (filepath, batchFilepath, batchSize) => {
7404
- ipcRenderer$5.invoke(ALGOLIA_CREATE_BATCH, {
7799
+ ipcRenderer$6.invoke(ALGOLIA_CREATE_BATCH, {
7405
7800
  filepath,
7406
7801
  batchFilepath,
7407
7802
  batchSize,
@@ -7409,7 +7804,7 @@ const algoliaApi$2 = {
7409
7804
  },
7410
7805
 
7411
7806
  browseObjectsToFile: (appId, apiKey, indexName, toFilename, query = "") => {
7412
- ipcRenderer$5.invoke(ALGOLIA_BROWSE_OBJECTS, {
7807
+ ipcRenderer$6.invoke(ALGOLIA_BROWSE_OBJECTS, {
7413
7808
  appId,
7414
7809
  apiKey,
7415
7810
  indexName,
@@ -7419,7 +7814,7 @@ const algoliaApi$2 = {
7419
7814
  },
7420
7815
 
7421
7816
  search: (appId, apiKey, indexName, query = "", options = {}) =>
7422
- ipcRenderer$5.invoke(ALGOLIA_SEARCH, {
7817
+ ipcRenderer$6.invoke(ALGOLIA_SEARCH, {
7423
7818
  appId,
7424
7819
  apiKey,
7425
7820
  indexName,
@@ -7434,14 +7829,14 @@ var algoliaApi_1 = algoliaApi$2;
7434
7829
  * openAI
7435
7830
  */
7436
7831
 
7437
- const { ipcRenderer: ipcRenderer$4 } = require$$0;
7832
+ const { ipcRenderer: ipcRenderer$5 } = require$$0;
7438
7833
 
7439
7834
  const { OPENAI_DESCRIBE_IMAGE } = openaiEvents$1;
7440
7835
 
7441
7836
  const openaiApi$2 = {
7442
7837
  // convert a json array of objects to a csv string and save to file
7443
7838
  describeImage: (imageUrl, apiKey, prompt = "What's in this image?") =>
7444
- ipcRenderer$4.invoke(OPENAI_DESCRIBE_IMAGE, { imageUrl, apiKey, prompt }),
7839
+ ipcRenderer$5.invoke(OPENAI_DESCRIBE_IMAGE, { imageUrl, apiKey, prompt }),
7445
7840
  };
7446
7841
 
7447
7842
  var openaiApi_1 = openaiApi$2;
@@ -7452,14 +7847,14 @@ var openaiApi_1 = openaiApi$2;
7452
7847
  */
7453
7848
 
7454
7849
  // ipcRenderer that must be used to invoke the events
7455
- const { ipcRenderer: ipcRenderer$3 } = require$$0;
7850
+ const { ipcRenderer: ipcRenderer$4 } = require$$0;
7456
7851
 
7457
7852
  const { MENU_ITEMS_SAVE, MENU_ITEMS_LIST } = events$8;
7458
7853
 
7459
7854
  const menuItemsApi$2 = {
7460
7855
  saveMenuItem: (appId, menuItem) =>
7461
- ipcRenderer$3.invoke(MENU_ITEMS_SAVE, { appId, menuItem }),
7462
- listMenuItems: (appId) => ipcRenderer$3.invoke(MENU_ITEMS_LIST, { appId }),
7856
+ ipcRenderer$4.invoke(MENU_ITEMS_SAVE, { appId, menuItem }),
7857
+ listMenuItems: (appId) => ipcRenderer$4.invoke(MENU_ITEMS_LIST, { appId }),
7463
7858
  };
7464
7859
 
7465
7860
  var menuItemsApi_1 = menuItemsApi$2;
@@ -7471,16 +7866,123 @@ var menuItemsApi_1 = menuItemsApi$2;
7471
7866
  */
7472
7867
 
7473
7868
  // ipcRenderer that must be used to invoke the events
7474
- const { ipcRenderer: ipcRenderer$2 } = require$$0;
7869
+ const { ipcRenderer: ipcRenderer$3 } = require$$0;
7475
7870
 
7476
7871
  const pluginApi$2 = {
7477
7872
  install: (packageName, filepath) =>
7478
- ipcRenderer$2.invoke("plugin-install", { packageName, filepath }),
7479
- uninstall: (filepath) => ipcRenderer$2.invoke("plugin-uninstall", filepath),
7873
+ ipcRenderer$3.invoke("plugin-install", { packageName, filepath }),
7874
+ uninstall: (filepath) => ipcRenderer$3.invoke("plugin-uninstall", filepath),
7480
7875
  };
7481
7876
 
7482
7877
  var pluginApi_1 = pluginApi$2;
7483
7878
 
7879
+ /**
7880
+ * llmApi.js
7881
+ *
7882
+ * Preload bridge for LLM chat operations.
7883
+ * Communicates with main process via IPC for streaming chat,
7884
+ * tool-use events, and request cancellation.
7885
+ */
7886
+
7887
+ const { ipcRenderer: ipcRenderer$2 } = require$$0;
7888
+ const {
7889
+ LLM_SEND_MESSAGE,
7890
+ LLM_ABORT_REQUEST,
7891
+ LLM_LIST_CONNECTED_TOOLS,
7892
+ LLM_STREAM_DELTA,
7893
+ LLM_STREAM_TOOL_CALL,
7894
+ LLM_STREAM_TOOL_RESULT,
7895
+ LLM_STREAM_COMPLETE,
7896
+ LLM_STREAM_ERROR,
7897
+ } = llmEvents$1;
7898
+
7899
+ const llmApi$2 = {
7900
+ /**
7901
+ * sendMessage
7902
+ * Start a streaming LLM request with optional tool-use.
7903
+ *
7904
+ * @param {string} requestId - unique ID for filtering stream events
7905
+ * @param {object} params - { apiKey, model, messages, tools, toolServerMap, systemPrompt, maxToolRounds }
7906
+ * @returns {Promise<void>}
7907
+ */
7908
+ sendMessage: (requestId, params) =>
7909
+ ipcRenderer$2.invoke(LLM_SEND_MESSAGE, { requestId, ...params }),
7910
+
7911
+ /**
7912
+ * abortRequest
7913
+ * Cancel an in-flight LLM request.
7914
+ *
7915
+ * @param {string} requestId - the request to cancel
7916
+ * @returns {Promise<{ success: boolean }>}
7917
+ */
7918
+ abortRequest: (requestId) =>
7919
+ ipcRenderer$2.invoke(LLM_ABORT_REQUEST, { requestId }),
7920
+
7921
+ /**
7922
+ * listConnectedTools
7923
+ * Get all tools from all connected MCP servers.
7924
+ *
7925
+ * @returns {Promise<Array<{ serverName, tools, resources, status }>>}
7926
+ */
7927
+ listConnectedTools: () => ipcRenderer$2.invoke(LLM_LIST_CONNECTED_TOOLS),
7928
+
7929
+ // --- Stream event listeners ---
7930
+
7931
+ /**
7932
+ * onStreamDelta
7933
+ * Listen for text chunks as they stream in.
7934
+ */
7935
+ onStreamDelta: (callback) => {
7936
+ ipcRenderer$2.on(LLM_STREAM_DELTA, (_event, data) => callback(data));
7937
+ },
7938
+
7939
+ /**
7940
+ * onStreamToolCall
7941
+ * Listen for tool call notifications.
7942
+ */
7943
+ onStreamToolCall: (callback) => {
7944
+ ipcRenderer$2.on(LLM_STREAM_TOOL_CALL, (_event, data) => callback(data));
7945
+ },
7946
+
7947
+ /**
7948
+ * onStreamToolResult
7949
+ * Listen for tool result notifications.
7950
+ */
7951
+ onStreamToolResult: (callback) => {
7952
+ ipcRenderer$2.on(LLM_STREAM_TOOL_RESULT, (_event, data) => callback(data));
7953
+ },
7954
+
7955
+ /**
7956
+ * onStreamComplete
7957
+ * Listen for stream completion (final response).
7958
+ */
7959
+ onStreamComplete: (callback) => {
7960
+ ipcRenderer$2.on(LLM_STREAM_COMPLETE, (_event, data) => callback(data));
7961
+ },
7962
+
7963
+ /**
7964
+ * onStreamError
7965
+ * Listen for stream errors.
7966
+ */
7967
+ onStreamError: (callback) => {
7968
+ ipcRenderer$2.on(LLM_STREAM_ERROR, (_event, data) => callback(data));
7969
+ },
7970
+
7971
+ /**
7972
+ * removeAllStreamListeners
7973
+ * Clean up all LLM stream listeners.
7974
+ */
7975
+ removeAllStreamListeners: () => {
7976
+ ipcRenderer$2.removeAllListeners(LLM_STREAM_DELTA);
7977
+ ipcRenderer$2.removeAllListeners(LLM_STREAM_TOOL_CALL);
7978
+ ipcRenderer$2.removeAllListeners(LLM_STREAM_TOOL_RESULT);
7979
+ ipcRenderer$2.removeAllListeners(LLM_STREAM_COMPLETE);
7980
+ ipcRenderer$2.removeAllListeners(LLM_STREAM_ERROR);
7981
+ },
7982
+ };
7983
+
7984
+ var llmApi_1 = llmApi$2;
7985
+
7484
7986
  /**
7485
7987
  * clientCacheApi.js
7486
7988
  *
@@ -8934,6 +9436,7 @@ const algoliaApi$1 = algoliaApi_1;
8934
9436
  const openaiApi$1 = openaiApi_1;
8935
9437
  const menuItemsApi$1 = menuItemsApi_1;
8936
9438
  const pluginApi$1 = pluginApi_1;
9439
+ const llmApi$1 = llmApi_1;
8937
9440
  const clientCacheApi$1 = clientCacheApi_1;
8938
9441
 
8939
9442
  // Events constants
@@ -8997,6 +9500,9 @@ function createMainApi$1(extensions = {}) {
8997
9500
 
8998
9501
  pathPlugins: "",
8999
9502
 
9503
+ // LLM
9504
+ llm: llmApi$1,
9505
+
9000
9506
  // APIs previously in template
9001
9507
  algolia: algoliaApi$1,
9002
9508
  openai: openaiApi$1,
@@ -9046,6 +9552,7 @@ const algoliaController = algoliaController_1;
9046
9552
  const openaiController = openaiController_1;
9047
9553
  const menuItemsController = menuItemsController_1;
9048
9554
  const pluginController = pluginController_1;
9555
+ const llmController = llmController_1;
9049
9556
 
9050
9557
  // --- Utils ---
9051
9558
  const clientCache = requireClientCache();
@@ -9071,6 +9578,7 @@ const algoliaApi = algoliaApi_1;
9071
9578
  const openaiApi = openaiApi_1;
9072
9579
  const menuItemsApi = menuItemsApi_1;
9073
9580
  const pluginApi = pluginApi_1;
9581
+ const llmApi = llmApi_1;
9074
9582
  const clientCacheApi = clientCacheApi_1;
9075
9583
 
9076
9584
  // --- Events ---
@@ -9100,6 +9608,7 @@ var electron = {
9100
9608
  openaiController,
9101
9609
  menuItemsController,
9102
9610
  pluginController,
9611
+ llmController,
9103
9612
 
9104
9613
  // Controller functions (flat) — spread for convenient destructuring
9105
9614
  ...controllers,
@@ -9120,6 +9629,7 @@ var electron = {
9120
9629
  openaiApi,
9121
9630
  menuItemsApi,
9122
9631
  pluginApi,
9632
+ llmApi,
9123
9633
  clientCacheApi,
9124
9634
 
9125
9635
  // Events