@duckflux/runner 0.7.0 → 0.7.2

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 (3) hide show
  1. package/dist/main.js +1126 -16
  2. package/package.json +1 -1
  3. package/src/main.ts +2 -8
package/dist/main.js CHANGED
@@ -126,9 +126,7 @@ async function createHub(config) {
126
126
  var init_eventhub = () => {};
127
127
 
128
128
  // src/main.ts
129
- import { readFileSync as readFileSync3 } from "fs";
130
129
  import { parseArgs } from "util";
131
- import { dirname as dirname5, resolve as resolve5 } from "path";
132
130
 
133
131
  // src/lint.ts
134
132
  import { dirname as dirname2 } from "node:path";
@@ -136,7 +134,6 @@ import { dirname as dirname2 } from "node:path";
136
134
  // ../core/dist/index.js
137
135
  import { createRequire as createRequire2 } from "node:module";
138
136
  import { readFile } from "node:fs/promises";
139
- import { readFileSync } from "node:fs";
140
137
  import { constants } from "node:fs";
141
138
  import { access } from "node:fs/promises";
142
139
  import { resolve } from "node:path";
@@ -25799,6 +25796,549 @@ var require_dist2 = __commonJS((exports, module) => {
25799
25796
  Object.defineProperty(exports, "__esModule", { value: true });
25800
25797
  exports.default = formatsPlugin;
25801
25798
  });
25799
+ var duckflux_schema_default;
25800
+ var init_duckflux_schema = __esm2(() => {
25801
+ duckflux_schema_default = {
25802
+ $schema: "https://json-schema.org/draft/2020-12/schema",
25803
+ $id: "https://raw.githubusercontent.com/duckflux/spec/main/duckflux.schema.json",
25804
+ title: "duckflux Workflow",
25805
+ description: "Schema for duckflux — a minimal, deterministic, runtime-agnostic workflow DSL.",
25806
+ type: "object",
25807
+ required: ["flow"],
25808
+ additionalProperties: false,
25809
+ properties: {
25810
+ id: {
25811
+ type: "string",
25812
+ description: "Unique identifier for the workflow."
25813
+ },
25814
+ name: {
25815
+ type: "string",
25816
+ description: "Human-readable workflow name."
25817
+ },
25818
+ version: {
25819
+ description: "Version identifier for the workflow definition.",
25820
+ oneOf: [
25821
+ { type: "string" },
25822
+ { type: "integer" }
25823
+ ]
25824
+ },
25825
+ defaults: {
25826
+ $ref: "#/$defs/defaults"
25827
+ },
25828
+ inputs: {
25829
+ $ref: "#/$defs/inputs"
25830
+ },
25831
+ participants: {
25832
+ type: "object",
25833
+ description: "Named steps that can be referenced in the flow.",
25834
+ additionalProperties: {
25835
+ $ref: "#/$defs/participant"
25836
+ },
25837
+ not: {
25838
+ anyOf: [
25839
+ { required: ["workflow"] },
25840
+ { required: ["execution"] },
25841
+ { required: ["input"] },
25842
+ { required: ["output"] },
25843
+ { required: ["env"] },
25844
+ { required: ["loop"] },
25845
+ { required: ["event"] }
25846
+ ]
25847
+ }
25848
+ },
25849
+ flow: {
25850
+ $ref: "#/$defs/flowSequence"
25851
+ },
25852
+ output: {
25853
+ $ref: "#/$defs/workflowOutput"
25854
+ }
25855
+ },
25856
+ $defs: {
25857
+ duration: {
25858
+ type: "string",
25859
+ pattern: "^[0-9]+(ms|s|m|h|d)$",
25860
+ description: "Duration string, e.g. '30s', '5m', '2h', '1d'."
25861
+ },
25862
+ celExpression: {
25863
+ type: "string",
25864
+ description: "A Google CEL expression."
25865
+ },
25866
+ defaults: {
25867
+ type: "object",
25868
+ description: "Global defaults applied to all participants.",
25869
+ additionalProperties: false,
25870
+ properties: {
25871
+ timeout: {
25872
+ $ref: "#/$defs/duration"
25873
+ },
25874
+ cwd: {
25875
+ type: "string",
25876
+ description: "Default working directory for exec participants. Supports CEL expressions."
25877
+ }
25878
+ }
25879
+ },
25880
+ inputs: {
25881
+ type: "object",
25882
+ description: "Workflow input parameters. Accessed in CEL as workflow.inputs.<field>. Each key is a parameter name. Value can be null (string, no schema), or a JSON Schema object for validation.",
25883
+ additionalProperties: {
25884
+ oneOf: [
25885
+ { type: "null" },
25886
+ { $ref: "#/$defs/inputField" }
25887
+ ]
25888
+ }
25889
+ },
25890
+ inputField: {
25891
+ type: "object",
25892
+ description: "JSON Schema field definition with optional 'required: true' shortcut.",
25893
+ properties: {
25894
+ type: {
25895
+ type: "string",
25896
+ enum: ["string", "integer", "number", "boolean", "array", "object"]
25897
+ },
25898
+ description: { type: "string" },
25899
+ default: {},
25900
+ required: { type: "boolean" },
25901
+ format: { type: "string" },
25902
+ enum: { type: "array" },
25903
+ minimum: { type: "number" },
25904
+ maximum: { type: "number" },
25905
+ minLength: { type: "integer" },
25906
+ maxLength: { type: "integer" },
25907
+ pattern: { type: "string" },
25908
+ items: {
25909
+ $ref: "#/$defs/inputField"
25910
+ }
25911
+ },
25912
+ additionalProperties: false
25913
+ },
25914
+ retryConfig: {
25915
+ type: "object",
25916
+ description: "Retry configuration. Only applies when onError is 'retry'.",
25917
+ additionalProperties: false,
25918
+ required: ["max"],
25919
+ properties: {
25920
+ max: {
25921
+ type: "integer",
25922
+ minimum: 1,
25923
+ description: "Maximum number of retry attempts."
25924
+ },
25925
+ backoff: {
25926
+ $ref: "#/$defs/duration",
25927
+ description: "Interval between attempts. Default: 0s."
25928
+ },
25929
+ factor: {
25930
+ type: "number",
25931
+ minimum: 1,
25932
+ description: "Backoff multiplier. Default: 1 (no escalation)."
25933
+ }
25934
+ }
25935
+ },
25936
+ onError: {
25937
+ type: "string",
25938
+ description: "Error handling strategy: 'fail' (default), 'skip', 'retry', or a participant name for redirect.",
25939
+ minLength: 1
25940
+ },
25941
+ onTimeout: {
25942
+ type: "string",
25943
+ description: "Timeout handling strategy: 'fail' (default), 'skip', or a participant name for redirect.",
25944
+ minLength: 1
25945
+ },
25946
+ participantInput: {
25947
+ description: "Explicit input mapping. String for direct passthrough, object for structured mapping. Values are CEL expressions. Merged with implicit I/O chain input at runtime.",
25948
+ oneOf: [
25949
+ { type: "string" },
25950
+ {
25951
+ type: "object",
25952
+ additionalProperties: {
25953
+ type: "string"
25954
+ }
25955
+ }
25956
+ ]
25957
+ },
25958
+ participantOutputSchema: {
25959
+ type: "object",
25960
+ description: "Output schema (JSON Schema fields). Opt-in validation.",
25961
+ additionalProperties: {
25962
+ $ref: "#/$defs/inputField"
25963
+ }
25964
+ },
25965
+ payload: {
25966
+ description: "Event payload. String (CEL expression) or object with CEL expressions as values.",
25967
+ oneOf: [
25968
+ { type: "string" },
25969
+ {
25970
+ type: "object",
25971
+ additionalProperties: {}
25972
+ }
25973
+ ]
25974
+ },
25975
+ participant: {
25976
+ type: "object",
25977
+ required: ["type"],
25978
+ description: "A named, reusable building block of the workflow.",
25979
+ properties: {
25980
+ type: {
25981
+ type: "string",
25982
+ enum: ["exec", "http", "mcp", "workflow", "emit"],
25983
+ description: "Participant type."
25984
+ },
25985
+ as: {
25986
+ type: "string",
25987
+ description: "Human-readable display name."
25988
+ },
25989
+ timeout: {
25990
+ $ref: "#/$defs/duration"
25991
+ },
25992
+ onError: {
25993
+ $ref: "#/$defs/onError"
25994
+ },
25995
+ retry: {
25996
+ $ref: "#/$defs/retryConfig"
25997
+ },
25998
+ input: {
25999
+ $ref: "#/$defs/participantInput"
26000
+ },
26001
+ output: {
26002
+ $ref: "#/$defs/participantOutputSchema"
26003
+ },
26004
+ run: {
26005
+ type: "string",
26006
+ description: "[exec] Shell command to execute."
26007
+ },
26008
+ cwd: {
26009
+ type: "string",
26010
+ description: "[exec] Working directory. Supports CEL expressions."
26011
+ },
26012
+ url: {
26013
+ type: "string",
26014
+ description: "[http] Target URL. Supports CEL expressions."
26015
+ },
26016
+ method: {
26017
+ type: "string",
26018
+ enum: ["GET", "POST", "PUT", "PATCH", "DELETE"],
26019
+ description: "[http] HTTP method."
26020
+ },
26021
+ headers: {
26022
+ type: "object",
26023
+ additionalProperties: { type: "string" },
26024
+ description: "[http] HTTP headers. Values support CEL expressions."
26025
+ },
26026
+ body: {
26027
+ description: "[http] Request body. String or object. Supports CEL expressions.",
26028
+ oneOf: [
26029
+ { type: "string" },
26030
+ { type: "object" }
26031
+ ]
26032
+ },
26033
+ path: {
26034
+ type: "string",
26035
+ description: "[workflow] Path to the sub-workflow YAML file."
26036
+ },
26037
+ server: {
26038
+ type: "string",
26039
+ description: "[mcp] MCP server identifier."
26040
+ },
26041
+ tool: {
26042
+ type: "string",
26043
+ description: "[mcp] MCP tool name to invoke."
26044
+ },
26045
+ event: {
26046
+ type: "string",
26047
+ description: "[emit] Event name to emit."
26048
+ },
26049
+ payload: {
26050
+ $ref: "#/$defs/payload",
26051
+ description: "[emit] Event payload. CEL expression or object with CEL expressions."
26052
+ },
26053
+ ack: {
26054
+ type: "boolean",
26055
+ description: "[emit] If true, wait for delivery acknowledgment. Default: false.",
26056
+ default: false
26057
+ }
26058
+ },
26059
+ additionalProperties: false
26060
+ },
26061
+ inlineParticipant: {
26062
+ type: "object",
26063
+ required: ["type"],
26064
+ description: "An inline participant definition in the flow. 'as' is optional — if omitted, the participant is anonymous and its output is only accessible via the implicit I/O chain.",
26065
+ properties: {
26066
+ as: {
26067
+ type: "string",
26068
+ description: "Optional name for inline participants. If provided, must be unique across all participant names. Enables output reference by name."
26069
+ },
26070
+ type: {
26071
+ type: "string",
26072
+ enum: ["exec", "http", "mcp", "workflow", "emit"],
26073
+ description: "Participant type."
26074
+ },
26075
+ when: {
26076
+ $ref: "#/$defs/celExpression",
26077
+ description: "Guard condition. If false, step is skipped."
26078
+ },
26079
+ timeout: {
26080
+ $ref: "#/$defs/duration"
26081
+ },
26082
+ onError: {
26083
+ $ref: "#/$defs/onError"
26084
+ },
26085
+ retry: {
26086
+ $ref: "#/$defs/retryConfig"
26087
+ },
26088
+ input: {
26089
+ $ref: "#/$defs/participantInput"
26090
+ },
26091
+ output: {
26092
+ $ref: "#/$defs/participantOutputSchema"
26093
+ },
26094
+ run: { type: "string" },
26095
+ cwd: { type: "string" },
26096
+ url: { type: "string" },
26097
+ method: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE"] },
26098
+ headers: { type: "object", additionalProperties: { type: "string" } },
26099
+ body: { oneOf: [{ type: "string" }, { type: "object" }] },
26100
+ path: { type: "string" },
26101
+ server: { type: "string" },
26102
+ tool: { type: "string" },
26103
+ event: { type: "string" },
26104
+ payload: { $ref: "#/$defs/payload" },
26105
+ ack: { type: "boolean" }
26106
+ },
26107
+ additionalProperties: false
26108
+ },
26109
+ flowSequence: {
26110
+ type: "array",
26111
+ description: "Ordered list of flow steps. Each step's output is implicitly chained as input to the next step.",
26112
+ minItems: 1,
26113
+ items: {
26114
+ $ref: "#/$defs/flowStep"
26115
+ }
26116
+ },
26117
+ flowStep: {
26118
+ description: "A single step in the flow: participant reference (string), control construct, inline participant (named or anonymous), or participant override.",
26119
+ oneOf: [
26120
+ {
26121
+ type: "string",
26122
+ description: "Simple participant reference by name."
26123
+ },
26124
+ { $ref: "#/$defs/loopStep" },
26125
+ { $ref: "#/$defs/parallelStep" },
26126
+ { $ref: "#/$defs/ifStep" },
26127
+ { $ref: "#/$defs/setStep" },
26128
+ { $ref: "#/$defs/waitStep" },
26129
+ { $ref: "#/$defs/inlineParticipant" },
26130
+ { $ref: "#/$defs/participantOverrideStep" }
26131
+ ]
26132
+ },
26133
+ loopStep: {
26134
+ type: "object",
26135
+ required: ["loop"],
26136
+ additionalProperties: false,
26137
+ properties: {
26138
+ loop: {
26139
+ type: "object",
26140
+ additionalProperties: false,
26141
+ required: ["steps"],
26142
+ properties: {
26143
+ as: {
26144
+ type: "string",
26145
+ description: "Renames the loop context variable. Access as <as>.index, <as>.iteration, etc. instead of loop.*"
26146
+ },
26147
+ until: {
26148
+ $ref: "#/$defs/celExpression",
26149
+ description: "CEL condition to break out of the loop."
26150
+ },
26151
+ max: {
26152
+ description: "Maximum iterations. Integer or CEL expression.",
26153
+ oneOf: [
26154
+ { type: "integer", minimum: 1 },
26155
+ { type: "string" }
26156
+ ]
26157
+ },
26158
+ steps: {
26159
+ $ref: "#/$defs/flowSequence"
26160
+ }
26161
+ },
26162
+ anyOf: [
26163
+ { required: ["until"] },
26164
+ { required: ["max"] }
26165
+ ]
26166
+ }
26167
+ }
26168
+ },
26169
+ parallelStep: {
26170
+ type: "object",
26171
+ required: ["parallel"],
26172
+ additionalProperties: false,
26173
+ properties: {
26174
+ parallel: {
26175
+ $ref: "#/$defs/flowSequence",
26176
+ description: "Steps to run concurrently. The chained output after a parallel block is an array of all branch outputs in declaration order."
26177
+ }
26178
+ }
26179
+ },
26180
+ ifStep: {
26181
+ type: "object",
26182
+ required: ["if"],
26183
+ additionalProperties: false,
26184
+ properties: {
26185
+ if: {
26186
+ type: "object",
26187
+ required: ["condition", "then"],
26188
+ additionalProperties: false,
26189
+ properties: {
26190
+ condition: {
26191
+ $ref: "#/$defs/celExpression",
26192
+ description: "CEL expression that determines which branch to take."
26193
+ },
26194
+ then: {
26195
+ $ref: "#/$defs/flowSequence"
26196
+ },
26197
+ else: {
26198
+ $ref: "#/$defs/flowSequence"
26199
+ }
26200
+ }
26201
+ }
26202
+ }
26203
+ },
26204
+ setStep: {
26205
+ type: "object",
26206
+ required: ["set"],
26207
+ additionalProperties: false,
26208
+ properties: {
26209
+ set: {
26210
+ type: "object",
26211
+ description: "Writes values into execution.context. Each key becomes execution.context.<key>. Values are CEL expressions.",
26212
+ minProperties: 1,
26213
+ additionalProperties: {
26214
+ $ref: "#/$defs/celExpression"
26215
+ },
26216
+ not: {
26217
+ anyOf: [
26218
+ { required: ["workflow"] },
26219
+ { required: ["execution"] },
26220
+ { required: ["input"] },
26221
+ { required: ["output"] },
26222
+ { required: ["env"] },
26223
+ { required: ["loop"] },
26224
+ { required: ["event"] }
26225
+ ]
26226
+ }
26227
+ }
26228
+ }
26229
+ },
26230
+ waitStep: {
26231
+ type: "object",
26232
+ required: ["wait"],
26233
+ additionalProperties: false,
26234
+ properties: {
26235
+ wait: {
26236
+ type: "object",
26237
+ additionalProperties: false,
26238
+ properties: {
26239
+ event: {
26240
+ type: "string",
26241
+ description: "Event name to wait for (event mode)."
26242
+ },
26243
+ match: {
26244
+ $ref: "#/$defs/celExpression",
26245
+ description: "CEL condition to match against event payload. 'event' variable contains the payload."
26246
+ },
26247
+ until: {
26248
+ $ref: "#/$defs/celExpression",
26249
+ description: "CEL condition to wait for (polling mode)."
26250
+ },
26251
+ poll: {
26252
+ $ref: "#/$defs/duration",
26253
+ description: "Polling interval for 'until' condition. Default: runtime decides."
26254
+ },
26255
+ timeout: {
26256
+ $ref: "#/$defs/duration",
26257
+ description: "Maximum wait time."
26258
+ },
26259
+ onTimeout: {
26260
+ $ref: "#/$defs/onTimeout",
26261
+ description: "Strategy when timeout is reached: 'fail' (default), 'skip', or participant name."
26262
+ }
26263
+ }
26264
+ }
26265
+ }
26266
+ },
26267
+ participantOverrideStep: {
26268
+ type: "object",
26269
+ description: "A participant reference with flow-level overrides (timeout, onError, when, input, workflow, etc.).",
26270
+ minProperties: 1,
26271
+ maxProperties: 1,
26272
+ not: {
26273
+ anyOf: [
26274
+ { required: ["loop"] },
26275
+ { required: ["parallel"] },
26276
+ { required: ["if"] },
26277
+ { required: ["wait"] },
26278
+ { required: ["set"] },
26279
+ { required: ["type"] }
26280
+ ]
26281
+ },
26282
+ additionalProperties: {
26283
+ type: "object",
26284
+ properties: {
26285
+ when: {
26286
+ $ref: "#/$defs/celExpression",
26287
+ description: "Guard condition. If false, step is skipped."
26288
+ },
26289
+ timeout: {
26290
+ $ref: "#/$defs/duration"
26291
+ },
26292
+ onError: {
26293
+ $ref: "#/$defs/onError"
26294
+ },
26295
+ retry: {
26296
+ $ref: "#/$defs/retryConfig"
26297
+ },
26298
+ input: {
26299
+ $ref: "#/$defs/participantInput"
26300
+ },
26301
+ workflow: {
26302
+ type: "string",
26303
+ description: "Inline sub-workflow path (alternative to defining as participant)."
26304
+ }
26305
+ },
26306
+ additionalProperties: false
26307
+ }
26308
+ },
26309
+ workflowOutput: {
26310
+ description: "Workflow output. Accessed in CEL as workflow.output. String (single CEL expression), object (structured mapping), or object with schema+map.",
26311
+ oneOf: [
26312
+ {
26313
+ type: "string",
26314
+ description: "Single CEL expression mapping."
26315
+ },
26316
+ {
26317
+ type: "object",
26318
+ description: "Structured output mapping (key → CEL expression) or schema+map.",
26319
+ properties: {
26320
+ schema: {
26321
+ type: "object",
26322
+ additionalProperties: {
26323
+ $ref: "#/$defs/inputField"
26324
+ }
26325
+ },
26326
+ map: {
26327
+ type: "object",
26328
+ additionalProperties: {
26329
+ type: "string"
26330
+ }
26331
+ }
26332
+ },
26333
+ additionalProperties: {
26334
+ type: "string"
26335
+ }
26336
+ }
26337
+ ]
26338
+ }
26339
+ }
26340
+ };
26341
+ });
25802
26342
  function validateSchema(workflow) {
25803
26343
  const valid = validate(workflow);
25804
26344
  if (valid) {
@@ -25812,15 +26352,14 @@ function validateSchema(workflow) {
25812
26352
  }
25813
26353
  var import__2020;
25814
26354
  var import_ajv_formats;
25815
- var rawSchema;
25816
26355
  var schema;
25817
26356
  var ajv;
25818
26357
  var validate;
25819
26358
  var init_schema = __esm2(() => {
26359
+ init_duckflux_schema();
25820
26360
  import__2020 = __toESM(require_2020(), 1);
25821
26361
  import_ajv_formats = __toESM(require_dist2(), 1);
25822
- rawSchema = readFileSync(new URL("./schema/duckflux.schema.json", import.meta.url), "utf-8");
25823
- schema = JSON.parse(rawSchema);
26362
+ schema = { ...duckflux_schema_default };
25824
26363
  delete schema.$schema;
25825
26364
  ajv = new import__2020.default({ allErrors: true, strict: false });
25826
26365
  import_ajv_formats.default(ajv);
@@ -27883,7 +28422,6 @@ import { readFile as readFile5 } from "node:fs/promises";
27883
28422
  // ../core/dist/engine/index.js
27884
28423
  import { createRequire as createRequire3 } from "node:module";
27885
28424
  import { readFile as readFile3 } from "node:fs/promises";
27886
- import { readFileSync as readFileSync2 } from "node:fs";
27887
28425
  import { constants as constants2 } from "node:fs";
27888
28426
  import { access as access2 } from "node:fs/promises";
27889
28427
  import { resolve as resolve3 } from "node:path";
@@ -53549,6 +54087,549 @@ var require_dist22 = __commonJS2((exports, module) => {
53549
54087
  Object.defineProperty(exports, "__esModule", { value: true });
53550
54088
  exports.default = formatsPlugin;
53551
54089
  });
54090
+ var duckflux_schema_default2;
54091
+ var init_duckflux_schema2 = __esm3(() => {
54092
+ duckflux_schema_default2 = {
54093
+ $schema: "https://json-schema.org/draft/2020-12/schema",
54094
+ $id: "https://raw.githubusercontent.com/duckflux/spec/main/duckflux.schema.json",
54095
+ title: "duckflux Workflow",
54096
+ description: "Schema for duckflux — a minimal, deterministic, runtime-agnostic workflow DSL.",
54097
+ type: "object",
54098
+ required: ["flow"],
54099
+ additionalProperties: false,
54100
+ properties: {
54101
+ id: {
54102
+ type: "string",
54103
+ description: "Unique identifier for the workflow."
54104
+ },
54105
+ name: {
54106
+ type: "string",
54107
+ description: "Human-readable workflow name."
54108
+ },
54109
+ version: {
54110
+ description: "Version identifier for the workflow definition.",
54111
+ oneOf: [
54112
+ { type: "string" },
54113
+ { type: "integer" }
54114
+ ]
54115
+ },
54116
+ defaults: {
54117
+ $ref: "#/$defs/defaults"
54118
+ },
54119
+ inputs: {
54120
+ $ref: "#/$defs/inputs"
54121
+ },
54122
+ participants: {
54123
+ type: "object",
54124
+ description: "Named steps that can be referenced in the flow.",
54125
+ additionalProperties: {
54126
+ $ref: "#/$defs/participant"
54127
+ },
54128
+ not: {
54129
+ anyOf: [
54130
+ { required: ["workflow"] },
54131
+ { required: ["execution"] },
54132
+ { required: ["input"] },
54133
+ { required: ["output"] },
54134
+ { required: ["env"] },
54135
+ { required: ["loop"] },
54136
+ { required: ["event"] }
54137
+ ]
54138
+ }
54139
+ },
54140
+ flow: {
54141
+ $ref: "#/$defs/flowSequence"
54142
+ },
54143
+ output: {
54144
+ $ref: "#/$defs/workflowOutput"
54145
+ }
54146
+ },
54147
+ $defs: {
54148
+ duration: {
54149
+ type: "string",
54150
+ pattern: "^[0-9]+(ms|s|m|h|d)$",
54151
+ description: "Duration string, e.g. '30s', '5m', '2h', '1d'."
54152
+ },
54153
+ celExpression: {
54154
+ type: "string",
54155
+ description: "A Google CEL expression."
54156
+ },
54157
+ defaults: {
54158
+ type: "object",
54159
+ description: "Global defaults applied to all participants.",
54160
+ additionalProperties: false,
54161
+ properties: {
54162
+ timeout: {
54163
+ $ref: "#/$defs/duration"
54164
+ },
54165
+ cwd: {
54166
+ type: "string",
54167
+ description: "Default working directory for exec participants. Supports CEL expressions."
54168
+ }
54169
+ }
54170
+ },
54171
+ inputs: {
54172
+ type: "object",
54173
+ description: "Workflow input parameters. Accessed in CEL as workflow.inputs.<field>. Each key is a parameter name. Value can be null (string, no schema), or a JSON Schema object for validation.",
54174
+ additionalProperties: {
54175
+ oneOf: [
54176
+ { type: "null" },
54177
+ { $ref: "#/$defs/inputField" }
54178
+ ]
54179
+ }
54180
+ },
54181
+ inputField: {
54182
+ type: "object",
54183
+ description: "JSON Schema field definition with optional 'required: true' shortcut.",
54184
+ properties: {
54185
+ type: {
54186
+ type: "string",
54187
+ enum: ["string", "integer", "number", "boolean", "array", "object"]
54188
+ },
54189
+ description: { type: "string" },
54190
+ default: {},
54191
+ required: { type: "boolean" },
54192
+ format: { type: "string" },
54193
+ enum: { type: "array" },
54194
+ minimum: { type: "number" },
54195
+ maximum: { type: "number" },
54196
+ minLength: { type: "integer" },
54197
+ maxLength: { type: "integer" },
54198
+ pattern: { type: "string" },
54199
+ items: {
54200
+ $ref: "#/$defs/inputField"
54201
+ }
54202
+ },
54203
+ additionalProperties: false
54204
+ },
54205
+ retryConfig: {
54206
+ type: "object",
54207
+ description: "Retry configuration. Only applies when onError is 'retry'.",
54208
+ additionalProperties: false,
54209
+ required: ["max"],
54210
+ properties: {
54211
+ max: {
54212
+ type: "integer",
54213
+ minimum: 1,
54214
+ description: "Maximum number of retry attempts."
54215
+ },
54216
+ backoff: {
54217
+ $ref: "#/$defs/duration",
54218
+ description: "Interval between attempts. Default: 0s."
54219
+ },
54220
+ factor: {
54221
+ type: "number",
54222
+ minimum: 1,
54223
+ description: "Backoff multiplier. Default: 1 (no escalation)."
54224
+ }
54225
+ }
54226
+ },
54227
+ onError: {
54228
+ type: "string",
54229
+ description: "Error handling strategy: 'fail' (default), 'skip', 'retry', or a participant name for redirect.",
54230
+ minLength: 1
54231
+ },
54232
+ onTimeout: {
54233
+ type: "string",
54234
+ description: "Timeout handling strategy: 'fail' (default), 'skip', or a participant name for redirect.",
54235
+ minLength: 1
54236
+ },
54237
+ participantInput: {
54238
+ description: "Explicit input mapping. String for direct passthrough, object for structured mapping. Values are CEL expressions. Merged with implicit I/O chain input at runtime.",
54239
+ oneOf: [
54240
+ { type: "string" },
54241
+ {
54242
+ type: "object",
54243
+ additionalProperties: {
54244
+ type: "string"
54245
+ }
54246
+ }
54247
+ ]
54248
+ },
54249
+ participantOutputSchema: {
54250
+ type: "object",
54251
+ description: "Output schema (JSON Schema fields). Opt-in validation.",
54252
+ additionalProperties: {
54253
+ $ref: "#/$defs/inputField"
54254
+ }
54255
+ },
54256
+ payload: {
54257
+ description: "Event payload. String (CEL expression) or object with CEL expressions as values.",
54258
+ oneOf: [
54259
+ { type: "string" },
54260
+ {
54261
+ type: "object",
54262
+ additionalProperties: {}
54263
+ }
54264
+ ]
54265
+ },
54266
+ participant: {
54267
+ type: "object",
54268
+ required: ["type"],
54269
+ description: "A named, reusable building block of the workflow.",
54270
+ properties: {
54271
+ type: {
54272
+ type: "string",
54273
+ enum: ["exec", "http", "mcp", "workflow", "emit"],
54274
+ description: "Participant type."
54275
+ },
54276
+ as: {
54277
+ type: "string",
54278
+ description: "Human-readable display name."
54279
+ },
54280
+ timeout: {
54281
+ $ref: "#/$defs/duration"
54282
+ },
54283
+ onError: {
54284
+ $ref: "#/$defs/onError"
54285
+ },
54286
+ retry: {
54287
+ $ref: "#/$defs/retryConfig"
54288
+ },
54289
+ input: {
54290
+ $ref: "#/$defs/participantInput"
54291
+ },
54292
+ output: {
54293
+ $ref: "#/$defs/participantOutputSchema"
54294
+ },
54295
+ run: {
54296
+ type: "string",
54297
+ description: "[exec] Shell command to execute."
54298
+ },
54299
+ cwd: {
54300
+ type: "string",
54301
+ description: "[exec] Working directory. Supports CEL expressions."
54302
+ },
54303
+ url: {
54304
+ type: "string",
54305
+ description: "[http] Target URL. Supports CEL expressions."
54306
+ },
54307
+ method: {
54308
+ type: "string",
54309
+ enum: ["GET", "POST", "PUT", "PATCH", "DELETE"],
54310
+ description: "[http] HTTP method."
54311
+ },
54312
+ headers: {
54313
+ type: "object",
54314
+ additionalProperties: { type: "string" },
54315
+ description: "[http] HTTP headers. Values support CEL expressions."
54316
+ },
54317
+ body: {
54318
+ description: "[http] Request body. String or object. Supports CEL expressions.",
54319
+ oneOf: [
54320
+ { type: "string" },
54321
+ { type: "object" }
54322
+ ]
54323
+ },
54324
+ path: {
54325
+ type: "string",
54326
+ description: "[workflow] Path to the sub-workflow YAML file."
54327
+ },
54328
+ server: {
54329
+ type: "string",
54330
+ description: "[mcp] MCP server identifier."
54331
+ },
54332
+ tool: {
54333
+ type: "string",
54334
+ description: "[mcp] MCP tool name to invoke."
54335
+ },
54336
+ event: {
54337
+ type: "string",
54338
+ description: "[emit] Event name to emit."
54339
+ },
54340
+ payload: {
54341
+ $ref: "#/$defs/payload",
54342
+ description: "[emit] Event payload. CEL expression or object with CEL expressions."
54343
+ },
54344
+ ack: {
54345
+ type: "boolean",
54346
+ description: "[emit] If true, wait for delivery acknowledgment. Default: false.",
54347
+ default: false
54348
+ }
54349
+ },
54350
+ additionalProperties: false
54351
+ },
54352
+ inlineParticipant: {
54353
+ type: "object",
54354
+ required: ["type"],
54355
+ description: "An inline participant definition in the flow. 'as' is optional — if omitted, the participant is anonymous and its output is only accessible via the implicit I/O chain.",
54356
+ properties: {
54357
+ as: {
54358
+ type: "string",
54359
+ description: "Optional name for inline participants. If provided, must be unique across all participant names. Enables output reference by name."
54360
+ },
54361
+ type: {
54362
+ type: "string",
54363
+ enum: ["exec", "http", "mcp", "workflow", "emit"],
54364
+ description: "Participant type."
54365
+ },
54366
+ when: {
54367
+ $ref: "#/$defs/celExpression",
54368
+ description: "Guard condition. If false, step is skipped."
54369
+ },
54370
+ timeout: {
54371
+ $ref: "#/$defs/duration"
54372
+ },
54373
+ onError: {
54374
+ $ref: "#/$defs/onError"
54375
+ },
54376
+ retry: {
54377
+ $ref: "#/$defs/retryConfig"
54378
+ },
54379
+ input: {
54380
+ $ref: "#/$defs/participantInput"
54381
+ },
54382
+ output: {
54383
+ $ref: "#/$defs/participantOutputSchema"
54384
+ },
54385
+ run: { type: "string" },
54386
+ cwd: { type: "string" },
54387
+ url: { type: "string" },
54388
+ method: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE"] },
54389
+ headers: { type: "object", additionalProperties: { type: "string" } },
54390
+ body: { oneOf: [{ type: "string" }, { type: "object" }] },
54391
+ path: { type: "string" },
54392
+ server: { type: "string" },
54393
+ tool: { type: "string" },
54394
+ event: { type: "string" },
54395
+ payload: { $ref: "#/$defs/payload" },
54396
+ ack: { type: "boolean" }
54397
+ },
54398
+ additionalProperties: false
54399
+ },
54400
+ flowSequence: {
54401
+ type: "array",
54402
+ description: "Ordered list of flow steps. Each step's output is implicitly chained as input to the next step.",
54403
+ minItems: 1,
54404
+ items: {
54405
+ $ref: "#/$defs/flowStep"
54406
+ }
54407
+ },
54408
+ flowStep: {
54409
+ description: "A single step in the flow: participant reference (string), control construct, inline participant (named or anonymous), or participant override.",
54410
+ oneOf: [
54411
+ {
54412
+ type: "string",
54413
+ description: "Simple participant reference by name."
54414
+ },
54415
+ { $ref: "#/$defs/loopStep" },
54416
+ { $ref: "#/$defs/parallelStep" },
54417
+ { $ref: "#/$defs/ifStep" },
54418
+ { $ref: "#/$defs/setStep" },
54419
+ { $ref: "#/$defs/waitStep" },
54420
+ { $ref: "#/$defs/inlineParticipant" },
54421
+ { $ref: "#/$defs/participantOverrideStep" }
54422
+ ]
54423
+ },
54424
+ loopStep: {
54425
+ type: "object",
54426
+ required: ["loop"],
54427
+ additionalProperties: false,
54428
+ properties: {
54429
+ loop: {
54430
+ type: "object",
54431
+ additionalProperties: false,
54432
+ required: ["steps"],
54433
+ properties: {
54434
+ as: {
54435
+ type: "string",
54436
+ description: "Renames the loop context variable. Access as <as>.index, <as>.iteration, etc. instead of loop.*"
54437
+ },
54438
+ until: {
54439
+ $ref: "#/$defs/celExpression",
54440
+ description: "CEL condition to break out of the loop."
54441
+ },
54442
+ max: {
54443
+ description: "Maximum iterations. Integer or CEL expression.",
54444
+ oneOf: [
54445
+ { type: "integer", minimum: 1 },
54446
+ { type: "string" }
54447
+ ]
54448
+ },
54449
+ steps: {
54450
+ $ref: "#/$defs/flowSequence"
54451
+ }
54452
+ },
54453
+ anyOf: [
54454
+ { required: ["until"] },
54455
+ { required: ["max"] }
54456
+ ]
54457
+ }
54458
+ }
54459
+ },
54460
+ parallelStep: {
54461
+ type: "object",
54462
+ required: ["parallel"],
54463
+ additionalProperties: false,
54464
+ properties: {
54465
+ parallel: {
54466
+ $ref: "#/$defs/flowSequence",
54467
+ description: "Steps to run concurrently. The chained output after a parallel block is an array of all branch outputs in declaration order."
54468
+ }
54469
+ }
54470
+ },
54471
+ ifStep: {
54472
+ type: "object",
54473
+ required: ["if"],
54474
+ additionalProperties: false,
54475
+ properties: {
54476
+ if: {
54477
+ type: "object",
54478
+ required: ["condition", "then"],
54479
+ additionalProperties: false,
54480
+ properties: {
54481
+ condition: {
54482
+ $ref: "#/$defs/celExpression",
54483
+ description: "CEL expression that determines which branch to take."
54484
+ },
54485
+ then: {
54486
+ $ref: "#/$defs/flowSequence"
54487
+ },
54488
+ else: {
54489
+ $ref: "#/$defs/flowSequence"
54490
+ }
54491
+ }
54492
+ }
54493
+ }
54494
+ },
54495
+ setStep: {
54496
+ type: "object",
54497
+ required: ["set"],
54498
+ additionalProperties: false,
54499
+ properties: {
54500
+ set: {
54501
+ type: "object",
54502
+ description: "Writes values into execution.context. Each key becomes execution.context.<key>. Values are CEL expressions.",
54503
+ minProperties: 1,
54504
+ additionalProperties: {
54505
+ $ref: "#/$defs/celExpression"
54506
+ },
54507
+ not: {
54508
+ anyOf: [
54509
+ { required: ["workflow"] },
54510
+ { required: ["execution"] },
54511
+ { required: ["input"] },
54512
+ { required: ["output"] },
54513
+ { required: ["env"] },
54514
+ { required: ["loop"] },
54515
+ { required: ["event"] }
54516
+ ]
54517
+ }
54518
+ }
54519
+ }
54520
+ },
54521
+ waitStep: {
54522
+ type: "object",
54523
+ required: ["wait"],
54524
+ additionalProperties: false,
54525
+ properties: {
54526
+ wait: {
54527
+ type: "object",
54528
+ additionalProperties: false,
54529
+ properties: {
54530
+ event: {
54531
+ type: "string",
54532
+ description: "Event name to wait for (event mode)."
54533
+ },
54534
+ match: {
54535
+ $ref: "#/$defs/celExpression",
54536
+ description: "CEL condition to match against event payload. 'event' variable contains the payload."
54537
+ },
54538
+ until: {
54539
+ $ref: "#/$defs/celExpression",
54540
+ description: "CEL condition to wait for (polling mode)."
54541
+ },
54542
+ poll: {
54543
+ $ref: "#/$defs/duration",
54544
+ description: "Polling interval for 'until' condition. Default: runtime decides."
54545
+ },
54546
+ timeout: {
54547
+ $ref: "#/$defs/duration",
54548
+ description: "Maximum wait time."
54549
+ },
54550
+ onTimeout: {
54551
+ $ref: "#/$defs/onTimeout",
54552
+ description: "Strategy when timeout is reached: 'fail' (default), 'skip', or participant name."
54553
+ }
54554
+ }
54555
+ }
54556
+ }
54557
+ },
54558
+ participantOverrideStep: {
54559
+ type: "object",
54560
+ description: "A participant reference with flow-level overrides (timeout, onError, when, input, workflow, etc.).",
54561
+ minProperties: 1,
54562
+ maxProperties: 1,
54563
+ not: {
54564
+ anyOf: [
54565
+ { required: ["loop"] },
54566
+ { required: ["parallel"] },
54567
+ { required: ["if"] },
54568
+ { required: ["wait"] },
54569
+ { required: ["set"] },
54570
+ { required: ["type"] }
54571
+ ]
54572
+ },
54573
+ additionalProperties: {
54574
+ type: "object",
54575
+ properties: {
54576
+ when: {
54577
+ $ref: "#/$defs/celExpression",
54578
+ description: "Guard condition. If false, step is skipped."
54579
+ },
54580
+ timeout: {
54581
+ $ref: "#/$defs/duration"
54582
+ },
54583
+ onError: {
54584
+ $ref: "#/$defs/onError"
54585
+ },
54586
+ retry: {
54587
+ $ref: "#/$defs/retryConfig"
54588
+ },
54589
+ input: {
54590
+ $ref: "#/$defs/participantInput"
54591
+ },
54592
+ workflow: {
54593
+ type: "string",
54594
+ description: "Inline sub-workflow path (alternative to defining as participant)."
54595
+ }
54596
+ },
54597
+ additionalProperties: false
54598
+ }
54599
+ },
54600
+ workflowOutput: {
54601
+ description: "Workflow output. Accessed in CEL as workflow.output. String (single CEL expression), object (structured mapping), or object with schema+map.",
54602
+ oneOf: [
54603
+ {
54604
+ type: "string",
54605
+ description: "Single CEL expression mapping."
54606
+ },
54607
+ {
54608
+ type: "object",
54609
+ description: "Structured output mapping (key → CEL expression) or schema+map.",
54610
+ properties: {
54611
+ schema: {
54612
+ type: "object",
54613
+ additionalProperties: {
54614
+ $ref: "#/$defs/inputField"
54615
+ }
54616
+ },
54617
+ map: {
54618
+ type: "object",
54619
+ additionalProperties: {
54620
+ type: "string"
54621
+ }
54622
+ }
54623
+ },
54624
+ additionalProperties: {
54625
+ type: "string"
54626
+ }
54627
+ }
54628
+ ]
54629
+ }
54630
+ }
54631
+ };
54632
+ });
53552
54633
  function validateSchema2(workflow) {
53553
54634
  const valid = validate2(workflow);
53554
54635
  if (valid) {
@@ -53562,15 +54643,14 @@ function validateSchema2(workflow) {
53562
54643
  }
53563
54644
  var import__20202;
53564
54645
  var import_ajv_formats2;
53565
- var rawSchema2;
53566
54646
  var schema2;
53567
54647
  var ajv2;
53568
54648
  var validate2;
53569
54649
  var init_schema2 = __esm3(() => {
54650
+ init_duckflux_schema2();
53570
54651
  import__20202 = __toESM2(require_20202(), 1);
53571
54652
  import_ajv_formats2 = __toESM2(require_dist22(), 1);
53572
- rawSchema2 = readFileSync2(new URL("./schema/duckflux.schema.json", import.meta.url), "utf-8");
53573
- schema2 = JSON.parse(rawSchema2);
54653
+ schema2 = { ...duckflux_schema_default2 };
53574
54654
  delete schema2.$schema;
53575
54655
  ajv2 = new import__20202.default({ allErrors: true, strict: false });
53576
54656
  import_ajv_formats2.default(ajv2);
@@ -55957,15 +57037,45 @@ async function validateCommand(filePath, cliValues) {
55957
57037
  return 1;
55958
57038
  }
55959
57039
  }
57040
+ // package.json
57041
+ var package_default = {
57042
+ name: "@duckflux/runner",
57043
+ version: "0.7.2",
57044
+ type: "module",
57045
+ bin: {
57046
+ quack: "dist/main.js"
57047
+ },
57048
+ exports: {
57049
+ ".": "./dist/index.js",
57050
+ "./dist/main.js": "./dist/main.js"
57051
+ },
57052
+ files: [
57053
+ "dist",
57054
+ "src"
57055
+ ],
57056
+ scripts: {
57057
+ build: "bun build src/main.ts --outdir dist --target node --format esm --banner '#!/usr/bin/env node' && tsc --project tsconfig.build.json",
57058
+ postbuild: "chmod +x dist/main.js",
57059
+ prepublishOnly: "bun run build",
57060
+ "compile:linux-x64": "bun build --compile --target=bun-linux-x64 src/main.ts --outfile bin/quack-linux-x64",
57061
+ "compile:linux-arm64": "bun build --compile --target=bun-linux-arm64 src/main.ts --outfile bin/quack-linux-arm64",
57062
+ "compile:darwin-x64": "bun build --compile --target=bun-darwin-x64 src/main.ts --outfile bin/quack-darwin-x64",
57063
+ "compile:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 src/main.ts --outfile bin/quack-darwin-arm64",
57064
+ "compile:windows-x64": "bun build --compile --target=bun-windows-x64 src/main.ts --outfile bin/quack-windows-x64.exe",
57065
+ compile: "bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:darwin-x64 && bun run compile:darwin-arm64 && bun run compile:windows-x64"
57066
+ },
57067
+ dependencies: {
57068
+ "@duckflux/core": "workspace:*"
57069
+ },
57070
+ optionalDependencies: {
57071
+ "@duckflux/hub-nats": "workspace:*",
57072
+ "@duckflux/hub-redis": "workspace:*"
57073
+ }
57074
+ };
55960
57075
 
55961
57076
  // src/main.ts
55962
57077
  function getVersion() {
55963
- try {
55964
- const pkg = JSON.parse(readFileSync3(resolve5(dirname5(new URL(import.meta.url).pathname), "../package.json"), "utf-8"));
55965
- return pkg.version ?? "0.0.0";
55966
- } catch {
55967
- return "0.0.0";
55968
- }
57078
+ return package_default.version ?? "0.0.0";
55969
57079
  }
55970
57080
  if (__require.main == __require.module) {
55971
57081
  const argv = Bun.argv.slice(2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckflux/runner",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "quack": "dist/main.js"
package/src/main.ts CHANGED
@@ -1,19 +1,13 @@
1
1
  #!/usr/bin/env bun
2
- import { readFileSync } from "node:fs";
3
2
  import { parseArgs } from "node:util";
4
- import { dirname, resolve } from "node:path";
5
3
  import lintCommand from "./lint";
6
4
  import runCommand from "./run";
7
5
  import serverCommand from "./server";
8
6
  import validateCommand from "./validate";
7
+ import pkg from "../package.json";
9
8
 
10
9
  function getVersion(): string {
11
- try {
12
- const pkg = JSON.parse(readFileSync(resolve(dirname(new URL(import.meta.url).pathname), "../package.json"), "utf-8"));
13
- return pkg.version ?? "0.0.0";
14
- } catch {
15
- return "0.0.0";
16
- }
10
+ return pkg.version ?? "0.0.0";
17
11
  }
18
12
 
19
13
  if (import.meta.main) {