@synergenius/flow-weaver 0.15.2 → 0.16.0

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.
@@ -8787,10 +8787,10 @@ var init_ignore = __esm({
8787
8787
  ignored(p) {
8788
8788
  const fullpath = p.fullpath();
8789
8789
  const fullpaths = `${fullpath}/`;
8790
- const relative7 = p.relative() || ".";
8791
- const relatives = `${relative7}/`;
8790
+ const relative9 = p.relative() || ".";
8791
+ const relatives = `${relative9}/`;
8792
8792
  for (const m of this.relative) {
8793
- if (m.match(relative7) || m.match(relatives))
8793
+ if (m.match(relative9) || m.match(relatives))
8794
8794
  return true;
8795
8795
  }
8796
8796
  for (const m of this.absolute) {
@@ -8801,9 +8801,9 @@ var init_ignore = __esm({
8801
8801
  }
8802
8802
  childrenIgnored(p) {
8803
8803
  const fullpath = p.fullpath() + "/";
8804
- const relative7 = (p.relative() || ".") + "/";
8804
+ const relative9 = (p.relative() || ".") + "/";
8805
8805
  for (const m of this.relativeChildren) {
8806
- if (m.match(relative7))
8806
+ if (m.match(relative9))
8807
8807
  return true;
8808
8808
  }
8809
8809
  for (const m of this.absoluteChildren) {
@@ -9671,7 +9671,7 @@ var VERSION;
9671
9671
  var init_generated_version = __esm({
9672
9672
  "src/generated-version.ts"() {
9673
9673
  "use strict";
9674
- VERSION = "0.15.2";
9674
+ VERSION = "0.16.0";
9675
9675
  }
9676
9676
  });
9677
9677
 
@@ -10559,7 +10559,7 @@ function buildNodeArgumentsWithContext(opts) {
10559
10559
  const args = [];
10560
10560
  const instance = workflow.instances.find((i) => i.id === id);
10561
10561
  const getInstancePortConfig = (portName) => instance?.config?.portConfigs?.find(
10562
- (pc) => pc.portName === portName && (pc.direction == null || pc.direction === "INPUT")
10562
+ (pc2) => pc2.portName === portName && (pc2.direction == null || pc2.direction === "INPUT")
10563
10563
  );
10564
10564
  const executeConnections = inputConnections.filter((conn) => conn.to.port === "execute");
10565
10565
  const effectiveNodeTypeName = nodeTypeName || node.functionName;
@@ -12816,11 +12816,11 @@ var require_util = __commonJS({
12816
12816
  return computeRelativeURL(base, newPath);
12817
12817
  }
12818
12818
  exports2.join = join28;
12819
- function relative7(rootURL, targetURL) {
12819
+ function relative9(rootURL, targetURL) {
12820
12820
  const result = relativeIfPossible(rootURL, targetURL);
12821
12821
  return typeof result === "string" ? result : normalize2(targetURL);
12822
12822
  }
12823
- exports2.relative = relative7;
12823
+ exports2.relative = relative9;
12824
12824
  function relativeIfPossible(rootURL, targetURL) {
12825
12825
  const urlType = getURLType(rootURL);
12826
12826
  if (urlType !== getURLType(targetURL)) {
@@ -14969,12 +14969,12 @@ is not a problem with esbuild. You need to fix your environment instead.
14969
14969
  }
14970
14970
  return validated;
14971
14971
  }
14972
- function pushLogFlags(flags, options, keys2, isTTY2, logLevelDefault) {
14972
+ function pushLogFlags(flags, options, keys2, isTTY22, logLevelDefault) {
14973
14973
  let color = getFlag(options, keys2, "color", mustBeBoolean);
14974
14974
  let logLevel = getFlag(options, keys2, "logLevel", mustBeString);
14975
14975
  let logLimit = getFlag(options, keys2, "logLimit", mustBeInteger);
14976
14976
  if (color !== void 0) flags.push(`--color=${color}`);
14977
- else if (isTTY2) flags.push(`--color=true`);
14977
+ else if (isTTY22) flags.push(`--color=true`);
14978
14978
  flags.push(`--log-level=${logLevel || logLevelDefault}`);
14979
14979
  flags.push(`--log-limit=${logLimit || 0}`);
14980
14980
  }
@@ -15069,14 +15069,14 @@ is not a problem with esbuild. You need to fix your environment instead.
15069
15069
  if (pure) for (let fn of pure) flags.push(`--pure:${validateStringValue(fn, "pure")}`);
15070
15070
  if (keepNames) flags.push(`--keep-names`);
15071
15071
  }
15072
- function flagsForBuildOptions(callName, options, isTTY2, logLevelDefault, writeDefault) {
15072
+ function flagsForBuildOptions(callName, options, isTTY22, logLevelDefault, writeDefault) {
15073
15073
  var _a22;
15074
15074
  let flags = [];
15075
15075
  let entries = [];
15076
15076
  let keys2 = /* @__PURE__ */ Object.create(null);
15077
15077
  let stdinContents = null;
15078
15078
  let stdinResolveDir = null;
15079
- pushLogFlags(flags, options, keys2, isTTY2, logLevelDefault);
15079
+ pushLogFlags(flags, options, keys2, isTTY22, logLevelDefault);
15080
15080
  pushCommonFlags(flags, options, keys2);
15081
15081
  let sourcemap = getFlag(options, keys2, "sourcemap", mustBeStringOrBoolean);
15082
15082
  let bundle = getFlag(options, keys2, "bundle", mustBeBoolean);
@@ -15214,10 +15214,10 @@ is not a problem with esbuild. You need to fix your environment instead.
15214
15214
  mangleCache: validateMangleCache(mangleCache)
15215
15215
  };
15216
15216
  }
15217
- function flagsForTransformOptions(callName, options, isTTY2, logLevelDefault) {
15217
+ function flagsForTransformOptions(callName, options, isTTY22, logLevelDefault) {
15218
15218
  let flags = [];
15219
15219
  let keys2 = /* @__PURE__ */ Object.create(null);
15220
- pushLogFlags(flags, options, keys2, isTTY2, logLevelDefault);
15220
+ pushLogFlags(flags, options, keys2, isTTY22, logLevelDefault);
15221
15221
  pushCommonFlags(flags, options, keys2);
15222
15222
  let sourcemap = getFlag(options, keys2, "sourcemap", mustBeStringOrBoolean);
15223
15223
  let sourcefile = getFlag(options, keys2, "sourcefile", mustBeString);
@@ -15340,7 +15340,7 @@ is not a problem with esbuild. You need to fix your environment instead.
15340
15340
  else callback(null, packet.value);
15341
15341
  }
15342
15342
  };
15343
- let buildOrContext = ({ callName, refs, options, isTTY: isTTY2, defaultWD: defaultWD2, callback }) => {
15343
+ let buildOrContext = ({ callName, refs, options, isTTY: isTTY22, defaultWD: defaultWD2, callback }) => {
15344
15344
  let refCount = 0;
15345
15345
  const buildKey = nextBuildKey++;
15346
15346
  const requestCallbacks = {};
@@ -15368,7 +15368,7 @@ is not a problem with esbuild. You need to fix your environment instead.
15368
15368
  streamIn,
15369
15369
  requestCallbacks,
15370
15370
  options,
15371
- isTTY2,
15371
+ isTTY22,
15372
15372
  defaultWD2,
15373
15373
  (err, res) => {
15374
15374
  try {
@@ -15379,7 +15379,7 @@ is not a problem with esbuild. You need to fix your environment instead.
15379
15379
  }
15380
15380
  );
15381
15381
  };
15382
- let transform22 = ({ callName, refs, input, options, isTTY: isTTY2, fs: fs310, callback }) => {
15382
+ let transform22 = ({ callName, refs, input, options, isTTY: isTTY22, fs: fs310, callback }) => {
15383
15383
  const details = createObjectStash();
15384
15384
  let start = (inputPath) => {
15385
15385
  try {
@@ -15388,7 +15388,7 @@ is not a problem with esbuild. You need to fix your environment instead.
15388
15388
  let {
15389
15389
  flags,
15390
15390
  mangleCache
15391
- } = flagsForTransformOptions(callName, options, isTTY2, transformLogLevelDefault);
15391
+ } = flagsForTransformOptions(callName, options, isTTY22, transformLogLevelDefault);
15392
15392
  let request = {
15393
15393
  command: "transform",
15394
15394
  flags,
@@ -15443,7 +15443,7 @@ is not a problem with esbuild. You need to fix your environment instead.
15443
15443
  } catch (e) {
15444
15444
  let flags = [];
15445
15445
  try {
15446
- pushLogFlags(flags, options, {}, isTTY2, transformLogLevelDefault);
15446
+ pushLogFlags(flags, options, {}, isTTY22, transformLogLevelDefault);
15447
15447
  } catch {
15448
15448
  }
15449
15449
  const error2 = extractErrorMessageV8(e, streamIn, details, void 0, "");
@@ -15508,13 +15508,13 @@ is not a problem with esbuild. You need to fix your environment instead.
15508
15508
  }
15509
15509
  };
15510
15510
  }
15511
- function buildOrContextImpl(callName, buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, options, isTTY2, defaultWD2, callback) {
15511
+ function buildOrContextImpl(callName, buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, options, isTTY22, defaultWD2, callback) {
15512
15512
  const details = createObjectStash();
15513
15513
  const isContext = callName === "context";
15514
15514
  const handleError = (e, pluginName) => {
15515
15515
  const flags = [];
15516
15516
  try {
15517
- pushLogFlags(flags, options, {}, isTTY2, buildLogLevelDefault);
15517
+ pushLogFlags(flags, options, {}, isTTY22, buildLogLevelDefault);
15518
15518
  } catch {
15519
15519
  }
15520
15520
  const message = extractErrorMessageV8(e, streamIn, details, void 0, pluginName);
@@ -15573,7 +15573,7 @@ is not a problem with esbuild. You need to fix your environment instead.
15573
15573
  absWorkingDir,
15574
15574
  nodePaths,
15575
15575
  mangleCache
15576
- } = flagsForBuildOptions(callName, options, isTTY2, buildLogLevelDefault, writeDefault);
15576
+ } = flagsForBuildOptions(callName, options, isTTY22, buildLogLevelDefault, writeDefault);
15577
15577
  if (write && !streamIn.hasFS) throw new Error(`The "write" option is unavailable in this environment`);
15578
15578
  const request = {
15579
15579
  command: "build",
@@ -16503,7 +16503,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
16503
16503
  }
16504
16504
  }
16505
16505
  };
16506
- var isTTY = () => tty.isatty(2);
16506
+ var isTTY2 = () => tty.isatty(2);
16507
16507
  var fsSync = {
16508
16508
  readFile(tempFile, callback) {
16509
16509
  try {
@@ -16566,7 +16566,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
16566
16566
  callName: "buildSync",
16567
16567
  refs: null,
16568
16568
  options,
16569
- isTTY: isTTY(),
16569
+ isTTY: isTTY2(),
16570
16570
  defaultWD,
16571
16571
  callback: (err, res) => {
16572
16572
  if (err) throw err;
@@ -16586,7 +16586,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
16586
16586
  refs: null,
16587
16587
  input,
16588
16588
  options: options || {},
16589
- isTTY: isTTY(),
16589
+ isTTY: isTTY2(),
16590
16590
  fs: fsSync,
16591
16591
  callback: (err, res) => {
16592
16592
  if (err) throw err;
@@ -16705,7 +16705,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
16705
16705
  callName: "build",
16706
16706
  refs,
16707
16707
  options,
16708
- isTTY: isTTY(),
16708
+ isTTY: isTTY2(),
16709
16709
  defaultWD,
16710
16710
  callback: (err, res) => err ? reject2(err) : resolve37(res)
16711
16711
  });
@@ -16714,7 +16714,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
16714
16714
  callName: "context",
16715
16715
  refs,
16716
16716
  options,
16717
- isTTY: isTTY(),
16717
+ isTTY: isTTY2(),
16718
16718
  defaultWD,
16719
16719
  callback: (err, res) => err ? reject2(err) : resolve37(res)
16720
16720
  })),
@@ -16723,7 +16723,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
16723
16723
  refs,
16724
16724
  input,
16725
16725
  options: options || {},
16726
- isTTY: isTTY(),
16726
+ isTTY: isTTY2(),
16727
16727
  fs: fsAsync,
16728
16728
  callback: (err, res) => err ? reject2(err) : resolve37(res)
16729
16729
  })),
@@ -18435,16 +18435,16 @@ function generateNodeInstanceTag(instance) {
18435
18435
  }
18436
18436
  let portOrderAttr = "";
18437
18437
  if (instance.config?.portConfigs && instance.config.portConfigs.length > 0) {
18438
- const orderConfigs = instance.config.portConfigs.filter((pc) => pc.order !== void 0).map((pc) => `${pc.portName}=${pc.order}`).join(",");
18438
+ const orderConfigs = instance.config.portConfigs.filter((pc2) => pc2.order !== void 0).map((pc2) => `${pc2.portName}=${pc2.order}`).join(",");
18439
18439
  if (orderConfigs) {
18440
18440
  portOrderAttr = ` [portOrder: ${orderConfigs}]`;
18441
18441
  }
18442
18442
  }
18443
18443
  let portLabelAttr = "";
18444
18444
  if (instance.config?.portConfigs && instance.config.portConfigs.length > 0) {
18445
- const labelConfigs = instance.config.portConfigs.filter((pc) => pc.label !== void 0 && pc.label !== "").map((pc) => {
18446
- const escapedLabel = String(pc.label).replace(/"/g, '\\"');
18447
- return `${pc.portName}="${escapedLabel}"`;
18445
+ const labelConfigs = instance.config.portConfigs.filter((pc2) => pc2.label !== void 0 && pc2.label !== "").map((pc2) => {
18446
+ const escapedLabel = String(pc2.label).replace(/"/g, '\\"');
18447
+ return `${pc2.portName}="${escapedLabel}"`;
18448
18448
  }).join(", ");
18449
18449
  if (labelConfigs) {
18450
18450
  portLabelAttr = ` [portLabel: ${labelConfigs}]`;
@@ -18452,9 +18452,9 @@ function generateNodeInstanceTag(instance) {
18452
18452
  }
18453
18453
  let exprAttr = "";
18454
18454
  if (instance.config?.portConfigs && instance.config.portConfigs.length > 0) {
18455
- const exprConfigs = instance.config.portConfigs.filter((pc) => pc.expression !== void 0).map((pc) => {
18456
- const escapedExpr = String(pc.expression).replace(/"/g, '\\"').replace(/\*\//g, "*\\/");
18457
- return `${pc.portName}="${escapedExpr}"`;
18455
+ const exprConfigs = instance.config.portConfigs.filter((pc2) => pc2.expression !== void 0).map((pc2) => {
18456
+ const escapedExpr = String(pc2.expression).replace(/"/g, '\\"').replace(/\*\//g, "*\\/");
18457
+ return `${pc2.portName}="${escapedExpr}"`;
18458
18458
  }).join(", ");
18459
18459
  if (exprConfigs) {
18460
18460
  exprAttr = ` [expr: ${exprConfigs}]`;
@@ -34497,7 +34497,7 @@ var init_jsdoc_parser = __esm({
34497
34497
  if (portLabel) {
34498
34498
  portConfigs = portConfigs || [];
34499
34499
  for (const [portName, labelVal] of Object.entries(portLabel)) {
34500
- const existingIndex = portConfigs.findIndex((pc) => pc.portName === portName);
34500
+ const existingIndex = portConfigs.findIndex((pc2) => pc2.portName === portName);
34501
34501
  if (existingIndex >= 0) {
34502
34502
  portConfigs[existingIndex] = { ...portConfigs[existingIndex], label: labelVal };
34503
34503
  } else {
@@ -34508,7 +34508,7 @@ var init_jsdoc_parser = __esm({
34508
34508
  if (expressions) {
34509
34509
  portConfigs = portConfigs || [];
34510
34510
  for (const [portName, expression] of Object.entries(expressions)) {
34511
- const existingIndex = portConfigs.findIndex((pc) => pc.portName === portName);
34511
+ const existingIndex = portConfigs.findIndex((pc2) => pc2.portName === portName);
34512
34512
  if (existingIndex >= 0) {
34513
34513
  portConfigs[existingIndex] = { ...portConfigs[existingIndex], expression };
34514
34514
  } else {
@@ -38738,7 +38738,7 @@ Add '@param ${fromPort}' to the workflow JSDoc and include it in the params obje
38738
38738
  if (isExecutePort(portName)) return;
38739
38739
  if (portConfig.scope) return;
38740
38740
  const instancePortConfig = instance?.config?.portConfigs?.find(
38741
- (pc) => pc.portName === portName && (pc.direction == null || pc.direction === "INPUT")
38741
+ (pc2) => pc2.portName === portName && (pc2.direction == null || pc2.direction === "INPUT")
38742
38742
  );
38743
38743
  const hasInstanceExpression = instancePortConfig?.expression !== void 0;
38744
38744
  const isRequired = !portConfig.optional && portConfig.default === void 0 && !portConfig.expression && !hasInstanceExpression;
@@ -39308,7 +39308,7 @@ Add '@param ${fromPort}' to the workflow JSDoc and include it in the params obje
39308
39308
  if (portConfig.optional || portConfig.default !== void 0) continue;
39309
39309
  const childInstance = workflow.instances.find((i) => i.id === childId);
39310
39310
  const instancePortConfig = childInstance?.config?.portConfigs?.find(
39311
- (pc) => pc.portName === portName && (pc.direction == null || pc.direction === "INPUT")
39311
+ (pc2) => pc2.portName === portName && (pc2.direction == null || pc2.direction === "INPUT")
39312
39312
  );
39313
39313
  if (portConfig.expression || instancePortConfig?.expression !== void 0) continue;
39314
39314
  const isConnected = workflow.connections.some(
@@ -39488,14 +39488,14 @@ Add '@param ${fromPort}' to the workflow JSDoc and include it in the params obje
39488
39488
  ...Object.keys(nodeType.inputs),
39489
39489
  ...Object.keys(nodeType.outputs)
39490
39490
  ]);
39491
- for (const pc of portConfigs) {
39492
- if (!allPorts.has(pc.portName)) {
39493
- const suggestions = findClosestMatches(pc.portName, [...allPorts]);
39491
+ for (const pc2 of portConfigs) {
39492
+ if (!allPorts.has(pc2.portName)) {
39493
+ const suggestions = findClosestMatches(pc2.portName, [...allPorts]);
39494
39494
  const hint = suggestions.length > 0 ? ` Did you mean "${suggestions[0]}"?` : "";
39495
39495
  this.warnings.push({
39496
39496
  type: "warning",
39497
39497
  code: "INVALID_PORT_CONFIG_REF",
39498
- message: `Instance "${instance.id}" references port "${pc.portName}" in portConfig, but this port does not exist on node type "${instance.nodeType}".${hint}`,
39498
+ message: `Instance "${instance.id}" references port "${pc2.portName}" in portConfig, but this port does not exist on node type "${instance.nodeType}".${hint}`,
39499
39499
  node: instance.id,
39500
39500
  location: instance.sourceLocation
39501
39501
  });
@@ -47172,7 +47172,7 @@ function resolvePortValue(portName, instanceId, nodeType, workflow, _nodeTypes)
47172
47172
  const portDef = nodeType.inputs[portName];
47173
47173
  const instance = workflow.instances.find((i) => i.id === instanceId);
47174
47174
  const instancePortConfig = instance?.config?.portConfigs?.find(
47175
- (pc) => pc.portName === portName && (pc.direction == null || pc.direction === "INPUT")
47175
+ (pc2) => pc2.portName === portName && (pc2.direction == null || pc2.direction === "INPUT")
47176
47176
  );
47177
47177
  if (instancePortConfig?.expression !== void 0) {
47178
47178
  const expr = String(instancePortConfig.expression);
@@ -48243,6 +48243,78 @@ var init_api6 = __esm({
48243
48243
  }
48244
48244
  });
48245
48245
 
48246
+ // node_modules/picocolors/picocolors.js
48247
+ var require_picocolors = __commonJS({
48248
+ "node_modules/picocolors/picocolors.js"(exports2, module2) {
48249
+ var p = process || {};
48250
+ var argv = p.argv || [];
48251
+ var env = p.env || {};
48252
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
48253
+ var formatter = (open, close, replace = open) => (input) => {
48254
+ let string3 = "" + input, index = string3.indexOf(close, open.length);
48255
+ return ~index ? open + replaceClose(string3, close, replace, index) + close : open + string3 + close;
48256
+ };
48257
+ var replaceClose = (string3, close, replace, index) => {
48258
+ let result = "", cursor = 0;
48259
+ do {
48260
+ result += string3.substring(cursor, index) + replace;
48261
+ cursor = index + close.length;
48262
+ index = string3.indexOf(close, cursor);
48263
+ } while (~index);
48264
+ return result + string3.substring(cursor);
48265
+ };
48266
+ var createColors = (enabled = isColorSupported) => {
48267
+ let f = enabled ? formatter : () => String;
48268
+ return {
48269
+ isColorSupported: enabled,
48270
+ reset: f("\x1B[0m", "\x1B[0m"),
48271
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
48272
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
48273
+ italic: f("\x1B[3m", "\x1B[23m"),
48274
+ underline: f("\x1B[4m", "\x1B[24m"),
48275
+ inverse: f("\x1B[7m", "\x1B[27m"),
48276
+ hidden: f("\x1B[8m", "\x1B[28m"),
48277
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
48278
+ black: f("\x1B[30m", "\x1B[39m"),
48279
+ red: f("\x1B[31m", "\x1B[39m"),
48280
+ green: f("\x1B[32m", "\x1B[39m"),
48281
+ yellow: f("\x1B[33m", "\x1B[39m"),
48282
+ blue: f("\x1B[34m", "\x1B[39m"),
48283
+ magenta: f("\x1B[35m", "\x1B[39m"),
48284
+ cyan: f("\x1B[36m", "\x1B[39m"),
48285
+ white: f("\x1B[37m", "\x1B[39m"),
48286
+ gray: f("\x1B[90m", "\x1B[39m"),
48287
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
48288
+ bgRed: f("\x1B[41m", "\x1B[49m"),
48289
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
48290
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
48291
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
48292
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
48293
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
48294
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
48295
+ blackBright: f("\x1B[90m", "\x1B[39m"),
48296
+ redBright: f("\x1B[91m", "\x1B[39m"),
48297
+ greenBright: f("\x1B[92m", "\x1B[39m"),
48298
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
48299
+ blueBright: f("\x1B[94m", "\x1B[39m"),
48300
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
48301
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
48302
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
48303
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
48304
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
48305
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
48306
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
48307
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
48308
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
48309
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
48310
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
48311
+ };
48312
+ };
48313
+ module2.exports = createColors();
48314
+ module2.exports.createColors = createColors;
48315
+ }
48316
+ });
48317
+
48246
48318
  // node_modules/js-yaml/dist/js-yaml.mjs
48247
48319
  function isNothing(subject) {
48248
48320
  return typeof subject === "undefined" || subject === null;
@@ -52242,67 +52314,67 @@ function buildDiagramGraph(ast, options = {}) {
52242
52314
  return a.sourcePort.cy - b.sourcePort.cy;
52243
52315
  });
52244
52316
  const allocator = new TrackAllocator();
52245
- const srcPortKey = (pc) => `srcPort:${pc.fromNodeId}.${pc.fromPortName}`;
52246
- const tgtPortKey = (pc) => `tgtPort:${pc.toNodeId}.${pc.toPortName}`;
52247
- const tgtNodeKey = (pc) => `tgtNode:${pc.toNodeId}`;
52317
+ const srcPortKey = (pc2) => `srcPort:${pc2.fromNodeId}.${pc2.fromPortName}`;
52318
+ const tgtPortKey = (pc2) => `tgtPort:${pc2.toNodeId}.${pc2.toPortName}`;
52319
+ const tgtNodeKey = (pc2) => `tgtNode:${pc2.toNodeId}`;
52248
52320
  const routingGroups = /* @__PURE__ */ new Map();
52249
- for (const pc of pendingConnections) {
52250
- for (const key of [srcPortKey(pc), tgtPortKey(pc), tgtNodeKey(pc)]) {
52321
+ for (const pc2 of pendingConnections) {
52322
+ for (const key of [srcPortKey(pc2), tgtPortKey(pc2), tgtNodeKey(pc2)]) {
52251
52323
  if (!routingGroups.has(key)) routingGroups.set(key, []);
52252
- routingGroups.get(key).push(pc);
52324
+ routingGroups.get(key).push(pc2);
52253
52325
  }
52254
52326
  }
52255
52327
  const forceCurveKeys = /* @__PURE__ */ new Set();
52256
52328
  for (const [key, group] of routingGroups) {
52257
52329
  if (group.length < 2) continue;
52258
- const anyShort = group.some((pc) => {
52259
- const dx = pc.targetPort.cx - pc.sourcePort.cx;
52260
- const dy = pc.targetPort.cy - pc.sourcePort.cy;
52330
+ const anyShort = group.some((pc2) => {
52331
+ const dx = pc2.targetPort.cx - pc2.sourcePort.cx;
52332
+ const dy = pc2.targetPort.cy - pc2.sourcePort.cy;
52261
52333
  return Math.sqrt(dx * dx + dy * dy) <= ORTHOGONAL_DISTANCE_THRESHOLD;
52262
52334
  });
52263
52335
  if (anyShort) forceCurveKeys.add(key);
52264
52336
  }
52265
52337
  const forceCurveSet = /* @__PURE__ */ new Set();
52266
- for (const pc of pendingConnections) {
52267
- if (forceCurveKeys.has(srcPortKey(pc)) || forceCurveKeys.has(tgtPortKey(pc)) || forceCurveKeys.has(tgtNodeKey(pc))) {
52268
- forceCurveSet.add(pc);
52338
+ for (const pc2 of pendingConnections) {
52339
+ if (forceCurveKeys.has(srcPortKey(pc2)) || forceCurveKeys.has(tgtPortKey(pc2)) || forceCurveKeys.has(tgtNodeKey(pc2))) {
52340
+ forceCurveSet.add(pc2);
52269
52341
  }
52270
52342
  }
52271
52343
  const connections = [];
52272
- for (const pc of pendingConnections) {
52273
- const sx = pc.sourcePort.cx;
52274
- const sy = pc.sourcePort.cy;
52275
- const tx = pc.targetPort.cx;
52276
- const ty = pc.targetPort.cy;
52344
+ for (const pc2 of pendingConnections) {
52345
+ const sx = pc2.sourcePort.cx;
52346
+ const sy = pc2.sourcePort.cy;
52347
+ const tx = pc2.targetPort.cx;
52348
+ const ty = pc2.targetPort.cy;
52277
52349
  const dx = tx - sx;
52278
52350
  const dy = ty - sy;
52279
52351
  const distance = Math.sqrt(dx * dx + dy * dy);
52280
- const useCurve = forceCurveSet.has(pc);
52352
+ const useCurve = forceCurveSet.has(pc2);
52281
52353
  let path54;
52282
52354
  if (!useCurve && distance > ORTHOGONAL_DISTANCE_THRESHOLD) {
52283
52355
  const orthoPath = calculateOrthogonalPathSafe(
52284
52356
  [sx, sy],
52285
52357
  [tx, ty],
52286
52358
  nodeBoxes,
52287
- pc.fromNodeId,
52288
- pc.toNodeId,
52289
- { fromPortIndex: pc.fromPortIndex, toPortIndex: pc.toPortIndex },
52359
+ pc2.fromNodeId,
52360
+ pc2.toNodeId,
52361
+ { fromPortIndex: pc2.fromPortIndex, toPortIndex: pc2.toPortIndex },
52290
52362
  allocator
52291
52363
  );
52292
52364
  path54 = orthoPath ?? computeConnectionPath(sx, sy, tx, ty);
52293
52365
  } else {
52294
52366
  path54 = computeConnectionPath(sx, sy, tx, ty);
52295
52367
  }
52296
- const sourceColor = getPortColor(pc.sourcePort.dataType, pc.sourcePort.isFailure, themeName);
52297
- const targetColor = getPortColor(pc.targetPort.dataType, pc.targetPort.isFailure, themeName);
52368
+ const sourceColor = getPortColor(pc2.sourcePort.dataType, pc2.sourcePort.isFailure, themeName);
52369
+ const targetColor = getPortColor(pc2.targetPort.dataType, pc2.targetPort.isFailure, themeName);
52298
52370
  connections.push({
52299
- fromNode: pc.fromNodeId,
52300
- fromPort: pc.fromPortName,
52301
- toNode: pc.toNodeId,
52302
- toPort: pc.toPortName,
52371
+ fromNode: pc2.fromNodeId,
52372
+ fromPort: pc2.fromPortName,
52373
+ toNode: pc2.toNodeId,
52374
+ toPort: pc2.toPortName,
52303
52375
  sourceColor,
52304
52376
  targetColor,
52305
- isStepConnection: pc.sourcePort.dataType === "STEP",
52377
+ isStepConnection: pc2.sourcePort.dataType === "STEP",
52306
52378
  path: path54
52307
52379
  });
52308
52380
  }
@@ -56431,8 +56503,10 @@ async function executeWorkflowFromFile(filePath, params, options) {
56431
56503
  globalThis.__fw_workflow_registry__ = workflowRegistry;
56432
56504
  const exportedFn = findExportedFunction(mod, options?.workflowName);
56433
56505
  if (!exportedFn) {
56506
+ const available = Object.entries(mod).filter(([k, v]) => k !== "__esModule" && typeof v === "function").map(([k]) => k);
56507
+ const availStr = available.length > 0 ? `. Available: ${available.join(", ")}` : "";
56434
56508
  throw new Error(
56435
- `No exported workflow function found${options?.workflowName ? ` named "${options.workflowName}"` : ""}`
56509
+ options?.workflowName ? `Workflow "${options.workflowName}" not found in file${availStr}` : `No exported workflow function found in file${availStr}`
56436
56510
  );
56437
56511
  }
56438
56512
  const startTime = Date.now();
@@ -68547,49 +68621,49 @@ var require_fast_uri = __commonJS({
68547
68621
  schemelessOptions.skipEscape = true;
68548
68622
  return serialize(resolved, schemelessOptions);
68549
68623
  }
68550
- function resolveComponent(base, relative7, options, skipNormalization) {
68624
+ function resolveComponent(base, relative9, options, skipNormalization) {
68551
68625
  const target = {};
68552
68626
  if (!skipNormalization) {
68553
68627
  base = parse7(serialize(base, options), options);
68554
- relative7 = parse7(serialize(relative7, options), options);
68628
+ relative9 = parse7(serialize(relative9, options), options);
68555
68629
  }
68556
68630
  options = options || {};
68557
- if (!options.tolerant && relative7.scheme) {
68558
- target.scheme = relative7.scheme;
68559
- target.userinfo = relative7.userinfo;
68560
- target.host = relative7.host;
68561
- target.port = relative7.port;
68562
- target.path = removeDotSegments(relative7.path || "");
68563
- target.query = relative7.query;
68631
+ if (!options.tolerant && relative9.scheme) {
68632
+ target.scheme = relative9.scheme;
68633
+ target.userinfo = relative9.userinfo;
68634
+ target.host = relative9.host;
68635
+ target.port = relative9.port;
68636
+ target.path = removeDotSegments(relative9.path || "");
68637
+ target.query = relative9.query;
68564
68638
  } else {
68565
- if (relative7.userinfo !== void 0 || relative7.host !== void 0 || relative7.port !== void 0) {
68566
- target.userinfo = relative7.userinfo;
68567
- target.host = relative7.host;
68568
- target.port = relative7.port;
68569
- target.path = removeDotSegments(relative7.path || "");
68570
- target.query = relative7.query;
68639
+ if (relative9.userinfo !== void 0 || relative9.host !== void 0 || relative9.port !== void 0) {
68640
+ target.userinfo = relative9.userinfo;
68641
+ target.host = relative9.host;
68642
+ target.port = relative9.port;
68643
+ target.path = removeDotSegments(relative9.path || "");
68644
+ target.query = relative9.query;
68571
68645
  } else {
68572
- if (!relative7.path) {
68646
+ if (!relative9.path) {
68573
68647
  target.path = base.path;
68574
- if (relative7.query !== void 0) {
68575
- target.query = relative7.query;
68648
+ if (relative9.query !== void 0) {
68649
+ target.query = relative9.query;
68576
68650
  } else {
68577
68651
  target.query = base.query;
68578
68652
  }
68579
68653
  } else {
68580
- if (relative7.path[0] === "/") {
68581
- target.path = removeDotSegments(relative7.path);
68654
+ if (relative9.path[0] === "/") {
68655
+ target.path = removeDotSegments(relative9.path);
68582
68656
  } else {
68583
68657
  if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
68584
- target.path = "/" + relative7.path;
68658
+ target.path = "/" + relative9.path;
68585
68659
  } else if (!base.path) {
68586
- target.path = relative7.path;
68660
+ target.path = relative9.path;
68587
68661
  } else {
68588
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative7.path;
68662
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative9.path;
68589
68663
  }
68590
68664
  target.path = removeDotSegments(target.path);
68591
68665
  }
68592
- target.query = relative7.query;
68666
+ target.query = relative9.query;
68593
68667
  }
68594
68668
  target.userinfo = base.userinfo;
68595
68669
  target.host = base.host;
@@ -68597,7 +68671,7 @@ var require_fast_uri = __commonJS({
68597
68671
  }
68598
68672
  target.scheme = base.scheme;
68599
68673
  }
68600
- target.fragment = relative7.fragment;
68674
+ target.fragment = relative9.fragment;
68601
68675
  return target;
68602
68676
  }
68603
68677
  function equal(uriA, uriB, options) {
@@ -74411,6 +74485,12 @@ var init_deployment = __esm({
74411
74485
  }
74412
74486
  });
74413
74487
 
74488
+ // src/cli/env-setup.ts
74489
+ if (process.env.FORCE_COLOR === "0") {
74490
+ process.env.NO_COLOR = "1";
74491
+ delete process.env.FORCE_COLOR;
74492
+ }
74493
+
74414
74494
  // node_modules/commander/esm.mjs
74415
74495
  var import_index = __toESM(require_commander(), 1);
74416
74496
  var {
@@ -74438,30 +74518,25 @@ import * as fs10 from "fs";
74438
74518
  import * as path9 from "path";
74439
74519
 
74440
74520
  // src/cli/utils/logger.ts
74441
- var USE_COLOR = !process.env.NO_COLOR && process.stdout.isTTY !== false;
74442
- var RESET = USE_COLOR ? "\x1B[0m" : "";
74443
- var GREEN = USE_COLOR ? "\x1B[32m" : "";
74444
- var RED = USE_COLOR ? "\x1B[31m" : "";
74445
- var YELLOW = USE_COLOR ? "\x1B[33m" : "";
74446
- var BLUE = USE_COLOR ? "\x1B[34m" : "";
74447
- var BOLD = USE_COLOR ? "\x1B[1m" : "";
74448
- var DIM = USE_COLOR ? "\x1B[2m" : "";
74521
+ var import_picocolors = __toESM(require_picocolors(), 1);
74522
+ var isTTY = process.stdout.isTTY === true;
74523
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
74449
74524
  var logger = {
74450
74525
  info(message) {
74451
- console.log(`${BLUE}\u2139 ${message}${RESET}`);
74526
+ console.log(`${import_picocolors.default.blue("\u2139")} ${message}`);
74452
74527
  },
74453
74528
  success(message) {
74454
- console.log(`${GREEN}\u2713 ${message}${RESET}`);
74529
+ console.log(`${import_picocolors.default.green("\u2713")} ${message}`);
74455
74530
  },
74456
74531
  error(message) {
74457
- console.error(`${RED}\u2717 ${message}${RESET}`);
74532
+ console.error(`${import_picocolors.default.red("\u2717")} ${message}`);
74458
74533
  },
74459
74534
  warn(message) {
74460
- console.warn(`${YELLOW}\u26A0 ${message}${RESET}`);
74535
+ console.warn(`${import_picocolors.default.yellow("\u26A0")} ${message}`);
74461
74536
  },
74462
74537
  debug(message) {
74463
74538
  if (process.env.DEBUG) {
74464
- console.log(`${DIM}\u{1F50D} ${message}${RESET}`);
74539
+ console.log(`${import_picocolors.default.dim("\u{1F50D}")} ${import_picocolors.default.dim(message)}`);
74465
74540
  }
74466
74541
  },
74467
74542
  log(message) {
@@ -74472,10 +74547,97 @@ var logger = {
74472
74547
  },
74473
74548
  section(title) {
74474
74549
  console.log();
74475
- console.log(`${BOLD}\u2501\u2501\u2501 ${title} \u2501\u2501\u2501${RESET}`);
74550
+ console.log(` ${import_picocolors.default.bold(title)}`);
74551
+ console.log();
74476
74552
  },
74477
74553
  progress(current2, total, item) {
74478
- console.log(`[${current2}/${total}] ${item}`);
74554
+ console.log(`${import_picocolors.default.dim(`[${current2}/${total}]`)} ${item}`);
74555
+ },
74556
+ // --- Formatting helpers ---
74557
+ dim(message) {
74558
+ return import_picocolors.default.dim(message);
74559
+ },
74560
+ bold(message) {
74561
+ return import_picocolors.default.bold(message);
74562
+ },
74563
+ highlight(value2) {
74564
+ return import_picocolors.default.cyan(value2);
74565
+ },
74566
+ // --- Branded output ---
74567
+ banner(version3) {
74568
+ console.log(` ${import_picocolors.default.bold(import_picocolors.default.cyan("flow-weaver"))} ${import_picocolors.default.dim(`v${version3}`)}`);
74569
+ },
74570
+ // --- Table output ---
74571
+ table(rows) {
74572
+ if (rows.length === 0) return;
74573
+ const col0 = Math.max(...rows.map((r) => r[0].length)) + 2;
74574
+ const col1 = Math.max(...rows.map((r) => r[1].length)) + 2;
74575
+ for (const [label, value2, status] of rows) {
74576
+ const line = ` ${label.padEnd(col0)}${value2.padEnd(col1)}${status ?? ""}`;
74577
+ console.log(line);
74578
+ }
74579
+ },
74580
+ // --- Spinner ---
74581
+ spinner(message) {
74582
+ if (!isTTY) {
74583
+ process.stderr.write(` ${message}
74584
+ `);
74585
+ return {
74586
+ stop(msg) {
74587
+ if (msg) process.stderr.write(` ${import_picocolors.default.green("\u2713")} ${msg}
74588
+ `);
74589
+ },
74590
+ fail(msg) {
74591
+ if (msg) process.stderr.write(` ${import_picocolors.default.red("\u2717")} ${msg}
74592
+ `);
74593
+ },
74594
+ update() {
74595
+ }
74596
+ };
74597
+ }
74598
+ let frame = 0;
74599
+ let text = message;
74600
+ const interval = setInterval(() => {
74601
+ const spinner = import_picocolors.default.cyan(SPINNER_FRAMES[frame % SPINNER_FRAMES.length]);
74602
+ process.stderr.write(`\r\x1B[K ${spinner} ${text}`);
74603
+ frame++;
74604
+ }, 80);
74605
+ const clear = () => {
74606
+ clearInterval(interval);
74607
+ process.stderr.write("\r\x1B[K");
74608
+ };
74609
+ return {
74610
+ stop(msg) {
74611
+ clear();
74612
+ if (msg) process.stderr.write(` ${import_picocolors.default.green("\u2713")} ${msg}
74613
+ `);
74614
+ },
74615
+ fail(msg) {
74616
+ clear();
74617
+ if (msg) process.stderr.write(` ${import_picocolors.default.red("\u2717")} ${msg}
74618
+ `);
74619
+ },
74620
+ update(msg) {
74621
+ text = msg;
74622
+ }
74623
+ };
74624
+ },
74625
+ // --- Timer ---
74626
+ timer() {
74627
+ const start = performance.now();
74628
+ return {
74629
+ elapsed() {
74630
+ const ms = performance.now() - start;
74631
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
74632
+ if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
74633
+ const mins = Math.floor(ms / 6e4);
74634
+ const secs = Math.round(ms % 6e4 / 1e3);
74635
+ return `${mins}m ${secs}s`;
74636
+ },
74637
+ ms() {
74638
+ return Math.round(performance.now() - start);
74639
+ }
74640
+ };
74479
74641
  }
74480
74642
  };
74481
74643
 
@@ -75725,37 +75887,25 @@ async function doctorCommand(options = {}) {
75725
75887
  console.log(JSON.stringify(report, null, 2));
75726
75888
  } else {
75727
75889
  logger.section("Flow Weaver Doctor");
75728
- logger.info(`Checking project at ${cwd}`);
75729
- logger.newline();
75730
- for (const check2 of report.checks) {
75731
- switch (check2.status) {
75732
- case "pass":
75733
- logger.success(check2.message);
75734
- break;
75735
- case "warn":
75736
- logger.warn(check2.message);
75737
- if (check2.fix) {
75738
- logger.log(` Fix: ${check2.fix}`);
75739
- }
75740
- break;
75741
- case "fail":
75742
- logger.error(check2.message);
75743
- if (check2.fix) {
75744
- logger.log(` Fix: ${check2.fix}`);
75745
- }
75746
- break;
75890
+ const statusIcon = (s) => s === "pass" ? logger.highlight("pass") : s === "warn" ? "\u26A0 warn" : "\u2717 fail";
75891
+ const rows = report.checks.map((check2) => [
75892
+ check2.name,
75893
+ check2.message,
75894
+ statusIcon(check2.status)
75895
+ ]);
75896
+ logger.table(rows);
75897
+ const fixable = report.checks.filter((c) => c.status !== "pass" && c.fix);
75898
+ if (fixable.length > 0) {
75899
+ logger.newline();
75900
+ for (const check2 of fixable) {
75901
+ logger.log(` ${logger.dim(check2.name + ":")} ${check2.fix}`);
75747
75902
  }
75748
75903
  }
75749
75904
  logger.newline();
75750
- logger.section("Module Format");
75751
- logger.info(
75752
- ` Detected: ${report.moduleFormat.format.toUpperCase()} (${report.moduleFormat.details})`
75753
- );
75754
- logger.newline();
75755
- logger.section("Summary");
75905
+ logger.log(` Module format: ${report.moduleFormat.format.toUpperCase()} ${logger.dim(`(${report.moduleFormat.details})`)}`);
75756
75906
  const parts2 = [];
75757
75907
  if (report.summary.pass > 0) parts2.push(`${report.summary.pass} passed`);
75758
- if (report.summary.warn > 0) parts2.push(`${report.summary.warn} warning(s)`);
75908
+ if (report.summary.warn > 0) parts2.push(`${report.summary.warn} warnings`);
75759
75909
  if (report.summary.fail > 0) parts2.push(`${report.summary.fail} failed`);
75760
75910
  logger.log(` ${parts2.join(", ")}`);
75761
75911
  if (report.ok) {
@@ -75763,7 +75913,7 @@ async function doctorCommand(options = {}) {
75763
75913
  logger.success("Environment is ready for flow-weaver!");
75764
75914
  } else {
75765
75915
  logger.newline();
75766
- logger.error("Some checks failed. Please fix the issues above.");
75916
+ logger.error("Fix the issues above to continue.");
75767
75917
  }
75768
75918
  }
75769
75919
  if (!report.ok) {
@@ -75774,6 +75924,13 @@ async function doctorCommand(options = {}) {
75774
75924
  // src/cli/commands/compile.ts
75775
75925
  init_inngest();
75776
75926
  init_parser2();
75927
+ function displayPath(filePath) {
75928
+ const rel = path9.relative(process.cwd(), filePath);
75929
+ if (rel && !rel.startsWith("..") && rel.length < filePath.length) {
75930
+ return rel;
75931
+ }
75932
+ return filePath;
75933
+ }
75777
75934
  function resolveModuleFormat(format, cwd) {
75778
75935
  if (format === "esm" || format === "cjs") {
75779
75936
  return format;
@@ -75788,168 +75945,169 @@ async function compileCommand(input, options = {}) {
75788
75945
  }
75789
75946
  const cwd = process.cwd();
75790
75947
  const moduleFormat = resolveModuleFormat(format, cwd);
75948
+ let pattern = input;
75791
75949
  try {
75792
- let pattern = input;
75950
+ if (fs10.existsSync(input) && fs10.statSync(input).isDirectory()) {
75951
+ pattern = path9.join(input, "**/*.ts");
75952
+ }
75953
+ } catch {
75954
+ }
75955
+ const allFiles = await glob(pattern, { absolute: true });
75956
+ const files = allFiles.filter((f) => {
75793
75957
  try {
75794
- if (fs10.existsSync(input) && fs10.statSync(input).isDirectory()) {
75795
- pattern = path9.join(input, "**/*.ts");
75796
- }
75958
+ return fs10.statSync(f).isFile();
75797
75959
  } catch {
75960
+ return false;
75798
75961
  }
75799
- const allFiles = await glob(pattern, { absolute: true });
75800
- const files = allFiles.filter((f) => {
75801
- try {
75802
- return fs10.statSync(f).isFile();
75803
- } catch {
75804
- return false;
75805
- }
75806
- });
75807
- if (files.length === 0) {
75808
- throw new Error(`No files found matching pattern: ${input}`);
75809
- }
75810
- logger.section("Compiling Workflows");
75962
+ });
75963
+ if (files.length === 0) {
75964
+ throw new Error(`No files found matching pattern: ${input}`);
75965
+ }
75966
+ const totalTimer = logger.timer();
75967
+ logger.section("Compiling Workflows");
75968
+ if (verbose) {
75811
75969
  logger.info(`Found ${files.length} file(s)`);
75812
75970
  logger.info(`Module format: ${moduleFormat.toUpperCase()}`);
75813
75971
  if (sourceMap) {
75814
75972
  logger.info("Source maps: enabled");
75815
75973
  }
75816
- if (verbose) {
75817
- files.forEach((file) => logger.info(` - ${file}`));
75818
- }
75974
+ files.forEach((file) => logger.info(` ${displayPath(file)}`));
75819
75975
  logger.newline();
75820
- let successCount = 0;
75821
- let errorCount = 0;
75822
- for (let i = 0; i < files.length; i++) {
75823
- const file = files[i];
75824
- const fileName = path9.basename(file);
75825
- logger.progress(i + 1, files.length, fileName);
75826
- try {
75827
- const rawSource = fs10.readFileSync(file, "utf8");
75828
- if (!rawSource.includes("@flowWeaver")) {
75976
+ }
75977
+ let successCount = 0;
75978
+ let errorCount = 0;
75979
+ for (let i = 0; i < files.length; i++) {
75980
+ const file = files[i];
75981
+ const fileName = path9.basename(file);
75982
+ const fileTimer = logger.timer();
75983
+ try {
75984
+ const rawSource = fs10.readFileSync(file, "utf8");
75985
+ if (!rawSource.includes("@flowWeaver")) {
75986
+ if (verbose) {
75987
+ logger.info(` ${logger.dim("skip")} ${fileName} ${logger.dim("(no @flowWeaver annotations)")}`);
75988
+ }
75989
+ continue;
75990
+ }
75991
+ const parseResult = await parseWorkflow(file, { workflowName });
75992
+ if (parseResult.warnings.length > 0 && verbose) {
75993
+ logger.warn(`Parse warnings in ${fileName}:`);
75994
+ parseResult.warnings.forEach((w) => logger.warn(` ${w}`));
75995
+ }
75996
+ if (parseResult.errors.length > 0) {
75997
+ const isNonWorkflowFile = parseResult.errors.length === 1 && typeof parseResult.errors[0] === "string" && parseResult.errors[0].startsWith("No workflows found");
75998
+ if (isNonWorkflowFile) {
75829
75999
  if (verbose) {
75830
- logger.info(` Skipped ${fileName} (no @flowWeaver annotations)`);
76000
+ logger.info(` ${logger.dim("skip")} ${fileName} ${logger.dim("(no workflow)")}`);
75831
76001
  }
75832
76002
  continue;
75833
76003
  }
75834
- const parseResult = await parseWorkflow(file, { workflowName });
75835
- if (parseResult.warnings.length > 0) {
75836
- parseResult.warnings.forEach((w) => logger.warn(` ${w}`));
75837
- }
75838
- if (parseResult.errors.length > 0) {
75839
- const isNonWorkflowFile = parseResult.errors.length === 1 && typeof parseResult.errors[0] === "string" && parseResult.errors[0].startsWith("No workflows found");
75840
- if (isNonWorkflowFile) {
75841
- if (verbose) {
75842
- logger.info(` Skipped ${fileName} (no workflow)`);
76004
+ logger.error(` ${fileName}`);
76005
+ parseResult.errors.forEach((err) => logger.error(` ${err}`));
76006
+ errorCount++;
76007
+ continue;
76008
+ }
76009
+ if (strict) {
76010
+ const validation = validator.validate(parseResult.ast, { strictMode: true });
76011
+ if (validation.errors.length > 0) {
76012
+ logger.error(` ${fileName}`);
76013
+ validation.errors.forEach((err) => {
76014
+ const friendly = getFriendlyError(err);
76015
+ if (friendly) {
76016
+ const loc = err.location ? `[line ${err.location.line}] ` : "";
76017
+ logger.error(` ${loc}${friendly.title}: ${friendly.explanation}`);
76018
+ logger.warn(` How to fix: ${friendly.fix}`);
76019
+ if (err.docUrl) {
76020
+ logger.warn(` See: ${err.docUrl}`);
76021
+ }
76022
+ } else {
76023
+ let msg = ` ${err.message}`;
76024
+ if (err.node) {
76025
+ msg += ` (node: ${err.node})`;
76026
+ }
76027
+ logger.error(msg);
76028
+ if (err.docUrl) {
76029
+ logger.warn(` See: ${err.docUrl}`);
76030
+ }
75843
76031
  }
75844
- continue;
75845
- }
75846
- logger.error(`Failed to parse ${fileName}:`);
75847
- parseResult.errors.forEach((err) => logger.error(` ${err}`));
76032
+ });
75848
76033
  errorCount++;
75849
76034
  continue;
75850
76035
  }
75851
- if (strict) {
75852
- const validation = validator.validate(parseResult.ast, { strictMode: true });
75853
- if (validation.errors.length > 0) {
75854
- logger.error(`Validation errors in ${fileName}:`);
75855
- validation.errors.forEach((err) => {
75856
- const friendly = getFriendlyError(err);
75857
- if (friendly) {
75858
- const loc = err.location ? `[line ${err.location.line}] ` : "";
75859
- logger.error(` ${loc}${friendly.title}: ${friendly.explanation}`);
75860
- logger.info(` How to fix: ${friendly.fix}`);
75861
- if (err.docUrl) {
75862
- logger.info(` See: ${err.docUrl}`);
75863
- }
75864
- } else {
75865
- let msg = ` - ${err.message}`;
75866
- if (err.node) {
75867
- msg += ` (node: ${err.node})`;
75868
- }
75869
- logger.error(msg);
75870
- if (err.docUrl) {
75871
- logger.info(` See: ${err.docUrl}`);
75872
- }
75873
- }
75874
- });
75875
- errorCount++;
75876
- continue;
75877
- }
75878
- if (validation.warnings.length > 0 && verbose) {
75879
- validation.warnings.forEach((warn) => {
75880
- const friendly = getFriendlyError(warn);
75881
- if (friendly) {
75882
- const loc = warn.location ? `[line ${warn.location.line}] ` : "";
75883
- logger.warn(` ${loc}${friendly.title}: ${friendly.explanation}`);
75884
- logger.info(` How to fix: ${friendly.fix}`);
75885
- } else {
75886
- logger.warn(` ${warn.message}`);
75887
- }
75888
- });
75889
- }
76036
+ if (validation.warnings.length > 0 && verbose) {
76037
+ validation.warnings.forEach((warn) => {
76038
+ const friendly = getFriendlyError(warn);
76039
+ if (friendly) {
76040
+ const loc = warn.location ? `[line ${warn.location.line}] ` : "";
76041
+ logger.warn(` ${loc}${friendly.title}: ${friendly.explanation}`);
76042
+ logger.warn(` How to fix: ${friendly.fix}`);
76043
+ } else {
76044
+ logger.warn(` ${warn.message}`);
76045
+ }
76046
+ });
75890
76047
  }
75891
- const sourceCode = fs10.readFileSync(file, "utf8");
75892
- const result = generateInPlace(sourceCode, parseResult.ast, { production, moduleFormat, inlineRuntime, sourceFile: file, skipParamReturns: clean });
75893
- if (!dryRun) {
75894
- fs10.writeFileSync(file, result.code, "utf8");
75895
- if (sourceMap) {
75896
- const mapResult = generateCode(parseResult.ast, {
75897
- production,
75898
- sourceMap: true,
75899
- moduleFormat
75900
- });
75901
- if (mapResult.sourceMap) {
75902
- const mapPath = file + ".map";
75903
- fs10.writeFileSync(mapPath, mapResult.sourceMap, "utf8");
75904
- const sourceMappingComment = `
76048
+ }
76049
+ const sourceCode = fs10.readFileSync(file, "utf8");
76050
+ const result = generateInPlace(sourceCode, parseResult.ast, { production, moduleFormat, inlineRuntime, sourceFile: file, skipParamReturns: clean });
76051
+ if (!dryRun) {
76052
+ fs10.writeFileSync(file, result.code, "utf8");
76053
+ if (sourceMap) {
76054
+ const mapResult = generateCode(parseResult.ast, {
76055
+ production,
76056
+ sourceMap: true,
76057
+ moduleFormat
76058
+ });
76059
+ if (mapResult.sourceMap) {
76060
+ const mapPath = file + ".map";
76061
+ fs10.writeFileSync(mapPath, mapResult.sourceMap, "utf8");
76062
+ const sourceMappingComment = `
75905
76063
  //# sourceMappingURL=${path9.basename(mapPath)}
75906
76064
  `;
75907
- if (!result.code.includes("//# sourceMappingURL=")) {
75908
- fs10.appendFileSync(file, sourceMappingComment, "utf8");
75909
- }
75910
- if (verbose) {
75911
- logger.info(` Source map: ${mapPath}`);
75912
- }
76065
+ if (!result.code.includes("//# sourceMappingURL=")) {
76066
+ fs10.appendFileSync(file, sourceMappingComment, "utf8");
76067
+ }
76068
+ if (verbose) {
76069
+ logger.info(` source map: ${displayPath(mapPath)}`);
75913
76070
  }
75914
76071
  }
75915
76072
  }
75916
- if (dryRun) {
75917
- if (result.hasChanges) {
75918
- logger.success(` Would compile: ${file}`);
75919
- } else if (verbose) {
75920
- logger.info(` No changes: ${file}`);
75921
- }
75922
- } else if (result.hasChanges) {
75923
- logger.success(` Compiled: ${file}`);
75924
- } else if (verbose) {
75925
- logger.info(` No changes: ${file}`);
76073
+ }
76074
+ const timing = logger.dim(fileTimer.elapsed());
76075
+ const filePrint = displayPath(file);
76076
+ if (dryRun) {
76077
+ if (result.hasChanges) {
76078
+ logger.success(`${filePrint} ${timing} ${logger.dim("(dry run)")}`);
76079
+ } else {
76080
+ logger.log(` ${filePrint} ${logger.dim("(no changes, dry run)")}`);
75926
76081
  }
75927
- successCount++;
75928
- } catch (error2) {
75929
- logger.error(`Failed to compile ${fileName}: ${getErrorMessage(error2)}`);
75930
- errorCount++;
76082
+ } else if (result.hasChanges) {
76083
+ logger.success(`${filePrint} ${timing}`);
76084
+ } else if (verbose) {
76085
+ logger.info(` ${filePrint} ${logger.dim("no changes")}`);
75931
76086
  }
76087
+ successCount++;
76088
+ } catch (error2) {
76089
+ logger.error(` ${fileName}: ${getErrorMessage(error2)}`);
76090
+ errorCount++;
75932
76091
  }
75933
- logger.newline();
75934
- logger.section("Summary");
75935
- logger.success(`${successCount} file(s) compiled successfully`);
75936
- if (errorCount > 0) {
75937
- throw new Error(`${errorCount} file(s) failed to compile`);
75938
- }
75939
- } catch (error2) {
75940
- if (error2 instanceof Error && error2.message.includes("file(s) failed")) {
75941
- throw error2;
75942
- }
75943
- throw new Error(`Compilation failed: ${getErrorMessage(error2)}`);
76092
+ }
76093
+ const elapsed = totalTimer.elapsed();
76094
+ const formatNote = verbose ? "" : ` (${moduleFormat.toUpperCase()})`;
76095
+ const dryRunNote = dryRun ? " (dry run)" : "";
76096
+ logger.newline();
76097
+ if (errorCount > 0) {
76098
+ logger.log(` ${successCount} compiled, ${errorCount} failed${formatNote} in ${elapsed}${dryRunNote}`);
76099
+ throw new Error(`${errorCount} file(s) failed to compile`);
76100
+ } else {
76101
+ logger.log(` ${successCount} file${successCount !== 1 ? "s" : ""} compiled${formatNote} in ${elapsed}${dryRunNote}`);
75944
76102
  }
75945
76103
  }
75946
76104
  async function compileInngestTarget(input, options) {
75947
76105
  const filePath = path9.resolve(input);
75948
76106
  if (!fs10.existsSync(filePath)) {
75949
- throw new Error(`File not found: ${filePath}`);
76107
+ throw new Error(`File not found: ${displayPath(filePath)}`);
75950
76108
  }
75951
76109
  logger.section("Compiling to Inngest");
75952
- logger.info(`Input: ${filePath}`);
76110
+ logger.info(`Input: ${displayPath(filePath)}`);
75953
76111
  logger.info(`Target: Inngest (per-node step.run)`);
75954
76112
  logger.newline();
75955
76113
  const parser3 = new AnnotationParser();
@@ -75988,7 +76146,7 @@ ${msgs}`);
75988
76146
  });
75989
76147
  const outputPath = filePath.replace(/\.ts$/, ".inngest.ts");
75990
76148
  if (options.dryRun) {
75991
- logger.success(`Would generate: ${outputPath}`);
76149
+ logger.success(`Would generate: ${displayPath(outputPath)}`);
75992
76150
  logger.newline();
75993
76151
  logger.section("Preview");
75994
76152
  const lines = code.split("\n");
@@ -75999,7 +76157,7 @@ ${msgs}`);
75999
76157
  }
76000
76158
  } else {
76001
76159
  fs10.writeFileSync(outputPath, code, "utf8");
76002
- logger.success(`Compiled: ${outputPath}`);
76160
+ logger.success(`Compiled: ${displayPath(outputPath)}`);
76003
76161
  }
76004
76162
  logger.newline();
76005
76163
  logger.section("Summary");
@@ -77129,7 +77287,11 @@ async function diffCommand(file1, file2, options = {}) {
77129
77287
  }
77130
77288
  const diff = WorkflowDiffer.compare(result1.ast, result2.ast);
77131
77289
  if (diff.identical) {
77132
- logger.success("Workflows are identical");
77290
+ if (format === "json") {
77291
+ console.log(JSON.stringify({ identical: true }));
77292
+ } else {
77293
+ logger.success("Workflows are identical");
77294
+ }
77133
77295
  } else {
77134
77296
  console.log(formatDiff(diff, format));
77135
77297
  if (!exitZero) {
@@ -77350,7 +77512,7 @@ async function templatesCommand(options = {}) {
77350
77512
  logger.newline();
77351
77513
  logger.section("Usage");
77352
77514
  logger.log(" $ flow-weaver create workflow <template> <file> [--async] [--line N]");
77353
- logger.log(" $ flow-weaver create node <template> <name> <file> [--line N]");
77515
+ logger.log(" $ flow-weaver create node <name> <file> [-t <template>] [--line N]");
77354
77516
  logger.newline();
77355
77517
  }
77356
77518
 
@@ -77383,15 +77545,18 @@ async function validateCommand(input, options = {}) {
77383
77545
  if (files.length === 0) {
77384
77546
  if (json2) {
77385
77547
  console.log(JSON.stringify({ error: `No files found matching pattern: ${input}` }));
77386
- } else {
77387
- logger.error(`No files found matching pattern: ${input}`);
77548
+ process.exitCode = 1;
77549
+ return;
77388
77550
  }
77389
- process.exit(1);
77551
+ throw new Error(`No files found matching pattern: ${input}`);
77390
77552
  }
77553
+ const totalTimer = logger.timer();
77391
77554
  if (!json2) {
77392
77555
  logger.section("Validating Workflows");
77393
- logger.info(`Found ${files.length} file(s)`);
77394
- logger.newline();
77556
+ if (verbose) {
77557
+ logger.info(`Found ${files.length} file(s)`);
77558
+ logger.newline();
77559
+ }
77395
77560
  }
77396
77561
  let totalErrors = 0;
77397
77562
  let totalWarnings = 0;
@@ -77400,7 +77565,7 @@ async function validateCommand(input, options = {}) {
77400
77565
  for (let i = 0; i < files.length; i++) {
77401
77566
  const file = files[i];
77402
77567
  const fileName = path15.basename(file);
77403
- if (!json2) {
77568
+ if (!json2 && verbose) {
77404
77569
  logger.progress(i + 1, files.length, fileName);
77405
77570
  }
77406
77571
  try {
@@ -77482,9 +77647,9 @@ async function validateCommand(input, options = {}) {
77482
77647
  if (friendly) {
77483
77648
  const loc = err.location ? `[line ${err.location.line}] ` : "";
77484
77649
  logger.error(` ${loc}${friendly.title}: ${friendly.explanation}`);
77485
- logger.info(` How to fix: ${friendly.fix}`);
77650
+ logger.warn(` How to fix: ${friendly.fix}`);
77486
77651
  if (err.docUrl) {
77487
- logger.info(` See: ${err.docUrl}`);
77652
+ logger.warn(` See: ${err.docUrl}`);
77488
77653
  }
77489
77654
  } else {
77490
77655
  let msg = ` - ${err.message}`;
@@ -77499,7 +77664,7 @@ async function validateCommand(input, options = {}) {
77499
77664
  }
77500
77665
  logger.error(msg);
77501
77666
  if (err.docUrl) {
77502
- logger.info(` See: ${err.docUrl}`);
77667
+ logger.warn(` See: ${err.docUrl}`);
77503
77668
  }
77504
77669
  }
77505
77670
  });
@@ -77514,9 +77679,9 @@ async function validateCommand(input, options = {}) {
77514
77679
  if (friendly) {
77515
77680
  const loc = warn.location ? `[line ${warn.location.line}] ` : "";
77516
77681
  logger.warn(` ${loc}${friendly.title}: ${friendly.explanation}`);
77517
- logger.info(` How to fix: ${friendly.fix}`);
77682
+ logger.warn(` How to fix: ${friendly.fix}`);
77518
77683
  if (warn.docUrl) {
77519
- logger.info(` See: ${warn.docUrl}`);
77684
+ logger.warn(` See: ${warn.docUrl}`);
77520
77685
  }
77521
77686
  } else {
77522
77687
  let msg = ` - ${warn.message}`;
@@ -77528,7 +77693,7 @@ async function validateCommand(input, options = {}) {
77528
77693
  }
77529
77694
  logger.warn(msg);
77530
77695
  if (warn.docUrl) {
77531
- logger.info(` See: ${warn.docUrl}`);
77696
+ logger.warn(` See: ${warn.docUrl}`);
77532
77697
  }
77533
77698
  }
77534
77699
  });
@@ -77571,16 +77736,16 @@ async function validateCommand(input, options = {}) {
77571
77736
  )
77572
77737
  );
77573
77738
  } else {
77739
+ const elapsed = totalTimer.elapsed();
77574
77740
  logger.newline();
77575
- logger.section("Validation Summary");
77576
- logger.success(`${successCount} file(s) valid`);
77577
- if (totalWarnings > 0) {
77578
- logger.warn(`${totalWarnings} warning(s) found`);
77579
- }
77580
77741
  if (totalErrors > 0) {
77581
- logger.error(`${totalErrors} error(s) found`);
77742
+ const parts2 = [`${successCount} valid`, `${totalErrors} error${totalErrors !== 1 ? "s" : ""}`];
77743
+ if (totalWarnings > 0) parts2.push(`${totalWarnings} warning${totalWarnings !== 1 ? "s" : ""}`);
77744
+ logger.log(` ${parts2.join(", ")} in ${elapsed}`);
77745
+ } else if (totalWarnings > 0) {
77746
+ logger.log(` ${successCount} valid, ${totalWarnings} warning${totalWarnings !== 1 ? "s" : ""} in ${elapsed}`);
77582
77747
  } else {
77583
- logger.success("All workflows are valid!");
77748
+ logger.success(`${successCount} file${successCount !== 1 ? "s" : ""} valid in ${elapsed}`);
77584
77749
  }
77585
77750
  }
77586
77751
  if (totalErrors > 0) {
@@ -77589,10 +77754,10 @@ async function validateCommand(input, options = {}) {
77589
77754
  } catch (error2) {
77590
77755
  if (json2) {
77591
77756
  console.log(JSON.stringify({ error: getErrorMessage(error2) }));
77592
- } else {
77593
- logger.error(`Validation failed: ${getErrorMessage(error2)}`);
77757
+ process.exitCode = 1;
77758
+ return;
77594
77759
  }
77595
- process.exit(1);
77760
+ throw error2;
77596
77761
  }
77597
77762
  }
77598
77763
 
@@ -80897,16 +81062,15 @@ async function initCommand(dirArg, options) {
80897
81062
  });
80898
81063
  let installResult;
80899
81064
  if (config2.install) {
80900
- if (!options.json) {
80901
- logger.info("Installing dependencies...");
80902
- }
81065
+ const spinner = !options.json ? logger.spinner("Installing dependencies...") : null;
80903
81066
  installResult = runNpmInstall(config2.targetDir);
81067
+ if (spinner) {
81068
+ if (installResult.success) spinner.stop("Dependencies installed");
81069
+ else spinner.fail(`npm install failed: ${installResult.error}`);
81070
+ }
80904
81071
  }
80905
81072
  let gitResult;
80906
81073
  if (config2.git) {
80907
- if (!options.json) {
80908
- logger.info("Initializing git repository...");
80909
- }
80910
81074
  gitResult = runGitInit(config2.targetDir);
80911
81075
  }
80912
81076
  const workflowFile = `${config2.projectName}-workflow.ts`;
@@ -80914,7 +81078,6 @@ async function initCommand(dirArg, options) {
80914
81078
  let compileResult;
80915
81079
  if (!options.json && fs17.existsSync(workflowPath)) {
80916
81080
  try {
80917
- logger.info("Compiling workflow...");
80918
81081
  await compileCommand(workflowPath, { format: config2.format });
80919
81082
  compileResult = { success: true };
80920
81083
  } catch (err) {
@@ -80935,36 +81098,28 @@ async function initCommand(dirArg, options) {
80935
81098
  console.log(JSON.stringify(report, null, 2));
80936
81099
  return;
80937
81100
  }
80938
- logger.section("Project created");
80939
- for (const file of filesCreated) {
80940
- logger.success(`Created ${file}`);
80941
- }
80942
- for (const file of filesSkipped) {
80943
- logger.warn(`Skipped ${file} (already exists)`);
80944
- }
80945
- if (installResult) {
80946
- if (installResult.success) {
80947
- logger.success("Dependencies installed");
80948
- } else {
80949
- logger.warn(`npm install failed: ${installResult.error}`);
80950
- }
81101
+ logger.newline();
81102
+ logger.success(`Created ${logger.highlight(config2.projectName)} ${logger.dim(`(${config2.template}, ${config2.format.toUpperCase()})`)}`);
81103
+ logger.log(` ${filesCreated.join(", ")}`);
81104
+ if (filesSkipped.length > 0) {
81105
+ logger.warn(`Skipped ${filesSkipped.length} existing file(s)`);
80951
81106
  }
80952
81107
  if (gitResult) {
80953
81108
  if (gitResult.success) {
80954
- logger.success("Git repository initialized");
81109
+ logger.success("Git initialized");
80955
81110
  } else {
80956
81111
  logger.warn(`git init failed: ${gitResult.error}`);
80957
81112
  }
80958
81113
  }
80959
81114
  if (compileResult) {
80960
81115
  if (compileResult.success) {
80961
- logger.success("Workflow compiled (npm start works immediately)");
81116
+ logger.success("Workflow compiled");
80962
81117
  } else {
80963
- logger.warn(`Workflow compile failed: ${compileResult.error}`);
81118
+ logger.warn(`Compile failed: ${compileResult.error}`);
80964
81119
  }
80965
81120
  }
80966
81121
  logger.newline();
80967
- logger.section("Next steps");
81122
+ logger.log(` ${logger.bold("Next steps")}`);
80968
81123
  const relDir = path16.relative(process.cwd(), config2.targetDir);
80969
81124
  const displayDir = !relDir || relDir === "." ? null : relDir.startsWith("../../") ? config2.targetDir : relDir;
80970
81125
  if (displayDir) {
@@ -81055,7 +81210,16 @@ function timestamp3() {
81055
81210
  const h = String(now.getHours()).padStart(2, "0");
81056
81211
  const m = String(now.getMinutes()).padStart(2, "0");
81057
81212
  const s = String(now.getSeconds()).padStart(2, "0");
81058
- return `[${h}:${m}:${s}]`;
81213
+ return `${h}:${m}:${s}`;
81214
+ }
81215
+ function cycleSeparator(file) {
81216
+ const ts5 = timestamp3();
81217
+ const pad = "\u2500".repeat(40);
81218
+ logger.log(`
81219
+ ${logger.dim(`\u2500\u2500\u2500 ${ts5} ${pad}`)}`);
81220
+ if (file) {
81221
+ logger.log(` ${logger.dim("File changed:")} ${path19.basename(file)}`);
81222
+ }
81059
81223
  }
81060
81224
  function parseParams(options) {
81061
81225
  if (options.params) {
@@ -81085,9 +81249,10 @@ async function compileAndRun(filePath, params, options) {
81085
81249
  clean: options.clean
81086
81250
  };
81087
81251
  try {
81252
+ const ct = logger.timer();
81088
81253
  await compileCommand(filePath, compileOpts);
81089
81254
  if (!options.json) {
81090
- logger.success("Compiled successfully");
81255
+ logger.success(`Compiled in ${ct.elapsed()}`);
81091
81256
  }
81092
81257
  } catch (error2) {
81093
81258
  const errorMsg = getErrorMessage(error2);
@@ -81098,7 +81263,7 @@ async function compileAndRun(filePath, params, options) {
81098
81263
  const friendly = getFriendlyError(err);
81099
81264
  if (friendly) {
81100
81265
  logger.error(` ${friendly.title}: ${friendly.explanation}`);
81101
- logger.info(` How to fix: ${friendly.fix}`);
81266
+ logger.warn(` How to fix: ${friendly.fix}`);
81102
81267
  } else {
81103
81268
  logger.error(` - ${err.message}`);
81104
81269
  }
@@ -81129,8 +81294,6 @@ async function compileAndRun(filePath, params, options) {
81129
81294
  );
81130
81295
  } else {
81131
81296
  logger.success(`Workflow "${result.functionName}" completed in ${result.executionTime}ms`);
81132
- logger.newline();
81133
- logger.section("Result");
81134
81297
  logger.log(JSON.stringify(result.result, null, 2));
81135
81298
  }
81136
81299
  return true;
@@ -81285,10 +81448,8 @@ async function runInngestDevMode(filePath, options) {
81285
81448
  ignoreInitial: true
81286
81449
  });
81287
81450
  watcher.on("change", async (file) => {
81288
- logger.newline();
81289
- logger.info(`${timestamp3()} File changed: ${path19.basename(file)}`);
81451
+ cycleSeparator(file);
81290
81452
  logger.info("Recompiling and restarting server...");
81291
- logger.newline();
81292
81453
  await restartServer();
81293
81454
  });
81294
81455
  const sourceOutput = filePath.replace(/\.ts$/, ".inngest.ts");
@@ -81345,9 +81506,7 @@ async function devCommand(input, options = {}) {
81345
81506
  });
81346
81507
  watcher.on("change", async (file) => {
81347
81508
  if (!options.json) {
81348
- logger.newline();
81349
- logger.info(`${timestamp3()} File changed: ${path19.basename(file)}`);
81350
- logger.newline();
81509
+ cycleSeparator(file);
81351
81510
  }
81352
81511
  await compileAndRun(filePath, params, options);
81353
81512
  });
@@ -85550,7 +85709,7 @@ var mutationHandlers = {
85550
85709
  const node = wf.instances?.find((n) => n.id === nodeId);
85551
85710
  if (!node) throw new Error(`Node "${nodeId}" not found`);
85552
85711
  const existing = node.config?.portConfigs || [];
85553
- const idx = existing.findIndex((pc) => pc.portName === portName);
85712
+ const idx = existing.findIndex((pc2) => pc2.portName === portName);
85554
85713
  const updated = [...existing];
85555
85714
  if (idx >= 0) {
85556
85715
  updated[idx] = { ...updated[idx], ...portConfig };
@@ -85567,7 +85726,7 @@ var mutationHandlers = {
85567
85726
  const node = wf.instances?.find((n) => n.id === nodeId);
85568
85727
  if (!node) throw new Error(`Node "${nodeId}" not found`);
85569
85728
  const existing = node.config?.portConfigs || [];
85570
- const filtered = existing.filter((pc) => pc.portName !== portName);
85729
+ const filtered = existing.filter((pc2) => pc2.portName !== portName);
85571
85730
  return updateNode(wf, nodeId, { config: { ...node.config, portConfigs: filtered } });
85572
85731
  };
85573
85732
  }),
@@ -104851,7 +105010,8 @@ init_grammar_diagrams();
104851
105010
  import * as fs39 from "fs";
104852
105011
  init_error_utils();
104853
105012
  async function grammarCommand(options = {}) {
104854
- const { format = "html", output } = options;
105013
+ const defaultFormat = options.output ? "html" : process.stdout.isTTY ? "ebnf" : "html";
105014
+ const { format = defaultFormat, output } = options;
104855
105015
  try {
104856
105016
  let content;
104857
105017
  if (format === "ebnf") {
@@ -104887,10 +105047,29 @@ import * as readline8 from "readline";
104887
105047
  init_query();
104888
105048
  init_error_utils();
104889
105049
  init_api6();
105050
+ function displayPath2(filePath) {
105051
+ const rel = path43.relative(process.cwd(), filePath);
105052
+ if (rel && !rel.startsWith("..") && rel.length < filePath.length) {
105053
+ return rel;
105054
+ }
105055
+ return filePath;
105056
+ }
104890
105057
  async function runCommand(input, options) {
105058
+ if (options.json) {
105059
+ try {
105060
+ await runCommandInner(input, options);
105061
+ } catch (e) {
105062
+ console.log(JSON.stringify({ success: false, error: getErrorMessage(e) }));
105063
+ process.exitCode = 1;
105064
+ }
105065
+ return;
105066
+ }
105067
+ await runCommandInner(input, options);
105068
+ }
105069
+ async function runCommandInner(input, options) {
104891
105070
  const filePath = path43.resolve(input);
104892
105071
  if (!fs40.existsSync(filePath)) {
104893
- throw new Error(`File not found: ${filePath}`);
105072
+ throw new Error(`File not found: ${displayPath2(filePath)}`);
104894
105073
  }
104895
105074
  let params = {};
104896
105075
  if (options.params) {
@@ -104956,7 +105135,7 @@ async function runCommand(input, options) {
104956
105135
  const checkpointPath = typeof options.resume === "string" ? options.resume : findLatestCheckpoint(filePath, options.workflow);
104957
105136
  if (!checkpointPath) {
104958
105137
  throw new Error(
104959
- `No checkpoint file found for ${filePath}. Checkpoints are created when running with --checkpoint.`
105138
+ `No checkpoint file found for ${displayPath2(filePath)}. Checkpoints are created when running with --checkpoint.`
104960
105139
  );
104961
105140
  }
104962
105141
  const { data, stale, rerunNodes, skipNodes } = loadCheckpoint(
@@ -105140,16 +105319,18 @@ async function runCommand(input, options) {
105140
105319
  logger.newline();
105141
105320
  logger.section("Result");
105142
105321
  logger.log(JSON.stringify(result.result, null, 2));
105143
- if (result.trace && result.trace.length > 0) {
105322
+ if (options.trace && !options.stream && result.trace && result.trace.length > 0) {
105144
105323
  logger.newline();
105145
105324
  logger.section("Trace");
105146
105325
  logger.log(`${result.trace.length} events captured`);
105147
- const preview = result.trace.slice(0, 5);
105326
+ const meaningful = result.trace.filter((e) => e.data?.nodeId || e.data?.id);
105327
+ const preview = meaningful.slice(0, 5);
105148
105328
  for (const event of preview) {
105149
- logger.log(` [${event.type}] ${event.data?.nodeId || ""}`);
105329
+ const nodeId = event.data?.nodeId || event.data?.id || "";
105330
+ logger.log(` [${event.type}] ${nodeId}`);
105150
105331
  }
105151
- if (result.trace.length > 5) {
105152
- logger.log(` ... and ${result.trace.length - 5} more events`);
105332
+ if (meaningful.length > 5) {
105333
+ logger.log(` ... and ${meaningful.length - 5} more events`);
105153
105334
  }
105154
105335
  }
105155
105336
  }
@@ -105162,7 +105343,7 @@ async function runCommand(input, options) {
105162
105343
  const friendly = getFriendlyError(err);
105163
105344
  if (friendly) {
105164
105345
  logger.error(` ${friendly.title}: ${friendly.explanation}`);
105165
- logger.info(` How to fix: ${friendly.fix}`);
105346
+ logger.warn(` How to fix: ${friendly.fix}`);
105166
105347
  } else {
105167
105348
  logger.error(` - ${err.message}`);
105168
105349
  }
@@ -105171,19 +105352,20 @@ async function runCommand(input, options) {
105171
105352
  const friendly = getFriendlyError({ code: errorObj.code, message: errorMsg });
105172
105353
  if (friendly) {
105173
105354
  logger.error(`${friendly.title}: ${friendly.explanation}`);
105174
- logger.info(` How to fix: ${friendly.fix}`);
105355
+ logger.warn(` How to fix: ${friendly.fix}`);
105175
105356
  } else {
105176
105357
  logger.error(`Workflow execution failed: ${errorMsg}`);
105177
105358
  }
105178
105359
  } else {
105179
105360
  logger.error(`Workflow execution failed: ${errorMsg}`);
105180
105361
  }
105181
- if (!options.json) {
105182
- throw error2;
105183
- } else {
105362
+ if (options.json) {
105184
105363
  process.stdout.write(
105185
105364
  JSON.stringify({ success: false, error: errorMsg }, null, 2) + "\n"
105186
105365
  );
105366
+ process.exitCode = 1;
105367
+ } else {
105368
+ process.exitCode = 1;
105187
105369
  }
105188
105370
  } finally {
105189
105371
  if (timeoutId) {
@@ -106168,6 +106350,7 @@ async function exportCommand(input, options) {
106168
106350
  throw new Error("--target is required. Install a target pack (e.g. npm install flowweaver-pack-lambda)");
106169
106351
  }
106170
106352
  const isDryRun = options.dryRun ?? false;
106353
+ const t = logger.timer();
106171
106354
  const isMulti = options.multi ?? false;
106172
106355
  const workflowsList = options.workflows ? options.workflows.split(",").map((w) => w.trim()) : void 0;
106173
106356
  logger.section(isDryRun ? "Export Preview (Dry Run)" : "Exporting Workflow");
@@ -106224,6 +106407,7 @@ async function exportCommand(input, options) {
106224
106407
  } else {
106225
106408
  logger.success(`Exported workflow "${result.workflow}" for ${result.target}`);
106226
106409
  }
106410
+ logger.info(`done in ${t.elapsed()}`);
106227
106411
  }
106228
106412
  logger.newline();
106229
106413
  logger.section(isDryRun ? "Files That Would Be Generated" : "Generated Files");
@@ -106287,7 +106471,9 @@ async function openapiCommand(dir, options) {
106287
106471
  if (endpoints.length === 0) {
106288
106472
  throw new Error(`No workflows found in ${workflowDir}`);
106289
106473
  }
106290
- logger.info(`Found ${endpoints.length} workflow(s)`);
106474
+ if (options.output) {
106475
+ logger.info(`Found ${endpoints.length} workflow(s)`);
106476
+ }
106291
106477
  const generatorOptions = {
106292
106478
  title: options.title || "Flow Weaver API",
106293
106479
  version: options.version || "1.0.0",
@@ -106480,6 +106666,7 @@ async function migrateCommand(globPattern, options = {}) {
106480
106666
  if (registeredMigrations.length > 0) {
106481
106667
  logger.info(`Registered edge-case migrations: ${registeredMigrations.map((m) => m.name).join(", ")}`);
106482
106668
  }
106669
+ const t = logger.timer();
106483
106670
  let migratedCount = 0;
106484
106671
  let skippedCount = 0;
106485
106672
  let errorCount = 0;
@@ -106529,9 +106716,9 @@ ${file}:`);
106529
106716
  }
106530
106717
  logger.newline();
106531
106718
  if (dryRun) {
106532
- logger.info(`Dry run complete: ${migratedCount} file(s) would be updated, ${skippedCount} already current, ${errorCount} error(s)`);
106719
+ logger.info(`Dry run: ${migratedCount} file(s) would be updated, ${skippedCount} already current, ${errorCount} error(s) in ${t.elapsed()}`);
106533
106720
  } else {
106534
- logger.info(`Migration complete: ${migratedCount} file(s) updated, ${skippedCount} already current, ${errorCount} error(s)`);
106721
+ logger.info(`${migratedCount} file(s) migrated, ${skippedCount} already current, ${errorCount} error(s) in ${t.elapsed()}`);
106535
106722
  }
106536
106723
  }
106537
106724
 
@@ -106675,6 +106862,7 @@ async function stripCommand(input, options = {}) {
106675
106862
  logger.error(`No files found matching pattern: ${input}`);
106676
106863
  process.exit(1);
106677
106864
  }
106865
+ const t = logger.timer();
106678
106866
  let stripped = 0;
106679
106867
  let skipped = 0;
106680
106868
  for (const filePath of files) {
@@ -106702,7 +106890,8 @@ async function stripCommand(input, options = {}) {
106702
106890
  logger.success(`Stripped: ${path49.relative(process.cwd(), outPath)}`);
106703
106891
  }
106704
106892
  }
106705
- logger.success(`${stripped} file${stripped !== 1 ? "s" : ""} stripped, ${skipped} skipped`);
106893
+ const verb = dryRun ? "would be stripped" : "stripped";
106894
+ logger.success(`${stripped} file${stripped !== 1 ? "s" : ""} ${verb}, ${skipped} skipped in ${t.elapsed()}`);
106706
106895
  }
106707
106896
 
106708
106897
  // src/cli/commands/docs.ts
@@ -106843,7 +107032,8 @@ async function statusCommand(input, options = {}) {
106843
107032
  } else {
106844
107033
  logger.error(`File not found: ${input}`);
106845
107034
  }
106846
- process.exit(1);
107035
+ process.exitCode = 1;
107036
+ return;
106847
107037
  }
106848
107038
  const parseResult = await parseWorkflow(filePath, { workflowName });
106849
107039
  if (parseResult.errors.length > 0) {
@@ -106853,7 +107043,8 @@ async function statusCommand(input, options = {}) {
106853
107043
  logger.error("Parse errors:");
106854
107044
  parseResult.errors.forEach((e) => logger.error(` ${e}`));
106855
107045
  }
106856
- process.exit(1);
107046
+ process.exitCode = 1;
107047
+ return;
106857
107048
  }
106858
107049
  const ast = parseResult.ast;
106859
107050
  const instanceTypeMap = /* @__PURE__ */ new Map();
@@ -106922,7 +107113,7 @@ async function statusCommand(input, options = {}) {
106922
107113
  } else {
106923
107114
  logger.error(`Status failed: ${getErrorMessage(error2)}`);
106924
107115
  }
106925
- process.exit(1);
107116
+ process.exitCode = 1;
106926
107117
  }
106927
107118
  }
106928
107119
 
@@ -107200,7 +107391,9 @@ async function marketPackCommand(directory, options = {}) {
107200
107391
  validation,
107201
107392
  parsedFiles: parsedFiles.length
107202
107393
  }, null, 2));
107203
- if (!validation.valid) process.exit(1);
107394
+ if (!validation.valid) {
107395
+ process.exitCode = 1;
107396
+ }
107204
107397
  return;
107205
107398
  }
107206
107399
  logger.info(`Parsed ${parsedFiles.length} file(s)`);
@@ -107267,7 +107460,8 @@ async function marketInstallCommand(packageSpec, options = {}) {
107267
107460
  } else {
107268
107461
  logger.error(`npm install failed: ${getErrorMessage(err)}`);
107269
107462
  }
107270
- process.exit(1);
107463
+ process.exitCode = 1;
107464
+ return;
107271
107465
  }
107272
107466
  const packageName = resolvePackageName2(packageSpec);
107273
107467
  const manifest = readManifest(path52.join(process.cwd(), "node_modules", packageName));
@@ -107298,13 +107492,19 @@ async function marketSearchCommand(query, options = {}) {
107298
107492
  logger.newline();
107299
107493
  }
107300
107494
  try {
107301
- const results = await searchPackages({ query, limit, registryUrl: registry2 });
107495
+ let results = await searchPackages({ query, limit, registryUrl: registry2 });
107496
+ if (query) {
107497
+ const q = query.toLowerCase();
107498
+ results = results.filter(
107499
+ (pkg) => pkg.name.toLowerCase().includes(q) || pkg.description && pkg.description.toLowerCase().includes(q)
107500
+ );
107501
+ }
107302
107502
  if (json2) {
107303
107503
  console.log(JSON.stringify(results, null, 2));
107304
107504
  return;
107305
107505
  }
107306
107506
  if (results.length === 0) {
107307
- logger.info("No packages found");
107507
+ logger.info(query ? `No packages matching "${query}"` : "No packages found");
107308
107508
  return;
107309
107509
  }
107310
107510
  for (const pkg of results) {
@@ -107322,7 +107522,8 @@ async function marketSearchCommand(query, options = {}) {
107322
107522
  } else {
107323
107523
  logger.error(`Search failed: ${getErrorMessage(err)}`);
107324
107524
  }
107325
- process.exit(1);
107525
+ process.exitCode = 1;
107526
+ return;
107326
107527
  }
107327
107528
  }
107328
107529
  async function marketListCommand(options = {}) {
@@ -107729,11 +107930,19 @@ async function mcpSetupCommand(options, deps) {
107729
107930
 
107730
107931
  // src/cli/index.ts
107731
107932
  init_error_utils();
107732
- var version2 = true ? "0.15.2" : "0.0.0-dev";
107933
+ var version2 = true ? "0.16.0" : "0.0.0-dev";
107733
107934
  var program2 = new Command();
107734
- program2.name("flow-weaver").description("Flow Weaver Annotations - Compile and validate workflow files").version(version2, "-v, --version", "Output the current version");
107935
+ program2.name("flow-weaver").description("Flow Weaver Annotations - Compile and validate workflow files").option("-v, --version", "Output the current version").option("--no-color", "Disable colors").option("--color", "Force colors").on("option:version", () => {
107936
+ logger.banner(version2);
107937
+ process.exit(0);
107938
+ }).configureHelp({
107939
+ sortSubcommands: false,
107940
+ subcommandTerm: (cmd) => cmd.name() + (cmd.usage() ? " " + cmd.usage() : "")
107941
+ });
107942
+ var actionErrorHandled = false;
107735
107943
  program2.configureOutput({
107736
107944
  writeErr: (str2) => {
107945
+ if (actionErrorHandled) return;
107737
107946
  const trimmed = str2.replace(/^error:\s*/i, "").trimEnd();
107738
107947
  if (trimmed) {
107739
107948
  logger.error(trimmed);
@@ -107741,452 +107950,211 @@ program2.configureOutput({
107741
107950
  },
107742
107951
  writeOut: (str2) => process.stdout.write(str2)
107743
107952
  });
107744
- program2.command("compile <input>").description("Compile workflow files to TypeScript").option("-o, --output <path>", "Output file or directory").option("-p, --production", "Generate production code (no debug events)", false).option("-s, --source-map", "Generate source maps", false).option("--verbose", "Verbose output", false).option("--dry-run", "Preview compilation without writing files", false).option("-w, --workflow-name <name>", "Specific workflow name to compile").option("-f, --format <format>", "Module format: esm, cjs, or auto (default: auto)", "auto").option("--strict", "Treat type coercion warnings as errors", false).option("--inline-runtime", "Force inline runtime even when @synergenius/flow-weaver package is installed", false).option("--clean", "Omit redundant @param/@returns annotations from compiled output", false).option("--target <target>", "Compilation target: typescript (default) or inngest (per-node step.run)").option("--cron <schedule>", "Set cron trigger schedule (Inngest target only)").option("--serve", "Generate serve() handler for HTTP event reception").option("--framework <name>", "Framework adapter for serve handler (next, express, hono, fastify, remix)").option("--typed-events", "Generate Zod event schemas from workflow @param annotations").option("--retries <n>", "Number of retries per function (Inngest target only)", parseInt).option("--timeout <duration>", 'Function timeout (e.g. "30m", "1h")').action(async (input, options) => {
107745
- try {
107746
- await compileCommand(input, options);
107747
- } catch (error2) {
107748
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107749
- process.exit(1);
107750
- }
107751
- });
107752
- program2.command("strip <input>").description("Remove generated code from compiled workflow files").option("-o, --output <path>", "Output directory (default: in-place)").option("--dry-run", "Preview without writing", false).option("--verbose", "Verbose output", false).action(async (input, options) => {
107753
- try {
107754
- await stripCommand(input, options);
107755
- } catch (error2) {
107756
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107757
- process.exit(1);
107758
- }
107759
- });
107760
- program2.command("describe <input>").description("Output workflow structure in LLM-friendly formats (JSON, text, mermaid)").option("-f, --format <format>", "Output format: json (default), text, mermaid, paths, ascii, ascii-compact", "json").option("-n, --node <id>", "Focus on a specific node").option("--compile", "Also update runtime markers in the source file").option("-w, --workflow-name <name>", "Specific workflow name to describe").action(async (input, options) => {
107761
- try {
107762
- await describeCommand(input, options);
107763
- } catch (error2) {
107764
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107765
- process.exit(1);
107766
- }
107767
- });
107768
- program2.command("diagram <input>").description("Generate SVG or interactive HTML diagram of a workflow").option("-t, --theme <theme>", "Color theme: dark (default), light", "dark").option("-w, --width <pixels>", "SVG width in pixels").option("-p, --padding <pixels>", "Canvas padding in pixels").option("--no-port-labels", "Hide data type labels on ports").option("--workflow-name <name>", "Specific workflow to render").option("-f, --format <format>", "Output format: svg (default), html, ascii, ascii-compact, text", "svg").option("-o, --output <file>", "Write output to file instead of stdout").action(async (input, options) => {
107769
- try {
107770
- if (options.width) options.width = Number(options.width);
107771
- if (options.padding) options.padding = Number(options.padding);
107772
- options.showPortLabels = options.portLabels;
107773
- await diagramCommand(input, options);
107774
- } catch (error2) {
107775
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107776
- process.exit(1);
107777
- }
107778
- });
107779
- program2.command("diff <file1> <file2>").description("Compare two workflow files semantically").option("-f, --format <format>", "Output format: text (default), json, compact", "text").option("-w, --workflow-name <name>", "Specific workflow name to compare").option("--exit-zero", "Exit 0 even when differences are found", false).action(async (file1, file2, options) => {
107780
- try {
107781
- await diffCommand(file1, file2, options);
107782
- } catch (error2) {
107783
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107784
- process.exit(1);
107785
- }
107786
- });
107787
- program2.command("validate <input>").description("Validate workflow files without compiling").option("--verbose", "Verbose output", false).option("-q, --quiet", "Suppress warnings", false).option("--json", "Output results as JSON", false).option("-w, --workflow-name <name>", "Specific workflow name to validate").option("--strict", "Treat type coercion warnings as errors", false).action(async (input, options) => {
107788
- try {
107789
- await validateCommand(input, options);
107790
- } catch (error2) {
107791
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107792
- process.exit(1);
107793
- }
107794
- });
107795
- program2.command("doctor").description("Check project environment and configuration for flow-weaver compatibility").option("--json", "Output results as JSON", false).action(async (options) => {
107796
- try {
107797
- await doctorCommand(options);
107798
- } catch (error2) {
107799
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107800
- process.exit(1);
107801
- }
107802
- });
107803
- program2.command("init [directory]").description("Create a new flow-weaver project").option("-n, --name <name>", "Project name (defaults to directory name)").option("-t, --template <template>", "Workflow template (default: simple)").option("-f, --format <format>", "Module format: esm or cjs (default: esm)").option("-y, --yes", "Skip prompts and use defaults", false).option("--install", "Run npm install after scaffolding").option("--no-install", "Skip npm install").option("--git", "Initialize a git repository").option("--no-git", "Skip git init").option("--force", "Overwrite existing files", false).option("--json", "Output results as JSON", false).action(async (directory, options) => {
107804
- try {
107805
- await initCommand(directory, options);
107806
- } catch (error2) {
107807
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107808
- process.exit(1);
107809
- }
107810
- });
107811
- program2.command("watch <input>").description("Watch workflow files and recompile on changes").option("-o, --output <path>", "Output file or directory").option("-p, --production", "Generate production code (no debug events)", false).option("-s, --source-map", "Generate source maps", false).option("--verbose", "Verbose output", false).option("-w, --workflow-name <name>", "Specific workflow name to compile").option("-f, --format <format>", "Module format: esm, cjs, or auto (default: auto)", "auto").action(async (input, options) => {
107812
- try {
107813
- await watchCommand(input, options);
107814
- } catch (error2) {
107815
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107816
- process.exit(1);
107817
- }
107818
- });
107819
- program2.command("dev <input>").description("Watch, compile, and run workflow on changes").option("--params <json>", "Input parameters as JSON string").option("--params-file <path>", "Path to JSON file with input parameters").option("-w, --workflow <name>", "Specific workflow name to run").option("-p, --production", "Run in production mode (no trace events)", false).option("-f, --format <format>", "Module format: esm, cjs, or auto (default: auto)", "auto").option("--clean", "Omit redundant @param/@returns annotations", false).option("--once", "Run once then exit", false).option("--json", "Output result as JSON", false).option("--target <target>", "Compilation target: typescript or inngest (default: typescript)").option("--framework <framework>", "Framework for serve handler (inngest target only)", "express").option("--port <port>", "Port for dev server (inngest target only)", (v) => parseInt(v, 10), 3e3).action(async (input, options) => {
107820
- try {
107821
- await devCommand(input, options);
107822
- } catch (error2) {
107823
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107824
- process.exit(1);
107825
- }
107826
- });
107827
- program2.command("listen").description("Connect to Studio and stream integration events as JSON lines").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(async (options) => {
107828
- try {
107829
- await listenCommand(options);
107830
- } catch (error2) {
107831
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107832
- process.exit(1);
107833
- }
107834
- });
107835
- program2.command("tunnel").description("Connect cloud Studio to your local project directory").requiredOption("-k, --key <apiKey>", "API key for cloud authentication (fw_xxxx)").option("-c, --cloud <url>", "Cloud server URL", "https://flowweaver.dev").option("-d, --dir <path>", "Project directory", process.cwd()).action(async (options) => {
107836
- try {
107837
- await tunnelCommand(options);
107838
- } catch (error2) {
107839
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107840
- process.exit(1);
107841
- }
107842
- });
107843
- program2.command("mcp-server").description("Start MCP server for Claude Code integration").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).option("--stdio", "Run in MCP stdio mode (skip interactive registration)").action(async (options) => {
107844
- try {
107845
- await mcpServerCommand(options);
107846
- } catch (error2) {
107847
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107848
- process.exit(1);
107849
- }
107850
- });
107851
- program2.command("mcp-setup").description("Configure MCP server for AI coding tools (Claude, Cursor, VS Code, Windsurf, Codex, OpenClaw)").option("--tool <tools...>", "Specific tools to configure (claude, cursor, vscode, windsurf, codex, openclaw)").option("--all", "Configure all detected tools without prompting").option("--list", "List detected tools without configuring").action(async (options) => {
107852
- try {
107853
- await mcpSetupCommand(options);
107854
- } catch (error2) {
107855
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107856
- process.exit(1);
107857
- }
107858
- });
107953
+ function wrapAction(fn) {
107954
+ return async (...args) => {
107955
+ try {
107956
+ await fn(...args);
107957
+ } catch (error2) {
107958
+ actionErrorHandled = true;
107959
+ logger.error(getErrorMessage(error2));
107960
+ process.exit(1);
107961
+ }
107962
+ };
107963
+ }
107964
+ program2.command("compile <input>").description("Compile workflow files to TypeScript").option("-o, --output <path>", "Output file or directory").option("-p, --production", "Generate production code (no debug events)", false).option("-s, --source-map", "Generate source maps", false).option("--verbose", "Verbose output", false).option("--dry-run", "Preview compilation without writing files", false).option("-w, --workflow <name>", "Specific workflow name to compile").addOption(new Option("-f, --format <format>", "Module format").choices(["esm", "cjs", "auto"]).default("auto")).option("--strict", "Treat type coercion warnings as errors", false).option("--inline-runtime", "Force inline runtime even when @synergenius/flow-weaver package is installed", false).option("--clean", "Omit redundant @param/@returns annotations from compiled output", false).option("--target <target>", "Compilation target: typescript (default) or inngest (per-node step.run)").option("--cron <schedule>", "Set cron trigger schedule (Inngest target only)").option("--serve", "Generate serve() handler for HTTP event reception").option("--framework <name>", "Framework adapter for serve handler (next, express, hono, fastify, remix)").option("--typed-events", "Generate Zod event schemas from workflow @param annotations").option("--retries <n>", "Number of retries per function (Inngest target only)", parseInt).option("--timeout <duration>", 'Function timeout (e.g. "30m", "1h")').action(wrapAction(async (input, options) => {
107965
+ if (options.workflow) options.workflowName = options.workflow;
107966
+ await compileCommand(input, options);
107967
+ }));
107968
+ program2.command("strip <input>").description("Remove generated code from compiled workflow files").option("-o, --output <path>", "Output directory (default: in-place)").option("--dry-run", "Preview without writing", false).option("--verbose", "Verbose output", false).action(wrapAction(async (input, options) => {
107969
+ await stripCommand(input, options);
107970
+ }));
107971
+ program2.command("describe <input>").description("Output workflow structure in LLM-friendly formats (JSON, text, mermaid)").addOption(new Option("-f, --format <format>", "Output format").choices(["json", "text", "mermaid", "paths", "ascii", "ascii-compact"]).default("json")).option("-n, --node <id>", "Focus on a specific node").option("--compile", "Also update runtime markers in the source file").option("-w, --workflow <name>", "Specific workflow name to describe").action(wrapAction(async (input, options) => {
107972
+ if (options.workflow) options.workflowName = options.workflow;
107973
+ await describeCommand(input, options);
107974
+ }));
107975
+ program2.command("diagram <input>").description("Generate SVG or interactive HTML diagram of a workflow").option("-t, --theme <theme>", "Color theme: dark, light", "dark").option("--width <pixels>", "SVG width in pixels").option("-p, --padding <pixels>", "Canvas padding in pixels").option("--no-port-labels", "Hide data type labels on ports").option("-w, --workflow <name>", "Specific workflow to render").addOption(new Option("-f, --format <format>", "Output format").choices(["svg", "html", "ascii", "ascii-compact", "text"]).default("svg")).option("-o, --output <file>", "Write output to file instead of stdout").action(wrapAction(async (input, options) => {
107976
+ if (options.width) options.width = Number(options.width);
107977
+ if (options.padding) options.padding = Number(options.padding);
107978
+ options.showPortLabels = options.portLabels;
107979
+ if (options.workflow) options.workflowName = options.workflow;
107980
+ await diagramCommand(input, options);
107981
+ }));
107982
+ program2.command("diff <file1> <file2>").description("Compare two workflow files semantically").addOption(new Option("-f, --format <format>", "Output format").choices(["text", "json", "compact"]).default("text")).option("-w, --workflow <name>", "Specific workflow name to compare").option("--exit-zero", "Exit 0 even when differences are found", false).action(wrapAction(async (file1, file2, options) => {
107983
+ if (options.workflow) options.workflowName = options.workflow;
107984
+ await diffCommand(file1, file2, options);
107985
+ }));
107986
+ program2.command("validate <input>").description("Validate workflow files without compiling").option("--verbose", "Verbose output", false).option("-q, --quiet", "Suppress warnings", false).option("--json", "Output results as JSON", false).option("-w, --workflow <name>", "Specific workflow name to validate").option("--strict", "Treat type coercion warnings as errors", false).action(wrapAction(async (input, options) => {
107987
+ if (options.workflow) options.workflowName = options.workflow;
107988
+ await validateCommand(input, options);
107989
+ }));
107990
+ program2.command("doctor").description("Check project environment and configuration for flow-weaver compatibility").option("--json", "Output results as JSON", false).action(wrapAction(async (options) => {
107991
+ await doctorCommand(options);
107992
+ }));
107993
+ program2.command("init [directory]").description("Create a new flow-weaver project").option("-n, --name <name>", "Project name (defaults to directory name)").option("-t, --template <template>", "Workflow template (default: sequential)").option("-f, --format <format>", "Module format: esm or cjs (default: esm)").option("-y, --yes", "Skip prompts and use defaults", false).option("--install", "Run npm install after scaffolding").option("--no-install", "Skip npm install").option("--git", "Initialize a git repository").option("--no-git", "Skip git init").option("--force", "Overwrite existing files", false).option("--json", "Output results as JSON", false).action(wrapAction(async (directory, options) => {
107994
+ await initCommand(directory, options);
107995
+ }));
107996
+ program2.command("watch <input>").description("Watch workflow files and recompile on changes").option("-o, --output <path>", "Output file or directory").option("-p, --production", "Generate production code (no debug events)", false).option("-s, --source-map", "Generate source maps", false).option("--verbose", "Verbose output", false).option("-w, --workflow <name>", "Specific workflow name to compile").option("-f, --format <format>", "Module format: esm, cjs, or auto", "auto").action(wrapAction(async (input, options) => {
107997
+ if (options.workflow) options.workflowName = options.workflow;
107998
+ await watchCommand(input, options);
107999
+ }));
108000
+ program2.command("dev <input>").description("Watch, compile, and run workflow on changes").option("--params <json>", "Input parameters as JSON string").option("--params-file <path>", "Path to JSON file with input parameters").option("-w, --workflow <name>", "Specific workflow name to run").option("-p, --production", "Run in production mode (no trace events)", false).option("-f, --format <format>", "Module format: esm, cjs, or auto", "auto").option("--clean", "Omit redundant @param/@returns annotations", false).option("--once", "Run once then exit", false).option("--json", "Output result as JSON", false).option("--target <target>", "Compilation target: typescript or inngest (default: typescript)").option("--framework <framework>", "Framework for serve handler (inngest target only)", "express").option("--port <port>", "Port for dev server (inngest target only)", (v) => parseInt(v, 10), 3e3).action(wrapAction(async (input, options) => {
108001
+ await devCommand(input, options);
108002
+ }));
108003
+ program2.command("listen").description("Connect to Studio and stream integration events as JSON lines").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(wrapAction(async (options) => {
108004
+ await listenCommand(options);
108005
+ }));
108006
+ program2.command("tunnel").description("Connect cloud Studio to your local project directory").requiredOption("-k, --key <apiKey>", "API key for cloud authentication (fw_xxxx)").option("-c, --cloud <url>", "Cloud server URL", "https://flowweaver.dev").option("-d, --dir <path>", "Project directory", process.cwd()).action(wrapAction(async (options) => {
108007
+ await tunnelCommand(options);
108008
+ }));
108009
+ program2.command("mcp-server").description("Start MCP server for Claude Code integration").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).option("--stdio", "Run in MCP stdio mode (skip interactive registration)").action(wrapAction(async (options) => {
108010
+ await mcpServerCommand(options);
108011
+ }));
108012
+ program2.command("mcp-setup").description("Configure MCP server for AI coding tools (Claude, Cursor, VS Code, Windsurf, Codex, OpenClaw)").option("--tool <tools...>", "Specific tools to configure (claude, cursor, vscode, windsurf, codex, openclaw)").option("--all", "Configure all detected tools without prompting").option("--list", "List detected tools without configuring").action(wrapAction(async (options) => {
108013
+ await mcpSetupCommand(options);
108014
+ }));
107859
108015
  var uiCmd = program2.command("ui").description("Send commands to Studio");
107860
- uiCmd.command("focus-node <nodeId>").description("Select and center a node in Studio").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(async (nodeId, options) => {
107861
- try {
107862
- await uiFocusNode(nodeId, options);
107863
- } catch (error2) {
107864
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107865
- process.exit(1);
107866
- }
107867
- });
107868
- uiCmd.command("add-node <nodeTypeName>").description("Add a node at viewport center").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(async (nodeTypeName, options) => {
107869
- try {
107870
- await uiAddNode(nodeTypeName, options);
107871
- } catch (error2) {
107872
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107873
- process.exit(1);
107874
- }
107875
- });
107876
- uiCmd.command("open-workflow <filePath>").description("Open a workflow file in Studio").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(async (filePath, options) => {
107877
- try {
107878
- await uiOpenWorkflow(filePath, options);
107879
- } catch (error2) {
107880
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107881
- process.exit(1);
107882
- }
107883
- });
107884
- uiCmd.command("get-state").description("Return current workflow state from Studio").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(async (options) => {
107885
- try {
107886
- await uiGetState(options);
107887
- } catch (error2) {
107888
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107889
- process.exit(1);
107890
- }
107891
- });
107892
- uiCmd.command("batch <json>").description("Execute a batch of commands with auto-snapshot rollback").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(async (json2, options) => {
107893
- try {
107894
- await uiBatch(json2, options);
107895
- } catch (error2) {
107896
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107897
- process.exit(1);
107898
- }
107899
- });
108016
+ uiCmd.command("focus-node <nodeId>").description("Select and center a node in Studio").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(wrapAction(async (nodeId, options) => {
108017
+ await uiFocusNode(nodeId, options);
108018
+ }));
108019
+ uiCmd.command("add-node <nodeTypeName>").description("Add a node at viewport center").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(wrapAction(async (nodeTypeName, options) => {
108020
+ await uiAddNode(nodeTypeName, options);
108021
+ }));
108022
+ uiCmd.command("open-workflow <filePath>").description("Open a workflow file in Studio").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(wrapAction(async (filePath, options) => {
108023
+ await uiOpenWorkflow(filePath, options);
108024
+ }));
108025
+ uiCmd.command("get-state").description("Return current workflow state from Studio").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(wrapAction(async (options) => {
108026
+ await uiGetState(options);
108027
+ }));
108028
+ uiCmd.command("batch <json>").description("Execute a batch of commands with auto-snapshot rollback").option("-s, --server <url>", "Studio URL", DEFAULT_SERVER_URL).action(wrapAction(async (json2, options) => {
108029
+ await uiBatch(json2, options);
108030
+ }));
107900
108031
  var createCmd = program2.command("create").description("Create workflows or nodes from templates");
107901
- createCmd.command("workflow <template> <file>").description("Create a workflow from a template").option("-l, --line <number>", "Insert at specific line number", parseInt).option("-a, --async", "Generate an async workflow", false).option("-p, --preview", "Preview generated code without writing", false).option("--provider <provider>", "LLM provider (openai, anthropic, ollama, mock)").option("--model <model>", "Model identifier (e.g., gpt-4o, claude-3-5-sonnet-20241022)").option("--config <json>", "Configuration as JSON string").option("--name <name>", "Override the derived workflow function name").option("--nodes <names>", 'Comma-separated node function names (e.g., "fetch,parse,store")').option("--input <name>", 'Custom input port name (default: "data")').option("--output <name>", 'Custom output port name (default: "result")').action(async (template, file, options) => {
107902
- try {
107903
- await createWorkflowCommand(template, file, options);
107904
- } catch (error2) {
107905
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107906
- process.exit(1);
107907
- }
107908
- });
107909
- createCmd.command("node <name> <file>").description("Create a node type (uses processor template by default)").option("-l, --line <number>", "Insert at specific line number", parseInt).option("-t, --template <template>", "Node template to use", "processor").option("-p, --preview", "Preview generated code without writing", false).option("--strategy <strategy>", "Template strategy (e.g. mock, callback, webhook)").option("--config <json>", "Additional configuration (JSON)").action(async (name, file, options) => {
107910
- try {
107911
- await createNodeCommand(name, file, options);
107912
- } catch (error2) {
107913
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107914
- process.exit(1);
107915
- }
107916
- });
107917
- program2.command("templates").description("List available templates").option("--json", "Output as JSON", false).action(async (options) => {
107918
- try {
107919
- await templatesCommand(options);
107920
- } catch (error2) {
107921
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107922
- process.exit(1);
107923
- }
107924
- });
108032
+ createCmd.command("workflow <template> <file>").description("Create a workflow from a template").option("-l, --line <number>", "Insert at specific line number", parseInt).option("-a, --async", "Generate an async workflow", false).option("-p, --preview", "Preview generated code without writing", false).option("--provider <provider>", "LLM provider (openai, anthropic, ollama, mock)").option("--model <model>", "Model identifier (e.g., gpt-4o, claude-3-5-sonnet-20241022)").option("--config <json>", "Configuration as JSON string").option("--name <name>", "Override the derived workflow function name").option("--nodes <names>", 'Comma-separated node function names (e.g., "fetch,parse,store")').option("--input <name>", 'Custom input port name (default: "data")').option("--output <name>", 'Custom output port name (default: "result")').action(wrapAction(async (template, file, options) => {
108033
+ await createWorkflowCommand(template, file, options);
108034
+ }));
108035
+ createCmd.command("node <name> <file>").description("Create a node type from a template").option("-l, --line <number>", "Insert at specific line number", parseInt).option("-t, --template <template>", "Node template to use", "transformer").option("-p, --preview", "Preview generated code without writing", false).option("--strategy <strategy>", "Template strategy (e.g. mock, callback, webhook)").option("--config <json>", "Additional configuration (JSON)").action(wrapAction(async (name, file, options) => {
108036
+ await createNodeCommand(name, file, options);
108037
+ }));
108038
+ program2.command("templates").description("List available templates").option("--json", "Output as JSON", false).action(wrapAction(async (options) => {
108039
+ await templatesCommand(options);
108040
+ }));
107925
108041
  program2.command("grammar").description(
107926
108042
  "Output JSDoc annotation grammar (@input, @output, @connect, @node, @scope) as HTML railroad diagrams or EBNF text"
107927
- ).option("-f, --format <format>", "Output format: html (default), ebnf", "html").option("-o, --output <path>", "Write output to file instead of stdout").action(async (options) => {
107928
- try {
107929
- await grammarCommand(options);
107930
- } catch (error2) {
107931
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107932
- process.exit(1);
107933
- }
107934
- });
108043
+ ).addOption(new Option("-f, --format <format>", "Output format").choices(["html", "ebnf"])).option("-o, --output <path>", "Write output to file instead of stdout").action(wrapAction(async (options) => {
108044
+ await grammarCommand(options);
108045
+ }));
107935
108046
  var patternCmd = program2.command("pattern").description("Work with reusable workflow patterns");
107936
- patternCmd.command("list <path>").description("List patterns in a file or directory").option("--json", "Output as JSON", false).action(async (inputPath, options) => {
107937
- try {
107938
- await patternListCommand(inputPath, options);
107939
- } catch (error2) {
107940
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107941
- process.exit(1);
107942
- }
107943
- });
107944
- patternCmd.command("apply <pattern-file> <target-file>").description("Apply a pattern to a workflow file").option("-p, --preview", "Preview changes without writing", false).option("--prefix <prefix>", "Prefix for node instance IDs").option("-n, --name <name>", "Specific pattern name to apply").action(async (patternFile, targetFile, options) => {
107945
- try {
107946
- await patternApplyCommand(patternFile, targetFile, options);
107947
- } catch (error2) {
107948
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107949
- process.exit(1);
107950
- }
107951
- });
107952
- patternCmd.command("extract <source-file>").description("Extract a pattern from workflow nodes").requiredOption("--nodes <nodes>", "Comma-separated list of node IDs to extract").requiredOption("-o, --output <file>", "Output pattern file").option("-n, --name <name>", "Pattern name").option("-p, --preview", "Preview pattern without writing", false).action(async (sourceFile, options) => {
107953
- try {
107954
- await patternExtractCommand(sourceFile, options);
107955
- } catch (error2) {
107956
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107957
- process.exit(1);
107958
- }
107959
- });
107960
- program2.command("run <input>").description("Execute a workflow file directly").option("-w, --workflow <name>", "Specific workflow name to run").option("--params <json>", "Input parameters as JSON string").option("--params-file <path>", "Path to JSON file with input parameters").option("-p, --production", "Production mode (no trace events)", false).option("-t, --trace", "Include execution trace events").option("-s, --stream", "Stream trace events in real-time").option("--json", "Output result as JSON", false).option("--timeout <ms>", "Execution timeout in milliseconds", parseInt).option("--mocks <json>", "Mock config for built-in nodes (events, invocations, agents, fast) as JSON").option("--mocks-file <path>", "Path to JSON file with mock config for built-in nodes").option("-d, --debug", "Start in step-through debug mode").option("--checkpoint", "Enable checkpointing to disk after each node").option("--resume [file]", "Resume from a checkpoint file (auto-detects latest if no file)").option("-b, --breakpoint <nodeIds...>", "Set initial breakpoints (repeatable)").action(async (input, options) => {
107961
- try {
107962
- await runCommand(input, options);
107963
- } catch (error2) {
107964
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107965
- process.exit(1);
107966
- }
107967
- });
107968
- program2.command("serve [directory]").description("Start HTTP server exposing workflows as endpoints").option("-p, --port <port>", "Server port", "3000").option("-H, --host <host>", "Server host", "0.0.0.0").option("--no-watch", "Disable file watching for hot reload").option("--production", "Production mode (no trace events)", false).option("--precompile", "Precompile all workflows on startup", false).option("--cors <origin>", "CORS origin", "*").option("--swagger", "Enable Swagger UI at /docs", false).action(async (directory, options) => {
107969
- try {
107970
- await serveCommand(directory, {
107971
- port: parseInt(options.port, 10),
107972
- host: options.host,
107973
- watch: options.watch,
107974
- production: options.production,
107975
- precompile: options.precompile,
107976
- cors: options.cors,
107977
- swagger: options.swagger
107978
- });
107979
- } catch (error2) {
107980
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107981
- process.exit(1);
107982
- }
107983
- });
107984
- program2.command("export <input>").description("Export workflow as serverless function").requiredOption("-t, --target <target>", "Target platform (lambda, vercel, cloudflare)").requiredOption("-o, --output <path>", "Output directory").option("-w, --workflow <name>", "Specific workflow name to export").option("-p, --production", "Production mode", true).option("--dry-run", "Preview without writing files", false).option("--multi", "Export all workflows in file as a single multi-workflow service", false).option("--workflows <names>", "Comma-separated list of workflows to export (used with --multi)").option("--docs", "Include API documentation routes (/docs and /openapi.json)", false).option("--durable-steps", "Use deep generator with per-node Inngest steps for durability (inngest target only)", false).action(async (input, options) => {
107985
- try {
107986
- await exportCommand(input, options);
107987
- } catch (error2) {
107988
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107989
- process.exit(1);
107990
- }
107991
- });
107992
- program2.command("openapi <directory>").description("Generate OpenAPI specification from workflows").option("-o, --output <path>", "Output file path").option("--title <title>", "API title", "Flow Weaver API").option("--version <version>", "API version", "1.0.0").option("--description <desc>", "API description").option("-f, --format <format>", "Output format: json (default), yaml", "json").option("--server <url>", "Server URL").action(async (directory, options) => {
107993
- try {
107994
- await openapiCommand(directory, options);
107995
- } catch (error2) {
107996
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
107997
- process.exit(1);
107998
- }
107999
- });
108047
+ patternCmd.command("list <path>").description("List patterns in a file or directory").option("--json", "Output as JSON", false).action(wrapAction(async (inputPath, options) => {
108048
+ await patternListCommand(inputPath, options);
108049
+ }));
108050
+ patternCmd.command("apply <pattern-file> <target-file>").description("Apply a pattern to a workflow file").option("-p, --preview", "Preview changes without writing", false).option("--prefix <prefix>", "Prefix for node instance IDs").option("-n, --name <name>", "Specific pattern name to apply").action(wrapAction(async (patternFile, targetFile, options) => {
108051
+ await patternApplyCommand(patternFile, targetFile, options);
108052
+ }));
108053
+ patternCmd.command("extract <source-file>").description("Extract a pattern from workflow nodes").requiredOption("--nodes <nodes>", "Comma-separated list of node IDs to extract").requiredOption("-o, --output <file>", "Output pattern file").option("-n, --name <name>", "Pattern name").option("-p, --preview", "Preview pattern without writing", false).action(wrapAction(async (sourceFile, options) => {
108054
+ await patternExtractCommand(sourceFile, options);
108055
+ }));
108056
+ program2.command("run <input>").description("Execute a workflow file directly").option("-w, --workflow <name>", "Specific workflow name to run").option("--params <json>", "Input parameters as JSON string").option("--params-file <path>", "Path to JSON file with input parameters").option("-p, --production", "Production mode (no trace events)", false).option("-t, --trace", "Include execution trace events").option("-s, --stream", "Stream trace events in real-time").option("--json", "Output result as JSON", false).option("--timeout <ms>", "Execution timeout in milliseconds", parseInt).option("--mocks <json>", "Mock config for built-in nodes (events, invocations, agents, fast) as JSON").option("--mocks-file <path>", "Path to JSON file with mock config for built-in nodes").option("-d, --debug", "Start in step-through debug mode").option("--checkpoint", "Enable checkpointing to disk after each node").option("--resume [file]", "Resume from a checkpoint file (auto-detects latest if no file)").option("-b, --breakpoint <nodeIds...>", "Set initial breakpoints (repeatable)").action(wrapAction(async (input, options) => {
108057
+ await runCommand(input, options);
108058
+ }));
108059
+ program2.command("serve [directory]").description("Start HTTP server exposing workflows as endpoints").option("-p, --port <port>", "Server port", "3000").option("-H, --host <host>", "Server host", "0.0.0.0").option("--no-watch", "Disable file watching for hot reload").option("--production", "Production mode (no trace events)", false).option("--precompile", "Precompile all workflows on startup", false).option("--cors <origin>", "CORS origin", "*").option("--swagger", "Enable Swagger UI at /docs", false).action(wrapAction(async (directory, options) => {
108060
+ await serveCommand(directory, {
108061
+ port: parseInt(options.port, 10),
108062
+ host: options.host,
108063
+ watch: options.watch,
108064
+ production: options.production,
108065
+ precompile: options.precompile,
108066
+ cors: options.cors,
108067
+ swagger: options.swagger
108068
+ });
108069
+ }));
108070
+ program2.command("export <input>").description("Export workflow as serverless function").requiredOption("-t, --target <target>", "Target platform (install target packs via marketplace)").requiredOption("-o, --output <path>", "Output directory").option("-w, --workflow <name>", "Specific workflow name to export").option("-p, --production", "Production mode", true).option("--dry-run", "Preview without writing files", false).option("--multi", "Export all workflows in file as a single multi-workflow service", false).option("--workflows <names>", "Comma-separated list of workflows to export (used with --multi)").option("--docs", "Include API documentation routes (/docs and /openapi.json)", false).option("--durable-steps", "Use deep generator with per-node Inngest steps for durability (inngest target only)", false).action(wrapAction(async (input, options) => {
108071
+ await exportCommand(input, options);
108072
+ }));
108073
+ program2.command("openapi <directory>").description("Generate OpenAPI specification from workflows").option("-o, --output <path>", "Output file path").option("--title <title>", "API title", "Flow Weaver API").option("--version <version>", "API version", "1.0.0").option("--description <desc>", "API description").option("-f, --format <format>", "Output format: json, yaml", "json").option("--server <url>", "Server URL").action(wrapAction(async (directory, options) => {
108074
+ await openapiCommand(directory, options);
108075
+ }));
108000
108076
  var pluginCmd = program2.command("plugin").description("Scaffold and manage external plugins");
108001
- pluginCmd.command("init <name>").description("Scaffold a new external plugin").option("-a, --area <area>", "Component area: sidebar, main, toolbar, modal, panel", "panel").option("--no-system", "Skip generating a system module").option("-p, --preview", "Preview generated files without writing", false).option("--force", "Overwrite existing files", false).action(async (name, options) => {
108002
- try {
108003
- await pluginInitCommand(name, options);
108004
- } catch (error2) {
108005
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108006
- process.exit(1);
108007
- }
108008
- });
108009
- program2.command("migrate <glob>").description("Migrate workflow files to current syntax via parse \u2192 regenerate round-trip").option("--dry-run", "Preview changes without writing files", false).option("--diff", "Show semantic diff before/after", false).action(async (glob2, options) => {
108010
- try {
108011
- await migrateCommand(glob2, options);
108012
- } catch (error2) {
108013
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108014
- process.exit(1);
108015
- }
108016
- });
108017
- program2.command("status <input>").description("Report implementation progress for stub workflows").option("-w, --workflow-name <name>", "Specific workflow name").option("--json", "Output as JSON", false).action(async (input, options) => {
108018
- try {
108019
- await statusCommand(input, options);
108020
- } catch (error2) {
108021
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108022
- process.exit(1);
108023
- }
108024
- });
108025
- program2.command("implement <input> <node>").description("Replace a stub node with a real function skeleton").option("-w, --workflow-name <name>", "Specific workflow name").option("-p, --preview", "Preview the generated code without writing", false).action(async (input, node, options) => {
108026
- try {
108027
- await implementCommand(input, node, options);
108028
- } catch (error2) {
108029
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108030
- process.exit(1);
108031
- }
108032
- });
108033
- program2.command("changelog").description("Generate changelog from git history, categorized by file path").option("--last-tag", "From last git tag to HEAD", false).option("--since <date>", 'Date-based range (e.g., "2024-01-01")').option("-r, --range <range>", 'Custom git range (e.g., "v0.1.0..HEAD")').action(async (options) => {
108034
- try {
108035
- await changelogCommand(options);
108036
- } catch (error2) {
108037
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108038
- process.exit(1);
108039
- }
108040
- });
108041
- program2.command("docs [args...]").description("Browse reference documentation").option("--json", "Output as JSON", false).option("--compact", "Return compact LLM-friendly version", false).action(async (args, options) => {
108042
- try {
108043
- if (args.length === 0) {
108044
- await docsListCommand(options);
108045
- } else if (args[0] === "search") {
108046
- const query = args.slice(1).join(" ");
108047
- if (!query) {
108048
- logger.error("Usage: flow-weaver docs search <query>");
108049
- process.exit(1);
108050
- }
108051
- await docsSearchCommand(query, options);
108052
- } else {
108053
- await docsReadCommand(args[0], options);
108077
+ pluginCmd.command("init <name>").description("Scaffold a new external plugin").option("-a, --area <area>", "Component area: sidebar, main, toolbar, modal, panel", "panel").option("--no-system", "Skip generating a system module").option("-p, --preview", "Preview generated files without writing", false).option("--force", "Overwrite existing files", false).action(wrapAction(async (name, options) => {
108078
+ await pluginInitCommand(name, options);
108079
+ }));
108080
+ program2.command("migrate <glob>").description("Migrate workflow files to current syntax via parse \u2192 regenerate round-trip").option("--dry-run", "Preview changes without writing files", false).option("--diff", "Show semantic diff before/after", false).action(wrapAction(async (glob2, options) => {
108081
+ await migrateCommand(glob2, options);
108082
+ }));
108083
+ program2.command("status <input>").description("Report implementation progress for stub workflows").option("-w, --workflow <name>", "Specific workflow name").option("--json", "Output as JSON", false).action(wrapAction(async (input, options) => {
108084
+ if (options.workflow) options.workflowName = options.workflow;
108085
+ await statusCommand(input, options);
108086
+ }));
108087
+ program2.command("implement <input> <node>").description("Replace a stub node with a real function skeleton").option("-w, --workflow <name>", "Specific workflow name").option("-p, --preview", "Preview the generated code without writing", false).action(wrapAction(async (input, node, options) => {
108088
+ if (options.workflow) options.workflowName = options.workflow;
108089
+ await implementCommand(input, node, options);
108090
+ }));
108091
+ program2.command("changelog").description("Generate changelog from git history, categorized by file path").option("--last-tag", "From last git tag to HEAD", false).option("--since <date>", 'Date-based range (e.g., "2024-01-01")').option("-r, --range <range>", 'Custom git range (e.g., "v0.1.0..HEAD")').action(wrapAction(async (options) => {
108092
+ await changelogCommand(options);
108093
+ }));
108094
+ program2.command("docs [args...]").description("Browse reference documentation").option("--json", "Output as JSON", false).option("--compact", "Return compact LLM-friendly version", false).action(wrapAction(async (args, options) => {
108095
+ if (args.length === 0 || args[0] === "list") {
108096
+ await docsListCommand(options);
108097
+ } else if (args[0] === "search") {
108098
+ const query = args.slice(1).join(" ");
108099
+ if (!query) {
108100
+ logger.error("Usage: flow-weaver docs search <query>");
108101
+ process.exit(1);
108054
108102
  }
108055
- } catch (error2) {
108056
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108057
- process.exit(1);
108058
- }
108059
- });
108060
- program2.command("context [preset]").description("Generate LLM context bundle from documentation and grammar").option("--profile <profile>", "Output profile: standalone or assistant", "standalone").option("--topics <slugs>", "Comma-separated topic slugs (overrides preset)").option("--add <slugs>", "Comma-separated topic slugs to add to preset").option("--no-grammar", "Omit EBNF grammar section").option("-o, --output <path>", "Write to file instead of stdout").option("--list", "List available presets and exit").action(async (preset, options) => {
108061
- try {
108062
- await contextCommand(preset, options);
108063
- } catch (error2) {
108064
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108065
- process.exit(1);
108103
+ await docsSearchCommand(query, options);
108104
+ } else {
108105
+ await docsReadCommand(args[0], options);
108066
108106
  }
108067
- });
108107
+ }));
108108
+ program2.command("context [preset]").description("Generate LLM context bundle from documentation and grammar").option("--profile <profile>", "Output profile: standalone or assistant", "standalone").option("--topics <slugs>", "Comma-separated topic slugs (overrides preset)").option("--add <slugs>", "Comma-separated topic slugs to add to preset").option("--no-grammar", "Omit EBNF grammar section").option("-o, --output <path>", "Write to file instead of stdout").option("--list", "List available presets and exit").action(wrapAction(async (preset, options) => {
108109
+ await contextCommand(preset, options);
108110
+ }));
108068
108111
  var marketCmd = program2.command("market").description("Discover, install, and publish marketplace packages");
108069
- marketCmd.command("init <name>").description("Scaffold a new marketplace package").option("-d, --description <desc>", "Package description").option("-a, --author <author>", "Author name").option("-y, --yes", "Skip prompts and use defaults", false).action(async (name, options) => {
108070
- try {
108071
- await marketInitCommand(name, options);
108072
- } catch (error2) {
108073
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108074
- process.exit(1);
108075
- }
108076
- });
108077
- marketCmd.command("pack [directory]").description("Validate and generate flowweaver.manifest.json").option("--json", "Output results as JSON", false).option("--verbose", "Show parse warnings", false).action(async (directory, options) => {
108078
- try {
108079
- await marketPackCommand(directory, options);
108080
- } catch (error2) {
108081
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108082
- process.exit(1);
108083
- }
108084
- });
108085
- marketCmd.command("publish [directory]").description("Pack and publish to npm").option("--dry-run", "Preview without publishing", false).option("--tag <tag>", "npm dist-tag").action(async (directory, options) => {
108086
- try {
108087
- await marketPublishCommand(directory, options);
108088
- } catch (error2) {
108089
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108090
- process.exit(1);
108091
- }
108092
- });
108093
- marketCmd.command("install <package>").description("Install a marketplace package").option("--json", "Output results as JSON", false).action(async (packageSpec, options) => {
108094
- try {
108095
- await marketInstallCommand(packageSpec, options);
108096
- } catch (error2) {
108097
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108098
- process.exit(1);
108099
- }
108100
- });
108101
- marketCmd.command("search [query]").description("Search npm for marketplace packages").option("-l, --limit <number>", "Max results", "20").option("-r, --registry <url>", "Custom registry search URL (e.g., private npm registry)").option("--json", "Output as JSON", false).action(async (query, options) => {
108102
- try {
108103
- await marketSearchCommand(query, { ...options, limit: parseInt(options.limit, 10) });
108104
- } catch (error2) {
108105
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108106
- process.exit(1);
108107
- }
108108
- });
108109
- marketCmd.command("list").description("List installed marketplace packages").option("--json", "Output as JSON", false).action(async (options) => {
108110
- try {
108111
- await marketListCommand(options);
108112
- } catch (error2) {
108113
- logger.error(`Command failed: ${getErrorMessage(error2)}`);
108114
- process.exit(1);
108115
- }
108116
- });
108117
- program2.on("--help", () => {
108118
- logger.newline();
108119
- logger.section("Examples");
108120
- logger.log(" $ flow-weaver compile my-workflow.ts");
108121
- logger.log(" $ flow-weaver compile '**/*.ts' -o .output");
108122
- logger.log(" $ flow-weaver compile my-workflow.ts --format cjs");
108123
- logger.log(" $ flow-weaver describe workflow.ts");
108124
- logger.log(" $ flow-weaver describe workflow.ts --format mermaid");
108125
- logger.log(" $ flow-weaver describe workflow.ts --node validator");
108126
- logger.log(" $ flow-weaver diagram workflow.ts");
108127
- logger.log(" $ flow-weaver diagram workflow.ts --theme light -o diagram.svg");
108128
- logger.log(" $ flow-weaver diagram workflow.ts --format html -o diagram.html");
108129
- logger.log(" $ flow-weaver diff workflow-v1.ts workflow-v2.ts");
108130
- logger.log(" $ flow-weaver diff workflow-v1.ts workflow-v2.ts --format json");
108131
- logger.log(" $ flow-weaver validate '**/*.ts'");
108132
- logger.log(" $ flow-weaver watch 'src/**/*.ts' -o dist");
108133
- logger.log(" $ flow-weaver create workflow simple my-workflow.ts");
108134
- logger.log(" $ flow-weaver create workflow ai-agent agent.ts --provider openai --model gpt-4o");
108135
- logger.log(" $ flow-weaver create node myProcessor my-workflow.ts");
108136
- logger.log(" $ flow-weaver templates");
108137
- logger.log(" $ flow-weaver pattern list ./patterns");
108138
- logger.log(" $ flow-weaver pattern apply pattern.ts workflow.ts");
108139
- logger.log(" $ flow-weaver pattern extract workflow.ts --nodes a,b -o extracted.ts");
108140
- logger.log(" $ flow-weaver init my-project");
108141
- logger.log(" $ flow-weaver init --template ai-agent -y");
108142
- logger.log(" $ flow-weaver init my-project --format cjs");
108143
- logger.log(" $ flow-weaver doctor");
108144
- logger.log(" $ flow-weaver doctor --json");
108145
- logger.newline();
108146
- logger.section("Plugin Commands");
108147
- logger.log(" $ flow-weaver plugin init my-plugin");
108148
- logger.log(" $ flow-weaver plugin init my-plugin --area sidebar --no-system");
108149
- logger.log(" $ flow-weaver plugin init my-plugin --preview");
108150
- logger.newline();
108151
- logger.section("Deployment Commands");
108152
- logger.log(` $ flow-weaver run workflow.ts --params '{"a": 5}'`);
108153
- logger.log(" $ flow-weaver serve ./workflows --port 8080");
108154
- logger.log(" $ flow-weaver export workflow.ts --target vercel --output api/");
108155
- logger.log(" $ flow-weaver export workflows.ts --target lambda --output dist/ --multi");
108156
- logger.log(" $ flow-weaver export workflows.ts --target lambda --output dist/ --multi --docs");
108157
- logger.log(" $ flow-weaver export workflow.ts --target inngest --output dist/ --durable-steps");
108158
- logger.log(" $ flow-weaver compile workflow.ts --target inngest");
108159
- logger.log(" $ flow-weaver openapi ./workflows --output api-spec.json");
108160
- logger.newline();
108161
- logger.section("Marketplace Commands");
108162
- logger.log(" $ flow-weaver market init openai");
108163
- logger.log(" $ flow-weaver market pack");
108164
- logger.log(" $ flow-weaver market publish");
108165
- logger.log(" $ flow-weaver market publish --dry-run");
108166
- logger.log(" $ flow-weaver market install flowweaver-pack-openai");
108167
- logger.log(" $ flow-weaver market search openai");
108168
- logger.log(" $ flow-weaver market list");
108169
- logger.newline();
108170
- logger.section("Documentation");
108171
- logger.log(" $ flow-weaver docs");
108172
- logger.log(" $ flow-weaver docs read error-codes");
108173
- logger.log(" $ flow-weaver docs read scaffold --compact");
108174
- logger.log(' $ flow-weaver docs search "missing workflow"');
108175
- logger.log(" $ flow-weaver docs read error-codes --json");
108176
- logger.newline();
108177
- logger.section("Migration & Changelog");
108178
- logger.log(" $ flow-weaver migrate '**/*.ts'");
108179
- logger.log(" $ flow-weaver migrate '**/*.ts' --dry-run");
108180
- logger.log(" $ flow-weaver migrate 'src/**/*.ts' --diff");
108181
- logger.log(" $ flow-weaver changelog --last-tag");
108182
- logger.log(" $ flow-weaver changelog --range v0.1.0..HEAD");
108183
- logger.log(" $ flow-weaver changelog --since 2024-01-01");
108184
- logger.newline();
108185
- });
108186
- program2.parse(process.argv);
108112
+ marketCmd.command("init <name>").description("Scaffold a new marketplace package").option("-d, --description <desc>", "Package description").option("-a, --author <author>", "Author name").option("-y, --yes", "Skip prompts and use defaults", false).action(wrapAction(async (name, options) => {
108113
+ await marketInitCommand(name, options);
108114
+ }));
108115
+ marketCmd.command("pack [directory]").description("Validate and generate flowweaver.manifest.json").option("--json", "Output results as JSON", false).option("--verbose", "Show parse warnings", false).action(wrapAction(async (directory, options) => {
108116
+ await marketPackCommand(directory, options);
108117
+ }));
108118
+ marketCmd.command("publish [directory]").description("Pack and publish to npm").option("--dry-run", "Preview without publishing", false).option("--tag <tag>", "npm dist-tag").action(wrapAction(async (directory, options) => {
108119
+ await marketPublishCommand(directory, options);
108120
+ }));
108121
+ marketCmd.command("install <package>").description("Install a marketplace package").option("--json", "Output results as JSON", false).action(wrapAction(async (packageSpec, options) => {
108122
+ await marketInstallCommand(packageSpec, options);
108123
+ }));
108124
+ marketCmd.command("search [query]").description("Search npm for marketplace packages").option("-l, --limit <number>", "Max results", "20").option("-r, --registry <url>", "Custom registry search URL (e.g., private npm registry)").option("--json", "Output as JSON", false).action(wrapAction(async (query, options) => {
108125
+ await marketSearchCommand(query, { ...options, limit: parseInt(options.limit, 10) });
108126
+ }));
108127
+ marketCmd.command("list").description("List installed marketplace packages").option("--json", "Output as JSON", false).action(wrapAction(async (options) => {
108128
+ await marketListCommand(options);
108129
+ }));
108130
+ program2.addHelpText("after", `
108131
+ Examples:
108132
+
108133
+ $ flow-weaver compile my-workflow.ts
108134
+ $ flow-weaver validate 'src/**/*.ts'
108135
+ $ flow-weaver run workflow.ts --params '{"a": 5}'
108136
+ $ flow-weaver describe workflow.ts --format ascii-compact
108137
+ $ flow-weaver init my-project
108138
+
108139
+ Run flow-weaver <command> --help for detailed usage.
108140
+ `);
108187
108141
  if (!process.argv.slice(2).length) {
108188
- program2.outputHelp();
108142
+ logger.banner(version2);
108143
+ console.log();
108144
+ console.log(" Usage: flow-weaver <command> [options]");
108145
+ console.log();
108146
+ console.log(" Get started:");
108147
+ console.log(" init [dir] Create a new project");
108148
+ console.log(" compile <input> Compile workflow files");
108149
+ console.log(" validate <input> Validate without compiling");
108150
+ console.log(" run <input> Execute a workflow");
108151
+ console.log(" doctor Check project environment");
108152
+ console.log();
108153
+ console.log(" Run " + logger.highlight("flow-weaver --help") + " for all commands.");
108154
+ console.log();
108155
+ process.exit(0);
108189
108156
  }
108157
+ program2.parse(process.argv);
108190
108158
  /*! Bundled license information:
108191
108159
 
108192
108160
  lodash-es/lodash.js: