@trops/dash-core 0.1.380 → 0.1.382

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/index.js CHANGED
@@ -56553,10 +56553,18 @@ function AssistantTextContent(_ref) {
56553
56553
  var MessageBubble = function MessageBubble(_ref2) {
56554
56554
  var message = _ref2.message,
56555
56555
  isStreaming = _ref2.isStreaming,
56556
- streamingText = _ref2.streamingText;
56556
+ streamingText = _ref2.streamingText,
56557
+ _ref2$isLast = _ref2.isLast,
56558
+ isLast = _ref2$isLast === void 0 ? false : _ref2$isLast;
56557
56559
  var role = message.role,
56558
56560
  content = message.content,
56559
- toolCalls = message.toolCalls;
56561
+ toolCalls = message.toolCalls,
56562
+ hidden = message.hidden;
56563
+
56564
+ // App-injected priming messages (e.g. widget-builder "Hello…" seed)
56565
+ // are kept in state for conversation continuity but suppressed from
56566
+ // the rendered timeline — the user sees only the agent's reply.
56567
+ if (hidden) return null;
56560
56568
  if (role === "user") {
56561
56569
  var text = typeof content === "string" ? content : Array.isArray(content) ? content.filter(function (c) {
56562
56570
  return c.type === "text";
@@ -56611,12 +56619,51 @@ var MessageBubble = function MessageBubble(_ref2) {
56611
56619
  } else if (typeof content === "string") {
56612
56620
  textParts.push(content);
56613
56621
  }
56622
+
56623
+ // Fallback: CLI backend (Claude Code) tracks tool calls on the
56624
+ // message's `toolCalls` field without placing tool_use blocks in
56625
+ // `content`. If we found no tool blocks in content but have toolCalls,
56626
+ // render those directly so the user sees what Claude is doing.
56627
+ if (toolBlocks.length === 0 && Array.isArray(toolCalls)) {
56628
+ var _iterator2 = _createForOfIteratorHelper$1(toolCalls),
56629
+ _step2;
56630
+ try {
56631
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
56632
+ var tc = _step2.value;
56633
+ toolBlocks.push({
56634
+ id: tc.toolUseId,
56635
+ name: tc.toolName,
56636
+ input: tc.input,
56637
+ serverName: tc.serverName,
56638
+ result: tc.result,
56639
+ isError: tc.isError,
56640
+ isLoading: tc.isLoading
56641
+ });
56642
+ }
56643
+ } catch (err) {
56644
+ _iterator2.e(err);
56645
+ } finally {
56646
+ _iterator2.f();
56647
+ }
56648
+ }
56614
56649
  var _text = textParts.join("");
56615
56650
 
56616
- // Hide empty assistant bubbles (e.g., tool-use-only responses from
56617
- // the CLI backend where content is [] and tool calls are tracked
56618
- // separately). Nothing useful to show the user.
56651
+ // Hide empty assistant bubbles (tool-use-only responses from the
56652
+ // CLI backend). But if this is the LAST message, show a thinking
56653
+ // indicator so the user knows the AI is working.
56619
56654
  if (!isStreaming && !_text && toolBlocks.length === 0) {
56655
+ if (isLast) {
56656
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
56657
+ className: "mb-4",
56658
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
56659
+ className: "text-[10px] font-semibold uppercase tracking-wider text-gray-500 mb-1",
56660
+ children: "Assistant"
56661
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
56662
+ className: "text-sm leading-relaxed px-3 py-2 rounded-lg bg-gray-800/40 text-gray-500 italic",
56663
+ children: "Thinking..."
56664
+ })]
56665
+ });
56666
+ }
56620
56667
  return null;
56621
56668
  }
