@oomol-lab/open-flow 0.1.0-beta.65 → 0.1.0-beta.67

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 (54) hide show
  1. package/dist/browser/{createResourceDialog-BAJXbzNH.js → createResourceDialog-BQVD8Rqb.js} +2 -2
  2. package/dist/browser/{icons-Db2Jb2iX.js → dialog-CS2Vt2if.js} +5736 -5621
  3. package/dist/browser/event-sources.d.ts +4 -1
  4. package/dist/browser/flow-authoring-node.d.ts +14 -3
  5. package/dist/browser/flow-authoring.js +120 -24
  6. package/dist/browser/flow-change-schema.d.ts +3 -1
  7. package/dist/browser/flow-change.d.ts +15 -3
  8. package/dist/browser/flow-change.js +117 -21
  9. package/dist/browser/{flowChanges-DkvG5uDq.js → flowChanges-VB9Y4iy7.js} +3423 -2380
  10. package/dist/browser/{flowRunInputEditorStore-B2Rw4VsT.js → flowRunInputEditorStore-DJqmR6Qh.js} +3 -2
  11. package/dist/browser/{flowWorkspace-BEp-lxqF.js → flowWorkspace-C1hlTnZq.js} +1410 -799
  12. package/dist/browser/preview.css +273 -119
  13. package/dist/browser/preview.js +17118 -15810
  14. package/dist/browser/theme.css +1 -0
  15. package/dist/browser/ui.css +119 -7
  16. package/dist/browser/ui.js +8 -5
  17. package/dist/browser/workbench-contract.d.ts +1 -1
  18. package/dist/browser/workbench.css +282 -162
  19. package/dist/browser/workbench.d.ts +0 -1
  20. package/dist/browser/workbench.js +503 -173
  21. package/dist/browser/{workbenchSelect-C-jf6NIM.js → workbenchSelect-CpXhjUou.js} +1 -1
  22. package/dist/command/index.js +49 -49
  23. package/dist/common/authoring.d.ts +7 -5
  24. package/dist/common/authoringExamples.d.ts +4 -4
  25. package/dist/common/authoringFields.d.ts +20 -0
  26. package/dist/common/authoringSchema.d.ts +404 -15
  27. package/dist/common/control-api-conformance.js +415 -146
  28. package/dist/common/control-api.d.ts +67 -8
  29. package/dist/common/control-api.js +3587 -3443
  30. package/dist/common/control-requests.d.ts +10 -3
  31. package/dist/common/control-requests.js +425 -49
  32. package/dist/common/decision.js +33 -7
  33. package/dist/common/flow-encoding.d.ts +4 -2
  34. package/dist/common/flow-encoding.js +151 -14
  35. package/dist/common/flow-graph.d.ts +1 -1
  36. package/dist/common/flow-semantics.d.ts +12 -2
  37. package/dist/common/flow-semantics.js +157 -41
  38. package/dist/common/integration-trigger.js +33 -7
  39. package/dist/common/liveDetails.d.ts +26 -11
  40. package/dist/common/mcp.d.ts +6 -3
  41. package/dist/common/mcp.js +219 -90
  42. package/dist/common/openapi.js +33 -7
  43. package/dist/common/poll-trigger.js +33 -7
  44. package/dist/common/run-events.d.ts +2 -0
  45. package/dist/common/run-events.js +9 -3
  46. package/dist/common/scheduler.d.ts +10 -1
  47. package/dist/common/scheduler.js +172 -49
  48. package/dist/common/trigger-contract.d.ts +2 -0
  49. package/dist/common/webhook-trigger.js +33 -7
  50. package/dist/common/workflow.d.ts +93 -0
  51. package/dist/common/workflow.js +10492 -0
  52. package/package.json +5 -1
  53. package/skills/open-flow/SKILL.md +9 -0
  54. package/skills/open-flow/references/flow-authoring.md +28 -16
@@ -1,6 +1,9 @@
1
1
  import type { ControlClient, EventSource } from '../common/control-api.js';
2
2
  import type { UiLanguage } from '../common/localization.js';
