@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
@@ -1,11 +1,12 @@
1
1
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
2
- import { $ as useIconifyCollectionLoader, $t as EmptyTitle, A as calendarDate, B as mapSource, Bn as IconThemeContext, Bt as NativeScrollArea, C as schemaForEditor, Cn as sourceOutputLabel, D as isUnconstrainedSchema, Dn as triggerConfigValues, E as getDefaultValue, En as triggerConfigValue, Ft as PopoverContent, G as resourceValue, Gt as InputGroup$1, Ht as VirtualScrollArea, I as indexAddNodeOptions, It as PopoverDescription, J as triggerNodeIcon, Jt as Empty, K as designerGraph, Kt as InputGroupAddon, L as feishuResourceKind, Lt as PopoverPanelContent, M as datePickerValue, Mt as followWorkbenchLink, N as isDateFormat, Nt as Switch, O as typeOfSchema, On as variableInputCompatible, Pt as Popover, Q as IconifyProvider, Qt as EmptyMedia, R as supportsFeishuChatFilter, Rn as controlErrorCode, Rt as PopoverTitle, S as editorGroups, Sn as resolutionOutputPorts, T as valueForEditor, Tn as isJsonObject, U as observeResource, Ut as Z$2, Vt as ScrollArea, W as resourceData, Wt as useTriggerFocusGuards, X as providerIcon, Xt as EmptyDescription, Y as actionSummary, Yt as EmptyContent, Z as ContentIcon, Zt as EmptyHeader, an as waitBranchDescription, bn as decodeResultList, cn as ru_default$1, ct as diagnosticMessage, dn as fr_default$1, et as useIconifyData, fn as en_default$1, ft as connectionCatalog, gn as errorNotice, hn as EventSourceSetup, in as uiLocales, it as revisionView, j as datePickerChange, jn as inputValue, jt as IdTooltip, k as calendarChange, ln as ko_default$1, lt as diagnosticNodeId, mn as FeishuEventPicker, n as agentTool, nn as SourceSelect, nt as canCancelRun, on as zh_TW_default$1, pn as I18n, q as semanticNodeIcon, qt as InputGroupInput, rn as createI18n$1, rt as hasRunFilter, sn as zh_CN_default$1, tn as SourceForm, un as ja_default$1, ut as schemaMismatchMessage, w as valueForDataType, wn as triggerOutputDefinitions, x as editorComponent, zn as Checkbox, zt as PopoverTrigger } from "./flowChanges-DbYrpHnS.js";
2
+ import { $ as useIconifyCollectionLoader, $t as InputGroup, A as calendarDate, An as resolutionOutputPorts, B as mapSource, Bn as inputValue, Bt as followWorkbenchLink, C as editorGroups, Cn as EventSourceSetup, D as isUnconstrainedSchema, E as getDefaultValue, Fn as triggerConfigValue, Ft as securityOptions, G as resourceValue, Gt as PopoverPanelContent, Ht as Popover, I as indexAddNodeOptions, In as triggerConfigValues, It as selectOperation, J as triggerNodeIcon, Jn as Checkbox, Jt as NativeScrollArea, K as designerGraph, Kt as PopoverTitle, L as feishuResourceKind, Ln as variableInputCompatible, Lt as serverAddress, M as datePickerValue, Mt as object, N as isDateFormat, Nn as triggerOutputDefinitions, Nt as openApiFieldIssues, O as typeOfSchema, On as decodeResultList, Pn as isJsonObject, Pt as openApiTask, Q as IconifyProvider, Qt as useTriggerFocusGuards, R as supportsFeishuChatFilter, Rt as servers, S as editorComponent, Sn as FeishuEventPicker, T as valueForEditor, U as observeResource, Ut as PopoverContent, Vt as Switch, W as resourceData, Wt as PopoverDescription, X as providerIcon, Xt as VirtualScrollArea, Y as actionSummary, Yn as IconThemeContext, Yt as ScrollArea, Z as ContentIcon, Zt as Z$2, _n as ko_default$1, an as EmptyHeader, bn as en_default$1, ct as diagnosticMessage, dn as createI18n$1, en as InputGroupAddon, et as useIconifyData, fn as uiLocales, ft as connectionCatalog, gn as ru_default$1, hn as zh_CN_default$1, in as EmptyDescription, it as revisionView, j as datePickerChange, jn as sourceOutputLabel, jt as listOperations, k as calendarChange, ln as SourceForm, lt as diagnosticNodeId, mn as zh_TW_default$1, n as agentTool, nn as Empty, nt as canCancelRun, on as EmptyMedia, pn as waitBranchDescription, q as semanticNodeIcon, qn as controlErrorCode, qt as PopoverTrigger, rn as EmptyContent, rt as hasRunFilter, sn as EmptyTitle, tn as InputGroupInput, un as SourceSelect, ut as schemaMismatchMessage, vn as ja_default$1, w as schemaForEditor, wn as errorNotice, x as defaultValueEditorSchema, xn as I18n, yn as fr_default$1, zt as IdTooltip } from "./flowChanges-DtraMpva.js";
3
3
  import { a as derive, c as strictEqual, i as compute, l as val, n as attachSetter, r as combine, s as readonlyVal } from "./dist-bO8nvHFH.js";
4
4
  import { a as useVal, i as useTranslate, n as useI18n, r as useLang, t as I18nProvider } from "./main-BPABKzwN.js";
5
- import { $n as ownerDocument, $r as useStableCallback, $t as useHoverFloatingInteraction, An as useOnFirstRender, Ar as useId$1, At as isNativeInput, B as operatorsForType, Bn as findNonDisabledListIndex, Br as useRenderElement, Bt as CompositeList, C as FieldDescription, Cn as addEventListener, Ct as COMPOSITE_KEYS, Dn as require_with_selector, Dt as MODIFIER_KEYS, E as FieldLabel, En as fastComponentRef, Et as HORIZONTAL_KEYS_WITH_EXTRA_KEYS, F as comparisonIssue, Fr as Button$1, Ft as getDisabledMountTransitionStyles, G as webhookMethods, Gn as getMinListIndex, Gr as useMergedRefs, Gt as triggerOpenStateMapping, H as unaryOperator, Hn as getGridCellIndices, Hr as EMPTY_OBJECT, Ht as getPseudoElementBounds, Ir as buttonVariants, It as InternalBackdrop, Jn as stopEvent$1, Jr as useCompositeRootContext, Jt as useTypeahead, K as webhookSupportsBody, Kn as isIndexOutOfListBounds, Kr as useButton, Kt as useOpenInteractionType, Lr as cn$1, Lt as useAnchorPositioning, Mn as Input$1, Mt as useToolbarRootContext, Nt as useAnchoredPopupScrollLock, On as require_builtin_esm_external_require_react, Ot as VERTICAL_KEYS, Pn as useTimeout, Pr as useControlled, Pt as usePositioner, Qn as isMac$1, Qr as SafeReact, Qt as useHoverReferenceInteraction, R as nodeInputMappings, Rr as cva, Rt as adaptiveOrigin, S as Field, Sn as FocusGuard, St as ARROW_UP, T as FieldGroup, Tn as fastComponent, Tt as HORIZONTAL_KEYS, U as valueType, Un as getGridNavigatedIndex, Ut as popupStateMapping, Vn as getGridCellIndexOfCorner, Vr as EMPTY_ARRAY$1, Vt as inertValue, W as decodeRevisionContent, Wn as getMaxListIndex, Wr as warn, Wt as pressableTriggerOpenStateMapping, Xn as contains, Xr as mergeProps, Xt as useListNavigation, Yn as activeElement, Yr as formatErrorMessage, Yt as useRole, Zn as getTarget, Zr as useIsoLayoutEffect, Zt as useInteractions, _ as TooltipPositioner, _n as FloatingTreeStore, _r as itemPress, _t as ALL_KEYS, a as DialogContent, an as useImplicitActiveTrigger, ar as useOpenChangeComplete, at as string, b as TooltipRoot, bn as DROPDOWN_COLLISION_AVOIDANCE, bt as ARROW_LEFT, cn as useTriggerRegistration, cr as transitionStatusMapping, ct as SelectChevron, d as Tooltip, dn as FloatingFocusManager, dr as createChangeEventDetails, dt as SelectItem, ei as useRefWithInit, en as useFocus$1, f as TooltipContent, fn as FloatingNode, fr as cancelOpen, ft as SelectSeparator, g as TooltipPopup, gn as useFloatingTree, gr as imperativeAction, gt as useCompositeListItem, h as TooltipArrow, hn as useFloatingParentNodeId, ht as Separator, in as PopupTriggerMap, ir as useTransitionStatus, j as nodeNameIssue, jn as Label, jt as scrollIntoViewIfNeeded, kn as createSelector, kr as useBaseUiId, kt as VERTICAL_KEYS_WITH_EXTRA_KEYS, l as DialogTitle, ln as useDismiss, lt as SelectContent, m as TooltipTrigger, mn as useFloatingNodeId, mt as SelectValue, n as Icon, ni as isHTMLElement, nn as createInitialPopupStoreState, nr as Check, o as DialogDescription, on as useOpenStateTransitions, or as useAnimationsFinished, p as TooltipProvider, pn as FloatingTree, pt as SelectTrigger, q as dequal, qn as isListIndexDisabled, qr as CompositeRootContext, qt as safePolygon, r as Dialog, ri as isLastTraversableNode, rn as popupStoreSelectors, rr as createLucideIcon, sn as useTriggerDataForwarding, sr as TransitionStatusDataAttributes, st as Select$1, t as WorkbenchSelect, ti as getParentNode, tn as useSyncedFloatingRootContext, tr as ChevronDown, u as DialogTrigger, un as useClick, ut as SelectGroup, v as TooltipPortal, vn as FloatingPortal, vt as ARROW_DOWN, w as FieldError, wn as ReactStore, wr as triggerPress, x as Spinner, xn as POPUP_COLLISION_AVOIDANCE, xr as siblingOpen, xt as ARROW_RIGHT, y as TooltipTrigger$1, yr as none$1, yt as ARROW_KEYS, z as operandHandle, zn as createGridCellMap, zr as clsx, zt as useDirection } from "./workbenchSelect-oVujN2z6.js";
5
+ import { $r as useRefWithInit, $t as useFocus$1, A as nodeNameIssue, An as Label, At as scrollIntoViewIfNeeded, Bn as getGridCellIndexOfCorner, Br as EMPTY_ARRAY$1, Bt as inertValue, C as FieldError, Cn as ReactStore, Cr as triggerPress, Dn as require_builtin_esm_external_require_react, Dt as VERTICAL_KEYS, En as require_with_selector, Et as MODIFIER_KEYS, Fr as buttonVariants, Ft as InternalBackdrop, G as webhookSupportsBody, Gn as isIndexOutOfListBounds, Gr as useButton, Gt as useOpenInteractionType, H as valueType, Hn as getGridNavigatedIndex, Ht as popupStateMapping, Ir as cn$1, It as useAnchorPositioning, Jn as activeElement, Jr as formatErrorMessage, Jt as useRole, K as dequal, Kn as isListIndexDisabled, Kr as CompositeRootContext, Kt as safePolygon, L as nodeInputMappings, Lr as cva, Lt as adaptiveOrigin, Mt as useAnchoredPopupScrollLock, Nn as useTimeout, Nr as useControlled, Nt as usePositioner, On as createSelector, Or as useBaseUiId, Ot as VERTICAL_KEYS_WITH_EXTRA_KEYS, P as comparisonIssue, Pr as Button$1, Pt as getDisabledMountTransitionStyles, Qn as ownerDocument, Qr as useStableCallback, Qt as useHoverFloatingInteraction, R as operandHandle, Rn as createGridCellMap, Rr as clsx, Rt as useDirection, S as FieldDescription, Sn as addEventListener, St as COMPOSITE_KEYS, T as FieldLabel, Tn as fastComponentRef, Tt as HORIZONTAL_KEYS_WITH_EXTRA_KEYS, U as decodeRevisionContent, Un as getMaxListIndex, Ur as warn, Ut as pressableTriggerOpenStateMapping, V as unaryOperator, Vn as getGridCellIndices, Vr as EMPTY_OBJECT, Vt as getPseudoElementBounds, W as webhookMethods, Wn as getMinListIndex, Wr as useMergedRefs, Wt as triggerOpenStateMapping, Xn as getTarget, Xr as useIsoLayoutEffect, Xt as useInteractions, Yn as contains, Yr as mergeProps, Yt as useListNavigation, Zn as isMac$1, Zr as SafeReact, Zt as useHoverReferenceInteraction, _ as TooltipPortal, _n as FloatingPortal, _t as ARROW_DOWN, a as DialogDescription, an as useOpenStateTransitions, ar as useAnimationsFinished, b as Spinner, bn as POPUP_COLLISION_AVOIDANCE, br as siblingOpen, bt as ARROW_RIGHT, c as DialogTitle, cn as useDismiss, ct as SelectContent, d as TooltipContent, dn as FloatingNode, dr as cancelOpen, dt as SelectSeparator, ei as getParentNode, en as useSyncedFloatingRootContext, er as ChevronDown, f as TooltipProvider, fn as FloatingTree, ft as SelectTrigger, g as TooltipPositioner, gn as FloatingTreeStore, gr as itemPress, gt as ALL_KEYS, h as TooltipPopup, hn as useFloatingTree, hr as imperativeAction, ht as useCompositeListItem, i as DialogContent, in as useImplicitActiveTrigger, ir as useOpenChangeComplete, it as string, jn as Input$1, jt as useToolbarRootContext, kn as useOnFirstRender, kr as useId$1, kt as isNativeInput, l as DialogTrigger, ln as useClick, lt as SelectGroup, m as TooltipArrow, mn as useFloatingParentNodeId, mt as Separator, n as Dialog, ni as isLastTraversableNode, nn as popupStoreSelectors, nr as createLucideIcon, on as useTriggerDataForwarding, or as TransitionStatusDataAttributes, ot as Select$1, p as TooltipTrigger, pn as useFloatingNodeId, pt as SelectValue, qn as stopEvent$1, qr as useCompositeRootContext, qt as useTypeahead, rn as PopupTriggerMap, rr as useTransitionStatus, sn as useTriggerRegistration, sr as transitionStatusMapping, st as SelectChevron, t as Icon, ti as isHTMLElement, tn as createInitialPopupStoreState, tr as Check, u as Tooltip, un as FloatingFocusManager, ur as createChangeEventDetails, ut as SelectItem, v as TooltipTrigger$1, vr as none$1, vt as ARROW_KEYS, w as FieldGroup, wn as fastComponent, wt as HORIZONTAL_KEYS, x as Field, xn as FocusGuard, xt as ARROW_UP, y as TooltipRoot, yn as DROPDOWN_COLLISION_AVOIDANCE, yt as ARROW_LEFT, z as operatorsForType, zn as findNonDisabledListIndex, zr as useRenderElement, zt as CompositeList } from "./icons-0s-Q_3lp.js";
6
6
  import { i as isString, n as isBoolean, r as isPlainObject, t as isArray$1 } from "./dist-BDBTOgS5.js";
7
7
  import { a as renameObjectField, i as objectValue, l as resolveUiLanguage, n as isJsonValue, o as setObjectField, r as jsonDataTypes, s as valueType$1, t as initialValue } from "./value-DL_poNiC.js";
8
8
  import { n as compile, r as validate } from "./flowRunInputEditorStore-Dsxyfwae.js";
9
+ import { t as WorkbenchSelect } from "./workbenchSelect-BqUPacsr.js";
9
10
  import * as React from "react";