56622
56669
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -56656,9 +56703,12 @@ var MessageBubble = function MessageBubble(_ref2) {
56656
56703
  * Scrollable message list that auto-scrolls to the bottom on new messages.
56657
56704
  */
56658
56705
  var ChatMessages = function ChatMessages(_ref) {
56706
+ var _messages;
56659
56707
  var messages = _ref.messages,
56660
56708
  streamingRequestId = _ref.streamingRequestId,
56661
- streamingText = _ref.streamingText;
56709
+ streamingText = _ref.streamingText,
56710
+ _ref$isLoading = _ref.isLoading,
56711
+ isLoading = _ref$isLoading === void 0 ? false : _ref$isLoading;
56662
56712
  var scrollRef = React.useRef(null);
56663
56713
  React.useEffect(function () {
56664
56714
  if (scrollRef.current) {
@@ -56679,18 +56729,46 @@ var ChatMessages = function ChatMessages(_ref) {
56679
56729
  })
56680
56730
  });
56681
56731
  }
56682
- return /*#__PURE__*/jsxRuntime.jsx("div", {
56732
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
56683
56733
  ref: scrollRef,
56684
56734
  className: "flex-1 overflow-y-auto px-4 py-3 scroll-smooth",
56685
- children: messages.map(function (message, index) {
56735
+ children: [messages.map(function (message, index) {
56686
56736
  var isLastAssistant = message.role === "assistant" && index === messages.length - 1;
56687
56737
  var isStreaming = isLastAssistant && streamingRequestId !== null;
56688
56738
  return /*#__PURE__*/jsxRuntime.jsx(MessageBubble, {
56689
56739
  message: message,
56690
56740
  isStreaming: isStreaming,
56691
- streamingText: isStreaming ? streamingText : ""
56741
+ streamingText: isStreaming ? streamingText : "",
56742
+ isLast: index === messages.length - 1
56692
56743
  }, message.id || index);
56693
- })
56744
+ }), isLoading && !streamingRequestId && ((_messages = messages[messages.length - 1]) === null || _messages === void 0 ? void 0 : _messages.role) === "user" && /*#__PURE__*/jsxRuntime.jsxs("div", {
56745
+ className: "mb-4",
56746
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
56747
+ className: "text-[10px] font-semibold uppercase tracking-wider text-gray-500 mb-1",
56748
+ children: "Assistant"
56749
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
56750
+ className: "text-sm leading-relaxed px-3 py-2 rounded-lg bg-gray-800/40 text-gray-500 italic flex items-center gap-2",
56751
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
56752
+ className: "inline-flex gap-0.5",
56753
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
56754
+ className: "w-1.5 h-1.5 bg-gray-500 rounded-full animate-bounce",
56755
+ style: {
56756
+ animationDelay: "0ms"
56757
+ }
56758
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
56759
+ className: "w-1.5 h-1.5 bg-gray-500 rounded-full animate-bounce",
56760
+ style: {
56761
+ animationDelay: "150ms"
56762
+ }
56763
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
56764
+ className: "w-1.5 h-1.5 bg-gray-500 rounded-full animate-bounce",
56765
+ style: {
56766
+ animationDelay: "300ms"
56767
+ }
56768
+ })]
56769
+ }), "Thinking..."]
56770
+ })]
56771
+ })]
56694
56772
  });
56695
56773
  };
56696
56774
 
@@ -56840,6 +56918,8 @@ function ChatCore(_ref) {
56840
56918
  uuid = _ref$uuid === void 0 ? null : _ref$uuid,
56841
56919
  _ref$persistKey = _ref.persistKey,
56842
56920
  persistKey = _ref$persistKey === void 0 ? null : _ref$persistKey,
56921
+ _ref$sessionKey = _ref.sessionKey,
56922
+ sessionKey = _ref$sessionKey === void 0 ? null : _ref$sessionKey,
56843
56923
  _ref$backend = _ref.backend,
56844
56924
  backend = _ref$backend === void 0 ? "anthropic" : _ref$backend,
56845
56925
  _ref$onPublishEvent = _ref.onPublishEvent,
@@ -56847,7 +56927,9 @@ function ChatCore(_ref) {
56847
56927
  _ref$hideToolsBanner = _ref.hideToolsBanner,
56848
56928
  hideToolsBanner = _ref$hideToolsBanner === void 0 ? false : _ref$hideToolsBanner,
56849
56929
  _ref$cwd = _ref.cwd,
56850
- cwd = _ref$cwd === void 0 ? null : _ref$cwd;
56930
+ cwd = _ref$cwd === void 0 ? null : _ref$cwd,
56931
+ _ref$initialMessage = _ref.initialMessage,
56932
+ initialMessage = _ref$initialMessage === void 0 ? null : _ref$initialMessage;
56851
56933
  var mainApi = window.mainApi;
56852
56934
 
56853
56935
  // Conversation state
@@ -56939,8 +57021,14 @@ function ChatCore(_ref) {
56939
57021
  } catch (e) {
56940
57022
  /* ignore quota errors */
56941
57023
  }
57024
+ } else if (sessionKey) {
57025
+ try {
57026
+ sessionStorage.setItem(sessionKey, JSON.stringify(data));
57027
+ } catch (e) {
57028
+ /* ignore quota errors */
57029
+ }
56942
57030
  }
56943
- }, [api, uuid, persistKey, enabledTools]);
57031
+ }, [api, uuid, persistKey, sessionKey, enabledTools]);
56944
57032
 
