@oomol-lab/open-flow 0.1.0-beta.50 → 0.1.0-beta.52

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.
Files changed (44) hide show
  1. package/dist/browser/{createResourceDialog-CSltk-qY.js → createResourceDialog-BsaBMf7_.js} +2 -1
  2. package/dist/browser/flow-authoring-node.d.ts +3 -1
  3. package/dist/browser/flow-authoring.js +82 -3
  4. package/dist/browser/flow-change-schema.d.ts +1 -1
  5. package/dist/browser/flow-change.d.ts +15 -2
  6. package/dist/browser/flow-change.js +81 -3
  7. package/dist/browser/{flowChanges-DbYrpHnS.js → flowChanges-DtraMpva.js} +3858 -1921
  8. package/dist/browser/{flowWorkspace-CjwpbVBR.js → flowWorkspace-DLgti4Lk.js} +1353 -513
  9. package/dist/browser/{workbenchSelect-oVujN2z6.js → icons-0s-Q_3lp.js} +92 -35
  10. package/dist/browser/licenses.md +204 -0
  11. package/dist/browser/preview.css +302 -179
  12. package/dist/browser/preview.js +4829 -2198
  13. package/dist/browser/theme.css +2 -0
  14. package/dist/browser/ui-hostNavigationActions.d.ts +13 -0
  15. package/dist/browser/ui-hostTooltip.d.ts +8 -0
  16. package/dist/browser/ui-logo.d.ts +5 -0
  17. package/dist/browser/ui.css +102 -8
  18. package/dist/browser/ui.d.ts +3 -0
  19. package/dist/browser/ui.js +176 -11
  20. package/dist/browser/workbench-contract.d.ts +5 -11
  21. package/dist/browser/workbench.css +366 -200
  22. package/dist/browser/workbench.d.ts +1 -1
  23. package/dist/browser/workbench.js +1154 -379
  24. package/dist/browser/workbenchSelect-BqUPacsr.js +31 -0
  25. package/dist/common/authoringExamples.d.ts +4 -2
  26. package/dist/common/control-api-conformance.js +129 -11
  27. package/dist/common/control-api.d.ts +38 -5
  28. package/dist/common/control-api.js +198 -12
  29. package/dist/common/control-requests.d.ts +4 -0
  30. package/dist/common/control-requests.js +1320 -67
  31. package/dist/common/flow-encoding.js +64 -5
  32. package/dist/common/flow-semantics.js +823 -316
  33. package/dist/common/integration-trigger.js +39 -1
  34. package/dist/common/mcp.js +129 -11
  35. package/dist/common/openapi.d.ts +53 -0
  36. package/dist/common/openapi.js +10390 -0
  37. package/dist/common/poll-trigger.js +39 -1
  38. package/dist/common/provider-triggers.js +39 -1
  39. package/dist/common/run-events.js +26 -1
  40. package/dist/common/scheduler.d.ts +4 -1
  41. package/dist/common/scheduler.js +122 -6
  42. package/dist/common/trigger-contract.d.ts +2 -0
  43. package/dist/common/webhook-trigger.js +39 -1
  44. package/package.json +5 -1
@@ -29,6 +29,8 @@
29
29
  --open-flow-input: #d2d2d2;
30
30
  --open-flow-ring: #777777;
31
31
  --open-flow-radius: 10px;
