@oomol-lab/open-flow 0.1.0-beta.64 → 0.1.0-beta.66

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 (50) hide show
  1. package/dist/browser/{createResourceDialog-BAJXbzNH.js → createResourceDialog-C-Si_cYs.js} +2 -2
  2. package/dist/browser/flow-authoring-node.d.ts +12 -3
  3. package/dist/browser/flow-authoring.js +135 -21
  4. package/dist/browser/flow-change-schema.d.ts +3 -1
  5. package/dist/browser/flow-change.d.ts +15 -3
  6. package/dist/browser/flow-change.js +111 -16
  7. package/dist/browser/{flowChanges-BAMkSaKF.js → flowChanges-T4_R5p1f.js} +3031 -2124
  8. package/dist/browser/{flowRunInputEditorStore-B2Rw4VsT.js → flowRunInputEditorStore-DJqmR6Qh.js} +3 -2
  9. package/dist/browser/{flowWorkspace-DxLc1Ybv.js → flowWorkspace-C0J5C0oM.js} +754 -163
  10. package/dist/browser/{icons-Db2Jb2iX.js → icons-BD3m0RQq.js} +4484 -4370
  11. package/dist/browser/preview.css +160 -64
  12. package/dist/browser/preview.js +6487 -5232
  13. package/dist/browser/ui.css +93 -3
  14. package/dist/browser/ui.js +8 -5
  15. package/dist/browser/workbench.css +160 -64
  16. package/dist/browser/workbench.js +175 -59
  17. package/dist/browser/{workbenchSelect-C-jf6NIM.js → workbenchSelect-B-PFpF_Q.js} +1 -1
  18. package/dist/command/index.js +49 -49
  19. package/dist/common/authoring.d.ts +7 -5
  20. package/dist/common/authoringExamples.d.ts +3 -3
  21. package/dist/common/authoringFields.d.ts +20 -0
  22. package/dist/common/authoringSchema.d.ts +404 -15
  23. package/dist/common/connectorDecoders.d.ts +2 -1
  24. package/dist/common/control-api-conformance.js +403 -137
  25. package/dist/common/control-api.d.ts +70 -7
  26. package/dist/common/control-api.js +3587 -3428
  27. package/dist/common/control-requests.d.ts +10 -3
  28. package/dist/common/control-requests.js +463 -48
  29. package/dist/common/decision.js +28 -3
  30. package/dist/common/flow-encoding.d.ts +4 -2
  31. package/dist/common/flow-encoding.js +144 -10
  32. package/dist/common/flow-graph.d.ts +1 -1
  33. package/dist/common/flow-semantics.d.ts +12 -2
  34. package/dist/common/flow-semantics.js +152 -33
  35. package/dist/common/integration-trigger.js +28 -3
  36. package/dist/common/liveDetails.d.ts +26 -11
  37. package/dist/common/mcp.d.ts +6 -3
  38. package/dist/common/mcp.js +3541 -3403
  39. package/dist/common/openapi.js +28 -3
  40. package/dist/common/poll-trigger.js +28 -3
  41. package/dist/common/run-events.d.ts +2 -0
  42. package/dist/common/run-events.js +9 -3
  43. package/dist/common/scheduler.d.ts +11 -1
  44. package/dist/common/scheduler.js +216 -48
  45. package/dist/common/trigger-contract.d.ts +2 -0
  46. package/dist/common/webhook-trigger.js +28 -3
  47. package/dist/common/workflow.d.ts +93 -0
  48. package/dist/common/workflow.js +10491 -0
  49. package/package.json +5 -1
  50. package/skills/open-flow/references/flow-authoring.md +26 -16
