@oomol-lab/open-flow 0.1.0-beta.69 → 0.1.0-beta.70

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 (49) hide show
  1. package/dist/browser/{ContentIcon-CsECY5id.js → ContentIcon-CUQHjQIw.js} +16 -8
  2. package/dist/browser/{FlowCanvas-C5X22xQ7.js → FlowCanvas-CqtUDPGj.js} +11 -26
  3. package/dist/browser/{createResourceDialog-Di5BBrQv.js → createResourceDialog-BAHYW9yu.js} +3 -3
  4. package/dist/browser/{dialog-Bjo-r9B0.js → dialog-DcGOzUP2.js} +162 -12
  5. package/dist/browser/{exportSvg-Cj6Spxx-.js → exportSvg-Dv5Qgrq7.js} +2 -2
  6. package/dist/browser/flow-authoring.js +95 -12
  7. package/dist/browser/flow-change-schema.d.ts +24 -1
  8. package/dist/browser/flow-change.d.ts +33 -4
  9. package/dist/browser/flow-change.js +96 -13
  10. package/dist/browser/{flowChanges-Dp-rcEJ6.js → flowChanges-CYyehKer.js} +2593 -2254
  11. package/dist/browser/{flowWorkspace-CB1QACku.js → flowWorkspace-qYUZPJHR.js} +1114 -392
  12. package/dist/browser/preview.css +225 -221
  13. package/dist/browser/preview.js +3781 -2655
  14. package/dist/browser/{tooltip-CJjYs_2I.js → tooltip-wZJRB9oP.js} +28 -1
  15. package/dist/browser/ui.css +8 -20
  16. package/dist/browser/workbench.css +225 -221
  17. package/dist/browser/workbench.js +31 -10
  18. package/dist/browser/{workbenchSelect-C3hxUcYm.js → workbenchSelect-D8_vP2p5.js} +2 -2
  19. package/dist/command/index.js +45 -45
  20. package/dist/common/authoring.d.ts +3 -3
  21. package/dist/common/authoringExamples.d.ts +3 -2
  22. package/dist/common/authoringSchema.d.ts +37 -374
  23. package/dist/common/control-api-conformance.js +151 -55
  24. package/dist/common/control-api.d.ts +12 -78
  25. package/dist/common/control-api.js +162 -39
  26. package/dist/common/control-requests.d.ts +3 -3
  27. package/dist/common/control-requests.js +221 -35
  28. package/dist/common/decision.js +85 -7
  29. package/dist/common/engine-contract.d.ts +4 -2
  30. package/dist/common/flow-encoding.js +110 -14
  31. package/dist/common/flow-graph.d.ts +3 -0
  32. package/dist/common/flow-semantics.js +273 -14
  33. package/dist/common/integration-trigger.js +85 -7
  34. package/dist/common/liveDetails.d.ts +15 -0
  35. package/dist/common/mcp.d.ts +3 -3
  36. package/dist/common/mcp.js +134 -38
  37. package/dist/common/openapi.js +85 -7
  38. package/dist/common/poll-trigger.js +85 -7
  39. package/dist/common/run-events.d.ts +2 -0
  40. package/dist/common/run-events.js +59 -2
  41. package/dist/common/runtime-contract.js +14 -4
  42. package/dist/common/scheduler.d.ts +6 -2
  43. package/dist/common/scheduler.js +178 -11
  44. package/dist/common/webhook-response.d.ts +43 -0
  45. package/dist/common/webhook-trigger.d.ts +12 -0
  46. package/dist/common/webhook-trigger.js +236 -9
  47. package/dist/common/workflow.js +85 -7
  48. package/package.json +1 -1
  49. package/skills/open-flow/references/flow-authoring.md +15 -10
@@ -1,15 +1,15 @@
1
1
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
2
- import { A as DropdownMenuSub, C as DropdownMenuContent, D as DropdownMenuRadioGroup, E as DropdownMenuLabel, I as useCompositeItem, J as waitBranchDescription, M as DropdownMenuSubTrigger, N as DropdownMenuTrigger, O as DropdownMenuRadioItem, P as isElementDisabled, S as DropdownMenuCheckboxItem, T as DropdownMenuItem, _ as NativeScrollArea, at as Checkbox, b as Z$1, c as useIconifyData, d as PopoverContent, f as PopoverDescription, g as PopoverTrigger, h as PopoverTitle, j as DropdownMenuSubContent, k as DropdownMenuSeparator, m as PopoverPanelContent, o as IconifyProvider, ot as useAriaLabelledBy, p as PopoverHeader, s as useIconifyCollectionLoader, t as ContentIcon, u as Popover, v as ScrollArea, w as DropdownMenuGroup, x as DropdownMenu, y as VirtualScrollArea } from "./ContentIcon-CsECY5id.js";
2
+ import { A as DropdownMenuSub, C as DropdownMenuContent, D as DropdownMenuRadioGroup, E as DropdownMenuLabel, I as useCompositeItem, J as waitBranchDescription, M as DropdownMenuSubTrigger, N as DropdownMenuTrigger, O as DropdownMenuRadioItem, P as isElementDisabled, S as DropdownMenuCheckboxItem, T as DropdownMenuItem, _ as NativeScrollArea, at as Checkbox, b as Z$1, c as useIconifyData, d as PopoverContent, f as PopoverDescription, g as PopoverTrigger, h as PopoverTitle, j as DropdownMenuSubContent, k as DropdownMenuSeparator, m as PopoverPanelContent, o as IconifyProvider, ot as useAriaLabelledBy, p as PopoverHeader, s as useIconifyCollectionLoader, t as ContentIcon, u as Popover, v as ScrollArea, w as DropdownMenuGroup, x as DropdownMenu, y as VirtualScrollArea } from "./ContentIcon-CUQHjQIw.js";
3
3
  import { i as compute, l as val } from "./dist-bO8nvHFH.js";
4
4
  import { c as useLang, l as useTranslate, o as I18nProvider, r as isPlainObject, s as useI18n, u as useVal } from "./dist-BFmpkX4P.js";
5
- import { $ as InternalBackdrop, $t as useOnFirstRender, An as useOpenChangeComplete, Ar as useIsoLayoutEffect, At as useClick, Bn as clearPress, Bt as DROPDOWN_COLLISION_AVOIDANCE, Cn as isFirefox, D as string, En as ownerDocument, Er as CompositeRootContext, F as ARROW_KEYS, G as VERTICAL_KEYS_WITH_EXTRA_KEYS, Gn as inputChange, Gt as Store, H as HORIZONTAL_KEYS_WITH_EXTRA_KEYS, Hn as escapeKey, I as ARROW_LEFT, In as useValueChanged, Ir as isElement, Jn as itemPress, K as isNativeInput, Kn as inputClear, Kt as useStore, L as ARROW_RIGHT, Ln as createChangeEventDetails, M as useCompositeListItem, Mn as TransitionStatusDataAttributes, Mr as useStableCallback, N as ALL_KEYS, Nn as transitionStatusMapping, Nr as useRefWithInit, Or as formatErrorMessage, P as ARROW_DOWN, Q as getDisabledMountTransitionStyles, Qt as useValueAsRef, R as ARROW_UP, Rn as createGenericEventDetails, Rt as FloatingPortal, Sn as isAndroid, Sr as NOOP, Tr as useButton, U as MODIFIER_KEYS, V as HORIZONTAL_KEYS, Vn as closePress, W as VERTICAL_KEYS, Xn as none, Xt as require_builtin_esm_external_require_react, Y as useAnchoredPopupScrollLock, Yn as listNavigation, Z as usePositioner, Zt as createSelector, _r as cva, a as createTooltipHandle, ar as useRegisterFieldControl, at as getPseudoElementBounds, bn as contains, br as EMPTY_ARRAY$1, bt as useFloatingRootContext, c as TooltipPositioner, cn as getGridCellIndexOfCorner, ct as pressableTriggerOpenStateMapping, d as TooltipRoot, dn as getMaxListIndex, dr as visuallyHidden, et as useAnchorPositioning, fn as getMinListIndex, fr as visuallyHiddenInput, ft as useTypeahead, gn as stopEvent, gr as cn, hr as buttonVariants, ht as useInteractions, i as TooltipTrigger, ir as useFormContext, it as inertValue, j as IndexGuessBehavior, jt as FloatingFocusManager, kn as useTransitionStatus, kr as mergeProps, kt as useDismiss, l as TooltipPortal, ln as getGridCellIndices, lr as DEFAULT_FIELD_STATE_ATTRIBUTES, lt as triggerOpenStateMapping, mn as isListIndexDisabled, mr as Button$1, mt as useListNavigation, n as TooltipContent, nt as useDirection, o as TooltipArrow, on as createGridCellMap, or as useFieldRootContext, pn as isIndexOutOfListBounds, pr as useControlled, q as scrollIntoViewIfNeeded, qn as inputPress, r as TooltipProvider, rr as useLabelableContext, rt as CompositeList, s as TooltipPopup, sn as findNonDisabledListIndex, sr as useBaseUiId, st as popupStateMapping, t as Tooltip, tn as useTimeout, u as TooltipTrigger$1, un as getGridNavigatedIndex, ur as fieldValidityMapping, ut as useOpenInteractionType, vn as isInteractiveElement, vr as clsx, wr as useMergedRefs, xn as getTarget, xr as EMPTY_OBJECT, yn as activeElement, yr as useRenderElement } from "./tooltip-CJjYs_2I.js";
6
- import { $ as decisionLimits, B as operatorsForType, Ct as removeItem, Dt as useLabelableId, Et as Input, F as comparisonIssue, G as decodeRevisionContent, H as unaryOperator, J as defaultNodeRetry, K as webhookMethods, M as nodeSystemOutputPorts, N as supportsNodeErrorHandling, Ot as ChevronDown, St as findItemIndex, T as nodeNameIssue, Tt as Label, U as valueType, X as retryConfigurationSchema, Y as nodeRetryLimits, Z as supportsNodeRetry, _ as matchesSchema, _t as isGroupedItems, bt as compareItemEquality, c as DialogTrigger, ct as SelectChevron, d as Field, dt as SelectItem, f as FieldDescription, ft as SelectSeparator, gt as hasNullItemLabel, h as FieldLabel, ht as resolveAriaLabelledBy, i as DialogDescription, it as limitDecisionQuestions, j as nodeErrorSchema, l as Icon, lt as SelectContent, m as FieldGroup, mt as SelectValue, nt as decisionTask, ot as dequal, p as FieldError, pt as SelectTrigger, q as webhookSupportsBody, r as DialogContent, rt as defaultDecisionQuestion, s as DialogTitle, st as Select$1, t as Dialog, tt as decisionQuestionIssues, u as Spinner, ut as SelectGroup, v as schemaObject, vt as stringifyAsLabel, wt as selectedValueIncludes, xt as defaultItemEquality, y as variableInputCompatible, yt as stringifyAsValue, z as operandHandle } from "./dialog-Bjo-r9B0.js";
7
- import { C as isMac, S as toManifestNodeId, _ as E$1, a as collapseAllNested, b as toViewEdge, c as defaultTriggerIcon, d as selectableTimeZones, f as timeZoneLabel, g as cronDescription, h as timeZoneOffsetMinutes, i as JSONViewer, l as useDebouncedValue, m as timeZoneOffset, n as setAddItemId, o as formatDuration, p as timeZoneLongLabel, r as Textarea, s as CanvasNodeIcon, t as FlowCanvas, u as IconStack, v as CanvasTooltip, w as isSameViewport, x as toManifestHandleName, y as CanvasStore } from "./FlowCanvas-C5X22xQ7.js";
8
- import { $ as providerIcon, $t as decodeResultList, A as getDefaultValue, At as WorkflowExportMenuItem, B as indexAddNodeOptions, Bt as EmptyMedia, C as feishuResourceKind, Cn as servers, D as editorGroups, Dn as inputValue, E as editorComponent, En as workflowSelectionTask, F as datePickerChange, Ft as InputGroupInput, G as observeResource, Gt as SourceSelect, H as mapSource, Ht as Badge, I as datePickerValue, It as Empty, Jt as EventSourceSetup, K as resourceData, Kt as createI18n, L as isDateFormat, Lt as EmptyContent, M as typeOfSchema, Mt as followWorkbenchLink, N as calendarChange, Nn as controlErrorCode, Nt as InputGroup, O as schemaForEditor, P as calendarDate, Pn as eventSourceKind, Pt as InputGroupAddon, Q as actionSummary, Rt as EmptyDescription, Sn as serverAddress, T as defaultValueEditorSchema, Tn as workflowCandidateGroup, Vt as EmptyTitle, Wt as SourceForm, X as semanticNodeIcon, Y as designerGraph, Yt as errorNotice, Z as triggerNodeIcon, _n as object, bn as securityOptions, ct as diagnosticMessage, ft as connectionCatalog, gn as listOperations, hn as triggerConfigValues, j as isUnconstrainedSchema, jt as IdTooltip, k as valueForEditor, lt as diagnosticNodeId, mn as triggerConfigValue, n as agentTool, nn as sourceOutputLabel, nt as hasRunFilter, on as triggerOutputDefinitions, q as resourceValue, qt as FeishuEventPicker, rn as sourcePort, rt as revisionView, sn as isJsonObject, tn as resolutionOutputPorts, tt as canCancelRun, ut as schemaMismatchMessage, vn as openApiFieldIssues, w as supportsFeishuChatFilter, xn as selectOperation, yn as openApiTask, zt as EmptyHeader } from "./flowChanges-Dp-rcEJ6.js";
5
+ import { $ as useAnchoredPopupScrollLock, $n as listNavigation, A as string, An as ownerDocument, Ar as CompositeRootContext, B as ARROW_LEFT, Bn as useValueChanged, Br as isElement, Cn as activeElement, Cr as useRenderElement, Dn as isFirefox, En as isAndroid, Er as NOOP, F as IndexGuessBehavior, Ft as FloatingFocusManager, G as HORIZONTAL_KEYS, Gn as closePress, H as ARROW_UP, Hn as createGenericEventDetails, Ht as FloatingPortal, I as useCompositeListItem, In as TransitionStatusDataAttributes, Ir as useStableCallback, J as VERTICAL_KEYS, K as HORIZONTAL_KEYS_WITH_EXTRA_KEYS, Kn as escapeKey, L as ALL_KEYS, Ln as transitionStatusMapping, Lr as useRefWithInit, Mr as formatErrorMessage, Nn as useTransitionStatus, Nr as mergeProps, Nt as useDismiss, Or as useMergedRefs, Pn as useOpenChangeComplete, Pr as useIsoLayoutEffect, Pt as useClick, Qn as itemPress, R as ARROW_DOWN, Sn as isInteractiveElement, Sr as clsx, Tn as getTarget, Tr as EMPTY_OBJECT, V as ARROW_RIGHT, Vn as createChangeEventDetails, Wn as clearPress, Wt as DROPDOWN_COLLISION_AVOIDANCE, X as isNativeInput, Xn as inputClear, Xt as useStore, Y as VERTICAL_KEYS_WITH_EXTRA_KEYS, Yn as inputChange, Yt as Store, Z as scrollIntoViewIfNeeded, Zn as inputPress, _n as isIndexOutOfListBounds, _r as useControlled, a as createTooltipHandle, an as useTimeout, bn as stopEvent, br as cn, c as TooltipPositioner, cr as useFormContext, ct as inertValue, d as TooltipRoot, dn as findNonDisabledListIndex, dr as useBaseUiId, dt as popupStateMapping, en as require_builtin_esm_external_require_react, er as none, fn as getGridCellIndexOfCorner, ft as pressableTriggerOpenStateMapping, gn as getMinListIndex, gr as visuallyHiddenInput, gt as useTypeahead, hn as getMaxListIndex, hr as visuallyHidden, i as TooltipTrigger, it as useAnchorPositioning, kr as useButton, l as TooltipPortal, lr as useRegisterFieldControl, lt as getPseudoElementBounds, mn as getGridNavigatedIndex, mr as fieldValidityMapping, mt as useOpenInteractionType, n as TooltipContent, nn as useValueAsRef, nt as getDisabledMountTransitionStyles, o as TooltipArrow, ot as useDirection, p as timeZoneOffsetMinutes, pn as getGridCellIndices, pr as DEFAULT_FIELD_STATE_ATTRIBUTES, pt as triggerOpenStateMapping, q as MODIFIER_KEYS, r as TooltipProvider, rn as useOnFirstRender, rt as InternalBackdrop, s as TooltipPopup, sr as useLabelableContext, st as CompositeList, t as Tooltip, tn as createSelector, tt as usePositioner, u as TooltipTrigger$1, un as createGridCellMap, ur as useFieldRootContext, vn as isListIndexDisabled, vr as Button$1, vt as useListNavigation, wn as contains, wr as EMPTY_ARRAY$1, wt as useFloatingRootContext, xr as cva, yr as buttonVariants, yt as useInteractions, z as ARROW_KEYS } from "./tooltip-wZJRB9oP.js";
6
+ import { $ as webhookStatusCodePort, At as compareItemEquality, B as operandHandle, Ct as SelectTrigger, Dt as isGroupedItems, E as nodeNameIssue, Et as hasNullItemLabel, Ft as Label, I as comparisonIssue, It as Input, J as webhookHeaderValuePort, K as decodeRevisionContent, Lt as useLabelableId, M as nodeErrorSchema, Mt as findItemIndex, N as nodeSystemOutputPorts, Nt as removeItem, Ot as stringifyAsLabel, P as supportsNodeErrorHandling, Pt as selectedValueIncludes, Q as webhookResponseTimeout, Rt as ChevronDown, St as SelectSeparator, Tt as resolveAriaLabelledBy, U as unaryOperator, V as operatorsForType, W as valueType, X as webhookResponseAllowsBody, Y as webhookHeadersPort, Z as webhookResponseInputs, _ as matchesSchema, _t as Select$1, at as nodeRetryLimits, b as variableInputCompatible, bt as SelectGroup, c as DialogTrigger, d as Field, dt as decisionQuestionIssues, et as workflowOutputsPort, f as FieldDescription, ft as decisionTask, gt as dequal, h as FieldLabel, i as DialogDescription, it as defaultNodeRetry, jt as defaultItemEquality, kt as stringifyAsValue, l as Icon, lt as decisionLimits, m as FieldGroup, mt as limitDecisionQuestions, nt as webhookSupportsBody, ot as retryConfigurationSchema, p as FieldError, pt as defaultDecisionQuestion, q as webhookHeaderNameIssue, r as DialogContent, rt as waitAutoContinueSchema, s as DialogTitle, st as supportsNodeRetry, t as Dialog, tt as webhookMethods, u as Spinner, v as portsAssignable, vt as SelectChevron, wt as SelectValue, xt as SelectItem, y as schemaObject, yt as SelectContent } from "./dialog-DcGOzUP2.js";
7
+ import { C as isSameViewport, S as isMac, _ as CanvasTooltip, a as collapseAllNested, b as toManifestHandleName, c as defaultTriggerIcon, d as selectableTimeZones, f as timeZoneLabel, g as E$1, h as cronDescription, i as JSONViewer, l as useDebouncedValue, m as timeZoneOffset, n as setAddItemId, o as formatDuration, p as timeZoneLongLabel, r as Textarea, s as CanvasNodeIcon, t as FlowCanvas, u as IconStack, v as CanvasStore, x as toManifestNodeId, y as toViewEdge } from "./FlowCanvas-CqtUDPGj.js";
8
+ import { $ as designerGraph, $t as errorNotice, A as valueForEditor, B as dateTimeWall, Bn as eventSourceKind, Bt as Empty, Cn as object, D as editorComponent, Dn as selectOperation, E as defaultValueEditorSchema, En as securityOptions, F as calendarDate, Ft as IdTooltip, Gt as EmptyTitle, Ht as EmptyDescription, I as dateFromTimeZone, It as followWorkbenchLink, Jt as SourceForm, K as mapSource, Kt as Badge, L as dateInTimeZone, Lt as InputGroup, M as isUnconstrainedSchema, Mn as workflowSelectionTask, N as typeOfSchema, Nn as inputValue, O as editorGroups, On as serverAddress, P as calendarChange, Pt as WorkflowExportMenuItem, Qt as EventSourceSetup, R as datePickerChange, Rt as InputGroupAddon, Sn as listOperations, T as supportsFeishuChatFilter, Tn as openApiTask, Ut as EmptyHeader, V as isDateFormat, Vt as EmptyContent, W as indexAddNodeOptions, Wt as EmptyMedia, X as resourceData, Xt as createI18n, Y as observeResource, Yt as SourceSelect, Z as resourceValue, Zt as FeishuEventPicker, an as executionReachableNodes, at as canCancelRun, bn as triggerConfigValue, cn as sourceOutputLabel, et as semanticNodeIcon, fn as triggerOutputDefinitions, ft as diagnosticMessage, gt as connectionCatalog, j as getDefaultValue, jn as workflowCandidateGroup, k as schemaForEditor, kn as servers, ln as sourcePort, mt as schemaMismatchMessage, n as agentTool, nt as actionSummary, on as resolutionOutputPorts, ot as hasRunFilter, pn as isJsonObject, pt as diagnosticNodeId, rn as decodeResultList, rt as providerIcon, sn as webhookResponseDiagnostics, st as revisionView, tt as triggerNodeIcon, w as feishuResourceKind, wn as openApiFieldIssues, xn as triggerConfigValues, z as datePickerValue, zn as controlErrorCode, zt as InputGroupInput } from "./flowChanges-CYyehKer.js";
9
9
  import { r as resolveUiLanguage } from "./languages-gYzoQqCi.js";