32
+ --ui-code-gutter-background: light-dark(#fff, #333338);
33
+ --ui-code-gutter-border: light-dark(#ddd, #333338);
32
34
  --ui-background: var(--open-flow-background);
33
35
  --ui-foreground: var(--open-flow-foreground);
34
36
  --ui-card: var(--open-flow-card);
@@ -0,0 +1,13 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { UiLanguage } from '../common/localization.js';
3
+ export type HostThemeMode = 'light' | 'dark' | 'auto';
4
+ export interface HostNavigationActionsProps {
5
+ readonly className?: string;
6
+ readonly language: UiLanguage;
7
+ readonly onLanguageChange: (language: UiLanguage) => void;
8
+ readonly theme: HostThemeMode;
9
+ readonly onThemeChange: (theme: HostThemeMode) => void;
10
+ readonly labels: Readonly<Record<HostThemeMode | 'theme' | 'language', string>>;
11
+ }
12
+ /** Shared host navigation; each host owns preference storage and localized labels. */
13
+ export declare function HostNavigationActions({ className, language, onLanguageChange, theme, onThemeChange, labels }: HostNavigationActionsProps): ReactElement;
@@ -0,0 +1,8 @@
1
+ import type { ReactElement } from 'react';
2
+ export interface HostTooltipProps {
3
+ readonly children: ReactElement;
4
+ readonly label: string;
5
+ readonly side?: 'top' | 'bottom' | 'left' | 'right';
6
+ }
7
+ /** Compose a host control with the shared tooltip while preserving its theme and semantics. */
8
+ export declare function HostTooltip({ children, label, side }: HostTooltipProps): ReactElement;
@@ -0,0 +1,5 @@
1
+ import type { ComponentPropsWithoutRef } from 'react';
2
+ export interface OpenFlowLogoProps extends Omit<ComponentPropsWithoutRef<'img'>, 'src' | 'srcSet'> {
3
+ readonly theme: 'light' | 'dark';
4
+ }
5
+ export declare function OpenFlowLogo({ theme, alt, width, height, style, ...props }: OpenFlowLogoProps): import("react").JSX.Element;
@@ -125,6 +125,8 @@
125
125
  --open-flow-input: #d2d2d2;
126
126
  --open-flow-ring: #777;
127
127
  --open-flow-radius: 10px;
128
+ --ui-code-gutter-background: light-dark(#fff, #333338);
129
+ --ui-code-gutter-border: light-dark(#ddd, #333338);
128
130
  --ui-background: var(--open-flow-background);
129
131
  --ui-foreground: var(--open-flow-foreground);
130
132
  --ui-card: var(--open-flow-card);
@@ -1144,6 +1146,10 @@
1144
1146
  margin-left: -1px;
1145
1147
  }
1146
1148
 
1149
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .ml-2 {
1150
+ margin-left: calc(var(--spacing) * 2);
1151
+ }
1152
+
1147
1153
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .ml-4 {
1148
1154
  margin-left: calc(var(--spacing) * 4);
1149
1155
  }
@@ -1388,6 +1394,10 @@
1388
1394
  max-height: calc(var(--spacing) * 40);
1389
1395
  }
1390
1396
 
1397
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .max-h-48 {
1398
+ max-height: calc(var(--spacing) * 48);
1399
+ }
1400
+
1391
1401
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .max-h-56 {
1392
1402
  max-height: calc(var(--spacing) * 56);
1393
1403
  }
@@ -1416,6 +1426,10 @@
1416
1426
  max-height: calc(100dvh - 32px);
1417
1427
  }
1418
1428
 
1429
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .max-h-\[min\(40vh\,280px\)\] {
1430
+ max-height: min(40vh, 280px);
1431
+ }
1432
+
1419
1433
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .max-h-\[min\(60dvh\,480px\)\] {
1420
1434
  max-height: min(60dvh, 480px);
1421
1435
  }
@@ -1676,10 +1690,6 @@
1676
1690
  min-width: calc(var(--spacing) * 36);
1677
1691
  }
1678
1692
 
1679
- :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .min-w-40 {
1680
- min-width: calc(var(--spacing) * 40);
1681
- }
1682
-
1683
1693
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .min-w-44 {
1684
1694
  min-width: calc(var(--spacing) * 44);
1685
1695
  }
@@ -2043,10 +2053,10 @@
2043
2053
  column-gap: calc(var(--spacing) * 3);
2044
2054
  }
2045
2055
 
