@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.js CHANGED
@@ -63125,6 +63125,29 @@ function AuthRequiredBody(_ref11) {
63125
63125
  });
63126
63126
  }
63127
63127
 
63128
+ /**
63129
+ * untitledDashboardName — a new blank dashboard's name, told apart from the
63130
+ * ones already there: "Untitled dashboard", then "Untitled dashboard 2", 3…
63131
+ * (the lowest number not in use). Two tabs, the Dashboards list and their
63132
+ * leads no longer read the same.
63133
+ *
63134
+ * @param {Array<{ name?: string }>} workspaces the dashboards there now
63135
+ * @returns {string}
63136
+ */
63137
+ var UNTITLED_DASHBOARD = "Untitled dashboard";
63138
+ function untitledDashboardName(workspaces) {
63139
+ var taken = new Set((Array.isArray(workspaces) ? workspaces : []).map(function (w) {
63140
+ return w && typeof w.name === "string" ? w.name.trim() : "";
63141
+ }).filter(Boolean).map(function (n) {
63142
+ return n.toLowerCase();
63143
+ }));
63144
+ var base = UNTITLED_DASHBOARD.toLowerCase();
63145
+ if (!taken.has(base)) return UNTITLED_DASHBOARD;
63146
+ for (var n = 2;; n += 1) {
63147
+ if (!taken.has("".concat(base, " ").concat(n))) return "".concat(UNTITLED_DASHBOARD, " ").concat(n);
63148
+ }
63149
+ }
63150
+
63128
63151
  /**
63129
63152
  * appPages — the Manage pages in the left nav (app-navigation PRD NAV-001/002).
63130
63153
  *
@@ -77151,6 +77174,259 @@ var BotsView = function BotsView(_ref5) {
77151
77174
  });
77152
77175
  };
77153
77176
 
77177
+ var EMPTY$4 = [];
77178
+ // Which status token colours each run state's dot.
77179
+ var STATUS_TONE = {
77180
+ completed: "success",
77181
+ failed: "error",
77182
+ running: "info"
77183
+ };
77184
+ var TICK_MS$2 = 30000;
77185
+ function relativeTime(iso) {
77186
+ var now = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Date.now();
77187
+ var t = iso ? Date.parse(iso) : NaN;
77188
+ if (Number.isNaN(t)) return "";
77189
+ var min = Math.floor((now - t) / 60000);
77190
+ if (min < 1) return "just now";
77191
+ if (min < 60) return "".concat(min, " min ago");
77192
+ var h = Math.floor(min / 60);
77193
+ if (h < 24) return "".concat(h, " h ago");
77194
+ return new Date(t).toLocaleDateString(undefined, {
77195
+ month: "short",
77196
+ day: "numeric"
77197
+ });
77198
+ }
77199
+ function runningFor(iso, now) {
77200
+ var t = iso ? Date.parse(iso) : NaN;
77201
+ if (Number.isNaN(t)) return "Running";
77202
+ var min = Math.floor((now - t) / 60000);
77203
+ return min < 1 ? "Running · just started" : "Running \xB7 ".concat(min, " min");
77204
+ }
77205
+ function statusLabel(s) {
77206
+ return s ? s.charAt(0).toUpperCase() + s.slice(1) : "Unknown";
77207
+ }
77208
+ function firstLine(run) {
77209
+ if (run.status === "failed" && run.error) return run.error;
77210
+ if (run.outputUnavailable) return "Answer unavailable";
77211
+ if (run.status === "interrupted" && !run.output) return INTERRUPTED_TEXT;
77212
+ return toPlainText(run.output || "").split("\n")[0];
77213
+ }
77214
+ var BotMonitor = function BotMonitor(_ref) {
77215
+ var monitor = _ref.monitor,
77216
+ _ref$workspaces = _ref.workspaces,
77217
+ workspaces = _ref$workspaces === void 0 ? EMPTY$4 : _ref$workspaces,
77218
+ _ref$onOpenBotsView = _ref.onOpenBotsView,
77219
+ onOpenBotsView = _ref$onOpenBotsView === void 0 ? null : _ref$onOpenBotsView,
77220
+ _ref$onOpenSettings = _ref.onOpenSettings,
77221
+ onOpenSettings = _ref$onOpenSettings === void 0 ? null : _ref$onOpenSettings;
77222
+ var currentTheme = (React.useContext(DashReact.ThemeContext) || {}).currentTheme || {};
77223
+ var muted = currentTheme["text-neutral-medium"] || "text-gray-400";
77224
+ var strong = currentTheme["text-neutral-light"] || "text-gray-200";
77225
+ var hairline = currentTheme["border-neutral-dark"] || "border-gray-700";
77226
+ var statusTokens = DashReact.useStatusTokens();
77227
+ var dotClass = function dotClass(status) {
77228
+ return STATUS_TONE[status] ? statusTokens[STATUS_TONE[status]].solidBg : currentTheme["bg-neutral-medium"] || "";
77229
+ };
77230
+
77231
+ // Re-render periodically so "5 min ago" / "Running · 3 min" stay true.
77232
+ var _useState = React.useState(function () {
77233
+ return Date.now();
77234
+ }),
77235
+ _useState2 = _slicedToArray(_useState, 2),
77236
+ now = _useState2[0],
77237
+ setNow = _useState2[1];
77238
+ React.useEffect(function () {
77239
+ var t = setInterval(function () {
77240
+ return setNow(Date.now());
77241
+ }, TICK_MS$2);
77242
+ return function () {
77243
+ return clearInterval(t);
77244
+ };
77245
+ }, []);
77246
+ if (!monitor) return null;
77247
+ var _monitor$approvals = monitor.approvals,
77248
+ approvals = _monitor$approvals === void 0 ? EMPTY$4 : _monitor$approvals,
77249
+ _monitor$running = monitor.running,
77250
+ running = _monitor$running === void 0 ? EMPTY$4 : _monitor$running,
77251
+ _monitor$recent = monitor.recent,
77252
+ recent = _monitor$recent === void 0 ? EMPTY$4 : _monitor$recent;
77253
+ var dashboardName = function dashboardName(workspaceId) {
77254
+ if (workspaceId === null || workspaceId === undefined) {
77255
+ return "No dashboard";
77256
+ }
77257
+ var ws = workspaces.find(function (w) {
77258
+ return String(w.id) === String(workspaceId);
77259
+ });
77260
+ return ws ? ws.name : "Unknown dashboard";
77261
+ };
77262
+ var workspaceOf = function workspaceOf(botId, fallback) {
77263
+ var bot = monitor.botById ? monitor.botById(botId) : null;
77264
+ var id = bot ? bot.workspaceId : fallback;
77265
+ return id === null || id === undefined ? null : String(id);
77266
+ };
77267
+ var label = function label(botId, name, workspaceId) {
77268
+ return "".concat(name, " \xB7 ").concat(dashboardName(workspaceId));
77269
+ };
77270
+ var openAction = function openAction(botId, workspaceId, tab) {
77271
+ if (workspaceId !== null && onOpenBotsView) {
77272
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
77273
+ title: "Open in Bots view",
77274
+ size: "sm",
77275
+ onClick: function onClick() {
77276
+ return onOpenBotsView(workspaceId, botId, tab);
77277
+ }
77278
+ });
77279
+ }
77280
+ if (workspaceId === null && onOpenSettings) {
77281
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
77282
+ title: "Open in Settings",
77283
+ size: "sm",
77284
+ onClick: function onClick() {
77285
+ return onOpenSettings(botId);
77286
+ }
77287
+ });
77288
+ }
77289
+ return null;
77290
+ };
77291
+ var sectionHeader = function sectionHeader(text, count) {
77292
+ return /*#__PURE__*/jsxRuntime.jsxs("h3", {
77293
+ className: "text-sm font-semibold ".concat(strong),
77294
+ children: [text, count ? /*#__PURE__*/jsxRuntime.jsxs("span", {
77295
+ className: "font-normal ".concat(muted),
77296
+ children: [" \xB7 ", count]
77297
+ }) : null]
77298
+ });
77299
+ };
77300
+ var nothing = !approvals.length && !running.length && !recent.length;
77301
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
77302
+ className: "flex flex-col gap-5 p-4 ".concat(strong),
77303
+ children: [nothing && !monitor.loading ? /*#__PURE__*/jsxRuntime.jsx("div", {
77304
+ className: "text-sm ".concat(muted),
77305
+ children: "All quiet \u2014 no approvals waiting, nothing running, no runs yet. Start a bot from a dashboard's Bots view."
77306
+ }) : null, approvals.length ? /*#__PURE__*/jsxRuntime.jsxs("section", {
77307
+ "aria-label": "Needs you",
77308
+ className: "flex flex-col gap-2",
77309
+ children: [sectionHeader("Needs you", approvals.length), approvals.map(function (a) {
77310
+ var req = a.request || {};
77311
+ var bot = monitor.botById ? monitor.botById(req.botId) : null;
77312
+ var ws = workspaceOf(req.botId, null);
77313
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
77314
+ className: "rounded-lg border border-amber-700 px-3 py-2.5 flex flex-col gap-2",
77315
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
77316
+ className: "text-sm font-medium",
77317
+ children: label(req.botId, bot ? bot.name : "A bot", ws)
77318
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
77319
+ className: "text-xs ".concat(muted),
77320
+ children: ["Wants to use", " ", /*#__PURE__*/jsxRuntime.jsx("span", {
77321
+ className: "font-mono",
77322
+ children: req.toolName || "a tool"
77323
+ }), req.serverName ? " on ".concat(req.serverName) : " (built-in)"]
77324
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
77325
+ className: "flex flex-row flex-wrap items-center gap-2",
77326
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
77327
+ title: "Allow once",
77328
+ size: "sm",
77329
+ onClick: function onClick() {
77330
+ return monitor.approve(a.id, {
77331
+ allow: true
77332
+ });
77333
+ }
77334
+ }), req.serverName ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
77335
+ title: "Always allow",
77336
+ size: "sm",
77337
+ onClick: function onClick() {
77338
+ return monitor.approve(a.id, {
77339
+ allow: true,
77340
+ remember: true
77341
+ });
77342
+ }
77343
+ }) : null, /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
77344
+ title: "Deny",
77345
+ size: "sm",
77346
+ onClick: function onClick() {
77347
+ return monitor.approve(a.id, {
77348
+ allow: false
77349
+ });
77350
+ }
77351
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
77352
+ className: "flex-1"
77353
+ }), openAction(req.botId, ws, "conversation")]
77354
+ })]
77355
+ }, a.id);
77356
+ })]
77357
+ }) : null, running.length ? /*#__PURE__*/jsxRuntime.jsxs("section", {
77358
+ "aria-label": "Running now",
77359
+ className: "flex flex-col gap-2",
77360
+ children: [sectionHeader("Running now", running.length), running.map(function (r) {
77361
+ var ws = workspaceOf(r.id, r.workspaceId);
77362
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
77363
+ className: "rounded-lg border px-3 py-2.5 flex flex-col gap-1.5 ".concat(hairline),
77364
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
77365
+ className: "flex flex-row items-center gap-2",
77366
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
77367
+ className: "h-2 w-2 rounded-full flex-shrink-0 bg-indigo-400"
77368
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
77369
+ className: "text-sm font-medium truncate",
77370
+ children: label(r.id, r.name, ws)
77371
+ })]
77372
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
77373
+ className: "flex flex-row items-center gap-2",
77374
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
77375
+ className: "text-xs ".concat(muted),
77376
+ children: runningFor(r.startedAt, now)
77377
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
77378
+ className: "flex-1"
77379
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
77380
+ title: "Stop",
77381
+ size: "sm",
77382
+ onClick: function onClick() {
77383
+ return monitor.stop(r.id);
77384
+ }
77385
+ }), openAction(r.id, ws, "conversation")]
77386
+ })]
77387
+ }, r.id);
77388
+ })]
77389
+ }) : null, recent.length ? /*#__PURE__*/jsxRuntime.jsxs("section", {
77390
+ "aria-label": "Recent",
77391
+ className: "flex flex-col gap-1",
77392
+ children: [sectionHeader("Recent runs", recent.length), recent.map(function (item, i) {
77393
+ var ws = workspaceOf(item.botId, item.workspaceId);
77394
+ var run = item.run || {};
77395
+ var canOpen = ws !== null && onOpenBotsView || ws === null && onOpenSettings;
77396
+ var open = function open() {
77397
+ if (ws !== null && onOpenBotsView) {
77398
+ onOpenBotsView(ws, item.botId, "activity");
77399
+ } else if (ws === null && onOpenSettings) {
77400
+ onOpenSettings(item.botId);
77401
+ }
77402
+ };
77403
+ var when = relativeTime(run.endedAt || run.at, now);
77404
+ var result = firstLine(run) || statusLabel(run.status);
77405
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.ListRow, {
77406
+ icon: /*#__PURE__*/jsxRuntime.jsx("span", {
77407
+ role: "img",
77408
+ "aria-label": statusLabel(run.status),
77409
+ title: statusLabel(run.status),
77410
+ className: "inline-block mt-1 h-2 w-2 rounded-full ".concat(dotClass(run.status))
77411
+ }),
77412
+ title: result,
77413
+ meta: [label(item.botId, item.botName, ws), when].filter(Boolean).join(" · "),
77414
+ onClick: canOpen ? open : null
77415
+ }, "".concat(item.botId, "-").concat(i));
77416
+ })]
77417
+ }) : null]
77418
+ });
77419
+ };
77420
+
77421
+ function lastRunWhen(run) {
77422
+ var s = run && run.status;
77423
+ var word = s ? s.charAt(0).toUpperCase() + s.slice(1) : "";
77424
+ var when = relativeTime(run && (run.endedAt || run.at || run.startedAt));
77425
+ return [word, when].filter(Boolean).join(" · ");
77426
+ }
77427
+
77428
+ // A run's answer as words: the Scout's <matches> and the Planner's <plan>
77429
+ // blocks are for the app, not to read (QA 2026-10-22: a raw tag showed).
77154
77430
  function answerText(output) {
77155
77431
  return withoutMatches(output).replace(/<plan>[\s\S]*?<\/plan>/gi, "").trim();
77156
77432
  }
