@trops/dash-core 0.1.636 → 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.js CHANGED
@@ -26958,7 +26958,7 @@ var LayoutGridContainer = /*#__PURE__*/React.memo(function (_ref3) {
26958
26958
  })
26959
26959
  }) : useGridLayout ? scrollable ? /*#__PURE__*/jsxRuntime.jsx("div", {
26960
26960
  id: "grid-container-".concat(id),
26961
- className: "grid w-full min-h-24 p-3 ".concat(item.grid.gap || "gap-2"),
26961
+ className: "dr-grid ".concat(!item.grid.gap || item.grid.gap === "gap-2" ? "dr-grid-gap" : "", " grid w-full min-h-24 p-3 ").concat(item.grid.gap || "gap-2"),
26962
26962
  style: {
26963
26963
  gridTemplateRows: getRowTemplate(item.grid),
26964
26964
  gridTemplateColumns: hasExplicitColModes() ? getColTemplate(item.grid) : "repeat(".concat(item.grid.cols, ", 1fr)"),
@@ -26969,7 +26969,7 @@ var LayoutGridContainer = /*#__PURE__*/React.memo(function (_ref3) {
26969
26969
  className: "relative w-full ".concat(height, " min-h-24"),
26970
26970
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
26971
26971
  id: "grid-container-".concat(id),
26972
- className: "absolute inset-0 grid p-3 ".concat(item.grid.gap || "gap-2"),
26972
+ className: "dr-grid ".concat(!item.grid.gap || item.grid.gap === "gap-2" ? "dr-grid-gap" : "", " absolute inset-0 grid p-3 ").concat(item.grid.gap || "gap-2"),
26973
26973
  style: {
26974
26974
  gridTemplateRows: hasExplicitRowModes() ? getRowTemplate(item.grid) : "repeat(".concat(item.grid.rows, ", minmax(0, 1fr))"),
26975
26975
  gridTemplateColumns: hasExplicitColModes() ? getColTemplate(item.grid) : "repeat(".concat(item.grid.cols, ", 1fr)"),
@@ -47439,6 +47439,12 @@ function prettyServer(name) {
47439
47439
  return w.charAt(0).toUpperCase() + w.slice(1);
47440
47440
  }).join(" ");
47441
47441
  }
47442
+
47443
+ // "search_emails" / "list-calendars" → "Search emails" / "List calendars".
47444
+ function prettyTool(name) {
47445
+ var words = String(name || "").split(/[-_\s]+/).filter(Boolean).join(" ");
47446
+ return words.charAt(0).toUpperCase() + words.slice(1);
47447
+ }
47442
47448
  function getMainApi() {
47443
47449
  return typeof window !== "undefined" ? window.mainApi : null;
47444
47450
  }
@@ -47478,77 +47484,87 @@ var BotDetail = function BotDetail(_ref) {
47478
47484
  approvalPolicy = _useState10[0],
47479
47485
  setApprovalPolicy = _useState10[1];
47480
47486
 
47481
- // --- Tools & integrations (MCP servers) ---
47487
+ // --- Providers: the user's Dash MCP providers (Settings → Providers) ---
47482
47488
  var _useState11 = React.useState((bot === null || bot === void 0 ? void 0 : bot.mcpServers) || []),
47483
47489
  _useState12 = _slicedToArray(_useState11, 2),
47484
47490
  selectedServers = _useState12[0],
47485
47491
  setSelectedServers = _useState12[1];
47486
- var _useState13 = React.useState([]),
47492
+ // Per-provider narrowing within the provider's declared tools:
47493
+ // { [providerName]: string[] }. No entry → every tool the provider allows.
47494
+ var _useState13 = React.useState((bot === null || bot === void 0 ? void 0 : bot.toolSelections) || {}),
47487
47495
  _useState14 = _slicedToArray(_useState13, 2),
47488
- connectedServers = _useState14[0],
47489
- setConnectedServers = _useState14[1];
47490
-
47491
- // --- Model options (fetched per provider) ---
47496
+ toolSelections = _useState14[0],
47497
+ setToolSelections = _useState14[1];
47492
47498
  var _useState15 = React.useState([]),
47493
47499
  _useState16 = _slicedToArray(_useState15, 2),
47494
- modelOptions = _useState16[0],
47495
- setModelOptions = _useState16[1];
47500
+ toolSources = _useState16[0],
47501
+ setToolSources = _useState16[1];
47502
+ var _useState17 = React.useState(false),
47503
+ _useState18 = _slicedToArray(_useState17, 2),
47504
+ sourcesLoaded = _useState18[0],
47505
+ setSourcesLoaded = _useState18[1];
47506
+
47507
+ // --- Model options (fetched per provider) ---
47508
+ var _useState19 = React.useState([]),
47509
+ _useState20 = _slicedToArray(_useState19, 2),
47510
+ modelOptions = _useState20[0],
47511
+ setModelOptions = _useState20[1];
47496
47512
 
47497
47513
  // --- Schedule (friendly dropdowns; raw cron behind Advanced) ---
47498
47514
  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) || "";
47499
47515
  var parsed = parseCron(initialCron);
47500
- var _useState17 = React.useState(parsed.frequency === "custom" ? "off" : parsed.frequency),
47501
- _useState18 = _slicedToArray(_useState17, 2),
47502
- frequency = _useState18[0],
47503
- setFrequency = _useState18[1];
47504
- var _useState19 = React.useState(parsed.time || DEFAULT_SCHEDULE.time),
47505
- _useState20 = _slicedToArray(_useState19, 2),
47506
- time = _useState20[0],
47507
- setTime = _useState20[1];
47508
- var _useState21 = React.useState(parsed.dayOfWeek || DEFAULT_SCHEDULE.dayOfWeek),
47516
+ var _useState21 = React.useState(parsed.frequency === "custom" ? "off" : parsed.frequency),
47509
47517
  _useState22 = _slicedToArray(_useState21, 2),
47510
- dayOfWeek = _useState22[0],
47511
- setDayOfWeek = _useState22[1];
47512
- var _useState23 = React.useState(parsed.dayOfMonth || DEFAULT_SCHEDULE.dayOfMonth),
47518
+ frequency = _useState22[0],
47519
+ setFrequency = _useState22[1];
47520
+ var _useState23 = React.useState(parsed.time || DEFAULT_SCHEDULE.time),
47513
47521
  _useState24 = _slicedToArray(_useState23, 2),
47514
- dayOfMonth = _useState24[0],
47515
- setDayOfMonth = _useState24[1];
47516
- var _useState25 = React.useState(parsed.frequency === "custom"),
47522
+ time = _useState24[0],
47523
+ setTime = _useState24[1];
47524
+ var _useState25 = React.useState(parsed.dayOfWeek || DEFAULT_SCHEDULE.dayOfWeek),
47517
47525
  _useState26 = _slicedToArray(_useState25, 2),
47518
- advanced = _useState26[0],
47519
- setAdvanced = _useState26[1];
47520
- var _useState27 = React.useState(initialCron),
47526
+ dayOfWeek = _useState26[0],
47527
+ setDayOfWeek = _useState26[1];
47528
+ var _useState27 = React.useState(parsed.dayOfMonth || DEFAULT_SCHEDULE.dayOfMonth),
47521
47529
  _useState28 = _slicedToArray(_useState27, 2),
47522
- advancedCron = _useState28[0],
47523
- setAdvancedCron = _useState28[1];
47524
- var _useState29 = React.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) || ""),
47530
+ dayOfMonth = _useState28[0],
47531
+ setDayOfMonth = _useState28[1];
47532
+ var _useState29 = React.useState(parsed.frequency === "custom"),
47525
47533
  _useState30 = _slicedToArray(_useState29, 2),
47526
- schedulePrompt = _useState30[0],
47527
- setSchedulePrompt = _useState30[1];
47534
+ advanced = _useState30[0],
47535
+ setAdvanced = _useState30[1];
47536
+ var _useState31 = React.useState(initialCron),
47537
+ _useState32 = _slicedToArray(_useState31, 2),
47538
+ advancedCron = _useState32[0],
47539
+ setAdvancedCron = _useState32[1];
47540
+ var _useState33 = React.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) || ""),
47541
+ _useState34 = _slicedToArray(_useState33, 2),
47542
+ schedulePrompt = _useState34[0],
47543
+ setSchedulePrompt = _useState34[1];
47528
47544
 