2046
- :where(:where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .-space-x-2 > :not(:last-child)) {
2056
+ :where(:where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .-space-x-0\.5 > :not(:last-child)) {
2047
2057
  --tw-space-x-reverse: 0;
2048
- margin-inline-start: calc(calc(var(--spacing) * -2) * var(--tw-space-x-reverse));
2049
- margin-inline-end: calc(calc(var(--spacing) * -2) * calc(1 - var(--tw-space-x-reverse)));
2058
+ margin-inline-start: calc(calc(var(--spacing) * -.5) * var(--tw-space-x-reverse));
2059
+ margin-inline-end: calc(calc(var(--spacing) * -.5) * calc(1 - var(--tw-space-x-reverse)));
2050
2060
  }
2051
2061
 
2052
2062
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .gap-y-1 {
@@ -2988,6 +2998,10 @@
2988
2998
  text-decoration-line: underline;
2989
2999
  }
2990
3000
 
3001
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .underline-offset-2 {
3002
+ text-underline-offset: 2px;
3003
+ }
3004
+
2991
3005
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .underline-offset-4 {
2992
3006
  text-underline-offset: 4px;
2993
3007
  }
@@ -3174,6 +3188,10 @@
3174
3188
  --content-icon-initials-background: transparent;
3175
3189
  }
3176
3190
 
3191
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .\[--ui-control-hover-background\:var\(--ui-control-background\,var\(--ui-muted\)\)\] {
3192
+ --ui-control-hover-background: var(--ui-control-background, var(--ui-muted));
3193
+ }
3194
+
3177
3195
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .\[--ui-control-hover-background\:var\(--warning-subtle-hover\)\] {
3178
3196
  --ui-control-hover-background: var(--warning-subtle-hover);
3179
3197
  }
@@ -3422,6 +3440,21 @@
3422
3440
  }
3423
3441
  }
3424
3442
 
3443
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .placeholder\:opacity-70::placeholder {
3444
+ opacity: .7;
3445
+ }
3446
+
3447
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .placeholder\:transition-opacity::placeholder {
3448
+ transition-property: opacity;
3449
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
3450
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
3451
+ }
3452
+
3453
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .placeholder\:duration-300::placeholder {
3454
+ --tw-duration: .3s;
3455
+ transition-duration: .3s;
3456
+ }
3457
+
3425
3458
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .before\:absolute:before {
3426
3459
  content: var(--tw-content);
3427
3460
  position: absolute;
@@ -3661,6 +3694,10 @@
3661
3694
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, #0000001a), 0 1px 2px -1px var(--tw-shadow-color, #0000001a);
3662
3695
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
3663
3696
  }
3697
+
3698
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .hover\:placeholder\:opacity-50:hover::placeholder {
3699
+ opacity: .5;
3700
+ }
3664
3701
  }
3665
3702
 
3666
3703
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .focus\:z-10:focus {
@@ -3679,6 +3716,10 @@
3679
3716
  color: var(--ui-accent-foreground);
3680
3717
  }
3681
3718
 
3719
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .focus\:placeholder\:opacity-30:focus::placeholder {
3720
+ opacity: .3;
3721
+ }
3722
+
3682
3723
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .focus-visible\:z-10:focus-visible {
3683
3724
  z-index: 10;
3684
3725
  }
@@ -4635,6 +4676,33 @@
4635
4676
  border-radius: calc(var(--ui-radius) - 2px);
4636
4677
  }
4637
4678
 