@@ -1,7 +1,7 @@
1
- import { $n as isJsonObject, $t as EmptyTitle, An as createI18n, At as updateTriggerSchedule, B as CacheResource, Cr as controlErrorCode, Ct as repairNodeNames, Dn as EventSourcesPage, Dt as setInputSources, En as Badge, Er as IconThemeContext, Et as setConnectorConnection, F as feishuResourceKind, Ft as PopoverContent, G as designerGraph, Gn as randomId, Gt as InputGroup, H as resourceData, I as supportsFeishuChatFilter, Jn as decodeTriggerCatalog, Jt as Empty, Kn as allConnectorConnectionsQuery, Kt as InputGroupAddon, L as combineSources, M as addNodeIntent, Mt as IdTooltip, N as deriveAddNodeOptions, Nt as followWorkbenchLink, Ot as setTriggerConnection, Pt as Popover, Qn as triggerOutputDefinitions, Qt as EmptyMedia, Sr as ApiError, St as setNodePositions, Tt as setCodeActions, U as resourceValue, Un as errorNotice, W as connectorActionPorts, Wn as WorkbenchClient, Xt as EmptyDescription, Y as providerIcon, Yt as EmptyContent, Zn as sampleErrorOutputs, Zt as EmptyHeader, _ as updateValue, _r as inputValue, _t as removeComments, a as nameCreatedNodes, ar as workflowNameFromFile, at as flowResourceReferences, br as record, bt as setFlowViewport, c as updateCondition, cn as DropdownMenuSeparator, cr as providerIconAppearance, ct as diagnosticItems, d as updateNodeName, en as DropdownMenu, er as connection, f as updateNodeSettings, fn as DropdownMenuTrigger, ft as actionWithConnections, g as updateTaskPorts, gt as flowPresentation, h as updateTaskAdditionalInputs, ht as commentIds, i as deleteSelection, in as DropdownMenuItem, ir as workflowFileName, it as revisionView, jt as WorkflowExportMenuItem, kt as updateTriggerConfig, l as updateNodeDescription, m as updateTask, mt as canvasPresentationChange, nn as DropdownMenuContent, nr as encodeWorkflowFile, o as setInputValue, ot as Latest, p as updateResolution, pt as connectionCatalog, qt as InputGroupInput, r as applyFlowChanges, rr as parseWorkflowFile, s as setInputVariable, st as deriveInspectorDiagnostics, t as addNode, tr as connectorActionMetadata, tt as RunStore, u as updateNodeIcon, v as updateWebhook, vr as invalidResponse, vt as restoreCanvasPresentation, wt as resetInputValues, xr as string, xt as setNodeContentHidden, yr as jsonValue, yt as setComment, z as scopedValue, zt as PopoverTitle } from "./flowChanges-BAMkSaKF.js";
1
+ import { $n as normalizeTriggerOutputs, $t as EmptyHeader, At as updateStartInputDefs, B as scopedValue, Cr as inputValue, Ct as setNodePositions, Dr as string, Dt as setConnectorConnection, Er as record, Et as setCodeActions, Ft as followWorkbenchLink, G as connectorActionPorts, Gn as errorNotice, I as feishuResourceKind, It as Popover, Jn as allConnectorConnectionsQuery, Jt as InputGroupAddon, K as designerGraph, Kn as WorkbenchClient, L as supportsFeishuChatFilter, Lt as PopoverContent, Mn as createI18n, Mr as IconThemeContext, Mt as updateTriggerSchedule, N as addNodeIntent, Nt as WorkflowExportMenuItem, On as Badge, Or as ApiError, Ot as setInputSources, P as deriveAddNodeOptions, Pt as IdTooltip, Qt as EmptyDescription, R as combineSources, St as setNodeContentHidden, Tr as jsonValue, Tt as resetInputValues, U as resourceData, V as CacheResource, Vt as PopoverTitle, W as resourceValue, X as providerIcon, Xn as decodeTriggerCatalog, Xt as Empty, Yt as InputGroupInput, Zt as EmptyContent, _ as updateTaskPorts, _t as flowPresentation, a as nameCreatedNodes, ar as encodeWorkflowFile, at as revisionView, br as workflowCandidate, bt as setComment, c as updateCondition, cr as workflowNameFromFile, ct as deriveInspectorDiagnostics, d as updateNodeName, dr as providerIconAppearance, en as EmptyMedia, er as sampleErrorOutputs, f as updateNodeSettings, g as updateTaskAdditionalInputs, gt as commentIds, h as updateTask, ht as canvasPresentationChange, i as deleteSelection, in as DropdownMenuContent, ir as connectorActionMetadata, jt as updateTriggerConfig, kn as EventSourcesPage, kr as controlErrorCode, kt as setTriggerConnection, l as updateNodeDescription, lt as diagnosticItems, m as updateResolution, mn as DropdownMenuTrigger, mt as connectionCatalog, nn as DropdownMenu, nr as isJsonObject, nt as RunStore, o as setInputValue, on as DropdownMenuItem, or as parseWorkflowFile, ot as flowResourceReferences, p as updateOutputPorts, pt as actionWithConnections, qn as randomId, qt as InputGroup, r as applyFlowChanges, rr as connection, s as setInputVariable, sr as workflowFileName, st as Latest, t as addNode, tn as EmptyTitle, tr as triggerOutputDefinitions, u as updateNodeIcon, un as DropdownMenuSeparator, v as updateValue, vt as removeComments, wr as invalidResponse, wt as repairNodeNames, xt as setFlowViewport, y as updateWebhook, yt as restoreCanvasPresentation } from "./flowChanges-T4_R5p1f.js";
2
2
  import { a as derive, i as compute, l as val } from "./dist-bO8nvHFH.js";
3
3
  import { c as useLang, l as useTranslate, o as I18nProvider, u as useVal } from "./dist-BFmpkX4P.js";
4
- import { B as FlowChangeError, Ci as cn, E as FieldLabel, Q as nodeInputMappings, S as Field, T as FieldGroup, V as applyFlowChanges$1, Z as mapConditionSources, a as DialogDescription, at as dequal$1, c as DialogTitle, d as TooltipContent, i as DialogContent, lr as Input, n as Dialog, o as DialogFooter, p as TooltipTrigger, q as resourceNameIssue, r as DialogClose, s as DialogHeader, t as Icon, u as Tooltip, w as FieldError, x as Spinner, xi as Button } from "./icons-Db2Jb2iX.js";
4
+ import { B as upgradeManualTrigger, E as FieldLabel, Ei as cn, G as mapConditionSources, K as nodeInputMappings, M as applyFlowChanges$1, P as isTriggerNode, S as Field, T as FieldGroup, Tt as dequal$1, V as upgradeRevisionContent, a as DialogDescription, c as DialogTitle, d as TooltipContent, fr as Input, i as DialogContent, j as FlowChangeError, n as Dialog, o as DialogFooter, p as TooltipTrigger, r as DialogClose, s as DialogHeader, t as Icon, u as Tooltip, w as FieldError, wi as Button, x as Spinner, z as resourceNameIssue } from "./icons-BD3m0RQq.js";
5
5
  import { c as importedWorkflowName, d as uiLanguageNames, f as uiLanguages, l as isUiLanguage, u as resolveUiLanguage } from "./value-BADHeZ9I.js";