47529
47545
  // --- Run-on-events (subscriptions) ---
47530
- var _useState31 = React.useState(((bot === null || bot === void 0 ? void 0 : bot.subscriptions) || []).map(function (s) {
47546
+ var _useState35 = React.useState(((bot === null || bot === void 0 ? void 0 : bot.subscriptions) || []).map(function (s) {
47531
47547
  return s && s.eventType;
47532
47548
  }).filter(Boolean)),
47533
- _useState32 = _slicedToArray(_useState31, 2),
47534
- subscriptions = _useState32[0],
47535
- setSubscriptions = _useState32[1];
47536
- var _useState33 = React.useState(""),
47537
- _useState34 = _slicedToArray(_useState33, 2),
47538
- newEvent = _useState34[0],
47539
- setNewEvent = _useState34[1];
47540
- var _useState35 = React.useState([]),
47541
47549
  _useState36 = _slicedToArray(_useState35, 2),
47542
- knownEvents = _useState36[0],
47543
- setKnownEvents = _useState36[1];
47544
- var _useState37 = React.useState(false),
47550
+ subscriptions = _useState36[0],
47551
+ setSubscriptions = _useState36[1];
47552
+ var _useState37 = React.useState(""),
47545
47553
  _useState38 = _slicedToArray(_useState37, 2),
47546
- saving = _useState38[0],
47547
- setSaving = _useState38[1];
47548
- var _useState39 = React.useState(null),
47554
+ newEvent = _useState38[0],
47555
+ setNewEvent = _useState38[1];
47556
+ var _useState39 = React.useState([]),
47549
47557
  _useState40 = _slicedToArray(_useState39, 2),
47550
- error = _useState40[0],
47551
- setError = _useState40[1];
47558
+ knownEvents = _useState40[0],
47559
+ setKnownEvents = _useState40[1];
47560
+ var _useState41 = React.useState(false),
47561
+ _useState42 = _slicedToArray(_useState41, 2),
47562
+ saving = _useState42[0],
47563
+ setSaving = _useState42[1];
47564
+ var _useState43 = React.useState(null),
47565
+ _useState44 = _slicedToArray(_useState43, 2),
47566
+ error = _useState44[0],
47567
+ setError = _useState44[1];
47552
47568
 
47553
47569
  // Discover recently-seen widget event types to suggest as subscriptions.
47554
47570
  React.useEffect(function () {
@@ -47564,29 +47580,32 @@ var BotDetail = function BotDetail(_ref) {
47564
47580
  };
47565
47581
  }, []);
47566
47582
 
47567
- // Discover the user's connected integrations for the picker.
47583
+ // Discover the user's configured MCP providers — running or not. The bot
47584
+ // starts any that aren't running when it runs.
47568
47585
  React.useEffect(function () {
47569
- var _api$llm;
47586
+ var _api$bots;
47570
47587
  var alive = true;
47571
47588
  var api = getMainApi();
47572
- if (!(api !== null && api !== void 0 && (_api$llm = api.llm) !== null && _api$llm !== void 0 && _api$llm.listConnectedTools)) return undefined;
47573
- api.llm.listConnectedTools().then(function (servers) {
47574
- if (!alive || !Array.isArray(servers)) return;
47575
- setConnectedServers(servers.map(function (s) {
47576
- return s.serverName;
47577
- }).filter(Boolean));
47578
- })["catch"](function () {});
47589
+ if (!(api !== null && api !== void 0 && (_api$bots = api.bots) !== null && _api$bots !== void 0 && _api$bots.listToolSources)) {
47590
+ setSourcesLoaded(true);
47591
+ return undefined;
47592
+ }
47593
+ Promise.resolve(api.bots.listToolSources((bot === null || bot === void 0 ? void 0 : bot.workspaceId) || null)).then(function (sources) {
47594
+ if (alive && Array.isArray(sources)) setToolSources(sources);
47595
+ })["catch"](function () {})["finally"](function () {
47596
+ if (alive) setSourcesLoaded(true);
47597
+ });
47579
47598
  return function () {
47580
47599
  alive = false;
47581
47600
  };
47582
- }, []);
47601
+ }, [bot === null || bot === void 0 ? void 0 : bot.workspaceId]);
47583
47602
 
47584
47603
  // Fetch the model list for the chosen provider.
47585
47604
  React.useEffect(function () {
47586
- var _api$llm2;
47605
+ var _api$llm;
47587
47606
  var alive = true;
47588
47607
  var api = getMainApi();
47589
- if (!(api !== null && api !== void 0 && (_api$llm2 = api.llm) !== null && _api$llm2 !== void 0 && _api$llm2.listModels)) {
47608
+ if (!(api !== null && api !== void 0 && (_api$llm = api.llm) !== null && _api$llm !== void 0 && _api$llm.listModels)) {
47590
47609
  setModelOptions([]);
47591
47610
  return undefined;
47592
47611
  }
@@ -47600,12 +47619,32 @@ var BotDetail = function BotDetail(_ref) {
47600
47619
  };
47601
47620
  }, [provider]);
47602
47621
 
47603
- // Union of connected servers + any the bot already has (so an attached server
47604
- // that isn't currently connected still shows, checked, and isn't dropped).
47605
- var availableServers = _toConsumableArray(new Set([].concat(_toConsumableArray(selectedServers || []), _toConsumableArray(connectedServers)))).map(function (serverName) {
47622
+ // Configured providers + any the bot already has (so a provider that was
47623
+ // since removed still shows, checked, and isn't silently dropped on save).
47624
+ var availableServers = [].concat(_toConsumableArray(toolSources.map(function (s) {
47625
+ return _objectSpread$t(_objectSpread$t({}, s), {}, {
47626
+ missing: false
47627
+ });
47628
+ })), _toConsumableArray((selectedServers || []).filter(function (name) {
47629
+ return !toolSources.some(function (s) {
47630
+ return s.name === name;
47631
+ });
47632
+ }).map(function (name) {
47633
+ return {
47634
+ name: name,
47635
+ running: false,
47636
+ toolCount: null,
47637
+ missing: true
47638
+ };
47639
+ }))).map(function (s) {
47640
+ var _s$toolCount;
47606
47641
  return {
47607
- serverName: serverName,
47608
- label: prettyServer(serverName)
47642
+ serverName: s.name,
47643
+ label: prettyServer(s.name),
47644
+ // The provider's declared tools (or live tools if undeclared + running);
47645
+ // null → every tool, list not known yet.
47646
+ tools: Array.isArray(s.tools) ? s.tools : null,
47647
+ 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"
47609
47648
  };
47610
47649
  });
47611
47650
  var modelSelectOptions = [{
@@ -47624,6 +47663,35 @@ var BotDetail = function BotDetail(_ref) {
47624
47663
  }) : [].concat(_toConsumableArray(prev), [serverName]);
47625
47664
  });
47626
47665
  };
47666
+
47667
+ // Is `tool` allowed for this bot on `serverName`? No stored selection → yes.
47668
+ var isToolOn = function isToolOn(serverName, tool) {
47669
+ var sel = toolSelections[serverName];
47670
+ return Array.isArray(sel) ? sel.includes(tool) : true;
47671
+ };
47672
+
47673
+ // Toggle one tool. Selecting every tool again clears the entry (= all), so
47674
+ // a later provider-side addition is picked up automatically.
47675
+ var toggleTool = function toggleTool(serverName, allTools, tool) {
47676
+ setToolSelections(function (prev) {
47677
+ var current = Array.isArray(prev[serverName]) ? prev[serverName] : _toConsumableArray(allTools);
47678
+ var next = current.includes(tool) ? current.filter(function (t) {
47679
+ return t !== tool;
47680
+ }) : allTools.filter(function (t) {
47681
+ return t === tool || current.includes(t);
47682
+ });
47683
+ var copy = _objectSpread$t({}, prev);
47684
+ if (next.length === allTools.length) delete copy[serverName];else copy[serverName] = next;
47685
+ return copy;
47686
+ });
47687
+ };
47688
+ var setAllTools = function setAllTools(serverName, on) {
47689
+ setToolSelections(function (prev) {
47690
+ var copy = _objectSpread$t({}, prev);
47691
+ if (on) delete copy[serverName];else copy[serverName] = [];
47692
+ return copy;
47693
+ });
47694
+ };
47627
47695
  var addSubscription = function addSubscription(eventType) {
47628
47696
  var ev = (eventType || "").trim();
47629
47697
  if (!ev) return;
@@ -47672,6 +47740,12 @@ var BotDetail = function BotDetail(_ref) {
47672
47740
  engine: engine || null,
47673
47741
  approvalPolicy: approvalPolicy,
47674
47742
  mcpServers: selectedServers,
47743
+ // Only keep narrowing for providers the bot still uses.
47744
+ toolSelections: Object.fromEntries(Object.entries(toolSelections).filter(function (_ref3) {
47745
+ var _ref4 = _slicedToArray(_ref3, 1),
47746
+ server = _ref4[0];
47747
+ return selectedServers.includes(server);
47748
+ })),
47675
47749
  schedules: schedules,
47676
47750
  subscriptions: subscriptions.map(function (eventType) {
47677
47751
  return {
@@ -47730,57 +47804,113 @@ var BotDetail = function BotDetail(_ref) {
47730
47804
  placeholder: "What should this bot do?",
47731
47805
  rows: 5
47732
47806
  })]
47733
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47734
- className: "flex flex-col gap-1",
47735
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47736
- label: "Provider",
47737
- value: provider,
47738
- onChange: setProvider,
47739
- options: providerOptionsFrom(providers)
47740
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
47741
- className: "text-xs opacity-50",
47742
- children: "The AI that runs this bot. \"Claude Code (CLI)\" uses your Claude login \u2014 no API key needed."
47743
- })]
47744
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47745
- label: "Model",
47746
- value: model,
47747
- onChange: setModel,
47748
- options: modelSelectOptions,
47749
- placeholder: "Recommended (default)"
47750
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47751
- label: "Engine",
47752
- value: engine,
47753
- onChange: setEngine,
47754
- options: ENGINE_OPTIONS,
47755
- placeholder: "Standard (default)"
47756
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47757
- label: "Approval policy",
47758
- value: approvalPolicy,
47759
- onChange: setApprovalPolicy,
47760
- options: APPROVAL_OPTIONS
47761
47807
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47762
47808
  className: "flex flex-col gap-2",
47763
47809
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47764
47810
  className: "text-sm font-medium",
47765
- children: "Tools & integrations"
47811
+ children: "Providers"
47812
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47813
+ className: "text-xs opacity-50",
47814
+ 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."
47766
47815
  }), availableServers.length ? /*#__PURE__*/jsxRuntime.jsx("div", {
47767
47816
  className: "flex flex-col gap-1",
47768
47817
  children: availableServers.map(function (s) {
47769
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Checkbox, {
47770
- label: s.label,
47771
- checked: selectedServers.includes(s.serverName),
47772
- onChange: function onChange() {
47773
- return toggleServer(s.serverName);
47774
- }
47818
+ var on = selectedServers.includes(s.serverName);
47819
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
47820
+ className: "flex flex-col gap-1",
47821
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
47822
+ className: "flex flex-row items-center justify-between gap-3",
47823
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Checkbox, {
47824
+ label: s.label,
47825
+ checked: on,
47826
+ onChange: function onChange() {
47827
+ return toggleServer(s.serverName);
47828
+ }
47829
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47830
+ className: "text-xs opacity-50",
47831
+ children: s.status
47832
+ })]
47833
+ }), on ? /*#__PURE__*/jsxRuntime.jsx("div", {
47834
+ className: "flex flex-col gap-1 pl-7 pb-2",
47835
+ children: s.tools && s.tools.length ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
47836
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
47837
+ className: "flex flex-row items-center gap-2",
47838
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47839
+ className: "text-xs opacity-50",
47840
+ children: "Tools this bot may use (from the provider's allowed tools):"
47841
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
47842
+ title: "All",
47843
+ size: "xs",
47844
+ onClick: function onClick() {
47845
+ return setAllTools(s.serverName, true);
47846
+ }
47847
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
47848
+ title: "None",
47849
+ size: "xs",
47850
+ onClick: function onClick() {
47851
+ return setAllTools(s.serverName, false);
47852
+ }
47853
+ })]
47854
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
47855
+ className: "grid grid-cols-2 gap-x-4 gap-y-1",
47856
+ children: s.tools.map(function (tool) {
47857
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Checkbox, {
47858
+ label: prettyTool(tool),
47859
+ checked: isToolOn(s.serverName, tool),
47860
+ onChange: function onChange() {
47861
+ return toggleTool(s.serverName, s.tools, tool);
47862
+ }
47863
+ }, tool);
47864
+ })
47865
+ })]
47866
+ }) : /*#__PURE__*/jsxRuntime.jsx("span", {
47867
+ className: "text-xs opacity-50",
47868
+ children: "All tools this provider offers \u2014 it has no tool limit set in Settings \u2192 Providers."
47869
+ })
47870
+ }) : null]
47775
47871
  }, s.serverName);