56945
57033
  // Load saved conversation on mount
56946
57034
  React.useEffect(function () {
@@ -56972,8 +57060,23 @@ function ChatCore(_ref) {
56972
57060
  } catch (e) {
56973
57061
  /* ignore */
56974
57062
  }
57063
+ } else if (sessionKey) {
57064
+ try {
57065
+ var _raw = sessionStorage.getItem(sessionKey);
57066
+ if (_raw) {
57067
+ var _data = JSON.parse(_raw);
57068
+ if (_data !== null && _data !== void 0 && _data.messages && Array.isArray(_data.messages)) {
57069
+ setMessages(_data.messages);
57070
+ }
57071
+ if (_data !== null && _data !== void 0 && _data.enabledTools) {
57072
+ setEnabledTools(_data.enabledTools);
57073
+ }
57074
+ }
57075
+ } catch (e) {
57076
+ /* ignore */
57077
+ }
56975
57078
  }
56976
- }, [api, uuid, persistKey]);
57079
+ }, [api, uuid, persistKey, sessionKey]);
56977
57080
 
56978
57081
  // Discover connected MCP tools (only for anthropic backend)
56979
57082
  var refreshTools = React.useCallback(function () {
@@ -57024,6 +57127,13 @@ function ChatCore(_ref) {
57024
57127
  tc.isError = data.isError;
57025
57128
  tc.isLoading = false;
57026
57129
  }
57130
+ // Force re-render so MessageBubble picks up the updated tool
57131
+ // result state (isLoading=false, result populated). Can't rely on
57132
+ // setStreamingText since it may already be empty (tool-only
57133
+ // response from CLI backend).
57134
+ setMessages(function (prev) {
57135
+ return _toConsumableArray(prev);
57136
+ });
57027
57137
  setStreamingText("");
57028
57138
  if (onPublishEvent) {
57029
57139
  onPublishEvent("toolUsed", {
@@ -57082,14 +57192,19 @@ function ChatCore(_ref) {
57082
57192
  };
57083
57193
  }, [mainApi, onPublishEvent, saveConversation]);
57084
57194
 
57085
- // Send message
57195
+ // Send message. `options.hidden` marks the user message so
57196
+ // MessageBubble skips rendering it — useful for app-injected
57197
+ // priming prompts where the agent's reply should appear first,
57198
+ // but the prompt still needs to be in conversation history.
57086
57199
  var handleSend = React.useCallback(function (text) {
57200
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
57087
57201
  if (!(mainApi !== null && mainApi !== void 0 && mainApi.llm) || isLoading) return;
57088
57202
  setError(null);
57089
57203
  var userMessage = {
57090
57204
  id: "msg-".concat(Date.now()),
57091
57205
  role: "user",
57092
- content: text
57206
+ content: text,
57207
+ hidden: options.hidden === true
57093
57208
  };
57094
57209
  var updatedMessages = [].concat(_toConsumableArray(messages), [userMessage]);
57095
57210
  setMessages(updatedMessages);
@@ -57134,7 +57249,7 @@ function ChatCore(_ref) {
57134
57249
  _iterator2.f();
57135
57250
  }
57136
57251
  }
57137
- var requestId = generateRequestId(uuid || persistKey);
57252
+ var requestId = generateRequestId(uuid || persistKey || sessionKey);
57138
57253
  activeRequestId.current = requestId;
57139
57254
  toolCallsRef.current = [];
57140
57255
  setIsLoading(true);
@@ -57156,7 +57271,7 @@ function ChatCore(_ref) {
57156
57271
  toolServerMap: toolServerMap,
57157
57272
  systemPrompt: systemPrompt,
57158
57273
  maxToolRounds: parseInt(maxToolRounds, 10) || 10,
57159
- widgetUuid: uuid || persistKey,
57274
+ widgetUuid: uuid || persistKey || sessionKey,
57160
57275
  cwd: cwd || undefined
57161
57276
  });
57162
57277
  }, [mainApi, isLoading, messages, servers, enabledTools, apiKey, model, systemPrompt, maxToolRounds, uuid, persistKey, onPublishEvent, backend, isAnthropicBackend]);
@@ -57199,6 +57314,27 @@ function ChatCore(_ref) {
57199
57314
  }
57200
57315
  }, [mainApi, streamingText, saveConversation]);
