@trops/dash-core 0.1.825 → 0.1.826

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.esm.js CHANGED
@@ -63107,6 +63107,29 @@ function AuthRequiredBody(_ref11) {
63107
63107
  });
63108
63108
  }
63109
63109
 
63110
+ /**
63111
+ * untitledDashboardName — a new blank dashboard's name, told apart from the
63112
+ * ones already there: "Untitled dashboard", then "Untitled dashboard 2", 3…
63113
+ * (the lowest number not in use). Two tabs, the Dashboards list and their
63114
+ * leads no longer read the same.
63115
+ *
63116
+ * @param {Array<{ name?: string }>} workspaces the dashboards there now
63117
+ * @returns {string}
63118
+ */
63119
+ var UNTITLED_DASHBOARD = "Untitled dashboard";
63120
+ function untitledDashboardName(workspaces) {
63121
+ var taken = new Set((Array.isArray(workspaces) ? workspaces : []).map(function (w) {
63122
+ return w && typeof w.name === "string" ? w.name.trim() : "";
63123
+ }).filter(Boolean).map(function (n) {
63124
+ return n.toLowerCase();
63125
+ }));
63126
+ var base = UNTITLED_DASHBOARD.toLowerCase();
63127
+ if (!taken.has(base)) return UNTITLED_DASHBOARD;
63128
+ for (var n = 2;; n += 1) {
63129
+ if (!taken.has("".concat(base, " ").concat(n))) return "".concat(UNTITLED_DASHBOARD, " ").concat(n);
63130
+ }
63131
+ }
63132
+
63110
63133
  /**
63111
63134
  * appPages — the Manage pages in the left nav (app-navigation PRD NAV-001/002).
63112
63135
  *
@@ -77133,6 +77156,259 @@ var BotsView = function BotsView(_ref5) {
77133
77156
  });
77134
77157
  };
77135
77158
 
77159
+ var EMPTY$4 = [];
77160
+ // Which status token colours each run state's dot.
77161
+ var STATUS_TONE = {
77162
+ completed: "success",
77163
+ failed: "error",
77164
+ running: "info"
77165
+ };
77166
+ var TICK_MS$2 = 30000;
77167
+ function relativeTime(iso) {
77168
+ var now = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Date.now();
77169
+ var t = iso ? Date.parse(iso) : NaN;
77170
+ if (Number.isNaN(t)) return "";
77171
+ var min = Math.floor((now - t) / 60000);
77172
+ if (min < 1) return "just now";
77173
+ if (min < 60) return "".concat(min, " min ago");
77174
+ var h = Math.floor(min / 60);
77175
+ if (h < 24) return "".concat(h, " h ago");
77176
+ return new Date(t).toLocaleDateString(undefined, {
77177
+ month: "short",
77178
+ day: "numeric"
77179
+ });
77180
+ }
77181
+ function runningFor(iso, now) {
77182
+ var t = iso ? Date.parse(iso) : NaN;
77183
+ if (Number.isNaN(t)) return "Running";
77184
+ var min = Math.floor((now - t) / 60000);
77185
+ return min < 1 ? "Running · just started" : "Running \xB7 ".concat(min, " min");
77186
+ }
77187
+ function statusLabel(s) {
77188
+ return s ? s.charAt(0).toUpperCase() + s.slice(1) : "Unknown";
77189
+ }
77190
+ function firstLine(run) {
77191
+ if (run.status === "failed" && run.error) return run.error;
77192
+ if (run.outputUnavailable) return "Answer unavailable";
77193
+ if (run.status === "interrupted" && !run.output) return INTERRUPTED_TEXT;
77194
+ return toPlainText(run.output || "").split("\n")[0];
77195
+ }
77196
+ var BotMonitor = function BotMonitor(_ref) {
77197
+ var monitor = _ref.monitor,
77198
+ _ref$workspaces = _ref.workspaces,
77199
+ workspaces = _ref$workspaces === void 0 ? EMPTY$4 : _ref$workspaces,
77200
+ _ref$onOpenBotsView = _ref.onOpenBotsView,
77201
+ onOpenBotsView = _ref$onOpenBotsView === void 0 ? null : _ref$onOpenBotsView,
77202
+ _ref$onOpenSettings = _ref.onOpenSettings,
77203
+ onOpenSettings = _ref$onOpenSettings === void 0 ? null : _ref$onOpenSettings;
77204
+ var currentTheme = (useContext(ThemeContext) || {}).currentTheme || {};
77205
+ var muted = currentTheme["text-neutral-medium"] || "text-gray-400";
77206
+ var strong = currentTheme["text-neutral-light"] || "text-gray-200";
77207
+ var hairline = currentTheme["border-neutral-dark"] || "border-gray-700";
77208
+ var statusTokens = useStatusTokens();
77209
+ var dotClass = function dotClass(status) {
77210
+ return STATUS_TONE[status] ? statusTokens[STATUS_TONE[status]].solidBg : currentTheme["bg-neutral-medium"] || "";
77211
+ };
77212
+
77213
+ // Re-render periodically so "5 min ago" / "Running · 3 min" stay true.
77214
+ var _useState = useState(function () {
77215
+ return Date.now();
77216
+ }),
77217
+ _useState2 = _slicedToArray(_useState, 2),
77218
+ now = _useState2[0],
77219
+ setNow = _useState2[1];
77220
+ useEffect(function () {
77221
+ var t = setInterval(function () {
77222
+ return setNow(Date.now());
77223
+ }, TICK_MS$2);
77224
+ return function () {
77225
+ return clearInterval(t);
77226
+ };
77227
+ }, []);
77228
+ if (!monitor) return null;
77229
+ var _monitor$approvals = monitor.approvals,
77230
+ approvals = _monitor$approvals === void 0 ? EMPTY$4 : _monitor$approvals,
77231
+ _monitor$running = monitor.running,
77232
+ running = _monitor$running === void 0 ? EMPTY$4 : _monitor$running,
77233
+ _monitor$recent = monitor.recent,
77234
+ recent = _monitor$recent === void 0 ? EMPTY$4 : _monitor$recent;
77235
+ var dashboardName = function dashboardName(workspaceId) {
77236
+ if (workspaceId === null || workspaceId === undefined) {
77237
+ return "No dashboard";
77238
+ }
77239
+ var ws = workspaces.find(function (w) {
77240
+ return String(w.id) === String(workspaceId);
77241
+ });
77242
+ return ws ? ws.name : "Unknown dashboard";
77243
+ };
77244
+ var workspaceOf = function workspaceOf(botId, fallback) {
77245
+ var bot = monitor.botById ? monitor.botById(botId) : null;
77246
+ var id = bot ? bot.workspaceId : fallback;
77247
+ return id === null || id === undefined ? null : String(id);
77248
+ };
77249
+ var label = function label(botId, name, workspaceId) {
77250
+ return "".concat(name, " \xB7 ").concat(dashboardName(workspaceId));
77251
+ };
77252
+ var openAction = function openAction(botId, workspaceId, tab) {
77253
+ if (workspaceId !== null && onOpenBotsView) {
77254
+ return /*#__PURE__*/jsx(Button3, {
77255
+ title: "Open in Bots view",
77256
+ size: "sm",
77257
+ onClick: function onClick() {
77258
+ return onOpenBotsView(workspaceId, botId, tab);
77259
+ }
77260
+ });
77261
+ }
77262
+ if (workspaceId === null && onOpenSettings) {
77263
+ return /*#__PURE__*/jsx(Button3, {
77264
+ title: "Open in Settings",
77265
+ size: "sm",
77266
+ onClick: function onClick() {
77267
+ return onOpenSettings(botId);
77268
+ }
77269
+ });
77270
+ }
77271
+ return null;
77272
+ };
77273
+ var sectionHeader = function sectionHeader(text, count) {
77274
+ return /*#__PURE__*/jsxs("h3", {
77275
+ className: "text-sm font-semibold ".concat(strong),
77276
+ children: [text, count ? /*#__PURE__*/jsxs("span", {
77277
+ className: "font-normal ".concat(muted),
77278
+ children: [" \xB7 ", count]
77279
+ }) : null]
77280
+ });
77281
+ };
77282
+ var nothing = !approvals.length && !running.length && !recent.length;
77283
+ return /*#__PURE__*/jsxs("div", {
77284
+ className: "flex flex-col gap-5 p-4 ".concat(strong),
77285
+ children: [nothing && !monitor.loading ? /*#__PURE__*/jsx("div", {
77286
+ className: "text-sm ".concat(muted),
77287
+ children: "All quiet \u2014 no approvals waiting, nothing running, no runs yet. Start a bot from a dashboard's Bots view."
77288
+ }) : null, approvals.length ? /*#__PURE__*/jsxs("section", {
77289
+ "aria-label": "Needs you",
77290
+ className: "flex flex-col gap-2",
77291
+ children: [sectionHeader("Needs you", approvals.length), approvals.map(function (a) {
77292
+ var req = a.request || {};
77293
+ var bot = monitor.botById ? monitor.botById(req.botId) : null;
77294
+ var ws = workspaceOf(req.botId, null);
77295
+ return /*#__PURE__*/jsxs("div", {
77296
+ className: "rounded-lg border border-amber-700 px-3 py-2.5 flex flex-col gap-2",
77297
+ children: [/*#__PURE__*/jsx("span", {
77298
+ className: "text-sm font-medium",
77299
+ children: label(req.botId, bot ? bot.name : "A bot", ws)
77300
+ }), /*#__PURE__*/jsxs("span", {
77301
+ className: "text-xs ".concat(muted),
77302
+ children: ["Wants to use", " ", /*#__PURE__*/jsx("span", {
77303
+ className: "font-mono",
77304
+ children: req.toolName || "a tool"
77305
+ }), req.serverName ? " on ".concat(req.serverName) : " (built-in)"]
77306
+ }), /*#__PURE__*/jsxs("div", {
77307
+ className: "flex flex-row flex-wrap items-center gap-2",
77308
+ children: [/*#__PURE__*/jsx(Button3, {
77309
+ title: "Allow once",
77310
+ size: "sm",
77311
+ onClick: function onClick() {
77312
+ return monitor.approve(a.id, {
77313
+ allow: true
77314
+ });
77315
+ }
77316
+ }), req.serverName ? /*#__PURE__*/jsx(Button, {
77317
+ title: "Always allow",
77318
+ size: "sm",
77319
+ onClick: function onClick() {
77320
+ return monitor.approve(a.id, {
77321
+ allow: true,
77322
+ remember: true
77323
+ });
77324
+ }
77325
+ }) : null, /*#__PURE__*/jsx(Button3, {
77326
+ title: "Deny",
77327
+ size: "sm",
77328
+ onClick: function onClick() {
77329
+ return monitor.approve(a.id, {
77330
+ allow: false
77331
+ });
77332
+ }
77333
+ }), /*#__PURE__*/jsx("div", {
77334
+ className: "flex-1"
77335
+ }), openAction(req.botId, ws, "conversation")]
77336
+ })]
77337
+ }, a.id);
77338
+ })]
77339
+ }) : null, running.length ? /*#__PURE__*/jsxs("section", {
77340
+ "aria-label": "Running now",
77341
+ className: "flex flex-col gap-2",
77342
+ children: [sectionHeader("Running now", running.length), running.map(function (r) {
77343
+ var ws = workspaceOf(r.id, r.workspaceId);
77344
+ return /*#__PURE__*/jsxs("div", {
77345
+ className: "rounded-lg border px-3 py-2.5 flex flex-col gap-1.5 ".concat(hairline),
77346
+ children: [/*#__PURE__*/jsxs("div", {
77347
+ className: "flex flex-row items-center gap-2",
77348
+ children: [/*#__PURE__*/jsx("span", {
77349
+ className: "h-2 w-2 rounded-full flex-shrink-0 bg-indigo-400"
77350
+ }), /*#__PURE__*/jsx("span", {
77351
+ className: "text-sm font-medium truncate",
77352
+ children: label(r.id, r.name, ws)
77353
+ })]
77354
+ }), /*#__PURE__*/jsxs("div", {
77355
+ className: "flex flex-row items-center gap-2",
77356
+ children: [/*#__PURE__*/jsx("span", {
77357
+ className: "text-xs ".concat(muted),
77358
+ children: runningFor(r.startedAt, now)
77359
+ }), /*#__PURE__*/jsx("div", {
77360
+ className: "flex-1"
77361
+ }), /*#__PURE__*/jsx(Button3, {
77362
+ title: "Stop",
77363
+ size: "sm",
77364
+ onClick: function onClick() {
77365
+ return monitor.stop(r.id);
77366
+ }
77367
+ }), openAction(r.id, ws, "conversation")]
77368
+ })]
77369
+ }, r.id);
77370
+ })]
77371
+ }) : null, recent.length ? /*#__PURE__*/jsxs("section", {
77372
+ "aria-label": "Recent",
77373
+ className: "flex flex-col gap-1",
77374
+ children: [sectionHeader("Recent runs", recent.length), recent.map(function (item, i) {
77375
+ var ws = workspaceOf(item.botId, item.workspaceId);
77376
+ var run = item.run || {};
77377
+ var canOpen = ws !== null && onOpenBotsView || ws === null && onOpenSettings;
77378
+ var open = function open() {
77379
+ if (ws !== null && onOpenBotsView) {
77380
+ onOpenBotsView(ws, item.botId, "activity");
77381
+ } else if (ws === null && onOpenSettings) {
77382
+ onOpenSettings(item.botId);
77383
+ }
77384
+ };
77385
+ var when = relativeTime(run.endedAt || run.at, now);
77386
+ var result = firstLine(run) || statusLabel(run.status);
77387
+ return /*#__PURE__*/jsx(ListRow, {
77388
+ icon: /*#__PURE__*/jsx("span", {
77389
+ role: "img",
77390
+ "aria-label": statusLabel(run.status),
77391
+ title: statusLabel(run.status),
77392
+ className: "inline-block mt-1 h-2 w-2 rounded-full ".concat(dotClass(run.status))
77393
+ }),
77394
+ title: result,
77395
+ meta: [label(item.botId, item.botName, ws), when].filter(Boolean).join(" · "),
77396
+ onClick: canOpen ? open : null
77397
+ }, "".concat(item.botId, "-").concat(i));
77398
+ })]
77399
+ }) : null]
77400
+ });
77401
+ };
77402
+
77403
+ function lastRunWhen(run) {
77404
+ var s = run && run.status;
77405
+ var word = s ? s.charAt(0).toUpperCase() + s.slice(1) : "";
77406
+ var when = relativeTime(run && (run.endedAt || run.at || run.startedAt));
77407
+ return [word, when].filter(Boolean).join(" · ");
77408
+ }
77409
+
77410
+ // A run's answer as words: the Scout's <matches> and the Planner's <plan>
77411
+ // blocks are for the app, not to read (QA 2026-10-22: a raw tag showed).
77136
77412
  function answerText(output) {
77137
77413
  return withoutMatches(output).replace(/<plan>[\s\S]*?<\/plan>/gi, "").trim();
77138
77414
  }
