@trops/dash-core 0.1.50 → 0.1.52

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.
@@ -4828,6 +4828,25 @@ let _shellPath$1 = null;
4828
4828
  function getShellPath$1() {
4829
4829
  if (_shellPath$1 !== null) return _shellPath$1;
4830
4830
 
4831
+ const fallbackDirs = [
4832
+ "/usr/local/bin",
4833
+ "/opt/homebrew/bin",
4834
+ ];
4835
+
4836
+ // Add nvm/volta/nodenv paths if available
4837
+ const home = process.env.HOME || "";
4838
+ if (home) {
4839
+ fallbackDirs.push(`${home}/.volta/bin`);
4840
+ fallbackDirs.push(`${home}/.nodenv/shims`);
4841
+ try {
4842
+ const nvmDir = `${home}/.nvm/versions/node`;
4843
+ const versions = fs$5.readdirSync(nvmDir).sort();
4844
+ if (versions.length > 0) {
4845
+ fallbackDirs.push(`${nvmDir}/${versions[versions.length - 1]}/bin`);
4846
+ }
4847
+ } catch {}
4848
+ }
4849
+
4831
4850
  try {
4832
4851
  const { execSync } = require("child_process");
4833
4852
  const shell = process.env.SHELL || "/bin/bash";
@@ -4835,10 +4854,20 @@ function getShellPath$1() {
4835
4854
  encoding: "utf8",
4836
4855
  timeout: 5000,
4837
4856
  });
4838
- } catch {
4857
+ } catch (err) {
4858
+ console.warn("[mcpController] Failed to resolve shell PATH:", err.message);
4839
4859
  _shellPath$1 = process.env.PATH || "";
4840
4860
  }
4841
4861
 
4862
+ // Append fallback dirs that aren't already present
4863
+ const currentPaths = _shellPath$1.split(":");
4864
+ for (const dir of fallbackDirs) {
4865
+ if (!currentPaths.includes(dir)) {
4866
+ _shellPath$1 += `:${dir}`;
4867
+ }
4868
+ }
4869
+
4870
+ console.log("[mcpController] Resolved PATH:", _shellPath$1);
4842
4871
  return _shellPath$1;
4843
4872
  }
4844
4873
 
@@ -8348,6 +8377,17 @@ const {
8348
8377
  LLM_STREAM_ERROR,
8349
8378
  } = llmEvents$1;
8350
8379
 