57201
57316
 
57317
+ // Auto-send an initial message once the chat is ready and empty.
57318
+ // Runs at most once per mount. Skipped if the conversation was
57319
+ // restored from persistence (messages already populated) or the
57320
+ // backend isn't ready yet.
57321
+ var initialMessageFiredRef = React.useRef(false);
57322
+ React.useEffect(function () {
57323
+ if (initialMessageFiredRef.current) return;
57324
+ if (!initialMessage) return;
57325
+ if (!(mainApi !== null && mainApi !== void 0 && mainApi.llm)) return;
57326
+ if (isLoading) return;
57327
+ if (messages.length !== 0) return;
57328
+ // CLI backend: wait for availability check to resolve.
57329
+ if (isCliBackend && cliAvailable === null) return;
57330
+ if (isCliBackend && !cliAvailable) return;
57331
+ initialMessageFiredRef.current = true;
57332
+ handleSend(initialMessage, {
57333
+ hidden: true
57334
+ });
57335
+ // eslint-disable-next-line react-hooks/exhaustive-deps
57336
+ }, [initialMessage, mainApi, messages, isCliBackend, cliAvailable, isLoading]);
57337
+
57202
57338
  // New chat
57203
57339
  var handleNewChat = function handleNewChat() {
57204
57340
  var _mainApi$llm3;
@@ -57209,7 +57345,7 @@ function ChatCore(_ref) {
57209
57345
  setSessionActive(false);
57210
57346
  saveConversation([]);
57211
57347
  if (isCliBackend && mainApi !== null && mainApi !== void 0 && (_mainApi$llm3 = mainApi.llm) !== null && _mainApi$llm3 !== void 0 && _mainApi$llm3.clearCliSession) {
57212
- mainApi.llm.clearCliSession(uuid || persistKey);
57348
+ mainApi.llm.clearCliSession(uuid || persistKey || sessionKey);
57213
57349
  }
57214
57350
  };
57215
57351
 
@@ -57218,7 +57354,7 @@ function ChatCore(_ref) {
57218
57354
  var _mainApi$llm4;
57219
57355
  if (!isCliBackend || !(mainApi !== null && mainApi !== void 0 && (_mainApi$llm4 = mainApi.llm) !== null && _mainApi$llm4 !== void 0 && _mainApi$llm4.endCliSession)) return;
57220
57356
  if (isLoading) handleStop();
57221
- mainApi.llm.endCliSession(uuid || persistKey);
57357
+ mainApi.llm.endCliSession(uuid || persistKey || sessionKey);
57222
57358
  setSessionActive(false);
57223
57359
  };
57224
57360
 
@@ -57329,7 +57465,8 @@ function ChatCore(_ref) {
57329
57465
  }), /*#__PURE__*/jsxRuntime.jsx(ChatMessages, {
57330
57466
  messages: messages,
57331
57467
  streamingRequestId: isLoading ? activeRequestId.current : null,
57332
- streamingText: streamingText
57468
+ streamingText: streamingText,
57469
+ isLoading: isLoading
57333
57470
  }), /*#__PURE__*/jsxRuntime.jsx(ChatInput, {
57334
57471
  onSend: handleSend,
57335
57472
  onStop: handleStop,