@oomol-lab/open-flow 0.1.0-beta.62 → 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 (51) hide show
  1. package/dist/browser/{createResourceDialog-DZgJsr3e.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-CzYIVevI.js → flowChanges-DpZOQuJE.js} +784 -443
  7. package/dist/browser/{flowRunInputEditorStore-Dsxyfwae.js → flowRunInputEditorStore-B2Rw4VsT.js} +1 -1
  8. package/dist/browser/{flowWorkspace-BgZaFKZm.js → flowWorkspace-B7a5NNA_.js} +41 -29
  9. package/dist/browser/{icons-CajfDpy_.js → icons-Db2Jb2iX.js} +30 -10
  10. package/dist/browser/preview.css +5 -6
  11. package/dist/browser/preview.js +437 -402
  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 +5 -6
  18. package/dist/browser/workbench.d.ts +5 -3
  19. package/dist/browser/workbench.js +198 -171
  20. package/dist/browser/{workbenchSelect-H9wzEFkH.js → workbenchSelect-C-jf6NIM.js} +1 -1
  21. package/dist/command/index.js +40 -39
  22. package/dist/common/authoringSchema.d.ts +1 -0
  23. package/dist/common/connector-action.d.ts +1 -0
  24. package/dist/common/connector-action.js +15 -12
  25. package/dist/common/control-api-conformance.js +107 -8
  26. package/dist/common/control-api.d.ts +8 -0
  27. package/dist/common/control-api.js +47 -8
  28. package/dist/common/control-requests.d.ts +6 -0
  29. package/dist/common/control-requests.js +41 -18
  30. package/dist/common/decision.js +8 -7
  31. package/dist/common/flow-connectionUsage.d.ts +1 -0
  32. package/dist/common/flow-encoding.d.ts +1 -0
  33. package/dist/common/flow-encoding.js +202 -10
  34. package/dist/common/flow-semantics.js +64 -46
  35. package/dist/common/flow-workflowFile.d.ts +23 -0
  36. package/dist/common/integration-trigger.js +8 -7
  37. package/dist/common/localization.d.ts +1 -0
  38. package/dist/common/localization.js +12 -1
  39. package/dist/common/mcp.d.ts +61 -0
  40. package/dist/common/mcp.js +92 -9
  41. package/dist/common/openapi.js +8 -7
  42. package/dist/common/poll-trigger.js +8 -7
  43. package/dist/common/runtime-contract.js +1 -1
  44. package/dist/common/scheduler.d.ts +22 -2
  45. package/dist/common/scheduler.js +354 -83
  46. package/dist/common/trigger-config.d.ts +2 -0
  47. package/dist/common/webhook-trigger.js +8 -7
  48. package/dist/index.d.ts +2 -2
  49. package/package.json +1 -1
  50. package/skills/open-flow/SKILL.md +1 -1
  51. package/skills/open-flow/references/flow-authoring.md +20 -0
@@ -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
  }
