@trops/dash-core 0.1.645 → 0.1.647

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
@@ -28,6 +28,7 @@ var reactInstantsearchHooksWeb = require('react-instantsearch-hooks-web');
28
28
  var ReactDOM = require('react-dom');
29
29
  var reactRouterDom = require('react-router-dom');
30
30
  var marked = require('marked');
31
+ var DOMPurify = require('dompurify');
31
32
  var PropTypes = require('prop-types');
32
33
 
33
34
  function _interopNamespaceDefault(e) {
@@ -69054,6 +69055,58 @@ var ToolCallBlock = function ToolCallBlock(_ref) {
69054
69055
  });
69055
69056
  };
69056
69057
 
69058
+ /**
69059
+ * safeMarkdown.js
69060
+ *
69061
+ * Markdown → HTML that is safe to insert with dangerouslySetInnerHTML.
69062
+ *
69063
+ * AI replies are Markdown, and they can quote untrusted content (emails, web
69064
+ * pages, tool results). `marked` passes raw HTML through untouched, so a reply
69065
+ * containing `<img onerror=…>` or `<script>` would run in the app window —
69066
+ * which can reach window.mainApi. Every Markdown render of model or tool text
69067
+ * goes through here: `marked`, then DOMPurify.
69068
+ *
69069
+ * Kept: normal formatting (headings, emphasis, lists, code, tables, links).
69070
+ * Removed: scripts, event-handler attributes, javascript:/data: URLs,
69071
+ * iframes/objects/embeds/forms/styles, and inline style. Links get
69072
+ * rel="noopener noreferrer" (the app also blocks in-window navigation).
69073
+ */
69074
+ var FORBID_TAGS = ["style", "iframe", "object", "embed", "form", "input", "button", "textarea", "select", "link", "meta", "base"];
69075
+ var FORBID_ATTR = ["style"];
69076
+ // http(s), mailto, and in-page anchors only.
69077
+ var ALLOWED_URI_REGEXP = /^(?:(?:https?|mailto):|#)/i;
69078
+ var hooked = false;
69079
+ function ensureLinkHook() {
69080
+ if (hooked || typeof DOMPurify.addHook !== "function") return;
69081
+ DOMPurify.addHook("afterSanitizeAttributes", function (node) {
69082
+ if (node.tagName === "A" && node.hasAttribute("href")) {
69083
+ node.setAttribute("rel", "noopener noreferrer");
69084
+ node.setAttribute("target", "_blank");
69085
+ }
69086
+ });
69087
+ hooked = true;
69088
+ }
69089
+
69090
+ /**
69091
+ * @param {string} text Markdown (from a model, a tool, or a user)
69092
+ * @returns {string} sanitized HTML
69093
+ */
69094
+ function renderSafeMarkdown(text) {
69095
+ if (!text) return "";
69096
+ ensureLinkHook();
69097
+ var html = marked.marked(String(text), {
69098
+ breaks: true
69099
+ });
69100
+ return DOMPurify.sanitize(html, {
69101
+ USE_PROFILES: {
69102
+ html: true
69103
+ },
69104
+ FORBID_TAGS: FORBID_TAGS,
69105
+ FORBID_ATTR: FORBID_ATTR,
69106
+ ALLOWED_URI_REGEXP: ALLOWED_URI_REGEXP
69107
+ });
69108
+ }
69109
+
69057
69110
  function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
69058
69111
  function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
69059
69112
  function _createForOfIteratorHelper$4(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$4(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -69062,9 +69115,10 @@ function _arrayLikeToArray$4(r, a) { (null == a || a > r.length) && (a = r.lengt
69062
69115
  function AssistantTextContent(_ref) {
69063
69116
  var text = _ref.text;
69064
69117
  if (!text) return null;
69065
- var html = marked.marked(text, {
69066
- breaks: true
69067
- });
69118
+
69119
+ // Sanitized: replies can quote untrusted content (emails, web pages), and
69120
+ // this HTML is inserted into the app window.
69121
+ var html = renderSafeMarkdown(text);
69068
69122
  return /*#__PURE__*/jsxRuntime.jsx("div", {
69069
69123
  className: "prose prose-invert prose-sm max-w-none prose-p:my-2 prose-headings:my-3 prose-ul:my-2 prose-ol:my-2 prose-li:my-0.5 prose-pre:bg-black/40 prose-pre:text-gray-300 prose-code:text-indigo-300 prose-a:text-indigo-400 leading-relaxed",
69070
69124
  dangerouslySetInnerHTML: {
@@ -70943,6 +70997,165 @@ function MarkdownFormEditor(_ref8) {
70943
70997
  });
70944
70998
  }
70945
70999
 
71000
+ /**
71001
+ * botConversation.js
71002
+ *
71003
+ * Pure helpers for the Bots view (bot-teams PRD TEAM-011): turn a bot's run
71004
+ * records into chat turns, and work out each bot's status and how many things
71005
+ * on a team need the user.
71006
+ *
71007
+ * A run record (BotRunner) carries: trigger, status, startedAt/endedAt,
71008
+ * prompt, output (the answer), toolCalls [{ tool, provider, ok }], continued
71009
+ * (a reply in the same session), error, outputUnavailable.
71010
+ *
71011
+ * Turn kinds: "user" (what was asked), "system" (what started a run that
71012
+ * nobody typed), "tools" (tool-call rows), "bot" (the answer), "error",
71013
+ * "divider" (a new conversation started).
71014
+ */
71015
+
71016
+ function startedBy(r) {
71017
+ if (r.trigger === "schedule") return "Scheduled run";
71018
+ if (r.trigger === "event") return "Triggered by an event";
71019
+ return null;
71020
+ }
71021
+ function turnsForRun(r) {
71022
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
71023
+ _ref$pending = _ref.pending,
71024
+ pending = _ref$pending === void 0 ? false : _ref$pending;
71025
+ var turns = [];
71026
+ var at = r.startedAt || r.at || null;
71027
+ var label = startedBy(r);
71028
+ if (label) {
71029
+ // Event prompts are machine-written (and fence untrusted payloads) — show
71030
+ // what started the run, not the raw prompt.
71031
+ turns.push({
71032
+ kind: "system",
71033
+ text: label,
71034
+ at: at
71035
+ });
71036
+ } else if (r.prompt) {
71037
+ // Typed by the user: a manual run, a reply, or a question to the lead.
71038
+ turns.push({
71039
+ kind: "user",
71040
+ text: r.prompt,
71041
+ at: at
71042
+ });
71043
+ }
71044
+ if (Array.isArray(r.toolCalls) && r.toolCalls.length) {
71045
+ turns.push({
71046
+ kind: "tools",
71047
+ calls: r.toolCalls,
71048
+ at: at
71049
+ });
71050
+ }
71051
+ if (r.status === "failed" && r.error) {
71052
+ turns.push({
71053
+ kind: "error",
71054
+ text: r.error,
71055
+ at: r.endedAt || at
71056
+ });
71057
+ }
71058
+ if (r.outputUnavailable) {
71059
+ turns.push({
71060
+ kind: "bot",
71061
+ unavailable: true,
71062
+ text: "",
71063
+ at: r.endedAt || at
71064
+ });
71065
+ } else if (r.output || pending) {
71066
+ turns.push({
71067
+ kind: "bot",
71068
+ text: r.output || r.text || "",
71069
+ pending: pending,
71070
+ at: r.endedAt || at
71071
+ });
71072
+ }
71073
+ return turns;
71074
+ }
71075
+
71076
+ /**
71077
+ * @param {object[]} runs oldest first
71078
+ * @param {{ live?: { prompt?, text?, toolCalls?, continued? } }} [opts]
71079
+ * the run in progress, if any
71080
+ * @returns {object[]} turns
71081
+ */
71082
+ function buildConversation(runs) {
71083
+ var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
71084
+ _ref2$live = _ref2.live,
71085
+ live = _ref2$live === void 0 ? null : _ref2$live;
71086
+ var list = Array.isArray(runs) ? runs.filter(Boolean) : [];
71087
+ var turns = [];
71088
+ list.forEach(function (r, i) {
71089
+ if (i > 0 && !r.continued) {
71090
+ turns.push({
71091
+ kind: "divider",
71092
+ text: "New conversation",
71093
+ at: r.startedAt || r.at || null
71094
+ });
71095
+ }
71096
+ turns.push.apply(turns, _toConsumableArray(turnsForRun(r)));
71097
+ });
71098
+ if (live) {
71099
+ if (list.length && !live.continued) {
71100
+ turns.push({
71101
+ kind: "divider",
71102
+ text: "New conversation",
71103
+ at: null
71104
+ });
71105
+ }
71106
+ turns.push.apply(turns, _toConsumableArray(turnsForRun({
71107
+ trigger: live.trigger || "manual",
71108
+ prompt: live.prompt || "",
71109
+ toolCalls: live.toolCalls || [],
71110
+ text: live.text || ""
71111
+ }, {
71112
+ pending: true
71113
+ })));
71114
+ }
71115
+ return turns;
71116
+ }
71117
+
71118
+ /**
71119
+ * One bot's status. Needs approval > Running > Paused > Failed (its last run)
71120
+ * > Idle.
71121
+ */
71122
+ function botStatus(_ref3) {
71123
+ var botId = _ref3.botId,
71124
+ running = _ref3.running,
71125
+ paused = _ref3.paused,
71126
+ approvals = _ref3.approvals,
71127
+ lastRun = _ref3.lastRun;
71128
+ if ((approvals || []).some(function (a) {
71129
+ return a && a.request && a.request.botId === botId;
71130
+ })) {
71131
+ return "Needs approval";
71132
+ }
71133
+ if ((running || []).includes(botId)) return "Running";
71134
+ if (paused && (paused.global || (paused.bots || []).includes(botId))) {
71135
+ return "Paused";
71136
+ }
71137
+ if (lastRun && lastRun.status === "failed") return "Failed";
71138
+ return "Idle";
71139
+ }
71140
+
71141
+ /**
71142
+ * The Bots switch badge: the team's pending approvals plus bots whose last
71143
+ * run failed.
71144
+ */
71145
+ function attentionCount(_ref4) {
71146
+ var botIds = _ref4.botIds,
71147
+ approvals = _ref4.approvals,
71148
+ lastRunByBot = _ref4.lastRunByBot;
71149
+ var ids = new Set(botIds || []);
71150
+ var pending = (approvals || []).filter(function (a) {
71151
+ return a && a.request && ids.has(a.request.botId);
71152
+ }).length;
71153
+ var failed = _toConsumableArray(ids).filter(function (id) {
71154
+ return lastRunByBot && lastRunByBot[id] && lastRunByBot[id].status === "failed";
71155
+ }).length;
71156
+ return pending + failed;
71157
+ }
71158
+
70946
71159
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
70947
71160
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
70948
71161
 
@@ -71942,7 +72155,10 @@ exports.WorkspaceModel = WorkspaceModel;
71942
72155
  exports.WorkspaceScopeContext = WorkspaceScopeContext;
71943
72156
  exports.addChildToLayoutItem = addChildToLayoutItem;
71944
72157
  exports.addItemToItemLayout = addItemToItemLayout;
72158
+ exports.attentionCount = attentionCount;
71945
72159
  exports.bareComponentName = bareComponentName;
72160
+ exports.botStatus = botStatus;
72161
+ exports.buildConversation = buildConversation;
71946
72162
  exports.buildMcpConfigFromOverrides = buildMcpConfigFromOverrides;
71947
72163
  exports.canHaveChildren = canHaveChildren;
71948
72164
  exports.changeDirectionForLayoutItem = changeDirectionForLayoutItem;
@@ -72008,6 +72224,7 @@ exports.renderGridLayout = renderGridLayout;
72008
72224
  exports.renderGridLayoutFlow = renderGridLayoutFlow;
72009
72225
  exports.renderLayout = _renderLayout;
72010
72226
  exports.renderLayoutMenu = renderLayoutMenu;
72227
+ exports.renderSafeMarkdown = renderSafeMarkdown;
72011
72228
  exports.replaceItemInLayout = replaceItemInLayout;
72012
72229
  exports.resolveGateWidgetId = resolveGateWidgetId;
72013
72230
  exports.resolveIcon = resolveIcon;