@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
@@ -22,6 +22,15 @@ function dequal(foo, bar) {
22
22
  return foo !== foo && bar !== bar;
23
23
  }
24
24
  //#endregion
25
+ //#region src/openapi/common/authBindings.ts
26
+ /** Never allow credentials to enter a Revision as literal node inputs. */
27
+ function assertOpenApiAuthBindings(document) {
28
+ for (const node of Object.values(document.graph.nodes)) {
29
+ if (node.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "openapi") continue;
30
+ for (const [handle, mapping] of Object.entries(node.inputs)) if (handle.startsWith("auth.") && mapping.kind == "value") throw new TypeError("OpenAPI authentication accepts deployment variables and upstream outputs only.");
31
+ }
32
+ }
33
+ //#endregion
25
34
  //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
26
35
  function getEnumValues(entries) {
27
36
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
@@ -5691,50 +5700,6 @@ function preprocess(fn, schema) {
5691
5700
  });
5692
5701
  }
5693
5702
  //#endregion
5694
- //#region src/flow/common/webhookMethod.ts
5695
- var webhookMethods = [
5696
- "GET",
5697
- "POST",
5698
- "PUT",
5699
- "PATCH",
5700
- "DELETE"
5701
- ];
5702
- function webhookSupportsBody(method) {
5703
- return method !== "GET";
5704
- }
5705
- //#endregion
5706
- //#region src/openapi/common/authBindings.ts
5707
- /** Never allow credentials to enter a Revision as literal node inputs. */
5708
- function assertOpenApiAuthBindings(document) {
5709
- for (const node of Object.values(document.graph.nodes)) {
5710
- if (node.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "openapi") continue;
5711
- for (const [handle, mapping] of Object.entries(node.inputs)) if (handle.startsWith("auth.") && mapping.kind == "value") throw new TypeError("OpenAPI authentication accepts deployment variables and upstream outputs only.");
5712
- }
5713
- }
5714
- //#endregion
5715
- //#region src/flow/common/change.ts
5716
- var schemaKeywords = /* @__PURE__ */ new Set([
5717
- "const",
5718
- "enum",
5719
- "exclusiveMaximum",
5720
- "exclusiveMinimum",
5721
- "maximum",
5722
- "maxItems",
5723
- "maxLength",
5724
- "maxProperties",
5725
- "minimum",
5726
- "minItems",
5727
- "minLength",
5728
- "minProperties",
5729
- "multipleOf",
5730
- "pattern",
5731
- "required",
5732
- "type"
5733
- ]);
5734
- function isSchemaKeyword(value) {
5735
- return schemaKeywords.has(value);
5736
- }
5737
- //#endregion
5738
5703
  //#region src/json-schema-subset/utils.ts
5739
5704
  var nextId = 0;
5740
5705
  function createId() {
@@ -8601,7 +8566,20 @@ var triggerScheduleSchema = array(union([object({
8601
8566
  ]),
8602
8567
  value: number()
8603
8568
  })]));
8569
+ //#endregion
8570
+ //#region src/flow/common/webhookMethod.ts
8571
+ var webhookMethods = [
8572
+ "GET",
8573
+ "POST",
8574
+ "PUT",
8575
+ "PATCH",
8576
+ "DELETE"
8577
+ ];
8578
+ function webhookSupportsBody(method) {
8579
+ return method !== "GET";
8580
+ }
8604
8581
  var text = string$1();
8582
+ 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.");
8605
8583
  var json$3 = json$4();
8606
8584
  var strings$1 = array(text);