3
+ import type { WorkbenchNotification } from './workbench-contract.js';
3
4
  interface Props {
5
+ /** Host notification channel for operation failures; use the same handler as WorkbenchHost.notify. */
6
+ readonly notify: (notification: WorkbenchNotification) => void;
4
7
  readonly client: Pick<ControlClient, 'listEventSources' | 'createEventSource' | 'updateEventSource' | 'deleteEventSource' | 'listEventSourceConnections' | 'createConnectorConnectionPage'>;
5
8
  readonly language: UiLanguage;
6
9
  readonly onSourcesChange?: (sources: readonly EventSource[]) => void;
@@ -10,7 +13,7 @@ interface Props {
10
13
  }[];
11
14
  }
12
15
  export declare function EventSourcesPage(props: Props): import("react").JSX.Element;
13
- export declare function SourceForm({ source, existingNames, fixedTeamId, onPendingChange, client, teams, onSaved, onCancel, }: Omit<Props, 'language'> & {
16
+ export declare function SourceForm({ source, existingNames, fixedTeamId, onPendingChange, client, teams, onSaved, onCancel, notify, }: Omit<Props, 'language'> & {
14
17
  readonly source?: EventSource;
15
18
  readonly existingNames?: readonly string[];
16
19
  readonly onPendingChange?: (pending: boolean) => void;
@@ -1,5 +1,5 @@
1
1
  import type { DecisionQuestion } from '../common/decision.js';
2
- import type { ChangeOperation, CodeModule, ConnectorCapability, GraphNode, InputMapping, InputValues, InputPort, JsonValue, PortDefinition, RevisionContent, TaskDefinition, TriggerKeySnapshot, TriggerNode, TriggerSchedule, WebhookOptions } from './flow-change.js';
2
+ import type { ChangeOperation, CodeModule, ConnectorCapability, Group, GraphNode, InputMapping, InputValues, InputPort, JsonValue, Port, PortDefinition, RevisionContent, TaskDefinition, TriggerKeySnapshot, TriggerNode, TriggerSchedule, WebhookOptions } from './flow-change.js';
3
3
  export declare const defaultCodeTaskPorts: Pick<Extract<TaskDefinition, {
4
4
  readonly moduleId: string;
5
5
  }>, 'inputs' | 'outputs' | 'capabilities'>;
@@ -14,13 +14,17 @@ export interface LlmTaskOptions {
14
14
  }
15
15
  export type LlmInputHandle = 'input' | 'messages' | 'model' | 'template';
16
16
  export declare function defaultNodeName(_content: RevisionContent, node: GraphNode): string;
17
- export declare function repairNodeNames(content: RevisionContent): readonly ChangeOperation[];
17
+ export declare function repairNodeNames(content: RevisionContent, defaults?: {
18
+ readonly start?: string;
19
+ }): readonly ChangeOperation[];
18
20
  interface TriggerSettingsBase {
19
21
  readonly description?: string;
20
22
  readonly name: string;
21
23
  }
22
24
  export type TriggerSettings = (TriggerSettingsBase & {
23
25
  readonly kind: 'manual';
26
+ }) | (TriggerSettingsBase & {
27
+ readonly kind: 'start';
24
28
  }) | (TriggerSettingsBase & {
25
29
  readonly kind: 'error';
26
30
  }) | (TriggerSettingsBase & {
@@ -69,7 +73,7 @@ export declare function createValue(nodeId: string, name: string, values?: reado
69
73
  export declare function createWait(nodeId: string, name: string): readonly ChangeOperation[];
70
74
  export declare function createApproval(nodeId: string, name: string): readonly ChangeOperation[];
71
75
  export declare function createBuiltinTrigger(nodeId: string, node: Extract<TriggerNode, {
72
- readonly kind: 'error' | 'cron' | 'manual' | 'webhook';
76
+ readonly kind: 'error' | 'cron' | 'manual' | 'start' | 'webhook';
73
77
  }>): readonly ChangeOperation[];
74
78
  export declare function createProviderTrigger(nodeId: string, definition: TriggerKeySnapshot, options: {
75
79
  readonly config: Readonly<Record<string, JsonValue>>;
@@ -89,6 +93,10 @@ export declare function setInputSources(content: RevisionContent, nodeId: string
89
93
  export declare function setInputVariable(content: RevisionContent, nodeId: string, handle: string, name: string, bindingId: string): readonly ChangeOperation[] | undefined;
90
94
  export declare function cleanVariableBindings(content: RevisionContent, operations: readonly ChangeOperation[]): readonly ChangeOperation[];
91
95
  export declare function setConnectorConnection(content: RevisionContent, nodeId: string, connectionId: string | undefined): readonly ChangeOperation[] | undefined;
96
+ /** Update one service’s unresolved or explicitly deferred references as one undoable edit. */
97
+ export declare function setServiceConnections(content: RevisionContent, providerId: string, connectionId: string | undefined, previousConnectionId?: ''): readonly ChangeOperation[];
98
+ /** Edit the workflow input contract and preserve references on a single-field rename. */
99
+ export declare function updateStartInputDefs(content: RevisionContent, nodeId: string, value: readonly Port[]): readonly ChangeOperation[];
92
100
  export declare function updateTrigger(content: RevisionContent, nodeId: string, settings: TriggerSettings): readonly ChangeOperation[] | undefined;
93
101
  export declare function updateTriggerConfig(content: RevisionContent, nodeId: string, name: string, value: JsonValue | undefined): readonly ChangeOperation[] | undefined;
94
102
  export declare function updateTriggerSchedule(content: RevisionContent, nodeId: string, schedule: readonly TriggerSchedule[]): readonly ChangeOperation[] | undefined;
@@ -97,4 +105,7 @@ export declare function setCodeActions(content: RevisionContent, nodeId: string,
97
105
  export declare function createDecisionTask(identity: {
98
106
  readonly nodeId: string;
99
107
  }, name?: string, questions?: readonly DecisionQuestion[]): readonly ChangeOperation[];
108
+ /** Edit an Outputs node's definitions and mappings as one undoable change. */
109
+ export declare function updateOutputsDefs(content: RevisionContent, nodeId: string, value: readonly Port[], outputMappings?: Readonly<Record<string, InputMapping>>): readonly ChangeOperation[];
110
+ export declare function renameFlowOutputSources(content: RevisionContent, nodeIds: ReadonlySet<string>, previous: readonly (Port | Group)[], next: readonly (Port | Group)[]): readonly ChangeOperation[];
100
111
  export {};
@@ -5822,6 +5822,10 @@ function preprocess(fn, schema) {
5822
5822
  out: schema
5823
5823
  });
5824
5824
  }
5825
+ function checkJsonDepth(value, depth = 0) {
5826
+ if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
5827
+ if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
5828
+ }
5825
5829
  //#endregion
5826
5830
  //#region src/flow/common/triggerScheduleSchema.ts
5827
5831
  var triggerScheduleSchema = array(union([object({
@@ -5849,6 +5853,7 @@ var webhookMethods = [
5849
5853
  "DELETE"
5850
5854
  ];
5851
5855
  var text = string();
5856
+ var actionConnection = text.describe("Account selection: omit while unconfigured; use an account ID to select it; use \"\" to explicitly defer configuration. Deferred Actions fail if called; deferred Agent tools are excluded from the callable tool set. Not supported by Triggers.");
5852
5857
  var json = json$1();
5853
5858
  var strings = array(text);
5854
5859
  var port = object({
@@ -5857,6 +5862,7 @@ var port = object({
5857
5862
  nullable: boolean(),
5858
5863
  handle: text
5859
5864
  });
5865
+ var workflowInputDefs = array(port.strict());
5860
5866
  var input = port.extend({ value: json.optional() });
5861
5867
  var group = object({
5862
5868
  collapsed: boolean().optional(),
@@ -5903,7 +5909,7 @@ var capability = union([
5903
5909
  mode: literal("independent"),
5904
5910
  actions: array(strictObject({
5905
5911
  action: text,
5906
- connectionId: text.optional()
5912
+ connectionId: actionConnection.optional()
5907
5913
  }))
5908
5914
  }),
5909
5915
  strictObject({
@@ -5963,7 +5969,7 @@ var managedFields = object({
5963
5969
  object({
5964
5970
  kind: literal("connector"),
5965
5971
  action: text,
5966
- connectionId: text.optional(),
5972
+ connectionId: actionConnection.optional(),
5967
5973
  outputMode: literal("value").optional()
5968
5974
  }),
5969
5975
  object({
@@ -6003,17 +6009,22 @@ var managedFields = object({
6003
6009
  name: text,
6004
6010
  description: text,
6005
6011
  action: text,
6006
- connectionId: text.optional(),
6012
+ connectionId: actionConnection.optional(),
6007
6013
  approval: boolean(),
6008
6014
  inputs: array(input.extend({ source: agentInput }))
6009
6015
  })),
6010
6016
  notification: object({
6011
6017
  action: text,
6012
- connectionId: text.optional(),
6018
+ connectionId: actionConnection.optional(),
6013
6019
  inputDefinitions: array(input),
6014
6020
  messageHandle: text,
6015
6021
  inputs: record$1(text, agentValue)
6016
6022
  }).optional()
6023
+ }),
6024
+ strictObject({
6025
+ kind: literal("workflow"),
6026
+ flowId: text,
6027
+ revisionId: text
6017
6028
  })
6018
6029
  ])
6019
6030
  });
@@ -6122,6 +6133,12 @@ var base = {
6122
6133
  timeoutMs: number().optional()
6123
6134
  };
6124
6135
  var node = union([
6136
+ strictObject({
6137
+ ...base,
6138
+ kind: literal("outputs"),
6139
+ outputDefs: array(port.strict()),
6140
+ outputMappings: inputs
6141
+ }).omit({ inputs: true }),
6125
6142
  object({
6126
6143
  ...base,
6127
6144
  inputs: record$1(text, never()),
@@ -6154,6 +6171,11 @@ var node = union([
6154
6171
  ...trigger,
6155
6172
  kind: literal("manual")
6156
6173
  }),
6174
+ strictObject({
6175
+ ...trigger,
6176
+ kind: literal("start"),
6177
+ inputDefs: workflowInputDefs
6178
+ }),
6157
6179
  strictObject({
6158
6180
  ...trigger,
6159
6181
  kind: literal("error"),
@@ -6218,35 +6240,51 @@ var module = object({
6218
6240
  imports: strings,
6219
6241
  source: text
6220
6242
  });
6221
- var document = preprocess(rejectRetiredDefinitions, object({
6243
+ var document = preprocess(normalizeDocument, object({
6222
6244
  bindings: record$1(text, binding),
6223
6245
  graph
6224
6246
  }));
6225
- object({
6247
+ var revision = object({
6226
6248
  modelVersion: union([
6227
6249
  literal(2),
6228
6250
  literal(4),
6229
6251
  literal(5),
6230
- literal(6)
6252
+ literal(6),
6253
+ literal(7),
6254
+ literal(8)
6231
6255
  ]),
6232
6256
  document,
6233
6257
  modules: record$1(text, module)
6234
- }).extend({
6258
+ });
6259
+ revision.extend({
6235
6260
  kind: literal("open-flow-flow-revision"),
6236
6261
  version: literal(1)
6237
6262
  });
6238
- function rejectRetiredDefinitions(value) {
6263
+ function normalizeDocument(value) {
6239
6264
  const candidate = record(value);
6240
6265
  if (candidate.tasks !== void 0 && (candidate.tasks === null || typeof candidate.tasks !== "object" || Array.isArray(candidate.tasks) || Object.keys(candidate.tasks).length > 0)) throw new TypeError("Independent Task definitions are no longer supported.");
6241
6266
  if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
6242
6267
  const subflows = candidate.subflows;
6243
6268
  if (subflows !== void 0 && (subflows === null || typeof subflows !== "object" || Array.isArray(subflows) || Object.keys(subflows).length > 0)) throw new TypeError("Subflows are no longer supported.");
6244
6269
  if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => record(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
6270
+ if ([
6271
+ "inputDefs",
6272
+ "outputDefs",
6273
+ "outputMappings"
6274
+ ].some((field) => Object.hasOwn(candidate, field))) throw new TypeError("Workflow interface configuration must belong to Start and Outputs nodes.");
6275
+ if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => record(candidateNode).kind == "start" && Object.hasOwn(record(candidateNode), "parameters"))) throw new TypeError("Legacy Start.parameters is unsupported; configure node.inputDefs.");
6245
6276
  return value;
6246
6277
  }
6247
6278
  function record(value) {
6248
6279
  return value != null && typeof value == "object" && !Array.isArray(value) ? value : {};
6249
6280
  }
6281
+ function decodeRevisionContent(value) {
6282
+ checkJsonDepth(value);
6283
+ const content = revision.parse(value);
6284
+ checkModelVersion(content);
6285
+ assertOpenApiAuthBindings(content.document);
6286
+ return content;
6287
+ }
6250
6288
  var shapes = {
6251
6289
  "graph.trigger.sources.set": {
6252
6290
  nodeId: text,
@@ -6399,6 +6437,12 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
6399
6437
  kind: literal(kind),
6400
6438
  ...shape
6401
6439
  })])).values()])).min(1);
6440
+ function checkModelVersion(content) {
6441
+ if (content.modelVersion < 8 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "outputs")) throw new TypeError("Workflow outputs require Flow model version 8.");
6442
+ if (content.modelVersion < 7 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "start")) throw new TypeError("Start Triggers require Flow model version 7.");
6443
+ if (content.modelVersion < 6 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task)) throw new TypeError("Node-owned managed Tasks require Flow model version 6.");
6444
+ if (content.modelVersion < 5 && Object.values(content.document.graph.nodes).some((itemNode) => itemNode.kind == "error")) throw new TypeError("Error workflows require Flow model version 5.");
6445
+ }
6402
6446
  //#endregion
6403
6447
  //#region src/flow/common/condition.ts
6404
6448
  var unaryOperator = (operator) => operator.startsWith("is");
@@ -6418,6 +6462,7 @@ function conditionOperands(node) {
6418
6462
  }] : []])));
6419
6463
  }
6420
6464
  function nodeInputMappings(node) {
6465
+ if (node.kind == "outputs") return node.outputMappings;
6421
6466
  if (node.kind != "condition") return "inputs" in node ? node.inputs : {};
6422
6467
  return Object.fromEntries(conditionOperands(node).flatMap(({ handle, operand }) => operand.kind == "source" ? [[handle, {
6423
6468
  kind: "sources",
@@ -6477,7 +6522,7 @@ function decodeConnectorCapabilities(value) {
6477
6522
  const actions = source.actions.map((entry) => {
6478
6523
  if (entry == null || typeof entry != "object" || Array.isArray(entry)) throw new TypeError("Invalid Connector Action.");
6479
6524
  const action = entry;
6480
- if (Object.keys(action).some((key) => !["action", "connectionId"].includes(key)) || typeof action.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action.action) || Object.hasOwn(action, "connectionId") && (typeof action.connectionId != "string" || action.connectionId.length == 0)) throw new TypeError("Invalid Connector Action permission.");
6525
+ if (Object.keys(action).some((key) => !["action", "connectionId"].includes(key)) || typeof action.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action.action) || Object.hasOwn(action, "connectionId") && typeof action.connectionId != "string") throw new TypeError("Invalid Connector Action permission.");
6481
6526
  return action.connectionId == null ? { action: action.action } : {
6482
6527
  action: action.action,
6483
6528
  connectionId: action.connectionId
@@ -6569,6 +6614,40 @@ function decodeConnectorCapabilities(value) {
6569
6614
  };
6570
6615
  });
6571
6616
  }
6617
+ function isTriggerNode(node) {
6618
+ return [
6619
+ "manual",
6620
+ "start",
6621
+ "error",
6622
+ "webhook",
6623
+ "cron",
6624
+ "poll",
6625
+ "integration"
6626
+ ].includes(node.kind);
6627
+ }
6628
+ function upgradeDecodedRevisionContent(content) {
6629
+ const graph = content.document.graph;
6630
+ const hasManual = Object.values(graph.nodes).some((node) => node.kind == "manual");
6631
+ if (!hasManual && content.modelVersion == 8) return content;
6632
+ return {
6633
+ ...content,
6634
+ modelVersion: 8,
6635
+ document: {
6636
+ ...content.document,
6637
+ graph: hasManual ? {
6638
+ ...graph,
6639
+ nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => [id, upgradeManualTrigger(node)]))
6640
+ } : graph
6641
+ }
6642
+ };
6643
+ }
6644
+ function upgradeManualTrigger(node) {
6645
+ return node.kind == "manual" ? {
6646
+ ...node,
6647
+ kind: "start",
6648
+ inputDefs: []
6649
+ } : node;
6650
+ }
6572
6651
  function normalizeNodeName(value) {
6573
6652
  return value.trim().normalize("NFC");
6574
6653
  }
@@ -6587,8 +6666,9 @@ function invalid(message) {
6587
6666
  throw new FlowChangeError(message);
6588
6667
  }
6589
6668
  function applyFlowChanges(content, operations) {
6590
- const document = { ...content.document };
6591
- const modules = { ...content.modules };
6669
+ const source = content.modelVersion != 8 || Object.values(content.document.graph.nodes).some((node) => node.kind == "manual") ? decodeRevisionContent(content) : content;
6670
+ const document = { ...source.document };
6671
+ const modules = { ...source.modules };
6592
6672
  for (const operation of operations) switch (operation.kind) {
6593
6673
  case "graph.trigger.sources.set": {
6594
6674
  const graph = document.graph;
@@ -6639,8 +6719,9 @@ function applyFlowChanges(content, operations) {
6639
6719
  case "graph.edge.connect": {
6640
6720
  const graph = document.graph;
6641
6721
  if (graph.nodes[operation.edge.source] == null) invalid("The source Node does not exist.");
6722
+ if (graph.nodes[operation.edge.source]?.kind == "outputs") invalid("Outputs cannot have downstream execution edges.");
6642
6723
  const node = graph.nodes[operation.edge.target];
6643
- if (node == null || !("inputs" in node)) invalid("The target Node does not accept execution dependencies.");
6724
+ if (node == null || isTriggerNode(node)) invalid("The target Node does not accept execution dependencies.");
6644
6725
  if (graph.edges.some((edge) => dequal(edge, operation.edge))) invalid("The Nodes are already connected.");
6645
6726
  Object.assign(document, { graph: {
6646
6727
  ...graph,
@@ -6720,9 +6801,10 @@ function applyFlowChanges(content, operations) {
6720
6801
  const graph = document.graph;
6721
6802
  if (graph.nodes[operation.nodeId] != null) invalid("A Node with this ID already exists in the target graph.");
6722
6803
  if (operation.node.kind == "error" && Object.values(graph.nodes).some((node) => node.kind == "error")) invalid("A graph can contain only one Flow Error node.");
6723
- if (operation.node.kind == "manual" && Object.values(graph.nodes).some((node) => node.kind == "manual")) invalid("A graph can contain only one manual Trigger.");
6804
+ if ((operation.node.kind == "manual" || operation.node.kind == "start") && Object.values(graph.nodes).some((node) => node.kind == "manual" || node.kind == "start")) invalid("A graph can contain only one Start Trigger.");
6724
6805
  if (operation.node.kind == "task" && "moduleId" in operation.node.task && operation.node.task.capabilities !== void 0) decodeConnectorCapabilities(operation.node.task.capabilities);
6725
6806
  if (operation.node.name == null) invalid("A Node name cannot be empty.");
6807
+ if (operation.node.kind == "outputs" && Object.values(graph.nodes).some((node) => node.kind == "outputs")) invalid("A graph can contain only one Outputs node.");
6726
6808
  const name = normalizeNodeName(operation.node.name);
6727
6809
  const issue = nodeNameIssue(graph, operation.nodeId, name);
6728
6810
  if (issue == "empty") invalid("A Node name cannot be empty.");
@@ -6780,11 +6862,24 @@ function applyFlowChanges(content, operations) {
6780
6862
  case "graph.node.input.set": {
6781
6863
  const graph = document.graph;
6782
6864
  const node = graph.nodes[operation.nodeId];
6783
- if (node == null || !("inputs" in node)) invalid("The Node does not accept inputs.");
6865
+ if (node == null || isTriggerNode(node)) invalid("The Node does not accept inputs.");
6784
6866
  if (!dequal(nodeInputMappings(node)[operation.handle], operation.before)) invalid("The Node input changed before this operation was applied.");
6785
- const inputs = { ...node.inputs };
6867
+ const inputs = { ...nodeInputMappings(node) };
6786
6868
  if (operation.value == null) delete inputs[operation.handle];
6787
6869
  else inputs[operation.handle] = operation.value;
6870
+ if (node.kind == "outputs") {
6871
+ document.graph = {
6872
+ ...graph,
6873
+ nodes: {
6874
+ ...graph.nodes,
6875
+ [operation.nodeId]: {
6876
+ ...node,
6877
+ outputMappings: inputs
6878
+ }
6879
+ }
6880
+ };
6881
+ break;
6882
+ }
6788
6883
  Object.assign(document, { graph: {
6789
6884
  ...graph,
6790
6885
  nodes: {
@@ -7012,11 +7107,11 @@ function applyFlowChanges(content, operations) {
7012
7107
  }
7013
7108
  }
7014
7109
  assertOpenApiAuthBindings(document);
7015
- return {
7110
+ return upgradeDecodedRevisionContent({
7016
7111
  document,
7017
- modelVersion: 6,
7112
+ modelVersion: 8,
7018
7113
  modules
7019
- };
7114
+ });
7020
7115
  }
7021
7116
  //#endregion
7022
7117
  //#region src/json-schema-subset/utils.ts
@@ -10136,7 +10231,7 @@ function deleteNodes(content, nodeIds) {
10136
10231
  }
10137
10232
  function updateSettings(content, nodeId, settings) {
10138
10233
  const node = content.document.graph?.nodes[nodeId];
10139
- if (node == null || !("inputs" in node)) return;
10234
+ if (node == null || isTriggerNode(node)) return;
10140
10235
  const operations = [];
10141
10236
  if (node.name != settings.name) operations.push({
10142
10237
  before: node.name,
@@ -10163,7 +10258,7 @@ function updateSettings(content, nodeId, settings) {
10163
10258
  }
10164
10259
  function setInputValues(content, nodeId, values) {
10165
10260
  const node = content.document.graph?.nodes[nodeId];
10166
- if (node == null || !("inputs" in node)) return;
10261
+ if (node == null || isTriggerNode(node)) return;
10167
10262
  const operations = [];
10168
10263
  for (const [handle, value] of Object.entries(values)) {
10169
10264
  const before = nodeInputMappings(node)[handle];
@@ -10181,7 +10276,7 @@ function setInputValues(content, nodeId, values) {
10181
10276
  }
10182
10277
  function setInputSources(content, nodeId, handle, sources) {
10183
10278
  const node = content.document.graph?.nodes[nodeId];
10184
- if (node == null || !("inputs" in node)) return [];
10279
+ if (node == null || isTriggerNode(node)) return [];
10185
10280
  return cleanVariableBindings(content, [{
10186
10281
  kind: "graph.node.input.set",
10187
10282
  nodeId,
@@ -10195,7 +10290,7 @@ function setInputSources(content, nodeId, handle, sources) {
10195
10290
  }
10196
10291
  function setInputVariable(content, nodeId, handle, name, bindingId) {
10197
10292
  const node = content.document.graph?.nodes[nodeId];
10198
- if (node == null || !("inputs" in node)) return;
10293
+ if (node == null || isTriggerNode(node)) return;
10199
10294
  const mapping = nodeInputMappings(node)[handle];
10200
10295
  const currentId = mapping?.kind == "sources" && mapping.sources.length == 1 && mapping.sources[0]?.kind == "binding" ? mapping.sources[0].bindingId : void 0;
10201
10296
  const current = currentId == null ? void 0 : content.document.bindings[currentId];
@@ -10245,7 +10340,7 @@ function bindingReferences(document) {
10245
10340
  references.set(bindingId, (references.get(bindingId) ?? 0) + 1);
10246
10341
  };
10247
10342
  for (const node of Object.values(document.graph.nodes)) {
10248
- if (!("inputs" in node)) continue;
10343
+ if (isTriggerNode(node)) continue;
10249
10344
  const inputs = Object.values(nodeInputMappings(node));
10250
10345
  for (const mapping of inputs) {
10251
10346
  if (mapping.kind != "sources") continue;
@@ -10293,6 +10388,7 @@ function updateTrigger(content, nodeId, settings) {
10293
10388
  value: settings.description
10294
10389
  });
10295
10390
  switch (settings.kind) {
10391
+ case "start":
10296
10392
  case "error":
10297
10393
  case "manual":
10298
10394
  if (trigger.kind != settings.kind) return;
@@ -1,6 +1,6 @@
1
1
  import type { ChangeOperation, FlowDocument, JsonValue, RevisionContent } from './flow-change.js';
2
2
  import { z } from 'zod';
3
- export declare const currentFlowModelVersion = 6;
3
+ export declare const currentFlowModelVersion = 8;
4
4
  /** Configuration schemas shared by the node authoring boundary. */
5
5
  export declare const authoringDefinitionSchemas: {
6
6
  input: z.ZodObject<{
@@ -267,6 +267,8 @@ export declare const authoringDefinitionSchemas: {
267
267
  }, z.core.$strip>>;
268
268
  }, z.core.$strict>;
269
269
  };
270
+ /** Explicit storage upgrade only. Normal reads and authoring still reject retired fields. */
271
+ export declare function upgradeWorkflowInterfaceDocument(value: unknown): unknown;
270
272
  /** Best-effort recovery for a parseable Revision envelope. Invalid collection entries are discarded. */
271
273
  export declare function repairRevisionEnvelope(value: unknown): RevisionContent;
272
274
  export declare function decodeFlowDocument(value: unknown): FlowDocument;
@@ -108,7 +108,7 @@ export interface ConditionNode extends GraphNodeBase {
108
108
  readonly matchMode: 'first' | 'all';
109
109
  readonly kind: 'condition';
110
110
  }
111
- export type ManagedTaskExecutor = import('../common/decision.js').DecisionExecutor | import('../common/openapi.js').OpenApiExecutor | {
111
+ export type ManagedTaskExecutor = import('../common/workflow.js').WorkflowExecutor | import('../common/decision.js').DecisionExecutor | import('../common/openapi.js').OpenApiExecutor | {
112
112
  readonly kind: 'connector';
113
113
  readonly action: string;
114
114
  readonly connectionId?: string;
@@ -257,6 +257,9 @@ interface TriggerNodeBase {
257
257
  }
258
258
  export type TriggerNode = (TriggerNodeBase & {
259
259
  readonly kind: 'manual';
260
+ }) | (TriggerNodeBase & {
261
+ readonly kind: 'start';
262
+ readonly inputDefs: readonly Port[];
260
263
  }) | (TriggerNodeBase & {
261
264
  readonly kind: 'error';
262
265
  readonly sourceFlowIds?: readonly string[];
@@ -284,7 +287,13 @@ export type TriggerNode = (TriggerNodeBase & {
284
287
  };
285
288
  readonly kind: 'integration';
286
289
  });
287
- export type GraphNode = ApprovalNode | ConditionNode | TaskNode | TriggerNode | ValueNode | WaitNode;
290
+ export interface OutputsNode extends Omit<GraphNodeBase, 'inputs'> {
291
+ readonly kind: 'outputs';
292
+ readonly outputDefs: readonly Port[];
293
+ readonly outputMappings: Readonly<Record<string, InputMapping>>;
294
+ }
295
+ export declare function isTriggerNode(node: GraphNode): node is TriggerNode;
296
+ export type GraphNode = OutputsNode | ApprovalNode | ConditionNode | TaskNode | TriggerNode | ValueNode | WaitNode;
288
297
  export interface FlowDocument {
289
298
  readonly bindings: Readonly<Record<string, {
290
299
  readonly kind: 'variable';
@@ -299,7 +308,7 @@ export interface CodeModule {
299
308
  }
300
309
  export interface RevisionContent {
301
310
  readonly document: FlowDocument;
302
- readonly modelVersion: 2 | 4 | 5 | typeof currentFlowModelVersion;
311
+ readonly modelVersion: 2 | 4 | 5 | 6 | 7 | typeof currentFlowModelVersion;
303
312
  readonly modules: Readonly<Record<string, CodeModule>>;
304
313
  }
305
314
  export interface GraphEdge {
@@ -307,6 +316,9 @@ export interface GraphEdge {
307
316
  readonly sourceHandle?: string;
308
317
  readonly target: string;
309
318
  }
319
+ /** Lossless upgrade of readable content. Historical content and its encoding stay unchanged. */
320
+ export declare function upgradeRevisionContent(content: RevisionContent): RevisionContent;
321
+ export declare function upgradeManualTrigger(node: GraphNode): GraphNode;
310
322
  export declare function normalizeNodeName(value: string): string;
311
323
  export declare function nextNodeName(value: string, names: Iterable<string>): string;
312
324
  export declare function nodeNameIssue(graph: Graph, nodeId: string, value: string): 'duplicate' | 'empty' | undefined;