10
11
  import reactExports, { Children, Fragment, Suspense, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
11
12
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -3659,6 +3660,9 @@ function ProviderGroupHeading({ group, container, onClick }) {
3659
3660
  }
3660
3661
  //#endregion
3661
3662
  //#region src/workbench/browser/runtime/editor/nodePicker.tsx
3663
+ function pickerViewKey(appId, term, page) {
3664
+ return `${page}:${appId ?? "catalog"}:${term}`;
3665
+ }
3662
3666
  function NodePickerContent({ options, connections, loadConnections, browseOptions, searchOptions, provideChoices, onAdd, onDragStart, onDragEnd, onRegisterDragOption, draggable = true, disabled, isOptionDisabled, catalogFailed, initialQuery = "", initialTab = "nodes" }) {
3663
3667
  const t = useTranslate();
3664
3668
  const [page, setPage] = useState(initialTab);
@@ -3666,6 +3670,7 @@ function NodePickerContent({ options, connections, loadConnections, browseOption
3666
3670
  const [appQuery, setAppQuery] = useState("");
3667
3671
  const searchInput = useRef(null);
3668
3672
  const searchSession = useRef(null);
3673
+ const scrollPositions = useRef(/* @__PURE__ */ new Map());
3669
3674
  useEffect(() => {
3670
3675
  const controller = new AbortController();
3671
3676
  searchSession.current = controller;
@@ -3678,6 +3683,7 @@ function NodePickerContent({ options, connections, loadConnections, browseOption
3678
3683
  const [appId, setAppId] = useState();
3679
3684
  const [navigation, setNavigation] = useState();
3680
3685
  const navigateApp = (id) => {
3686
+ if (list.current) scrollPositions.current.set(pickerViewKey(appId, term, page), list.current.scrollTop);
3681
3687
  setNavigation(id ? "forward" : "back");
3682
3688
  setAppId(id);
3683
3689
  setAppQuery("");
@@ -3763,7 +3769,7 @@ function NodePickerContent({ options, connections, loadConnections, browseOption
3763
3769
  return [...entries.values()].toSorted(comparePickerApps);
3764
3770
  }, [catalog, connections]);
3765
3771
  const app = apps.find((item) => item.id == appId);
3766
- const directoryId = app?.directory?.id;
3772
+ const directoryId = app?.directory?.id ?? (app == null ? void 0 : `connector-provider:${app.id}`);
3767
3773
  const searching = term != "" && app == null;
3768
3774
  const [choicesLoading, setChoicesLoading] = useState(false);
3769
3775
  const [choicesFailed, setChoicesFailed] = useState(false);
@@ -3783,12 +3789,15 @@ function NodePickerContent({ options, connections, loadConnections, browseOption
3783
3789
  provideChoices,
3784
3790
  t
3785
3791
  ]);
3786
- useEffect(() => {
3787
- list.current?.scrollTo(0, 0);
3792
+ useLayoutEffect(() => {
3793
+ list.current?.scrollTo(0, scrollPositions.current.get(pickerViewKey(appId, term, page)) ?? 0);
3788
3794
  }, [
3789
3795
  appId,
3790
3796
  term,
3791
- page
3797
+ page,
3798
+ catalog.length,
3799
+ results.length,
3800
+ actions.length
3792
3801
  ]);
3793
3802
  const add = async (item) => {
3794
3803
  if (busy.current || disabled || isOptionDisabled?.(item)) return;
@@ -3921,7 +3930,7 @@ function NodePickerContent({ options, connections, loadConnections, browseOption
3921
3930
  /* @__PURE__ */ jsx("div", {
3922
3931
  ref: mount,
3923
3932
  className: "shrink-0 px-3 pb-2 pt-3",
3924
- children: /* @__PURE__ */ jsxs(InputGroup$1, { children: [
3933
+ children: /* @__PURE__ */ jsxs(InputGroup, { children: [
3925
3934
  /* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Icon, {
3926
3935
  name: "search",
3927
3936
  size: 16
@@ -4163,6 +4172,7 @@ function fallbackIcon$1(item) {
4163
4172
  switch (item.type) {
4164
4173
  case "agent": return "llm";
4165
4174
  case "condition": return "condition";
4175
+ case "openapi":
4166
4176
  case "connector":
4167
4177
  case "connector-group": return "connection";
4168
4178
  case "llm": return "llm";
@@ -4585,7 +4595,7 @@ function SidebarBlockLibrary({ catalogFailed, refreshCatalog, browseOptions, dis
4585
4595
  children: [
4586
4596
  /* @__PURE__ */ jsx("div", {
4587
4597
  className: cn$1("mb-2 flex-none", presentation == "actions" || presentation == "providers" ? "mt-1" : "mx-3.5 mt-3"),
4588
- children: /* @__PURE__ */ jsxs(InputGroup$1, { children: [
4598
+ children: /* @__PURE__ */ jsxs(InputGroup, { children: [
4589
4599
  /* @__PURE__ */ jsx("span", {
4590
4600
  className: "sr-only",
4591
4601
  children: searchLabel
@@ -6797,7 +6807,7 @@ var IconPicker = ({ className, emoji, carbon = true, defaultTab = rememberLastTa
6797
6807
  children: [
6798
6808
  /* @__PURE__ */ jsxs("div", {
6799
6809
  className: IconPicker_module_default.filter,
6800
- children: [/* @__PURE__ */ jsxs(InputGroup$1, {
6810
+ children: [/* @__PURE__ */ jsxs(InputGroup, {
6801
6811
  className: "h-6",
6802
6812
  children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx("i", {
6803
6813
  "aria-hidden": "true",
@@ -7150,44 +7160,44 @@ function FlowNodeList({ nodes, onFocusNode, onSelect, groupTriggers = false }) {
7150
7160
  });
7151
7161
  }
7152
7162
  var valueEditor_module_default = {
7153
- root: "valueEditor_root_8d3fa",
7154
- errorAnchor: "valueEditor_errorAnchor_8d3fa",
7155
- valueTools: "valueEditor_valueTools_8d3fa",
7156
- body: "valueEditor_body_8d3fa",
7157
- options: "valueEditor_options_8d3fa",
7158
- toolbar: "valueEditor_toolbar_8d3fa",
7159
- presence: "valueEditor_presence_8d3fa",
7160
- actions: "valueEditor_actions_8d3fa",
7161
- collection: "valueEditor_collection_8d3fa",
7162
- fieldName: "valueEditor_fieldName_8d3fa",
7163
- fieldType: "valueEditor_fieldType_8d3fa",
7164
- json: "valueEditor_json_8d3fa",
7165
- description: "valueEditor_description_8d3fa",
7166
- error: "valueEditor_error_8d3fa",
7167
- summary: "valueEditor_summary_8d3fa",
7168
- summaryError: "valueEditor_summaryError_8d3fa",
7169
- srOnly: "valueEditor_srOnly_8d3fa",
7170
- option: "valueEditor_option_8d3fa",
7171
- header: "valueEditor_header_8d3fa",
7172
- leadingControl: "valueEditor_leadingControl_8d3fa",
7173
- toggleControl: "valueEditor_toggleControl_8d3fa",
7174
- valueAddon: "valueEditor_valueAddon_8d3fa",
7175
- summaryText: "valueEditor_summaryText_8d3fa",
7176
- clearValue: "valueEditor_clearValue_8d3fa",
7177
- resetValue: "valueEditor_resetValue_8d3fa",
7178
- unsetValue: "valueEditor_unsetValue_8d3fa",
7179
- arrayIndex: "valueEditor_arrayIndex_8d3fa",
7180
- nullValue: "valueEditor_nullValue_8d3fa",
7181
- nullChip: "valueEditor_nullChip_8d3fa",
7182
- collectionActions: "valueEditor_collectionActions_8d3fa",
7183
- emptyObjectContent: "valueEditor_emptyObjectContent_8d3fa",
7184
- emptyObjectConstraint: "valueEditor_emptyObjectConstraint_8d3fa",
7185
- jsonCode: "valueEditor_jsonCode_8d3fa",
7186
- emptyString: "valueEditor_emptyString_8d3fa",
7187
- booleanControl: "valueEditor_booleanControl_8d3fa",
7188
- booleanIndicator: "valueEditor_booleanIndicator_8d3fa",
7189
- objectNotice: "valueEditor_objectNotice_8d3fa",
7190
- valuePrefix: "valueEditor_valuePrefix_8d3fa"
7163
+ root: "valueEditor_root_d4b23",
7164
+ errorAnchor: "valueEditor_errorAnchor_d4b23",
7165
+ valueTools: "valueEditor_valueTools_d4b23",
7166
+ body: "valueEditor_body_d4b23",
7167
+ options: "valueEditor_options_d4b23",
7168
+ toolbar: "valueEditor_toolbar_d4b23",
7169
+ presence: "valueEditor_presence_d4b23",
7170
+ actions: "valueEditor_actions_d4b23",
7171
+ collection: "valueEditor_collection_d4b23",
7172
+ fieldName: "valueEditor_fieldName_d4b23",
7173
+ fieldType: "valueEditor_fieldType_d4b23",
7174
+ json: "valueEditor_json_d4b23",
7175
+ description: "valueEditor_description_d4b23",
7176
+ error: "valueEditor_error_d4b23",
7177
+ summary: "valueEditor_summary_d4b23",
7178
+ summaryError: "valueEditor_summaryError_d4b23",
7179
+ srOnly: "valueEditor_srOnly_d4b23",
7180
+ option: "valueEditor_option_d4b23",
7181
+ header: "valueEditor_header_d4b23",
7182
+ leadingControl: "valueEditor_leadingControl_d4b23",
7183
+ toggleControl: "valueEditor_toggleControl_d4b23",
7184
+ valueAddon: "valueEditor_valueAddon_d4b23",
7185
+ summaryText: "valueEditor_summaryText_d4b23",
7186
+ clearValue: "valueEditor_clearValue_d4b23",
7187
+ resetValue: "valueEditor_resetValue_d4b23",
7188
+ unsetValue: "valueEditor_unsetValue_d4b23",
7189
+ arrayIndex: "valueEditor_arrayIndex_d4b23",
7190
+ nullValue: "valueEditor_nullValue_d4b23",
7191
+ nullChip: "valueEditor_nullChip_d4b23",
7192
+ collectionActions: "valueEditor_collectionActions_d4b23",
7193
+ emptyObjectContent: "valueEditor_emptyObjectContent_d4b23",
7194
+ emptyObjectConstraint: "valueEditor_emptyObjectConstraint_d4b23",
7195
+ jsonCode: "valueEditor_jsonCode_d4b23",
7196
+ emptyString: "valueEditor_emptyString_d4b23",
7197
+ booleanControl: "valueEditor_booleanControl_d4b23",
7198
+ booleanIndicator: "valueEditor_booleanIndicator_d4b23",
7199
+ objectNotice: "valueEditor_objectNotice_d4b23",
7200
+ valuePrefix: "valueEditor_valuePrefix_d4b23"
7191
7201
  };
7192
7202
  //#endregion
7193
7203
  //#region src/form/browser/fieldControl.tsx
@@ -7285,18 +7295,21 @@ function agentFixedValuesValid(config, notificationInputs = []) {
7285
7295
  //#region src/ui/browser/icon-stack.tsx
7286
7296
  /** A visual summary; the caller supplies an accessible label and tooltip. */
7287
7297
  function IconStack({ icons, count, limit = 3, size = "default", countClassName }) {
7288
- const circle = cn$1("relative flex shrink-0 items-center justify-center rounded-full border border-border/50 bg-popover", size === "sm" ? "size-5" : "size-6");
7298
+ const frame = cn$1("relative flex shrink-0 items-center justify-center rounded-[6px] border border-border/50 bg-popover", size === "sm" ? "size-5" : "size-6");
7289
7299
  return /* @__PURE__ */ jsxs("span", {
7290
7300
  "aria-hidden": "true",
7291
- className: "inline-flex shrink-0 items-center -space-x-2",
7292
- children: [icons.slice(0, limit).map((item) => /* @__PURE__ */ jsx("span", {
7293
- className: circle,
7294
- children: /* @__PURE__ */ jsx(ContentIcon, {
7295
- src: item.icon,
7296
- className: size === "sm" ? "size-3.5" : "size-4"
7297
- })
7298
- }, item.id)), /* @__PURE__ */ jsxs("span", {
7299
- className: cn$1(circle, "text-[10px] font-medium tabular-nums text-foreground", countClassName),
7301
+ className: "inline-flex shrink-0 items-center gap-1",
7302
+ children: [/* @__PURE__ */ jsx("span", {
7303
+ className: "inline-flex items-center -space-x-0.5",
7304
+ children: icons.slice(0, limit).map((item) => /* @__PURE__ */ jsx("span", {
7305
+ className: frame,
7306
+ children: /* @__PURE__ */ jsx(ContentIcon, {
7307
+ src: item.icon,
7308
+ className: size === "sm" ? "size-3.5" : "size-4"
7309
+ })
7310
+ }, item.id))
7311
+ }), /* @__PURE__ */ jsxs("span", {
7312
+ className: cn$1("text-[10px] font-normal tabular-nums text-muted-foreground", countClassName),
7300
7313
  children: ["+", count]
7301
7314
  })]
7302
7315
  });
@@ -7321,17 +7334,20 @@ var PickerVirtualItem = forwardRef(({ children, style, index }, ref) => {
7321
7334
  function ActionPicker(props) {
7322
7335
  const [provider, setProvider] = useState();
7323
7336
  const [navigation, setNavigation] = useState();
7337
+ const scrollPositions = useRef(/* @__PURE__ */ new Map());
7324
7338
  return /* @__PURE__ */ jsx(ActionPickerPage, {
7325
7339
  ...props,
7326
7340
  provider,
7341
+ initialScrollTop: scrollPositions.current.get(provider?.id ?? "providers") ?? 0,
7327
7342
  navigation,
7328
- onNavigate: (next) => {
7343
+ onNavigate: (next, scrollTop) => {
7344
+ scrollPositions.current.set(provider?.id ?? "providers", scrollTop);
7329
7345
  setNavigation(next == null ? "back" : "forward");
7330
7346
  setProvider(next);
7331
7347
  }
7332
7348
  }, provider?.id ?? "providers");
7333
7349
  }
7334
- function ActionPickerPage({ portalRoot, connectors, disabled, selected, onToggle, provider, onNavigate, navigation }) {
7350
+ function ActionPickerPage({ portalRoot, connectors, disabled, selected, onToggle, provider, onNavigate, navigation, initialScrollTop }) {
7335
7351
  const t = useTranslate();
7336
7352
  const id = useId();
7337
7353
  const [query, setQuery] = useState("");
@@ -7414,11 +7430,20 @@ function ActionPickerPage({ portalRoot, connectors, disabled, selected, onToggle
7414
7430
  virtualizer.current?.scrollTo(0);
7415
7431
  setVisibleIndex(0);
7416
7432
  }, [term]);
7433
+ useLayoutEffect(() => {
7434
+ if (viewport == null) return;
7435
+ virtualizer.current?.scrollTo(initialScrollTop);
7436
+ viewport.scrollTop = initialScrollTop;
7437
+ }, [
7438
+ viewport,
7439
+ initialScrollTop,
7440
+ rows.length
7441
+ ]);
7417
7442
  return /* @__PURE__ */ jsxs("div", {
7418
7443
  className: "flex min-h-0 min-w-0 flex-1 flex-col gap-3",
7419
7444
  children: [/* @__PURE__ */ jsx("div", {
7420
7445
  className: "flex shrink-0 items-center gap-2 px-4",
7421
- children: /* @__PURE__ */ jsxs(InputGroup$1, { children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx("i", {
7446
+ children: /* @__PURE__ */ jsxs(InputGroup, { children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx("i", {
7422
7447
  "aria-hidden": "true",
7423
7448
  className: "i-lucide-light:search size-4"
7424
7449
  }) }), /* @__PURE__ */ jsx(InputGroupInput, {
@@ -7439,7 +7464,7 @@ function ActionPickerPage({ portalRoot, connectors, disabled, selected, onToggle
7439
7464
  variant: "ghost",
7440
7465
  size: "icon-sm",
7441
7466
  "aria-label": t("actionPicker.back"),
7442
- onClick: () => onNavigate(void 0),
7467
+ onClick: () => onNavigate(void 0, viewport?.scrollTop ?? 0),
7443
7468
  children: /* @__PURE__ */ jsx("i", {
7444
7469
  "aria-hidden": "true",
7445
7470
  className: "i-lucide-light:chevron-left size-4"
@@ -7511,7 +7536,7 @@ function ActionPickerPage({ portalRoot, connectors, disabled, selected, onToggle
7511
7536
  variant: "ghost",
7512
7537
  size: "lg",
7513
7538
  className: "group/app h-auto min-w-0 w-full justify-start gap-2.5 rounded-lg px-2.5 py-1.5 text-[13px] font-normal hover:bg-accent focus-visible:bg-accent",
7514
- onClick: () => onNavigate(item),
7539
+ onClick: () => onNavigate(item, viewport?.scrollTop ?? 0),
7515
7540
  children: [
7516
7541
  /* @__PURE__ */ jsx(ProviderAppIcon, { src: item.icon }),
7517
7542
  /* @__PURE__ */ jsx("span", {
@@ -7733,6 +7758,7 @@ function AccountSelect({ connections, disabled, loading = false, id, invalid, wa
7733
7758
  const t = useTranslate();
7734
7759
  const [container, setContainer] = useState(null);
7735
7760
  const selected = selectedConnection ?? connections.find((candidate) => candidate.connectionId == selectedId);
7761
+ const showLoading = loading && selected == null;
7736
7762
  const builtInName = t("inspector.account.oomolBuiltIn");
7737
7763
  const displayName = (connection) => accountDisplayName(connection, connection.displayName, builtInName);
7738
7764
  const selectedLabel = selected == null ? selectedId == null ? void 0 : `${selectedId} (${t("inspector.account.unavailable")})` : `${displayName(selected)}${selected.isDefault ? ` (${t("inspector.account.teamDefault")})` : ""}`;
@@ -7781,18 +7807,18 @@ function AccountSelect({ connections, disabled, loading = false, id, invalid, wa
7781
7807
  children: /* @__PURE__ */ jsx(SelectValue, {
7782
7808
  className: !loading && selectedId != null ? "mr-5" : void 0,
7783
7809
  placeholder: t("inspector.account.chooseAccount"),
7784
- children: loading ? /* @__PURE__ */ jsxs("span", {
7810
+ children: showLoading ? /* @__PURE__ */ jsxs("span", {
7785
7811
  role: "status",
7786
7812
  className: "flex min-w-0 items-center gap-2 text-muted-foreground",
7787
7813
  children: [/* @__PURE__ */ jsx(Spinner, {}), /* @__PURE__ */ jsx("span", {
7788
7814
  className: "truncate",
7789
7815
  children: t("inspector.account.loading")
7790
7816
  })]
7791
- }) : selected == null ? selectedLabel : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AccountName, {
7817
+ }) : selected == null ? selectedLabel : /* @__PURE__ */ jsx(AccountName, {
7792
7818
  name: displayName(selected),
7793
7819
  builtIn: selected.builtInAccount,
7794
7820
  truncate: true
7795
- }), selected.isDefault ? ` (${t("inspector.account.teamDefault")})` : ""] })
7821
+ })
7796
7822
  })
7797
7823
  }), /* @__PURE__ */ jsxs(SelectContent, {
7798
7824
  container,
@@ -8082,6 +8108,8 @@ function ActionSelectionDialog({ title, entries, connectors, prepareAction, disa
8082
8108
  function ActionSelectionEditor({ entries, connectors, prepareAction, disabled, createEntry, onSave, onCancel, settings }) {
8083
8109
  const t = useTranslate();
8084
8110
  const [draft, setDraft] = useState(entries);
8111
+ const actions = useVal(connectors.$.actions);
8112
+ const connections = useVal(connectors.$.connections);
8085
8113
  const [initialEntries] = useState(entries);
8086
8114
  const [displayOrder, setDisplayOrder] = useState(entries.length === 0 ? [] : null);
8087
8115
  const [prepared, setPrepared] = useState({});
@@ -8286,10 +8314,10 @@ function ActionSelectionEditor({ entries, connectors, prepareAction, disabled, c
8286
8314
  className: "flex flex-col divide-y divide-border/50 px-4",
8287
8315
  children: sortedEntries.map(({ entry, index }) => {
8288
8316
  const resolved = prepared[entry.action];
8289
- const action = resolved?.action ?? discovered.current.get(entry.action) ?? connectors.$.actions.value[entry.action];
8317
+ const action = resolved?.action ?? discovered.current.get(entry.action) ?? actions[entry.action];
8290
8318
  const accounts = resolved?.connections ?? [];
8291
- const selected = accounts.find((account) => account.connectionId == entry.connectionId);
8292
- const accountInvalid = action?.authenticated && entry.connectionId != null && selected?.status != "active";
8319
+ const selected = connections.find((account) => account.connectionId == entry.connectionId);
8320
+ const accountInvalid = resolved != null && action?.authenticated && entry.connectionId != null && !accounts.some((account) => account.connectionId == entry.connectionId && account.status == "active");
8293
8321
  return /* @__PURE__ */ jsxs("section", {
8294
8322
  className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-x-2.5 gap-y-1 py-4 first:pt-1 last:pb-1",
8295
8323
  children: [/* @__PURE__ */ jsxs("div", {
@@ -8368,29 +8396,27 @@ function ActionSelectionEditor({ entries, connectors, prepareAction, disabled, c
8368
8396
  ]
8369
8397
  }), /* @__PURE__ */ jsx("div", {
8370
8398
  className: "open-flow-property-panel col-start-2 flex min-h-[30px] min-w-0 items-center [&>*]:w-full",
8371
- children: resolved == null ? preparationErrors[entry.action] != null ? /* @__PURE__ */ jsx(AccountControlButton, {
8399
+ children: resolved == null && preparationErrors[entry.action] != null ? /* @__PURE__ */ jsx(AccountControlButton, {
8372
8400
  status: "danger",
8373
8401
  disabled,
8374
8402
  label: t("inspector.account.retry"),
8375
8403
  hint: preparationErrors[entry.action],
8376
- onClick: () => setAttempt((value) => value + 1)
8377
- }) : /* @__PURE__ */ jsx(AccountSelect, {
8378
- loading: true,
8379
- connections: [],
8380
- disabled,
8381
- onChange: () => {},
8382
- onManage: void 0
8383
- }) : !resolved.action.authenticated ? /* @__PURE__ */ jsx("div", {
8404
+ onClick: () => {
8405
+ connectors.retryAction(entry.action);
8406
+ setAttempt((value) => value + 1);
8407
+ }
8408
+ }) : action?.authenticated === false ? /* @__PURE__ */ jsx("div", {
8384
8409
  className: "text-muted-foreground",
8385
8410
  children: t("actionPicker.noAccount")
8386
8411
  }) : /* @__PURE__ */ jsx(AccountSelect, {
8412
+ loading: resolved == null,
8387
8413
  connections: accounts.filter((account) => account.status == "active"),
8388
8414
  selectedConnection: selected,
8389
8415
  selectedId: entry.connectionId,
8390
8416
  invalid: accountInvalid === true,
8391
8417
  warning: entry.connectionId == null,
8392
8418
  addWhenEmpty: true,
8393
- label: t("actionPicker.accountFor", { action: resolved.action.name }),
8419
+ label: t("actionPicker.accountFor", { action: action?.name ?? entry.action }),
8394
8420
  disabled,
8395
8421
  onChange: (connectionId) => {
8396
8422
  const { connectionId: _previous, ...rest } = entry;
@@ -8399,7 +8425,7 @@ function ActionSelectionEditor({ entries, connectors, prepareAction, disabled, c
8399
8425
  connectionId
8400
8426
  });
8401
8427
  },
8402
- onManage: () => void connectors.connect(resolved.action.serviceId).catch((cause) => setError(String(cause)))
8428
+ onManage: resolved == null ? void 0 : () => void connectors.connect(resolved.action.serviceId).catch((cause) => setError(String(cause)))
8403
8429
  })
8404
8430
  })]
8405
8431
  }, entry.id ?? entry.action);
@@ -8751,11 +8777,15 @@ function MenuHeader({ children }) {
8751
8777
  }
8752
8778
  //#endregion
8753
8779
  //#region src/form/browser/editorComponentSelect.tsx
8754
- function EditorComponentSelect({ schema, id, name, disabled, invalid, readOnly, compact = true, showIcon = true, readOnlySurface = false, showArrayItemType = false, menuTitle, addon = false, disclosure, onChange }) {
8780
+ function EditorComponentSelect({ schema, id, name, disabled, invalid, readOnly, compact = true, showIcon = true, readOnlySurface = false, showArrayItemType = false, menuTitle, addon = false, valueOnly = false, disclosure, onChange }) {
8755
8781
  const t = useTranslate();
8756
8782
  const [container, setContainer] = useState(null);
8757
8783
  const selectedComponent = editorComponent(schema);
8758
- const label = t(`valueEditor.components.${selectedComponent}`);
8784
+ const label = t(valueOnly && selectedComponent === "json" ? "valueEditor.any" : `valueEditor.components.${selectedComponent}`);
8785
+ const accessibleLabel = valueOnly ? t("valueEditor.valueDataType", {
8786
+ name,
8787
+ type: label
8788
+ }) : `${t("valueEditor.type", { name })}: ${label}`;
8759
8789
  if (showArrayItemType && selectedComponent === "array" && !Array.isArray(objectValue(schema)?.items)) {
8760
8790
  const source = objectValue(schema) ?? {};
8761
8791
  return /* @__PURE__ */ jsxs("div", {
@@ -8800,7 +8830,7 @@ function EditorComponentSelect({ schema, id, name, disabled, invalid, readOnly,
8800
8830
  if (readOnly) return /* @__PURE__ */ jsx(FieldTypeDisplay, {
8801
8831
  id,
8802
8832
  label,
8803
- accessibleLabel: `${t("valueEditor.type", { name })}: ${label}`,
8833
+ accessibleLabel,
8804
8834
  icon: showIcon && /* @__PURE__ */ jsx(EditorComponentIcon, { component: selectedComponent }),
8805
8835
  compact,
8806
8836
  addon,
@@ -8809,7 +8839,7 @@ function EditorComponentSelect({ schema, id, name, disabled, invalid, readOnly,
8809
8839
  });
8810
8840
  const items = Object.values(editorGroups).flat().map((value) => ({
8811
8841
  value,
8812
- label: t(`valueEditor.components.${value}`)
8842
+ label: t(valueOnly && value === "json" ? "valueEditor.any" : `valueEditor.components.${value}`)
8813
8843
  }));
8814
8844
  return /* @__PURE__ */ jsx("div", {
8815
8845
  ref: setContainer,
@@ -8826,7 +8856,7 @@ function EditorComponentSelect({ schema, id, name, disabled, invalid, readOnly,
8826
8856
  id,
8827
8857
  size: "field",
8828
8858
  "aria-invalid": invalid,
8829
- "aria-label": `${t("valueEditor.type", { name })}: ${label}`,
8859
+ "aria-label": accessibleLabel,
8830
8860
  variant: addon ? "addon" : "default",
8831
8861
  className: addon ? void 0 : fieldSelectTriggerClass
8832
8862
  }),
@@ -8848,15 +8878,23 @@ function EditorComponentSelect({ schema, id, name, disabled, invalid, readOnly,
8848
8878
  children: /* @__PURE__ */ jsxs(SelectGroup, {
8849
8879
  className: "p-0",
8850
8880
  "aria-label": menuTitle ?? t("valueEditor.typeTitle"),
8851
- children: [/* @__PURE__ */ jsx(MenuHeader, { children: menuTitle ?? t("valueEditor.typeTitle") }), Object.entries(editorGroups).map(([group, components], index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && /* @__PURE__ */ jsx(SelectSeparator, { className: "mx-2 bg-border/50" }), /* @__PURE__ */ jsx(SelectGroup, {
8852
- "aria-label": t(`valueEditor.componentGroups.${group}`),
8853
- className: "p-0",
8854
- children: components.map((component) => /* @__PURE__ */ jsxs(SelectItem, {
8855
- value: component,
8856
- className: selectionMenuItemClass,
8857
- children: [showIcon && /* @__PURE__ */ jsx(EditorComponentIcon, { component }), t(`valueEditor.components.${component}`)]
8858
- }, component))
8859
- })] }, group))]
8881
+ children: [
8882
+ /* @__PURE__ */ jsx(MenuHeader, { children: menuTitle ?? t("valueEditor.typeTitle") }),
8883
+ valueOnly && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(SelectItem, {
8884
+ value: "json",
8885
+ className: "mt-1 first-of-type:mt-0 min-h-7 rounded-[var(--ui-control-radius,var(--ui-radius))] py-1 text-xs leading-5 font-normal",
8886
+ children: [showIcon && /* @__PURE__ */ jsx(EditorComponentIcon, { component: "json" }), t("valueEditor.any")]
8887
+ }), /* @__PURE__ */ jsx(SelectSeparator, { className: "mx-2 bg-border/50" })] }),
8888
+ Object.entries(editorGroups).map(([group, components], index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && /* @__PURE__ */ jsx(SelectSeparator, { className: "mx-2 bg-border/50" }), /* @__PURE__ */ jsx(SelectGroup, {
8889
+ "aria-label": t(`valueEditor.componentGroups.${group}`),
8890
+ className: "p-0",
8891
+ children: components.filter((component) => !valueOnly || component !== "json").map((component) => /* @__PURE__ */ jsxs(SelectItem, {
8892
+ value: component,
8893
+ className: selectionMenuItemClass,
8894
+ children: [showIcon && /* @__PURE__ */ jsx(EditorComponentIcon, { component }), t(`valueEditor.components.${component}`)]
8895
+ }, component))
8896
+ })] }, group))
8897
+ ]
8860
8898
  })
8861
8899
  })]
8862
8900
  })
@@ -11382,7 +11420,7 @@ function ColorEditor({ value, schema, label, disabled, onChange, path, onDraftIs
11382
11420
  return /* @__PURE__ */ jsxs("div", {
11383
11421
  ref: setContainer,
11384
11422
  className: valueEditor_module_default.errorAnchor,
11385
- children: [/* @__PURE__ */ jsxs(InputGroup$1, {
11423
+ children: [/* @__PURE__ */ jsxs(InputGroup, {
11386
11424
  className: "h-[30px]",
11387
11425
  children: [/* @__PURE__ */ jsx(InputGroupInput, {
11388
11426
  className: "h-full min-w-0 px-2 text-xs md:text-xs",
@@ -21477,7 +21515,7 @@ function DateEditor({ value, onChange, label, disabled, invalid, format }) {
21477
21515
  return /* @__PURE__ */ jsx("div", {
21478
21516
  ref: setContainer,
21479
21517
  className: "min-w-0",
21480
- children: /* @__PURE__ */ jsxs(InputGroup$1, {
21518
+ children: /* @__PURE__ */ jsxs(InputGroup, {
21481
21519
  className: "h-[30px]",
21482
21520
  children: [/* @__PURE__ */ jsx(InputGroupInput, {
21483
21521
  className: "h-full min-w-0 px-2 text-xs md:text-xs",
@@ -21565,6 +21603,7 @@ function ValueEditor(props) {
21565
21603
  const source = objectValue(schema) ?? {};
21566
21604
  const type = valueType$1(schema, value);
21567
21605
  const presence = value === void 0 ? "unset" : value === null ? "null" : "value";
21606
+ const textValue = typeof value === "string" ? value : value === void 0 ? "" : JSON.stringify(value);
21568
21607
  return type === "boolean" ? /* @__PURE__ */ jsxs("div", {
21569
21608
  className: valueEditor_module_default.booleanControl,
21570
21609
  children: [/* @__PURE__ */ jsx(Button$1, {
@@ -21636,7 +21675,7 @@ function ValueEditor(props) {
21636
21675
  className: value === "" ? valueEditor_module_default.emptyString : void 0,
21637
21676
  placeholder: t(value === "" ? "valueEditor.emptyStringValue" : "valueEditor.unset"),
21638
21677
  readOnly: disabled,
21639
- value: typeof value === "string" ? value : "",
21678
+ value: textValue,
21640
21679
  onChange: (event) => onChange(event.target.value)
21641
21680
  }) : /* @__PURE__ */ jsx(Input$1, {
21642
21681
  id,
@@ -21645,7 +21684,7 @@ function ValueEditor(props) {
21645
21684
  className: value === "" ? valueEditor_module_default.emptyString : void 0,
21646
21685
  placeholder: t(value === "" ? "valueEditor.emptyStringValue" : "valueEditor.unset"),
21647
21686
  readOnly: disabled,
21648
- value: typeof value === "string" ? value : "",
21687
+ value: textValue,
21649
21688
  onChange: (event) => onChange(event.target.value)
21650
21689
  })] });
21651
21690
  }
@@ -21799,98 +21838,6 @@ function ValueTools({ label, container, raw, danger, onReset, onClear, onToggleJ
21799
21838
  });
21800
21839
  }
21801
21840
  //#endregion
21802
- //#region src/form/browser/valueTypeAddon.tsx
21803
- /** Selects the stored data type of an unconstrained schema without changing the schema itself. */
21804
- function DataTypeAddon({ name, value, any, disabled, onChange }) {
21805
- const t = useTranslate();
21806
- const [container, setContainer] = useState(null);
21807
- const [open, setOpen] = useState(false);
21808
- const selected = any || value === void 0 ? "any" : valueType$1({}, value);
21809
- const label = t(selected === "any" ? "valueEditor.any" : `valueEditor.${selected}`);
21810
- const accessibleLabel = t("valueEditor.valueDataType", {
21811
- name,
21812
- type: label
21813
- });
21814
- const icon = selected === "any" ? editorComponentIcons.json : editorComponentIcons[selected];
21815
- if (disabled || !onChange) return /* @__PURE__ */ jsx(FieldTypeDisplay, {
21816
- label,
21817
- accessibleLabel,
21818
- icon: /* @__PURE__ */ jsx("i", {
21819
- "aria-hidden": "true",
21820
- className: `${icon} inline-block shrink-0 text-base`
21821
- }),
21822
- addon: true
21823
- });
21824
- const items = [{
21825
- value: "any",
21826
- label: t("valueEditor.any")
21827
- }, ...jsonDataTypes.map((type) => ({
21828
- value: type,
21829
- label: t(`valueEditor.${type}`)
21830
- }))];
21831
- return /* @__PURE__ */ jsx("div", {
21832
- ref: setContainer,
21833
- className: "min-w-0",
21834
- children: /* @__PURE__ */ jsxs(Select$1, {
21835
- open,
21836
- onOpenChange: setOpen,
21837
- value: selected,
21838
- items,
21839
- onValueChange: (next) => {
21840
- if (next != null) onChange(next === "any" ? void 0 : next);
21841
- },
21842
- children: [/* @__PURE__ */ jsxs(Tooltip, {
21843
- disabled: open,
21844
- children: [/* @__PURE__ */ jsx(TooltipTrigger, {
21845
- render: /* @__PURE__ */ jsx(SelectTrigger, {
21846
- variant: "addon",
21847
- "aria-label": accessibleLabel
21848
- }),
21849
- children: /* @__PURE__ */ jsx(SelectValue, {
21850
- className: "flex-none justify-center",
21851
- children: /* @__PURE__ */ jsx("i", {
21852
- "aria-hidden": "true",
21853
- className: `${icon} inline-block shrink-0 text-base`
21854
- })
21855
- })
21856
- }), /* @__PURE__ */ jsx(TooltipContent, {
21857
- container,
21858
- children: label
21859
- })]
21860
- }), /* @__PURE__ */ jsx(SelectContent, {
21861
- container,
21862
- align: "start",
21863
- alignItemWithTrigger: false,
21864
- className: `min-w-36 ${selectionMenuContentClass}`,
21865
- children: /* @__PURE__ */ jsxs(SelectGroup, {
21866
- className: "p-0",
21867
- "aria-label": t("valueEditor.dataTypeTitle"),
21868
- children: [
21869
- /* @__PURE__ */ jsx(MenuHeader, { children: t("valueEditor.dataTypeTitle") }),
21870
- /* @__PURE__ */ jsxs(SelectItem, {
21871
- value: "any",
21872
- className: selectionMenuItemClass,
21873
- children: [/* @__PURE__ */ jsx("i", {
21874
- "aria-hidden": "true",
21875
- className: `${editorComponentIcons.json} inline-block shrink-0 text-base`
21876
- }), t("valueEditor.any")]
21877
- }),
21878
- /* @__PURE__ */ jsx(SelectSeparator, { className: "mx-2 bg-border/50" }),
21879
- jsonDataTypes.map((type) => /* @__PURE__ */ jsxs(SelectItem, {
21880
- value: type,
21881
- className: selectionMenuItemClass,
21882
- children: [/* @__PURE__ */ jsx("i", {
21883
- "aria-hidden": "true",
21884
- className: `${editorComponentIcons[type]} inline-block shrink-0 text-base`
21885
- }), t(`valueEditor.${type}`)]
21886
- }, type))
21887
- ]
21888
- })
21889
- })]
21890
- })
21891
- });
21892
- }
21893
- //#endregion
21894
21841
  //#region src/form/browser/fieldValueEditor.tsx
21895
21842
  /** Controlled JSON value editing. It has no graph, port, persistence, or theme context. */
21896
21843
  function FieldValueEditor(suppliedProps) {
@@ -21902,24 +21849,29 @@ function FieldValueEditor(suppliedProps) {
21902
21849
  const { schema, value, onChange, label, nullable, disabled, onDraftIssue, depth = 0 } = props;
21903
21850
  const t = useTranslate();
21904
21851
  const id = useId();
21905
- const source = objectValue(schema) ?? {};
21906
21852
  const valueEditable = props.valueEditable !== false;
21907
21853
  const unconstrained = isUnconstrainedSchema(schema);
21908
21854
  const definitionEditable = props.onDefinitionChange != null && !disabled;
21909
- const showDataType = unconstrained && !definitionEditable && valueEditable && props.valueSuffix == null;
21855
+ const showDataType = editorComponent(schema) === "json" && !definitionEditable && valueEditable && props.valueSuffix == null && props.editor == null;
21856
+ const [selectedEditorSchema, setSelectedEditorSchema] = useState();
21857
+ const editorSchema = showDataType ? selectedEditorSchema ?? defaultValueEditorSchema(schema) : schema;
21858
+ const editorProps = {
21859
+ ...props,
21860
+ schema: editorSchema
21861
+ };
21862
+ const source = objectValue(editorSchema) ?? {};
21910
21863
  const compactValue = props.compact === true || props.header != null || props.valueAddon != null || props.valueSuffix != null || showDataType;
21911
21864
  const state = fieldValueState(schema, value, nullable);
21912
21865
  const { presence, missing, invalidNull } = state;
21913
- const shape = fieldValueShape(schema, value, {
21914
- compactCollection: compactValue && props.header == null,
21866
+ const shape = fieldValueShape(editorSchema, value, {
21867
+ compactCollection: compactValue && props.header == null && !showDataType,
21915
21868
  objectChild: props.objectChild,
21916
21869
  depth
21917
21870
  });
21918
21871
  const { type, enumeration, choiceOptions } = shape;
21919
21872
  const complex = shape.complex || unconstrained && definitionEditable;
21920
21873
  const [container, setContainer] = useState(null);
21921
- const [raw, setRaw] = useState(false);
21922
- const jsonMode = raw || showDataType && value === void 0;
21874
+ const [jsonMode, setJsonMode] = useState(false);
21923
21875
  const focusCreatedValue = useRef(false);
21924
21876
  const [editorFocusRequest, setEditorFocusRequest] = useState(0);
21925
21877
  const [optionsOpen, setOptionsOpen] = useState(false);
@@ -22033,25 +21985,29 @@ function FieldValueEditor(suppliedProps) {
22033
21985
  const canReset = inlineTools && props.onReset != null && (showUnset || !!nullable && nullControl);
22034
21986
  const canClear = inlineTools && state.canClear;
22035
21987
  const canToggleJson = inlineTools && expanded && shape.collection && presence === "value";
22036
- const arrayDefinition = props.header != null && source.type === "array" && !Array.isArray(source.items) && !choiceOptions;
22037
- const changeDataType = (nextType) => {
22038
- if (nextType === void 0) {
22039
- setRaw(true);
21988
+ const arrayDefinition = !showDataType && props.header != null && source.type === "array" && !Array.isArray(source.items) && !choiceOptions;
21989
+ const changeValueEditor = (nextSchema) => {
21990
+ if (isUnconstrainedSchema(nextSchema)) {
21991
+ setSelectedEditorSchema(void 0);
21992
+ setJsonMode(true);
22040
21993
  setExpanded(true);
22041
21994
  setEditorFocusRequest((request) => request + 1);
22042
21995
  } else {
22043
- onChange(valueForDataType(nextType, value));
22044
- setRaw(false);
21996
+ setSelectedEditorSchema(nextSchema);
21997
+ onChange(valueForEditor(nextSchema, value, { createIfUnset: true }));
21998
+ setJsonMode(false);
22045
21999
  setExpanded(false);
22046
22000
  setEditorFocusRequest(0);
22047
22001
  }
22048
22002
  };
22049
- const dataTypeAddon = showDataType ? /* @__PURE__ */ jsx(DataTypeAddon, {
22003
+ const dataTypeAddon = showDataType ? /* @__PURE__ */ jsx(EditorComponentSelect, {
22004
+ schema: jsonMode ? {} : editorSchema,
22050
22005
  name: label,
22051
- value,
22052
- any: jsonMode,
22053
- disabled,
22054
- onChange: changeDataType
22006
+ menuTitle: t("valueEditor.dataTypeTitle"),
22007
+ addon: true,
22008
+ valueOnly: true,
22009
+ readOnly: disabled,
22010
+ onChange: changeValueEditor
22055
22011
  }) : void 0;
22056
22012
  const startAddon = props.valueAddon ?? dataTypeAddon;
22057
22013
  const endAddon = props.valueSuffix ?? (props.valueAddon != null && dataTypeAddon != null ? dataTypeAddon : arrayDefinition ? /* @__PURE__ */ jsx(FieldTypeAddon, {
@@ -22070,7 +22026,7 @@ function FieldValueEditor(suppliedProps) {
22070
22026
  const createValue = uncreatedText && valueEditable && !disabled ? () => {
22071
22027
  onChange("");
22072
22028
  setEditorFocusRequest((request) => request + 1);
22073
- } : emptyCollection ? collectionCreateAction(props) : void 0;
22029
+ } : emptyCollection ? collectionCreateAction(editorProps) : void 0;
22074
22030
  const toggleExpanded = () => {
22075
22031
  restorePreviewFocus.current = !!inlineExpansion && expanded;
22076
22032
  setExpanded(!expanded);
@@ -22080,7 +22036,7 @@ function FieldValueEditor(suppliedProps) {
22080
22036
  const clearTextItem = props.arrayChild && shape.text && !jsonMode && !complex;
22081
22037
  onChange(clearTextItem ? "" : void 0);
22082
22038
  setExpanded(shape.expandable);
22083
- setRaw(false);
22039
+ setJsonMode(false);
22084
22040
  setEditorFocusRequest((request) => clearTextItem ? request + 1 : 0);
22085
22041
  };
22086
22042
  const toolbar = /* @__PURE__ */ jsxs("div", {
@@ -22111,7 +22067,8 @@ function FieldValueEditor(suppliedProps) {
22111
22067
  variant: "ghost",
22112
22068
  disabled,
22113
22069
  onClick: () => {
22114
- setRaw(!jsonMode);
22070
+ if (showDataType) setSelectedEditorSchema(void 0);
22071
+ setJsonMode(!jsonMode);
22115
22072
  setExpanded(true);
22116
22073
  },
22117
22074
  "aria-pressed": jsonMode || complex,
@@ -22189,15 +22146,19 @@ function FieldValueEditor(suppliedProps) {
22189
22146
  "data-field-prompt": invalid || void 0,
22190
22147
  "data-field-control": true,
22191
22148
  "aria-invalid": invalid || void 0,
22192
- "aria-label": `${label} ${t("valueEditor.setValue")}`,
22193
- disabled: disabled || !valueEditable,
22149
+ "aria-label": `${label} ${customUnset ? props.unset.label : t("valueEditor.setValue")}`,
22150
+ disabled: disabled || !valueEditable && props.unset?.onActivate == null,
22194
22151
  onClick: () => {
22195
- const next = getDefaultValue(typeOfSchema(schema), schema);
22152
+ if (customUnset && props.unset?.onActivate != null) {
22153
+ props.unset.onActivate();
22154
+ return;
22155
+ }
22156
+ const next = getDefaultValue(typeOfSchema(editorSchema), editorSchema);
22196
22157
  focusCreatedValue.current = true;
22197
22158
  onChange(next === void 0 ? getDefaultValue(type) : next);
22198
22159
  if (type === "object" || type === "array" || source["ui:widget"] === "text") setExpanded(true);
22199
22160
  },
22200
- children: [/* @__PURE__ */ jsx("span", { children: customUnset ? props.unset.label : t("valueEditor.setValue") }), /* @__PURE__ */ jsx("i", {
22161
+ children: [/* @__PURE__ */ jsx("span", { children: customUnset ? props.unset.label : t("valueEditor.setValue") }), props.unset?.onActivate == null && /* @__PURE__ */ jsx("i", {
22201
22162
  "aria-hidden": "true",
22202
22163
  className: "i-lucide-light:pencil"
22203
22164
  })]
@@ -22208,10 +22169,10 @@ function FieldValueEditor(suppliedProps) {
22208
22169
  invalid,
22209
22170
  focusRequest: expanded ? editorFocusRequest : 0
22210
22171
  }) : props.editor !== void 0 ? props.editor : structured ? type === "object" ? /* @__PURE__ */ jsx(ObjectValueFields, {
22211
- ...props,
22172
+ ...editorProps,
22212
22173
  empty: presence !== "value"
22213
22174
  }) : /* @__PURE__ */ jsx(ArrayValueFields, {
22214
- ...props,
22175
+ ...editorProps,
22215
22176
  empty: presence !== "value"
22216
22177
  }) : (state.display === "null" || presence === "null") && !choiceOptions && !enumeration ? /* @__PURE__ */ jsx(Button$1, {
22217
22178
  type: "button",
@@ -22223,7 +22184,7 @@ function FieldValueEditor(suppliedProps) {
22223
22184
  "aria-invalid": invalid,
22224
22185
  "aria-label": `${label} null`,
22225
22186
  onClick: () => {
22226
- const next = initialValue(schema);
22187
+ const next = initialValue(editorSchema);
22227
22188
  onChange(next == null && type !== "null" ? getDefaultValue(type) : next);
22228
22189
  },
22229
22190
  children: /* @__PURE__ */ jsx("span", {
@@ -22239,7 +22200,7 @@ function FieldValueEditor(suppliedProps) {
22239
22200
  invalid,
22240
22201
  multiple: !Array.isArray(source.enum),
22241
22202
  onChange,
22242
- onOptionsChange: props.onDefinitionChange ? (options, deletion) => {
22203
+ onOptionsChange: props.onDefinitionChange || showDataType ? (options, deletion) => {
22243
22204
  const nextSchema = Array.isArray(source.enum) ? {
22244
22205
  ...source,
22245
22206
  enum: options
@@ -22250,7 +22211,12 @@ function FieldValueEditor(suppliedProps) {
22250
22211
  enum: options
22251
22212
  }
22252
22213
  };
22253
- props.onDefinitionChange(nextSchema, valueForEditor(nextSchema, value), deletion);
22214
+ const nextValue = valueForEditor(nextSchema, value);
22215
+ if (props.onDefinitionChange) props.onDefinitionChange(nextSchema, nextValue, deletion);
22216
+ else {
22217
+ setSelectedEditorSchema(nextSchema);
22218
+ onChange(nextValue);
22219
+ }
22254
22220
  } : void 0
22255
22221
  }) : enumeration ? /* @__PURE__ */ jsxs(FieldSelect, {
22256
22222
  "aria-label": label,
@@ -22268,7 +22234,7 @@ function FieldValueEditor(suppliedProps) {
22268
22234
  children: Array.isArray(optionLabels) && typeof optionLabels[index] === "string" ? optionLabels[index] : typeof item === "string" ? item : JSON.stringify(item)
22269
22235
  }, index))]
22270
22236
  }) : /* @__PURE__ */ jsx(ValueEditor, {
22271
- ...props,
22237
+ ...editorProps,
22272
22238
  onDraftIssue: reportDraftIssue,
22273
22239
  invalid
22274
22240
  }),
@@ -22365,7 +22331,8 @@ function FieldValueEditor(suppliedProps) {
22365
22331
  onReset: canReset ? props.onReset : void 0,
22366
22332
  onClear: canClear ? clearValue : void 0,
22367
22333
  onToggleJson: canToggleJson ? () => {
22368
- setRaw(!jsonMode);
22334
+ if (showDataType) setSelectedEditorSchema(void 0);
22335
+ setJsonMode(!jsonMode);
22369
22336
  if (!jsonMode) setEditorFocusRequest((request) => request + 1);
22370
22337
  } : void 0
22371
22338
  }),
@@ -22526,6 +22493,25 @@ function AgentInputSource({ disabled, readOnly, source, port, inputs, onChange,
22526
22493
  });
22527
22494
  }
22528
22495
  //#endregion
22496
+ //#region src/workbench/browser/runtime/editor/purposeField.tsx
22497
+ function PurposeField({ compact = false, ...props }) {
22498
+ const t = useTranslate();
22499
+ const id = useId();
22500
+ return /* @__PURE__ */ jsxs(Field, {
22501
+ className: compact ? "gap-1.5" : "inspector-field-section",
22502
+ children: [/* @__PURE__ */ jsx(FieldLabel, {
22503
+ className: compact ? "text-xs font-normal text-muted-foreground" : "inspector-section-title",
22504
+ htmlFor: id,
22505
+ children: t("inspector.node.description")
22506
+ }), /* @__PURE__ */ jsx(Textarea, {
22507
+ ...props,
22508
+ id,
22509
+ rows: compact ? 2 : void 0,
22510
+ className: cn$1("[--ui-control-hover-background:var(--ui-control-background,var(--ui-muted))] placeholder:opacity-70 placeholder:transition-opacity placeholder:duration-300 hover:placeholder:opacity-50 focus:placeholder:opacity-30 motion-reduce:placeholder:transition-none", compact && "min-h-16 max-h-40 resize-y text-xs md:text-xs")
22511
+ })]
22512
+ });
22513
+ }
22514
+ //#endregion
22529
22515
  //#region src/workbench/browser/runtime/editor/agentTools.tsx
22530
22516
  function EditableAgentTools({ config, disabled, inputs, connectors, prepareAction, onSave }) {
22531
22517
  const t = useTranslate();
@@ -22548,7 +22534,8 @@ function EditableAgentTools({ config, disabled, inputs, connectors, prepareActio
22548
22534
  className: "i-lucide-light:plus size-3.5"
22549
22535
  }), t("actionPicker.triggerLabel")] }) : /* @__PURE__ */ jsx(IconStack, {
22550
22536
  icons: summary.providers,
22551
- count: summary.count
22537
+ count: summary.count,
22538
+ size: "sm"
22552
22539
  })
22553
22540
  }),
22554
22541
  entries: config.tools,
@@ -22597,22 +22584,14 @@ function AgentToolSettings({ entry: tool, onChange, disabled, onValidChange, inp
22597
22584
  })
22598
22585
  })]
22599
22586
  }),
22600
- /* @__PURE__ */ jsxs(Field, {
22601
- className: "gap-1.5",
22602
- children: [/* @__PURE__ */ jsx(FieldLabel, {
22603
- className: "text-xs font-normal text-muted-foreground",
22604
- children: t("inspector.node.description")
22605
- }), /* @__PURE__ */ jsx(Textarea, {
22606
- rows: 2,
22607
- className: "min-h-16 max-h-40 resize-y text-xs md:text-xs",
22608
- readOnly: disabled,
22609
- "aria-label": t("inspector.node.description"),
22610
- value: tool.description,
22611
- onChange: (event) => onChange?.({
22612
- ...tool,
22613
- description: event.target.value
22614
- })
22615
- })]
22587
+ /* @__PURE__ */ jsx(PurposeField, {
22588
+ compact: true,
22589
+ readOnly: disabled,
22590
+ value: tool.description,
22591
+ onChange: (event) => onChange?.({
22592
+ ...tool,
22593
+ description: event.target.value
22594
+ })
22616
22595
  }),
22617
22596
  tool.inputs.length > 0 && /* @__PURE__ */ jsx("div", { className: "h-px bg-border/50" }),
22618
22597
  tool.inputs.map((port) => /* @__PURE__ */ jsx(AgentInputSource, {
@@ -22664,6 +22643,19 @@ function AgentTools(props) {
22664
22643
  }) })] });
22665
22644
  }
22666
22645
  //#endregion
22646
+ //#region src/workbench/browser/runtime/editor/codeEditorPlaceholder.tsx
22647
+ function CodeEditorPlaceholder({ label }) {
22648
+ return /* @__PURE__ */ jsx("div", {
22649
+ className: "code-editor-placeholder",
22650
+ role: "status",
22651
+ "aria-label": label,
22652
+ children: /* @__PURE__ */ jsx("div", {
22653
+ className: "code-editor-placeholder-gutter",
22654
+ "aria-hidden": "true"
22655
+ })
22656
+ });
22657
+ }
22658
+ //#endregion
22667
22659
  //#region src/workbench/browser/runtime/editor/promptEditor.tsx
22668
22660
  function PromptEditor({ ariaDescribedBy, invalid, value, inputs, disabled, theme, onChange, onSave }) {
22669
22661
  const t = useTranslate();
@@ -22791,14 +22783,18 @@ function PromptEditor({ ariaDescribedBy, invalid, value, inputs, disabled, theme
22791
22783
  if (!disabled) onSave();
22792
22784
  }
22793
22785
  },
22794
- children: [/* @__PURE__ */ jsx("div", {
22795
- className: "code-editor-host",
22796
- ref: host
22797
- }), state != "ready" && /* @__PURE__ */ jsx("span", {
22798
- className: "code-editor-state",
22799
- role: state == "failed" ? "alert" : void 0,
22800
- children: t(state == "failed" ? "inspector.task.editorUnavailable" : "inspector.task.editorLoading")
22801
- })]
22786
+ children: [
22787
+ /* @__PURE__ */ jsx("div", {
22788
+ className: "code-editor-host",
22789
+ ref: host
22790
+ }),
22791
+ state == "loading" && /* @__PURE__ */ jsx(CodeEditorPlaceholder, { label: t("inspector.task.editorLoading") }),
22792
+ state == "failed" && /* @__PURE__ */ jsx("span", {
22793
+ className: "code-editor-state",
22794
+ role: "alert",
22795
+ children: t("inspector.task.editorUnavailable")
22796
+ })
22797
+ ]
22802
22798
  });
22803
22799
  }
22804
22800
  //#endregion
@@ -22821,7 +22817,7 @@ function EditableAgentSettingsProvider({ children, task, nodeId, store, connecto
22821
22817
  const definition = current?.kind == "task" ? current.definition : void 0;
22822
22818
  if (definition == null || !("executor" in definition) || !dequal(definition.executor, before)) return false;
22823
22819
  const decoded = decodeRevisionContent({
22824
- modelVersion: 4,
22820
+ modelVersion: 5,
22825
22821
  modules: {},
22826
22822
  document: {
22827
22823
  bindings: {},
@@ -23058,6 +23054,7 @@ function withDescriptions$1(ports, descriptionFor) {
23058
23054
  function presentBuiltInTriggerOutputs(trigger, t) {
23059
23055
  const ports = triggerOutputDefinitions(trigger);
23060
23056
  switch (trigger.kind) {
23057
+ case "error": return withDescriptions$1(ports, (handle) => t(`errorWorkflow.${handle}`));
23061
23058
  case "cron": return withDescriptions$1(ports, (handle) => handle === "scheduledAt" ? t("inspector.ports.builtIn.cron.scheduledAt") : void 0);
23062
23059
  case "webhook": return withDescriptions$1(ports, (handle) => {
23063
23060
  switch (handle) {
@@ -23079,6 +23076,7 @@ function presentedBuiltInOutputs(node, t) {
23079
23076
  switch (node.kind) {
23080
23077
  case "approval":
23081
23078
  case "wait": return presentResolutionOutputs(node, t);
23079
+ case "error":
23082
23080
  case "cron":
23083
23081
  case "webhook": return presentBuiltInTriggerOutputs(node, t);
23084
23082
  default: return;
@@ -23794,10 +23792,7 @@ function CodeEditor({ ariaDescribedBy, ariaLabel, diagnostics, disabled, errorLa
23794
23792
  className: "code-editor-host",
23795
23793
  ref: host
23796
23794
  }),
23797
- loading && /* @__PURE__ */ jsx("span", {
23798
- className: "code-editor-state",
23799
- children: loadingLabel
23800
- }),
23795
+ loading && /* @__PURE__ */ jsx(CodeEditorPlaceholder, { label: loadingLabel }),
23801
23796
  failed && /* @__PURE__ */ jsx("span", {
23802
23797
  className: "code-editor-state error",
23803
23798
  children: errorLabel
@@ -24100,7 +24095,8 @@ function EditableCodeTaskSection({ connectorAccess, connectorCandidates, connect
24100
24095
  className: "i-lucide-light:plus size-3.5"
24101
24096
  }), t("actionPicker.triggerLabel")] }) : /* @__PURE__ */ jsx(IconStack, {
24102
24097
  icons: summary.providers,
24103
- count: summary.count
24098
+ count: summary.count,
24099
+ size: "sm"
24104
24100
  })]
24105
24101
  }),
24106
24102
  entries: selectedActions,
@@ -24316,7 +24312,7 @@ function NativeSelect({ className, size = "default", ...props }) {
24316
24312
  children: [/* @__PURE__ */ jsx("select", {
24317
24313
  "data-slot": "native-select",
24318
24314
  "data-size": size,
24319
- className: "h-8 w-full min-w-0 appearance-none rounded-lg border border-input bg-[var(--ui-control-background,var(--ui-muted))] py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-solid focus-visible:ring-0 focus-visible:aria-invalid:ring-0 focus-visible:outline-offset-1 focus-visible:outline-ring focus-visible:aria-invalid:outline-destructive disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive data-[size=sm]:h-7 data-[size=sm]:rounded-md data-[size=sm]:py-0.5 dark:bg-[var(--ui-control-background,var(--ui-muted))] dark:hover:bg-input/50",
24315
+ className: "h-8 w-full min-w-0 appearance-none rounded-[var(--ui-control-radius,calc(var(--ui-radius)_+_2px))] border border-input bg-[var(--ui-control-background,var(--ui-muted))] py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground data-[slot=native-select]:focus-visible:text-field-focus data-[slot=native-select]:focus-visible:aria-invalid:invalid-text-field-focus disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive data-[size=sm]:h-7 data-[size=sm]:rounded-[var(--ui-control-radius,var(--ui-radius))] data-[size=sm]:py-0.5 dark:bg-[var(--ui-control-background,var(--ui-muted))] dark:hover:bg-input/50",
24320
24316
  ...props
24321
24317
  }), /* @__PURE__ */ jsx(ChevronDown, {
24322
24318
  className: "pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 text-muted-foreground select-none",
@@ -25070,7 +25066,7 @@ function SelectedSourceValue({ bound, readOnly, connected, sourceMissing, onInva
25070
25066
  children: t("inspector.sources.checkFailed")
25071
25067
  })] });
25072
25068
  }
25073
- function SourceValueEditor({ fixed = false, editor: customEditor, schema, label: fieldLabel, nullable, description: fieldDescription, presentation, upstream: providedUpstream, embedded = false, handleNames = [], value, connected, sourceMissing, onInvalidChange, validationError, variableName, variables, disabled, readOnly, onValue, onVariable, onReset }) {
25069
+ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEditor, schema, label: fieldLabel, nullable, description: fieldDescription, presentation, upstream: providedUpstream, embedded = false, handleNames = [], value, connected, sourceMissing, onInvalidChange, validationError, variableName, variables, disabled, readOnly, onValue, onVariable, onReset }) {
25074
25070
  const t = useTranslate();
25075
25071
  const [sourceOpen, setSourceOpen] = useState(false);
25076
25072
  const candidates = useInputSourceQuery(providedUpstream?.query?.candidates, sourceOpen);
@@ -25148,6 +25144,7 @@ function SourceValueEditor({ fixed = false, editor: customEditor, schema, label:
25148
25144
  ref: setSourceContainer,
25149
25145
  className: "flex items-center",
25150
25146
  children: /* @__PURE__ */ jsxs(DropdownMenu, {
25147
+ open: sourceOpen,
25151
25148
  onOpenChange: (open) => {
25152
25149
  setSourceOpen(open);
25153
25150
  if (open && variables.enabled) variables.onOpen?.();
@@ -25177,7 +25174,7 @@ function SourceValueEditor({ fixed = false, editor: customEditor, schema, label:
25177
25174
  container: sourcePortal,
25178
25175
  children: [
25179
25176
  /* @__PURE__ */ jsx(MenuHeader, { children: t("inspector.sources.title") }),
25180
- /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
25177
+ !sourceOnly && /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
25181
25178
  value: sourceKind === "literal" ? literalSource : "",
25182
25179
  onValueChange: () => {
25183
25180
  if (bound) onVariable(void 0);
@@ -25346,7 +25343,7 @@ function SourceValueEditor({ fixed = false, editor: customEditor, schema, label:
25346
25343
  variableCompatible,
25347
25344
  variableName,
25348
25345
  variables
25349
- }) : llm ? /* @__PURE__ */ jsx(LlmInputEditor, {
25346
+ }) : llm && !sourceOnly ? /* @__PURE__ */ jsx(LlmInputEditor, {
25350
25347
  readOnly,
25351
25348
  addon: sourceControl,
25352
25349
  schema,
@@ -25363,16 +25360,24 @@ function SourceValueEditor({ fixed = false, editor: customEditor, schema, label:
25363
25360
  ...presentation,
25364
25361
  validationError,
25365
25362
  onInvalidChange: connected || bound || sourceMissing ? void 0 : onInvalidChange,
25366
- valueAddon: llm && !connected && !bound ? void 0 : sourceControl,
25363
+ valueAddon: llm && !sourceOnly && !connected && !bound ? void 0 : sourceControl,
25367
25364
  description: presentation?.description ?? fieldDescription,
25368
25365
  schema,
25369
25366
  nullable,
25370
- value,
25367
+ value: sourceOnly && !connected && !bound && !sourceMissing ? void 0 : value,
25368
+ unset: sourceOnly && !connected && !bound && !sourceMissing ? {
25369
+ label: t("inspector.sources.select"),
25370
+ required: true,
25371
+ onActivate: fixed ? void 0 : () => {
25372
+ setSourceOpen(true);
25373
+ if (variables.enabled) variables.onOpen?.();
25374
+ }
25375
+ } : void 0,
25371
25376
  label: fieldLabel,
25372
25377
  path: `/${fieldLabel.replaceAll("~", "~0").replaceAll("/", "~1")}`,
25373
25378
  disabled,
25374
25379
  onReset,
25375
- valueEditable: !connected && !bound && !sourceMissing,
25380
+ valueEditable: !sourceOnly && !connected && !bound && !sourceMissing,
25376
25381
  editor: customEditor ?? editor,
25377
25382
  onDraftIssue: draftIssue,
25378
25383
  onChange: (next, deletion) => onValue(next, deletion)
@@ -25892,21 +25897,13 @@ function ConditionBranchesEditor({ value: configuration, disabled, readOnly, onC
25892
25897
  disabled: false,
25893
25898
  onChange: renameOutput
25894
25899
  })]
25895
- }), /* @__PURE__ */ jsxs(Field, {
25896
- className: "gap-1.5",
25897
- children: [/* @__PURE__ */ jsx(FieldLabel, {
25898
- className: "text-xs font-normal text-muted-foreground",
25899
- children: t("inspector.node.description")
25900
- }), /* @__PURE__ */ jsx(Textarea, {
25901
- "aria-label": t("inspector.node.description"),
25902
- rows: 2,
25903
- className: "min-h-16 max-h-40 resize-y text-xs md:text-xs",
25904
- value: item.description ?? "",
25905
- onChange: (event) => save({
25906
- ...item,
25907
- description: event.target.value
25908
- })
25909
- })]
25900
+ }), /* @__PURE__ */ jsx(PurposeField, {
25901
+ compact: true,
25902
+ value: item.description ?? "",
25903
+ onChange: (event) => save({
25904
+ ...item,
25905
+ description: event.target.value
25906
+ })
25910
25907
  })]
25911
25908
  })
25912
25909
  })
@@ -25951,6 +25948,200 @@ function ConditionBranchesEditor({ value: configuration, disabled, readOnly, onC
25951
25948
  });
25952
25949
  }
25953
25950
  //#endregion
25951
+ //#region src/workbench/browser/runtime/editor/errorTriggerSources.tsx
25952
+ function ErrorTriggerSources({ flows, flowId, value, disabled = false, complete = true, footer, onChange }) {
25953
+ const t = useTranslate();
25954
+ const id = useId();
25955
+ const [query, setQuery] = useState("");
25956
+ const [open, setOpen] = useState(false);
25957
+ const [container, setContainer] = useState(null);
25958
+ const search = useRef(null);
25959
+ const eligible = flows.filter((flow) => flow.flowId != flowId && flow.status == "active" && flow.live != null);
25960
+ const candidates = [.../* @__PURE__ */ new Set([...eligible.map((flow) => flow.flowId), ...value])].map((sourceId) => {
25961
+ const flow = flows.find((item) => item.flowId == sourceId);
25962
+ const issue = sourceId == flowId ? "self" : flow?.status == "retiring" ? "retiring" : flow == null ? complete ? "deleted" : void 0 : flow.live == null ? "unpublished" : void 0;
25963
+ return {
25964
+ id: sourceId,
25965
+ name: flow?.name ?? (issue == "deleted" ? t("errorWorkflow.deletedName") : sourceId),
25966
+ issue
25967
+ };
25968
+ });
25969
+ const visible = candidates.filter((flow) => `${flow.name} ${flow.id}`.toLocaleLowerCase().includes(query.toLocaleLowerCase()));
25970
+ const selected = candidates.filter((flow) => value.includes(flow.id));
25971
+ const summary = selected.map((flow) => flow.name).join(", ");
25972
+ const unavailable = selected.filter((flow) => flow.issue);
25973
+ return /* @__PURE__ */ jsxs(Field, {
25974
+ className: "inspector-field-section",
25975
+ children: [/* @__PURE__ */ jsx(FieldLabel, {
25976
+ className: "inspector-section-title",
25977
+ htmlFor: id,
25978
+ children: t("errorWorkflow.sources")
25979
+ }), /* @__PURE__ */ jsxs("div", {
25980
+ className: "flex flex-col gap-3",
25981
+ children: [
25982
+ /* @__PURE__ */ jsx("div", {
25983
+ ref: setContainer,
25984
+ className: "min-w-0",
25985
+ children: /* @__PURE__ */ jsxs(Popover, {
25986
+ open,
25987
+ onOpenChange: (next) => {
25988
+ setOpen(next);
25989
+ if (!next) setQuery("");
25990
+ },
25991
+ children: [/* @__PURE__ */ jsxs(PopoverTrigger, {
25992
+ render: /* @__PURE__ */ jsx(Button$1, {
25993
+ id,
25994
+ type: "button",
25995
+ variant: "field",
25996
+ size: "field",
25997
+ disabled,
25998
+ "aria-label": `${t("errorWorkflow.sources")}: ${summary || t("errorWorkflow.choose")}`,
25999
+ "aria-describedby": `${id}-hint${unavailable.length > 0 ? ` ${id}-error` : ""}`,
26000
+ "aria-invalid": unavailable.length > 0 || void 0,
26001
+ className: "w-full min-w-0 justify-between"
26002
+ }),
26003
+ children: [/* @__PURE__ */ jsx("span", {
26004
+ className: `min-w-0 flex-1 truncate text-left ${value.length == 0 ? "text-muted-foreground" : ""}`,
26005
+ title: summary || void 0,
26006
+ children: summary || t("errorWorkflow.choose")
26007
+ }), /* @__PURE__ */ jsx(SelectChevron, {})]
26008
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
26009
+ container,
26010
+ align: "start",
26011
+ initialFocus: search,
26012
+ "aria-label": t("errorWorkflow.sources"),
26013
+ className: `w-(--anchor-width) min-w-56 max-w-[calc(100vw-24px)] gap-1 ${selectionMenuContentClass}`,
26014
+ children: [
26015
+ /* @__PURE__ */ jsx("div", {
26016
+ className: "p-1",
26017
+ children: /* @__PURE__ */ jsx(Input$1, {
26018
+ ref: search,
26019
+ "aria-label": t("errorWorkflow.search"),
26020
+ placeholder: t("errorWorkflow.search"),
26021
+ value: query,
26022
+ onChange: (event) => setQuery(event.target.value)
26023
+ })
26024
+ }),
26025
+ /* @__PURE__ */ jsxs("div", {
26026
+ role: "group",
26027
+ "aria-label": t("errorWorkflow.sources"),
26028
+ className: "max-h-[min(40vh,280px)] overflow-y-auto overscroll-contain",
26029
+ children: [visible.map((flow) => /* @__PURE__ */ jsxs(Label, {
26030
+ className: `flex cursor-default items-center gap-2 px-2 hover:bg-accent focus-within:bg-accent ${selectionMenuItemClass}`,
26031
+ children: [/* @__PURE__ */ jsx(Checkbox, {
26032
+ checked: value.includes(flow.id),
26033
+ disabled,
26034
+ onCheckedChange: (checked) => onChange(checked ? [...value, flow.id] : value.filter((item) => item != flow.id))
26035
+ }), /* @__PURE__ */ jsxs("span", {
26036
+ className: "min-w-0 flex-1 break-words",
26037
+ children: [
26038
+ flow.name,
26039
+ flow.issue == "deleted" && /* @__PURE__ */ jsx("span", {
26040
+ className: "block break-all text-muted-foreground",
26041
+ children: flow.id
26042
+ }),
26043
+ flow.issue && /* @__PURE__ */ jsx("span", {
26044
+ className: "block text-destructive",
26045
+ children: t(`errorWorkflow.${flow.issue}`)
26046
+ })
26047
+ ]
26048
+ })]
26049
+ }, flow.id)), visible.length == 0 && /* @__PURE__ */ jsx("p", {
26050
+ className: "px-2 py-3 text-xs text-muted-foreground",
26051
+ children: t(query ? "errorWorkflow.noMatches" : "errorWorkflow.empty")
26052
+ })]
26053
+ }),
26054
+ footer,
26055
+ /* @__PURE__ */ jsx("div", {
26056
+ role: "separator",
26057
+ className: "mx-2 my-1 h-px bg-border/50"
26058
+ }),
26059
+ /* @__PURE__ */ jsxs("div", {
26060
+ className: "flex items-center justify-between gap-2 px-1 pb-1",
26061
+ children: [/* @__PURE__ */ jsx(Button$1, {
26062
+ variant: "ghost",
26063
+ size: "sm",
26064
+ disabled: disabled || value.length == 0,
26065
+ onClick: () => onChange([]),
26066
+ children: t("errorWorkflow.clear")
26067
+ }), /* @__PURE__ */ jsx(Button$1, {
26068
+ variant: "ghost",
26069
+ size: "sm",
26070
+ onClick: () => {
26071
+ setOpen(false);
26072
+ setQuery("");
26073
+ },
26074
+ children: t("errorWorkflow.done")
26075
+ })]
26076
+ })
26077
+ ]
26078
+ })]
26079
+ })
26080
+ }),
26081
+ /* @__PURE__ */ jsx(FieldDescription, {
26082
+ id: `${id}-hint`,
26083
+ children: t("errorWorkflow.setupHint")
26084
+ }),
26085
+ unavailable.length > 0 && /* @__PURE__ */ jsxs("div", {
26086
+ className: "flex flex-col items-start gap-2",
26087
+ children: [/* @__PURE__ */ jsxs(FieldError, {
26088
+ id: `${id}-error`,
26089
+ children: [/* @__PURE__ */ jsx("ul", { children: unavailable.map((flow) => /* @__PURE__ */ jsxs("li", { children: [
26090
+ flow.name,
26091
+ " · ",
26092
+ t(`errorWorkflow.${flow.issue}`)
26093
+ ] }, flow.id)) }), /* @__PURE__ */ jsx("p", { children: t("errorWorkflow.removeHint") })]
26094
+ }), !disabled && /* @__PURE__ */ jsx(Button$1, {
26095
+ variant: "outline",
26096
+ size: "sm",
26097
+ onClick: () => onChange(value.filter((sourceId) => !unavailable.some((flow) => flow.id == sourceId))),
26098
+ children: t("errorWorkflow.removeUnavailable")
26099
+ })]
26100
+ })
26101
+ ]
26102
+ })]
26103
+ });
26104
+ }
26105
+ function ErrorTriggerSourcesEditor({ store, nodeId, value, disabled }) {
26106
+ const t = useTranslate();
26107
+ const draft = useVal(store.$.draft);
26108
+ const flows = useVal(store.$.flows);
26109
+ const loading = useVal(store.$.flowLoading);
26110
+ const failed = useVal(store.$.flowLoadFailed);
26111
+ const more = useVal(store.$.flowNextCursor);
26112
+ const loadingMore = useVal(store.$.flowLoadingMore);
26113
+ const moreFailed = useVal(store.$.flowLoadMoreFailed);
26114
+ useEffect(() => {
26115
+ store.reloadFlows();
26116
+ }, [store]);
26117
+ return /* @__PURE__ */ jsx("div", {
26118
+ className: "flex flex-col gap-3",
26119
+ "aria-busy": loading || loadingMore,
26120
+ children: /* @__PURE__ */ jsx(ErrorTriggerSources, {
26121
+ flows,
26122
+ flowId: draft?.flowId ?? "",
26123
+ value,
26124
+ disabled: disabled || loading,
26125
+ complete: !loading && !failed && more == null,
26126
+ footer: /* @__PURE__ */ jsxs(Fragment$1, { children: [failed && /* @__PURE__ */ jsx(Button$1, {
26127
+ variant: "outline",
26128
+ size: "sm",
26129
+ onClick: () => void store.reloadFlows(),
26130
+ children: t("errorWorkflow.retry")
26131
+ }), more != null && /* @__PURE__ */ jsx(Button$1, {
26132
+ variant: "outline",
26133
+ size: "sm",
26134
+ disabled: loadingMore,
26135
+ onClick: () => void store.loadMoreFlows(),
26136
+ children: t(moreFailed ? "errorWorkflow.retry" : "errorWorkflow.more")
26137
+ })] }),
26138
+ onChange: (next) => {
26139
+ store.saveErrorSources(nodeId, next);
26140
+ }
26141
+ })
26142
+ });
26143
+ }
26144
+ //#endregion
25954
26145
  //#region src/workbench/browser/runtime/createEventSourceDialog.tsx
25955
26146
  function CreateEventSourceDialog({ client, teamId, existingNames, disabled, defaultOpen = false, className, trigger, onSelect, onCreated }) {
25956
26147
  const t = useTranslate();
@@ -26579,23 +26770,14 @@ function PortSettingsFields({ port, names, disabled, showNullable, onChange }) {
26579
26770
  })
26580
26771
  })]
26581
26772
  }),
26582
- /* @__PURE__ */ jsxs(Field, {
26583
- className: "gap-1.5",
26584
- children: [/* @__PURE__ */ jsx(FieldLabel, {
26585
- htmlFor: `${id}-description`,
26586
- className: "text-xs font-normal text-muted-foreground",
26587
- children: t("inspector.node.description")
26588
- }), /* @__PURE__ */ jsx(Textarea, {
26589
- id: `${id}-description`,
26590
- rows: 2,
26591
- className: "min-h-16 max-h-40 resize-y text-xs md:text-xs",
26592
- value: port.description ?? "",
26593
- readOnly: disabled,
26594
- onChange: (event) => onChange({
26595
- ...port,
26596
- description: event.target.value
26597
- })
26598
- })]
26773
+ /* @__PURE__ */ jsx(PurposeField, {
26774
+ compact: true,
26775
+ value: port.description ?? "",
26776
+ readOnly: disabled,
26777
+ onChange: (event) => onChange({
26778
+ ...port,
26779
+ description: event.target.value
26780
+ })
26599
26781
  }),
26600
26782
  /* @__PURE__ */ jsxs(Field, {
26601
26783
  className: "gap-1.5",
@@ -27897,26 +28079,533 @@ function LlmTaskSection({ selection, disabled, store }) {
27897
28079
  //#endregion
27898
28080
  //#region src/workbench/browser/runtime/editor/nodeDescription.tsx
27899
28081
  /** The draft belongs to this field; the product revision owns the saved description. */
27900
- function NodeDescription({ value, disabled = false, readOnly = false, onSave }) {
28082
+ function NodeDescription({ value, placeholder, disabled = false, readOnly = false, onSave }) {
27901
28083
  const t = useTranslate();
27902
- const id = useId();
27903
28084
  const [draft, setDraft] = useState(value ?? "");
27904
28085
  useEffect(() => setDraft(value ?? ""), [value]);
27905
- return /* @__PURE__ */ jsxs(Field, {
28086
+ return /* @__PURE__ */ jsx(PurposeField, {
28087
+ readOnly: disabled || readOnly,
28088
+ placeholder: placeholder?.trim() || t("inspector.node.describe"),
28089
+ value: draft,
28090
+ onChange: (event) => setDraft(event.target.value),
28091
+ onBlur: () => {
28092
+ if (!disabled && !readOnly && draft !== (value ?? "")) onSave?.(draft === "" ? void 0 : draft);
28093
+ }
28094
+ });
28095
+ }
28096
+ //#endregion
28097
+ //#region src/openapi/common/documentSession.ts
28098
+ /** Owned by one mounted panel, never shared across nodes or persisted. */
28099
+ var OpenApiDocumentSession = class {
28100
+ #controller;
28101
+ #request;
28102
+ #value;
28103
+ #url;
28104
+ constructor(load) {
28105
+ this.load = load;
28106
+ }
28107
+ read(url, refresh = false) {
28108
+ if (this.#url == url && !refresh) {
28109
+ if (this.#value != null) return Promise.resolve(this.#value);
28110
+ if (this.#request != null) return this.#request;
28111
+ }
28112
+ this.clear();
28113
+ this.#url = url;
28114
+ const controller = new AbortController();
28115
+ this.#controller = controller;
28116
+ const request = this.load(url, controller.signal).then((value) => {
28117
+ if (controller.signal.aborted || this.#controller != controller) throw new Error("Document loading was cancelled.");
28118
+ listOperations(value);
28119
+ this.#value = value;
28120
+ return value;
28121
+ }).finally(() => {
28122
+ if (this.#controller == controller) this.#request = void 0;
28123
+ });
28124
+ this.#request = request;
28125
+ return request;
28126
+ }
28127
+ clear() {
28128
+ this.#controller?.abort();
28129
+ this.#controller = void 0;
28130
+ this.#value = void 0;
28131
+ this.#request = void 0;
28132
+ this.#url = void 0;
28133
+ }
28134
+ };
28135
+ //#endregion
28136
+ //#region src/workbench/browser/runtime/editor/openApiSection.tsx
28137
+ function OpenApiSection({ task, disabled, load, onSave, credentials }) {
28138
+ const t = useTranslate();
28139
+ const config = task.executor;
28140
+ const [url, setUrl] = useState(config.sourceUrl);
28141
+ const [address, setAddress] = useState(config.serverUrl);
28142
+ const [document, setDocument] = useState();
28143
+ const [serverError, setServerError] = useState("");
28144
+ const [operationFailure, setOperationFailure] = useState("");
28145
+ const [documentError, setDocumentError] = useState("");
28146
+ const [container, setContainer] = useState(null);
28147
+ const [operationsOpen, setOperationsOpen] = useState(false);
28148
+ const [loading, setLoading] = useState(false);
28149
+ const [search, setSearch] = useState("");
28150
+ const [serverIndex, setServerIndex] = useState();
28151
+ const [serversOpen, setServersOpen] = useState(false);
28152
+ const [serverVariables, setServerVariables] = useState({});
28153
+ const [keyName, setKeyName] = useState(config.auth.find((item) => item.id == "manual")?.name ?? "X-API-Key");
28154
+ const keyLocation = config.auth.find((item) => item.id == "manual")?.in ?? "header";
28155
+ const loadRef = useRef(load);
28156
+ loadRef.current = load;
28157
+ const [session] = useState(() => new OpenApiDocumentSession((source, signal) => loadRef.current(source, signal)));
28158
+ const generation = useRef(0);
28159
+ useEffect(() => () => {
28160
+ generation.current++;
28161
+ session.clear();
28162
+ }, [session]);
28163
+ useEffect(() => {
28164
+ setAddress(config.serverUrl);
28165
+ }, [config.serverUrl]);
28166
+ async function read(refresh = false) {
28167
+ const current = ++generation.current;
28168
+ if (!url.trim()) return;
28169
+ setLoading(true);
28170
+ setDocumentError("");
28171
+ try {
28172
+ const result = await session.read(url, refresh);
28173
+ if (generation.current != current) return;
28174
+ setDocument(result);
28175
+ return result;
28176
+ } catch (error) {
28177
+ if (generation.current == current) {
28178
+ setDocument(void 0);
28179
+ setOperationsOpen(false);
28180
+ setDocumentError(error.message);
28181
+ }
28182
+ } finally {
28183
+ if (generation.current == current) setLoading(false);
28184
+ }
28185
+ }
28186
+ async function save(next, field = "operation") {
28187
+ const report = field == "serverUrl" ? setServerError : setOperationFailure;
28188
+ try {
28189
+ if (next.serverUrl) {
28190
+ const server = new URL(next.serverUrl);
28191
+ if (!["http:", "https:"].includes(server.protocol) || server.username || server.password || server.search || server.hash) throw new Error("Enter an HTTP(S) server URL without credentials, query or fragment.");
28192
+ }
28193
+ if (await onSave(task, openApiTask(next, task.name))) {
28194
+ report("");
28195
+ setOperationsOpen(false);
28196
+ } else report(t("openapi.saveFailed"));
28197
+ } catch (error) {
28198
+ report(error.message);
28199
+ }
28200
+ }
28201
+ const savedSelection = !!config.path && url == config.sourceUrl;
28202
+ const issues = openApiFieldIssues({
28203
+ ...task,
28204
+ executor: {
28205
+ ...config,
28206
+ sourceUrl: url,
28207
+ serverUrl: address
28208
+ }
28209
+ });
28210
+ const sourceIssue = issues.find((issue) => issue.field == "sourceUrl");
28211
+ const showOperations = savedSelection || !!url.trim() && !documentError && document != null;
28212
+ const urlError = loading ? void 0 : documentError || (sourceIssue ? !url.trim() ? t("openapi.urlRequired") : sourceIssue.message : !savedSelection && document == null ? t("openapi.loadRequired") : void 0);
28213
+ const operationError = operationFailure || (!savedSelection ? t("openapi.operationRequired") : issues.find((issue) => issue.field == "operation")?.message);
28214
+ const addressError = serverError || issues.find((issue) => issue.field == "serverUrl")?.message;
28215
+ const operations = document == null ? [] : listOperations(document);
28216
+ const grouped = operations.some((op) => op.tag.trim() != "");
28217
+ const query = search.toLowerCase();
28218
+ const choices = operations.filter((op) => `${op.tag} ${op.label} ${op.method} ${op.path}`.toLowerCase().includes(query));
28219
+ const groups = Map.groupBy(choices, (op) => op.tag.trim());
28220
+ const untagged = groups.get("");
28221
+ if (untagged != null) {
28222
+ groups.delete("");
28223
+ groups.set("", untagged);
28224
+ }
28225
+ const availableServers = config.path ? (() => {
28226
+ try {
28227
+ return servers(document ?? config.document, config.path, config.method);
28228
+ } catch {
28229
+ return [];
28230
+ }
28231
+ })() : [];
28232
+ const selectedServer = serverIndex == null ? void 0 : availableServers[serverIndex];
28233
+ const security = config.path ? securityOptions(config.document, config.path, config.method) : [];
28234
+ const declaredAuth = security.findIndex((entry) => dequal(entry.auth, config.auth));
28235
+ const manualAuth = config.auth.find((item) => item.id == "manual");
28236
+ function useServer(index, variables = {}) {
28237
+ try {
28238
+ const serverUrl = serverAddress(availableServers[index], url, variables);
28239
+ setServerIndex(index);
28240
+ setServerVariables(variables);
28241
+ setAddress(serverUrl);
28242
+ setServersOpen(false);
28243
+ save({
28244
+ ...config,
28245
+ serverUrl
28246
+ }, "serverUrl");
28247
+ } catch (error) {
28248
+ setServerError(error.message);
28249
+ }
28250
+ }
28251
+ function useAuth(type, name = keyName, location = keyLocation) {
28252
+ save({
28253
+ ...config,
28254
+ auth: [{
28255
+ id: "manual",
28256
+ type,
28257
+ ...type == "apiKey" ? {
28258
+ name,
28259
+ in: location
28260
+ } : {}
28261
+ }]
28262
+ });
28263
+ }
28264
+ const renderOperation = (op) => /* @__PURE__ */ jsxs(Button$1, {
28265
+ className: `w-full h-auto justify-start px-2 whitespace-normal text-left ${selectionMenuItemClass}`,
28266
+ variant: "ghost",
28267
+ disabled,
28268
+ onClick: () => {
28269
+ try {
28270
+ save(selectOperation(document, url, op.path, op.method));
28271
+ } catch (error) {
28272
+ setOperationFailure(error.message);
28273
+ }
28274
+ },
28275
+ children: [/* @__PURE__ */ jsx("span", {
28276
+ className: "shrink-0 self-start font-mono text-muted-foreground",
28277
+ children: op.method.toUpperCase()
28278
+ }), /* @__PURE__ */ jsxs("span", {
28279
+ className: "min-w-0 break-words",
28280
+ children: [/* @__PURE__ */ jsx("span", {
28281
+ className: "font-mono text-foreground",
28282
+ children: op.path
28283
+ }), /* @__PURE__ */ jsxs("span", {
28284
+ className: "pl-2 text-muted-foreground",
28285
+ children: [" ", op.label]
28286
+ })]
28287
+ })]
28288
+ }, `${op.method} ${op.path}`);
28289
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Field, {
27906
28290
  className: "inspector-field-section",
28291
+ "data-inspector-section": "task",
27907
28292
  children: [/* @__PURE__ */ jsx(FieldLabel, {
27908
28293
  className: "inspector-section-title",
27909
- htmlFor: id,
27910
- children: t("inspector.node.description")
27911
- }), /* @__PURE__ */ jsx(Textarea, {
27912
- id,
27913
- readOnly: disabled || readOnly,
27914
- placeholder: t("inspector.node.describe"),
27915
- value: draft,
27916
- onChange: (event) => setDraft(event.target.value),
27917
- onBlur: () => {
27918
- if (!disabled && !readOnly && draft !== (value ?? "")) onSave?.(draft === "" ? void 0 : draft);
27919
- }
28294
+ children: "OpenAPI"
28295
+ }), /* @__PURE__ */ jsxs("div", {
28296
+ ref: setContainer,
28297
+ className: "node-settings flex flex-col gap-3",
28298
+ children: [
28299
+ /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
28300
+ htmlFor: "openapi-url",
28301
+ children: t("openapi.document")
28302
+ }), /* @__PURE__ */ jsxs("div", {
28303
+ className: "flex items-start gap-2",
28304
+ children: [/* @__PURE__ */ jsx("div", {
28305
+ className: "min-w-0 flex-1",
28306
+ children: /* @__PURE__ */ jsx(ValueEditorFeedback, {
28307
+ error: urlError,
28308
+ children: (errorId) => /* @__PURE__ */ jsx(Input$1, {
28309
+ "aria-invalid": urlError != null,
28310
+ "aria-describedby": errorId,
28311
+ id: "openapi-url",
28312
+ disabled,
28313
+ value: url,
28314
+ onChange: (event) => {
28315
+ generation.current++;
28316
+ session.clear();
28317
+ setDocument(void 0);
28318
+ setOperationsOpen(false);
28319
+ setLoading(false);
28320
+ setDocumentError("");
28321
+ setOperationFailure("");
28322
+ setUrl(event.target.value);
28323
+ }
28324
+ })
28325
+ })
28326
+ }), /* @__PURE__ */ jsx(Button$1, {
28327
+ variant: "outline",
28328
+ size: "sm",
28329
+ disabled: disabled || loading || !url.trim(),
28330
+ onClick: async () => {
28331
+ const value = await read(true);
28332
+ if (value != null) {
28333
+ if (!savedSelection) return;
28334
+ try {
28335
+ const next = selectOperation(value, url, config.path, config.method);
28336
+ save({
28337
+ ...next,
28338
+ serverUrl: config.serverUrl,
28339
+ auth: securityOptions(next.document, next.path, next.method).some((choice) => dequal(choice.auth, config.auth)) || config.auth.every((item) => item.id == "manual") ? config.auth : next.auth
28340
+ });
28341
+ } catch (error) {
28342
+ setOperationFailure(error.message);
28343
+ }
28344
+ }
28345
+ },
28346
+ children: t(loading ? "openapi.loading" : "openapi.update")
28347
+ })]
28348
+ })] }),
28349
+ showOperations && (document != null && operations.length == 0 ? /* @__PURE__ */ jsx("p", {
28350
+ role: "status",
28351
+ className: "m-0 px-2 py-1 text-xs text-muted-foreground",
28352
+ children: t("openapi.noOperations")
28353
+ }) : /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: t("openapi.operation") }), /* @__PURE__ */ jsxs(Popover, {
28354
+ open: operationsOpen,
28355
+ onOpenChange: (open) => {
28356
+ setOperationsOpen(open);
28357
+ if (open) {
28358
+ setSearch("");
28359
+ read();
28360
+ }
28361
+ },
28362
+ children: [/* @__PURE__ */ jsx(ValueEditorFeedback, {
28363
+ error: operationsOpen ? void 0 : operationError,
28364
+ children: (errorId) => /* @__PURE__ */ jsxs(PopoverTrigger, {
28365
+ render: /* @__PURE__ */ jsx(Button$1, {
28366
+ variant: "field",
28367
+ size: "field"
28368
+ }),
28369
+ className: "w-full justify-between",
28370
+ "aria-label": savedSelection ? `${config.method.toUpperCase()} ${config.path}` : t("openapi.operation"),
28371
+ "aria-expanded": operationsOpen,
28372
+ "aria-invalid": operationError != null,
28373
+ "aria-describedby": errorId,
28374
+ disabled,
28375
+ children: [/* @__PURE__ */ jsx("span", {
28376
+ className: "min-w-0 truncate",
28377
+ children: savedSelection ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
28378
+ className: "mr-2 font-mono text-muted-foreground",
28379
+ children: config.method.toUpperCase()
28380
+ }), /* @__PURE__ */ jsx("span", {
28381
+ className: "font-mono",
28382
+ children: config.path
28383
+ })] }) : t("openapi.operation")
28384
+ }), /* @__PURE__ */ jsx(SelectChevron, {})]
28385
+ })
28386
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
28387
+ container,
28388
+ align: "start",
28389
+ className: `w-(--anchor-width) max-w-[calc(100vw-24px)] gap-0 rounded-[calc(var(--ui-control-radius,var(--ui-radius))_+_2px)] p-1`,
28390
+ "aria-label": t("openapi.operation"),
28391
+ children: [
28392
+ /* @__PURE__ */ jsx("div", {
28393
+ className: "p-1",
28394
+ children: /* @__PURE__ */ jsx(Input$1, {
28395
+ "aria-label": t("openapi.search"),
28396
+ placeholder: t("openapi.search"),
28397
+ value: search,
28398
+ onChange: (event) => setSearch(event.target.value)
28399
+ })
28400
+ }),
28401
+ loading && /* @__PURE__ */ jsx("span", {
28402
+ role: "status",
28403
+ children: t("openapi.loading")
28404
+ }),
28405
+ !loading && choices.length == 0 && /* @__PURE__ */ jsx("p", {
28406
+ role: "status",
28407
+ className: "m-0 px-2 py-1 text-xs text-muted-foreground",
28408
+ children: t("openapi.noMatches")
28409
+ }),
28410
+ /* @__PURE__ */ jsx("div", {
28411
+ className: "flex max-h-64 flex-col overflow-auto px-1 pb-1",
28412
+ children: grouped ? [...groups].map(([tag, entries]) => /* @__PURE__ */ jsxs("div", {
28413
+ role: "group",
28414
+ "aria-label": tag || t("openapi.untagged"),
28415
+ children: [/* @__PURE__ */ jsx("div", {
28416
+ className: "px-2 py-0.5 text-xs font-normal leading-5 text-muted-foreground",
28417
+ children: tag || t("openapi.untagged")
28418
+ }), /* @__PURE__ */ jsx("div", {
28419
+ className: "ml-2 flex flex-col",
28420
+ children: entries.map(renderOperation)
28421
+ })]
28422
+ }, tag)) : choices.map(renderOperation)
28423
+ })
28424
+ ]
28425
+ })]
28426
+ })] })),
28427
+ savedSelection && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
28428
+ htmlFor: "openapi-server",
28429
+ children: t("openapi.server")
28430
+ }), /* @__PURE__ */ jsx(ValueEditorFeedback, {
28431
+ error: addressError,
28432
+ children: (errorId) => /* @__PURE__ */ jsxs("div", {
28433
+ className: "flex min-w-0 items-center gap-1",
28434
+ children: [/* @__PURE__ */ jsx(Input$1, {
28435
+ "aria-invalid": addressError != null,
28436
+ "aria-describedby": errorId,
28437
+ id: "openapi-server",
28438
+ disabled,
28439
+ value: address,
28440
+ onChange: (event) => {
28441
+ setAddress(event.target.value);
28442
+ setServerIndex(void 0);
28443
+ setServerError("");
28444
+ },
28445
+ onBlur: () => {
28446
+ if (address != config.serverUrl) save({
28447
+ ...config,
28448
+ serverUrl: address
28449
+ }, "serverUrl");
28450
+ }
28451
+ }), /* @__PURE__ */ jsxs(Popover, {
28452
+ open: serversOpen,
28453
+ onOpenChange: (open) => {
28454
+ setServersOpen(open);
28455
+ if (open) read();
28456
+ },
28457
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
28458
+ render: /* @__PURE__ */ jsx(Button$1, {
28459
+ variant: "field",
28460
+ size: "icon-sm"
28461
+ }),
28462
+ disabled,
28463
+ "aria-label": t("openapi.servers"),
28464
+ children: /* @__PURE__ */ jsx(SelectChevron, {})
28465
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
28466
+ container,
28467
+ align: "end",
28468
+ "aria-label": t("openapi.servers"),
28469
+ children: [loading && /* @__PURE__ */ jsx("span", {
28470
+ role: "status",
28471
+ children: t("openapi.loading")
28472
+ }), availableServers.map((server, index) => {
28473
+ let label;
28474
+ try {
28475
+ label = serverAddress(server, url);
28476
+ } catch {
28477
+ label = String(server.url);
28478
+ }
28479
+ return /* @__PURE__ */ jsx(Button$1, {
28480
+ variant: "ghost",
28481
+ className: "justify-start whitespace-normal break-all text-left h-auto",
28482
+ onClick: () => useServer(index),
28483
+ children: label
28484
+ }, index);
28485
+ })]
28486
+ })]
28487
+ })]
28488
+ })
28489
+ })] }), selectedServer != null && Object.entries(object(selectedServer.variables ?? {})).map(([name, definition]) => /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: name }), /* @__PURE__ */ jsx(Input$1, {
28490
+ "aria-label": name,
28491
+ value: serverVariables[name] ?? String(object(definition).default ?? ""),
28492
+ disabled,
28493
+ onChange: (event) => setServerVariables({
28494
+ ...serverVariables,
28495
+ [name]: event.target.value
28496
+ }),
28497
+ onBlur: () => useServer(serverIndex, serverVariables)
28498
+ })] }, name))] })
28499
+ ]
28500
+ })]
28501
+ }), savedSelection && /* @__PURE__ */ jsx(AuthenticationDisclosure, {
28502
+ title: t("openapi.auth"),
28503
+ children: (onInvalidChange) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
28504
+ /* @__PURE__ */ jsx(Field, { children: /* @__PURE__ */ jsxs(NativeSelect, {
28505
+ "aria-label": t("openapi.auth"),
28506
+ id: "openapi-auth",
28507
+ className: "w-full",
28508
+ disabled,
28509
+ value: declaredAuth >= 0 ? `declared:${declaredAuth}` : manualAuth?.type ?? "none",
28510
+ onChange: (event) => {
28511
+ const value = event.target.value;
28512
+ if (value.startsWith("declared:")) {
28513
+ const auth = security[Number(value.slice(9))]?.auth;
28514
+ if (auth != null) save({
28515
+ ...config,
28516
+ auth
28517
+ });
28518
+ } else if (value == "none") save({
28519
+ ...config,
28520
+ auth: []
28521
+ });
28522
+ else useAuth(value);
28523
+ },
28524
+ children: [
28525
+ security.map((entry, index) => /* @__PURE__ */ jsxs(NativeSelectOption, {
28526
+ value: `declared:${index}`,
28527
+ disabled: entry.auth == null,
28528
+ children: [entry.auth?.length == 0 ? t("openapi.none") : entry.label, entry.error ? ` (${t("openapi.unsupported")})` : ""]
28529
+ }, index)),
28530
+ !security.some((entry) => entry.auth?.length == 0) && /* @__PURE__ */ jsx(NativeSelectOption, {
28531
+ value: "none",
28532
+ children: t("openapi.none")
28533
+ }),
28534
+ /* @__PURE__ */ jsx(NativeSelectOption, {
28535
+ value: "bearer",
28536
+ children: "Bearer"
28537
+ }),
28538
+ /* @__PURE__ */ jsx(NativeSelectOption, {
28539
+ value: "basic",
28540
+ children: "Basic"
28541
+ }),
28542
+ /* @__PURE__ */ jsx(NativeSelectOption, {
28543
+ value: "apiKey",
28544
+ children: "API Key"
28545
+ })
28546
+ ]
28547
+ }) }),
28548
+ manualAuth?.type == "apiKey" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
28549
+ htmlFor: "openapi-key-name",
28550
+ children: t("openapi.keyName")
28551
+ }), /* @__PURE__ */ jsx(Input$1, {
28552
+ id: "openapi-key-name",
28553
+ value: keyName,
28554
+ disabled,
28555
+ onChange: (event) => setKeyName(event.target.value),
28556
+ onBlur: () => {
28557
+ if (keyName != manualAuth.name) useAuth("apiKey");
28558
+ }
28559
+ })] }), /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
28560
+ htmlFor: "openapi-key-location",
28561
+ children: t("openapi.keyLocation")
28562
+ }), /* @__PURE__ */ jsxs(NativeSelect, {
28563
+ id: "openapi-key-location",
28564
+ className: "w-full",
28565
+ value: keyLocation,
28566
+ disabled,
28567
+ onChange: (event) => useAuth("apiKey", keyName, event.target.value),
28568
+ children: [/* @__PURE__ */ jsx(NativeSelectOption, {
28569
+ value: "header",
28570
+ children: "Header"
28571
+ }), /* @__PURE__ */ jsx(NativeSelectOption, {
28572
+ value: "query",
28573
+ children: "Query"
28574
+ })]
28575
+ })] })] }),
28576
+ credentials?.(onInvalidChange)
28577
+ ] })
28578
+ }, JSON.stringify(config.auth))] });
28579
+ }
28580
+ /** Initial validation can reveal errors; subsequent checks respect manual disclosure. */
28581
+ function AuthenticationDisclosure({ title, children }) {
28582
+ const [open, setOpen] = useState(false);
28583
+ const interacted = useRef(false);
28584
+ const onInvalidChange = useCallback((invalid) => {
28585
+ if (invalid && !interacted.current) setOpen(true);
28586
+ }, []);
28587
+ return /* @__PURE__ */ jsxs("details", {
28588
+ className: "inspector-disclosure",
28589
+ "data-inspector-section": "inputs",
28590
+ open,
28591
+ onToggle: (event) => setOpen(event.currentTarget.open),
28592
+ children: [/* @__PURE__ */ jsxs("summary", {
28593
+ onClick: () => {
28594
+ interacted.current = true;
28595
+ },
28596
+ children: [/* @__PURE__ */ jsx(Icon, {
28597
+ name: "chevron-down",
28598
+ size: 14
28599
+ }), /* @__PURE__ */ jsx("span", {
28600
+ className: "inspector-disclosure-summary",
28601
+ children: /* @__PURE__ */ jsx("strong", {
28602
+ className: "inspector-section-title-text",
28603
+ children: title
28604
+ })
28605
+ })]
28606
+ }), /* @__PURE__ */ jsx("div", {
28607
+ className: "inspector-disclosure-content node-settings flex flex-col gap-3",
28608
+ children: children(onInvalidChange)
27920
28609
  })]
27921
28610
  });
27922
28611
  }
@@ -32456,9 +33145,43 @@ function inspectorIcon(node, target) {
32456
33145
  if (node?.kind == "approval") return "check";
32457
33146
  if (node?.kind == "wait") return "wait";
32458
33147
  if (node?.kind == "subflow" || node == null && target.kind == "subflow") return "subflow";
32459
- if (node?.kind == "task" && node.definition != null && "executor" in node.definition) return node.definition.executor.kind == "connector" ? "connection" : "llm";
33148
+ if (node?.kind == "task" && node.definition != null && "executor" in node.definition) {
33149
+ if (node.definition.executor.kind == "openapi") return "task";
33150
+ return node.definition.executor.kind == "connector" ? "connection" : "llm";
33151
+ }
32460
33152
  return "task";
32461
33153
  }
33154
+ function nodePurposePlaceholder(selection, t, action, displays) {
33155
+ switch (selection.kind) {
33156
+ case "condition": return t("addNode.conditionDescription");
33157
+ case "value": return t("addNode.valueDescription");
33158
+ case "approval": return t("addNode.approvalDescription");
33159
+ case "wait": return t("addNode.waitDescription");
33160
+ case "subflow": return t("addNode.subflowDescription");
33161
+ case "trigger": {
33162
+ const node = selection.node;
33163
+ switch (node.kind) {
33164
+ case "manual": return t("addNode.manualDescription");
33165
+ case "error": return t("errorWorkflow.description");
33166
+ case "cron": return t("addNode.cronDescription");
33167
+ case "webhook": return t("addNode.webhookDescription");
33168
+ case "integration":
33169
+ case "poll": return displays?.[node.definition.key]?.description ?? node.definition.description;
33170
+ }
33171
+ }
33172
+ case "task": {
33173
+ const definition = selection.definition;
33174
+ if (definition == null) return;
33175
+ if (!("executor" in definition)) return t("addNode.javascriptDescription");
33176
+ switch (definition.executor.kind) {
33177
+ case "agent": return t("addNode.agentDescription");
33178
+ case "openapi": return t("openapi.description");
33179
+ case "connector": return action?.description;
33180
+ case "llm": return t(definition.executor.mode == "json" ? "addNode.llmStructuredDescription" : "addNode.llmChatDescription");
33181
+ }
33182
+ }
33183
+ }
33184
+ }
32462
33185
  function inputUpstreamSources({ revision, sourceNodeIcons, target, selection, store, handleName, t, triggerDisplays }) {
32463
33186
  const graph = revision.graph(target);
32464
33187
  const mapping = nodeInputMappings(selection.node)[handleName];
@@ -32508,6 +33231,8 @@ function NodeInspector({ variables = {
32508
33231
  const content = useRef(null);
32509
33232
  const task = selection?.kind == "task" ? selection.definition : void 0;
32510
33233
  const isAgent = task != null && "executor" in task && task.executor.kind == "agent";
33234
+ const isOpenApi = task != null && "executor" in task && task.executor.kind == "openapi";
33235
+ const unconfiguredOpenApi = task != null && "executor" in task && task.executor.kind == "openapi" && !task.executor.path;
32511
33236
  const isLlm = task != null && "executor" in task && task.executor.kind == "llm";
32512
33237
  const connector = task != null && "executor" in task && task.executor.kind == "connector" ? task.executor : void 0;
32513
33238
  const taskId = selection?.kind == "task" && selection.node.task == null ? selection.node.taskId : void 0;
@@ -32531,7 +33256,7 @@ function NodeInspector({ variables = {
32531
33256
  selection?.id,
32532
33257
  selection?.kind
32533
33258
  ]);
32534
- const panel = /* @__PURE__ */ jsx(NativeScrollArea, {
33259
+ const panel = /* @__PURE__ */ jsx(ScrollArea, {
32535
33260
  className: "inspector-scroll",
32536
33261
  tabIndex: -1,
32537
33262
  children: /* @__PURE__ */ jsxs("div", {
@@ -32576,6 +33301,7 @@ function NodeInspector({ variables = {
32576
33301
  }),
32577
33302
  selection != null && /* @__PURE__ */ jsx(NodeDescription, {
32578
33303
  value: selection.node.description,
33304
+ placeholder: nodePurposePlaceholder(selection, t, connectorAction, triggerDisplays),
32579
33305
  disabled,
32580
33306
  onSave: (description) => {
32581
33307
  store?.saveNodeDescription(selection.id, description);
@@ -32628,6 +33354,19 @@ function NodeInspector({ variables = {
32628
33354
  store?.saveTriggerConfig(selection.id, name, value);
32629
33355
  }
32630
33356
  }, `config:${selection.id}`)),
33357
+ selection?.kind === "trigger" && selection.trigger.kind === "error" && /* @__PURE__ */ jsx(Fragment$1, { children: store == null ? /* @__PURE__ */ jsx(ErrorTriggerSources, {
33358
+ flows: [],
33359
+ flowId: revision.revision.flowId,
33360
+ value: selection.trigger.sourceFlowIds ?? [],
33361
+ disabled: true,
33362
+ complete: false,
33363
+ onChange: () => {}
33364
+ }) : /* @__PURE__ */ jsx(ErrorTriggerSourcesEditor, {
33365
+ store,
33366
+ nodeId: selection.id,
33367
+ value: selection.trigger.sourceFlowIds ?? [],
33368
+ disabled
33369
+ }) }),
32631
33370
  selection?.kind === "trigger" && selection.trigger.kind !== "webhook" && /* @__PURE__ */ jsx(TriggerSummary, {
32632
33371
  trigger: selection.trigger,
32633
33372
  display: selection.trigger.kind == "integration" || selection.trigger.kind == "poll" ? triggerDisplays?.[selection.trigger.definition.key] : void 0
@@ -32651,7 +33390,56 @@ function NodeInspector({ variables = {
32651
33390
  store?.saveTriggerSchedule(selection.id, schedule);
32652
33391
  }
32653
33392
  }, `schedule:${selection.id}`),
32654
- (selection?.kind === "approval" || selection?.kind === "wait" || selection?.kind === "subflow" || selection?.kind === "task") && (() => {
33393
+ isOpenApi && task != null && "executor" in task && /* @__PURE__ */ jsx(OpenApiSection, {
33394
+ task,
33395
+ credentials: (onInvalidChange) => selection?.kind === "task" && task.inputs.filter((port) => "handle" in port && port.handle.startsWith("auth.")).map((definition) => {
33396
+ const mapping = selection.node.inputs[definition.handle];
33397
+ const source = mapping?.kind === "sources" ? mapping.sources.find((item) => item.kind === "binding") : void 0;
33398
+ const binding = source?.kind === "binding" ? revision.binding(source.bindingId) : void 0;
33399
+ return /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: definition.handle.slice(5).replace(/^manual\./, "").replaceAll(".", " · ") }), /* @__PURE__ */ jsx(NodeInputValue, {
33400
+ embedded: true,
33401
+ definition,
33402
+ label: task.executor.kind == "openapi" && task.executor.auth.length == 1 ? definition.handle.split(".").at(-1) : definition.handle.slice(5).replaceAll(".", " · "),
33403
+ presentation: {
33404
+ compact: true,
33405
+ hideOptions: true
33406
+ },
33407
+ onInvalidChange,
33408
+ sourceOnly: true,
33409
+ readOnly,
33410
+ disabled,
33411
+ value: inputValue(mapping, definition.value),
33412
+ connected: mapping?.kind === "sources" && binding?.kind !== "variable",
33413
+ variableName: binding?.kind === "variable" ? binding.target : void 0,
33414
+ upstream: inputUpstreamSources({
33415
+ revision,
33416
+ sourceNodeIcons,
33417
+ target,
33418
+ selection,
33419
+ store,
33420
+ handleName: definition.handle,
33421
+ t,
33422
+ triggerDisplays
33423
+ }),
33424
+ variables,
33425
+ onValue: (value, deletion) => {
33426
+ store?.setInputValue(selection.id, definition.handle, value, deletion);
33427
+ },
33428
+ onVariable: (name) => {
33429
+ store?.setInputVariable(selection.id, definition.handle, name);
33430
+ }
33431
+ })] }, definition.handle);
33432
+ }),
33433
+ disabled,
33434
+ load: (url, signal) => store.loadOpenApiDocument(url, signal),
33435
+ onSave: (before, value) => store?.saveTaskSettings(selection.id, {
33436
+ kind: "openapi",
33437
+ name: task.name,
33438
+ before,
33439
+ task: value
33440
+ }) ?? Promise.resolve(false)
33441
+ }, `openapi:${selection?.id}`),
33442
+ !unconfiguredOpenApi && (selection?.kind === "approval" || selection?.kind === "wait" || selection?.kind === "subflow" || selection?.kind === "task") && (() => {
32655
33443
  const definitions = selection.kind === "task" ? [...selection.definition?.inputs ?? []] : selection.kind === "subflow" ? [...selection.definition?.inputs ?? []] : [...selection.node.inputDefinitions];
32656
33444
  const handles = new Set(definitions.flatMap((definition) => "handle" in definition ? [definition.handle] : []));
32657
33445
  for (const handle of Object.keys(selection.node.inputs)) if (!handles.has(handle) && !(selection.kind === "task" && selection.node.additionalInputs?.some((port) => port.handle === handle))) definitions.push({
@@ -32659,7 +33447,7 @@ function NodeInspector({ variables = {
32659
33447
  jsonSchema: {},
32660
33448
  nullable: true
32661
33449
  });
32662
- const entries = definitions.map((definition) => {
33450
+ const entries = definitions.filter((definition) => !isOpenApi || !("handle" in definition) || !definition.handle.startsWith("auth.")).map((definition) => {
32663
33451
  if ("group" in definition) return definition;
32664
33452
  const mapping = selection.node.inputs[definition.handle];
32665
33453
  const source = mapping?.kind === "sources" ? mapping.sources.find((item) => item.kind === "binding") : void 0;
@@ -32794,7 +33582,7 @@ function NodeInspector({ variables = {
32794
33582
  }
32795
33583
  })
32796
33584
  }),
32797
- selection?.kind === "task" && selection.definition != null && /* @__PURE__ */ jsx("section", {
33585
+ !unconfiguredOpenApi && selection?.kind === "task" && selection.definition != null && /* @__PURE__ */ jsx("section", {
32798
33586
  className: "inspector-port-section",
32799
33587
  children: /* @__PURE__ */ jsx(PortDefinitionEditor, {
32800
33588
  readOnly,
@@ -48469,7 +49257,7 @@ function CanvasNode({ nodeStore, problem, branches, compact = false, compactCont
48469
49257
  const title = node.title;
48470
49258
  const { values, summary, schedules, images, inline, hidden } = nodeCardContent(node);
48471
49259
  const kind = node?.kind ?? "task";
48472
- const triggerSource = node.kind == "trigger" ? node.presentation?.kind == "manual" || node.presentation?.kind == "cron" || node.presentation?.kind == "webhook" ? t(`canvasCard.triggerSource.${node.presentation.kind}`) : node.presentation?.source : void 0;
49260
+ const triggerSource = node.kind == "trigger" ? node.presentation?.kind == "error" || node.presentation?.kind == "manual" || node.presentation?.kind == "cron" || node.presentation?.kind == "webhook" ? t(`canvasCard.triggerSource.${node.presentation.kind}`) : node.presentation?.source : void 0;
48473
49261
  const subtitle = inline ? summary : node.kind == "task" ? node.executorName || t("canvasCard.kind.task") : node.kind == "trigger" && triggerSource ? `${t("canvasCard.kind.trigger")} · ${triggerSource}` : t(`canvasCard.kind.${kind}`);
48474
49262
  const runContent = node?.run == null || node.run.status == "idle" ? void 0 : /* @__PURE__ */ jsx(RunChips, { run: node.run });
48475
49263
  return /* @__PURE__ */ jsx("div", {
@@ -52640,6 +53428,52 @@ function PublicationsView({ store, onClose, theme = "light" }) {
52640
53428
  });
52641
53429
  }
52642
53430
  //#endregion
53431
+ //#region src/workbench/browser/runtime/runs/errorHandling.tsx
53432
+ var RunLinkContext = createContext(void 0);
53433
+ function ErrorHandling({ run }) {
53434
+ const t = useTranslate();
53435
+ const hrefFor = useContext(RunLinkContext);
53436
+ if (run == null || !("waits" in run) || run.errorSource == null && run.errorDispatches == null) return null;
53437
+ const link = (flowId, runId, label) => hrefFor == null ? /* @__PURE__ */ jsxs("span", { children: [
53438
+ label,
53439
+ ": ",
53440
+ runId
53441
+ ] }) : /* @__PURE__ */ jsx("a", {
53442
+ className: "text-foreground underline underline-offset-2 hover:text-muted-foreground",
53443
+ href: hrefFor({
53444
+ flowId,
53445
+ runId,
53446
+ view: "runs"
53447
+ }),
53448
+ children: label
53449
+ });
53450
+ return /* @__PURE__ */ jsxs("div", {
53451
+ className: "flex flex-col gap-1 px-4 py-2 text-sm",
53452
+ role: "status",
53453
+ children: [run.errorSource != null && link(run.errorSource.flowId, run.errorSource.runId, t("errorWorkflow.source")), run.errorDispatches?.map((dispatch) => /* @__PURE__ */ jsxs("div", { children: [
53454
+ dispatch.status == "pending" && /* @__PURE__ */ jsxs("span", {
53455
+ className: "text-muted-foreground",
53456
+ children: [
53457
+ t("errorWorkflow.pending"),
53458
+ ": ",
53459
+ dispatch.flowId
53460
+ ]
53461
+ }),
53462
+ dispatch.status == "dispatched" && link(dispatch.flowId, dispatch.runId, `${t("errorWorkflow.dispatched")}: ${dispatch.flowId}`),
53463
+ dispatch.status == "failed" && /* @__PURE__ */ jsxs("span", {
53464
+ className: "text-destructive",
53465
+ children: [
53466
+ t("errorWorkflow.failed"),
53467
+ " (",
53468
+ dispatch.flowId,
53469
+ "): ",
53470
+ dispatch.message
53471
+ ]
53472
+ })
53473
+ ] }, dispatch.flowId))]
53474
+ });
53475
+ }
53476
+ //#endregion
52643
53477
  //#region src/workbench/browser/runtime/runs/runControl.tsx
52644
53478
  function RunControl({ disabled, inputContent, inputOpen, inputStatus, onInputOpenChange, onRun, onSelectTrigger, selectedTriggerId, starting, title, triggers }) {
52645
53479
  const t = useTranslate();
@@ -54125,7 +54959,7 @@ function RunLog({ presentation, resultClient, events, eventsExpiresAt, eventNode
54125
54959
  tabIndex: -1,
54126
54960
  data: rows,
54127
54961
  item: RunVirtualItem,
54128
- ssrCount: Math.min(20, rows.length),
54962
+ ssrCount: typeof window == "undefined" ? Math.min(20, rows.length) : void 0,
54129
54963
  keepMounted: focusIndex >= 0 ? [focusIndex] : [],
54130
54964
  onScrollIntent: beginManualScroll,
54131
54965
  onKeyDown: (event) => {
@@ -54273,26 +55107,30 @@ function RunDrawer({ resultClient, cancelDisabled, canceling, events, eventsExpi
54273
55107
  }),
54274
55108
  /* @__PURE__ */ jsxs("div", {
54275
55109
  className: "run-content",
54276
- children: [run != null && /* @__PURE__ */ jsx(ActiveWait, {
54277
- onLocate: onLocateWait,
54278
- onResolve,
54279
- resolvingActions,
54280
- run
54281
- }), /* @__PURE__ */ jsx(RunLog, {
54282
- presentation,
54283
- resultClient,
54284
- events,
54285
- eventsExpiresAt,
54286
- eventNodes,
54287
- historyComplete,
54288
- observationFailed,
54289
- onConfigureConnector,
54290
- onLocateEvent,
54291
- onRetryObservation,
54292
- result,
54293
- run,
54294
- submitting
54295
- })]
55110
+ children: [
55111
+ /* @__PURE__ */ jsx(ErrorHandling, { run }),
55112
+ run != null && /* @__PURE__ */ jsx(ActiveWait, {
55113
+ onLocate: onLocateWait,
55114
+ onResolve,
55115
+ resolvingActions,
55116
+ run
55117
+ }),
55118
+ /* @__PURE__ */ jsx(RunLog, {
55119
+ presentation,
55120
+ resultClient,
55121
+ events,
55122
+ eventsExpiresAt,
55123
+ eventNodes,
55124
+ historyComplete,
55125
+ observationFailed,
55126
+ onConfigureConnector,
55127
+ onLocateEvent,
55128
+ onRetryObservation,
55129
+ result,
55130
+ run,
55131
+ submitting
55132
+ })
55133
+ ]
54296
55134
  })
54297
55135
  ]
54298
55136
  });
@@ -54404,16 +55242,6 @@ function InputFields({ store, showErrors, labelledBy }) {
54404
55242
  }
54405
55243
  //#endregion
54406
55244
  //#region src/workbench/browser/runtime/runs/runInputPanel.tsx
54407
- function InputGroup({ attempted, group, title, theme }) {
54408
- return /* @__PURE__ */ jsxs("section", {
54409
- className: "run-input-group",
54410
- children: [/* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsx("strong", { children: title }) }), /* @__PURE__ */ jsx(FlowRunInputEditor, {
54411
- store: group.editor,
54412
- theme,
54413
- showErrors: attempted
54414
- })]
54415
- });
54416
- }
54417
55245
  function Form({ onStarted, request, store, theme }) {
54418
55246
  const t = useTranslate();
54419
55247
  const valid = useVal(request.valid);
@@ -54447,12 +55275,14 @@ function Form({ onStarted, request, store, theme }) {
54447
55275
  variant: "destructive",
54448
55276
  children: [/* @__PURE__ */ jsx(Icon, { name: "alert" }), /* @__PURE__ */ jsx(AlertDescription, { children: t("runInput.invalid") })]
54449
55277
  }),
54450
- request.groups.map((group) => /* @__PURE__ */ jsx(InputGroup, {
54451
- attempted: request.attempted,
54452
- group,
54453
- title: group.nodeId == request.triggerId ? t("inspector.ports.outputsTitle") : group.title,
54454
- theme
54455
- }, group.nodeId))
55278
+ request.editor && /* @__PURE__ */ jsxs("section", {
55279
+ className: "run-input-group",
55280
+ children: [/* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsx("strong", { children: t("inspector.ports.outputsTitle") }) }), /* @__PURE__ */ jsx(FlowRunInputEditor, {
55281
+ store: request.editor,
55282
+ theme,
55283
+ showErrors: request.attempted
55284
+ })]
55285
+ })
54456
55286
  ]
54457
55287
  }),
54458
55288
  /* @__PURE__ */ jsxs("footer", { children: [/* @__PURE__ */ jsx(Button$1, {
@@ -55029,116 +55859,120 @@ function RunsView({ flowName, onClose, onConfigureConnector, onLocateEvent, onLo
55029
55859
  variant: "outline",
55030
55860
  children: t("run.filterClear")
55031
55861
  })]
55032
- }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("header", {
55033
- className: "run-detail-header",
55034
- children: [
55035
- /* @__PURE__ */ jsxs("div", {
55036
- className: "run-detail-summary",
55037
- children: [narrow && /* @__PURE__ */ jsxs("div", {
55038
- className: "flex min-w-0 items-center gap-2",
55039
- children: [/* @__PURE__ */ jsx(RunTooltipButton, {
55040
- "aria-label": t("run.history"),
55041
- onClick: closeNarrowDetail,
55042
- size: "icon-sm",
55043
- variant: "ghost",
55044
- children: /* @__PURE__ */ jsx("i", {
55045
- "aria-hidden": "true",
55046
- className: "i-lucide-light:list size-4"
55047
- })
55048
- }), /* @__PURE__ */ jsx("span", {
55049
- className: "truncate text-xs text-muted-foreground",
55050
- title: flowName,
55051
- children: flowName
55862
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", { children: [
55863
+ /* @__PURE__ */ jsxs("header", {
55864
+ className: "run-detail-header",
55865
+ children: [
55866
+ /* @__PURE__ */ jsxs("div", {
55867
+ className: "run-detail-summary",
55868
+ children: [narrow && /* @__PURE__ */ jsxs("div", {
55869
+ className: "flex min-w-0 items-center gap-2",
55870
+ children: [/* @__PURE__ */ jsx(RunTooltipButton, {
55871
+ "aria-label": t("run.history"),
55872
+ onClick: closeNarrowDetail,
55873
+ size: "icon-sm",
55874
+ variant: "ghost",
55875
+ children: /* @__PURE__ */ jsx("i", {
55876
+ "aria-hidden": "true",
55877
+ className: "i-lucide-light:list size-4"
55878
+ })
55879
+ }), /* @__PURE__ */ jsx("span", {
55880
+ className: "truncate text-xs text-muted-foreground",
55881
+ title: flowName,
55882
+ children: flowName
55883
+ })]
55884
+ }), /* @__PURE__ */ jsxs("div", {
55885
+ className: "flex min-h-7 flex-wrap items-center gap-2",
55886
+ children: [
55887
+ /* @__PURE__ */ jsx("span", { className: `status-dot ${statusClass(run)}` }),
55888
+ /* @__PURE__ */ jsx("strong", { children: runLabel(run, t) }),
55889
+ /* @__PURE__ */ jsx(Badge, {
55890
+ variant: "secondary",
55891
+ children: sourceLabel(run, t)
55892
+ })
55893
+ ]
55052
55894
  })]
55053
- }), /* @__PURE__ */ jsxs("div", {
55054
- className: "flex min-h-7 flex-wrap items-center gap-2",
55895
+ }),
55896
+ /* @__PURE__ */ jsxs("div", {
55897
+ className: "run-detail-actions pr-9",
55898
+ children: [/* @__PURE__ */ jsx(RunLogButton, {
55899
+ events,
55900
+ eventsExpiresAt,
55901
+ historyComplete,
55902
+ run
55903
+ }), canCancelRun(run) && /* @__PURE__ */ jsx(Button$1, {
55904
+ disabled: cancelingRunId != null,
55905
+ onClick: () => void store.runs.cancel(),
55906
+ size: "sm",
55907
+ variant: "destructive",
55908
+ children: t(cancelingRunId == run.runId ? "run.canceling" : "run.cancel")
55909
+ })]
55910
+ }),
55911
+ /* @__PURE__ */ jsxs("div", {
55912
+ className: "run-detail-meta",
55055
55913
  children: [
55056
- /* @__PURE__ */ jsx("span", { className: `status-dot ${statusClass(run)}` }),
55057
- /* @__PURE__ */ jsx("strong", { children: runLabel(run, t) }),
55058
- /* @__PURE__ */ jsx(Badge, {
55059
- variant: "secondary",
55060
- children: sourceLabel(run, t)
55061
- })
55062
- ]
55063
- })]
55064
- }),
55065
- /* @__PURE__ */ jsxs("div", {
55066
- className: "run-detail-actions pr-9",
55067
- children: [/* @__PURE__ */ jsx(RunLogButton, {
55068
- events,
55069
- eventsExpiresAt,
55070
- historyComplete,
55071
- run
55072
- }), canCancelRun(run) && /* @__PURE__ */ jsx(Button$1, {
55073
- disabled: cancelingRunId != null,
55074
- onClick: () => void store.runs.cancel(),
55075
- size: "sm",
55076
- variant: "destructive",
55077
- children: t(cancelingRunId == run.runId ? "run.canceling" : "run.cancel")
55078
- })]
55079
- }),
55080
- /* @__PURE__ */ jsxs("div", {
55081
- className: "run-detail-meta",
55082
- children: [
55083
- /* @__PURE__ */ jsx("time", {
55084
- dateTime: run.createdAt,
55085
- children: new Date(run.createdAt).toLocaleString(language, {
55086
- year: "numeric",
55087
- month: "short",
55088
- day: "numeric",
55089
- hour: "2-digit",
55090
- minute: "2-digit"
55091
- })
55092
- }),
55093
- /* @__PURE__ */ jsxs("span", { children: [
55094
- t("run.duration"),
55095
- ": ",
55096
- duration(run)
55097
- ] }),
55098
- /* @__PURE__ */ jsx(IdTooltip, {
55099
- value: run.runId,
55100
- label: t("run.runId", { id: shortRunId(run.runId) }),
55101
- trigger: /* @__PURE__ */ jsx("span", {
55102
- className: "cursor-help text-xs",
55103
- tabIndex: 0
55914
+ /* @__PURE__ */ jsx("time", {
55915
+ dateTime: run.createdAt,
55916
+ children: new Date(run.createdAt).toLocaleString(language, {
55917
+ year: "numeric",
55918
+ month: "short",
55919
+ day: "numeric",
55920
+ hour: "2-digit",
55921
+ minute: "2-digit"
55922
+ })
55104
55923
  }),
55105
- container: root.current,
55106
- children: triggerRun != null && /* @__PURE__ */ jsxs(Fragment$1, { children: [
55107
- /* @__PURE__ */ jsxs("span", {
55108
- className: "break-all",
55109
- children: [
55110
- t("run.triggerNode"),
55111
- ": ",
55112
- triggerName ?? triggerRun.triggerNodeId
55113
- ]
55114
- }),
55115
- /* @__PURE__ */ jsxs("span", {
55116
- className: "break-all",
55117
- children: [
55118
- t("run.triggerOccurrence"),
55119
- ": ",
55120
- triggerRun.occurrenceId
55121
- ]
55924
+ /* @__PURE__ */ jsxs("span", { children: [
55925
+ t("run.duration"),
55926
+ ": ",
55927
+ duration(run)
55928
+ ] }),
55929
+ /* @__PURE__ */ jsx(IdTooltip, {
55930
+ value: run.runId,
55931
+ label: t("run.runId", { id: shortRunId(run.runId) }),
55932
+ trigger: /* @__PURE__ */ jsx("span", {
55933
+ className: "cursor-help text-xs",
55934
+ tabIndex: 0
55122
55935
  }),
55123
- /* @__PURE__ */ jsxs("span", {
55124
- className: "break-all",
55125
- children: [
55126
- t("run.triggerPublication"),
55127
- ": ",
55128
- triggerRun.publicationId
55129
- ]
55130
- })
55131
- ] })
55132
- }, run.runId)
55133
- ]
55134
- })
55135
- ]
55136
- }), /* @__PURE__ */ jsx(ActiveWait, {
55137
- onLocate: onLocateWait,
55138
- onResolve: (waitId, action, comment) => void store.runs.resolve(waitId, action, comment),
55139
- resolvingActions,
55140
- run
55141
- })] }), /* @__PURE__ */ jsxs("div", {
55936
+ container: root.current,
55937
+ children: triggerRun != null && /* @__PURE__ */ jsxs(Fragment$1, { children: [
55938
+ /* @__PURE__ */ jsxs("span", {
55939
+ className: "break-all",
55940
+ children: [
55941
+ t("run.triggerNode"),
55942
+ ": ",
55943
+ triggerName ?? triggerRun.triggerNodeId
55944
+ ]
55945
+ }),
55946
+ /* @__PURE__ */ jsxs("span", {
55947
+ className: "break-all",
55948
+ children: [
55949
+ t("run.triggerOccurrence"),
55950
+ ": ",
55951
+ triggerRun.occurrenceId
55952
+ ]
55953
+ }),
55954
+ /* @__PURE__ */ jsxs("span", {
55955
+ className: "break-all",
55956
+ children: [
55957
+ t("run.triggerPublication"),
55958
+ ": ",
55959
+ triggerRun.publicationId
55960
+ ]
55961
+ })
55962
+ ] })
55963
+ }, run.runId)
55964
+ ]
55965
+ })
55966
+ ]
55967
+ }),
55968
+ /* @__PURE__ */ jsx(ErrorHandling, { run }),
55969
+ /* @__PURE__ */ jsx(ActiveWait, {
55970
+ onLocate: onLocateWait,
55971
+ onResolve: (waitId, action, comment) => void store.runs.resolve(waitId, action, comment),
55972
+ resolvingActions,
55973
+ run
55974
+ })
55975
+ ] }), /* @__PURE__ */ jsxs("div", {
55142
55976
  className: "run-history-content",
55143
55977
  children: [/* @__PURE__ */ jsxs("div", {
55144
55978
  className: "run-toolbar",
@@ -56155,7 +56989,10 @@ function FlowWorkspace({ hrefFor, navigation, onConfigureConnector, onManageConn
56155
56989
  const draftReady = draft != null;
56156
56990
  const canvasReady = draftReady && !workspaceLoading;
56157
56991
  useEffect(() => {
56158
- if (view == "runs" && flowId != null) store.runs.load(flowId, { source: navigation.runSource });
56992
+ if (view == "runs" && flowId != null) store.runs.load(flowId, {
56993
+ source: navigation.runSource,
56994
+ runId: navigation.runId
56995
+ });
56159
56996
  }, [
56160
56997
  flowId,
56161
56998
  navigation,
@@ -56209,66 +57046,69 @@ function FlowWorkspace({ hrefFor, navigation, onConfigureConnector, onManageConn
56209
57046
  flowsHref: hrefFor({ view: "design" }),
56210
57047
  onOpenFlows: () => void navigation.openFlows()
56211
57048
  });
56212
- return /* @__PURE__ */ jsx(IconifyProvider, { children: /* @__PURE__ */ jsxs("main", {
56213
- className: "workspace",
56214
- children: [view == "design" && !canvasReady && /* @__PURE__ */ jsx("div", {
56215
- className: "workspace-navigation-placement",
56216
- children: navigationIsland
56217
- }), view == "design" && !canvasReady ? /* @__PURE__ */ jsx("div", {
56218
- "aria-label": t("workspace.design"),
56219
- className: "editor-grid context-panel-closed",
56220
- id: "workspace-panel-design",
56221
- role: "region",
56222
- tabIndex: 0,
56223
- children: /* @__PURE__ */ jsx("section", {
56224
- "aria-busy": !workspaceLoadFailed,
56225
- className: "canvas-panel workbench-canvas",
56226
- children: workspaceLoadFailed ? /* @__PURE__ */ jsx(WorkspaceRecovery, {
56227
- kind: workspaceLoadProblem?.kind ?? "failed",
56228
- message: workspaceLoadProblem?.message,
56229
- repairing: workspaceRepairing,
56230
- onRepair: () => void store.workspace.repairWorkspace(),
56231
- onRetry: () => flowId != null && void store.selectFlow(flowId)
56232
- }) : /* @__PURE__ */ jsx(Empty, {
56233
- className: "h-full",
56234
- children: /* @__PURE__ */ jsx(EmptyHeader, { children: /* @__PURE__ */ jsx(EmptyTitle, { children: t("workspace.status.loading") }) })
57049
+ return /* @__PURE__ */ jsx(IconifyProvider, { children: /* @__PURE__ */ jsx(RunLinkContext.Provider, {
57050
+ value: hrefFor,
57051
+ children: /* @__PURE__ */ jsxs("main", {
57052
+ className: "workspace",
57053
+ children: [view == "design" && !canvasReady && /* @__PURE__ */ jsx("div", {
57054
+ className: "workspace-navigation-placement",
57055
+ children: navigationIsland
57056
+ }), view == "design" && !canvasReady ? /* @__PURE__ */ jsx("div", {
57057
+ "aria-label": t("workspace.design"),
57058
+ className: "editor-grid context-panel-closed",
57059
+ id: "workspace-panel-design",
57060
+ role: "region",
57061
+ tabIndex: 0,
57062
+ children: /* @__PURE__ */ jsx("section", {
57063
+ "aria-busy": !workspaceLoadFailed,
57064
+ className: "canvas-panel workbench-canvas",
57065
+ children: workspaceLoadFailed ? /* @__PURE__ */ jsx(WorkspaceRecovery, {
57066
+ kind: workspaceLoadProblem?.kind ?? "failed",
57067
+ message: workspaceLoadProblem?.message,
57068
+ repairing: workspaceRepairing,
57069
+ onRepair: () => void store.workspace.repairWorkspace(),
57070
+ onRetry: () => flowId != null && void store.selectFlow(flowId)
57071
+ }) : /* @__PURE__ */ jsx(Empty, {
57072
+ className: "h-full",
57073
+ children: /* @__PURE__ */ jsx(EmptyHeader, { children: /* @__PURE__ */ jsx(EmptyTitle, { children: t("workspace.status.loading") }) })
57074
+ })
56235
57075
  })
56236
- })
56237
- }) : view == "design" ? /* @__PURE__ */ jsx(FlowEditor, {
56238
- navigationIsland,
56239
- onRun: (triggerId) => void run(triggerId),
56240
- onRunStarted: revealRun,
56241
- onCloseRuns: () => changeRunDrawerOpen(false),
56242
- onConfigureConnector,
56243
- onOpenPublications: () => {
56244
- store.runRequests.dismissInputs();
56245
- navigation.open("publications");
56246
- },
56247
- onOpenRuns: () => {
56248
- store.runRequests.dismissInputs();
56249
- navigation.open("runs");
56250
- },
56251
- onManageConnectorAccess,
56252
- connectionHref,
56253
- onToggleRuns: () => changeRunDrawerOpen(!runDrawerOpen),
56254
- runDrawerOpen,
56255
- store,
56256
- theme
56257
- }) : view == "runs" ? /* @__PURE__ */ jsx(RunsView, {
56258
- onSourceChange: (source) => navigation.open("runs", source),
56259
- flowName: flow?.name ?? flow?.flowId ?? "",
56260
- onClose: () => navigation.open("design"),
56261
- onConfigureConnector,
56262
- onLocateEvent: locateRunEvent,
56263
- onLocateWait: (nodeId) => {
56264
- if (store.locateRunWait(nodeId)) navigation.open("design");
56265
- },
56266
- store
56267
- }) : /* @__PURE__ */ jsx(PublicationsView, {
56268
- theme,
56269
- onClose: () => navigation.open("design"),
56270
- store
56271
- }, flowId)]
57076
+ }) : view == "design" ? /* @__PURE__ */ jsx(FlowEditor, {
57077
+ navigationIsland,
57078
+ onRun: (triggerId) => void run(triggerId),
57079
+ onRunStarted: revealRun,
57080
+ onCloseRuns: () => changeRunDrawerOpen(false),
57081
+ onConfigureConnector,
57082
+ onOpenPublications: () => {
57083
+ store.runRequests.dismissInputs();
57084
+ navigation.open("publications");
57085
+ },
57086
+ onOpenRuns: () => {
57087
+ store.runRequests.dismissInputs();
57088
+ navigation.open("runs");
57089
+ },
57090
+ onManageConnectorAccess,
57091
+ connectionHref,
57092
+ onToggleRuns: () => changeRunDrawerOpen(!runDrawerOpen),
57093
+ runDrawerOpen,
57094
+ store,
57095
+ theme
57096
+ }) : view == "runs" ? /* @__PURE__ */ jsx(RunsView, {
57097
+ onSourceChange: (source) => navigation.open("runs", source),
57098
+ flowName: flow?.name ?? flow?.flowId ?? "",
57099
+ onClose: () => navigation.open("design"),
57100
+ onConfigureConnector,
57101
+ onLocateEvent: locateRunEvent,
57102
+ onLocateWait: (nodeId) => {
57103
+ if (store.locateRunWait(nodeId)) navigation.open("design");
57104
+ },
57105
+ store
57106
+ }) : /* @__PURE__ */ jsx(PublicationsView, {
57107
+ theme,
57108
+ onClose: () => navigation.open("design"),
57109
+ store
57110
+ }, flowId)]
57111
+ })
56272
57112
  }) });
56273
57113
  }
56274
57114
  //#endregion