10
10
  import { a as renameObjectField, i as objectValue, n as isJsonValue, o as setObjectField, r as jsonDataTypes, s as valueType$1, t as initialValue } from "./value-BbFQZZ_V.js";
11
11
  import { n as compile, r as validate } from "./flowRunInputEditorStore-ys1-w9GW.js";
12
- import { t as WorkbenchSelect } from "./workbenchSelect-C3hxUcYm.js";
12
+ import { t as WorkbenchSelect } from "./workbenchSelect-D8_vP2p5.js";
13
13
  import * as React from "react";
14
14
  import reactExports, { Children, Fragment, Suspense, createContext, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
15
15
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -1399,17 +1399,24 @@ var selectionMenuItemClass = "mt-1 first-of-type:mt-0 min-h-7 rounded-[var(--ui-
1399
1399
  //#region src/form/browser/fieldSelect.tsx
1400
1400
  var fieldSelectTriggerClass = "w-full min-w-0 px-2 text-xs font-normal text-foreground";
1401
1401
  /** The field editor uses the product selection surface instead of the browser menu. */
1402
- function FieldSelect({ id, value, onChange, children, disabled, readOnly, danger, icons, displayValue, showTooltip, variant, "aria-label": label, "aria-invalid": invalid, "aria-describedby": describedBy }) {
1402
+ function FieldSelect({ id, value, onChange, children, disabled, readOnly, danger, icons, displayValue, renderOption, showTooltip, showDisabledOptions = false, variant, "aria-label": label, "aria-invalid": invalid, "aria-describedby": describedBy }) {
1403
1403
  const [open, setOpen] = useState(false);
1404
1404
  const [container, setContainer] = useState(null);
1405
- const options = Children.toArray(children).filter(isValidElement).map((child) => {
1405
+ const entries = Children.toArray(children).filter(isValidElement).map((child) => {
1406
+ if (child.type === "hr") return {
1407
+ kind: "separator",
1408
+ key: child.key
1409
+ };
1406
1410
  const props = child.props;
1407
1411
  return {
1412
+ kind: "option",
1408
1413
  value: String(props.value ?? props.children),
1409
1414
  label: props.children,
1410
- disabled: props.disabled
1415
+ disabled: props.disabled,
1416
+ hidden: props.hidden
1411
1417
  };
1412
1418
  });
1419
+ const options = entries.filter((entry) => entry.kind === "option");
1413
1420
  const selected = options.find((option) => option.value === String(value));
1414
1421
  if (readOnly && icons?.[value]) return /* @__PURE__ */ jsx(FieldTypeDisplay, {
1415
1422
  addon: variant === "addon",
@@ -1461,15 +1468,15 @@ function FieldSelect({ id, value, onChange, children, disabled, readOnly, danger
1461
1468
  align: "start",
1462
1469
  alignItemWithTrigger: false,
1463
1470
  className: `${selectionMenuContentClass} w-max min-w-[max(9rem,var(--anchor-width))] max-w-(--available-width)`,
1464
- children: options.filter((option) => !option.disabled).map((option) => /* @__PURE__ */ jsxs(SelectItem, {
1465
- value: option.value,
1466
- disabled: option.disabled,
1471
+ children: entries.map((entry) => entry.kind === "separator" ? /* @__PURE__ */ jsx(SelectSeparator, { className: "mx-2 bg-border/50" }, entry.key) : entry.hidden || entry.disabled && !showDisabledOptions ? null : /* @__PURE__ */ jsx(SelectItem, {
1472
+ disabled: entry.disabled,
1473
+ value: entry.value,
1467
1474
  className: selectionMenuItemClass,
1468
- children: [icons?.[option.value] && /* @__PURE__ */ jsx("i", {
1475
+ children: renderOption ? renderOption(entry.value, entry.label) : /* @__PURE__ */ jsxs(Fragment$1, { children: [icons?.[entry.value] && /* @__PURE__ */ jsx("i", {
1469
1476
  "aria-hidden": "true",
1470
- className: `${icons[option.value]} inline-block shrink-0 text-base`
1471
- }), option.label]
1472
- }, option.value))
1477
+ className: `${icons[entry.value]} inline-block shrink-0 text-base`
1478
+ }), entry.label] })
1479
+ }, entry.value))
1473
1480
  })]
1474
1481
  })
1475
1482
  });
@@ -2547,6 +2554,7 @@ function fallbackIcon$1(item) {
2547
2554
  case "approval": return "task";
2548
2555
  case "trigger": return "trigger";
2549
2556
  case "value": return "value";
2557
+ case "webhook-response": return "response";
2550
2558
  case "outputs": return "outputs";
2551
2559
  case "wait": return "wait";
2552
2560
  case "new-task":
@@ -5495,6 +5503,7 @@ function fallbackIcon(node) {
5495
5503
  "aria-hidden": "true",
5496
5504
  className: "i-carbon:stamp"
5497
5505
  });
5506
+ if (node.kind === "webhook-response") return /* @__PURE__ */ jsx(Icon, { name: "response" });
5498
5507
  if (node.kind == "wait") return /* @__PURE__ */ jsx("i", {
5499
5508
  "aria-hidden": "true",
5500
5509
  className: "i-carbon:hourglass"
@@ -5586,44 +5595,44 @@ function FlowNodeList({ nodes, onFocusNode, onSelect, groupTriggers = false }) {
5586
5595
  });
5587
5596
  }
5588
5597
  var valueEditor_module_default = {
5589
- root: "valueEditor_root_fd302",
5590
- errorAnchor: "valueEditor_errorAnchor_fd302",
5591
- body: "valueEditor_body_fd302",
5592
- valueTools: "valueEditor_valueTools_fd302",
5593
- options: "valueEditor_options_fd302",
5594
- toolbar: "valueEditor_toolbar_fd302",
5595
- presence: "valueEditor_presence_fd302",
5596
- actions: "valueEditor_actions_fd302",
5597
- collection: "valueEditor_collection_fd302",
5598
- fieldName: "valueEditor_fieldName_fd302",
5599
- fieldType: "valueEditor_fieldType_fd302",
5600
- json: "valueEditor_json_fd302",
5601
- description: "valueEditor_description_fd302",
5602
- error: "valueEditor_error_fd302",
5603
- summary: "valueEditor_summary_fd302",
5604
- summaryError: "valueEditor_summaryError_fd302",
5605
- srOnly: "valueEditor_srOnly_fd302",
5606
- option: "valueEditor_option_fd302",
5607
- header: "valueEditor_header_fd302",
5608
- leadingControl: "valueEditor_leadingControl_fd302",
5609
- toggleControl: "valueEditor_toggleControl_fd302",
5610
- valueAddon: "valueEditor_valueAddon_fd302",
5611
- summaryText: "valueEditor_summaryText_fd302",
5612
- clearValue: "valueEditor_clearValue_fd302",
5613
- resetValue: "valueEditor_resetValue_fd302",
5614
- unsetValue: "valueEditor_unsetValue_fd302",
5615
- arrayIndex: "valueEditor_arrayIndex_fd302",
5616
- nullValue: "valueEditor_nullValue_fd302",
5617
- nullChip: "valueEditor_nullChip_fd302",
5618
- collectionActions: "valueEditor_collectionActions_fd302",
5619
- emptyObjectContent: "valueEditor_emptyObjectContent_fd302",
5620
- emptyObjectConstraint: "valueEditor_emptyObjectConstraint_fd302",
5621
- jsonCode: "valueEditor_jsonCode_fd302",
5622
- emptyString: "valueEditor_emptyString_fd302",
5623
- booleanControl: "valueEditor_booleanControl_fd302",
5624
- booleanIndicator: "valueEditor_booleanIndicator_fd302",
5625
- objectNotice: "valueEditor_objectNotice_fd302",
5626
- valuePrefix: "valueEditor_valuePrefix_fd302"
5598
+ root: "valueEditor_root_64cb9",
5599
+ errorAnchor: "valueEditor_errorAnchor_64cb9",
5600
+ body: "valueEditor_body_64cb9",
5601
+ valueTools: "valueEditor_valueTools_64cb9",
5602
+ options: "valueEditor_options_64cb9",
5603
+ toolbar: "valueEditor_toolbar_64cb9",
5604
+ presence: "valueEditor_presence_64cb9",
5605
+ actions: "valueEditor_actions_64cb9",
5606
+ collection: "valueEditor_collection_64cb9",
5607
+ fieldName: "valueEditor_fieldName_64cb9",
5608
+ fieldType: "valueEditor_fieldType_64cb9",
5609
+ json: "valueEditor_json_64cb9",
5610
+ description: "valueEditor_description_64cb9",
5611
+ error: "valueEditor_error_64cb9",
5612
+ summary: "valueEditor_summary_64cb9",
5613
+ summaryError: "valueEditor_summaryError_64cb9",
5614
+ srOnly: "valueEditor_srOnly_64cb9",
5615
+ option: "valueEditor_option_64cb9",
5616
+ header: "valueEditor_header_64cb9",
5617
+ leadingControl: "valueEditor_leadingControl_64cb9",
5618
+ toggleControl: "valueEditor_toggleControl_64cb9",
5619
+ valueAddon: "valueEditor_valueAddon_64cb9",
5620
+ summaryText: "valueEditor_summaryText_64cb9",
5621
+ clearValue: "valueEditor_clearValue_64cb9",
5622
+ resetValue: "valueEditor_resetValue_64cb9",
5623
+ unsetValue: "valueEditor_unsetValue_64cb9",
5624
+ arrayIndex: "valueEditor_arrayIndex_64cb9",
5625
+ nullValue: "valueEditor_nullValue_64cb9",
5626
+ nullChip: "valueEditor_nullChip_64cb9",
5627
+ collectionActions: "valueEditor_collectionActions_64cb9",
5628
+ emptyObjectContent: "valueEditor_emptyObjectContent_64cb9",
5629
+ emptyObjectConstraint: "valueEditor_emptyObjectConstraint_64cb9",
5630
+ jsonCode: "valueEditor_jsonCode_64cb9",
5631
+ emptyString: "valueEditor_emptyString_64cb9",
5632
+ booleanControl: "valueEditor_booleanControl_64cb9",
5633
+ booleanIndicator: "valueEditor_booleanIndicator_64cb9",
5634
+ objectNotice: "valueEditor_objectNotice_64cb9",
5635
+ valuePrefix: "valueEditor_valuePrefix_64cb9"
5627
5636
  };
5628
5637
  //#endregion
5629
5638
  //#region src/form/browser/fieldControl.tsx
@@ -7167,22 +7176,26 @@ function PropertyName({ name, onRename, disabled }) {
7167
7176
  //#region src/form/browser/collectionValueFields.tsx
7168
7177
  function childFields(props) {
7169
7178
  const { label, disabled, path, onDraftIssue, depth = 0, valueEditable } = props;
7170
- const child = (key, childSchema, childValue, change, presentation) => /* @__PURE__ */ jsx(FieldValueEditor, {
7171
- readOnly: props.readOnly,
7172
- layout: props.layout,
7173
- expansionPolicy: props.expansionPolicy,
7174
- schema: childSchema,
7175
- value: childValue,
7176
- onChange: change,
7177
- valueEditable,
7178
- disabled,
7179
- label: `${label}.${key}`,
7180
- path: `${path}/${String(key).replaceAll("~", "~0").replaceAll("/", "~1")}`,
7181
- onDraftIssue,
7182
- depth: depth + 1,
7183
- ...presentation,
7184
- description: typeof objectValue(childSchema)?.description === "string" ? String(objectValue(childSchema).description) : void 0
7185
- });
7179
+ const child = (key, childSchema, childValue, change, presentation) => {
7180
+ const childProps = {
7181
+ readOnly: props.readOnly,
7182
+ layout: props.layout,
7183
+ hideValueTools: props.hideValueTools,
7184
+ expansionPolicy: props.expansionPolicy,
7185
+ schema: childSchema,
7186
+ value: childValue,
7187
+ onChange: change,
7188
+ valueEditable,
7189
+ disabled,
7190
+ label: `${label}.${key}`,
7191
+ path: `${path}/${String(key).replaceAll("~", "~0").replaceAll("/", "~1")}`,
7192
+ onDraftIssue,
7193
+ depth: depth + 1,
7194
+ ...presentation,
7195
+ description: typeof objectValue(childSchema)?.description === "string" ? String(objectValue(childSchema).description) : void 0
7196
+ };
7197
+ return typeof key === "string" && props.renderObjectField != null ? props.renderObjectField(key, childProps) : /* @__PURE__ */ jsx(FieldValueEditor, { ...childProps });
7198
+ };
7186
7199
  return child;
7187
7200
  }
7188
7201
  function ObjectValueFields(props) {
@@ -7249,7 +7262,7 @@ function ObjectValueFields(props) {
7249
7262
  leadingControl: handle,
7250
7263
  objectChild: true,
7251
7264
  layout: "values",
7252
- typeWidth: !disabled && (props.onDefinitionChange || !(typeof fieldSource.type === "string" || fieldSource.enum != null || fieldSource.const !== void 0)) ? "editable" : "fixed",
7265
+ typeWidth: props.hideChildTypes ? void 0 : !disabled && (props.onDefinitionChange || !(typeof fieldSource.type === "string" || fieldSource.enum != null || fieldSource.const !== void 0)) ? "editable" : "fixed",
7253
7266
  hideOptions: true,
7254
7267
  header: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(FieldName, {
7255
7268
  name,
@@ -7262,6 +7275,7 @@ function ObjectValueFields(props) {
7262
7275
  name,
7263
7276
  disabled,
7264
7277
  onRename: (nextName) => {
7278
+ if (props.validateObjectFieldName?.(nextName, name) === false) return false;
7265
7279
  if (props.onDefinitionChange) {
7266
7280
  const nextSchema = renameFieldDefinition(schema, name, nextName);
7267
7281
  if (!nextSchema) return false;
@@ -7275,7 +7289,7 @@ function ObjectValueFields(props) {
7275
7289
  return true;
7276
7290
  }
7277
7291
  })
7278
- }), /* @__PURE__ */ jsx("div", {
7292
+ }), !props.hideChildTypes && /* @__PURE__ */ jsx("div", {
7279
7293
  "data-field-type": true,
7280
7294
  children: props.onDefinitionChange ? /* @__PURE__ */ jsx(EditorComponentSelect, {
7281
7295
  schema: fieldSchema,
@@ -7661,16 +7675,18 @@ function FieldLayout({ children, depth = 0, layout = "values", columns, gap }) {
7661
7675
  children
7662
7676
  });
7663
7677
  }
7664
- var FieldRow = forwardRef(({ columns, gap, header, leadingControl, disclosureContent, trailingControl, actions, layout, depth, typeWidth, disclosure, label, sorting, disclosureInvalid, stacking = "editor", children, style, className, ...props }, ref) => {
7678
+ var FieldRow = forwardRef(({ columns, gap, header, valueOnly, leadingControl, disclosureContent, trailingControl, actions, layout, depth, typeWidth, disclosure, label, sorting, disclosureInvalid, stacking = "editor", children, style, className, ...props }, ref) => {
7665
7679
  const geometry = useContext(Geometry);
7666
7680
  const level = depth ?? geometry.depth;
7681
+ const hasHeader = header != null || valueOnly === true;
7667
7682
  return /* @__PURE__ */ jsxs("div", {
7668
7683
  ...props,
7669
7684
  ref,
7670
7685
  className: [valueEditor_module_default.root, className].filter(Boolean).join(" "),
7671
7686
  "data-stacking": stacking,
7672
7687
  "data-layout": layout ?? geometry.layout,
7673
- "data-header": header != null || void 0,
7688
+ "data-header": hasHeader || void 0,
7689
+ "data-value-only": valueOnly || void 0,
7674
7690
  "data-nested-field": level > 0 || void 0,
7675
7691
  style: {
7676
7692
  "gridTemplateColumns": columns ?? geometry.columns,
@@ -7680,7 +7696,7 @@ var FieldRow = forwardRef(({ columns, gap, header, leadingControl, disclosureCon
7680
7696
  ...style
7681
7697
  },
7682
7698
  children: [
7683
- header != null && /* @__PURE__ */ jsxs("div", {
7699
+ hasHeader && /* @__PURE__ */ jsxs("div", {
7684
7700
  className: valueEditor_module_default.header,
7685
7701
  children: [
7686
7702
  leadingControl != null && /* @__PURE__ */ jsx("div", {
@@ -7705,7 +7721,7 @@ var FieldRow = forwardRef(({ columns, gap, header, leadingControl, disclosureCon
7705
7721
  })
7706
7722
  }), !disclosure && leadingControl == null && disclosureContent]
7707
7723
  }),
7708
- typeof header === "function" ? header(disclosure) : header
7724
+ !valueOnly && (typeof header === "function" ? header(disclosure) : header)
7709
7725
  ]
7710
7726
  }),
7711
7727
  children,
@@ -19714,11 +19730,23 @@ function Calendar(props) {
19714
19730
  }
19715
19731
  //#endregion
19716
19732
  //#region src/form/browser/dateEditor.tsx
19717
- function DateEditor({ value, onChange, label, disabled, invalid, format }) {
19733
+ function DateEditor({ value, onChange, label, disabled, invalid, format, onCommit, id, precision = "second", describedBy }) {
19734
+ const commit = (next) => {
19735
+ const committed = precision == "minute" && typeof next == "string" ? next.replace(/^((?:\d{4}-\d{2}-\d{2}T)?\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?(Z|[+-]\d{2}:\d{2})?$/, "$1:00$2") : next;
19736
+ onChange(committed);
19737
+ onCommit?.(committed);
19738
+ };
19718
19739
  const t = useTranslate();
19719
19740
  const [open, setOpen] = useState(false);
19720
19741
  const wall = datePickerValue(value, format);
19721
19742
  const time = (format === "time" ? wall : wall.split("T")[1]) || "00:00:00";
19743
+ const text = typeof value == "string" ? value : "";
19744
+ const display = precision == "minute" ? text.replace(/^((?:\d{4}-\d{2}-\d{2}T)?\d{2}:\d{2}):\d{2}(?:\.\d+)?(Z|[+-]\d{2}:\d{2})?$/, "$1$2") : text;
19745
+ const timeParts = precision == "minute" ? ["hours", "minutes"] : [
19746
+ "hours",
19747
+ "minutes",
19748
+ "seconds"
19749
+ ];
19722
19750
  const [container, setContainer] = useState(null);
19723
19751
  return /* @__PURE__ */ jsx("div", {
19724
19752
  ref: setContainer,
@@ -19727,11 +19755,16 @@ function DateEditor({ value, onChange, label, disabled, invalid, format }) {
19727
19755
  className: "h-[30px]",
19728
19756
  children: [/* @__PURE__ */ jsx(InputGroupInput, {
19729
19757
  className: "h-full min-w-0 px-2 text-xs md:text-xs",
19758
+ id,
19730
19759
  "aria-label": label,
19731
19760
  "aria-invalid": invalid,
19761
+ "aria-describedby": describedBy,
19732
19762
  readOnly: disabled,
19733
- value: typeof value === "string" ? value : "",
19734
- onChange: (event) => onChange(event.target.value)
19763
+ value: display,
19764
+ onChange: (event) => onChange(event.target.value),
19765
+ onBlur: (event) => {
19766
+ if (onCommit != null) commit(event.currentTarget.value);
19767
+ }
19735
19768
  }), /* @__PURE__ */ jsx(InputGroupAddon, {
19736
19769
  align: "inline-end",
19737
19770
  children: /* @__PURE__ */ jsxs(Popover, {
@@ -19760,16 +19793,12 @@ function DateEditor({ value, onChange, label, disabled, invalid, format }) {
19760
19793
  defaultMonth: calendarDate(value, format),
19761
19794
  disabled,
19762
19795
  onSelect: (day) => {
19763
- onChange(calendarChange(day, value, format));
19796
+ commit(calendarChange(day, value, format));
19764
19797
  if (format === "date") setOpen(false);
19765
19798
  }
19766
19799
  }), format !== "date" && /* @__PURE__ */ jsx("div", {
19767
- className: "grid grid-cols-3 gap-2",
19768
- children: [
19769
- "hours",
19770
- "minutes",
19771
- "seconds"
19772
- ].map((part, index) => /* @__PURE__ */ jsxs("label", {
19800
+ className: "flex gap-2",
19801
+ children: timeParts.map((part, index) => /* @__PURE__ */ jsxs("label", {
19773
19802
  className: "flex min-w-0 flex-col gap-1 text-xs text-muted-foreground",
19774
19803
  children: [t(`valueEditor.${part}`), /* @__PURE__ */ jsx(Input, {
19775
19804
  type: "number",
@@ -19790,7 +19819,7 @@ function DateEditor({ value, onChange, label, disabled, invalid, format }) {
19790
19819
  parts[index] = input.value.padStart(2, "0");
19791
19820
  const date = calendarDate(value, format) ?? /* @__PURE__ */ new Date();
19792
19821
  const next = format === "time" ? parts.join(":") : `${calendarChange(date, void 0, "date")}T${parts.join(":")}`;
19793
- onChange(datePickerChange(next, value, format, date.getTimezoneOffset()));
19822
+ commit(datePickerChange(next, value, format, date.getTimezoneOffset()));
19794
19823
  }
19795
19824
  }, time.split(":")[index])]
19796
19825
  }, part))
@@ -20055,6 +20084,7 @@ function FieldValueEditor(suppliedProps) {
20055
20084
  disabled: true
20056
20085
  } : suppliedProps;
20057
20086
  const { schema, value, onChange, label, nullable, disabled, onDraftIssue, depth = 0 } = props;
20087
+ const hasHeader = props.header != null || props.valueOnly === true;
20058
20088
  const t = useTranslate();
20059
20089
  const id = useId();
20060
20090
  const valueEditable = props.valueEditable !== false;
@@ -20068,11 +20098,11 @@ function FieldValueEditor(suppliedProps) {
20068
20098
  schema: editorSchema
20069
20099
  };
20070
20100
  const source = objectValue(editorSchema) ?? {};
20071
- const compactValue = props.compact === true || props.header != null || props.valueAddon != null || props.valueSuffix != null || showDataType;
20101
+ const compactValue = props.compact === true || hasHeader || props.valueAddon != null || props.valueSuffix != null || showDataType;
20072
20102
  const state = fieldValueState(schema, value, nullable);
20073
20103
  const { presence, missing, invalidNull } = state;
20074
20104
  const shape = fieldValueShape(editorSchema, value, {
20075
- compactCollection: compactValue && props.header == null && !showDataType,
20105
+ compactCollection: compactValue && !hasHeader && !showDataType,
20076
20106
  objectChild: props.objectChild,
20077
20107
  depth
20078
20108
  });
@@ -20126,6 +20156,7 @@ function FieldValueEditor(suppliedProps) {
20126
20156
  instancePath: "",
20127
20157
  message: props.validationError
20128
20158
  });
20159
+ if (!draftInvalid && props.editor === void 0 && props.validationErrors != null) errors.push(...props.validationErrors);
20129
20160
  if (!errors.length && props.invalid && !draftInvalid && props.editor === void 0) errors.push({
20130
20161
  instancePath: "",
20131
20162
  message: t("valueEditor.schema")
@@ -20193,7 +20224,7 @@ function FieldValueEditor(suppliedProps) {
20193
20224
  const canReset = inlineTools && props.onReset != null && (showUnset || !!nullable && nullControl);
20194
20225
  const canClear = inlineTools && state.canClear;
20195
20226
  const canToggleJson = inlineTools && expanded && shape.collection && presence === "value";
20196
- const arrayDefinition = !showDataType && props.header != null && source.type === "array" && !Array.isArray(source.items) && !choiceOptions;
20227
+ const arrayDefinition = !showDataType && hasHeader && source.type === "array" && !Array.isArray(source.items) && !choiceOptions;
20197
20228
  const changeValueEditor = (nextSchema) => {
20198
20229
  if (isUnconstrainedSchema(nextSchema)) {
20199
20230
  setSelectedEditorSchema(void 0);
@@ -20230,7 +20261,7 @@ function FieldValueEditor(suppliedProps) {
20230
20261
  }) : void 0);
20231
20262
  const emptyCollection = structured && presence !== "value";
20232
20263
  const needsCreation = emptyCollection || uncreatedText;
20233
- const valueSuffix = !nullControl && !expandable && !showUnset && (enumeration || choiceOptions || source["ui:widget"] === "color" || isDateFormat(source.format)) ? 26 : !nullControl && type === "boolean" && !expandable && !showUnset ? 30 : expandable && compactValue && props.header == null && !needsCreation ? 26 : 0;
20264
+ const valueSuffix = !nullControl && !expandable && !showUnset && (enumeration || choiceOptions || source["ui:widget"] === "color" || isDateFormat(source.format)) ? 26 : !nullControl && type === "boolean" && !expandable && !showUnset ? 30 : expandable && compactValue && !hasHeader && !needsCreation ? 26 : 0;
20234
20265
  const createValue = uncreatedText && valueEditable && !disabled ? () => {
20235
20266
  onChange("");
20236
20267
  setEditorFocusRequest((request) => request + 1);
@@ -20285,7 +20316,7 @@ function FieldValueEditor(suppliedProps) {
20285
20316
  className: "i-lucide-light:braces"
20286
20317
  }), "JSON"]
20287
20318
  }),
20288
- props.header != null && !complex && type === "string" && presence === "unset" && /* @__PURE__ */ jsxs(Button$1, {
20319
+ hasHeader && !complex && type === "string" && presence === "unset" && /* @__PURE__ */ jsxs(Button$1, {
20289
20320
  type: "button",
20290
20321
  size: "xs",
20291
20322
  variant: "ghost",
@@ -20452,6 +20483,7 @@ function FieldValueEditor(suppliedProps) {
20452
20483
  return /* @__PURE__ */ jsxs(FieldRow, {
20453
20484
  label,
20454
20485
  header: props.header,
20486
+ valueOnly: props.valueOnly,
20455
20487
  leadingControl: props.leadingControl,
20456
20488
  disclosureContent: props.disclosureContent,
20457
20489
  layout: props.layout,
@@ -20469,7 +20501,7 @@ function FieldValueEditor(suppliedProps) {
20469
20501
  "aria-label": label,
20470
20502
  "aria-describedby": messages.length ? `${id}-error` : void 0,
20471
20503
  ref: setContainer,
20472
- "data-inline": props.hideOptions && !props.header || void 0,
20504
+ "data-inline": props.hideOptions && !hasHeader || void 0,
20473
20505
  "data-compact": props.compact || void 0,
20474
20506
  "data-value-tools": canReset || canClear || canToggleJson || inlineExpansion && hasExpandedContent || void 0,
20475
20507
  "data-array-child": props.arrayChild || void 0,
@@ -20481,7 +20513,6 @@ function FieldValueEditor(suppliedProps) {
20481
20513
  "--value-native-action-width": `${canReset && showUnset ? 24 : 0}px`,
20482
20514
  "--value-suffix-width": `${valueSuffix}px`
20483
20515
  },
20484
- "data-header": props.header != null || void 0,
20485
20516
  "data-expansion": expansionPlacement,
20486
20517
  "data-value-addon": startAddon != null || void 0,
20487
20518
  "data-value-suffix": endAddon != null || void 0,
@@ -20509,7 +20540,7 @@ function FieldValueEditor(suppliedProps) {
20509
20540
  "aria-expanded": needsCreation || !hasExpandedContent ? void 0 : expanded,
20510
20541
  "aria-invalid": summaryInvalid,
20511
20542
  "aria-controls": `${id}-body`,
20512
- trailing: !inlineExpansion && props.header == null && hasExpandedContent && !needsCreation ? /* @__PURE__ */ jsx(SelectChevron, { className: expanded ? "rotate-180" : void 0 }) : void 0,
20543
+ trailing: !inlineExpansion && !hasHeader && hasExpandedContent && !needsCreation ? /* @__PURE__ */ jsx(SelectChevron, { className: expanded ? "rotate-180" : void 0 }) : void 0,
20513
20544
  onClick: needsCreation ? () => {
20514
20545
  createValue?.();
20515
20546
  setExpanded(true);
@@ -20545,7 +20576,7 @@ function FieldValueEditor(suppliedProps) {
20545
20576
  props.trailingControl,
20546
20577
  (!props.hideOptions || props.actions) && /* @__PURE__ */ jsxs("div", {
20547
20578
  className: valueEditor_module_default.options,
20548
- children: [props.actions, !props.hideOptions && (props.options && props.header != null && (props.layout === "values" || props.layout === "ports") ? props.options : /* @__PURE__ */ jsxs(Popover, {
20579
+ children: [props.actions, !props.hideOptions && (props.options && hasHeader && (props.layout === "values" || props.layout === "ports") ? props.options : /* @__PURE__ */ jsxs(Popover, {
20549
20580
  open: optionsOpen,
20550
20581
  onOpenChange: setOptionsOpen,
20551
20582
  children: [/* @__PURE__ */ jsx(PopoverTrigger, {
@@ -21066,7 +21097,7 @@ function EditableAgentSettingsProvider({ children, task, nodeId, store, connecto
21066
21097
  return false;
21067
21098
  }
21068
21099
  const decoded = decodeRevisionContent({
21069
- modelVersion: 9,
21100
+ modelVersion: 10,
21070
21101
  modules: {},
21071
21102
  document: {
21072
21103
  bindings: {},
@@ -22684,6 +22715,84 @@ function LlmInputEditor({ schema, addon, value, disabled, readOnly, handleNames,
22684
22715
  });
22685
22716
  }
22686
22717
  //#endregion
22718
+ //#region src/workbench/browser/runtime/editor/sourceMenuOption.tsx
22719
+ var sourceMenuItemClass = `${selectionMenuItemClass} gap-2 px-2`;
22720
+ /** Source menus share field identity, compatibility feedback, and description tooltips. */
22721
+ function SourceMenuOption({ value, label, selected, compatibility = "available", icon, description, disabled = false, container }) {
22722
+ const t = useTranslate();
22723
+ const status = compatibility === "incompatible" ? t("inspector.sources.incompatible") : compatibility === "unverified" ? t("inspector.sources.unverified") : void 0;
22724
+ const sourceDescription = description?.trim();
22725
+ const item = /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
22726
+ disabled,
22727
+ className: `${sourceMenuItemClass} data-disabled:opacity-100 ${status == null || selected ? "pr-8" : "pr-20"}`,
22728
+ value,
22729
+ closeOnClick: true,
22730
+ "aria-description": sourceDescription,
22731
+ children: [
22732
+ /* @__PURE__ */ jsx("i", {
22733
+ "aria-hidden": "true",
22734
+ className: `${icon ?? (status == null ? "i-lucide-light:corner-down-right" : compatibility === "incompatible" ? "i-lucide-light:triangle-alert" : "i-lucide-light:circle-help")} ${status == null ? "text-muted-foreground" : ""} size-3.5 shrink-0`,
22735
+ style: status == null ? void 0 : { color: "var(--warning-foreground)" }
22736
+ }),
22737
+ /* @__PURE__ */ jsx("span", {
22738
+ className: "min-w-0 flex-1 truncate font-mono",
22739
+ title: label,
22740
+ children: label
22741
+ }),
22742
+ !selected && status != null && /* @__PURE__ */ jsx("span", {
22743
+ className: "pointer-events-none absolute right-2 shrink-0 text-[10px] leading-4",
22744
+ style: { color: "var(--warning-foreground)" },
22745
+ children: status
22746
+ }),
22747
+ selected && status != null && /* @__PURE__ */ jsx("span", {
22748
+ className: "sr-only",
22749
+ children: status
22750
+ })
22751
+ ]
22752
+ });
22753
+ if (sourceDescription == null || sourceDescription === "") return item;
22754
+ return /* @__PURE__ */ jsxs(TooltipRoot, { children: [/* @__PURE__ */ jsx(TooltipTrigger$1, { render: item }), /* @__PURE__ */ jsx(TooltipPortal, {
22755
+ container,
22756
+ className: "contents",
22757
+ children: /* @__PURE__ */ jsx(TooltipPositioner, {
22758
+ side: "right",
22759
+ align: "start",
22760
+ sideOffset: 8,
22761
+ positionMethod: "fixed",
22762
+ className: "pointer-events-none isolate z-[1000]",
22763
+ children: /* @__PURE__ */ jsxs(TooltipPopup, {
22764
+ className: "pointer-events-none max-w-64 rounded-[6px] bg-foreground px-3 py-2 text-xs leading-5 text-background shadow-md outline-none",
22765
+ children: [sourceDescription, /* @__PURE__ */ jsx(TooltipArrow, { className: "size-2.5 rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-2.5" })]
22766
+ })
22767
+ })
22768
+ })] });
22769
+ }
22770
+ //#endregion
22771
+ //#region src/workbench/browser/runtime/editor/sourceSelectorTrigger.tsx
22772
+ /** Source actions share the attached addon's surface instead of drawing an inset button. */
22773
+ function SourceSelectorTrigger({ label, description = label, open, pressed, disabled, container }) {
22774
+ return /* @__PURE__ */ jsxs(Tooltip, {
22775
+ disabled: open,
22776
+ children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
22777
+ type: "button",
22778
+ variant: "ghost",
22779
+ size: "icon-xs",
22780
+ "data-source-trigger": true,
22781
+ className: "[--ui-control-hover-background:transparent] aria-pressed:text-foreground",
22782
+ "aria-label": label,
22783
+ "aria-pressed": pressed,
22784
+ disabled,
22785
+ children: /* @__PURE__ */ jsx("i", {
22786
+ "aria-hidden": "true",
22787
+ className: "i-lucide-light:link"
22788
+ })
22789
+ }) }) }), /* @__PURE__ */ jsx(TooltipContent, {
22790
+ container,
22791
+ children: description
22792
+ })]
22793
+ });
22794
+ }
22795
+ //#endregion
22687
22796
  //#region src/workbench/browser/runtime/editor/useInputSourceQuery.ts
22688
22797
  /** Yield the selection/menu event before doing bounded, per-field graph work. */
22689
22798
  function deferInputSourceQuery(calculate, signal) {
@@ -22756,9 +22865,8 @@ var upstreamSource = (nodeId, output, field, system) => JSON.stringify(system ?
22756
22865
  output,
22757
22866
  field
22758
22867
  ]);
22759
- var sourceItemClass = `${selectionMenuItemClass} gap-2 px-2`;
22760
- var sourceEmptyItemClass = `${sourceItemClass} font-normal text-muted-foreground data-disabled:opacity-100`;
22761
- var sourceSubTriggerClass = sourceItemClass;
22868
+ var sourceEmptyItemClass = `${sourceMenuItemClass} font-normal text-muted-foreground data-disabled:opacity-100`;
22869
+ var sourceSubTriggerClass = sourceMenuItemClass;
22762
22870
  function inputSourceIssue(check, source, t) {
22763
22871
  switch (check?.kind) {
22764
22872
  case void 0:
@@ -22782,7 +22890,6 @@ function inputSourceIssue(check, source, t) {
22782
22890
  }
22783
22891
  function SelectedSourceValue({ bound, readOnly, connected, sourceMissing, onInvalidChange, validationError, upstream, variableCompatible, variableName, variables }) {
22784
22892
  const t = useTranslate();
22785
- const [tooltipContainer, setTooltipContainer] = useState(null);
22786
22893
  let checks;
22787
22894
  let checkFailed = false;
22788
22895
  if (upstream?.query != null && upstream.current.length > 0) try {
@@ -22804,17 +22911,35 @@ function SelectedSourceValue({ bound, readOnly, connected, sourceMissing, onInva
22804
22911
  const selectedUpstreamIcon = connected && current?.length === 1 ? current[0]?.icon : void 0;
22805
22912
  const sourceDescriptions = connected && current?.length ? current.map((source) => source.description?.trim()).filter(Boolean) : [];
22806
22913
  const sourceTooltip = connected && current?.length ? [sourceLabel, ...sourceDescriptions].join("\n") : void 0;
22807
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ValueEditorFeedback, {
22808
- error: sourceIssue,
22914
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SourceValueControl, {
22915
+ label: sourceLabel ?? "",
22916
+ description: sourceTooltip,
22917
+ variable: bound,
22918
+ node: connected && current?.length === 1,
22919
+ icon: selectedUpstreamIcon,
22920
+ error: sourceIssue
22921
+ }), checkFailed && /* @__PURE__ */ jsx("p", {
22922
+ role: "status",
22923
+ className: "text-xs text-muted-foreground",
22924
+ children: t("inspector.sources.checkFailed")
22925
+ })] });
22926
+ }
22927
+ /** The selected source surface shared by node inputs and response projections. */
22928
+ function SourceValueControl({ label, description, variable = false, node = false, icon, error, name }) {
22929
+ const t = useTranslate();
22930
+ const [tooltipContainer, setTooltipContainer] = useState(null);
22931
+ return /* @__PURE__ */ jsx(ValueEditorFeedback, {
22932
+ error,
22809
22933
  children: (errorId) => /* @__PURE__ */ jsxs("div", {
22810
22934
  ref: setTooltipContainer,
22811
22935
  "data-field-control": true,
22812
22936
  "data-value-control": true,
22813
22937
  className: `${nodeInputValue_module_default.sourceControl} flex h-[30px] min-w-0 items-center rounded-[var(--ui-control-radius,var(--ui-radius))] border border-input bg-[var(--ui-control-background,var(--ui-muted))] px-[7px] text-xs`,
22814
- "aria-invalid": sourceIssue != null,
22938
+ "aria-invalid": error != null,
22939
+ "aria-label": name,
22815
22940
  "aria-describedby": errorId,
22816
- tabIndex: sourceIssue ? 0 : void 0,
22817
- children: [bound ? /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
22941
+ tabIndex: error ? 0 : void 0,
22942
+ children: [variable ? /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
22818
22943
  render: /* @__PURE__ */ jsx("span", {
22819
22944
  role: "img",
22820
22945
  "aria-label": t("nodeInput.variable"),
@@ -22828,36 +22953,32 @@ function SelectedSourceValue({ bound, readOnly, connected, sourceMissing, onInva
22828
22953
  container: tooltipContainer,
22829
22954
  sideOffset: 0,
22830
22955
  children: t("nodeInput.variable")
22831
- })] }) : connected && current?.length === 1 && /* @__PURE__ */ jsx(ContentIcon, {
22832
- src: selectedUpstreamIcon,
22956
+ })] }) : node && /* @__PURE__ */ jsx(ContentIcon, {
22957
+ src: icon,
22833
22958
  className: "mr-2 size-3.5 shrink-0 data-[icon-kind=initials]:text-[16px]",
22834
22959
  fallback: /* @__PURE__ */ jsx("i", {
22835
22960
  "aria-hidden": "true",
22836
22961
  className: "i-lucide-light:workflow mr-2 size-3.5 shrink-0 text-muted-foreground"
22837
22962
  })
22838
22963
  }), /* @__PURE__ */ jsxs(Tooltip, {
22839
- disabled: sourceTooltip == null,
22964
+ disabled: description == null,
22840
22965
  children: [/* @__PURE__ */ jsx(TooltipTrigger, {
22841
22966
  render: /* @__PURE__ */ jsx("span", {
22842
22967
  className: "min-w-0 flex-1 truncate",
22843
- "aria-description": sourceTooltip
22968
+ "aria-description": description
22844
22969
  }),
22845
- children: sourceLabel
22970
+ children: label
22846
22971
  }), /* @__PURE__ */ jsx(TooltipContent, {
22847
22972
  container: tooltipContainer,
22848
22973
  sideOffset: 11,
22849
22974
  positionMethod: "fixed",
22850
22975
  collisionBoundary: [],
22851
22976
  className: "whitespace-pre-wrap",
22852
- children: sourceTooltip
22977
+ children: description
22853
22978
  })]
22854
22979
  })]
22855
22980
  })
22856
- }), checkFailed && /* @__PURE__ */ jsx("p", {
22857
- role: "status",
22858
- className: "text-xs text-muted-foreground",
22859
- children: t("inspector.sources.checkFailed")
22860
- })] });
22981
+ });
22861
22982
  }
22862
22983
  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 }) {
22863
22984
  const t = useTranslate();
@@ -22878,52 +22999,16 @@ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEd
22878
22999
  const sourcePortal = sourceContainer?.closest(".editor-context-panel") ?? sourceContainer;
22879
23000
  const sourceOption = (nodeId, { description, output, field, fields, check, system }, label) => {
22880
23001
  const selected = sourceKind === "upstream" && currentSource === upstreamSource(nodeId, output, field, system);
22881
- const status = check.kind == "schema" ? t("inspector.sources.incompatible") : check.kind == "schema-error" ? t("inspector.sources.unverified") : void 0;
22882
23002
  const itemKey = upstreamSource(nodeId, output, field, system);
22883
- const sourceDescription = description?.trim();
22884
- const item = /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
22885
- className: `${sourceItemClass} ${status == null || selected ? "pr-8" : "pr-20"}`,
23003
+ return /* @__PURE__ */ jsx(SourceMenuOption, {
22886
23004
  value: itemKey,
22887
- closeOnClick: true,
22888
- "aria-description": sourceDescription,
22889
- children: [
22890
- /* @__PURE__ */ jsx("i", {
22891
- "aria-hidden": "true",
22892
- className: `${fields?.length ? `${editorComponentIcons.object} ${status == null ? "text-muted-foreground" : ""}` : check.kind == "available" ? "i-lucide-light:corner-down-right text-muted-foreground" : check.kind == "schema" ? "i-lucide-light:triangle-alert" : "i-lucide-light:circle-help"} size-3.5 shrink-0`,
22893
- style: status == null ? void 0 : { color: "var(--warning-foreground)" }
22894
- }),
22895
- /* @__PURE__ */ jsx("span", {
22896
- className: "min-w-0 flex-1 truncate font-mono",
22897
- title: label,
22898
- children: label
22899
- }),
22900
- !selected && status != null && /* @__PURE__ */ jsx("span", {
22901
- className: "pointer-events-none absolute right-2 shrink-0 text-[10px] leading-4",
22902
- style: { color: "var(--warning-foreground)" },
22903
- children: status
22904
- }),
22905
- selected && status != null && /* @__PURE__ */ jsx("span", {
22906
- className: "sr-only",
22907
- children: status
22908
- })
22909
- ]
23005
+ label,
23006
+ selected,
23007
+ compatibility: check.kind === "schema" ? "incompatible" : check.kind === "schema-error" ? "unverified" : "available",
23008
+ icon: fields?.length ? editorComponentIcons.object : void 0,
23009
+ description,
23010
+ container: sourcePortal
22910
23011
  }, itemKey);
22911
- if (sourceDescription == null || sourceDescription === "") return item;
22912
- return /* @__PURE__ */ jsxs(TooltipRoot, { children: [/* @__PURE__ */ jsx(TooltipTrigger$1, { render: item }), /* @__PURE__ */ jsx(TooltipPortal, {
22913
- container: sourcePortal,
22914
- className: "contents",
22915
- children: /* @__PURE__ */ jsx(TooltipPositioner, {
22916
- side: "right",
22917
- align: "start",
22918
- sideOffset: 8,
22919
- positionMethod: "fixed",
22920
- className: "pointer-events-none isolate z-[1000]",
22921
- children: /* @__PURE__ */ jsxs(TooltipPopup, {
22922
- className: "pointer-events-none max-w-64 rounded-[6px] bg-foreground px-3 py-2 text-xs leading-5 text-background shadow-md outline-none",
22923
- children: [sourceDescription, /* @__PURE__ */ jsx(TooltipArrow, { className: "size-2.5 rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=left]:-right-1 data-[side=right]:-left-1 data-[side=top]:-bottom-2.5" })]
22924
- })
22925
- })
22926
- })] }, itemKey);
22927
23012
  };
22928
23013
  const selectUpstream = (next) => {
22929
23014
  const [, nodeId, output, field, system] = JSON.parse(next);
@@ -22943,24 +23028,13 @@ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEd
22943
23028
  setSourceOpen(open);
22944
23029
  if (open && variables.enabled) variables.onOpen?.();
22945
23030
  },
22946
- children: [/* @__PURE__ */ jsxs(Tooltip, {
22947
- disabled: sourceOpen,
22948
- children: [/* @__PURE__ */ jsx(TooltipTrigger, { render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
22949
- type: "button",
22950
- variant: "ghost",
22951
- size: "icon-xs",
22952
- className: "aria-pressed:bg-[var(--ui-control-hover-background,var(--ui-muted))] aria-pressed:text-foreground",
22953
- "aria-label": `${fieldLabel} ${t("inspector.sources.select")}`,
22954
- "aria-pressed": sourceKind !== "literal",
22955
- disabled,
22956
- children: /* @__PURE__ */ jsx("i", {
22957
- "aria-hidden": "true",
22958
- className: "i-lucide-light:link"
22959
- })
22960
- }) }) }), /* @__PURE__ */ jsx(TooltipContent, {
22961
- container: sourcePortal,
22962
- children: t("inspector.sources.select")
22963
- })]
23031
+ children: [/* @__PURE__ */ jsx(SourceSelectorTrigger, {
23032
+ label: `${fieldLabel} ${t("inspector.sources.select")}`,
23033
+ description: t("inspector.sources.select"),
23034
+ open: sourceOpen,
23035
+ pressed: sourceKind !== "literal",
23036
+ disabled,
23037
+ container: sourcePortal
22964
23038
  }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
22965
23039
  align: "start",
22966
23040
  sideOffset: 6,
@@ -22975,7 +23049,7 @@ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEd
22975
23049
  else if (connected) onValue(void 0);
22976
23050
  },
22977
23051
  children: /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
22978
- className: sourceItemClass,
23052
+ className: sourceMenuItemClass,
22979
23053
  value: literalSource,
22980
23054
  closeOnClick: true,
22981
23055
  children: [/* @__PURE__ */ jsx("i", {
@@ -23006,7 +23080,7 @@ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEd
23006
23080
  onVariable(name);
23007
23081
  },
23008
23082
  children: [bound && !variables.names.includes(variableName) && /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
23009
- className: sourceItemClass,
23083
+ className: sourceMenuItemClass,
23010
23084
  value: variableSource(variableName),
23011
23085
  disabled: true,
23012
23086
  children: [/* @__PURE__ */ jsx("i", {
@@ -23021,7 +23095,7 @@ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEd
23021
23095
  const selected = sourceKind === "variable" && currentSource === variableSource(name);
23022
23096
  const status = variableCompatible ? void 0 : t("inspector.sources.incompatible");
23023
23097
  return /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
23024
- className: `${sourceItemClass} ${status == null || selected ? "pr-8" : "pr-20"}`,
23098
+ className: `${sourceMenuItemClass} ${status == null || selected ? "pr-8" : "pr-20"}`,
23025
23099
  value: variableSource(name),
23026
23100
  closeOnClick: true,
23027
23101
  children: [
@@ -23086,7 +23160,7 @@ function SourceValueEditor({ fixed = false, sourceOnly = false, editor: customEd
23086
23160
  value: sourceKind === "upstream" && upstream.current.length === 1 && upstream.current[0]?.nodeId === group.nodeId ? currentSource : "",
23087
23161
  onValueChange: selectUpstream,
23088
23162
  children: [upstream.current.filter((source) => source.nodeId === group.nodeId && source.check != null && source.check.kind != "available" && !group.outputs.some((candidate) => candidate.output === source.output && candidate.system === source.system && (source.field === void 0 || candidate.fields?.some((child) => child.field === source.field)))).map((source) => /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
23089
- className: sourceItemClass,
23163
+ className: sourceMenuItemClass,
23090
23164
  value: upstreamSource(source.nodeId, source.output, source.field, source.system),
23091
23165
  disabled: true,
23092
23166
  children: [/* @__PURE__ */ jsx("i", {
@@ -23763,19 +23837,19 @@ function presentConnectorInputs(inputs, t) {
23763
23837
  ];
23764
23838
  }
23765
23839
  var fieldTable_module_default = {
23766
- list: "fieldTable_list_58822",
23767
- columns: "fieldTable_columns_58822",
23768
- nameHeading: "fieldTable_nameHeading_58822",
23769
- typeHeading: "fieldTable_typeHeading_58822",
23770
- valueHeading: "fieldTable_valueHeading_58822",
23771
- row: "fieldTable_row_58822",
23772
- nullableControl: "fieldTable_nullableControl_58822",
23773
- nullableHeading: "fieldTable_nullableHeading_58822"
23840
+ list: "fieldTable_list_14bfd",
23841
+ columns: "fieldTable_columns_14bfd",
23842
+ nameHeading: "fieldTable_nameHeading_14bfd",
23843
+ typeHeading: "fieldTable_typeHeading_14bfd",
23844
+ valueHeading: "fieldTable_valueHeading_14bfd",
23845
+ row: "fieldTable_row_14bfd",
23846
+ nullableControl: "fieldTable_nullableControl_14bfd",
23847
+ nullableHeading: "fieldTable_nullableHeading_14bfd"
23774
23848
  };
23775
23849
  //#endregion
23776
23850
  //#region src/form/browser/fieldTable.tsx
23777
23851
  /** Shared field geometry. Callers own definitions, values, actions and persistence. */
23778
- var FieldTable = forwardRef(({ layout = "definition", fixedTypes, typeColumn = true, columnHeadings = true, output, nullable, empty, actionSlots = 1, className, children, ...props }, ref) => {
23852
+ var FieldTable = forwardRef(({ layout = "definition", fixedTypes, typeColumn = true, columnHeadings = true, output, nullable, empty, actionSlots = 1, standalone, className, children, ...props }, ref) => {
23779
23853
  const t = useTranslate();
23780
23854
  return /* @__PURE__ */ jsxs("div", {
23781
23855
  ...props,
@@ -23789,6 +23863,7 @@ var FieldTable = forwardRef(({ layout = "definition", fixedTypes, typeColumn = t
23789
23863
  "data-nullable": nullable || void 0,
23790
23864
  "data-empty": empty || void 0,
23791
23865
  "data-action-slots": actionSlots,
23866
+ "data-standalone": standalone || void 0,
23792
23867
  children: [columnHeadings && !empty && /* @__PURE__ */ jsxs("div", {
23793
23868
  className: fieldTable_module_default.columns,
23794
23869
  "data-layout": layout,
@@ -29636,7 +29711,253 @@ function presentProviderOutputDescription(node, output, description, display) {
29636
29711
  return display?.outputs[output] ?? description;
29637
29712
  }
29638
29713
  //#endregion
29714
+ //#region src/workbench/browser/runtime/editor/timeZoneSelect.tsx
29715
+ function TimeZoneSelect({ id, value, disabled, label, onChange, at = /* @__PURE__ */ new Date() }) {
29716
+ const t = useTranslate();
29717
+ const language = useLang();
29718
+ const [open, setOpen] = useState(false);
29719
+ const [container, setContainer] = useState(null);
29720
+ const timezones = (selectableTimeZones.includes(value) ? selectableTimeZones : [value, ...selectableTimeZones]).toSorted((left, right) => {
29721
+ return (timeZoneOffsetMinutes(left, at) ?? Number.POSITIVE_INFINITY) - (timeZoneOffsetMinutes(right, at) ?? Number.POSITIVE_INFINITY) || timeZoneLongLabel(left, language).localeCompare(timeZoneLongLabel(right, language), language);
29722
+ });
29723
+ const items = timezones.map((timezone) => ({
29724
+ value: timezone,
29725
+ label: timeZoneLongLabel(timezone, language)
29726
+ }));
29727
+ return /* @__PURE__ */ jsx("div", {
29728
+ ref: setContainer,
29729
+ className: "min-w-0",
29730
+ children: /* @__PURE__ */ jsxs(Select$1, {
29731
+ open,
29732
+ onOpenChange: setOpen,
29733
+ value,
29734
+ onValueChange: (next) => {
29735
+ if (next != null) onChange(next);
29736
+ },
29737
+ disabled,
29738
+ items,
29739
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
29740
+ id,
29741
+ size: "field",
29742
+ "aria-label": label,
29743
+ className: fieldSelectTriggerClass,
29744
+ children: /* @__PURE__ */ jsx(SelectValue, { children: timeZoneLabel(value, t, language) })
29745
+ }), /* @__PURE__ */ jsx(SelectContent, {
29746
+ container,
29747
+ align: "start",
29748
+ alignItemWithTrigger: false,
29749
+ className: selectionMenuContentClass,
29750
+ children: timezones.map((timezone) => /* @__PURE__ */ jsx(SelectItem, {
29751
+ value: timezone,
29752
+ className: selectionMenuItemClass,
29753
+ children: /* @__PURE__ */ jsxs("span", {
29754
+ className: "flex w-full min-w-0 items-baseline gap-3",
29755
+ children: [/* @__PURE__ */ jsx("span", {
29756
+ className: "w-[72px] shrink-0 font-mono text-[11px] text-muted-foreground",
29757
+ children: timeZoneOffset(timezone, at) ?? "—"
29758
+ }), /* @__PURE__ */ jsx("span", {
29759
+ className: "min-w-0 flex-1 truncate",
29760
+ children: timeZoneLongLabel(timezone, language)
29761
+ })]
29762
+ })
29763
+ }, timezone))
29764
+ })]
29765
+ })
29766
+ });
29767
+ }
29768
+ //#endregion
29639
29769
  //#region src/workbench/browser/runtime/editor/resolutionDefinition.tsx
29770
+ function timingDraft(config) {
29771
+ const timezone = config?.kind == "at" && config.timezone != null ? config.timezone : Intl.DateTimeFormat().resolvedOptions().timeZone;
29772
+ if (config?.kind == "after") return {
29773
+ mode: "after",
29774
+ value: config.durationMs == null ? "" : String(config.durationMs / 1e3),
29775
+ timezone
29776
+ };
29777
+ if (config?.kind == "at") return {
29778
+ mode: "at",
29779
+ value: waitAutoContinueSchema.safeParse(config).success ? dateTimeWall(dateInTimeZone(config.at, timezone)) : config.at,
29780
+ timezone
29781
+ };
29782
+ return {
29783
+ mode: "off",
29784
+ value: "",
29785
+ timezone
29786
+ };
29787
+ }
29788
+ function timing({ mode, value, timezone }) {
29789
+ if (mode == "off") return null;
29790
+ if (mode == "at") return {
29791
+ kind: "at",
29792
+ at: dateFromTimeZone(value, timezone) ?? value,
29793
+ timezone
29794
+ };
29795
+ const duration = value.trim() == "" ? null : Number(value) * 1e3;
29796
+ if (duration == null || !Number.isFinite(duration)) return {
29797
+ kind: "after",
29798
+ durationMs: null
29799
+ };
29800
+ const nearest = Math.round(duration);
29801
+ const tolerance = Number.EPSILON * Math.max(1, Math.abs(duration));
29802
+ return {
29803
+ kind: "after",
29804
+ durationMs: Math.abs(duration - nearest) <= tolerance ? nearest : duration
29805
+ };
29806
+ }
29807
+ function AutoContinue({ selection, disabled, store }) {
29808
+ const t = useTranslate();
29809
+ const config = selection.node.autoContinue;
29810
+ const [draft, setDraft] = useState(() => timingDraft(config));
29811
+ const saved = useRef({
29812
+ nodeId: selection.id,
29813
+ config
29814
+ });
29815
+ const [error, setError] = useState(false);
29816
+ const request = useRef();
29817
+ useEffect(() => {
29818
+ if (saved.current.nodeId == selection.id && dequal(saved.current.config, config)) return;
29819
+ saved.current = {
29820
+ nodeId: selection.id,
29821
+ config
29822
+ };
29823
+ request.current?.abort();
29824
+ setDraft(timingDraft(config));
29825
+ }, [config, selection.id]);
29826
+ useEffect(() => {
29827
+ const controller = new AbortController();
29828
+ request.current = controller;
29829
+ Promise.resolve().then(() => {
29830
+ if (controller.signal.aborted || request.current !== controller) return;
29831
+ const candidate = timing(draft);
29832
+ setError(candidate != null && !waitAutoContinueSchema.safeParse(candidate).success);
29833
+ });
29834
+ return () => controller.abort();
29835
+ }, [draft]);
29836
+ const change = (next) => {
29837
+ request.current?.abort();
29838
+ setDraft(next);
29839
+ };
29840
+ const save = async (next = draft) => {
29841
+ if (disabled || store == null) return;
29842
+ await store.nodes.saveResolution(selection.id, {
29843
+ name: selection.node.name,
29844
+ prompt: selection.node.prompt,
29845
+ autoContinue: timing(next)
29846
+ });
29847
+ };
29848
+ const { mode, value, timezone } = draft;
29849
+ const id = `wait-${selection.id}-auto`;
29850
+ return /* @__PURE__ */ jsx(InspectorSection, {
29851
+ title: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(FieldLabel, {
29852
+ htmlFor: id,
29853
+ children: t("inspector.wait.autoContinue")
29854
+ }), /* @__PURE__ */ jsx(HelpButton, {
29855
+ label: t("inspector.wait.autoContinue"),
29856
+ children: t("inspector.wait.autoDescription")
29857
+ })] }),
29858
+ children: /* @__PURE__ */ jsx("div", {
29859
+ className: "node-settings",
29860
+ children: /* @__PURE__ */ jsxs(FieldGroup, { children: [
29861
+ /* @__PURE__ */ jsx(Field, { children: /* @__PURE__ */ jsxs(NativeSelect, {
29862
+ id,
29863
+ disabled,
29864
+ value: mode,
29865
+ onChange: (event) => {
29866
+ const next = {
29867
+ ...draft,
29868
+ mode: event.target.value,
29869
+ value: ""
29870
+ };
29871
+ change(next);
29872
+ save(next);
29873
+ },
29874
+ children: [
29875
+ /* @__PURE__ */ jsx(NativeSelectOption, {
29876
+ value: "off",
29877
+ children: t("inspector.wait.autoOff")
29878
+ }),
29879
+ /* @__PURE__ */ jsx(NativeSelectOption, {
29880
+ value: "after",
29881
+ children: t("inspector.wait.autoAfter")
29882
+ }),
29883
+ /* @__PURE__ */ jsx(NativeSelectOption, {
29884
+ value: "at",
29885
+ children: t("inspector.wait.autoAt")
29886
+ })
29887
+ ]
29888
+ }) }),
29889
+ mode == "after" && /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
29890
+ htmlFor: `${id}-value`,
29891
+ children: t("inspector.wait.autoSeconds")
29892
+ }), /* @__PURE__ */ jsx(ValueEditorFeedback, {
29893
+ error: error ? t("inspector.wait.autoInvalid") : void 0,
29894
+ children: (errorId) => /* @__PURE__ */ jsx(Input, {
29895
+ id: `${id}-value`,
29896
+ type: "number",
29897
+ min: "0.001",
29898
+ step: "0.001",
29899
+ disabled,
29900
+ value,
29901
+ "aria-invalid": error,
29902
+ "aria-describedby": errorId,
29903
+ onChange: (event) => change({
29904
+ ...draft,
29905
+ value: event.target.value
29906
+ }),
29907
+ onBlur: () => void save(),
29908
+ onKeyDown: (event) => {
29909
+ if (event.key == "Enter") {
29910
+ event.preventDefault();
29911
+ save();
29912
+ }
29913
+ }
29914
+ })
29915
+ })] }),
29916
+ mode == "at" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
29917
+ htmlFor: `${id}-value`,
29918
+ children: t("inspector.wait.autoDate")
29919
+ }), /* @__PURE__ */ jsx(ValueEditorFeedback, {
29920
+ error: error ? t("inspector.wait.autoInvalid") : void 0,
29921
+ children: (errorId) => /* @__PURE__ */ jsx(DateEditor, {
29922
+ id: `${id}-value`,
29923
+ label: t("inspector.wait.autoDate"),
29924
+ format: "date-time",
29925
+ precision: "minute",
29926
+ value,
29927
+ disabled,
29928
+ invalid: error,
29929
+ describedBy: errorId,
29930
+ onChange: (next) => change({
29931
+ ...draft,
29932
+ value: dateTimeWall(next)
29933
+ }),
29934
+ onCommit: (next) => void save({
29935
+ ...draft,
29936
+ value: dateTimeWall(next)
29937
+ })
29938
+ })
29939
+ })] }), /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, {
29940
+ htmlFor: `${id}-timezone`,
29941
+ children: t("triggerSchedule.scheduleTimezone")
29942
+ }), /* @__PURE__ */ jsx(TimeZoneSelect, {
29943
+ id: `${id}-timezone`,
29944
+ label: t("triggerSchedule.scheduleTimezone"),
29945
+ value: timezone,
29946
+ disabled,
29947
+ at: new Date(dateFromTimeZone(value, timezone) ?? Date.now()),
29948
+ onChange: (zone) => {
29949
+ const next = {
29950
+ ...draft,
29951
+ timezone: zone
29952
+ };
29953
+ change(next);
29954
+ save(next);
29955
+ }
29956
+ })] })] })
29957
+ ] })
29958
+ })
29959
+ });
29960
+ }
29640
29961
  function ResolutionDefinition({ disabled, selection, store }) {
29641
29962
  const t = useTranslate();
29642
29963
  const node = selection.node;
@@ -29659,14 +29980,14 @@ function ResolutionDefinition({ disabled, selection, store }) {
29659
29980
  prompt: value
29660
29981
  });
29661
29982
  };
29662
- return /* @__PURE__ */ jsx("form", {
29983
+ return /* @__PURE__ */ jsxs("form", {
29663
29984
  className: "inspector-form wait-form",
29664
29985
  "data-inspector-section": "resolution",
29665
29986
  onSubmit: (event) => {
29666
29987
  event.preventDefault();
29667
29988
  save();
29668
29989
  },
29669
- children: /* @__PURE__ */ jsxs(FieldGroup, { children: [/* @__PURE__ */ jsxs(Field, {
29990
+ children: [/* @__PURE__ */ jsxs(FieldGroup, { children: [/* @__PURE__ */ jsxs(Field, {
29670
29991
  className: "inspector-field-section",
29671
29992
  children: [/* @__PURE__ */ jsx(FieldLabel, {
29672
29993
  className: "inspector-section-title",
@@ -29682,7 +30003,11 @@ function ResolutionDefinition({ disabled, selection, store }) {
29682
30003
  if (event.currentTarget.value.trim() != node.prompt) save(event.currentTarget.value);
29683
30004
  }
29684
30005
  })]
29685
- }), error != null && /* @__PURE__ */ jsx(FieldError, { children: error })] })
30006
+ }), error != null && /* @__PURE__ */ jsx(FieldError, { children: error })] }), selection.kind == "wait" && /* @__PURE__ */ jsx(AutoContinue, {
30007
+ selection,
30008
+ disabled,
30009
+ store
30010
+ })]
29686
30011
  });
29687
30012
  }
29688
30013
  //#endregion
@@ -29916,60 +30241,6 @@ function ScheduleText({ value, disabled, label, commit, inspect, numeric = false
29916
30241
  })]
29917
30242
  });
29918
30243
  }
29919
- function TimeZoneSelect({ id, value, disabled, label, onChange }) {
29920
- const t = useTranslate();
29921
- const language = useLang();
29922
- const [open, setOpen] = useState(false);
29923
- const [container, setContainer] = useState(null);
29924
- const at = /* @__PURE__ */ new Date();
29925
- const timezones = (selectableTimeZones.includes(value) ? selectableTimeZones : [value, ...selectableTimeZones]).toSorted((left, right) => {
29926
- return (timeZoneOffsetMinutes(left, at) ?? Number.POSITIVE_INFINITY) - (timeZoneOffsetMinutes(right, at) ?? Number.POSITIVE_INFINITY) || timeZoneLongLabel(left, language).localeCompare(timeZoneLongLabel(right, language), language);
29927
- });
29928
- const items = timezones.map((timezone) => ({
29929
- value: timezone,
29930
- label: timeZoneLongLabel(timezone, language)
29931
- }));
29932
- return /* @__PURE__ */ jsx("div", {
29933
- ref: setContainer,
29934
- className: "min-w-0",
29935
- children: /* @__PURE__ */ jsxs(Select$1, {
29936
- open,
29937
- onOpenChange: setOpen,
29938
- value,
29939
- onValueChange: (next) => {
29940
- if (next != null) onChange(next);
29941
- },
29942
- disabled,
29943
- items,
29944
- children: [/* @__PURE__ */ jsx(SelectTrigger, {
29945
- id,
29946
- size: "field",
29947
- "aria-label": label,
29948
- className: fieldSelectTriggerClass,
29949
- children: /* @__PURE__ */ jsx(SelectValue, { children: timeZoneLabel(value, t, language) })
29950
- }), /* @__PURE__ */ jsx(SelectContent, {
29951
- container,
29952
- align: "start",
29953
- alignItemWithTrigger: false,
29954
- className: selectionMenuContentClass,
29955
- children: timezones.map((timezone) => /* @__PURE__ */ jsx(SelectItem, {
29956
- value: timezone,
29957
- className: selectionMenuItemClass,
29958
- children: /* @__PURE__ */ jsxs("span", {
29959
- className: "flex w-full min-w-0 items-baseline gap-3",
29960
- children: [/* @__PURE__ */ jsx("span", {
29961
- className: "w-[72px] shrink-0 font-mono text-[11px] text-muted-foreground",
29962
- children: timeZoneOffset(timezone, at) ?? "—"
29963
- }), /* @__PURE__ */ jsx("span", {
29964
- className: "min-w-0 flex-1 truncate",
29965
- children: timeZoneLongLabel(timezone, language)
29966
- })]
29967
- })
29968
- }, timezone))
29969
- })]
29970
- })
29971
- });
29972
- }
29973
30244
  function TriggerScheduleEditor({ schedules, disabled, collapsible = false, onChange }) {
29974
30245
  const t = useTranslate();
29975
30246
  const language = useLang();
@@ -30279,6 +30550,238 @@ function WebhookDeployment({ binding, status, enabled, hasUnpublishedChanges, on
30279
30550
  });
30280
30551
  }
30281
30552
  //#endregion
30553
+ //#region src/workbench/browser/runtime/editor/webhookStatusSource.tsx
30554
+ function WebhookResponseSource({ outputs, label, port: targetPort, wholeObject = false, value, disabled, onChange }) {
30555
+ const t = useTranslate();
30556
+ const [open, setOpen] = useState(false);
30557
+ const [container, setContainer] = useState(null);
30558
+ const portal = container?.closest(".editor-context-panel") ?? container;
30559
+ const missing = value?.output != null && !outputs?.outputDefs.some((port) => port.handle === value.output);
30560
+ const nodeName = outputs?.name ?? t("addNode.outputs");
30561
+ const wholeCompatible = wholeObject && outputs != null && portsAssignable(workflowOutputsPort(outputs.outputDefs), targetPort);
30562
+ return /* @__PURE__ */ jsx("div", {
30563
+ ref: setContainer,
30564
+ className: "flex items-center",
30565
+ children: /* @__PURE__ */ jsxs(DropdownMenu, {
30566
+ open,
30567
+ onOpenChange: setOpen,
30568
+ children: [/* @__PURE__ */ jsx(SourceSelectorTrigger, {
30569
+ label,
30570
+ open,
30571
+ pressed: value != null,
30572
+ disabled,
30573
+ container: portal
30574
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
30575
+ align: "start",
30576
+ sideOffset: 6,
30577
+ className: `w-44 min-w-44 ${selectionMenuContentClass}`,
30578
+ container: portal,
30579
+ children: [
30580
+ /* @__PURE__ */ jsx(MenuHeader, { children: label }),
30581
+ /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
30582
+ value: value == null ? "fixed" : "",
30583
+ onValueChange: () => onChange(void 0),
30584
+ children: /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
30585
+ className: sourceMenuItemClass,
30586
+ value: "fixed",
30587
+ closeOnClick: true,
30588
+ children: [/* @__PURE__ */ jsx("i", {
30589
+ "aria-hidden": "true",
30590
+ className: "i-lucide-light:pen-line size-3.5 shrink-0 text-muted-foreground"
30591
+ }), /* @__PURE__ */ jsx("span", {
30592
+ className: "min-w-0 flex-1 truncate",
30593
+ children: t("nodeInput.literal")
30594
+ })]
30595
+ })
30596
+ }),
30597
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "mx-2 bg-border/50" }),
30598
+ outputs != null && /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, {
30599
+ className: `${sourceMenuItemClass} ${value != null ? "bg-accent" : ""}`,
30600
+ children: [/* @__PURE__ */ jsx(ContentIcon, {
30601
+ src: outputs.icon,
30602
+ className: "size-3.5 shrink-0 data-[icon-kind=initials]:text-[16px]",
30603
+ fallback: /* @__PURE__ */ jsx(Icon, {
30604
+ name: "outputs",
30605
+ size: 14
30606
+ })
30607
+ }), /* @__PURE__ */ jsx("span", {
30608
+ className: "min-w-0 flex-1 truncate",
30609
+ title: nodeName,
30610
+ children: nodeName
30611
+ })]
30612
+ }), /* @__PURE__ */ jsx(DropdownMenuSubContent, {
30613
+ className: `w-56 min-w-56 rounded-[calc(var(--ui-control-radius,var(--ui-radius))_+_2px)] p-1`,
30614
+ container: portal,
30615
+ children: /* @__PURE__ */ jsxs(DropdownMenuRadioGroup, {
30616
+ value: value == null ? "" : value.output == null ? "all" : `field:${value.output}`,
30617
+ onValueChange: (next) => onChange(next === "all" ? {} : { output: next.slice(6) }),
30618
+ children: [
30619
+ wholeObject && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SourceMenuOption, {
30620
+ value: "all",
30621
+ label: t("inspector.sources.wholeObject"),
30622
+ icon: "i-lucide-light:braces",
30623
+ selected: value != null && value.output == null,
30624
+ compatibility: wholeCompatible ? "available" : "incompatible",
30625
+ disabled: !wholeCompatible,
30626
+ container: portal
30627
+ }), /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: "mx-2 bg-border/50" })] }),
30628
+ !wholeObject && outputs.outputDefs.length === 0 && !missing && /* @__PURE__ */ jsx(DropdownMenuItem, {
30629
+ className: `${sourceMenuItemClass} font-normal text-muted-foreground data-disabled:opacity-100`,
30630
+ disabled: true,
30631
+ children: t("inspector.ports.noOutputs")
30632
+ }),
30633
+ outputs.outputDefs.map((port) => {
30634
+ const compatible = portsAssignable(port, targetPort);
30635
+ return /* @__PURE__ */ jsx(SourceMenuOption, {
30636
+ value: `field:${port.handle}`,
30637
+ label: port.handle,
30638
+ selected: port.handle === value?.output,
30639
+ compatibility: compatible ? "available" : "incompatible",
30640
+ disabled: !compatible,
30641
+ container: portal,
30642
+ description: port.description
30643
+ }, port.handle);
30644
+ }),
30645
+ missing && /* @__PURE__ */ jsx(SourceMenuOption, {
30646
+ value: `field:${value?.output}`,
30647
+ label: t("webhookEditor.webhookMissingOutput", { output: value?.output }),
30648
+ selected: true,
30649
+ disabled: true,
30650
+ container: portal
30651
+ })
30652
+ ]
30653
+ })
30654
+ })] })
30655
+ ]
30656
+ })]
30657
+ })
30658
+ });
30659
+ }
30660
+ function WebhookStatusSource(props) {
30661
+ const t = useTranslate();
30662
+ return /* @__PURE__ */ jsx(WebhookResponseSource, {
30663
+ ...props,
30664
+ label: t("webhookEditor.webhookStatusSource"),
30665
+ port: webhookStatusCodePort,
30666
+ value: props.value == null ? void 0 : { output: props.value },
30667
+ onChange: (source) => props.onChange(source?.output)
30668
+ });
30669
+ }
30670
+ //#endregion
30671
+ //#region src/workbench/browser/runtime/editor/webhookHeadersEditor.tsx
30672
+ var headersSchema = {
30673
+ type: "object",
30674
+ additionalProperties: { type: "string" }
30675
+ };
30676
+ var ignoreDraft = () => {};
30677
+ var expanded$1 = () => true;
30678
+ function WebhookHeadersEditor({ options, outputs, disabled, readOnly, sourceDisabled, diagnostics, onChange }) {
30679
+ const t = useTranslate();
30680
+ const whole = options.responseHeadersSource;
30681
+ const bindings = options.responseHeaderOutputs ?? {};
30682
+ const fixed = options.responseHeaders ?? {};
30683
+ const fixedNames = new Set(Object.keys(fixed).map((name) => name.toLowerCase()));
30684
+ const bindingOnlyNames = Object.keys(bindings).filter((name) => !fixedNames.has(name.toLowerCase()));
30685
+ const headers = {
30686
+ ...fixed,
30687
+ ...Object.fromEntries(bindingOnlyNames.map((name) => [name, ""]))
30688
+ };
30689
+ const label = t("webhookEditor.webhookHeaders");
30690
+ const issue = (suffix) => diagnostics.filter((item) => item.path.endsWith(suffix)).map((item) => diagnosticMessage(item, t)).join(" ") || void 0;
30691
+ const binding = (name) => {
30692
+ const key = Object.keys(bindings).find((candidate) => candidate.toLowerCase() === name.toLowerCase());
30693
+ return key == null ? void 0 : {
30694
+ output: bindings[key],
30695
+ error: issue(`/responseHeaderOutputs/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`)
30696
+ };
30697
+ };
30698
+ const sourceLabel = (output) => `${outputs?.name ?? t("addNode.outputs")} · ${output ?? t("inspector.sources.wholeObject")}`;
30699
+ const selected = (output, error, fieldLabel = label) => /* @__PURE__ */ jsx(SourceValueControl, {
30700
+ name: fieldLabel,
30701
+ label: sourceLabel(output),
30702
+ description: sourceLabel(output),
30703
+ node: true,
30704
+ icon: outputs?.icon,
30705
+ error
30706
+ });
30707
+ const source = (name) => options.responseBody == null || readOnly ? void 0 : /* @__PURE__ */ jsx(WebhookResponseSource, {
30708
+ label: name == null ? t("webhookEditor.webhookHeadersSource") : `${name} ${t("inspector.sources.select")}`,
30709
+ outputs,
30710
+ disabled: disabled || sourceDisabled,
30711
+ wholeObject: name == null,
30712
+ port: name == null ? webhookHeadersPort : webhookHeaderValuePort,
30713
+ value: name == null ? whole : binding(name),
30714
+ onChange: (next) => {
30715
+ const updated = { ...options };
30716
+ if (name == null) {
30717
+ if (next == null) delete updated.responseHeadersSource;
30718
+ else updated.responseHeadersSource = {
30719
+ kind: "workflow-outputs",
30720
+ ...next
30721
+ };
30722
+ } else {
30723
+ const values = Object.fromEntries([...Object.entries(bindings).filter(([key]) => key.toLowerCase() !== name.toLowerCase()), ...next == null ? [] : [[name, next.output]]]);
30724
+ if (Object.keys(values).length === 0) delete updated.responseHeaderOutputs;
30725
+ else updated.responseHeaderOutputs = values;
30726
+ }
30727
+ onChange(updated);
30728
+ }
30729
+ });
30730
+ return /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: label }), /* @__PURE__ */ jsx(FieldTable, {
30731
+ layout: "values",
30732
+ typeColumn: false,
30733
+ columnHeadings: false,
30734
+ actionSlots: 2,
30735
+ standalone: true,
30736
+ children: /* @__PURE__ */ jsx(FieldValueEditor, {
30737
+ label,
30738
+ valueOnly: true,
30739
+ schema: headersSchema,
30740
+ value: headers,
30741
+ path: "/responseHeaders",
30742
+ disabled,
30743
+ readOnly,
30744
+ hideOptions: true,
30745
+ hideValueTools: true,
30746
+ hideChildTypes: true,
30747
+ validationErrors: diagnostics.filter((item) => item.path.includes("/responseHeaderOutputs") || item.path.endsWith("/responseHeaders")).map((item) => ({
30748
+ instancePath: item.path.includes("/responseHeaderOutputs/") ? item.path.slice(item.path.indexOf("/responseHeaderOutputs/") + 22) : "",
30749
+ message: diagnosticMessage(item, t)
30750
+ })),
30751
+ expansionPolicy: expanded$1,
30752
+ onDraftIssue: ignoreDraft,
30753
+ valueAddon: source(),
30754
+ editor: whole == null ? void 0 : selected(whole.output, issue("/responseHeadersSource")),
30755
+ validateObjectFieldName: (name, current) => webhookHeaderNameIssue(name, Object.keys(headers).filter((candidate) => candidate !== current)) == null,
30756
+ renderObjectField: (name, props) => {
30757
+ const reference = binding(name);
30758
+ return /* @__PURE__ */ jsx(FieldValueEditor, {
30759
+ ...props,
30760
+ valueAddon: source(name),
30761
+ editor: reference == null ? void 0 : selected(reference.output, reference.error, name)
30762
+ });
30763
+ },
30764
+ onChange: (value, deletion) => {
30765
+ const next = value ?? {};
30766
+ const removed = Object.keys(headers).filter((name) => !Object.hasOwn(next, name));
30767
+ const added = Object.keys(next).filter((name) => !Object.hasOwn(headers, name));
30768
+ const nextBindings = Object.fromEntries(Object.entries(bindings).flatMap(([key, output]) => {
30769
+ if (!removed.some((name) => name.toLowerCase() === key.toLowerCase())) return [[key, output]];
30770
+ return removed.length === 1 && added.length === 1 ? [[added[0], output]] : [];
30771
+ }));
30772
+ const placeholders = new Set(bindingOnlyNames.map((name) => removed.length === 1 && added.length === 1 && removed[0] === name ? added[0] : name));
30773
+ const nextFixed = Object.fromEntries(Object.entries(next).filter(([name, text]) => text !== "" || !placeholders.has(name)));
30774
+ const updated = { ...options };
30775
+ if (Object.keys(nextFixed).length === 0) delete updated.responseHeaders;
30776
+ else updated.responseHeaders = nextFixed;
30777
+ if (Object.keys(nextBindings).length === 0) delete updated.responseHeaderOutputs;
30778
+ else updated.responseHeaderOutputs = nextBindings;
30779
+ onChange(updated, deletion);
30780
+ }
30781
+ })
30782
+ })] });
30783
+ }
30784
+ //#endregion
30282
30785
  //#region src/workbench/browser/runtime/editor/webhookEditor.tsx
30283
30786
  function deferInspection(check, signal) {
30284
30787
  return new Promise((resolve, reject) => {
@@ -30292,7 +30795,7 @@ function deferInspection(check, signal) {
30292
30795
  else signal.addEventListener("abort", abort, { once: true });
30293
30796
  });
30294
30797
  }
30295
- function DraftTextField({ label, value, disabled, description, inputMode, multiline, placeholder, inspect, onSave }) {
30798
+ function DraftTextField({ label, value, disabled, description, inputMode, multiline, placeholder, inspect, onSave, addon, editor, error }) {
30296
30799
  const id = useId();
30297
30800
  const descriptionId = `${id}-description`;
30298
30801
  const [draft, setDraft] = useState(value);
@@ -30320,9 +30823,9 @@ function DraftTextField({ label, value, disabled, description, inputMode, multil
30320
30823
  return () => controller.abort();
30321
30824
  }, [draft]);
30322
30825
  useEffect(() => () => commitController.current?.abort(), []);
30323
- const issue = inspection?.draft === draft ? inspection.result.issue : void 0;
30826
+ const issue = error ?? (editor == null && inspection?.draft === draft ? inspection.result.issue : void 0);
30324
30827
  const commit = () => {
30325
- if (disabled || draft === value) return;
30828
+ if (disabled || editor != null || draft === value) return;
30326
30829
  commitController.current?.abort();
30327
30830
  const controller = new AbortController();
30328
30831
  commitController.current = controller;
@@ -30365,11 +30868,14 @@ function DraftTextField({ label, value, disabled, description, inputMode, multil
30365
30868
  htmlFor: id,
30366
30869
  children: label
30367
30870
  }),
30368
- /* @__PURE__ */ jsx(ValueEditorFeedback, {
30369
- error: issue,
30370
- children: (errorId) => multiline ? /* @__PURE__ */ jsx(Textarea, { ...controlProps(errorId) }) : /* @__PURE__ */ jsx(Input, {
30371
- ...controlProps(errorId),
30372
- controlSize: "field"
30871
+ /* @__PURE__ */ jsx(ValueControl, {
30872
+ addon,
30873
+ children: /* @__PURE__ */ jsx(ValueEditorFeedback, {
30874
+ error: issue,
30875
+ children: (errorId) => editor?.(id, errorId) ?? (multiline ? /* @__PURE__ */ jsx(Textarea, { ...controlProps(errorId) }) : /* @__PURE__ */ jsx(Input, {
30876
+ ...controlProps(errorId),
30877
+ controlSize: "field"
30878
+ }))
30373
30879
  })
30374
30880
  }),
30375
30881
  description != null && /* @__PURE__ */ jsx(FieldDescription, {
@@ -30398,45 +30904,28 @@ function validOriginList(value, issue, signal) {
30398
30904
  };
30399
30905
  }, signal);
30400
30906
  }
30401
- function validStatus(value, issue, signal) {
30907
+ function validStatus(value, issue, signal, dynamic = false) {
30402
30908
  return deferInspection(() => {
30403
30909
  const normalized = value.trim();
30404
30910
  const status = Number(normalized);
30405
30911
  return {
30406
30912
  value: normalized,
30407
- ...normalized !== "" && (!Number.isInteger(status) || status < 200 || status > 599) ? { issue } : {}
30408
- };
30409
- }, signal);
30410
- }
30411
- function validHeaderName(value, current, headers, messages, signal) {
30412
- return deferInspection(() => {
30413
- const normalized = value.trim();
30414
- if (normalized === "") return {
30415
- value: normalized,
30416
- issue: messages.invalid
30417
- };
30418
- if (hasHeader(headers, normalized, current)) return {
30419
- value: normalized,
30420
- issue: messages.duplicate
30913
+ ...normalized !== "" && (!Number.isInteger(status) || status < 200 || status > 599 || dynamic && !webhookResponseAllowsBody(status)) ? { issue } : {}
30421
30914
  };
30422
- try {
30423
- new Headers([[normalized, "value"]]);
30424
- return { value: normalized };
30425
- } catch {
30426
- return {
30427
- value: normalized,
30428
- issue: messages.invalid
30429
- };
30430
- }
30431
30915
  }, signal);
30432
30916
  }
30433
- function hasHeader(headers, candidate, except) {
30434
- const normalized = candidate.toLowerCase();
30435
- return Object.keys(headers).some((name) => name !== except && name.toLowerCase() === normalized);
30436
- }
30437
- function WebhookEditor({ bodyFields, method, options, disabled, readOnly, outputSection, onChange }) {
30917
+ function WebhookEditor({ bodyFields, method, options, disabled, readOnly, outputSection, workflowOutputs, responseDiagnostics = [], onAddWorkflowOutputs, responseNodes = [], onAddResponseNode, onChange }) {
30438
30918
  const t = useTranslate();
30439
- const headers = options.responseHeaders ?? {};
30919
+ const policy = options.responseBody;
30920
+ const response = policy?.kind === "workflow-outputs" ? policy : void 0;
30921
+ const responseNode = policy?.kind === "webhook-response" ? policy : void 0;
30922
+ const outputsMissing = responseDiagnostics.some((issue) => issue.code === "trigger.webhook-response-outputs-missing");
30923
+ const outputsDisconnected = responseDiagnostics.some((issue) => issue.code === "trigger.webhook-response-unreachable");
30924
+ const responseIssue = responseDiagnostics.filter((issue) => issue.path.includes("/responseBody")).map((issue) => diagnosticMessage(issue, t)).join(" ") || void 0;
30925
+ const outputDefs = workflowOutputs?.outputDefs ?? [];
30926
+ const selectedMissing = response?.output != null && !outputDefs.some((port) => port.handle === response.output);
30927
+ const statusOutput = options.responseStatusCodeOutput;
30928
+ const statusIssue = responseDiagnostics.filter((issue) => issue.path.endsWith("/responseStatusCodeOutput")).map((issue) => diagnosticMessage(issue, t)).join(" ") || void 0;
30440
30929
  const changeOption = (key, value, deletion) => {
30441
30930
  const next = { ...options };
30442
30931
  if (value === void 0) delete next[key];
@@ -30447,16 +30936,12 @@ function WebhookEditor({ bodyFields, method, options, disabled, readOnly, output
30447
30936
  options: next
30448
30937
  }, deletion);
30449
30938
  };
30450
- const changeHeaders = (next, deletion) => changeOption("responseHeaders", Object.keys(next).length === 0 ? void 0 : next, deletion);
30451
- const addHeader = () => {
30452
- let name = "X-Header";
30453
- let index = 2;
30454
- while (hasHeader(headers, name)) name = `X-Header-${index++}`;
30455
- changeHeaders({
30456
- ...headers,
30457
- [name]: ""
30458
- });
30459
- };
30939
+ const statusSource = response == null || readOnly ? void 0 : /* @__PURE__ */ jsx(WebhookStatusSource, {
30940
+ outputs: workflowOutputs,
30941
+ value: statusOutput,
30942
+ disabled: disabled || outputsMissing || outputsDisconnected,
30943
+ onChange: (output) => changeOption("responseStatusCodeOutput", output)
30944
+ });
30460
30945
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
30461
30946
  /* @__PURE__ */ jsx(InspectorSection, {
30462
30947
  title: t("webhookEditor.webhookRequest"),
@@ -30497,6 +30982,209 @@ function WebhookEditor({ bodyFields, method, options, disabled, readOnly, output
30497
30982
  })] })
30498
30983
  }),
30499
30984
  outputSection,
30985
+ /* @__PURE__ */ jsx(InspectorSection, {
30986
+ title: t("webhookEditor.webhookResponse"),
30987
+ className: "inspector-form",
30988
+ "data-inspector-section": "trigger",
30989
+ children: /* @__PURE__ */ jsxs(FieldGroup, { children: [
30990
+ /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: t("webhookEditor.webhookResponseMode") }), /* @__PURE__ */ jsxs(FieldSelect, {
30991
+ "aria-label": t("webhookEditor.webhookResponseMode"),
30992
+ disabled,
30993
+ value: policy?.kind === "webhook-response" ? "node" : response == null ? "immediate" : "workflow",
30994
+ onChange: (mode) => {
30995
+ const next = { ...options };
30996
+ if (mode === "immediate") delete next.responseBody;
30997
+ else next.responseBody = {
30998
+ kind: mode === "node" ? "webhook-response" : "workflow-outputs",
30999
+ ...policy?.timeoutMs == null ? {} : { timeoutMs: policy.timeoutMs }
31000
+ };
31001
+ delete next.responseStatusCodeOutput;
31002
+ delete next.responseHeadersSource;
31003
+ delete next.responseHeaderOutputs;
31004
+ onChange({
31005
+ bodyFields,
31006
+ method,
31007
+ options: next
31008
+ });
31009
+ },
31010
+ children: [
31011
+ /* @__PURE__ */ jsx("option", {
31012
+ value: "immediate",
31013
+ children: t("webhookEditor.webhookImmediate")
31014
+ }),
31015
+ /* @__PURE__ */ jsx("option", {
31016
+ value: "workflow",
31017
+ children: t("webhookEditor.webhookAfterWorkflow")
31018
+ }),
31019
+ /* @__PURE__ */ jsx("option", {
31020
+ value: "node",
31021
+ children: t("addNode.webhookResponse")
31022
+ })
31023
+ ]
31024
+ })] }),
31025
+ responseNode != null ? /* @__PURE__ */ jsxs(Field, {
31026
+ "data-invalid": responseIssue != null || void 0,
31027
+ children: [/* @__PURE__ */ jsx(FieldLabel, { children: t("addNode.webhookResponse") }), /* @__PURE__ */ jsx(ValueEditorFeedback, {
31028
+ error: responseIssue,
31029
+ children: (errorId) => responseNodes.length === 0 ? /* @__PURE__ */ jsx(Button$1, {
31030
+ type: "button",
31031
+ variant: "field",
31032
+ size: "field",
31033
+ className: "w-full justify-start",
31034
+ "data-field-control": true,
31035
+ "data-field-prompt": true,
31036
+ "aria-invalid": responseIssue != null || void 0,
31037
+ "aria-describedby": errorId,
31038
+ disabled: disabled || readOnly || onAddResponseNode == null,
31039
+ onClick: onAddResponseNode,
31040
+ children: t("webhookEditor.webhookAddResponse")
31041
+ }) : /* @__PURE__ */ jsxs(FieldSelect, {
31042
+ showDisabledOptions: true,
31043
+ "aria-label": t("addNode.webhookResponse"),
31044
+ "aria-describedby": errorId,
31045
+ danger: responseIssue != null,
31046
+ disabled: disabled || !responseNodes.some((node) => node.reachable),
31047
+ value: responseNode.nodeId ?? "",
31048
+ displayValue: responseNode.nodeId == null && !responseNodes.some((node) => node.reachable) || responseNodes.some((node) => node.id === responseNode.nodeId && !node.reachable) ? t("webhookEditor.webhookResponseDisconnected") : void 0,
31049
+ onChange: (nodeId) => changeOption("responseBody", {
31050
+ ...responseNode,
31051
+ nodeId
31052
+ }),
31053
+ children: [
31054
+ /* @__PURE__ */ jsx("option", {
31055
+ value: "",
31056
+ disabled: true,
31057
+ hidden: true,
31058
+ children: t("webhookEditor.webhookSelectResponse")
31059
+ }),
31060
+ responseNodes.map((node) => /* @__PURE__ */ jsx("option", {
31061
+ value: node.id,
31062
+ disabled: !node.reachable,
31063
+ children: node.name
31064
+ }, node.id)),
31065
+ responseNode.nodeId != null && !responseNodes.some((node) => node.id === responseNode.nodeId) && /* @__PURE__ */ jsx("option", {
31066
+ value: responseNode.nodeId,
31067
+ disabled: true,
31068
+ children: t("webhookEditor.webhookMissingResponse")
31069
+ })
31070
+ ]
31071
+ })
31072
+ })]
31073
+ }) : response == null ? /* @__PURE__ */ jsx(DraftTextField, {
31074
+ label: t("webhookEditor.webhookResponseData"),
31075
+ multiline: true,
31076
+ value: options.responseData ?? "",
31077
+ disabled,
31078
+ placeholder: t("webhookEditor.webhookResponseDataPlaceholder"),
31079
+ onSave: (text) => changeOption("responseData", text === "" ? void 0 : text)
31080
+ }) : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsxs(Field, {
31081
+ "data-invalid": responseIssue != null || void 0,
31082
+ children: [/* @__PURE__ */ jsx(FieldLabel, { children: t("webhookEditor.webhookResponseContent") }), /* @__PURE__ */ jsx(ValueEditorFeedback, {
31083
+ error: responseIssue,
31084
+ children: (errorId) => outputsMissing ? /* @__PURE__ */ jsx(Button$1, {
31085
+ type: "button",
31086
+ variant: "field",
31087
+ size: "field",
31088
+ className: "w-full justify-start",
31089
+ "data-field-control": true,
31090
+ "data-field-prompt": true,
31091
+ "aria-invalid": true,
31092
+ "aria-describedby": errorId,
31093
+ disabled: disabled || readOnly || onAddWorkflowOutputs == null,
31094
+ onClick: onAddWorkflowOutputs,
31095
+ children: t("webhookEditor.webhookAddOutputs")
31096
+ }) : /* @__PURE__ */ jsxs(FieldSelect, {
31097
+ "aria-label": t("webhookEditor.webhookResponseContent"),
31098
+ "aria-describedby": errorId,
31099
+ danger: responseIssue != null,
31100
+ disabled: disabled || outputsDisconnected,
31101
+ value: response.output == null ? "all" : `field:${response.output}`,
31102
+ displayValue: outputsDisconnected ? t("webhookEditor.webhookOutputsDisconnected") : void 0,
31103
+ renderOption: (value, label) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("i", {
31104
+ "aria-hidden": "true",
31105
+ className: `${value === "all" ? editorComponentIcons.object : "i-lucide-light:corner-down-right"} size-3.5 shrink-0 text-muted-foreground`
31106
+ }), /* @__PURE__ */ jsx("span", {
31107
+ className: `min-w-0 flex-1 truncate ${value === "all" ? "" : "font-mono"}`,
31108
+ children: label
31109
+ })] }),
31110
+ onChange: (value) => changeOption("responseBody", value === "all" ? {
31111
+ kind: response.kind,
31112
+ ...response.timeoutMs == null ? {} : { timeoutMs: response.timeoutMs }
31113
+ } : {
31114
+ ...response,
31115
+ output: value.slice(6)
31116
+ }),
31117
+ children: [
31118
+ /* @__PURE__ */ jsx("option", {
31119
+ value: "all",
31120
+ children: t("webhookEditor.webhookAllOutputs")
31121
+ }),
31122
+ (outputDefs.length > 0 || selectedMissing) && /* @__PURE__ */ jsx("hr", {}),
31123
+ outputDefs.map((port) => /* @__PURE__ */ jsx("option", {
31124
+ value: `field:${port.handle}`,
31125
+ children: port.handle
31126
+ }, port.handle)),
31127
+ selectedMissing && /* @__PURE__ */ jsx("option", {
31128
+ value: `field:${response.output}`,
31129
+ children: t("webhookEditor.webhookMissingOutput", { output: response.output })
31130
+ })
31131
+ ]
31132
+ })
31133
+ })]
31134
+ }) }),
31135
+ policy != null && /* @__PURE__ */ jsx(DraftTextField, {
31136
+ label: t("webhookEditor.webhookTimeout"),
31137
+ description: t("webhookEditor.webhookTimeoutDescription"),
31138
+ value: String((policy.timeoutMs ?? webhookResponseTimeout.defaultMs) / 1e3),
31139
+ disabled,
31140
+ inputMode: "numeric",
31141
+ inspect: (draft, signal) => deferInspection(() => {
31142
+ const timeoutMs = Number(draft) * 1e3;
31143
+ return {
31144
+ value: draft.trim(),
31145
+ ...!Number.isInteger(timeoutMs) || timeoutMs < webhookResponseTimeout.minMs || timeoutMs > webhookResponseTimeout.maxMs ? { issue: t("webhookEditor.webhookTimeoutInvalid") } : {}
31146
+ };
31147
+ }, signal),
31148
+ onSave: (value) => changeOption("responseBody", {
31149
+ ...policy,
31150
+ timeoutMs: Number(value) * 1e3
31151
+ })
31152
+ }),
31153
+ responseNode == null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DraftTextField, {
31154
+ label: t("webhookEditor.webhookStatus"),
31155
+ value: options.responseStatusCode?.toString() ?? "",
31156
+ disabled,
31157
+ inputMode: "numeric",
31158
+ placeholder: t("webhookEditor.webhookStatusDefault"),
31159
+ inspect: (draft, signal) => validStatus(draft, t(response == null ? "webhookEditor.webhookStatusInvalid" : "webhookEditor.webhookDynamicStatusInvalid"), signal, response != null),
31160
+ onSave: (text) => changeOption("responseStatusCode", text === "" ? void 0 : Number(text)),
31161
+ addon: statusSource,
31162
+ error: statusIssue,
31163
+ editor: response != null && statusOutput != null ? (id, errorId) => /* @__PURE__ */ jsx(Input, {
31164
+ id,
31165
+ controlSize: "field",
31166
+ readOnly: true,
31167
+ disabled,
31168
+ "aria-label": t("webhookEditor.webhookStatus"),
31169
+ "aria-invalid": statusIssue != null,
31170
+ "aria-describedby": errorId,
31171
+ value: `${workflowOutputs?.name ?? t("addNode.outputs")} · ${statusOutput}`
31172
+ }) : void 0
31173
+ }, response == null ? "immediate" : "workflow"), /* @__PURE__ */ jsx(WebhookHeadersEditor, {
31174
+ options,
31175
+ outputs: workflowOutputs,
31176
+ disabled,
31177
+ readOnly,
31178
+ sourceDisabled: outputsMissing || outputsDisconnected || workflowOutputs == null,
31179
+ diagnostics: responseDiagnostics,
31180
+ onChange: (next, deletion) => onChange({
31181
+ bodyFields,
31182
+ method,
31183
+ options: next
31184
+ }, deletion)
31185
+ })] })
31186
+ ] })
31187
+ }),
30500
31188
  /* @__PURE__ */ jsxs("details", {
30501
31189
  className: "inspector-disclosure",
30502
31190
  "data-inspector-section": "trigger",
@@ -30511,104 +31199,77 @@ function WebhookEditor({ bodyFields, method, options, disabled, readOnly, output
30511
31199
  })
30512
31200
  })] }), /* @__PURE__ */ jsx("div", {
30513
31201
  className: "inspector-disclosure-content inspector-form",
30514
- children: /* @__PURE__ */ jsxs(FieldGroup, { children: [
30515
- /* @__PURE__ */ jsx(DraftTextField, {
30516
- label: t("webhookEditor.webhookOrigins"),
30517
- value: options.allowedOrigins?.join(", ") ?? "",
30518
- disabled,
30519
- description: t("webhookEditor.webhookOriginsHint"),
30520
- placeholder: "https://example.com, *",
30521
- inspect: (draft, signal) => validOriginList(draft, t("webhookEditor.webhookOriginsInvalid"), signal),
30522
- onSave: (text) => changeOption("allowedOrigins", text === "" ? void 0 : text.split(", "))
30523
- }),
30524
- /* @__PURE__ */ jsx(DraftTextField, {
30525
- label: t("webhookEditor.webhookStatus"),
30526
- value: options.responseStatusCode?.toString() ?? "",
30527
- disabled,
30528
- inputMode: "numeric",
30529
- placeholder: t("webhookEditor.webhookStatusDefault"),
30530
- inspect: (draft, signal) => validStatus(draft, t("webhookEditor.webhookStatusInvalid"), signal),
30531
- onSave: (text) => changeOption("responseStatusCode", text === "" ? void 0 : Number(text))
30532
- }),
30533
- /* @__PURE__ */ jsx(DraftTextField, {
30534
- label: t("webhookEditor.webhookResponseData"),
30535
- multiline: true,
30536
- value: options.responseData ?? "",
30537
- disabled,
30538
- placeholder: t("webhookEditor.webhookResponseDataPlaceholder"),
30539
- onSave: (text) => changeOption("responseData", text === "" ? void 0 : text)
30540
- }),
30541
- /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldSectionHeader, {
30542
- compact: true,
30543
- title: t("webhookEditor.webhookHeaders"),
30544
- disabled,
30545
- canSort: false,
30546
- sorting: false,
30547
- onToggleSorting: () => {},
30548
- addLabel: t("webhookEditor.webhookAddHeader"),
30549
- onAdd: addHeader
30550
- }), Object.keys(headers).length === 0 ? /* @__PURE__ */ jsx("p", {
30551
- className: "m-0 pl-4 text-xs text-muted-foreground",
30552
- children: t("webhookEditor.webhookNoHeaders")
30553
- }) : /* @__PURE__ */ jsxs("div", {
30554
- className: "flex flex-col gap-2",
30555
- children: [/* @__PURE__ */ jsxs("div", {
30556
- className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_28px] gap-2 text-xs text-muted-foreground",
30557
- children: [
30558
- /* @__PURE__ */ jsx("span", { children: t("webhookEditor.webhookHeaderName") }),
30559
- /* @__PURE__ */ jsx("span", { children: t("webhookEditor.webhookHeaderValue") }),
30560
- /* @__PURE__ */ jsx("span", {})
30561
- ]
30562
- }), Object.entries(headers).map(([name, value]) => /* @__PURE__ */ jsxs("div", {
30563
- className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_28px] items-start gap-2 [&_[data-slot=field-label]]:sr-only",
30564
- children: [
30565
- /* @__PURE__ */ jsx(DraftTextField, {
30566
- label: t("webhookEditor.webhookHeaderName"),
30567
- value: name,
30568
- disabled,
30569
- inspect: (draft, signal) => validHeaderName(draft, name, headers, {
30570
- invalid: t("webhookEditor.webhookHeaderNameInvalid"),
30571
- duplicate: t("webhookEditor.webhookHeaderNameDuplicate")
30572
- }, signal),
30573
- onSave: (nextName) => {
30574
- if (nextName === name) return;
30575
- changeHeaders(Object.fromEntries(Object.entries(headers).map(([key, content]) => [key === name ? nextName : key, content])));
30576
- }
30577
- }),
30578
- /* @__PURE__ */ jsx(DraftTextField, {
30579
- label: t("webhookEditor.webhookHeaderValue"),
30580
- value,
30581
- disabled,
30582
- onSave: (text) => changeHeaders({
30583
- ...headers,
30584
- [name]: text
30585
- })
30586
- }),
30587
- !disabled && /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
30588
- render: /* @__PURE__ */ jsx(Button$1, {
30589
- type: "button",
30590
- size: "icon-sm",
30591
- variant: "ghost",
30592
- "aria-label": t("webhookEditor.webhookDeleteHeader"),
30593
- onClick: () => changeHeaders(Object.fromEntries(Object.entries(headers).filter(([key]) => key !== name)), {
30594
- target: "objectItem",
30595
- name
30596
- })
30597
- }),
30598
- children: /* @__PURE__ */ jsx("i", {
30599
- "aria-hidden": "true",
30600
- className: "i-lucide-light:trash-2 text-base"
30601
- })
30602
- }), /* @__PURE__ */ jsx(TooltipContent, { children: t("webhookEditor.webhookDeleteHeader") })] })
30603
- ]
30604
- }, name))]
30605
- })] })
30606
- ] })
31202
+ children: /* @__PURE__ */ jsx(FieldGroup, { children: /* @__PURE__ */ jsx(DraftTextField, {
31203
+ label: t("webhookEditor.webhookOrigins"),
31204
+ value: options.allowedOrigins?.join(", ") ?? "",
31205
+ disabled,
31206
+ description: t("webhookEditor.webhookOriginsHint"),
31207
+ placeholder: "https://example.com, *",
31208
+ inspect: (draft, signal) => validOriginList(draft, t("webhookEditor.webhookOriginsInvalid"), signal),
31209
+ onSave: (text) => changeOption("allowedOrigins", text === "" ? void 0 : text.split(", "))
31210
+ }) })
30607
31211
  })]
