@trops/dash-core 0.1.61 → 0.1.63

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.
@@ -4464,6 +4464,7 @@ function requireProviderController () {
4464
4464
  * @param {object} credentials credentials object
4465
4465
  * @param {string} providerClass "credential" (default) or "mcp"
4466
4466
  * @param {object} mcpConfig MCP server config (transport, command, args, envMapping) - only for providerClass "mcp"
4467
+ * @param {string[]|null} allowedTools optional list of allowed tool names - only for providerClass "mcp"
4467
4468
  */
4468
4469
  saveProvider: (
4469
4470
  win,
@@ -4473,6 +4474,7 @@ function requireProviderController () {
4473
4474
  credentials,
4474
4475
  providerClass = "credential",
4475
4476
  mcpConfig = null,
4477
+ allowedTools = null,
4476
4478
  ) => {
4477
4479
  try {
4478
4480
  // Build file path
@@ -4508,6 +4510,11 @@ function requireProviderController () {
4508
4510
  providerEntry.mcpConfig = mcpConfig;
4509
4511
  }
4510
4512
 
4513
+ // Add allowedTools for MCP providers
4514
+ if (providerClass === "mcp" && allowedTools) {
4515
+ providerEntry.allowedTools = allowedTools;
4516
+ }
4517
+
4511
4518
  providers[providerName] = providerEntry;
4512
4519
 
4513
4520
  // Save to file with restrictive permissions (owner read/write only)
@@ -4580,6 +4587,11 @@ function requireProviderController () {
4580
4587
  provider.mcpConfig = data.mcpConfig;
4581
4588
  }
4582
4589
 
4590
+ // Include allowedTools for MCP providers
4591
+ if (data.allowedTools) {
4592
+ provider.allowedTools = data.allowedTools;
4593
+ }
4594
+
4583
4595
  decryptedProviders.push(provider);
4584
4596
  } catch (decryptError) {
4585
4597
  console.error(
@@ -4652,6 +4664,11 @@ function requireProviderController () {
4652
4664
  provider.mcpConfig = providerData.mcpConfig;
4653
4665
  }
4654
4666
 
4667
+ // Include allowedTools for MCP providers
4668
+ if (providerData.allowedTools) {
4669
+ provider.allowedTools = providerData.allowedTools;
4670
+ }
4671
+
4655
4672
  console.log(`[providerController] Provider retrieved: ${providerName}`);
4656
4673
 
4657
4674
  // Return the data for ipcMain.handle() - modern promise-based approach
@@ -4827,18 +4844,43 @@ const fs$5 = require$$2;
4827
4844
  */
4828
4845
  let _shellPath$1 = null;
4829
4846
 
4847
+ /**
4848
+ * Check if a Node.js major version is compatible (v18, v20, or v22).
4849
+ * Node v24+ has stricter ESM resolution that breaks some MCP packages.
4850
+ */
4851
+ function isCompatibleNodeVersion(majorVersion) {
4852
+ return majorVersion >= 18 && majorVersion <= 22;
4853
+ }
4854
+
4855
+ /**
4856
+ * Detect if an error message indicates Node v24+ ESM incompatibility.
4857
+ */
4858
+ function isNodeEsmError(errorText) {
4859
+ if (!errorText) return false;
4860
+ return (
4861
+ errorText.includes("ERR_PACKAGE_PATH_NOT_EXPORTED") ||
4862
+ errorText.includes("ERR_MODULE_NOT_FOUND")
4863
+ );
4864
+ }
4865
+
4830
4866
  /**
4831
4867
  * Get the user's full shell PATH (including nvm, homebrew, volta, etc.).
4832
4868
  * Electron GUI apps on macOS don't inherit the shell PATH, so we
4833
4869
  * resolve it once by invoking a login shell.
4870
+ *
4871
+ * On systems where Node v24+ is the default, this will prefer a compatible
4872
+ * nvm-managed Node version (v18/v20/v22) to avoid ESM resolution errors
4873
+ * in MCP packages.
4834
4874
  */
4835
4875
  function getShellPath$1() {
4836
4876
  if (_shellPath$1 !== null) return _shellPath$1;
4837
4877
 
4878
+ const { execSync } = require$$5$2;
4838
4879
  const fallbackDirs = ["/usr/local/bin", "/opt/homebrew/bin"];
4839
4880
 
4840
- // Add nvm/volta/nodenv paths if available
4881
+ // Scan nvm versions, tracking both latest and best compatible version
4841
4882
  const home = process.env.HOME || "";
4883
+ let compatibleNvmBin = null;
4842
4884
  if (home) {
4843
4885
  fallbackDirs.push(`${home}/.volta/bin`);
4844
4886
  fallbackDirs.push(`${home}/.nodenv/shims`);
@@ -4846,13 +4888,21 @@ function getShellPath$1() {
4846
4888
  const nvmDir = `${home}/.nvm/versions/node`;
4847
4889
  const versions = fs$5.readdirSync(nvmDir).sort();
4848
4890
  if (versions.length > 0) {
4891
+ // Find the highest compatible version (v18/v20/v22)
4892
+ for (let i = versions.length - 1; i >= 0; i--) {
4893
+ const match = versions[i].match(/^v(\d+)/);
4894
+ if (match && isCompatibleNodeVersion(parseInt(match[1], 10))) {
4895
+ compatibleNvmBin = `${nvmDir}/${versions[i]}/bin`;
4896
+ break;
4897
+ }
4898
+ }
4899
+ // Always add the latest nvm version as fallback
4849
4900
  fallbackDirs.push(`${nvmDir}/${versions[versions.length - 1]}/bin`);
4850
4901
  }
4851
4902
  } catch {}
4852
4903
  }
4853
4904
 
4854
4905
  try {
4855
- const { execSync } = require("child_process");
4856
4906
  const shell = process.env.SHELL || "/bin/bash";
4857
4907
  _shellPath$1 = execSync(`${shell} -ilc 'echo -n "$PATH"'`, {
4858
4908
  encoding: "utf8",
@@ -4871,6 +4921,24 @@ function getShellPath$1() {
4871
4921
  }
4872
4922
  }
4873
4923
 
4924
+ // If system Node is v24+, prepend compatible nvm version so it's found first
4925
+ if (compatibleNvmBin) {
4926
+ try {
4927
+ const nodeVersion = execSync(
4928
+ `PATH="${_shellPath$1}" node --version 2>/dev/null`,
4929
+ { encoding: "utf8", timeout: 5000 },
4930
+ ).trim();
4931
+ const majorMatch = nodeVersion.match(/^v(\d+)/);
4932
+ if (majorMatch && !isCompatibleNodeVersion(parseInt(majorMatch[1], 10))) {
4933
+ console.log(
4934
+ `[mcpController] System Node is ${nodeVersion} (incompatible), ` +
4935
+ `prepending compatible nvm path: ${compatibleNvmBin}`,
4936
+ );
4937
+ _shellPath$1 = `${compatibleNvmBin}:${_shellPath$1}`;
4938
+ }
4939
+ } catch {}
4940
+ }
4941
+
4874
4942
  console.log("[mcpController] Resolved PATH:", _shellPath$1);
4875
4943
  return _shellPath$1;
4876
4944
  }
@@ -5073,6 +5141,14 @@ const mcpController$2 = {
5073
5141
  error,
5074
5142
  );
5075
5143
 
5144
+ // Detect Node v24+ ESM compatibility errors and provide actionable message
5145
+ let errorMessage = error.message;
5146
+ if (isNodeEsmError(error.message)) {
5147
+ errorMessage =
5148
+ "This MCP server is incompatible with your system Node.js version. " +
5149
+ "Install Node.js v22 (LTS) using nvm and restart the app.";
5150
+ }
5151
+
5076
5152
  // Mark as error state
5077
5153
  activeServers.set(serverName, {
5078
5154
  client: null,
@@ -5080,12 +5156,12 @@ const mcpController$2 = {
5080
5156
  tools: [],
5081
5157
  resources: [],
5082
5158
  status: STATUS.ERROR,
5083
- error: error.message,
5159
+ error: errorMessage,
5084
5160
  });
5085
5161
 
5086
5162
  return {
5087
5163
  error: true,
5088
- message: error.message,
5164
+ message: errorMessage,
5089
5165
  serverName,
5090
5166
  status: STATUS.ERROR,
5091
5167
  };
@@ -5469,6 +5545,16 @@ const mcpController$2 = {
5469
5545
  resolve({ success: true });
5470
5546
  } else {
5471
5547
  const detail = stderr.trim() || stdout.trim() || "";
5548
+ // Detect Node v24+ ESM compatibility errors and provide actionable message
5549
+ if (isNodeEsmError(detail)) {
5550
+ resolve({
5551
+ error: true,
5552
+ message:
5553
+ "This MCP server is incompatible with your system Node.js version. " +
5554
+ "Install Node.js v22 (LTS) using nvm and restart the app.",
5555
+ });
5556
+ return;
5557
+ }
5472
5558
  resolve({
5473
5559
  error: true,
5474
5560
  message: `Auth exited with code ${code}${detail ? ": " + detail : ""}`,
@@ -7934,6 +8020,7 @@ const providerApi$2 = {
7934
8020
  * @param {Object} credentials - credentials object (shape depends on provider type)
7935
8021
  * @param {String} providerClass - "credential" (default) or "mcp"
7936
8022
  * @param {Object} mcpConfig - MCP server config (only for providerClass "mcp")
8023
+ * @param {String[]|null} allowedTools - optional list of allowed tool names (MCP only)
7937
8024
  * @returns {Promise}
7938
8025
  */
7939
8026
  saveProvider: (
@@ -7943,6 +8030,7 @@ const providerApi$2 = {
7943
8030
  credentials,
7944
8031
  providerClass = "credential",
7945
8032
  mcpConfig = null,
8033
+ allowedTools = null,
7946
8034
  ) =>
7947
8035
  ipcRenderer$a.invoke(PROVIDER_SAVE, {
7948
8036
  appId,
@@ -7951,6 +8039,7 @@ const providerApi$2 = {
7951
8039
  credentials,
7952
8040
  providerClass,
7953
8041
  mcpConfig,
8042
+ allowedTools,
7954
8043
  }),
7955
8044
 
7956
8045
  /**