6
6
  import { Suspense, forwardRef, lazy, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -190,7 +190,7 @@ function Skeleton({ className, ...props }) {
190
190
  }
191
191
  //#endregion
192
192
  //#region src/workbench/browser/runtime/shell/resourceBrowser.tsx
193
- var CreateResourceDialog = lazy(() => import("./createResourceDialog-BAJXbzNH.js"));
193
+ var CreateResourceDialog = lazy(() => import("./createResourceDialog-C-Si_cYs.js"));
194
194
  var flowIdTooltipAlignOffset = 44;
195
195
  var renamePopoverAlignOffset = -12;
196
196
  function compactFlowId(flowId) {
@@ -998,11 +998,30 @@ var customAlphabet = (alphabet, size = 21) => customRandom(alphabet, size | 0, r
998
998
  //#endregion
999
999
  //#region src/flow/common/edgeChanges.ts
1000
1000
  function connect(content, edge) {
1001
- if (content.document.graph?.edges.some((candidate) => dequal$1(candidate, edge))) return [];
1002
- return [{
1001
+ const selected = content.document.graph;
1002
+ if (selected?.edges.some((candidate) => dequal$1(candidate, edge))) return [];
1003
+ const changes = [{
1003
1004
  edge,
1004
1005
  kind: "graph.edge.connect"
1005
1006
  }];
1007
+ const source = selected.nodes[edge.source];
1008
+ const target = selected.nodes[edge.target];
1009
+ if (edge.sourceHandle == "pending" && (source?.kind == "approval" || source?.kind == "wait") && target?.kind == "task" && "executor" in target.task && target.task.executor.kind == "connector" && target.task.executor.action == "leina.send_notification" && (target.inputs.message == null || target.inputs.message.kind == "unset")) changes.push({
1010
+ kind: "graph.node.input.set",
1011
+ nodeId: edge.target,
1012
+ handle: "message",
1013
+ before: target.inputs.message,
1014
+ value: {
1015
+ kind: "sources",
1016
+ sources: [{
1017
+ kind: "node",
1018
+ nodeId: edge.source,
1019
+ output: "pending",
1020
+ field: "message"
1021
+ }]
1022
+ }
1023
+ });
1024
+ return changes;
1006
1025
  }
1007
1026
  function disconnect(content, edge) {
1008
1027
  if (!content.document.graph?.edges.some((candidate) => dequal$1(candidate, edge))) return [];
@@ -1612,26 +1631,30 @@ var PublicationStore = class {
1612
1631
  var initialState$5 = { starting: false };
1613
1632
  function inputSpec(draft, triggerId) {
1614
1633
  const trigger = revisionView(draft).graph()?.nodes[triggerId];
1615
- if (trigger == null || "inputs" in trigger || trigger.kind == "manual" || trigger.kind == "cron") return void 0;
1634
+ if (trigger == null || !isTriggerNode(trigger) || trigger.kind == "manual" || trigger.kind == "cron") return void 0;
1616
1635
  const definitions = triggerOutputDefinitions(trigger);
1617
1636
  return definitions.length === 0 ? void 0 : {
1618
1637
  definitions,
1638
+ allowOmittedNullable: trigger.kind == "start",
1619
1639
  samples: trigger.kind == "error" ? sampleErrorOutputs : void 0
1620
1640
  };
1621
1641
  }
1622
1642
  function inputSignature(spec) {
1623
- return JSON.stringify(spec?.definitions.map((definition) => [
1624
- definition.handle,
1625
- definition.jsonSchema,
1626
- definition.nullable
1627
- ]) ?? []);
1643
+ return JSON.stringify({
1644
+ allowOmittedNullable: spec?.allowOmittedNullable ?? false,
1645
+ definitions: spec?.definitions.map((definition) => [
1646
+ definition.handle,
1647
+ definition.jsonSchema,
1648
+ definition.nullable
1649
+ ]) ?? []
1650
+ });
1628
1651
  }
1629
1652
  async function inputEditor(spec, language, values) {
1630
1653
  if (spec == null) return void 0;
1631
- const { FlowRunInputEditorStore } = await import("./flowRunInputEditorStore-B2Rw4VsT.js").then((n) => n.t);
1632
- const editor = new FlowRunInputEditorStore(spec.definitions, language);
1654
+ const { FlowRunInputEditorStore } = await import("./flowRunInputEditorStore-DJqmR6Qh.js").then((n) => n.t);
1655
+ const editor = new FlowRunInputEditorStore(spec.definitions, language, { allowOmittedNullable: spec.allowOmittedNullable });
1633
1656
  const initial = values ?? spec.samples;
1634
- if (initial != null) editor.replaceValues(initial);
1657
+ if (initial != null) editor.replaceValues(Object.fromEntries(spec.definitions.flatMap(({ handle }) => Object.hasOwn(initial, handle) ? [[handle, initial[handle]]] : [])));
1635
1658
  return editor;
1636
1659
  }
1637
1660
  function testOutputs(revision, triggerId) {
@@ -1683,7 +1706,7 @@ var RunRequestStore = class {
1683
1706
  async requestDraft(flow, draft, triggerId) {
1684
1707
  const current = this.#requests.begin();
1685
1708
  try {
1686
- return await this.#request("draft", flow, draft, draft.revisionId, current, void 0, triggerId);
1709
+ return await this.#request("draft", flow, draft, current, void 0, triggerId);
1687
1710
  } catch (error) {
1688
1711
  if (current()) this.#setNotice(errorNotice(error, this.#i18n.t));
1689
1712
  return "unavailable";
@@ -1694,7 +1717,7 @@ var RunRequestStore = class {
1694
1717
  async editDraft(flow, draft, triggerId) {
1695
1718
  const current = this.#requests.begin();
1696
1719
  try {
1697
- return await this.#request("draft", flow, draft, draft.revisionId, current, void 0, triggerId, true);
1720
+ return await this.#request("draft", flow, draft, current, void 0, triggerId, true);
1698
1721
  } catch (error) {
1699
1722
  if (current()) this.#setNotice(errorNotice(error, this.#i18n.t));
1700
1723
  return "unavailable";
@@ -1704,7 +1727,10 @@ var RunRequestStore = class {
1704
1727
  }
1705
1728
  inputStatus(flowId, draft, triggerId) {
1706
1729
  const spec = inputSpec(draft, triggerId);
1707
- if (spec == null) return "none";
1730
+ if (spec == null) {
1731
+ const request = this.#state.value.inputRequest;
1732
+ return request?.flow.flowId == flowId && request.triggerId == triggerId ? "ready" : "none";
1733
+ }
1708
1734
  const saved = this.#savedInputs.get(this.#inputKey(flowId, triggerId));
1709
1735
  return saved?.valid == true && saved.signature == inputSignature(spec) ? "ready" : "missing";
1710
1736
  }
@@ -1716,7 +1742,7 @@ var RunRequestStore = class {
1716
1742
  if (publication == null) return "unavailable";
1717
1743
  const revision = await this.#client.getRevision(flow.flowId, publication.revisionId);
1718
1744
  if (!current()) return "unavailable";
1719
- return await this.#request("live", flow, revision, publication.revisionId, current, publication.publicationId);
1745
+ return await this.#request("live", flow, revision, current, publication.publicationId);
1720
1746
  } catch (error) {
1721
1747
  if (current()) this.#setNotice(errorNotice(error, this.#i18n.t));
1722
1748
  return "unavailable";
@@ -1733,7 +1759,7 @@ var RunRequestStore = class {
1733
1759
  async confirmInputs() {
1734
1760
  const request = this.#state.value.inputRequest;
1735
1761
  if (request == null || request.triggerId == null) return false;
1736
- if (!request.valid.value) {
1762
+ if (request.source == "live" && !request.valid.value) {
1737
1763
  this.#set({ inputRequest: {
1738
1764
  ...request,
1739
1765
  attempted: true
@@ -1742,10 +1768,10 @@ var RunRequestStore = class {
1742
1768
  }
1743
1769
  this.#rememberInputs(request);
1744
1770
  const outputs = request.editor?.values() ?? testOutputs(request.revision, request.triggerId);
1745
- const started = await this.#start(request.source, request.flow, request.revisionId, {
1771
+ const started = await this.#start(request.source, request.flow, request.revision, {
1746
1772
  nodeId: request.triggerId,
1747
1773
  outputs
1748
- }, request.publicationId);
1774
+ }, request.publicationId, request);
1749
1775
  if (started && this.#state.value.inputRequest === request) this.dismissInputs();
1750
1776
  return started;
1751
1777
  }
@@ -1778,7 +1804,7 @@ var RunRequestStore = class {
1778
1804
  if (current()) this.#set({ starting: false });
1779
1805
  }
1780
1806
  }
1781
- async #request(source, flow, revision, revisionId, current, publicationId, triggerId, edit = false) {
1807
+ async #request(source, flow, revision, current, publicationId, triggerId, edit = false) {
1782
1808
  const previous = this.#state.value.inputRequest;
1783
1809
  this.#rememberInputs(previous);
1784
1810
  this.#set({
@@ -1788,7 +1814,7 @@ var RunRequestStore = class {
1788
1814
  });
1789
1815
  this.#disposeInputRequest(previous);
1790
1816
  const graph = revisionView(revision).graph();
1791
- const triggers = Object.entries(graph?.nodes ?? {}).flatMap(([nodeId, node]) => "inputs" in node ? [] : [{
1817
+ const triggers = Object.entries(graph?.nodes ?? {}).flatMap(([nodeId, node]) => !isTriggerNode(node) ? [] : [{
1792
1818
  nodeId,
1793
1819
  title: node.name
1794
1820
  }]);
@@ -1800,7 +1826,7 @@ var RunRequestStore = class {
1800
1826
  });
1801
1827
  return "unavailable";
1802
1828
  }
1803
- const only = triggerId == null ? triggers[0] : triggers.find((trigger) => trigger.nodeId == triggerId);
1829
+ const only = triggerId == null ? triggers.find((trigger) => graph?.nodes[trigger.nodeId]?.kind == "start") ?? triggers[0] : triggers.find((trigger) => trigger.nodeId == triggerId);
1804
1830
  if (triggerId != null && only == null) {
1805
1831
  this.#set({ starting: false });
1806
1832
  this.#setNotice({
@@ -1817,14 +1843,14 @@ var RunRequestStore = class {
1817
1843
  editor?.dispose();
1818
1844
  return "unavailable";
1819
1845
  }
1820
- if (!edit && only != null && editor == null) return await this.#start(source, flow, revisionId, {
1846
+ if (!edit && only != null && editor == null) return await this.#start(source, flow, revision, {
1821
1847
  nodeId: only.nodeId,
1822
1848
  outputs: testOutputs(revision, only.nodeId)
1823
1849
  }, publicationId) ? "started" : "unavailable";
1824
1850
  if (!edit && only != null && saved?.valid == true && saved.signature == signature && editor != null && editor.valid$.value) {
1825
1851
  const outputs = editor.values();
1826
1852
  editor?.dispose();
1827
- return await this.#start(source, flow, revisionId, {
1853
+ return await this.#start(source, flow, revision, {
1828
1854
  nodeId: only.nodeId,
1829
1855
  outputs
1830
1856
  }, publicationId) ? "started" : "unavailable";
@@ -1839,7 +1865,6 @@ var RunRequestStore = class {
1839
1865
  triggers,
1840
1866
  triggerId: only?.nodeId,
1841
1867
  ...publicationId == null ? {} : { publicationId },
1842
- revisionId,
1843
1868
  source,
1844
1869
  valid
1845
1870
  },
@@ -1848,23 +1873,46 @@ var RunRequestStore = class {
1848
1873
  });
1849
1874
  return "input";
1850
1875
  }
1851
- async #start(source, flow, revisionId, trigger, publicationId) {
1876
+ async #start(source, flow, revision, trigger, publicationId, request) {
1852
1877
  if (source == "live" && publicationId == null) return false;
1853
1878
  const alive = this.#lifetime.capture();
1854
- const current = this.#runs.prepareStart();
1879
+ const requestCurrent = this.#requests.begin();
1880
+ let current = this.#runs.captureSelection();
1855
1881
  this.#set({
1856
1882
  starting: true,
1857
1883
  submitting: source
1858
1884
  });
1859
1885
  try {
1860
- if (source == "draft") {
1861
- const savedRevision = await this.#prepareDraft(flow.flowId);
1862
- if (savedRevision == null || !alive() || !current()) return false;
1863
- revisionId = savedRevision;
1886
+ const prepared = source == "draft" ? await this.#prepareDraft(flow.flowId) : revision;
1887
+ if (prepared == null || !alive() || !current() || !requestCurrent()) return false;
1888
+ const node = revisionView(prepared).trigger(trigger.nodeId);
1889
+ if (node == null || node.kind !== revisionView(revision).trigger(trigger.nodeId)?.kind || inputSignature(inputSpec(prepared, trigger.nodeId)) !== inputSignature(inputSpec(revision, trigger.nodeId))) {
1890
+ await this.#request(source, flow, prepared, requestCurrent, publicationId, trigger.nodeId, true);
1891
+ return false;
1892
+ }
1893
+ if (request != null && !request.valid.value) {
1894
+ if (this.#state.value.inputRequest === request) this.#set({ inputRequest: {
1895
+ ...request,
1896
+ attempted: true
1897
+ } });
1898
+ return false;
1899
+ }
1900
+ const outputs = normalizeTriggerOutputs(node, request?.editor?.values() ?? trigger.outputs);
1901
+ if (outputs == null) {
1902
+ this.#setNotice({
1903
+ kind: "error",
1904
+ message: this.#i18n.t("runInput.invalid")
1905
+ });
1906
+ return false;
1864
1907
  }
1908
+ current = this.#runs.prepareStart();
1909
+ trigger = {
1910
+ nodeId: trigger.nodeId,
1911
+ outputs
1912
+ };
1865
1913
  const target = source == "draft" ? {
1866
1914
  flowId: flow.flowId,
1867
- revisionId
1915
+ revisionId: prepared.revisionId
1868
1916
  } : { publicationId };
1869
1917
  const signature = JSON.stringify({
1870
1918
  trigger,
@@ -1876,7 +1924,7 @@ var RunRequestStore = class {
1876
1924
  signature
1877
1925
  };
1878
1926
  this.#attempt = attempt;
1879
- const run = source == "draft" ? await this.#client.createDraftRun(flow.flowId, revisionId, {
1927
+ const run = source == "draft" ? await this.#client.createDraftRun(flow.flowId, prepared.revisionId, {
1880
1928
  idempotencyKey: attempt.key,
1881
1929
  inputs: {},
1882
1930
  trigger
@@ -1885,14 +1933,14 @@ var RunRequestStore = class {
1885
1933
  inputs: {},
1886
1934
  trigger
1887
1935
  });
1888
- if (!alive() || !current()) return false;
1936
+ if (!alive() || !current() || !requestCurrent()) return false;
1889
1937
  this.#attempt = void 0;
1890
1938
  return this.#runs.follow(run, current);
1891
1939
  } catch (error) {
1892
- if (alive() && current()) this.#setNotice(errorNotice(error, this.#i18n.t));
1940
+ if (alive() && current() && requestCurrent()) this.#setNotice(errorNotice(error, this.#i18n.t));
1893
1941
  return false;
1894
1942
  } finally {
1895
- if (alive()) this.#set({
1943
+ if (alive() && requestCurrent()) this.#set({
1896
1944
  starting: false,
1897
1945
  submitting: void 0
1898
1946
  });
@@ -3367,6 +3415,11 @@ function ports(values) {
3367
3415
  }));
3368
3416
  }
3369
3417
  function option$1(action, t) {
3418
+ if (action.actionId == "leina.send_notification") action = {
3419
+ ...action,
3420
+ name: t("leina.notification"),
3421
+ description: t("leina.description")
3422
+ };
3370
3423
  return {
3371
3424
  connector: action,
3372
3425
  description: action.authenticated && action.defaultConnection == null ? t("addNode.connectorNeedsConnection", {
@@ -3459,6 +3512,9 @@ function connectionDiagnostics(revision, actions, catalogs) {
3459
3512
  }
3460
3513
  var ConnectorStore = class {
3461
3514
  #client;
3515
+ listLeinaBots(flowId, signal) {
3516
+ return this.#client.listLeinaBots(flowId, signal);
3517
+ }
3462
3518
  #i18n;
3463
3519
  #language;
3464
3520
  #host;
@@ -4072,11 +4128,19 @@ var TriggerStore = class {
4072
4128
  };
4073
4129
  //#endregion
4074
4130
  //#region src/flow/common/inverseChanges.ts
4075
- /** Invert canvas authoring operations, including the reducer's cascading deletions. */
4131
+ /** Invert authoring operations and cascading deletions while retaining model upgrades. */
4076
4132
  function inverseFlowChanges(content, operations) {
4077
- let current = content;
4133
+ let current = upgradeRevisionContent(content);
4078
4134
  const groups = [];
4079
- for (const operation of operations) {
4135
+ for (const requested of operations) {
4136
+ const operation = requested.kind == "graph.node.create" ? {
4137
+ ...requested,
4138
+ node: upgradeManualTrigger(requested.node)
4139
+ } : requested.kind == "graph.node.replace" && requested.before.kind == "manual" && requested.node.kind == "manual" ? {
4140
+ ...requested,
4141
+ before: upgradeManualTrigger(requested.before),
4142
+ node: upgradeManualTrigger(requested.node)
4143
+ } : requested;
4080
4144
  const after = applyFlowChanges$1(current, [operation]);
4081
4145
  const restore = [];
4082
4146
  switch (operation.kind) {
@@ -4173,7 +4237,13 @@ function inverseFlowChanges(content, operations) {
4173
4237
  const afterGraph = after.document.graph;
4174
4238
  const beforeNode = beforeGraph.nodes[operation.nodeId];
4175
4239
  const afterNode = afterGraph.nodes[operation.nodeId];
4176
- if (beforeNode.kind === "condition" && afterNode.kind === "condition") restore.push({
4240
+ if (beforeNode.kind === "outputs") restore.push({
4241
+ kind: "graph.node.replace",
4242
+ nodeId: operation.nodeId,
4243
+ before: afterNode,
4244
+ node: beforeNode
4245
+ });
4246
+ else if (beforeNode.kind === "condition" && afterNode.kind === "condition") restore.push({
4177
4247
  kind: "graph.node.condition.set",
4178
4248
  nodeId: operation.nodeId,
4179
4249
  before: {
@@ -4305,7 +4375,7 @@ function copyNodes(revision, nodeIds) {
4305
4375
  return {
4306
4376
  edges: (revision.graph()?.edges ?? []).filter((edge) => copied[edge.source] != null && copied[edge.target] != null),
4307
4377
  bindings: Object.fromEntries(Object.values(copied).flatMap((node) => {
4308
- if (!("inputs" in node)) return [];
4378
+ if (!("inputs" in node) && node.kind != "outputs") return [];
4309
4379
  return Object.values(nodeInputMappings(node)).flatMap((mapping) => mapping.kind == "sources" ? mapping.sources.flatMap((source) => {
4310
4380
  if (source.kind != "binding") return [];
4311
4381
  const binding = revision.binding(source.bindingId);
@@ -4321,15 +4391,16 @@ function copyNodes(revision, nodeIds) {
4321
4391
  };
4322
4392
  }
4323
4393
  function pasteNodes(revision, clipboard, identity) {
4394
+ const hasOutputs = Object.values(revision.graph().nodes).some((node) => node.kind == "outputs");
4324
4395
  const hasErrorTrigger = Object.values(revision.graph()?.nodes ?? {}).some((node) => node.kind === "error");
4325
- const hasManualTrigger = Object.values(revision.graph()?.nodes ?? {}).some((node) => node.kind === "manual");
4326
- const entries = Object.entries(clipboard.nodes).filter(([, node]) => (node.kind !== "manual" || !hasManualTrigger) && (node.kind !== "error" || !hasErrorTrigger) && (node.kind != "task" || !("moduleId" in node.task) || clipboard.modules[node.task.moduleId] != null));
4396
+ const hasStartTrigger = Object.values(revision.graph()?.nodes ?? {}).some((node) => node.kind === "manual" || node.kind === "start");
4397
+ const entries = Object.entries(clipboard.nodes).filter(([, node]) => (node.kind !== "manual" && node.kind !== "start" || !hasStartTrigger) && (node.kind !== "outputs" || !hasOutputs) && (node.kind !== "error" || !hasErrorTrigger) && (node.kind != "task" || !("moduleId" in node.task) || clipboard.modules[node.task.moduleId] != null));
4327
4398
  const sourceIds = entries.map(([sourceId]) => sourceId);
4328
4399
  const ids = new Map(sourceIds.map((sourceId) => [sourceId, identity()]));
4329
4400
  const operations = [];
4330
4401
  const bindingIds = /* @__PURE__ */ new Map();
4331
4402
  for (const [, node] of entries) {
4332
- if (!("inputs" in node)) continue;
4403
+ if (!("inputs" in node) && node.kind != "outputs") continue;
4333
4404
  const inputs = Object.values(nodeInputMappings(node));
4334
4405
  for (const mapping of inputs) {
4335
4406
  if (mapping.kind != "sources") continue;
@@ -4349,7 +4420,7 @@ function pasteNodes(revision, clipboard, identity) {
4349
4420
  }
4350
4421
  for (const [sourceId, node] of entries) {
4351
4422
  const nodeId = ids.get(sourceId);
4352
- if (!("inputs" in node)) {
4423
+ if (!("inputs" in node) && node.kind != "outputs") {
4353
4424
  operations.push({
4354
4425
  kind: "graph.node.create",
4355
4426
  node,
@@ -4391,8 +4462,11 @@ function pasteNodes(revision, clipboard, identity) {
4391
4462
  }
4392
4463
  return inputs;
4393
4464
  };
4394
- const inputs = remapInputs(node.inputs);
4395
- let copy = {
4465
+ const inputs = remapInputs(nodeInputMappings(node));
4466
+ let copy = node.kind == "outputs" ? {
4467
+ ...node,
4468
+ outputMappings: inputs
4469
+ } : {
4396
4470
  ...node,
4397
4471
  inputs
4398
4472
  };
@@ -5464,7 +5538,18 @@ var WorkspaceStore = class {
5464
5538
  this.#stopFlowWatch = subscription.stop;
5465
5539
  await subscription.ready;
5466
5540
  if (!current()) return false;
5467
- const { flow, draft, live, presentation } = await this.#client.getEditor(flowId);
5541
+ let editor = await this.#client.getEditor(flowId);
5542
+ for (let attempt = 0; current() && Object.values(revisionView(editor.draft).graph().nodes).some((node) => node.kind == "manual"); attempt += 1) {
5543
+ if (attempt >= 3) throw new ApiError(409, controlErrorCode.flowRevisionConflict, "The Draft changed while upgrading its Start node.");
5544
+ try {
5545
+ await this.#client.upgradeDraft(flowId, editor.draft.revisionId, { idempotencyKey: this.#identity() });
5546
+ } catch (error) {
5547
+ if (!(error instanceof ApiError) || error.code !== controlErrorCode.flowRevisionConflict || attempt >= 2) throw error;
5548
+ }
5549
+ if (!current()) return false;
5550
+ editor = await this.#client.getEditor(flowId);
5551
+ }
5552
+ const { flow, draft, live, presentation } = editor;
5468
5553
  if (!current()) return false;
5469
5554
  this.#draftChanges.reset(draft);
5470
5555
  this.#presentationChanges.reset(presentation);
@@ -5474,10 +5559,11 @@ var WorkspaceStore = class {
5474
5559
  live,
5475
5560
  presentation,
5476
5561
  workspaceLoadFailed: false,
5477
- workspaceLoadProblem: void 0,
5478
- workspaceLoading: false
5562
+ workspaceLoadProblem: void 0
5479
5563
  });
5480
5564
  await this.#repairDraftNodeNames(current);
5565
+ if (!current()) return false;
5566
+ this.#set({ workspaceLoading: false });
5481
5567
  if (invalidated && pendingRevision != draft.revisionId) this.#refreshDraft(pendingRevision);
5482
5568
  } catch (error) {
5483
5569
  if (!current()) return false;
@@ -5821,6 +5907,17 @@ var WorkspaceStore = class {
5821
5907
  if (revision == null) return false;
5822
5908
  return await this.#editDraft(resetInputValues(revision.revision.content, nodeId, handles)) != null;
5823
5909
  }
5910
+ async saveOutputsDefs(nodeId, definitions, deletion, values) {
5911
+ const revision = this.$.revision.value;
5912
+ if (revision == null || revision.graph().nodes[nodeId]?.kind != "outputs") return false;
5913
+ return await this.#editDraft(updateOutputPorts(revision, nodeId, definitions, values), deletion) != null;
5914
+ }
5915
+ async saveStartInputDefs(nodeId, inputDefs, deletion) {
5916
+ const revision = this.$.revision.value;
5917
+ if (revision == null || revision.graph().nodes[nodeId]?.kind != "start") return false;
5918
+ const changes = updateStartInputDefs(revision.revision.content, nodeId, inputDefs);
5919
+ return await this.#editDraft(changes, deletion) != null;
5920
+ }
5824
5921
  async resetTriggerConfig(triggerId, names) {
5825
5922
  const revision = this.$.revision.value;
5826
5923
  if (revision == null) return false;
@@ -5881,6 +5978,25 @@ var WorkspaceStore = class {
5881
5978
  position
5882
5979
  }));
5883
5980
  }
5981
+ async listWorkflowTargets(signal) {
5982
+ const flowId = this.$.revision.value?.revision.flowId;
5983
+ if (flowId == null) return [];
5984
+ const candidates = [];
5985
+ let cursor;
5986
+ do {
5987
+ const page = await this.#client.listFlows({
5988
+ cursor,
5989
+ limit: 100,
5990
+ signal
5991
+ });
5992
+ candidates.push(...page.flows.filter((flow) => flow.flowId != flowId).map((flow) => workflowCandidate(flow)));
5993
+ cursor = page.nextCursor;
5994
+ } while (cursor != null);
5995
+ return candidates;
5996
+ }
5997
+ loadWorkflowContract(flowId, signal) {
5998
+ return this.#client.getWorkflowContract(flowId, signal);
5999
+ }
5884
6000
  loadOpenApiDocument(url, signal) {
5885
6001
  return this.#client.loadOpenApiDocument(url, signal);
5886
6002
  }
@@ -6108,7 +6224,7 @@ var WorkspaceStore = class {
6108
6224
  for (let attempt = 0; attempt < 2 && current(); attempt += 1) {
6109
6225
  const draft = this.#model.value.draft;
6110
6226
  if (draft == null) return;
6111
- const repairs = repairNodeNames(draft.content);
6227
+ const repairs = repairNodeNames(draft.content, { start: this.#i18n.t("addNode.start") });
6112
6228
  if (repairs.length == 0) {
6113
6229
  this.#checkDraft();
6114
6230
  return;
@@ -6462,8 +6578,8 @@ var WorkbenchStore = class {
6462
6578
  this.triggers = new TriggerStore(client, this.workspace, setNotice, host, i18n);
6463
6579
  this.publications = new PublicationStore(client, this.workspace, setNotice, preferences, identity, i18n);
6464
6580
  this.runRequests = new RunRequestStore(client, this.runs, setNotice, async (flowId) => {
6465
- if (flowId != this.workspace.$.flowId.value || !await this.workspace.saveModuleEditor() || this.#disposed || flowId != this.workspace.$.flowId.value) return;
6466
- return this.workspace.$.draft.value?.revisionId;
6581
+ if (flowId != this.workspace.$.flowId.value || !await this.workspace.saveDraft() || this.#disposed || flowId != this.workspace.$.flowId.value) return;
6582
+ return this.workspace.$.draft.value;
6467
6583
  }, i18n, identity);
6468
6584
  const diagnostics = compute((get) => {
6469
6585
  const check = get(this.workspace.$.diagnostics);
@@ -6638,14 +6754,14 @@ var WorkbenchStore = class {
6638
6754
  return await this.#openNewFlow(await this.workspace.importFlow(file, name, key, importer), "notice.flowImported");
6639
6755
  }
6640
6756
  async createFlow(name, create) {
6641
- return await this.#openNewFlow(await this.workspace.createFlow(name, create), "notice.created");
6757
+ return await this.#openNewFlow(await this.workspace.createFlow(name, create));
6642
6758
  }
6643
6759
  async #openNewFlow(created, notice) {
6644
6760
  if (this.#disposed || created == null) return false;
6645
6761
  await this.selectFlow(created.flowId);
6646
- if (!this.#disposed) this.#notice.set({
6762
+ if (!this.#disposed && notice != null) this.#notice.set({
6647
6763
  kind: "success",
6648
- message: this.#i18n.t(notice, { name: created.name })
6764
+ message: this.#i18n.t(notice)
6649
6765
  });
6650
6766
  return true;
6651
6767
  }
@@ -6825,7 +6941,7 @@ var WorkbenchStore = class {
6825
6941
  };
6826
6942
  //#endregion
6827
6943
  //#region src/workbench/browser/runtime/openFlowWorkbench.tsx
6828
- var FlowWorkspace = lazy(() => import("./flowWorkspace-DxLc1Ybv.js"));
6944
+ var FlowWorkspace = lazy(() => import("./flowWorkspace-C0J5C0oM.js"));
6829
6945
  function OpenFlowSessionGate({ action, description, error, onSubmit, onTokenChange, pending = false, title, token, tokenLabel }) {
6830
6946
  const hasToken = token != null && tokenLabel != null && onTokenChange != null;
6831
6947
  const tokenValue = token ?? "";
@@ -1,4 +1,4 @@
1
- import { At as SelectValue, Ci as cn, Ct as Select, Dt as SelectItem, Et as SelectGroup, Tt as SelectContent, kt as SelectTrigger } from "./icons-Db2Jb2iX.js";
1
+ import { At as SelectItem, Ei as cn, Et as Select, Mt as SelectTrigger, Nt as SelectValue, Ot as SelectContent, kt as SelectGroup } from "./icons-BD3m0RQq.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/workbench/browser/runtime/shell/workbenchSelect.tsx
4
4
  function WorkbenchSelect({ ariaLabel, className, disabled = false, id, onValueChange, options, portalRoot, size, value, variant }) {