4679
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .data-\[slot\=native-select\]\:focus-visible\:text-field-focus[data-slot="native-select"]:focus-visible {
4680
+ outline: 2px solid var(--ui-ring);
4681
+ outline-offset: -1px;
4682
+ box-shadow: none;
4683
+ transition-property: color, background-color;
4684
+ }
4685
+
4686
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .data-\[slot\=native-select\]\:focus-visible\:text-field-focus[data-slot="native-select"]:focus-visible[readonly] {
4687
+ outline: var(--ui-readonly-focus-outline, 2px solid var(--ui-ring));
4688
+ }
4689
+
4690
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .data-\[slot\=native-select\]\:focus-visible\:aria-invalid\:invalid-text-field-focus[data-slot="native-select"]:focus-visible[aria-invalid="true"] {
4691
+ outline: 2px solid var(--ui-ring);
4692
+ outline-offset: -1px;
4693
+ box-shadow: none;
4694
+ transition-property: color, background-color;
4695
+ }
4696
+
4697
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .data-\[slot\=native-select\]\:focus-visible\:aria-invalid\:invalid-text-field-focus[data-slot="native-select"]:focus-visible[aria-invalid="true"][readonly] {
4698
+ outline: var(--ui-readonly-focus-outline, 2px solid var(--ui-ring));
4699
+ }
4700
+
4701
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .data-\[slot\=native-select\]\:focus-visible\:aria-invalid\:invalid-text-field-focus[data-slot="native-select"]:focus-visible[aria-invalid="true"] {
4702
+ outline-color: var(--ui-destructive);
4703
+ outline-offset: calc(-1 * var(--ui-danger-border-width, 1px));
4704
+ }
4705
+
4638
4706
  :is(:where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .\*\:data-\[slot\=select-value\]\:line-clamp-1 > *)[data-slot="select-value"] {
4639
4707
  -webkit-line-clamp: 1;
4640
4708
  -webkit-box-orient: vertical;
@@ -4749,7 +4817,7 @@
4749
4817
  animation: none;
4750
4818
  }
4751
4819
 
4752
- :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .motion-reduce\:transition-none {
4820
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .motion-reduce\:transition-none, :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .motion-reduce\:placeholder\:transition-none::placeholder {
4753
4821
  transition-property: none;
4754
4822
  }
4755
4823
 
@@ -4837,6 +4905,10 @@
4837
4905
  }
4838
4906
 
4839
4907
  @media (min-width: 48rem) {
4908
+ :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .md\:grid-cols-2 {
4909
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4910
+ }
4911
+
4840
4912
  :where(.open-flow-theme, .open-flow-workbench, .open-flow-canvas-root) .md\:text-sm {
4841
4913
  font-size: var(--ui-font-size);
4842
4914
  line-height: var(--tw-leading, var(--text-sm--line-height));
@@ -5715,6 +5787,28 @@
5715
5787
  width: 28px;
5716
5788
  }
5717
5789
 
5790
+ .open-flow-navigation-menu {
5791
+ border: 1px solid var(--ui-border);
5792
+ border-radius: var(--ui-radius);
5793
+ background: var(--ui-popover);
5794
+ color: var(--ui-popover-foreground);
5795
+ margin: 0;
5796
+ padding: 4px;
5797
+ position: fixed;
5798
+ inset: 48px 16px auto auto;
5799
+ box-shadow: 0 4px 12px #0002;
5800
+ }
5801
+
5802
+ .open-flow-navigation-menu:popover-open {
5803
+ flex-direction: column;
5804
+ align-items: stretch;
5805
+ display: flex;
5806
+ }
5807
+
5808
+ .open-flow-navigation-menu button[aria-pressed="true"] {
5809
+ background: var(--ui-muted);
5810
+ }
5811
+
5718
5812
  .npm__react-simple-code-editor__textarea:focus {
5719
5813
  outline: none;
5720
5814
  }
@@ -37,6 +37,7 @@ export declare const InputGroupAddon: ComponentType<ComponentPropsWithoutRef<'di
37
37
  }>;
38
38
  export declare const InputGroupInput: ForwardRefExoticComponent<ComponentPropsWithoutRef<'input'> & RefAttributes<HTMLInputElement>>;
39
39
  export { Label } from './ui-label.js';
40
+ export { OpenFlowLogo, type OpenFlowLogoProps } from './ui-logo.js';
40
41
  export { Textarea } from './ui-textarea.js';
41
42
  /** Shared Sonner presentation for hosts and the component Lab. */