30608
31212
  })
30609
31213
  ] });
30610
31214
  }
30611
31215
  //#endregion
31216
+ //#region src/workbench/browser/runtime/editor/webhookResponseEditor.tsx
31217
+ var headerSchema = {
31218
+ type: "object",
31219
+ additionalProperties: { type: "string" }
31220
+ };
31221
+ var expanded = () => true;
31222
+ /** Fixed response inputs compose the ordinary source editor and object field layout. */
31223
+ function WebhookResponseEditor({ entries, disabled, readOnly, variables, renderSource, onValue, onVariable }) {
31224
+ const t = useTranslate();
31225
+ const labels = {
31226
+ body: t("webhookEditor.webhookResponseContent"),
31227
+ statusCode: t("webhookEditor.webhookStatus"),
31228
+ headers: t("webhookEditor.webhookHeaders")
31229
+ };
31230
+ return /* @__PURE__ */ jsx(InspectorSection, {
31231
+ title: t("webhookEditor.webhookResponse"),
31232
+ className: "inspector-form",
31233
+ "data-inspector-section": "inputs",
31234
+ children: /* @__PURE__ */ jsx(FieldGroup, { children: entries.map((entry) => {
31235
+ const { definition, value } = entry;
31236
+ const label = labels[definition.handle] ?? definition.handle;
31237
+ const headers = definition.handle === "headers";
31238
+ const editor = /* @__PURE__ */ jsx(NodeInputValue, {
31239
+ ...entry,
31240
+ embedded: true,
31241
+ definition: headers ? {
31242
+ ...definition,
31243
+ jsonSchema: headerSchema
31244
+ } : definition,
31245
+ label,
31246
+ variables,
31247
+ disabled,
31248
+ readOnly,
31249
+ upstream: renderSource?.(definition.handle),
31250
+ onValue: (next) => onValue(definition.handle, next),
31251
+ onVariable: (next) => onVariable(definition.handle, next),
31252
+ presentation: headers ? {
31253
+ valueOnly: true,
31254
+ hideOptions: true,
31255
+ hideValueTools: true,
31256
+ hideChildTypes: true,
31257
+ expansionPolicy: expanded,
31258
+ validateObjectFieldName: (next, current) => webhookHeaderNameIssue(next, Object.keys(value != null && typeof value === "object" && !Array.isArray(value) ? value : {}).filter((key) => key !== current)) == null
31259
+ } : { hideOptions: true }
31260
+ });
31261
+ return /* @__PURE__ */ jsxs(Field, { children: [/* @__PURE__ */ jsx(FieldLabel, { children: label }), headers ? /* @__PURE__ */ jsx(FieldTable, {
31262
+ standalone: true,
31263
+ layout: "values",
31264
+ typeColumn: false,
31265
+ columnHeadings: false,
31266
+ actionSlots: 2,
31267
+ children: editor
31268
+ }) : editor] }, definition.handle);
31269
+ }) })
31270
+ });
31271
+ }
31272
+ //#endregion
30612
31273
  //#region src/workbench/browser/runtime/linkContext.ts