47776
47872
  })
47777
- }) : /*#__PURE__*/jsxRuntime.jsx("span", {
47873
+ }) : sourcesLoaded ? /*#__PURE__*/jsxRuntime.jsx("span", {
47778
47874
  className: "text-xs opacity-50",
47779
- children: "No connected integrations yet. Add one under Settings \u2192 MCP Server, then it will appear here."
47780
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
47875
+ children: "You haven't set up any MCP providers yet. Add one under Settings \u2192 Providers, then it will appear here."
47876
+ }) : null, /*#__PURE__*/jsxRuntime.jsx("span", {
47781
47877
  className: "text-xs opacity-50",
47782
- children: "Tools on these integrations route through the approval policy above."
47878
+ children: "Each tool call follows the approval policy below."
47879
+ })]
47880
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47881
+ className: "flex flex-col gap-2",
47882
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47883
+ className: "text-sm font-medium",
47884
+ children: "AI model"
47885
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47886
+ className: "flex flex-col gap-1",
47887
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47888
+ label: "Model source",
47889
+ value: provider,
47890
+ onChange: setProvider,
47891
+ options: providerOptionsFrom(providers)
47892
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47893
+ className: "text-xs opacity-50",
47894
+ 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."
47895
+ })]
47896
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47897
+ label: "Model",
47898
+ value: model,
47899
+ onChange: setModel,
47900
+ options: modelSelectOptions,
47901
+ placeholder: "Recommended (default)"
47902
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47903
+ label: "Engine",
47904
+ value: engine,
47905
+ onChange: setEngine,
47906
+ options: ENGINE_OPTIONS,
47907
+ placeholder: "Standard (default)"
47783
47908
  })]
