@trops/dash-core 0.1.637 → 0.1.638

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
@@ -47421,6 +47421,12 @@ function prettyServer(name) {
47421
47421
  return w.charAt(0).toUpperCase() + w.slice(1);
47422
47422
  }).join(" ");
47423
47423
  }
47424
+
47425
+ // "search_emails" / "list-calendars" → "Search emails" / "List calendars".
47426
+ function prettyTool(name) {
47427
+ var words = String(name || "").split(/[-_\s]+/).filter(Boolean).join(" ");
47428
+ return words.charAt(0).toUpperCase() + words.slice(1);
47429
+ }
47424
47430
  function getMainApi() {
47425
47431
  return typeof window !== "undefined" ? window.mainApi : null;
47426
47432
  }
@@ -47460,77 +47466,87 @@ var BotDetail = function BotDetail(_ref) {
47460
47466
  approvalPolicy = _useState10[0],
47461
47467
  setApprovalPolicy = _useState10[1];
47462
47468
 
47463
- // --- Tools & integrations (MCP servers) ---
47469
+ // --- Providers: the user's Dash MCP providers (Settings → Providers) ---
47464
47470
  var _useState11 = useState((bot === null || bot === void 0 ? void 0 : bot.mcpServers) || []),
47465
47471
  _useState12 = _slicedToArray(_useState11, 2),
47466
47472
  selectedServers = _useState12[0],
47467
47473
  setSelectedServers = _useState12[1];
47468
- var _useState13 = useState([]),
47474
+ // Per-provider narrowing within the provider's declared tools:
47475
+ // { [providerName]: string[] }. No entry → every tool the provider allows.
47476
+ var _useState13 = useState((bot === null || bot === void 0 ? void 0 : bot.toolSelections) || {}),
47469
47477
  _useState14 = _slicedToArray(_useState13, 2),
47470
- connectedServers = _useState14[0],
47471
- setConnectedServers = _useState14[1];
47472
-
47473
- // --- Model options (fetched per provider) ---
47478
+ toolSelections = _useState14[0],
47479
+ setToolSelections = _useState14[1];
47474
47480
  var _useState15 = useState([]),
47475
47481
  _useState16 = _slicedToArray(_useState15, 2),
47476
- modelOptions = _useState16[0],
47477
- setModelOptions = _useState16[1];
47482
+ toolSources = _useState16[0],
47483
+ setToolSources = _useState16[1];
47484
+ var _useState17 = useState(false),
47485
+ _useState18 = _slicedToArray(_useState17, 2),
47486
+ sourcesLoaded = _useState18[0],
47487
+ setSourcesLoaded = _useState18[1];
47488
+
47489
+ // --- Model options (fetched per provider) ---
47490
+ var _useState19 = useState([]),
47491
+ _useState20 = _slicedToArray(_useState19, 2),
47492
+ modelOptions = _useState20[0],
47493
+ setModelOptions = _useState20[1];
47478
47494
 
47479
47495
  // --- Schedule (friendly dropdowns; raw cron behind Advanced) ---
47480
47496
  var initialCron = (bot === null || bot === void 0 || (_bot$schedules = bot.schedules) === null || _bot$schedules === void 0 || (_bot$schedules = _bot$schedules[0]) === null || _bot$schedules === void 0 ? void 0 : _bot$schedules.cron) || "";
47481
47497
  var parsed = parseCron(initialCron);
47482
- var _useState17 = useState(parsed.frequency === "custom" ? "off" : parsed.frequency),
47483
- _useState18 = _slicedToArray(_useState17, 2),
47484
- frequency = _useState18[0],
47485
- setFrequency = _useState18[1];
47486
- var _useState19 = useState(parsed.time || DEFAULT_SCHEDULE.time),
47487
- _useState20 = _slicedToArray(_useState19, 2),
47488
- time = _useState20[0],
47489
- setTime = _useState20[1];
47490
- var _useState21 = useState(parsed.dayOfWeek || DEFAULT_SCHEDULE.dayOfWeek),
47498
+ var _useState21 = useState(parsed.frequency === "custom" ? "off" : parsed.frequency),
47491
47499
  _useState22 = _slicedToArray(_useState21, 2),
47492
- dayOfWeek = _useState22[0],
47493
- setDayOfWeek = _useState22[1];
47494
- var _useState23 = useState(parsed.dayOfMonth || DEFAULT_SCHEDULE.dayOfMonth),
47500
+ frequency = _useState22[0],
47501
+ setFrequency = _useState22[1];
47502
+ var _useState23 = useState(parsed.time || DEFAULT_SCHEDULE.time),
47495
47503
  _useState24 = _slicedToArray(_useState23, 2),
47496
- dayOfMonth = _useState24[0],
47497
- setDayOfMonth = _useState24[1];
47498
- var _useState25 = useState(parsed.frequency === "custom"),
47504
+ time = _useState24[0],
47505
+ setTime = _useState24[1];
47506
+ var _useState25 = useState(parsed.dayOfWeek || DEFAULT_SCHEDULE.dayOfWeek),
47499
47507
  _useState26 = _slicedToArray(_useState25, 2),
47500
- advanced = _useState26[0],
47501
- setAdvanced = _useState26[1];
47502
- var _useState27 = useState(initialCron),
47508
+ dayOfWeek = _useState26[0],
47509
+ setDayOfWeek = _useState26[1];
47510
+ var _useState27 = useState(parsed.dayOfMonth || DEFAULT_SCHEDULE.dayOfMonth),
47503
47511
  _useState28 = _slicedToArray(_useState27, 2),
47504
- advancedCron = _useState28[0],
47505
- setAdvancedCron = _useState28[1];
47506
- var _useState29 = useState((bot === null || bot === void 0 || (_bot$schedules2 = bot.schedules) === null || _bot$schedules2 === void 0 || (_bot$schedules2 = _bot$schedules2[0]) === null || _bot$schedules2 === void 0 ? void 0 : _bot$schedules2.prompt) || ""),
47512
+ dayOfMonth = _useState28[0],
47513
+ setDayOfMonth = _useState28[1];
47514
+ var _useState29 = useState(parsed.frequency === "custom"),
47507
47515
  _useState30 = _slicedToArray(_useState29, 2),
47508
- schedulePrompt = _useState30[0],
47509
- setSchedulePrompt = _useState30[1];
47516
+ advanced = _useState30[0],
47517
+ setAdvanced = _useState30[1];
47518
+ var _useState31 = useState(initialCron),
47519
+ _useState32 = _slicedToArray(_useState31, 2),
47520
+ advancedCron = _useState32[0],
47521
+ setAdvancedCron = _useState32[1];
47522
+ var _useState33 = useState((bot === null || bot === void 0 || (_bot$schedules2 = bot.schedules) === null || _bot$schedules2 === void 0 || (_bot$schedules2 = _bot$schedules2[0]) === null || _bot$schedules2 === void 0 ? void 0 : _bot$schedules2.prompt) || ""),
47523
+ _useState34 = _slicedToArray(_useState33, 2),
47524
+ schedulePrompt = _useState34[0],
47525
+ setSchedulePrompt = _useState34[1];
47510
47526
 
47511
47527
  // --- Run-on-events (subscriptions) ---
47512
- var _useState31 = useState(((bot === null || bot === void 0 ? void 0 : bot.subscriptions) || []).map(function (s) {
47528
+ var _useState35 = useState(((bot === null || bot === void 0 ? void 0 : bot.subscriptions) || []).map(function (s) {
47513
47529
  return s && s.eventType;
47514
47530
  }).filter(Boolean)),
47515
- _useState32 = _slicedToArray(_useState31, 2),
47516
- subscriptions = _useState32[0],
47517
- setSubscriptions = _useState32[1];
47518
- var _useState33 = useState(""),
47519
- _useState34 = _slicedToArray(_useState33, 2),
47520
- newEvent = _useState34[0],
47521
- setNewEvent = _useState34[1];
47522
- var _useState35 = useState([]),
47523
47531
  _useState36 = _slicedToArray(_useState35, 2),
47524
- knownEvents = _useState36[0],
47525
- setKnownEvents = _useState36[1];
47526
- var _useState37 = useState(false),
47532
+ subscriptions = _useState36[0],
47533
+ setSubscriptions = _useState36[1];
47534
+ var _useState37 = useState(""),
47527
47535
  _useState38 = _slicedToArray(_useState37, 2),
47528
- saving = _useState38[0],
47529
- setSaving = _useState38[1];
47530
- var _useState39 = useState(null),
47536
+ newEvent = _useState38[0],
47537
+ setNewEvent = _useState38[1];
47538
+ var _useState39 = useState([]),
47531
47539
  _useState40 = _slicedToArray(_useState39, 2),
47532
- error = _useState40[0],
47533
- setError = _useState40[1];
47540
+ knownEvents = _useState40[0],
47541
+ setKnownEvents = _useState40[1];
47542
+ var _useState41 = useState(false),
47543
+ _useState42 = _slicedToArray(_useState41, 2),
47544
+ saving = _useState42[0],
47545
+ setSaving = _useState42[1];
47546
+ var _useState43 = useState(null),
47547
+ _useState44 = _slicedToArray(_useState43, 2),
47548
+ error = _useState44[0],
47549
+ setError = _useState44[1];
47534
47550
 
47535
47551
  // Discover recently-seen widget event types to suggest as subscriptions.
47536
47552
  useEffect(function () {
@@ -47546,29 +47562,32 @@ var BotDetail = function BotDetail(_ref) {
47546
47562
  };
47547
47563
  }, []);
47548
47564
 
47549
- // Discover the user's connected integrations for the picker.
47565
+ // Discover the user's configured MCP providers — running or not. The bot
47566
+ // starts any that aren't running when it runs.
47550
47567
  useEffect(function () {
47551
- var _api$llm;
47568
+ var _api$bots;
47552
47569
  var alive = true;
47553
47570
  var api = getMainApi();
47554
- if (!(api !== null && api !== void 0 && (_api$llm = api.llm) !== null && _api$llm !== void 0 && _api$llm.listConnectedTools)) return undefined;
47555
- api.llm.listConnectedTools().then(function (servers) {
47556
- if (!alive || !Array.isArray(servers)) return;
47557
- setConnectedServers(servers.map(function (s) {
47558
- return s.serverName;
47559
- }).filter(Boolean));
47560
- })["catch"](function () {});
47571
+ if (!(api !== null && api !== void 0 && (_api$bots = api.bots) !== null && _api$bots !== void 0 && _api$bots.listToolSources)) {
47572
+ setSourcesLoaded(true);
47573
+ return undefined;
47574
+ }
47575
+ Promise.resolve(api.bots.listToolSources((bot === null || bot === void 0 ? void 0 : bot.workspaceId) || null)).then(function (sources) {
47576
+ if (alive && Array.isArray(sources)) setToolSources(sources);
47577
+ })["catch"](function () {})["finally"](function () {
47578
+ if (alive) setSourcesLoaded(true);
47579
+ });
47561
47580
  return function () {
47562
47581
  alive = false;
47563
47582
  };
47564
- }, []);
47583
+ }, [bot === null || bot === void 0 ? void 0 : bot.workspaceId]);
47565
47584
 
47566
47585
  // Fetch the model list for the chosen provider.
47567
47586
  useEffect(function () {
47568
- var _api$llm2;
47587
+ var _api$llm;
47569
47588
  var alive = true;
47570
47589
  var api = getMainApi();
47571
- if (!(api !== null && api !== void 0 && (_api$llm2 = api.llm) !== null && _api$llm2 !== void 0 && _api$llm2.listModels)) {
47590
+ if (!(api !== null && api !== void 0 && (_api$llm = api.llm) !== null && _api$llm !== void 0 && _api$llm.listModels)) {
47572
47591
  setModelOptions([]);
47573
47592
  return undefined;
47574
47593
  }
@@ -47582,12 +47601,32 @@ var BotDetail = function BotDetail(_ref) {
47582
47601
  };
47583
47602
  }, [provider]);
47584
47603
 
47585
- // Union of connected servers + any the bot already has (so an attached server
47586
- // that isn't currently connected still shows, checked, and isn't dropped).
47587
- var availableServers = _toConsumableArray(new Set([].concat(_toConsumableArray(selectedServers || []), _toConsumableArray(connectedServers)))).map(function (serverName) {
47604
+ // Configured providers + any the bot already has (so a provider that was
47605
+ // since removed still shows, checked, and isn't silently dropped on save).
47606
+ var availableServers = [].concat(_toConsumableArray(toolSources.map(function (s) {
47607
+ return _objectSpread$t(_objectSpread$t({}, s), {}, {
47608
+ missing: false
47609
+ });
47610
+ })), _toConsumableArray((selectedServers || []).filter(function (name) {
47611
+ return !toolSources.some(function (s) {
47612
+ return s.name === name;
47613
+ });
47614
+ }).map(function (name) {
47588
47615
  return {
47589
- serverName: serverName,
47590
- label: prettyServer(serverName)
47616
+ name: name,
47617
+ running: false,
47618
+ toolCount: null,
47619
+ missing: true
47620
+ };
47621
+ }))).map(function (s) {
47622
+ var _s$toolCount;
47623
+ return {
47624
+ serverName: s.name,
47625
+ label: prettyServer(s.name),
47626
+ // The provider's declared tools (or live tools if undeclared + running);
47627
+ // null → every tool, list not known yet.
47628
+ tools: Array.isArray(s.tools) ? s.tools : null,
47629
+ status: s.missing ? "No longer set up under Settings → Providers" : s.running ? "Running \xB7 ".concat((_s$toolCount = s.toolCount) !== null && _s$toolCount !== void 0 ? _s$toolCount : 0, " tools") : "Starts when the bot runs"
47591
47630
  };
47592
47631
  });
47593
47632
  var modelSelectOptions = [{
@@ -47606,6 +47645,35 @@ var BotDetail = function BotDetail(_ref) {
47606
47645
  }) : [].concat(_toConsumableArray(prev), [serverName]);
47607
47646
  });
47608
47647
  };
47648
+
47649
+ // Is `tool` allowed for this bot on `serverName`? No stored selection → yes.
47650
+ var isToolOn = function isToolOn(serverName, tool) {
47651
+ var sel = toolSelections[serverName];
47652
+ return Array.isArray(sel) ? sel.includes(tool) : true;
47653
+ };
47654
+
47655
+ // Toggle one tool. Selecting every tool again clears the entry (= all), so
47656
+ // a later provider-side addition is picked up automatically.
47657
+ var toggleTool = function toggleTool(serverName, allTools, tool) {
47658
+ setToolSelections(function (prev) {
47659
+ var current = Array.isArray(prev[serverName]) ? prev[serverName] : _toConsumableArray(allTools);
47660
+ var next = current.includes(tool) ? current.filter(function (t) {
47661
+ return t !== tool;
47662
+ }) : allTools.filter(function (t) {
47663
+ return t === tool || current.includes(t);
47664
+ });
47665
+ var copy = _objectSpread$t({}, prev);
47666
+ if (next.length === allTools.length) delete copy[serverName];else copy[serverName] = next;
47667
+ return copy;
47668
+ });
47669
+ };
47670
+ var setAllTools = function setAllTools(serverName, on) {
47671
+ setToolSelections(function (prev) {
47672
+ var copy = _objectSpread$t({}, prev);
47673
+ if (on) delete copy[serverName];else copy[serverName] = [];
47674
+ return copy;
47675
+ });
47676
+ };
47609
47677
  var addSubscription = function addSubscription(eventType) {
47610
47678
  var ev = (eventType || "").trim();
47611
47679
  if (!ev) return;
@@ -47654,6 +47722,12 @@ var BotDetail = function BotDetail(_ref) {
47654
47722
  engine: engine || null,
47655
47723
  approvalPolicy: approvalPolicy,
47656
47724
  mcpServers: selectedServers,
47725
+ // Only keep narrowing for providers the bot still uses.
47726
+ toolSelections: Object.fromEntries(Object.entries(toolSelections).filter(function (_ref3) {
47727
+ var _ref4 = _slicedToArray(_ref3, 1),
47728
+ server = _ref4[0];
47729
+ return selectedServers.includes(server);
47730
+ })),
47657
47731
  schedules: schedules,
47658
47732
  subscriptions: subscriptions.map(function (eventType) {
47659
47733
  return {
@@ -47712,57 +47786,113 @@ var BotDetail = function BotDetail(_ref) {
47712
47786
  placeholder: "What should this bot do?",
47713
47787
  rows: 5
47714
47788
  })]
47715
- }), /*#__PURE__*/jsxs("div", {
47716
- className: "flex flex-col gap-1",
47717
- children: [/*#__PURE__*/jsx(SelectInput, {
47718
- label: "Provider",
47719
- value: provider,
47720
- onChange: setProvider,
47721
- options: providerOptionsFrom(providers)
47722
- }), /*#__PURE__*/jsx("span", {
47723
- className: "text-xs opacity-50",
47724
- children: "The AI that runs this bot. \"Claude Code (CLI)\" uses your Claude login \u2014 no API key needed."
47725
- })]
47726
- }), /*#__PURE__*/jsx(SelectInput, {
47727
- label: "Model",
47728
- value: model,
47729
- onChange: setModel,
47730
- options: modelSelectOptions,
47731
- placeholder: "Recommended (default)"
47732
- }), /*#__PURE__*/jsx(SelectInput, {
47733
- label: "Engine",
47734
- value: engine,
47735
- onChange: setEngine,
47736
- options: ENGINE_OPTIONS,
47737
- placeholder: "Standard (default)"
47738
- }), /*#__PURE__*/jsx(SelectInput, {
47739
- label: "Approval policy",
47740
- value: approvalPolicy,
47741
- onChange: setApprovalPolicy,
47742
- options: APPROVAL_OPTIONS
47743
47789
  }), /*#__PURE__*/jsxs("div", {
47744
47790
  className: "flex flex-col gap-2",
47745
47791
  children: [/*#__PURE__*/jsx("span", {
47746
47792
  className: "text-sm font-medium",
47747
- children: "Tools & integrations"
47793
+ children: "Providers"
47794
+ }), /*#__PURE__*/jsx("span", {
47795
+ className: "text-xs opacity-50",
47796
+ children: "What this bot can use \u2014 your MCP providers from Settings \u2192 Providers. The bot starts any that aren't running when it runs."
47748
47797
  }), availableServers.length ? /*#__PURE__*/jsx("div", {
47749
47798
  className: "flex flex-col gap-1",
47750
47799
  children: availableServers.map(function (s) {
47751
- return /*#__PURE__*/jsx(Checkbox, {
47752
- label: s.label,
47753
- checked: selectedServers.includes(s.serverName),
47754
- onChange: function onChange() {
47755
- return toggleServer(s.serverName);
47756
- }
47800
+ var on = selectedServers.includes(s.serverName);
47801
+ return /*#__PURE__*/jsxs("div", {
47802
+ className: "flex flex-col gap-1",
47803
+ children: [/*#__PURE__*/jsxs("div", {
47804
+ className: "flex flex-row items-center justify-between gap-3",
47805
+ children: [/*#__PURE__*/jsx(Checkbox, {
47806
+ label: s.label,
47807
+ checked: on,
47808
+ onChange: function onChange() {
47809
+ return toggleServer(s.serverName);
47810
+ }
47811
+ }), /*#__PURE__*/jsx("span", {
47812
+ className: "text-xs opacity-50",
47813
+ children: s.status
47814
+ })]
47815
+ }), on ? /*#__PURE__*/jsx("div", {
47816
+ className: "flex flex-col gap-1 pl-7 pb-2",
47817
+ children: s.tools && s.tools.length ? /*#__PURE__*/jsxs(Fragment, {
47818
+ children: [/*#__PURE__*/jsxs("div", {
47819
+ className: "flex flex-row items-center gap-2",
47820
+ children: [/*#__PURE__*/jsx("span", {
47821
+ className: "text-xs opacity-50",
47822
+ children: "Tools this bot may use (from the provider's allowed tools):"
47823
+ }), /*#__PURE__*/jsx(Button3, {
47824
+ title: "All",
47825
+ size: "xs",
47826
+ onClick: function onClick() {
47827
+ return setAllTools(s.serverName, true);
47828
+ }
47829
+ }), /*#__PURE__*/jsx(Button3, {
47830
+ title: "None",
47831
+ size: "xs",
47832
+ onClick: function onClick() {
47833
+ return setAllTools(s.serverName, false);
47834
+ }
47835
+ })]
47836
+ }), /*#__PURE__*/jsx("div", {
47837
+ className: "grid grid-cols-2 gap-x-4 gap-y-1",
47838
+ children: s.tools.map(function (tool) {
47839
+ return /*#__PURE__*/jsx(Checkbox, {
47840
+ label: prettyTool(tool),
47841
+ checked: isToolOn(s.serverName, tool),
47842
+ onChange: function onChange() {
47843
+ return toggleTool(s.serverName, s.tools, tool);
47844
+ }
47845
+ }, tool);
47846
+ })
47847
+ })]
47848
+ }) : /*#__PURE__*/jsx("span", {
47849
+ className: "text-xs opacity-50",
47850
+ children: "All tools this provider offers \u2014 it has no tool limit set in Settings \u2192 Providers."
47851
+ })
47852
+ }) : null]
47757
47853
  }, s.serverName);
47758
47854
  })
47759
- }) : /*#__PURE__*/jsx("span", {
47855
+ }) : sourcesLoaded ? /*#__PURE__*/jsx("span", {
47760
47856
  className: "text-xs opacity-50",
47761
- children: "No connected integrations yet. Add one under Settings \u2192 MCP Server, then it will appear here."
47762
- }), /*#__PURE__*/jsx("span", {
47857
+ children: "You haven't set up any MCP providers yet. Add one under Settings \u2192 Providers, then it will appear here."
47858
+ }) : null, /*#__PURE__*/jsx("span", {
47763
47859
  className: "text-xs opacity-50",
47764
- children: "Tools on these integrations route through the approval policy above."
47860
+ children: "Each tool call follows the approval policy below."
47765
47861
  })]
47862
+ }), /*#__PURE__*/jsxs("div", {
47863
+ className: "flex flex-col gap-2",
47864
+ children: [/*#__PURE__*/jsx("span", {
47865
+ className: "text-sm font-medium",
47866
+ children: "AI model"
47867
+ }), /*#__PURE__*/jsxs("div", {
47868
+ className: "flex flex-col gap-1",
47869
+ children: [/*#__PURE__*/jsx(SelectInput, {
47870
+ label: "Model source",
47871
+ value: provider,
47872
+ onChange: setProvider,
47873
+ options: providerOptionsFrom(providers)
47874
+ }), /*#__PURE__*/jsx("span", {
47875
+ className: "text-xs opacity-50",
47876
+ children: "Which AI powers the bot \u2014 an API key from your Anthropic, OpenAI or xAI providers, or \"Claude Code (CLI)\", which uses your Claude login with no API key."
47877
+ })]
47878
+ }), /*#__PURE__*/jsx(SelectInput, {
47879
+ label: "Model",
47880
+ value: model,
47881
+ onChange: setModel,
47882
+ options: modelSelectOptions,
47883
+ placeholder: "Recommended (default)"
47884
+ }), /*#__PURE__*/jsx(SelectInput, {
47885
+ label: "Engine",
47886
+ value: engine,
47887
+ onChange: setEngine,
47888
+ options: ENGINE_OPTIONS,
47889
+ placeholder: "Standard (default)"
47890
+ })]
47891
+ }), /*#__PURE__*/jsx(SelectInput, {
47892
+ label: "Approval policy",
47893
+ value: approvalPolicy,
47894
+ onChange: setApprovalPolicy,
47895
+ options: APPROVAL_OPTIONS
47766
47896
  }), /*#__PURE__*/jsxs("div", {
47767
47897
  className: "flex flex-col gap-2",
47768
47898
  children: [/*#__PURE__*/jsx("span", {