@tutti-os/workspace-app-center 0.0.37 → 0.0.39

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.
@@ -62,6 +62,7 @@ interface AppCenterHostActions {
62
62
  readonly retryFactoryValidation?: (jobId: string) => Promise<void> | void;
63
63
  readonly retryApp?: (appId: string) => Promise<void> | void;
64
64
  readonly restartAndOpenApp?: (appId: string) => Promise<void> | void;
65
+ readonly shouldConfirmAppUpdate?: (appId: string) => boolean;
65
66
  readonly updateApp?: (appId: string, trigger: "badge_button" | "primary_action") => Promise<void> | void;
66
67
  readonly uninstallApp?: (appId: string) => Promise<void> | void;
67
68
  }
package/dist/ui/index.js CHANGED
@@ -522,11 +522,6 @@ import {
522
522
  Select,
523
523
  SelectContent,
524
524
  SelectItem,
525
- SelectSplitColumn,
526
- SelectSplitColumnItems,
527
- SelectSplitColumnLabel,
528
- SelectSplitDivider,
529
- SelectSplitLayout,
530
525
  SelectTrigger,
531
526
  SelectValue,
532
527
  SectionTabs,
@@ -823,7 +818,8 @@ function AppCenterPanel({
823
818
  if (!app) {
824
819
  return;
825
820
  }
826
- if (app.installed && app.status === "running") {
821
+ const shouldConfirmUpdate = app.installed && app.status === "running" && (actions.shouldConfirmAppUpdate?.(app.id) ?? true);
822
+ if (shouldConfirmUpdate) {
827
823
  setPendingUpdateApp({
828
824
  id: app.id,
829
825
  name: app.name,
@@ -1321,21 +1317,48 @@ function AppCenterPanel({
1321
1317
  }
1322
1318
  ),
1323
1319
  /* @__PURE__ */ jsx2(
1324
- FactoryModelReasoningDropdown,
1320
+ FactoryOptionDropdown,
1325
1321
  {
1326
- copy,
1322
+ ariaLabel: copy.t("factory.labels.model"),
1323
+ emptyMessage: copy.t("factory.messages.noModelOptions"),
1324
+ loading: providerConfigurationStatus === "loading",
1325
+ loadingMessage: copy.t(
1326
+ "factory.messages.loadingConfiguration"
1327
+ ),
1328
+ open: openFactorySettingsMenu === "model",
1329
+ options: modelOptions,
1330
+ selectedValue: selectedModel,
1331
+ triggerClassName: "h-6 w-auto max-w-full border-0 bg-transparent px-1.5 text-[11px] font-medium text-[var(--text-secondary)] shadow-none hover:bg-transparent focus-visible:bg-transparent",
1332
+ onOpenChange: (nextOpen) => setOpenFactorySettingsMenu(nextOpen ? "model" : null),
1333
+ onSelectValue: setSelectedModel
1334
+ }
1335
+ ),
1336
+ /* @__PURE__ */ jsx2(
1337
+ "div",
1338
+ {
1339
+ "aria-hidden": "true",
1340
+ className: "h-4 w-px bg-[var(--line-2)]"
1341
+ }
1342
+ ),
1343
+ /* @__PURE__ */ jsx2(
1344
+ FactoryOptionDropdown,
1345
+ {
1346
+ ariaLabel: copy.t("factory.labels.reasoningEffort"),
1347
+ emptyMessage: copy.t(
1348
+ "factory.messages.noReasoningEffortOptions"
1349
+ ),
1327
1350
  loading: providerConfigurationStatus === "loading",
1328
- modelOptions,
1329
- open: openFactorySettingsMenu === "modelReasoning",
1330
- reasoningEffortOptions,
1331
- selectedModel,
1332
- selectedReasoningEffort,
1351
+ loadingMessage: copy.t(
1352
+ "factory.messages.loadingConfiguration"
1353
+ ),
1354
+ open: openFactorySettingsMenu === "reasoning",
1355
+ options: reasoningEffortOptions,
1356
+ selectedValue: selectedReasoningEffort,
1333
1357
  triggerClassName: "h-6 w-auto max-w-full border-0 bg-transparent px-1.5 text-[11px] font-medium text-[var(--text-secondary)] shadow-none hover:bg-transparent focus-visible:bg-transparent",
1334
1358
  onOpenChange: (nextOpen) => setOpenFactorySettingsMenu(
1335
- nextOpen ? "modelReasoning" : null
1359
+ nextOpen ? "reasoning" : null
1336
1360
  ),
1337
- onSelectModel: setSelectedModel,
1338
- onSelectReasoningEffort: setSelectedReasoningEffort
1361
+ onSelectValue: setSelectedReasoningEffort
1339
1362
  }
1340
1363
  )
1341
1364
  ] })
@@ -1512,37 +1535,20 @@ function FactoryPermissionDropdown({
1512
1535
  }
1513
1536
  );
1514
1537
  }
1515
- function FactoryModelReasoningDropdown({
1516
- copy,
1538
+ function FactoryOptionDropdown({
1539
+ ariaLabel,
1540
+ emptyMessage,
1517
1541
  loading,
1518
- modelOptions,
1542
+ loadingMessage,
1519
1543
  onOpenChange,
1520
- onSelectModel,
1521
- onSelectReasoningEffort,
1544
+ onSelectValue,
1522
1545
  open,
1523
- reasoningEffortOptions,
1524
- selectedModel,
1525
- selectedReasoningEffort,
1546
+ options,
1547
+ selectedValue,
1526
1548
  triggerClassName
1527
1549
  }) {
1528
- const showModelSection = modelOptions.length > 0;
1529
- const showReasoningSection = reasoningEffortOptions.length > 0;
1530
- const disabled = loading || !showModelSection && !showReasoningSection;
1531
- const selectedModelLabel = modelOptions.find((option) => option.value === selectedModel)?.label ?? selectedModel;
1532
- const selectedReasoningLabel = reasoningEffortOptions.find(
1533
- (option) => option.value === selectedReasoningEffort
1534
- )?.label ?? selectedReasoningEffort;
1535
- const triggerLabel = [selectedModelLabel, selectedReasoningLabel].filter((value) => value.trim().length > 0).join(" ");
1536
- const selectedValue = showModelSection ? selectedModel ? `model:${selectedModel}` : "" : selectedReasoningEffort ? `reasoning:${selectedReasoningEffort}` : "";
1537
- const applySettingsValue = (nextValue) => {
1538
- if (nextValue.startsWith("reasoning:")) {
1539
- onSelectReasoningEffort(nextValue.slice("reasoning:".length));
1540
- return;
1541
- }
1542
- if (nextValue.startsWith("model:")) {
1543
- onSelectModel(nextValue.slice("model:".length));
1544
- }
1545
- };
1550
+ const disabled = loading || options.length === 0;
1551
+ const selectedLabel = options.find((option) => option.value === selectedValue)?.label ?? selectedValue;
1546
1552
  return /* @__PURE__ */ jsxs2(
1547
1553
  Select,
1548
1554
  {
@@ -1550,60 +1556,29 @@ function FactoryModelReasoningDropdown({
1550
1556
  open,
1551
1557
  value: selectedValue,
1552
1558
  onOpenChange,
1553
- onValueChange: applySettingsValue,
1559
+ onValueChange: onSelectValue,
1554
1560
  children: [
1555
1561
  /* @__PURE__ */ jsx2(
1556
1562
  SelectTrigger,
1557
1563
  {
1558
- "aria-label": copy.t("factory.labels.modelReasoning"),
1564
+ "aria-label": ariaLabel,
1559
1565
  className: cn2(
1560
1566
  "h-9 max-w-full rounded-[999px] border border-[color:var(--line-2)] bg-[var(--background-panel)] px-3 text-[13px] font-medium text-[var(--text-primary)] shadow-none hover:bg-[var(--transparency-block)] [&>svg:last-child]:opacity-70",
1561
1567
  loading ? "animate-pulse rounded-none border-transparent bg-transparent px-1 opacity-100 shadow-none hover:bg-transparent disabled:bg-transparent disabled:opacity-100" : null,
1562
1568
  disabled && !loading ? "cursor-not-allowed text-[var(--text-tertiary)] opacity-60 hover:bg-[var(--background-panel)]" : null,
1563
1569
  triggerClassName
1564
1570
  ),
1565
- children: /* @__PURE__ */ jsx2("span", { className: "flex min-w-0 items-center gap-2 overflow-hidden", children: triggerLabel ? selectedModelLabel && selectedReasoningLabel ? /* @__PURE__ */ jsxs2(Fragment, { children: [
1566
- /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: selectedModelLabel }),
1567
- /* @__PURE__ */ jsx2("span", { className: "shrink-0 text-[var(--text-secondary)]", children: selectedReasoningLabel })
1568
- ] }) : /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: triggerLabel }) : /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate text-[var(--text-tertiary)]", children: loading ? copy.t("factory.messages.loadingConfiguration") : copy.t("factory.messages.noConfigurationOptions") }) })
1571
+ children: /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: selectedLabel ? selectedLabel : /* @__PURE__ */ jsx2("span", { className: "text-[var(--text-tertiary)]", children: loading ? loadingMessage : emptyMessage }) })
1569
1572
  }
1570
1573
  ),
1571
1574
  /* @__PURE__ */ jsx2(
1572
1575
  SelectContent,
1573
1576
  {
1574
1577
  align: "end",
1575
- className: cn2(
1576
- "max-w-[min(100vw-32px,460px)] data-[side=top]:!translate-y-0",
1577
- showModelSection && showReasoningSection ? "w-[430px]" : "w-max min-w-[240px]"
1578
- ),
1578
+ className: "w-max min-w-[200px] max-w-[min(100vw-32px,320px)] data-[side=top]:!translate-y-0",
1579
1579
  sideOffset: 4,
1580
1580
  style: { zIndex: "var(--z-dialog-popover)" },
1581
- children: showModelSection && showReasoningSection ? /* @__PURE__ */ jsxs2(SelectSplitLayout, { children: [
1582
- /* @__PURE__ */ jsxs2(SelectSplitColumn, { children: [
1583
- /* @__PURE__ */ jsx2(SelectSplitColumnLabel, { children: copy.t("factory.labels.model") }),
1584
- /* @__PURE__ */ jsx2(SelectSplitColumnItems, { children: modelOptions.map((option) => /* @__PURE__ */ jsx2(
1585
- SelectItem,
1586
- {
1587
- value: `model:${option.value}`,
1588
- children: /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: option.label })
1589
- },
1590
- option.value
1591
- )) })
1592
- ] }),
1593
- /* @__PURE__ */ jsx2(SelectSplitDivider, {}),
1594
- /* @__PURE__ */ jsxs2(SelectSplitColumn, { children: [
1595
- /* @__PURE__ */ jsx2(SelectSplitColumnLabel, { children: copy.t("factory.labels.reasoningEffort") }),
1596
- /* @__PURE__ */ jsx2(SelectSplitColumnItems, { children: reasoningEffortOptions.map((option) => /* @__PURE__ */ jsx2(
1597
- SelectItem,
1598
- {
1599
- forceSelectedIndicator: selectedReasoningEffort === option.value,
1600
- value: `reasoning:${option.value}`,
1601
- children: /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: option.label })
1602
- },
1603
- option.value
1604
- )) })
1605
- ] })
1606
- ] }) : showModelSection ? modelOptions.map((option) => /* @__PURE__ */ jsx2(SelectItem, { value: `model:${option.value}`, children: /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: option.label }) }, option.value)) : showReasoningSection ? reasoningEffortOptions.map((option) => /* @__PURE__ */ jsx2(SelectItem, { value: `reasoning:${option.value}`, children: /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: option.label }) }, option.value)) : /* @__PURE__ */ jsx2(SelectItem, { disabled: true, value: "__empty__", children: copy.t("factory.messages.noConfigurationOptions") })
1581
+ children: options.length > 0 ? options.map((option) => /* @__PURE__ */ jsx2(SelectItem, { value: option.value, children: /* @__PURE__ */ jsx2("span", { className: "min-w-0 truncate", children: option.label }) }, option.value)) : /* @__PURE__ */ jsx2(SelectItem, { disabled: true, value: "__empty__", children: emptyMessage })
1607
1582
  }
1608
1583
  )
1609
1584
  ]