47909
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
47910
+ label: "Approval policy",
47911
+ value: approvalPolicy,
47912
+ onChange: setApprovalPolicy,
47913
+ options: APPROVAL_OPTIONS
47784
47914
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47785
47915
  className: "flex flex-col gap-2",
47786
47916
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
@@ -58061,7 +58191,7 @@ var DashTabBar = function DashTabBar(_ref) {
58061
58191
  currentTheme = _useContext.currentTheme;
58062
58192
  if (tabs.length === 0) return null;
58063
58193
  return /*#__PURE__*/jsxRuntime.jsx("div", {
58064
- className: "flex flex-row items-center shrink-0 overflow-x-auto gap-1 px-2 py-2.5 border-t ".concat(currentTheme["border-primary-dark"] || "border-gray-700", " ").concat(currentTheme["bg-primary-dark"] || "bg-gray-900", " scrollbar-none"),
58194
+ className: "dr-tabstrip flex flex-row items-center shrink-0 overflow-x-auto gap-1 px-2 py-2.5 border-t ".concat(currentTheme["border-primary-dark"] || "border-gray-700", " ").concat(currentTheme["bg-primary-dark"] || "bg-gray-900", " scrollbar-none"),
58065
58195
  children: tabs.map(function (tab) {
58066
58196
  var isActive = tab.id === activeTabId;
58067
58197
  return /*#__PURE__*/jsxRuntime.jsxs("button", {
@@ -58069,7 +58199,7 @@ var DashTabBar = function DashTabBar(_ref) {
58069
58199
  onClick: function onClick() {
58070
58200
  return onSwitchTab && onSwitchTab(tab.id);
58071
58201
  },
58072
- className: "group flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md whitespace-nowrap transition-all duration-100 cursor-pointer ".concat(isActive ? "bg-white/15 text-white" : "text-gray-400 hover:bg-white/10 hover:text-gray-200"),
58202
+ className: "dr-pill ".concat(isActive ? "dr-pill-active" : "", " group flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md whitespace-nowrap transition-all duration-100 cursor-pointer ").concat(isActive ? "bg-white/15 text-white" : "text-gray-400 hover:bg-white/10 hover:text-gray-200"),
58073
58203
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
58074
58204
  className: "truncate max-w-[140px]",
58075
58205
  children: (tab.name || "Untitled").replace(/^./, function (c) {
@@ -58201,7 +58331,7 @@ var PageTabBar = function PageTabBar(_ref) {
58201
58331
  setDragOverId(null);
58202
58332
  };
58203
58333
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
58204
- className: "flex flex-row items-center shrink-0 overflow-x-auto gap-1 px-2 py-1.5 border-b ".concat(currentTheme["border-primary-dark"] || "border-gray-700", " ").concat(currentTheme["bg-primary-medium"] || "bg-gray-800/50", " scrollbar-none"),
58334
+ className: "dr-tabs flex flex-row items-center shrink-0 overflow-x-auto gap-1 px-2 py-1.5 border-b ".concat(currentTheme["border-neutral-dark"] || "border-neutral-800", " ").concat(currentTheme["bg-none"] || "bg-transparent", " scrollbar-none"),
58205
58335
  children: [pages.length > 1 && sortedPages.map(function (page) {
58206
58336
  var isActive = page.id === activePageId;
58207
58337
  var isDragOver = page.id === dragOverId;
@@ -58224,7 +58354,7 @@ var PageTabBar = function PageTabBar(_ref) {
58224
58354
  return handleDrop(e, page.id);
58225
58355
  },
58226
58356
  onDragEnd: handleDragEnd,
58227
- className: "group flex items-center gap-1.5 px-3 py-1 text-xs rounded-md whitespace-nowrap transition-all duration-100 cursor-pointer ".concat(isActive ? "bg-white/15 text-white" : "text-gray-400 hover:bg-white/10 hover:text-gray-200", " ").concat(isDragOver ? "ring-1 ring-blue-400" : "", " ").concat(editMode ? "cursor-grab active:cursor-grabbing" : ""),
58357
+ className: "dr-tab ".concat(isActive ? "dr-tab-active" : "", " group flex items-center gap-1.5 px-3 py-1 text-xs rounded-md whitespace-nowrap transition-all duration-100 cursor-pointer ").concat(isActive ? "bg-white/15 text-white" : "text-gray-400 hover:bg-white/10 hover:text-gray-200", " ").concat(isDragOver ? "ring-1 ring-blue-400" : "", " ").concat(editMode ? "cursor-grab active:cursor-grabbing" : ""),
58228
58358
  children: [editingId === page.id ? /*#__PURE__*/jsxRuntime.jsx("input", {
58229
58359
  ref: inputRef,
58230
58360
  type: "text",
@@ -58267,7 +58397,7 @@ var PageTabBar = function PageTabBar(_ref) {
58267
58397
  }), editMode && onAddPage && /*#__PURE__*/jsxRuntime.jsxs("button", {
58268
58398
  type: "button",
58269
58399
  onClick: onAddPage,
58270
- className: "flex items-center gap-1 px-2 py-1 text-xs rounded-md text-gray-500 hover:bg-white/10 hover:text-gray-300 transition-colors",
58400
+ className: "dr-tab flex items-center gap-1 px-2 py-1 text-xs rounded-md text-gray-500 hover:bg-white/10 hover:text-gray-300 transition-colors",
58271
58401
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
58272
58402
  icon: "plus",
58273
58403
  className: "h-2.5 w-2.5"
@@ -65854,7 +65984,7 @@ var DashboardHeader = function DashboardHeader(_ref) {
65854
65984
  }
65855
65985
  }, [workspace, workspaceSelected]);
65856
65986
  return /*#__PURE__*/jsxRuntime.jsx("div", {
65857
- className: "flex flex-row p-1 justify-between shrink items-center px-4 ".concat(currentTheme["bg-primary-dark"], " py-2"),
65987
+ className: "dr-header flex flex-row p-1 justify-between shrink items-center px-4 ".concat(currentTheme["bg-none"], " py-2"),
65858
65988
  children: preview === true ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
65859
65989
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
65860
65990
  title: (workspaceSelected.name || "Untitled").replace(/^./, function (c) {
@@ -65867,11 +65997,11 @@ var DashboardHeader = function DashboardHeader(_ref) {
65867
65997
  children: [onPopout !== null && /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
65868
65998
  icon: "arrow-up-right-from-square",
65869
65999
  onClick: onPopout,
65870
- hoverBackgroundColor: "hover:bg-indigo-700"
66000
+ hoverBackgroundColor: "hover:bg-neutral-700"
65871
66001
  }), onClickEdit !== null && /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
65872
66002
  icon: "pencil",
65873
66003
  onClick: onClickEdit,
65874
- hoverBackgroundColor: "hover:bg-indigo-700"
66004
+ hoverBackgroundColor: "hover:bg-neutral-700"
65875
66005
  })]
65876
66006
  })]
65877
66007
  }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
@@ -65883,7 +66013,7 @@ var DashboardHeader = function DashboardHeader(_ref) {
65883
66013
  onChange: onNameChange,
65884
66014
  textSize: "text-lg",
65885
66015
  placeholder: "My Workspace",
65886
- bgColor: currentTheme["bg-primary-very-dark"],
66016
+ bgColor: currentTheme["bg-neutral-very-dark"],
65887
66017
  textColor: currentTheme["text-primary-medium"],
65888
66018
  hasBorder: false,
65889
66019
  autoFocus: true
@@ -65907,7 +66037,7 @@ var DashboardHeader = function DashboardHeader(_ref) {
65907
66037
  onFolderChange(menuId);
65908
66038
  },
65909
66039
  placeholder: "Folder",
65910
- backgroundColor: currentTheme["bg-primary-very-dark"],
66040
+ backgroundColor: currentTheme["bg-neutral-very-dark"],
65911
66041
  textColor: currentTheme["text-primary-medium"],
65912
66042
  borderColor: currentTheme["border-primary-dark"],
65913
66043
  inputClassName: "py-1 text-sm",
@@ -65942,7 +66072,7 @@ var DashboardHeader = function DashboardHeader(_ref) {
65942
66072
  onThemeChange(themeKey);
65943
66073
  },
65944
66074
  placeholder: "Select a theme",
65945
- backgroundColor: currentTheme["bg-primary-very-dark"],
66075
+ backgroundColor: currentTheme["bg-neutral-very-dark"],
65946
66076
  textColor: currentTheme["text-primary-medium"],
65947
66077
  borderColor: currentTheme["border-primary-dark"],
65948
66078
  inputClassName: "py-1 text-sm",
@@ -65965,7 +66095,7 @@ var DashboardHeader = function DashboardHeader(_ref) {
65965
66095
  icon: "xmark",
65966
66096
  text: "Cancel",
65967
66097
  onClick: onClickEdit,
65968
- hoverBackgroundColor: "hover:bg-indigo-700"
66098
+ hoverBackgroundColor: "hover:bg-neutral-700"
65969
66099
  }), onSaveChanges !== null && /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon2, {
65970
66100
  icon: "check",
65971
66101
  text: "Save",
@@ -65993,7 +66123,7 @@ function DashboardConfigButton(_ref8) {
65993
66123
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
65994
66124
  icon: "sliders",
65995
66125
  onClick: onClick,
65996
- hoverBackgroundColor: "hover:bg-indigo-700"
66126
+ hoverBackgroundColor: "hover:bg-neutral-700"
65997
66127
  }), unresolvedCount > 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
65998
66128
  className: "absolute top-1 right-1 h-2 w-2 rounded-full bg-amber-400 border border-black/40 pointer-events-none",
65999
66129
  title: "".concat(unresolvedCount, " unresolved provider").concat(unresolvedCount === 1 ? "" : "s")
@@ -67759,6 +67889,15 @@ var ChatMessages = function ChatMessages(_ref) {
67759
67889
  });
67760
67890
  };
67761
67891
 
67892
+ var autoResize = function autoResize(el) {
67893
+ if (!el) return;
67894
+ el.style.height = "auto";
67895
+ if (el.scrollHeight === 0) {
67896
+ el.style.height = "";
67897
+ return;
67898
+ }
67899
+ el.style.height = Math.min(el.scrollHeight, 120) + "px";
67900
+ };
67762
67901
  var ChatInput = function ChatInput(_ref) {
67763
67902
  var onSend = _ref.onSend,
67764
67903
  onStop = _ref.onStop,
@@ -67769,13 +67908,24 @@ var ChatInput = function ChatInput(_ref) {
67769
67908
  input = _useState2[0],
67770
67909
  setInput = _useState2[1];
67771
67910
  var textareaRef = React.useRef(null);
67911
+
67912
+ // Auto-resize; re-measure once the input's container actually gets laid
67913
+ // out (e.g. the panel is expanded).
67772
67914
  React.useEffect(function () {
67773
- var el = textareaRef.current;
67774
- if (el) {
67775
- el.style.height = "auto";
67776
- el.style.height = Math.min(el.scrollHeight, 120) + "px";
67777
- }
67915
+ autoResize(textareaRef.current);
67778
67916
  }, [input]);
67917
+ React.useEffect(function () {
67918
+ var el = textareaRef.current;
67919
+ var parent = el === null || el === void 0 ? void 0 : el.parentElement;
67920
+ if (!parent || typeof ResizeObserver === "undefined") return;
67921
+ var observer = new ResizeObserver(function () {
67922
+ return autoResize(el);
67923
+ });
67924
+ observer.observe(parent);
67925
+ return function () {
67926
+ return observer.disconnect();
67927
+ };
67928
+ }, []);
67779
67929
  var handleSend = function handleSend() {
67780
67930
  var trimmed = input.trim();
67781
67931
  if (!trimmed || isLoading) return;