8380
+ let _nextListenerId = 0;
8381
+ const _listenerMap = new Map();
8382
+
8383
+ function _addListener(channel, callback) {
8384
+ const id = String(++_nextListenerId);
8385
+ const wrapped = (_event, data) => callback(data);
8386
+ ipcRenderer$2.on(channel, wrapped);
8387
+ _listenerMap.set(id, { channel, wrapped });
8388
+ return id;
8389
+ }
8390
+
8351
8391
  const llmApi$2 = {
8352
8392
  /**
8353
8393
  * sendMessage
@@ -8417,84 +8457,40 @@ const llmApi$2 = {
8417
8457
  ipcRenderer$2.invoke(LLM_CLI_END_SESSION, { widgetUuid }),
8418
8458
 
8419
8459
  // --- Stream event listeners ---
8420
- // Each on* method returns the wrapped callback so callers can remove
8421
- // their own listener without nuking listeners from other widgets.
8460
+ // Each on* method returns an opaque string ID. Strings cross the
8461
+ // contextBridge safely (unlike function refs which get proxied).
8462
+ // Use removeStreamListener(id) to clean up.
8422
8463
 
8423
- /**
8424
- * onStreamDelta
8425
- * Listen for text chunks as they stream in.
8426
- * @returns {Function} wrapped callback for use with removeStreamListener
8427
- */
8428
- onStreamDelta: (callback) => {
8429
- const wrapped = (_event, data) => callback(data);
8430
- ipcRenderer$2.on(LLM_STREAM_DELTA, wrapped);
8431
- return wrapped;
8432
- },
8464
+ /** @returns {string} listener ID */
8465
+ onStreamDelta: (callback) => _addListener(LLM_STREAM_DELTA, callback),
8433
8466
 
8434
- /**
8435
- * onStreamToolCall
8436
- * Listen for tool call notifications.
8437
- * @returns {Function} wrapped callback for use with removeStreamListener
8438
- */
8439
- onStreamToolCall: (callback) => {
8440
- const wrapped = (_event, data) => callback(data);
8441
- ipcRenderer$2.on(LLM_STREAM_TOOL_CALL, wrapped);
8442
- return wrapped;
8443
- },
8467
+ /** @returns {string} listener ID */
8468
+ onStreamToolCall: (callback) => _addListener(LLM_STREAM_TOOL_CALL, callback),
8444
8469
 
8445
- /**
8446
- * onStreamToolResult
8447
- * Listen for tool result notifications.
8448
- * @returns {Function} wrapped callback for use with removeStreamListener
8449
- */
8450
- onStreamToolResult: (callback) => {
8451
- const wrapped = (_event, data) => callback(data);
8452
- ipcRenderer$2.on(LLM_STREAM_TOOL_RESULT, wrapped);
8453
- return wrapped;
8454
- },
8470
+ /** @returns {string} listener ID */
8471
+ onStreamToolResult: (callback) =>
8472
+ _addListener(LLM_STREAM_TOOL_RESULT, callback),
8455
8473
 
8456
- /**
8457
- * onStreamComplete
8458
- * Listen for stream completion (final response).
8459
- * @returns {Function} wrapped callback for use with removeStreamListener
8460
- */
8461
- onStreamComplete: (callback) => {
8462
- const wrapped = (_event, data) => callback(data);
8463
- ipcRenderer$2.on(LLM_STREAM_COMPLETE, wrapped);
8464
- return wrapped;
8465
- },
8474
+ /** @returns {string} listener ID */
8475
+ onStreamComplete: (callback) => _addListener(LLM_STREAM_COMPLETE, callback),
8466
8476
 
8467
- /**
8468
- * onStreamError
8469
- * Listen for stream errors.
8470
- * @returns {Function} wrapped callback for use with removeStreamListener
8471
- */
8472
- onStreamError: (callback) => {
8473
- const wrapped = (_event, data) => callback(data);
8474
- ipcRenderer$2.on(LLM_STREAM_ERROR, wrapped);
8475
- return wrapped;
8476
- },
8477
+ /** @returns {string} listener ID */
8478
+ onStreamError: (callback) => _addListener(LLM_STREAM_ERROR, callback),
8477
8479
 
8478
8480
  /**
8479
8481
  * removeStreamListener
8480
- * Remove a specific stream listener by channel and callback reference.
8482
+ * Remove a specific stream listener by its opaque ID.
8481
8483
  *
8482
- * @param {string} channel - the IPC channel name
8483
- * @param {Function} wrapped - the callback returned by on*
8484
- */
8485
- removeStreamListener: (channel, wrapped) => {
8486
- ipcRenderer$2.removeListener(channel, wrapped);
8487
- },
8488
-
8489
- /**
8490
- * Stream channel constants for use with removeStreamListener.
8484
+ * @param {string} idOrChannel - listener ID (or legacy channel name when second arg is provided)
8485
+ * @param {string} [id] - listener ID when called with legacy (channel, id) signature
8491
8486
  */
8492
- streamChannels: {
8493
- delta: LLM_STREAM_DELTA,
8494
- toolCall: LLM_STREAM_TOOL_CALL,
8495
- toolResult: LLM_STREAM_TOOL_RESULT,
8496
- complete: LLM_STREAM_COMPLETE,
8497
- error: LLM_STREAM_ERROR,
8487
+ removeStreamListener: (idOrChannel, id) => {
8488
+ const listenerId = id !== undefined ? String(id) : String(idOrChannel);
8489
+ const entry = _listenerMap.get(listenerId);
8490
+ if (entry) {
8491
+ ipcRenderer$2.removeListener(entry.channel, entry.wrapped);
8492
+ _listenerMap.delete(listenerId);
8493
+ }
8498
8494
  },
8499
8495
 
8500
8496
  /**
@@ -8503,6 +8499,10 @@ const llmApi$2 = {
8503
8499
  * Prefer removeStreamListener for scoped cleanup.
8504
8500
  */
8505
8501
  removeAllStreamListeners: () => {
8502
+ for (const [, entry] of _listenerMap) {
8503
+ ipcRenderer$2.removeListener(entry.channel, entry.wrapped);
8504
+ }
8505
+ _listenerMap.clear();
8506
8506
  ipcRenderer$2.removeAllListeners(LLM_STREAM_DELTA);
8507
8507
  ipcRenderer$2.removeAllListeners(LLM_STREAM_TOOL_CALL);
8508
8508
  ipcRenderer$2.removeAllListeners(LLM_STREAM_TOOL_RESULT);