@@ -77393,12 +77669,21 @@ var DashTeamPanel = function DashTeamPanel(_ref) {
77393
77669
  title: "Last run",
77394
77670
  children: lastRun ? /*#__PURE__*/jsxRuntime.jsxs("div", {
77395
77671
  className: "flex flex-col gap-1 min-w-0",
77396
- children: [runCostLabel(lastRun) ? /*#__PURE__*/jsxRuntime.jsx("span", {
77672
+ children: [lastRunWhen(lastRun) ? /*#__PURE__*/jsxRuntime.jsx("span", {
77673
+ className: "text-sm",
77674
+ children: lastRunWhen(lastRun)
77675
+ }) : null, runCostLabel(lastRun) ? /*#__PURE__*/jsxRuntime.jsx("span", {
77397
77676
  className: "text-xs ".concat(muted),
77398
77677
  children: runCostLabel(lastRun)
77399
77678
  }) : null, lastRun.error || answerText(lastRun.output) ? /*#__PURE__*/jsxRuntime.jsx("span", {
77400
77679
  className: "text-sm line-clamp-3 ".concat(muted),
77401
77680
  children: toPlainText(lastRun.error || answerText(lastRun.output))
77681
+ }) : lastRun.status === "stopped" ? /*#__PURE__*/jsxRuntime.jsx("span", {
77682
+ className: "text-sm ".concat(muted),
77683
+ children: "Stopped before it answered."
77684
+ }) : lastRun.status === "interrupted" ? /*#__PURE__*/jsxRuntime.jsx("span", {
77685
+ className: "text-sm ".concat(muted),
77686
+ children: INTERRUPTED_TEXT
77402
77687
  }) : null]
77403
77688
  }) : /*#__PURE__*/jsxRuntime.jsx("span", {
77404
77689
  className: "text-sm ".concat(muted),
@@ -77415,7 +77700,7 @@ var DashTeamPanel = function DashTeamPanel(_ref) {
77415
77700
  * last run (one `listRecentRuns` call, not one request per bot). Mirrors
77416
77701
  * useTeamBots without the team filter.
77417
77702
  */
77418
- var EMPTY$4 = [];
77703
+ var EMPTY$3 = [];
77419
77704
  var NOT_PAUSED = {
77420
77705
  global: false,
77421
77706
  bots: []
@@ -77425,16 +77710,16 @@ function api$4() {
77425
77710
  return typeof window !== "undefined" && window.mainApi ? window.mainApi.bots : null;
77426
77711
  }
77427
77712
  function useAllBots() {
77428
- var _useState = React.useState(EMPTY$4),
77713
+ var _useState = React.useState(EMPTY$3),
77429
77714
  _useState2 = _slicedToArray(_useState, 2),
77430
77715
  bots = _useState2[0],
77431
77716
  setBots = _useState2[1];
77432
77717
  // The Dash team's role bots (CRE-011) — not in list().
77433
- var _useState3 = React.useState(EMPTY$4),
77718
+ var _useState3 = React.useState(EMPTY$3),
77434
77719
  _useState4 = _slicedToArray(_useState3, 2),
77435
77720
  dashTeam = _useState4[0],
77436
77721
  setDashTeam = _useState4[1];
77437
- var _useState5 = React.useState(EMPTY$4),
77722
+ var _useState5 = React.useState(EMPTY$3),
77438
77723
  _useState6 = _slicedToArray(_useState5, 2),
77439
77724
  running = _useState6[0],
77440
77725
  setRunning = _useState6[1];
@@ -77442,7 +77727,7 @@ function useAllBots() {
77442
77727
  _useState8 = _slicedToArray(_useState7, 2),
77443
77728
  paused = _useState8[0],
77444
77729
  setPaused = _useState8[1];
77445
- var _useState9 = React.useState(EMPTY$4),
77730
+ var _useState9 = React.useState(EMPTY$3),
77446
77731
  _useState0 = _slicedToArray(_useState9, 2),
77447
77732
  approvals = _useState0[0],
77448
77733
  setApprovals = _useState0[1];
@@ -77499,7 +77784,7 @@ function useAllBots() {
77499
77784
  case 1:
77500
77785
  _context2.prev = 1;
77501
77786
  _context2.next = 2;
77502
- 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()]);
77787
+ 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()]);
77503
77788
  case 2:
77504
77789
  _yield$Promise$all = _context2.sent;
77505
77790
  _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 5);
@@ -77508,13 +77793,13 @@ function useAllBots() {
77508
77793
  pause = _yield$Promise$all2[2];
77509
77794
  pending = _yield$Promise$all2[3];
77510
77795
  team = _yield$Promise$all2[4];
77511
- setBots(Array.isArray(list) ? list : EMPTY$4);
77512
- setDashTeam(Array.isArray(team) ? team : EMPTY$4);
77796
+ setBots(Array.isArray(list) ? list : EMPTY$3);
77797
+ setDashTeam(Array.isArray(team) ? team : EMPTY$3);
77513
77798
  setRunning((run || []).map(function (r) {
77514
77799
  return r && r.id || r;
77515
77800
  }));
77516
77801
  setPaused(pause || NOT_PAUSED);
77517
- setApprovals(pending || EMPTY$4);
77802
+ setApprovals(pending || EMPTY$3);
77518
77803
  _context2.next = 4;
77519
77804
  break;
77520
77805
  case 3:
@@ -77539,14 +77824,14 @@ function useAllBots() {
77539
77824
  var ids = [];
77540
77825
  if (b.onRunActive) {
77541
77826
  ids.push(b.onRunActive(function (payload) {
77542
- return setRunning(payload && payload.running || EMPTY$4);
77827
+ return setRunning(payload && payload.running || EMPTY$3);
77543
77828
  }));
77544
77829
  }
77545
77830
  // The whole queue after any change (answered anywhere, denied, timed
77546
77831
  // out) — replaces this copy, so answered approvals disappear here too.
77547
77832
  if (b.onApprovalsChanged) {
77548
77833
  ids.push(b.onApprovalsChanged(function (p) {
77549
- return setApprovals(p && p.approvals || EMPTY$4);
77834
+ return setApprovals(p && p.approvals || EMPTY$3);
77550
77835
  }));
77551
77836
  }
77552
77837
  if (b.onApprovalPending) {
@@ -78424,18 +78709,18 @@ var TABS = [{
78424
78709
  label: "Settings"
78425
78710
  }];
78426
78711
  var ROLE_ORDER = ["planner", "scout", "builder", "checker"];
78427
- var EMPTY$3 = [];
78712
+ var EMPTY$2 = [];
78428
78713
  function botsApi() {
78429
78714
  return typeof window !== "undefined" && window.mainApi ? window.mainApi.bots : null;
78430
78715
  }
78431
78716
  var getWidgetConfig$3 = function getWidgetConfig(name) {
78432
78717
  return name && ComponentManager.config(name) || null;
78433
78718
  };
78434
- var TICK_MS$2 = 60000;
78719
+ var TICK_MS$1 = 60000;
78435
78720
 
78436
78721
  /** The questions in Recent, live; their ages kept current. */
78437
78722
  function useThreads() {
78438
- var _useState = React.useState(EMPTY$3),
78723
+ var _useState = React.useState(EMPTY$2),
78439
78724
  _useState2 = _slicedToArray(_useState, 2),
78440
78725
  entries = _useState2[0],
78441
78726
  setEntries = _useState2[1];
@@ -78452,7 +78737,7 @@ function useThreads() {
78452
78737
  React.useEffect(function () {
78453
78738
  var t = setInterval(function () {
78454
78739
  return setNow(Date.now());
78455
- }, TICK_MS$2);
78740
+ }, TICK_MS$1);
78456
78741
  return function () {
78457
78742
  return clearInterval(t);
78458
78743
  };
@@ -78467,7 +78752,7 @@ function useThreads() {
78467
78752
  }
78468
78753
  Promise.resolve(b.listCreateRecent()).then(function (l) {
78469
78754
  if (!alive) return;
78470
- setEntries(Array.isArray(l) ? l : EMPTY$3);
78755
+ setEntries(Array.isArray(l) ? l : EMPTY$2);
78471
78756
  setNow(Date.now());
78472
78757
  setLoaded(true);
78473
78758
  })["catch"](function () {
@@ -78795,7 +79080,7 @@ var DashTeamPage = function DashTeamPage(_ref4) {
78795
79080
  var _ref4$initialTab = _ref4.initialTab,
78796
79081
  initialTab = _ref4$initialTab === void 0 ? "conversation" : _ref4$initialTab,
78797
79082
  _ref4$workspaces = _ref4.workspaces,
78798
- workspaces = _ref4$workspaces === void 0 ? EMPTY$3 : _ref4$workspaces,
79083
+ workspaces = _ref4$workspaces === void 0 ? EMPTY$2 : _ref4$workspaces,
78799
79084
  _ref4$onOpenPlan = _ref4.onOpenPlan,
78800
79085
  onOpenPlan = _ref4$onOpenPlan === void 0 ? null : _ref4$onOpenPlan,
78801
79086
  _ref4$onClose = _ref4.onClose,
@@ -78936,7 +79221,7 @@ var DashTeamPage = function DashTeamPage(_ref4) {
78936
79221
  });
78937
79222
  };
78938
79223
 
78939
- var EMPTY$2 = [];
79224
+ var EMPTY$1 = [];
78940
79225
 
78941
79226
  /**
78942
79227
  * BotPageModal — the bot page (BotPage) in a large modal, opened from the
@@ -78962,7 +79247,7 @@ var BotPageModal = function BotPageModal(_ref) {
78962
79247
  request = _ref$request === void 0 ? null : _ref$request,
78963
79248
  onClose = _ref.onClose,
78964
79249
  _ref$workspaces = _ref.workspaces,
78965
- workspaces = _ref$workspaces === void 0 ? EMPTY$2 : _ref$workspaces,
79250
+ workspaces = _ref$workspaces === void 0 ? EMPTY$1 : _ref$workspaces,
78966
79251
  _ref$onOpenInBotsView = _ref.onOpenInBotsView,
78967
79252
  onOpenInBotsView = _ref$onOpenInBotsView === void 0 ? null : _ref$onOpenInBotsView,
78968
79253
  _ref$onOpenSettings = _ref.onOpenSettings,
@@ -79145,250 +79430,6 @@ function usePendingApprovalCount() {
79145
79430
  return count;
79146
79431
  }
79147
79432
 
79148
- var EMPTY$1 = [];
79149
- // Which status token colours each run state's dot.
79150
- var STATUS_TONE = {
79151
- completed: "success",
79152
- failed: "error",
79153
- running: "info"
79154
- };
79155
- var TICK_MS$1 = 30000;
79156
- function relativeTime(iso) {
79157
- var now = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Date.now();
79158
- var t = iso ? Date.parse(iso) : NaN;
79159
- if (Number.isNaN(t)) return "";
79160
- var min = Math.floor((now - t) / 60000);
79161
- if (min < 1) return "just now";
79162
- if (min < 60) return "".concat(min, " min ago");
79163
- var h = Math.floor(min / 60);
79164
- if (h < 24) return "".concat(h, " h ago");
79165
- return new Date(t).toLocaleDateString(undefined, {
79166
- month: "short",
79167
- day: "numeric"
79168
- });
79169
- }
79170
- function runningFor(iso, now) {
79171
- var t = iso ? Date.parse(iso) : NaN;
79172
- if (Number.isNaN(t)) return "Running";
79173
- var min = Math.floor((now - t) / 60000);
79174
- return min < 1 ? "Running · just started" : "Running \xB7 ".concat(min, " min");
79175
- }
79176
- function statusLabel(s) {
79177
- return s ? s.charAt(0).toUpperCase() + s.slice(1) : "Unknown";
79178
- }
79179
- function firstLine(run) {
79180
- if (run.status === "failed" && run.error) return run.error;
79181
- if (run.outputUnavailable) return "Answer unavailable";
79182
- if (run.status === "interrupted" && !run.output) return INTERRUPTED_TEXT;
79183
- return toPlainText(run.output || "").split("\n")[0];
79184
- }
79185
- var BotMonitor = function BotMonitor(_ref) {
79186
- var monitor = _ref.monitor,
79187
- _ref$workspaces = _ref.workspaces,
79188
- workspaces = _ref$workspaces === void 0 ? EMPTY$1 : _ref$workspaces,
79189
- _ref$onOpenBotsView = _ref.onOpenBotsView,
79190
- onOpenBotsView = _ref$onOpenBotsView === void 0 ? null : _ref$onOpenBotsView,
79191
- _ref$onOpenSettings = _ref.onOpenSettings,
79192
- onOpenSettings = _ref$onOpenSettings === void 0 ? null : _ref$onOpenSettings;
79193
- var currentTheme = (React.useContext(DashReact.ThemeContext) || {}).currentTheme || {};
79194
- var muted = currentTheme["text-neutral-medium"] || "text-gray-400";
79195
- var strong = currentTheme["text-neutral-light"] || "text-gray-200";
79196
- var hairline = currentTheme["border-neutral-dark"] || "border-gray-700";
79197
- var statusTokens = DashReact.useStatusTokens();
79198
- var dotClass = function dotClass(status) {
79199
- return STATUS_TONE[status] ? statusTokens[STATUS_TONE[status]].solidBg : currentTheme["bg-neutral-medium"] || "";
79200
- };
79201
-
79202
- // Re-render periodically so "5 min ago" / "Running · 3 min" stay true.
79203
- var _useState = React.useState(function () {
79204
- return Date.now();
79205
- }),
79206
- _useState2 = _slicedToArray(_useState, 2),
79207
- now = _useState2[0],
79208
- setNow = _useState2[1];
79209
- React.useEffect(function () {
79210
- var t = setInterval(function () {
79211
- return setNow(Date.now());
79212
- }, TICK_MS$1);
79213
- return function () {
79214
- return clearInterval(t);
79215
- };
79216
- }, []);
79217
- if (!monitor) return null;
79218
- var _monitor$approvals = monitor.approvals,
79219
- approvals = _monitor$approvals === void 0 ? EMPTY$1 : _monitor$approvals,
79220
- _monitor$running = monitor.running,
79221
- running = _monitor$running === void 0 ? EMPTY$1 : _monitor$running,
79222
- _monitor$recent = monitor.recent,
79223
- recent = _monitor$recent === void 0 ? EMPTY$1 : _monitor$recent;
79224
- var dashboardName = function dashboardName(workspaceId) {
79225
- if (workspaceId === null || workspaceId === undefined) {
79226
- return "No dashboard";
79227
- }
79228
- var ws = workspaces.find(function (w) {
79229
- return String(w.id) === String(workspaceId);
79230
- });
79231
- return ws ? ws.name : "Unknown dashboard";
79232
- };
79233
- var workspaceOf = function workspaceOf(botId, fallback) {
79234
- var bot = monitor.botById ? monitor.botById(botId) : null;
79235
- var id = bot ? bot.workspaceId : fallback;
79236
- return id === null || id === undefined ? null : String(id);
79237
- };
79238
- var label = function label(botId, name, workspaceId) {
79239
- return "".concat(name, " \xB7 ").concat(dashboardName(workspaceId));
79240
- };
79241
- var openAction = function openAction(botId, workspaceId, tab) {
79242
- if (workspaceId !== null && onOpenBotsView) {
79243
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
79244
- title: "Open in Bots view",
79245
- size: "sm",
79246
- onClick: function onClick() {
79247
- return onOpenBotsView(workspaceId, botId, tab);
79248
- }
79249
- });
79250
- }
79251
- if (workspaceId === null && onOpenSettings) {
79252
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
79253
- title: "Open in Settings",
79254
- size: "sm",
79255
- onClick: function onClick() {
79256
- return onOpenSettings(botId);
79257
- }
79258
- });
79259
- }
79260
- return null;
79261
- };
79262
- var sectionHeader = function sectionHeader(text, count) {
79263
- return /*#__PURE__*/jsxRuntime.jsxs("h3", {
79264
- className: "text-sm font-semibold ".concat(strong),
79265
- children: [text, count ? /*#__PURE__*/jsxRuntime.jsxs("span", {
79266
- className: "font-normal ".concat(muted),
79267
- children: [" \xB7 ", count]
79268
- }) : null]
79269
- });
79270
- };
79271
- var nothing = !approvals.length && !running.length && !recent.length;
79272
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
79273
- className: "flex flex-col gap-5 p-4 ".concat(strong),
79274
- children: [nothing && !monitor.loading ? /*#__PURE__*/jsxRuntime.jsx("div", {
79275
- className: "text-sm ".concat(muted),
79276
- children: "All quiet \u2014 no approvals waiting, nothing running, no runs yet. Start a bot from a dashboard's Bots view."
79277
- }) : null, approvals.length ? /*#__PURE__*/jsxRuntime.jsxs("section", {
79278
- "aria-label": "Needs you",
79279
- className: "flex flex-col gap-2",
79280
- children: [sectionHeader("Needs you", approvals.length), approvals.map(function (a) {
79281
- var req = a.request || {};
79282
- var bot = monitor.botById ? monitor.botById(req.botId) : null;
79283
- var ws = workspaceOf(req.botId, null);
79284
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
79285
- className: "rounded-lg border border-amber-700 px-3 py-2.5 flex flex-col gap-2",
79286
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
79287
- className: "text-sm font-medium",
79288
- children: label(req.botId, bot ? bot.name : "A bot", ws)
79289
- }), /*#__PURE__*/jsxRuntime.jsxs("span", {
79290
- className: "text-xs ".concat(muted),
79291
- children: ["Wants to use", " ", /*#__PURE__*/jsxRuntime.jsx("span", {
79292
- className: "font-mono",
79293
- children: req.toolName || "a tool"
79294
- }), req.serverName ? " on ".concat(req.serverName) : " (built-in)"]
79295
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
79296
- className: "flex flex-row flex-wrap items-center gap-2",
79297
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
79298
- title: "Allow once",
79299
- size: "sm",
79300
- onClick: function onClick() {
79301
- return monitor.approve(a.id, {
79302
- allow: true
79303
- });
79304
- }
79305
- }), req.serverName ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
79306
- title: "Always allow",
79307
- size: "sm",
79308
- onClick: function onClick() {
79309
- return monitor.approve(a.id, {
79310
- allow: true,
79311
- remember: true
79312
- });
79313
- }
79314
- }) : null, /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
79315
- title: "Deny",
79316
- size: "sm",
79317
- onClick: function onClick() {
79318
- return monitor.approve(a.id, {
79319
- allow: false
79320
- });
79321
- }
79322
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
79323
- className: "flex-1"
79324
- }), openAction(req.botId, ws, "conversation")]
79325
- })]
79326
- }, a.id);
79327
- })]
79328
- }) : null, running.length ? /*#__PURE__*/jsxRuntime.jsxs("section", {
79329
- "aria-label": "Running now",
79330
- className: "flex flex-col gap-2",
79331
- children: [sectionHeader("Running now", running.length), running.map(function (r) {
79332
- var ws = workspaceOf(r.id, r.workspaceId);
79333
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
79334
- className: "rounded-lg border px-3 py-2.5 flex flex-col gap-1.5 ".concat(hairline),
79335
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
79336
- className: "flex flex-row items-center gap-2",
79337
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
79338
- className: "h-2 w-2 rounded-full flex-shrink-0 bg-indigo-400"
79339
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
79340
- className: "text-sm font-medium truncate",
79341
- children: label(r.id, r.name, ws)
79342
- })]
79343
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
79344
- className: "flex flex-row items-center gap-2",
79345
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
79346
- className: "text-xs ".concat(muted),
79347
- children: runningFor(r.startedAt, now)
79348
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
79349
- className: "flex-1"
79350
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
79351
- title: "Stop",
79352
- size: "sm",
79353
- onClick: function onClick() {
79354
- return monitor.stop(r.id);
79355
- }
79356
- }), openAction(r.id, ws, "conversation")]
79357
- })]
79358
- }, r.id);
79359
- })]
79360
- }) : null, recent.length ? /*#__PURE__*/jsxRuntime.jsxs("section", {
79361
- "aria-label": "Recent",
79362
- className: "flex flex-col gap-1",
79363
- children: [sectionHeader("Recent runs", recent.length), recent.map(function (item, i) {
79364
- var ws = workspaceOf(item.botId, item.workspaceId);
79365
- var run = item.run || {};
79366
- var canOpen = ws !== null && onOpenBotsView || ws === null && onOpenSettings;
79367
- var open = function open() {
79368
- if (ws !== null && onOpenBotsView) {
79369
- onOpenBotsView(ws, item.botId, "activity");
79370
- } else if (ws === null && onOpenSettings) {
79371
- onOpenSettings(item.botId);
79372
- }
79373
- };
79374
- var when = relativeTime(run.endedAt || run.at, now);
79375
- var result = firstLine(run) || statusLabel(run.status);
79376
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.ListRow, {
79377
- icon: /*#__PURE__*/jsxRuntime.jsx("span", {
79378
- role: "img",
79379
- "aria-label": statusLabel(run.status),
79380
- title: statusLabel(run.status),
79381
- className: "inline-block mt-1 h-2 w-2 rounded-full ".concat(dotClass(run.status))
79382
- }),
79383
- title: result,
79384
- meta: [label(item.botId, item.botName, ws), when].filter(Boolean).join(" · "),
79385
- onClick: canOpen ? open : null
79386
- }, "".concat(item.botId, "-").concat(i));
79387
- })]
79388
- }) : null]
79389
- });
79390
- };
79391
-
79392
79433
  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; }
79393
79434
  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; }
79394
79435
  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; } } }; }
@@ -90976,7 +91017,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
90976
91017
  menuId = menuItems && menuItems.length > 0 ? menuItems[0].id : 1;
90977
91018
  _context6.prev = 1;
90978
91019
  _context6.next = 2;
90979
- return handleCreateFromTemplate(createLayoutFromTemplate(layoutTemplates[0], menuId), themeKey || null, "Untitled dashboard");
91020
+ return handleCreateFromTemplate(createLayoutFromTemplate(layoutTemplates[0], menuId), themeKey || null,
91021
+ // Told apart from the blank ones already there ("… 2").
91022
+ untitledDashboardName(workspaceConfig));
90980
91023
  case 2:
90981
91024
  _context6.next = 4;
90982
91025
  break;