@@ -77375,12 +77651,21 @@ var DashTeamPanel = function DashTeamPanel(_ref) {
77375
77651
  title: "Last run",
77376
77652
  children: lastRun ? /*#__PURE__*/jsxs("div", {
77377
77653
  className: "flex flex-col gap-1 min-w-0",
77378
- children: [runCostLabel(lastRun) ? /*#__PURE__*/jsx("span", {
77654
+ children: [lastRunWhen(lastRun) ? /*#__PURE__*/jsx("span", {
77655
+ className: "text-sm",
77656
+ children: lastRunWhen(lastRun)
77657
+ }) : null, runCostLabel(lastRun) ? /*#__PURE__*/jsx("span", {
77379
77658
  className: "text-xs ".concat(muted),
77380
77659
  children: runCostLabel(lastRun)
77381
77660
  }) : null, lastRun.error || answerText(lastRun.output) ? /*#__PURE__*/jsx("span", {
77382
77661
  className: "text-sm line-clamp-3 ".concat(muted),
77383
77662
  children: toPlainText(lastRun.error || answerText(lastRun.output))
77663
+ }) : lastRun.status === "stopped" ? /*#__PURE__*/jsx("span", {
77664
+ className: "text-sm ".concat(muted),
77665
+ children: "Stopped before it answered."
77666
+ }) : lastRun.status === "interrupted" ? /*#__PURE__*/jsx("span", {
77667
+ className: "text-sm ".concat(muted),
77668
+ children: INTERRUPTED_TEXT
77384
77669
  }) : null]
77385
77670
  }) : /*#__PURE__*/jsx("span", {
77386
77671
  className: "text-sm ".concat(muted),
@@ -77397,7 +77682,7 @@ var DashTeamPanel = function DashTeamPanel(_ref) {
77397
77682
  * last run (one `listRecentRuns` call, not one request per bot). Mirrors
77398
77683
  * useTeamBots without the team filter.
77399
77684
  */
77400
- var EMPTY$4 = [];
77685
+ var EMPTY$3 = [];
77401
77686
  var NOT_PAUSED = {
77402
77687
  global: false,
77403
77688
  bots: []
@@ -77407,16 +77692,16 @@ function api$4() {
77407
77692
  return typeof window !== "undefined" && window.mainApi ? window.mainApi.bots : null;
77408
77693
  }
77409
77694
  function useAllBots() {
77410
- var _useState = useState(EMPTY$4),
77695
+ var _useState = useState(EMPTY$3),
77411
77696
  _useState2 = _slicedToArray(_useState, 2),
77412
77697
  bots = _useState2[0],
77413
77698
  setBots = _useState2[1];
77414
77699
  // The Dash team's role bots (CRE-011) — not in list().
77415
- var _useState3 = useState(EMPTY$4),
77700
+ var _useState3 = useState(EMPTY$3),
77416
77701
  _useState4 = _slicedToArray(_useState3, 2),
77417
77702
  dashTeam = _useState4[0],
77418
77703
  setDashTeam = _useState4[1];
77419
- var _useState5 = useState(EMPTY$4),
77704
+ var _useState5 = useState(EMPTY$3),
77420
77705
  _useState6 = _slicedToArray(_useState5, 2),
77421
77706
  running = _useState6[0],
77422
77707
  setRunning = _useState6[1];
@@ -77424,7 +77709,7 @@ function useAllBots() {
77424
77709
  _useState8 = _slicedToArray(_useState7, 2),
77425
77710
  paused = _useState8[0],
77426
77711
  setPaused = _useState8[1];
77427
- var _useState9 = useState(EMPTY$4),
77712
+ var _useState9 = useState(EMPTY$3),
77428
77713
  _useState0 = _slicedToArray(_useState9, 2),
77429
77714
  approvals = _useState0[0],
77430
77715
  setApprovals = _useState0[1];
@@ -77481,7 +77766,7 @@ function useAllBots() {
77481
77766
  case 1:
77482
77767
  _context2.prev = 1;
77483
77768
  _context2.next = 2;
77484
- return Promise.all([b.list ? b.list() : EMPTY$4, b.listRunning ? b.listRunning() : EMPTY$4, b.getPauseState ? b.getPauseState() : NOT_PAUSED, b.listApprovals ? b.listApprovals() : EMPTY$4, b.listDashTeam ? b.listDashTeam() : EMPTY$4, loadRecent()]);
77769
+ return Promise.all([b.list ? b.list() : EMPTY$3, b.listRunning ? b.listRunning() : EMPTY$3, b.getPauseState ? b.getPauseState() : NOT_PAUSED, b.listApprovals ? b.listApprovals() : EMPTY$3, b.listDashTeam ? b.listDashTeam() : EMPTY$3, loadRecent()]);
77485
77770
  case 2:
77486
77771
  _yield$Promise$all = _context2.sent;
77487
77772
  _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 5);
@@ -77490,13 +77775,13 @@ function useAllBots() {
77490
77775
  pause = _yield$Promise$all2[2];
77491
77776
  pending = _yield$Promise$all2[3];
77492
77777
  team = _yield$Promise$all2[4];
77493
- setBots(Array.isArray(list) ? list : EMPTY$4);
77494
- setDashTeam(Array.isArray(team) ? team : EMPTY$4);
77778
+ setBots(Array.isArray(list) ? list : EMPTY$3);
77779
+ setDashTeam(Array.isArray(team) ? team : EMPTY$3);
77495
77780
  setRunning((run || []).map(function (r) {
77496
77781
  return r && r.id || r;
77497
77782
  }));
77498
77783
  setPaused(pause || NOT_PAUSED);
77499
- setApprovals(pending || EMPTY$4);
77784
+ setApprovals(pending || EMPTY$3);
77500
77785
  _context2.next = 4;
77501
77786
  break;
77502
77787
  case 3:
@@ -77521,14 +77806,14 @@ function useAllBots() {
77521
77806
  var ids = [];
77522
77807
  if (b.onRunActive) {
77523
77808
  ids.push(b.onRunActive(function (payload) {
77524
- return setRunning(payload && payload.running || EMPTY$4);
77809
+ return setRunning(payload && payload.running || EMPTY$3);
77525
77810
  }));
77526
77811
  }
77527
77812
  // The whole queue after any change (answered anywhere, denied, timed
77528
77813
  // out) — replaces this copy, so answered approvals disappear here too.
77529
77814
  if (b.onApprovalsChanged) {
77530
77815
  ids.push(b.onApprovalsChanged(function (p) {
77531
- return setApprovals(p && p.approvals || EMPTY$4);
77816
+ return setApprovals(p && p.approvals || EMPTY$3);
77532
77817
  }));
77533
77818
  }
77534
77819
  if (b.onApprovalPending) {
@@ -78406,18 +78691,18 @@ var TABS = [{
78406
78691
  label: "Settings"
78407
78692
  }];
78408
78693
  var ROLE_ORDER = ["planner", "scout", "builder", "checker"];
78409
- var EMPTY$3 = [];
78694
+ var EMPTY$2 = [];
78410
78695
  function botsApi() {
78411
78696
  return typeof window !== "undefined" && window.mainApi ? window.mainApi.bots : null;
78412
78697
  }
78413
78698
  var getWidgetConfig$3 = function getWidgetConfig(name) {
78414
78699
  return name && ComponentManager.config(name) || null;
78415
78700
  };
78416
- var TICK_MS$2 = 60000;
78701
+ var TICK_MS$1 = 60000;
78417
78702
 
78418
78703
  /** The questions in Recent, live; their ages kept current. */
78419
78704
  function useThreads() {
78420
- var _useState = useState(EMPTY$3),
78705
+ var _useState = useState(EMPTY$2),
78421
78706
  _useState2 = _slicedToArray(_useState, 2),
78422
78707
  entries = _useState2[0],
78423
78708
  setEntries = _useState2[1];
@@ -78434,7 +78719,7 @@ function useThreads() {
78434
78719
  useEffect(function () {
78435
78720
  var t = setInterval(function () {
78436
78721
  return setNow(Date.now());
78437
- }, TICK_MS$2);
78722
+ }, TICK_MS$1);
78438
78723
  return function () {
78439
78724
  return clearInterval(t);
78440
78725
  };
@@ -78449,7 +78734,7 @@ function useThreads() {
78449
78734
  }
78450
78735
  Promise.resolve(b.listCreateRecent()).then(function (l) {
78451
78736
  if (!alive) return;
78452
- setEntries(Array.isArray(l) ? l : EMPTY$3);
78737
+ setEntries(Array.isArray(l) ? l : EMPTY$2);
78453
78738
  setNow(Date.now());
78454
78739
  setLoaded(true);
78455
78740
  })["catch"](function () {
@@ -78777,7 +79062,7 @@ var DashTeamPage = function DashTeamPage(_ref4) {
78777
79062
  var _ref4$initialTab = _ref4.initialTab,
78778
79063
  initialTab = _ref4$initialTab === void 0 ? "conversation" : _ref4$initialTab,
78779
79064
  _ref4$workspaces = _ref4.workspaces,
78780
- workspaces = _ref4$workspaces === void 0 ? EMPTY$3 : _ref4$workspaces,
79065
+ workspaces = _ref4$workspaces === void 0 ? EMPTY$2 : _ref4$workspaces,
78781
79066
  _ref4$onOpenPlan = _ref4.onOpenPlan,
78782
79067
  onOpenPlan = _ref4$onOpenPlan === void 0 ? null : _ref4$onOpenPlan,
78783
79068
  _ref4$onClose = _ref4.onClose,
@@ -78918,7 +79203,7 @@ var DashTeamPage = function DashTeamPage(_ref4) {
78918
79203
  });
78919
79204
  };
78920
79205
 
78921
- var EMPTY$2 = [];
79206
+ var EMPTY$1 = [];
78922
79207
 
78923
79208
  /**
78924
79209
  * BotPageModal — the bot page (BotPage) in a large modal, opened from the
@@ -78944,7 +79229,7 @@ var BotPageModal = function BotPageModal(_ref) {
78944
79229
  request = _ref$request === void 0 ? null : _ref$request,
78945
79230
  onClose = _ref.onClose,
78946
79231
  _ref$workspaces = _ref.workspaces,
78947
- workspaces = _ref$workspaces === void 0 ? EMPTY$2 : _ref$workspaces,
79232
+ workspaces = _ref$workspaces === void 0 ? EMPTY$1 : _ref$workspaces,
78948
79233
  _ref$onOpenInBotsView = _ref.onOpenInBotsView,
78949
79234
  onOpenInBotsView = _ref$onOpenInBotsView === void 0 ? null : _ref$onOpenInBotsView,
78950
79235
  _ref$onOpenSettings = _ref.onOpenSettings,
@@ -79127,250 +79412,6 @@ function usePendingApprovalCount() {
79127
79412
  return count;
79128
79413
  }
79129
79414
 
79130
- var EMPTY$1 = [];
79131
- // Which status token colours each run state's dot.
79132
- var STATUS_TONE = {
79133
- completed: "success",
79134
- failed: "error",
79135
- running: "info"
79136
- };
79137
- var TICK_MS$1 = 30000;
79138
- function relativeTime(iso) {
79139
- var now = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Date.now();
79140
- var t = iso ? Date.parse(iso) : NaN;
79141
- if (Number.isNaN(t)) return "";
79142
- var min = Math.floor((now - t) / 60000);
79143
- if (min < 1) return "just now";
79144
- if (min < 60) return "".concat(min, " min ago");
79145
- var h = Math.floor(min / 60);
79146
- if (h < 24) return "".concat(h, " h ago");
79147
- return new Date(t).toLocaleDateString(undefined, {
79148
- month: "short",
79149
- day: "numeric"
79150
- });
79151
- }
79152
- function runningFor(iso, now) {
79153
- var t = iso ? Date.parse(iso) : NaN;
79154
- if (Number.isNaN(t)) return "Running";
79155
- var min = Math.floor((now - t) / 60000);
79156
- return min < 1 ? "Running · just started" : "Running \xB7 ".concat(min, " min");
79157
- }
79158
- function statusLabel(s) {
79159
- return s ? s.charAt(0).toUpperCase() + s.slice(1) : "Unknown";
79160
- }
79161
- function firstLine(run) {
79162
- if (run.status === "failed" && run.error) return run.error;
79163
- if (run.outputUnavailable) return "Answer unavailable";
79164
- if (run.status === "interrupted" && !run.output) return INTERRUPTED_TEXT;
79165
- return toPlainText(run.output || "").split("\n")[0];
79166
- }
79167
- var BotMonitor = function BotMonitor(_ref) {
79168
- var monitor = _ref.monitor,
79169
- _ref$workspaces = _ref.workspaces,
79170
- workspaces = _ref$workspaces === void 0 ? EMPTY$1 : _ref$workspaces,
79171
- _ref$onOpenBotsView = _ref.onOpenBotsView,
79172
- onOpenBotsView = _ref$onOpenBotsView === void 0 ? null : _ref$onOpenBotsView,
79173
- _ref$onOpenSettings = _ref.onOpenSettings,
79174
- onOpenSettings = _ref$onOpenSettings === void 0 ? null : _ref$onOpenSettings;
79175
- var currentTheme = (useContext(ThemeContext) || {}).currentTheme || {};
79176
- var muted = currentTheme["text-neutral-medium"] || "text-gray-400";
79177
- var strong = currentTheme["text-neutral-light"] || "text-gray-200";
79178
- var hairline = currentTheme["border-neutral-dark"] || "border-gray-700";
79179
- var statusTokens = useStatusTokens();
79180
- var dotClass = function dotClass(status) {
79181
- return STATUS_TONE[status] ? statusTokens[STATUS_TONE[status]].solidBg : currentTheme["bg-neutral-medium"] || "";
79182
- };
79183
-
79184
- // Re-render periodically so "5 min ago" / "Running · 3 min" stay true.
79185
- var _useState = useState(function () {
79186
- return Date.now();
79187
- }),
79188
- _useState2 = _slicedToArray(_useState, 2),
79189
- now = _useState2[0],
79190
- setNow = _useState2[1];
79191
- useEffect(function () {
79192
- var t = setInterval(function () {
79193
- return setNow(Date.now());
79194
- }, TICK_MS$1);
79195
- return function () {
79196
- return clearInterval(t);
79197
- };
79198
- }, []);
79199
- if (!monitor) return null;
79200
- var _monitor$approvals = monitor.approvals,
79201
- approvals = _monitor$approvals === void 0 ? EMPTY$1 : _monitor$approvals,
79202
- _monitor$running = monitor.running,
79203
- running = _monitor$running === void 0 ? EMPTY$1 : _monitor$running,
79204
- _monitor$recent = monitor.recent,
79205
- recent = _monitor$recent === void 0 ? EMPTY$1 : _monitor$recent;
79206
- var dashboardName = function dashboardName(workspaceId) {
79207
- if (workspaceId === null || workspaceId === undefined) {
79208
- return "No dashboard";
79209
- }
79210
- var ws = workspaces.find(function (w) {
79211
- return String(w.id) === String(workspaceId);
79212
- });
79213
- return ws ? ws.name : "Unknown dashboard";
79214
- };
79215
- var workspaceOf = function workspaceOf(botId, fallback) {
79216
- var bot = monitor.botById ? monitor.botById(botId) : null;
79217
- var id = bot ? bot.workspaceId : fallback;
79218
- return id === null || id === undefined ? null : String(id);
79219
- };
79220
- var label = function label(botId, name, workspaceId) {
79221
- return "".concat(name, " \xB7 ").concat(dashboardName(workspaceId));
79222
- };
79223
- var openAction = function openAction(botId, workspaceId, tab) {
79224
- if (workspaceId !== null && onOpenBotsView) {
79225
- return /*#__PURE__*/jsx(Button3, {
79226
- title: "Open in Bots view",
79227
- size: "sm",
79228
- onClick: function onClick() {
79229
- return onOpenBotsView(workspaceId, botId, tab);
79230
- }
79231
- });
79232
- }
79233
- if (workspaceId === null && onOpenSettings) {
79234
- return /*#__PURE__*/jsx(Button3, {
79235
- title: "Open in Settings",
79236
- size: "sm",
79237
- onClick: function onClick() {
79238
- return onOpenSettings(botId);
79239
- }
79240
- });
79241
- }
79242
- return null;
79243
- };
79244
- var sectionHeader = function sectionHeader(text, count) {
79245
- return /*#__PURE__*/jsxs("h3", {
79246
- className: "text-sm font-semibold ".concat(strong),
79247
- children: [text, count ? /*#__PURE__*/jsxs("span", {
79248
- className: "font-normal ".concat(muted),
79249
- children: [" \xB7 ", count]
79250
- }) : null]
79251
- });
79252
- };
79253
- var nothing = !approvals.length && !running.length && !recent.length;
79254
- return /*#__PURE__*/jsxs("div", {
79255
- className: "flex flex-col gap-5 p-4 ".concat(strong),
79256
- children: [nothing && !monitor.loading ? /*#__PURE__*/jsx("div", {
79257
- className: "text-sm ".concat(muted),
79258
- children: "All quiet \u2014 no approvals waiting, nothing running, no runs yet. Start a bot from a dashboard's Bots view."
79259
- }) : null, approvals.length ? /*#__PURE__*/jsxs("section", {
79260
- "aria-label": "Needs you",
79261
- className: "flex flex-col gap-2",
79262
- children: [sectionHeader("Needs you", approvals.length), approvals.map(function (a) {
79263
- var req = a.request || {};
79264
- var bot = monitor.botById ? monitor.botById(req.botId) : null;
79265
- var ws = workspaceOf(req.botId, null);
79266
- return /*#__PURE__*/jsxs("div", {
79267
- className: "rounded-lg border border-amber-700 px-3 py-2.5 flex flex-col gap-2",
79268
- children: [/*#__PURE__*/jsx("span", {
79269
- className: "text-sm font-medium",
79270
- children: label(req.botId, bot ? bot.name : "A bot", ws)
79271
- }), /*#__PURE__*/jsxs("span", {
79272
- className: "text-xs ".concat(muted),
79273
- children: ["Wants to use", " ", /*#__PURE__*/jsx("span", {
79274
- className: "font-mono",
79275
- children: req.toolName || "a tool"
79276
- }), req.serverName ? " on ".concat(req.serverName) : " (built-in)"]
79277
- }), /*#__PURE__*/jsxs("div", {
79278
- className: "flex flex-row flex-wrap items-center gap-2",
79279
- children: [/*#__PURE__*/jsx(Button3, {
79280
- title: "Allow once",
79281
- size: "sm",
79282
- onClick: function onClick() {
79283
- return monitor.approve(a.id, {
79284
- allow: true
79285
- });
79286
- }
79287
- }), req.serverName ? /*#__PURE__*/jsx(Button, {
79288
- title: "Always allow",
79289
- size: "sm",
79290
- onClick: function onClick() {
79291
- return monitor.approve(a.id, {
79292
- allow: true,
79293
- remember: true
79294
- });
79295
- }
79296
- }) : null, /*#__PURE__*/jsx(Button3, {
79297
- title: "Deny",
79298
- size: "sm",
79299
- onClick: function onClick() {
79300
- return monitor.approve(a.id, {
79301
- allow: false
79302
- });
79303
- }
79304
- }), /*#__PURE__*/jsx("div", {
79305
- className: "flex-1"
79306
- }), openAction(req.botId, ws, "conversation")]
79307
- })]
79308
- }, a.id);
79309
- })]
79310
- }) : null, running.length ? /*#__PURE__*/jsxs("section", {
79311
- "aria-label": "Running now",
79312
- className: "flex flex-col gap-2",
79313
- children: [sectionHeader("Running now", running.length), running.map(function (r) {
79314
- var ws = workspaceOf(r.id, r.workspaceId);
79315
- return /*#__PURE__*/jsxs("div", {
79316
- className: "rounded-lg border px-3 py-2.5 flex flex-col gap-1.5 ".concat(hairline),
79317
- children: [/*#__PURE__*/jsxs("div", {
79318
- className: "flex flex-row items-center gap-2",
79319
- children: [/*#__PURE__*/jsx("span", {
79320
- className: "h-2 w-2 rounded-full flex-shrink-0 bg-indigo-400"
79321
- }), /*#__PURE__*/jsx("span", {
79322
- className: "text-sm font-medium truncate",
79323
- children: label(r.id, r.name, ws)
79324
- })]
79325
- }), /*#__PURE__*/jsxs("div", {
79326
- className: "flex flex-row items-center gap-2",
79327
- children: [/*#__PURE__*/jsx("span", {
79328
- className: "text-xs ".concat(muted),
79329
- children: runningFor(r.startedAt, now)
79330
- }), /*#__PURE__*/jsx("div", {
79331
- className: "flex-1"
79332
- }), /*#__PURE__*/jsx(Button3, {
79333
- title: "Stop",
79334
- size: "sm",
79335
- onClick: function onClick() {
79336
- return monitor.stop(r.id);
79337
- }
79338
- }), openAction(r.id, ws, "conversation")]
79339
- })]
79340
- }, r.id);
79341
- })]
79342
- }) : null, recent.length ? /*#__PURE__*/jsxs("section", {
79343
- "aria-label": "Recent",
79344
- className: "flex flex-col gap-1",
79345
- children: [sectionHeader("Recent runs", recent.length), recent.map(function (item, i) {
79346
- var ws = workspaceOf(item.botId, item.workspaceId);
79347
- var run = item.run || {};
79348
- var canOpen = ws !== null && onOpenBotsView || ws === null && onOpenSettings;
79349
- var open = function open() {
79350
- if (ws !== null && onOpenBotsView) {
79351
- onOpenBotsView(ws, item.botId, "activity");
79352
- } else if (ws === null && onOpenSettings) {
79353
- onOpenSettings(item.botId);
79354
- }
79355
- };
79356
- var when = relativeTime(run.endedAt || run.at, now);
79357
- var result = firstLine(run) || statusLabel(run.status);
79358
- return /*#__PURE__*/jsx(ListRow, {
79359
- icon: /*#__PURE__*/jsx("span", {
79360
- role: "img",
79361
- "aria-label": statusLabel(run.status),
79362
- title: statusLabel(run.status),
79363
- className: "inline-block mt-1 h-2 w-2 rounded-full ".concat(dotClass(run.status))
79364
- }),
79365
- title: result,
79366
- meta: [label(item.botId, item.botName, ws), when].filter(Boolean).join(" · "),
79367
- onClick: canOpen ? open : null
79368
- }, "".concat(item.botId, "-").concat(i));
79369
- })]
79370
- }) : null]
79371
- });
79372
- };
79373
-
79374
79415
  function ownKeys$l(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; }
79375
79416
  function _objectSpread$l(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$l(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$l(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
79376
79417
  function _createForOfIteratorHelper$j(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$j(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; } } }; }
@@ -90958,7 +90999,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
90958
90999
  menuId = menuItems && menuItems.length > 0 ? menuItems[0].id : 1;
90959
91000
  _context6.prev = 1;
90960
91001
  _context6.next = 2;
90961
- return handleCreateFromTemplate(createLayoutFromTemplate(layoutTemplates[0], menuId), themeKey || null, "Untitled dashboard");
91002
+ return handleCreateFromTemplate(createLayoutFromTemplate(layoutTemplates[0], menuId), themeKey || null,
91003
+ // Told apart from the blank ones already there ("… 2").
91004
+ untitledDashboardName(workspaceConfig));
90962
91005
  case 2:
90963
91006
  _context6.next = 4;
90964
91007
  break;