8607
8585
  var port$1 = object({
@@ -8610,6 +8588,7 @@ var port$1 = object({
8610
8588
  nullable: boolean(),
8611
8589
  handle: text
8612
8590
  });
8591
+ var workflowInputDefs = array(port$1.strict());
8613
8592
  var input = port$1.extend({ value: json$3.optional() });
8614
8593
  var group = object({
8615
8594
  collapsed: boolean().optional(),
@@ -8656,7 +8635,7 @@ var capability = union([
8656
8635
  mode: literal("independent"),
8657
8636
  actions: array(strictObject({
8658
8637
  action: text,
8659
- connectionId: text.optional()
8638
+ connectionId: actionConnection.optional()
8660
8639
  }))
8661
8640
  }),
8662
8641
  strictObject({
@@ -8716,7 +8695,7 @@ var managedFields = object({
8716
8695
  object({
8717
8696
  kind: literal("connector"),
8718
8697
  action: text,
8719
- connectionId: text.optional(),
8698
+ connectionId: actionConnection.optional(),
8720
8699
  outputMode: literal("value").optional()
8721
8700
  }),
8722
8701
  object({
@@ -8756,17 +8735,22 @@ var managedFields = object({
8756
8735
  name: text,
8757
8736
  description: text,
8758
8737
  action: text,
8759
- connectionId: text.optional(),
8738
+ connectionId: actionConnection.optional(),
8760
8739
  approval: boolean(),
8761
8740
  inputs: array(input.extend({ source: agentInput }))
8762
8741
  })),
8763
8742
  notification: object({
8764
8743
  action: text,
8765
- connectionId: text.optional(),
8744
+ connectionId: actionConnection.optional(),
8766
8745
  inputDefinitions: array(input),
8767
8746
  messageHandle: text,
8768
8747
  inputs: record$3(text, agentValue)
8769
8748
  }).optional()
8749
+ }),
8750
+ strictObject({
8751
+ kind: literal("workflow"),
8752
+ flowId: text,
8753
+ revisionId: text
8770
8754
  })
8771
8755
  ])
8772
8756
  });
@@ -8875,6 +8859,12 @@ var base = {
8875
8859
  timeoutMs: number().optional()
8876
8860
  };
8877
8861
  var node = union([
8862
+ strictObject({
8863
+ ...base,
8864
+ kind: literal("outputs"),
8865
+ outputDefs: array(port$1.strict()),
8866
+ outputMappings: inputs
8867
+ }).omit({ inputs: true }),
8878
8868
  object({
8879
8869
  ...base,
8880
8870
  inputs: record$3(text, never()),
@@ -8907,6 +8897,11 @@ var node = union([
8907
8897
  ...trigger,
8908
8898
  kind: literal("manual")
8909
8899
  }),
8900
+ strictObject({
8901
+ ...trigger,
8902
+ kind: literal("start"),
8903
+ inputDefs: workflowInputDefs
8904
+ }),
8910
8905
  strictObject({
8911
8906
  ...trigger,
8912
8907
  kind: literal("error"),
@@ -8986,7 +8981,7 @@ var module = object({
8986
8981
  imports: strings$1,
8987
8982
  source: text
8988
8983
  });
8989
- var document = preprocess(rejectRetiredDefinitions, object({
8984
+ var document = preprocess(normalizeDocument, object({
8990
8985
  bindings: record$3(text, binding$1),
8991
8986
  graph
8992
8987
  }));
@@ -8995,7 +8990,9 @@ var revision = object({
8995
8990
  literal(2),
8996
8991
  literal(4),
8997
8992
  literal(5),
8998
- literal(6)
8993
+ literal(6),
8994
+ literal(7),
8995
+ literal(8)
8999
8996
  ]),
9000
8997
  document,
9001
8998
  modules: record$3(text, module)
@@ -9004,13 +9001,19 @@ revision.extend({
9004
9001
  kind: literal("open-flow-flow-revision"),
9005
9002
  version: literal(1)
9006
9003
  });
9007
- function rejectRetiredDefinitions(value) {
9004
+ function normalizeDocument(value) {
9008
9005
  const candidate = record$2(value);
9009
9006
  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.");
9010
9007
  if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record$2(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
9011
9008
  const subflows = candidate.subflows;
9012
9009
  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.");
9013
9010
  if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => record$2(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
9011
+ if ([
9012
+ "inputDefs",
9013
+ "outputDefs",
9014
+ "outputMappings"
9015
+ ].some((field) => Object.hasOwn(candidate, field))) throw new TypeError("Workflow interface configuration must belong to Start and Outputs nodes.");
9016
+ if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => record$2(candidateNode).kind == "start" && Object.hasOwn(record$2(candidateNode), "parameters"))) throw new TypeError("Legacy Start.parameters is unsupported; configure node.inputDefs.");
9014
9017
  return value;
9015
9018
  }
9016
9019
  function record$2(value) {
@@ -9176,10 +9179,100 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
9176
9179
  ...shape
9177
9180
  })])).values()])).min(1);
9178
9181
  function checkModelVersion(content) {
9182
+ 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.");
9183
+ 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.");
9179
9184
  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.");
9180
9185
  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.");
9181
9186
  }
9182
9187
  //#endregion
9188
+ //#region src/flow/common/change.ts
9189
+ var schemaKeywords = /* @__PURE__ */ new Set([
9190
+ "const",
9191
+ "enum",
9192
+ "exclusiveMaximum",
9193
+ "exclusiveMinimum",
9194
+ "maximum",
9195
+ "maxItems",
9196
+ "maxLength",
9197
+ "maxProperties",
9198
+ "minimum",
9199
+ "minItems",
9200
+ "minLength",
9201
+ "minProperties",
9202
+ "multipleOf",
9203
+ "pattern",
9204
+ "required",
9205
+ "type"
9206
+ ]);
9207
+ function isSchemaKeyword(value) {
9208
+ return schemaKeywords.has(value);
9209
+ }
9210
+ /** Lossless upgrade of readable content. Historical content and its encoding stay unchanged. */
9211
+ function upgradeRevisionContent(content) {
9212
+ const upgraded = upgradeDecodedRevisionContent(decodeRevisionContent(content));
9213
+ return dequal(content, upgraded) ? content : upgraded;
9214
+ }
9215
+ function upgradeDecodedRevisionContent(content) {
9216
+ const graph = content.document.graph;
9217
+ const hasManual = Object.values(graph.nodes).some((node) => node.kind == "manual");
9218
+ if (!hasManual && content.modelVersion == 8) return content;
9219
+ return {
9220
+ ...content,
9221
+ modelVersion: 8,
9222
+ document: {
9223
+ ...content.document,
9224
+ graph: hasManual ? {
9225
+ ...graph,
9226
+ nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => [id, upgradeManualTrigger(node)]))
9227
+ } : graph
9228
+ }
9229
+ };
9230
+ }
9231
+ function upgradeManualTrigger(node) {
9232
+ return node.kind == "manual" ? {
9233
+ ...node,
9234
+ kind: "start",
9235
+ inputDefs: []
9236
+ } : node;
9237
+ }
9238
+ //#endregion
9239
+ //#region src/workflow/common/workflow.ts
9240
+ var portSchema = object({
9241
+ handle: string$1().min(1),
9242
+ jsonSchema: json$4(),
9243
+ nullable: boolean(),
9244
+ description: string$1().optional()
9245
+ });
9246
+ strictObject({
9247
+ inputs: array(portSchema).nullable(),
9248
+ outputs: array(portSchema).nullable()
9249
+ });
9250
+ var workflowContractSchema = object({
9251
+ version: literal(1),
9252
+ flowId: string$1().min(1),
9253
+ name: string$1(),
9254
+ revisionId: string$1().min(1),
9255
+ publicationId: string$1().min(1),
9256
+ inputs: array(portSchema),
9257
+ outputs: array(portSchema).nullable()
9258
+ });
9259
+ var workflowReferencesSchema = object({
9260
+ version: literal(1),
9261
+ direction: _enum(["incoming", "outgoing"]),
9262
+ total: int().nonnegative(),
9263
+ nextOffset: int().nonnegative().optional(),
9264
+ references: array(object({
9265
+ flowId: string$1(),
9266
+ name: string$1().nullable(),
9267
+ available: boolean(),
9268
+ draft: boolean(),
9269
+ live: object({
9270
+ publicationId: string$1(),
9271
+ enabled: boolean()
9272
+ }).nullable()
9273
+ }))
9274
+ });
9275
+ //#endregion
9183
9276
  //#region src/control/common/authoringLlm.ts
9184
9277
  var authoringLlmConfiguration = strictObject({
9185
9278
  mode: _enum(["chat", "json"]),
@@ -9212,7 +9305,9 @@ var id$1 = string$1().min(1);
9212
9305
  var json$2 = json$4();
9213
9306
  var patch = record$3(id$1, json$2);
9214
9307
  var type = _enum([
9215
- "manual",
9308
+ "start",
9309
+ "outputs",
9310
+ "workflow",
9216
9311
  "webhook",
9217
9312
  "cron",
9218
9313
  "error",
@@ -9284,6 +9379,12 @@ var field = strictObject({
9284
9379
  description: string$1().optional()
9285
9380
  });
9286
9381
  var inputFields = record$3(id$1, field.extend({ default: json$2.optional() })).describe("Optional business input constraints by name. A binding to a new Code, Agent, LLM, Wait or Approval input automatically declares an input accepting any JSON. Existing constraints are preserved. Omitted schema accepts any JSON; omitted nullable is true. Use default for inherited values; input.set supplies data.");
9382
+ var flowInputFields = record$3(id$1, field).describe("Workflow input definitions by name. Omitted schema accepts any JSON; omitted nullable is true. No defaults. Supply call values as trigger.outputs.");
9383
+ var flowOutputFields = flowInputFields.describe("Workflow output definitions by name. Omitted schema accepts any JSON; omitted nullable is true. No defaults. Set values on the Outputs node with input.set or node.add.inputs.");
9384
+ var flowInputFieldsView = record$3(id$1, field.extend({
9385
+ schema: json$2,
9386
+ nullable: boolean()
9387
+ }));
9287
9388
  var outputFields = record$3(id$1, field).describe("Code return fields by name. Omitted schema accepts any JSON; omitted nullable is true.");
9288
9389
  var expression = strictObject({
9289
9390
  left: operand,
@@ -9297,7 +9398,9 @@ var when = union([
9297
9398
  strictObject({ any: array(union([expression, all])) })
9298
9399
  ]);
9299
9400
  var authoringConfigurations = {
9300
- manual: strictObject({}),
9401
+ workflow: strictObject({ flowId: id$1 }),
9402
+ start: strictObject({ inputDefs: flowInputFields.default({}) }),
9403
+ outputs: strictObject({ outputDefs: flowOutputFields.default({}) }),
9301
9404
  error: strictObject({ sourceFlowIds: array(id$1).optional() }),
9302
9405
  webhook: authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
9303
9406
  cron: strictObject({ schedule: authoringDefinitionSchemas.schedule }),
@@ -9368,6 +9471,10 @@ var authoringEditSchema = discriminatedUnion("op", [
9368
9471
  set: updates.optional(),
9369
9472
  clear: array(array(id$1).min(1)).optional()
9370
9473
  }),
9474
+ strictObject({
9475
+ op: literal("node.refresh"),
9476
+ node: referenceSchema
9477
+ }),
9371
9478
  strictObject({
9372
9479
  op: literal("node.remove"),
9373
9480
  node: referenceSchema
@@ -9478,7 +9585,7 @@ var authoringSearchResponse = object({
9478
9585
  revision: id$1,
9479
9586
  data: object({
9480
9587
  matches: array(object({
9481
- node: id$1,
9588
+ node: id$1.optional(),
9482
9589
  field: id$1,
9483
9590
  line: int().optional(),
9484
9591
  excerpt: string$1()
@@ -9566,6 +9673,10 @@ function record$1(value) {
9566
9673
  function string(value) {
9567
9674
  return typeof value == "string" && value.length > 0 ? value : invalidResponse("Expected a non-empty string.");
9568
9675
  }
9676
+ function requiredFields(value, keys) {
9677
+ const missing = keys.filter((key) => !Object.hasOwn(value, key));
9678
+ if (missing.length > 0) invalidResponse(`Missing fields: ${missing.join(", ")}.`);
9679
+ }
9569
9680
  function exact(value, keys) {
9570
9681
  const actual = Object.keys(value);
9571
9682
  if (actual.length != keys.length || actual.some((key) => !keys.includes(key))) {
@@ -9633,7 +9744,7 @@ function publishOperation(value) {
9633
9744
  if (source.version != 1) return invalidResponse();
9634
9745
  switch (status) {
9635
9746
  case "pending":
9636
- exact(source, [
9747
+ requiredFields(source, [
9637
9748
  "createdAt",
9638
9749
  "flowId",
9639
9750
  "operationId",
@@ -9647,7 +9758,7 @@ function publishOperation(value) {
9647
9758
  status
9648
9759
  };
9649
9760
  case "succeeded":
9650
- exact(source, [
9761
+ requiredFields(source, [
9651
9762
  "createdAt",
9652
9763
  "flowId",
9653
9764
  "operationId",
@@ -9663,7 +9774,7 @@ function publishOperation(value) {
9663
9774
  status
9664
9775
  };
9665
9776
  case "failed": {
9666
- exact(source, [
9777
+ requiredFields(source, [
9667
9778
  "createdAt",
9668
9779
  "flowId",
9669
9780
  "issue",
@@ -9675,7 +9786,7 @@ function publishOperation(value) {
9675
9786
  ]);
9676
9787
  const issue = record$1(source.issue);
9677
9788
  const nodeId = issue.nodeId;
9678
- exact(issue, [
9789
+ requiredFields(issue, [
9679
9790
  "code",
9680
9791
  "message",
9681
9792
  ...nodeId == null ? [] : ["nodeId"]
@@ -9916,43 +10027,48 @@ var metadata = {
9916
10027
  var binding = unknown().transform(triggerBinding);
9917
10028
  var provider = {
9918
10029
  provider: string$1().min(1),
9919
- inputs: record$3(string$1(), discriminatedUnion("kind", [strictObject({
10030
+ inputs: record$3(string$1(), discriminatedUnion("kind", [object({
9920
10031
  kind: literal("value"),
9921
10032
  value: json$4()
9922
- }), strictObject({ kind: literal("unset") })]))
10033
+ }), object({ kind: literal("unset") })]))
9923
10034
  };
9924
10035
  var entrySchema = discriminatedUnion("type", [
9925
- strictObject({
10036
+ object({
10037
+ ...metadata,
10038
+ type: literal("start"),
10039
+ config: authoringConfigurations.start
10040
+ }),
10041
+ object({
9926
10042
  ...metadata,
9927
10043
  type: literal("manual"),
9928
- config: authoringConfigurations.manual
10044
+ config: object({})
9929
10045
  }),
9930
- strictObject({
10046
+ object({
9931
10047
  ...metadata,
9932
10048
  type: literal("webhook"),
9933
10049
  config: authoringConfigurations.webhook,
9934
10050
  binding
9935
10051
  }),
9936
- strictObject({
10052
+ object({
9937
10053
  ...metadata,
9938
10054
  type: literal("cron"),
9939
10055
  config: authoringConfigurations.cron,
9940
10056
  binding
9941
10057
  }),
9942
- strictObject({
10058
+ object({
9943
10059
  ...metadata,
9944
10060
  type: literal("error"),
9945
10061
  config: authoringConfigurations.error,
9946
10062
  binding
9947
10063
  }),
9948
- strictObject({
10064
+ object({
9949
10065
  ...metadata,
9950
10066
  ...provider,
9951
10067
  type: literal("poll"),
9952
10068
  config: authoringConfigurations.poll,
9953
10069
  binding
9954
10070
  }),
9955
- strictObject({
10071
+ object({
9956
10072
  ...metadata,
9957
10073
  ...provider,
9958
10074
  type: literal("integration"),
@@ -9965,9 +10081,10 @@ function decodeLiveDetails(value) {
9965
10081
  const flowId = string(source.flowId);
9966
10082
  if (source.version != 1 || !Array.isArray(source.entries)) return invalidResponse();
9967
10083
  if (source.publication === null) {
9968
- if (source.status != "not-published" || source.entries.length != 0 || Object.hasOwn(source, "enabled")) return invalidResponse();
10084
+ if (source.inputDefs !== null || source.status != "not-published" || source.entries.length != 0 || Object.hasOwn(source, "enabled")) return invalidResponse();
9969
10085
  return {
9970
10086
  flowId,
10087
+ inputDefs: null,
9971
10088
  publication: null,
9972
10089
  status: "not-published",
9973
10090
  entries: [],
@@ -9979,8 +10096,11 @@ function decodeLiveDetails(value) {
9979
10096
  if (current.flowId != flowId || typeof source.enabled != "boolean") return invalidResponse();
9980
10097
  if (status != "runnable" && status != "suspended") return invalidResponse();
9981
10098
  if (!source.enabled && source.status == "runnable") return invalidResponse();
10099
+ const inputDefs = flowInputFieldsView.safeParse(source.inputDefs);
10100
+ if (!inputDefs.success) return invalidResponse();
9982
10101
  return {
9983
10102
  flowId,
10103
+ inputDefs: inputDefs.data,
9984
10104
  publication: current,
9985
10105
  status,
9986
10106
  enabled: source.enabled,
@@ -9996,7 +10116,7 @@ function decodeEntries(values, current) {
9996
10116
  for (const entry of parsed.data) {
9997
10117
  if (ids.has(entry.nodeId)) return invalidResponse();
9998
10118
  ids.add(entry.nodeId);
9999
- if (entry.type != "manual" && (entry.binding.flowId != current.flowId || entry.binding.triggerNodeId != entry.nodeId || entry.binding.kind != entry.type || entry.binding.currentPublicationId != current.publicationId || entry.binding.currentRevisionId != current.revisionId)) return invalidResponse();
10119
+ if (entry.type != "start" && entry.type != "manual" && (entry.binding.flowId != current.flowId || entry.binding.triggerNodeId != entry.nodeId || entry.binding.kind != entry.type || entry.binding.currentPublicationId != current.publicationId || entry.binding.currentRevisionId != current.revisionId)) return invalidResponse();
10000
10120
  if (entry.type == "webhook" && (!entry.binding.endpointUrl || !webhookSupportsBody(entry.config.method) && Object.keys(entry.config.body).length > 0)) return invalidResponse();
10001
10121
  }
10002
10122
  return parsed.data;
@@ -10309,7 +10429,7 @@ function connectorAccessCandidatesBatch(value, providerIds) {
10309
10429
  }
10310
10430
  function connection(value) {
10311
10431
  const source = record$1(value);
10312
- exact(source, [
10432
+ requiredFields(source, [
10313
10433
  ...Object.hasOwn(source, "providerAccountId") ? ["providerAccountId"] : [],
10314
10434
  ...Object.hasOwn(source, "alias") ? ["alias"] : [],
10315
10435
  ...Object.hasOwn(source, "builtInAccount") ? ["builtInAccount"] : [],
@@ -10338,7 +10458,7 @@ function port(value, input = false) {
10338
10458
  const source = record$1(value);
10339
10459
  const description = source.description;
10340
10460
  const hasValue = input && Object.hasOwn(source, "value");
10341
- exact(source, [
10461
+ requiredFields(source, [
10342
10462
  "jsonSchema",
10343
10463
  "nullable",
10344
10464
  ...description == null ? [] : ["description"],
@@ -10363,7 +10483,7 @@ function connectorActionMetadata(value) {
10363
10483
  const source = record$1(value);
10364
10484
  const homepageUrl = source.homepageUrl;
10365
10485
  const icon = source.icon;
10366
- exact(source, [
10486
+ requiredFields(source, [
10367
10487
  "actionId",
10368
10488
  ...Object.hasOwn(source, "operationType") ? ["operationType"] : [],
10369
10489
  ...Object.hasOwn(source, "inputSchema") ? ["inputSchema"] : [],
@@ -10414,7 +10534,7 @@ function connectorProvider(value) {
10414
10534
  const homepageUrl = source.homepageUrl;
10415
10535
  const icon = source.icon;
10416
10536
  if (source.noSetup !== void 0 && typeof source.noSetup != "boolean") return invalidResponse();
10417
- exact(source, [
10537
+ requiredFields(source, [
10418
10538
  ...Object.hasOwn(source, "noSetup") ? ["noSetup"] : [],
10419
10539
  "serviceId",
10420
10540
  "serviceName",
@@ -10438,7 +10558,7 @@ function connectorProvider(value) {
10438
10558
  var id = string$1().min(1).max(256);
10439
10559
  var eventType = string$1().regex(/^[a-z][a-z0-9_.]{0,127}$/);
10440
10560
  var name = string$1().trim().min(1).max(128);
10441
- var eventSourceSchema = strictObject({
10561
+ var eventSourceSchema = object({
10442
10562
  version: literal(1),
10443
10563
  sourceId: id,
10444
10564
  revision: int().positive(),
@@ -10456,7 +10576,7 @@ var eventSourceSchema = strictObject({
10456
10576
  verifiedAt: string$1().nullable(),
10457
10577
  lastReceivedAt: string$1().nullable(),
10458
10578
  updatedAt: string$1(),
10459
- consumers: array(strictObject({
10579
+ consumers: array(object({
10460
10580
  flowId: id,
10461
10581
  flowName: string$1(),
10462
10582
  triggerNodeId: id
@@ -10466,7 +10586,7 @@ function decodeEventSource(value) {
10466
10586
  return eventSourceSchema.parse(value);
10467
10587
  }
10468
10588
  function decodeEventSources(value) {
10469
- return strictObject({
10589
+ return object({
10470
10590
  version: literal(1),
10471
10591
  sources: array(eventSourceSchema),
10472
10592
  teamId: id.nullable().optional()
@@ -10488,7 +10608,7 @@ function isUiLanguage(value) {
10488
10608
  //#region src/control/common/triggerCatalog.ts
10489
10609
  function decodeTriggerCatalog(value) {
10490
10610
  const source = record$1(value);
10491
- exact(source, [
10611
+ requiredFields(source, [
10492
10612
  "version",
10493
10613
  "locale",
10494
10614
  "definitions",
@@ -10502,7 +10622,7 @@ function decodeTriggerCatalog(value) {
10502
10622
  const display = Object.fromEntries(definitions.map((definition) => {
10503
10623
  const { key } = definition;
10504
10624
  const copy = record$1(entries[key]);
10505
- exact(copy, [
10625
+ requiredFields(copy, [
10506
10626
  "configInputs",
10507
10627
  "configInputLabels",
10508
10628
  "displayName",
@@ -10546,7 +10666,7 @@ strictObject({
10546
10666
  //#endregion
10547
10667
  //#region src/control/common/results.ts
10548
10668
  var json$1 = json$4();
10549
- var entry = strictObject({
10669
+ var entry = object({
10550
10670
  pointer: string$1(),
10551
10671
  type: _enum([
10552
10672
  "object",
@@ -10565,25 +10685,25 @@ var page = entry.extend({
10565
10685
  nextOffset: number().int().positive().optional(),
10566
10686
  entries: array(entry).optional()
10567
10687
  });
10568
- var result = strictObject({
10688
+ var result = object({
10569
10689
  resultId: string$1().min(1),
10570
10690
  callId: string$1().min(1),
10571
10691
  toolId: string$1().min(1),
10572
- source: discriminatedUnion("kind", [strictObject({
10692
+ source: discriminatedUnion("kind", [object({
10573
10693
  kind: literal("connector"),
10574
10694
  action: string$1().min(1)
10575
- }), strictObject({ kind: literal("code") })]),
10695
+ }), object({ kind: literal("code") })]),
10576
10696
  bytes: number().int().nonnegative(),
10577
10697
  digest: string$1().regex(/^[a-f0-9]{64}$/),
10578
10698
  createdAt: string$1().datetime()
10579
10699
  });
10580
- var listSchema = strictObject({
10700
+ var listSchema = object({
10581
10701
  version: literal(1),
10582
10702
  runId: string$1(),
10583
10703
  results: array(result),
10584
10704
  nextAfter: string$1().optional()
10585
10705
  });
10586
- var readSchema = strictObject({
10706
+ var readSchema = object({
10587
10707
  version: literal(1),
10588
10708
  runId: string$1(),
10589
10709
  result,
@@ -10660,7 +10780,7 @@ function connectorProvidersQuery(flowId, locale) {
10660
10780
  path: `/v1/connector/providers${parameters ? `?${parameters}` : ""}`,
10661
10781
  decode: (value) => {
10662
10782
  const source = record$1(value);
10663
- exact(source, ["providers", "version"]);
10783
+ requiredFields(source, ["providers", "version"]);
10664
10784
  if (source.version != 1 || !Array.isArray(source.providers)) return invalidResponse();
10665
10785
  return source.providers.map(connectorProvider);
10666
10786
  }
@@ -10675,7 +10795,7 @@ function connectorActionQuery(actionId, flowId, locale) {
10675
10795
  path: `/v1/connector/actions/${encodeURIComponent(actionId)}${parameters ? `?${parameters}` : ""}`,
10676
10796
  decode: (value) => {
10677
10797
  const source = record$1(value);
10678
- exact(source, ["action", "version"]);
10798
+ requiredFields(source, ["action", "version"]);
10679
10799
  if (source.version != 1) return invalidResponse();
10680
10800
  return connectorAction(source.action);
10681
10801
  }
@@ -10686,7 +10806,7 @@ function allConnectorConnectionsQuery(flowId) {
10686
10806
  path: `/v1/connector/connections${scope(flowId)}`,
10687
10807
  decode: (value) => {
10688
10808
  const source = record$1(value);
10689
- exact(source, ["connections", "version"]);
10809
+ requiredFields(source, ["connections", "version"]);
10690
10810
  if (source.version != 1 || !Array.isArray(source.connections)) return invalidResponse();
10691
10811
  return source.connections.map(connection);
10692
10812
  }
@@ -10697,7 +10817,7 @@ function connectorConnectionsQuery(serviceId, flowId) {
10697
10817
  path: `/v1/connector/connections/${encodeURIComponent(serviceId)}${scope(flowId)}`,
10698
10818
  decode: (value) => {
10699
10819
  const source = record$1(value);
10700
- exact(source, [
10820
+ requiredFields(source, [
10701
10821
  "connections",
10702
10822
  "serviceId",
10703
10823
  "version"
@@ -10722,6 +10842,7 @@ function resourceReferences(input) {
10722
10842
  if (accessRevision < 0) return invalidResponse();
10723
10843
  return {
10724
10844
  draft: draft == null ? null : {
10845
+ ...draft.calledFlowIds === void 0 ? {} : { calledFlowIds: strings(draft.calledFlowIds) },
10725
10846
  variableNames: strings(draft.variableNames),
10726
10847
  errorSourceFlowIds: strings(draft.errorSourceFlowIds),
10727
10848
  connections: draft.connections.map((value) => {
@@ -10752,10 +10873,11 @@ function flow(value) {
10752
10873
  if (source.version != 1) return invalidResponse();
10753
10874
  if (status != "active" && status != "retiring") return invalidResponse();
10754
10875
  const target = source.live == null ? void 0 : record$1(source.live);
10755
- if (target != null && typeof target.enabled != "boolean") return invalidResponse();
10876
+ if (target != null && (typeof target.enabled != "boolean" || typeof target.hasStart != "boolean")) return invalidResponse();
10756
10877
  return {
10757
10878
  ...target == null ? {} : { live: {
10758
10879
  enabled: target.enabled,
10880
+ hasStart: target.hasStart,
10759
10881
  publicationId: string(target.publicationId),
10760
10882
  revisionId: string(target.revisionId)
10761
10883
  } },
@@ -10770,6 +10892,15 @@ function flow(value) {
10770
10892
  version: 1
10771
10893
  };
10772
10894
  }
10895
+ function flowListItem(value) {
10896
+ const source = record$1(value);
10897
+ const referenceCount = integer(source.referenceCount);
10898
+ if (referenceCount < 0) return invalidResponse();
10899
+ return {
10900
+ ...flow(source),
10901
+ referenceCount
10902
+ };
10903
+ }
10773
10904
  function flowPage(value) {
10774
10905
  const source = record$1(value);
10775
10906
  if (source.version != 1 || !Array.isArray(source.flows)) return invalidResponse();
@@ -10779,14 +10910,14 @@ function flowPage(value) {
10779
10910
  if (total != null && !Number.isSafeInteger(total)) return invalidResponse();
10780
10911
  return {
10781
10912
  ...nextCursor == null ? {} : { nextCursor },
10782
- flows: source.flows.map(flow),
10913
+ flows: source.flows.map(flowListItem),
10783
10914
  ...total == null ? {} : { total },
10784
10915
  version: 1
10785
10916
  };
10786
10917
  }
10787
10918
  function variable(value) {
10788
10919
  const source = record$1(value);
10789
- exact(source, [
10920
+ requiredFields(source, [
10790
10921
  "name",
10791
10922
  "updatedAt",
10792
10923
  "value",
@@ -10806,6 +10937,15 @@ function variable(value) {
10806
10937
  version: 1
10807
10938
  };
10808
10939
  }
10940
+ function variableListItem(value) {
10941
+ const { referenceCount, ...fields } = record$1(value);
10942
+ const count = integer(referenceCount);
10943
+ if (count < 0) return invalidResponse();
10944
+ return {
10945
+ ...variable(fields),
10946
+ referenceCount: count
10947
+ };
10948
+ }
10809
10949
  function errorListener(value) {
10810
10950
  const source = record$1(value);
10811
10951
  if (typeof source.enabled != "boolean") return invalidResponse();
@@ -10819,17 +10959,13 @@ function errorListener(value) {
10819
10959
  }
10820
10960
  function variableReferences(input) {
10821
10961
  const source = record$1(input);
10822
- exact(source, [
10823
- "version",
10824
- "references",
10825
- "unknown"
10826
- ]);
10827
- if (source.version != 1 || !Array.isArray(source.references) || !Array.isArray(source.unknown)) return invalidResponse();
10962
+ requiredFields(source, ["version", "references"]);
10963
+ if (source.version != 1 || !Array.isArray(source.references)) return invalidResponse();
10828
10964
  return {
10829
10965
  version: 1,
10830
10966
  references: source.references.map((value) => {
10831
10967
  const item = record$1(value);
10832
- exact(item, [
10968
+ requiredFields(item, [
10833
10969
  "flowId",
10834
10970
  "flowName",
10835
10971
  "draft",
@@ -10838,7 +10974,7 @@ function variableReferences(input) {
10838
10974
  if (typeof item.draft != "boolean") return invalidResponse();
10839
10975
  const live = item.live === null ? null : record$1(item.live);
10840
10976
  if (live != null) {
10841
- exact(live, ["publicationId", "enabled"]);
10977
+ requiredFields(live, ["publicationId", "enabled"]);
10842
10978
  if (typeof live.enabled != "boolean") return invalidResponse();
10843
10979
  }
10844
10980
  return {
@@ -10850,20 +10986,6 @@ function variableReferences(input) {
10850
10986
  enabled: live.enabled
10851
10987
  }
10852
10988
  };
10853
- }),
10854
- unknown: source.unknown.map((value) => {
10855
- const item = record$1(value);
10856
- exact(item, [
10857
- "flowId",
10858
- "flowName",
10859
- "scope"
10860
- ]);
10861
- if (item.scope !== "draft" && item.scope !== "live") return invalidResponse();
10862
- return {
10863
- flowId: string(item.flowId),
10864
- flowName: string(item.flowName),
10865
- scope: item.scope
10866
- };
10867
10989
  })
10868
10990
  };
10869
10991
  }
@@ -10961,7 +11083,7 @@ function run(value) {
10961
11083
  }
10962
11084
  function runWaiting(value) {
10963
11085
  const source = record$1(value);
10964
- exact(source, [
11086
+ requiredFields(source, [
10965
11087
  "actions",
10966
11088
  "expiresAt",
10967
11089
  "nodeId",
@@ -10980,6 +11102,15 @@ function runWaiting(value) {
10980
11102
  waitingSince: string(source.waitingSince)
10981
11103
  };
10982
11104
  }
11105
+ function workflowIdentity(value) {
11106
+ const ref = record$1(value);
11107
+ return {
11108
+ flowId: string(ref.flowId),
11109
+ runId: string(ref.runId),
11110
+ nodeId: string(ref.nodeId),
11111
+ executionId: string(ref.executionId)
11112
+ };
11113
+ }
10983
11114
  function runDetails(value) {
10984
11115
  const source = record$1(value);
10985
11116
  const summary = run(source);
@@ -10987,20 +11118,24 @@ function runDetails(value) {
10987
11118
  if (eventsExpiresAt != null && typeof eventsExpiresAt != "string") return invalidResponse();
10988
11119
  if (source.waiting !== void 0 || !Array.isArray(source.waits)) return invalidResponse();
10989
11120
  const waits = source.waits.map(runWaiting);
10990
- if (new Set(waits.map((wait) => wait.waitId)).size != waits.length || summary.status == "waiting" && waits.length == 0 || [
11121
+ if (new Set(waits.map((wait) => wait.waitId)).size != waits.length || summary.status == "waiting" && waits.length == 0 && (!Array.isArray(source.calls) || source.calls.length == 0) || [
10991
11122
  "completed",
10992
11123
  "failed",
10993
11124
  "canceled",
10994
11125
  "indeterminate"
10995
11126
  ].includes(summary.status) && waits.length > 0) return invalidResponse();
10996
- if (source.occurrenceId === void 0 != (source.triggerNodeId === void 0)) return invalidResponse();
11127
+ if (source.occurrenceId !== void 0 && source.triggerNodeId === void 0) return invalidResponse();
10997
11128
  const state = {
10998
11129
  status: summary.status,
10999
11130
  waits
11000
11131
  };
11132
+ if (source.calls !== void 0 && !Array.isArray(source.calls)) return invalidResponse();
11001
11133
  const details = {
11002
11134
  ...summary,
11003
11135
  ...errorHandling(source),
11136
+ ...source.triggerNodeId === void 0 ? {} : { triggerNodeId: string(source.triggerNodeId) },
11137
+ ...source.caller === void 0 ? {} : { caller: workflowIdentity(source.caller) },
11138
+ ...source.calls === void 0 ? {} : { calls: source.calls.map((item) => Object.assign(workflowIdentity(item), { status: record$1(item).status === null ? null : runStatus(record$1(item).status) })) },
11004
11139
  closureDigest: string(source.closureDigest),
11005
11140
  engineContract: string(source.engineContract),
11006
11141
  engineDigest: string(source.engineDigest),
@@ -11051,7 +11186,7 @@ function runCancellation(value) {
11051
11186
  }
11052
11187
  function waitResolution(value) {
11053
11188
  const source = record$1(value);
11054
- exact(source, [
11189
+ requiredFields(source, [
11055
11190
  "action",
11056
11191
  "comment",
11057
11192
  "resolutionAccepted",
@@ -11268,7 +11403,7 @@ function decodeRunEvent(value) {
11268
11403
  switch (kind) {
11269
11404
  case "node.started": {
11270
11405
  const nodeKind = payload.nodeKind;
11271
- if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "wait") return invalidResponse();
11406
+ if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "outputs" && nodeKind !== "workflow" && nodeKind !== "wait") return invalidResponse();
11272
11407
  return {
11273
11408
  ...base,
11274
11409
  kind,
@@ -11395,14 +11530,14 @@ var ControlClient = class {
11395
11530
  if (options.limit != null) parameters.set("limit", String(options.limit));
11396
11531
  if (options.includeTotal != null) parameters.set("includeTotal", String(options.includeTotal));
11397
11532
  const query = parameters.size == 0 ? "" : `?${parameters}`;
11398
- return flowPage(await this.request(`/v1/flows${query}`));
11533
+ return flowPage(await this.request(`/v1/flows${query}`, options.signal == null ? void 0 : { signal: options.signal }));
11399
11534
  }
11400
11535
  async listEventSources(flowId, signal) {
11401
11536
  return decodeEventSources(await this.request("/v1/event-sources" + (flowId == null ? "" : `?flowId=${segment(flowId)}`), { signal }));
11402
11537
  }
11403
11538
  async listEventSourceConnections(teamId, signal) {
11404
11539
  const source = record$1(await this.request(`/v1/event-sources/connections${teamId == null ? "" : `?teamId=${segment(teamId)}`}`, { signal }));
11405
- exact(source, ["version", "connections"]);
11540
+ requiredFields(source, ["version", "connections"]);
11406
11541
  if (source.version != 1 || !Array.isArray(source.connections)) return invalidResponse();
11407
11542
  return source.connections.map(connection);
11408
11543
  }
@@ -11429,13 +11564,24 @@ var ControlClient = class {
11429
11564
  }
11430
11565
  async listVariables() {
11431
11566
  const source = record$1(await this.request("/v1/variables"));
11432
- exact(source, ["variables", "version"]);
11567
+ requiredFields(source, ["variables", "version"]);
11433
11568
  if (source.version != 1 || !Array.isArray(source.variables)) return invalidResponse();
11434
11569
  return {
11435
- variables: source.variables.map(variable),
11570
+ variables: source.variables.map(variableListItem),
11436
11571
  version: 1
11437
11572
  };
11438
11573
  }
11574
+ async getFlowReferences(flowId, options = {}) {
11575
+ const query = new URLSearchParams({
11576
+ direction: options.direction ?? "incoming",
11577
+ offset: String(options.offset ?? 0),
11578
+ limit: String(options.limit ?? 50)
11579
+ });
11580
+ return workflowReferencesSchema.parse(await this.request(`/v1/flows/${segment(flowId)}/references?${query}`, { signal: options.signal }));
11581
+ }
11582
+ async getWorkflowContract(flowId, signal) {
11583
+ return workflowContractSchema.parse(await this.request(`/v1/flows/${segment(flowId)}/call-contract`, { signal }));
11584
+ }
11439
11585
  async getVariableReferences(name, signal) {
11440
11586
  return variableReferences(await this.request(`/v1/variables/${segment(name)}/references`, { signal }));
11441
11587
  }
@@ -11450,7 +11596,7 @@ var ControlClient = class {
11450
11596
  }
11451
11597
  async deleteVariable(name) {
11452
11598
  const source = record$1(await this.request(`/v1/variables/${segment(name)}`, { method: "DELETE" }));
11453
- exact(source, ["version"]);
11599
+ requiredFields(source, ["version"]);
11454
11600
  if (source.version != 1) return invalidResponse();
11455
11601
  }
11456
11602
  async exportFlow(flowId) {
@@ -11492,7 +11638,7 @@ var ControlClient = class {
11492
11638
  command
11493
11639
  })
11494
11640
  }));
11495
- exact(source, [
11641
+ requiredFields(source, [
11496
11642
  "version",
11497
11643
  "flowId",
11498
11644
  "broadcast"
@@ -11632,11 +11778,11 @@ var ControlClient = class {
11632
11778
  }
11633
11779
  async listTriggerConfigOptions(flowId, nodeId, field, signal) {
11634
11780
  const source = record$1(await this.request(`/v1/flows/${segment(flowId)}/triggers/${segment(nodeId)}/options/${segment(field)}`, { signal }));
11635
- exact(source, ["options", "version"]);
11781
+ requiredFields(source, ["options", "version"]);
11636
11782
  if (source.version != 1 || !Array.isArray(source.options) || source.options.length > 1e3) return invalidResponse();
11637
11783
  return source.options.map((value) => {
11638
11784
  const item = record$1(value);
11639
- exact(item, [
11785
+ requiredFields(item, [
11640
11786
  "value",
11641
11787
  "label",
11642
11788
  ...item.color == null ? [] : ["color"]
@@ -11655,7 +11801,7 @@ var ControlClient = class {
11655
11801
  }
11656
11802
  async listConnectorTeams(signal) {
11657
11803
  const source = record$1(await this.request("/v1/connector/teams", { signal }));
11658
- exact(source, [
11804
+ requiredFields(source, [
11659
11805
  "enabled",
11660
11806
  "teams",
11661
11807
  "version"
@@ -11665,7 +11811,7 @@ var ControlClient = class {
11665
11811
  enabled: source.enabled,
11666
11812
  teams: source.teams.map((value) => {
11667
11813
  const team = record$1(value);
11668
- exact(team, [
11814
+ requiredFields(team, [
11669
11815
  "id",
11670
11816
  "name",
11671
11817
  "systemCreated"
@@ -11778,7 +11924,7 @@ var ControlClient = class {
11778
11924
  body: JSON.stringify({ version: 1 }),
11779
11925
  method: "POST"
11780
11926
  }));
11781
- exact(source, ["url", "version"]);
11927
+ requiredFields(source, ["url", "version"]);
11782
11928
  if (source.version != 1) return invalidResponse();
11783
11929
  try {
11784
11930
  const url = new URL(string(source.url));
@@ -11840,6 +11986,16 @@ var ControlClient = class {
11840
11986
  method: "POST"
11841
11987
  }));
11842
11988
  }
11989
+ async upgradeDraft(flowId, expectedRevisionId, options = {}) {
11990
+ return draftChange(await this.request(`/v1/flows/${segment(flowId)}/draft/upgrade`, {
11991
+ body: JSON.stringify({
11992
+ expectedRevisionId,
11993
+ version: 1
11994
+ }),
11995
+ headers: { "idempotency-key": options.idempotencyKey ?? operationKey("upgrade") },
11996
+ method: "POST"
11997
+ }));
11998
+ }
11843
11999
  async checkFlow(flowId, revisionId) {
11844
12000
  return flowCheck(await this.request(`/v1/flows/${segment(flowId)}/revisions/${segment(revisionId)}/check`, {
11845
12001
  body: JSON.stringify({
@@ -11982,7 +12138,7 @@ var ControlClient = class {
11982
12138
  const suffix = query == "" ? "" : `?${query}`;
11983
12139
  return this.connectorRequest(`/v1/connector/actions${suffix}`, "actions", signal, (value) => {
11984
12140
  const source = record$1(value);
11985
- exact(source, ["actions", "version"]);
12141
+ requiredFields(source, ["actions", "version"]);
11986
12142
  if (source.version != 1 || !Array.isArray(source.actions)) return invalidResponse();
11987
12143
  return source.actions.map(connectorAction);
11988
12144
  });
@@ -12119,15 +12275,16 @@ function addValueNode(harness, flowId, revisionId, nodeId = "marker", changeId)
12119
12275
  nodeId
12120
12276
  }], changeId);
12121
12277
  }
12122
- async function addManualTrigger(harness, flowId, revisionId) {
12278
+ async function addStartTrigger(harness, flowId, revisionId) {
12123
12279
  return changedRevisionId(await json(await changeRequest(harness, flowId, revisionId, [{
12124
12280
  kind: "graph.node.create",
12125
12281
  node: {
12126
- kind: "manual",
12282
+ inputDefs: [],
12283
+ kind: "start",
12127
12284
  name: "Start"
12128
12285
  },
12129
12286
  nodeId: "start"
12130
- }]), 200, "Add manual trigger"), "Manual trigger Revision");
12287
+ }]), 200, "Add Start node"), "Start Revision");
12131
12288
  }
12132
12289
  function changedRevisionId(change, message) {
12133
12290
  return requiredString(record(change.revision, `${message} revision`).revisionId, `${message} revisionId`);
@@ -12216,7 +12373,10 @@ var controlApiConformanceCases = [
12216
12373
  const idempotencyKey = crypto.randomUUID();
12217
12374
  const created = await api.importFlow(file, { idempotencyKey });
12218
12375
  equal(dequal(await api.importFlow(file, { idempotencyKey }), created), true, "Import retry must return the same Flow.");
12219
- equal(dequal(await api.exportFlow(created.flowId), file), true, "Export must retain the graph and Presentation.");
12376
+ equal(dequal(await api.exportFlow(created.flowId), {
12377
+ ...file,
12378
+ content: upgradeRevisionContent(file.content)
12379
+ }), true, "Export must upgrade legacy Manual nodes and retain the graph and Presentation.");
12220
12380
  const editor = await api.getEditor(created.flowId);
12221
12381
  equal(editor.live.publication == null, true, "Import must not publish.");
12222
12382
  equal(editor.draft.parentRevisionId == null, true, "Import must create an initial Revision.");
@@ -12323,12 +12483,107 @@ var controlApiConformanceCases = [
12323
12483
  equal((await api.checkAuthoring(flow.flowId, changed.revision)).revisionId, changed.revision, "Fixed check identity");
12324
12484
  }
12325
12485
  },
12486
+ {
12487
+ name: "authors Start parameters and admits their shared call contract",
12488
+ async verify(harness) {
12489
+ const api = client(harness), flow = await api.createFlow("Start parameters");
12490
+ equal((await api.authoringSchema(flow.flowId, { type: "start" })).type, "start", "Start discovery");
12491
+ const created = await api.editAuthoring(flow.flowId, {
12492
+ baseRevision: flow.draftRevisionId,
12493
+ requestId: "start-parameters-create",
12494
+ edits: [{
12495
+ op: "node.add",
12496
+ as: "start",
12497
+ type: "start",
12498
+ name: "Start",
12499
+ config: { inputDefs: {
12500
+ message: {
12501
+ schema: { type: "string" },
12502
+ nullable: false,
12503
+ description: "Original"
12504
+ },
12505
+ note: {
12506
+ schema: { type: "string" },
12507
+ nullable: true
12508
+ }
12509
+ } }
12510
+ }]
12511
+ });
12512
+ const nodeId = created.nodes.start;
12513
+ const changed = await api.editAuthoring(flow.flowId, {
12514
+ baseRevision: created.revision,
12515
+ requestId: "start-parameters-update",
12516
+ edits: [{
12517
+ op: "node.update",
12518
+ node: nodeId,
12519
+ set: { config: { inputDefs: { message: { description: "Call message" } } } }
12520
+ }]
12521
+ });
12522
+ equal(((await api.readAuthoring(flow.flowId, { nodes: [nodeId] })).data.nodes?.[0]?.config)?.inputDefs, {
12523
+ message: {
12524
+ schema: { type: "string" },
12525
+ nullable: false,
12526
+ description: "Call message"
12527
+ },
12528
+ note: {
12529
+ schema: { type: "string" },
12530
+ nullable: true
12531
+ }
12532
+ }, "Local parameter update preserves the contract");
12533
+ const runPath = `/v1/flows/${flow.flowId}/revisions/${changed.revision}/runs`;
12534
+ const run = (outputs, key) => request(harness, runPath, {
12535
+ method: "POST",
12536
+ headers: { "idempotency-key": key },
12537
+ body: JSON.stringify({
12538
+ engineContract,
12539
+ inputs: {},
12540
+ trigger: {
12541
+ nodeId,
12542
+ outputs
12543
+ },
12544
+ version: 2
12545
+ })
12546
+ });
12547
+ for (const [index, outputs] of [
12548
+ {},
12549
+ { message: 0 },
12550
+ {
12551
+ message: "Hello",
12552
+ extra: true
12553
+ }
12554
+ ].entries()) await error(await run(outputs, `start-invalid-${index}`), 400, "run.invalid", "Reject invalid Start parameters");
12555
+ const admitted = await json(await run({ message: "Hello" }, "start-call"), 202, "Admit omitted nullable parameter");
12556
+ equal(await json(await run({ message: "Hello" }, "start-call"), 200, "Replay Start call"), admitted, "Stable Start admission");
12557
+ await error(await run({
12558
+ message: "Hello",
12559
+ note: null
12560
+ }, "start-call"), 409, "run.conflict", "Preserve original request identity before normalization");
12561
+ await json(await run({
12562
+ message: "Hello",
12563
+ note: null
12564
+ }, "start-explicit-null"), 202, "Admit explicit null");
12565
+ equal(((await api.readAuthoring(flow.flowId, {
12566
+ revision: created.revision,
12567
+ nodes: [nodeId]
12568
+ })).data.nodes?.[0]?.config)?.inputDefs, {
12569
+ message: {
12570
+ schema: { type: "string" },
12571
+ nullable: false,
12572
+ description: "Original"
12573
+ },
12574
+ note: {
12575
+ schema: { type: "string" },
12576
+ nullable: true
12577
+ }
12578
+ }, "Fixed Start read preserves old configuration");
12579
+ }
12580
+ },
12326
12581
  {
12327
12582
  name: "admits simultaneous retries as one Run and preserves its Trigger identity",
12328
12583
  async verify(harness) {
12329
12584
  const flow = await createFlow(harness, "Concurrent Run", "concurrent-run-flow");
12330
12585
  const flowId = requiredString(flow.flowId, "Flow ID");
12331
- const revisionId = await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Revision ID"));
12586
+ const revisionId = await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Revision ID"));
12332
12587
  const submit = (payload = {}) => request(harness, `/v1/flows/${flowId}/revisions/${revisionId}/runs`, {
12333
12588
  method: "POST",
12334
12589
  headers: { "idempotency-key": "concurrent-run" },
@@ -12458,6 +12713,7 @@ var controlApiConformanceCases = [
12458
12713
  equal(created.name, "Control flow", "Created Flow name");
12459
12714
  equal(created.status, "active", "Created Flow status");
12460
12715
  equal(record(created.resourceReferences, "Flow resource references").draft, {
12716
+ calledFlowIds: [],
12461
12717
  variableNames: [],
12462
12718
  connections: [],
12463
12719
  errorSourceFlowIds: []
@@ -12466,13 +12722,22 @@ var controlApiConformanceCases = [
12466
12722
  await error(await createFlowRequest(harness, "Different flow", "flow-lifecycle"), 409, "flow.conflict", "Conflicting Flow");
12467
12723
  equal(await json(await request(harness, `/v1/flows/${flowId}`), 200, "Read Flow"), created, "Read Flow");
12468
12724
  const page = await json(await request(harness, "/v1/flows?includeTotal=true"), 200, "List Flows");
12469
- equal(page.flows, [created], "Listed Flows");
12725
+ equal(page.flows, [{
12726
+ ...created,
12727
+ referenceCount: 0
12728
+ }], "Listed Flows");
12470
12729
  equal(page.total, 1, "Flow total");
12471
12730
  const second = await createFlow(harness, "Second control flow", "flow-lifecycle-second");
12472
12731
  const firstPage = await json(await request(harness, "/v1/flows?limit=1"), 200, "List first Flow page");
12473
- equal(firstPage.flows, [created], "First Flow page");
12732
+ equal(firstPage.flows, [{
12733
+ ...created,
12734
+ referenceCount: 0
12735
+ }], "First Flow page");
12474
12736
  const cursor = requiredString(firstPage.nextCursor, "Flow cursor");
12475
- equal((await json(await request(harness, `/v1/flows?limit=1&cursor=${encodeURIComponent(cursor)}`), 200, "List second Flow page")).flows, [second], "Second Flow page");
12737
+ equal((await json(await request(harness, `/v1/flows?limit=1&cursor=${encodeURIComponent(cursor)}`), 200, "List second Flow page")).flows, [{
12738
+ ...second,
12739
+ referenceCount: 0
12740
+ }], "Second Flow page");
12476
12741
  equal((await json(await request(harness, `/v1/flows/${flowId}`, {
12477
12742
  body: JSON.stringify({
12478
12743
  name: "Renamed flow",
@@ -12629,7 +12894,7 @@ var controlApiConformanceCases = [
12629
12894
  async verify(harness) {
12630
12895
  const flow = await createFlow(harness, "Partial Draft", "partial-draft");
12631
12896
  const flowId = requiredString(flow.flowId, "Partial Flow identity");
12632
- const revisionId = changedRevisionId(await json(await changeRequest(harness, flowId, await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Partial Draft identity")), [
12897
+ const revisionId = changedRevisionId(await json(await changeRequest(harness, flowId, await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Partial Draft identity")), [
12633
12898
  {
12634
12899
  kind: "graph.node.create",
12635
12900
  nodeId: "other",
@@ -12699,7 +12964,7 @@ var controlApiConformanceCases = [
12699
12964
  async verify(harness) {
12700
12965
  const flow = await createFlow(harness, "Run flow", "run-flow");
12701
12966
  const flowId = requiredString(flow.flowId, "Run Flow flowId");
12702
- const draftRevisionId = await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Run Flow revisionId"));
12967
+ const draftRevisionId = await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Run Flow revisionId"));
12703
12968
  equal((await json(await request(harness, `/v1/flows/${flowId}/revisions/${draftRevisionId}/check`, {
12704
12969
  body: JSON.stringify({
12705
12970
  engineContract,
@@ -12823,7 +13088,7 @@ var controlApiConformanceCases = [
12823
13088
  async verify(harness) {
12824
13089
  const flow = await createFlow(harness, "Wait flow", "wait-flow");
12825
13090
  const flowId = requiredString(flow.flowId, "Wait Flow flowId");
12826
- const runPath = `/v1/flows/${flowId}/revisions/${changedRevisionId(await json(await changeRequest(harness, flowId, await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Wait Flow revisionId")), [{
13091
+ const runPath = `/v1/flows/${flowId}/revisions/${changedRevisionId(await json(await changeRequest(harness, flowId, await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Wait Flow revisionId")), [{
12827
13092
  kind: "graph.node.create",
12828
13093
  node: {
12829
13094
  inputDefinitions: [{
@@ -12995,7 +13260,7 @@ var publicationControlApiConformanceCases = [
12995
13260
  async verify(harness) {
12996
13261
  const flow = await createFlow(harness, "Enabled flow", "enabled-flow");
12997
13262
  const flowId = requiredString(flow.flowId, "Flow id");
12998
- const revisionId = await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Draft id"));
13263
+ const revisionId = await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Draft id"));
12999
13264
  const change = (enabled, expectedPublicationId) => request(harness, `/v1/flows/${flowId}/enabled`, {
13000
13265
  method: "PUT",
13001
13266
  body: JSON.stringify({
@@ -13009,10 +13274,14 @@ var publicationControlApiConformanceCases = [
13009
13274
  const disabled = await json(await change(false, publicationId), 200, "Disable");
13010
13275
  equal(disabled.live, {
13011
13276
  enabled: false,
13277
+ hasStart: true,
13012
13278
  publicationId,
13013
13279
  revisionId
13014
13280
  }, "Disabled summary");
13015
- equal((await json(await request(harness, "/v1/flows"), 200, "List disabled Flow")).flows, [disabled], "List includes Live state");
13281
+ equal((await json(await request(harness, "/v1/flows"), 200, "List disabled Flow")).flows, [{
13282
+ ...disabled,
13283
+ referenceCount: 0
13284
+ }], "List includes Live state");
13016
13285
  equal((await json(await request(harness, `/v1/flows/${flowId}/live`), 200, "Disabled Live")).status, "suspended", "Disabled Live status");
13017
13286
  await error(await liveRunRequest(harness, publicationId, "disabled-run"), 412, "live.conflict", "Disabled Live rejects Run");
13018
13287
  await json(await request(harness, `/v1/flows/${flowId}/revisions/${revisionId}/runs`, {
@@ -13040,7 +13309,7 @@ var publicationControlApiConformanceCases = [
13040
13309
  async verify(harness) {
13041
13310
  const flow = await createFlow(harness, "Publication flow", "publication-flow");
13042
13311
  const flowId = requiredString(flow.flowId, "Publication Flow flowId");
13043
- const draftRevisionId = await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Publication Flow revisionId"));
13312
+ const draftRevisionId = await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Publication Flow revisionId"));
13044
13313
  equal((await json(await request(harness, `/v1/flows/${flowId}/live`), 200, "Read Live")).status, "not-published", "Initial Live status");
13045
13314
  const publish = () => publishRequest(harness, flowId, draftRevisionId, null, "publication-first");
13046
13315
  const completed = await completePublish(harness, await publish(), 202, "Publish Flow");
@@ -13073,7 +13342,7 @@ var publicationControlApiConformanceCases = [
13073
13342
  async verify(harness) {
13074
13343
  const flow = await createFlow(harness, "Rollback flow", "rollback-flow");
13075
13344
  const flowId = requiredString(flow.flowId, "Rollback Flow flowId");
13076
- const firstRevisionId = await addManualTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Rollback Flow revisionId"));
13345
+ const firstRevisionId = await addStartTrigger(harness, flowId, requiredString(flow.draftRevisionId, "Rollback Flow revisionId"));
13077
13346
  const layoutApi = client(harness);
13078
13347
  const initialLayout = await layoutApi.getPresentation(flowId);
13079
13348
  const publishedLayout = await json(await request(harness, `/v1/flows/${flowId}/presentation`, {
@@ -13434,7 +13703,7 @@ function selectableConnectorAccessControlApiConformanceCases(fixture) {
13434
13703
  equal(record(binding, "Selected Connector access binding").connectionDisplayName, fixture.connectionDisplayName, "Selected Provider access binding connection display name");
13435
13704
  equal(record(binding, "Selected Connector access binding").permissionGroupName, fixture.permissionGroupName, "Selected Provider access binding permission group name");
13436
13705
  const selectedDigest = requiredString(selected.sharedAccessDigest, "Selected Connector access digest");
13437
- const revisionId = await addManualTrigger(harness, flowId, requiredString(created.draftRevisionId, "Draft Revision ID"));
13706
+ const revisionId = await addStartTrigger(harness, flowId, requiredString(created.draftRevisionId, "Draft Revision ID"));
13438
13707
  equal((await json(await request(harness, `/v1/flows/${flowId}/revisions/${revisionId}/runs`, {
13439
13708
  body: JSON.stringify({
13440
13709
  engineContract,