@oomol-lab/open-flow 0.1.0-beta.61 → 0.1.0-beta.63

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 (55) hide show
  1. package/dist/browser/{createResourceDialog-D71fO68i.js → createResourceDialog-BAJXbzNH.js} +20 -7
  2. package/dist/browser/flow-authoring.js +8 -7
  3. package/dist/browser/flow-change-schema.d.ts +1 -0
  4. package/dist/browser/flow-change.d.ts +1 -0
  5. package/dist/browser/flow-change.js +8 -7
  6. package/dist/browser/{flowChanges-DSA0FxxN.js → flowChanges-DpZOQuJE.js} +3001 -2588
  7. package/dist/browser/{flowRunInputEditorStore-Dsxyfwae.js → flowRunInputEditorStore-B2Rw4VsT.js} +1 -1
  8. package/dist/browser/{flowWorkspace-0sUJ5JhQ.js → flowWorkspace-B7a5NNA_.js} +217 -83
  9. package/dist/browser/{icons-DVJvrj1H.js → icons-Db2Jb2iX.js} +2907 -2887
  10. package/dist/browser/preview.css +5 -6
  11. package/dist/browser/preview.js +889 -541
  12. package/dist/browser/{typeScriptSession-fXPMFGjW.js → typeScriptSession-D0bjYDeg.js} +1 -1
  13. package/dist/browser/ui.css +4 -5
  14. package/dist/browser/ui.js +2 -2
  15. package/dist/browser/{value-DL_poNiC.js → value-BADHeZ9I.js} +12 -1
  16. package/dist/browser/workbench-contract.d.ts +10 -0
  17. package/dist/browser/workbench.css +9 -26
  18. package/dist/browser/workbench.d.ts +5 -3
  19. package/dist/browser/workbench.js +272 -178
  20. package/dist/browser/{workbenchSelect-cr4-mKq3.js → workbenchSelect-C-jf6NIM.js} +1 -1
  21. package/dist/command/index.js +45 -44
  22. package/dist/common/authoring.d.ts +1 -1
  23. package/dist/common/authoringSchema.d.ts +1 -0
  24. package/dist/common/connector-action.d.ts +1 -0
  25. package/dist/common/connector-action.js +15 -12
  26. package/dist/common/control-api-conformance.js +1371 -1207
  27. package/dist/common/control-api-errors.d.ts +0 -4
  28. package/dist/common/control-api.d.ts +18 -11
  29. package/dist/common/control-api.js +2053 -2274
  30. package/dist/common/control-requests.d.ts +6 -0
  31. package/dist/common/control-requests.js +64 -33
  32. package/dist/common/decision.js +8 -7
  33. package/dist/common/flow-connectionUsage.d.ts +1 -0
  34. package/dist/common/flow-encoding.d.ts +1 -0
  35. package/dist/common/flow-encoding.js +202 -10
  36. package/dist/common/flow-semantics.js +64 -46
  37. package/dist/common/flow-workflowFile.d.ts +23 -0
  38. package/dist/common/integration-trigger.js +8 -7
  39. package/dist/common/liveDetails.d.ts +138 -0
  40. package/dist/common/localization.d.ts +1 -0
  41. package/dist/common/localization.js +12 -1
  42. package/dist/common/mcp.d.ts +55 -26
  43. package/dist/common/mcp.js +377 -245
  44. package/dist/common/openapi.js +8 -7
  45. package/dist/common/poll-trigger.js +8 -7
  46. package/dist/common/runtime-contract.js +1 -1
  47. package/dist/common/scheduler.d.ts +22 -2
  48. package/dist/common/scheduler.js +354 -83
  49. package/dist/common/trigger-config.d.ts +2 -0
  50. package/dist/common/webhook-trigger.js +8 -7
  51. package/dist/index.d.ts +2 -2
  52. package/package.json +1 -1
  53. package/skills/open-flow/SKILL.md +6 -3
  54. package/skills/open-flow/references/flow-authoring.md +48 -24
  55. package/dist/common/publicationResources.d.ts +0 -29
@@ -6850,10 +6850,10 @@ function compileEnumAndConst(context, enumList, constValue, schema) {
6850
6850
  }
6851
6851
  if (compiledEnum.length === 0) recordWarn(context, "all of elements from list is rejected by currently schema object", "enum");
6852
6852
  }