42
43
  export declare const notificationToasterProps: {
@@ -60,3 +61,5 @@ export declare const notificationToasterProps: {
60
61
  export declare function NotificationUndoLabel({ children }: {
61
62
  children: ReactNode;
62
63
  }): ReactNode;
64
+ export { HostTooltip, type HostTooltipProps } from './ui-hostTooltip.js';
65
+ export { HostNavigationActions, type HostNavigationActionsProps, type HostThemeMode } from './ui-hostNavigationActions.js';
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import { createElement, forwardRef, useLayoutEffect } from "react";
2
+ import { createElement, forwardRef, useId, useLayoutEffect, useState } from "react";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import * as ReactDOM from "react-dom";
5
5
  //#region \0rolldown/runtime.js
@@ -4526,7 +4526,7 @@ var maybeReactUseId = SafeReact.useId;
4526
4526
  * @param idOverride
4527
4527
  * @returns {string}
4528
4528
  */
4529
- function useId(idOverride, prefix) {
4529
+ function useId$1(idOverride, prefix) {
4530
4530
  if (maybeReactUseId !== void 0) {
4531
4531
  const reactId = maybeReactUseId();
4532
4532
  return idOverride ?? (prefix ? `${prefix}-${reactId}` : reactId);
@@ -4541,7 +4541,7 @@ function useId(idOverride, prefix) {
4541
4541
  * @returns {string | undefined}
4542
4542
  */
4543
4543
  function useBaseUiId(idOverride) {
4544
- return useId(idOverride, "base-ui");
4544
+ return useId$1(idOverride, "base-ui");
4545
4545
  }
4546
4546
  //#endregion
4547
4547
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/dialog/description/DialogDescription.js
@@ -5506,7 +5506,7 @@ var usePortalContext = () => React.useContext(PortalContext);
5506
5506
  var attr = createAttribute("portal");
5507
5507
  function useFloatingPortalNode(props = {}) {
5508
5508
  const { ref, container: containerProp, componentProps = EMPTY_OBJECT, elementProps } = props;
5509
- const uniqueId = useId();
5509
+ const uniqueId = useId$1();
5510
5510
  const parentPortalNode = usePortalContext()?.portalNode;
5511
5511
  const [containerElement, setContainerElement] = React.useState(null);
5512
5512
  const [portalNode, setPortalNode] = React.useState(null);
@@ -9157,7 +9157,7 @@ var popupStoreSelectors = {
9157
9157
  //#region ../../node_modules/.bun/@base-ui+react@1.4.1+fa6c2f29eeb10566/node_modules/@base-ui/react/esm/floating-ui-react/hooks/useFloatingRootContext.js
9158
9158
  function useFloatingRootContext(options) {
9159
9159
  const { open = false, onOpenChange, elements = {} } = options;
9160
- const floatingId = useId();
9160
+ const floatingId = useId$1();
9161
9161
  const nested = useFloatingParentNodeId() != null;
9162
9162
  if (process.env.NODE_ENV !== "production") {
9163
9163
  const optionDomReference = elements.reference;
@@ -9315,7 +9315,7 @@ function useFloating(options = {}) {
9315
9315
  */
9316
9316
  function useSyncedFloatingRootContext(options) {
9317
9317
  const { popupStore, treatPopupAsFloatingElement = false, onOpenChange } = options;
9318
- const floatingId = useId();
9318
+ const floatingId = useId$1();
9319
9319
  const nested = useFloatingParentNodeId() != null;
9320
9320
  const open = popupStore.useState("open");
9321
9321
  const referenceElement = popupStore.useState("activeTriggerElement");
@@ -9992,7 +9992,7 @@ function useRole(context, props = {}) {
9992
9992
  const domReference = store.useState("domReferenceElement");
9993
9993
  const floatingElement = store.useState("floatingElement");
9994
9994
  const { role = "dialog" } = props;
9995
- const defaultReferenceId = useId();
9995
+ const defaultReferenceId = useId$1();
9996
9996
  const referenceId = domReference?.id || defaultReferenceId;
9997
9997
  const floatingId = React.useMemo(() => getFloatingFocusElement(floatingElement)?.id || defaultFloatingId, [floatingElement, defaultFloatingId]);
9998
9998
  const ariaRole = componentRoleToAriaRoleMap.get(role) ?? role;
@@ -12112,12 +12112,13 @@ function Dialog$1(props) {
12112
12112
  ...props
12113
12113
  });
12114
12114
  }
12115
- function DialogTrigger$1(props) {
12115
+ var DialogTrigger$1 = React.forwardRef(function DialogTrigger(props, ref) {
12116
12116
  return /* @__PURE__ */ jsx(DialogTrigger$2, {
12117
12117
  "data-slot": "dialog-trigger",
12118
- ...props
12118
+ ...props,
12119
+ ref
12119
12120
  });
12120
- }
12121
+ });
12121
12122
  function DialogPortal(props) {
12122
12123
  return /* @__PURE__ */ jsx(DialogPortal$1, {
12123
12124
  "data-slot": "dialog-portal",
@@ -12610,6 +12611,28 @@ function Label({ className, ...props }) {
12610
12611
  });
12611
12612
  }
12612
12613
  //#endregion
12614
+ //#region ../../assets/logo/open-flow-dark.svg
12615
+ var open_flow_dark_default = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%20viewBox='0%200%20100%20100'%20role='img'%20aria-label='Open%20Flow'%3e%3cpath%20fill='%23e0e2e6'%20d='M32%2016H68Q84%2016%2084%2032V36H68C46%2036%2054%2056%2032%2056H16V32Q16%2016%2032%2016Z'/%3e%3cpath%20fill='%238c919a'%20d='M16%2068H32C54%2068%2046%2048%2068%2048H84V68Q84%2084%2068%2084H32Q16%2084%2016%2068Z'/%3e%3c/svg%3e";
12616
+ //#endregion
12617
+ //#region ../../assets/logo/open-flow-light.svg
12618
+ var open_flow_light_default = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='100'%20height='100'%20viewBox='0%200%20100%20100'%20role='img'%20aria-label='Open%20Flow'%3e%3cpath%20fill='%2344474c'%20d='M32%2016H68Q84%2016%2084%2032V36H68C46%2036%2054%2056%2032%2056H16V32Q16%2016%2032%2016Z'/%3e%3cpath%20fill='%2393979f'%20d='M16%2068H32C54%2068%2046%2048%2068%2048H84V68Q84%2084%2068%2084H32Q16%2084%2016%2068Z'/%3e%3c/svg%3e";
12619
+ //#endregion
12620
+ //#region src/ui/browser/logo.tsx
12621
+ function OpenFlowLogo({ theme, alt = "Open Flow", width = 24, height = 24, style, ...props }) {
12622
+ return /* @__PURE__ */ jsx("img", {
12623
+ ...props,
12624
+ src: theme === "dark" ? open_flow_dark_default : open_flow_light_default,
12625
+ alt,
12626
+ width,
12627
+ height,
12628
+ style: {
12629
+ flexShrink: 0,
12630
+ objectFit: "contain",
12631
+ ...style
12632
+ }
12633
+ });
12634
+ }
12635
+ //#endregion
12613
12636
  //#region src/ui/browser/textarea.tsx
12614
12637
  var Textarea = React.forwardRef(function Textarea({ className, ...props }, ref) {
12615
12638
  return /* @__PURE__ */ jsx("textarea", {
@@ -12620,6 +12643,148 @@ var Textarea = React.forwardRef(function Textarea({ className, ...props }, ref)
12620
12643
  });
12621
12644
  });
12622
12645
  //#endregion
12646
+ //#region src/ui/browser/hostTooltip.tsx
12647
+ /** Compose a host control with the shared tooltip while preserving its theme and semantics. */
12648
+ function HostTooltip({ children, label, side = "top" }) {
12649
+ const [anchor, setAnchor] = useState(null);
12650
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
12651
+ ref: setAnchor,
12652
+ render: children
12653
+ }), /* @__PURE__ */ jsx(TooltipContent, {
12654
+ container: anchor?.closest(".open-flow-theme"),
12655
+ side,
12656
+ children: label
12657
+ })] });
12658
+ }
12659
+ //#endregion
12660
+ //#region src/localization/common/languages.ts
12661
+ var uiLanguages = [
12662
+ "en",
12663
+ "zh-CN",
12664
+ "zh-TW",
12665
+ "ja",
12666
+ "ko",
12667
+ "ru",
12668
+ "fr"
12669
+ ];
12670
+ /** Endonyms, shown in language pickers regardless of the current UI language. */
12671
+ var uiLanguageNames = {
12672
+ "en": "English",
12673
+ "zh-CN": "简体中文",
12674
+ "zh-TW": "繁體中文",
12675
+ "ja": "日本語",
12676
+ "ko": "한국어",
12677
+ "ru": "Русский",
12678
+ "fr": "Français"
12679
+ };
12680
+ new Map(uiLanguages.map((language) => [language.toLowerCase(), language]));
12681
+ //#endregion
12682
+ //#region src/ui/browser/hostNavigationActions.tsx
12683
+ var themeIcons = {
12684
+ light: "i-lucide-light:sun",
12685
+ dark: "i-lucide-light:moon",
12686
+ auto: "i-lucide-light:sun-moon"
12687
+ };
12688
+ /** Shared host navigation; each host owns preference storage and localized labels. */
12689
+ function HostNavigationActions({ className, language, onLanguageChange, theme, onThemeChange, labels }) {
12690
+ const themeId = useId();
12691
+ const languageId = useId();
12692
+ return /* @__PURE__ */ jsxs("div", {
12693
+ className,
12694
+ children: [
12695
+ /* @__PURE__ */ jsx(HostTooltip, {
12696
+ label: "GitHub",
12697
+ side: "bottom",
12698
+ children: /* @__PURE__ */ jsx("a", {
12699
+ href: "https://github.com/oomol-lab/open-flow",
12700
+ target: "_blank",
12701
+ rel: "noopener noreferrer",
12702
+ className: buttonVariants({
12703
+ variant: "ghost",
12704
+ size: "icon-sm",
12705
+ className: "text-foreground"
12706
+ }),
12707
+ "aria-label": "GitHub",
12708
+ children: /* @__PURE__ */ jsx("i", {
12709
+ "aria-hidden": "true",
12710
+ className: "i-lucide-light:github size-4"
12711
+ })
12712
+ })
12713
+ }),
12714
+ /* @__PURE__ */ jsx(HostTooltip, {
12715
+ label: labels.theme,
12716
+ side: "bottom",
12717
+ children: /* @__PURE__ */ jsx(Button$1, {
12718
+ variant: "ghost",
12719
+ size: "icon-sm",
12720
+ type: "button",
12721
+ "aria-label": labels.theme,
12722
+ popovertarget: themeId,
12723
+ children: /* @__PURE__ */ jsx("i", {
12724
+ "aria-hidden": "true",
12725
+ className: `${themeIcons[theme]} size-4`
12726
+ })
12727
+ })
12728
+ }),
12729
+ /* @__PURE__ */ jsx(HostTooltip, {
12730
+ label: labels.language,
12731
+ side: "bottom",
12732
+ children: /* @__PURE__ */ jsx(Button$1, {
12733
+ variant: "ghost",
12734
+ size: "icon-sm",
12735
+ type: "button",
12736
+ popovertarget: languageId,
12737
+ "aria-label": labels.language,
12738
+ children: /* @__PURE__ */ jsx("i", {
12739
+ "aria-hidden": "true",
12740
+ className: "i-lucide-light:languages size-4"
12741
+ })
12742
+ })
12743
+ }),
12744
+ /* @__PURE__ */ jsx("div", {
12745
+ id: themeId,
12746
+ popover: "auto",
12747
+ className: "open-flow-navigation-menu",
12748
+ children: [
12749
+ "light",
12750
+ "dark",
12751
+ "auto"
12752
+ ].map((value) => /* @__PURE__ */ jsxs(Button$1, {
12753
+ className: "justify-start gap-2",
12754
+ variant: "ghost",
12755
+ size: "sm",
12756
+ type: "button",
12757
+ "aria-pressed": theme == value,
12758
+ onClick: (event) => {
12759
+ onThemeChange(value);
12760
+ event.currentTarget.closest("[popover]")?.hidePopover();
12761
+ },
12762
+ children: [/* @__PURE__ */ jsx("i", {
12763
+ "aria-hidden": "true",
12764
+ className: `${themeIcons[value]} size-4`
12765
+ }), labels[value]]
12766
+ }, value))
12767
+ }),
12768
+ /* @__PURE__ */ jsx("div", {
12769
+ id: languageId,
12770
+ popover: "auto",
12771
+ className: "open-flow-navigation-menu",
12772
+ children: uiLanguages.map((value) => /* @__PURE__ */ jsx(Button$1, {
12773
+ variant: "ghost",
12774
+ size: "sm",
12775
+ type: "button",
12776
+ "aria-pressed": language == value,
12777
+ onClick: (event) => {
12778
+ onLanguageChange(value);
12779
+ event.currentTarget.closest("[popover]")?.hidePopover();
12780
+ },
12781
+ children: uiLanguageNames[value]
12782
+ }, value))
12783
+ })
12784
+ ]
12785
+ });
12786
+ }
12787
+ //#endregion
12623
12788
  //#region src/ui/browser/public.ts
12624
12789
  var Button = Button$1;
12625
12790
  var Dialog = Dialog$1;
@@ -12668,4 +12833,4 @@ function NotificationUndoLabel({ children }) {
12668
12833
  }), children);
12669
12834
  }
12670
12835
  //#endregion
12671
- export { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Input, InputGroup, InputGroupAddon, InputGroupInput, Label, NotificationUndoLabel, Textarea, notificationToasterProps };
12836
+ export { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, HostNavigationActions, HostTooltip, Input, InputGroup, InputGroupAddon, InputGroupInput, Label, NotificationUndoLabel, OpenFlowLogo, Textarea, notificationToasterProps };
@@ -21,13 +21,10 @@ export interface WorkbenchActor {
21
21
  export interface WorkbenchHost {
22
22
  /** Optional deployment-owned identity lookup. Return null for an unknown actor. */
23
23
  readonly resolveActor?: (actorId: string, signal: AbortSignal) => Promise<WorkbenchActor | null>;
24
- /** Shared, optional persistent catalog responses, isolated by browser origin. */
25
- readonly catalogCache?: {
26
- readonly storage?: CatalogCacheStorage;
27
- };
28
- readonly connectionCache?: {
29
- readonly storage?: WorkbenchPreferences;
30
- };
24
+ /** Cache deployment identity. The session id must be stable and non-secret. */
25
+ readonly cacheEnvironment?: string;
26
+ /** Host-selected connector owner identity, typically the Team from the host route. */
27
+ readonly connectorOwnerId?: string;
31
28
  notify(notification: WorkbenchNotification | undefined): void;
32
29
  openExternalPage(resolveUrl: () => Promise<string>): Promise<boolean>;
33
30
  request(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
@@ -43,6 +40,7 @@ export interface WorkbenchHost {
43
40
  export interface WorkbenchLocation {
44
41
  /** Runs-only source filter. Hosts treat unknown URL values as absent. */
45
42
  readonly runSource?: 'draft' | 'live';
43
+ readonly runId?: string;
46
44
  readonly flowId?: string;
47
45
  readonly view: WorkbenchView;
48
46
  }
@@ -56,7 +54,3 @@ export interface WorkbenchPreferences {
56
54
  /** The host resolves deployment and Flow scope before rendering navigation links. */
57
55
  export type ConnectionHref = (flowId: string, providerId: string, connectionId?: string) => string | undefined;
58
56
  /** Object values are complete response/ETag records; implementations must reject failures. */
59
- export interface CatalogCacheStorage {
60
- get(key: string): Promise<unknown>;
61
- set(key: string, value: unknown): Promise<void>;
62
- }