@@ -8894,7 +8894,8 @@ var managedFields = object({
8894
8894
  object({
8895
8895
  kind: literal("connector"),
8896
8896
  action: text,
8897
- connectionId: text.optional()
8897
+ connectionId: text.optional(),
8898
+ outputMode: literal("value").optional()
8898
8899
  }),
8899
8900
  object({
8900
8901
  kind: literal("openapi"),
@@ -9525,7 +9526,7 @@ var authoringConfigurations = {
9525
9526
  outputs: outputFields,
9526
9527
  capabilities: authoringDefinitionSchemas.capabilities.optional()
9527
9528
  }),
9528
- connector: authoringDefinitionSchemas.connector.strict(),
9529
+ connector: authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
9529
9530
  openapi: authoringOpenApiSchema,
9530
9531
  agent: authoringDefinitionSchemas.agent.omit({
9531
9532
  prompt: true,
@@ -10253,6 +10254,24 @@ function providerIconAppearance(metadata, position) {
10253
10254
  }
10254
10255
  };
10255
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
+ }
10256
10275
  new TextEncoder();
10257
10276
  //#endregion
10258
10277
  //#region src/control/common/providerAccess.ts
@@ -11620,6 +11639,26 @@ var ControlClient = class {
11620
11639
  exact(source, ["version"]);
11621
11640
  if (source.version != 1) return invalidResponse();
11622
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
+ }
11623
11662
  async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId) {
11624
11663
  return flow$1(await this.request("/v1/flows", {
11625
11664
  body: JSON.stringify({
@@ -12179,6 +12218,43 @@ async function rpc(harness, method, params) {
12179
12218
  return body.result;
12180
12219
  }
12181
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
+ },
12182
12258
  {
12183
12259
  name: "publishes the public MCP catalog, input schemas and annotations",
12184
12260
  async verify(harness) {
@@ -12314,7 +12390,7 @@ var mutationKey = id.max(256).describe("Stable identity for this mutation. Retry
12314
12390
  var pageLimit = int().min(1).max(100).default(50);
12315
12391
  var flow = id.describe("Exact Flow ID returned by flow_list or flow_create.");
12316
12392
  var run = id.describe("Exact Run ID returned by flow_run or run_list.");
12317
- 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_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.";
12318
12394
  function tool(description, schema, readOnly) {
12319
12395
  return {
12320
12396
  description,
@@ -12350,6 +12426,13 @@ var mcpTools = {
12350
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),
12351
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),
12352
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),
12353
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({
12354
12437
  name: id.refine((name) => name == name.trim() && resourceNameIssue(name) == null, "Flow name is invalid."),
12355
12438
  idempotencyKey: mutationKey,
@@ -6801,7 +6801,8 @@ var managedFields = object$1({
6801
6801
  object$1({
6802
6802
  kind: literal("connector"),
6803
6803
  action: text,
6804
- connectionId: text.optional()
6804
+ connectionId: text.optional(),
6805
+ outputMode: literal("value").optional()
6805
6806
  }),
6806
6807
  object$1({
6807
6808
  kind: literal("openapi"),
@@ -8186,10 +8187,10 @@ function compileEnumAndConst(context, enumList, constValue, schema) {
8186
8187
  }
8187
8188
  if (compiledEnum.length === 0) recordWarn(context, "all of elements from list is rejected by currently schema object", "enum");
8188
8189
  }
8189
- if (constValue && valid(schema, constValue) === ValidResult.Invalid) isNever = true;
8190
+ if (constValue !== void 0 && valid(schema, constValue) === ValidResult.Invalid) isNever = true;
8190
8191
  if (compiledEnum) {
8191
8192
  if (compiledEnum.length === 0) isNever = true;
8192
- else if (constValue) {
8193
+ else if (constValue !== void 0) {
8193
8194
  let foundEquals = false;
8194
8195
  for (const enumValue of compiledEnum) if (isDeepEquals(enumValue, constValue)) {
8195
8196
  foundEquals = true;
@@ -8202,7 +8203,7 @@ function compileEnumAndConst(context, enumList, constValue, schema) {
8202
8203
  const compiledSchema = {};
8203
8204
  if (schema.type) compiledSchema.type = schema.type;
8204
8205
  if (compiledEnum) compiledSchema.enum = compiledEnum;
8205
- if (constValue) compiledSchema.const = wrapCompiledValue(deepCopy(constValue));
8206
+ if (constValue !== void 0) compiledSchema.const = wrapCompiledValue(deepCopy(constValue));
8206
8207
  return wrapCompiledSchema(kind, compiledSchema, context.delegate, context.path);
8207
8208
  }
8208
8209
  //#endregion
@@ -8597,7 +8598,7 @@ function compileSchema(context, schema) {
8597
8598
  let targetSchema = schema;
8598
8599
  let shouldHandleEnumAndConst = false;
8599
8600
  const { enum: enumList, const: constValue } = schema;
8600
- if (enumList || constValue) {
8601
+ if (enumList || constValue !== void 0) {
8601
8602
  const { enum: _0, const: _1, ...rest } = schema;
8602
8603
  targetSchema = rest;
8603
8604
  shouldHandleEnumAndConst = true;
@@ -9187,7 +9188,7 @@ function schemaEqualsChecker(extendsContext) {
9187
9188
  }
9188
9189
  function isValueEquals(value1, value2) {
9189
9190
  if (value1 === value2) return true;
9190
- if (value1 === null) return false;
9191
+ if (value1 === null || value2 === null) return false;
9191
9192
  if (typeof value1 !== "object") return false;
9192
9193
  if (typeof value1 !== typeof value2) return false;
9193
9194
  if (isCompiledSchema(value1) && isCompiledSchema(value2)) return isCompiledSchemaEquals(value1, value2);
@@ -9753,7 +9754,7 @@ function findMismatchPath(source, target) {
9753
9754
  if ((sourceSchema.maxProperties ?? Number.POSITIVE_INFINITY) > (targetSchema.maxProperties ?? Number.POSITIVE_INFINITY)) return [...targetPath, "maxProperties"];
9754
9755
  break;
9755
9756
  }
9756
- case CompiledKind.EnumOrConst: return [...targetPath, targetSchema.const == null ? "enum" : "const"];
9757
+ case CompiledKind.EnumOrConst: return [...targetPath, targetSchema.const === void 0 ? "enum" : "const"];
9757
9758
  }
9758
9759
  return targetPath;
9759
9760
  }
@@ -6808,7 +6808,8 @@ var managedFields = object({
6808
6808
  object({
6809
6809
  kind: literal("connector"),
6810
6810
  action: text,
6811
- connectionId: text.optional()
6811
+ connectionId: text.optional(),
6812
+ outputMode: literal("value").optional()
6812
6813
  }),
6813
6814
  object({
6814
6815
  kind: literal("openapi"),
@@ -8193,10 +8194,10 @@ function compileEnumAndConst(context, enumList, constValue, schema) {
8193
8194
  }
8194
8195
  if (compiledEnum.length === 0) recordWarn(context, "all of elements from list is rejected by currently schema object", "enum");
8195
8196
  }
8196
- if (constValue && valid(schema, constValue) === ValidResult.Invalid) isNever = true;
8197
+ if (constValue !== void 0 && valid(schema, constValue) === ValidResult.Invalid) isNever = true;
8197
8198
  if (compiledEnum) {
8198
8199
  if (compiledEnum.length === 0) isNever = true;
8199
- else if (constValue) {
8200
+ else if (constValue !== void 0) {
8200
8201
  let foundEquals = false;
8201
8202
  for (const enumValue of compiledEnum) if (isDeepEquals(enumValue, constValue)) {
8202
8203
  foundEquals = true;
@@ -8209,7 +8210,7 @@ function compileEnumAndConst(context, enumList, constValue, schema) {
8209
8210
  const compiledSchema = {};
8210
8211
  if (schema.type) compiledSchema.type = schema.type;
8211
8212
  if (compiledEnum) compiledSchema.enum = compiledEnum;
8212
- if (constValue) compiledSchema.const = wrapCompiledValue(deepCopy(constValue));
8213
+ if (constValue !== void 0) compiledSchema.const = wrapCompiledValue(deepCopy(constValue));
8213
8214
  return wrapCompiledSchema(kind, compiledSchema, context.delegate, context.path);
8214
8215
  }
8215
8216
  //#endregion
@@ -8604,7 +8605,7 @@ function compileSchema(context, schema) {
8604
8605
  let targetSchema = schema;
8605
8606
  let shouldHandleEnumAndConst = false;
8606
8607
  const { enum: enumList, const: constValue } = schema;
8607
- if (enumList || constValue) {
8608
+ if (enumList || constValue !== void 0) {
8608
8609
  const { enum: _0, const: _1, ...rest } = schema;
8609
8610
  targetSchema = rest;
8610
8611
  shouldHandleEnumAndConst = true;
@@ -9194,7 +9195,7 @@ function schemaEqualsChecker(extendsContext) {
9194
9195
  }
9195
9196
  function isValueEquals(value1, value2) {
9196
9197
  if (value1 === value2) return true;
9197
- if (value1 === null) return false;
9198
+ if (value1 === null || value2 === null) return false;
9198
9199
  if (typeof value1 !== "object") return false;
9199
9200
  if (typeof value1 !== typeof value2) return false;
9200
9201
  if (isCompiledSchema(value1) && isCompiledSchema(value2)) return isCompiledSchemaEquals(value1, value2);
@@ -9760,7 +9761,7 @@ function findMismatchPath(source, target) {
9760
9761
  if ((sourceSchema.maxProperties ?? Number.POSITIVE_INFINITY) > (targetSchema.maxProperties ?? Number.POSITIVE_INFINITY)) return [...targetPath, "maxProperties"];
9761
9762
  break;
9762
9763
  }
9763
- case CompiledKind.EnumOrConst: return [...targetPath, targetSchema.const == null ? "enum" : "const"];
9764
+ case CompiledKind.EnumOrConst: return [...targetPath, targetSchema.const === void 0 ? "enum" : "const"];
9764
9765
  }
9765
9766
  return targetPath;
9766
9767
  }
@@ -398,7 +398,7 @@ export default () => fs.readFileSync('/etc/passwd', 'utf8')`)
398
398
  program: program(harness, `export default async (_input, context) => ({ available: typeof context.outputs, previous: await context.getPrevious(), value: 1 })`)
399
399
  }), {
400
400
  available: "undefined",
401
- previous: null,
401
+ previous: [],
402
402
  value: 1
403
403
  }, "Final Task outputs");
404
404
  }
@@ -9,6 +9,8 @@ export interface WaitResolution {
9
9
  readonly resolvedAt: string;
10
10
  readonly comment: string | null;
11
11
  }
12
+ export declare class PortValidationError extends Error {
13
+ }
12
14
  export type SchedulerEvent = {
13
15
  readonly flowId: string;
14
16
  readonly parentJobId?: string;
@@ -103,6 +105,24 @@ export interface WaitHost {
103
105
  readonly resolutions: (waitIds: readonly string[], block: boolean) => Effect.Effect<Readonly<Record<string, WaitResolution>>, Error>;
104
106
  }
105
107
  export declare const waitRetentionMs = 120000;
108
+ export interface DependenciesCheckpoint {
109
+ nextId: number;
110
+ iterations: Record<string, number>;
111
+ nodes: Record<string, DependencyState>;
112
+ }
113
+ interface DependencyState {
114
+ id: number;
115
+ status: 'pending' | 'running' | 'completed' | 'skipped';
116
+ input: Record<string, {
117
+ readonly execution: number;
118
+ readonly outputs: Readonly<Record<string, JsonValue>>;
119
+ }>;
120
+ output?: Readonly<Record<string, JsonValue>>;
121
+ previous: string[];
122
+ released: string[];
123
+ jobId?: string;
124
+ seeded: boolean;
125
+ }
106
126
  export interface FlowRunCheckpoint {
107
127
  readonly bindingValues: Readonly<Record<string, string>>;
108
128
  readonly inputs: Readonly<Record<string, Readonly<Record<string, JsonValue>>>>;
@@ -111,7 +131,7 @@ export interface FlowRunCheckpoint {
111
131
  readonly outputs: Readonly<Record<string, JsonValue>>;
112
132
  }>>;
113
133
  readonly counts: Readonly<Record<string, Readonly<Record<string, number>>>>;
114
- readonly frames: Readonly<Record<string, Readonly<Record<string, Readonly<Record<string, JsonValue>>>>>>;
134
+ readonly dependencies: DependenciesCheckpoint;
115
135
  readonly version: 5;
116
136
  readonly waits: readonly PendingWait[];
117
137
  readonly agents: Readonly<Record<string, {
@@ -143,7 +163,7 @@ interface TaskInvocationBase {
143
163
  export type TaskInvocation = TaskInvocationBase & ({
144
164
  readonly capabilities: readonly ConnectorCapability[];
145
165
  readonly moduleId: string;
146
- readonly getPrevious: () => PreviousNode | null;
166
+ readonly getPrevious: () => readonly PreviousNode[];
147
167
  } | {
148
168
  readonly kind: 'managed';
149
169
  });