6853
- if (constValue && valid(schema, constValue) === ValidResult.Invalid) isNever = true;
6853
+ if (constValue !== void 0 && valid(schema, constValue) === ValidResult.Invalid) isNever = true;
6854
6854
  if (compiledEnum) {
6855
6855
  if (compiledEnum.length === 0) isNever = true;
6856
- else if (constValue) {
6856
+ else if (constValue !== void 0) {
6857
6857
  let foundEquals = false;
6858
6858
  for (const enumValue of compiledEnum) if (isDeepEquals(enumValue, constValue)) {
6859
6859
  foundEquals = true;
@@ -6866,7 +6866,7 @@ function compileEnumAndConst(context, enumList, constValue, schema) {
6866
6866
  const compiledSchema = {};
6867
6867
  if (schema.type) compiledSchema.type = schema.type;
6868
6868
  if (compiledEnum) compiledSchema.enum = compiledEnum;
6869
- if (constValue) compiledSchema.const = wrapCompiledValue(deepCopy(constValue));
6869
+ if (constValue !== void 0) compiledSchema.const = wrapCompiledValue(deepCopy(constValue));
6870
6870
  return wrapCompiledSchema(kind, compiledSchema, context.delegate, context.path);
6871
6871
  }
6872
6872
  //#endregion
@@ -7261,7 +7261,7 @@ function compileSchema(context, schema) {
7261
7261
  let targetSchema = schema;
7262
7262
  let shouldHandleEnumAndConst = false;
7263
7263
  const { enum: enumList, const: constValue } = schema;
7264
- if (enumList || constValue) {
7264
+ if (enumList || constValue !== void 0) {
7265
7265
  const { enum: _0, const: _1, ...rest } = schema;
7266
7266
  targetSchema = rest;
7267
7267
  shouldHandleEnumAndConst = true;
@@ -7851,7 +7851,7 @@ function schemaEqualsChecker(extendsContext) {
7851
7851
  }
7852
7852
  function isValueEquals(value1, value2) {
7853
7853
  if (value1 === value2) return true;
7854
- if (value1 === null) return false;
7854
+ if (value1 === null || value2 === null) return false;
7855
7855
  if (typeof value1 !== "object") return false;
7856
7856
  if (typeof value1 !== typeof value2) return false;
7857
7857
  if (isCompiledSchema(value1) && isCompiledSchema(value2)) return isCompiledSchemaEquals(value1, value2);
@@ -8417,7 +8417,7 @@ function findMismatchPath(source, target) {
8417
8417
  if ((sourceSchema.maxProperties ?? Number.POSITIVE_INFINITY) > (targetSchema.maxProperties ?? Number.POSITIVE_INFINITY)) return [...targetPath, "maxProperties"];
8418
8418
  break;
8419
8419
  }
8420
- case CompiledKind.EnumOrConst: return [...targetPath, targetSchema.const == null ? "enum" : "const"];
8420
+ case CompiledKind.EnumOrConst: return [...targetPath, targetSchema.const === void 0 ? "enum" : "const"];
8421
8421
  }
8422
8422
  return targetPath;
8423
8423
  }
@@ -8776,6 +8776,9 @@ var webhookMethods = [
8776
8776
  "PATCH",
8777
8777
  "DELETE"
8778
8778
  ];
8779
+ function webhookSupportsBody(method) {
8780
+ return method !== "GET";
8781
+ }
8779
8782
  var text = string$1();
8780
8783
  var json$3 = json$4();
8781
8784
  var strings$1 = array(text);
@@ -8891,7 +8894,8 @@ var managedFields = object({
8891
8894
  object({
8892
8895
  kind: literal("connector"),
8893
8896
  action: text,
8894
- connectionId: text.optional()
8897
+ connectionId: text.optional(),
8898
+ outputMode: literal("value").optional()
8895
8899
  }),
8896
8900
  object({
8897
8901
  kind: literal("openapi"),
@@ -9151,7 +9155,7 @@ var graph = object({
9151
9155
  nodes: record$2(text, node),
9152
9156
  edges: array(edge).default([])
9153
9157
  });
9154
- var binding = object({
9158
+ var binding$1 = object({
9155
9159
  kind: literal("variable"),
9156
9160
  target: text
9157
9161
  });
@@ -9161,7 +9165,7 @@ var module = object({
9161
9165
  source: text
9162
9166
  });
9163
9167
  var document = preprocess(rejectRetiredDefinitions, object({
9164
- bindings: record$2(text, binding),
9168
+ bindings: record$2(text, binding$1),
9165
9169
  graph
9166
9170
  }));
9167
9171
  var revision = object({
@@ -9205,7 +9209,7 @@ var shapes = {
9205
9209
  },
9206
9210
  "binding.create": {
9207
9211
  bindingId: text,
9208
- binding
9212
+ binding: binding$1
9209
9213
  },
9210
9214
  "binding.delete": { bindingId: text },
9211
9215
  "binding.target.set": {
@@ -9406,7 +9410,7 @@ var authenticationSchema = union([
9406
9410
  in: _enum(["header", "query"])
9407
9411
  })
9408
9412
  ]);
9409
- strictObject({
9413
+ var authoringOpenApiSchema = strictObject({
9410
9414
  sourceUrl: string$1().min(1),
9411
9415
  path: string$1().min(1),
9412
9416
  method: string$1().min(1),
@@ -9503,36 +9507,53 @@ var when = union([
9503
9507
  all,
9504
9508
  strictObject({ any: array(union([expression, all])) })
9505
9509
  ]);
9506
- strictObject({}), strictObject({ sourceFlowIds: array(id$2).optional() }), authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(), strictObject({ schedule: authoringDefinitionSchemas.schedule }), strictObject({
9507
- key: id$2,
9508
- connectionId: id$2.optional(),
9509
- schedule: authoringDefinitionSchemas.schedule
9510
- }), strictObject({
9511
- key: id$2,
9512
- connectionId: id$2.optional()
9513
- }), strictObject({
9514
- inputs: inputFields,
9515
- outputs: outputFields,
9516
- capabilities: authoringDefinitionSchemas.capabilities.optional()
9517
- }), authoringDefinitionSchemas.connector.strict(), authoringDefinitionSchemas.agent.omit({
9518
- prompt: true,
9519
- tools: true
9520
- }).extend({
9521
- inputs: inputFields,
9522
- resultSchema: json$2.describe("JSON schema of the final result. Defaults to text. The tool manages the output definition; references can omit port."),
9523
- tools: array(agentTool),
9524
- notification: notification.optional()
9525
- }).strict(), authoringLlmConfiguration.extend({ inputs: inputFields }), authoringDefinitionSchemas.decision, strictObject({
9526
- match: _enum(["first", "all"]),
9527
- branches: array(strictObject({
9528
- name: id$2,
9529
- description: string$1().optional(),
9530
- when
9531
- }))
9532
- }), strictObject({
9533
- values: patch,
9534
- outputs: outputFields
9535
- }), strictObject({ inputs: inputFields }), strictObject({ inputs: inputFields });
9510
+ var authoringConfigurations = {
9511
+ manual: strictObject({}),
9512
+ error: strictObject({ sourceFlowIds: array(id$2).optional() }),
9513
+ webhook: authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
9514
+ cron: strictObject({ schedule: authoringDefinitionSchemas.schedule }),
9515
+ poll: strictObject({
9516
+ key: id$2,
9517
+ connectionId: id$2.optional(),
9518
+ schedule: authoringDefinitionSchemas.schedule
9519
+ }),
9520
+ integration: strictObject({
9521
+ key: id$2,
9522
+ connectionId: id$2.optional()
9523
+ }),
9524
+ code: strictObject({
9525
+ inputs: inputFields,
9526
+ outputs: outputFields,
9527
+ capabilities: authoringDefinitionSchemas.capabilities.optional()
9528
+ }),
9529
+ connector: authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
9530
+ openapi: authoringOpenApiSchema,
9531
+ agent: authoringDefinitionSchemas.agent.omit({
9532
+ prompt: true,
9533
+ tools: true
9534
+ }).extend({
9535
+ inputs: inputFields,
9536
+ resultSchema: json$2.describe("JSON schema of the final result. Defaults to text. The tool manages the output definition; references can omit port."),
9537
+ tools: array(agentTool),
9538
+ notification: notification.optional()
9539
+ }).strict(),
9540
+ llm: authoringLlmConfiguration.extend({ inputs: inputFields }),
9541
+ decision: authoringDefinitionSchemas.decision,
9542
+ condition: strictObject({
9543
+ match: _enum(["first", "all"]),
9544
+ branches: array(strictObject({
9545
+ name: id$2,
9546
+ description: string$1().optional(),
9547
+ when
9548
+ }))
9549
+ }),
9550
+ value: strictObject({
9551
+ values: patch,
9552
+ outputs: outputFields
9553
+ }),
9554
+ wait: strictObject({ inputs: inputFields }),
9555
+ approval: strictObject({ inputs: inputFields })
9556
+ };
9536
9557
  var updates = strictObject({
9537
9558
  name: id$2.optional(),
9538
9559
  description: string$1().optional(),
@@ -9720,7 +9741,6 @@ var controlErrorCode = {
9720
9741
  publicationConflict: "publication.conflict",
9721
9742
  publicationNotFound: "publication.not-found",
9722
9743
  publicationUnsupported: "publication.unsupported",
9723
- resourceNotFound: "resource.not-found",
9724
9744
  publishOperationNotFound: "publication.operation-not-found",
9725
9745
  routeNotFound: "route.not-found",
9726
9746
  runConflict: "run.conflict",
@@ -9737,7 +9757,7 @@ var controlErrorCode = {
9737
9757
  variableLimitReached: "variable.limit-reached",
9738
9758
  variableNotFound: "variable.not-found"
9739
9759
  };
9740
- controlErrorCode.eventSourceInvalid, controlErrorCode.eventSourceIdentityUnavailable, controlErrorCode.eventSourceNotFound, controlErrorCode.eventSourceConflict, controlErrorCode.authenticationRequired, controlErrorCode.authorizationDenied, controlErrorCode.bindingUnresolved, controlErrorCode.connectorActionNotFound, controlErrorCode.connectorAccessConflict, controlErrorCode.connectorAccessInvalid, controlErrorCode.connectorAccessRequired, controlErrorCode.connectorAccessUnsupported, controlErrorCode.connectorUnconfigured, controlErrorCode.connectorUnavailable, controlErrorCode.connectorConsoleUnconfigured, controlErrorCode.engineUnavailable, controlErrorCode.engineUnsupported, controlErrorCode.flowInvalid, controlErrorCode.flowRepairRequired, controlErrorCode.flowUpgradeRequired, controlErrorCode.flowNotFound, controlErrorCode.flowBusy, controlErrorCode.flowConflict, controlErrorCode.flowPresentationConflict, controlErrorCode.flowRevisionConflict, controlErrorCode.liveConflict, controlErrorCode.liveNotFound, controlErrorCode.pageInvalidCursor, controlErrorCode.publicationConflict, controlErrorCode.publicationNotFound, controlErrorCode.publicationUnsupported, controlErrorCode.resourceNotFound, controlErrorCode.publishOperationNotFound, controlErrorCode.routeNotFound, controlErrorCode.runConflict, controlErrorCode.runEventsExpired, controlErrorCode.runInvalid, controlErrorCode.runNotFound, controlErrorCode.runNotTerminal, controlErrorCode.runOverloaded, controlErrorCode.runWaitNotFound, controlErrorCode.triggerKeyInvalid, controlErrorCode.triggerKeyNotFound, controlErrorCode.triggerNotFound, controlErrorCode.variableInvalid, controlErrorCode.variableLimitReached, controlErrorCode.variableNotFound;
9760
+ controlErrorCode.eventSourceInvalid, controlErrorCode.eventSourceIdentityUnavailable, controlErrorCode.eventSourceNotFound, controlErrorCode.eventSourceConflict, controlErrorCode.authenticationRequired, controlErrorCode.authorizationDenied, controlErrorCode.bindingUnresolved, controlErrorCode.connectorActionNotFound, controlErrorCode.connectorAccessConflict, controlErrorCode.connectorAccessInvalid, controlErrorCode.connectorAccessRequired, controlErrorCode.connectorAccessUnsupported, controlErrorCode.connectorUnconfigured, controlErrorCode.connectorUnavailable, controlErrorCode.connectorConsoleUnconfigured, controlErrorCode.engineUnavailable, controlErrorCode.engineUnsupported, controlErrorCode.flowInvalid, controlErrorCode.flowRepairRequired, controlErrorCode.flowUpgradeRequired, controlErrorCode.flowNotFound, controlErrorCode.flowBusy, controlErrorCode.flowConflict, controlErrorCode.flowPresentationConflict, controlErrorCode.flowRevisionConflict, controlErrorCode.liveConflict, controlErrorCode.liveNotFound, controlErrorCode.pageInvalidCursor, controlErrorCode.publicationConflict, controlErrorCode.publicationNotFound, controlErrorCode.publicationUnsupported, controlErrorCode.publishOperationNotFound, controlErrorCode.routeNotFound, controlErrorCode.runConflict, controlErrorCode.runEventsExpired, controlErrorCode.runInvalid, controlErrorCode.runNotFound, controlErrorCode.runNotTerminal, controlErrorCode.runOverloaded, controlErrorCode.runWaitNotFound, controlErrorCode.triggerKeyInvalid, controlErrorCode.triggerKeyNotFound, controlErrorCode.triggerNotFound, controlErrorCode.variableInvalid, controlErrorCode.variableLimitReached, controlErrorCode.variableNotFound;
9741
9761
  var ApiError = class extends Error {
9742
9762
  constructor(status, code, message, details) {
9743
9763
  super(message);
@@ -9788,6 +9808,142 @@ function optionalString(value) {
9788
9808
  return string(value);
9789
9809
  }
9790
9810
  //#endregion
9811
+ //#region src/control/common/publicationDecoders.ts
9812
+ function publication(value) {
9813
+ const source = record(value);
9814
+ const liveEnd = source.liveEnd == null ? void 0 : record(source.liveEnd);
9815
+ if (liveEnd != null && typeof liveEnd.enabled != "boolean") return invalidResponse();
9816
+ const operation = source.operation;
9817
+ const sourcePublicationId = source.sourcePublicationId;
9818
+ if (source.version != 1) return invalidResponse();
9819
+ if (operation != "publish" && operation != "rollback") return invalidResponse();
9820
+ if (sourcePublicationId != null && typeof sourcePublicationId != "string") return invalidResponse();
9821
+ return {
9822
+ ...liveEnd == null ? {} : { liveEnd: {
9823
+ enabled: liveEnd.enabled,
9824
+ endedAt: string(liveEnd.endedAt)
9825
+ } },
9826
+ actorId: string(source.actorId),
9827
+ closureDigest: string(source.closureDigest),
9828
+ createdAt: string(source.createdAt),
9829
+ engineContract: string(source.engineContract),
9830
+ flowId: string(source.flowId),
9831
+ modelVersion: integer(source.modelVersion),
9832
+ operation,
9833
+ publicationId: string(source.publicationId),
9834
+ sharedAccessDigest: string(source.sharedAccessDigest),
9835
+ revisionDigest: string(source.revisionDigest),
9836
+ revisionId: string(source.revisionId),
9837
+ ...sourcePublicationId == null ? {} : { sourcePublicationId },
9838
+ version: 1
9839
+ };
9840
+ }
9841
+ function publishOperation(value) {
9842
+ const source = record(value);
9843
+ const status = source.status;
9844
+ const common = {
9845
+ createdAt: string(source.createdAt),
9846
+ flowId: string(source.flowId),
9847
+ operationId: string(source.operationId),
9848
+ revisionId: string(source.revisionId),
9849
+ updatedAt: string(source.updatedAt),
9850
+ version: 1
9851
+ };
9852
+ if (source.version != 1) return invalidResponse();
9853
+ switch (status) {
9854
+ case "pending":
9855
+ exact(source, [
9856
+ "createdAt",
9857
+ "flowId",
9858
+ "operationId",
9859
+ "revisionId",
9860
+ "status",
9861
+ "updatedAt",
9862
+ "version"
9863
+ ]);
9864
+ return {
9865
+ ...common,
9866
+ status
9867
+ };
9868
+ case "succeeded":
9869
+ exact(source, [
9870
+ "createdAt",
9871
+ "flowId",
9872
+ "operationId",
9873
+ "publicationId",
9874
+ "revisionId",
9875
+ "status",
9876
+ "updatedAt",
9877
+ "version"
9878
+ ]);
9879
+ return {
9880
+ ...common,
9881
+ publicationId: string(source.publicationId),
9882
+ status
9883
+ };
9884
+ case "failed": {
9885
+ exact(source, [
9886
+ "createdAt",
9887
+ "flowId",
9888
+ "issue",
9889
+ "operationId",
9890
+ "revisionId",
9891
+ "status",
9892
+ "updatedAt",
9893
+ "version"
9894
+ ]);
9895
+ const issue = record(source.issue);
9896
+ const nodeId = issue.nodeId;
9897
+ exact(issue, [
9898
+ "code",
9899
+ "message",
9900
+ ...nodeId == null ? [] : ["nodeId"]
9901
+ ]);
9902
+ return {
9903
+ ...common,
9904
+ issue: {
9905
+ code: string(issue.code),
9906
+ message: string(issue.message),
9907
+ ...nodeId == null ? {} : { nodeId: string(nodeId) }
9908
+ },
9909
+ status
9910
+ };
9911
+ }
9912
+ default: return invalidResponse();
9913
+ }
9914
+ }
9915
+ function live(value) {
9916
+ const source = record(value);
9917
+ const status = source.status;
9918
+ const candidate = source.publication;
9919
+ if (source.version != 1 || typeof source.hasUnpublishedChanges != "boolean") return invalidResponse();
9920
+ if (status != "not-published" && status != "runnable" && status != "suspended") return invalidResponse();
9921
+ if (status == "not-published" && candidate !== null) return invalidResponse();
9922
+ if (status != "not-published" && candidate === null) return invalidResponse();
9923
+ return {
9924
+ flowId: string(source.flowId),
9925
+ hasUnpublishedChanges: source.hasUnpublishedChanges,
9926
+ publication: candidate === null ? null : publication(candidate),
9927
+ revision: integer(source.revision),
9928
+ status,
9929
+ version: 1
9930
+ };
9931
+ }
9932
+ function publicationPage(value) {
9933
+ const source = record(value);
9934
+ const nextCursor = source.nextCursor;
9935
+ const total = source.total;
9936
+ if (source.version != 1 || !Array.isArray(source.publications)) return invalidResponse();
9937
+ if (nextCursor != null && typeof nextCursor != "string") return invalidResponse();
9938
+ if (total != null && !Number.isSafeInteger(total)) return invalidResponse();
9939
+ return {
9940
+ ...nextCursor == null ? {} : { nextCursor },
9941
+ publications: source.publications.map(publication),
9942
+ ...total == null ? {} : { total },
9943
+ version: 1
9944
+ };
9945
+ }
9946
+ //#endregion
9791
9947
  //#region src/trigger/common/configSchema.ts
9792
9948
  var configInputsSchema = array(union([strictObject({
9793
9949
  handle: string$1().min(1),
@@ -9970,54 +10126,99 @@ function pollTriggerTestResult(value) {
9970
10126
  };
9971
10127
  }
9972
10128
  //#endregion
9973
- //#region src/control/common/publicationResources.ts
9974
- function context(source) {
9975
- if (source.version != 1 || source.status != "live" && source.status != "historical") return invalidResponse();
9976
- if (source.status == "live" ? typeof source.enabled != "boolean" : source.enabled !== void 0) return invalidResponse();
9977
- return {
9978
- flowId: string(source.flowId),
9979
- publicationId: string(source.publicationId),
9980
- revisionId: string(source.revisionId),
9981
- status: source.status,
9982
- ...source.enabled == null ? {} : { enabled: source.enabled },
9983
- version: 1
9984
- };
9985
- }
9986
- function resource(value, scope) {
9987
- const source = record(value);
9988
- const type = source.type;
9989
- if (source.kind != "trigger" || type != "webhook" && type != "cron" && type != "poll" && type != "integration" && type != "error") return invalidResponse();
9990
- if (source.description != null && typeof source.description != "string") return invalidResponse();
9991
- const resourceId = string(source.resourceId);
9992
- const runtime = source.runtime == null ? void 0 : triggerBinding(source.runtime);
9993
- if (runtime != null && (scope.status != "live" || runtime.flowId != scope.flowId || runtime.currentPublicationId != scope.publicationId || runtime.currentRevisionId != scope.revisionId || runtime.triggerNodeId != resourceId || runtime.kind != type)) return invalidResponse();
9994
- return {
9995
- resourceId,
9996
- kind: "trigger",
9997
- type,
9998
- name: string(source.name),
9999
- ...source.description == null ? {} : { description: source.description },
10000
- config: jsonValue(source.config),
10001
- inputs: jsonValue(source.inputs),
10002
- ...runtime == null ? {} : { runtime }
10003
- };
10004
- }
10005
- function decodePublicationResources(value) {
10129
+ //#region src/control/common/liveDetails.ts
10130
+ var metadata = {
10131
+ nodeId: string$1().min(1),
10132
+ name: string$1(),
10133
+ description: string$1().optional()
10134
+ };
10135
+ var binding = unknown().transform(triggerBinding);
10136
+ var provider = {
10137
+ provider: string$1().min(1),
10138
+ inputs: record$2(string$1(), discriminatedUnion("kind", [strictObject({
10139
+ kind: literal("value"),
10140
+ value: json$4()
10141
+ }), strictObject({ kind: literal("unset") })]))
10142
+ };
10143
+ var entrySchema = discriminatedUnion("type", [
10144
+ strictObject({
10145
+ ...metadata,
10146
+ type: literal("manual"),
10147
+ config: authoringConfigurations.manual
10148
+ }),
10149
+ strictObject({
10150
+ ...metadata,
10151
+ type: literal("webhook"),
10152
+ config: authoringConfigurations.webhook,
10153
+ binding
10154
+ }),
10155
+ strictObject({
10156
+ ...metadata,
10157
+ type: literal("cron"),
10158
+ config: authoringConfigurations.cron,
10159
+ binding
10160
+ }),
10161
+ strictObject({
10162
+ ...metadata,
10163
+ type: literal("error"),
10164
+ config: authoringConfigurations.error,
10165
+ binding
10166
+ }),
10167
+ strictObject({
10168
+ ...metadata,
10169
+ ...provider,
10170
+ type: literal("poll"),
10171
+ config: authoringConfigurations.poll,
10172
+ binding
10173
+ }),
10174
+ strictObject({
10175
+ ...metadata,
10176
+ ...provider,
10177
+ type: literal("integration"),
10178
+ config: authoringConfigurations.integration,
10179
+ binding
10180
+ })
10181
+ ]);
10182
+ function decodeLiveDetails(value) {
10006
10183
  const source = record(value);
10007
- const scope = context(source);
10008
- if (!Array.isArray(source.resources)) return invalidResponse();
10184
+ const flowId = string(source.flowId);
10185
+ if (source.version != 1 || !Array.isArray(source.entries)) return invalidResponse();
10186
+ if (source.publication === null) {
10187
+ if (source.status != "not-published" || source.entries.length != 0 || Object.hasOwn(source, "enabled")) return invalidResponse();
10188
+ return {
10189
+ flowId,
10190
+ publication: null,
10191
+ status: "not-published",
10192
+ entries: [],
10193
+ version: 1
10194
+ };
10195
+ }
10196
+ const current = publication(source.publication);
10197
+ const status = source.status;
10198
+ if (current.flowId != flowId || typeof source.enabled != "boolean") return invalidResponse();
10199
+ if (status != "runnable" && status != "suspended") return invalidResponse();
10200
+ if (!source.enabled && source.status == "runnable") return invalidResponse();
10009
10201
  return {
10010
- ...scope,
10011
- resources: source.resources.map((item) => resource(item, scope))
10202
+ flowId,
10203
+ publication: current,
10204
+ status,
10205
+ enabled: source.enabled,
10206
+ entries: decodeEntries(source.entries, current),
10207
+ version: 1
10012
10208
  };
10013
10209
  }
10014
- function decodePublicationResource(value) {
10015
- const source = record(value);
10016
- const scope = context(source);
10017
- return {
10018
- ...scope,
10019
- resource: resource(source.resource, scope)
10020
- };
10210
+ /** Both producers and consumers enforce the same published-entry invariants. */
10211
+ function decodeEntries(values, current) {
10212
+ const parsed = array(entrySchema).safeParse(values);
10213
+ if (!parsed.success) return invalidResponse();
10214
+ const ids = /* @__PURE__ */ new Set();
10215
+ for (const entry of parsed.data) {
10216
+ if (ids.has(entry.nodeId)) return invalidResponse();
10217
+ ids.add(entry.nodeId);
10218
+ 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();
10219
+ if (entry.type == "webhook" && (!entry.binding.endpointUrl || !webhookSupportsBody(entry.config.method) && Object.keys(entry.config.body).length > 0)) return invalidResponse();
10220
+ }
10221
+ return parsed.data;
10021
10222
  }
10022
10223
  //#endregion
10023
10224
  //#region src/control/common/providerIconSprite.ts
@@ -10053,6 +10254,24 @@ function providerIconAppearance(metadata, position) {
10053
10254
  }
10054
10255
  };
10055
10256
  }
10257
+ //#endregion
10258
+ //#region src/flow/common/workflowFile.ts
10259
+ var envelope = strictObject({
10260
+ kind: literal("open-flow-workflow"),
10261
+ version: literal(1),
10262
+ name: string$1().optional(),
10263
+ content: unknown(),
10264
+ presentation: record$2(string$1(), json$4()).optional()
10265
+ });
10266
+ /** Structural decoding only: incomplete drafts are supported, repair is never attempted. */
10267
+ function decodeWorkflowFile(value) {
10268
+ checkJsonDepth(value, -1);
10269
+ const file = envelope.parse(value);
10270
+ return {
10271
+ ...file,
10272
+ content: decodeRevisionContent(file.content)
10273
+ };
10274
+ }
10056
10275
  new TextEncoder();
10057
10276
  //#endregion
10058
10277
  //#region src/control/common/providerAccess.ts
@@ -10846,142 +11065,6 @@ function variableReferences(input) {
10846
11065
  };
10847
11066
  }
10848
11067
  //#endregion
10849
- //#region src/control/common/publicationDecoders.ts
10850
- function publication(value) {
10851
- const source = record(value);
10852
- const liveEnd = source.liveEnd == null ? void 0 : record(source.liveEnd);
10853
- if (liveEnd != null && typeof liveEnd.enabled != "boolean") return invalidResponse();
10854
- const operation = source.operation;
10855
- const sourcePublicationId = source.sourcePublicationId;
10856
- if (source.version != 1) return invalidResponse();
10857
- if (operation != "publish" && operation != "rollback") return invalidResponse();
10858
- if (sourcePublicationId != null && typeof sourcePublicationId != "string") return invalidResponse();
10859
- return {
10860
- ...liveEnd == null ? {} : { liveEnd: {
10861
- enabled: liveEnd.enabled,
10862
- endedAt: string(liveEnd.endedAt)
10863
- } },
10864
- actorId: string(source.actorId),
10865
- closureDigest: string(source.closureDigest),
10866
- createdAt: string(source.createdAt),
10867
- engineContract: string(source.engineContract),
10868
- flowId: string(source.flowId),
10869
- modelVersion: integer(source.modelVersion),
10870
- operation,
10871
- publicationId: string(source.publicationId),
10872
- sharedAccessDigest: string(source.sharedAccessDigest),
10873
- revisionDigest: string(source.revisionDigest),
10874
- revisionId: string(source.revisionId),
10875
- ...sourcePublicationId == null ? {} : { sourcePublicationId },
10876
- version: 1
10877
- };
10878
- }
10879
- function publishOperation(value) {
10880
- const source = record(value);
10881
- const status = source.status;
10882
- const common = {
10883
- createdAt: string(source.createdAt),
10884
- flowId: string(source.flowId),
10885
- operationId: string(source.operationId),
10886
- revisionId: string(source.revisionId),
10887
- updatedAt: string(source.updatedAt),
10888
- version: 1
10889
- };
10890
- if (source.version != 1) return invalidResponse();
10891
- switch (status) {
10892
- case "pending":
10893
- exact(source, [
10894
- "createdAt",
10895
- "flowId",
10896
- "operationId",
10897
- "revisionId",
10898
- "status",
10899
- "updatedAt",
10900
- "version"
10901
- ]);
10902
- return {
10903
- ...common,
10904
- status
10905
- };
10906
- case "succeeded":
10907
- exact(source, [
10908
- "createdAt",
10909
- "flowId",
10910
- "operationId",
10911
- "publicationId",
10912
- "revisionId",
10913
- "status",
10914
- "updatedAt",
10915
- "version"
10916
- ]);
10917
- return {
10918
- ...common,
10919
- publicationId: string(source.publicationId),
10920
- status
10921
- };
10922
- case "failed": {
10923
- exact(source, [
10924
- "createdAt",
10925
- "flowId",
10926
- "issue",
10927
- "operationId",
10928
- "revisionId",
10929
- "status",
10930
- "updatedAt",
10931
- "version"
10932
- ]);
10933
- const issue = record(source.issue);
10934
- const nodeId = issue.nodeId;
10935
- exact(issue, [
10936
- "code",
10937
- "message",
10938
- ...nodeId == null ? [] : ["nodeId"]
10939
- ]);
10940
- return {
10941
- ...common,
10942
- issue: {
10943
- code: string(issue.code),
10944
- message: string(issue.message),
10945
- ...nodeId == null ? {} : { nodeId: string(nodeId) }
10946
- },
10947
- status
10948
- };
10949
- }
10950
- default: return invalidResponse();
10951
- }
10952
- }
10953
- function live(value) {
10954
- const source = record(value);
10955
- const status = source.status;
10956
- const candidate = source.publication;
10957
- if (source.version != 1 || typeof source.hasUnpublishedChanges != "boolean") return invalidResponse();
10958
- if (status != "not-published" && status != "runnable" && status != "suspended") return invalidResponse();
10959
- if (status == "not-published" && candidate !== null) return invalidResponse();
10960
- if (status != "not-published" && candidate === null) return invalidResponse();
10961
- return {
10962
- flowId: string(source.flowId),
10963
- hasUnpublishedChanges: source.hasUnpublishedChanges,
10964
- publication: candidate === null ? null : publication(candidate),
10965
- revision: integer(source.revision),
10966
- status,
10967
- version: 1
10968
- };
10969
- }
10970
- function publicationPage(value) {
10971
- const source = record(value);
10972
- const nextCursor = source.nextCursor;
10973
- const total = source.total;
10974
- if (source.version != 1 || !Array.isArray(source.publications)) return invalidResponse();
10975
- if (nextCursor != null && typeof nextCursor != "string") return invalidResponse();
10976
- if (total != null && !Number.isSafeInteger(total)) return invalidResponse();
10977
- return {
10978
- ...nextCursor == null ? {} : { nextCursor },
10979
- publications: source.publications.map(publication),
10980
- ...total == null ? {} : { total },
10981
- version: 1
10982
- };
10983
- }
10984
- //#endregion
10985
11068
  //#region src/control/common/revisionDecoders.ts
10986
11069
  function revisionMetadata(value) {
10987
11070
  const source = record(value);
@@ -11556,6 +11639,26 @@ var ControlClient = class {
11556
11639
  exact(source, ["version"]);
11557
11640
  if (source.version != 1) return invalidResponse();
11558
11641
  }
11642
+ async exportFlow(flowId) {
11643
+ const value = await this.request(`/v1/flows/${segment(flowId)}/export`);
11644
+ try {
11645
+ return decodeWorkflowFile(value);
11646
+ } catch {
11647
+ return invalidResponse();
11648
+ }
11649
+ }
11650
+ async importFlow(file, options = {}) {
11651
+ return flow$1(await this.request("/v1/flows/import", {
11652
+ method: "POST",
11653
+ headers: { "Idempotency-Key": options.idempotencyKey ?? `flow-${randomId()}` },
11654
+ body: JSON.stringify({
11655
+ file,
11656
+ name: options.name,
11657
+ teamId: options.teamId,
11658
+ version: 1
11659
+ })
11660
+ }));
11661
+ }
11559
11662
  async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId) {
11560
11663
  return flow$1(await this.request("/v1/flows", {
11561
11664
  body: JSON.stringify({
@@ -11909,21 +12012,14 @@ var ControlClient = class {
11909
12012
  method: "POST"
11910
12013
  }));
11911
12014
  }
12015
+ async getLiveDetails(flowId, signal) {
12016
+ const details = decodeLiveDetails(await this.request(`/v1/flows/${segment(flowId)}/live/details`, { signal }));
12017
+ if (details.flowId != flowId) return invalidResponse();
12018
+ return details;
12019
+ }
11912
12020
  async getLive(flowId, signal) {
11913
12021
  return live(await this.request(`/v1/flows/${segment(flowId)}/live`, { signal }));
11914
12022
  }
11915
- async listPublicationResources(flowId, publicationId) {
11916
- const query = publicationId == null ? "" : `?publicationId=${encodeURIComponent(publicationId)}`;
11917
- const result = decodePublicationResources(await this.request(`/v1/flows/${segment(flowId)}/resources${query}`));
11918
- if (result.flowId != flowId || publicationId != null && result.publicationId != publicationId) return invalidResponse();
11919
- return result;
11920
- }
11921
- async getPublicationResource(flowId, resourceId, publicationId) {
11922
- const query = publicationId == null ? "" : `?publicationId=${encodeURIComponent(publicationId)}`;
11923
- const result = decodePublicationResource(await this.request(`/v1/flows/${segment(flowId)}/resources/${segment(resourceId)}${query}`));
11924
- if (result.flowId != flowId || result.resource.resourceId != resourceId || publicationId != null && result.publicationId != publicationId) return invalidResponse();
11925
- return result;
11926
- }
11927
12023
  async listPublications(flowId, options = {}, signal) {
11928
12024
  const parameters = new URLSearchParams();
11929
12025
  if (options.cursor != null) parameters.set("cursor", options.cursor);
@@ -12122,6 +12218,43 @@ async function rpc(harness, method, params) {
12122
12218
  return body.result;
12123
12219
  }
12124
12220
  var mcpConformanceCases = [
12221
+ {
12222
+ name: "shares workflow import and export with REST and preserves idempotency",
12223
+ async verify(harness) {
12224
+ const client = new ControlClient((url, init) => harness.request(new Request(new URL(url, harness.origin), init)));
12225
+ const original = await client.createFlow("Template source");
12226
+ const exported = await rpc(harness, "tools/call", {
12227
+ name: "flow_export",
12228
+ arguments: { flowId: original.flowId }
12229
+ });
12230
+ assert(exported.isError != true, "MCP export failed.");
12231
+ assert(dequal(exported.structuredContent, await client.exportFlow(original.flowId)), "MCP and REST exports differ.");
12232
+ const args = {
12233
+ file: exported.structuredContent,
12234
+ name: "Imported template",
12235
+ idempotencyKey: crypto.randomUUID()
12236
+ };
12237
+ const imported = await rpc(harness, "tools/call", {
12238
+ name: "flow_import",
12239
+ arguments: args
12240
+ });
12241
+ assert(imported.isError != true, "MCP import failed.");
12242
+ const flow = imported.structuredContent;
12243
+ assert(flow.flowId != original.flowId && flow.draftRevisionId != original.draftRevisionId, "Import reused resource identities.");
12244
+ assert((await client.getEditor(flow.flowId)).live.publication == null, "Import published the Flow.");
12245
+ assert(dequal((await rpc(harness, "tools/call", {
12246
+ name: "flow_import",
12247
+ arguments: args
12248
+ })).structuredContent, imported.structuredContent), "Import retry created another Flow.");
12249
+ assert((await rpc(harness, "tools/call", {
12250
+ name: "flow_import",
12251
+ arguments: {
12252
+ ...args,
12253
+ name: "Changed import"
12254
+ }
12255
+ })).isError == true, "Changed import must conflict.");
12256
+ }
12257
+ },
12125
12258
  {
12126
12259
  name: "publishes the public MCP catalog, input schemas and annotations",
12127
12260
  async verify(harness) {
@@ -12257,7 +12390,7 @@ var mutationKey = id.max(256).describe("Stable identity for this mutation. Retry
12257
12390
  var pageLimit = int().min(1).max(100).default(50);
12258
12391
  var flow = id.describe("Exact Flow ID returned by flow_list or flow_create.");
12259
12392
  var run = id.describe("Exact Run ID returned by flow_run or run_list.");
12260
- var mcpInstructions = "Use flow_list, flow_read and flow_search to inspect root workflows. Read node type schemas with flow_schema. Use flow_edit with the observed baseRevision and a stable requestId. Node edits affect only the selected node. Text edits require exactly one match. Execution edges and input sources are independent. Legacy Subflow content is unsupported. Edits can save incomplete drafts; inspect returned diagnostics and use flow_check before running. Use flow_check before flow_run. Select an explicit Trigger node ID and fixed revision or publication. A new Flow has no Trigger until you add one. Before adding a Feishu Trigger, use event_source_list and compare its Connection IDs with connector_connections in the Flow scope. If no source is available, create and verify one in Workbench. Use flow_publish to publish a fixed Revision, then poll flow_publish_status until succeeded or failed. Use flow_set_enabled to enable or disable the observed Live publication. flow_run returns an accepted Run, not its final result. Find Runs with run_list, poll run_get and use run_result after terminal. Resolve a waiting Run only with an explicit run_resolve_wait action allowed by run_get. Use run_results and run_result_read to inspect stored Agent tool results; these are separate from the terminal Run result. Retry flow_edit with identical arguments and the same requestId. Retry flow_create, flow_publish and flow_run only with identical arguments and the same idempotencyKey; a new key can execute the Flow again. Other mutations use the same resource identity and arguments when retrying. Cancel a Run explicitly with run_cancel. Use nextCursor and nextAfter to read subsequent pages. Connector-backed deployments may require a Team; inspect connector_teams before creating a Flow.";
12393
+ var mcpInstructions = "Use flow_list, flow_read and flow_search to inspect root workflows. Read node type schemas with flow_schema. Use flow_edit with the observed baseRevision and a stable requestId. Node edits affect only the selected node. Text edits require exactly one match. Execution edges and input sources are independent. Legacy Subflow content is unsupported. Edits can save incomplete drafts; inspect returned diagnostics and use flow_check before running. Use flow_check before flow_run. Select an explicit Trigger node ID and fixed revision or publication. A new Flow has no Trigger until you add one. Before adding a Feishu Trigger, use event_source_list and compare its Connection IDs with connector_connections in the Flow scope. If no source is available, create and verify one in Workbench. Use flow_publish to publish a fixed Revision, then poll flow_publish_status until succeeded or failed. Use flow_live to inspect current online entries after publication. Use flow_set_enabled to enable or disable the observed Live publication. flow_run returns an accepted Run, not its final result. Find Runs with run_list, poll run_get and use run_result after terminal. Resolve a waiting Run only with an explicit run_resolve_wait action allowed by run_get. Use run_results and run_result_read to inspect stored Agent tool results; these are separate from the terminal Run result. Retry flow_edit with identical arguments and the same requestId. Retry flow_create, flow_import, flow_publish and flow_run only with identical arguments and the same idempotencyKey; a new key can execute the Flow again. Other mutations use the same resource identity and arguments when retrying. Cancel a Run explicitly with run_cancel. Use nextCursor and nextAfter to read subsequent pages. Connector-backed deployments may require a Team; inspect connector_teams before creating a Flow.";
12261
12394
  function tool(description, schema, readOnly) {
12262
12395
  return {
12263
12396
  description,
@@ -12285,15 +12418,7 @@ function tool(description, schema, readOnly) {
12285
12418
  };
12286
12419
  }
12287
12420
  var mcpTools = {
12288
- flow_resources: tool("List published resources, currently non-Manual Triggers. Defaults to current Live; supply publicationId for a fixed publication. Historical publications return configuration only. Live resources include current runtime state and Webhook URLs.", strictObject({
12289
- flowId: flow,
12290
- publicationId: id.optional()
12291
- }), true),
12292
- flow_resource_get: tool("Read a published resource by resourceId from flow_resources. Defaults to current Live; supply publicationId to keep the publication fixed. Historical resources have no current runtime state or callable URL.", strictObject({
12293
- flowId: flow,
12294
- resourceId: id,
12295
- publicationId: id.optional()
12296
- }), true),
12421
+ flow_live: tool("Read the current published Flow, enablement and online entries, including Webhook URLs and request fields. Draft changes do not affect this view. An unpublished Flow returns not-published with no entries.", strictObject({ flowId: flow }), true),
12297
12422
  flow_list: tool("List Flows in this deployment. Continue with nextCursor; cursors are compatible with the Control API.", strictObject({
12298
12423
  cursor: id.optional(),
12299
12424
  limit: pageLimit
@@ -12301,6 +12426,13 @@ var mcpTools = {
12301
12426
  flow_read: tool("Read an outline, selected node details, or a bounded code/prompt excerpt. Carry the returned revision into subsequent reads and edits.", authoringReadSchema.safeExtend({ flowId: flow }).meta({ ...authoringReadSchema.meta() }), true),
12302
12427
  flow_search: tool("Find nodes by name, configuration or source text in a fixed Revision. Follow nextOffset for more matches.", authoringSearchSchema.extend({ flowId: flow }), true),
12303
12428
  flow_schema: tool("Read node configuration schemas and the edit grammar, or an Action contract. Action lookup requires a flowId.", authoringSchemaQuery.safeExtend({ flowId: flow.optional() }), true),
12429
+ flow_export: tool("Export the current draft as a shareable workflow JSON file. Structured external references are cleared. Literal secrets in code, prompts or business JSON remain; review before sharing.", strictObject({ flowId: flow }), true),
12430
+ flow_import: tool("Import workflow JSON as a new unpublished draft. External references are cleared and must be configured again. Keep identical arguments and idempotencyKey when retrying.", strictObject({
12431
+ file: json,
12432
+ name: id.optional(),
12433
+ teamId: id.optional(),
12434
+ idempotencyKey: mutationKey
12435
+ }), false),
12304
12436
  flow_create: tool("Create an empty Flow. If this deployment uses OOMOL Connector, choose a teamId from connector_teams. Keep the key and arguments stable when retrying.", strictObject({
12305
12437
  name: id.refine((name) => name == name.trim() && resourceNameIssue(name) == null, "Flow name is invalid."),
12306
12438
  idempotencyKey: mutationKey,