30613
31274
  /** The host owns URLs for links within the deployment. */
30614
31275
  var WorkbenchLinkContext = createContext(void 0);
@@ -30904,6 +31565,7 @@ function inspectorIcon(node) {
30904
31565
  if (node?.kind == "value") return "value";
30905
31566
  if (node?.kind == "approval") return "check";
30906
31567
  if (node?.kind == "wait") return "wait";
31568
+ if (node?.kind === "webhook-response") return "response";
30907
31569
  if (node?.kind == "outputs") return "outputs";
30908
31570
  if (node?.kind == "task" && node.definition != null && "executor" in node.definition) {
30909
31571
  if (node.definition.executor.kind == "decision") return "decision";
@@ -30915,6 +31577,7 @@ function inspectorIcon(node) {
30915
31577
  }
30916
31578
  function nodePurposePlaceholder(selection, t, action, displays) {
30917
31579
  switch (selection.kind) {
31580
+ case "webhook-response": return t("addNode.webhookResponseDescription");
30918
31581
  case "condition": return t("addNode.conditionDescription");
30919
31582
  case "outputs": return t("addNode.outputsDescription");
30920
31583
  case "value": return t("addNode.valueDescription");
@@ -30982,7 +31645,7 @@ function inputUpstreamSources({ revision, sourceNodeIcons, selection, store, han
30982
31645
  }
30983
31646
  };
30984
31647
  }
30985
- function NodeInspector({ webhookDeployment, variables = {
31648
+ function NodeInspector({ onAddWorkflowOutputs, onAddResponseNode, webhookDeployment, variables = {
30986
31649
  enabled: false,
30987
31650
  loaded: false,
30988
31651
  loading: false,
@@ -30995,6 +31658,14 @@ function NodeInspector({ webhookDeployment, variables = {
30995
31658
  const disabled = readOnly || temporarilyDisabled || store == null;
30996
31659
  const t = useTranslate();
30997
31660
  const content = useRef(null);
31661
+ const outputNodes = selection?.kind === "trigger" && selection.trigger.kind === "webhook" ? Object.entries(revision.graph().nodes).filter(([, node]) => node.kind === "outputs") : [];
31662
+ const outputNode = outputNodes.length === 1 ? outputNodes[0] : void 0;
31663
+ const responseReachable = selection?.kind === "trigger" && selection.trigger.kind === "webhook" ? executionReachableNodes(revision.graph(), selection.id) : void 0;
31664
+ const responseNodes = responseReachable == null ? [] : Object.entries(revision.graph().nodes).flatMap(([id, node]) => node.kind === "webhook-response" ? [{
31665
+ id,
31666
+ name: node.name ?? t("addNode.webhookResponse"),
31667
+ reachable: responseReachable.has(id)
31668
+ }] : []);
30998
31669
  const providerTrigger = selection?.kind === "trigger" && (selection.trigger.kind === "integration" || selection.trigger.kind === "poll") ? selection.trigger : void 0;
30999
31670
  const providerDisplay = providerTrigger == null ? void 0 : triggerDisplays?.[providerTrigger.definition.key];
31000
31671
  const providerConfigInputs = providerTrigger == null ? [] : presentProviderTriggerConfig(providerTrigger.definition.configInputs, providerDisplay, { "Advanced settings": t("valueEditor.advancedSettings") });
@@ -31198,11 +31869,53 @@ function NodeInspector({ webhookDeployment, variables = {
31198
31869
  trigger: selection.trigger,
31199
31870
  display: selection.trigger.kind == "integration" || selection.trigger.kind == "poll" ? triggerDisplays?.[selection.trigger.definition.key] : void 0
31200
31871
  }),
31872
+ selection?.kind === "webhook-response" && /* @__PURE__ */ jsx(WebhookResponseEditor, {
31873
+ entries: webhookResponseInputs.map((definition) => {
31874
+ const mapping = selection.node.inputs[definition.handle];
31875
+ const source = mapping?.kind === "sources" ? mapping.sources.find((item) => item.kind === "binding") : void 0;
31876
+ const binding = source?.kind === "binding" ? revision.binding(source.bindingId) : void 0;
31877
+ return {
31878
+ definition,
31879
+ value: inputValue(mapping, definition.value),
31880
+ connected: mapping?.kind === "sources" && binding == null,
31881
+ variableName: binding?.target,
31882
+ onReset: mapping == null ? void 0 : () => {
31883
+ store?.nodes.resetInputs(selection.id, [definition.handle]);
31884
+ }
31885
+ };
31886
+ }),
31887
+ disabled,
31888
+ readOnly,
31889
+ variables,
31890
+ renderSource: (handle) => inputUpstreamSources({
31891
+ revision,
31892
+ sourceNodeIcons,
31893
+ selection,
31894
+ store,
31895
+ handleName: handle,
31896
+ t,
31897
+ triggerDisplays
31898
+ }),
31899
+ onValue: (handle, value) => {
31900
+ store?.nodes.setInputValue(selection.id, handle, value);
31901
+ },
31902
+ onVariable: (handle, name) => {
31903
+ store?.nodes.setInputVariable(selection.id, handle, name);
31904
+ }
31905
+ }),
31201
31906
  selection?.kind === "trigger" && selection.trigger.kind === "webhook" && /* @__PURE__ */ jsx(WebhookEditor, {
31202
31907
  readOnly,
31203
31908
  bodyFields: selection.trigger.bodyFields,
31204
31909
  method: selection.trigger.method,
31205
31910
  options: selection.trigger.options ?? {},
31911
+ workflowOutputs: outputNode?.[1].kind === "outputs" ? {
31912
+ ...outputNode[1],
31913
+ icon: sourceNodeIcons?.[outputNode[0]] ?? outputNode[1].icon
31914
+ } : void 0,
31915
+ responseDiagnostics: webhookResponseDiagnostics(revision.graph(), selection.id),
31916
+ onAddWorkflowOutputs: readOnly ? void 0 : onAddWorkflowOutputs,
31917
+ onAddResponseNode: readOnly ? void 0 : onAddResponseNode,
31918
+ responseNodes,
31206
31919
  disabled,
31207
31920
  outputSection: /* @__PURE__ */ jsx(TriggerSummary, { trigger: selection.trigger }),
31208
31921
  onChange: (settings, deletion) => {
@@ -34102,6 +34815,7 @@ function WaitDecision({ waiting, onLocate, onResolve, resolvingActions }) {
34102
34815
  /* @__PURE__ */ jsx(AlertTitle, { children: waiting.prompt }),
34103
34816
  /* @__PURE__ */ jsxs(AlertDescription, { children: [
34104
34817
  /* @__PURE__ */ jsx("div", { children: t("run.waitExpires", { date: new Date(waiting.expiresAt).toLocaleString(language) }) }),
34818
+ waiting.autoContinueAt != null && /* @__PURE__ */ jsx("div", { children: t("run.waitAutoContinue", { date: new Date(waiting.autoContinueAt).toLocaleString(language) }) }),
34105
34819
  /* @__PURE__ */ jsxs(Field, {
34106
34820
  className: "mt-2",
34107
34821
  children: [
@@ -34275,7 +34989,7 @@ function eventTone(event) {
34275
34989
  function eventSummary(event, t) {
34276
34990
  switch (event.kind) {
34277
34991
  case "run.queued": return t("run.eventEnqueued");
34278
- case "run.resolved": return t("run.eventWaitResolved");
34992
+ case "run.resolved": return t(event.payload.source == "automatic" ? "run.eventWaitAutomatic" : event.payload.source == "manual" ? "run.eventWaitManual" : "run.eventWaitResolved");
34279
34993
  case "wait.created":
34280
34994
  case "run.waiting": return t("run.statusWaiting");
34281
34995
  case "run.started":
@@ -36290,7 +37004,7 @@ function RunDrawerContainer({ onOpenRuns, onClose, onConfigureConnector, open, s
36290
37004
  submitting: submitting != null
36291
37005
  });
36292
37006
  }
36293
- var NodeInspectorContainer = memo(function NodeInspectorContainer({ store, focus, disabled, revision, selection, theme }) {
37007
+ var NodeInspectorContainer = memo(function NodeInspectorContainer({ onAddWorkflowOutputs, store, focus, disabled, revision, selection, theme }) {
36294
37008
  const t = useTranslate();
36295
37009
  const language = useLang();
36296
37010
  const bindings = useVal(store.publications.$.bindings);
@@ -36352,6 +37066,10 @@ var NodeInspectorContainer = memo(function NodeInspectorContainer({ store, focus
36352
37066
  store.triggers.catalog.get();
36353
37067
  }, [language, store]);
36354
37068
  return /* @__PURE__ */ jsx(NodeInspector, {
37069
+ onAddWorkflowOutputs,
37070
+ onAddResponseNode: webhookId == null ? void 0 : () => {
37071
+ store.workspace.addWebhookResponseNode(webhookId);
37072
+ },
36355
37073
  webhookDeployment: webhookId == null ? void 0 : {
36356
37074
  binding: bindings.bindings.find((binding) => binding.flowId == flowId && binding.triggerNodeId == webhookId && binding.kind == "webhook"),
36357
37075
  status: bindings.flowId === flowId ? bindings.status : "idle",
@@ -36765,6 +37483,10 @@ function FlowEditor({ navigationIsland, onRun, onRunStarted, onCloseRuns, onConf
36765
37483
  dark: theme == "dark",
36766
37484
  onSave: (comment) => void store.workspace.saveComment(selectedDesignerNode.id, comment)
36767
37485
  }, selectedDesignerNode.id) : revision != null && /* @__PURE__ */ jsx(NodeInspectorContainer, {
37486
+ onAddWorkflowOutputs: () => {
37487
+ const option = store.workspace.$.addNodeOptions.value.find((item) => item.kind === "outputs");
37488
+ if (option != null) addFromPicker(option);
37489
+ },
36768
37490
  store,
36769
37491
  focus: diagnosticFocus,
36770
37492
  disabled: authoringDisabled,