@formigio/fazemos-cli 0.10.6 → 0.10.8

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.
package/dist/index.js CHANGED
@@ -19,6 +19,20 @@ function parseNumber(val) {
19
19
  throw new Error(`Invalid number: ${val}`);
20
20
  return n;
21
21
  }
22
+ function parseStreamSilenceAbortMs(val) {
23
+ const n = Number(val);
24
+ if (!Number.isInteger(n) || n < 30000 || n > 1800000) {
25
+ throw new Error(`stream_silence_abort_ms must be an integer between 30000 and 1800000 (got ${val})`);
26
+ }
27
+ return n;
28
+ }
29
+ function formatMsHuman(ms) {
30
+ if (ms >= 60000) {
31
+ const min = ms / 60000;
32
+ return Number.isInteger(min) ? `${min} min` : `${min.toFixed(1)} min`;
33
+ }
34
+ return `${ms / 1000}s`;
35
+ }
22
36
  function parseJson(val, flag) {
23
37
  try {
24
38
  return JSON.parse(val);
@@ -2809,6 +2823,9 @@ templates
2809
2823
  else if (step.outputs?.length) {
2810
2824
  console.log(' Inputs: none');
2811
2825
  }
2826
+ if (step.stream_silence_abort_ms) {
2827
+ console.log(` Stream Silence Abort: ${step.stream_silence_abort_ms.toLocaleString()}ms (${formatMsHuman(step.stream_silence_abort_ms)})`);
2828
+ }
2812
2829
  if (step.execution_config && Object.keys(step.execution_config).length) {
2813
2830
  const ec = step.execution_config;
2814
2831
  console.log(' Execution config:');
@@ -3161,6 +3178,7 @@ templates
3161
3178
  .option('--after <stepId>', 'Insert after this step within the same phase (sets sort_order to target + 1, shifts subsequent steps). Target must live in the phase named by --phase.')
3162
3179
  .option('--sort-order <n>', 'Set sort_order directly (lower-level escape hatch)', parseNumber)
3163
3180
  .option('--agent-config <json>', 'Per-step agent config overrides as JSON (e.g., \'{"model":"opus","maxBudgetUsd":20}\'). Overrides agent member defaults for: model, maxBudgetUsd, maxTurns, timeoutMs, cwd, repos')
3181
+ .option('--stream-silence-abort-ms <ms>', 'Stream silence abort threshold in milliseconds (30000-1800000)', parseStreamSilenceAbortMs)
3164
3182
  .action(async (templateId, opts) => {
3165
3183
  try {
3166
3184
  if (!VALID_STEP_TYPES.includes(opts.type)) {
@@ -3220,6 +3238,8 @@ templates
3220
3238
  };
3221
3239
  if (opts.agentConfig)
3222
3240
  step.agent_config = parseJson(opts.agentConfig, '--agent-config');
3241
+ if (opts.streamSilenceAbortMs !== undefined)
3242
+ step.stream_silence_abort_ms = opts.streamSilenceAbortMs;
3223
3243
  // Positioning: --after or --sort-order
3224
3244
  if (opts.after && opts.sortOrder !== undefined) {
3225
3245
  console.error(chalk.red('Cannot use both --after and --sort-order'));
@@ -3245,6 +3265,9 @@ templates
3245
3265
  await api('PUT', `/api/pipeline-templates/${templateId}`, { definition: t.definition });
3246
3266
  console.log(chalk.green(`Added step: ${opts.name} (${opts.type}) to phase ${phase.name}`));
3247
3267
  console.log(` ID: ${step.id}`);
3268
+ if (step.stream_silence_abort_ms) {
3269
+ console.log(` Stream Silence Abort: ${step.stream_silence_abort_ms.toLocaleString()}ms (${formatMsHuman(step.stream_silence_abort_ms)})`);
3270
+ }
3248
3271
  }
3249
3272
  catch (err) {
3250
3273
  console.error(chalk.red(err.message));
@@ -3313,12 +3336,13 @@ templates
3313
3336
  .option('--env <json>', 'Environment variables for script steps as JSON')
3314
3337
  .option('--sections <text>', 'Agent instructions / step content. Use @filepath to load from a file (e.g., --sections @steps/review.md)')
3315
3338
  .option('--agent-config <json>', 'Per-step agent config overrides as JSON (merges with existing)')
3339
+ .option('--stream-silence-abort-ms <ms>', 'Stream silence abort threshold in milliseconds (30000-1800000)', parseStreamSilenceAbortMs)
3316
3340
  .action(async (templateId, opts) => {
3317
3341
  try {
3318
3342
  const hasUpdate = opts.name || opts.type || opts.role || opts.description != null
3319
3343
  || opts.reviewer != null || opts.maxReviewCycles != null || opts.parallelGroup != null
3320
3344
  || opts.image || opts.command || opts.timeout !== undefined || opts.workingDir || opts.env
3321
- || opts.agentConfig || opts.sections != null;
3345
+ || opts.agentConfig || opts.sections != null || opts.streamSilenceAbortMs !== undefined;
3322
3346
  if (!hasUpdate) {
3323
3347
  console.error(chalk.red('Provide at least one field to update'));
3324
3348
  process.exit(1);
@@ -3387,6 +3411,10 @@ templates
3387
3411
  if (opts.agentConfig) {
3388
3412
  step.agent_config = { ...(step.agent_config || {}), ...parseJson(opts.agentConfig, '--agent-config') };
3389
3413
  }
3414
+ // stream silence abort threshold
3415
+ if (opts.streamSilenceAbortMs !== undefined) {
3416
+ step.stream_silence_abort_ms = opts.streamSilenceAbortMs;
3417
+ }
3390
3418
  await api('PUT', `/api/pipeline-templates/${templateId}`, { definition: t.definition });
3391
3419
  console.log(chalk.green(`Updated step: ${step.name}`));
3392
3420
  }
@@ -3536,6 +3564,7 @@ templates
3536
3564
  .option('--pipeline-input <name>', 'Pipeline-level input name (use instead of --source-step/--source-output)')
3537
3565
  .option('--description <desc>', 'What this data is used for')
3538
3566
  .option('--optional', 'Mark as not required (default: required)')
3567
+ .option('--required-value <value>', 'Require the upstream output to have this value before dispatching. Comma-separate multiple accepted values. Example: --required-value approved Example: --required-value "published,skipped"')
3539
3568
  .action(async (templateId, opts) => {
3540
3569
  try {
3541
3570
  const hasSrc = opts.sourceStep || opts.sourceOutput;
@@ -3601,14 +3630,24 @@ templates
3601
3630
  }
3602
3631
  if (opts.description)
3603
3632
  input.description = opts.description;
3633
+ if (opts.requiredValue !== undefined) {
3634
+ const parts = opts.requiredValue.split(',').map((v) => v.trim()).filter((v) => v.length > 0);
3635
+ input.required_value = parts.length === 1 ? parts[0] : parts;
3636
+ }
3604
3637
  step.inputs.push(input);
3605
3638
  await api('PUT', `/api/pipeline-templates/${templateId}`, { definition: t.definition });
3606
3639
  if (opts.sourceStep) {
3607
3640
  const srcStep = findStepById(t.definition, opts.sourceStep);
3608
- console.log(chalk.green(`Added input ← ${opts.name} ← ${srcStep.name}.${opts.sourceOutput} to ${step.name}`));
3641
+ let msg = `Added input ← ${opts.name} ← ${srcStep.name}.${opts.sourceOutput} to ${step.name}`;
3642
+ if (opts.requiredValue !== undefined)
3643
+ msg += `\n Required value: ${opts.requiredValue}`;
3644
+ console.log(chalk.green(msg));
3609
3645
  }
3610
3646
  else {
3611
- console.log(chalk.green(`Added input ← ${opts.name} ← pipeline.${opts.pipelineInput} to ${step.name}`));
3647
+ let msg = `Added input ← ${opts.name} ← pipeline.${opts.pipelineInput} to ${step.name}`;
3648
+ if (opts.requiredValue !== undefined)
3649
+ msg += `\n Required value: ${opts.requiredValue}`;
3650
+ console.log(chalk.green(msg));
3612
3651
  }
3613
3652
  }
3614
3653
  catch (err) {